Skip to content

Instantly share code, notes, and snippets.

@H7-25
Last active March 28, 2023 21:17
Show Gist options
  • Save H7-25/44d7f539d9274285a13b93db9b51f74f to your computer and use it in GitHub Desktop.
Save H7-25/44d7f539d9274285a13b93db9b51f74f to your computer and use it in GitHub Desktop.
const http = require('http');
const { exec } = require('child_process');
const mysql = require('mysql');
const jsonRpc = require('jayson');
const fetch = require('node-fetch');
// Read configuration from file
const config = require('./example.conf');
// Create MySQL connection pool
const pool = mysql.createPool({
connectionLimit: config.mysql.connectionLimit,
host: config.mysql.host,
user: config.mysql.user,
password: config.mysql.password,
database: config.mysql.database
});
// Create JSON-RPC client
let base64 = require('base-64');
let url = 'http://192.168.178.50:22555';
let username = 'dogetips';
let password = 'XXXXXXXXXXX';
const rpcClient = jsonRpc.Client.http({ host: 'localhost', port: 22555, version: 1, headers: {'jsonrpc': '1.0', 'Authorization': 'Basic ' + Buffer.from(username + ":" + password).toString('base64')} });
let cache = {}; // Initialize cache object
const CACHE_DURATION = 5 * 60 * 1000; // Cache duration in milliseconds
// Define function to insert transaction data into MySQL database
function insertTransaction(txid, address, amount, doge_USD, time, sender) {
const query = `INSERT INTO transactions (txid, sender, recipient, amount, doge_usd, time)
VALUES ('${txid}', '${sender}', '${address}', ${amount}, ${doge_USD}, '${time}')`;
pool.query(query, (error, results) => {
if (error) {
console.error(error);
}
});
}
let doge_USD;
// Define function to handle incoming blocks
async function handleBlock(blockHash) {
rpcClient.request('getblock', [blockHash, true], async (err, blockData) => {
if (err) {
console.log(blockHash);
console.error(`Error getting block information: ${err.message}`);
return;
}
const blockTime = blockData.result.time;
const now = new Date().getTime();
if (cache.lastUpdated && now - cache.lastUpdated < CACHE_DURATION) {
// Use cached value if it's still fresh
doge_USD = cache.value;
//return cache.value;
} else {
try {
const response = await fetch('https://api.coingecko.com/api/v3/simple/price?ids=DOGECOIN&vs_currencies=USD');
const coingecko = await response.json();
doge_USD = coingecko.dogecoin.usd;
cache = {
value: doge_USD,
lastUpdated: now,
};
//
//return doge_USD;
} catch (error) {
console.error(error);
throw new Error('Error fetching Dogecoin price');
}
}
// const response = await fetch('https://api.coingecko.com/api/v3/simple/price?ids=DOGECOIN&vs_currencies=USD');
// const coingecko = await response.json();
// const doge_USD = coingecko.dogecoin.usd;
// Loop through the block's transactions
blockData.result.tx.forEach( async (txid) => {
rpcClient.request('getrawtransaction', [txid, true], async (err, txData) => {
if (err) {
console.error(`Error getting transaction information: ${err.message}`);
return;
}
// Parse the transaction information
const txTime = txData.result.time;
const txAmount = txData.result.vout.reduce((acc, output) => {
return acc + output.value;
}, 0);
if(!txData.result.vin[0].txid) {
return;
}
const vinvout = txData.result.vin[0].vout;
// Retrieve RECIPIENT address from input transaction
const vintxid = txData.result.vin[0].txid;
//console.log('VIN LEN: ', txData.result.vin.length);
const data = new Promise((resolve, reject) => {
rpcClient.request('getrawtransaction', [vintxid, true], (err, result) => {
if (err) {
reject(err);
} else {
resolve(result);
}
});
});
data.then((response) => {
//console.log(response);
const txSender = response.result.vout[vinvout].scriptPubKey.addresses[0];
// Check if the transaction amount is over 10 million Dogecoins
//console.log(txAmount);
if (txAmount > 1000000) {
console.log('SENDERS: ', response.result.vout.length);
const filteredVout = txData.result.vout.filter(item => item.scriptPubKey.type === 'pubkeyhash');
console.log('RECIPIENTS: ', filteredVout.length);
// Loop through the transaction's outputs
txData.result.vout.forEach((output) => {
// Check if the output is a payment to a single address
if (output.scriptPubKey.type === 'pubkeyhash') {
// Insert transaction data into MySQL database
const txid = txData.result.txid;
const address = output.scriptPubKey.addresses[0];
const amount = output.value;
//const amount_usd = amount * doge_USD;
const time = txTime;
const date = new Date(txTime * 1000);
let datetime = date.toISOString().split('.')[0].replace('T', ' ');
console.log(datetime);
console.log('DOGE/USD: ', doge_USD);
console.log('TRANSACTION: ', txid, txSender, address, amount, doge_USD, datetime)
// Check is not an unspent and is over 10 million Dogecoins
if (amount > 1000000) {
if (address !== txSender ) {
console.log('INSERT', amount, address, txSender);
insertTransaction(txid, address, amount, doge_USD, datetime, txSender);
}
}
}
});
}
}).catch((err) => {
console.error(`Error getting transaction information: ${err.message}`);
});
});
});
});
}
// Start listening for incoming block notifications using HTTP server
http.createServer(async (req, res) => {
if (req.method === 'GET') {
try {
// Retrieve block information
const blockHash = req.url.split('=');
const block = blockHash[1];
handleBlock(block);
res.end('OK');
} catch (err) {
console.error(err);
res.statusCode = 500;
res.end();
}
} else {
res.statusCode = 404;
res.end();
}
}).listen(8000, () => {
console.log('Listening for incoming block notifications on port 8000...');
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment