UNPKG

wallet-storage-client

Version:
125 lines 5.13 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.getMerklePathFromWhatsOnChainTsc = getMerklePathFromWhatsOnChainTsc; exports.getRawTxFromWhatsOnChain = getRawTxFromWhatsOnChain; exports.getUtxoStatusFromWhatsOnChain = getUtxoStatusFromWhatsOnChain; exports.updateBsvExchangeRate = updateBsvExchangeRate; const index_client_1 = require("../../index.client"); const tscProofToMerklePath_1 = require("../../utility/tscProofToMerklePath"); const axios_1 = __importDefault(require("axios")); const whatsonchain_1 = __importDefault(require("whatsonchain")); /** * WhatOnChain.com has their own "hash/pos/R/L" proof format and a more TSC compliant proof format. * * The "/proof/tsc" endpoint is much closer to the TSC specification. It provides "index" directly and each node is just the provided hash value. * The "targetType" is unspecified and thus defaults to block header hash, requiring a Chaintracks lookup to get the merkleRoot... * Duplicate hash values are provided in full instead of being replaced by "*". * * @param txid * @param chain * @returns */ async function getMerklePathFromWhatsOnChainTsc(txid, chain, services) { const r = { name: 'WoCTsc' }; try { const url = `https://api.whatsonchain.com/v1/bsv/${chain}/tx/${txid}/proof/tsc`; let { data } = await axios_1.default.get(url); if (!data || data.length < 1) return r; if (!data['target']) data = data[0]; const p = data; const header = await services.hashToHeader(p.target); if (!header) throw new index_client_1.sdk.WERR_INVALID_PARAMETER('blockhash', 'a valid on-chain block hash'); const proof = { index: p.index, nodes: p.nodes, height: header.height }; r.merklePath = (0, tscProofToMerklePath_1.convertProofToMerklePath)(txid, proof); r.header = header; } catch (err) { r.error = index_client_1.sdk.WalletError.fromUnknown(err); } return r; } async function getRawTxFromWhatsOnChain(txid, chain) { const r = { name: 'WoC', txid: (0, index_client_1.asString)(txid) }; try { const url = `https://api.whatsonchain.com/v1/bsv/${chain}/tx/${txid}/hex`; const { data } = await axios_1.default.get(url); if (!data) return r; r.rawTx = (0, index_client_1.asArray)(data); } catch (err) { r.error = index_client_1.sdk.WalletError.fromUnknown(err); } return r; } async function getUtxoStatusFromWhatsOnChain(output, chain, outputFormat) { const r = { name: 'WoC', status: 'error', error: new index_client_1.sdk.WERR_INTERNAL(), details: [] }; for (let retry = 0;; retry++) { let url = ''; try { const scriptHash = (0, index_client_1.validateScriptHash)(output, outputFormat); url = `https://api.whatsonchain.com/v1/bsv/${chain}/script/${scriptHash}/unspent`; const { data } = await axios_1.default.get(url); if (Array.isArray(data)) { if (data.length === 0) { r.status = 'success'; r.error = undefined; r.isUtxo = false; } else { r.status = 'success'; r.error = undefined; r.isUtxo = true; for (const s of data) { r.details.push({ txid: s.tx_hash, satoshis: s.value, height: s.height, index: s.tx_pos }); } } } else { throw new index_client_1.sdk.WERR_INTERNAL("data is not an array"); } return r; } catch (eu) { const e = index_client_1.sdk.WalletError.fromUnknown(eu); if (e.code !== 'ECONNRESET' || retry > 2) { r.error = new index_client_1.sdk.WERR_INTERNAL(`service failure: ${url}, error: ${JSON.stringify(index_client_1.sdk.WalletError.fromUnknown(eu))}`); return r; } } } return r; } async function updateBsvExchangeRate(rate, updateMsecs) { if (rate) { // Check if the rate we know is stale enough to update. updateMsecs || (updateMsecs = 1000 * 60 * 15); if (new Date(Date.now() - updateMsecs) < rate.timestamp) return rate; } // TODO: Expand to redundant services with caching... const woc = new whatsonchain_1.default(); const r = await woc.exchangeRate(); const wocrate = r; if (wocrate.currency !== 'USD') wocrate.rate = NaN; const newRate = { timestamp: new Date(), base: 'USD', rate: wocrate.rate }; //console.log(`new bsv rate=${JSON.stringify(newRate)}`) return newRate; } //# sourceMappingURL=whatsonchain.js.map