UNPKG

@stacks/blockchain-api-client

Version:
158 lines 6.19 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.StacksApiSocketClient = void 0; const socket_io_client_1 = require("socket.io-client"); const common_1 = require("../common"); function getWsUrl(url) { let urlObj; try { urlObj = new URL(url); if (!urlObj.protocol || !urlObj.host) { throw new TypeError(`[ERR_INVALID_URL]: Invalid URL: ${url}`); } } catch (error) { console.error(`Pass an absolute URL with a protocol/schema, e.g. "wss://example.com"`); throw error; } return urlObj; } function createStacksApiSocket(opts) { const socketOpts = { ...opts?.socketOpts, query: { ...opts?.socketOpts?.query, // Subscriptions can be specified on init using this handshake query param. subscriptions: Array.from(new Set(opts?.subscriptions)).join(','), }, }; if (!socketOpts.transports) { socketOpts.transports = ['websocket']; } const socket = (0, socket_io_client_1.io)(getWsUrl(opts?.url ?? common_1.BASE_PATH).href, socketOpts); return socket; } class StacksApiSocketClient { constructor(args) { if (args instanceof socket_io_client_1.Socket) { this.socket = args; } else { this.socket = createStacksApiSocket(args); } } static connect(opts) { return new StacksApiSocketClient(opts); } handleSubscription(topic, subscribe = false, listener) { const subsQuery = this.socket.io.opts.query?.subscriptions; const subscriptions = new Set(subsQuery ? subsQuery.split(',') : []); if (subscribe) { this.socket.emit('subscribe', topic, error => { if (error) console.error(`Error subscribing: ${error}`); }); subscriptions.add(topic); } else { this.socket.emit('unsubscribe', topic); subscriptions.delete(topic); } // Update the subscriptions in the socket handshake so topics are persisted on re-connect. if (this.socket.io.opts.query === undefined) { this.socket.io.opts.query = {}; } this.socket.io.opts.query.subscriptions = Array.from(subscriptions).join(','); return { unsubscribe: () => { if (listener) { this.socket.off(topic, listener); } this.handleSubscription(topic, false); }, }; } subscribeBlocks(listener) { if (listener) this.socket.on('block', listener); return this.handleSubscription('block', true, listener); } unsubscribeBlocks() { this.handleSubscription('block', false); } subscribeMicroblocks(listener) { if (listener) this.socket.on('microblock', listener); return this.handleSubscription('microblock', true, listener); } unsubscribeMicroblocks() { this.handleSubscription('microblock', false); } subscribeMempool(listener) { if (listener) this.socket.on('mempool', listener); return this.handleSubscription('mempool', true, listener); } unsubscribeMempool() { this.handleSubscription('mempool', false); } subscribeAddressTransactions(address, listener) { if (listener) this.socket.on(`address-transaction:${address}`, listener); return this.handleSubscription(`address-transaction:${address}`, true, listener); } unsubscribeAddressTransactions(address) { this.handleSubscription(`address-transaction:${address}`, false); } subscribeAddressStxBalance(address, listener) { if (listener) this.socket.on(`address-stx-balance:${address}`, listener); return this.handleSubscription(`address-stx-balance:${address}`, true, listener); } unsubscribeAddressStxBalance(address) { this.handleSubscription(`address-stx-balance:${address}`, false); } subscribeTransaction(txId, listener) { if (listener) this.socket.on(`transaction:${txId}`, listener); return this.handleSubscription(`transaction:${txId}`, true, listener); } unsubscribeTransaction(txId) { this.handleSubscription(`transaction:${txId}`, false); } subscribeNftEvent(listener) { if (listener) this.socket.on('nft-event', listener); return this.handleSubscription('nft-event', true, listener); } unsubscribeNftEvent() { this.handleSubscription('nft-event', false); } subscribeNftAssetEvent(assetIdentifier, value, listener) { if (listener) this.socket.on(`nft-asset-event:${assetIdentifier}+${value}`, listener); return this.handleSubscription(`nft-asset-event:${assetIdentifier}+${value}`, true, listener); } unsubscribeNftAssetEvent(assetIdentifier, value) { this.handleSubscription(`nft-asset-event:${assetIdentifier}+${value}`, false); } subscribeNftCollectionEvent(assetIdentifier, listener) { if (listener) this.socket.on(`nft-collection-event:${assetIdentifier}`, listener); return this.handleSubscription(`nft-collection-event:${assetIdentifier}`, true, listener); } unsubscribeNftCollectionEvent(assetIdentifier) { this.handleSubscription(`nft-collection-event:${assetIdentifier}`, false); } logEvents() { this.socket.on('connect', () => console.log('socket connected')); this.socket.on('disconnect', reason => console.warn('disconnected', reason)); this.socket.on('connect_error', error => console.error('connect_error', error)); this.socket.on('block', block => console.log('block', block)); this.socket.on('microblock', microblock => console.log('microblock', microblock)); this.socket.on('mempool', tx => console.log('mempool', tx)); this.socket.on('nft-event', event => console.log('nft-event', event)); } } exports.StacksApiSocketClient = StacksApiSocketClient; //# sourceMappingURL=index.js.map