const https = require('https'); const fs = require('fs'); const ProgressBar = require('progress'); const colors = require('colors'); console.log(` ██ ██████ ███████ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ███████ ███████ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██████ ███████ ██ ██ ██ ██ ██ ██ ███ ██ ██████ ███████ ██ ██ ███████ ██████ ██████ ██████ ██████ ██████ ██████ ██ ██ ██ ████ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ████ ██ ██ ██ ██ ██ ██ ██ ██ █████ ███ █████ ██████ ██████ ██████ ██ █████ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ████ ██ ██ ██ ██ ██ ████ ██████ ███████ ██ ██ ███████ ██ ██ ██████ ██ ██ ██████ ███████ ██████ ██ `.rainbow); const oshindexer = { blockstreamAPIEndpoint: 'https://blockstream.info/api', apiKey: null, esploraEndpoint: null, setApiKey: function(key) { this.apiKey = key; }, setEsploraEndpoint: function(endpoint) { this.esploraEndpoint = endpoint; }, getEndpoint: function() { return this.esploraEndpoint || this.blockstreamAPIEndpoint; }, isValidJSON: function(str) { try { JSON.parse(str); return true; } catch (e) { return false; } }, decodeAndExtractData: function(hexData) { const decodedData = Buffer.from(hexData, 'hex').toString('utf8'); const startIndex = decodedData.indexOf('{"p":"brc-20"'); const endIndex = decodedData.lastIndexOf('}') + 1; if (startIndex !== -1 && endIndex !== -1) { const extractedJSON = decodedData.substring(startIndex, endIndex); if (this.isValidJSON(extractedJSON)) { return JSON.parse(extractedJSON); } } return null; }, sleep: function(ms) { return new Promise(resolve => setTimeout(resolve, ms)); }, fetchBlockHash: async function(blockHeight) { return new Promise((resolve, reject) => { https.get(`${this.getEndpoint()}/block-height/${blockHeight}`, (res) => { let data = ''; res.on('data', (chunk) => { data += chunk; }); res.on('end', () => { resolve(data.trim()); }); }).on('error', (err) => { reject(err); }); }); }, fetchTxData: async function(txid) { return new Promise((resolve, reject) => { https.get(`${this.getEndpoint()}/tx/${txid}`, (res) => { let data = ''; res.on('data', (chunk) => { data += chunk; }); res.on('end', () => { if (this.isValidJSON(data)) { resolve(JSON.parse(data)); } else { reject(`Unexpected response for transaction ${txid}: ${data}`); } }); }).on('error', (err) => { reject(err); }); }); }, extractBRC20FromTx: async function(txData) { const brc20Data = []; if (txData && txData.vin) { for (let vin of txData.vin) { if (vin.witness && vin.witness.length > 0) { for (const witnessData of vin.witness) { const parsedData = this.decodeAndExtractData(witnessData); if (parsedData) { brc20Data.push(parsedData); } } } } } return brc20Data; }, fetchBlockTxs: async function(blockHash) { return new Promise((resolve, reject) => { https.get(`${this.getEndpoint()}/block/${blockHash}/txids`, (res) => { let data = ''; res.on('data', (chunk) => { data += chunk; }); res.on('end', () => { if (this.isValidJSON(data)) { resolve(JSON.parse(data)); } else { reject(`Unexpected response for block ${blockHash} transactions: ${data}`); } }); }).on('error', (err) => { reject(err); }); }); }, main: async function(startingBlockHeight = 785993) { let currentBlockHeight = startingBlockHeight; let allBRC20Data = []; while (true) { try { const blockHash = await this.fetchBlockHash(currentBlockHeight); if (!blockHash || blockHash.includes("Block not found")) { console.log("Waiting for a new block..."); await this.sleep(5 * 60 * 1000); // Wait for 5 minutes before checking again continue; } const txids = await this.fetchBlockTxs(blockHash); const progressBar = new ProgressBar(`Processing Block ${currentBlockHeight} [:bar] :current/:total :percent :etas`, { complete: '=', incomplete: ' ', width: 50, total: txids.length, }); for (const txid of txids) { const txData = await this.fetchTxData(txid); const brc20Data = await this.extractBRC20FromTx(txData); allBRC20Data = allBRC20Data.concat(brc20Data); progressBar.tick(); await this.sleep(12); } // Save all BRC20 data to a JSON file after processing each block fs.writeFileSync('indexer.json', JSON.stringify(allBRC20Data, null, 2)); console.log(`All BRC20 data up to block ${currentBlockHeight} saved to indexer.json`); // Increment block height to process the next block currentBlockHeight++; } catch (error) { console.error("Error:", error); await this.sleep(5 * 60 * 1000); // Wait for 5 minutes before trying again } } } }; // Exécution du SDK const startingBlockHeight = process.argv[2] ? parseInt(process.argv[2]) : 785993; oshindexer.main(startingBlockHeight);
Inscription number 35,788,991
Genesis block 813,961
File type text
File size 7.83 KB
Creation date Oct 26,2023 7:24 pm