How to wait for the incoming or outgoing transactions on BCH network to the particular address
So, you've implemented Bitcoin Cash in your site or app, now you need to react as soon as a user sends a transaction or gets an incoming transaction to his/her address. You could, of course listen to the entire BCH blockchain, like here: https://bitsocket.bch.sx/s, but that's pretty ineffective.
Here's how to listen to a single address:
Bitcoin Cash MainNet
MainNet is better, because it has a few BitSocket servers.
// These imports are not necessary in browser, only in npm
// const btoa = require('btoa');
// const EventSource = require('eventsource');
function waitForTxMainnet(cashAddress) {
return new Promise((resolve) => {
const addr = cashAddress.split(':')[1];
const query = {
"v": 3,
"q": {"find": {$or: [{"out.e.a": addr}, {"in.e.a": addr}]}},
"r": {
"f": ".[] | { id: .tx.h }"
}
};
const b64 = btoa(JSON.stringify(query));
const bitsocket = new EventSource('https://bitsocket.bch.sx/s/' + b64);
bitsocket.onmessage = function (e) {
// console.log(e);
const data = JSON.parse(e.data);
if(data.type === 'mempool') {
bitsocket.close();
resolve(data.data.id);
}
}
});
}
// Usage:
(async () => {
const txid = await waitForTxMainnet('bitcoincash:qrg8ppy89pq9znsgws5e85x8xy5d3njvvus7825tev');
console.log(txid);
})();
The q
parameter is the query in BitSocket.
r.f
is the "output script" (just the transaction's hex representation).
To use it call: await waitForTxMainnet(cashAddress)
in your async
function.
This returns the actual transaction id.
This uses https://bitsocket.bch.sx/s/
BitSocket, but similarly https://bitsocket.bitcoin.com/s/
is also available.
Details of the transaction:
Balance of the address:
https://rest.bitcoin.com/v2/address/details/bitcoincash:qrg8ppy89pq9znsgws5e85x8xy5d3njvvus7825tev
Bitcoin Cash TestNet
We haven't found any Socket servers watching Bitcoin Cash testnet, so the only way we've found is to watch UTXOs (unspent transaction outputs) for change:
const axios = require('axios').default;
async function waitForTxTestnet(cashAddress) {
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
const url = `https://trest.bitcoin.com/v2/address/details/${cashAddress}`;
const r = await axios.get(url);
const txOriginal = r.data.transactions;
while (true) {
const r2 = await axios.get(url);
const txNew = r2.data.transactions;
if (JSON.stringify(txNew) !== JSON.stringify(txOriginal)) {
const allNewTxes = txNew.filter(function (el) {
return txOriginal.indexOf(el) < 0;
});
return allNewTxes[0];
}
await sleep(3000);
}
}
// Usage:
(async () => {
const txid = await waitForTxTestnet('bchtest:qpfay8rvp96rrhefean4u97hn6tse5nu2s2wh95tkr');
console.log(txid);
})();
It will poll rest.bitcoin.com every 3 seconds to see if UTXOs changed. It's not immediate, but good enough for testing.
Just call await waitForTxTestnet(cashAddress)
in your async
function.
Details of the transaction:
Balance of the address:
https://trest.bitcoin.com/v2/address/details/bchtest:qrn808zezlasdgwp0ychx0npr2k0x446hudhkuzlep