var img = document.createElement('img'); img.src = "https://terradocs.matomo.cloud//piwik.php?idsite=1&rec=1&url=https://docs.terra.money" + location.pathname; img.style = "border:0"; img.alt = "tracker"; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(img,s);
Skip to main content

Websockets

WebSocketClient

Feather.js comes with WebSocketClient, which abstracts a subscription to Tendermint RPC's WebSocket endpoint. This requires access to a Terra node's RPC server, which may require privileged access as it exposes functions that can kill a node's operation.


_26
import {WebSocketClient } from '@terra-money/feather.js';
_26
_26
const wsclient = new WebSocketClient('ws://your-server-ip:26657/websocket');
_26
_26
_26
let count = 0;
_26
wsclient.subscribe('NewBlock', {}, (_) => {
_26
console.log(count);
_26
count += 1;
_26
_26
if (count === 3) {
_26
wsclient.destroy();
_26
}
_26
});
_26
_26
// send tracker
_26
wsclient.subscribe(
_26
'Tx',
_26
{ 'message.action': '/cosmos.bank.v1beta1.MsgSend' },
_26
(data) => {
_26
console.log('Send occured!');
_26
console.log(data.value);
_26
},
_26
);
_26
_26
wsclient.start();

LocalTerra example

If you are using LocalTerra, the WebSocket endpoint can be accessed at ws://localhost:26657/websocket.


_27
import { LocalTerra, WebSocketClient } from '@terra-money/feather.js';
_27
_27
const wsclient = new WebSocketClient('ws://localhost:26657/websocket');
_27
_27
const terra = new LocalTerra();
_27
_27
let count = 0;
_27
wsclient.subscribe('NewBlock', {}, (_) => {
_27
console.log(count);
_27
count += 1;
_27
_27
if (count === 3) {
_27
wsclient.destroy();
_27
}
_27
});
_27
_27
// send tracker
_27
wsclient.subscribe(
_27
'Tx',
_27
{ 'message.action': '/cosmos.bank.v1beta1.MsgSend' },
_27
(data) => {
_27
console.log('Send occured!');
_27
console.log(data.value);
_27
},
_27
);
_27
_27
wsclient.start();

Supported Events

You can subscribe to the following recognized Tendermint events:

  • CompleteProposal
  • Evidence
  • Lock
  • NewBlock
  • NewBlockHeader
  • NewRound
  • NewRoundStep
  • Polka
  • Relock
  • TimeoutPropose
  • TimeoutWait
  • Tx
  • Unlock
  • ValidatorSetUpdates
  • ValidBlock
  • Vote

Query

Use the following syntax to specify the Tendermint query:


_12
type TendermintQueryOperand = string | number | Date;
_12
_12
interface TendermintQuery {
_12
[k: string]:
_12
| TendermintQueryOperand
_12
| ['>', number | Date]
_12
| ['<', number | Date]
_12
| ['<=', number | Date]
_12
| ['>=', number | Date]
_12
| ['CONTAINS', string]
_12
| ['EXISTS'];
_12
}

The following shows an example of how to construct a TendermintQuery and use it for a subscription:


_10
const tmQuery = {
_10
'message.action': '/cosmos.bank.v1beta1.MsgSend',
_10
'tx.timestamp': ['>=', new Date()],
_10
'store_code.abc': ['EXISTS'],
_10
'abc.xyz': ['CONTAINS', 'terra1...'],
_10
};
_10
_10
wsclient.subscribe('Tx', tmQuery, (data) => {
_10
// do something with data ...
_10
});

The resultant query will be:

tm.event='Tx' AND message.action='/cosmos.bank.v1beta1.MsgSend' tx.timestamp >= 2020-12-12 AND store_code.abc EXISTS AND abc.xyz CONTAINS 'terra1...'

subscribeTx

It is a common use case to subscribe to transactions with a Tendermint query, such as listening for when specific addresses send or receive funds, or when specific events are triggered from within smart contracts. However, it is hard to extract data because the transaction result is encoded in Base64 Amino encoding. If you use subscribeTx, feather.js will automatically inject the txhash into the resultant data value so you can more easily look up the transaction to decode it using LCDClient.


_8
// swap tracker
_8
wsclient.subscribeTx({ 'message.action': 'swap' }, async (data) => {
_8
console.log('Swap occured!');
_8
const txInfo = await terra.tx.txInfo(data.value.TxResult.txhash);
_8
if (txInfo.logs) {
_8
console.log(txInfo.logs[0].eventsByType);
_8
}
_8
});