WebSocket API

Subscribe to JSON-RPC Real-Time Events

Overview

Shinami supports publish / subscribe using JSON-RPC notifications via our WebSocket API. This service allows clients to filter and subscribe to real-time event streams of transactions and events generated by the Sui network.

Authentication, Connection and Subscription Limits, and Error Handling

Authentication

You authenticate via an access key passed in a header ('X-Api-Key: ACCESS_KEY') or in the request url: https://api.shinami.com/node/v1/ACCESS_KEY. Node Service access keys are network-specific (Devnet, Testnet, Mainnet). In your Shinami dashboard you can create multiple keys per network if needed. When you create a key with Node Service rights, you assign a max QPS and max number of WebSocket subscriptions the key is allowed. Your account plan determines the total QPS and WebSocket subscriptions you can assign per network, and we show this in your dashboard. You can change a key's values later by clicking on the + next to the key in Access Keys table to open the key editor.

Connection and Subscription Limits

🚧

WebSocket Connection and Subscription Limits:

The Access Keys page in your Shinami web dashboard show how many WebSocket subscriptions you can have per network (Devnet, Testnet, Mainnet). This varies based on your billing plan.

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 and the Shinami Clients 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 "@shinami/clients";
import { SuiEvent } from "@mysten/sui.js";

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

Methods

suix_subscribeEvent

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.

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 and the Shinami Clients 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}}"}]}

# This example targets a Testnet event that gets emitted when following
# our Sponsored Transaction and Invisible Wallet tutorials 
# If you're following those tutorials, make sure to use a testnet 
# Node Service access key when you connect to this service.
 { "jsonrpc":"2.0", "id":1, "method": "suix_subscribeEvent", "params": [{"MoveEventType":"0xfa0e78030bd16672174c2d6cc4cd5d1d1423d03c28a74909b2a148eda8bcca16::clock::TimeEvent"}]}
 
import { createSuiClient } from "@shinami/clients";
import { SuiEvent } from "@mysten/sui.js";

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

await provider.subscribeEvent({ 
    filter: {{SuiEventFilter}},
    onMessage : {{eventReceiptCallbackFunction: (SuiEvent) => void}}
});
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);
} 

// This targets a Testnet event that gets emitted when following
// our Sponsored Transaction and Invisible Wallet tutorials 
// If you're following those tutorials, make sure to use a testnet 
// Node Service access key when you connect to this service.
let unsubscribeMethod = await provider.subscribeEvent({ 
    filter: {
        MoveEventType: "0xfa0e78030bd16672174c2d6cc4cd5d1d1423d03c28a74909b2a148eda8bcca16::clock::TimeEvent"
    },
    onMessage : printEventType // function to be called when an event is received
});

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.

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'
}

suix_unsubscribeEvent

Description
Unsubscribe from a Sui event stream.

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.

suix_subscribeTransaction

Description
Subscribe to a Sui transaction stream that matches the provided filter.

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 and the Shinami Clients 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";
import { TransactionEffects } from "@mysten/sui.js";

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

await provider.subscribeTransaction({
    filter: {{TransactionFilter}}
    },
    onMessage: {{eventReceiptCallbackFunction: (TransactionEffects)=> void}}
});
import { createSuiClient } from "@shinami/clients";
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
});

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.

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'
    ]
}

suix_unsubscribeTransaction

Description
Unsubscribe from a Sui transaction stream.

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 ---- ##

## 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.
##
##   {"Package": "0xa0eba10b173538c8fecca1dff298e488402cc9ff374f8a12ca7758eebe830b66"}
##
{ "jsonrpc":"2.0", "id":1, "method": "suix_subscribeEvent", "params": [{ "Package": "0xa0eba10b173538c8fecca1dff298e488402cc9ff374f8a12ca7758eebe830b66"}]}

## 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"}]}



## ---- Combining filters with operators ---- ##

## And: matches if both filters match the event
##
##   {"And": [{"Package": "0x01102b1385ec3741f1becb20ed4d3bb19a37b6cbf53d7df64a1d848b2bd6ec7b"},{"Sender": "0xa39edfb89e6a21e89570711845c6c8f412d86bb208e571faf6ea1fc6470172d7"}]}
##
{ "jsonrpc":"2.0", "id":1, "method": "suix_subscribeEvent", "params": [{"And": [{"Package": "0x01102b1385ec3741f1becb20ed4d3bb19a37b6cbf53d7df64a1d848b2bd6ec7b"},{"Sender": "0xa39edfb89e6a21e89570711845c6c8f412d86bb208e571faf6ea1fc6470172d7"}]}]}


## Or: matches if one or both filters match the event
##
##   {"Or": [{"Package": "0x01102b1385ec3741f1becb20ed4d3bb19a37b6cbf53d7df64a1d848b2bd6ec7b"},{"Sender": "0xa39edfb89e6a21e89570711845c6c8f412d86bb208e571faf6ea1fc6470172d7"}]}
##
{ "jsonrpc":"2.0", "id":1, "method": "suix_subscribeEvent", "params": [{"Or": [{"Package": "0x01102b1385ec3741f1becb20ed4d3bb19a37b6cbf53d7df64a1d848b2bd6ec7b"},{"Sender": "0xa39edfb89e6a21e89570711845c6c8f412d86bb208e571faf6ea1fc6470172d7"}]}]}


## Any: matches if any of the filters match the event
##
##   {"Any": [{"Package": "0x01102b1385ec3741f1becb20ed4d3bb19a37b6cbf53d7df64a1d848b2bd6ec7b"},{"Sender": "0xa39edfb89e6a21e89570711845c6c8f412d86bb208e571faf6ea1fc6470172d7"}]}
##
{ "jsonrpc":"2.0", "id":1, "method": "suix_subscribeEvent", "params": [{"Any": [{"Package": "0x01102b1385ec3741f1becb20ed4d3bb19a37b6cbf53d7df64a1d848b2bd6ec7b"},{"Sender": "0xa39edfb89e6a21e89570711845c6c8f412d86bb208e571faf6ea1fc6470172d7"}]}]}


## All: matches if all of the filters match the event
##
##   {"All": [{"Package": "0x01102b1385ec3741f1becb20ed4d3bb19a37b6cbf53d7df64a1d848b2bd6ec7b"},{"Sender": "0xa39edfb89e6a21e89570711845c6c8f412d86bb208e571faf6ea1fc6470172d7"}]}
##
{ "jsonrpc":"2.0", "id":1, "method": "suix_subscribeEvent", "params": [{"And": [{"Package": "0x01102b1385ec3741f1becb20ed4d3bb19a37b6cbf53d7df64a1d848b2bd6ec7b"},{"Sender": "0xa39edfb89e6a21e89570711845c6c8f412d86bb208e571faf6ea1fc6470172d7"}]}]}



## -- 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";
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}}"
}