UNPKG

bitcore-node

Version:

A blockchain indexing node with extended capabilities using bitcore

74 lines (66 loc) 2.1 kB
import request from 'request'; import util from 'util'; import logger from '../../logger'; import { NetworkType } from '../../types/ChainNetwork'; import { FeeCacheType, IFeeProvider } from '../../types/FeeProvider'; export class BlockCypherClass implements IFeeProvider { private feeUrls = { mainnet: 'https://api.blockcypher.com/v1/btc/main', testnet3: 'https://api.blockcypher.com/v1/btc/test3' }; private cache: { mainnet: FeeCacheType; testnet3: FeeCacheType; } = { mainnet: { timestamp: 0, response: null }, testnet3: { timestamp: 0, response: null } }; public async getFee(network: NetworkType, nblocks: number): Promise<number> { try { network = network === 'regtest' ? 'testnet3' : network; // blockcypher rate limits to 3 req/s or 100 req/hr, so cache for 1.5 minutes if (this.cache[network] && this.cache[network].timestamp > Date.now() - 1000 * 90) { return this._getFeeLevel(this.cache[network].response, nblocks); } const res = await util.promisify(request.get).call(request, { uri: this.feeUrls[network], json: true }); if (res.statusCode !== 200) { throw new Error(`Status code: ${res.statusCode}`); } const fee = res.body; this.cache[network] = { timestamp: Date.now(), response: fee }; return this._getFeeLevel(fee, nblocks); } catch (err: any) { logger.warn('Error getting fee from blockcypher: %o', err.message || err); throw err; } }; /** * Return the appropriate fee level for nblocks per the ref. * REF: https://www.blockcypher.com/dev/bitcoin/#blockchain * @param response * @param nblocks * @returns */ private _getFeeLevel(response, nblocks: number): number { if (nblocks <= 2) { return response.high_fee_per_kb / 1000; } else if (nblocks <= 6) { return response.medium_fee_per_kb / 1000; } else { return response.low_fee_per_kb / 1000; } }; }; export const BlockCypher = new BlockCypherClass();