@leather.io/bitcoin 0.19.8 → 0.19.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
 
2
- > @leather.io/bitcoin@0.19.8 build /home/runner/work/mono/mono/packages/bitcoin
2
+ > @leather.io/bitcoin@0.19.10 build /home/runner/work/mono/mono/packages/bitcoin
3
3
  > tsup
4
4
 
5
5
  CLI Building entry: src/index.ts
@@ -8,9 +8,9 @@ CLI tsup v8.1.0
8
8
  CLI Using tsup config: /home/runner/work/mono/mono/packages/bitcoin/tsup.config.ts
9
9
  CLI Target: es2022
10
10
  ESM Build start
11
- ESM dist/index.js 49.93 KB
12
- ESM dist/index.js.map 97.61 KB
13
- ESM ⚡️ Build success in 77ms
11
+ ESM dist/index.js 49.49 KB
12
+ ESM dist/index.js.map 97.42 KB
13
+ ESM ⚡️ Build success in 84ms
14
14
  DTS Build start
15
- DTS ⚡️ Build success in 4515ms
16
- DTS dist/index.d.ts 23.04 KB
15
+ DTS ⚡️ Build success in 4310ms
16
+ DTS dist/index.d.ts 22.99 KB
package/CHANGELOG.md CHANGED
@@ -382,6 +382,33 @@
382
382
  * devDependencies
383
383
  * @leather.io/rpc bumped to 2.4.1
384
384
 
385
+ ## [0.19.10](https://github.com/leather-io/mono/compare/@leather.io/bitcoin-v0.19.9...@leather.io/bitcoin-v0.19.10) (2025-01-07)
386
+
387
+
388
+ ### Bug Fixes
389
+
390
+ * address all occurrences triggering no-unused-vars ([6708dea](https://github.com/leather-io/mono/commit/6708deaf298fa4203dbfc7304bd75d0faa7a64b5))
391
+ * safely fix or silence few surfaced eslint errors until addressed ([f0bb35b](https://github.com/leather-io/mono/commit/f0bb35bdfe97486bebca94d5cd3451872dae5a3d))
392
+
393
+
394
+ ### Dependencies
395
+
396
+ * The following workspace dependencies were updated
397
+ * dependencies
398
+ * @leather.io/constants bumped to 0.15.3
399
+ * @leather.io/crypto bumped to 1.6.26
400
+ * @leather.io/models bumped to 0.24.3
401
+ * @leather.io/utils bumped to 0.22.6
402
+ * devDependencies
403
+ * @leather.io/rpc bumped to 2.4.2
404
+
405
+ ## [0.19.9](https://github.com/leather-io/mono/compare/@leather.io/bitcoin-v0.19.8...@leather.io/bitcoin-v0.19.9) (2024-12-25)
406
+
407
+
408
+ ### Bug Fixes
409
+
410
+ * psbt error and controller handling ([34b9287](https://github.com/leather-io/mono/commit/34b9287bfadb16fee8bdcb8444243a8737017965))
411
+
385
412
  ## [0.19.6](https://github.com/leather-io/mono/compare/@leather.io/bitcoin-v0.19.5...@leather.io/bitcoin-v0.19.6) (2024-12-13)
386
413
 
387
414
 
package/dist/index.d.ts CHANGED
@@ -211,7 +211,7 @@ declare function btcSignerLibPaymentTypeToPaymentTypeMap(payment: BtcSignerLibPa
211
211
  declare function isBtcSignerLibPaymentType(payment: string): payment is BtcSignerLibPaymentTypeIdentifers;
212
212
  declare function parseKnownPaymentType(payment: BtcSignerLibPaymentTypeIdentifers | PaymentTypes): PaymentTypes;
213
213
  type PaymentTypeMap<T> = Record<PaymentTypes, T>;
214
- declare function whenPaymentType(mode: PaymentTypes | BtcSignerLibPaymentTypeIdentifers): <T extends unknown>(paymentMap: PaymentTypeMap<T>) => T;
214
+ declare function whenPaymentType(mode: PaymentTypes | BtcSignerLibPaymentTypeIdentifers): <T>(paymentMap: PaymentTypeMap<T>) => T;
215
215
  type SupportedPaymentType = 'p2wpkh' | 'p2tr';
216
216
  type SupportedPaymentTypeMap<T> = Record<SupportedPaymentType, T>;
217
217
  declare function whenSupportedPaymentType(mode: SupportedPaymentType): <T>(paymentMap: SupportedPaymentTypeMap<T>) => T;
@@ -363,22 +363,19 @@ interface GenerateBitcoinUnsignedTransactionArgs {
363
363
  recipients: CoinSelectionRecipient[];
364
364
  utxos: CoinSelectionUtxo[];
365
365
  }
366
- declare function generateBitcoinUnsignedTransactionNativeSegwit({ feeRate, isSendingMax, payerAddress, payerPublicKey, bip32Derivation, network, recipients, utxos, }: GenerateBitcoinUnsignedTransactionArgs): Promise<{
366
+ declare function generateBitcoinUnsignedTransactionNativeSegwit({ feeRate, isSendingMax, payerAddress, payerPublicKey, bip32Derivation, network, recipients, utxos, }: GenerateBitcoinUnsignedTransactionArgs): {
367
367
  tx: btc.Transaction;
368
368
  hex: string;
369
369
  psbt: Uint8Array;
370
370
  inputs: CoinSelectionUtxo[];
371
371
  fee: _leather_io_models.Money;
372
- } | null>;
372
+ };
373
373
 
374
- declare enum BitcoinErrorMessage {
375
- InsufficientFunds = "Insufficient funds",
376
- NoInputsToSign = "No inputs to sign",
377
- NoOutputsToSign = "No outputs to sign"
378
- }
379
374
  declare class BitcoinError extends Error {
380
- constructor(message: string);
375
+ message: BitcoinErrorKey;
376
+ constructor(message: BitcoinErrorKey);
381
377
  }
378
+ type BitcoinErrorKey = 'InvalidAddress' | 'InsufficientFunds' | 'NoInputsToSign' | 'NoOutputsToSign';
382
379
 
383
380
  declare function makeTaprootAccountDerivationPath(network: BitcoinNetworkModes, accountIndex: number): string;
384
381
  /** @deprecated Use makeTaprootAccountDerivationPath */
@@ -517,4 +514,4 @@ type RawPsbt = ReturnType<typeof RawPSBTV0.decode>;
517
514
  declare function getPsbtAsTransaction(psbt: string | Uint8Array): btc.Transaction;
518
515
  declare function getRawPsbt(psbt: string | Uint8Array): ReturnType<typeof RawPSBTV0.decode>;
519
516
 
520
- export { type AllowedSighashTypes, type BitcoinAccount, type BitcoinAccountKeychain, BitcoinError, BitcoinErrorMessage, type BitcoinFees, type BitcoinNativeSegwitPayer, type BitcoinPayer, type BitcoinPayerBase, type BitcoinPayerInfo, type BitcoinSigner, type BitcoinTaprootPayer, type BtcSignerDefaultBip32Derivation, type BtcSignerLibPaymentTypeIdentifers, type BtcSignerNetwork, type BtcSignerTapBip32Derivation, type CoinSelectionOutput, type CoinSelectionRecipient, type CoinSelectionUtxo, type DetermineUtxosForSpendArgs, type GenerateBitcoinUnsignedTransactionArgs, type GetBitcoinFeesArgs, type PaymentTypeMap, type PsbtInput, type PsbtOutput, type RawPsbt, type SupportedPaymentType, type SupportedPaymentTypeMap, type WithDerivePayer, bip322TransactionToSignValues, bitcoinNetworkModeToCoreNetworkMode, bitcoinNetworkToCoreNetworkMap, btcSignerLibPaymentTypeToPaymentTypeMap, calculateMaxBitcoinSpend, coinTypeMap, createNativeSegwitBitcoinJsSigner, createTaprootBitcoinJsSigner, createToSpendTx, createWalletIdDecoratedPath, decodeBitcoinTx, decodeCompressedWifPrivateKey, deriveAddressIndexKeychainFromAccount, deriveAddressIndexZeroFromAccount, deriveBitcoinPayerFromAccount, deriveBtcBip49SeedFromMnemonic, deriveNativeSegwitAccountFromRootKeychain, deriveNativeSegwitReceiveAddressIndexZero, deriveRootBtcKeychain, deriveTaprootAccount, deriveTaprootReceiveAddressIndexZero, determineUtxosForSpend, determineUtxosForSpendAll, ecPairFromPrivateKey, ecdsaPublicKeyLength, ecdsaPublicKeyToSchnorr, encodeMessageWitnessData, extractExtendedPublicKeyFromPolicy, extractRequiredKeyOrigins, filterUneconomicalUtxos, generateBitcoinUnsignedTransactionNativeSegwit, getAddressFromOutScript, getBitcoinCoinTypeIndexByNetwork, getBitcoinFees, getBitcoinInputAddress, getBitcoinInputValue, getBitcoinJsLibNetworkConfigByMode, getBitcoinTransactionFee, getBtcSignerLibNetworkConfigByMode, getHdKeyVersionsFromNetwork, getInputPaymentType, getNativeSegwitAccountDerivationPath, getNativeSegwitAddress, getNativeSegwitAddressIndexDerivationPath, getNativeSegwitPaymentFromAddressIndex, getParsedInputs, getParsedOutputs, getPsbtAsTransaction, getPsbtDetails, getPsbtTotals, getPsbtTxInputs, getPsbtTxOutputs, getRawPsbt, getSizeInfo, getSpendableAmount, getTaprootAccountDerivationPath, getTaprootAddress, getTaprootAddressIndexDerivationPath, getTaprootPayment, getTaprootPaymentFromAddressIndex, getUtxoTotal, hashBip322Message, inferNetworkFromAddress, inferNetworkFromPath, inferPaymentTypeFromAddress, inferPaymentTypeFromPath, initBitcoinAccount, initializeBitcoinAccountKeychainFromDescriptor, isBtcSignerLibPaymentType, isSupportedMessageSigningPaymentType, lookUpLedgerKeysByPath, lookupDerivationByAddress, makeNativeSegwitAccountDerivationPath, makeNativeSegwitAddressIndexDerivationPath, makePayToScriptHashAddress, makePayToScriptHashAddressBytes, makePayToScriptHashKeyHash, makeTaprootAccountDerivationPath, makeTaprootAddressIndexDerivationPath, mnemonicToRootNode, parseKnownPaymentType, payToScriptHashTestnetPrefix, payerToBip32Derivation, payerToTapBip32Derivation, paymentTypeMap, publicKeyToPayToScriptHashAddress, serializeKeyOrigin, signBip322MessageSimple, toXOnly, tweakSigner, whenBitcoinNetwork, whenPaymentType, whenSupportedPaymentType };
517
+ export { type AllowedSighashTypes, type BitcoinAccount, type BitcoinAccountKeychain, BitcoinError, type BitcoinErrorKey, type BitcoinFees, type BitcoinNativeSegwitPayer, type BitcoinPayer, type BitcoinPayerBase, type BitcoinPayerInfo, type BitcoinSigner, type BitcoinTaprootPayer, type BtcSignerDefaultBip32Derivation, type BtcSignerLibPaymentTypeIdentifers, type BtcSignerNetwork, type BtcSignerTapBip32Derivation, type CoinSelectionOutput, type CoinSelectionRecipient, type CoinSelectionUtxo, type DetermineUtxosForSpendArgs, type GenerateBitcoinUnsignedTransactionArgs, type GetBitcoinFeesArgs, type PaymentTypeMap, type PsbtInput, type PsbtOutput, type RawPsbt, type SupportedPaymentType, type SupportedPaymentTypeMap, type WithDerivePayer, bip322TransactionToSignValues, bitcoinNetworkModeToCoreNetworkMode, bitcoinNetworkToCoreNetworkMap, btcSignerLibPaymentTypeToPaymentTypeMap, calculateMaxBitcoinSpend, coinTypeMap, createNativeSegwitBitcoinJsSigner, createTaprootBitcoinJsSigner, createToSpendTx, createWalletIdDecoratedPath, decodeBitcoinTx, decodeCompressedWifPrivateKey, deriveAddressIndexKeychainFromAccount, deriveAddressIndexZeroFromAccount, deriveBitcoinPayerFromAccount, deriveBtcBip49SeedFromMnemonic, deriveNativeSegwitAccountFromRootKeychain, deriveNativeSegwitReceiveAddressIndexZero, deriveRootBtcKeychain, deriveTaprootAccount, deriveTaprootReceiveAddressIndexZero, determineUtxosForSpend, determineUtxosForSpendAll, ecPairFromPrivateKey, ecdsaPublicKeyLength, ecdsaPublicKeyToSchnorr, encodeMessageWitnessData, extractExtendedPublicKeyFromPolicy, extractRequiredKeyOrigins, filterUneconomicalUtxos, generateBitcoinUnsignedTransactionNativeSegwit, getAddressFromOutScript, getBitcoinCoinTypeIndexByNetwork, getBitcoinFees, getBitcoinInputAddress, getBitcoinInputValue, getBitcoinJsLibNetworkConfigByMode, getBitcoinTransactionFee, getBtcSignerLibNetworkConfigByMode, getHdKeyVersionsFromNetwork, getInputPaymentType, getNativeSegwitAccountDerivationPath, getNativeSegwitAddress, getNativeSegwitAddressIndexDerivationPath, getNativeSegwitPaymentFromAddressIndex, getParsedInputs, getParsedOutputs, getPsbtAsTransaction, getPsbtDetails, getPsbtTotals, getPsbtTxInputs, getPsbtTxOutputs, getRawPsbt, getSizeInfo, getSpendableAmount, getTaprootAccountDerivationPath, getTaprootAddress, getTaprootAddressIndexDerivationPath, getTaprootPayment, getTaprootPaymentFromAddressIndex, getUtxoTotal, hashBip322Message, inferNetworkFromAddress, inferNetworkFromPath, inferPaymentTypeFromAddress, inferPaymentTypeFromPath, initBitcoinAccount, initializeBitcoinAccountKeychainFromDescriptor, isBtcSignerLibPaymentType, isSupportedMessageSigningPaymentType, lookUpLedgerKeysByPath, lookupDerivationByAddress, makeNativeSegwitAccountDerivationPath, makeNativeSegwitAddressIndexDerivationPath, makePayToScriptHashAddress, makePayToScriptHashAddressBytes, makePayToScriptHashKeyHash, makeTaprootAccountDerivationPath, makeTaprootAddressIndexDerivationPath, mnemonicToRootNode, parseKnownPaymentType, payToScriptHashTestnetPrefix, payerToBip32Derivation, payerToTapBip32Derivation, paymentTypeMap, publicKeyToPayToScriptHashAddress, serializeKeyOrigin, signBip322MessageSimple, toXOnly, tweakSigner, whenBitcoinNetwork, whenPaymentType, whenSupportedPaymentType };
package/dist/index.js CHANGED
@@ -485,6 +485,7 @@ import { sumNumbers } from "@leather.io/utils";
485
485
 
486
486
  // src/btc-size-fee-estimator.ts
487
487
  import BigNumber from "bignumber.js";
488
+ import { assertUnreachable } from "@leather.io/utils";
488
489
  var BtcSizeFeeEstimator = class {
489
490
  P2PKH_IN_SIZE = 148;
490
491
  P2PKH_OUT_SIZE = 34;
@@ -683,6 +684,9 @@ var BtcSizeFeeEstimator = class {
683
684
  if (this.params.input_script === "p2sh-p2wsh") {
684
685
  inputSize += 32 + 3;
685
686
  }
687
+ break;
688
+ default:
689
+ assertUnreachable(this.params.input_script);
686
690
  }
687
691
  return {
688
692
  inputSize,
@@ -827,16 +831,12 @@ import { BTC_P2WPKH_DUST_AMOUNT as BTC_P2WPKH_DUST_AMOUNT2 } from "@leather.io/c
827
831
  import { createMoney as createMoney2, sumMoney } from "@leather.io/utils";
828
832
 
829
833
  // src/bitcoin-error.ts
830
- var BitcoinErrorMessage = /* @__PURE__ */ ((BitcoinErrorMessage2) => {
831
- BitcoinErrorMessage2["InsufficientFunds"] = "Insufficient funds";
832
- BitcoinErrorMessage2["NoInputsToSign"] = "No inputs to sign";
833
- BitcoinErrorMessage2["NoOutputsToSign"] = "No outputs to sign";
834
- return BitcoinErrorMessage2;
835
- })(BitcoinErrorMessage || {});
836
834
  var BitcoinError = class extends Error {
835
+ message;
837
836
  constructor(message) {
838
837
  super(message);
839
838
  this.name = "BitcoinError";
839
+ this.message = message;
840
840
  Object.setPrototypeOf(this, new.target.prototype);
841
841
  }
842
842
  };
@@ -848,8 +848,7 @@ function determineUtxosForSpendAll({
848
848
  utxos
849
849
  }) {
850
850
  recipients.forEach((recipient) => {
851
- if (!validate2(recipient.address))
852
- throw new Error("Cannot calculate spend of invalid address type");
851
+ if (!validate2(recipient.address)) throw new BitcoinError("InvalidAddress");
853
852
  });
854
853
  const filteredUtxos = filterUneconomicalUtxos({ utxos, feeRate, recipients });
855
854
  const sizeInfo = getSizeInfo({
@@ -871,15 +870,14 @@ function determineUtxosForSpendAll({
871
870
  }
872
871
  function determineUtxosForSpend({ feeRate, recipients, utxos }) {
873
872
  recipients.forEach((recipient) => {
874
- if (!validate2(recipient.address))
875
- throw new Error("Cannot calculate spend of invalid address type");
873
+ if (!validate2(recipient.address)) throw new BitcoinError("InvalidAddress");
876
874
  });
877
875
  const filteredUtxos = filterUneconomicalUtxos({
878
876
  utxos: utxos.sort((a, b) => b.value - a.value),
879
877
  feeRate,
880
878
  recipients
881
879
  });
882
- if (!filteredUtxos.length) throw new BitcoinError("Insufficient funds" /* InsufficientFunds */);
880
+ if (!filteredUtxos.length) throw new BitcoinError("InsufficientFunds");
883
881
  const amount = sumMoney(recipients.map((recipient) => recipient.amount));
884
882
  const neededUtxos = [filteredUtxos[0]];
885
883
  function estimateTransactionSize() {
@@ -898,7 +896,7 @@ function determineUtxosForSpend({ feeRate, recipients, utxos }) {
898
896
  }
899
897
  while (!hasSufficientUtxosForTx()) {
900
898
  const [nextUtxo] = getRemainingUnspentUtxos();
901
- if (!nextUtxo) throw new BitcoinError("Insufficient funds" /* InsufficientFunds */);
899
+ if (!nextUtxo) throw new BitcoinError("InsufficientFunds");
902
900
  neededUtxos.push(nextUtxo);
903
901
  }
904
902
  const fee = Math.ceil(
@@ -932,7 +930,7 @@ function getBitcoinTransactionFee({ isSendingMax, ...props }) {
932
930
  try {
933
931
  const { fee } = isSendingMax ? determineUtxosForSpendAll({ ...props }) : determineUtxosForSpend({ ...props });
934
932
  return fee;
935
- } catch (error) {
933
+ } catch {
936
934
  return null;
937
935
  }
938
936
  }
@@ -967,7 +965,7 @@ function getBitcoinFees({ feeRates, isSendingMax, recipients, utxos }) {
967
965
  // src/transactions/generate-unsigned-transaction.ts
968
966
  import { hexToBytes as hexToBytes3 } from "@noble/hashes/utils";
969
967
  import * as btc4 from "@scure/btc-signer";
970
- async function generateBitcoinUnsignedTransactionNativeSegwit({
968
+ function generateBitcoinUnsignedTransactionNativeSegwit({
971
969
  feeRate,
972
970
  isSendingMax,
973
971
  payerAddress,
@@ -977,37 +975,33 @@ async function generateBitcoinUnsignedTransactionNativeSegwit({
977
975
  recipients,
978
976
  utxos
979
977
  }) {
980
- try {
981
- const determineUtxosArgs = { feeRate, recipients, utxos };
982
- const { inputs, outputs, fee } = isSendingMax ? determineUtxosForSpendAll(determineUtxosArgs) : determineUtxosForSpend(determineUtxosArgs);
983
- if (!inputs.length) throw new BitcoinError("No inputs to sign" /* NoInputsToSign */);
984
- if (!outputs.length) throw new BitcoinError("No outputs to sign" /* NoOutputsToSign */);
985
- const tx = new btc4.Transaction();
986
- const p2wpkh3 = btc4.p2wpkh(hexToBytes3(payerPublicKey), network);
987
- for (const input of inputs) {
988
- tx.addInput({
989
- txid: input.txid,
990
- index: input.vout,
991
- sequence: 0,
992
- bip32Derivation,
993
- witnessUtxo: {
994
- // script = 0014 + pubKeyHash
995
- script: p2wpkh3.script,
996
- amount: BigInt(input.value)
997
- }
998
- });
999
- }
1000
- outputs.forEach((output) => {
1001
- if (!output.address) {
1002
- tx.addOutputAddress(payerAddress, BigInt(output.value), network);
1003
- return;
978
+ const determineUtxosArgs = { feeRate, recipients, utxos };
979
+ const { inputs, outputs, fee } = isSendingMax ? determineUtxosForSpendAll(determineUtxosArgs) : determineUtxosForSpend(determineUtxosArgs);
980
+ if (!inputs.length) throw new BitcoinError("NoInputsToSign");
981
+ if (!outputs.length) throw new BitcoinError("NoOutputsToSign");
982
+ const tx = new btc4.Transaction();
983
+ const p2wpkh3 = btc4.p2wpkh(hexToBytes3(payerPublicKey), network);
984
+ for (const input of inputs) {
985
+ tx.addInput({
986
+ txid: input.txid,
987
+ index: input.vout,
988
+ sequence: 0,
989
+ bip32Derivation,
990
+ witnessUtxo: {
991
+ // script = 0014 + pubKeyHash
992
+ script: p2wpkh3.script,
993
+ amount: BigInt(input.value)
1004
994
  }
1005
- tx.addOutputAddress(output.address, BigInt(output.value), network);
1006
995
  });
1007
- return { tx, hex: tx.hex, psbt: tx.toPSBT(), inputs, fee };
1008
- } catch (e) {
1009
- return null;
1010
996
  }
997
+ outputs.forEach((output) => {
998
+ if (!output.address) {
999
+ tx.addOutputAddress(payerAddress, BigInt(output.value), network);
1000
+ return;
1001
+ }
1002
+ tx.addOutputAddress(output.address, BigInt(output.value), network);
1003
+ });
1004
+ return { tx, hex: tx.hex, psbt: tx.toPSBT(), inputs, fee };
1011
1005
  }
1012
1006
 
1013
1007
  // src/bitcoin-signer.ts
@@ -1348,7 +1342,6 @@ function getPsbtDetails({
1348
1342
  }
1349
1343
  export {
1350
1344
  BitcoinError,
1351
- BitcoinErrorMessage,
1352
1345
  bip322TransactionToSignValues,
1353
1346
  bitcoinNetworkModeToCoreNetworkMode,
1354
1347
  bitcoinNetworkToCoreNetworkMap,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/bip322/bip322-utils.ts","../src/bitcoin.utils.ts","../src/bitcoin.network.ts","../src/p2tr-address-gen.ts","../src/p2wpkh-address-gen.ts","../src/bip322/sign-message-bip322-bitcoinjs.ts","../src/coin-selection/calculate-max-spend.ts","../src/coin-selection/coin-selection.utils.ts","../src/btc-size-fee-estimator.ts","../src/coin-selection/coin-selection.ts","../src/bitcoin-error.ts","../src/fees/bitcoin-fees.ts","../src/transactions/generate-unsigned-transaction.ts","../src/bitcoin-signer.ts","../src/p2wsh-p2sh-address-gen.ts","../src/lookup-derivation-by-address.ts","../src/psbt/psbt-totals.ts","../src/psbt/psbt-inputs.ts","../src/psbt/psbt-outputs.ts","../src/psbt/psbt-details.ts","../src/psbt/utils.ts"],"sourcesContent":["import ecc from '@bitcoinerlab/secp256k1';\nimport { sha256 } from '@noble/hashes/sha256';\nimport { hexToBytes, utf8ToBytes } from '@stacks/common';\nimport * as bitcoin from 'bitcoinjs-lib';\nimport { ECPairFactory } from 'ecpair';\nimport { encode } from 'varuint-bitcoin';\n\nimport { PaymentTypes } from '@leather.io/rpc';\nimport { isString } from '@leather.io/utils';\n\nimport { toXOnly } from '../bitcoin.utils';\n\nconst bip322MessageTag = 'BIP0322-signed-message';\n\nconst ECPair = ECPairFactory(ecc);\nbitcoin.initEccLib(ecc);\n\nexport function ecPairFromPrivateKey(key: Uint8Array) {\n return ECPair.fromPrivateKey(Buffer.from(key));\n}\n\n// See tagged hashes section of BIP-340\n// https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki#design\nconst messageTagHash = Uint8Array.from([\n ...sha256(utf8ToBytes(bip322MessageTag)),\n ...sha256(utf8ToBytes(bip322MessageTag)),\n]);\n\nexport function hashBip322Message(message: Uint8Array | string) {\n return sha256(\n Uint8Array.from([...messageTagHash, ...(isString(message) ? utf8ToBytes(message) : message)])\n );\n}\n\nexport const bip322TransactionToSignValues = {\n prevoutHash: hexToBytes('0000000000000000000000000000000000000000000000000000000000000000'),\n prevoutIndex: 0xffffffff,\n sequence: 0,\n};\n\nfunction encodeVarString(b: Buffer) {\n return Buffer.concat([encode(b.byteLength), b]);\n}\n\nconst supportedMessageSigningPaymentTypes: PaymentTypes[] = ['p2wpkh', 'p2tr'];\n\nexport function isSupportedMessageSigningPaymentType(paymentType: string) {\n return supportedMessageSigningPaymentTypes.includes(paymentType as PaymentTypes);\n}\n\n/**\n * Encode witness data for a BIP322 message\n * TODO: Refactor to remove `Buffer` use\n */\nexport function encodeMessageWitnessData(witnessArray: Buffer[]) {\n const len = encode(witnessArray.length);\n return Buffer.concat([len, ...witnessArray.map(witness => encodeVarString(witness))]);\n}\n\nfunction tapTweakHash(pubKey: Buffer, h: Buffer | undefined): Buffer {\n return bitcoin.crypto.taggedHash('TapTweak', Buffer.concat(h ? [pubKey, h] : [pubKey]));\n}\n\nexport function tweakSigner(signer: bitcoin.Signer, opts: any = {}): bitcoin.Signer {\n // @ts-expect-error privateKey exists on signer\n let privateKey: Uint8Array | undefined = signer.privateKey!;\n if (!privateKey) {\n throw new Error('Private key is required for tweaking signer!');\n }\n if (signer.publicKey[0] === 3) {\n privateKey = ecc.privateNegate(privateKey);\n }\n\n const tweakedPrivateKey = ecc.privateAdd(\n privateKey,\n tapTweakHash(toXOnly(signer.publicKey), opts.tweakHash)\n );\n if (!tweakedPrivateKey) {\n throw new Error('Invalid tweaked private key!');\n }\n\n return ECPair.fromPrivateKey(Buffer.from(tweakedPrivateKey), {\n network: opts.network,\n });\n}\n","import { hexToBytes } from '@noble/hashes/utils';\nimport { HDKey, Versions } from '@scure/bip32';\nimport { mnemonicToSeedSync } from '@scure/bip39';\nimport * as btc from '@scure/btc-signer';\nimport { TransactionInput, TransactionOutput } from '@scure/btc-signer/psbt';\n\nimport {\n DerivationPathDepth,\n extractAccountIndexFromPath,\n extractPurposeFromPath,\n} from '@leather.io/crypto';\nimport { BitcoinNetworkModes, NetworkModes } from '@leather.io/models';\nimport type { PaymentTypes } from '@leather.io/rpc';\nimport { defaultWalletKeyId, isDefined, whenNetwork } from '@leather.io/utils';\n\nimport { BtcSignerNetwork, getBtcSignerLibNetworkConfigByMode } from './bitcoin.network';\nimport { getTaprootPayment } from './p2tr-address-gen';\nimport { getNativeSegwitPaymentFromAddressIndex } from './p2wpkh-address-gen';\n\nexport interface BitcoinAccount {\n type: PaymentTypes;\n derivationPath: string;\n keychain: HDKey;\n accountIndex: number;\n network: BitcoinNetworkModes;\n}\nexport function initBitcoinAccount(derivationPath: string, policy: string): BitcoinAccount {\n const xpub = extractExtendedPublicKeyFromPolicy(policy);\n const network = inferNetworkFromPath(derivationPath);\n return {\n keychain: HDKey.fromExtendedKey(xpub, getHdKeyVersionsFromNetwork(network)),\n network,\n derivationPath,\n type: inferPaymentTypeFromPath(derivationPath),\n accountIndex: extractAccountIndexFromPath(derivationPath),\n };\n}\n\n/**\n * Represents a map of `BitcoinNetworkModes` to `NetworkModes`. While Bitcoin\n * has a number of networks, its often only necessary to consider the higher\n * level concept of mainnet and testnet\n */\nexport const bitcoinNetworkToCoreNetworkMap: Record<BitcoinNetworkModes, NetworkModes> = {\n mainnet: 'mainnet',\n testnet: 'testnet',\n regtest: 'testnet',\n signet: 'testnet',\n};\nexport function bitcoinNetworkModeToCoreNetworkMode(mode: BitcoinNetworkModes) {\n return bitcoinNetworkToCoreNetworkMap[mode];\n}\n\ntype BitcoinNetworkMap<T> = Record<BitcoinNetworkModes, T>;\n\nexport function whenBitcoinNetwork(mode: BitcoinNetworkModes) {\n return <T extends BitcoinNetworkMap<unknown>>(networkMap: T) =>\n networkMap[mode] as T[BitcoinNetworkModes];\n}\n\n/**\n * Map representing the \"Coin Type\" section of a derivation path.\n * Consider example below, Coin type is one, thus testnet\n * @example\n * `m/86'/1'/0'/0/0`\n */\nexport const coinTypeMap: Record<NetworkModes, 0 | 1> = {\n mainnet: 0,\n testnet: 1,\n};\n\nexport function getBitcoinCoinTypeIndexByNetwork(network: BitcoinNetworkModes) {\n return coinTypeMap[bitcoinNetworkModeToCoreNetworkMode(network)];\n}\n\nexport function deriveAddressIndexKeychainFromAccount(keychain: HDKey) {\n if (keychain.depth !== DerivationPathDepth.Account)\n throw new Error('Keychain passed is not an account');\n\n return (index: number) => keychain.deriveChild(0).deriveChild(index);\n}\n\nexport function deriveAddressIndexZeroFromAccount(keychain: HDKey) {\n return deriveAddressIndexKeychainFromAccount(keychain)(0);\n}\n\nexport const ecdsaPublicKeyLength = 33;\n\nexport function ecdsaPublicKeyToSchnorr(pubKey: Uint8Array) {\n if (pubKey.byteLength !== ecdsaPublicKeyLength) throw new Error('Invalid public key length');\n return pubKey.slice(1);\n}\n\n// Basically same as above, to remove\nexport const toXOnly = (pubKey: Buffer) => (pubKey.length === 32 ? pubKey : pubKey.subarray(1, 33));\n\nexport function decodeBitcoinTx(tx: string): ReturnType<typeof btc.RawTx.decode> {\n return btc.RawTx.decode(hexToBytes(tx));\n}\n\nexport function getAddressFromOutScript(script: Uint8Array, bitcoinNetwork: BtcSignerNetwork) {\n const outputScript = btc.OutScript.decode(script);\n\n switch (outputScript.type) {\n case 'pkh':\n case 'sh':\n case 'wpkh':\n case 'wsh':\n return btc.Address(bitcoinNetwork).encode({\n type: outputScript.type,\n hash: outputScript.hash,\n });\n case 'tr':\n return btc.Address(bitcoinNetwork).encode({\n type: outputScript.type,\n pubkey: outputScript.pubkey,\n });\n case 'ms':\n return btc.p2ms(outputScript.m, outputScript.pubkeys).address ?? '';\n case 'pk':\n return btc.p2pk(outputScript.pubkey, bitcoinNetwork).address ?? '';\n case 'unknown':\n return 'unknown';\n case 'tr_ms':\n case 'tr_ns':\n default:\n return '';\n }\n}\n\n/**\n * Payment type identifiers, as described by `@scure/btc-signer` library\n */\nexport type BtcSignerLibPaymentTypeIdentifers = 'wpkh' | 'wsh' | 'tr' | 'pkh' | 'sh';\n\nexport const paymentTypeMap: Record<BtcSignerLibPaymentTypeIdentifers, PaymentTypes> = {\n wpkh: 'p2wpkh',\n wsh: 'p2wpkh-p2sh',\n tr: 'p2tr',\n pkh: 'p2pkh',\n sh: 'p2sh',\n};\n\nexport function btcSignerLibPaymentTypeToPaymentTypeMap(\n payment: BtcSignerLibPaymentTypeIdentifers\n) {\n return paymentTypeMap[payment];\n}\n\nexport function isBtcSignerLibPaymentType(\n payment: string\n): payment is BtcSignerLibPaymentTypeIdentifers {\n return payment in paymentTypeMap;\n}\n\nexport function parseKnownPaymentType(payment: BtcSignerLibPaymentTypeIdentifers | PaymentTypes) {\n return isBtcSignerLibPaymentType(payment)\n ? btcSignerLibPaymentTypeToPaymentTypeMap(payment)\n : payment;\n}\n\nexport type PaymentTypeMap<T> = Record<PaymentTypes, T>;\nexport function whenPaymentType(mode: PaymentTypes | BtcSignerLibPaymentTypeIdentifers) {\n return <T extends unknown>(paymentMap: PaymentTypeMap<T>): T =>\n paymentMap[parseKnownPaymentType(mode)];\n}\n\nexport type SupportedPaymentType = 'p2wpkh' | 'p2tr';\nexport type SupportedPaymentTypeMap<T> = Record<SupportedPaymentType, T>;\nexport function whenSupportedPaymentType(mode: SupportedPaymentType) {\n return <T>(paymentMap: SupportedPaymentTypeMap<T>): T => paymentMap[mode];\n}\n\n/**\n * Infers the Bitcoin payment type from the derivation path.\n * Below we see path has 86 in it, per convention, this refers to taproot payments\n * @example\n * `m/86'/1'/0'/0/0`\n */\nexport function inferPaymentTypeFromPath(path: string): PaymentTypes {\n const purpose = extractPurposeFromPath(path);\n switch (purpose) {\n case 84:\n return 'p2wpkh';\n case 86:\n return 'p2tr';\n case 44:\n return 'p2pkh';\n default:\n throw new Error(`Unable to infer payment type from purpose=${purpose}`);\n }\n}\n\nexport function inferNetworkFromPath(path: string): NetworkModes {\n return path.split('/')[2].startsWith('0') ? 'mainnet' : 'testnet';\n}\n\nexport function extractExtendedPublicKeyFromPolicy(policy: string) {\n return policy.split(']')[1];\n}\n\nexport function createWalletIdDecoratedPath(policy: string, walletId: string) {\n return policy.split(']')[0].replace('[', '').replace('m', walletId);\n}\n\n// Primarily used to get the correct `Version` when passing Ledger Bitcoin\n// extended public keys to the HDKey constructor\nexport function getHdKeyVersionsFromNetwork(network: NetworkModes) {\n return whenNetwork(network)({\n mainnet: undefined,\n testnet: {\n private: 0x00000000,\n public: 0x043587cf,\n } as Versions,\n });\n}\n\nexport function getBitcoinInputAddress(input: TransactionInput, bitcoinNetwork: BtcSignerNetwork) {\n if (isDefined(input.witnessUtxo))\n return getAddressFromOutScript(input.witnessUtxo.script, bitcoinNetwork);\n if (isDefined(input.nonWitnessUtxo) && isDefined(input.index))\n return getAddressFromOutScript(\n input.nonWitnessUtxo.outputs[input.index]?.script,\n bitcoinNetwork\n );\n return '';\n}\n\nexport function getInputPaymentType(\n input: TransactionInput,\n network: BitcoinNetworkModes\n): PaymentTypes {\n const address = getBitcoinInputAddress(input, getBtcSignerLibNetworkConfigByMode(network));\n if (address === '') throw new Error('Input address cannot be empty');\n if (address.startsWith('bc1p') || address.startsWith('tb1p') || address.startsWith('bcrt1p'))\n return 'p2tr';\n if (address.startsWith('bc1q') || address.startsWith('tb1q') || address.startsWith('bcrt1q'))\n return 'p2wpkh';\n throw new Error('Unable to infer payment type from input address');\n}\n\n// Ledger wallets are keyed by their derivation path. To reuse the look up logic\n// between payment types, this factory fn accepts a fn that generates the path\nexport function lookUpLedgerKeysByPath(\n getDerivationPath: (network: BitcoinNetworkModes, accountIndex: number) => string\n) {\n return (\n ledgerKeyMap: Record<string, { policy: string } | undefined>,\n network: BitcoinNetworkModes\n ) =>\n (accountIndex: number) => {\n const path = getDerivationPath(network, accountIndex);\n // Single wallet mode, hardcoded default walletId\n const account = ledgerKeyMap[path.replace('m', defaultWalletKeyId)];\n if (!account) return;\n return initBitcoinAccount(path, account.policy);\n };\n}\n\ninterface GetAddressArgs {\n index: number;\n keychain?: HDKey;\n network: BitcoinNetworkModes;\n}\n\nexport function getTaprootAddress({ index, keychain, network }: GetAddressArgs) {\n if (!keychain) throw new Error('Expected keychain to be provided');\n\n if (keychain.depth !== DerivationPathDepth.Account)\n throw new Error('Expects keychain to be on the account index');\n\n const addressIndex = deriveAddressIndexKeychainFromAccount(keychain)(index);\n\n if (!addressIndex.publicKey) throw new Error('Expected publicKey to be defined');\n\n const payment = getTaprootPayment(addressIndex.publicKey, network);\n\n if (!payment.address) throw new Error('Expected address to be defined');\n return payment.address;\n}\n\nexport function getNativeSegwitAddress({ index, keychain, network }: GetAddressArgs) {\n if (!keychain) throw new Error('Expected keychain to be provided');\n\n if (keychain.depth !== DerivationPathDepth.Account)\n throw new Error('Expects keychain to be on the account index');\n\n const addressIndex = deriveAddressIndexKeychainFromAccount(keychain)(index);\n\n if (!addressIndex.publicKey) throw new Error('Expected publicKey to be defined');\n\n const payment = getNativeSegwitPaymentFromAddressIndex(addressIndex, network);\n\n if (!payment.address) throw new Error('Expected address to be defined');\n return payment.address;\n}\n\n/**\n * @deprecated\n * Use `deriveRootBip32Keychain` in `@leather.io/crypto` instead\n */\nexport function mnemonicToRootNode(secretKey: string) {\n const seed = mnemonicToSeedSync(secretKey);\n return HDKey.fromMasterSeed(seed);\n}\n\nexport function getPsbtTxInputs(psbtTx: btc.Transaction): TransactionInput[] {\n const inputsLength = psbtTx.inputsLength;\n const inputs: TransactionInput[] = [];\n for (let i = 0; i < inputsLength; i++) inputs.push(psbtTx.getInput(i));\n return inputs;\n}\n\nexport function getPsbtTxOutputs(psbtTx: btc.Transaction): TransactionOutput[] {\n const outputsLength = psbtTx.outputsLength;\n const outputs: TransactionOutput[] = [];\n for (let i = 0; i < outputsLength; i++) outputs.push(psbtTx.getOutput(i));\n return outputs;\n}\n\nexport function inferNetworkFromAddress(address: string): BitcoinNetworkModes {\n if (address.startsWith('bc1')) return 'mainnet';\n if (address.startsWith('tb1')) return 'testnet';\n if (address.startsWith('bcrt1')) return 'regtest';\n\n const firstChar = address[0];\n\n if (firstChar === '1' || firstChar === '3') return 'mainnet';\n if (firstChar === 'm' || firstChar === 'n') return 'testnet';\n if (firstChar === '2') return 'testnet';\n\n throw new Error('Invalid or unsupported Bitcoin address format');\n}\n\nexport function inferPaymentTypeFromAddress(address: string): SupportedPaymentType {\n if (address.startsWith('bc1q') || address.startsWith('tb1q') || address.startsWith('bcrt1q'))\n return 'p2wpkh';\n\n if (address.startsWith('bc1p') || address.startsWith('tb1p') || address.startsWith('bcrt1p'))\n return 'p2tr';\n\n throw new Error('Unable to infer payment type from address');\n}\n\nexport function getBitcoinInputValue(input: TransactionInput) {\n if (isDefined(input.witnessUtxo)) return Number(input.witnessUtxo.amount);\n if (isDefined(input.nonWitnessUtxo) && isDefined(input.index))\n return Number(input.nonWitnessUtxo.outputs[input.index]?.amount);\n // logger.warn('Unable to find either `witnessUtxo` or `nonWitnessUtxo` in input. Defaulting to 0');\n return 0;\n}\n","import * as bitcoinJs from 'bitcoinjs-lib';\n\nimport { BitcoinNetworkModes } from '@leather.io/models';\n\n// See this PR https://github.com/paulmillr/@scure/btc-signer/pull/15\n// Atttempting to add these directly to the library\nexport interface BtcSignerNetwork {\n bech32: string;\n pubKeyHash: number;\n scriptHash: number;\n wif: number;\n}\n\nconst bitcoinMainnet: BtcSignerNetwork = {\n bech32: 'bc',\n pubKeyHash: 0x00,\n scriptHash: 0x05,\n wif: 0x80,\n};\n\nconst bitcoinTestnet: BtcSignerNetwork = {\n bech32: 'tb',\n pubKeyHash: 0x6f,\n scriptHash: 0xc4,\n wif: 0xef,\n};\n\nconst bitcoinRegtest: BtcSignerNetwork = {\n bech32: 'bcrt',\n pubKeyHash: 0x6f,\n scriptHash: 0xc4,\n wif: 0xef,\n};\n\nconst btcSignerLibNetworks: Record<BitcoinNetworkModes, BtcSignerNetwork> = {\n mainnet: bitcoinMainnet,\n testnet: bitcoinTestnet,\n regtest: bitcoinRegtest,\n // Signet originally was going to have its own prefix but authors decided to\n // copy testnet\n signet: bitcoinTestnet,\n};\n\nexport function getBtcSignerLibNetworkConfigByMode(network: BitcoinNetworkModes) {\n return btcSignerLibNetworks[network];\n}\n\nconst bitcoinJsLibNetworks: Record<BitcoinNetworkModes, bitcoinJs.Network> = {\n mainnet: bitcoinJs.networks.bitcoin,\n testnet: bitcoinJs.networks.testnet,\n regtest: bitcoinJs.networks.regtest,\n signet: bitcoinJs.networks.testnet,\n};\n\nexport function getBitcoinJsLibNetworkConfigByMode(network: BitcoinNetworkModes) {\n return bitcoinJsLibNetworks[network];\n}\n","import { HDKey } from '@scure/bip32';\nimport * as btc from '@scure/btc-signer';\n\nimport { DerivationPathDepth } from '@leather.io/crypto';\nimport { BitcoinNetworkModes } from '@leather.io/models';\n\nimport { getBtcSignerLibNetworkConfigByMode } from './bitcoin.network';\nimport {\n BitcoinAccount,\n deriveAddressIndexZeroFromAccount,\n ecdsaPublicKeyToSchnorr,\n getBitcoinCoinTypeIndexByNetwork,\n} from './bitcoin.utils';\n\nexport function makeTaprootAccountDerivationPath(\n network: BitcoinNetworkModes,\n accountIndex: number\n) {\n return `m/86'/${getBitcoinCoinTypeIndexByNetwork(network)}'/${accountIndex}'`;\n}\n/** @deprecated Use makeTaprootAccountDerivationPath */\nexport const getTaprootAccountDerivationPath = makeTaprootAccountDerivationPath;\n\nexport function makeTaprootAddressIndexDerivationPath(\n network: BitcoinNetworkModes,\n accountIndex: number,\n addressIndex: number\n) {\n return makeTaprootAccountDerivationPath(network, accountIndex) + `/0/${addressIndex}`;\n}\n/** @deprecated Use makeTaprootAddressIndexDerivationPath */\nexport const getTaprootAddressIndexDerivationPath = makeTaprootAddressIndexDerivationPath;\n\nexport function deriveTaprootAccount(keychain: HDKey, network: BitcoinNetworkModes) {\n if (keychain.depth !== DerivationPathDepth.Root)\n throw new Error('Keychain passed is not an account');\n\n return (accountIndex: number): BitcoinAccount => ({\n type: 'p2tr',\n network,\n accountIndex,\n derivationPath: makeTaprootAccountDerivationPath(network, accountIndex),\n keychain: keychain.derive(makeTaprootAccountDerivationPath(network, accountIndex)),\n });\n}\n\nexport function getTaprootPayment(publicKey: Uint8Array, network: BitcoinNetworkModes) {\n return btc.p2tr(\n ecdsaPublicKeyToSchnorr(publicKey),\n undefined,\n getBtcSignerLibNetworkConfigByMode(network),\n true // allow unknown outputs\n );\n}\n\nexport function getTaprootPaymentFromAddressIndex(keychain: HDKey, network: BitcoinNetworkModes) {\n if (keychain.depth !== DerivationPathDepth.AddressIndex)\n throw new Error('Keychain passed is not an address index');\n\n if (!keychain.publicKey) throw new Error('Keychain has no public key');\n\n return getTaprootPayment(keychain.publicKey, network);\n}\n\ninterface DeriveTaprootReceiveAddressIndexArgs {\n keychain: HDKey;\n network: BitcoinNetworkModes;\n}\nexport function deriveTaprootReceiveAddressIndexZero({\n keychain,\n network,\n}: DeriveTaprootReceiveAddressIndexArgs) {\n const zeroAddressIndex = deriveAddressIndexZeroFromAccount(keychain);\n return {\n keychain: zeroAddressIndex,\n payment: getTaprootPaymentFromAddressIndex(zeroAddressIndex, network),\n };\n}\n","import { HDKey } from '@scure/bip32';\nimport * as btc from '@scure/btc-signer';\n\nimport { DerivationPathDepth } from '@leather.io/crypto';\nimport { BitcoinNetworkModes } from '@leather.io/models';\n\nimport { getBtcSignerLibNetworkConfigByMode } from './bitcoin.network';\nimport {\n BitcoinAccount,\n deriveAddressIndexZeroFromAccount,\n getBitcoinCoinTypeIndexByNetwork,\n} from './bitcoin.utils';\n\nexport function makeNativeSegwitAccountDerivationPath(\n network: BitcoinNetworkModes,\n accountIndex: number\n) {\n return `m/84'/${getBitcoinCoinTypeIndexByNetwork(network)}'/${accountIndex}'`;\n}\n\n/** @deprecated Use makeNativeSegwitAccountDerivationPath */\nexport const getNativeSegwitAccountDerivationPath = makeNativeSegwitAccountDerivationPath;\n\nexport function makeNativeSegwitAddressIndexDerivationPath(\n network: BitcoinNetworkModes,\n accountIndex: number,\n addressIndex: number\n) {\n return makeNativeSegwitAccountDerivationPath(network, accountIndex) + `/0/${addressIndex}`;\n}\n\n/** @deprecated Use makeNativeSegwitAddressIndexDerivationPath */\nexport const getNativeSegwitAddressIndexDerivationPath = makeNativeSegwitAddressIndexDerivationPath;\n\nexport function deriveNativeSegwitAccountFromRootKeychain(\n keychain: HDKey,\n network: BitcoinNetworkModes\n) {\n if (keychain.depth !== DerivationPathDepth.Root) throw new Error('Keychain passed is not a root');\n return (accountIndex: number): BitcoinAccount => ({\n type: 'p2wpkh',\n network,\n accountIndex,\n derivationPath: makeNativeSegwitAccountDerivationPath(network, accountIndex),\n keychain: keychain.derive(makeNativeSegwitAccountDerivationPath(network, accountIndex)),\n });\n}\n\nexport function getNativeSegwitPaymentFromAddressIndex(\n keychain: HDKey,\n network: BitcoinNetworkModes\n) {\n if (keychain.depth !== DerivationPathDepth.AddressIndex)\n throw new Error('Keychain passed is not an address index');\n\n if (!keychain.publicKey) throw new Error('Keychain does not have a public key');\n\n return btc.p2wpkh(keychain.publicKey, getBtcSignerLibNetworkConfigByMode(network));\n}\n\ninterface DeriveNativeSegwitReceiveAddressIndexArgs {\n keychain: HDKey;\n network: BitcoinNetworkModes;\n}\nexport function deriveNativeSegwitReceiveAddressIndexZero({\n keychain,\n network,\n}: DeriveNativeSegwitReceiveAddressIndexArgs) {\n const zeroAddressIndex = deriveAddressIndexZeroFromAccount(keychain);\n return {\n keychain: zeroAddressIndex,\n payment: getNativeSegwitPaymentFromAddressIndex(zeroAddressIndex, network),\n };\n}\n","import { base64 } from '@scure/base';\nimport * as btc from '@scure/btc-signer';\nimport * as bitcoin from 'bitcoinjs-lib';\n\nimport { BitcoinNetworkModes } from '@leather.io/models';\n\nimport { getBitcoinJsLibNetworkConfigByMode } from '../bitcoin.network';\nimport {\n bip322TransactionToSignValues,\n ecPairFromPrivateKey,\n encodeMessageWitnessData,\n hashBip322Message,\n tweakSigner,\n} from './bip322-utils';\n\nexport function createNativeSegwitBitcoinJsSigner(privateKey: Buffer) {\n return ecPairFromPrivateKey(privateKey);\n}\n\nexport function createTaprootBitcoinJsSigner(privateKey: Buffer) {\n return tweakSigner(ecPairFromPrivateKey(privateKey));\n}\n\nexport function createToSpendTx(address: string, message: string, network: BitcoinNetworkModes) {\n const { prevoutHash, prevoutIndex, sequence } = bip322TransactionToSignValues;\n\n const script = bitcoin.address.toOutputScript(\n address,\n getBitcoinJsLibNetworkConfigByMode(network)\n );\n\n const hash = hashBip322Message(message);\n const commands = [0, Buffer.from(hash)];\n const scriptSig = bitcoin.script.compile(commands);\n\n const virtualToSpend = new bitcoin.Transaction();\n virtualToSpend.version = 0;\n virtualToSpend.addInput(Buffer.from(prevoutHash), prevoutIndex, sequence, scriptSig);\n virtualToSpend.addOutput(script, 0);\n return { virtualToSpend, script };\n}\n\nfunction createToSignTx(toSpendTxHex: Buffer, script: Buffer, network: BitcoinNetworkModes) {\n const virtualToSign = new bitcoin.Psbt({ network: getBitcoinJsLibNetworkConfigByMode(network) });\n virtualToSign.setVersion(0);\n const prevTxHash = toSpendTxHex;\n const prevOutIndex = 0;\n const toSignScriptSig = bitcoin.script.compile([bitcoin.script.OPS.OP_RETURN]);\n\n virtualToSign.addInput({\n hash: prevTxHash,\n index: prevOutIndex,\n sequence: 0,\n witnessUtxo: { script, value: 0 },\n });\n\n virtualToSign.addOutput({ script: toSignScriptSig, value: 0 });\n return virtualToSign;\n}\n\ninterface SignBip322MessageSimple {\n address: string;\n message: string;\n network: BitcoinNetworkModes;\n signPsbt(psbt: bitcoin.Psbt): Promise<btc.Transaction>;\n}\nexport async function signBip322MessageSimple(args: SignBip322MessageSimple) {\n const { address, message, network, signPsbt } = args;\n\n const { virtualToSpend, script } = createToSpendTx(address, message, network);\n\n const virtualToSign = createToSignTx(virtualToSpend.getHash(), script, network);\n\n const signedTx = await signPsbt(virtualToSign);\n\n const asBitcoinJsTransaction = bitcoin.Psbt.fromBuffer(Buffer.from(signedTx.toPSBT()));\n\n asBitcoinJsTransaction.finalizeInput(0);\n\n // sign the tx\n // section 5.1\n // github.com/LegReq/bip0322-signatures/blob/master/BIP0322_signing.ipynb\n const toSignTx = asBitcoinJsTransaction.extractTransaction();\n\n const result = encodeMessageWitnessData(toSignTx.ins[0].witness);\n\n return {\n virtualToSpend,\n virtualToSign: toSignTx,\n unencodedSig: result,\n signature: base64.encode(result),\n };\n}\n","import BigNumber from 'bignumber.js';\n\nimport type { AverageBitcoinFeeRates } from '@leather.io/models';\nimport { createMoney, satToBtc } from '@leather.io/utils';\n\nimport { CoinSelectionUtxo } from './coin-selection';\nimport { filterUneconomicalUtxos, getSpendableAmount } from './coin-selection.utils';\n\ninterface CalculateMaxBitcoinSpend {\n address: string;\n utxos: CoinSelectionUtxo[];\n fetchedFeeRates?: AverageBitcoinFeeRates;\n feeRate?: number;\n}\n\nexport function calculateMaxBitcoinSpend({\n address,\n utxos,\n feeRate,\n fetchedFeeRates,\n}: CalculateMaxBitcoinSpend) {\n if (!utxos.length || !fetchedFeeRates)\n return {\n spendAllFee: 0,\n amount: createMoney(0, 'BTC'),\n spendableBitcoin: new BigNumber(0),\n };\n\n const currentFeeRate = feeRate ?? fetchedFeeRates.halfHourFee.toNumber();\n\n const filteredUtxos = filterUneconomicalUtxos({\n utxos,\n feeRate: currentFeeRate,\n recipients: [{ address, amount: createMoney(0, 'BTC') }],\n });\n\n const { spendableAmount, fee } = getSpendableAmount({\n utxos: filteredUtxos,\n feeRate: currentFeeRate,\n recipients: [{ address, amount: createMoney(0, 'BTC') }],\n });\n\n return {\n spendAllFee: fee,\n amount: createMoney(spendableAmount, 'BTC'),\n spendableBitcoin: satToBtc(spendableAmount),\n };\n}\n","import BigNumber from 'bignumber.js';\nimport validate, { AddressInfo, AddressType, getAddressInfo } from 'bitcoin-address-validation';\n\nimport { BTC_P2WPKH_DUST_AMOUNT } from '@leather.io/constants';\nimport { sumNumbers } from '@leather.io/utils';\n\nimport { BtcSizeFeeEstimator } from '../btc-size-fee-estimator';\nimport { CoinSelectionRecipient, CoinSelectionUtxo } from './coin-selection';\n\nexport function getUtxoTotal(utxos: CoinSelectionUtxo[]) {\n return sumNumbers(utxos.map(utxo => utxo.value));\n}\n\nexport function getSizeInfo(payload: {\n inputLength: number;\n recipients: CoinSelectionRecipient[];\n isSendMax?: boolean;\n}) {\n const { inputLength, recipients, isSendMax } = payload;\n\n const validAddressesInfo = recipients\n .map(recipient => validate(recipient.address) && getAddressInfo(recipient.address))\n .filter(Boolean) as AddressInfo[];\n\n function getTxOutputsLengthByPaymentType() {\n return validAddressesInfo.reduce(\n (acc, { type }) => {\n acc[type] = (acc[type] || 0) + 1;\n return acc;\n },\n {} as Record<AddressType, number>\n );\n }\n\n const outputTypesCount = getTxOutputsLengthByPaymentType();\n\n // Add a change address if not sending max (defaults to p2wpkh)\n if (!isSendMax) {\n outputTypesCount[AddressType.p2wpkh] = (outputTypesCount[AddressType.p2wpkh] || 0) + 1;\n }\n\n // Prepare the output data map for consumption by the txSizer\n const outputsData = Object.entries(outputTypesCount).reduce(\n (acc, [type, count]) => {\n acc[type + '_output_count'] = count;\n return acc;\n },\n {} as Record<string, number>\n );\n\n const txSizer = new BtcSizeFeeEstimator();\n const sizeInfo = txSizer.calcTxSize({\n input_script: 'p2wpkh',\n input_count: inputLength,\n ...outputsData,\n });\n\n return sizeInfo;\n}\n\nexport function getSpendableAmount({\n utxos,\n feeRate,\n recipients,\n}: {\n utxos: CoinSelectionUtxo[];\n feeRate: number;\n recipients: CoinSelectionRecipient[];\n}) {\n const balance = utxos\n .map(utxo => Number(utxo.value))\n .reduce((prevVal, curVal) => prevVal + curVal, 0);\n\n const size = getSizeInfo({\n inputLength: utxos.length,\n recipients,\n });\n const fee = Math.ceil(size.txVBytes * feeRate);\n const bigNumberBalance = BigNumber(balance);\n return {\n spendableAmount: BigNumber.max(0, bigNumberBalance.minus(fee)),\n fee,\n };\n}\n\n// Check if the spendable amount drops when adding a utxo\nexport function filterUneconomicalUtxos({\n utxos,\n feeRate,\n recipients,\n}: {\n utxos: CoinSelectionUtxo[];\n feeRate: number;\n recipients: CoinSelectionRecipient[];\n}) {\n const { spendableAmount: fullSpendableAmount } = getSpendableAmount({\n utxos,\n feeRate,\n recipients,\n });\n\n const filteredUtxos = utxos\n .filter(utxo => utxo.value >= BTC_P2WPKH_DUST_AMOUNT)\n .filter(utxo => {\n // Calculate spendableAmount without that utxo\n const { spendableAmount } = getSpendableAmount({\n utxos: utxos.filter(u => u.txid !== utxo.txid),\n feeRate,\n recipients,\n });\n // If fullSpendableAmount is greater, do not use utxo\n return spendableAmount.toNumber() < fullSpendableAmount.toNumber();\n });\n return filteredUtxos;\n}\n","// https://github.com/argvil19/bitcoin-transaction-size-calculator/blob/master/index.js\nimport BigNumber from 'bignumber.js';\n\nexport type InputScriptType =\n | 'p2pkh'\n | 'p2sh'\n | 'p2sh-p2wpkh'\n | 'p2sh-p2wsh'\n | 'p2wpkh'\n | 'p2wsh'\n | 'p2tr';\n\nexport interface TxSizerParams {\n input_count: number;\n input_script: InputScriptType;\n input_m: number;\n input_n: number;\n p2pkh_output_count: number;\n p2sh_output_count: number;\n p2sh_p2wpkh_output_count: number;\n p2sh_p2wsh_output_count: number;\n p2wpkh_output_count: number;\n p2wsh_output_count: number;\n p2tr_output_count: number;\n}\n\nexport class BtcSizeFeeEstimator {\n P2PKH_IN_SIZE = 148;\n P2PKH_OUT_SIZE = 34;\n P2SH_OUT_SIZE = 32;\n P2SH_P2WPKH_OUT_SIZE = 32;\n P2SH_P2WSH_OUT_SIZE = 32;\n P2SH_P2WPKH_IN_SIZE = 91;\n P2WPKH_IN_SIZE = 67.75;\n P2WPKH_OUT_SIZE = 31;\n P2WSH_OUT_SIZE = 43;\n P2TR_OUT_SIZE = 43;\n P2TR_IN_SIZE = 57.25;\n PUBKEY_SIZE = 33;\n SIGNATURE_SIZE = 72;\n SUPPORTED_INPUT_SCRIPT_TYPES: InputScriptType[] = [\n 'p2pkh',\n 'p2sh',\n 'p2sh-p2wpkh',\n 'p2sh-p2wsh',\n 'p2wpkh',\n 'p2wsh',\n 'p2tr',\n ];\n\n defaultParams: TxSizerParams = {\n input_count: 0,\n input_script: 'p2wpkh',\n input_m: 0,\n input_n: 0,\n p2pkh_output_count: 0,\n p2sh_output_count: 0,\n p2sh_p2wpkh_output_count: 0,\n p2sh_p2wsh_output_count: 0,\n p2wpkh_output_count: 0,\n p2wsh_output_count: 0,\n p2tr_output_count: 0,\n };\n\n params: TxSizerParams = { ...this.defaultParams };\n\n getSizeOfScriptLengthElement(length: number) {\n if (length < 75) {\n return 1;\n } else if (length <= 255) {\n return 2;\n } else if (length <= 65535) {\n return 3;\n } else if (length <= 4294967295) {\n return 5;\n } else {\n throw new Error('Size of redeem script is too large');\n }\n }\n\n getSizeOfletInt(length: number) {\n if (length < 253) {\n return 1;\n } else if (length < 65535) {\n return 3;\n } else if (length < 4294967295) {\n return 5;\n } else if (new BigNumber(length).isLessThan('18446744073709551615')) {\n return 9;\n } else {\n throw new Error('Invalid let int');\n }\n }\n\n getTxOverheadVBytes(input_script: InputScriptType, input_count: number, output_count: number) {\n let witness_vbytes;\n if (input_script === 'p2pkh' || input_script === 'p2sh') {\n witness_vbytes = 0;\n } else {\n // Transactions with segwit inputs have extra overhead\n witness_vbytes =\n 0.25 + // segwit marker\n 0.25 + // segwit flag\n this.getSizeOfletInt(input_count) / 4; // witness element count\n }\n\n return (\n 4 + // nVersion\n this.getSizeOfletInt(input_count) + // number of inputs\n this.getSizeOfletInt(output_count) + // number of outputs\n 4 + // nLockTime\n witness_vbytes\n );\n }\n\n getTxOverheadExtraRawBytes(input_script: InputScriptType, input_count: number) {\n let witness_vbytes;\n if (input_script === 'p2pkh' || input_script === 'p2sh') {\n witness_vbytes = 0;\n } else {\n // Transactions with segwit inputs have extra overhead\n witness_vbytes =\n 0.25 + // segwit marker\n 0.25 + // segwit flag\n this.getSizeOfletInt(input_count) / 4; // witness element count\n }\n\n return witness_vbytes * 3;\n }\n\n prepareParams(opts: Partial<TxSizerParams>) {\n // Verify opts and set them to this.params\n opts = opts || Object.assign(this.defaultParams);\n\n const input_count = opts.input_count || this.defaultParams.input_count;\n if (!Number.isInteger(input_count) || input_count < 0) {\n throw new Error('expecting positive input count, got: ' + input_count);\n }\n\n const input_script = opts.input_script || this.defaultParams.input_script;\n if (this.SUPPORTED_INPUT_SCRIPT_TYPES.indexOf(input_script) === -1) {\n throw new Error('Not supported input script type');\n }\n\n const input_m = opts.input_m || this.defaultParams.input_m;\n if (!Number.isInteger(input_m) || input_m < 0) {\n throw new Error('expecting positive signature count');\n }\n\n const input_n = opts.input_n || this.defaultParams.input_n;\n if (!Number.isInteger(input_n) || input_n < 0) {\n throw new Error('expecting positive pubkey count');\n }\n\n const p2pkh_output_count = opts.p2pkh_output_count || this.defaultParams.p2pkh_output_count;\n if (!Number.isInteger(p2pkh_output_count) || p2pkh_output_count < 0) {\n throw new Error('expecting positive p2pkh output count');\n }\n\n const p2sh_output_count = opts.p2sh_output_count || this.defaultParams.p2sh_output_count;\n if (!Number.isInteger(p2sh_output_count) || p2sh_output_count < 0) {\n throw new Error('expecting positive p2sh output count');\n }\n\n const p2sh_p2wpkh_output_count =\n opts.p2sh_p2wpkh_output_count || this.defaultParams.p2sh_p2wpkh_output_count;\n if (!Number.isInteger(p2sh_p2wpkh_output_count) || p2sh_p2wpkh_output_count < 0) {\n throw new Error('expecting positive p2sh-p2wpkh output count');\n }\n\n const p2sh_p2wsh_output_count =\n opts.p2sh_p2wsh_output_count || this.defaultParams.p2sh_p2wsh_output_count;\n if (!Number.isInteger(p2sh_p2wsh_output_count) || p2sh_p2wsh_output_count < 0) {\n throw new Error('expecting positive p2sh-p2wsh output count');\n }\n\n const p2wpkh_output_count = opts.p2wpkh_output_count || this.defaultParams.p2wpkh_output_count;\n if (!Number.isInteger(p2wpkh_output_count) || p2wpkh_output_count < 0) {\n throw new Error('expecting positive p2wpkh output count');\n }\n\n const p2wsh_output_count = opts.p2wsh_output_count || this.defaultParams.p2wsh_output_count;\n if (!Number.isInteger(p2wsh_output_count) || p2wsh_output_count < 0) {\n throw new Error('expecting positive p2wsh output count');\n }\n\n const p2tr_output_count = opts.p2tr_output_count || this.defaultParams.p2tr_output_count;\n if (!Number.isInteger(p2tr_output_count) || p2tr_output_count < 0) {\n throw new Error('expecting positive p2tr output count');\n }\n\n this.params = {\n input_count,\n input_script,\n input_m,\n input_n,\n p2pkh_output_count,\n p2sh_output_count,\n p2sh_p2wpkh_output_count,\n p2sh_p2wsh_output_count,\n p2wpkh_output_count,\n p2wsh_output_count,\n p2tr_output_count,\n };\n\n return this.params;\n }\n\n getOutputCount() {\n return (\n this.params.p2pkh_output_count +\n this.params.p2sh_output_count +\n this.params.p2sh_p2wpkh_output_count +\n this.params.p2sh_p2wsh_output_count +\n this.params.p2wpkh_output_count +\n this.params.p2wsh_output_count +\n this.params.p2tr_output_count\n );\n }\n\n getSizeBasedOnInputType() {\n // In most cases the input size is predictable. For multisig inputs we need to perform a detailed calculation\n let inputSize = 0; // in virtual bytes\n let inputWitnessSize = 0;\n let redeemScriptSize;\n switch (this.params.input_script) {\n case 'p2pkh':\n inputSize = this.P2PKH_IN_SIZE;\n break;\n case 'p2sh-p2wpkh':\n inputSize = this.P2SH_P2WPKH_IN_SIZE;\n inputWitnessSize = 107; // size(signature) + signature + size(pubkey) + pubkey\n break;\n case 'p2wpkh':\n inputSize = this.P2WPKH_IN_SIZE;\n inputWitnessSize = 107; // size(signature) + signature + size(pubkey) + pubkey\n break;\n case 'p2tr': // Only consider the cooperative taproot signing path assume multisig is done via aggregate signatures\n inputSize = this.P2TR_IN_SIZE;\n inputWitnessSize = 65; // getSizeOfletInt(schnorrSignature) + schnorrSignature\n break;\n case 'p2sh':\n redeemScriptSize =\n 1 + // OP_M\n this.params.input_n * (1 + this.PUBKEY_SIZE) + // OP_PUSH33 <pubkey>\n 1 + // OP_N\n 1; // OP_CHECKMULTISIG\n const scriptSigSize =\n 1 + // size(0)\n this.params.input_m * (1 + this.SIGNATURE_SIZE) + // size(SIGNATURE_SIZE) + signature\n this.getSizeOfScriptLengthElement(redeemScriptSize) +\n redeemScriptSize;\n inputSize = 32 + 4 + this.getSizeOfletInt(scriptSigSize) + scriptSigSize + 4;\n break;\n case 'p2sh-p2wsh':\n case 'p2wsh':\n redeemScriptSize =\n 1 + // OP_M\n this.params.input_n * (1 + this.PUBKEY_SIZE) + // OP_PUSH33 <pubkey>\n 1 + // OP_N\n 1; // OP_CHECKMULTISIG\n inputWitnessSize =\n 1 + // size(0)\n this.params.input_m * (1 + this.SIGNATURE_SIZE) + // size(SIGNATURE_SIZE) + signature\n this.getSizeOfScriptLengthElement(redeemScriptSize) +\n redeemScriptSize;\n inputSize =\n 36 + // outpoint (spent UTXO ID)\n inputWitnessSize / 4 + // witness program\n 4; // nSequence\n if (this.params.input_script === 'p2sh-p2wsh') {\n inputSize += 32 + 3; // P2SH wrapper (redeemscript hash) + overhead?\n }\n }\n\n return {\n inputSize,\n inputWitnessSize,\n };\n }\n\n calcTxSize(opts: Partial<TxSizerParams>) {\n this.prepareParams(opts);\n const output_count = this.getOutputCount();\n const { inputSize, inputWitnessSize } = this.getSizeBasedOnInputType();\n\n const txVBytes =\n this.getTxOverheadVBytes(this.params.input_script, this.params.input_count, output_count) +\n inputSize * this.params.input_count +\n this.P2PKH_OUT_SIZE * this.params.p2pkh_output_count +\n this.P2SH_OUT_SIZE * this.params.p2sh_output_count +\n this.P2SH_P2WPKH_OUT_SIZE * this.params.p2sh_p2wpkh_output_count +\n this.P2SH_P2WSH_OUT_SIZE * this.params.p2sh_p2wsh_output_count +\n this.P2WPKH_OUT_SIZE * this.params.p2wpkh_output_count +\n this.P2WSH_OUT_SIZE * this.params.p2wsh_output_count +\n this.P2TR_OUT_SIZE * this.params.p2tr_output_count;\n\n const txBytes =\n this.getTxOverheadExtraRawBytes(this.params.input_script, this.params.input_count) +\n txVBytes +\n inputWitnessSize * this.params.input_count;\n const txWeight = txVBytes * 4;\n\n return { txVBytes, txBytes, txWeight };\n }\n\n estimateFee(vbyte: number, satVb: number) {\n if (isNaN(vbyte) || isNaN(satVb)) {\n throw new Error('Parameters should be numbers');\n }\n return vbyte * satVb;\n }\n\n formatFeeRange(fee: number, multiplier: number) {\n if (isNaN(fee) || isNaN(multiplier)) {\n throw new Error('Parameters should be numbers');\n }\n\n if (multiplier < 0) {\n throw new Error('Multiplier cant be negative');\n }\n\n const multipliedFee = fee * multiplier;\n\n return fee - multipliedFee + ' - ' + (fee + multipliedFee);\n }\n}\n","import BigNumber from 'bignumber.js';\nimport { validate } from 'bitcoin-address-validation';\n\nimport { BTC_P2WPKH_DUST_AMOUNT } from '@leather.io/constants';\nimport { Money } from '@leather.io/models';\nimport { createMoney, sumMoney } from '@leather.io/utils';\n\nimport { BitcoinError, BitcoinErrorMessage } from '../bitcoin-error';\nimport { filterUneconomicalUtxos, getSizeInfo, getUtxoTotal } from './coin-selection.utils';\n\nexport interface CoinSelectionOutput {\n value: bigint;\n address?: string;\n}\n\nexport interface CoinSelectionUtxo {\n address: string;\n txid: string;\n value: number;\n vout: number;\n}\n\nexport interface CoinSelectionRecipient {\n address: string;\n amount: Money;\n}\n\nexport interface DetermineUtxosForSpendArgs {\n feeRate: number;\n recipients: CoinSelectionRecipient[];\n utxos: CoinSelectionUtxo[];\n}\n\nexport function determineUtxosForSpendAll({\n feeRate,\n recipients,\n utxos,\n}: DetermineUtxosForSpendArgs) {\n recipients.forEach(recipient => {\n if (!validate(recipient.address))\n throw new Error('Cannot calculate spend of invalid address type');\n });\n const filteredUtxos = filterUneconomicalUtxos({ utxos, feeRate, recipients });\n\n const sizeInfo = getSizeInfo({\n inputLength: filteredUtxos.length,\n isSendMax: true,\n recipients,\n });\n\n // Fee has already been deducted from the amount with send all\n const outputs = recipients.map(({ address, amount }) => ({\n value: BigInt(amount.amount.toNumber()),\n address,\n }));\n\n const fee = Math.ceil(sizeInfo.txVBytes * feeRate);\n\n return {\n inputs: filteredUtxos,\n outputs,\n size: sizeInfo.txVBytes,\n fee: createMoney(new BigNumber(fee), 'BTC'),\n };\n}\n\nexport function determineUtxosForSpend({ feeRate, recipients, utxos }: DetermineUtxosForSpendArgs) {\n recipients.forEach(recipient => {\n if (!validate(recipient.address))\n throw new Error('Cannot calculate spend of invalid address type');\n });\n const filteredUtxos = filterUneconomicalUtxos({\n utxos: utxos.sort((a, b) => b.value - a.value),\n feeRate,\n recipients,\n });\n if (!filteredUtxos.length) throw new BitcoinError(BitcoinErrorMessage.InsufficientFunds);\n\n const amount = sumMoney(recipients.map(recipient => recipient.amount));\n\n // Prepopulate with first utxo, at least one is needed\n const neededUtxos: CoinSelectionUtxo[] = [filteredUtxos[0]];\n\n function estimateTransactionSize() {\n return getSizeInfo({\n inputLength: neededUtxos.length,\n recipients,\n });\n }\n\n function hasSufficientUtxosForTx() {\n const txEstimation = estimateTransactionSize();\n const neededAmount = new BigNumber(txEstimation.txVBytes * feeRate).plus(amount.amount);\n return getUtxoTotal(neededUtxos).isGreaterThanOrEqualTo(neededAmount);\n }\n\n function getRemainingUnspentUtxos() {\n return filteredUtxos.filter(utxo => !neededUtxos.includes(utxo));\n }\n\n while (!hasSufficientUtxosForTx()) {\n const [nextUtxo] = getRemainingUnspentUtxos();\n if (!nextUtxo) throw new BitcoinError(BitcoinErrorMessage.InsufficientFunds);\n neededUtxos.push(nextUtxo);\n }\n\n const fee = Math.ceil(\n new BigNumber(estimateTransactionSize().txVBytes).multipliedBy(feeRate).toNumber()\n );\n\n const changeAmount =\n BigInt(getUtxoTotal(neededUtxos).toString()) - BigInt(amount.amount.toNumber()) - BigInt(fee);\n\n const changeUtxos: CoinSelectionOutput[] =\n changeAmount > BTC_P2WPKH_DUST_AMOUNT\n ? [\n {\n value: changeAmount,\n },\n ]\n : [];\n\n const outputs: CoinSelectionOutput[] = [\n ...recipients.map(({ address, amount }) => ({\n value: BigInt(amount.amount.toNumber()),\n address,\n })),\n ...changeUtxos,\n ];\n\n return {\n filteredUtxos,\n inputs: neededUtxos,\n outputs,\n size: estimateTransactionSize().txVBytes,\n fee: createMoney(new BigNumber(fee), 'BTC'),\n ...estimateTransactionSize(),\n };\n}\n","export enum BitcoinErrorMessage {\n InsufficientFunds = 'Insufficient funds',\n NoInputsToSign = 'No inputs to sign',\n NoOutputsToSign = 'No outputs to sign',\n}\n\nexport class BitcoinError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'BitcoinError';\n\n // Fix the prototype chain\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n","import { AverageBitcoinFeeRates, Money } from '@leather.io/models';\n\nimport {\n CoinSelectionRecipient,\n CoinSelectionUtxo,\n DetermineUtxosForSpendArgs,\n determineUtxosForSpend,\n determineUtxosForSpendAll,\n} from '../coin-selection/coin-selection';\n\ntype GetBitcoinTransactionFeeArgs = DetermineUtxosForSpendArgs & {\n isSendingMax?: boolean;\n};\n\nexport function getBitcoinTransactionFee({ isSendingMax, ...props }: GetBitcoinTransactionFeeArgs) {\n try {\n const { fee } = isSendingMax\n ? determineUtxosForSpendAll({ ...props })\n : determineUtxosForSpend({ ...props });\n return fee;\n } catch (error) {\n return null;\n }\n}\n\nexport interface BitcoinFees {\n blockchain: 'bitcoin';\n high: { fee: Money | null; feeRate: number };\n standard: { fee: Money | null; feeRate: number };\n low: { fee: Money | null; feeRate: number };\n}\n\nexport interface GetBitcoinFeesArgs {\n feeRates: AverageBitcoinFeeRates;\n isSendingMax?: boolean;\n recipients: CoinSelectionRecipient[];\n utxos: CoinSelectionUtxo[];\n}\nexport function getBitcoinFees({ feeRates, isSendingMax, recipients, utxos }: GetBitcoinFeesArgs) {\n const defaultArgs = {\n isSendingMax,\n recipients,\n utxos,\n };\n\n const highFeeRate = feeRates.fastestFee.toNumber();\n const standardFeeRate = feeRates.halfHourFee.toNumber();\n const lowFeeRate = feeRates.hourFee.toNumber();\n\n const highFeeValue = getBitcoinTransactionFee({\n ...defaultArgs,\n feeRate: highFeeRate,\n });\n const standardFeeValue = getBitcoinTransactionFee({\n ...defaultArgs,\n feeRate: standardFeeRate,\n });\n const lowFeeValue = getBitcoinTransactionFee({\n ...defaultArgs,\n feeRate: lowFeeRate,\n });\n\n return {\n high: { feeRate: highFeeRate, fee: highFeeValue },\n standard: { feeRate: standardFeeRate, fee: standardFeeValue },\n low: { feeRate: lowFeeRate, fee: lowFeeValue },\n };\n}\n","import { hexToBytes } from '@noble/hashes/utils';\nimport * as btc from '@scure/btc-signer';\nimport { BtcSignerDefaultBip32Derivation } from 'bitcoin-signer';\n\nimport { BitcoinError, BitcoinErrorMessage } from '../bitcoin-error';\nimport { BtcSignerNetwork } from '../bitcoin.network';\nimport {\n CoinSelectionRecipient,\n CoinSelectionUtxo,\n determineUtxosForSpend,\n determineUtxosForSpendAll,\n} from '../coin-selection/coin-selection';\n\nexport interface GenerateBitcoinUnsignedTransactionArgs {\n feeRate: number;\n isSendingMax?: boolean;\n payerAddress: string;\n payerPublicKey: string;\n bip32Derivation: BtcSignerDefaultBip32Derivation[];\n network: BtcSignerNetwork;\n recipients: CoinSelectionRecipient[];\n utxos: CoinSelectionUtxo[];\n}\n\nexport async function generateBitcoinUnsignedTransactionNativeSegwit({\n feeRate,\n isSendingMax,\n payerAddress,\n payerPublicKey,\n bip32Derivation,\n network,\n recipients,\n utxos,\n}: GenerateBitcoinUnsignedTransactionArgs) {\n try {\n const determineUtxosArgs = { feeRate, recipients, utxos };\n const { inputs, outputs, fee } = isSendingMax\n ? determineUtxosForSpendAll(determineUtxosArgs)\n : determineUtxosForSpend(determineUtxosArgs);\n\n if (!inputs.length) throw new BitcoinError(BitcoinErrorMessage.NoInputsToSign);\n if (!outputs.length) throw new BitcoinError(BitcoinErrorMessage.NoOutputsToSign);\n\n const tx = new btc.Transaction();\n const p2wpkh = btc.p2wpkh(hexToBytes(payerPublicKey), network);\n\n for (const input of inputs) {\n tx.addInput({\n txid: input.txid,\n index: input.vout,\n sequence: 0,\n bip32Derivation,\n witnessUtxo: {\n // script = 0014 + pubKeyHash\n script: p2wpkh.script,\n amount: BigInt(input.value),\n },\n });\n }\n\n outputs.forEach(output => {\n // When coin selection returns an output with no address,\n // we assume it is a change output\n if (!output.address) {\n tx.addOutputAddress(payerAddress, BigInt(output.value), network);\n return;\n }\n tx.addOutputAddress(output.address, BigInt(output.value), network);\n });\n\n return { tx, hex: tx.hex, psbt: tx.toPSBT(), inputs, fee };\n } catch (e) {\n return null;\n }\n}\n","import { HARDENED_OFFSET, HDKey } from '@scure/bip32';\nimport * as btc from '@scure/btc-signer';\nimport { P2Ret, P2TROut } from '@scure/btc-signer/payment';\nimport { SigHash } from '@scure/btc-signer/transaction';\n\nimport {\n DerivationPathDepth,\n appendAddressIndexToPath,\n decomposeDescriptor,\n deriveKeychainFromXpub,\n keyOriginToDerivationPath,\n} from '@leather.io/crypto';\nimport type { BitcoinNetworkModes } from '@leather.io/models';\nimport { PaymentTypes, SignatureHash } from '@leather.io/rpc';\nimport { hexToNumber, toHexString } from '@leather.io/utils';\n\nimport {\n SupportedPaymentType,\n ecdsaPublicKeyToSchnorr,\n extractExtendedPublicKeyFromPolicy,\n inferPaymentTypeFromPath,\n whenSupportedPaymentType,\n} from './bitcoin.utils';\nimport { getTaprootPaymentFromAddressIndex } from './p2tr-address-gen';\nimport { getNativeSegwitPaymentFromAddressIndex } from './p2wpkh-address-gen';\n\nexport type AllowedSighashTypes = SignatureHash | SigHash;\n\nexport interface BitcoinAccountKeychain {\n descriptor: string;\n masterKeyFingerprint: string;\n keyOrigin: string;\n keychain: HDKey;\n xpub: string;\n}\n\nexport type WithDerivePayer<T, P> = T & { derivePayer: (args: BitcoinPayerInfo) => P };\n\nexport interface BitcoinSigner<Payment> {\n network: BitcoinNetworkModes;\n payment: Payment;\n keychain: HDKey;\n derivationPath: string;\n address: string;\n publicKey: Uint8Array;\n sign(tx: btc.Transaction): void;\n signIndex(tx: btc.Transaction, index: number, allowedSighash?: AllowedSighashTypes[]): void;\n}\n\nexport interface BitcoinPayerBase {\n paymentType: PaymentTypes;\n network: BitcoinNetworkModes;\n address: string;\n keyOrigin: string;\n masterKeyFingerprint: string;\n publicKey: Uint8Array;\n}\n\nexport interface BitcoinNativeSegwitPayer extends BitcoinPayerBase {\n paymentType: 'p2wpkh';\n payment: P2Ret;\n}\n\nexport interface BitcoinTaprootPayer extends BitcoinPayerBase {\n paymentType: 'p2tr';\n payment: P2TROut;\n}\n\nexport type BitcoinPayer = BitcoinNativeSegwitPayer | BitcoinTaprootPayer;\n\nexport function initializeBitcoinAccountKeychainFromDescriptor(\n descriptor: string\n): BitcoinAccountKeychain {\n const { fingerprint, keyOrigin } = decomposeDescriptor(descriptor);\n return {\n descriptor,\n xpub: extractExtendedPublicKeyFromPolicy(descriptor),\n keyOrigin,\n masterKeyFingerprint: fingerprint,\n keychain: deriveKeychainFromXpub(extractExtendedPublicKeyFromPolicy(descriptor)),\n };\n}\n\nexport interface BitcoinPayerInfo {\n receive?: number;\n addressIndex: number;\n}\nexport function deriveBitcoinPayerFromAccount(descriptor: string, network: BitcoinNetworkModes) {\n const { fingerprint, keyOrigin } = decomposeDescriptor(descriptor);\n const accountKeychain = deriveKeychainFromXpub(extractExtendedPublicKeyFromPolicy(descriptor));\n const paymentType = inferPaymentTypeFromPath(keyOrigin) as SupportedPaymentType;\n\n if (accountKeychain.depth !== DerivationPathDepth.Account)\n throw new Error('Keychain passed is not an account');\n\n return ({ receive = 0, addressIndex }: BitcoinPayerInfo) => {\n const childKeychain = accountKeychain.deriveChild(receive).deriveChild(addressIndex);\n\n const derivePayerFromAccount = whenSupportedPaymentType(paymentType)({\n p2tr: getTaprootPaymentFromAddressIndex,\n p2wpkh: getNativeSegwitPaymentFromAddressIndex,\n });\n\n const payment = derivePayerFromAccount(childKeychain, network);\n\n return {\n keyOrigin: appendAddressIndexToPath(keyOrigin, 0),\n masterKeyFingerprint: fingerprint,\n paymentType,\n network,\n payment,\n get address() {\n if (!payment.address) throw new Error('Payment address could not be derived');\n return payment.address;\n },\n get publicKey() {\n if (!childKeychain.publicKey) throw new Error('Public key could not be derived');\n return childKeychain.publicKey;\n },\n };\n };\n}\n\ninterface BtcSignerDerivationPath {\n fingerprint: number;\n path: number[];\n}\nexport type BtcSignerDefaultBip32Derivation = [Uint8Array, BtcSignerDerivationPath];\nexport type BtcSignerTapBip32Derivation = [\n Uint8Array,\n { hashes: Uint8Array[]; der: BtcSignerDerivationPath },\n];\n\ntype BtcSignerBip32Derivation = BtcSignerDefaultBip32Derivation | BtcSignerTapBip32Derivation;\n\ntype PayerToBip32DerivationArgs = Pick<\n BitcoinPayer,\n 'masterKeyFingerprint' | 'keyOrigin' | 'publicKey'\n>;\n\n/**\n * @example\n * ```ts\n * tx.addInput({\n * ...input,\n * bip32Derivation: [payerToBip32Derivation(payer)],\n * })\n * ```\n */\nexport function payerToBip32Derivation(\n args: PayerToBip32DerivationArgs\n): BtcSignerDefaultBip32Derivation {\n return [\n args.publicKey,\n {\n fingerprint: hexToNumber(args.masterKeyFingerprint),\n path: btc.bip32Path(keyOriginToDerivationPath(args.keyOrigin)),\n },\n ];\n}\n\n/**\n * @example\n * ```ts\n * tx.addInput({\n * ...input,\n * tapBip32Derivation: [payerToTapBip32Derivation(payer)],\n * })\n * ```\n */\nexport function payerToTapBip32Derivation(\n args: PayerToBip32DerivationArgs\n): BtcSignerTapBip32Derivation {\n return [\n // TODO: @kyranjamie to default to schnoor when TR so conversion isn't\n // necessary here?\n ecdsaPublicKeyToSchnorr(args.publicKey),\n {\n hashes: [],\n der: {\n fingerprint: hexToNumber(args.masterKeyFingerprint),\n path: btc.bip32Path(keyOriginToDerivationPath(args.keyOrigin)),\n },\n },\n ];\n}\n\n/**\n * @description\n * Turns key format from @scure/btc-signer lib back into key origin string\n * @example\n * ```ts\n * const [inputOne] = getPsbtTxInputs(tx);\n * const keyOrigin = serializeKeyOrigin(inputOne.bip32Derivation[0][1]);\n * ```\n */\nexport function serializeKeyOrigin({ fingerprint, path }: BtcSignerDerivationPath) {\n const values = path.map(num => (num >= HARDENED_OFFSET ? num - HARDENED_OFFSET + \"'\" : num));\n return `${toHexString(fingerprint)}/${values.join('/')}`;\n}\n\n/**\n * @description\n * Of a given set of a `tx.input`s bip32 derivation paths from\n * `@scure/btc-signer`, serialize the paths back to the string format used\n * internally\n */\nexport function extractRequiredKeyOrigins(derivation: BtcSignerBip32Derivation[]) {\n return derivation.map(([_pubkey, path]) =>\n serializeKeyOrigin('hashes' in path ? path.der : path)\n );\n}\n","import { ripemd160 } from '@noble/hashes/ripemd160';\nimport { sha256 } from '@noble/hashes/sha256';\nimport { base58check } from '@scure/base';\n\nimport { deriveBip39SeedFromMnemonic, deriveRootBip32Keychain } from '@leather.io/crypto';\nimport { NetworkModes } from '@leather.io/models';\n\n/**\n * @deprecated\n * Use `deriveBip39MnemonicFromSeed` from `@leather.io/crypto`\n */\nexport const deriveBtcBip49SeedFromMnemonic = deriveBip39SeedFromMnemonic;\n\n/**\n * @deprecated\n * Use `deriveRootBip32Keychain` from `@leather.io/crypto`\n */\nexport const deriveRootBtcKeychain = deriveRootBip32Keychain;\n\nexport function decodeCompressedWifPrivateKey(key: string) {\n // https://en.bitcoinwiki.org/wiki/Wallet_import_format\n // Decode Compressed WIF format private key\n const compressedWifFormatPrivateKey = base58check(sha256).decode(key);\n // Drop leading network byte, trailing public key SEC format byte\n return compressedWifFormatPrivateKey.slice(1, compressedWifFormatPrivateKey.length - 1);\n}\n\n// https://en.bitcoin.it/wiki/List_of_address_prefixes\nconst payToScriptHashMainnetPrefix = 0x05;\nexport const payToScriptHashTestnetPrefix = 0xc4;\n\nconst payToScriptHashPrefixMap: Record<NetworkModes, number> = {\n mainnet: payToScriptHashMainnetPrefix,\n testnet: payToScriptHashTestnetPrefix,\n};\n\nfunction hash160(input: Uint8Array) {\n return ripemd160(sha256(input));\n}\n\nexport function makePayToScriptHashKeyHash(publicKey: Uint8Array) {\n return hash160(publicKey);\n}\n\nexport function makePayToScriptHashAddressBytes(keyHash: Uint8Array) {\n const redeemScript = Uint8Array.from([\n ...Uint8Array.of(0x00),\n ...Uint8Array.of(keyHash.length),\n ...keyHash,\n ]);\n return hash160(redeemScript);\n}\n\nexport function makePayToScriptHashAddress(addressBytes: Uint8Array, network: NetworkModes) {\n const networkByte = payToScriptHashPrefixMap[network];\n const addressWithPrefix = Uint8Array.from([networkByte, ...addressBytes]);\n return base58check(sha256).encode(addressWithPrefix);\n}\n\nexport function publicKeyToPayToScriptHashAddress(publicKey: Uint8Array, network: NetworkModes) {\n const hash = makePayToScriptHashKeyHash(publicKey);\n const addrBytes = makePayToScriptHashAddressBytes(hash);\n return makePayToScriptHashAddress(addrBytes, network);\n}\n","import { HARDENED_OFFSET, HDKey } from '@scure/bip32';\n\nimport { createCounter } from '@leather.io/utils';\n\nimport {\n getNativeSegwitAddress,\n getTaprootAddress,\n inferNetworkFromAddress,\n inferPaymentTypeFromAddress,\n whenSupportedPaymentType,\n} from './bitcoin.utils';\nimport { makeTaprootAddressIndexDerivationPath } from './p2tr-address-gen';\nimport { makeNativeSegwitAddressIndexDerivationPath } from './p2wpkh-address-gen';\n\ninterface LookUpDerivationByAddressArgs {\n taprootXpub: string;\n nativeSegwitXpub: string;\n iterationLimit: number;\n}\nexport function lookupDerivationByAddress(args: LookUpDerivationByAddressArgs) {\n const { taprootXpub, nativeSegwitXpub, iterationLimit } = args;\n\n const taprootKeychain = HDKey.fromExtendedKey(taprootXpub);\n const nativeSegwitKeychain = HDKey.fromExtendedKey(nativeSegwitXpub);\n\n return (address: string) => {\n const network = inferNetworkFromAddress(address);\n const paymentType = inferPaymentTypeFromAddress(address);\n\n const accountIndex = whenSupportedPaymentType(paymentType)({\n p2tr: taprootKeychain.index - HARDENED_OFFSET,\n p2wpkh: nativeSegwitKeychain.index - HARDENED_OFFSET,\n });\n\n function getTaprootAddressAtIndex(index: number) {\n return getTaprootAddress({ index, keychain: taprootKeychain, network });\n }\n\n function getNativeSegwitAddressAtIndex(index: number) {\n return getNativeSegwitAddress({ index, keychain: nativeSegwitKeychain, network });\n }\n\n const paymentFn = whenSupportedPaymentType(paymentType)({\n p2tr: getTaprootAddressAtIndex,\n p2wpkh: getNativeSegwitAddressAtIndex,\n });\n\n const derivationPathFn = whenSupportedPaymentType(paymentType)({\n p2tr: makeTaprootAddressIndexDerivationPath,\n p2wpkh: makeNativeSegwitAddressIndexDerivationPath,\n });\n\n const count = createCounter();\n const t0 = performance.now();\n\n while (count.getValue() <= iterationLimit) {\n const currentIndex = count.getValue();\n\n const addressToCheck = paymentFn(currentIndex);\n\n if (addressToCheck !== address) {\n count.increment();\n continue;\n }\n\n const t1 = performance.now();\n\n return {\n status: 'success',\n duration: t1 - t0,\n path: derivationPathFn(network, accountIndex, currentIndex),\n } as const;\n }\n\n return { status: 'failure' } as const;\n };\n}\n","import { inferPaymentTypeFromAddress } from 'bitcoin.utils';\n\nimport { createMoney, sumNumbers } from '@leather.io/utils';\n\nimport { PsbtInput } from './psbt-inputs';\nimport { PsbtOutput } from './psbt-outputs';\n\nfunction calculateAddressInputsTotal(addresses: string[], inputs: PsbtInput[]) {\n const sumsByAddress = addresses.map(address =>\n inputs\n .filter(input => input.address === address)\n .map(input => input.value)\n .reduce((acc, curVal) => acc + curVal, 0)\n );\n\n return createMoney(sumNumbers(sumsByAddress), 'BTC');\n}\n\nfunction calculateAddressOutputsTotal(addresses: string[], outputs: PsbtOutput[]) {\n const sumsByAddress = addresses.map(address =>\n outputs\n .filter(output => output.address === address)\n .map(output => Number(output.value))\n .reduce((acc, curVal) => acc + curVal, 0)\n );\n return createMoney(sumNumbers(sumsByAddress), 'BTC');\n}\n\nfunction calculatePsbtInputsTotal(inputs: PsbtInput[]) {\n return createMoney(sumNumbers(inputs.map(input => input.value)), 'BTC');\n}\n\nfunction calculatePsbtOutputsTotal(outputs: PsbtOutput[]) {\n return createMoney(sumNumbers(outputs.map(output => output.value)), 'BTC');\n}\n\ninterface GetPsbtTotalsProps {\n psbtAddresses: string[];\n parsedInputs: PsbtInput[];\n parsedOutputs: PsbtOutput[];\n}\nexport function getPsbtTotals({ psbtAddresses, parsedInputs, parsedOutputs }: GetPsbtTotalsProps) {\n const nativeSegwitAddresses = psbtAddresses.filter(\n addr => inferPaymentTypeFromAddress(addr) === 'p2wpkh'\n );\n const taprootAddresses = psbtAddresses.filter(\n addr => inferPaymentTypeFromAddress(addr) === 'p2tr'\n );\n\n return {\n inputsTotalNativeSegwit: calculateAddressInputsTotal(nativeSegwitAddresses, parsedInputs),\n inputsTotalTaproot: calculateAddressInputsTotal(taprootAddresses, parsedInputs),\n outputsTotalNativeSegwit: calculateAddressOutputsTotal(nativeSegwitAddresses, parsedOutputs),\n outputsTotalTaproot: calculateAddressOutputsTotal(taprootAddresses, parsedOutputs),\n psbtInputsTotal: calculatePsbtInputsTotal(parsedInputs),\n psbtOutputsTotal: calculatePsbtOutputsTotal(parsedOutputs),\n };\n}\n","import type { TransactionInput } from '@scure/btc-signer/psbt';\nimport { bytesToHex } from '@stacks/common';\nimport { getBtcSignerLibNetworkConfigByMode } from 'bitcoin.network';\nimport { getBitcoinInputAddress, getBitcoinInputValue } from 'bitcoin.utils';\n\nimport type { BitcoinNetworkModes, Inscription } from '@leather.io/models';\nimport { isDefined, isUndefined } from '@leather.io/utils';\n\nexport interface PsbtInput {\n address: string;\n index?: number;\n // TODO: inject inscription later on. getParsedInputs should be a pure function\n inscription?: Inscription;\n isMutable: boolean;\n toSign: boolean;\n txid: string;\n value: number;\n bip32Derivation: TransactionInput['bip32Derivation'];\n tapBip32Derivation: TransactionInput['tapBip32Derivation'];\n}\n\ninterface GetParsedInputsArgs {\n inputs: TransactionInput[];\n indexesToSign?: number[];\n networkMode: BitcoinNetworkModes;\n psbtAddresses: string[];\n}\n\ninterface GetParsedInputsResponse {\n isPsbtMutable: boolean;\n parsedInputs: PsbtInput[];\n}\nexport function getParsedInputs({\n inputs,\n indexesToSign,\n networkMode,\n psbtAddresses,\n}: GetParsedInputsArgs): GetParsedInputsResponse {\n const bitcoinNetwork = getBtcSignerLibNetworkConfigByMode(networkMode);\n\n const signAll = isUndefined(indexesToSign);\n const psbtInputs = inputs.map((input, i) => {\n const inputAddress = isDefined(input.index)\n ? getBitcoinInputAddress(input, bitcoinNetwork)\n : '';\n const isCurrentAddress = psbtAddresses.includes(inputAddress);\n // Flags when not signing ALL inputs/outputs (NONE, SINGLE, and ANYONECANPAY)\n const canChange =\n isCurrentAddress &&\n !(!input.sighashType || input.sighashType === 0 || input.sighashType === 1);\n // Should we check the sighashType here before it gets to the signing lib?\n const toSignAll = isCurrentAddress && signAll;\n const toSignIndex = isCurrentAddress && !signAll && indexesToSign.includes(i);\n\n return {\n address: inputAddress,\n index: input.index,\n bip32Derivation: input.bip32Derivation,\n tapBip32Derivation: input.tapBip32Derivation,\n // inscription: inscriptions[i],\n isMutable: canChange,\n toSign: toSignAll || toSignIndex,\n txid: input.txid ? bytesToHex(input.txid) : '',\n value: isDefined(input.index) ? getBitcoinInputValue(input) : 0,\n };\n });\n\n const isPsbtMutable = psbtInputs.some(input => input.isMutable);\n\n return { isPsbtMutable, parsedInputs: psbtInputs };\n}\n","import type { TransactionOutput } from '@scure/btc-signer/psbt';\nimport { getBtcSignerLibNetworkConfigByMode } from 'bitcoin.network';\nimport { getAddressFromOutScript } from 'bitcoin.utils';\n\nimport type { BitcoinNetworkModes } from '@leather.io/models';\nimport { isDefined, isUndefined } from '@leather.io/utils';\n\nexport interface PsbtOutput {\n address: string;\n isMutable: boolean;\n toSign: boolean;\n value: number;\n}\n\ninterface GetParsedOutputsArgs {\n isPsbtMutable: boolean;\n outputs: TransactionOutput[];\n networkMode: BitcoinNetworkModes;\n psbtAddresses: string[];\n}\n\nexport function getParsedOutputs({\n isPsbtMutable,\n outputs,\n networkMode,\n psbtAddresses,\n}: GetParsedOutputsArgs): PsbtOutput[] {\n const bitcoinNetwork = getBtcSignerLibNetworkConfigByMode(networkMode);\n\n return outputs\n .map(output => {\n if (isUndefined(output.script)) {\n // TODO: handle error here\n // logger.error('Output has no script');\n return;\n }\n const outputAddress = getAddressFromOutScript(output.script, bitcoinNetwork);\n\n const isCurrentAddress = psbtAddresses.includes(outputAddress);\n\n return {\n address: outputAddress,\n isMutable: isPsbtMutable,\n toSign: isCurrentAddress,\n value: Number(output.amount),\n };\n })\n .filter(isDefined);\n}\n","import { getPsbtTxInputs, getPsbtTxOutputs } from 'bitcoin.utils';\n\nimport { BitcoinNetworkModes } from '@leather.io/models';\nimport { createMoney, subtractMoney } from '@leather.io/utils';\n\nimport { getParsedInputs } from './psbt-inputs';\nimport { getParsedOutputs } from './psbt-outputs';\nimport { getPsbtTotals } from './psbt-totals';\nimport { getPsbtAsTransaction } from './utils';\n\ninterface GetPsbtDetailsArgs {\n psbtHex: string;\n psbtAddresses: string[];\n networkMode: BitcoinNetworkModes;\n indexesToSign?: number[];\n}\nexport function getPsbtDetails({\n psbtHex,\n networkMode,\n indexesToSign,\n psbtAddresses,\n}: GetPsbtDetailsArgs) {\n const tx = getPsbtAsTransaction(psbtHex);\n const inputs = getPsbtTxInputs(tx);\n const outputs = getPsbtTxOutputs(tx);\n\n const { isPsbtMutable, parsedInputs } = getParsedInputs({\n inputs,\n indexesToSign,\n networkMode,\n psbtAddresses,\n });\n const parsedOutputs = getParsedOutputs({ isPsbtMutable, outputs, networkMode, psbtAddresses });\n\n const {\n inputsTotalNativeSegwit,\n inputsTotalTaproot,\n outputsTotalNativeSegwit,\n outputsTotalTaproot,\n psbtInputsTotal,\n psbtOutputsTotal,\n } = getPsbtTotals({\n psbtAddresses,\n parsedInputs,\n parsedOutputs,\n });\n function getFee() {\n if (psbtInputsTotal.amount.isGreaterThan(psbtOutputsTotal.amount))\n return subtractMoney(psbtInputsTotal, psbtOutputsTotal);\n return createMoney(0, 'BTC');\n }\n return {\n addressNativeSegwitTotal: subtractMoney(inputsTotalNativeSegwit, outputsTotalNativeSegwit),\n addressTaprootTotal: subtractMoney(inputsTotalTaproot, outputsTotalTaproot),\n fee: getFee(),\n isPsbtMutable,\n psbtInputs: parsedInputs,\n psbtOutputs: parsedOutputs,\n };\n}\n","import { hexToBytes } from '@noble/hashes/utils';\nimport * as btc from '@scure/btc-signer';\nimport { RawPSBTV0, RawPSBTV2 } from '@scure/btc-signer/psbt';\n\nimport { isString } from '@leather.io/utils';\n\nexport type RawPsbt = ReturnType<typeof RawPSBTV0.decode>;\n\nexport function getPsbtAsTransaction(psbt: string | Uint8Array) {\n const bytes = isString(psbt) ? hexToBytes(psbt) : psbt;\n return btc.Transaction.fromPSBT(bytes);\n}\n\nexport function getRawPsbt(psbt: string | Uint8Array): ReturnType<typeof RawPSBTV0.decode> {\n const bytes = isString(psbt) ? hexToBytes(psbt) : psbt;\n try {\n return RawPSBTV0.decode(bytes);\n } catch (e1) {\n try {\n return RawPSBTV2.decode(bytes);\n } catch (e2) {\n throw new Error(`Unable to decode PSBT, ${e1 ?? e2}`);\n }\n }\n}\n"],"mappings":"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","names":["hexToBytes","btc","DerivationPathDepth","btc","DerivationPathDepth","DerivationPathDepth","DerivationPathDepth","script","address","hexToBytes","bitcoin","address","script","BigNumber","BigNumber","BigNumber","address","BigNumber","BigNumber","validate","BTC_P2WPKH_DUST_AMOUNT","createMoney","BitcoinErrorMessage","validate","address","createMoney","BigNumber","BTC_P2WPKH_DUST_AMOUNT","amount","hexToBytes","btc","p2wpkh","hexToBytes","btc","DerivationPathDepth","DerivationPathDepth","sha256","HARDENED_OFFSET","HDKey","HDKey","address","HARDENED_OFFSET","createMoney","sumNumbers","address","isDefined","isDefined","isUndefined","createMoney","hexToBytes","btc","isString","createMoney"]}
1
+ {"version":3,"sources":["../src/bip322/bip322-utils.ts","../src/bitcoin.utils.ts","../src/bitcoin.network.ts","../src/p2tr-address-gen.ts","../src/p2wpkh-address-gen.ts","../src/bip322/sign-message-bip322-bitcoinjs.ts","../src/coin-selection/calculate-max-spend.ts","../src/coin-selection/coin-selection.utils.ts","../src/btc-size-fee-estimator.ts","../src/coin-selection/coin-selection.ts","../src/bitcoin-error.ts","../src/fees/bitcoin-fees.ts","../src/transactions/generate-unsigned-transaction.ts","../src/bitcoin-signer.ts","../src/p2wsh-p2sh-address-gen.ts","../src/lookup-derivation-by-address.ts","../src/psbt/psbt-totals.ts","../src/psbt/psbt-inputs.ts","../src/psbt/psbt-outputs.ts","../src/psbt/psbt-details.ts","../src/psbt/utils.ts"],"sourcesContent":["import ecc from '@bitcoinerlab/secp256k1';\nimport { sha256 } from '@noble/hashes/sha256';\nimport { hexToBytes, utf8ToBytes } from '@stacks/common';\nimport * as bitcoin from 'bitcoinjs-lib';\nimport { ECPairFactory } from 'ecpair';\nimport { encode } from 'varuint-bitcoin';\n\nimport { PaymentTypes } from '@leather.io/rpc';\nimport { isString } from '@leather.io/utils';\n\nimport { toXOnly } from '../bitcoin.utils';\n\nconst bip322MessageTag = 'BIP0322-signed-message';\n\nconst ECPair = ECPairFactory(ecc);\nbitcoin.initEccLib(ecc);\n\nexport function ecPairFromPrivateKey(key: Uint8Array) {\n return ECPair.fromPrivateKey(Buffer.from(key));\n}\n\n// See tagged hashes section of BIP-340\n// https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki#design\nconst messageTagHash = Uint8Array.from([\n ...sha256(utf8ToBytes(bip322MessageTag)),\n ...sha256(utf8ToBytes(bip322MessageTag)),\n]);\n\nexport function hashBip322Message(message: Uint8Array | string) {\n return sha256(\n Uint8Array.from([...messageTagHash, ...(isString(message) ? utf8ToBytes(message) : message)])\n );\n}\n\nexport const bip322TransactionToSignValues = {\n prevoutHash: hexToBytes('0000000000000000000000000000000000000000000000000000000000000000'),\n prevoutIndex: 0xffffffff,\n sequence: 0,\n};\n\nfunction encodeVarString(b: Buffer) {\n return Buffer.concat([encode(b.byteLength), b]);\n}\n\nconst supportedMessageSigningPaymentTypes: PaymentTypes[] = ['p2wpkh', 'p2tr'];\n\nexport function isSupportedMessageSigningPaymentType(paymentType: string) {\n return supportedMessageSigningPaymentTypes.includes(paymentType as PaymentTypes);\n}\n\n/**\n * Encode witness data for a BIP322 message\n * TODO: Refactor to remove `Buffer` use\n */\nexport function encodeMessageWitnessData(witnessArray: Buffer[]) {\n const len = encode(witnessArray.length);\n return Buffer.concat([len, ...witnessArray.map(witness => encodeVarString(witness))]);\n}\n\nfunction tapTweakHash(pubKey: Buffer, h: Buffer | undefined): Buffer {\n return bitcoin.crypto.taggedHash('TapTweak', Buffer.concat(h ? [pubKey, h] : [pubKey]));\n}\n\nexport function tweakSigner(signer: bitcoin.Signer, opts: any = {}): bitcoin.Signer {\n // @ts-expect-error privateKey exists on signer\n let privateKey: Uint8Array | undefined = signer.privateKey;\n if (!privateKey) {\n throw new Error('Private key is required for tweaking signer!');\n }\n if (signer.publicKey[0] === 3) {\n privateKey = ecc.privateNegate(privateKey);\n }\n\n const tweakedPrivateKey = ecc.privateAdd(\n privateKey,\n tapTweakHash(toXOnly(signer.publicKey), opts.tweakHash)\n );\n if (!tweakedPrivateKey) {\n throw new Error('Invalid tweaked private key!');\n }\n\n return ECPair.fromPrivateKey(Buffer.from(tweakedPrivateKey), {\n network: opts.network,\n });\n}\n","import { hexToBytes } from '@noble/hashes/utils';\nimport { HDKey, Versions } from '@scure/bip32';\nimport { mnemonicToSeedSync } from '@scure/bip39';\nimport * as btc from '@scure/btc-signer';\nimport { TransactionInput, TransactionOutput } from '@scure/btc-signer/psbt';\n\nimport {\n DerivationPathDepth,\n extractAccountIndexFromPath,\n extractPurposeFromPath,\n} from '@leather.io/crypto';\nimport { BitcoinNetworkModes, NetworkModes } from '@leather.io/models';\nimport type { PaymentTypes } from '@leather.io/rpc';\nimport { defaultWalletKeyId, isDefined, whenNetwork } from '@leather.io/utils';\n\nimport { BtcSignerNetwork, getBtcSignerLibNetworkConfigByMode } from './bitcoin.network';\nimport { getTaprootPayment } from './p2tr-address-gen';\nimport { getNativeSegwitPaymentFromAddressIndex } from './p2wpkh-address-gen';\n\nexport interface BitcoinAccount {\n type: PaymentTypes;\n derivationPath: string;\n keychain: HDKey;\n accountIndex: number;\n network: BitcoinNetworkModes;\n}\nexport function initBitcoinAccount(derivationPath: string, policy: string): BitcoinAccount {\n const xpub = extractExtendedPublicKeyFromPolicy(policy);\n const network = inferNetworkFromPath(derivationPath);\n return {\n keychain: HDKey.fromExtendedKey(xpub, getHdKeyVersionsFromNetwork(network)),\n network,\n derivationPath,\n type: inferPaymentTypeFromPath(derivationPath),\n accountIndex: extractAccountIndexFromPath(derivationPath),\n };\n}\n\n/**\n * Represents a map of `BitcoinNetworkModes` to `NetworkModes`. While Bitcoin\n * has a number of networks, its often only necessary to consider the higher\n * level concept of mainnet and testnet\n */\nexport const bitcoinNetworkToCoreNetworkMap: Record<BitcoinNetworkModes, NetworkModes> = {\n mainnet: 'mainnet',\n testnet: 'testnet',\n regtest: 'testnet',\n signet: 'testnet',\n};\nexport function bitcoinNetworkModeToCoreNetworkMode(mode: BitcoinNetworkModes) {\n return bitcoinNetworkToCoreNetworkMap[mode];\n}\n\ntype BitcoinNetworkMap<T> = Record<BitcoinNetworkModes, T>;\n\nexport function whenBitcoinNetwork(mode: BitcoinNetworkModes) {\n return <T extends BitcoinNetworkMap<unknown>>(networkMap: T) =>\n networkMap[mode] as T[BitcoinNetworkModes];\n}\n\n/**\n * Map representing the \"Coin Type\" section of a derivation path.\n * Consider example below, Coin type is one, thus testnet\n * @example\n * `m/86'/1'/0'/0/0`\n */\nexport const coinTypeMap: Record<NetworkModes, 0 | 1> = {\n mainnet: 0,\n testnet: 1,\n};\n\nexport function getBitcoinCoinTypeIndexByNetwork(network: BitcoinNetworkModes) {\n return coinTypeMap[bitcoinNetworkModeToCoreNetworkMode(network)];\n}\n\nexport function deriveAddressIndexKeychainFromAccount(keychain: HDKey) {\n if (keychain.depth !== DerivationPathDepth.Account)\n throw new Error('Keychain passed is not an account');\n\n return (index: number) => keychain.deriveChild(0).deriveChild(index);\n}\n\nexport function deriveAddressIndexZeroFromAccount(keychain: HDKey) {\n return deriveAddressIndexKeychainFromAccount(keychain)(0);\n}\n\nexport const ecdsaPublicKeyLength = 33;\n\nexport function ecdsaPublicKeyToSchnorr(pubKey: Uint8Array) {\n if (pubKey.byteLength !== ecdsaPublicKeyLength) throw new Error('Invalid public key length');\n return pubKey.slice(1);\n}\n\n// Basically same as above, to remove\nexport const toXOnly = (pubKey: Buffer) => (pubKey.length === 32 ? pubKey : pubKey.subarray(1, 33));\n\nexport function decodeBitcoinTx(tx: string): ReturnType<typeof btc.RawTx.decode> {\n return btc.RawTx.decode(hexToBytes(tx));\n}\n\nexport function getAddressFromOutScript(script: Uint8Array, bitcoinNetwork: BtcSignerNetwork) {\n const outputScript = btc.OutScript.decode(script);\n\n switch (outputScript.type) {\n case 'pkh':\n case 'sh':\n case 'wpkh':\n case 'wsh':\n return btc.Address(bitcoinNetwork).encode({\n type: outputScript.type,\n hash: outputScript.hash,\n });\n case 'tr':\n return btc.Address(bitcoinNetwork).encode({\n type: outputScript.type,\n pubkey: outputScript.pubkey,\n });\n case 'ms':\n return btc.p2ms(outputScript.m, outputScript.pubkeys).address ?? '';\n case 'pk':\n return btc.p2pk(outputScript.pubkey, bitcoinNetwork).address ?? '';\n case 'unknown':\n return 'unknown';\n case 'tr_ms':\n case 'tr_ns':\n default:\n return '';\n }\n}\n\n/**\n * Payment type identifiers, as described by `@scure/btc-signer` library\n */\nexport type BtcSignerLibPaymentTypeIdentifers = 'wpkh' | 'wsh' | 'tr' | 'pkh' | 'sh';\n\nexport const paymentTypeMap: Record<BtcSignerLibPaymentTypeIdentifers, PaymentTypes> = {\n wpkh: 'p2wpkh',\n wsh: 'p2wpkh-p2sh',\n tr: 'p2tr',\n pkh: 'p2pkh',\n sh: 'p2sh',\n};\n\nexport function btcSignerLibPaymentTypeToPaymentTypeMap(\n payment: BtcSignerLibPaymentTypeIdentifers\n) {\n return paymentTypeMap[payment];\n}\n\nexport function isBtcSignerLibPaymentType(\n payment: string\n): payment is BtcSignerLibPaymentTypeIdentifers {\n return payment in paymentTypeMap;\n}\n\nexport function parseKnownPaymentType(payment: BtcSignerLibPaymentTypeIdentifers | PaymentTypes) {\n return isBtcSignerLibPaymentType(payment)\n ? btcSignerLibPaymentTypeToPaymentTypeMap(payment)\n : payment;\n}\n\nexport type PaymentTypeMap<T> = Record<PaymentTypes, T>;\nexport function whenPaymentType(mode: PaymentTypes | BtcSignerLibPaymentTypeIdentifers) {\n return <T>(paymentMap: PaymentTypeMap<T>): T => paymentMap[parseKnownPaymentType(mode)];\n}\n\nexport type SupportedPaymentType = 'p2wpkh' | 'p2tr';\nexport type SupportedPaymentTypeMap<T> = Record<SupportedPaymentType, T>;\nexport function whenSupportedPaymentType(mode: SupportedPaymentType) {\n return <T>(paymentMap: SupportedPaymentTypeMap<T>): T => paymentMap[mode];\n}\n\n/**\n * Infers the Bitcoin payment type from the derivation path.\n * Below we see path has 86 in it, per convention, this refers to taproot payments\n * @example\n * `m/86'/1'/0'/0/0`\n */\nexport function inferPaymentTypeFromPath(path: string): PaymentTypes {\n const purpose = extractPurposeFromPath(path);\n switch (purpose) {\n case 84:\n return 'p2wpkh';\n case 86:\n return 'p2tr';\n case 44:\n return 'p2pkh';\n default:\n throw new Error(`Unable to infer payment type from purpose=${purpose}`);\n }\n}\n\nexport function inferNetworkFromPath(path: string): NetworkModes {\n return path.split('/')[2].startsWith('0') ? 'mainnet' : 'testnet';\n}\n\nexport function extractExtendedPublicKeyFromPolicy(policy: string) {\n return policy.split(']')[1];\n}\n\nexport function createWalletIdDecoratedPath(policy: string, walletId: string) {\n return policy.split(']')[0].replace('[', '').replace('m', walletId);\n}\n\n// Primarily used to get the correct `Version` when passing Ledger Bitcoin\n// extended public keys to the HDKey constructor\nexport function getHdKeyVersionsFromNetwork(network: NetworkModes) {\n return whenNetwork(network)({\n mainnet: undefined,\n testnet: {\n private: 0x00000000,\n public: 0x043587cf,\n } as Versions,\n });\n}\n\nexport function getBitcoinInputAddress(input: TransactionInput, bitcoinNetwork: BtcSignerNetwork) {\n if (isDefined(input.witnessUtxo))\n return getAddressFromOutScript(input.witnessUtxo.script, bitcoinNetwork);\n if (isDefined(input.nonWitnessUtxo) && isDefined(input.index))\n return getAddressFromOutScript(\n input.nonWitnessUtxo.outputs[input.index]?.script,\n bitcoinNetwork\n );\n return '';\n}\n\nexport function getInputPaymentType(\n input: TransactionInput,\n network: BitcoinNetworkModes\n): PaymentTypes {\n const address = getBitcoinInputAddress(input, getBtcSignerLibNetworkConfigByMode(network));\n if (address === '') throw new Error('Input address cannot be empty');\n if (address.startsWith('bc1p') || address.startsWith('tb1p') || address.startsWith('bcrt1p'))\n return 'p2tr';\n if (address.startsWith('bc1q') || address.startsWith('tb1q') || address.startsWith('bcrt1q'))\n return 'p2wpkh';\n throw new Error('Unable to infer payment type from input address');\n}\n\n// Ledger wallets are keyed by their derivation path. To reuse the look up logic\n// between payment types, this factory fn accepts a fn that generates the path\nexport function lookUpLedgerKeysByPath(\n getDerivationPath: (network: BitcoinNetworkModes, accountIndex: number) => string\n) {\n return (\n ledgerKeyMap: Record<string, { policy: string } | undefined>,\n network: BitcoinNetworkModes\n ) =>\n (accountIndex: number) => {\n const path = getDerivationPath(network, accountIndex);\n // Single wallet mode, hardcoded default walletId\n const account = ledgerKeyMap[path.replace('m', defaultWalletKeyId)];\n if (!account) return;\n return initBitcoinAccount(path, account.policy);\n };\n}\n\ninterface GetAddressArgs {\n index: number;\n keychain?: HDKey;\n network: BitcoinNetworkModes;\n}\n\nexport function getTaprootAddress({ index, keychain, network }: GetAddressArgs) {\n if (!keychain) throw new Error('Expected keychain to be provided');\n\n if (keychain.depth !== DerivationPathDepth.Account)\n throw new Error('Expects keychain to be on the account index');\n\n const addressIndex = deriveAddressIndexKeychainFromAccount(keychain)(index);\n\n if (!addressIndex.publicKey) throw new Error('Expected publicKey to be defined');\n\n const payment = getTaprootPayment(addressIndex.publicKey, network);\n\n if (!payment.address) throw new Error('Expected address to be defined');\n return payment.address;\n}\n\nexport function getNativeSegwitAddress({ index, keychain, network }: GetAddressArgs) {\n if (!keychain) throw new Error('Expected keychain to be provided');\n\n if (keychain.depth !== DerivationPathDepth.Account)\n throw new Error('Expects keychain to be on the account index');\n\n const addressIndex = deriveAddressIndexKeychainFromAccount(keychain)(index);\n\n if (!addressIndex.publicKey) throw new Error('Expected publicKey to be defined');\n\n const payment = getNativeSegwitPaymentFromAddressIndex(addressIndex, network);\n\n if (!payment.address) throw new Error('Expected address to be defined');\n return payment.address;\n}\n\n/**\n * @deprecated\n * Use `deriveRootBip32Keychain` in `@leather.io/crypto` instead\n */\nexport function mnemonicToRootNode(secretKey: string) {\n const seed = mnemonicToSeedSync(secretKey);\n return HDKey.fromMasterSeed(seed);\n}\n\nexport function getPsbtTxInputs(psbtTx: btc.Transaction): TransactionInput[] {\n const inputsLength = psbtTx.inputsLength;\n const inputs: TransactionInput[] = [];\n for (let i = 0; i < inputsLength; i++) inputs.push(psbtTx.getInput(i));\n return inputs;\n}\n\nexport function getPsbtTxOutputs(psbtTx: btc.Transaction): TransactionOutput[] {\n const outputsLength = psbtTx.outputsLength;\n const outputs: TransactionOutput[] = [];\n for (let i = 0; i < outputsLength; i++) outputs.push(psbtTx.getOutput(i));\n return outputs;\n}\n\nexport function inferNetworkFromAddress(address: string): BitcoinNetworkModes {\n if (address.startsWith('bc1')) return 'mainnet';\n if (address.startsWith('tb1')) return 'testnet';\n if (address.startsWith('bcrt1')) return 'regtest';\n\n const firstChar = address[0];\n\n if (firstChar === '1' || firstChar === '3') return 'mainnet';\n if (firstChar === 'm' || firstChar === 'n') return 'testnet';\n if (firstChar === '2') return 'testnet';\n\n throw new Error('Invalid or unsupported Bitcoin address format');\n}\n\nexport function inferPaymentTypeFromAddress(address: string): SupportedPaymentType {\n if (address.startsWith('bc1q') || address.startsWith('tb1q') || address.startsWith('bcrt1q'))\n return 'p2wpkh';\n\n if (address.startsWith('bc1p') || address.startsWith('tb1p') || address.startsWith('bcrt1p'))\n return 'p2tr';\n\n throw new Error('Unable to infer payment type from address');\n}\n\nexport function getBitcoinInputValue(input: TransactionInput) {\n if (isDefined(input.witnessUtxo)) return Number(input.witnessUtxo.amount);\n if (isDefined(input.nonWitnessUtxo) && isDefined(input.index))\n return Number(input.nonWitnessUtxo.outputs[input.index]?.amount);\n // logger.warn('Unable to find either `witnessUtxo` or `nonWitnessUtxo` in input. Defaulting to 0');\n return 0;\n}\n","import * as bitcoinJs from 'bitcoinjs-lib';\n\nimport { BitcoinNetworkModes } from '@leather.io/models';\n\n// See this PR https://github.com/paulmillr/@scure/btc-signer/pull/15\n// Atttempting to add these directly to the library\nexport interface BtcSignerNetwork {\n bech32: string;\n pubKeyHash: number;\n scriptHash: number;\n wif: number;\n}\n\nconst bitcoinMainnet: BtcSignerNetwork = {\n bech32: 'bc',\n pubKeyHash: 0x00,\n scriptHash: 0x05,\n wif: 0x80,\n};\n\nconst bitcoinTestnet: BtcSignerNetwork = {\n bech32: 'tb',\n pubKeyHash: 0x6f,\n scriptHash: 0xc4,\n wif: 0xef,\n};\n\nconst bitcoinRegtest: BtcSignerNetwork = {\n bech32: 'bcrt',\n pubKeyHash: 0x6f,\n scriptHash: 0xc4,\n wif: 0xef,\n};\n\nconst btcSignerLibNetworks: Record<BitcoinNetworkModes, BtcSignerNetwork> = {\n mainnet: bitcoinMainnet,\n testnet: bitcoinTestnet,\n regtest: bitcoinRegtest,\n // Signet originally was going to have its own prefix but authors decided to\n // copy testnet\n signet: bitcoinTestnet,\n};\n\nexport function getBtcSignerLibNetworkConfigByMode(network: BitcoinNetworkModes) {\n return btcSignerLibNetworks[network];\n}\n\nconst bitcoinJsLibNetworks: Record<BitcoinNetworkModes, bitcoinJs.Network> = {\n mainnet: bitcoinJs.networks.bitcoin,\n testnet: bitcoinJs.networks.testnet,\n regtest: bitcoinJs.networks.regtest,\n signet: bitcoinJs.networks.testnet,\n};\n\nexport function getBitcoinJsLibNetworkConfigByMode(network: BitcoinNetworkModes) {\n return bitcoinJsLibNetworks[network];\n}\n","import { HDKey } from '@scure/bip32';\nimport * as btc from '@scure/btc-signer';\n\nimport { DerivationPathDepth } from '@leather.io/crypto';\nimport { BitcoinNetworkModes } from '@leather.io/models';\n\nimport { getBtcSignerLibNetworkConfigByMode } from './bitcoin.network';\nimport {\n BitcoinAccount,\n deriveAddressIndexZeroFromAccount,\n ecdsaPublicKeyToSchnorr,\n getBitcoinCoinTypeIndexByNetwork,\n} from './bitcoin.utils';\n\nexport function makeTaprootAccountDerivationPath(\n network: BitcoinNetworkModes,\n accountIndex: number\n) {\n return `m/86'/${getBitcoinCoinTypeIndexByNetwork(network)}'/${accountIndex}'`;\n}\n/** @deprecated Use makeTaprootAccountDerivationPath */\nexport const getTaprootAccountDerivationPath = makeTaprootAccountDerivationPath;\n\nexport function makeTaprootAddressIndexDerivationPath(\n network: BitcoinNetworkModes,\n accountIndex: number,\n addressIndex: number\n) {\n return makeTaprootAccountDerivationPath(network, accountIndex) + `/0/${addressIndex}`;\n}\n/** @deprecated Use makeTaprootAddressIndexDerivationPath */\nexport const getTaprootAddressIndexDerivationPath = makeTaprootAddressIndexDerivationPath;\n\nexport function deriveTaprootAccount(keychain: HDKey, network: BitcoinNetworkModes) {\n if (keychain.depth !== DerivationPathDepth.Root)\n throw new Error('Keychain passed is not an account');\n\n return (accountIndex: number): BitcoinAccount => ({\n type: 'p2tr',\n network,\n accountIndex,\n derivationPath: makeTaprootAccountDerivationPath(network, accountIndex),\n keychain: keychain.derive(makeTaprootAccountDerivationPath(network, accountIndex)),\n });\n}\n\nexport function getTaprootPayment(publicKey: Uint8Array, network: BitcoinNetworkModes) {\n return btc.p2tr(\n ecdsaPublicKeyToSchnorr(publicKey),\n undefined,\n getBtcSignerLibNetworkConfigByMode(network),\n true // allow unknown outputs\n );\n}\n\nexport function getTaprootPaymentFromAddressIndex(keychain: HDKey, network: BitcoinNetworkModes) {\n if (keychain.depth !== DerivationPathDepth.AddressIndex)\n throw new Error('Keychain passed is not an address index');\n\n if (!keychain.publicKey) throw new Error('Keychain has no public key');\n\n return getTaprootPayment(keychain.publicKey, network);\n}\n\ninterface DeriveTaprootReceiveAddressIndexArgs {\n keychain: HDKey;\n network: BitcoinNetworkModes;\n}\nexport function deriveTaprootReceiveAddressIndexZero({\n keychain,\n network,\n}: DeriveTaprootReceiveAddressIndexArgs) {\n const zeroAddressIndex = deriveAddressIndexZeroFromAccount(keychain);\n return {\n keychain: zeroAddressIndex,\n payment: getTaprootPaymentFromAddressIndex(zeroAddressIndex, network),\n };\n}\n","import { HDKey } from '@scure/bip32';\nimport * as btc from '@scure/btc-signer';\n\nimport { DerivationPathDepth } from '@leather.io/crypto';\nimport { BitcoinNetworkModes } from '@leather.io/models';\n\nimport { getBtcSignerLibNetworkConfigByMode } from './bitcoin.network';\nimport {\n BitcoinAccount,\n deriveAddressIndexZeroFromAccount,\n getBitcoinCoinTypeIndexByNetwork,\n} from './bitcoin.utils';\n\nexport function makeNativeSegwitAccountDerivationPath(\n network: BitcoinNetworkModes,\n accountIndex: number\n) {\n return `m/84'/${getBitcoinCoinTypeIndexByNetwork(network)}'/${accountIndex}'`;\n}\n\n/** @deprecated Use makeNativeSegwitAccountDerivationPath */\nexport const getNativeSegwitAccountDerivationPath = makeNativeSegwitAccountDerivationPath;\n\nexport function makeNativeSegwitAddressIndexDerivationPath(\n network: BitcoinNetworkModes,\n accountIndex: number,\n addressIndex: number\n) {\n return makeNativeSegwitAccountDerivationPath(network, accountIndex) + `/0/${addressIndex}`;\n}\n\n/** @deprecated Use makeNativeSegwitAddressIndexDerivationPath */\nexport const getNativeSegwitAddressIndexDerivationPath = makeNativeSegwitAddressIndexDerivationPath;\n\nexport function deriveNativeSegwitAccountFromRootKeychain(\n keychain: HDKey,\n network: BitcoinNetworkModes\n) {\n if (keychain.depth !== DerivationPathDepth.Root) throw new Error('Keychain passed is not a root');\n return (accountIndex: number): BitcoinAccount => ({\n type: 'p2wpkh',\n network,\n accountIndex,\n derivationPath: makeNativeSegwitAccountDerivationPath(network, accountIndex),\n keychain: keychain.derive(makeNativeSegwitAccountDerivationPath(network, accountIndex)),\n });\n}\n\nexport function getNativeSegwitPaymentFromAddressIndex(\n keychain: HDKey,\n network: BitcoinNetworkModes\n) {\n if (keychain.depth !== DerivationPathDepth.AddressIndex)\n throw new Error('Keychain passed is not an address index');\n\n if (!keychain.publicKey) throw new Error('Keychain does not have a public key');\n\n return btc.p2wpkh(keychain.publicKey, getBtcSignerLibNetworkConfigByMode(network));\n}\n\ninterface DeriveNativeSegwitReceiveAddressIndexArgs {\n keychain: HDKey;\n network: BitcoinNetworkModes;\n}\nexport function deriveNativeSegwitReceiveAddressIndexZero({\n keychain,\n network,\n}: DeriveNativeSegwitReceiveAddressIndexArgs) {\n const zeroAddressIndex = deriveAddressIndexZeroFromAccount(keychain);\n return {\n keychain: zeroAddressIndex,\n payment: getNativeSegwitPaymentFromAddressIndex(zeroAddressIndex, network),\n };\n}\n","import { base64 } from '@scure/base';\nimport * as btc from '@scure/btc-signer';\nimport * as bitcoin from 'bitcoinjs-lib';\n\nimport { BitcoinNetworkModes } from '@leather.io/models';\n\nimport { getBitcoinJsLibNetworkConfigByMode } from '../bitcoin.network';\nimport {\n bip322TransactionToSignValues,\n ecPairFromPrivateKey,\n encodeMessageWitnessData,\n hashBip322Message,\n tweakSigner,\n} from './bip322-utils';\n\nexport function createNativeSegwitBitcoinJsSigner(privateKey: Buffer) {\n return ecPairFromPrivateKey(privateKey);\n}\n\nexport function createTaprootBitcoinJsSigner(privateKey: Buffer) {\n return tweakSigner(ecPairFromPrivateKey(privateKey));\n}\n\nexport function createToSpendTx(address: string, message: string, network: BitcoinNetworkModes) {\n const { prevoutHash, prevoutIndex, sequence } = bip322TransactionToSignValues;\n\n const script = bitcoin.address.toOutputScript(\n address,\n getBitcoinJsLibNetworkConfigByMode(network)\n );\n\n const hash = hashBip322Message(message);\n const commands = [0, Buffer.from(hash)];\n const scriptSig = bitcoin.script.compile(commands);\n\n const virtualToSpend = new bitcoin.Transaction();\n virtualToSpend.version = 0;\n virtualToSpend.addInput(Buffer.from(prevoutHash), prevoutIndex, sequence, scriptSig);\n virtualToSpend.addOutput(script, 0);\n return { virtualToSpend, script };\n}\n\nfunction createToSignTx(toSpendTxHex: Buffer, script: Buffer, network: BitcoinNetworkModes) {\n const virtualToSign = new bitcoin.Psbt({ network: getBitcoinJsLibNetworkConfigByMode(network) });\n virtualToSign.setVersion(0);\n const prevTxHash = toSpendTxHex;\n const prevOutIndex = 0;\n const toSignScriptSig = bitcoin.script.compile([bitcoin.script.OPS.OP_RETURN]);\n\n virtualToSign.addInput({\n hash: prevTxHash,\n index: prevOutIndex,\n sequence: 0,\n witnessUtxo: { script, value: 0 },\n });\n\n virtualToSign.addOutput({ script: toSignScriptSig, value: 0 });\n return virtualToSign;\n}\n\ninterface SignBip322MessageSimple {\n address: string;\n message: string;\n network: BitcoinNetworkModes;\n signPsbt(psbt: bitcoin.Psbt): Promise<btc.Transaction>;\n}\nexport async function signBip322MessageSimple(args: SignBip322MessageSimple) {\n const { address, message, network, signPsbt } = args;\n\n const { virtualToSpend, script } = createToSpendTx(address, message, network);\n\n const virtualToSign = createToSignTx(virtualToSpend.getHash(), script, network);\n\n const signedTx = await signPsbt(virtualToSign);\n\n const asBitcoinJsTransaction = bitcoin.Psbt.fromBuffer(Buffer.from(signedTx.toPSBT()));\n\n asBitcoinJsTransaction.finalizeInput(0);\n\n // sign the tx\n // section 5.1\n // github.com/LegReq/bip0322-signatures/blob/master/BIP0322_signing.ipynb\n const toSignTx = asBitcoinJsTransaction.extractTransaction();\n\n const result = encodeMessageWitnessData(toSignTx.ins[0].witness);\n\n return {\n virtualToSpend,\n virtualToSign: toSignTx,\n unencodedSig: result,\n signature: base64.encode(result),\n };\n}\n","import BigNumber from 'bignumber.js';\n\nimport type { AverageBitcoinFeeRates } from '@leather.io/models';\nimport { createMoney, satToBtc } from '@leather.io/utils';\n\nimport { CoinSelectionUtxo } from './coin-selection';\nimport { filterUneconomicalUtxos, getSpendableAmount } from './coin-selection.utils';\n\ninterface CalculateMaxBitcoinSpend {\n address: string;\n utxos: CoinSelectionUtxo[];\n fetchedFeeRates?: AverageBitcoinFeeRates;\n feeRate?: number;\n}\n\nexport function calculateMaxBitcoinSpend({\n address,\n utxos,\n feeRate,\n fetchedFeeRates,\n}: CalculateMaxBitcoinSpend) {\n if (!utxos.length || !fetchedFeeRates)\n return {\n spendAllFee: 0,\n amount: createMoney(0, 'BTC'),\n spendableBitcoin: new BigNumber(0),\n };\n\n const currentFeeRate = feeRate ?? fetchedFeeRates.halfHourFee.toNumber();\n\n const filteredUtxos = filterUneconomicalUtxos({\n utxos,\n feeRate: currentFeeRate,\n recipients: [{ address, amount: createMoney(0, 'BTC') }],\n });\n\n const { spendableAmount, fee } = getSpendableAmount({\n utxos: filteredUtxos,\n feeRate: currentFeeRate,\n recipients: [{ address, amount: createMoney(0, 'BTC') }],\n });\n\n return {\n spendAllFee: fee,\n amount: createMoney(spendableAmount, 'BTC'),\n spendableBitcoin: satToBtc(spendableAmount),\n };\n}\n","import BigNumber from 'bignumber.js';\nimport validate, { AddressInfo, AddressType, getAddressInfo } from 'bitcoin-address-validation';\n\nimport { BTC_P2WPKH_DUST_AMOUNT } from '@leather.io/constants';\nimport { sumNumbers } from '@leather.io/utils';\n\nimport { BtcSizeFeeEstimator } from '../btc-size-fee-estimator';\nimport { CoinSelectionRecipient, CoinSelectionUtxo } from './coin-selection';\n\nexport function getUtxoTotal(utxos: CoinSelectionUtxo[]) {\n return sumNumbers(utxos.map(utxo => utxo.value));\n}\n\nexport function getSizeInfo(payload: {\n inputLength: number;\n recipients: CoinSelectionRecipient[];\n isSendMax?: boolean;\n}) {\n const { inputLength, recipients, isSendMax } = payload;\n\n const validAddressesInfo = recipients\n .map(recipient => validate(recipient.address) && getAddressInfo(recipient.address))\n .filter(Boolean) as AddressInfo[];\n\n function getTxOutputsLengthByPaymentType() {\n return validAddressesInfo.reduce(\n (acc, { type }) => {\n acc[type] = (acc[type] || 0) + 1;\n return acc;\n },\n {} as Record<AddressType, number>\n );\n }\n\n const outputTypesCount = getTxOutputsLengthByPaymentType();\n\n // Add a change address if not sending max (defaults to p2wpkh)\n if (!isSendMax) {\n outputTypesCount[AddressType.p2wpkh] = (outputTypesCount[AddressType.p2wpkh] || 0) + 1;\n }\n\n // Prepare the output data map for consumption by the txSizer\n const outputsData = Object.entries(outputTypesCount).reduce(\n (acc, [type, count]) => {\n acc[type + '_output_count'] = count;\n return acc;\n },\n {} as Record<string, number>\n );\n\n const txSizer = new BtcSizeFeeEstimator();\n const sizeInfo = txSizer.calcTxSize({\n input_script: 'p2wpkh',\n input_count: inputLength,\n ...outputsData,\n });\n\n return sizeInfo;\n}\n\nexport function getSpendableAmount({\n utxos,\n feeRate,\n recipients,\n}: {\n utxos: CoinSelectionUtxo[];\n feeRate: number;\n recipients: CoinSelectionRecipient[];\n}) {\n const balance = utxos\n .map(utxo => Number(utxo.value))\n .reduce((prevVal, curVal) => prevVal + curVal, 0);\n\n const size = getSizeInfo({\n inputLength: utxos.length,\n recipients,\n });\n const fee = Math.ceil(size.txVBytes * feeRate);\n const bigNumberBalance = BigNumber(balance);\n return {\n spendableAmount: BigNumber.max(0, bigNumberBalance.minus(fee)),\n fee,\n };\n}\n\n// Check if the spendable amount drops when adding a utxo\nexport function filterUneconomicalUtxos({\n utxos,\n feeRate,\n recipients,\n}: {\n utxos: CoinSelectionUtxo[];\n feeRate: number;\n recipients: CoinSelectionRecipient[];\n}) {\n const { spendableAmount: fullSpendableAmount } = getSpendableAmount({\n utxos,\n feeRate,\n recipients,\n });\n\n const filteredUtxos = utxos\n .filter(utxo => utxo.value >= BTC_P2WPKH_DUST_AMOUNT)\n .filter(utxo => {\n // Calculate spendableAmount without that utxo\n const { spendableAmount } = getSpendableAmount({\n utxos: utxos.filter(u => u.txid !== utxo.txid),\n feeRate,\n recipients,\n });\n // If fullSpendableAmount is greater, do not use utxo\n return spendableAmount.toNumber() < fullSpendableAmount.toNumber();\n });\n return filteredUtxos;\n}\n","// https://github.com/argvil19/bitcoin-transaction-size-calculator/blob/master/index.js\nimport BigNumber from 'bignumber.js';\n\nimport { assertUnreachable } from '@leather.io/utils';\n\nexport type InputScriptType =\n | 'p2pkh'\n | 'p2sh'\n | 'p2sh-p2wpkh'\n | 'p2sh-p2wsh'\n | 'p2wpkh'\n | 'p2wsh'\n | 'p2tr';\n\nexport interface TxSizerParams {\n input_count: number;\n input_script: InputScriptType;\n input_m: number;\n input_n: number;\n p2pkh_output_count: number;\n p2sh_output_count: number;\n p2sh_p2wpkh_output_count: number;\n p2sh_p2wsh_output_count: number;\n p2wpkh_output_count: number;\n p2wsh_output_count: number;\n p2tr_output_count: number;\n}\n\nexport class BtcSizeFeeEstimator {\n P2PKH_IN_SIZE = 148;\n P2PKH_OUT_SIZE = 34;\n P2SH_OUT_SIZE = 32;\n P2SH_P2WPKH_OUT_SIZE = 32;\n P2SH_P2WSH_OUT_SIZE = 32;\n P2SH_P2WPKH_IN_SIZE = 91;\n P2WPKH_IN_SIZE = 67.75;\n P2WPKH_OUT_SIZE = 31;\n P2WSH_OUT_SIZE = 43;\n P2TR_OUT_SIZE = 43;\n P2TR_IN_SIZE = 57.25;\n PUBKEY_SIZE = 33;\n SIGNATURE_SIZE = 72;\n SUPPORTED_INPUT_SCRIPT_TYPES: InputScriptType[] = [\n 'p2pkh',\n 'p2sh',\n 'p2sh-p2wpkh',\n 'p2sh-p2wsh',\n 'p2wpkh',\n 'p2wsh',\n 'p2tr',\n ];\n\n defaultParams: TxSizerParams = {\n input_count: 0,\n input_script: 'p2wpkh',\n input_m: 0,\n input_n: 0,\n p2pkh_output_count: 0,\n p2sh_output_count: 0,\n p2sh_p2wpkh_output_count: 0,\n p2sh_p2wsh_output_count: 0,\n p2wpkh_output_count: 0,\n p2wsh_output_count: 0,\n p2tr_output_count: 0,\n };\n\n params: TxSizerParams = { ...this.defaultParams };\n\n getSizeOfScriptLengthElement(length: number) {\n if (length < 75) {\n return 1;\n } else if (length <= 255) {\n return 2;\n } else if (length <= 65535) {\n return 3;\n } else if (length <= 4294967295) {\n return 5;\n } else {\n throw new Error('Size of redeem script is too large');\n }\n }\n\n getSizeOfletInt(length: number) {\n if (length < 253) {\n return 1;\n } else if (length < 65535) {\n return 3;\n } else if (length < 4294967295) {\n return 5;\n } else if (new BigNumber(length).isLessThan('18446744073709551615')) {\n return 9;\n } else {\n throw new Error('Invalid let int');\n }\n }\n\n getTxOverheadVBytes(input_script: InputScriptType, input_count: number, output_count: number) {\n let witness_vbytes;\n if (input_script === 'p2pkh' || input_script === 'p2sh') {\n witness_vbytes = 0;\n } else {\n // Transactions with segwit inputs have extra overhead\n witness_vbytes =\n 0.25 + // segwit marker\n 0.25 + // segwit flag\n this.getSizeOfletInt(input_count) / 4; // witness element count\n }\n\n return (\n 4 + // nVersion\n this.getSizeOfletInt(input_count) + // number of inputs\n this.getSizeOfletInt(output_count) + // number of outputs\n 4 + // nLockTime\n witness_vbytes\n );\n }\n\n getTxOverheadExtraRawBytes(input_script: InputScriptType, input_count: number) {\n let witness_vbytes;\n if (input_script === 'p2pkh' || input_script === 'p2sh') {\n witness_vbytes = 0;\n } else {\n // Transactions with segwit inputs have extra overhead\n witness_vbytes =\n 0.25 + // segwit marker\n 0.25 + // segwit flag\n this.getSizeOfletInt(input_count) / 4; // witness element count\n }\n\n return witness_vbytes * 3;\n }\n\n prepareParams(opts: Partial<TxSizerParams>) {\n // Verify opts and set them to this.params\n opts = opts || Object.assign(this.defaultParams);\n\n const input_count = opts.input_count || this.defaultParams.input_count;\n if (!Number.isInteger(input_count) || input_count < 0) {\n throw new Error('expecting positive input count, got: ' + input_count);\n }\n\n const input_script = opts.input_script || this.defaultParams.input_script;\n if (this.SUPPORTED_INPUT_SCRIPT_TYPES.indexOf(input_script) === -1) {\n throw new Error('Not supported input script type');\n }\n\n const input_m = opts.input_m || this.defaultParams.input_m;\n if (!Number.isInteger(input_m) || input_m < 0) {\n throw new Error('expecting positive signature count');\n }\n\n const input_n = opts.input_n || this.defaultParams.input_n;\n if (!Number.isInteger(input_n) || input_n < 0) {\n throw new Error('expecting positive pubkey count');\n }\n\n const p2pkh_output_count = opts.p2pkh_output_count || this.defaultParams.p2pkh_output_count;\n if (!Number.isInteger(p2pkh_output_count) || p2pkh_output_count < 0) {\n throw new Error('expecting positive p2pkh output count');\n }\n\n const p2sh_output_count = opts.p2sh_output_count || this.defaultParams.p2sh_output_count;\n if (!Number.isInteger(p2sh_output_count) || p2sh_output_count < 0) {\n throw new Error('expecting positive p2sh output count');\n }\n\n const p2sh_p2wpkh_output_count =\n opts.p2sh_p2wpkh_output_count || this.defaultParams.p2sh_p2wpkh_output_count;\n if (!Number.isInteger(p2sh_p2wpkh_output_count) || p2sh_p2wpkh_output_count < 0) {\n throw new Error('expecting positive p2sh-p2wpkh output count');\n }\n\n const p2sh_p2wsh_output_count =\n opts.p2sh_p2wsh_output_count || this.defaultParams.p2sh_p2wsh_output_count;\n if (!Number.isInteger(p2sh_p2wsh_output_count) || p2sh_p2wsh_output_count < 0) {\n throw new Error('expecting positive p2sh-p2wsh output count');\n }\n\n const p2wpkh_output_count = opts.p2wpkh_output_count || this.defaultParams.p2wpkh_output_count;\n if (!Number.isInteger(p2wpkh_output_count) || p2wpkh_output_count < 0) {\n throw new Error('expecting positive p2wpkh output count');\n }\n\n const p2wsh_output_count = opts.p2wsh_output_count || this.defaultParams.p2wsh_output_count;\n if (!Number.isInteger(p2wsh_output_count) || p2wsh_output_count < 0) {\n throw new Error('expecting positive p2wsh output count');\n }\n\n const p2tr_output_count = opts.p2tr_output_count || this.defaultParams.p2tr_output_count;\n if (!Number.isInteger(p2tr_output_count) || p2tr_output_count < 0) {\n throw new Error('expecting positive p2tr output count');\n }\n\n this.params = {\n input_count,\n input_script,\n input_m,\n input_n,\n p2pkh_output_count,\n p2sh_output_count,\n p2sh_p2wpkh_output_count,\n p2sh_p2wsh_output_count,\n p2wpkh_output_count,\n p2wsh_output_count,\n p2tr_output_count,\n };\n\n return this.params;\n }\n\n getOutputCount() {\n return (\n this.params.p2pkh_output_count +\n this.params.p2sh_output_count +\n this.params.p2sh_p2wpkh_output_count +\n this.params.p2sh_p2wsh_output_count +\n this.params.p2wpkh_output_count +\n this.params.p2wsh_output_count +\n this.params.p2tr_output_count\n );\n }\n\n getSizeBasedOnInputType() {\n // In most cases the input size is predictable. For multisig inputs we need to perform a detailed calculation\n let inputSize = 0; // in virtual bytes\n let inputWitnessSize = 0;\n let redeemScriptSize;\n switch (this.params.input_script) {\n case 'p2pkh':\n inputSize = this.P2PKH_IN_SIZE;\n break;\n case 'p2sh-p2wpkh':\n inputSize = this.P2SH_P2WPKH_IN_SIZE;\n inputWitnessSize = 107; // size(signature) + signature + size(pubkey) + pubkey\n break;\n case 'p2wpkh':\n inputSize = this.P2WPKH_IN_SIZE;\n inputWitnessSize = 107; // size(signature) + signature + size(pubkey) + pubkey\n break;\n case 'p2tr': // Only consider the cooperative taproot signing path assume multisig is done via aggregate signatures\n inputSize = this.P2TR_IN_SIZE;\n inputWitnessSize = 65; // getSizeOfletInt(schnorrSignature) + schnorrSignature\n break;\n case 'p2sh':\n redeemScriptSize =\n 1 + // OP_M\n this.params.input_n * (1 + this.PUBKEY_SIZE) + // OP_PUSH33 <pubkey>\n 1 + // OP_N\n 1; // OP_CHECKMULTISIG\n // eslint-disable-next-line no-case-declarations\n const scriptSigSize =\n 1 + // size(0)\n this.params.input_m * (1 + this.SIGNATURE_SIZE) + // size(SIGNATURE_SIZE) + signature\n this.getSizeOfScriptLengthElement(redeemScriptSize) +\n redeemScriptSize;\n inputSize = 32 + 4 + this.getSizeOfletInt(scriptSigSize) + scriptSigSize + 4;\n break;\n case 'p2sh-p2wsh':\n case 'p2wsh':\n redeemScriptSize =\n 1 + // OP_M\n this.params.input_n * (1 + this.PUBKEY_SIZE) + // OP_PUSH33 <pubkey>\n 1 + // OP_N\n 1; // OP_CHECKMULTISIG\n inputWitnessSize =\n 1 + // size(0)\n this.params.input_m * (1 + this.SIGNATURE_SIZE) + // size(SIGNATURE_SIZE) + signature\n this.getSizeOfScriptLengthElement(redeemScriptSize) +\n redeemScriptSize;\n inputSize =\n 36 + // outpoint (spent UTXO ID)\n inputWitnessSize / 4 + // witness program\n 4; // nSequence\n if (this.params.input_script === 'p2sh-p2wsh') {\n inputSize += 32 + 3; // P2SH wrapper (redeemscript hash) + overhead?\n }\n break;\n default:\n assertUnreachable(this.params.input_script);\n }\n\n return {\n inputSize,\n inputWitnessSize,\n };\n }\n\n calcTxSize(opts: Partial<TxSizerParams>) {\n this.prepareParams(opts);\n const output_count = this.getOutputCount();\n const { inputSize, inputWitnessSize } = this.getSizeBasedOnInputType();\n\n const txVBytes =\n this.getTxOverheadVBytes(this.params.input_script, this.params.input_count, output_count) +\n inputSize * this.params.input_count +\n this.P2PKH_OUT_SIZE * this.params.p2pkh_output_count +\n this.P2SH_OUT_SIZE * this.params.p2sh_output_count +\n this.P2SH_P2WPKH_OUT_SIZE * this.params.p2sh_p2wpkh_output_count +\n this.P2SH_P2WSH_OUT_SIZE * this.params.p2sh_p2wsh_output_count +\n this.P2WPKH_OUT_SIZE * this.params.p2wpkh_output_count +\n this.P2WSH_OUT_SIZE * this.params.p2wsh_output_count +\n this.P2TR_OUT_SIZE * this.params.p2tr_output_count;\n\n const txBytes =\n this.getTxOverheadExtraRawBytes(this.params.input_script, this.params.input_count) +\n txVBytes +\n inputWitnessSize * this.params.input_count;\n const txWeight = txVBytes * 4;\n\n return { txVBytes, txBytes, txWeight };\n }\n\n estimateFee(vbyte: number, satVb: number) {\n if (isNaN(vbyte) || isNaN(satVb)) {\n throw new Error('Parameters should be numbers');\n }\n return vbyte * satVb;\n }\n\n formatFeeRange(fee: number, multiplier: number) {\n if (isNaN(fee) || isNaN(multiplier)) {\n throw new Error('Parameters should be numbers');\n }\n\n if (multiplier < 0) {\n throw new Error('Multiplier cant be negative');\n }\n\n const multipliedFee = fee * multiplier;\n\n return fee - multipliedFee + ' - ' + (fee + multipliedFee);\n }\n}\n","import BigNumber from 'bignumber.js';\nimport { validate } from 'bitcoin-address-validation';\n\nimport { BTC_P2WPKH_DUST_AMOUNT } from '@leather.io/constants';\nimport { Money } from '@leather.io/models';\nimport { createMoney, sumMoney } from '@leather.io/utils';\n\nimport { BitcoinError } from '../bitcoin-error';\nimport { filterUneconomicalUtxos, getSizeInfo, getUtxoTotal } from './coin-selection.utils';\n\nexport interface CoinSelectionOutput {\n value: bigint;\n address?: string;\n}\n\nexport interface CoinSelectionUtxo {\n address: string;\n txid: string;\n value: number;\n vout: number;\n}\n\nexport interface CoinSelectionRecipient {\n address: string;\n amount: Money;\n}\n\nexport interface DetermineUtxosForSpendArgs {\n feeRate: number;\n recipients: CoinSelectionRecipient[];\n utxos: CoinSelectionUtxo[];\n}\n\nexport function determineUtxosForSpendAll({\n feeRate,\n recipients,\n utxos,\n}: DetermineUtxosForSpendArgs) {\n recipients.forEach(recipient => {\n if (!validate(recipient.address)) throw new BitcoinError('InvalidAddress');\n });\n const filteredUtxos = filterUneconomicalUtxos({ utxos, feeRate, recipients });\n\n const sizeInfo = getSizeInfo({\n inputLength: filteredUtxos.length,\n isSendMax: true,\n recipients,\n });\n\n // Fee has already been deducted from the amount with send all\n const outputs = recipients.map(({ address, amount }) => ({\n value: BigInt(amount.amount.toNumber()),\n address,\n }));\n\n const fee = Math.ceil(sizeInfo.txVBytes * feeRate);\n\n return {\n inputs: filteredUtxos,\n outputs,\n size: sizeInfo.txVBytes,\n fee: createMoney(new BigNumber(fee), 'BTC'),\n };\n}\n\nexport function determineUtxosForSpend({ feeRate, recipients, utxos }: DetermineUtxosForSpendArgs) {\n recipients.forEach(recipient => {\n if (!validate(recipient.address)) throw new BitcoinError('InvalidAddress');\n });\n const filteredUtxos = filterUneconomicalUtxos({\n utxos: utxos.sort((a, b) => b.value - a.value),\n feeRate,\n recipients,\n });\n if (!filteredUtxos.length) throw new BitcoinError('InsufficientFunds');\n\n const amount = sumMoney(recipients.map(recipient => recipient.amount));\n\n // Prepopulate with first utxo, at least one is needed\n const neededUtxos: CoinSelectionUtxo[] = [filteredUtxos[0]];\n\n function estimateTransactionSize() {\n return getSizeInfo({\n inputLength: neededUtxos.length,\n recipients,\n });\n }\n\n function hasSufficientUtxosForTx() {\n const txEstimation = estimateTransactionSize();\n const neededAmount = new BigNumber(txEstimation.txVBytes * feeRate).plus(amount.amount);\n return getUtxoTotal(neededUtxos).isGreaterThanOrEqualTo(neededAmount);\n }\n\n function getRemainingUnspentUtxos() {\n return filteredUtxos.filter(utxo => !neededUtxos.includes(utxo));\n }\n\n while (!hasSufficientUtxosForTx()) {\n const [nextUtxo] = getRemainingUnspentUtxos();\n if (!nextUtxo) throw new BitcoinError('InsufficientFunds');\n neededUtxos.push(nextUtxo);\n }\n\n const fee = Math.ceil(\n new BigNumber(estimateTransactionSize().txVBytes).multipliedBy(feeRate).toNumber()\n );\n\n const changeAmount =\n BigInt(getUtxoTotal(neededUtxos).toString()) - BigInt(amount.amount.toNumber()) - BigInt(fee);\n\n const changeUtxos: CoinSelectionOutput[] =\n changeAmount > BTC_P2WPKH_DUST_AMOUNT\n ? [\n {\n value: changeAmount,\n },\n ]\n : [];\n\n const outputs: CoinSelectionOutput[] = [\n ...recipients.map(({ address, amount }) => ({\n value: BigInt(amount.amount.toNumber()),\n address,\n })),\n ...changeUtxos,\n ];\n\n return {\n filteredUtxos,\n inputs: neededUtxos,\n outputs,\n size: estimateTransactionSize().txVBytes,\n fee: createMoney(new BigNumber(fee), 'BTC'),\n ...estimateTransactionSize(),\n };\n}\n","export class BitcoinError extends Error {\n public message: BitcoinErrorKey;\n constructor(message: BitcoinErrorKey) {\n super(message);\n this.name = 'BitcoinError';\n this.message = message;\n\n // Fix the prototype chain\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport type BitcoinErrorKey =\n | 'InvalidAddress'\n | 'InsufficientFunds'\n | 'NoInputsToSign'\n | 'NoOutputsToSign';\n","import { AverageBitcoinFeeRates, Money } from '@leather.io/models';\n\nimport {\n CoinSelectionRecipient,\n CoinSelectionUtxo,\n DetermineUtxosForSpendArgs,\n determineUtxosForSpend,\n determineUtxosForSpendAll,\n} from '../coin-selection/coin-selection';\n\ntype GetBitcoinTransactionFeeArgs = DetermineUtxosForSpendArgs & {\n isSendingMax?: boolean;\n};\n\nexport function getBitcoinTransactionFee({ isSendingMax, ...props }: GetBitcoinTransactionFeeArgs) {\n try {\n const { fee } = isSendingMax\n ? determineUtxosForSpendAll({ ...props })\n : determineUtxosForSpend({ ...props });\n return fee;\n } catch {\n return null;\n }\n}\n\nexport interface BitcoinFees {\n blockchain: 'bitcoin';\n high: { fee: Money | null; feeRate: number };\n standard: { fee: Money | null; feeRate: number };\n low: { fee: Money | null; feeRate: number };\n}\n\nexport interface GetBitcoinFeesArgs {\n feeRates: AverageBitcoinFeeRates;\n isSendingMax?: boolean;\n recipients: CoinSelectionRecipient[];\n utxos: CoinSelectionUtxo[];\n}\nexport function getBitcoinFees({ feeRates, isSendingMax, recipients, utxos }: GetBitcoinFeesArgs) {\n const defaultArgs = {\n isSendingMax,\n recipients,\n utxos,\n };\n\n const highFeeRate = feeRates.fastestFee.toNumber();\n const standardFeeRate = feeRates.halfHourFee.toNumber();\n const lowFeeRate = feeRates.hourFee.toNumber();\n\n const highFeeValue = getBitcoinTransactionFee({\n ...defaultArgs,\n feeRate: highFeeRate,\n });\n const standardFeeValue = getBitcoinTransactionFee({\n ...defaultArgs,\n feeRate: standardFeeRate,\n });\n const lowFeeValue = getBitcoinTransactionFee({\n ...defaultArgs,\n feeRate: lowFeeRate,\n });\n\n return {\n high: { feeRate: highFeeRate, fee: highFeeValue },\n standard: { feeRate: standardFeeRate, fee: standardFeeValue },\n low: { feeRate: lowFeeRate, fee: lowFeeValue },\n };\n}\n","import { hexToBytes } from '@noble/hashes/utils';\nimport * as btc from '@scure/btc-signer';\nimport { BtcSignerDefaultBip32Derivation } from 'bitcoin-signer';\n\nimport { BitcoinError } from '../bitcoin-error';\nimport { BtcSignerNetwork } from '../bitcoin.network';\nimport {\n CoinSelectionRecipient,\n CoinSelectionUtxo,\n determineUtxosForSpend,\n determineUtxosForSpendAll,\n} from '../coin-selection/coin-selection';\n\nexport interface GenerateBitcoinUnsignedTransactionArgs {\n feeRate: number;\n isSendingMax?: boolean;\n payerAddress: string;\n payerPublicKey: string;\n bip32Derivation: BtcSignerDefaultBip32Derivation[];\n network: BtcSignerNetwork;\n recipients: CoinSelectionRecipient[];\n utxos: CoinSelectionUtxo[];\n}\n\nexport function generateBitcoinUnsignedTransactionNativeSegwit({\n feeRate,\n isSendingMax,\n payerAddress,\n payerPublicKey,\n bip32Derivation,\n network,\n recipients,\n utxos,\n}: GenerateBitcoinUnsignedTransactionArgs) {\n const determineUtxosArgs = { feeRate, recipients, utxos };\n const { inputs, outputs, fee } = isSendingMax\n ? determineUtxosForSpendAll(determineUtxosArgs)\n : determineUtxosForSpend(determineUtxosArgs);\n\n if (!inputs.length) throw new BitcoinError('NoInputsToSign');\n if (!outputs.length) throw new BitcoinError('NoOutputsToSign');\n\n const tx = new btc.Transaction();\n const p2wpkh = btc.p2wpkh(hexToBytes(payerPublicKey), network);\n\n for (const input of inputs) {\n tx.addInput({\n txid: input.txid,\n index: input.vout,\n sequence: 0,\n bip32Derivation,\n witnessUtxo: {\n // script = 0014 + pubKeyHash\n script: p2wpkh.script,\n amount: BigInt(input.value),\n },\n });\n }\n\n outputs.forEach(output => {\n // When coin selection returns an output with no address,\n // we assume it is a change output\n if (!output.address) {\n tx.addOutputAddress(payerAddress, BigInt(output.value), network);\n return;\n }\n tx.addOutputAddress(output.address, BigInt(output.value), network);\n });\n\n return { tx, hex: tx.hex, psbt: tx.toPSBT(), inputs, fee };\n}\n","import { HARDENED_OFFSET, HDKey } from '@scure/bip32';\nimport * as btc from '@scure/btc-signer';\nimport { P2Ret, P2TROut } from '@scure/btc-signer/payment';\nimport { SigHash } from '@scure/btc-signer/transaction';\n\nimport {\n DerivationPathDepth,\n appendAddressIndexToPath,\n decomposeDescriptor,\n deriveKeychainFromXpub,\n keyOriginToDerivationPath,\n} from '@leather.io/crypto';\nimport type { BitcoinNetworkModes } from '@leather.io/models';\nimport { PaymentTypes, SignatureHash } from '@leather.io/rpc';\nimport { hexToNumber, toHexString } from '@leather.io/utils';\n\nimport {\n SupportedPaymentType,\n ecdsaPublicKeyToSchnorr,\n extractExtendedPublicKeyFromPolicy,\n inferPaymentTypeFromPath,\n whenSupportedPaymentType,\n} from './bitcoin.utils';\nimport { getTaprootPaymentFromAddressIndex } from './p2tr-address-gen';\nimport { getNativeSegwitPaymentFromAddressIndex } from './p2wpkh-address-gen';\n\nexport type AllowedSighashTypes = SignatureHash | SigHash;\n\nexport interface BitcoinAccountKeychain {\n descriptor: string;\n masterKeyFingerprint: string;\n keyOrigin: string;\n keychain: HDKey;\n xpub: string;\n}\n\nexport type WithDerivePayer<T, P> = T & { derivePayer: (args: BitcoinPayerInfo) => P };\n\nexport interface BitcoinSigner<Payment> {\n network: BitcoinNetworkModes;\n payment: Payment;\n keychain: HDKey;\n derivationPath: string;\n address: string;\n publicKey: Uint8Array;\n sign(tx: btc.Transaction): void;\n signIndex(tx: btc.Transaction, index: number, allowedSighash?: AllowedSighashTypes[]): void;\n}\n\nexport interface BitcoinPayerBase {\n paymentType: PaymentTypes;\n network: BitcoinNetworkModes;\n address: string;\n keyOrigin: string;\n masterKeyFingerprint: string;\n publicKey: Uint8Array;\n}\n\nexport interface BitcoinNativeSegwitPayer extends BitcoinPayerBase {\n paymentType: 'p2wpkh';\n payment: P2Ret;\n}\n\nexport interface BitcoinTaprootPayer extends BitcoinPayerBase {\n paymentType: 'p2tr';\n payment: P2TROut;\n}\n\nexport type BitcoinPayer = BitcoinNativeSegwitPayer | BitcoinTaprootPayer;\n\nexport function initializeBitcoinAccountKeychainFromDescriptor(\n descriptor: string\n): BitcoinAccountKeychain {\n const { fingerprint, keyOrigin } = decomposeDescriptor(descriptor);\n return {\n descriptor,\n xpub: extractExtendedPublicKeyFromPolicy(descriptor),\n keyOrigin,\n masterKeyFingerprint: fingerprint,\n keychain: deriveKeychainFromXpub(extractExtendedPublicKeyFromPolicy(descriptor)),\n };\n}\n\nexport interface BitcoinPayerInfo {\n receive?: number;\n addressIndex: number;\n}\nexport function deriveBitcoinPayerFromAccount(descriptor: string, network: BitcoinNetworkModes) {\n const { fingerprint, keyOrigin } = decomposeDescriptor(descriptor);\n const accountKeychain = deriveKeychainFromXpub(extractExtendedPublicKeyFromPolicy(descriptor));\n const paymentType = inferPaymentTypeFromPath(keyOrigin) as SupportedPaymentType;\n\n if (accountKeychain.depth !== DerivationPathDepth.Account)\n throw new Error('Keychain passed is not an account');\n\n return ({ receive = 0, addressIndex }: BitcoinPayerInfo) => {\n const childKeychain = accountKeychain.deriveChild(receive).deriveChild(addressIndex);\n\n const derivePayerFromAccount = whenSupportedPaymentType(paymentType)({\n p2tr: getTaprootPaymentFromAddressIndex,\n p2wpkh: getNativeSegwitPaymentFromAddressIndex,\n });\n\n const payment = derivePayerFromAccount(childKeychain, network);\n\n return {\n keyOrigin: appendAddressIndexToPath(keyOrigin, 0),\n masterKeyFingerprint: fingerprint,\n paymentType,\n network,\n payment,\n get address() {\n if (!payment.address) throw new Error('Payment address could not be derived');\n return payment.address;\n },\n get publicKey() {\n if (!childKeychain.publicKey) throw new Error('Public key could not be derived');\n return childKeychain.publicKey;\n },\n };\n };\n}\n\ninterface BtcSignerDerivationPath {\n fingerprint: number;\n path: number[];\n}\nexport type BtcSignerDefaultBip32Derivation = [Uint8Array, BtcSignerDerivationPath];\nexport type BtcSignerTapBip32Derivation = [\n Uint8Array,\n { hashes: Uint8Array[]; der: BtcSignerDerivationPath },\n];\n\ntype BtcSignerBip32Derivation = BtcSignerDefaultBip32Derivation | BtcSignerTapBip32Derivation;\n\ntype PayerToBip32DerivationArgs = Pick<\n BitcoinPayer,\n 'masterKeyFingerprint' | 'keyOrigin' | 'publicKey'\n>;\n\n/**\n * @example\n * ```ts\n * tx.addInput({\n * ...input,\n * bip32Derivation: [payerToBip32Derivation(payer)],\n * })\n * ```\n */\nexport function payerToBip32Derivation(\n args: PayerToBip32DerivationArgs\n): BtcSignerDefaultBip32Derivation {\n return [\n args.publicKey,\n {\n fingerprint: hexToNumber(args.masterKeyFingerprint),\n path: btc.bip32Path(keyOriginToDerivationPath(args.keyOrigin)),\n },\n ];\n}\n\n/**\n * @example\n * ```ts\n * tx.addInput({\n * ...input,\n * tapBip32Derivation: [payerToTapBip32Derivation(payer)],\n * })\n * ```\n */\nexport function payerToTapBip32Derivation(\n args: PayerToBip32DerivationArgs\n): BtcSignerTapBip32Derivation {\n return [\n // TODO: @kyranjamie to default to schnoor when TR so conversion isn't\n // necessary here?\n ecdsaPublicKeyToSchnorr(args.publicKey),\n {\n hashes: [],\n der: {\n fingerprint: hexToNumber(args.masterKeyFingerprint),\n path: btc.bip32Path(keyOriginToDerivationPath(args.keyOrigin)),\n },\n },\n ];\n}\n\n/**\n * @description\n * Turns key format from @scure/btc-signer lib back into key origin string\n * @example\n * ```ts\n * const [inputOne] = getPsbtTxInputs(tx);\n * const keyOrigin = serializeKeyOrigin(inputOne.bip32Derivation[0][1]);\n * ```\n */\nexport function serializeKeyOrigin({ fingerprint, path }: BtcSignerDerivationPath) {\n const values = path.map(num => (num >= HARDENED_OFFSET ? num - HARDENED_OFFSET + \"'\" : num));\n return `${toHexString(fingerprint)}/${values.join('/')}`;\n}\n\n/**\n * @description\n * Of a given set of a `tx.input`s bip32 derivation paths from\n * `@scure/btc-signer`, serialize the paths back to the string format used\n * internally\n */\nexport function extractRequiredKeyOrigins(derivation: BtcSignerBip32Derivation[]) {\n return derivation.map(([_pubkey, path]) =>\n serializeKeyOrigin('hashes' in path ? path.der : path)\n );\n}\n","import { ripemd160 } from '@noble/hashes/ripemd160';\nimport { sha256 } from '@noble/hashes/sha256';\nimport { base58check } from '@scure/base';\n\nimport { deriveBip39SeedFromMnemonic, deriveRootBip32Keychain } from '@leather.io/crypto';\nimport { NetworkModes } from '@leather.io/models';\n\n/**\n * @deprecated\n * Use `deriveBip39MnemonicFromSeed` from `@leather.io/crypto`\n */\nexport const deriveBtcBip49SeedFromMnemonic = deriveBip39SeedFromMnemonic;\n\n/**\n * @deprecated\n * Use `deriveRootBip32Keychain` from `@leather.io/crypto`\n */\nexport const deriveRootBtcKeychain = deriveRootBip32Keychain;\n\nexport function decodeCompressedWifPrivateKey(key: string) {\n // https://en.bitcoinwiki.org/wiki/Wallet_import_format\n // Decode Compressed WIF format private key\n const compressedWifFormatPrivateKey = base58check(sha256).decode(key);\n // Drop leading network byte, trailing public key SEC format byte\n return compressedWifFormatPrivateKey.slice(1, compressedWifFormatPrivateKey.length - 1);\n}\n\n// https://en.bitcoin.it/wiki/List_of_address_prefixes\nconst payToScriptHashMainnetPrefix = 0x05;\nexport const payToScriptHashTestnetPrefix = 0xc4;\n\nconst payToScriptHashPrefixMap: Record<NetworkModes, number> = {\n mainnet: payToScriptHashMainnetPrefix,\n testnet: payToScriptHashTestnetPrefix,\n};\n\nfunction hash160(input: Uint8Array) {\n return ripemd160(sha256(input));\n}\n\nexport function makePayToScriptHashKeyHash(publicKey: Uint8Array) {\n return hash160(publicKey);\n}\n\nexport function makePayToScriptHashAddressBytes(keyHash: Uint8Array) {\n const redeemScript = Uint8Array.from([\n ...Uint8Array.of(0x00),\n ...Uint8Array.of(keyHash.length),\n ...keyHash,\n ]);\n return hash160(redeemScript);\n}\n\nexport function makePayToScriptHashAddress(addressBytes: Uint8Array, network: NetworkModes) {\n const networkByte = payToScriptHashPrefixMap[network];\n const addressWithPrefix = Uint8Array.from([networkByte, ...addressBytes]);\n return base58check(sha256).encode(addressWithPrefix);\n}\n\nexport function publicKeyToPayToScriptHashAddress(publicKey: Uint8Array, network: NetworkModes) {\n const hash = makePayToScriptHashKeyHash(publicKey);\n const addrBytes = makePayToScriptHashAddressBytes(hash);\n return makePayToScriptHashAddress(addrBytes, network);\n}\n","import { HARDENED_OFFSET, HDKey } from '@scure/bip32';\n\nimport { createCounter } from '@leather.io/utils';\n\nimport {\n getNativeSegwitAddress,\n getTaprootAddress,\n inferNetworkFromAddress,\n inferPaymentTypeFromAddress,\n whenSupportedPaymentType,\n} from './bitcoin.utils';\nimport { makeTaprootAddressIndexDerivationPath } from './p2tr-address-gen';\nimport { makeNativeSegwitAddressIndexDerivationPath } from './p2wpkh-address-gen';\n\ninterface LookUpDerivationByAddressArgs {\n taprootXpub: string;\n nativeSegwitXpub: string;\n iterationLimit: number;\n}\nexport function lookupDerivationByAddress(args: LookUpDerivationByAddressArgs) {\n const { taprootXpub, nativeSegwitXpub, iterationLimit } = args;\n\n const taprootKeychain = HDKey.fromExtendedKey(taprootXpub);\n const nativeSegwitKeychain = HDKey.fromExtendedKey(nativeSegwitXpub);\n\n return (address: string) => {\n const network = inferNetworkFromAddress(address);\n const paymentType = inferPaymentTypeFromAddress(address);\n\n const accountIndex = whenSupportedPaymentType(paymentType)({\n p2tr: taprootKeychain.index - HARDENED_OFFSET,\n p2wpkh: nativeSegwitKeychain.index - HARDENED_OFFSET,\n });\n\n function getTaprootAddressAtIndex(index: number) {\n return getTaprootAddress({ index, keychain: taprootKeychain, network });\n }\n\n function getNativeSegwitAddressAtIndex(index: number) {\n return getNativeSegwitAddress({ index, keychain: nativeSegwitKeychain, network });\n }\n\n const paymentFn = whenSupportedPaymentType(paymentType)({\n p2tr: getTaprootAddressAtIndex,\n p2wpkh: getNativeSegwitAddressAtIndex,\n });\n\n const derivationPathFn = whenSupportedPaymentType(paymentType)({\n p2tr: makeTaprootAddressIndexDerivationPath,\n p2wpkh: makeNativeSegwitAddressIndexDerivationPath,\n });\n\n const count = createCounter();\n const t0 = performance.now();\n\n while (count.getValue() <= iterationLimit) {\n const currentIndex = count.getValue();\n\n const addressToCheck = paymentFn(currentIndex);\n\n if (addressToCheck !== address) {\n count.increment();\n continue;\n }\n\n const t1 = performance.now();\n\n return {\n status: 'success',\n duration: t1 - t0,\n path: derivationPathFn(network, accountIndex, currentIndex),\n } as const;\n }\n\n return { status: 'failure' } as const;\n };\n}\n","import { inferPaymentTypeFromAddress } from 'bitcoin.utils';\n\nimport { createMoney, sumNumbers } from '@leather.io/utils';\n\nimport { PsbtInput } from './psbt-inputs';\nimport { PsbtOutput } from './psbt-outputs';\n\nfunction calculateAddressInputsTotal(addresses: string[], inputs: PsbtInput[]) {\n const sumsByAddress = addresses.map(address =>\n inputs\n .filter(input => input.address === address)\n .map(input => input.value)\n .reduce((acc, curVal) => acc + curVal, 0)\n );\n\n return createMoney(sumNumbers(sumsByAddress), 'BTC');\n}\n\nfunction calculateAddressOutputsTotal(addresses: string[], outputs: PsbtOutput[]) {\n const sumsByAddress = addresses.map(address =>\n outputs\n .filter(output => output.address === address)\n .map(output => Number(output.value))\n .reduce((acc, curVal) => acc + curVal, 0)\n );\n return createMoney(sumNumbers(sumsByAddress), 'BTC');\n}\n\nfunction calculatePsbtInputsTotal(inputs: PsbtInput[]) {\n return createMoney(sumNumbers(inputs.map(input => input.value)), 'BTC');\n}\n\nfunction calculatePsbtOutputsTotal(outputs: PsbtOutput[]) {\n return createMoney(sumNumbers(outputs.map(output => output.value)), 'BTC');\n}\n\ninterface GetPsbtTotalsProps {\n psbtAddresses: string[];\n parsedInputs: PsbtInput[];\n parsedOutputs: PsbtOutput[];\n}\nexport function getPsbtTotals({ psbtAddresses, parsedInputs, parsedOutputs }: GetPsbtTotalsProps) {\n const nativeSegwitAddresses = psbtAddresses.filter(\n addr => inferPaymentTypeFromAddress(addr) === 'p2wpkh'\n );\n const taprootAddresses = psbtAddresses.filter(\n addr => inferPaymentTypeFromAddress(addr) === 'p2tr'\n );\n\n return {\n inputsTotalNativeSegwit: calculateAddressInputsTotal(nativeSegwitAddresses, parsedInputs),\n inputsTotalTaproot: calculateAddressInputsTotal(taprootAddresses, parsedInputs),\n outputsTotalNativeSegwit: calculateAddressOutputsTotal(nativeSegwitAddresses, parsedOutputs),\n outputsTotalTaproot: calculateAddressOutputsTotal(taprootAddresses, parsedOutputs),\n psbtInputsTotal: calculatePsbtInputsTotal(parsedInputs),\n psbtOutputsTotal: calculatePsbtOutputsTotal(parsedOutputs),\n };\n}\n","import type { TransactionInput } from '@scure/btc-signer/psbt';\nimport { bytesToHex } from '@stacks/common';\nimport { getBtcSignerLibNetworkConfigByMode } from 'bitcoin.network';\nimport { getBitcoinInputAddress, getBitcoinInputValue } from 'bitcoin.utils';\n\nimport type { BitcoinNetworkModes, Inscription } from '@leather.io/models';\nimport { isDefined, isUndefined } from '@leather.io/utils';\n\nexport interface PsbtInput {\n address: string;\n index?: number;\n // TODO: inject inscription later on. getParsedInputs should be a pure function\n inscription?: Inscription;\n isMutable: boolean;\n toSign: boolean;\n txid: string;\n value: number;\n bip32Derivation: TransactionInput['bip32Derivation'];\n tapBip32Derivation: TransactionInput['tapBip32Derivation'];\n}\n\ninterface GetParsedInputsArgs {\n inputs: TransactionInput[];\n indexesToSign?: number[];\n networkMode: BitcoinNetworkModes;\n psbtAddresses: string[];\n}\n\ninterface GetParsedInputsResponse {\n isPsbtMutable: boolean;\n parsedInputs: PsbtInput[];\n}\nexport function getParsedInputs({\n inputs,\n indexesToSign,\n networkMode,\n psbtAddresses,\n}: GetParsedInputsArgs): GetParsedInputsResponse {\n const bitcoinNetwork = getBtcSignerLibNetworkConfigByMode(networkMode);\n\n const signAll = isUndefined(indexesToSign);\n const psbtInputs = inputs.map((input, i) => {\n const inputAddress = isDefined(input.index)\n ? getBitcoinInputAddress(input, bitcoinNetwork)\n : '';\n const isCurrentAddress = psbtAddresses.includes(inputAddress);\n // Flags when not signing ALL inputs/outputs (NONE, SINGLE, and ANYONECANPAY)\n const canChange =\n isCurrentAddress &&\n !(!input.sighashType || input.sighashType === 0 || input.sighashType === 1);\n // Should we check the sighashType here before it gets to the signing lib?\n const toSignAll = isCurrentAddress && signAll;\n const toSignIndex = isCurrentAddress && !signAll && indexesToSign.includes(i);\n\n return {\n address: inputAddress,\n index: input.index,\n bip32Derivation: input.bip32Derivation,\n tapBip32Derivation: input.tapBip32Derivation,\n // inscription: inscriptions[i],\n isMutable: canChange,\n toSign: toSignAll || toSignIndex,\n txid: input.txid ? bytesToHex(input.txid) : '',\n value: isDefined(input.index) ? getBitcoinInputValue(input) : 0,\n };\n });\n\n const isPsbtMutable = psbtInputs.some(input => input.isMutable);\n\n return { isPsbtMutable, parsedInputs: psbtInputs };\n}\n","import type { TransactionOutput } from '@scure/btc-signer/psbt';\nimport { getBtcSignerLibNetworkConfigByMode } from 'bitcoin.network';\nimport { getAddressFromOutScript } from 'bitcoin.utils';\n\nimport type { BitcoinNetworkModes } from '@leather.io/models';\nimport { isDefined, isUndefined } from '@leather.io/utils';\n\nexport interface PsbtOutput {\n address: string;\n isMutable: boolean;\n toSign: boolean;\n value: number;\n}\n\ninterface GetParsedOutputsArgs {\n isPsbtMutable: boolean;\n outputs: TransactionOutput[];\n networkMode: BitcoinNetworkModes;\n psbtAddresses: string[];\n}\n\nexport function getParsedOutputs({\n isPsbtMutable,\n outputs,\n networkMode,\n psbtAddresses,\n}: GetParsedOutputsArgs): PsbtOutput[] {\n const bitcoinNetwork = getBtcSignerLibNetworkConfigByMode(networkMode);\n\n return outputs\n .map(output => {\n if (isUndefined(output.script)) {\n // TODO: handle error here\n // logger.error('Output has no script');\n return;\n }\n const outputAddress = getAddressFromOutScript(output.script, bitcoinNetwork);\n\n const isCurrentAddress = psbtAddresses.includes(outputAddress);\n\n return {\n address: outputAddress,\n isMutable: isPsbtMutable,\n toSign: isCurrentAddress,\n value: Number(output.amount),\n };\n })\n .filter(isDefined);\n}\n","import { getPsbtTxInputs, getPsbtTxOutputs } from 'bitcoin.utils';\n\nimport { BitcoinNetworkModes } from '@leather.io/models';\nimport { createMoney, subtractMoney } from '@leather.io/utils';\n\nimport { getParsedInputs } from './psbt-inputs';\nimport { getParsedOutputs } from './psbt-outputs';\nimport { getPsbtTotals } from './psbt-totals';\nimport { getPsbtAsTransaction } from './utils';\n\ninterface GetPsbtDetailsArgs {\n psbtHex: string;\n psbtAddresses: string[];\n networkMode: BitcoinNetworkModes;\n indexesToSign?: number[];\n}\nexport function getPsbtDetails({\n psbtHex,\n networkMode,\n indexesToSign,\n psbtAddresses,\n}: GetPsbtDetailsArgs) {\n const tx = getPsbtAsTransaction(psbtHex);\n const inputs = getPsbtTxInputs(tx);\n const outputs = getPsbtTxOutputs(tx);\n\n const { isPsbtMutable, parsedInputs } = getParsedInputs({\n inputs,\n indexesToSign,\n networkMode,\n psbtAddresses,\n });\n const parsedOutputs = getParsedOutputs({ isPsbtMutable, outputs, networkMode, psbtAddresses });\n\n const {\n inputsTotalNativeSegwit,\n inputsTotalTaproot,\n outputsTotalNativeSegwit,\n outputsTotalTaproot,\n psbtInputsTotal,\n psbtOutputsTotal,\n } = getPsbtTotals({\n psbtAddresses,\n parsedInputs,\n parsedOutputs,\n });\n function getFee() {\n if (psbtInputsTotal.amount.isGreaterThan(psbtOutputsTotal.amount))\n return subtractMoney(psbtInputsTotal, psbtOutputsTotal);\n return createMoney(0, 'BTC');\n }\n return {\n addressNativeSegwitTotal: subtractMoney(inputsTotalNativeSegwit, outputsTotalNativeSegwit),\n addressTaprootTotal: subtractMoney(inputsTotalTaproot, outputsTotalTaproot),\n fee: getFee(),\n isPsbtMutable,\n psbtInputs: parsedInputs,\n psbtOutputs: parsedOutputs,\n };\n}\n","import { hexToBytes } from '@noble/hashes/utils';\nimport * as btc from '@scure/btc-signer';\nimport { RawPSBTV0, RawPSBTV2 } from '@scure/btc-signer/psbt';\n\nimport { isString } from '@leather.io/utils';\n\nexport type RawPsbt = ReturnType<typeof RawPSBTV0.decode>;\n\nexport function getPsbtAsTransaction(psbt: string | Uint8Array) {\n const bytes = isString(psbt) ? hexToBytes(psbt) : psbt;\n return btc.Transaction.fromPSBT(bytes);\n}\n\nexport function getRawPsbt(psbt: string | Uint8Array): ReturnType<typeof RawPSBTV0.decode> {\n const bytes = isString(psbt) ? hexToBytes(psbt) : psbt;\n try {\n return RawPSBTV0.decode(bytes);\n } catch (e1) {\n try {\n return RawPSBTV2.decode(bytes);\n } catch (e2) {\n throw new Error(`Unable to decode PSBT, ${e1 ?? e2}`);\n }\n }\n}\n"],"mappings":"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","names":["hexToBytes","btc","DerivationPathDepth","btc","DerivationPathDepth","DerivationPathDepth","DerivationPathDepth","script","address","hexToBytes","bitcoin","address","script","BigNumber","BigNumber","BigNumber","address","BigNumber","BigNumber","validate","BTC_P2WPKH_DUST_AMOUNT","createMoney","validate","address","createMoney","BigNumber","BTC_P2WPKH_DUST_AMOUNT","amount","hexToBytes","btc","p2wpkh","hexToBytes","btc","DerivationPathDepth","DerivationPathDepth","sha256","HARDENED_OFFSET","HDKey","HDKey","address","HARDENED_OFFSET","createMoney","sumNumbers","address","isDefined","isDefined","isUndefined","createMoney","hexToBytes","btc","isString","createMoney"]}
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@leather.io/bitcoin",
3
3
  "author": "Leather.io contact@leather.io",
4
4
  "description": "Shared bitcoin utilities",
5
- "version": "0.19.8",
5
+ "version": "0.19.10",
6
6
  "license": "MIT",
7
7
  "homepage": "https://github.com/leather.io/mono/tree/dev/packages/bitcoin",
8
8
  "repository": {
@@ -32,22 +32,20 @@
32
32
  "ecpair": "2.1.0",
33
33
  "just-memoize": "2.2.0",
34
34
  "varuint-bitcoin": "1.1.2",
35
- "@leather.io/crypto": "1.6.25",
36
- "@leather.io/constants": "0.15.2",
37
- "@leather.io/models": "0.24.2",
38
- "@leather.io/utils": "0.22.5"
35
+ "@leather.io/models": "0.24.3",
36
+ "@leather.io/crypto": "1.6.26",
37
+ "@leather.io/constants": "0.15.3",
38
+ "@leather.io/utils": "0.22.6"
39
39
  },
40
40
  "devDependencies": {
41
- "eslint": "8.53.0",
42
41
  "prettier": "3.3.3",
43
42
  "tslib": "2.6.2",
44
43
  "tsup": "8.1.0",
45
44
  "typescript": "5.5.4",
46
45
  "vitest": "2.1.5",
47
- "@leather.io/rpc": "2.4.1",
48
46
  "@leather.io/prettier-config": "0.6.0",
49
- "@leather.io/eslint-config": "0.7.0",
50
- "@leather.io/tsconfig-config": "0.6.0"
47
+ "@leather.io/tsconfig-config": "0.6.0",
48
+ "@leather.io/rpc": "2.4.2"
51
49
  },
52
50
  "keywords": [
53
51
  "bitcoin",
@@ -63,8 +61,6 @@
63
61
  "build:watch": "tsup --watch --onSuccess 'tsup --dts-only'",
64
62
  "format": "prettier . --write --ignore-path ../../.prettierignore",
65
63
  "format:check": "prettier . --check --ignore-path ../../.prettierignore",
66
- "lint": "eslint . --fix --ignore-path ../../.eslintignore",
67
- "lint:fix": "eslint . --fix --ignore-path ../../.eslintignore",
68
64
  "test:coverage": "vitest run --coverage",
69
65
  "test:unit": "vitest run",
70
66
  "typecheck": "tsc --noEmit -p ./tsconfig.json"
@@ -63,7 +63,7 @@ function tapTweakHash(pubKey: Buffer, h: Buffer | undefined): Buffer {
63
63
 
64
64
  export function tweakSigner(signer: bitcoin.Signer, opts: any = {}): bitcoin.Signer {
65
65
  // @ts-expect-error privateKey exists on signer
66
- let privateKey: Uint8Array | undefined = signer.privateKey!;
66
+ let privateKey: Uint8Array | undefined = signer.privateKey;
67
67
  if (!privateKey) {
68
68
  throw new Error('Private key is required for tweaking signer!');
69
69
  }
@@ -36,9 +36,9 @@ describe(signBip322MessageSimple.name, () => {
36
36
  const nativeSegwitAddress = btc.getAddress('wpkh', testVectorKey);
37
37
  const payment = btc.p2wpkh(secp.getPublicKey(testVectorKey, true));
38
38
 
39
- async function signPsbt(psbt: bitcoin.Psbt) {
39
+ function signPsbt(psbt: bitcoin.Psbt) {
40
40
  psbt.signAllInputs(createNativeSegwitBitcoinJsSigner(Buffer.from(testVectorKey)));
41
- return btc.Transaction.fromPSBT(psbt.toBuffer());
41
+ return Promise.resolve(btc.Transaction.fromPSBT(psbt.toBuffer()));
42
42
  }
43
43
 
44
44
  if (!nativeSegwitAddress) throw new Error('nativeSegwitAddress is undefined');
@@ -121,12 +121,12 @@ describe(signBip322MessageSimple.name, () => {
121
121
  ecdsaPublicKeyToSchnorr(secp.getPublicKey(Buffer.from(testVectorKey), true))
122
122
  );
123
123
 
124
- async function signPsbt(psbt: bitcoin.Psbt) {
124
+ function signPsbt(psbt: bitcoin.Psbt) {
125
125
  psbt.data.inputs.forEach(
126
126
  input => (input.tapInternalKey = Buffer.from(payment.tapInternalKey))
127
127
  );
128
128
  psbt.signAllInputs(createTaprootBitcoinJsSigner(Buffer.from(testVectorKey)));
129
- return btc.Transaction.fromPSBT(psbt.toBuffer());
129
+ return Promise.resolve(btc.Transaction.fromPSBT(psbt.toBuffer()));
130
130
  }
131
131
 
132
132
  test('Addresses against taproot test vectors', () => {
@@ -1,15 +1,17 @@
1
- export enum BitcoinErrorMessage {
2
- InsufficientFunds = 'Insufficient funds',
3
- NoInputsToSign = 'No inputs to sign',
4
- NoOutputsToSign = 'No outputs to sign',
5
- }
6
-
7
1
  export class BitcoinError extends Error {
8
- constructor(message: string) {
2
+ public message: BitcoinErrorKey;
3
+ constructor(message: BitcoinErrorKey) {
9
4
  super(message);
10
5
  this.name = 'BitcoinError';
6
+ this.message = message;
11
7
 
12
8
  // Fix the prototype chain
13
9
  Object.setPrototypeOf(this, new.target.prototype);
14
10
  }
15
11
  }
12
+
13
+ export type BitcoinErrorKey =
14
+ | 'InvalidAddress'
15
+ | 'InsufficientFunds'
16
+ | 'NoInputsToSign'
17
+ | 'NoOutputsToSign';
@@ -161,8 +161,7 @@ export function parseKnownPaymentType(payment: BtcSignerLibPaymentTypeIdentifers
161
161
 
162
162
  export type PaymentTypeMap<T> = Record<PaymentTypes, T>;
163
163
  export function whenPaymentType(mode: PaymentTypes | BtcSignerLibPaymentTypeIdentifers) {
164
- return <T extends unknown>(paymentMap: PaymentTypeMap<T>): T =>
165
- paymentMap[parseKnownPaymentType(mode)];
164
+ return <T>(paymentMap: PaymentTypeMap<T>): T => paymentMap[parseKnownPaymentType(mode)];
166
165
  }
167
166
 
168
167
  export type SupportedPaymentType = 'p2wpkh' | 'p2tr';
@@ -1,6 +1,8 @@
1
1
  // https://github.com/argvil19/bitcoin-transaction-size-calculator/blob/master/index.js
2
2
  import BigNumber from 'bignumber.js';
3
3
 
4
+ import { assertUnreachable } from '@leather.io/utils';
5
+
4
6
  export type InputScriptType =
5
7
  | 'p2pkh'
6
8
  | 'p2sh'
@@ -245,6 +247,7 @@ export class BtcSizeFeeEstimator {
245
247
  this.params.input_n * (1 + this.PUBKEY_SIZE) + // OP_PUSH33 <pubkey>
246
248
  1 + // OP_N
247
249
  1; // OP_CHECKMULTISIG
250
+ // eslint-disable-next-line no-case-declarations
248
251
  const scriptSigSize =
249
252
  1 + // size(0)
250
253
  this.params.input_m * (1 + this.SIGNATURE_SIZE) + // size(SIGNATURE_SIZE) + signature
@@ -271,6 +274,9 @@ export class BtcSizeFeeEstimator {
271
274
  if (this.params.input_script === 'p2sh-p2wsh') {
272
275
  inputSize += 32 + 3; // P2SH wrapper (redeemscript hash) + overhead?
273
276
  }
277
+ break;
278
+ default:
279
+ assertUnreachable(this.params.input_script);
274
280
  }
275
281
 
276
282
  return {
@@ -5,7 +5,7 @@ import { BTC_P2WPKH_DUST_AMOUNT } from '@leather.io/constants';
5
5
  import { Money } from '@leather.io/models';
6
6
  import { createMoney, sumMoney } from '@leather.io/utils';
7
7
 
8
- import { BitcoinError, BitcoinErrorMessage } from '../bitcoin-error';
8
+ import { BitcoinError } from '../bitcoin-error';
9
9
  import { filterUneconomicalUtxos, getSizeInfo, getUtxoTotal } from './coin-selection.utils';
10
10
 
11
11
  export interface CoinSelectionOutput {
@@ -37,8 +37,7 @@ export function determineUtxosForSpendAll({
37
37
  utxos,
38
38
  }: DetermineUtxosForSpendArgs) {
39
39
  recipients.forEach(recipient => {
40
- if (!validate(recipient.address))
41
- throw new Error('Cannot calculate spend of invalid address type');
40
+ if (!validate(recipient.address)) throw new BitcoinError('InvalidAddress');
42
41
  });
43
42
  const filteredUtxos = filterUneconomicalUtxos({ utxos, feeRate, recipients });
44
43
 
@@ -66,15 +65,14 @@ export function determineUtxosForSpendAll({
66
65
 
67
66
  export function determineUtxosForSpend({ feeRate, recipients, utxos }: DetermineUtxosForSpendArgs) {
68
67
  recipients.forEach(recipient => {
69
- if (!validate(recipient.address))
70
- throw new Error('Cannot calculate spend of invalid address type');
68
+ if (!validate(recipient.address)) throw new BitcoinError('InvalidAddress');
71
69
  });
72
70
  const filteredUtxos = filterUneconomicalUtxos({
73
71
  utxos: utxos.sort((a, b) => b.value - a.value),
74
72
  feeRate,
75
73
  recipients,
76
74
  });
77
- if (!filteredUtxos.length) throw new BitcoinError(BitcoinErrorMessage.InsufficientFunds);
75
+ if (!filteredUtxos.length) throw new BitcoinError('InsufficientFunds');
78
76
 
79
77
  const amount = sumMoney(recipients.map(recipient => recipient.amount));
80
78
 
@@ -100,7 +98,7 @@ export function determineUtxosForSpend({ feeRate, recipients, utxos }: Determine
100
98
 
101
99
  while (!hasSufficientUtxosForTx()) {
102
100
  const [nextUtxo] = getRemainingUnspentUtxos();
103
- if (!nextUtxo) throw new BitcoinError(BitcoinErrorMessage.InsufficientFunds);
101
+ if (!nextUtxo) throw new BitcoinError('InsufficientFunds');
104
102
  neededUtxos.push(nextUtxo);
105
103
  }
106
104
 
@@ -18,7 +18,7 @@ export function getBitcoinTransactionFee({ isSendingMax, ...props }: GetBitcoinT
18
18
  ? determineUtxosForSpendAll({ ...props })
19
19
  : determineUtxosForSpend({ ...props });
20
20
  return fee;
21
- } catch (error) {
21
+ } catch {
22
22
  return null;
23
23
  }
24
24
  }
@@ -56,8 +56,8 @@ describe('generateBitcoinUnsignedTransactionNativeSegwit', () => {
56
56
  ],
57
57
  };
58
58
 
59
- it('should generate an unsigned transaction with correct inputs and outputs', async () => {
60
- const result = await generateBitcoinUnsignedTransactionNativeSegwit(mockArgs);
59
+ it('should generate an unsigned transaction with correct inputs and outputs', () => {
60
+ const result = generateBitcoinUnsignedTransactionNativeSegwit(mockArgs);
61
61
  if (result) {
62
62
  expect(result.inputs).toEqual(mockResult.inputs);
63
63
  expect(result.fee).toEqual(mockResult.fee);
@@ -66,8 +66,8 @@ describe('generateBitcoinUnsignedTransactionNativeSegwit', () => {
66
66
  }
67
67
  });
68
68
 
69
- it('should add change address to output correctly', async () => {
70
- const result = await generateBitcoinUnsignedTransactionNativeSegwit(mockArgs);
69
+ it('should add change address to output correctly', () => {
70
+ const result = generateBitcoinUnsignedTransactionNativeSegwit(mockArgs);
71
71
 
72
72
  if (result) {
73
73
  expect(result.tx.outputsLength).toBe(2);
@@ -75,16 +75,14 @@ describe('generateBitcoinUnsignedTransactionNativeSegwit', () => {
75
75
  }
76
76
  });
77
77
 
78
- it('should throw an error if inputs are empty', async () => {
78
+ it('should throw an error if inputs are empty', () => {
79
79
  const argsWithNoInputs: GenerateBitcoinUnsignedTransactionArgs = {
80
80
  ...mockArgs,
81
81
  utxos: [],
82
82
  };
83
83
 
84
- const result = await generateBitcoinUnsignedTransactionNativeSegwit(argsWithNoInputs);
85
-
86
- if (result) {
87
- expect(result.inputs.length).toBe(0);
88
- }
84
+ expect(() => generateBitcoinUnsignedTransactionNativeSegwit(argsWithNoInputs)).toThrowError(
85
+ 'InsufficientFunds'
86
+ );
89
87
  });
90
88
  });
@@ -2,7 +2,7 @@ import { hexToBytes } from '@noble/hashes/utils';
2
2
  import * as btc from '@scure/btc-signer';
3
3
  import { BtcSignerDefaultBip32Derivation } from 'bitcoin-signer';
4
4
 
5
- import { BitcoinError, BitcoinErrorMessage } from '../bitcoin-error';
5
+ import { BitcoinError } from '../bitcoin-error';
6
6
  import { BtcSignerNetwork } from '../bitcoin.network';
7
7
  import {
8
8
  CoinSelectionRecipient,
@@ -22,7 +22,7 @@ export interface GenerateBitcoinUnsignedTransactionArgs {
22
22
  utxos: CoinSelectionUtxo[];
23
23
  }
24
24
 
25
- export async function generateBitcoinUnsignedTransactionNativeSegwit({
25
+ export function generateBitcoinUnsignedTransactionNativeSegwit({
26
26
  feeRate,
27
27
  isSendingMax,
28
28
  payerAddress,
@@ -32,44 +32,40 @@ export async function generateBitcoinUnsignedTransactionNativeSegwit({
32
32
  recipients,
33
33
  utxos,
34
34
  }: GenerateBitcoinUnsignedTransactionArgs) {
35
- try {
36
- const determineUtxosArgs = { feeRate, recipients, utxos };
37
- const { inputs, outputs, fee } = isSendingMax
38
- ? determineUtxosForSpendAll(determineUtxosArgs)
39
- : determineUtxosForSpend(determineUtxosArgs);
35
+ const determineUtxosArgs = { feeRate, recipients, utxos };
36
+ const { inputs, outputs, fee } = isSendingMax
37
+ ? determineUtxosForSpendAll(determineUtxosArgs)
38
+ : determineUtxosForSpend(determineUtxosArgs);
40
39
 
41
- if (!inputs.length) throw new BitcoinError(BitcoinErrorMessage.NoInputsToSign);
42
- if (!outputs.length) throw new BitcoinError(BitcoinErrorMessage.NoOutputsToSign);
40
+ if (!inputs.length) throw new BitcoinError('NoInputsToSign');
41
+ if (!outputs.length) throw new BitcoinError('NoOutputsToSign');
43
42
 
44
- const tx = new btc.Transaction();
45
- const p2wpkh = btc.p2wpkh(hexToBytes(payerPublicKey), network);
43
+ const tx = new btc.Transaction();
44
+ const p2wpkh = btc.p2wpkh(hexToBytes(payerPublicKey), network);
46
45
 
47
- for (const input of inputs) {
48
- tx.addInput({
49
- txid: input.txid,
50
- index: input.vout,
51
- sequence: 0,
52
- bip32Derivation,
53
- witnessUtxo: {
54
- // script = 0014 + pubKeyHash
55
- script: p2wpkh.script,
56
- amount: BigInt(input.value),
57
- },
58
- });
59
- }
60
-
61
- outputs.forEach(output => {
62
- // When coin selection returns an output with no address,
63
- // we assume it is a change output
64
- if (!output.address) {
65
- tx.addOutputAddress(payerAddress, BigInt(output.value), network);
66
- return;
67
- }
68
- tx.addOutputAddress(output.address, BigInt(output.value), network);
46
+ for (const input of inputs) {
47
+ tx.addInput({
48
+ txid: input.txid,
49
+ index: input.vout,
50
+ sequence: 0,
51
+ bip32Derivation,
52
+ witnessUtxo: {
53
+ // script = 0014 + pubKeyHash
54
+ script: p2wpkh.script,
55
+ amount: BigInt(input.value),
56
+ },
69
57
  });
70
-
71
- return { tx, hex: tx.hex, psbt: tx.toPSBT(), inputs, fee };
72
- } catch (e) {
73
- return null;
74
58
  }
59
+
60
+ outputs.forEach(output => {
61
+ // When coin selection returns an output with no address,
62
+ // we assume it is a change output
63
+ if (!output.address) {
64
+ tx.addOutputAddress(payerAddress, BigInt(output.value), network);
65
+ return;
66
+ }
67
+ tx.addOutputAddress(output.address, BigInt(output.value), network);
68
+ });
69
+
70
+ return { tx, hex: tx.hex, psbt: tx.toPSBT(), inputs, fee };
75
71
  }
package/.eslintrc.yml DELETED
@@ -1,4 +0,0 @@
1
- extends: '@leather.io/eslint-config'
2
- parserOptions:
3
- project: ./tsconfig.json
4
- ignorePatterns: .eslintrc.js