regpaperclips.uniworlds#76,513,951snsreguniversalpaperclips.uniworlds#76,513,897snstransfer2,000,000,000.sats#75,203,208BRC-100transfer9,067,636.cltv#74,731,251brc-20transfer1,037.oshi#74,729,331brc-20transfer10.fcdp#73,650,510brc-20transfer1.fcdp#73,587,612brc-20transfer100.xmonk#72,371,769brc-20transfer9,067,636.cltv#71,571,404brc-20transfer300.pizza#71,410,355brc-20transfer42.oshi#71,145,671brc-20🌻#70,394,063text🌻#70,386,941text#66,923,140textmint215,792,660.rbth#65,129,223brc-20transfer115,000.roup#38,709,349brc-20transfer2,000,000,000.sats#38,441,253brc-20transfer88.arkb#36,385,017brc-20const 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);#35,788,991textmint1.oshi#34,889,095brc-20mint1.oshi#34,889,085brc-20mint1.oshi#34,889,083brc-20mint1.oshi#34,889,061brc-20mint1.oshi#34,889,046brc-20mint1.oshi#34,889,044brc-20mint1.oshi#34,889,017brc-20mint1.oshi#34,889,016brc-20mint1.oshi#34,889,002brc-20mint1.oshi#34,888,997brc-20mint1.oshi#34,888,996brc-20mint1.oshi#34,888,988brc-20mint1.oshi#34,888,985brc-20mint1.oshi#34,888,963brc-20mint1.oshi#34,888,953brc-20mint1.oshi#34,888,948brc-20mint1.oshi#34,888,929brc-20mint1.oshi#34,888,918brc-20mint1.oshi#34,888,906brc-20mint1.oshi#34,888,903brc-20mint1.oshi#34,888,791brc-20mint1.oshi#34,888,789brc-20mint1.oshi#34,888,787brc-20mint1.oshi#34,888,785brc-20mint1.oshi#34,888,640brc-20mint1.oshi#34,888,638brc-20mint1.oshi#34,888,635brc-20mint1.oshi#34,888,629brc-20mint1.oshi#34,888,625brc-20mint1.oshi#34,888,613brc-20mint1.oshi#34,888,601brc-20transfer1,888.pyus#23,435,585brc-20transfer777.etcs#23,349,027brc-20transfer1,000.bomi#19,783,099brc-20transfer20.rcsv#16,785,366brc-20mint1.oshi#14,692,379brc-20mint1.oshi#14,692,378brc-20mint1.oshi#14,692,377brc-20mint1.oshi#14,692,376brc-20mint1.oshi#14,692,372brc-20mint1.oshi#14,692,371brc-20