I have a contract account which has some tables. I want to watch for onchain table changes and sync them to an offline database as soon as possible. What is the most reliable way to do this? I have tried dfuse.io, but sometimes it's not working. Is there a way to do this myself?
1 Answer
You could use the demux-js library to listen to contract actions that affect the table. Demux allows you to integrate with your DB of choice. You establish an API endpoint and demux will ping it based on a set frequency (say 2 times per block or 250ms). For the best reliability you would want to run your own node, but the next best thing would probably be to use Scatter's API which load balances across the different bps. You can find their endpoint / other endpoints here and here.
It uses effects/handlers to specify if I see contract:action
, do (this) and you can pull data from the transaction to use as well.
I've integrated this into my chess-eos game if you would like a code example.
demux-js: https://github.com/EOSIO/demux-js
code example: https://github.com/NatPDeveloper/eos-chess/tree/master/js/lib/demux-js
block one code example: https://github.com/EOSIO/demux-js/tree/develop/examples/eos-transfers
block one simple blog example: https://github.com/EOSIO/eosio-project-demux-example
app.js: https://github.com/NatPDeveloper/eos-chess/blob/master/app.js#L35
// DEMUX ACTION READER SETUP
const { NodeosActionReader } = require("demux-eos")
const MyActionHandler = require("./js/lib/demux-js/ActionHandler")
const { BaseActionWatcher } = require("demux")
const updaters = require("./js/lib/demux-js/updaters")
const effects = require("./js/lib/demux-js/effects")
// LOCAL
// const actionReader = new NodeosActionReader(
// "http://127.0.0.1:8888", // Locally hosted node needed for reasonable indexing speed
// 179000, // First actions relevant to this dapp happen at this block
// )
// JUNGLE TESTNET
const actionReader = new NodeosActionReader(
"https://jungle.eosn.io:443", // Locally hosted node needed for reasonable indexing speed
1196555, // First actions relevant to this dapp happens at this block
)
const actionHandler = new MyActionHandler(
updaters,
effects,
)
const actionWatcher = new BaseActionWatcher(
actionReader,
actionHandler,
250, // Poll at twice the block interval for less latency
)
actionWatcher.watch() // Start watch loop
-
Thank you for the detailed explanation. Does demuxjs gives the exact ram table snapshot for the transaction? For example, if my contract action has multiple updates to a table, after transaction, the table snapshot changed from A to A'. Do I get to notified of the delta? Commented Feb 4, 2019 at 9:53
-
Hm. Not sure on that one. Demux is pulling the transaction that you specify. Ram tables cannot be changed without a transaction, so I would just listen to the transaction then update my DB as the contract would update the RAM tablet.– NatCommented Feb 4, 2019 at 20:47