WebSocket Connections
To use WebSocket subscriptions, create a WebSocketClient and attach it to your API instance:
// socket.js
import {WebSocketClient} from 'adamant-api';
const ws = new WebSocketClient({
/* options */
});
export {ws};// api.js
import {AdamantApi} from 'adamant-api';
import {ws} from './socket.js';
const api = new AdamantApi({
/* options */
});
api.initSocket(ws); // WebSocket initialization
export {api};Options
type WsType = 'ws' | 'wss';
type TransactionDirection =
| 'allDirections'
| 'self'
| 'incoming'
| 'outgoing';
interface WsOptions {
/** ADM address to subscribe to transactions. */
admAddress?: AdamantAddress;
/** Multiple ADM addresses to subscribe to transactions. */
admAddresses?: AdamantAddress[];
/** Transaction types to subscribe to. */
types?: number[];
/** Message (chat asset) types to subscribe to. */
assetChatTypes?: number[];
/** Transaction direction delivered to handlers. Default is `allDirections`. */
direction?: TransactionDirection;
/** Websocket type: `'wss'` or `'ws'`. `'wss'` is recommended. */
wsType?: WsType;
/**
* Connect to the node with the lowest ping. Not recommended.
* Default is `false`.
*/
useFastest?: boolean;
/** Max attempts to reconnect to the websocket. Default is `3`. */
maxTries?: number;
/** Delay before reconnection, in ms. Default is `5000`. */
reconnectionDelay?: number;
/** Logger for websocket events. Default logger is `console`. */
logger?: Logger;
}Example:
const ws = new WebSocketClient({admAddress: 'U1234567890', useFastest: true});Subscribing to multiple addresses and types
Since ADAMANT Node v0.8.4/v0.9.0, a single client can subscribe to several addresses, several transaction types, and several chat asset (message) types at once:
import {WebSocketClient, TransactionType, MessageType} from 'adamant-api';
const ws = new WebSocketClient({
// Watch several accounts with one connection
admAddresses: ['U1234567890', 'U0987654321'],
// Only these transaction types
types: [TransactionType.SEND, TransactionType.CHAT_MESSAGE],
// Of chat messages, only these asset (message) types
assetChatTypes: [MessageType.Chat, MessageType.Rich],
});Use the singular admAddress for a single account, or admAddresses for several. The WebSocket client delivers live events only and does not backfill transactions missed while disconnected. Applications that require gap-free processing should reconcile transaction history through the REST API after a reconnection.
Filtering by transaction direction
ADAMANT Node sends transactions where a subscribed address is either the sender or recipient. The SDK can filter them client-side before calling handlers:
api.initSocket({
admAddress: config.address,
wsType: config.ws_type,
direction: 'incoming',
});
api.socket?.on(transaction => {
// Only incoming transactions for config.address are delivered here.
txParser(transaction);
});Use incoming for transactions received by a subscribed address, outgoing for transactions sent by one, and self when sender and recipient are the same subscribed address. allDirections is the default and preserves the previous behavior. A transaction between two different addresses in admAddresses matches both incoming and outgoing. Direction filtering requires at least one admAddress or admAddresses entry.
Blocks and balance changes
ADAMANT Node v0.10.2 adds opt-in block and account-balance events. Registering the corresponding SDK handler sends the subscription after every connection, so reconnecting to the same or another healthy node restores it automatically.
.onNewBlock()
Registers a handler for compact headers of newly applied blocks and opts the socket in to the node's newBlock event:
ws.onNewBlock(block => {
console.log(block.height, block.id, block.numberOfTransactions);
});The payload includes id, height, timestamp, generatorPublicKey, numberOfTransactions, totalAmount, totalFee, and reward. It is a live notification, not a backfill: blocks applied while the client is disconnected must be reconciled through getBlocks().
.onBalanceChange()
Registers a handler for current confirmed and/or unconfirmed balances. Balance subscriptions require at least one admAddress or admAddresses value:
const ws = new WebSocketClient({
admAddresses: ['U1234567890', 'U0987654321'],
});
// Both supported fields
ws.onBalanceChange(change => {
console.log(change.address, change.balance, change.unconfirmedBalance);
});
// Only confirmed-balance changes
ws.onBalanceChange('balance', change => {
console.log(change.address, change.balance);
});You can also pass ['balance', 'unconfirmedBalance'] explicitly. Each included value is the account's current absolute balance after the node processes the change, not an amount added to or subtracted from the previous balance. Replace the cached value with it; do not apply it as a delta. Values are decimal strings in 1/10^8 ADM units.
The node emits no initial snapshot and may include only the fields that changed. An omitted field is unchanged, not zero. Fetch getAccountBalance() first when the application needs a starting value.
Connection lifecycle
.connect() / .disconnect()
Open and close the underlying socket connection explicitly.
ws.connect();
ws.disconnect();.onConnection()
Adds an event listener for the initial connection.
type ConnectionHandler = (connectedNode: string) => void;
function onConnection(callback: ConnectionHandler): this;// wss://clown.adamant.im
ws.onConnection(connectedNode => console.log(connectedNode));.onReconnection()
Adds an event listener for reconnection. When options.useFastest is true, each reconnection uses the currently fastest node from the latest health-check results, which may differ from the previously connected node.
function onReconnection(callback: ConnectionHandler): this;// wss://endless.adamant.im
ws.onReconnection(connectedNode => console.log(connectedNode));.catch()
Sets an error handler for all event handlers and disconnection errors.
function catch(callback: ErrorHandler): this;Handling a middleware error:
ws.onMessage(() => {
throw new Error('catch me');
});
ws.catch(error => {
console.log(error); // Error: catch me
});Handling a disconnection error:
ws.catch(error => {
if (error.name === 'AdamantWsConnectionError') {
const errorMessages = {
connection_error: 'Connection error',
disconnection: 'Disconnected',
};
console.log(errorMessages[error.reason]);
} else {
// Other errors
}
});Subscribing to transactions
.on()
Adds a handler for all transaction types, or for specific transaction types.
function on(handler: AnyTransactionHandler): this;
function on<T extends EventType>(
types: T | T[],
handler: TransactionHandler<TransactionMap[T]>
): this;import {TransactionType} from 'adamant-api';
// All transactions
ws.on(genericTransactionHandler);
// Specific transaction type
ws.on(TransactionType.SEND, sendTransactionHandler);.off()
Removes a handler from all transaction, block, and balance event types. Removing the last block handler also disables the node-side block subscription for the current socket.
function off(handler: SingleWebSocketHandler): this;function myFunction() {
console.log('Hello!');
ws.off(myFunction);
}
ws.on(myFunction);.onMessage()
Registers a handler for Chat Message transactions. You may optionally filter by message type.
function onMessage(handler: TransactionHandler<ChatMessageTransaction>): this;
function onMessage(
messageTypes: MessageType | MessageType[],
handler: TransactionHandler<ChatMessageTransaction>
): this;ws.onMessage(chatMessageHandler);Convenience helpers for specific message types:
ws.onChatMessage(handler); // MessageType.Chat
ws.onRichMessage(handler); // MessageType.Rich
ws.onSignalMessage(handler); // MessageType.SignalOther transaction helpers
ws.onTransfer(tokenTransferHandler); // Token Transfer
ws.onNewDelegate(registerDelegateHandler); // Register Delegate
ws.onVoteForDelegate(voteForDelegateHandler); // Vote for Delegate
ws.onKVS(kvsHandler); // Key-Value StoreFor the full, generated type signatures, see the API Reference.