This article is a practical guide on making a simple Node.js server that will receive BTC transactions as a Webhook and detect if a transaction contains more than $2Bln worth of BTC transfer. It doesn’t necessarily mean that someone cashes out or buys that match of BTC once; we don’t know, BUT if that kind of amount gets transferred a lot during the week, then we can assume that the overall network is quite active. It would be possible to make some investment design based on that information. Of course, this is not a financial or investment guide, and it is pure curiosity as a software engineer 🧐
First of all, we need some source for our data, which will give us the latest block and transactions confirmed by the blockchain network. There are not many services that we can use to monitor confirmed blocks for free, so Blockpulsar.com seems the best choice here because they even have Webhook events, which is ideal for us.
After registering with Blockpulsar, now we can set a Webhook event on every new confirmed transaction in the Bitcoin network. They will send us a Transaction object every time there is a new confirmed transaction, from where we can get a value of how much BTC it contains.
Based on types documented in Blockpulsar’s docs we will get the following JSON Object for each Transaction Webhook callback. We need a transaction id, transaction inputs, outputs, and their addresses with BTC amount.
{
"txid": "fff2525b8931402dd09222c50775608f75787bd2b87e56995a7bdd30f79702c4",
...
...
"vin": [
{
...
"value": 3.54312,
"addresses": [
"1JqBybe5nWtENrHnMyafbSXXtTh5Uv5Qab"
],
...
}
],
"vout": [
{
"value": 5.56,
...
...
"script_pub_key": {
...
...
"addresses": [
"1JqDybm2nWTENrHvMyafbSXXtTk5Uv5QAn"
]
}
}
],
...
...
}
This object structure seems pretty straightforward. We have to make some Node.js, Golang, or any other language-based HTTP Server, which will handle a Transaction JSON Request and parse it accordingly.
I’m choosing the Node.js server because that’s the most widespread technology for this kind of light server development.
To get started, we need a simple Express.js server to receive POST requests from Blockpulsar’s Webhook events. Because our server’s URL must be public, we have to make some “security“ measures to ensure that incoming requests are sent only from Blockpulsar servers. It sounds tricky, but in practice, almost all Webhook-based callbacks use the same technique. We either have to provide a unique Query parameter to check or check request headers.
It looks like in practice with a basic Express.js setup and Body Parser for having JSON POST body available as an object.
const express = require('express');
const bodyParser = require('body-parser');
const FIXED_QUERY_TOKEN = "some-long-token-for-security";
const app = express();
app.use(bodyParser.json());
app.post('/transaction', (req, res) => {
if (req.query.token !== FIXED_QUERY_TOKEN) {
return res.send(401);
}
const transaction = req.body;
console.log(transaction);
res.json({});
});
app.listen(process.env.PORT ?? 3000);
Now we have a simple Express.js server to handle a transaction object as an HTTP POST request and make sure that the upcoming request contains our unique ?token=<our-token>
query parameter because our API is going to be a public URL.
There are many ways to deploy this as a public URL-based API server for free because we do not match here. I’ve chosen to deploy this to Heroku, which is quite good as a free option, and it is pretty simple to do—not going to explain how Heroku deployment works. You can find pretty much anything on that topic. I’ll assume that you know how to do it 😀
After a simple deployment process to Heroku, I got a public URL for my Express.js server, and I can have my transaction tracking endpoint available as the following URL
https://bitcoin-transaction-tracking.herokuapp.com/transaction?token=some-long-token-for-security
Now is the time to set this URL as a Blockpulsar Webhook callback as a Bitcoin transaction event callback URL. To do that, we have to call a simple API, which you can do over Postman or just a light HTTP client directly embedded to your VSCode or Webstorm, whichever you want, but the request looks like this.
POST https://api.blockpulsar.com/hooks/webhook
x-api-key: <your api key>
x-api-secret: <your api secret>
Content-Type: application/json
{
"url": "https://bitcoin-transaction-tracking.herokuapp.com/transaction?token=some-long-token-for-security",
"subscriptions": [
{
"type": "TRANSACTION",
"currency": "BTC"
}
]
}
With this API call to Blockpulsar, we tell that “Send an HTTP POST request to our given URL, whenever there is a new transaction confirmed in Bitcoin Blockchain. “
It might take a few minutes to start receiving new transactions because the average block mining time is around 8 minutes, which sometimes takes even 30 minutes, but after some time, you will begin seeing a blast of JSON objects in your server logs from console.log(transaction)
. All you have to do now is parse the coming transaction and find if more than 5000 BTC is being transferred or not.
Each Bitcoin blockchain transaction contains vin, vout
fields that represent sending and receiving amounts to specific addresses. We don’t know for sure which specific address sends to whom, but if there is only one vin
and one vout
then it is clear which address sends and which one is receiving.
To check an actual amount, we have to go over all transaction.vin
and transaction.vout
arrays and check if we have a transfer of more than 5000 BTC at once.
function checkTransferAmount(transaction, amount = 5000) {
const findModeThanAmount = (vinOrVout) => vinOrVout.find(
({ value }) => value >= amount
);
return !!findModeThanAmount(transaction.vin) || !!findModeThanAmount(transaction.vout);
}
This conditional aggregation is a straightforward example of finding if there is a spend or receiving amount more than the given amount (default 5000 BTC).
We have to call this function every time we get a transaction to log only transaction ids that contain more than 5000 BTC input or output.
const express = require('express');
const bodyParser = require('body-parser');
const FIXED_QUERY_TOKEN = "some-long-token-for-security";
const app = express();
app.use(bodyParser.json());
app.post('/transaction', (req, res) => {
if (req.query.token !== FIXED_QUERY_TOKEN) {
return res.send(401);
}
const transaction = req.body;
if (checkTransferAmount(transaction)) {
console.log('MORE THAN 5000 BTC -> ', transaction.id);
}
res.json({});
});
app.listen(process.env.PORT ?? 3000);
function checkTransferAmount(transaction, amount = 5000) {
const findModeThanAmount = (vinOrVout) => vinOrVout.find(
({ value }) => value >= amount
);
return !!findModeThanAmount(transaction.vin) || !!findModeThanAmount(transaction.vout);
}
Now we will get an output to our Server logs similar to this one
MORE THAN 5000 BTC -> fff2525b8931402dd09222c50775608f75787bd2b87e56995a7bdd30f79702c4
You now have a tool that can trigger some chatbot or even automation API for your trading bot on a specific hook of finding if the newly confirmed transaction matches your condition. One of the best use-cases is making a Twitter bot similar to Wealth Alert, where you can tweet BTC Addresses that are making transactions with more than configured amounts.
Let me know what kind of use case you have. I would be happy to assist 🤞
Disclaimer: I’m a CTO at Blockpulsar Inc. and with this article wanted to showcase use-cases for our event-driven blockchain API.