UNPKG

@bsv/wallet-toolbox

Version:

BRC100 conforming wallet, wallet storage and wallet signer components

137 lines 5.87 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.WhatsOnChainServices = void 0; exports.wocGetHeadersHeaderToBlockHeader = wocGetHeadersHeaderToBlockHeader; const WhatsOnChain_1 = require("../../../providers/WhatsOnChain"); const ChaintracksFetch_1 = require("../util/ChaintracksFetch"); const HeightRange_1 = require("../util/HeightRange"); class WhatsOnChainServices { static createWhatsOnChainServicesOptions(chain) { const options = { chain, apiKey: '', timeout: 30000, userAgent: 'BabbageWhatsOnChainServices', enableCache: true, chainInfoMsecs: 5000 }; return options; } constructor(options) { this.options = options; const config = { apiKey: this.options.apiKey, timeout: this.options.timeout, userAgent: this.options.userAgent, enableCache: this.options.enableCache }; this.chain = options.chain; WhatsOnChainServices.chainInfoMsecs[this.chain] = options.chainInfoMsecs; this.woc = new WhatsOnChain_1.WhatsOnChain(this.chain, config); } async getHeaderByHash(hash) { const header = await this.woc.getBlockHeaderByHash(hash); return header; } async getChainInfo() { const now = new Date(); let update = WhatsOnChainServices.chainInfo[this.chain] === undefined; if (!update && WhatsOnChainServices.chainInfoTime[this.chain] !== undefined) { const elapsed = now.getTime() - WhatsOnChainServices.chainInfoTime[this.chain].getTime(); update = elapsed > WhatsOnChainServices.chainInfoMsecs[this.chain]; } if (update) { WhatsOnChainServices.chainInfo[this.chain] = await this.woc.getChainInfo(); WhatsOnChainServices.chainInfoTime[this.chain] = now; } if (!WhatsOnChainServices.chainInfo[this.chain]) throw new Error('Unexpected failure to update chainInfo.'); return WhatsOnChainServices.chainInfo[this.chain]; } async getChainTipHeight() { return (await this.getChainInfo()).blocks; } async getChainTipHash() { return (await this.getChainInfo()).bestblockhash; } /** * @param fetch * @returns returns the last 10 block headers including height, size, chainwork... */ async getHeaders(fetch) { fetch || (fetch = new ChaintracksFetch_1.ChaintracksFetch()); const headers = await fetch.fetchJson(`https://api.whatsonchain.com/v1/bsv/${this.chain}/block/headers`); return headers; } async getHeaderByteFileLinks(neededRange, fetch) { fetch || (fetch = new ChaintracksFetch_1.ChaintracksFetch()); const files = await fetch.fetchJson(`https://api.whatsonchain.com/v1/bsv/${this.chain}/block/headers/resources`); const r = []; let range = undefined; for (const link of files.files) { const parsed = parseFileLink(link); if (parsed === undefined) continue; // parse error, return empty result if (parsed.range === 'latest') { if (range === undefined) continue; // should not happen on valid input const fromHeight = range.maxHeight + 1; if (neededRange.maxHeight >= fromHeight) { // We need this range but don't know maxHeight const data = await fetch.download(link); range = new HeightRange_1.HeightRange(fromHeight, fromHeight + data.length / 80 - 1); if (!neededRange.intersect(range).isEmpty) r.push({ sourceUrl: parsed.sourceUrl, fileName: parsed.fileName, range, data }); } } else { range = new HeightRange_1.HeightRange(parsed.range.fromHeight, parsed.range.toHeight); if (!neededRange.intersect(range).isEmpty) r.push({ sourceUrl: parsed.sourceUrl, fileName: parsed.fileName, range, data: undefined }); } } return r; function parseFileLink(file) { const url = new URL(file); const parts = url.pathname.split('/'); const fileName = parts.pop(); if (!fileName) return undefined; // no file name, invalid link const sourceUrl = `${url.protocol}//${url.hostname}${parts.join('/')}`; const bits = fileName.split('_'); if (bits.length === 1 && bits[0] === 'latest') { return { range: 'latest', sourceUrl, fileName }; } if (bits.length === 3) { const fromHeight = parseInt(bits[0], 10); const toHeight = parseInt(bits[1], 10); if (Number.isInteger(fromHeight) && Number.isInteger(toHeight)) { return { range: { fromHeight, toHeight }, sourceUrl, fileName }; } } return undefined; } } } exports.WhatsOnChainServices = WhatsOnChainServices; WhatsOnChainServices.chainInfo = []; WhatsOnChainServices.chainInfoTime = []; WhatsOnChainServices.chainInfoMsecs = []; function wocGetHeadersHeaderToBlockHeader(h) { const bits = typeof h.bits === 'string' ? parseInt(h.bits, 16) : h.bits; if (!h.previousblockhash) { h.previousblockhash = '0000000000000000000000000000000000000000000000000000000000000000'; // genesis } const bh = { height: h.height, hash: h.hash, version: h.version, previousHash: h.previousblockhash, merkleRoot: h.merkleroot, time: h.time, bits, nonce: h.nonce }; return bh; } //# sourceMappingURL=WhatsOnChainServices.js.map