Publish/Subscribe API (Klayr Service)
The Publish/Subscribe API is sometimes also called an Event-Driven API. The main difference between Event-Driven and regular REST API is not only technical. In practice, a two-way streaming connection is used, which means that not only can the client request the server for a data update, (and also potential updates) but also the server can notify the client about new data instantly as it arrives.
Klayr Service leverages the two-way communication approach by utilizing the WebSocket library responsible for updating users regarding changes in the blockchain network and markets.
Access paths and compatibility
The blockchain update API can be accessed by the following path wss://service.klayr.xyz/blockchain
.
If you are interested in accessing the testnet network, this can be accomplished by using the wss://testnet-service.klayr.xyz/blockchain
endpoint.
Important: The Klayr Service WebSocket API uses the socket.io
library.
This implementation is compatible with the version 2.0 of the socket.io library.
Using the wrong major version might result in a broken connection and messages not being passed.
The specification below contains numerous examples of how to use the API in practice.
Endpoint logic
The logic of the endpoints is derived as follows: the method naming is always based on the following pattern: <action>.<entity>
, where
-
the
action
is equivalent to the method type performed on the server (i.e.,update
), -
and
entity
is a part of the application logic, ex.accounts
,transactions
.
Payloads
All the event payloads are returned in the JSON format - application/json
and adhere to the following structure:
{
"data": {}, // Contains the update information
"meta": {
"count": <integer>, // number of items
"timestamp": <timestamp>, // timestamp in seconds
... // other metadata
},
}
Example of a client implementation
const io = require('socket.io-client');
const connection = io.connect('https://service.klayr.xyz/blockchain', { transports: ['websocket'] });
connection.on('update.block', (block) => { (...) });
Available subscriptions
new.block
Updates about a newly forged block with all its data.
{
"data": [
{
"id": "01967dba384998026fe028119bd099ecf073c05c045381500a93d1a7c7307e5b",
"version": 0,
"height": 8344448,
"timestamp": 85944650,
"previousBlockId": "827080df7829cd2757501a85f80a0767fcb40615304b701c2890dbbaf214bb89",
"generator": {
"address": "klydwsyfmcko6mcd357446yatromr9vzgu7eb8y99",
"name": "genesis_3",
"publicKey": "32ddb97e8d7e607a14fef8449c2a2180cd74a51f67b04a50a4b1917d3ca8a52e"
},
"transactionRoot": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"assetsRoot": "6e904b2f678eb3b6c3042acb188a607d903d441d61508d047fe36b3c982995c8",
"stateRoot": "95d9b1773b78034b8df9ac741c903b881da761d8ba002a939de28a4b86982c04",
"maxHeightGenerated": 559421,
"maxHeightPrevoted": 559434,
"validatorsHash": "ad0076aa444f6cda608bb163c3bd77d9bf172f1d2803d53095bc0f277db6bcb3",
"aggregateCommit": {
"height": 166,
"aggregationBits": "ffffffffffffffffffffffff1f",
"certificateSignature": "a7db952f87db29718c40afca9a9fb2f6b605f8588c1c99e41e92f26ec005e6d14327c33051fa383fe903b7040d16c7441570167a73d9468aa16a6720c765b3f22aeca42102c45b4616fd7543d7a0649e0fa934e0de1973486eede9d56f014f9f"
},
"numberOfTransactions": 10,
"numberOfAssets": 10,
"numberOfEvents": 10,
"totalBurnt": "0",
"networkFee": "15000000",
"totalForged": "65000000",
"reward": "50000000",
"signature": "a3733254aad600fa787d6223002278c3400be5e8ed4763ae27f9a15b80e20c22ac9259dc926f4f4cabdf0e4f8cec49308fa8296d71c288f56b9d1e11dfe81e07",
"isFinal": true
}
],
"meta": {
"count": 1,
"offset": 0,
"total": 1
}
}
delete.block
Updates about a deleted block. This usually happens when the chain switches forks.
{
"data": [
{
"id": "01967dba384998026fe028119bd099ecf073c05c045381500a93d1a7c7307e5b",
"version": 0,
"height": 8344448,
"timestamp": 85944650,
"previousBlockId": "827080df7829cd2757501a85f80a0767fcb40615304b701c2890dbbaf214bb89",
"generator": {
"address": "klydwsyfmcko6mcd357446yatromr9vzgu7eb8y99",
"name": "genesis_3",
"publicKey": "32ddb97e8d7e607a14fef8449c2a2180cd74a51f67b04a50a4b1917d3ca8a52e"
},
"transactionRoot": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"assetsRoot": "6e904b2f678eb3b6c3042acb188a607d903d441d61508d047fe36b3c982995c8",
"stateRoot": "95d9b1773b78034b8df9ac741c903b881da761d8ba002a939de28a4b86982c04",
"maxHeightGenerated": 559421,
"maxHeightPrevoted": 559434,
"validatorsHash": "ad0076aa444f6cda608bb163c3bd77d9bf172f1d2803d53095bc0f277db6bcb3",
"aggregateCommit": {
"height": 166,
"aggregationBits": "ffffffffffffffffffffffff1f",
"certificateSignature": "a7db952f87db29718c40afca9a9fb2f6b605f8588c1c99e41e92f26ec005e6d14327c33051fa383fe903b7040d16c7441570167a73d9468aa16a6720c765b3f22aeca42102c45b4616fd7543d7a0649e0fa934e0de1973486eede9d56f014f9f"
},
"numberOfTransactions": 10,
"numberOfAssets": 10,
"numberOfEvents": 10,
"totalBurnt": "0",
"networkFee": "15000000",
"totalForged": "65000000",
"reward": "50000000",
"signature": "a3733254aad600fa787d6223002278c3400be5e8ed4763ae27f9a15b80e20c22ac9259dc926f4f4cabdf0e4f8cec49308fa8296d71c288f56b9d1e11dfe81e07",
"isFinal": true
}
],
"meta": {
"count": 1,
"offset": 0,
"total": 1
}
}
new.transactions
Updates about included transactions within a newly generated block.
{
"data": [
{
"id": "65c28137c130c6609a67fccfcd9d0f7c3df3577324f8d33134326d653ded613f",
"moduleCommand": "token:transfer",
"nonce": "1",
"fee": "5166000",
"minFee": "165000",
"size": 166,
"sender": {
"address": "klyyvvam5rxyvbvofxbdfcupxetzmqxu22phm4yuo",
"publicKey": "475697e34ae02b394721020d38677a072dbd5c03d61c1c8fdd6563eb66160fa3",
"name": "genesis_0"
},
"params": {
"tokenID": "0400000100000000",
"amount": "10000000000",
"recipientAddress": "klyezo8pcrbsoceuuu64rpc8w2qkont2ec3n772yu",
"data": ""
},
"block": {
"id": "ebb1ba587a1e8385a2aac1317edcb872c05b2b07df6560fabd0f0d23d7d6a0df",
"height": 122721,
"timestamp": 1678989430,
"isFinal": true
},
"meta": {
"recipient": {
"address": "klyezo8pcrbsoceuuu64rpc8w2qkont2ec3n772yu",
"publicKey": null,
"name": null
}
},
"executionStatus": "success",
"index": 0
},
],
"meta": {
"count": 1,
"offset": 0,
"total": 1
}
}
delete.transactions
Updates about deleted transactions within a deleted block. This usually happens when the chain switches forks.
{
"data": [
{
"id": "65c28137c130c6609a67fccfcd9d0f7c3df3577324f8d33134326d653ded613f",
"moduleCommand": "token:transfer",
"nonce": "1",
"fee": "5166000",
"minFee": "165000",
"size": 166,
"sender": {
"address": "klyyvvam5rxyvbvofxbdfcupxetzmqxu22phm4yuo",
"publicKey": "475697e34ae02b394721020d38677a072dbd5c03d61c1c8fdd6563eb66160fa3",
"name": "genesis_0"
},
"params": {
"tokenID": "0400000100000000",
"amount": "10000000000",
"recipientAddress": "klyezo8pcrbsoceuuu64rpc8w2qkont2ec3n772yu",
"data": ""
},
"block": {
"id": "ebb1ba587a1e8385a2aac1317edcb872c05b2b07df6560fabd0f0d23d7d6a0df",
"height": 122721,
"timestamp": 1678989430,
"isFinal": true
},
"meta": {
"recipient": {
"address": "klyezo8pcrbsoceuuu64rpc8w2qkont2ec3n772yu",
"publicKey": null,
"name": null
}
},
"executionStatus": "success",
"index": 0
},
],
"meta": {
"count": 1,
"offset": 0,
"total": 1
}
}
update.round
Updates about the active generators for the next round.
{
"data": [
{
"address": "klyjta9erat6qqpa32hqbssttc6p5da3k7tydvhmv",
"name": "panzer",
"publicKey": "2ca9a7...c23079",
"nextAllocatedTime": 1659863166,
"status": "active"
},
...
],
"meta": {
"count": 10,
"offset": 0,
"total": 103,
},
}
update.generators
Updates the current generators list, so the current generator is in the first position.
{
"data": [
{
"address": "klyjta9erat6qqpa32hqbssttc6p5da3k7tydvhmv",
"name": "panzer",
"publicKey": "2ca9a7...c23079",
"nextAllocatedTime": 1659863166
},
...
],
"meta": {
"count": 10,
"offset": 0,
"total": 103,
},
}
update.fee_estimates
Updates about recent fee estimates.
{
"data": {
"feeEstimatePerByte": {
"low": 0,
"medium": 0,
"high": 0
},
"minFeePerByte": 1000,
"feeTokenID": "0000000000000000",
},
"meta": {
"lastUpdate": 1659974881,
"lastBlockHeight": 19264798,
"lastBlockID": "fbcb48456086d11dc797321a672cd964cebee85296ec8c7bd6ed036f88f27fb1"
}
}
update.metadata
Updates about recent metadata changes.
{
"mainnet": ["Klayr", "Colecti"],
"testnet": ["Klayr", "Enevti"],
"betanet": ["Klayr"],
}
update.index.status
Updates about index status changes.
{
"data": {
"genesisHeight": 0,
"lastBlockHeight": 18779,
"lastIndexedBlockHeight": 13955,
"chainLength": 18780,
"numBlocksIndexed": 13956,
"percentageIndexed": 74.31,
"isIndexingInProgress": true
},
"meta": {
"lastUpdate": 1700848735
}
}