UNPKG

@bitgo/utxo-lib

Version:

Client-side Bitcoin JavaScript library

85 lines 12.8 kB
"use strict"; /** * Contains helper methods for determining if a transaction output belongs to a given BitGo wallet */ Object.defineProperty(exports, "__esModule", { value: true }); exports.deriveKeyPairForOutput = deriveKeyPairForOutput; exports.isWalletOutput = isWalletOutput; exports.findWalletOutputIndices = findWalletOutputIndices; exports.getTotalAmountOfWalletOutputs = getTotalAmountOfWalletOutputs; exports.findInternalOutputIndices = findInternalOutputIndices; exports.getTotalAmountOfInternalOutputs = getTotalAmountOfInternalOutputs; const types_1 = require("../../types"); const outputScripts_1 = require("../../outputScripts"); const UtxoPsbt_1 = require("../../UtxoPsbt"); const utils_1 = require("bip174/src/lib/utils"); const RootNodes_1 = require("./RootNodes"); /** * Derives the appropriate BIP32 key pair for a given output. * It uses either tapBip32Derivation or bip32Derivation paths from the output. * @param bip32 - The BIP32Interface object to derive from. * @param output - The specific PSBT output to derive for. * @returns The derived BIP32 key pair if master fingerprint matches, or undefined. */ function deriveKeyPairForOutput(bip32, output) { return output.tapBip32Derivation?.length ? UtxoPsbt_1.UtxoPsbt.deriveKeyPair(bip32, output.tapBip32Derivation, { ignoreY: true }) : output.bip32Derivation?.length ? UtxoPsbt_1.UtxoPsbt.deriveKeyPair(bip32, output.bip32Derivation, { ignoreY: false }) : undefined; } /** * Determines if a specified output in a PSBT is an output of the wallet represented by the given root nodes. * @param psbt - The PSBT to check. * @param outputIndex - The index of the output to check. * @param rootWalletNodes - The root nodes representing the wallet. * @returns A boolean indicating if the output belongs to the wallet. */ function isWalletOutput(psbt, outputIndex, rootWalletNodes) { const output = (0, utils_1.checkForOutput)(psbt.data.outputs, outputIndex); const pubKeys = rootWalletNodes.map((rootNode) => deriveKeyPairForOutput(rootNode, output)?.publicKey); if (!(0, types_1.isBufferArray)(pubKeys)) { return false; } const outputScript = psbt.getOutputScript(outputIndex); return outputScripts_1.scriptTypes2Of3.some((scriptType) => (0, outputScripts_1.createOutputScript2of3)(pubKeys, scriptType).scriptPubKey.equals(outputScript)); } /** * Finds indices of all outputs in a PSBT that belong to the wallet represented by the given root nodes. * @param psbt - The PSBT to search through. * @param rootWalletNodes - The root nodes representing the wallet. * @returns An array of indices corresponding to wallet outputs. */ function findWalletOutputIndices(psbt, rootWalletNodes) { return psbt.data.outputs.flatMap((_, i) => (isWalletOutput(psbt, i, rootWalletNodes) ? [i] : [])); } /** * Calculates the total amount of all wallet outputs in a PSBT for the wallet represented by the given root nodes. * @param psbt - The PSBT to calculate for. * @param rootWalletNodes - The root nodes representing the wallet. * @returns The total amount of wallet outputs. */ function getTotalAmountOfWalletOutputs(psbt, rootWalletNodes) { const indices = findWalletOutputIndices(psbt, rootWalletNodes); const txOutputs = psbt.txOutputs; return indices.reduce((sum, i) => sum + txOutputs[i].value, BigInt(0)); } /** * Finds indices of all internal outputs in a PSBT, identified as outputs belonging to the wallet's root nodes within the PSBT. * @param psbt - The PSBT containing the wallet's root nodes as indicated by global Xpubs. * @returns An array of indices of internal outputs. */ function findInternalOutputIndices(psbt) { const rootNodes = (0, RootNodes_1.getSortedRootNodes)(psbt); return findWalletOutputIndices(psbt, rootNodes); } /** * Calculates the total amount of all internal outputs in a PSBT, identified as outputs belonging to the wallet's root nodes within the PSBT. * @param psbt - The PSBT containing the wallet's root nodes as indicated by global Xpubs. * @returns The total amount of internal outputs. */ function getTotalAmountOfInternalOutputs(psbt) { const rootNodes = (0, RootNodes_1.getSortedRootNodes)(psbt); return getTotalAmountOfWalletOutputs(psbt, rootNodes); } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUHNidE91dHB1dHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvYml0Z28vd2FsbGV0L3BzYnQvUHNidE91dHB1dHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOztHQUVHOztBQWlCSCx3REFNQztBQVNELHdDQWFDO0FBUUQsMERBRUM7QUFRRCxzRUFJQztBQU9ELDhEQUdDO0FBT0QsMEVBR0M7QUFyRkQsdUNBQW9EO0FBQ3BELHVEQUE4RTtBQUM5RSw2Q0FBMEM7QUFDMUMsZ0RBQXNEO0FBR3RELDJDQUFpRDtBQUVqRDs7Ozs7O0dBTUc7QUFDSCxTQUFnQixzQkFBc0IsQ0FBQyxLQUFxQixFQUFFLE1BQWtCO0lBQzlFLE9BQU8sTUFBTSxDQUFDLGtCQUFrQixFQUFFLE1BQU07UUFDdEMsQ0FBQyxDQUFDLG1CQUFRLENBQUMsYUFBYSxDQUFDLEtBQUssRUFBRSxNQUFNLENBQUMsa0JBQWtCLEVBQUUsRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLENBQUM7UUFDN0UsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxlQUFlLEVBQUUsTUFBTTtZQUNoQyxDQUFDLENBQUMsbUJBQVEsQ0FBQyxhQUFhLENBQUMsS0FBSyxFQUFFLE1BQU0sQ0FBQyxlQUFlLEVBQUUsRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLENBQUM7WUFDM0UsQ0FBQyxDQUFDLFNBQVMsQ0FBQztBQUNoQixDQUFDO0FBRUQ7Ozs7OztHQU1HO0FBQ0gsU0FBZ0IsY0FBYyxDQUFDLElBQWMsRUFBRSxXQUFtQixFQUFFLGVBQXVDO0lBQ3pHLE1BQU0sTUFBTSxHQUFHLElBQUEsc0JBQWMsRUFBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxXQUFXLENBQUMsQ0FBQztJQUU5RCxNQUFNLE9BQU8sR0FBRyxlQUFlLENBQUMsR0FBRyxDQUFDLENBQUMsUUFBUSxFQUFFLEVBQUUsQ0FBQyxzQkFBc0IsQ0FBQyxRQUFRLEVBQUUsTUFBTSxDQUFDLEVBQUUsU0FBUyxDQUFDLENBQUM7SUFFdkcsSUFBSSxDQUFDLElBQUEscUJBQWEsRUFBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1FBQzVCLE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztJQUVELE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsV0FBVyxDQUFDLENBQUM7SUFDdkQsT0FBTywrQkFBZSxDQUFDLElBQUksQ0FBQyxDQUFDLFVBQVUsRUFBRSxFQUFFLENBQ3pDLElBQUEsc0NBQXNCLEVBQUMsT0FBTyxFQUFFLFVBQVUsQ0FBQyxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsWUFBWSxDQUFDLENBQzlFLENBQUM7QUFDSixDQUFDO0FBRUQ7Ozs7O0dBS0c7QUFDSCxTQUFnQix1QkFBdUIsQ0FBQyxJQUFjLEVBQUUsZUFBdUM7SUFDN0YsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLGNBQWMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxFQUFFLGVBQWUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQ3BHLENBQUM7QUFFRDs7Ozs7R0FLRztBQUNILFNBQWdCLDZCQUE2QixDQUFDLElBQWMsRUFBRSxlQUF1QztJQUNuRyxNQUFNLE9BQU8sR0FBRyx1QkFBdUIsQ0FBQyxJQUFJLEVBQUUsZUFBZSxDQUFDLENBQUM7SUFDL0QsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQztJQUNqQyxPQUFPLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxHQUFHLEdBQUcsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN6RSxDQUFDO0FBRUQ7Ozs7R0FJRztBQUNILFNBQWdCLHlCQUF5QixDQUFDLElBQWM7SUFDdEQsTUFBTSxTQUFTLEdBQUcsSUFBQSw4QkFBa0IsRUFBQyxJQUFJLENBQUMsQ0FBQztJQUMzQyxPQUFPLHVCQUF1QixDQUFDLElBQUksRUFBRSxTQUFTLENBQUMsQ0FBQztBQUNsRCxDQUFDO0FBRUQ7Ozs7R0FJRztBQUNILFNBQWdCLCtCQUErQixDQUFDLElBQWM7SUFDNUQsTUFBTSxTQUFTLEdBQUcsSUFBQSw4QkFBa0IsRUFBQyxJQUFJLENBQUMsQ0FBQztJQUMzQyxPQUFPLDZCQUE2QixDQUFDLElBQUksRUFBRSxTQUFTLENBQUMsQ0FBQztBQUN4RCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBDb250YWlucyBoZWxwZXIgbWV0aG9kcyBmb3IgZGV0ZXJtaW5pbmcgaWYgYSB0cmFuc2FjdGlvbiBvdXRwdXQgYmVsb25ncyB0byBhIGdpdmVuIEJpdEdvIHdhbGxldFxuICovXG5cbmltcG9ydCB7IGlzQnVmZmVyQXJyYXksIFRyaXBsZSB9IGZyb20gJy4uLy4uL3R5cGVzJztcbmltcG9ydCB7IGNyZWF0ZU91dHB1dFNjcmlwdDJvZjMsIHNjcmlwdFR5cGVzMk9mMyB9IGZyb20gJy4uLy4uL291dHB1dFNjcmlwdHMnO1xuaW1wb3J0IHsgVXR4b1BzYnQgfSBmcm9tICcuLi8uLi9VdHhvUHNidCc7XG5pbXBvcnQgeyBjaGVja0Zvck91dHB1dCB9IGZyb20gJ2JpcDE3NC9zcmMvbGliL3V0aWxzJztcbmltcG9ydCB7IFBzYnRPdXRwdXQgfSBmcm9tICdiaXAxNzQvc3JjL2xpYi9pbnRlcmZhY2VzJztcbmltcG9ydCB7IEJJUDMySW50ZXJmYWNlIH0gZnJvbSAnQGJpdGdvL3NlY3AyNTZrMSc7XG5pbXBvcnQgeyBnZXRTb3J0ZWRSb290Tm9kZXMgfSBmcm9tICcuL1Jvb3ROb2Rlcyc7XG5cbi8qKlxuICogRGVyaXZlcyB0aGUgYXBwcm9wcmlhdGUgQklQMzIga2V5IHBhaXIgZm9yIGEgZ2l2ZW4gb3V0cHV0LlxuICogSXQgdXNlcyBlaXRoZXIgdGFwQmlwMzJEZXJpdmF0aW9uIG9yIGJpcDMyRGVyaXZhdGlvbiBwYXRocyBmcm9tIHRoZSBvdXRwdXQuXG4gKiBAcGFyYW0gYmlwMzIgLSBUaGUgQklQMzJJbnRlcmZhY2Ugb2JqZWN0IHRvIGRlcml2ZSBmcm9tLlxuICogQHBhcmFtIG91dHB1dCAtIFRoZSBzcGVjaWZpYyBQU0JUIG91dHB1dCB0byBkZXJpdmUgZm9yLlxuICogQHJldHVybnMgVGhlIGRlcml2ZWQgQklQMzIga2V5IHBhaXIgaWYgbWFzdGVyIGZpbmdlcnByaW50IG1hdGNoZXMsIG9yIHVuZGVmaW5lZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRlcml2ZUtleVBhaXJGb3JPdXRwdXQoYmlwMzI6IEJJUDMySW50ZXJmYWNlLCBvdXRwdXQ6IFBzYnRPdXRwdXQpOiBCSVAzMkludGVyZmFjZSB8IHVuZGVmaW5lZCB7XG4gIHJldHVybiBvdXRwdXQudGFwQmlwMzJEZXJpdmF0aW9uPy5sZW5ndGhcbiAgICA/IFV0eG9Qc2J0LmRlcml2ZUtleVBhaXIoYmlwMzIsIG91dHB1dC50YXBCaXAzMkRlcml2YXRpb24sIHsgaWdub3JlWTogdHJ1ZSB9KVxuICAgIDogb3V0cHV0LmJpcDMyRGVyaXZhdGlvbj8ubGVuZ3RoXG4gICAgPyBVdHhvUHNidC5kZXJpdmVLZXlQYWlyKGJpcDMyLCBvdXRwdXQuYmlwMzJEZXJpdmF0aW9uLCB7IGlnbm9yZVk6IGZhbHNlIH0pXG4gICAgOiB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lcyBpZiBhIHNwZWNpZmllZCBvdXRwdXQgaW4gYSBQU0JUIGlzIGFuIG91dHB1dCBvZiB0aGUgd2FsbGV0IHJlcHJlc2VudGVkIGJ5IHRoZSBnaXZlbiByb290IG5vZGVzLlxuICogQHBhcmFtIHBzYnQgLSBUaGUgUFNCVCB0byBjaGVjay5cbiAqIEBwYXJhbSBvdXRwdXRJbmRleCAtIFRoZSBpbmRleCBvZiB0aGUgb3V0cHV0IHRvIGNoZWNrLlxuICogQHBhcmFtIHJvb3RXYWxsZXROb2RlcyAtIFRoZSByb290IG5vZGVzIHJlcHJlc2VudGluZyB0aGUgd2FsbGV0LlxuICogQHJldHVybnMgQSBib29sZWFuIGluZGljYXRpbmcgaWYgdGhlIG91dHB1dCBiZWxvbmdzIHRvIHRoZSB3YWxsZXQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1dhbGxldE91dHB1dChwc2J0OiBVdHhvUHNidCwgb3V0cHV0SW5kZXg6IG51bWJlciwgcm9vdFdhbGxldE5vZGVzOiBUcmlwbGU8QklQMzJJbnRlcmZhY2U+KTogYm9vbGVhbiB7XG4gIGNvbnN0IG91dHB1dCA9IGNoZWNrRm9yT3V0cHV0KHBzYnQuZGF0YS5vdXRwdXRzLCBvdXRwdXRJbmRleCk7XG5cbiAgY29uc3QgcHViS2V5cyA9IHJvb3RXYWxsZXROb2Rlcy5tYXAoKHJvb3ROb2RlKSA9PiBkZXJpdmVLZXlQYWlyRm9yT3V0cHV0KHJvb3ROb2RlLCBvdXRwdXQpPy5wdWJsaWNLZXkpO1xuXG4gIGlmICghaXNCdWZmZXJBcnJheShwdWJLZXlzKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGNvbnN0IG91dHB1dFNjcmlwdCA9IHBzYnQuZ2V0T3V0cHV0U2NyaXB0KG91dHB1dEluZGV4KTtcbiAgcmV0dXJuIHNjcmlwdFR5cGVzMk9mMy5zb21lKChzY3JpcHRUeXBlKSA9PlxuICAgIGNyZWF0ZU91dHB1dFNjcmlwdDJvZjMocHViS2V5cywgc2NyaXB0VHlwZSkuc2NyaXB0UHViS2V5LmVxdWFscyhvdXRwdXRTY3JpcHQpXG4gICk7XG59XG5cbi8qKlxuICogRmluZHMgaW5kaWNlcyBvZiBhbGwgb3V0cHV0cyBpbiBhIFBTQlQgdGhhdCBiZWxvbmcgdG8gdGhlIHdhbGxldCByZXByZXNlbnRlZCBieSB0aGUgZ2l2ZW4gcm9vdCBub2Rlcy5cbiAqIEBwYXJhbSBwc2J0IC0gVGhlIFBTQlQgdG8gc2VhcmNoIHRocm91Z2guXG4gKiBAcGFyYW0gcm9vdFdhbGxldE5vZGVzIC0gVGhlIHJvb3Qgbm9kZXMgcmVwcmVzZW50aW5nIHRoZSB3YWxsZXQuXG4gKiBAcmV0dXJucyBBbiBhcnJheSBvZiBpbmRpY2VzIGNvcnJlc3BvbmRpbmcgdG8gd2FsbGV0IG91dHB1dHMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmaW5kV2FsbGV0T3V0cHV0SW5kaWNlcyhwc2J0OiBVdHhvUHNidCwgcm9vdFdhbGxldE5vZGVzOiBUcmlwbGU8QklQMzJJbnRlcmZhY2U+KTogbnVtYmVyW10ge1xuICByZXR1cm4gcHNidC5kYXRhLm91dHB1dHMuZmxhdE1hcCgoXywgaSkgPT4gKGlzV2FsbGV0T3V0cHV0KHBzYnQsIGksIHJvb3RXYWxsZXROb2RlcykgPyBbaV0gOiBbXSkpO1xufVxuXG4vKipcbiAqIENhbGN1bGF0ZXMgdGhlIHRvdGFsIGFtb3VudCBvZiBhbGwgd2FsbGV0IG91dHB1dHMgaW4gYSBQU0JUIGZvciB0aGUgd2FsbGV0IHJlcHJlc2VudGVkIGJ5IHRoZSBnaXZlbiByb290IG5vZGVzLlxuICogQHBhcmFtIHBzYnQgLSBUaGUgUFNCVCB0byBjYWxjdWxhdGUgZm9yLlxuICogQHBhcmFtIHJvb3RXYWxsZXROb2RlcyAtIFRoZSByb290IG5vZGVzIHJlcHJlc2VudGluZyB0aGUgd2FsbGV0LlxuICogQHJldHVybnMgVGhlIHRvdGFsIGFtb3VudCBvZiB3YWxsZXQgb3V0cHV0cy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFRvdGFsQW1vdW50T2ZXYWxsZXRPdXRwdXRzKHBzYnQ6IFV0eG9Qc2J0LCByb290V2FsbGV0Tm9kZXM6IFRyaXBsZTxCSVAzMkludGVyZmFjZT4pOiBiaWdpbnQge1xuICBjb25zdCBpbmRpY2VzID0gZmluZFdhbGxldE91dHB1dEluZGljZXMocHNidCwgcm9vdFdhbGxldE5vZGVzKTtcbiAgY29uc3QgdHhPdXRwdXRzID0gcHNidC50eE91dHB1dHM7XG4gIHJldHVybiBpbmRpY2VzLnJlZHVjZSgoc3VtLCBpKSA9PiBzdW0gKyB0eE91dHB1dHNbaV0udmFsdWUsIEJpZ0ludCgwKSk7XG59XG5cbi8qKlxuICogRmluZHMgaW5kaWNlcyBvZiBhbGwgaW50ZXJuYWwgb3V0cHV0cyBpbiBhIFBTQlQsIGlkZW50aWZpZWQgYXMgb3V0cHV0cyBiZWxvbmdpbmcgdG8gdGhlIHdhbGxldCdzIHJvb3Qgbm9kZXMgd2l0aGluIHRoZSBQU0JULlxuICogQHBhcmFtIHBzYnQgLSBUaGUgUFNCVCBjb250YWluaW5nIHRoZSB3YWxsZXQncyByb290IG5vZGVzIGFzIGluZGljYXRlZCBieSBnbG9iYWwgWHB1YnMuXG4gKiBAcmV0dXJucyBBbiBhcnJheSBvZiBpbmRpY2VzIG9mIGludGVybmFsIG91dHB1dHMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmaW5kSW50ZXJuYWxPdXRwdXRJbmRpY2VzKHBzYnQ6IFV0eG9Qc2J0KTogbnVtYmVyW10ge1xuICBjb25zdCByb290Tm9kZXMgPSBnZXRTb3J0ZWRSb290Tm9kZXMocHNidCk7XG4gIHJldHVybiBmaW5kV2FsbGV0T3V0cHV0SW5kaWNlcyhwc2J0LCByb290Tm9kZXMpO1xufVxuXG4vKipcbiAqIENhbGN1bGF0ZXMgdGhlIHRvdGFsIGFtb3VudCBvZiBhbGwgaW50ZXJuYWwgb3V0cHV0cyBpbiBhIFBTQlQsIGlkZW50aWZpZWQgYXMgb3V0cHV0cyBiZWxvbmdpbmcgdG8gdGhlIHdhbGxldCdzIHJvb3Qgbm9kZXMgd2l0aGluIHRoZSBQU0JULlxuICogQHBhcmFtIHBzYnQgLSBUaGUgUFNCVCBjb250YWluaW5nIHRoZSB3YWxsZXQncyByb290IG5vZGVzIGFzIGluZGljYXRlZCBieSBnbG9iYWwgWHB1YnMuXG4gKiBAcmV0dXJucyBUaGUgdG90YWwgYW1vdW50IG9mIGludGVybmFsIG91dHB1dHMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRUb3RhbEFtb3VudE9mSW50ZXJuYWxPdXRwdXRzKHBzYnQ6IFV0eG9Qc2J0KTogYmlnaW50IHtcbiAgY29uc3Qgcm9vdE5vZGVzID0gZ2V0U29ydGVkUm9vdE5vZGVzKHBzYnQpO1xuICByZXR1cm4gZ2V0VG90YWxBbW91bnRPZldhbGxldE91dHB1dHMocHNidCwgcm9vdE5vZGVzKTtcbn1cbiJdfQ==