Subscribe to Real-Time Sui Events

🚧

NOTICE: This service is being fully removed by Mysten any day now. As of testnet-v1.28.2 release notes on July 2, 2024 (https://github.com/MystenLabs/sui/releases/tag/testnet-v1.28.2): "This also formally deprecates the websocket jsonrpc service which will be removed completely within another few releases... We have found that this service is overall unreliable and leads to production issues/missing data or events when used and as such have decided to sunset it." Removal will follow standard procedure, meaning it will leave Testnet first and then Mainnet a week or two later.

Note: For the JSON_RPC API, the non-websocket suix_queryEvents and suix_queryTransactionBlocks requests will still be supported moving forward as a means to obtain event and transaction data.

Overview

This service allows clients to subscribe to real-time event streams of transactions and events generated by the Sui network.

Authentication, Connection and Subscription Limits, and Error Handling

Authentication

See our Authentication and API Keys guide, which includes guidance on how to assign the maximum number of WebSocket Service connections and subscriptions an API key is allowed. The number you set for a key applies to both.

Connection and Subscription limits

If you are at your connection limit and try to open another, you will get a HTTP 429. If you are at your subscription limit and try to open another, you will get a JSON-RPC code -31011.

Error Handling

See our Error Reference for guidance on the errors you may receive from our services, including a section on errors specific to the WebSocket API.

Connecting to our WebSocket Service

Below is an example of connecting to our WebSocket service, subscribing to an event stream, and then unsubscribing. The examples use the command line tool wscat, the Shinami Clients SDK, and the Mysten Rust SDK.

Replace all instances of {{name}} with the actual value for that name

# connect to the service
% wscat -c wss://api.shinami.com/node/v1/{{nodeAccessKey}}

# create a subscription to see events for transactions sent to a given Move package
>  { "jsonrpc":"2.0", "id":1, "method":"suix_subscribeEvent", "params":[{"Package":"{{packageId}}"}]}
# will return to you a subscription_id
< {"jsonrpc":"2.0","result":<subscription_id>,"id":1} 
# e.g. {"jsonrpc":"2.0","result":2861815076633913,"id":1}

# unsubscribe from the previously created subscription
> {"jsonrpc":"2.0", "id":1, "method": "suix_unsubscribeEvent", "params": [{{subscription_id}}]} # e.g. {"jsonrpc":"2.0", "id":1, "method": "suix_unsubscribeEvent", "params": [2861815076633913]}
# will return to you whether the unsubscribe was successful.
< "jsonrpc":"2.0","result":true,"id":1}
import { createSuiClient } from from "@shinami/clients/sui";
import { SuiEvent } from "@mysten/sui.js/client";

const provider = createSuiClient({{nodeAccessKey}});

// simple example to print the event type of each event received
function onMessage(event: SuiEvent) {
    console.log(event.type);
} 

// when you add a subscription, you get a method to call to unsubscribe
let unsubscribeMethod = await provider.subscribeEvent({ 
    filter: {
        Package : "0xa0eba10b173538c8fecca1dff298e488402cc9ff374f8a12ca7758eebe830b66"
    },
    onMessage : onMessage // function to be called when an event is recieved
});

let unsubscriptionResponse = await unsubscribeMethod();

console.log(unsubscriptionResponse);
// prints true or false
use futures::stream::StreamExt;
use sui_sdk::rpc_types::EventFilter;
use sui_sdk::SuiClientBuilder;

#[tokio::main]
async fn main() -> Result<(), anyhow::Error> {

    let ws = SuiClientBuilder::default()
        .ws_url("wss://api.shinami.com:443/node/v1/{{nodeAccessKey}}")
        .build("https://api.shinami.com:443/node/v1/{{nodeAccessKey}}")
        .await?;

    let mut subscribe = ws
        .event_api()
        .subscribe_event(EventFilter::All(vec![]))
        .await?;

    loop {
        println!("{:?}", subscribe.next().await);
    }
}

Methods

(deprecated) suix_subscribeEvent

🚧

BE PREPARED: Active Websocket connections will be broken when our Fullnodes restart (due to regular protocol upgrades, auto-restarts due to a health issue, etc). Make sure that you have a way to handle a broken connection and reconnect.

Description
Subscribe to a Sui event stream that matches a provided filter. For each event that matches the filter, a notification with the event data and subscription ID is returned to the client. Deprecated. See notice at top of page.

Params

  • filter : SuiEventFilter - enables fine control of the event subscription stream using one or a combination of event attribute filters, as detailed in the Event filters section
  • Shinami TypeScript SDK only:
    • onMessage: Function of type (SuiEvent) => void to be called when a message is received in the event stream.

Example Request Template
The following example demonstrates how to subscribe to Move events that a given package emits. The examples use the command line tool wscat, the Shinami Clients SDK, and the Mysten Rust SDK. The last line of the Shell example shows how to listen for events to a Testnet package we make calls to in our Gas Station tutorial and our Invisible Wallets tutorial.

Replace all instances of {{name}} with the actual value for that name

# connect to the service
% wscat -c wss://api.shinami.com/node/v1/{{nodeAccessKey}}

# create a subscription to see events for transactions sent to a given Move package
>  { "jsonrpc":"2.0", "id":1, "method": "suix_subscribeEvent", "params": [{"Package":"{{packageId}}"}]}
 
import { createSuiClient } from "@shinami/clients/sui";
import { SuiEvent } from "@mysten/sui.js";

const provider = createSuiClient({{nodeAccessKey}});

await provider.subscribeEvent({ 
    filter: {{SuiEventFilter}},
    onMessage : {{eventReceiptCallbackFunction: (SuiEvent) => void}}
});
import { createSuiClient } from "@shinami/clients/sui";
import { SuiEvent } from "@mysten/sui.js";

const provider = createSuiClient({{nodeAccessKey}});

// simple example to print the type of each event received
function printEventType(event: SuiEvent) {
    console.log(event.type);
} 
use futures::stream::StreamExt;
use sui_sdk::rpc_types::EventFilter;
use sui_sdk::SuiClientBuilder;

#[tokio::main]
async fn main() -> Result<(), anyhow::Error> {

    let ws = SuiClientBuilder::default()
        .ws_url("wss://api.shinami.com:443/node/v1/{{nodeAccessKey}}")
        .build("https://api.shinami.com:443/node/v1/{{nodeAccessKey}}")
        .await?;

    let mut subscribe = ws
        .event_api()
        .subscribe_event(EventFilter::All(vec![]))
        .await?;

    loop {
        println!("{:?}", subscribe.next().await);
    }
}

Example Response

{
    "jsonrpc":"2.0",
    "result": <subscription_id>, // e.g. 2861815076633913
    "id":1
} 
// You recieve a function you can call to unsubscribe
() => Promise<boolean>

Response Data

  • wscat
  • Shinami TypeScript SDK
    • A function with no parameters that returns a boolean. Call this to unsubscribe from the subscription you just created. Returns true when the un-subscription was successful.
  • Mysten Rust SDK

Event Stream Data Type

  • SuiEvent and the subscription id for this event stream.

Event Stream Example Payload

{
    "jsonrpc":"2.0",
    "method":"suix_subscribeEvent",
    "params":{
        "subscription":498694087448692,
        "result":{
            "id":{
                "txDigest":"5VrUNde9D6VzHCw4jeimbhhWN1YXEFR8APqEsPWSTmGT",
                "eventSeq":"0"
            },
            "packageId":"0xa0eba10b173538c8fecca1dff298e488402cc9ff374f8a12ca7758eebe830b66",
            "transactionModule":"spot_dex",
            "sender":"0x25171ad6a67b8c56de8935350e1531c0d3b2fbf1d9635a4ae7540db991c855ed",
            "type":"0xa0eba10b173538c8fecca1dff298e488402cc9ff374f8a12ca7758eebe830b66::spot_dex::SwapEvent<0x2::sui::SUI>",
            "parsedJson":{
                "amount_in":"24007854747",
                "amount_out":"9510199",
                "pool_id":"0x5af4976b871fa1813362f352fa4cada3883a96191bb7212db1bd5d13685ae305",
                "reserve_x":"279134708847",
                "reserve_y":"703743451694313",
                "user":"0x25171ad6a67b8c56de8935350e1531c0d3b2fbf1d9635a4ae7540db991c855ed"
            },
            "bcs":"YLFPB51Fk3NvkyotqiwnjZ3KnoKXtUBNwJtbAAh4a6szzs2WKLVHYYjzCuWjXwXonsSJrMht2fdfgzZQCYD5nZH68soTTX9kp9yprRmfD4f2RNtFD5L3J2B26cXdMnePuSf",
            "timestampMs":"1698078843950"
        }
    }
}
{
    id: {
        txDigest: 'BBbKmMMEmvBJtsXeCSfA14ozHN7KZpd4Hch2dk41oUi5',
        eventSeq: '0'
    },
    packageId: '0xa0eba10b173538c8fecca1dff298e488402cc9ff374f8a12ca7758eebe830b66',
    transactionModule: 'spot_dex',
    sender: '0x08d141f4c4f3d861d07c9c85480b2ddc983f17f101afd0291d9f8197c2a160a8',
    type: '0xa0eba10b173538c8fecca1dff298e488402cc9ff374f8a12ca7758eebe830b66::spot_dex::SwapEvent<0x94e7a8e71830d2b34b3edaa195dc24c45d142584f06fa257b73af753d766e690::celer_usdc_coin::CELER_USDC_COIN>',
    parsedJson: {
        amount_in: '2997990',
        amount_out: '7382709572',
        pool_id: '0xc216cdafaee1f417779f3f3051bfc70a4a6c1fe8c42107bf1db6b7a7b16cc936',
        reserve_x: '18749962925',
        reserve_y: '46226878392070',
        user: '0x08d141f4c4f3d861d07c9c85480b2ddc983f17f101afd0291d9f8197c2a160a8'
    },
    bcs: '29rp2tC1N9GjC7rNJNrLbJDiXXKJwq4cG12bxMKEYysTURVm7pyZPrXwJZdvcbv4gmt7SupZBS8dPEHuAwZcqBphJUhU1UFZp3pNKNUAAt8ZmoMrLqV5Q2q3Y3Bz7Mk9xkgf',
    timestampMs: '1698078744849'
}

(deprecated) suix_unsubscribeEvent

Description

Unsubscribe from a Sui event stream. Deprecated. See notice at top of page.

Params

  • wscat only
    • subscription_id: the ID of the subscription you are unsubscribing to

Example Request Template
The following example demonstrates how to unsubscribe from the event stream subscribed to in the suix_subscribeEvent example. The examples use the command line tool wscat and the Shinami Clients SDK.

Replace all instances of {{name}} with the actual value for that name

{"jsonrpc":"2.0", "id": 1, "method": "suix_unsubscribeEvent", "params": [{{subscription_id}}]}
# e.g. {"jsonrpc":"2.0", "id": 1, "method": "suix_unsubscribeEvent", "params": [2861815076633913]}
await unsubscribeMethod();

Example Response

{
    "jsonrpc":"2.0",
    "result":true,
    "id":1
}
true

Response Data

  • A Boolean representing whether the un-subscription attempt was successful.

(deprecated) suix_subscribeTransaction

🚧

BE PREPARED: Active Websocket connections will be broken when our Fullnodes restart (due to regular protocol upgrades, auto-restarts due to a health issue, etc). Make sure that you have a way to handle a broken connection and reconnect.

Description
Subscribe to a Sui transaction stream that matches the provided filter. Deprecated. See notice at top of page.

Params

  • filter : TransactionFilter Note: the FromOrToAddress, Checkpoint, TransactionKind, and TransactionKindIn filters do not work for WebSocket subscriptions.
  • Shinami TypeScript SDK only:
    • onMessage: Function of type (TransactionEffects) => void to be called when a transaction is received. See TransactionEffects for more info.

Example Request Template
The following example demonstrates how to subscribe to transactions that call a given package. The examples use the command line tool wscat, the Shinami Clients SDK, and the Mysten Rust SDK.

Replace all instances of {{name}} with the actual value for that name

# connect to the service
% wscat -c wss://api.shinami.com/node/v1/{{nodeAccessKey}}

{"jsonrpc":"2.0", "id":1, "method": "suix_subscribeTransaction", "params": [ {"MoveFunction": { "package":"{{packageId}}" }}]}
# e.g. {"jsonrpc":"2.0", "id":1, "method": "suix_subscribeTransaction", "params": [ {"MoveFunction": { "package":"0xa0eba10b173538c8fecca1dff298e488402cc9ff374f8a12ca7758eebe830b66" }}]}

import { createSuiClient } from "@shinami/clients/sui";
import { TransactionEffects } from "@mysten/sui.js";

const provider = createSuiClient({{nodeAccessKey}});

await provider.subscribeTransaction({
    filter: {{TransactionFilter}}
    },
    onMessage: {{eventReceiptCallbackFunction: (TransactionEffects)=> void}}
});
import { createSuiClient } from "@shinami/clients/sui";
import { TransactionEffects } from "@mysten/sui.js";

const provider = createSuiClient({{nodeAccessKey}});

// simple example to print the digest of the transaction associated with the event
function printTxDigest(event: TransactionEffects) {
    console.log(event.transactionDigest);
}  

let unsubscribeMethod = await provider.subscribeTransaction({
    filter: {
        MoveFunction : {
           package: "0xa0eba10b173538c8fecca1dff298e488402cc9ff374f8a12ca7758eebe830b66"
        }
    },
    onMessage: printTxDigest
});
use futures::stream::StreamExt;
use sui_sdk::rpc_types::TransactionFilter;
use sui_sdk::SuiClientBuilder;

#[tokio::main]
async fn main() -> Result<(), anyhow::Error> {

    let ws = SuiClientBuilder::default()
        .ws_url("wss://api.shinami.com:443/node/v1/{{nodeAccessKey}}")
        .build("https://api.shinami.com:443/node/v1/{{nodeAccessKey}}")
        .await?;

    let mut subscribe = ws
        .read_api()
        .subscribe_transaction(TransactionFilter::MoveFunction {
            package: "0x000000000000000000000000000000000000000000000000000000000000dee9".parse()?,
            module: Some("clob_v2".to_owned()),
            function: Some("place_limit_order".to_owned()),
        })
        .await?;

    loop {
        println!("{:?}", subscribe.next().await);
    }
}

Example Response

{
    "jsonrpc":"2.0",
    "result":<subscription_id>, // e.g. 2740101920696262
    "id":1
}
// You recieve a function you can call to unsubscribe
() => Promise<boolean>

Response Data

  • wscat
  • Shinami TypeScript SDK
    • A function with no parameters that returns a boolean. Call this to unsubscribe from the subscription you just created. Returns true when the un-subscription was successful.
  • Mysten Rust SDK

Transaction Stream Data Type

Transaction Stream Example Payload

{
    "jsonrpc":"2.0",
    "method":"suix_subscribeTransaction",
    "params":{
        "subscription":1130080684748192,
        "result":{
            "messageVersion":"v1",
            "status":{
                "status":"success"
            },
            "executedEpoch":"193",
            "gasUsed":{
                "computationCost":"750000",
                "storageCost":"7698800",
                "storageRebate":"6147108",
                "nonRefundableStorageFee":"62092"
            },
            "modifiedAtVersions":[
                {
                    "objectId":"0x002cfa57179a9d704b40338aade07d7e964a25f42eed3a81a69862eca8458f95",
                    "sequenceNumber":"33873771"
                },
                {
                    "objectId":"0x12da3f2f187c8c2dde39326e8c7b030ccee25fd579b3e9325c6659d7451b70b6",
                    "sequenceNumber":"33873771"
                }
            ],
            "sharedObjects":[
                {
                    "objectId":"0xc216cdafaee1f417779f3f3051bfc70a4a6c1fe8c42107bf1db6b7a7b16cc936",
                    "version":33873771,
                    "digest":"4Nd3yXc11KrTpPQgTr44sGBsgfHLUCDSxgC6GG7pQNga"
                }
            ],
            "transactionDigest":"iWHW3f6EEJajsiLcztCE8NbnKGhvpfM9nUeVe1X3X77",
            "created":[
                {
                    "owner":{
                        "AddressOwner":"0x08d141f4c4f3d861d07c9c85480b2ddc983f17f101afd0291d9f8197c2a160a8"
                    },
                    "reference":{
                        "objectId":"0x68121914a572446631ee5be99168019b05e0b126b2282f2bbe696ea9601d9c1f",
                        "version":33873772,
                        "digest":"2WDuRjc9VULFeNP5y8zRcBX2zUhvdicHokECB7d8UQeU"
                    }
                },
                {
                    "owner":{
                        "AddressOwner":"0x08d141f4c4f3d861d07c9c85480b2ddc983f17f101afd0291d9f8197c2a160a8"
                    },
                    "reference":{
                        "objectId":"0x905ac00f3a17d0119fe794f76de1a067903ba1653853e06f9f2e065cffbe0a4c",
                        "version":33873772,
                        "digest":"E3yP1CwW94wvK9w521G2rjn1CYTv4nhS5ieidvBoogNi"
                    }
                }
            ],
             "mutated":[
                {
                    "owner":{
                        "AddressOwner":"0x08d141f4c4f3d861d07c9c85480b2ddc983f17f101afd0291d9f8197c2a160a8"
                    },
                    "reference":{
                        "objectId":"0x002cfa57179a9d704b40338aade07d7e964a25f42eed3a81a69862eca8458f95",
                        "version":33873772,
                        "digest":"332jmeHiV2SAviwHN7Spw7FfM1Y31VJxbxB1RLBPzVmK"
                    }
                },
                {
                    "owner":{
                        "Shared":{
                            "initial_shared_version":15819270
                        }
                    },
                    "reference":{
                        "objectId":"0xc216cdafaee1f417779f3f3051bfc70a4a6c1fe8c42107bf1db6b7a7b16cc936",
                        "version":33873772,
                        "digest":"CUAJvEx5J6EZk57C9ocogAZKG2Pq7bcTDAkrxmQnfiGh"
                    }
                }
            ],
            "deleted":[
                {
                    "objectId":"0x3909b5f3eb51418441d4c1ef9ee3a134737d97e83460ddaed4d1718dd7100365",
                    "version":33873772,
                    "digest":"7gyGAp71YXQRoxmFBaHxofQXAipvgHyBKPyxmdSJxyvz"
                }
            ],
            "gasObject":{
                "owner":{
                    "AddressOwner":"0x08d141f4c4f3d861d07c9c85480b2ddc983f17f101afd0291d9f8197c2a160a8"
                },
                "reference":{
                    "objectId":"0x002cfa57179a9d704b40338aade07d7e964a25f42eed3a81a69862eca8458f95",
                    "version":33873772,
                    "digest":"332jmeHiV2SAviwHN7Spw7FfM1Y31VJxbxB1RLBPzVmK"
                }
            },
            "eventsDigest":"4KSQza7XokSPgpjr3LeynzZnir2EmU3FgJR8wzDcH6PF",
            "dependencies":[
                "2bk5THZSzSwBt8zSaxPwcCYBE6sc1zCAULhMACd6Tp8f",
                "AyKtDH3SphRpC6smucm7MpJtfJFa5ZzHUVtpGwidbyo4",
                "GGsDqhUEP1QokmZyrJkYguJutuN1qf2XY6RmtyDtSeM3",
                "GMvEqg7sxZkKUFYGXE4NqWKw1Vzyh1GttREPEKvQKzzA"
            ]
        }
    }
}
{
    messageVersion: 'v1',
    status: { status: 'success' },
    executedEpoch: '193',
    gasUsed: {
      computationCost: '750000',
      storageCost: '5874800',
      storageRebate: '4506876',
      nonRefundableStorageFee: '45524'
    },
    modifiedAtVersions: [
        {
            objectId: '0x0032b06bf2dadd8bc3e140c25235beff6a8f1deea0274519f34ad633ac4885f0',
            sequenceNumber: '33877614'
        },
        {
            objectId: '0x5af4976b871fa1813362f352fa4cada3883a96191bb7212db1bd5d13685ae305',
            sequenceNumber: '33877746'
        }
    ],
    sharedObjects: [
        {
            objectId: '0x5af4976b871fa1813362f352fa4cada3883a96191bb7212db1bd5d13685ae305',
            version: 33877746,
            digest: 'BeSZAQUo4UBAKttMpJLVmfGbuSNaXq6AxcWUHwVUnBnH'
        }
    ],
    transactionDigest: 'FsZy1Za6TMW8qb9VG38mLjSK31AaGz9E27SMcRMc7A6A',
    created: [
        { owner: [Object], reference: [Object] },
        { owner: [Object], reference: [Object] }
    ],
    mutated: [
        { owner: [Object], reference: [Object] },
        { owner: [Object], reference: [Object] }
    ],
    deleted: [
        {
            objectId: '0x9a4923e25ca5e071a03280cf4f03191ca55a973ebf68992c237df848866f77aa',
            version: 33877747,
            digest: '7gyGAp71YXQRoxmFBaHxofQXAipvgHyBKPyxmdSJxyvz'
        }
    ],
    gasObject: {
        owner: {
            AddressOwner: '0x25171ad6a67b8c56de8935350e1531c0d3b2fbf1d9635a4ae7540db991c855ed'
        },
        reference: {
            objectId: '0x0032b06bf2dadd8bc3e140c25235beff6a8f1deea0274519f34ad633ac4885f0',
            version: 33877747,
            digest: '8MBn4KgssZA3pt7s6521A6HFn6AJsm1SrUaE9FTJdCJd'
        }
    },
    eventsDigest: '7obRF2kBa9njgQppsBfWu6ocdRjYcPBgYo5JNdEctwQx',
    dependencies: [
        '55CSxm3svH2fXJpWk9eQzBCjMjR5cyBu95AYrJVAUHRu',
        '5LxMs4wctfAiJJoQ4Nkig1v2RbRKYPwjSobSJxTrDJCa',
        '9b9wP1PcLQyn4LBaWNWGWsRunYQDYj5gyxoUEcutZVkr',
        'GGsDqhUEP1QokmZyrJkYguJutuN1qf2XY6RmtyDtSeM3',
        'GMvEqg7sxZkKUFYGXE4NqWKw1Vzyh1GttREPEKvQKzzA'
    ]
}

(deprecated) suix_unsubscribeTransaction

Description
Unsubscribe from a Sui transaction stream. Deprecated. See notice at top of page.

Params

  • wscat only
    • subscription_id: the ID of the subscription you are unsubscribing to

Example Request Template

The following example demonstrates how to unsubscribe from the transaction stream subscribed to in the suix_subscribeTransaction example. The examples use the command line tool wscat and the Shinami Clients SDK.

Replace all instances of {{name}} with the actual value for that name

{"jsonrpc":"2.0", "id": 1, "method": "suix_unsubscribeTransaction", "params": [subscription_id]}
// e.g.  {"jsonrpc":"2.0", "id":1, "method": "suix_unsubscribeTransaction", "params": [2740101920696262]}

await unsubscribeMethod();

Example Response

{
  "jsonrpc":"2.0",
  "result": true,
  "id": 1
}
true

Response Data

  • A Boolean representing whether the un-subscription attempt was successful.

Event and Transaction Filter Examples

Event Filter Examples

The following examples demonstrate how to use the various SuiEventFilter options. The examples use the command line tool wscat and the Shinami Clients SDK. Note that the TimeRange filter does not successfully match events.

Example Request Template

Replace all instances of {{name}} with the actual value for that name

# connect to the service
% wscat -c wss://api.shinami.com/node/v1/{{nodeAccessKey}}

# create a subscription to see events for transactions sent to a given Move package
{ "jsonrpc":"2.0", "id":1, "method": "suix_subscribeEvent", "params": [{{SuiEventFilter}}]}

## ---- Example SuiEventFilter usage ---- ##

## Sender: matches events triggered by transactions executed by the given sender address
##
##   {"Sender":"0x02a212de6a9dfa3a69e22387acfbafbb1a9e591bd9d636e7895dcfc8de05f331"}
##
{ "jsonrpc":"2.0", "id":1, "method": "suix_subscribeEvent", "params": [{"Sender":"0x02a212de6a9dfa3a69e22387acfbafbb1a9e591bd9d636e7895dcfc8de05f331"}]}

## MoveEventType: matches the provided Move module event name
##
##   NOTE: the request DOES NOT check that the function and module names exist,
##   and matching is also case sensitive. The request also does not check that the 
##   package id exists. It only checks that these parameters are sent in the expected format. 
##   Make sure you double check your names and package id.
##
##   {"MoveEventType":"{{packageId}}::{{moduleName}}::{{eventName}}"}
##   {"MoveEventType": "0xa0eba10b173538c8fecca1dff298e488402cc9ff374f8a12ca7758eebe830b66::spot_dex::SwapEvent" }
##
{ "jsonrpc":"2.0", "id":1, "method": "suix_subscribeEvent", "params": [{"MoveEventType": "0xa0eba10b173538c8fecca1dff298e488402cc9ff374f8a12ca7758eebe830b66::spot_dex::SwapEvent"}]}

## MoveModule: matches events emitted by the provided Move module
##
##    NOTE: the request DOES NOT check that and module name exists,
##    and matching is also case sensitive. The request also does not check that the 
##    package id exists. It only checks that these parameters are sent in the expected format. 
##    Make sure you double check your module name and package id.
##
##   {"MoveModule": { "module": "spot_dex","package": "0xa0eba10b173538c8fecca1dff298e488402cc9ff374f8a12ca7758eebe830b66"}}
##
{ "jsonrpc":"2.0", "id":1, "method": "suix_subscribeEvent", "params": [{ "MoveModule": { "module": "spot_dex","package": "0xa0eba10b173538c8fecca1dff298e488402cc9ff374f8a12ca7758eebe830b66"}}]}


## MoveEventModule: matches events emitted by the provided Move module
##
##   NOTE: the request DOES NOT check that and module name exists,
##   and matching is also case sensitive. The request also does not check that the 
##   package id exists. It only checks that these parameters are sent in the expected format. 
##   Make sure you double check your module name and package id.
##
##   {"MoveEventModule": {"module": "spot_dex","package": "0xa0eba10b173538c8fecca1dff298e488402cc9ff374f8a12ca7758eebe830b66"}}
##
{ "jsonrpc":"2.0", "id":1, "method": "suix_subscribeEvent", "params": [{"MoveEventModule": {"module": "spot_dex","package": "0xa0eba10b173538c8fecca1dff298e488402cc9ff374f8a12ca7758eebe830b66"}}]}

## Transaction: matches events emitted by the provided digest
##
##   NOTE: This one doesn't really make sense for a websocket connection -
##   to listen for one transaction - but, you could, for example
##   listen for one very special sponsored transaction to be executed
##
##   {"Transaction": "BqjfsayknWKj1kwqkMnpHo62SviUvhfE7yCCwj6pdMt8"}
##
{ "jsonrpc":"2.0", "id":1, "method": "suix_subscribeEvent", "params": [{"Transaction": "BqjfsayknWKj1kwqkMnpHo62SviUvhfE7yCCwj6pdMt8"}]}



## -- The following will not throw an error but do not match events -- ##

## TimeRange
## {"TimeRange": {"endTime": "1698720000","startTime": "1698092253"}}
## { "jsonrpc":"2.0", "id":1, "method": "suix_subscribeEvent", "params": [{"TimeRange": {"endTime": "1698720000","startTime": "1698092253"}}]}

import { createSuiClient } from "@shinami/clients";
import { SuiEvent } from "@mysten/sui.js";

const provider = createSuiClient({{nodeAccessKey}});

// simple example to print the type of each event received
function printEventType(event: SuiEvent) {
    console.log(event.type);
} 

let unsubscribeMethod = await provider.subscribeEvent({ 
    filter: {{SuiEventFilter}}, // see examples below
    onMessage : printEventType // `(SuiEvent) => void` function you define. To be called when an event is received
});

// ---- EXAMPLE SuiEventFilter USAGE BELOW ---- //

// Package: matches events emitted by the given package
//
//   NOTE: The request does not check that the package id exists, only that it's 
//   in the expected format. Make sure you double check the package id.
//
let unsubscribeMethod = await provider.subscribeEvent({ 
    filter: {
        Package: "0xa0eba10b173538c8fecca1dff298e488402cc9ff374f8a12ca7758eebe830b66"
    },
    onMessage : printEventType // `(SuiEvent) => void` function you define. To be called when an event is received
});


// Sender: matches events triggered by transactions executed by the given sender address
let unsubscribeMethod = await provider.subscribeEvent({ 
    filter: {
        Sender: "0x02a212de6a9dfa3a69e22387acfbafbb1a9e591bd9d636e7895dcfc8de05f331"
    },
    onMessage : printEventType // `(SuiEvent) => void` function you define. To be called when an event is received
});


// MoveEventType: matches the provided Move module event name  
//
//   NOTE: the request DOES NOT check that the function and module names exist,
//   and matching is also case sensitive. The request also does not check that the 
//   package id exists. It only checks that these parameters are sent in the expected format. 
//   Make sure you double check your names and package id.
//
//   { MoveEventType:"{{packageId}}::{{moduleName}}::{{eventName}}"}
//
let unsubscribeMethod = await provider.subscribeEvent({ 
    filter: {
        MoveEventType: "0xa0eba10b173538c8fecca1dff298e488402cc9ff374f8a12ca7758eebe830b66::spot_dex::LiquidityRemovedEvent"
    },
    onMessage : printEventType // `(SuiEvent) => void` function you define. To be called when an event is received
});


// MoveModule: matches events emitted by the provided Move module
//
//   NOTE: the request DOES NOT check that and module name exists,
//   and matching is also case sensitive. The request also does not check that the 
//   package id exists. It only checks that these parameters are sent in the expected format. 
//   Make sure you double check your module name and package id.
let unsubscribeMethod = await provider.subscribeEvent({ 
    filter: {
        MoveModule: {
            module: "spot_dex",
            package: "0xa0eba10b173538c8fecca1dff298e488402cc9ff374f8a12ca7758eebe830b66"
        }
    },
    onMessage : printEventType // `(SuiEvent) => void` function you define. To be called when an event is received
});


// MoveEventModule: matches events emitted by the provided Move module
//
//   NOTE: the request DOES NOT check that and module name exists,
//   and matching is also case sensitive. The request also does not check that the 
//   package id exists. It only checks that these parameters are sent in the expected format. 
//   Make sure you double check your module name and package id.
//
let unsubscribeMethod = await provider.subscribeEvent({ 
    filter: {
        MoveEventModule: {
            module: "spot_dex",
            package: "0xa0eba10b173538c8fecca1dff298e488402cc9ff374f8a12ca7758eebe830b66"
        }
    },
    onMessage : printEventType // `(SuiEvent) => void` function you define. To be called when an event is received
});


// Transaction: matches events emitted by the provided digest
//
//   NOTE: This one doesn't really make sense for a websocket connection -
//   to listen for one transaction - but, you could, for example
//   listen for one very special sponsored transaction to be executed
//
let unsubscribeMethod = await provider.subscribeEvent({ 
    filter: {
        Transaction: "Dg8e1tkr7AuTqGH7EAtra717zBYpzmshnKXhn1ioATJd"
    },
    onMessage : printEventType // `(SuiEvent) => void` function you define. To be called when an event is received
});


// ---- Combining filters with operators ---- //

// Any: matches events that satisfy any of the provided filters
let unsubscribeMethod = await provider.subscribeEvent({ 
    filter: {
        Any: [ 
            {Package: "0xa0eba10b173538c8fecca1dff298e488402cc9ff374f8a12ca7758eebe830b66"},
            {Sender: "0x02a212de6a9dfa3a69e22387acfbafbb1a9e591bd9d636e7895dcfc8de05f331"}
        ]
    },
    onMessage : printEventType // `(SuiEvent) => void` function you define. To be called when an event is received
});



// All: matches events that satisfy all the provided filters
let unsubscribeMethod = await provider.subscribeEvent({ 
    filter: {
        All: [ 
            {Package: "0xa0eba10b173538c8fecca1dff298e488402cc9ff374f8a12ca7758eebe830b66"},
            {Sender: "0x02a212de6a9dfa3a69e22387acfbafbb1a9e591bd9d636e7895dcfc8de05f331"}
        ]
    },
    onMessage : printEventType // `(SuiEvent) => void` function you define. To be called when an event is received
});


// Or: matches events that satisfy either of the provided filters. Takes exactly 2.
let unsubscribeMethod = await provider.subscribeEvent({ 
    filter: {
        Or: [ 
            {Package: "0xa0eba10b173538c8fecca1dff298e488402cc9ff374f8a12ca7758eebe830b66"},
            {Sender: "0x02a212de6a9dfa3a69e22387acfbafbb1a9e591bd9d636e7895dcfc8de05f331"}
        ]
    },
    onMessage : printEventType // `(SuiEvent) => void` function you define. To be called when an event is received
});



// And: matches events that satisfy both of the provided filters. Takes exactly 2.
let unsubscribeMethod = await provider.subscribeEvent({ 
    filter: {
        And: [ 
            {Package: "0xa0eba10b173538c8fecca1dff298e488402cc9ff374f8a12ca7758eebe830b66"},
            {Sender: "0x02a212de6a9dfa3a69e22387acfbafbb1a9e591bd9d636e7895dcfc8de05f331"}
        ]
    },
    onMessage : printEventType // `(SuiEvent) => void` function you define. To be called when an event is received
});



// -- The following will not throw an error but do not match events -- //

{TimeRange: {endTime: "1698092253",startTime: "1698720000"}}

Transaction Filter Examples

The following examples demonstrate how to use the variousTransactionFilter options. The examples use the command line tool wscat and the Shinami Clients SDK.. Note: the FromOrToAddress, Checkpoint, TransactionKind, and TransactionKindIn filters do not successfully match transactions.

Example Request Template

Replace all instances of {{name}} with the actual value for that name

# connect to the service
% wscat -c wss://api.shinami.com/node/v1/{{nodeAccessKey}}

{"jsonrpc":"2.0", "id":1, "method": "suix_subscribeTransaction", "params": [ {{TransactionFilter}}]}

## ---- Example TransactionFilter usage ---- ##

## MoveFunction: matches when the move function is called by a transaction
##
##   NOTE: the request DOES NOT check that the function and module names exist,
##   and matching is also case sensitive. The request also does not check that the 
##   package id exists. It only checks that these parameters are sent in the expected format. 
##   Make sure you double check your names and package id.
##
##   {"MoveFunction": { "function": "swap_token_y", "module": "spot_dex", "package": "0xa0eba10b173538c8fecca1dff298e488402cc9ff374f8a12ca7758eebe830b66"}} 
##
{"jsonrpc":"2.0", "id":1, "method": "suix_subscribeTransaction", "params": [ {"MoveFunction": { "function": "swap_token_y", "module": "spot_dex", "package": "0xa0eba10b173538c8fecca1dff298e488402cc9ff374f8a12ca7758eebe830b66"}}]}


## InputObject: matches when the objectId is a transaction input
##
##   NOTE: the request DOES NOT check that the object id exists, only that it's 
##   sent in a valid format. 
##   Make sure you double check your object id.
##
##   { "InputObject": "0xd0086b7713e0487bbf5bb4a1e30a000794e570590a6041155cdbebee3cb1cb77"} 
##
{"jsonrpc":"2.0", "id":1, "method": "suix_subscribeTransaction", "params": [ { "InputObject": "0xd0086b7713e0487bbf5bb4a1e30a000794e570590a6041155cdbebee3cb1cb77"}]}


## ChangedObject: matches when the objectId is changed by a transaction.
##
##   NOTE: the request DOES NOT check that the object id exists, only that it's 
##   sent in a valid format. 
##   Make sure you double check your object id.
##
##   {"ChangedObject": "0xd0086b7713e0487bbf5bb4a1e30a000794e570590a6041155cdbebee3cb1cb77"} 
##
{"jsonrpc":"2.0", "id":1, "method": "suix_subscribeTransaction", "params": [ {"ChangedObject": "0xd0086b7713e0487bbf5bb4a1e30a000794e570590a6041155cdbebee3cb1cb77"}]}

## FromAddress: matches when the provided address is the sender of a transaction
##
## { "FromAddress": "0xa66b25208b75d1cc0c0e73695ea1a295a9c2912b5b5d9154497a0f4dc08e11d0"} 
##
{"jsonrpc":"2.0", "id":1, "method": "suix_subscribeTransaction", "params": [ { "FromAddress": "0xa66b25208b75d1cc0c0e73695ea1a295a9c2912b5b5d9154497a0f4dc08e11d0"}]}


## ToAddress: matches when the provided address is the sender of a transaction
##
##   { "ToAddress": "0xa66b25208b75d1cc0c0e73695ea1a295a9c2912b5b5d9154497a0f4dc08e11d0"} 
##
{"jsonrpc":"2.0", "id":1, "method": "suix_subscribeTransaction", "params": [ { "ToAddress": "0xa66b25208b75d1cc0c0e73695ea1a295a9c2912b5b5d9154497a0f4dc08e11d0"}]}


## FromAndToAddress: matches when the provided addresses match the sender and recipient of a transaction, respectively
##
##   {"FromAndToAddress": {"from": "0xa66b25208b75d1cc0c0e73695ea1a295a9c2912b5b5d9154497a0f4dc08e11d0", "to": "0xa66b25208b75d1cc0c0e73695ea1a295a9c2912b5b5d9154497a0f4dc08e11d0"}} 
##
{"jsonrpc":"2.0", "id":1, "method": "suix_subscribeTransaction", "params": [ {"FromAndToAddress": {"from": "0xa66b25208b75d1cc0c0e73695ea1a295a9c2912b5b5d9154497a0f4dc08e11d0", "to": "0xa66b25208b75d1cc0c0e73695ea1a295a9c2912b5b5d9154497a0f4dc08e11d0"}}  ]}



## -- The following will not throw an error but do not match transactions -- ##

{"FromOrToAddress": {"addr": "{{SuiAddress}}"}} 

{"Checkpoint" : "{{checkpointNum}}"}

{"TransactionKind": "{{TransactionKindName}}"}
 
{"TransactionKindIn": ["{{TransactionKindName}}","{{TransactionKindName}}"]}

import { createSuiClient } from "@shinami/clients/sui";
import { TransactionEffects } from "@mysten/sui.js";

const provider = createSuiClient({{nodeAccessKey}});

// simple example to print the digest of the transaction associated with the event
function printTxDigest(event: TransactionEffects) {
    console.log(event.transactionDigest);
}

let unsubscribeMethod = await provider.subscribeTransaction({
    filter: {{TransactionFilter}},
    onMessage: printTxDigest // `(TransactionEffects)=> void` function you define to be called when an event is received
});

// ---- Example TransactionFilter usage ---- //

// MoveFunction: matches when the move function is called by a transaction
//
//   NOTE: the request DOES NOT check that the function and module names exist,
//   and matching is also case sensitive. The request also does not check that the 
//   package id exists. It only checks that these parameters are sent in the expected format. 
//   Make sure you double check your names and package id.
//
let unsubscribeMethod = await provider.subscribeTransaction({
    filter: {
        MoveFunction: {
            function: "swap_token_y",
            module: "spot_dex",
            package: "0xa0eba10b173538c8fecca1dff298e488402cc9ff374f8a12ca7758eebe830b66"
        }
    },
    onMessage: printTxDigest // `(TransactionEffects)=> void` function you define to be called when an event is received
});


// InputObject: matches when the objectId is a transaction input
//
//   NOTE: the request DOES NOT check that the object id exists, only that it's 
//   sent in a valid format. 
//   Make sure you double check your object id.
//
let unsubscribeMethod = await provider.subscribeTransaction({
    filter: {
        InputObject: "0xd0086b7713e0487bbf5bb4a1e30a000794e570590a6041155cdbebee3cb1cb77"
    },
    onMessage: printTxDigest // `(TransactionEffects)=> void` function you define to be called when an event is received
});


// ChangedObject: matches when the objectId is changed by a transaction.
//
//   NOTE: the request DOES NOT check that the object id exists, only that it's 
//   sent in a valid format. 
//   Make sure you double check your object id.
//
let unsubscribeMethod = await provider.subscribeTransaction({
    filter: {
        ChangedObject: "0xd0086b7713e0487bbf5bb4a1e30a000794e570590a6041155cdbebee3cb1cb77"
    },
    onMessage: printTxDigest // `(TransactionEffects)=> void` function you define to be called when an event is received
});


// FromAddress: matches when the provided address is the sender of a transaction
let unsubscribeMethod = await provider.subscribeTransaction({
    filter: {
        FromAddress: "0xa66b25208b75d1cc0c0e73695ea1a295a9c2912b5b5d9154497a0f4dc08e11d0"
    },
    onMessage: printTxDigest // `(TransactionEffects)=> void` function you define to be called when an event is received
});


// ToAddress: matches when the provided address is the sender of a transaction
let unsubscribeMethod = await provider.subscribeTransaction({
    filter: {
        ToAddress: "0xa66b25208b75d1cc0c0e73695ea1a295a9c2912b5b5d9154497a0f4dc08e11d0"
    },
    onMessage: printTxDigest // `(TransactionEffects)=> void` function you define to be called when an event is received
});


// FromAndToAddress: matches when the provided addresses match the sender and recipient of a transaction, respectively
let unsubscribeMethod = await provider.subscribeTransaction({
    filter: {
        FromAndToAddress: {
            from: "0xa66b25208b75d1cc0c0e73695ea1a295a9c2912b5b5d9154497a0f4dc08e11d0",
            to: "0xa66b25208b75d1cc0c0e73695ea1a295a9c2912b5b5d9154497a0f4dc08e11d0"
        }
    },
    onMessage: printTxDigest // `(TransactionEffects)=> void` function you define to be called when an event is received
});



// -- The following will not throw an error but do not match transactions -- //

{
    FromOrToAddress: {
        addr: "{{SuiAddress}}"
    }
}

{
    TransactionKind: "{{TransactionKindName}}"
}

{
    TransactionKindIn: ["{{TransactionKindName}}","{{TransactionKindName}}"]
}

{
    Checkpoint : "{{checkpointNum}}"
}