UNPKG

@bigmi/core

Version:

TypeScript library for Bitcoin apps.

91 lines 3.38 kB
import { RpcRequestError } from '../../errors/request.js'; import { RpcErrorCode } from '../../errors/rpc.js'; import { InsufficientUTXOBalanceError } from '../../errors/utxo.js'; import { urlWithParams } from '../../utils/url.js'; import { getBalance } from './getBalance.js'; const blockChairUTXOTransformer = (scriptHex) => (data) => ({ blockHeight: data.block_id, scriptHex, txId: data.transaction_hash, value: data.value, vout: data.index, }); const MAX_API_LIMIT = '100,100'; export const getUTXOs = async (client, { baseUrl, apiKey }, { address, minValue }) => { async function* fetchUTXOs() { let offset = 0; let hasMore = true; while (hasMore) { const apiUrl = urlWithParams(`${baseUrl}/dashboards/addresses/${address}`, { key: apiKey, offset: `0,${offset}`, limit: MAX_API_LIMIT, }); const response = (await client.request({ url: apiUrl, fetchOptions: { method: 'GET' }, })); if (response.context?.code !== 200 && response.context?.code !== 404) { throw new RpcRequestError({ url: apiUrl, body: { method: 'fetchUTXOs', params: { address, minValue, }, }, error: { code: response.context.code === 429 ? RpcErrorCode.ACCESS_DENIED : RpcErrorCode.MISC_ERROR, message: response.context.error || 'Error fetching utxos', }, }); } if (!response.data || response.data.utxo.length === 0) { hasMore = false; continue; } const { limit } = response.context; const totalRows = response.data.addresses[address].unspent_output_count; if (limit && totalRows) { const [, utxoLimit] = String(limit) .split(',') .map((val) => Number(val)); hasMore = offset + utxoLimit < totalRows; offset += utxoLimit; } else { hasMore = false; offset += 0; } yield response.data; } } if (minValue) { const { result: balance } = await getBalance(client, { baseUrl, apiKey }, { address }); if (minValue > Number(balance)) { throw new InsufficientUTXOBalanceError({ minValue, address, balance: Number(balance), }); } } const utxos = []; let valueCount = 0; for await (const batch of fetchUTXOs()) { const addressScriptHex = batch.addresses[address].script_hex; const utxoBatch = batch.utxo.map(blockChairUTXOTransformer(addressScriptHex)); utxos.push(...utxoBatch); if (minValue) { valueCount += utxoBatch.reduce((sum, utxo) => sum + utxo.value, 0); if (valueCount >= minValue) { break; } } } return { result: utxos }; }; //# sourceMappingURL=getUTXOs.js.map