@tomo-inc/ledger-bitcoin-babylon
Version:
Ledger Hardware Wallet Babylon Application Client
629 lines • 55.3 kB
JavaScript
"use strict";
/* eslint-disable @typescript-eslint/no-non-null-assertion */
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.PsbtV2 = exports.NoSuchEntry = exports.psbtOut = exports.psbtIn = exports.psbtGlobal = void 0;
const bjs = __importStar(require("bitcoinjs-lib"));
const buffertools_1 = require("./buffertools");
const varint_1 = require("./varint");
var psbtGlobal;
(function (psbtGlobal) {
psbtGlobal[psbtGlobal["UNSIGNED_TX"] = 0] = "UNSIGNED_TX";
psbtGlobal[psbtGlobal["XPUB"] = 1] = "XPUB";
psbtGlobal[psbtGlobal["TX_VERSION"] = 2] = "TX_VERSION";
psbtGlobal[psbtGlobal["FALLBACK_LOCKTIME"] = 3] = "FALLBACK_LOCKTIME";
psbtGlobal[psbtGlobal["INPUT_COUNT"] = 4] = "INPUT_COUNT";
psbtGlobal[psbtGlobal["OUTPUT_COUNT"] = 5] = "OUTPUT_COUNT";
psbtGlobal[psbtGlobal["TX_MODIFIABLE"] = 6] = "TX_MODIFIABLE";
psbtGlobal[psbtGlobal["VERSION"] = 251] = "VERSION";
})(psbtGlobal = exports.psbtGlobal || (exports.psbtGlobal = {}));
var psbtIn;
(function (psbtIn) {
psbtIn[psbtIn["NON_WITNESS_UTXO"] = 0] = "NON_WITNESS_UTXO";
psbtIn[psbtIn["WITNESS_UTXO"] = 1] = "WITNESS_UTXO";
psbtIn[psbtIn["PARTIAL_SIG"] = 2] = "PARTIAL_SIG";
psbtIn[psbtIn["SIGHASH_TYPE"] = 3] = "SIGHASH_TYPE";
psbtIn[psbtIn["REDEEM_SCRIPT"] = 4] = "REDEEM_SCRIPT";
psbtIn[psbtIn["WITNESS_SCRIPT"] = 5] = "WITNESS_SCRIPT";
psbtIn[psbtIn["BIP32_DERIVATION"] = 6] = "BIP32_DERIVATION";
psbtIn[psbtIn["FINAL_SCRIPTSIG"] = 7] = "FINAL_SCRIPTSIG";
psbtIn[psbtIn["FINAL_SCRIPTWITNESS"] = 8] = "FINAL_SCRIPTWITNESS";
psbtIn[psbtIn["PREVIOUS_TXID"] = 14] = "PREVIOUS_TXID";
psbtIn[psbtIn["OUTPUT_INDEX"] = 15] = "OUTPUT_INDEX";
psbtIn[psbtIn["SEQUENCE"] = 16] = "SEQUENCE";
psbtIn[psbtIn["TAP_KEY_SIG"] = 19] = "TAP_KEY_SIG";
psbtIn[psbtIn["TAP_BIP32_DERIVATION"] = 22] = "TAP_BIP32_DERIVATION";
})(psbtIn = exports.psbtIn || (exports.psbtIn = {}));
var psbtOut;
(function (psbtOut) {
psbtOut[psbtOut["REDEEM_SCRIPT"] = 0] = "REDEEM_SCRIPT";
psbtOut[psbtOut["WITNESS_SCRIPT"] = 1] = "WITNESS_SCRIPT";
psbtOut[psbtOut["BIP_32_DERIVATION"] = 2] = "BIP_32_DERIVATION";
psbtOut[psbtOut["AMOUNT"] = 3] = "AMOUNT";
psbtOut[psbtOut["SCRIPT"] = 4] = "SCRIPT";
psbtOut[psbtOut["TAP_BIP32_DERIVATION"] = 7] = "TAP_BIP32_DERIVATION";
})(psbtOut = exports.psbtOut || (exports.psbtOut = {}));
const PSBT_MAGIC_BYTES = Buffer.from([0x70, 0x73, 0x62, 0x74, 0xff]);
class NoSuchEntry extends Error {
}
exports.NoSuchEntry = NoSuchEntry;
/**
* Implements Partially Signed Bitcoin Transaction version 2, BIP370, as
* documented at https://github.com/bitcoin/bips/blob/master/bip-0370.mediawiki
* and https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki
*
* A psbt is a data structure that can carry all relevant information about a
* transaction through all stages of the signing process. From constructing an
* unsigned transaction to extracting the final serialized transaction ready for
* broadcast.
*
* This implementation is limited to what's needed in ledgerjs to carry out its
* duties, which means that support for features like multisig or taproot script
* path spending are not implemented. Specifically, it supports p2pkh,
* p2wpkhWrappedInP2sh, p2wpkh and p2tr key path spending.
*
* This class is made purposefully dumb, so it's easy to add support for
* complemantary fields as needed in the future.
*/
class PsbtV2 {
constructor() {
this.globalMap = new Map();
this.inputMaps = [];
this.outputMaps = [];
}
setGlobalTxVersion(version) {
this.setGlobal(psbtGlobal.TX_VERSION, uint32LE(version));
}
getGlobalTxVersion() {
return this.getGlobal(psbtGlobal.TX_VERSION).readUInt32LE(0);
}
setGlobalFallbackLocktime(locktime) {
this.setGlobal(psbtGlobal.FALLBACK_LOCKTIME, uint32LE(locktime));
}
getGlobalFallbackLocktime() {
var _a;
return (_a = this.getGlobalOptional(psbtGlobal.FALLBACK_LOCKTIME)) === null || _a === void 0 ? void 0 : _a.readUInt32LE(0);
}
setGlobalInputCount(inputCount) {
this.setGlobal(psbtGlobal.INPUT_COUNT, varint(inputCount));
}
getGlobalInputCount() {
return fromVarint(this.getGlobal(psbtGlobal.INPUT_COUNT));
}
setGlobalOutputCount(outputCount) {
this.setGlobal(psbtGlobal.OUTPUT_COUNT, varint(outputCount));
}
getGlobalOutputCount() {
return fromVarint(this.getGlobal(psbtGlobal.OUTPUT_COUNT));
}
setGlobalTxModifiable(byte) {
this.setGlobal(psbtGlobal.TX_MODIFIABLE, byte);
}
getGlobalTxModifiable() {
return this.getGlobalOptional(psbtGlobal.TX_MODIFIABLE);
}
setGlobalPsbtVersion(psbtVersion) {
this.setGlobal(psbtGlobal.VERSION, uint32LE(psbtVersion));
}
getGlobalPsbtVersion() {
return this.getGlobal(psbtGlobal.VERSION).readUInt32LE(0);
}
setInputNonWitnessUtxo(inputIndex, transaction) {
this.setInput(inputIndex, psbtIn.NON_WITNESS_UTXO, b(), transaction);
}
getInputNonWitnessUtxo(inputIndex) {
return this.getInputOptional(inputIndex, psbtIn.NON_WITNESS_UTXO, b());
}
setInputWitnessUtxo(inputIndex, amount, scriptPubKey) {
const buf = new buffertools_1.BufferWriter();
buf.writeSlice(uint64LE(amount));
buf.writeVarSlice(scriptPubKey);
this.setInput(inputIndex, psbtIn.WITNESS_UTXO, b(), buf.buffer());
}
getInputWitnessUtxo(inputIndex) {
const utxo = this.getInputOptional(inputIndex, psbtIn.WITNESS_UTXO, b());
if (!utxo)
return undefined;
const buf = new buffertools_1.BufferReader(utxo);
return {
amount: (0, buffertools_1.unsafeFrom64bitLE)(buf.readSlice(8)),
scriptPubKey: buf.readVarSlice()
};
}
setInputPartialSig(inputIndex, pubkey, signature) {
this.setInput(inputIndex, psbtIn.PARTIAL_SIG, pubkey, signature);
}
getInputPartialSig(inputIndex, pubkey) {
return this.getInputOptional(inputIndex, psbtIn.PARTIAL_SIG, pubkey);
}
setInputSighashType(inputIndex, sigHashtype) {
this.setInput(inputIndex, psbtIn.SIGHASH_TYPE, b(), uint32LE(sigHashtype));
}
getInputSighashType(inputIndex) {
const result = this.getInputOptional(inputIndex, psbtIn.SIGHASH_TYPE, b());
if (!result)
return undefined;
return result.readUInt32LE(0);
}
setInputRedeemScript(inputIndex, redeemScript) {
this.setInput(inputIndex, psbtIn.REDEEM_SCRIPT, b(), redeemScript);
}
getInputRedeemScript(inputIndex) {
return this.getInputOptional(inputIndex, psbtIn.REDEEM_SCRIPT, b());
}
setInputWitnessScript(inputIndex, witnessScript) {
this.setInput(inputIndex, psbtIn.WITNESS_SCRIPT, b(), witnessScript);
}
getInputWitnessScript(inputIndex) {
return this.getInputOptional(inputIndex, psbtIn.WITNESS_SCRIPT, b());
}
setInputBip32Derivation(inputIndex, pubkey, masterFingerprint, path) {
if (pubkey.length != 33)
throw new Error('Invalid pubkey length: ' + pubkey.length);
this.setInput(inputIndex, psbtIn.BIP32_DERIVATION, pubkey, this.encodeBip32Derivation(masterFingerprint, path));
}
getInputBip32Derivation(inputIndex, pubkey) {
const buf = this.getInputOptional(inputIndex, psbtIn.BIP32_DERIVATION, pubkey);
if (!buf)
return undefined;
return this.decodeBip32Derivation(buf);
}
setInputFinalScriptsig(inputIndex, scriptSig) {
this.setInput(inputIndex, psbtIn.FINAL_SCRIPTSIG, b(), scriptSig);
}
getInputFinalScriptsig(inputIndex) {
return this.getInputOptional(inputIndex, psbtIn.FINAL_SCRIPTSIG, b());
}
setInputFinalScriptwitness(inputIndex, scriptWitness) {
this.setInput(inputIndex, psbtIn.FINAL_SCRIPTWITNESS, b(), scriptWitness);
}
getInputFinalScriptwitness(inputIndex) {
return this.getInput(inputIndex, psbtIn.FINAL_SCRIPTWITNESS, b());
}
setInputPreviousTxId(inputIndex, txid) {
this.setInput(inputIndex, psbtIn.PREVIOUS_TXID, b(), txid);
}
getInputPreviousTxid(inputIndex) {
return this.getInput(inputIndex, psbtIn.PREVIOUS_TXID, b());
}
setInputOutputIndex(inputIndex, outputIndex) {
this.setInput(inputIndex, psbtIn.OUTPUT_INDEX, b(), uint32LE(outputIndex));
}
getInputOutputIndex(inputIndex) {
return this.getInput(inputIndex, psbtIn.OUTPUT_INDEX, b()).readUInt32LE(0);
}
setInputSequence(inputIndex, sequence) {
this.setInput(inputIndex, psbtIn.SEQUENCE, b(), uint32LE(sequence));
}
getInputSequence(inputIndex) {
var _a, _b;
return ((_b = (_a = this.getInputOptional(inputIndex, psbtIn.SEQUENCE, b())) === null || _a === void 0 ? void 0 : _a.readUInt32LE(0)) !== null && _b !== void 0 ? _b : 0xffffffff);
}
setInputTapKeySig(inputIndex, sig) {
this.setInput(inputIndex, psbtIn.TAP_KEY_SIG, b(), sig);
}
getInputTapKeySig(inputIndex) {
return this.getInputOptional(inputIndex, psbtIn.TAP_KEY_SIG, b());
}
setInputTapBip32Derivation(inputIndex, pubkey, hashes, masterFingerprint, path) {
if (pubkey.length != 32)
throw new Error('Invalid pubkey length: ' + pubkey.length);
const buf = this.encodeTapBip32Derivation(hashes, masterFingerprint, path);
this.setInput(inputIndex, psbtIn.TAP_BIP32_DERIVATION, pubkey, buf);
}
getInputTapBip32Derivation(inputIndex, pubkey) {
const buf = this.getInput(inputIndex, psbtIn.TAP_BIP32_DERIVATION, pubkey);
return this.decodeTapBip32Derivation(buf);
}
getInputKeyDatas(inputIndex, keyType) {
return this.getKeyDatas(this.inputMaps[inputIndex], keyType);
}
setOutputRedeemScript(outputIndex, redeemScript) {
this.setOutput(outputIndex, psbtOut.REDEEM_SCRIPT, b(), redeemScript);
}
getOutputRedeemScript(outputIndex) {
return this.getOutput(outputIndex, psbtOut.REDEEM_SCRIPT, b());
}
setOutputBip32Derivation(outputIndex, pubkey, masterFingerprint, path) {
this.setOutput(outputIndex, psbtOut.BIP_32_DERIVATION, pubkey, this.encodeBip32Derivation(masterFingerprint, path));
}
getOutputBip32Derivation(outputIndex, pubkey) {
const buf = this.getOutput(outputIndex, psbtOut.BIP_32_DERIVATION, pubkey);
return this.decodeBip32Derivation(buf);
}
setOutputAmount(outputIndex, amount) {
this.setOutput(outputIndex, psbtOut.AMOUNT, b(), uint64LE(amount));
}
getOutputAmount(outputIndex) {
const buf = this.getOutput(outputIndex, psbtOut.AMOUNT, b());
return (0, buffertools_1.unsafeFrom64bitLE)(buf);
}
setOutputScript(outputIndex, scriptPubKey) {
this.setOutput(outputIndex, psbtOut.SCRIPT, b(), scriptPubKey);
}
getOutputScript(outputIndex) {
return this.getOutput(outputIndex, psbtOut.SCRIPT, b());
}
setOutputTapBip32Derivation(outputIndex, pubkey, hashes, fingerprint, path) {
const buf = this.encodeTapBip32Derivation(hashes, fingerprint, path);
this.setOutput(outputIndex, psbtOut.TAP_BIP32_DERIVATION, pubkey, buf);
}
getOutputTapBip32Derivation(outputIndex, pubkey) {
const buf = this.getOutput(outputIndex, psbtOut.TAP_BIP32_DERIVATION, pubkey);
return this.decodeTapBip32Derivation(buf);
}
deleteInputEntries(inputIndex, keyTypes) {
const map = this.inputMaps[inputIndex];
map.forEach((_v, k, m) => {
if (this.isKeyType(k, keyTypes)) {
m.delete(k);
}
});
}
copy(to) {
this.copyMap(this.globalMap, to.globalMap);
this.copyMaps(this.inputMaps, to.inputMaps);
this.copyMaps(this.outputMaps, to.outputMaps);
}
copyMaps(from, to) {
from.forEach((m, index) => {
const to_index = new Map();
this.copyMap(m, to_index);
to[index] = to_index;
});
}
copyMap(from, to) {
from.forEach((v, k) => to.set(k, Buffer.from(v)));
}
serialize() {
const buf = new buffertools_1.BufferWriter();
buf.writeSlice(PSBT_MAGIC_BYTES);
serializeMap(buf, this.globalMap);
this.inputMaps.forEach((map) => {
serializeMap(buf, map);
});
this.outputMaps.forEach((map) => {
serializeMap(buf, map);
});
return buf.buffer();
}
deserialize(psbt) {
const buf = new buffertools_1.BufferReader(psbt);
if (!buf.readSlice(5).equals(PSBT_MAGIC_BYTES)) {
throw new Error('Invalid magic bytes');
}
while (this.readKeyPair(this.globalMap, buf))
;
let psbtVersion;
try {
psbtVersion = this.getGlobalPsbtVersion();
}
catch (_a) {
psbtVersion = 0;
}
if (psbtVersion !== 0 && psbtVersion !== 2)
throw new Error("Only PSBTs of version 0 or 2 are supported");
let nInputs;
let nOutputs;
if (psbtVersion == 0) {
// if PSBTv0, we parse the PSBT_GLOBAL_UNSIGNED_TX field
const txRaw = this.getGlobal(psbtGlobal.UNSIGNED_TX);
const tx = bjs.Transaction.fromBuffer(txRaw);
nInputs = tx.ins.length;
nOutputs = tx.outs.length;
}
else {
// if PSBTv2, we already have the counts
nInputs = this.getGlobalInputCount();
nOutputs = this.getGlobalOutputCount();
}
for (let i = 0; i < nInputs; i++) {
this.inputMaps[i] = new Map();
while (this.readKeyPair(this.inputMaps[i], buf))
;
}
for (let i = 0; i < nOutputs; i++) {
this.outputMaps[i] = new Map();
while (this.readKeyPair(this.outputMaps[i], buf))
;
}
this.normalizeToV2();
}
normalizeToV2() {
var _a;
// if the psbt is a PsbtV0, convert it to PsbtV2 instead.
// throw an error for any version other than 0 or 2,
const psbtVersion = (_a = this.getGlobalOptional(psbtGlobal.VERSION)) === null || _a === void 0 ? void 0 : _a.readInt32LE(0);
if (psbtVersion === 2)
return;
else if (psbtVersion !== undefined) {
throw new Error('Invalid or unsupported value for PSBT_GLOBAL_VERSION');
}
// Convert PsbtV0 to PsbtV2 by parsing the PSBT_GLOBAL_UNSIGNED_TX field
// and filling in the corresponding fields.
const txRaw = this.getGlobal(psbtGlobal.UNSIGNED_TX);
const tx = bjs.Transaction.fromBuffer(txRaw);
this.setGlobalPsbtVersion(2);
this.setGlobalTxVersion(tx.version);
this.setGlobalFallbackLocktime(tx.locktime);
this.setGlobalInputCount(tx.ins.length);
this.setGlobalOutputCount(tx.outs.length);
for (let i = 0; i < tx.ins.length; i++) {
this.setInputPreviousTxId(i, tx.ins[i].hash);
this.setInputOutputIndex(i, tx.ins[i].index);
this.setInputSequence(i, tx.ins[i].sequence);
}
for (let i = 0; i < tx.outs.length; i++) {
this.setOutputAmount(i, tx.outs[i].value);
this.setOutputScript(i, tx.outs[i].script);
}
// PSBT_GLOBAL_UNSIGNED_TX must be removed in a valid PSBTv2
this.globalMap.delete(psbtGlobal.UNSIGNED_TX.toString(16).padStart(2, '0'));
}
/**
* Imports a BitcoinJS (bitcoinjs-lib) Psbt object.
* https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/ts_src/psbt.ts
*
* Prepares the fields required for signing a Psbt on a Ledger
* device. It should be used exclusively before calling
* `appClient.signPsbt()` and not as a general Psbt conversion method.
*
* Note: This method supports all the policies that the Ledger is able to
* sign, with the exception of taproot: tr(@0).
*/
fromBitcoinJS(psbtBJS) {
function isTaprootInput(input) {
let isP2TR;
try {
bjs.payments.p2tr({ output: input.witnessUtxo.script });
isP2TR = true;
}
catch (err) {
isP2TR = false;
}
return (input &&
!!(input.tapInternalKey ||
input.tapMerkleRoot ||
(input.tapLeafScript && input.tapLeafScript.length) ||
(input.tapBip32Derivation && input.tapBip32Derivation.length) ||
isP2TR));
}
this.setGlobalPsbtVersion(2);
this.setGlobalTxVersion(psbtBJS.version);
this.setGlobalInputCount(psbtBJS.data.inputs.length);
this.setGlobalOutputCount(psbtBJS.txOutputs.length);
if (psbtBJS.locktime !== undefined)
this.setGlobalFallbackLocktime(psbtBJS.locktime);
psbtBJS.data.inputs.forEach((input, index) => {
if (isTaprootInput(input))
throw new Error(`Taproot inputs not supported`);
this.setInputPreviousTxId(index, psbtBJS.txInputs[index].hash);
if (psbtBJS.txInputs[index].sequence !== undefined)
this.setInputSequence(index, psbtBJS.txInputs[index].sequence);
this.setInputOutputIndex(index, psbtBJS.txInputs[index].index);
if (input.sighashType !== undefined)
this.setInputSighashType(index, input.sighashType);
if (input.nonWitnessUtxo)
this.setInputNonWitnessUtxo(index, input.nonWitnessUtxo);
if (input.witnessUtxo) {
this.setInputWitnessUtxo(index, input.witnessUtxo.value, input.witnessUtxo.script);
}
if (input.witnessScript)
this.setInputWitnessScript(index, input.witnessScript);
if (input.redeemScript)
this.setInputRedeemScript(index, input.redeemScript);
psbtBJS.data.inputs[index].bip32Derivation.forEach(derivation => {
if (!/^m\//i.test(derivation.path))
throw new Error(`Invalid input bip32 derivation`);
const pathArray = derivation.path
.replace(/m\//i, '')
.split('/')
.map(level => level.match(/['h]/i) ? parseInt(level) + 0x80000000 : Number(level));
this.setInputBip32Derivation(index, derivation.pubkey, derivation.masterFingerprint, pathArray);
});
});
psbtBJS.txOutputs.forEach((output, index) => {
this.setOutputAmount(index, output.value);
this.setOutputScript(index, output.script);
});
return this;
}
readKeyPair(map, buf) {
const keyLen = (0, varint_1.sanitizeBigintToNumber)(buf.readVarInt());
if (keyLen == 0) {
return false;
}
const keyType = buf.readUInt8();
const keyData = buf.readSlice(keyLen - 1);
const value = buf.readVarSlice();
set(map, keyType, keyData, value);
return true;
}
getKeyDatas(map, keyType) {
const result = [];
map.forEach((_v, k) => {
if (this.isKeyType(k, [keyType])) {
result.push(Buffer.from(k.substring(2), 'hex'));
}
});
return result;
}
isKeyType(hexKey, keyTypes) {
const keyType = Buffer.from(hexKey.substring(0, 2), 'hex').readUInt8(0);
return keyTypes.some((k) => k == keyType);
}
setGlobal(keyType, value) {
const key = new Key(keyType, Buffer.from([]));
this.globalMap.set(key.toString(), value);
}
getGlobal(keyType) {
return get(this.globalMap, keyType, b(), false);
}
getGlobalOptional(keyType) {
return get(this.globalMap, keyType, b(), true);
}
setInput(index, keyType, keyData, value) {
set(this.getMap(index, this.inputMaps), keyType, keyData, value);
}
getInput(index, keyType, keyData) {
return get(this.inputMaps[index], keyType, keyData, false);
}
getInputOptional(index, keyType, keyData) {
return get(this.inputMaps[index], keyType, keyData, true);
}
setOutput(index, keyType, keyData, value) {
set(this.getMap(index, this.outputMaps), keyType, keyData, value);
}
getOutput(index, keyType, keyData) {
return get(this.outputMaps[index], keyType, keyData, false);
}
getMap(index, maps) {
if (maps[index]) {
return maps[index];
}
return (maps[index] = new Map());
}
encodeBip32Derivation(masterFingerprint, path) {
const buf = new buffertools_1.BufferWriter();
this.writeBip32Derivation(buf, masterFingerprint, path);
return buf.buffer();
}
decodeBip32Derivation(buffer) {
const buf = new buffertools_1.BufferReader(buffer);
return this.readBip32Derivation(buf);
}
writeBip32Derivation(buf, masterFingerprint, path) {
buf.writeSlice(masterFingerprint);
path.forEach((element) => {
buf.writeUInt32(element);
});
}
readBip32Derivation(buf) {
const masterFingerprint = buf.readSlice(4);
const path = [];
while (buf.offset < buf.buffer.length) {
path.push(buf.readUInt32());
}
return { masterFingerprint, path };
}
encodeTapBip32Derivation(hashes, masterFingerprint, path) {
const buf = new buffertools_1.BufferWriter();
buf.writeVarInt(hashes.length);
hashes.forEach((h) => {
buf.writeSlice(h);
});
this.writeBip32Derivation(buf, masterFingerprint, path);
return buf.buffer();
}
decodeTapBip32Derivation(buffer) {
const buf = new buffertools_1.BufferReader(buffer);
const hashCount = (0, varint_1.sanitizeBigintToNumber)(buf.readVarInt());
const hashes = [];
for (let i = 0; i < hashCount; i++) {
hashes.push(buf.readSlice(32));
}
const deriv = this.readBip32Derivation(buf);
return Object.assign({ hashes }, deriv);
}
}
exports.PsbtV2 = PsbtV2;
function get(map, keyType, keyData, acceptUndefined) {
if (!map)
throw Error('No such map');
const key = new Key(keyType, keyData);
const value = map.get(key.toString());
if (!value) {
if (acceptUndefined) {
return undefined;
}
throw new NoSuchEntry(key.toString());
}
// Make sure to return a copy, to protect the underlying data.
return Buffer.from(value);
}
class Key {
constructor(keyType, keyData) {
this.keyType = keyType;
this.keyData = keyData;
}
toString() {
const buf = new buffertools_1.BufferWriter();
this.toBuffer(buf);
return buf.buffer().toString('hex');
}
serialize(buf) {
buf.writeVarInt(1 + this.keyData.length);
this.toBuffer(buf);
}
toBuffer(buf) {
buf.writeUInt8(this.keyType);
buf.writeSlice(this.keyData);
}
}
class KeyPair {
constructor(key, value) {
this.key = key;
this.value = value;
}
serialize(buf) {
this.key.serialize(buf);
buf.writeVarSlice(this.value);
}
}
function createKey(buf) {
return new Key(buf.readUInt8(0), buf.slice(1));
}
function serializeMap(buf, map) {
// serialize in lexicographical order of keys
for (let [key, value] of [...map].sort(([k1], [k2]) => k1.localeCompare(k2))) {
const keyPair = new KeyPair(createKey(Buffer.from(key, 'hex')), value);
keyPair.serialize(buf);
}
buf.writeUInt8(0);
}
function b() {
return Buffer.from([]);
}
function set(map, keyType, keyData, value) {
const key = new Key(keyType, keyData);
map.set(key.toString(), value);
}
function uint32LE(n) {
const buf = Buffer.alloc(4);
buf.writeUInt32LE(n, 0);
return buf;
}
function uint64LE(n) {
return (0, buffertools_1.unsafeTo64bitLE)(n);
}
function varint(n) {
const buf = new buffertools_1.BufferWriter();
buf.writeVarInt(n);
return buf.buffer();
}
function fromVarint(buf) {
return (0, varint_1.sanitizeBigintToNumber)(new buffertools_1.BufferReader(buf).readVarInt());
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHNidHYyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2xpYi9wc2J0djIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLDZEQUE2RDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFFN0QsbURBQXFDO0FBRXJDLCtDQUt1QjtBQUN2QixxQ0FBa0Q7QUFFbEQsSUFBWSxVQVNYO0FBVEQsV0FBWSxVQUFVO0lBQ3BCLHlEQUFrQixDQUFBO0lBQ2xCLDJDQUFXLENBQUE7SUFDWCx1REFBaUIsQ0FBQTtJQUNqQixxRUFBd0IsQ0FBQTtJQUN4Qix5REFBa0IsQ0FBQTtJQUNsQiwyREFBbUIsQ0FBQTtJQUNuQiw2REFBb0IsQ0FBQTtJQUNwQixtREFBYyxDQUFBO0FBQ2hCLENBQUMsRUFUVyxVQUFVLEdBQVYsa0JBQVUsS0FBVixrQkFBVSxRQVNyQjtBQUNELElBQVksTUFlWDtBQWZELFdBQVksTUFBTTtJQUNoQiwyREFBdUIsQ0FBQTtJQUN2QixtREFBbUIsQ0FBQTtJQUNuQixpREFBa0IsQ0FBQTtJQUNsQixtREFBbUIsQ0FBQTtJQUNuQixxREFBb0IsQ0FBQTtJQUNwQix1REFBcUIsQ0FBQTtJQUNyQiwyREFBdUIsQ0FBQTtJQUN2Qix5REFBc0IsQ0FBQTtJQUN0QixpRUFBMEIsQ0FBQTtJQUMxQixzREFBb0IsQ0FBQTtJQUNwQixvREFBbUIsQ0FBQTtJQUNuQiw0Q0FBZSxDQUFBO0lBQ2Ysa0RBQWtCLENBQUE7SUFDbEIsb0VBQTJCLENBQUE7QUFDN0IsQ0FBQyxFQWZXLE1BQU0sR0FBTixjQUFNLEtBQU4sY0FBTSxRQWVqQjtBQUNELElBQVksT0FPWDtBQVBELFdBQVksT0FBTztJQUNqQix1REFBb0IsQ0FBQTtJQUNwQix5REFBcUIsQ0FBQTtJQUNyQiwrREFBd0IsQ0FBQTtJQUN4Qix5Q0FBYSxDQUFBO0lBQ2IseUNBQWEsQ0FBQTtJQUNiLHFFQUEyQixDQUFBO0FBQzdCLENBQUMsRUFQVyxPQUFPLEdBQVAsZUFB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