@bigmi/core
Version:
TypeScript library for Bitcoin apps.
78 lines • 2.79 kB
JavaScript
import { RpcRequestError } from '../../errors/request.js';
import { InsufficientUTXOBalanceError } from '../../errors/utxo.js';
import { urlWithParams } from '../../utils/url.js';
import { getRpcErrorCode } from './utils.js';
const blockcypherUTXOTransformer = (utxo) => ({
blockHeight: utxo.block_height,
isConfirmed: Boolean(utxo.confirmations),
confirmations: utxo.confirmations,
value: utxo.value,
vout: utxo.tx_output_n,
txId: utxo.tx_hash,
scriptHex: utxo.script,
});
const MAX_API_LIMIT = 2000;
export const getUTXOs = async (client, { baseUrl, apiKey }, { address, minValue }) => {
async function* fetchUTXOs() {
let hasMore = true;
let beforeBlock;
while (hasMore) {
const apiUrl = urlWithParams(`${baseUrl}/addrs/${address}`, {
token: apiKey,
unspentOnly: 'true',
includeScript: 'true',
before: beforeBlock,
limit: MAX_API_LIMIT,
});
const response = (await client.request({
url: apiUrl,
fetchOptions: { method: 'GET' },
}));
if (response.error) {
throw new RpcRequestError({
url: apiUrl,
body: {
method: 'fetchUTXOs',
params: {
address,
minValue,
},
},
error: {
code: getRpcErrorCode(response.error),
message: response.error,
},
});
}
if (minValue && minValue > response.final_balance) {
throw new InsufficientUTXOBalanceError({
minValue,
address,
balance: response.final_balance,
});
}
if (!response.txrefs || response.txrefs.length === 0) {
hasMore = false;
continue;
}
const { hasMore: apiHasMore } = response;
hasMore = Boolean(apiHasMore);
beforeBlock = response.txrefs[response.txrefs.length - 1].block_height;
yield response.txrefs;
}
}
const utxos = [];
let valueCount = 0;
for await (const batch of fetchUTXOs()) {
const utxoBatch = batch.map(blockcypherUTXOTransformer);
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