Skip to content

Commit 7768d17

Browse files
committed
add filtered streams
1 parent 5fa3a7a commit 7768d17

1 file changed

Lines changed: 125 additions & 2 deletions

File tree

docs/sdk-and-tools/rest-api/ws-subscriptions.md

Lines changed: 125 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ Subscribers receive events strictly as they occur on the blockchain, filtered by
2525
* **Behavior:** You are notified immediately when a new event matches your filter.
2626
* **Content:** Data flows in real-time from the moment of subscription.
2727
* **Duplicates:** **No duplicate events are sent.** You receive each item exactly once.
28-
* **Available Streams:** Only `Transactions` and `Events` are supported in this mode.
28+
* **Available Streams:** `Transactions`, `Events`, and `Transfers` are supported in this mode.
2929

3030
## Rest API models compatibility
3131
The MultiversX WebSocket Subscription API provides real-time blockchain data identical in structure to REST API responses:
@@ -81,6 +81,7 @@ https://<returned-url>/ws/subscription
8181
| **Pulse** | Events | `subscribeEvents` | `eventsUpdate` | Recurring latest events |
8282
| **Pulse** | Stats | `subscribeStats` | `statsUpdate` | Recurring chain stats |
8383
| **Filtered** | Custom Txs | `subscribeCustomTransactions` | `customTransactionUpdate` | Real-time filtered Txs |
84+
| **Filtered** | Custom Transfers | `subscribeCustomTransfers` | `customTransferUpdate` | Real-time filtered Transfers |
8485
| **Filtered** | Custom Events| `subscribeCustomEvents` | `customEventUpdate` | Real-time filtered Events |
8586

8687
---
@@ -430,6 +431,116 @@ async function main() {
430431

431432
---
432433

434+
### Custom Transfers (Filtered)
435+
436+
Subscribes to value transfers (EGLD, ESDT, NFT) matching specific criteria. This stream is optimized for tracking movement of assets and supports flexible filtering like generic address matching and token identifiers.
437+
438+
#### Subscribe Event
439+
`subscribeCustomTransfers`
440+
441+
#### Payload (DTO)
442+
443+
| Field | Type | Required | Description |
444+
|---|---|---|---|
445+
| sender | string | NO* | Filter by sender address (bech32) |
446+
| receiver | string | NO* | Filter by receiver address (bech32) |
447+
| relayer | string | NO* | Filter by the relayer address (for meta-transactions) |
448+
| function | string | NO* | Filter by smart contract function name |
449+
| token | string | NO* | Filter by Token Identifier (e.g., `USDC-c76f1f` or `EGLD` for native egld) |
450+
| address | string | NO** | **Universal Filter:** Matches if the address is the Sender **OR** Receiver **OR** Relayer. |
451+
452+
*\*At least one field from the list above must be provided.*
453+
*\*\*The `address` field cannot be combined with `sender`, `receiver`, or `relayer` in the same payload.*
454+
455+
#### Example usage
456+
457+
**Scenario: Listen for specific Token transfers (e.g., USDC)**
458+
Useful for tracking volume on a specific token.
459+
460+
```js
461+
import { io } from "socket.io-client";
462+
463+
async function main() {
464+
const { url } = await fetch("https://api.multiversx.com/websocket/config")
465+
.then((r) => r.json());
466+
467+
const socket = io(`https://${url}`, { path: "/ws/subscription" });
468+
469+
const payload = {
470+
token: "USDC-c76f1f"
471+
};
472+
473+
socket.emit("subscribeCustomTransfers", payload);
474+
475+
socket.on("customTransferUpdate", (data) => {
476+
// data.transfers: Transaction[] (filtered)
477+
// data.timestampMs: number
478+
console.log("New USDC Transfer:", data);
479+
});
480+
}
481+
```
482+
483+
**Scenario: Listen for ANY activity related to an address**
484+
Using the `address` field is a shorthand to avoid creating 3 separate subscriptions (sender, receiver, relayer).
485+
486+
```js
487+
const payload = {
488+
address: "erd1..." // Will capture incoming, outgoing, and relayed transfers
489+
};
490+
491+
socket.emit("subscribeCustomTransfers", payload);
492+
```
493+
494+
#### Update Example
495+
496+
```json
497+
{
498+
"transfers": [
499+
{
500+
"txHash": "cb5d0644ef40943db8035ff50913c4a974a469c2479a73c3cd3ab8de9027be0f",
501+
"receiver": "erd1qqqqqqqqqqqqqpgqxn6hj5m9x33zuq0xynjkusd8tsz3u6a94fvsn2m2ry",
502+
"receiverShard": 1,
503+
"sender": "erd1qqqqqqqqqqqqqpgqcc69ts8409p3h77q5chsaqz57y6hugvc4fvs64k74v",
504+
"senderAssets": {
505+
...
506+
},
507+
"senderShard": 1,
508+
"status": "success",
509+
"value": "0",
510+
"timestamp": 1765963650,
511+
"function": "exchange",
512+
"action": {
513+
"category": "esdtNft",
514+
"name": "transfer",
515+
"description": "Transfer",
516+
"arguments": {
517+
"transfers": [
518+
{
519+
"type": "FungibleESDT",
520+
"ticker": "USDC",
521+
"svgUrl": "https://tools.multiversx.com/assets-cdn/tokens/USDC-c76f1f/icon.svg",
522+
"token": "USDC-c76f1f",
523+
"decimals": 6,
524+
"value": "4087442"
525+
}
526+
],
527+
"receiver": "erd1qqqqqqqqqqqqqpgqxn6hj5m9x33zuq0xynjkusd8tsz3u6a94fvsn2m2ry",
528+
"functionName": "exchange",
529+
"functionArgs": [
530+
"01"
531+
]
532+
}
533+
},
534+
"type": "SmartContractResult",
535+
"originalTxHash": "46bb841a087c5ce95ca28d0e95c860c661b4d32514bb2970137536036bf591b3"
536+
},
537+
],
538+
"timestampMs": 1763718888000
539+
}
540+
```
541+
542+
---
543+
433544
### Custom Events (Filtered)
434545

435546
Subscribes to smart contract events matching specific criteria as they happen.
@@ -517,6 +628,18 @@ You must unsubscribe with:
517628
socket.emit("unsubscribeCustomTransactions", payload);
518629
```
519630

631+
### Example: Unsubscribe from Custom Transfers
632+
If you subscribed with:
633+
```js
634+
const payload = { token: "USDC-c76f1f" };
635+
socket.emit("subscribeCustomTransfers", payload);
636+
```
637+
638+
You must unsubscribe with:
639+
```js
640+
socket.emit("unsubscribeCustomTransfers", payload);
641+
```
642+
520643
### Example: Unsubscribe from Blocks
521644
If you subscribed with:
522645
```js
@@ -597,7 +720,7 @@ socket.on("error", (errorData) => {
597720

598721
- WebSocket endpoint is dynamically obtained via `/websocket/config`.
599722
- **Pulse Stream Subscriptions:** periodic updates with possible duplicates (Transactions, Blocks, Pool, Events, Stats).
600-
- **Filtered Stream Subscriptions:** real-time updates with only new data (CustomTransactions, CustomEvents).
723+
- **Filtered Stream Subscriptions:** real-time updates with only new data (CustomTransactions, **CustomTransfers**, CustomEvents).
601724
- **Unsubscribing:** Use `un` prefix + same payload.
602725
- Payload DTOs define allowed fields and required/optional rules.
603726
- Update messages mirror REST API and include `<resource>Count` fields.

0 commit comments

Comments
 (0)