UNPKG

@bitgo/utxo-bin

Version:

Command-line utility for BitGo UTXO transactions

105 lines 15.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.fetchTransactionHex = fetchTransactionHex; exports.fetchTransactionStatus = fetchTransactionStatus; exports.fetchPrevOutputs = fetchPrevOutputs; exports.fetchPrevOutputSpends = fetchPrevOutputSpends; exports.fetchOutputSpends = fetchOutputSpends; exports.getClient = getClient; const fs = require("fs"); const process = require("process"); const util_1 = require("util"); const utxolib = require("@bitgo/utxo-lib"); const blockapis = require("@bitgo/blockapis"); const blockapis_1 = require("@bitgo/blockapis"); const statics_1 = require("@bitgo/statics"); function getTxOutPoints(tx) { if (tx instanceof utxolib.bitgo.UtxoTransaction) { return tx.ins.map((i) => utxolib.bitgo.getOutputIdForInput(i)); } else { return tx.txInputs.map((i) => utxolib.bitgo.getOutputIdForInput(i)); } } function getCoinName(network) { const networkName = utxolib.getNetworkName(network); // the bitcoincash network actually has two coins: bch and bcha - hardcode bch by default here switch (networkName) { case 'bitcoincash': return 'bch'; case 'bitcoincashTestnet': return 'tbch'; } const matches = [...statics_1.coins].flatMap(([, coin]) => coin instanceof statics_1.UtxoCoin && coin.network.utxolibName === networkName ? [coin.name] : []); switch (matches.length) { case 0: throw new Error(`no coin for network ${networkName}`); case 1: return matches[0]; default: throw new Error(`more than one coin for ${networkName}: ${matches}`); } } function getApi(httpClient, network) { const coinName = getCoinName(network); switch (coinName) { case 'btc': case 'tbtc': return blockapis.BlockstreamApi.forCoin(coinName, { httpClient }); default: return blockapis.BlockchairApi.forCoin(coinName, { httpClient }); } } async function fetchTransactionHex(httpClient, location, network) { location = Object.fromEntries(Object.entries(location).filter(([k, v]) => v !== undefined)); if (location.blockHeight !== undefined && location.txIndex !== undefined) { const api = getApi(httpClient, network); if (api instanceof blockapis.BlockstreamApi) { const txids = await (0, blockapis_1.getTransactionIdsAtHeight)(api, location.blockHeight); const txid = txids[location.txIndex]; if (!txid) { throw new Error(`no tx at height ${location.blockHeight} position ${location.txIndex}`); } return fetchTransactionHex(httpClient, { txid }, network); } throw new Error(`cannot use api ${api.constructor.name} to fetch tx by height`); } if (location.txid) { if (Object.keys(location).length > 1) { throw new Error(`cannot specify both txid and ${Object.keys(location)}`); } return await getApi(httpClient, network).getTransactionHex(location.txid); } throw new Error(`invalid location: ${JSON.stringify(location)}`); } async function fetchTransactionStatus(httpClient, txid, network) { return await getApi(httpClient, network).getTransactionStatus(txid); } async function fetchPrevOutputs(httpClient, tx) { return (await blockapis.fetchInputs(getTxOutPoints(tx), getApi(httpClient, tx.network), tx.network)).map((v) => ({ ...v, value: BigInt(v.value), })); } async function fetchPrevOutputSpends(httpClient, tx) { return await blockapis.fetchTransactionSpends(getTxOutPoints(tx), getApi(httpClient, tx.network)); } async function fetchOutputSpends(httpClient, tx) { try { return await getApi(httpClient, tx.network).getTransactionSpends(tx.getId()); } catch (e) { console.error(`error fetching spends for tx ${tx.getId()}: ${e}`); return []; } } async function getClient({ cache }) { if (cache) { const mkdir = (0, util_1.promisify)(fs.mkdir); const dir = `${process.env.HOME}/.cache/utxo-bin/`; await mkdir(dir, { recursive: true }); return new blockapis_1.CachingHttpClient(dir); } return new blockapis_1.BaseHttpClient(); } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmV0Y2guanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZmV0Y2gudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFzREEsa0RBZ0NDO0FBRUQsd0RBTUM7QUFFRCw0Q0FLQztBQUVELHNEQUtDO0FBRUQsOENBVUM7QUFFRCw4QkFRQztBQWxJRCx5QkFBeUI7QUFDekIsbUNBQW1DO0FBQ25DLCtCQUFpQztBQUVqQywyQ0FBMkM7QUFDM0MsOENBQThDO0FBQzlDLGdEQUE0RztBQUM1Ryw0Q0FBaUQ7QUFJakQsU0FBUyxjQUFjLENBQUMsRUFBWTtJQUNsQyxJQUFJLEVBQUUsWUFBWSxPQUFPLENBQUMsS0FBSyxDQUFDLGVBQWUsRUFBRSxDQUFDO1FBQ2hELE9BQU8sRUFBRSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsbUJBQW1CLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNqRSxDQUFDO1NBQU0sQ0FBQztRQUNOLE9BQU8sRUFBRSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsbUJBQW1CLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUN0RSxDQUFDO0FBQ0gsQ0FBQztBQUVELFNBQVMsV0FBVyxDQUFDLE9BQXdCO0lBQzNDLE1BQU0sV0FBVyxHQUFHLE9BQU8sQ0FBQyxjQUFjLENBQUMsT0FBTyxDQUFDLENBQUM7SUFFcEQsOEZBQThGO0lBQzlGLFFBQVEsV0FBVyxFQUFFLENBQUM7UUFDcEIsS0FBSyxhQUFhO1lBQ2hCLE9BQU8sS0FBSyxDQUFDO1FBQ2YsS0FBSyxvQkFBb0I7WUFDdkIsT0FBTyxNQUFNLENBQUM7SUFDbEIsQ0FBQztJQUVELE1BQU0sT0FBTyxHQUFHLENBQUMsR0FBRyxlQUFLLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUs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LENBQUM7SUFDL0UsQ0FBQztJQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7UUFDWCxPQUFPLENBQUMsS0FBSyxDQUFDLGdDQUFnQyxFQUFFLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUNsRSxPQUFPLEVBQUUsQ0FBQztJQUNaLENBQUM7QUFDSCxDQUFDO0FBRU0sS0FBSyxVQUFVLFNBQVMsQ0FBQyxFQUFFLEtBQUssRUFBc0I7SUFDM0QsSUFBSSxLQUFLLEVBQUUsQ0FBQztRQUNWLE1BQU0sS0FBSyxHQUFHLElBQUEsZ0JBQVMsRUFBQyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDbEMsTUFBTSxHQUFHLEdBQUcsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksbUJBQW1CLENBQUM7UUFDbkQsTUFBTSxLQUFLLENBQUMsR0FBRyxFQUFFLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7UUFDdEMsT0FBTyxJQUFJLDZCQUFpQixDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ3BDLENBQUM7SUFDRCxPQUFPLElBQUksMEJBQWMsRUFBRSxDQUFDO0FBQzlCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBmcyBmcm9tICdmcyc7XG5pbXBvcnQgKiBhcyBwcm9jZXNzIGZyb20gJ3Byb2Nlc3MnO1xuaW1wb3J0IHsgcHJvbWlzaWZ5IH0gZnJvbSAndXRpbCc7XG5cbmltcG9ydCAqIGFzIHV0eG9saWIgZnJvbSAnQGJpdGdvL3V0eG8tbGliJztcbmltcG9ydCAqIGFzIGJsb2NrYXBpcyBmcm9tICdAYml0Z28vYmxvY2thcGlzJztcbmltcG9ydCB7IEJhc2VIdHRwQ2xpZW50LCBDYWNoaW5nSHR0cENsaWVudCwgZ2V0VHJhbnNhY3Rpb25JZHNBdEhlaWdodCwgSHR0cENsaWVudCB9IGZyb20gJ0BiaXRnby9ibG9ja2FwaXMnO1xuaW1wb3J0IHsgY29pbnMsIFV0eG9Db2luIH0gZnJvbSAnQGJpdGdvL3N0YXRpY3MnO1xuXG5pbXBvcnQgeyBQYXJzZXJUeCB9IGZyb20gJy4vUGFyc2VyVHgnO1xuXG5mdW5jdGlvbiBnZXRUeE91dFBvaW50cyh0eDogUGFyc2VyVHgpOiB1dHhvbGliLmJpdGdvLlR4T3V0UG9pbnRbXSB7XG4gIGlmICh0eCBpbnN0YW5jZW9mIHV0eG9saWIuYml0Z28uVXR4b1RyYW5zYWN0aW9uKSB7XG4gICAgcmV0dXJuIHR4Lmlucy5tYXAoKGkpID0+IHV0eG9saWIuYml0Z28uZ2V0T3V0cHV0SWRGb3JJbnB1dChpKSk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHR4LnR4SW5wdXRzLm1hcCgoaSkgPT4gdXR4b2xpYi5iaXRnby5nZXRPdXRwdXRJZEZvcklucHV0KGkpKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBnZXRDb2luTmFtZShuZXR3b3JrOiB1dHhvbGliLk5ldHdvcmspOiBzdHJpbmcge1xuICBjb25zdCBuZXR3b3JrTmFtZSA9IHV0eG9saWIuZ2V0TmV0d29ya05hbWUobmV0d29yayk7XG5cbiAgLy8gdGhlIGJpdGNvaW5jYXNoIG5ldHdvcmsgYWN0dWFsbHkgaGFzIHR3byBjb2luczogYmNoIGFuZCBiY2hhIC0gaGFyZGNvZGUgYmNoIGJ5IGRlZmF1bHQgaGVyZVxuICBzd2l0Y2ggKG5ldHdvcmtOYW1lKSB7XG4gICAgY2FzZSAnYml0Y29pbmNhc2gnOlxuICAgICAgcmV0dXJuICdiY2gnO1xuICAgIGNhc2UgJ2JpdGNvaW5jYXNoVGVzdG5ldCc6XG4gICAgICByZXR1cm4gJ3RiY2gnO1xuICB9XG5cbiAgY29uc3QgbWF0Y2hlcyA9IFsuLi5jb2luc10uZmxhdE1hcCgoWywgY29pbl0pID0+XG4gICAgY29pbiBpbnN0YW5jZW9mIFV0eG9Db2luICYmIGNvaW4ubmV0d29yay51dHhvbGliTmFtZSA9PT0gbmV0d29ya05hbWUgPyBbY29pbi5uYW1lXSA6IFtdXG4gICk7XG4gIHN3aXRjaCAobWF0Y2hlcy5sZW5ndGgpIHtcbiAgICBjYXNlIDA6XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYG5vIGNvaW4gZm9yIG5ldHdvcmsgJHtuZXR3b3JrTmFtZX1gKTtcbiAgICBjYXNlIDE6XG4gICAgICByZXR1cm4gbWF0Y2hlc1swXTtcbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgbmV3IEVycm9yKGBtb3JlIHRoYW4gb25lIGNvaW4gZm9yICR7bmV0d29ya05hbWV9OiAke21hdGNoZXN9YCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gZ2V0QXBpKGh0dHBDbGllbnQ6IEh0dHBDbGllbnQsIG5ldHdvcms6IHV0eG9saWIuTmV0d29yayk6IGJsb2NrYXBpcy5VdHhvQXBpIHtcbiAgY29uc3QgY29pbk5hbWUgPSBnZXRDb2luTmFtZShuZXR3b3JrKTtcbiAgc3dpdGNoIChjb2luTmFtZSkge1xuICAgIGNhc2UgJ2J0Yyc6XG4gICAgY2FzZSAndGJ0Yyc6XG4gICAgICByZXR1cm4gYmxvY2thcGlzLkJsb2Nrc3RyZWFtQXBpLmZvckNvaW4oY29pbk5hbWUsIHsgaHR0cENsaWVudCB9KTtcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIGJsb2NrYXBpcy5CbG9ja2NoYWlyQXBpLmZvckNvaW4oY29pbk5hbWUsIHsgaHR0cENsaWVudCB9KTtcbiAgfVxufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZmV0Y2hUcmFuc2FjdGlvbkhleChcbiAgaHR0cENsaWVudDogSHR0cENsaWVudCxcbiAgbG9jYXRpb246IHtcbiAgICB0eGlkPzogc3RyaW5nO1xuICAgIGJsb2NrSGVpZ2h0PzogbnVtYmVyO1xuICAgIHR4SW5kZXg/OiBudW1iZXI7XG4gIH0sXG4gIG5ldHdvcms6IHV0eG9saWIuTmV0d29ya1xuKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgbG9jYXRpb24gPSBPYmplY3QuZnJvbUVudHJpZXMoT2JqZWN0LmVudHJpZXMobG9jYXRpb24pLmZpbHRlcigoW2ssIHZdKSA9PiB2ICE9PSB1bmRlZmluZWQpKTtcblxuICBpZiAobG9jYXRpb24uYmxvY2tIZWlnaHQgIT09IHVuZGVmaW5lZCAmJiBsb2NhdGlvbi50eEluZGV4ICE9PSB1bmRlZmluZWQpIHtcbiAgICBjb25zdCBhcGkgPSBnZXRBcGkoaHR0cENsaWVudCwgbmV0d29yayk7XG4gICAgaWYgKGFwaSBpbnN0YW5jZW9mIGJsb2NrYXBpcy5CbG9ja3N0cmVhbUFwaSkge1xuICAgICAgY29uc3QgdHhpZHMgPSBhd2FpdCBnZXRUcmFuc2FjdGlvbklkc0F0SGVpZ2h0KGFwaSwgbG9jYXRpb24uYmxvY2tIZWlnaHQpO1xuICAgICAgY29uc3QgdHhpZCA9IHR4aWRzW2xvY2F0aW9uLnR4SW5kZXhdO1xuICAgICAgaWYgKCF0eGlkKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgbm8gdHggYXQgaGVpZ2h0ICR7bG9jYXRpb24uYmxvY2tIZWlnaHR9IHBvc2l0aW9uICR7bG9jYXRpb24udHhJbmRleH1gKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBmZXRjaFRyYW5zYWN0aW9uSGV4KGh0dHBDbGllbnQsIHsgdHhpZCB9LCBuZXR3b3JrKTtcbiAgICB9XG4gICAgdGhyb3cgbmV3IEVycm9yKGBjYW5ub3QgdXNlIGFwaSAke2FwaS5jb25zdHJ1Y3Rvci5uYW1lfSB0byBmZXRjaCB0eCBieSBoZWlnaHRgKTtcbiAgfVxuXG4gIGlmIChsb2NhdGlvbi50eGlkKSB7XG4gICAgaWYgKE9iamVjdC5rZXlzKGxvY2F0aW9uKS5sZW5ndGggPiAxKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYGNhbm5vdCBzcGVjaWZ5IGJvdGggdHhpZCBhbmQgJHtPYmplY3Qua2V5cyhsb2NhdGlvbil9YCk7XG4gICAgfVxuICAgIHJldHVybiBhd2FpdCBnZXRBcGkoaHR0cENsaWVudCwgbmV0d29yaykuZ2V0VHJhbnNhY3Rpb25IZXgobG9jYXRpb24udHhpZCk7XG4gIH1cblxuICB0aHJvdyBuZXcgRXJyb3IoYGludmFsaWQgbG9jYXRpb246ICR7SlNPTi5zdHJpbmdpZnkobG9jYXRpb24pfWApO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZmV0Y2hUcmFuc2FjdGlvblN0YXR1cyhcbiAgaHR0cENsaWVudDogSHR0cENsaWVudCxcbiAgdHhpZDogc3RyaW5nLFxuICBuZXR3b3JrOiB1dHhvbGliLk5ldHdvcmtcbik6IFByb21pc2U8YmxvY2thcGlzLlRyYW5zYWN0aW9uU3RhdHVzPiB7XG4gIHJldHVybiBhd2FpdCBnZXRBcGkoaHR0cENsaWVudCwgbmV0d29yaykuZ2V0VHJhbnNhY3Rpb25TdGF0dXModHhpZCk7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBmZXRjaFByZXZPdXRwdXRzKGh0dHBDbGllbnQ6IEh0dHBDbGllbnQsIHR4OiBQYXJzZXJUeCk6IFByb21pc2U8dXR4b2xpYi5UeE91dHB1dDxiaWdpbnQ+W10+IHtcbiAgcmV0dXJuIChhd2FpdCBibG9ja2FwaXMuZmV0Y2hJbnB1dHMoZ2V0VHhPdXRQb2ludHModHgpLCBnZXRBcGkoaHR0cENsaWVudCwgdHgubmV0d29yayksIHR4Lm5ldHdvcmspKS5tYXAoKHYpID0+ICh7XG4gICAgLi4udixcbiAgICB2YWx1ZTogQmlnSW50KHYudmFsdWUpLFxuICB9KSk7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBmZXRjaFByZXZPdXRwdXRTcGVuZHMoXG4gIGh0dHBDbGllbnQ6IEh0dHBDbGllbnQsXG4gIHR4OiB1dHhvbGliLmJpdGdvLlV0eG9UcmFuc2FjdGlvbjxiaWdpbnQ+IHwgdXR4b2xpYi5iaXRnby5VdHhvUHNidFxuKTogUHJvbWlzZTxibG9ja2FwaXMuT3V0cHV0U3BlbmRbXT4ge1xuICByZXR1cm4gYXdhaXQgYmxvY2thcGlzLmZldGNoVHJhbnNhY3Rpb25TcGVuZHMoZ2V0VHhPdXRQb2ludHModHgpLCBnZXRBcGkoaHR0cENsaWVudCwgdHgubmV0d29yaykpO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZmV0Y2hPdXRwdXRTcGVuZHMoXG4gIGh0dHBDbGllbnQ6IEh0dHBDbGllbnQsXG4gIHR4OiB1dHhvbGliLmJpdGdvLlV0eG9UcmFuc2FjdGlvbjxiaWdpbnQ+XG4pOiBQcm9taXNlPGJsb2NrYXBpcy5PdXRwdXRTcGVuZFtdPiB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIGF3YWl0IGdldEFwaShodHRwQ2xpZW50LCB0eC5uZXR3b3JrKS5nZXRUcmFuc2FjdGlvblNwZW5kcyh0eC5nZXRJZCgpKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIGNvbnNvbGUuZXJyb3IoYGVycm9yIGZldGNoaW5nIHNwZW5kcyBmb3IgdHggJHt0eC5nZXRJZCgpfTogJHtlfWApO1xuICAgIHJldHVybiBbXTtcbiAgfVxufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZ2V0Q2xpZW50KHsgY2FjaGUgfTogeyBjYWNoZTogYm9vbGVhbiB9KTogUHJvbWlzZTxIdHRwQ2xpZW50PiB7XG4gIGlmIChjYWNoZSkge1xuICAgIGNvbnN0IG1rZGlyID0gcHJvbWlzaWZ5KGZzLm1rZGlyKTtcbiAgICBjb25zdCBkaXIgPSBgJHtwcm9jZXNzLmVudi5IT01FfS8uY2FjaGUvdXR4by1iaW4vYDtcbiAgICBhd2FpdCBta2RpcihkaXIsIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xuICAgIHJldHVybiBuZXcgQ2FjaGluZ0h0dHBDbGllbnQoZGlyKTtcbiAgfVxuICByZXR1cm4gbmV3IEJhc2VIdHRwQ2xpZW50KCk7XG59XG4iXX0=