Skip to content

Conversation

@vinhphuctadang
Copy link

@vinhphuctadang vinhphuctadang commented Mar 10, 2025

Context

CCXT supports stream via websocket for now => this PR unblocks the integration process
This also open doors for easier FE integration: no protos, no indexers needed to start some streams.

Changes

  1. Add websocket server on another the port that wraps existing ChainStream
  • 1 websocket supports multiple request => better scale, it's like industry standard, using cometbft WebsocketManager (which has good testsuite, neat, default dependency)
  • API: support subscribe, unsubscribe with schema just like binance schema:
{
   id: 1
   method: 'subscribe'
   params: any
}

https://developers.binance.com/docs/binance-spot-api-docs/web-socket-api/request-format
image

  1. For ChainStream > StreamRequest:
    Added OmitEmptyResponse flag, optional for now, when it's true, only changes are sent => no need to send messages every block

Test

Start injective-core

injectived start --websocket-server="0.0.0.0:8080" 

js client script

const WebSocket = require('ws');
const ws = new WebSocket('ws://localhost:8080/ws');
(async() => {
    let n = 0
    ws.on('open', () => {
        console.log('Connected to server');
        ws.send(JSON.stringify({
            'id': 1,
            'method': 'subscribe',
            'params': {
                'q': {
                    'bank_balances_filter': {
                        'accounts': ['inj1dzqd00lfd4y4qy2pxa0dsdwzfnmsu27hgttswz']
                    },
                    'omit_empty_response': true,
                },
            },
        }))

        ws.send(JSON.stringify({
            'id': 2,
            'method': 'subscribe',
            'params': {
                'q': {
                    'bank_balances_filter': {
                        'accounts': ['inj1jcltmuhplrdcwp7stlr4hlhlhgd4htqhe4c0cs']
                    },
                    'omit_empty_response': true,
                },
            },
        }))
    });
    
    ws.on('message', (message) => {
        console.log(`Received from server: ${message}`);
    });

    setInterval(() => {
        n++
        if (n == 3) {
            console.log('try unsubscribe balance request of inj1dzqd00lfd4y4qy2pxa0dsdwzfnmsu27hgttswz')
            ws.send(JSON.stringify({
                'id': 3,
                'method': 'unsubscribe',
                'params': {
                    'q': {'bank_balances_filter': 
                        {
                            'accounts': ['inj1dzqd00lfd4y4qy2pxa0dsdwzfnmsu27hgttswz']
                        },
                        'omit_empty_response': true,
                    },
                },
            }))
        }
    }, 1000);
    
    ws.on('close', () => {
        console.log('Disconnected from server');
    });
    
    ws.on('error', (error) => {
        console.error(`WebSocket error: ${error}`);
    });
})()

Then try sending bank balance from default user2 (i.e this inj1jcltmuhplrdcwp7stlr4hlhlhgd4htqhe4c0cs)

yes 12345678 | injectived tx bank send user2 inj1dzqd00lfd4y4qy2pxa0dsdwzfnmsu27hgttswz 1inj --chain-id=injective-888 -y --fees=100000000000000inj

Some pending TODOs:

  1. Add more ratelimit config for websocket server: Max subscriptions per clients, request/response size, blacklist (if any), disconnect on slow, idle connection to be ready for production use

  2. Filters: We haven't fully integrated with CCXT so the request might miss some filters we don't know, just add it chainstream and it'll work for both chainstream and websocket

  3. More tests

@vinhphuctadang vinhphuctadang changed the title feat: integrate web socket stream feat(stream): integrate web socket stream Mar 10, 2025
@vinhphuctadang vinhphuctadang changed the title feat(stream): integrate web socket stream feat(stream): integrate websocket stream Mar 10, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant