@leather.io/bitcoin 0.36.3 → 0.36.4

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.36.3 build /home/runner/work/mono/mono/packages/bitcoin
2
+ > @leather.io/bitcoin@0.36.4 build /home/runner/work/mono/mono/packages/bitcoin
3
3
  > tsdown
4
4
 
5
5
  ℹ tsdown v0.16.5 powered by rolldown v1.0.0-beta.50
@@ -7,9 +7,9 @@
7
7
  ℹ entry: src/index.ts
8
8
  ℹ tsconfig: tsconfig.json
9
9
  ℹ Build start
10
- ℹ dist/index.js  56.22 kB │ gzip: 13.31 kB
11
- ℹ dist/index.js.map 113.42 kB │ gzip: 26.77 kB
12
- ℹ dist/index.d.ts.map  10.29 kB │ gzip: 4.29 kB
10
+ ℹ dist/index.js  56.25 kB │ gzip: 13.32 kB
11
+ ℹ dist/index.js.map 113.46 kB │ gzip: 26.77 kB
12
+ ℹ dist/index.d.ts.map  10.29 kB │ gzip: 4.28 kB
13
13
  ℹ dist/index.d.ts  30.85 kB │ gzip: 6.36 kB
14
- ℹ 4 files, total: 210.79 kB
15
- ✔ Build complete in 4134ms
14
+ ℹ 4 files, total: 210.84 kB
15
+ ✔ Build complete in 4014ms
package/CHANGELOG.md CHANGED
@@ -939,6 +939,24 @@
939
939
  * @leather.io/prettier-config bumped to 0.9.0
940
940
  * @leather.io/rpc bumped to 2.20.17
941
941
 
942
+ ## [0.36.4](https://github.com/leather-io/mono/compare/@leather.io/bitcoin-v0.36.3...@leather.io/bitcoin-v0.36.4) (2026-01-23)
943
+
944
+
945
+ ### Bug Fixes
946
+
947
+ * **mobile:** migrate to correct fingerprint format ([ef15f7a](https://github.com/leather-io/mono/commit/ef15f7a3f3ea499bf6f1037d147b95c86aef0535))
948
+
949
+
950
+ ### Dependencies
951
+
952
+ * The following workspace dependencies were updated
953
+ * dependencies
954
+ * @leather.io/crypto bumped to 1.12.14
955
+ * @leather.io/utils bumped to 0.49.8
956
+ * devDependencies
957
+ * @leather.io/rpc bumped to 2.21.8
958
+ * @leather.io/test-config bumped to 0.1.3
959
+
942
960
  ## [0.36.3](https://github.com/leather-io/mono/compare/@leather.io/bitcoin-v0.36.2...@leather.io/bitcoin-v0.36.3) (2026-01-21)
943
961
 
944
962
 
package/dist/index.d.ts CHANGED
@@ -308,9 +308,9 @@ declare function getAddressFromOutScript(script: Uint8Array, bitcoinNetwork: Btc
308
308
  */
309
309
  type BtcSignerLibPaymentTypeIdentifers = 'wpkh' | 'wsh' | 'tr' | 'pkh' | 'sh';
310
310
  declare const paymentTypeMap: Record<BtcSignerLibPaymentTypeIdentifers, BitcoinPaymentTypes>;
311
- declare function btcSignerLibPaymentTypeToPaymentTypeMap(payment: BtcSignerLibPaymentTypeIdentifers): "p2pkh" | "p2sh" | "p2wpkh" | "p2tr" | "p2wpkh-p2sh";
311
+ declare function btcSignerLibPaymentTypeToPaymentTypeMap(payment: BtcSignerLibPaymentTypeIdentifers): "p2pkh" | "p2sh" | "p2wpkh-p2sh" | "p2wpkh" | "p2tr";
312
312
  declare function isBtcSignerLibPaymentType(payment: string): payment is BtcSignerLibPaymentTypeIdentifers;
313
- declare function parseKnownPaymentType(payment: BtcSignerLibPaymentTypeIdentifers | BitcoinPaymentTypes): "p2pkh" | "p2sh" | "p2wpkh" | "p2tr" | "p2wpkh-p2sh";
313
+ declare function parseKnownPaymentType(payment: BtcSignerLibPaymentTypeIdentifers | BitcoinPaymentTypes): "p2pkh" | "p2sh" | "p2wpkh-p2sh" | "p2wpkh" | "p2tr";
314
314
  type PaymentTypeMap<T> = Record<BitcoinPaymentTypes, T>;
315
315
  declare function whenPaymentType(mode: BitcoinPaymentTypes | BtcSignerLibPaymentTypeIdentifers): <T>(paymentMap: PaymentTypeMap<T>) => T;
316
316
  type SupportedPaymentType = 'p2wpkh' | 'p2tr';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/bip21/bip21.ts","../src/bip322/bip322-utils.ts","../src/bip322/sign-message-bip322-bitcoinjs.ts","../src/coin-selection/calculate-max-spend.ts","../src/coin-selection/coin-selection.ts","../src/coin-selection/coin-selection.utils.ts","../src/fees/bitcoin-fees.ts","../src/mocks/mocks.ts","../src/schemas/address-schema.ts","../src/utils/bitcoin.network.ts","../src/utils/bitcoin.utils.ts","../src/payments/p2tr-address-gen.ts","../src/payments/p2wpkh-address-gen.ts","../src/payments/p2wsh-p2sh-address-gen.ts","../src/psbt/psbt-inputs.ts","../src/psbt/psbt-outputs.ts","../src/psbt/psbt-totals.ts","../src/psbt/psbt-details.ts","../src/psbt/utils.ts","../src/signer/bitcoin-signer.ts","../src/transactions/generate-unsigned-transaction.ts","../src/validation/address-validation.ts","../src/validation/amount-validation.ts","../src/validation/bitcoin-address.ts","../src/validation/bitcoin-error.ts","../src/utils/bitcoin.descriptors.ts","../src/utils/lookup-derivation-by-address.ts","../src/utils/deconstruct-btc-address.ts"],"sourcesContent":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/bip21/bip21.ts","../src/bip322/bip322-utils.ts","../src/bip322/sign-message-bip322-bitcoinjs.ts","../src/coin-selection/calculate-max-spend.ts","../src/coin-selection/coin-selection.ts","../src/coin-selection/coin-selection.utils.ts","../src/fees/bitcoin-fees.ts","../src/mocks/mocks.ts","../src/schemas/address-schema.ts","../src/utils/bitcoin.network.ts","../src/utils/bitcoin.utils.ts","../src/payments/p2tr-address-gen.ts","../src/payments/p2wpkh-address-gen.ts","../src/payments/p2wsh-p2sh-address-gen.ts","../src/psbt/psbt-inputs.ts","../src/psbt/psbt-outputs.ts","../src/psbt/psbt-totals.ts","../src/psbt/psbt-details.ts","../src/psbt/utils.ts","../src/signer/bitcoin-signer.ts","../src/transactions/generate-unsigned-transaction.ts","../src/validation/address-validation.ts","../src/validation/amount-validation.ts","../src/validation/bitcoin-address.ts","../src/validation/bitcoin-error.ts","../src/utils/bitcoin.descriptors.ts","../src/utils/lookup-derivation-by-address.ts","../src/utils/deconstruct-btc-address.ts"],"sourcesContent":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { decode, encode } from "bip21";
2
- import { assertUnreachable, createCounter, createMoney, defaultWalletKeyId, hexToNumber, isDefined, isEmptyString, isError, isString, isUndefined, satToBtc, subtractMoney, sumMoney, sumNumbers, toHexString, whenNetwork } from "@leather.io/utils";
2
+ import { assertUnreachable, createCounter, createMoney, defaultWalletKeyId, hexToNumber, isDefined, isEmptyString, isError, isString, isUndefined, satToBtc, subtractMoney, sumMoney, sumNumbers, whenNetwork } from "@leather.io/utils";
3
3
  import ecc from "@bitcoinerlab/secp256k1";
4
4
  import { sha256 } from "@noble/hashes/sha256";
5
5
  import { bytesToHex, hexToBytes, utf8ToBytes } from "@noble/hashes/utils";
@@ -9,7 +9,7 @@ import { encode as encode$1 } from "varuint-bitcoin";
9
9
  import { HARDENED_OFFSET, HDKey } from "@scure/bip32";
10
10
  import { mnemonicToSeedSync } from "@scure/bip39";
11
11
  import * as btc from "@scure/btc-signer";
12
- import { DerivationPathDepth, appendAddressIndexToPath, decomposeDescriptor, deriveBip39SeedFromMnemonic, deriveKeychainFromXpub, deriveRootBip32Keychain, extractAccountIndexFromPath, extractAddressIndexFromPath, extractChangeIndexFromPath, extractPurposeFromPath, keyOriginToDerivationPath } from "@leather.io/crypto";
12
+ import { DerivationPathDepth, appendAddressIndexToPath, decomposeDescriptor, deriveBip39SeedFromMnemonic, deriveKeychainFromXpub, deriveRootBip32Keychain, extractAccountIndexFromPath, extractAddressIndexFromPath, extractChangeIndexFromPath, extractPurposeFromPath, fingerprintAsNumberToHex, keyOriginToDerivationPath } from "@leather.io/crypto";
13
13
  import validate$1, { AddressType, Network, getAddressInfo, validate } from "bitcoin-address-validation";
14
14
  import { base58check, base64 } from "@scure/base";
15
15
  import BigNumber from "bignumber.js";
@@ -1233,7 +1233,7 @@ function extractPayerInfoFromDerivationPath(path) {
1233
1233
  */
1234
1234
  function serializeKeyOrigin({ fingerprint, path }) {
1235
1235
  const values = path.map((num) => num >= HARDENED_OFFSET ? num - HARDENED_OFFSET + "'" : num);
1236
- return `${toHexString(fingerprint)}/${values.join("/")}`;
1236
+ return `${fingerprintAsNumberToHex(fingerprint)}/${values.join("/")}`;
1237
1237
  }
1238
1238
  /**
1239
1239
  * @description
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["bitcoinMainnet: BtcSignerNetwork","bitcoinTestnet: BtcSignerNetwork","btcSignerLibNetworks: Record<BitcoinNetworkModes, BtcSignerNetwork>","bitcoinJsLibNetworks: Record<BitcoinNetworkModes, bitcoinJs.Network>","bitcoinNetworkToCoreNetworkMap: Record<BitcoinNetworkModes, NetworkModes>","coinTypeMap: Record<NetworkModes, 0 | 1>","paymentTypeMap: Record<BtcSignerLibPaymentTypeIdentifers, BitcoinPaymentTypes>","inputs: TransactionInput[]","outputs: TransactionOutput[]","bitcoin","encode","supportedMessageSigningPaymentTypes: PaymentTypes[]","privateKey: Uint8Array | undefined","bitcoin","validate","neededUtxos: T[]","changeUtxos: CoinSelectionOutput[]","amount","network","payToScriptHashPrefixMap: Record<NetworkModes, number>","results: DeriveAddressesFromDescriptorResult[]","hashbytes: Uint8Array","bitcoin"],"sources":["../src/bip21/bip21.ts","../src/utils/bitcoin.network.ts","../src/payments/p2tr-address-gen.ts","../src/payments/p2wpkh-address-gen.ts","../src/validation/address-validation.ts","../src/validation/bitcoin-error.ts","../src/validation/bitcoin-address.ts","../src/utils/bitcoin.utils.ts","../src/bip322/bip322-utils.ts","../src/bip322/sign-message-bip322-bitcoinjs.ts","../src/fees/btc-size-fee-estimator.ts","../src/coin-selection/coin-selection.utils.ts","../src/coin-selection/calculate-max-spend.ts","../src/coin-selection/coin-selection.ts","../src/fees/bitcoin-fees.ts","../src/mocks/mocks.ts","../src/schemas/address-schema.ts","../src/payments/p2wsh-p2sh-address-gen.ts","../src/psbt/psbt-totals.ts","../src/psbt/psbt-inputs.ts","../src/psbt/psbt-outputs.ts","../src/psbt/utils.ts","../src/psbt/psbt-details.ts","../src/signer/bitcoin-signer.ts","../src/transactions/generate-unsigned-transaction.ts","../src/validation/amount-validation.ts","../src/utils/bitcoin.descriptors.ts","../src/utils/lookup-derivation-by-address.ts","../src/utils/deconstruct-btc-address.ts"],"sourcesContent":["import { Bip21Options, decode, encode } from 'bip21';\n\nimport { isError } from '@leather.io/utils';\n\ninterface Bip21ResultValue {\n address: string;\n [key: string]: string | number | undefined;\n}\n\ntype Bip21Result =\n | {\n success: true;\n data: Bip21ResultValue;\n }\n | {\n success: false;\n error: string;\n };\n\nexport const bip21 = {\n decode: (uri: string, urnScheme?: string): Bip21Result => {\n try {\n const { address, options } = decode(uri, urnScheme);\n return {\n success: true,\n data: { address, ...options },\n };\n } catch (error) {\n return {\n success: false,\n error: isError(error) ? error.message : 'invalid input',\n };\n }\n },\n encode: (address: string, options: Bip21Options, urnScheme?: string) => {\n try {\n return encode(address, options, urnScheme);\n } catch {\n return null;\n }\n },\n};\n","import * as bitcoinJs from 'bitcoinjs-lib';\n\nimport { BitcoinNetworkModes } from '@leather.io/models';\n\n// TODO - this PR was merged so we could update this\n// https://github.com/paulmillr/scure-btc-signer/blob/main/src/utils.ts\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 '../utils/bitcoin.network';\nimport {\n BitcoinAccount,\n deriveAddressIndexZeroFromAccount,\n ecdsaPublicKeyToSchnorr,\n getBitcoinCoinTypeIndexByNetwork,\n} from '../utils/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,\n accountIndex,\n changeIndex,\n addressIndex,\n}: {\n network: BitcoinNetworkModes;\n accountIndex: number;\n changeIndex: number;\n addressIndex: number;\n}) {\n return (\n makeTaprootAccountDerivationPath(network, accountIndex) + `/${changeIndex}/${addressIndex}`\n );\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 '../utils/bitcoin.network';\nimport {\n BitcoinAccount,\n deriveAddressIndexZeroFromAccount,\n getBitcoinCoinTypeIndexByNetwork,\n} from '../utils/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,\n accountIndex,\n changeIndex,\n addressIndex,\n}: {\n network: BitcoinNetworkModes;\n accountIndex: number;\n changeIndex: number;\n addressIndex: number;\n}) {\n return (\n makeNativeSegwitAccountDerivationPath(network, accountIndex) + `/${changeIndex}/${addressIndex}`\n );\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 { Network, validate } from 'bitcoin-address-validation';\n\nimport { BitcoinNetworkModes } from '@leather.io/models';\nimport { isEmptyString, isUndefined } from '@leather.io/utils';\n\n// todo investigate handling this in bitcoinNetworkToNetworkMode\nexport function getBitcoinAddressNetworkType(network: BitcoinNetworkModes): Network {\n // Signet uses testnet address format, this parsing is to please the\n // validation library - 'bitcoin-address-validation'\n if (network === 'signet') return Network.testnet;\n return network as Network;\n}\n\nexport function isValidBitcoinAddress(address: string) {\n if (isUndefined(address) || isEmptyString(address)) {\n return false;\n }\n\n return validate(address);\n}\n\nexport function isValidBitcoinNetworkAddress(address: string, network: BitcoinNetworkModes) {\n return validate(address, getBitcoinAddressNetworkType(network));\n}\n","import { TransactionErrorKey } from '@leather.io/models';\n\nexport 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 | TransactionErrorKey\n | 'InsufficientAmount'\n | 'NoInputsToSign'\n | 'NoOutputsToSign'\n | 'InscribedUtxos';\n","import { BitcoinAddress } from '@leather.io/models';\n\nimport { isValidBitcoinAddress } from './address-validation';\nimport { BitcoinError } from './bitcoin-error';\n\nexport function isBitcoinAddress(value: string): value is BitcoinAddress {\n try {\n isValidBitcoinAddress(value);\n return true;\n } catch {\n return false;\n }\n}\n\n// Function to create a BitcoinAddress\nexport function createBitcoinAddress(value: string): BitcoinAddress {\n if (!isBitcoinAddress(value)) {\n throw new BitcoinError('InvalidAddress');\n }\n\n return value;\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 { BitcoinAddress, BitcoinNetworkModes, NetworkModes } from '@leather.io/models';\nimport type { BitcoinPaymentTypes } from '@leather.io/rpc';\nimport { defaultWalletKeyId, isDefined, whenNetwork } from '@leather.io/utils';\n\nimport { getTaprootPayment } from '../payments/p2tr-address-gen';\nimport { getNativeSegwitPaymentFromAddressIndex } from '../payments/p2wpkh-address-gen';\nimport { createBitcoinAddress } from '../validation/bitcoin-address';\nimport { BtcSignerNetwork, getBtcSignerLibNetworkConfigByMode } from './bitcoin.network';\n\nexport interface BitcoinAccount {\n type: BitcoinPaymentTypes;\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 ({ changeIndex, addressIndex }: { changeIndex: number; addressIndex: number }) =>\n keychain.deriveChild(changeIndex).deriveChild(addressIndex);\n}\n\nexport function deriveAddressIndexZeroFromAccount(keychain: HDKey) {\n return deriveAddressIndexKeychainFromAccount(keychain)({\n changeIndex: 0,\n addressIndex: 0,\n });\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 function toXOnly(pubKey: Buffer) {\n return pubKey.length === 32 ? pubKey : pubKey.subarray(1, 33);\n}\n\nexport function decodeBitcoinTx(tx: string): ReturnType<typeof btc.RawTx.decode> {\n return btc.RawTx.decode(hexToBytes(tx));\n}\n\nexport function getAddressFromOutScript(\n script: Uint8Array,\n bitcoinNetwork: BtcSignerNetwork\n): BitcoinAddress | null {\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 createBitcoinAddress(\n btc.Address(bitcoinNetwork).encode({\n type: outputScript.type,\n hash: outputScript.hash,\n })\n );\n case 'tr':\n return createBitcoinAddress(\n btc.Address(bitcoinNetwork).encode({\n type: outputScript.type,\n pubkey: outputScript.pubkey,\n })\n );\n case 'ms':\n return createBitcoinAddress(btc.p2ms(outputScript.m, outputScript.pubkeys).address ?? '');\n case 'pk':\n return createBitcoinAddress(btc.p2pk(outputScript.pubkey, bitcoinNetwork).address ?? '');\n case 'unknown':\n case 'tr_ms':\n case 'tr_ns':\n case 'p2a':\n default:\n return null;\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, BitcoinPaymentTypes> = {\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(\n payment: BtcSignerLibPaymentTypeIdentifers | BitcoinPaymentTypes\n) {\n return isBtcSignerLibPaymentType(payment)\n ? btcSignerLibPaymentTypeToPaymentTypeMap(payment)\n : payment;\n}\n\nexport type PaymentTypeMap<T> = Record<BitcoinPaymentTypes, T>;\nexport function whenPaymentType(mode: BitcoinPaymentTypes | 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): BitcoinPaymentTypes {\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 null;\n}\n\nexport function getInputPaymentType(\n input: TransactionInput,\n network: BitcoinNetworkModes\n): BitcoinPaymentTypes {\n const address = getBitcoinInputAddress(input, getBtcSignerLibNetworkConfigByMode(network));\n if (address === null) 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 changeIndex: number;\n addressIndex: number;\n keychain?: HDKey;\n network: BitcoinNetworkModes;\n}\n\nexport function getTaprootAddress({\n changeIndex,\n addressIndex,\n keychain,\n network,\n}: 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 addresskeychain = deriveAddressIndexKeychainFromAccount(keychain)({\n changeIndex,\n addressIndex,\n });\n\n if (!addresskeychain.publicKey) throw new Error('Expected publicKey to be defined');\n\n const payment = getTaprootPayment(addresskeychain.publicKey, network);\n\n if (!payment.address) throw new Error('Expected address to be defined');\n return payment.address;\n}\n\nexport function getNativeSegwitAddress({\n changeIndex,\n addressIndex,\n keychain,\n network,\n}: 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 addressKeychain = deriveAddressIndexKeychainFromAccount(keychain)({\n changeIndex,\n addressIndex,\n });\n\n if (!addressKeychain.publicKey) throw new Error('Expected publicKey to be defined');\n\n const payment = getNativeSegwitPaymentFromAddressIndex(addressKeychain, 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: BitcoinAddress): 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: BitcoinAddress): 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\nexport function isTaprootDerivationPath(path: string) {\n return extractPurposeFromPath(path) === 86;\n}\n\nexport function isNativeSegwitDerivationPath(path: string) {\n return extractPurposeFromPath(path) === 84;\n}\n","import ecc from '@bitcoinerlab/secp256k1';\nimport { sha256 } from '@noble/hashes/sha256';\nimport { hexToBytes, utf8ToBytes } from '@noble/hashes/utils';\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 '../utils/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 { base64 } from '@scure/base';\nimport * as btc from '@scure/btc-signer';\nimport * as bitcoin from 'bitcoinjs-lib';\n\nimport { BitcoinAddress, BitcoinNetworkModes } from '@leather.io/models';\n\nimport { getBitcoinJsLibNetworkConfigByMode } from '../utils/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(\n address: BitcoinAddress,\n message: string,\n network: BitcoinNetworkModes\n) {\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: BitcoinAddress;\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","// 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, { 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 '../fees/btc-size-fee-estimator';\nimport { CoinSelectionRecipient } from './coin-selection';\n\nexport function getUtxoTotal<T extends { value: number }>(utxos: T[]) {\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}\ninterface GetSpendableAmountArgs<T> {\n utxos: T[];\n feeRate: number;\n recipients: CoinSelectionRecipient[];\n isSendMax?: boolean;\n}\nexport function getSpendableAmount<T extends { value: number }>({\n utxos,\n feeRate,\n recipients,\n}: GetSpendableAmountArgs<T>) {\n const balance = utxos.map(utxo => utxo.value).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<T extends { value: number; txid: string }>({\n utxos,\n feeRate,\n recipients,\n}: {\n utxos: T[];\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 => Number(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","import BigNumber from 'bignumber.js';\n\nimport type { Money } from '@leather.io/models';\nimport { createMoney, satToBtc } from '@leather.io/utils';\n\nimport { filterUneconomicalUtxos, getSpendableAmount } from './coin-selection.utils';\n\ninterface CalculateMaxSpendParams {\n recipient: string;\n utxos: { value: number; txid: string }[];\n feeRate: number;\n}\n\nexport interface CalculateMaxSpendResponse {\n spendAllFee: number;\n amount: Money;\n spendableBitcoin: BigNumber;\n}\nexport function calculateMaxSpend({\n recipient,\n utxos,\n feeRate,\n}: CalculateMaxSpendParams): CalculateMaxSpendResponse {\n if (!utxos.length)\n return {\n spendAllFee: 0,\n amount: createMoney(0, 'BTC'),\n spendableBitcoin: new BigNumber(0),\n };\n\n const filteredUtxos = filterUneconomicalUtxos({\n utxos,\n feeRate,\n recipients: [{ address: recipient, amount: createMoney(0, 'BTC') }],\n });\n\n const { spendableAmount, fee } = getSpendableAmount({\n utxos: filteredUtxos,\n feeRate,\n recipients: [{ address: recipient, amount: createMoney(0, 'BTC') }],\n isSendMax: true,\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 } 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 '../validation/bitcoin-error';\nimport { filterUneconomicalUtxos, getSizeInfo, getUtxoTotal } from './coin-selection.utils';\n\nexport interface CoinSelectionOutput {\n value: bigint;\n address?: string;\n}\n\nexport interface CoinSelectionRecipient {\n address: string;\n amount: Money;\n}\n\nexport interface DetermineUtxosForSpendArgs<T> {\n feeRate: number;\n recipients: CoinSelectionRecipient[];\n utxos: T[];\n}\nexport function determineUtxosForSpendAll<T extends { value: number; txid: string }>({\n feeRate,\n recipients,\n utxos,\n}: DetermineUtxosForSpendArgs<T>) {\n recipients.forEach(recipient => {\n if (!validate(recipient.address)) throw new BitcoinError('InvalidAddress');\n });\n const filteredUtxos = filterUneconomicalUtxos({ utxos, feeRate, recipients });\n\n if (!filteredUtxos.length) throw new BitcoinError('InsufficientFunds');\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<T extends { value: number; txid: string }>({\n feeRate,\n recipients,\n utxos,\n}: DetermineUtxosForSpendArgs<T>) {\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: T[] = [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","import { AverageBitcoinFeeRates, Money } from '@leather.io/models';\n\nimport {\n CoinSelectionRecipient,\n DetermineUtxosForSpendArgs,\n determineUtxosForSpend,\n determineUtxosForSpendAll,\n} from '../coin-selection/coin-selection';\n\ntype GetBitcoinTransactionFeeArgs = DetermineUtxosForSpendArgs<{ value: number; txid: string }> & {\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: { value: number; txid: string }[];\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 { createBitcoinAddress } from '../validation/bitcoin-address';\n\n// maybe these should be in mono/config?\n// from extension/tests/mocks/constants\nexport const TEST_ACCOUNT_1_NATIVE_SEGWIT_ADDRESS = createBitcoinAddress(\n 'bc1q530dz4h80kwlzywlhx2qn0k6vdtftd93c499yq'\n);\nexport const TEST_ACCOUNT_1_TAPROOT_ADDRESS = createBitcoinAddress(\n 'bc1putuzj9lyfcm8fef9jpy85nmh33cxuq9u6wyuk536t9kemdk37yjqmkc0pg'\n);\nexport const TEST_ACCOUNT_2_TAPROOT_ADDRESS = createBitcoinAddress(\n 'bc1pmk2sacpfyy4v5phl8tq6eggu4e8laztep7fsgkkx0nc6m9vydjesaw0g2r'\n);\n\nexport const TEST_TESNET_ACCOUNT_1_NATIVE_SEGWIT_ADDRESS = createBitcoinAddress(\n 'tb1q4qgnjewwun2llgken94zqjrx5kpqqycaz5522d'\n);\n\nexport const TEST_TESTNET_ACCOUNT_2_BTC_ADDRESS = createBitcoinAddress(\n 'tb1qr8me8t9gu9g6fu926ry5v44yp0wyljrespjtnz'\n);\n\nexport const TEST_TESTNET_ACCOUNT_2_TAPROOT_ADDRESS = createBitcoinAddress(\n 'tb1pve00jmp43whpqj2wpcxtc7m8wqhz0azq689y4r7h8tmj8ltaj87qj2nj6w'\n);\n\n// coin-selection.spec\nexport const recipientAddress = createBitcoinAddress('tb1qt28eagxcl9gvhq2rpj5slg7dwgxae2dn2hk93m');\nexport const legacyAddress = createBitcoinAddress('15PyZveQd28E2SHZu2ugkWZBp6iER41vXj');\nexport const segwitAddress = createBitcoinAddress('33SVjoCHJovrXxjDKLFSXo1h3t5KgkPzfH');\nexport const taprootAddress = createBitcoinAddress(\n 'tb1parwmj7533de3k2fw2kntyqacspvhm67qnjcmpqnnpfvzu05l69nsczdywd'\n);\nexport const invalidAddress = 'whoop-de-da-boop-da-de-not-a-bitcoin-address';\n\nexport const inValidCharactersAddress = createBitcoinAddress(\n 'tb1&*%wmj7533de3k2fw2kntyqacspvhm67qnjcmpqnnpfvzu05l69nsczdywd'\n);\nexport const inValidLengthAddress = createBitcoinAddress('tb1parwmj7533de3k2fw2kntyqacspvhm67wd');\n","import { Network, getAddressInfo, validate } from 'bitcoin-address-validation';\nimport { z } from 'zod';\n\nimport type { BitcoinNetworkModes } from '@leather.io/models';\nimport { isEmptyString, isUndefined } from '@leather.io/utils';\n\nexport function nonEmptyStringValidator(message = '') {\n return z\n .string()\n .refine((value: string) => value !== undefined && value.trim() !== '', { message });\n}\n\nexport function btcAddressValidator() {\n return z.string().refine(\n (value: string) => {\n if (isUndefined(value) || isEmptyString(value)) return true;\n return validate(value);\n },\n { message: 'Bitcoin address is not valid' }\n );\n}\n\nexport function getNetworkTypeFromAddress(address: string) {\n return getAddressInfo(address).network as BitcoinNetworkModes;\n}\n\nfunction btcAddressNetworkValidatorFactory(network: BitcoinNetworkModes) {\n function getAddressNetworkType(network: BitcoinNetworkModes): Network {\n // Signet uses testnet address format, this parsing is to please the\n // validation library\n if (network === 'signet') return Network.testnet;\n return network as Network;\n }\n return (value?: string) => {\n if (isUndefined(value) || isEmptyString(value)) return true;\n return validate(value, getAddressNetworkType(network));\n };\n}\n\nexport function btcAddressNetworkValidator(network: BitcoinNetworkModes) {\n return z.string().refine(btcAddressNetworkValidatorFactory(network), {\n message: 'Address is for incorrect network',\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 { BitcoinAddress } from '@leather.io/models';\nimport { createMoney, sumNumbers } from '@leather.io/utils';\n\nimport { inferPaymentTypeFromAddress } from '../utils/bitcoin.utils';\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: BitcoinAddress[];\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 { bytesToHex } from '@noble/hashes/utils';\nimport type { TransactionInput } from '@scure/btc-signer/psbt';\n\nimport type { BitcoinAddress, BitcoinNetworkModes, InscriptionAsset } from '@leather.io/models';\nimport { isDefined, isUndefined } from '@leather.io/utils';\n\nimport { getBtcSignerLibNetworkConfigByMode } from '../utils/bitcoin.network';\nimport { getBitcoinInputAddress, getBitcoinInputValue } from '../utils/bitcoin.utils';\n\nexport interface PsbtInput {\n address: BitcoinAddress;\n index?: number;\n // TODO: inject inscription later on. getParsedInputs should be a pure function\n inscription?: InscriptionAsset;\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: BitcoinAddress[];\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 bitcoinAddress = isDefined(input.index)\n ? getBitcoinInputAddress(input, bitcoinNetwork)\n : null;\n if (bitcoinAddress === null) {\n throw new Error('PSBT input has unsupported bitcoin address');\n }\n const isCurrentAddress = psbtAddresses.includes(bitcoinAddress);\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: bitcoinAddress,\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';\n\nimport { BitcoinAddress, BitcoinNetworkModes } from '@leather.io/models';\nimport { isDefined, isUndefined } from '@leather.io/utils';\n\nimport { getBtcSignerLibNetworkConfigByMode } from '../utils/bitcoin.network';\nimport { getAddressFromOutScript } from '../utils/bitcoin.utils';\n\nexport interface PsbtOutput {\n address: BitcoinAddress | null;\n isMutable: boolean;\n toSign: boolean;\n value: number;\n}\n\nexport interface PsbtOutputWithAddress extends PsbtOutput {\n address: BitcoinAddress;\n}\n\ninterface GetParsedOutputsArgs {\n isPsbtMutable: boolean;\n outputs: TransactionOutput[];\n networkMode: BitcoinNetworkModes;\n psbtAddresses: BitcoinAddress[];\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 = !!outputAddress && 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 { 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","import { BitcoinAddress, BitcoinNetworkModes } from '@leather.io/models';\nimport { createMoney, subtractMoney } from '@leather.io/utils';\n\nimport { getPsbtTxInputs, getPsbtTxOutputs } from '../utils/bitcoin.utils';\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: BitcoinAddress[];\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 { 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';\nimport * as bitcoin from 'bitcoinjs-lib';\n\nimport {\n DerivationPathDepth,\n appendAddressIndexToPath,\n decomposeDescriptor,\n deriveKeychainFromXpub,\n extractAddressIndexFromPath,\n extractChangeIndexFromPath,\n keyOriginToDerivationPath,\n} from '@leather.io/crypto';\nimport type { BitcoinAddress, BitcoinNetworkModes, ValueOf } from '@leather.io/models';\nimport { PaymentTypes, signatureHash } from '@leather.io/rpc';\nimport { hexToNumber, toHexString } from '@leather.io/utils';\n\nimport { getTaprootPaymentFromAddressIndex } from '../payments/p2tr-address-gen';\nimport { getNativeSegwitPaymentFromAddressIndex } from '../payments/p2wpkh-address-gen';\nimport {\n SupportedPaymentType,\n ecdsaPublicKeyToSchnorr,\n extractExtendedPublicKeyFromPolicy,\n inferPaymentTypeFromPath,\n whenSupportedPaymentType,\n} from '../utils/bitcoin.utils';\n\nexport type AllowedSighashTypes = ValueOf<typeof 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: BitcoinAddress;\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: BitcoinAddress;\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 change: 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 ({ change, addressIndex }: BitcoinPayerInfo) => {\n const childKeychain = accountKeychain.deriveChild(change).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, change, addressIndex),\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\ntype PsbtInputBitcoinJsLib = bitcoin.Psbt['data']['inputs']['0'];\n\ntype TapBip32DerivationBitcoinJsLib = NonNullable<PsbtInputBitcoinJsLib['tapBip32Derivation']>['0'];\n\nexport function payerToTapBip32DerivationBitcoinJsLib(\n args: PayerToBip32DerivationArgs\n): TapBip32DerivationBitcoinJsLib {\n return {\n masterFingerprint: Buffer.from(args.masterKeyFingerprint, 'hex'),\n path: keyOriginToDerivationPath(args.keyOrigin),\n leafHashes: [],\n pubkey: Buffer.from(ecdsaPublicKeyToSchnorr(args.publicKey)),\n };\n}\n\ntype Bip32DerivationBitcoinJsLib = NonNullable<PsbtInputBitcoinJsLib['bip32Derivation']>['0'];\n\nexport function payerToBip32DerivationBitcoinJsLib(\n args: PayerToBip32DerivationArgs\n): Bip32DerivationBitcoinJsLib {\n return {\n masterFingerprint: Buffer.from(args.masterKeyFingerprint, 'hex'),\n path: keyOriginToDerivationPath(args.keyOrigin),\n pubkey: Buffer.from(args.publicKey),\n };\n}\n\nexport function extractPayerInfoFromDerivationPath(path: string) {\n return {\n change: extractChangeIndexFromPath(path),\n addressIndex: extractAddressIndexFromPath(path),\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 * as btc from '@scure/btc-signer';\n\nimport {\n CoinSelectionRecipient,\n determineUtxosForSpend,\n determineUtxosForSpendAll,\n} from '../coin-selection/coin-selection';\nimport {\n BitcoinNativeSegwitPayer,\n BitcoinTaprootPayer,\n payerToBip32Derivation,\n payerToTapBip32Derivation,\n} from '../signer/bitcoin-signer';\nimport { BtcSignerNetwork } from '../utils/bitcoin.network';\nimport { BitcoinError } from '../validation/bitcoin-error';\n\nexport interface GenerateBitcoinUnsignedTransactionArgs<T> {\n feeRate: number;\n isSendingMax?: boolean;\n network: BtcSignerNetwork;\n recipients: CoinSelectionRecipient[];\n utxos: T[];\n changeAddress: string;\n payerLookup(keyOrigin: string): BitcoinNativeSegwitPayer | BitcoinTaprootPayer | undefined;\n}\nexport function generateBitcoinUnsignedTransaction<\n T extends { txid: string; vout: number; value: number; keyOrigin: string },\n>({\n feeRate,\n isSendingMax,\n network,\n recipients,\n changeAddress,\n utxos,\n payerLookup,\n}: GenerateBitcoinUnsignedTransactionArgs<T>) {\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\n for (const input of inputs) {\n const payer = payerLookup(input.keyOrigin);\n\n if (!payer) {\n // eslint-disable-next-line no-console\n console.log(`No payer found for input with keyOrigin ${input.keyOrigin}`);\n continue;\n }\n\n const bip32Derivation =\n payer.paymentType === 'p2tr'\n ? { tapBip32Derivation: [payerToTapBip32Derivation(payer)] }\n : { bip32Derivation: [payerToBip32Derivation(payer)] };\n\n const tapInternalKey =\n payer.paymentType === 'p2tr' ? { tapInternalKey: payer.payment.tapInternalKey } : {};\n\n tx.addInput({\n txid: input.txid,\n index: input.vout,\n witnessUtxo: {\n script: payer.payment.script,\n amount: BigInt(input.value),\n },\n ...bip32Derivation,\n ...tapInternalKey,\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(changeAddress, 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 { BITCOIN_MINIMUM_SPEND_IN_SATS } from '@leather.io/constants';\nimport { Money } from '@leather.io/models';\n\ninterface isBtcBalanceSufficientParams {\n desiredSpend: Money;\n maxSpend: Money;\n}\nexport function isBtcBalanceSufficient({ desiredSpend, maxSpend }: isBtcBalanceSufficientParams) {\n return !desiredSpend.amount.isGreaterThan(maxSpend.amount);\n}\n\nexport function isBtcMinimumSpend(desiredSpend: Money) {\n return !desiredSpend.amount.isLessThan(BITCOIN_MINIMUM_SPEND_IN_SATS);\n}\n","import { HARDENED_OFFSET, HDKey } from '@scure/bip32';\nimport { makeTaprootAddressIndexDerivationPath } from 'payments/p2tr-address-gen';\nimport { makeNativeSegwitAddressIndexDerivationPath } from 'payments/p2wpkh-address-gen';\n\nimport { BitcoinNetworkModes } from '@leather.io/models';\n\nimport {\n SupportedPaymentType,\n getNativeSegwitAddress,\n getTaprootAddress,\n inferPaymentTypeFromPath,\n whenSupportedPaymentType,\n} from './bitcoin.utils';\n\nexport function getDescriptorFromKeychain<T extends { keyOrigin: string; xpub: string }>(\n accountKeychain: T\n) {\n switch (inferPaymentTypeFromPath(accountKeychain.keyOrigin)) {\n case 'p2tr':\n return `tr(${accountKeychain.xpub})`;\n case 'p2wpkh':\n return `wpkh(${accountKeychain.xpub})`;\n default:\n return undefined;\n }\n}\n\nexport function inferPaymentTypeFromDescriptor(descriptor: string): SupportedPaymentType {\n const descriptorPrefix = descriptor.split('(')[0];\n switch (descriptorPrefix) {\n case 'tr':\n return 'p2tr';\n case 'wpkh':\n return 'p2wpkh';\n default:\n throw new Error('Unrecognized descriptor');\n }\n}\n\nexport function extractXpubFromDescriptor(descriptor: string) {\n const match = descriptor.match(/\\((xpub[0-9A-Za-z]+)\\)/);\n if (match && match[1]) {\n return match[1];\n }\n throw new Error('Invalid descriptor format');\n}\n\nexport interface DeriveAddressesFromDescriptorArgs {\n accountDescriptor: string;\n network: BitcoinNetworkModes;\n limit?: number; // number of addresses to derive\n}\n\nexport interface DeriveAddressesFromDescriptorResult {\n address: string;\n path: string;\n}\n\nexport function deriveAddressesFromDescriptor({\n accountDescriptor,\n network,\n limit = 1,\n}: DeriveAddressesFromDescriptorArgs): DeriveAddressesFromDescriptorResult[] {\n const accountKeychain = HDKey.fromExtendedKey(extractXpubFromDescriptor(accountDescriptor));\n const paymentType = inferPaymentTypeFromDescriptor(accountDescriptor);\n\n const derivationPathFn = whenSupportedPaymentType(paymentType)({\n p2tr: makeTaprootAddressIndexDerivationPath,\n p2wpkh: makeNativeSegwitAddressIndexDerivationPath,\n });\n\n const results: DeriveAddressesFromDescriptorResult[] = [];\n\n for (let addressIndex = 0; addressIndex < limit; ++addressIndex) {\n for (let changeIndex = 0; changeIndex < 2; ++changeIndex) {\n const address = whenSupportedPaymentType(paymentType)({\n p2tr: getTaprootAddress({ addressIndex, changeIndex, keychain: accountKeychain, network }),\n p2wpkh: getNativeSegwitAddress({\n addressIndex,\n changeIndex,\n keychain: accountKeychain,\n network,\n }),\n });\n results.push({\n address,\n path: derivationPathFn({\n network,\n accountIndex: accountKeychain.index - HARDENED_OFFSET,\n addressIndex,\n changeIndex,\n }),\n });\n }\n }\n return results;\n}\n","import { HARDENED_OFFSET, HDKey } from '@scure/bip32';\n\nimport { BitcoinAddress } from '@leather.io/models';\nimport { createCounter } from '@leather.io/utils';\n\nimport { makeTaprootAddressIndexDerivationPath } from '../payments/p2tr-address-gen';\nimport { makeNativeSegwitAddressIndexDerivationPath } from '../payments/p2wpkh-address-gen';\nimport {\n getNativeSegwitAddress,\n getTaprootAddress,\n inferNetworkFromAddress,\n inferPaymentTypeFromAddress,\n whenSupportedPaymentType,\n} from './bitcoin.utils';\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: BitcoinAddress) => {\n const network = inferNetworkFromAddress(address);\n const changeIndex = 0;\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(addressIndex: number) {\n return getTaprootAddress({ changeIndex, addressIndex, keychain: taprootKeychain, network });\n }\n\n function getNativeSegwitAddressAtIndex(addressIndex: number) {\n return getNativeSegwitAddress({\n changeIndex,\n addressIndex,\n keychain: nativeSegwitKeychain,\n network,\n });\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({\n network,\n accountIndex,\n addressIndex: currentIndex,\n changeIndex,\n }),\n } as const;\n }\n\n return { status: 'failure' } as const;\n };\n}\n","import { AddressType, getAddressInfo } from 'bitcoin-address-validation';\nimport * as bitcoin from 'bitcoinjs-lib';\n\nexport function deconstructBtcAddress(address: string) {\n const typeMapping = {\n [AddressType.p2pkh]: '0x00',\n [AddressType.p2sh]: '0x01',\n [AddressType.p2wpkh]: '0x04',\n [AddressType.p2wsh]: '0x05',\n [AddressType.p2tr]: '0x06',\n };\n\n const addressInfo = getAddressInfo(address);\n\n const { bech32 } = addressInfo;\n let hashbytes: Uint8Array;\n if (bech32) {\n hashbytes = bitcoin.address.fromBech32(address).data;\n } else {\n hashbytes = bitcoin.address.fromBase58Check(address).hash;\n }\n\n const type = typeMapping[addressInfo.type];\n if (!type) {\n throw new Error(`Unsupported address type: ${addressInfo.type}`);\n }\n\n return {\n type,\n hashbytes,\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAmBA,MAAa,QAAQ;CACnB,SAAS,KAAa,cAAoC;AACxD,MAAI;GACF,MAAM,EAAE,SAAS,YAAY,OAAO,KAAK,UAAU;AACnD,UAAO;IACL,SAAS;IACT,MAAM;KAAE;KAAS,GAAG;KAAS;IAC9B;WACM,OAAO;AACd,UAAO;IACL,SAAS;IACT,OAAO,QAAQ,MAAM,GAAG,MAAM,UAAU;IACzC;;;CAGL,SAAS,SAAiB,SAAuB,cAAuB;AACtE,MAAI;AACF,UAAO,OAAO,SAAS,SAAS,UAAU;UACpC;AACN,UAAO;;;CAGZ;;;;AC1BD,MAAMA,iBAAmC;CACvC,QAAQ;CACR,YAAY;CACZ,YAAY;CACZ,KAAK;CACN;AAED,MAAMC,iBAAmC;CACvC,QAAQ;CACR,YAAY;CACZ,YAAY;CACZ,KAAK;CACN;AASD,MAAMC,uBAAsE;CAC1E,SAAS;CACT,SAAS;CACT,SAVuC;EACvC,QAAQ;EACR,YAAY;EACZ,YAAY;EACZ,KAAK;EACN;CAQC,QAAQ;CACT;AAED,SAAgB,mCAAmC,SAA8B;AAC/E,QAAO,qBAAqB;;AAG9B,MAAMC,uBAAuE;CAC3E,SAAS,UAAU,SAAS;CAC5B,SAAS,UAAU,SAAS;CAC5B,SAAS,UAAU,SAAS;CAC5B,QAAQ,UAAU,SAAS;CAC5B;AAED,SAAgB,mCAAmC,SAA8B;AAC/E,QAAO,qBAAqB;;;;;AC3C9B,SAAgB,iCACd,SACA,cACA;AACA,QAAO,SAAS,iCAAiC,QAAQ,CAAC,IAAI,aAAa;;;AAG7E,MAAa,kCAAkC;AAE/C,SAAgB,sCAAsC,EACpD,SACA,cACA,aACA,gBAMC;AACD,QACE,iCAAiC,SAAS,aAAa,GAAG,IAAI,YAAY,GAAG;;;AAIjF,MAAa,uCAAuC;AAEpD,SAAgB,qBAAqB,UAAiB,SAA8B;AAClF,KAAI,SAAS,UAAU,oBAAoB,KACzC,OAAM,IAAI,MAAM,oCAAoC;AAEtD,SAAQ,kBAA0C;EAChD,MAAM;EACN;EACA;EACA,gBAAgB,iCAAiC,SAAS,aAAa;EACvE,UAAU,SAAS,OAAO,iCAAiC,SAAS,aAAa,CAAC;EACnF;;AAGH,SAAgB,kBAAkB,WAAuB,SAA8B;AACrF,QAAO,IAAI,KACT,wBAAwB,UAAU,EAClC,QACA,mCAAmC,QAAQ,EAC3C,KACD;;AAGH,SAAgB,kCAAkC,UAAiB,SAA8B;AAC/F,KAAI,SAAS,UAAU,oBAAoB,aACzC,OAAM,IAAI,MAAM,0CAA0C;AAE5D,KAAI,CAAC,SAAS,UAAW,OAAM,IAAI,MAAM,6BAA6B;AAEtE,QAAO,kBAAkB,SAAS,WAAW,QAAQ;;AAOvD,SAAgB,qCAAqC,EACnD,UACA,WACuC;CACvC,MAAM,mBAAmB,kCAAkC,SAAS;AACpE,QAAO;EACL,UAAU;EACV,SAAS,kCAAkC,kBAAkB,QAAQ;EACtE;;;;;ACvEH,SAAgB,sCACd,SACA,cACA;AACA,QAAO,SAAS,iCAAiC,QAAQ,CAAC,IAAI,aAAa;;;AAI7E,MAAa,uCAAuC;AAEpD,SAAgB,2CAA2C,EACzD,SACA,cACA,aACA,gBAMC;AACD,QACE,sCAAsC,SAAS,aAAa,GAAG,IAAI,YAAY,GAAG;;;AAKtF,MAAa,4CAA4C;AAEzD,SAAgB,0CACd,UACA,SACA;AACA,KAAI,SAAS,UAAU,oBAAoB,KAAM,OAAM,IAAI,MAAM,gCAAgC;AACjG,SAAQ,kBAA0C;EAChD,MAAM;EACN;EACA;EACA,gBAAgB,sCAAsC,SAAS,aAAa;EAC5E,UAAU,SAAS,OAAO,sCAAsC,SAAS,aAAa,CAAC;EACxF;;AAGH,SAAgB,uCACd,UACA,SACA;AACA,KAAI,SAAS,UAAU,oBAAoB,aACzC,OAAM,IAAI,MAAM,0CAA0C;AAE5D,KAAI,CAAC,SAAS,UAAW,OAAM,IAAI,MAAM,sCAAsC;AAE/E,QAAO,IAAI,OAAO,SAAS,WAAW,mCAAmC,QAAQ,CAAC;;AAOpF,SAAgB,0CAA0C,EACxD,UACA,WAC4C;CAC5C,MAAM,mBAAmB,kCAAkC,SAAS;AACpE,QAAO;EACL,UAAU;EACV,SAAS,uCAAuC,kBAAkB,QAAQ;EAC3E;;;;;AC1EH,SAAgB,6BAA6B,SAAuC;AAGlF,KAAI,YAAY,SAAU,QAAO,QAAQ;AACzC,QAAO;;AAGT,SAAgB,sBAAsB,SAAiB;AACrD,KAAI,YAAY,QAAQ,IAAI,cAAc,QAAQ,CAChD,QAAO;AAGT,QAAO,SAAS,QAAQ;;AAG1B,SAAgB,6BAA6B,SAAiB,SAA8B;AAC1F,QAAO,SAAS,SAAS,6BAA6B,QAAQ,CAAC;;;;;ACpBjE,IAAa,eAAb,cAAkC,MAAM;CACtC,AAAO;CACP,YAAY,SAA0B;AACpC,QAAM,QAAQ;AACd,OAAK,OAAO;AACZ,OAAK,UAAU;AAGf,SAAO,eAAe,MAAM,IAAI,OAAO,UAAU;;;;;;ACLrD,SAAgB,iBAAiB,OAAwC;AACvE,KAAI;AACF,wBAAsB,MAAM;AAC5B,SAAO;SACD;AACN,SAAO;;;AAKX,SAAgB,qBAAqB,OAA+B;AAClE,KAAI,CAAC,iBAAiB,MAAM,CAC1B,OAAM,IAAI,aAAa,iBAAiB;AAG1C,QAAO;;;;;ACOT,SAAgB,mBAAmB,gBAAwB,QAAgC;CACzF,MAAM,OAAO,mCAAmC,OAAO;CACvD,MAAM,UAAU,qBAAqB,eAAe;AACpD,QAAO;EACL,UAAU,MAAM,gBAAgB,MAAM,4BAA4B,QAAQ,CAAC;EAC3E;EACA;EACA,MAAM,yBAAyB,eAAe;EAC9C,cAAc,4BAA4B,eAAe;EAC1D;;;;;;;AAQH,MAAaC,iCAA4E;CACvF,SAAS;CACT,SAAS;CACT,SAAS;CACT,QAAQ;CACT;AACD,SAAgB,oCAAoC,MAA2B;AAC7E,QAAO,+BAA+B;;AAKxC,SAAgB,mBAAmB,MAA2B;AAC5D,SAA8C,eAC5C,WAAW;;;;;;;;AASf,MAAaC,cAA2C;CACtD,SAAS;CACT,SAAS;CACV;AAED,SAAgB,iCAAiC,SAA8B;AAC7E,QAAO,YAAY,oCAAoC,QAAQ;;AAGjE,SAAgB,sCAAsC,UAAiB;AACrE,KAAI,SAAS,UAAU,oBAAoB,QACzC,OAAM,IAAI,MAAM,oCAAoC;AAEtD,SAAQ,EAAE,aAAa,mBACrB,SAAS,YAAY,YAAY,CAAC,YAAY,aAAa;;AAG/D,SAAgB,kCAAkC,UAAiB;AACjE,QAAO,sCAAsC,SAAS,CAAC;EACrD,aAAa;EACb,cAAc;EACf,CAAC;;AAGJ,MAAa,uBAAuB;AAEpC,SAAgB,wBAAwB,QAAoB;AAC1D,KAAI,OAAO,eAAe,qBAAsB,OAAM,IAAI,MAAM,4BAA4B;AAC5F,QAAO,OAAO,MAAM,EAAE;;AAIxB,SAAgB,QAAQ,QAAgB;AACtC,QAAO,OAAO,WAAW,KAAK,SAAS,OAAO,SAAS,GAAG,GAAG;;AAG/D,SAAgB,gBAAgB,IAAiD;AAC/E,QAAO,IAAI,MAAM,OAAO,WAAW,GAAG,CAAC;;AAGzC,SAAgB,wBACd,QACA,gBACuB;CACvB,MAAM,eAAe,IAAI,UAAU,OAAO,OAAO;AAEjD,SAAQ,aAAa,MAArB;EACE,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK,MACH,QAAO,qBACL,IAAI,QAAQ,eAAe,CAAC,OAAO;GACjC,MAAM,aAAa;GACnB,MAAM,aAAa;GACpB,CAAC,CACH;EACH,KAAK,KACH,QAAO,qBACL,IAAI,QAAQ,eAAe,CAAC,OAAO;GACjC,MAAM,aAAa;GACnB,QAAQ,aAAa;GACtB,CAAC,CACH;EACH,KAAK,KACH,QAAO,qBAAqB,IAAI,KAAK,aAAa,GAAG,aAAa,QAAQ,CAAC,WAAW,GAAG;EAC3F,KAAK,KACH,QAAO,qBAAqB,IAAI,KAAK,aAAa,QAAQ,eAAe,CAAC,WAAW,GAAG;EAC1F,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,QACE,QAAO;;;AAQb,MAAaC,iBAAiF;CAC5F,MAAM;CACN,KAAK;CACL,IAAI;CACJ,KAAK;CACL,IAAI;CACL;AAED,SAAgB,wCACd,SACA;AACA,QAAO,eAAe;;AAGxB,SAAgB,0BACd,SAC8C;AAC9C,QAAO,WAAW;;AAGpB,SAAgB,sBACd,SACA;AACA,QAAO,0BAA0B,QAAQ,GACrC,wCAAwC,QAAQ,GAChD;;AAIN,SAAgB,gBAAgB,MAA+D;AAC7F,SAAW,eAAqC,WAAW,sBAAsB,KAAK;;AAKxF,SAAgB,yBAAyB,MAA4B;AACnE,SAAW,eAA8C,WAAW;;;;;;;;AAStE,SAAgB,yBAAyB,MAAmC;CAC1E,MAAM,UAAU,uBAAuB,KAAK;AAC5C,SAAQ,SAAR;EACE,KAAK,GACH,QAAO;EACT,KAAK,GACH,QAAO;EACT,KAAK,GACH,QAAO;EACT,QACE,OAAM,IAAI,MAAM,6CAA6C,UAAU;;;AAI7E,SAAgB,qBAAqB,MAA4B;AAC/D,QAAO,KAAK,MAAM,IAAI,CAAC,GAAG,WAAW,IAAI,GAAG,YAAY;;AAG1D,SAAgB,mCAAmC,QAAgB;AACjE,QAAO,OAAO,MAAM,IAAI,CAAC;;AAG3B,SAAgB,4BAA4B,QAAgB,UAAkB;AAC5E,QAAO,OAAO,MAAM,IAAI,CAAC,GAAG,QAAQ,KAAK,GAAG,CAAC,QAAQ,KAAK,SAAS;;AAKrE,SAAgB,4BAA4B,SAAuB;AACjE,QAAO,YAAY,QAAQ,CAAC;EAC1B,SAAS;EACT,SAAS;GACP,SAAS;GACT,QAAQ;GACT;EACF,CAAC;;AAGJ,SAAgB,uBAAuB,OAAyB,gBAAkC;AAChG,KAAI,UAAU,MAAM,YAAY,CAC9B,QAAO,wBAAwB,MAAM,YAAY,QAAQ,eAAe;AAC1E,KAAI,UAAU,MAAM,eAAe,IAAI,UAAU,MAAM,MAAM,CAC3D,QAAO,wBACL,MAAM,eAAe,QAAQ,MAAM,QAAQ,QAC3C,eACD;AACH,QAAO;;AAGT,SAAgB,oBACd,OACA,SACqB;CACrB,MAAM,UAAU,uBAAuB,OAAO,mCAAmC,QAAQ,CAAC;AAC1F,KAAI,YAAY,KAAM,OAAM,IAAI,MAAM,gCAAgC;AACtE,KAAI,QAAQ,WAAW,OAAO,IAAI,QAAQ,WAAW,OAAO,IAAI,QAAQ,WAAW,SAAS,CAC1F,QAAO;AACT,KAAI,QAAQ,WAAW,OAAO,IAAI,QAAQ,WAAW,OAAO,IAAI,QAAQ,WAAW,SAAS,CAC1F,QAAO;AACT,OAAM,IAAI,MAAM,kDAAkD;;AAKpE,SAAgB,uBACd,mBACA;AACA,SACI,cACA,aAED,iBAAyB;EACxB,MAAM,OAAO,kBAAkB,SAAS,aAAa;EAErD,MAAM,UAAU,aAAa,KAAK,QAAQ,KAAK,mBAAmB;AAClE,MAAI,CAAC,QAAS;AACd,SAAO,mBAAmB,MAAM,QAAQ,OAAO;;;AAWrD,SAAgB,kBAAkB,EAChC,aACA,cACA,UACA,WACiB;AACjB,KAAI,CAAC,SAAU,OAAM,IAAI,MAAM,mCAAmC;AAElE,KAAI,SAAS,UAAU,oBAAoB,QACzC,OAAM,IAAI,MAAM,8CAA8C;CAEhE,MAAM,kBAAkB,sCAAsC,SAAS,CAAC;EACtE;EACA;EACD,CAAC;AAEF,KAAI,CAAC,gBAAgB,UAAW,OAAM,IAAI,MAAM,mCAAmC;CAEnF,MAAM,UAAU,kBAAkB,gBAAgB,WAAW,QAAQ;AAErE,KAAI,CAAC,QAAQ,QAAS,OAAM,IAAI,MAAM,iCAAiC;AACvE,QAAO,QAAQ;;AAGjB,SAAgB,uBAAuB,EACrC,aACA,cACA,UACA,WACiB;AACjB,KAAI,CAAC,SAAU,OAAM,IAAI,MAAM,mCAAmC;AAElE,KAAI,SAAS,UAAU,oBAAoB,QACzC,OAAM,IAAI,MAAM,8CAA8C;CAEhE,MAAM,kBAAkB,sCAAsC,SAAS,CAAC;EACtE;EACA;EACD,CAAC;AAEF,KAAI,CAAC,gBAAgB,UAAW,OAAM,IAAI,MAAM,mCAAmC;CAEnF,MAAM,UAAU,uCAAuC,iBAAiB,QAAQ;AAEhF,KAAI,CAAC,QAAQ,QAAS,OAAM,IAAI,MAAM,iCAAiC;AACvE,QAAO,QAAQ;;;;;;AAOjB,SAAgB,mBAAmB,WAAmB;CACpD,MAAM,OAAO,mBAAmB,UAAU;AAC1C,QAAO,MAAM,eAAe,KAAK;;AAGnC,SAAgB,gBAAgB,QAA6C;CAC3E,MAAM,eAAe,OAAO;CAC5B,MAAMC,SAA6B,EAAE;AACrC,MAAK,IAAI,IAAI,GAAG,IAAI,cAAc,IAAK,QAAO,KAAK,OAAO,SAAS,EAAE,CAAC;AACtE,QAAO;;AAGT,SAAgB,iBAAiB,QAA8C;CAC7E,MAAM,gBAAgB,OAAO;CAC7B,MAAMC,UAA+B,EAAE;AACvC,MAAK,IAAI,IAAI,GAAG,IAAI,eAAe,IAAK,SAAQ,KAAK,OAAO,UAAU,EAAE,CAAC;AACzE,QAAO;;AAGT,SAAgB,wBAAwB,SAA8C;AACpF,KAAI,QAAQ,WAAW,MAAM,CAAE,QAAO;AACtC,KAAI,QAAQ,WAAW,MAAM,CAAE,QAAO;AACtC,KAAI,QAAQ,WAAW,QAAQ,CAAE,QAAO;CAExC,MAAM,YAAY,QAAQ;AAE1B,KAAI,cAAc,OAAO,cAAc,IAAK,QAAO;AACnD,KAAI,cAAc,OAAO,cAAc,IAAK,QAAO;AACnD,KAAI,cAAc,IAAK,QAAO;AAE9B,OAAM,IAAI,MAAM,gDAAgD;;AAGlE,SAAgB,4BAA4B,SAA+C;AACzF,KAAI,QAAQ,WAAW,OAAO,IAAI,QAAQ,WAAW,OAAO,IAAI,QAAQ,WAAW,SAAS,CAC1F,QAAO;AAET,KAAI,QAAQ,WAAW,OAAO,IAAI,QAAQ,WAAW,OAAO,IAAI,QAAQ,WAAW,SAAS,CAC1F,QAAO;AAET,OAAM,IAAI,MAAM,4CAA4C;;AAG9D,SAAgB,qBAAqB,OAAyB;AAC5D,KAAI,UAAU,MAAM,YAAY,CAAE,QAAO,OAAO,MAAM,YAAY,OAAO;AACzE,KAAI,UAAU,MAAM,eAAe,IAAI,UAAU,MAAM,MAAM,CAC3D,QAAO,OAAO,MAAM,eAAe,QAAQ,MAAM,QAAQ,OAAO;AAElE,QAAO;;AAGT,SAAgB,wBAAwB,MAAc;AACpD,QAAO,uBAAuB,KAAK,KAAK;;AAG1C,SAAgB,6BAA6B,MAAc;AACzD,QAAO,uBAAuB,KAAK,KAAK;;;;;ACxX1C,MAAM,mBAAmB;AAEzB,MAAM,SAAS,cAAc,IAAI;AACjCC,UAAQ,WAAW,IAAI;AAEvB,SAAgB,qBAAqB,KAAiB;AACpD,QAAO,OAAO,eAAe,OAAO,KAAK,IAAI,CAAC;;AAKhD,MAAM,iBAAiB,WAAW,KAAK,CACrC,GAAG,OAAO,YAAY,iBAAiB,CAAC,EACxC,GAAG,OAAO,YAAY,iBAAiB,CAAC,CACzC,CAAC;AAEF,SAAgB,kBAAkB,SAA8B;AAC9D,QAAO,OACL,WAAW,KAAK,CAAC,GAAG,gBAAgB,GAAI,SAAS,QAAQ,GAAG,YAAY,QAAQ,GAAG,QAAS,CAAC,CAC9F;;AAGH,MAAa,gCAAgC;CAC3C,aAAa,WAAW,mEAAmE;CAC3F,cAAc;CACd,UAAU;CACX;AAED,SAAS,gBAAgB,GAAW;AAClC,QAAO,OAAO,OAAO,CAACC,SAAO,EAAE,WAAW,EAAE,EAAE,CAAC;;AAGjD,MAAMC,sCAAsD,CAAC,UAAU,OAAO;AAE9E,SAAgB,qCAAqC,aAAqB;AACxE,QAAO,oCAAoC,SAAS,YAA4B;;;;;;AAOlF,SAAgB,yBAAyB,cAAwB;CAC/D,MAAM,MAAMD,SAAO,aAAa,OAAO;AACvC,QAAO,OAAO,OAAO,CAAC,KAAK,GAAG,aAAa,KAAI,YAAW,gBAAgB,QAAQ,CAAC,CAAC,CAAC;;AAGvF,SAAS,aAAa,QAAgB,GAA+B;AACnE,QAAOD,UAAQ,OAAO,WAAW,YAAY,OAAO,OAAO,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;;AAGzF,SAAgB,YAAY,QAAwB,OAAY,EAAE,EAAkB;CAElF,IAAIG,aAAqC,OAAO;AAChD,KAAI,CAAC,WACH,OAAM,IAAI,MAAM,+CAA+C;AAEjE,KAAI,OAAO,UAAU,OAAO,EAC1B,cAAa,IAAI,cAAc,WAAW;CAG5C,MAAM,oBAAoB,IAAI,WAC5B,YACA,aAAa,QAAQ,OAAO,UAAU,EAAE,KAAK,UAAU,CACxD;AACD,KAAI,CAAC,kBACH,OAAM,IAAI,MAAM,+BAA+B;AAGjD,QAAO,OAAO,eAAe,OAAO,KAAK,kBAAkB,EAAE,EAC3D,SAAS,KAAK,SACf,CAAC;;;;;ACpEJ,SAAgB,kCAAkC,YAAoB;AACpE,QAAO,qBAAqB,WAAW;;AAGzC,SAAgB,6BAA6B,YAAoB;AAC/D,QAAO,YAAY,qBAAqB,WAAW,CAAC;;AAGtD,SAAgB,gBACd,SACA,SACA,SACA;CACA,MAAM,EAAE,aAAa,cAAc,aAAa;CAEhD,MAAM,SAASC,UAAQ,QAAQ,eAC7B,SACA,mCAAmC,QAAQ,CAC5C;CAED,MAAM,OAAO,kBAAkB,QAAQ;CACvC,MAAM,WAAW,CAAC,GAAG,OAAO,KAAK,KAAK,CAAC;CACvC,MAAM,YAAYA,UAAQ,OAAO,QAAQ,SAAS;CAElD,MAAM,iBAAiB,IAAIA,UAAQ,aAAa;AAChD,gBAAe,UAAU;AACzB,gBAAe,SAAS,OAAO,KAAK,YAAY,EAAE,cAAc,UAAU,UAAU;AACpF,gBAAe,UAAU,QAAQ,EAAE;AACnC,QAAO;EAAE;EAAgB;EAAQ;;AAGnC,SAAS,eAAe,cAAsB,QAAgB,SAA8B;CAC1F,MAAM,gBAAgB,IAAIA,UAAQ,KAAK,EAAE,SAAS,mCAAmC,QAAQ,EAAE,CAAC;AAChG,eAAc,WAAW,EAAE;CAC3B,MAAM,aAAa;CACnB,MAAM,eAAe;CACrB,MAAM,kBAAkBA,UAAQ,OAAO,QAAQ,CAACA,UAAQ,OAAO,IAAI,UAAU,CAAC;AAE9E,eAAc,SAAS;EACrB,MAAM;EACN,OAAO;EACP,UAAU;EACV,aAAa;GAAE;GAAQ,OAAO;GAAG;EAClC,CAAC;AAEF,eAAc,UAAU;EAAE,QAAQ;EAAiB,OAAO;EAAG,CAAC;AAC9D,QAAO;;AAST,eAAsB,wBAAwB,MAA+B;CAC3E,MAAM,EAAE,SAAS,SAAS,SAAS,aAAa;CAEhD,MAAM,EAAE,gBAAgB,WAAW,gBAAgB,SAAS,SAAS,QAAQ;CAI7E,MAAM,WAAW,MAAM,SAFD,eAAe,eAAe,SAAS,EAAE,QAAQ,QAAQ,CAEjC;CAE9C,MAAM,yBAAyBA,UAAQ,KAAK,WAAW,OAAO,KAAK,SAAS,QAAQ,CAAC,CAAC;AAEtF,wBAAuB,cAAc,EAAE;CAKvC,MAAM,WAAW,uBAAuB,oBAAoB;CAE5D,MAAM,SAAS,yBAAyB,SAAS,IAAI,GAAG,QAAQ;AAEhE,QAAO;EACL;EACA,eAAe;EACf,cAAc;EACd,WAAW,OAAO,OAAO,OAAO;EACjC;;;;;ACnEH,IAAa,sBAAb,MAAiC;CAC/B,gBAAgB;CAChB,iBAAiB;CACjB,gBAAgB;CAChB,uBAAuB;CACvB,sBAAsB;CACtB,sBAAsB;CACtB,iBAAiB;CACjB,kBAAkB;CAClB,iBAAiB;CACjB,gBAAgB;CAChB,eAAe;CACf,cAAc;CACd,iBAAiB;CACjB,+BAAkD;EAChD;EACA;EACA;EACA;EACA;EACA;EACA;EACD;CAED,gBAA+B;EAC7B,aAAa;EACb,cAAc;EACd,SAAS;EACT,SAAS;EACT,oBAAoB;EACpB,mBAAmB;EACnB,0BAA0B;EAC1B,yBAAyB;EACzB,qBAAqB;EACrB,oBAAoB;EACpB,mBAAmB;EACpB;CAED,SAAwB,EAAE,GAAG,KAAK,eAAe;CAEjD,6BAA6B,QAAgB;AAC3C,MAAI,SAAS,GACX,QAAO;WACE,UAAU,IACnB,QAAO;WACE,UAAU,MACnB,QAAO;WACE,UAAU,WACnB,QAAO;MAEP,OAAM,IAAI,MAAM,qCAAqC;;CAIzD,gBAAgB,QAAgB;AAC9B,MAAI,SAAS,IACX,QAAO;WACE,SAAS,MAClB,QAAO;WACE,SAAS,WAClB,QAAO;WACE,IAAI,UAAU,OAAO,CAAC,WAAW,uBAAuB,CACjE,QAAO;MAEP,OAAM,IAAI,MAAM,kBAAkB;;CAItC,oBAAoB,cAA+B,aAAqB,cAAsB;EAC5F,IAAI;AACJ,MAAI,iBAAiB,WAAW,iBAAiB,OAC/C,kBAAiB;MAGjB,kBACE,KAEA,KAAK,gBAAgB,YAAY,GAAG;AAGxC,SACE,IACA,KAAK,gBAAgB,YAAY,GACjC,KAAK,gBAAgB,aAAa,GAClC,IACA;;CAIJ,2BAA2B,cAA+B,aAAqB;EAC7E,IAAI;AACJ,MAAI,iBAAiB,WAAW,iBAAiB,OAC/C,kBAAiB;MAGjB,kBACE,KAEA,KAAK,gBAAgB,YAAY,GAAG;AAGxC,SAAO,iBAAiB;;CAG1B,cAAc,MAA8B;AAE1C,SAAO,QAAQ,OAAO,OAAO,KAAK,cAAc;EAEhD,MAAM,cAAc,KAAK,eAAe,KAAK,cAAc;AAC3D,MAAI,CAAC,OAAO,UAAU,YAAY,IAAI,cAAc,EAClD,OAAM,IAAI,MAAM,0CAA0C,YAAY;EAGxE,MAAM,eAAe,KAAK,gBAAgB,KAAK,cAAc;AAC7D,MAAI,KAAK,6BAA6B,QAAQ,aAAa,KAAK,GAC9D,OAAM,IAAI,MAAM,kCAAkC;EAGpD,MAAM,UAAU,KAAK,WAAW,KAAK,cAAc;AACnD,MAAI,CAAC,OAAO,UAAU,QAAQ,IAAI,UAAU,EAC1C,OAAM,IAAI,MAAM,qCAAqC;EAGvD,MAAM,UAAU,KAAK,WAAW,KAAK,cAAc;AACnD,MAAI,CAAC,OAAO,UAAU,QAAQ,IAAI,UAAU,EAC1C,OAAM,IAAI,MAAM,kCAAkC;EAGpD,MAAM,qBAAqB,KAAK,sBAAsB,KAAK,cAAc;AACzE,MAAI,CAAC,OAAO,UAAU,mBAAmB,IAAI,qBAAqB,EAChE,OAAM,IAAI,MAAM,wCAAwC;EAG1D,MAAM,oBAAoB,KAAK,qBAAqB,KAAK,cAAc;AACvE,MAAI,CAAC,OAAO,UAAU,kBAAkB,IAAI,oBAAoB,EAC9D,OAAM,IAAI,MAAM,uCAAuC;EAGzD,MAAM,2BACJ,KAAK,4BAA4B,KAAK,cAAc;AACtD,MAAI,CAAC,OAAO,UAAU,yBAAyB,IAAI,2BAA2B,EAC5E,OAAM,IAAI,MAAM,8CAA8C;EAGhE,MAAM,0BACJ,KAAK,2BAA2B,KAAK,cAAc;AACrD,MAAI,CAAC,OAAO,UAAU,wBAAwB,IAAI,0BAA0B,EAC1E,OAAM,IAAI,MAAM,6CAA6C;EAG/D,MAAM,sBAAsB,KAAK,uBAAuB,KAAK,cAAc;AAC3E,MAAI,CAAC,OAAO,UAAU,oBAAoB,IAAI,sBAAsB,EAClE,OAAM,IAAI,MAAM,yCAAyC;EAG3D,MAAM,qBAAqB,KAAK,sBAAsB,KAAK,cAAc;AACzE,MAAI,CAAC,OAAO,UAAU,mBAAmB,IAAI,qBAAqB,EAChE,OAAM,IAAI,MAAM,wCAAwC;EAG1D,MAAM,oBAAoB,KAAK,qBAAqB,KAAK,cAAc;AACvE,MAAI,CAAC,OAAO,UAAU,kBAAkB,IAAI,oBAAoB,EAC9D,OAAM,IAAI,MAAM,uCAAuC;AAGzD,OAAK,SAAS;GACZ;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACD;AAED,SAAO,KAAK;;CAGd,iBAAiB;AACf,SACE,KAAK,OAAO,qBACZ,KAAK,OAAO,oBACZ,KAAK,OAAO,2BACZ,KAAK,OAAO,0BACZ,KAAK,OAAO,sBACZ,KAAK,OAAO,qBACZ,KAAK,OAAO;;CAIhB,0BAA0B;EAExB,IAAI,YAAY;EAChB,IAAI,mBAAmB;EACvB,IAAI;AACJ,UAAQ,KAAK,OAAO,cAApB;GACE,KAAK;AACH,gBAAY,KAAK;AACjB;GACF,KAAK;AACH,gBAAY,KAAK;AACjB,uBAAmB;AACnB;GACF,KAAK;AACH,gBAAY,KAAK;AACjB,uBAAmB;AACnB;GACF,KAAK;AACH,gBAAY,KAAK;AACjB,uBAAmB;AACnB;GACF,KAAK;AACH,uBACE,IACA,KAAK,OAAO,WAAW,IAAI,KAAK,eAChC,IACA;IAEF,MAAM,gBACJ,IACA,KAAK,OAAO,WAAW,IAAI,KAAK,kBAChC,KAAK,6BAA6B,iBAAiB,GACnD;AACF,gBAAY,KAAS,KAAK,gBAAgB,cAAc,GAAG,gBAAgB;AAC3E;GACF,KAAK;GACL,KAAK;AACH,uBACE,IACA,KAAK,OAAO,WAAW,IAAI,KAAK,eAChC,IACA;AACF,uBACE,IACA,KAAK,OAAO,WAAW,IAAI,KAAK,kBAChC,KAAK,6BAA6B,iBAAiB,GACnD;AACF,gBACE,KACA,mBAAmB,IACnB;AACF,QAAI,KAAK,OAAO,iBAAiB,aAC/B,cAAa;AAEf;GACF,QACE,mBAAkB,KAAK,OAAO,aAAa;;AAG/C,SAAO;GACL;GACA;GACD;;CAGH,WAAW,MAA8B;AACvC,OAAK,cAAc,KAAK;EACxB,MAAM,eAAe,KAAK,gBAAgB;EAC1C,MAAM,EAAE,WAAW,qBAAqB,KAAK,yBAAyB;EAEtE,MAAM,WACJ,KAAK,oBAAoB,KAAK,OAAO,cAAc,KAAK,OAAO,aAAa,aAAa,GACzF,YAAY,KAAK,OAAO,cACxB,KAAK,iBAAiB,KAAK,OAAO,qBAClC,KAAK,gBAAgB,KAAK,OAAO,oBACjC,KAAK,uBAAuB,KAAK,OAAO,2BACxC,KAAK,sBAAsB,KAAK,OAAO,0BACvC,KAAK,kBAAkB,KAAK,OAAO,sBACnC,KAAK,iBAAiB,KAAK,OAAO,qBAClC,KAAK,gBAAgB,KAAK,OAAO;AAQnC,SAAO;GAAE;GAAU,SALjB,KAAK,2BAA2B,KAAK,OAAO,cAAc,KAAK,OAAO,YAAY,GAClF,WACA,mBAAmB,KAAK,OAAO;GAGL,UAFX,WAAW;GAEU;;CAGxC,YAAY,OAAe,OAAe;AACxC,MAAI,MAAM,MAAM,IAAI,MAAM,MAAM,CAC9B,OAAM,IAAI,MAAM,+BAA+B;AAEjD,SAAO,QAAQ;;CAGjB,eAAe,KAAa,YAAoB;AAC9C,MAAI,MAAM,IAAI,IAAI,MAAM,WAAW,CACjC,OAAM,IAAI,MAAM,+BAA+B;AAGjD,MAAI,aAAa,EACf,OAAM,IAAI,MAAM,8BAA8B;EAGhD,MAAM,gBAAgB,MAAM;AAE5B,SAAO,MAAM,gBAAgB,SAAS,MAAM;;;;;;ACjUhD,SAAgB,aAA0C,OAAY;AACpE,QAAO,WAAW,MAAM,KAAI,SAAQ,KAAK,MAAM,CAAC;;AAGlD,SAAgB,YAAY,SAIzB;CACD,MAAM,EAAE,aAAa,YAAY,cAAc;CAE/C,MAAM,qBAAqB,WACxB,KAAI,cAAaC,WAAS,UAAU,QAAQ,IAAI,eAAe,UAAU,QAAQ,CAAC,CAClF,OAAO,QAAQ;CAElB,SAAS,kCAAkC;AACzC,SAAO,mBAAmB,QACvB,KAAK,EAAE,WAAW;AACjB,OAAI,SAAS,IAAI,SAAS,KAAK;AAC/B,UAAO;KAET,EAAE,CACH;;CAGH,MAAM,mBAAmB,iCAAiC;AAG1D,KAAI,CAAC,UACH,kBAAiB,YAAY,WAAW,iBAAiB,YAAY,WAAW,KAAK;CAIvF,MAAM,cAAc,OAAO,QAAQ,iBAAiB,CAAC,QAClD,KAAK,CAAC,MAAM,WAAW;AACtB,MAAI,OAAO,mBAAmB;AAC9B,SAAO;IAET,EAAE,CACH;AASD,QAPgB,IAAI,qBAAqB,CAChB,WAAW;EAClC,cAAc;EACd,aAAa;EACb,GAAG;EACJ,CAAC;;AAUJ,SAAgB,mBAAgD,EAC9D,OACA,SACA,cAC4B;CAC5B,MAAM,UAAU,MAAM,KAAI,SAAQ,KAAK,MAAM,CAAC,QAAQ,SAAS,WAAW,UAAU,QAAQ,EAAE;CAE9F,MAAM,OAAO,YAAY;EACvB,aAAa,MAAM;EACnB;EACD,CAAC;CACF,MAAM,MAAM,KAAK,KAAK,KAAK,WAAW,QAAQ;CAC9C,MAAM,mBAAmB,UAAU,QAAQ;AAC3C,QAAO;EACL,iBAAiB,UAAU,IAAI,GAAG,iBAAiB,MAAM,IAAI,CAAC;EAC9D;EACD;;AAIH,SAAgB,wBAAmE,EACjF,OACA,SACA,cAKC;CACD,MAAM,EAAE,iBAAiB,wBAAwB,mBAAmB;EAClE;EACA;EACA;EACD,CAAC;AAcF,QAZsB,MACnB,QAAO,SAAQ,OAAO,KAAK,MAAM,IAAI,uBAAuB,CAC5D,QAAO,SAAQ;EAEd,MAAM,EAAE,oBAAoB,mBAAmB;GAC7C,OAAO,MAAM,QAAO,MAAK,EAAE,SAAS,KAAK,KAAK;GAC9C;GACA;GACD,CAAC;AAEF,SAAO,gBAAgB,UAAU,GAAG,oBAAoB,UAAU;GAClE;;;;;AC7FN,SAAgB,kBAAkB,EAChC,WACA,OACA,WACqD;AACrD,KAAI,CAAC,MAAM,OACT,QAAO;EACL,aAAa;EACb,QAAQ,YAAY,GAAG,MAAM;EAC7B,kBAAkB,IAAI,UAAU,EAAE;EACnC;CAQH,MAAM,EAAE,iBAAiB,QAAQ,mBAAmB;EAClD,OAPoB,wBAAwB;GAC5C;GACA;GACA,YAAY,CAAC;IAAE,SAAS;IAAW,QAAQ,YAAY,GAAG,MAAM;IAAE,CAAC;GACpE,CAAC;EAIA;EACA,YAAY,CAAC;GAAE,SAAS;GAAW,QAAQ,YAAY,GAAG,MAAM;GAAE,CAAC;EACnE,WAAW;EACZ,CAAC;AAEF,QAAO;EACL,aAAa;EACb,QAAQ,YAAY,iBAAiB,MAAM;EAC3C,kBAAkB,SAAS,gBAAgB;EAC5C;;;;;ACtBH,SAAgB,0BAAqE,EACnF,SACA,YACA,SACgC;AAChC,YAAW,SAAQ,cAAa;AAC9B,MAAI,CAAC,SAAS,UAAU,QAAQ,CAAE,OAAM,IAAI,aAAa,iBAAiB;GAC1E;CACF,MAAM,gBAAgB,wBAAwB;EAAE;EAAO;EAAS;EAAY,CAAC;AAE7E,KAAI,CAAC,cAAc,OAAQ,OAAM,IAAI,aAAa,oBAAoB;CAEtE,MAAM,WAAW,YAAY;EAC3B,aAAa,cAAc;EAC3B,WAAW;EACX;EACD,CAAC;CAGF,MAAM,UAAU,WAAW,KAAK,EAAE,SAAS,cAAc;EACvD,OAAO,OAAO,OAAO,OAAO,UAAU,CAAC;EACvC;EACD,EAAE;CAEH,MAAM,MAAM,KAAK,KAAK,SAAS,WAAW,QAAQ;AAElD,QAAO;EACL,QAAQ;EACR;EACA,MAAM,SAAS;EACf,KAAK,YAAY,IAAI,UAAU,IAAI,EAAE,MAAM;EAC5C;;AAGH,SAAgB,uBAAkE,EAChF,SACA,YACA,SACgC;AAChC,YAAW,SAAQ,cAAa;AAC9B,MAAI,CAAC,SAAS,UAAU,QAAQ,CAAE,OAAM,IAAI,aAAa,iBAAiB;GAC1E;CACF,MAAM,gBAAgB,wBAAwB;EAC5C,OAAO,MAAM,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,MAAM;EAC9C;EACA;EACD,CAAC;AACF,KAAI,CAAC,cAAc,OAAQ,OAAM,IAAI,aAAa,oBAAoB;CAEtE,MAAM,SAAS,SAAS,WAAW,KAAI,cAAa,UAAU,OAAO,CAAC;CAGtE,MAAMC,cAAmB,CAAC,cAAc,GAAG;CAE3C,SAAS,0BAA0B;AACjC,SAAO,YAAY;GACjB,aAAa,YAAY;GACzB;GACD,CAAC;;CAGJ,SAAS,0BAA0B;EAEjC,MAAM,eAAe,IAAI,UADJ,yBAAyB,CACE,WAAW,QAAQ,CAAC,KAAK,OAAO,OAAO;AACvF,SAAO,aAAa,YAAY,CAAC,uBAAuB,aAAa;;CAGvE,SAAS,2BAA2B;AAClC,SAAO,cAAc,QAAO,SAAQ,CAAC,YAAY,SAAS,KAAK,CAAC;;AAGlE,QAAO,CAAC,yBAAyB,EAAE;EACjC,MAAM,CAAC,YAAY,0BAA0B;AAC7C,MAAI,CAAC,SAAU,OAAM,IAAI,aAAa,oBAAoB;AAC1D,cAAY,KAAK,SAAS;;CAG5B,MAAM,MAAM,KAAK,KACf,IAAI,UAAU,yBAAyB,CAAC,SAAS,CAAC,aAAa,QAAQ,CAAC,UAAU,CACnF;CAED,MAAM,eACJ,OAAO,aAAa,YAAY,CAAC,UAAU,CAAC,GAAG,OAAO,OAAO,OAAO,UAAU,CAAC,GAAG,OAAO,IAAI;CAE/F,MAAMC,cACJ,eAAe,yBACX,CACE,EACE,OAAO,cACR,CACF,GACD,EAAE;AAUR,QAAO;EACL;EACA,QAAQ;EACR,SAXqC,CACrC,GAAG,WAAW,KAAK,EAAE,SAAS,wBAAc;GAC1C,OAAO,OAAOC,SAAO,OAAO,UAAU,CAAC;GACvC;GACD,EAAE,EACH,GAAG,YACJ;EAMC,MAAM,yBAAyB,CAAC;EAChC,KAAK,YAAY,IAAI,UAAU,IAAI,EAAE,MAAM;EAC3C,GAAG,yBAAyB;EAC7B;;;;;ACxHH,SAAgB,yBAAyB,EAAE,cAAc,GAAG,SAAuC;AACjG,KAAI;EACF,MAAM,EAAE,QAAQ,eACZ,0BAA0B,EAAE,GAAG,OAAO,CAAC,GACvC,uBAAuB,EAAE,GAAG,OAAO,CAAC;AACxC,SAAO;SACD;AACN,SAAO;;;AAiBX,SAAgB,eAAe,EAAE,UAAU,cAAc,YAAY,SAA6B;CAChG,MAAM,cAAc;EAClB;EACA;EACA;EACD;CAED,MAAM,cAAc,SAAS,WAAW,UAAU;CAClD,MAAM,kBAAkB,SAAS,YAAY,UAAU;CACvD,MAAM,aAAa,SAAS,QAAQ,UAAU;CAE9C,MAAM,eAAe,yBAAyB;EAC5C,GAAG;EACH,SAAS;EACV,CAAC;CACF,MAAM,mBAAmB,yBAAyB;EAChD,GAAG;EACH,SAAS;EACV,CAAC;CACF,MAAM,cAAc,yBAAyB;EAC3C,GAAG;EACH,SAAS;EACV,CAAC;AAEF,QAAO;EACL,MAAM;GAAE,SAAS;GAAa,KAAK;GAAc;EACjD,UAAU;GAAE,SAAS;GAAiB,KAAK;GAAkB;EAC7D,KAAK;GAAE,SAAS;GAAY,KAAK;GAAa;EAC/C;;;;;AC7DH,MAAa,uCAAuC,qBAClD,6CACD;AACD,MAAa,iCAAiC,qBAC5C,iEACD;AACD,MAAa,iCAAiC,qBAC5C,iEACD;AAED,MAAa,8CAA8C,qBACzD,6CACD;AAED,MAAa,qCAAqC,qBAChD,6CACD;AAED,MAAa,yCAAyC,qBACpD,iEACD;AAGD,MAAa,mBAAmB,qBAAqB,6CAA6C;AAClG,MAAa,gBAAgB,qBAAqB,qCAAqC;AACvF,MAAa,gBAAgB,qBAAqB,qCAAqC;AACvF,MAAa,iBAAiB,qBAC5B,iEACD;AACD,MAAa,iBAAiB;AAE9B,MAAa,2BAA2B,qBACtC,iEACD;AACD,MAAa,uBAAuB,qBAAqB,wCAAwC;;;;AChCjG,SAAgB,wBAAwB,UAAU,IAAI;AACpD,QAAO,EACJ,QAAQ,CACR,QAAQ,UAAkB,UAAU,UAAa,MAAM,MAAM,KAAK,IAAI,EAAE,SAAS,CAAC;;AAGvF,SAAgB,sBAAsB;AACpC,QAAO,EAAE,QAAQ,CAAC,QACf,UAAkB;AACjB,MAAI,YAAY,MAAM,IAAI,cAAc,MAAM,CAAE,QAAO;AACvD,SAAO,SAAS,MAAM;IAExB,EAAE,SAAS,gCAAgC,CAC5C;;AAGH,SAAgB,0BAA0B,SAAiB;AACzD,QAAO,eAAe,QAAQ,CAAC;;AAGjC,SAAS,kCAAkC,SAA8B;CACvE,SAAS,sBAAsB,WAAuC;AAGpE,MAAIC,cAAY,SAAU,QAAO,QAAQ;AACzC,SAAOA;;AAET,SAAQ,UAAmB;AACzB,MAAI,YAAY,MAAM,IAAI,cAAc,MAAM,CAAE,QAAO;AACvD,SAAO,SAAS,OAAO,sBAAsB,QAAQ,CAAC;;;AAI1D,SAAgB,2BAA2B,SAA8B;AACvE,QAAO,EAAE,QAAQ,CAAC,OAAO,kCAAkC,QAAQ,EAAE,EACnE,SAAS,oCACV,CAAC;;;;;;;;;AC/BJ,MAAa,iCAAiC;;;;;AAM9C,MAAa,wBAAwB;AAErC,SAAgB,8BAA8B,KAAa;CAGzD,MAAM,gCAAgC,YAAY,OAAO,CAAC,OAAO,IAAI;AAErE,QAAO,8BAA8B,MAAM,GAAG,8BAA8B,SAAS,EAAE;;AAIzF,MAAM,+BAA+B;AACrC,MAAa,+BAA+B;AAE5C,MAAMC,2BAAyD;CAC7D,SAAS;CACT,SAAS;CACV;AAED,SAAS,QAAQ,OAAmB;AAClC,QAAO,UAAU,OAAO,MAAM,CAAC;;AAGjC,SAAgB,2BAA2B,WAAuB;AAChE,QAAO,QAAQ,UAAU;;AAG3B,SAAgB,gCAAgC,SAAqB;AAMnE,QAAO,QALc,WAAW,KAAK;EACnC,GAAG,WAAW,GAAG,EAAK;EACtB,GAAG,WAAW,GAAG,QAAQ,OAAO;EAChC,GAAG;EACJ,CAAC,CAC0B;;AAG9B,SAAgB,2BAA2B,cAA0B,SAAuB;CAC1F,MAAM,cAAc,yBAAyB;CAC7C,MAAM,oBAAoB,WAAW,KAAK,CAAC,aAAa,GAAG,aAAa,CAAC;AACzE,QAAO,YAAY,OAAO,CAAC,OAAO,kBAAkB;;AAGtD,SAAgB,kCAAkC,WAAuB,SAAuB;AAG9F,QAAO,2BADW,gCADL,2BAA2B,UAAU,CACK,EACV,QAAQ;;;;;ACvDvD,SAAS,4BAA4B,WAAqB,QAAqB;AAQ7E,QAAO,YAAY,WAPG,UAAU,KAAI,YAClC,OACG,QAAO,UAAS,MAAM,YAAY,QAAQ,CAC1C,KAAI,UAAS,MAAM,MAAM,CACzB,QAAQ,KAAK,WAAW,MAAM,QAAQ,EAAE,CAC5C,CAE2C,EAAE,MAAM;;AAGtD,SAAS,6BAA6B,WAAqB,SAAuB;AAOhF,QAAO,YAAY,WANG,UAAU,KAAI,YAClC,QACG,QAAO,WAAU,OAAO,YAAY,QAAQ,CAC5C,KAAI,WAAU,OAAO,OAAO,MAAM,CAAC,CACnC,QAAQ,KAAK,WAAW,MAAM,QAAQ,EAAE,CAC5C,CAC2C,EAAE,MAAM;;AAGtD,SAAS,yBAAyB,QAAqB;AACrD,QAAO,YAAY,WAAW,OAAO,KAAI,UAAS,MAAM,MAAM,CAAC,EAAE,MAAM;;AAGzE,SAAS,0BAA0B,SAAuB;AACxD,QAAO,YAAY,WAAW,QAAQ,KAAI,WAAU,OAAO,MAAM,CAAC,EAAE,MAAM;;AAQ5E,SAAgB,cAAc,EAAE,eAAe,cAAc,iBAAqC;CAChG,MAAM,wBAAwB,cAAc,QAC1C,SAAQ,4BAA4B,KAAK,KAAK,SAC/C;CACD,MAAM,mBAAmB,cAAc,QACrC,SAAQ,4BAA4B,KAAK,KAAK,OAC/C;AAED,QAAO;EACL,yBAAyB,4BAA4B,uBAAuB,aAAa;EACzF,oBAAoB,4BAA4B,kBAAkB,aAAa;EAC/E,0BAA0B,6BAA6B,uBAAuB,cAAc;EAC5F,qBAAqB,6BAA6B,kBAAkB,cAAc;EAClF,iBAAiB,yBAAyB,aAAa;EACvD,kBAAkB,0BAA0B,cAAc;EAC3D;;;;;ACvBH,SAAgB,gBAAgB,EAC9B,QACA,eACA,aACA,iBAC+C;CAC/C,MAAM,iBAAiB,mCAAmC,YAAY;CAEtE,MAAM,UAAU,YAAY,cAAc;CAC1C,MAAM,aAAa,OAAO,KAAK,OAAO,MAAM;EAC1C,MAAM,iBAAiB,UAAU,MAAM,MAAM,GACzC,uBAAuB,OAAO,eAAe,GAC7C;AACJ,MAAI,mBAAmB,KACrB,OAAM,IAAI,MAAM,6CAA6C;EAE/D,MAAM,mBAAmB,cAAc,SAAS,eAAe;EAE/D,MAAM,YACJ,oBACA,EAAE,CAAC,MAAM,eAAe,MAAM,gBAAgB,KAAK,MAAM,gBAAgB;EAE3E,MAAM,YAAY,oBAAoB;EACtC,MAAM,cAAc,oBAAoB,CAAC,WAAW,cAAc,SAAS,EAAE;AAE7E,SAAO;GACL,SAAS;GACT,OAAO,MAAM;GACb,iBAAiB,MAAM;GACvB,oBAAoB,MAAM;GAE1B,WAAW;GACX,QAAQ,aAAa;GACrB,MAAM,MAAM,OAAO,WAAW,MAAM,KAAK,GAAG;GAC5C,OAAO,UAAU,MAAM,MAAM,GAAG,qBAAqB,MAAM,GAAG;GAC/D;GACD;AAIF,QAAO;EAAE,eAFa,WAAW,MAAK,UAAS,MAAM,UAAU;EAEvC,cAAc;EAAY;;;;;AC/CpD,SAAgB,iBAAiB,EAC/B,eACA,SACA,aACA,iBACqC;CACrC,MAAM,iBAAiB,mCAAmC,YAAY;AAEtE,QAAO,QACJ,KAAI,WAAU;AACb,MAAI,YAAY,OAAO,OAAO,CAG5B;EAEF,MAAM,gBAAgB,wBAAwB,OAAO,QAAQ,eAAe;AAI5E,SAAO;GACL,SAAS;GACT,WAAW;GACX,QALuB,CAAC,CAAC,iBAAiB,cAAc,SAAS,cAAc;GAM/E,OAAO,OAAO,OAAO,OAAO;GAC7B;GACD,CACD,OAAO,UAAU;;;;;AC5CtB,SAAgB,qBAAqB,MAA2B;CAC9D,MAAM,QAAQ,SAAS,KAAK,GAAG,WAAW,KAAK,GAAG;AAClD,QAAO,IAAI,YAAY,SAAS,MAAM;;AAGxC,SAAgB,WAAW,MAAgE;CACzF,MAAM,QAAQ,SAAS,KAAK,GAAG,WAAW,KAAK,GAAG;AAClD,KAAI;AACF,SAAO,UAAU,OAAO,MAAM;UACvB,IAAI;AACX,MAAI;AACF,UAAO,UAAU,OAAO,MAAM;WACvB,IAAI;AACX,SAAM,IAAI,MAAM,0BAA0B,MAAM,KAAK;;;;;;;ACN3D,SAAgB,eAAe,EAC7B,SACA,aACA,eACA,iBACqB;CACrB,MAAM,KAAK,qBAAqB,QAAQ;CACxC,MAAM,SAAS,gBAAgB,GAAG;CAClC,MAAM,UAAU,iBAAiB,GAAG;CAEpC,MAAM,EAAE,eAAe,iBAAiB,gBAAgB;EACtD;EACA;EACA;EACA;EACD,CAAC;CACF,MAAM,gBAAgB,iBAAiB;EAAE;EAAe;EAAS;EAAa;EAAe,CAAC;CAE9F,MAAM,EACJ,yBACA,oBACA,0BACA,qBACA,iBACA,qBACE,cAAc;EAChB;EACA;EACA;EACD,CAAC;CACF,SAAS,SAAS;AAChB,MAAI,gBAAgB,OAAO,cAAc,iBAAiB,OAAO,CAC/D,QAAO,cAAc,iBAAiB,iBAAiB;AACzD,SAAO,YAAY,GAAG,MAAM;;AAE9B,QAAO;EACL,0BAA0B,cAAc,yBAAyB,yBAAyB;EAC1F,qBAAqB,cAAc,oBAAoB,oBAAoB;EAC3E,KAAK,QAAQ;EACb;EACA,YAAY;EACZ,aAAa;EACd;;;;;ACgBH,SAAgB,+CACd,YACwB;CACxB,MAAM,EAAE,aAAa,cAAc,oBAAoB,WAAW;AAClE,QAAO;EACL;EACA,MAAM,mCAAmC,WAAW;EACpD;EACA,sBAAsB;EACtB,UAAU,uBAAuB,mCAAmC,WAAW,CAAC;EACjF;;AAOH,SAAgB,8BAA8B,YAAoB,SAA8B;CAC9F,MAAM,EAAE,aAAa,cAAc,oBAAoB,WAAW;CAClE,MAAM,kBAAkB,uBAAuB,mCAAmC,WAAW,CAAC;CAC9F,MAAM,cAAc,yBAAyB,UAAU;AAEvD,KAAI,gBAAgB,UAAU,oBAAoB,QAChD,OAAM,IAAI,MAAM,oCAAoC;AAEtD,SAAQ,EAAE,QAAQ,mBAAqC;EACrD,MAAM,gBAAgB,gBAAgB,YAAY,OAAO,CAAC,YAAY,aAAa;EAOnF,MAAM,UALyB,yBAAyB,YAAY,CAAC;GACnE,MAAM;GACN,QAAQ;GACT,CAAC,CAEqC,eAAe,QAAQ;AAE9D,SAAO;GACL,WAAW,yBAAyB,WAAW,QAAQ,aAAa;GACpE,sBAAsB;GACtB;GACA;GACA;GACA,IAAI,UAAU;AACZ,QAAI,CAAC,QAAQ,QAAS,OAAM,IAAI,MAAM,uCAAuC;AAC7E,WAAO,QAAQ;;GAEjB,IAAI,YAAY;AACd,QAAI,CAAC,cAAc,UAAW,OAAM,IAAI,MAAM,kCAAkC;AAChF,WAAO,cAAc;;GAExB;;;;;;;;;;;;AA8BL,SAAgB,uBACd,MACiC;AACjC,QAAO,CACL,KAAK,WACL;EACE,aAAa,YAAY,KAAK,qBAAqB;EACnD,MAAM,IAAI,UAAU,0BAA0B,KAAK,UAAU,CAAC;EAC/D,CACF;;;;;;;;;;;AAYH,SAAgB,0BACd,MAC6B;AAC7B,QAAO,CAGL,wBAAwB,KAAK,UAAU,EACvC;EACE,QAAQ,EAAE;EACV,KAAK;GACH,aAAa,YAAY,KAAK,qBAAqB;GACnD,MAAM,IAAI,UAAU,0BAA0B,KAAK,UAAU,CAAC;GAC/D;EACF,CACF;;AAOH,SAAgB,sCACd,MACgC;AAChC,QAAO;EACL,mBAAmB,OAAO,KAAK,KAAK,sBAAsB,MAAM;EAChE,MAAM,0BAA0B,KAAK,UAAU;EAC/C,YAAY,EAAE;EACd,QAAQ,OAAO,KAAK,wBAAwB,KAAK,UAAU,CAAC;EAC7D;;AAKH,SAAgB,mCACd,MAC6B;AAC7B,QAAO;EACL,mBAAmB,OAAO,KAAK,KAAK,sBAAsB,MAAM;EAChE,MAAM,0BAA0B,KAAK,UAAU;EAC/C,QAAQ,OAAO,KAAK,KAAK,UAAU;EACpC;;AAGH,SAAgB,mCAAmC,MAAc;AAC/D,QAAO;EACL,QAAQ,2BAA2B,KAAK;EACxC,cAAc,4BAA4B,KAAK;EAChD;;;;;;;;;;;AAYH,SAAgB,mBAAmB,EAAE,aAAa,QAAiC;CACjF,MAAM,SAAS,KAAK,KAAI,QAAQ,OAAO,kBAAkB,MAAM,kBAAkB,MAAM,IAAK;AAC5F,QAAO,GAAG,YAAY,YAAY,CAAC,GAAG,OAAO,KAAK,IAAI;;;;;;;;AASxD,SAAgB,0BAA0B,YAAwC;AAChF,QAAO,WAAW,KAAK,CAAC,SAAS,UAC/B,mBAAmB,YAAY,OAAO,KAAK,MAAM,KAAK,CACvD;;;;;AC9NH,SAAgB,mCAEd,EACA,SACA,cACA,SACA,YACA,eACA,OACA,eAC4C;CAC5C,MAAM,qBAAqB;EAAE;EAAS;EAAY;EAAO;CACzD,MAAM,EAAE,QAAQ,SAAS,QAAQ,eAC7B,0BAA0B,mBAAmB,GAC7C,uBAAuB,mBAAmB;AAE9C,KAAI,CAAC,OAAO,OAAQ,OAAM,IAAI,aAAa,iBAAiB;AAC5D,KAAI,CAAC,QAAQ,OAAQ,OAAM,IAAI,aAAa,kBAAkB;CAE9D,MAAM,KAAK,IAAI,IAAI,aAAa;AAEhC,MAAK,MAAM,SAAS,QAAQ;EAC1B,MAAM,QAAQ,YAAY,MAAM,UAAU;AAE1C,MAAI,CAAC,OAAO;AAEV,WAAQ,IAAI,2CAA2C,MAAM,YAAY;AACzE;;EAGF,MAAM,kBACJ,MAAM,gBAAgB,SAClB,EAAE,oBAAoB,CAAC,0BAA0B,MAAM,CAAC,EAAE,GAC1D,EAAE,iBAAiB,CAAC,uBAAuB,MAAM,CAAC,EAAE;EAE1D,MAAM,iBACJ,MAAM,gBAAgB,SAAS,EAAE,gBAAgB,MAAM,QAAQ,gBAAgB,GAAG,EAAE;AAEtF,KAAG,SAAS;GACV,MAAM,MAAM;GACZ,OAAO,MAAM;GACb,aAAa;IACX,QAAQ,MAAM,QAAQ;IACtB,QAAQ,OAAO,MAAM,MAAM;IAC5B;GACD,GAAG;GACH,GAAG;GACJ,CAAC;;AAGJ,SAAQ,SAAQ,WAAU;AAGxB,MAAI,CAAC,OAAO,SAAS;AACnB,MAAG,iBAAiB,eAAe,OAAO,OAAO,MAAM,EAAE,QAAQ;AACjE;;AAEF,KAAG,iBAAiB,OAAO,SAAS,OAAO,OAAO,MAAM,EAAE,QAAQ;GAClE;AAEF,QAAO;EAAE;EAAI,KAAK,GAAG;EAAK,MAAM,GAAG,QAAQ;EAAE;EAAQ;EAAK;;;;;AC9E5D,SAAgB,uBAAuB,EAAE,cAAc,YAA0C;AAC/F,QAAO,CAAC,aAAa,OAAO,cAAc,SAAS,OAAO;;AAG5D,SAAgB,kBAAkB,cAAqB;AACrD,QAAO,CAAC,aAAa,OAAO,WAAW,8BAA8B;;;;;ACEvE,SAAgB,0BACd,iBACA;AACA,SAAQ,yBAAyB,gBAAgB,UAAU,EAA3D;EACE,KAAK,OACH,QAAO,MAAM,gBAAgB,KAAK;EACpC,KAAK,SACH,QAAO,QAAQ,gBAAgB,KAAK;EACtC,QACE;;;AAIN,SAAgB,+BAA+B,YAA0C;AAEvF,SADyB,WAAW,MAAM,IAAI,CAAC,IAC/C;EACE,KAAK,KACH,QAAO;EACT,KAAK,OACH,QAAO;EACT,QACE,OAAM,IAAI,MAAM,0BAA0B;;;AAIhD,SAAgB,0BAA0B,YAAoB;CAC5D,MAAM,QAAQ,WAAW,MAAM,yBAAyB;AACxD,KAAI,SAAS,MAAM,GACjB,QAAO,MAAM;AAEf,OAAM,IAAI,MAAM,4BAA4B;;AAc9C,SAAgB,8BAA8B,EAC5C,mBACA,SACA,QAAQ,KACmE;CAC3E,MAAM,kBAAkB,MAAM,gBAAgB,0BAA0B,kBAAkB,CAAC;CAC3F,MAAM,cAAc,+BAA+B,kBAAkB;CAErE,MAAM,mBAAmB,yBAAyB,YAAY,CAAC;EAC7D,MAAM;EACN,QAAQ;EACT,CAAC;CAEF,MAAMC,UAAiD,EAAE;AAEzD,MAAK,IAAI,eAAe,GAAG,eAAe,OAAO,EAAE,aACjD,MAAK,IAAI,cAAc,GAAG,cAAc,GAAG,EAAE,aAAa;EACxD,MAAM,UAAU,yBAAyB,YAAY,CAAC;GACpD,MAAM,kBAAkB;IAAE;IAAc;IAAa,UAAU;IAAiB;IAAS,CAAC;GAC1F,QAAQ,uBAAuB;IAC7B;IACA;IACA,UAAU;IACV;IACD,CAAC;GACH,CAAC;AACF,UAAQ,KAAK;GACX;GACA,MAAM,iBAAiB;IACrB;IACA,cAAc,gBAAgB,QAAQ;IACtC;IACA;IACD,CAAC;GACH,CAAC;;AAGN,QAAO;;;;;AC3ET,SAAgB,0BAA0B,MAAqC;CAC7E,MAAM,EAAE,aAAa,kBAAkB,mBAAmB;CAE1D,MAAM,kBAAkB,MAAM,gBAAgB,YAAY;CAC1D,MAAM,uBAAuB,MAAM,gBAAgB,iBAAiB;AAEpE,SAAQ,YAA4B;EAClC,MAAM,UAAU,wBAAwB,QAAQ;EAChD,MAAM,cAAc;EACpB,MAAM,cAAc,4BAA4B,QAAQ;EAExD,MAAM,eAAe,yBAAyB,YAAY,CAAC;GACzD,MAAM,gBAAgB,QAAQ;GAC9B,QAAQ,qBAAqB,QAAQ;GACtC,CAAC;EAEF,SAAS,yBAAyB,cAAsB;AACtD,UAAO,kBAAkB;IAAE;IAAa;IAAc,UAAU;IAAiB;IAAS,CAAC;;EAG7F,SAAS,8BAA8B,cAAsB;AAC3D,UAAO,uBAAuB;IAC5B;IACA;IACA,UAAU;IACV;IACD,CAAC;;EAGJ,MAAM,YAAY,yBAAyB,YAAY,CAAC;GACtD,MAAM;GACN,QAAQ;GACT,CAAC;EAEF,MAAM,mBAAmB,yBAAyB,YAAY,CAAC;GAC7D,MAAM;GACN,QAAQ;GACT,CAAC;EAEF,MAAM,QAAQ,eAAe;EAC7B,MAAM,KAAK,YAAY,KAAK;AAE5B,SAAO,MAAM,UAAU,IAAI,gBAAgB;GACzC,MAAM,eAAe,MAAM,UAAU;AAIrC,OAFuB,UAAU,aAAa,KAEvB,SAAS;AAC9B,UAAM,WAAW;AACjB;;AAKF,UAAO;IACL,QAAQ;IACR,UAJS,YAAY,KAAK,GAIX;IACf,MAAM,iBAAiB;KACrB;KACA;KACA,cAAc;KACd;KACD,CAAC;IACH;;AAGH,SAAO,EAAE,QAAQ,WAAW;;;;;;ACnFhC,SAAgB,sBAAsB,SAAiB;CACrD,MAAM,cAAc;GACjB,YAAY,QAAQ;GACpB,YAAY,OAAO;GACnB,YAAY,SAAS;GACrB,YAAY,QAAQ;GACpB,YAAY,OAAO;EACrB;CAED,MAAM,cAAc,eAAe,QAAQ;CAE3C,MAAM,EAAE,WAAW;CACnB,IAAIC;AACJ,KAAI,OACF,aAAYC,UAAQ,QAAQ,WAAW,QAAQ,CAAC;KAEhD,aAAYA,UAAQ,QAAQ,gBAAgB,QAAQ,CAAC;CAGvD,MAAM,OAAO,YAAY,YAAY;AACrC,KAAI,CAAC,KACH,OAAM,IAAI,MAAM,6BAA6B,YAAY,OAAO;AAGlE,QAAO;EACL;EACA;EACD"}
1
+ {"version":3,"file":"index.js","names":["bitcoinMainnet: BtcSignerNetwork","bitcoinTestnet: BtcSignerNetwork","btcSignerLibNetworks: Record<BitcoinNetworkModes, BtcSignerNetwork>","bitcoinJsLibNetworks: Record<BitcoinNetworkModes, bitcoinJs.Network>","bitcoinNetworkToCoreNetworkMap: Record<BitcoinNetworkModes, NetworkModes>","coinTypeMap: Record<NetworkModes, 0 | 1>","paymentTypeMap: Record<BtcSignerLibPaymentTypeIdentifers, BitcoinPaymentTypes>","inputs: TransactionInput[]","outputs: TransactionOutput[]","bitcoin","encode","supportedMessageSigningPaymentTypes: PaymentTypes[]","privateKey: Uint8Array | undefined","bitcoin","validate","neededUtxos: T[]","changeUtxos: CoinSelectionOutput[]","amount","network","payToScriptHashPrefixMap: Record<NetworkModes, number>","results: DeriveAddressesFromDescriptorResult[]","hashbytes: Uint8Array","bitcoin"],"sources":["../src/bip21/bip21.ts","../src/utils/bitcoin.network.ts","../src/payments/p2tr-address-gen.ts","../src/payments/p2wpkh-address-gen.ts","../src/validation/address-validation.ts","../src/validation/bitcoin-error.ts","../src/validation/bitcoin-address.ts","../src/utils/bitcoin.utils.ts","../src/bip322/bip322-utils.ts","../src/bip322/sign-message-bip322-bitcoinjs.ts","../src/fees/btc-size-fee-estimator.ts","../src/coin-selection/coin-selection.utils.ts","../src/coin-selection/calculate-max-spend.ts","../src/coin-selection/coin-selection.ts","../src/fees/bitcoin-fees.ts","../src/mocks/mocks.ts","../src/schemas/address-schema.ts","../src/payments/p2wsh-p2sh-address-gen.ts","../src/psbt/psbt-totals.ts","../src/psbt/psbt-inputs.ts","../src/psbt/psbt-outputs.ts","../src/psbt/utils.ts","../src/psbt/psbt-details.ts","../src/signer/bitcoin-signer.ts","../src/transactions/generate-unsigned-transaction.ts","../src/validation/amount-validation.ts","../src/utils/bitcoin.descriptors.ts","../src/utils/lookup-derivation-by-address.ts","../src/utils/deconstruct-btc-address.ts"],"sourcesContent":["import { Bip21Options, decode, encode } from 'bip21';\n\nimport { isError } from '@leather.io/utils';\n\ninterface Bip21ResultValue {\n address: string;\n [key: string]: string | number | undefined;\n}\n\ntype Bip21Result =\n | {\n success: true;\n data: Bip21ResultValue;\n }\n | {\n success: false;\n error: string;\n };\n\nexport const bip21 = {\n decode: (uri: string, urnScheme?: string): Bip21Result => {\n try {\n const { address, options } = decode(uri, urnScheme);\n return {\n success: true,\n data: { address, ...options },\n };\n } catch (error) {\n return {\n success: false,\n error: isError(error) ? error.message : 'invalid input',\n };\n }\n },\n encode: (address: string, options: Bip21Options, urnScheme?: string) => {\n try {\n return encode(address, options, urnScheme);\n } catch {\n return null;\n }\n },\n};\n","import * as bitcoinJs from 'bitcoinjs-lib';\n\nimport { BitcoinNetworkModes } from '@leather.io/models';\n\n// TODO - this PR was merged so we could update this\n// https://github.com/paulmillr/scure-btc-signer/blob/main/src/utils.ts\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 '../utils/bitcoin.network';\nimport {\n BitcoinAccount,\n deriveAddressIndexZeroFromAccount,\n ecdsaPublicKeyToSchnorr,\n getBitcoinCoinTypeIndexByNetwork,\n} from '../utils/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,\n accountIndex,\n changeIndex,\n addressIndex,\n}: {\n network: BitcoinNetworkModes;\n accountIndex: number;\n changeIndex: number;\n addressIndex: number;\n}) {\n return (\n makeTaprootAccountDerivationPath(network, accountIndex) + `/${changeIndex}/${addressIndex}`\n );\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 '../utils/bitcoin.network';\nimport {\n BitcoinAccount,\n deriveAddressIndexZeroFromAccount,\n getBitcoinCoinTypeIndexByNetwork,\n} from '../utils/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,\n accountIndex,\n changeIndex,\n addressIndex,\n}: {\n network: BitcoinNetworkModes;\n accountIndex: number;\n changeIndex: number;\n addressIndex: number;\n}) {\n return (\n makeNativeSegwitAccountDerivationPath(network, accountIndex) + `/${changeIndex}/${addressIndex}`\n );\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 { Network, validate } from 'bitcoin-address-validation';\n\nimport { BitcoinNetworkModes } from '@leather.io/models';\nimport { isEmptyString, isUndefined } from '@leather.io/utils';\n\n// todo investigate handling this in bitcoinNetworkToNetworkMode\nexport function getBitcoinAddressNetworkType(network: BitcoinNetworkModes): Network {\n // Signet uses testnet address format, this parsing is to please the\n // validation library - 'bitcoin-address-validation'\n if (network === 'signet') return Network.testnet;\n return network as Network;\n}\n\nexport function isValidBitcoinAddress(address: string) {\n if (isUndefined(address) || isEmptyString(address)) {\n return false;\n }\n\n return validate(address);\n}\n\nexport function isValidBitcoinNetworkAddress(address: string, network: BitcoinNetworkModes) {\n return validate(address, getBitcoinAddressNetworkType(network));\n}\n","import { TransactionErrorKey } from '@leather.io/models';\n\nexport 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 | TransactionErrorKey\n | 'InsufficientAmount'\n | 'NoInputsToSign'\n | 'NoOutputsToSign'\n | 'InscribedUtxos';\n","import { BitcoinAddress } from '@leather.io/models';\n\nimport { isValidBitcoinAddress } from './address-validation';\nimport { BitcoinError } from './bitcoin-error';\n\nexport function isBitcoinAddress(value: string): value is BitcoinAddress {\n try {\n isValidBitcoinAddress(value);\n return true;\n } catch {\n return false;\n }\n}\n\n// Function to create a BitcoinAddress\nexport function createBitcoinAddress(value: string): BitcoinAddress {\n if (!isBitcoinAddress(value)) {\n throw new BitcoinError('InvalidAddress');\n }\n\n return value;\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 { BitcoinAddress, BitcoinNetworkModes, NetworkModes } from '@leather.io/models';\nimport type { BitcoinPaymentTypes } from '@leather.io/rpc';\nimport { defaultWalletKeyId, isDefined, whenNetwork } from '@leather.io/utils';\n\nimport { getTaprootPayment } from '../payments/p2tr-address-gen';\nimport { getNativeSegwitPaymentFromAddressIndex } from '../payments/p2wpkh-address-gen';\nimport { createBitcoinAddress } from '../validation/bitcoin-address';\nimport { BtcSignerNetwork, getBtcSignerLibNetworkConfigByMode } from './bitcoin.network';\n\nexport interface BitcoinAccount {\n type: BitcoinPaymentTypes;\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 ({ changeIndex, addressIndex }: { changeIndex: number; addressIndex: number }) =>\n keychain.deriveChild(changeIndex).deriveChild(addressIndex);\n}\n\nexport function deriveAddressIndexZeroFromAccount(keychain: HDKey) {\n return deriveAddressIndexKeychainFromAccount(keychain)({\n changeIndex: 0,\n addressIndex: 0,\n });\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 function toXOnly(pubKey: Buffer) {\n return pubKey.length === 32 ? pubKey : pubKey.subarray(1, 33);\n}\n\nexport function decodeBitcoinTx(tx: string): ReturnType<typeof btc.RawTx.decode> {\n return btc.RawTx.decode(hexToBytes(tx));\n}\n\nexport function getAddressFromOutScript(\n script: Uint8Array,\n bitcoinNetwork: BtcSignerNetwork\n): BitcoinAddress | null {\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 createBitcoinAddress(\n btc.Address(bitcoinNetwork).encode({\n type: outputScript.type,\n hash: outputScript.hash,\n })\n );\n case 'tr':\n return createBitcoinAddress(\n btc.Address(bitcoinNetwork).encode({\n type: outputScript.type,\n pubkey: outputScript.pubkey,\n })\n );\n case 'ms':\n return createBitcoinAddress(btc.p2ms(outputScript.m, outputScript.pubkeys).address ?? '');\n case 'pk':\n return createBitcoinAddress(btc.p2pk(outputScript.pubkey, bitcoinNetwork).address ?? '');\n case 'unknown':\n case 'tr_ms':\n case 'tr_ns':\n case 'p2a':\n default:\n return null;\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, BitcoinPaymentTypes> = {\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(\n payment: BtcSignerLibPaymentTypeIdentifers | BitcoinPaymentTypes\n) {\n return isBtcSignerLibPaymentType(payment)\n ? btcSignerLibPaymentTypeToPaymentTypeMap(payment)\n : payment;\n}\n\nexport type PaymentTypeMap<T> = Record<BitcoinPaymentTypes, T>;\nexport function whenPaymentType(mode: BitcoinPaymentTypes | 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): BitcoinPaymentTypes {\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 null;\n}\n\nexport function getInputPaymentType(\n input: TransactionInput,\n network: BitcoinNetworkModes\n): BitcoinPaymentTypes {\n const address = getBitcoinInputAddress(input, getBtcSignerLibNetworkConfigByMode(network));\n if (address === null) 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 changeIndex: number;\n addressIndex: number;\n keychain?: HDKey;\n network: BitcoinNetworkModes;\n}\n\nexport function getTaprootAddress({\n changeIndex,\n addressIndex,\n keychain,\n network,\n}: 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 addresskeychain = deriveAddressIndexKeychainFromAccount(keychain)({\n changeIndex,\n addressIndex,\n });\n\n if (!addresskeychain.publicKey) throw new Error('Expected publicKey to be defined');\n\n const payment = getTaprootPayment(addresskeychain.publicKey, network);\n\n if (!payment.address) throw new Error('Expected address to be defined');\n return payment.address;\n}\n\nexport function getNativeSegwitAddress({\n changeIndex,\n addressIndex,\n keychain,\n network,\n}: 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 addressKeychain = deriveAddressIndexKeychainFromAccount(keychain)({\n changeIndex,\n addressIndex,\n });\n\n if (!addressKeychain.publicKey) throw new Error('Expected publicKey to be defined');\n\n const payment = getNativeSegwitPaymentFromAddressIndex(addressKeychain, 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: BitcoinAddress): 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: BitcoinAddress): 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\nexport function isTaprootDerivationPath(path: string) {\n return extractPurposeFromPath(path) === 86;\n}\n\nexport function isNativeSegwitDerivationPath(path: string) {\n return extractPurposeFromPath(path) === 84;\n}\n","import ecc from '@bitcoinerlab/secp256k1';\nimport { sha256 } from '@noble/hashes/sha256';\nimport { hexToBytes, utf8ToBytes } from '@noble/hashes/utils';\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 '../utils/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 { base64 } from '@scure/base';\nimport * as btc from '@scure/btc-signer';\nimport * as bitcoin from 'bitcoinjs-lib';\n\nimport { BitcoinAddress, BitcoinNetworkModes } from '@leather.io/models';\n\nimport { getBitcoinJsLibNetworkConfigByMode } from '../utils/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(\n address: BitcoinAddress,\n message: string,\n network: BitcoinNetworkModes\n) {\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: BitcoinAddress;\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","// 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, { 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 '../fees/btc-size-fee-estimator';\nimport { CoinSelectionRecipient } from './coin-selection';\n\nexport function getUtxoTotal<T extends { value: number }>(utxos: T[]) {\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}\ninterface GetSpendableAmountArgs<T> {\n utxos: T[];\n feeRate: number;\n recipients: CoinSelectionRecipient[];\n isSendMax?: boolean;\n}\nexport function getSpendableAmount<T extends { value: number }>({\n utxos,\n feeRate,\n recipients,\n}: GetSpendableAmountArgs<T>) {\n const balance = utxos.map(utxo => utxo.value).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<T extends { value: number; txid: string }>({\n utxos,\n feeRate,\n recipients,\n}: {\n utxos: T[];\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 => Number(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","import BigNumber from 'bignumber.js';\n\nimport type { Money } from '@leather.io/models';\nimport { createMoney, satToBtc } from '@leather.io/utils';\n\nimport { filterUneconomicalUtxos, getSpendableAmount } from './coin-selection.utils';\n\ninterface CalculateMaxSpendParams {\n recipient: string;\n utxos: { value: number; txid: string }[];\n feeRate: number;\n}\n\nexport interface CalculateMaxSpendResponse {\n spendAllFee: number;\n amount: Money;\n spendableBitcoin: BigNumber;\n}\nexport function calculateMaxSpend({\n recipient,\n utxos,\n feeRate,\n}: CalculateMaxSpendParams): CalculateMaxSpendResponse {\n if (!utxos.length)\n return {\n spendAllFee: 0,\n amount: createMoney(0, 'BTC'),\n spendableBitcoin: new BigNumber(0),\n };\n\n const filteredUtxos = filterUneconomicalUtxos({\n utxos,\n feeRate,\n recipients: [{ address: recipient, amount: createMoney(0, 'BTC') }],\n });\n\n const { spendableAmount, fee } = getSpendableAmount({\n utxos: filteredUtxos,\n feeRate,\n recipients: [{ address: recipient, amount: createMoney(0, 'BTC') }],\n isSendMax: true,\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 } 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 '../validation/bitcoin-error';\nimport { filterUneconomicalUtxos, getSizeInfo, getUtxoTotal } from './coin-selection.utils';\n\nexport interface CoinSelectionOutput {\n value: bigint;\n address?: string;\n}\n\nexport interface CoinSelectionRecipient {\n address: string;\n amount: Money;\n}\n\nexport interface DetermineUtxosForSpendArgs<T> {\n feeRate: number;\n recipients: CoinSelectionRecipient[];\n utxos: T[];\n}\nexport function determineUtxosForSpendAll<T extends { value: number; txid: string }>({\n feeRate,\n recipients,\n utxos,\n}: DetermineUtxosForSpendArgs<T>) {\n recipients.forEach(recipient => {\n if (!validate(recipient.address)) throw new BitcoinError('InvalidAddress');\n });\n const filteredUtxos = filterUneconomicalUtxos({ utxos, feeRate, recipients });\n\n if (!filteredUtxos.length) throw new BitcoinError('InsufficientFunds');\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<T extends { value: number; txid: string }>({\n feeRate,\n recipients,\n utxos,\n}: DetermineUtxosForSpendArgs<T>) {\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: T[] = [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","import { AverageBitcoinFeeRates, Money } from '@leather.io/models';\n\nimport {\n CoinSelectionRecipient,\n DetermineUtxosForSpendArgs,\n determineUtxosForSpend,\n determineUtxosForSpendAll,\n} from '../coin-selection/coin-selection';\n\ntype GetBitcoinTransactionFeeArgs = DetermineUtxosForSpendArgs<{ value: number; txid: string }> & {\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: { value: number; txid: string }[];\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 { createBitcoinAddress } from '../validation/bitcoin-address';\n\n// maybe these should be in mono/config?\n// from extension/tests/mocks/constants\nexport const TEST_ACCOUNT_1_NATIVE_SEGWIT_ADDRESS = createBitcoinAddress(\n 'bc1q530dz4h80kwlzywlhx2qn0k6vdtftd93c499yq'\n);\nexport const TEST_ACCOUNT_1_TAPROOT_ADDRESS = createBitcoinAddress(\n 'bc1putuzj9lyfcm8fef9jpy85nmh33cxuq9u6wyuk536t9kemdk37yjqmkc0pg'\n);\nexport const TEST_ACCOUNT_2_TAPROOT_ADDRESS = createBitcoinAddress(\n 'bc1pmk2sacpfyy4v5phl8tq6eggu4e8laztep7fsgkkx0nc6m9vydjesaw0g2r'\n);\n\nexport const TEST_TESNET_ACCOUNT_1_NATIVE_SEGWIT_ADDRESS = createBitcoinAddress(\n 'tb1q4qgnjewwun2llgken94zqjrx5kpqqycaz5522d'\n);\n\nexport const TEST_TESTNET_ACCOUNT_2_BTC_ADDRESS = createBitcoinAddress(\n 'tb1qr8me8t9gu9g6fu926ry5v44yp0wyljrespjtnz'\n);\n\nexport const TEST_TESTNET_ACCOUNT_2_TAPROOT_ADDRESS = createBitcoinAddress(\n 'tb1pve00jmp43whpqj2wpcxtc7m8wqhz0azq689y4r7h8tmj8ltaj87qj2nj6w'\n);\n\n// coin-selection.spec\nexport const recipientAddress = createBitcoinAddress('tb1qt28eagxcl9gvhq2rpj5slg7dwgxae2dn2hk93m');\nexport const legacyAddress = createBitcoinAddress('15PyZveQd28E2SHZu2ugkWZBp6iER41vXj');\nexport const segwitAddress = createBitcoinAddress('33SVjoCHJovrXxjDKLFSXo1h3t5KgkPzfH');\nexport const taprootAddress = createBitcoinAddress(\n 'tb1parwmj7533de3k2fw2kntyqacspvhm67qnjcmpqnnpfvzu05l69nsczdywd'\n);\nexport const invalidAddress = 'whoop-de-da-boop-da-de-not-a-bitcoin-address';\n\nexport const inValidCharactersAddress = createBitcoinAddress(\n 'tb1&*%wmj7533de3k2fw2kntyqacspvhm67qnjcmpqnnpfvzu05l69nsczdywd'\n);\nexport const inValidLengthAddress = createBitcoinAddress('tb1parwmj7533de3k2fw2kntyqacspvhm67wd');\n","import { Network, getAddressInfo, validate } from 'bitcoin-address-validation';\nimport { z } from 'zod';\n\nimport type { BitcoinNetworkModes } from '@leather.io/models';\nimport { isEmptyString, isUndefined } from '@leather.io/utils';\n\nexport function nonEmptyStringValidator(message = '') {\n return z\n .string()\n .refine((value: string) => value !== undefined && value.trim() !== '', { message });\n}\n\nexport function btcAddressValidator() {\n return z.string().refine(\n (value: string) => {\n if (isUndefined(value) || isEmptyString(value)) return true;\n return validate(value);\n },\n { message: 'Bitcoin address is not valid' }\n );\n}\n\nexport function getNetworkTypeFromAddress(address: string) {\n return getAddressInfo(address).network as BitcoinNetworkModes;\n}\n\nfunction btcAddressNetworkValidatorFactory(network: BitcoinNetworkModes) {\n function getAddressNetworkType(network: BitcoinNetworkModes): Network {\n // Signet uses testnet address format, this parsing is to please the\n // validation library\n if (network === 'signet') return Network.testnet;\n return network as Network;\n }\n return (value?: string) => {\n if (isUndefined(value) || isEmptyString(value)) return true;\n return validate(value, getAddressNetworkType(network));\n };\n}\n\nexport function btcAddressNetworkValidator(network: BitcoinNetworkModes) {\n return z.string().refine(btcAddressNetworkValidatorFactory(network), {\n message: 'Address is for incorrect network',\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 { BitcoinAddress } from '@leather.io/models';\nimport { createMoney, sumNumbers } from '@leather.io/utils';\n\nimport { inferPaymentTypeFromAddress } from '../utils/bitcoin.utils';\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: BitcoinAddress[];\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 { bytesToHex } from '@noble/hashes/utils';\nimport type { TransactionInput } from '@scure/btc-signer/psbt';\n\nimport type { BitcoinAddress, BitcoinNetworkModes, InscriptionAsset } from '@leather.io/models';\nimport { isDefined, isUndefined } from '@leather.io/utils';\n\nimport { getBtcSignerLibNetworkConfigByMode } from '../utils/bitcoin.network';\nimport { getBitcoinInputAddress, getBitcoinInputValue } from '../utils/bitcoin.utils';\n\nexport interface PsbtInput {\n address: BitcoinAddress;\n index?: number;\n // TODO: inject inscription later on. getParsedInputs should be a pure function\n inscription?: InscriptionAsset;\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: BitcoinAddress[];\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 bitcoinAddress = isDefined(input.index)\n ? getBitcoinInputAddress(input, bitcoinNetwork)\n : null;\n if (bitcoinAddress === null) {\n throw new Error('PSBT input has unsupported bitcoin address');\n }\n const isCurrentAddress = psbtAddresses.includes(bitcoinAddress);\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: bitcoinAddress,\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';\n\nimport { BitcoinAddress, BitcoinNetworkModes } from '@leather.io/models';\nimport { isDefined, isUndefined } from '@leather.io/utils';\n\nimport { getBtcSignerLibNetworkConfigByMode } from '../utils/bitcoin.network';\nimport { getAddressFromOutScript } from '../utils/bitcoin.utils';\n\nexport interface PsbtOutput {\n address: BitcoinAddress | null;\n isMutable: boolean;\n toSign: boolean;\n value: number;\n}\n\nexport interface PsbtOutputWithAddress extends PsbtOutput {\n address: BitcoinAddress;\n}\n\ninterface GetParsedOutputsArgs {\n isPsbtMutable: boolean;\n outputs: TransactionOutput[];\n networkMode: BitcoinNetworkModes;\n psbtAddresses: BitcoinAddress[];\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 = !!outputAddress && 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 { 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","import { BitcoinAddress, BitcoinNetworkModes } from '@leather.io/models';\nimport { createMoney, subtractMoney } from '@leather.io/utils';\n\nimport { getPsbtTxInputs, getPsbtTxOutputs } from '../utils/bitcoin.utils';\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: BitcoinAddress[];\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 { 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';\nimport * as bitcoin from 'bitcoinjs-lib';\n\nimport {\n DerivationPathDepth,\n appendAddressIndexToPath,\n decomposeDescriptor,\n deriveKeychainFromXpub,\n extractAddressIndexFromPath,\n extractChangeIndexFromPath,\n fingerprintAsNumberToHex,\n keyOriginToDerivationPath,\n} from '@leather.io/crypto';\nimport type { BitcoinAddress, BitcoinNetworkModes, ValueOf } from '@leather.io/models';\nimport { PaymentTypes, signatureHash } from '@leather.io/rpc';\nimport { hexToNumber } from '@leather.io/utils';\n\nimport { getTaprootPaymentFromAddressIndex } from '../payments/p2tr-address-gen';\nimport { getNativeSegwitPaymentFromAddressIndex } from '../payments/p2wpkh-address-gen';\nimport {\n SupportedPaymentType,\n ecdsaPublicKeyToSchnorr,\n extractExtendedPublicKeyFromPolicy,\n inferPaymentTypeFromPath,\n whenSupportedPaymentType,\n} from '../utils/bitcoin.utils';\n\nexport type AllowedSighashTypes = ValueOf<typeof 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: BitcoinAddress;\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: BitcoinAddress;\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 change: 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 ({ change, addressIndex }: BitcoinPayerInfo) => {\n const childKeychain = accountKeychain.deriveChild(change).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, change, addressIndex),\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\ntype PsbtInputBitcoinJsLib = bitcoin.Psbt['data']['inputs']['0'];\n\ntype TapBip32DerivationBitcoinJsLib = NonNullable<PsbtInputBitcoinJsLib['tapBip32Derivation']>['0'];\n\nexport function payerToTapBip32DerivationBitcoinJsLib(\n args: PayerToBip32DerivationArgs\n): TapBip32DerivationBitcoinJsLib {\n return {\n masterFingerprint: Buffer.from(args.masterKeyFingerprint, 'hex'),\n path: keyOriginToDerivationPath(args.keyOrigin),\n leafHashes: [],\n pubkey: Buffer.from(ecdsaPublicKeyToSchnorr(args.publicKey)),\n };\n}\n\ntype Bip32DerivationBitcoinJsLib = NonNullable<PsbtInputBitcoinJsLib['bip32Derivation']>['0'];\n\nexport function payerToBip32DerivationBitcoinJsLib(\n args: PayerToBip32DerivationArgs\n): Bip32DerivationBitcoinJsLib {\n return {\n masterFingerprint: Buffer.from(args.masterKeyFingerprint, 'hex'),\n path: keyOriginToDerivationPath(args.keyOrigin),\n pubkey: Buffer.from(args.publicKey),\n };\n}\n\nexport function extractPayerInfoFromDerivationPath(path: string) {\n return {\n change: extractChangeIndexFromPath(path),\n addressIndex: extractAddressIndexFromPath(path),\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 `${fingerprintAsNumberToHex(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 * as btc from '@scure/btc-signer';\n\nimport {\n CoinSelectionRecipient,\n determineUtxosForSpend,\n determineUtxosForSpendAll,\n} from '../coin-selection/coin-selection';\nimport {\n BitcoinNativeSegwitPayer,\n BitcoinTaprootPayer,\n payerToBip32Derivation,\n payerToTapBip32Derivation,\n} from '../signer/bitcoin-signer';\nimport { BtcSignerNetwork } from '../utils/bitcoin.network';\nimport { BitcoinError } from '../validation/bitcoin-error';\n\nexport interface GenerateBitcoinUnsignedTransactionArgs<T> {\n feeRate: number;\n isSendingMax?: boolean;\n network: BtcSignerNetwork;\n recipients: CoinSelectionRecipient[];\n utxos: T[];\n changeAddress: string;\n payerLookup(keyOrigin: string): BitcoinNativeSegwitPayer | BitcoinTaprootPayer | undefined;\n}\nexport function generateBitcoinUnsignedTransaction<\n T extends { txid: string; vout: number; value: number; keyOrigin: string },\n>({\n feeRate,\n isSendingMax,\n network,\n recipients,\n changeAddress,\n utxos,\n payerLookup,\n}: GenerateBitcoinUnsignedTransactionArgs<T>) {\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\n for (const input of inputs) {\n const payer = payerLookup(input.keyOrigin);\n\n if (!payer) {\n // eslint-disable-next-line no-console\n console.log(`No payer found for input with keyOrigin ${input.keyOrigin}`);\n continue;\n }\n\n const bip32Derivation =\n payer.paymentType === 'p2tr'\n ? { tapBip32Derivation: [payerToTapBip32Derivation(payer)] }\n : { bip32Derivation: [payerToBip32Derivation(payer)] };\n\n const tapInternalKey =\n payer.paymentType === 'p2tr' ? { tapInternalKey: payer.payment.tapInternalKey } : {};\n\n tx.addInput({\n txid: input.txid,\n index: input.vout,\n witnessUtxo: {\n script: payer.payment.script,\n amount: BigInt(input.value),\n },\n ...bip32Derivation,\n ...tapInternalKey,\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(changeAddress, 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 { BITCOIN_MINIMUM_SPEND_IN_SATS } from '@leather.io/constants';\nimport { Money } from '@leather.io/models';\n\ninterface isBtcBalanceSufficientParams {\n desiredSpend: Money;\n maxSpend: Money;\n}\nexport function isBtcBalanceSufficient({ desiredSpend, maxSpend }: isBtcBalanceSufficientParams) {\n return !desiredSpend.amount.isGreaterThan(maxSpend.amount);\n}\n\nexport function isBtcMinimumSpend(desiredSpend: Money) {\n return !desiredSpend.amount.isLessThan(BITCOIN_MINIMUM_SPEND_IN_SATS);\n}\n","import { HARDENED_OFFSET, HDKey } from '@scure/bip32';\nimport { makeTaprootAddressIndexDerivationPath } from 'payments/p2tr-address-gen';\nimport { makeNativeSegwitAddressIndexDerivationPath } from 'payments/p2wpkh-address-gen';\n\nimport { BitcoinNetworkModes } from '@leather.io/models';\n\nimport {\n SupportedPaymentType,\n getNativeSegwitAddress,\n getTaprootAddress,\n inferPaymentTypeFromPath,\n whenSupportedPaymentType,\n} from './bitcoin.utils';\n\nexport function getDescriptorFromKeychain<T extends { keyOrigin: string; xpub: string }>(\n accountKeychain: T\n) {\n switch (inferPaymentTypeFromPath(accountKeychain.keyOrigin)) {\n case 'p2tr':\n return `tr(${accountKeychain.xpub})`;\n case 'p2wpkh':\n return `wpkh(${accountKeychain.xpub})`;\n default:\n return undefined;\n }\n}\n\nexport function inferPaymentTypeFromDescriptor(descriptor: string): SupportedPaymentType {\n const descriptorPrefix = descriptor.split('(')[0];\n switch (descriptorPrefix) {\n case 'tr':\n return 'p2tr';\n case 'wpkh':\n return 'p2wpkh';\n default:\n throw new Error('Unrecognized descriptor');\n }\n}\n\nexport function extractXpubFromDescriptor(descriptor: string) {\n const match = descriptor.match(/\\((xpub[0-9A-Za-z]+)\\)/);\n if (match && match[1]) {\n return match[1];\n }\n throw new Error('Invalid descriptor format');\n}\n\nexport interface DeriveAddressesFromDescriptorArgs {\n accountDescriptor: string;\n network: BitcoinNetworkModes;\n limit?: number; // number of addresses to derive\n}\n\nexport interface DeriveAddressesFromDescriptorResult {\n address: string;\n path: string;\n}\n\nexport function deriveAddressesFromDescriptor({\n accountDescriptor,\n network,\n limit = 1,\n}: DeriveAddressesFromDescriptorArgs): DeriveAddressesFromDescriptorResult[] {\n const accountKeychain = HDKey.fromExtendedKey(extractXpubFromDescriptor(accountDescriptor));\n const paymentType = inferPaymentTypeFromDescriptor(accountDescriptor);\n\n const derivationPathFn = whenSupportedPaymentType(paymentType)({\n p2tr: makeTaprootAddressIndexDerivationPath,\n p2wpkh: makeNativeSegwitAddressIndexDerivationPath,\n });\n\n const results: DeriveAddressesFromDescriptorResult[] = [];\n\n for (let addressIndex = 0; addressIndex < limit; ++addressIndex) {\n for (let changeIndex = 0; changeIndex < 2; ++changeIndex) {\n const address = whenSupportedPaymentType(paymentType)({\n p2tr: getTaprootAddress({ addressIndex, changeIndex, keychain: accountKeychain, network }),\n p2wpkh: getNativeSegwitAddress({\n addressIndex,\n changeIndex,\n keychain: accountKeychain,\n network,\n }),\n });\n results.push({\n address,\n path: derivationPathFn({\n network,\n accountIndex: accountKeychain.index - HARDENED_OFFSET,\n addressIndex,\n changeIndex,\n }),\n });\n }\n }\n return results;\n}\n","import { HARDENED_OFFSET, HDKey } from '@scure/bip32';\n\nimport { BitcoinAddress } from '@leather.io/models';\nimport { createCounter } from '@leather.io/utils';\n\nimport { makeTaprootAddressIndexDerivationPath } from '../payments/p2tr-address-gen';\nimport { makeNativeSegwitAddressIndexDerivationPath } from '../payments/p2wpkh-address-gen';\nimport {\n getNativeSegwitAddress,\n getTaprootAddress,\n inferNetworkFromAddress,\n inferPaymentTypeFromAddress,\n whenSupportedPaymentType,\n} from './bitcoin.utils';\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: BitcoinAddress) => {\n const network = inferNetworkFromAddress(address);\n const changeIndex = 0;\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(addressIndex: number) {\n return getTaprootAddress({ changeIndex, addressIndex, keychain: taprootKeychain, network });\n }\n\n function getNativeSegwitAddressAtIndex(addressIndex: number) {\n return getNativeSegwitAddress({\n changeIndex,\n addressIndex,\n keychain: nativeSegwitKeychain,\n network,\n });\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({\n network,\n accountIndex,\n addressIndex: currentIndex,\n changeIndex,\n }),\n } as const;\n }\n\n return { status: 'failure' } as const;\n };\n}\n","import { AddressType, getAddressInfo } from 'bitcoin-address-validation';\nimport * as bitcoin from 'bitcoinjs-lib';\n\nexport function deconstructBtcAddress(address: string) {\n const typeMapping = {\n [AddressType.p2pkh]: '0x00',\n [AddressType.p2sh]: '0x01',\n [AddressType.p2wpkh]: '0x04',\n [AddressType.p2wsh]: '0x05',\n [AddressType.p2tr]: '0x06',\n };\n\n const addressInfo = getAddressInfo(address);\n\n const { bech32 } = addressInfo;\n let hashbytes: Uint8Array;\n if (bech32) {\n hashbytes = bitcoin.address.fromBech32(address).data;\n } else {\n hashbytes = bitcoin.address.fromBase58Check(address).hash;\n }\n\n const type = typeMapping[addressInfo.type];\n if (!type) {\n throw new Error(`Unsupported address type: ${addressInfo.type}`);\n }\n\n return {\n type,\n hashbytes,\n };\n}\n"],"mappings":"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"}
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.36.3",
5
+ "version": "0.36.4",
6
6
  "license": "MIT",
7
7
  "homepage": "https://github.com/leather.io/mono/tree/dev/packages/bitcoin",
8
8
  "repository": {
@@ -33,9 +33,9 @@
33
33
  "varuint-bitcoin": "1.1.2",
34
34
  "zod": "4.0.17",
35
35
  "@leather.io/constants": "0.30.0",
36
- "@leather.io/crypto": "1.12.13",
37
- "@leather.io/utils": "0.49.7",
38
- "@leather.io/models": "0.52.0"
36
+ "@leather.io/models": "0.52.0",
37
+ "@leather.io/utils": "0.49.8",
38
+ "@leather.io/crypto": "1.12.14"
39
39
  },
40
40
  "devDependencies": {
41
41
  "prettier": "3.5.1",
@@ -43,10 +43,10 @@
43
43
  "tslib": "2.6.2",
44
44
  "typescript": "5.9.3",
45
45
  "vitest": "2.1.9",
46
- "@leather.io/prettier-config": "0.9.0",
47
- "@leather.io/rpc": "2.21.7",
48
- "@leather.io/test-config": "0.1.2",
49
- "@leather.io/tsconfig-config": "0.11.1"
46
+ "@leather.io/rpc": "2.21.8",
47
+ "@leather.io/test-config": "0.1.3",
48
+ "@leather.io/tsconfig-config": "0.11.1",
49
+ "@leather.io/prettier-config": "0.9.0"
50
50
  },
51
51
  "keywords": [
52
52
  "bitcoin",
@@ -8,4 +8,14 @@ describe(serializeKeyOrigin.name, () => {
8
8
  };
9
9
  expect(serializeKeyOrigin(test)).toEqual("d7d96884/84'/0'/0'/0/0");
10
10
  });
11
+
12
+ test('that it correctly handles fingerprints with leading zeros', () => {
13
+ const testWithLeadingZero = {
14
+ fingerprint: 51208947,
15
+ path: [2147483732, 2147483648, 2147483648, 0, 0],
16
+ };
17
+ const result = serializeKeyOrigin(testWithLeadingZero);
18
+ expect(result.split('/')[0].length).toEqual(8);
19
+ expect(result).toContain("/84'/0'/0'/0/0");
20
+ });
11
21
  });
@@ -11,11 +11,12 @@ import {
11
11
  deriveKeychainFromXpub,
12
12
  extractAddressIndexFromPath,
13
13
  extractChangeIndexFromPath,
14
+ fingerprintAsNumberToHex,
14
15
  keyOriginToDerivationPath,
15
16
  } from '@leather.io/crypto';
16
17
  import type { BitcoinAddress, BitcoinNetworkModes, ValueOf } from '@leather.io/models';
17
18
  import { PaymentTypes, signatureHash } from '@leather.io/rpc';
18
- import { hexToNumber, toHexString } from '@leather.io/utils';
19
+ import { hexToNumber } from '@leather.io/utils';
19
20
 
20
21
  import { getTaprootPaymentFromAddressIndex } from '../payments/p2tr-address-gen';
21
22
  import { getNativeSegwitPaymentFromAddressIndex } from '../payments/p2wpkh-address-gen';
@@ -233,7 +234,7 @@ export function extractPayerInfoFromDerivationPath(path: string) {
233
234
  */
234
235
  export function serializeKeyOrigin({ fingerprint, path }: BtcSignerDerivationPath) {
235
236
  const values = path.map(num => (num >= HARDENED_OFFSET ? num - HARDENED_OFFSET + "'" : num));
236
- return `${toHexString(fingerprint)}/${values.join('/')}`;
237
+ return `${fingerprintAsNumberToHex(fingerprint)}/${values.join('/')}`;
237
238
  }
238
239
 
239
240
  /**