@leather.io/bitcoin 0.18.0 → 0.19.0

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.18.0 build /home/runner/work/mono/mono/packages/bitcoin
2
+ > @leather.io/bitcoin@0.19.0 build /home/runner/work/mono/mono/packages/bitcoin
3
3
  > tsup
4
4
 
5
5
  CLI Building entry: src/index.ts
@@ -8,9 +8,9 @@ CLI tsup v8.1.0
8
8
  CLI Using tsup config: /home/runner/work/mono/mono/packages/bitcoin/tsup.config.ts
9
9
  CLI Target: es2022
10
10
  ESM Build start
11
- ESM dist/index.js 43.72 KB
12
- ESM dist/index.js.map 84.58 KB
13
- ESM ⚡️ Build success in 58ms
11
+ ESM dist/index.js 49.89 KB
12
+ ESM dist/index.js.map 97.56 KB
13
+ ESM ⚡️ Build success in 61ms
14
14
  DTS Build start
15
- DTS ⚡️ Build success in 4435ms
16
- DTS dist/index.d.ts 20.41 KB
15
+ DTS ⚡️ Build success in 4575ms
16
+ DTS dist/index.d.ts 23.04 KB
package/CHANGELOG.md CHANGED
@@ -310,6 +310,33 @@
310
310
  * devDependencies
311
311
  * @leather.io/rpc bumped to 2.1.20
312
312
 
313
+ ### Dependencies
314
+
315
+ * The following workspace dependencies were updated
316
+ * dependencies
317
+ * @leather.io/constants bumped to 0.13.7
318
+ * @leather.io/crypto bumped to 1.6.16
319
+ * @leather.io/models bumped to 0.24.0
320
+ * @leather.io/utils bumped to 0.21.0
321
+ * devDependencies
322
+ * @leather.io/rpc bumped to 2.1.22
323
+
324
+ ## [0.19.0](https://github.com/leather-io/mono/compare/@leather.io/bitcoin-v0.18.1...@leather.io/bitcoin-v0.19.0) (2024-12-04)
325
+
326
+
327
+ ### Features
328
+
329
+ * add psbt functionality ([6b676a9](https://github.com/leather-io/mono/commit/6b676a971fbd7497e6c285a818374f13745b032c))
330
+
331
+
332
+ ### Dependencies
333
+
334
+ * The following workspace dependencies were updated
335
+ * dependencies
336
+ * @leather.io/constants bumped to 0.14.0
337
+ * @leather.io/crypto bumped to 1.6.17
338
+ * @leather.io/utils bumped to 0.21.1
339
+
313
340
  ## [0.18.0](https://github.com/leather-io/mono/compare/@leather.io/bitcoin-v0.17.0...@leather.io/bitcoin-v0.18.0) (2024-11-29)
314
341
 
315
342
 
package/dist/index.d.ts CHANGED
@@ -2,14 +2,14 @@ import * as ecpair from 'ecpair';
2
2
  import * as bitcoin from 'bitcoinjs-lib';
3
3
  import * as btc from '@scure/btc-signer';
4
4
  import * as _leather_io_models from '@leather.io/models';
5
- import { BitcoinNetworkModes, Money, AverageBitcoinFeeRates, NetworkModes } from '@leather.io/models';
5
+ import { BitcoinNetworkModes, Money, AverageBitcoinFeeRates, NetworkModes, Inscription } from '@leather.io/models';
6
6
  import BigNumber from 'bignumber.js';
7
7
  import { HDKey, Versions } from '@scure/bip32';
8
8
  import * as _scure_btc_signer_payment from '@scure/btc-signer/payment';
9
9
  import { P2Ret, P2TROut } from '@scure/btc-signer/payment';
10
10
  import { SigHash } from '@scure/btc-signer/transaction';
11
11
  import { PaymentTypes, SignatureHash } from '@leather.io/rpc';
12
- import { TransactionInput, TransactionOutput } from '@scure/btc-signer/psbt';
12
+ import { TransactionInput, TransactionOutput, RawPSBTV0 } from '@scure/btc-signer/psbt';
13
13
  import { deriveBip39SeedFromMnemonic, deriveRootBip32Keychain } from '@leather.io/crypto';
14
14
 
15
15
  declare function ecPairFromPrivateKey(key: Uint8Array): ecpair.ECPairInterface;
@@ -170,32 +170,6 @@ interface BtcSignerNetwork {
170
170
  declare function getBtcSignerLibNetworkConfigByMode(network: BitcoinNetworkModes): BtcSignerNetwork;
171
171
  declare function getBitcoinJsLibNetworkConfigByMode(network: BitcoinNetworkModes): bitcoin.networks.Network;
172
172
 
173
- interface GenerateBitcoinUnsignedTransactionArgs {
174
- feeRate: number;
175
- isSendingMax?: boolean;
176
- payerAddress: string;
177
- payerPublicKey: string;
178
- network: BtcSignerNetwork;
179
- recipients: CoinSelectionRecipient[];
180
- utxos: CoinSelectionUtxo[];
181
- }
182
- declare function generateBitcoinUnsignedTransactionNativeSegwit({ feeRate, isSendingMax, payerAddress, payerPublicKey, network, recipients, utxos, }: GenerateBitcoinUnsignedTransactionArgs): Promise<{
183
- tx: btc.Transaction;
184
- hex: string;
185
- psbt: Uint8Array;
186
- inputs: CoinSelectionUtxo[];
187
- fee: _leather_io_models.Money;
188
- } | null>;
189
-
190
- declare enum BitcoinErrorMessage {
191
- InsufficientFunds = "Insufficient funds",
192
- NoInputsToSign = "No inputs to sign",
193
- NoOutputsToSign = "No outputs to sign"
194
- }
195
- declare class BitcoinError extends Error {
196
- constructor(message: string);
197
- }
198
-
199
173
  interface BitcoinAccount {
200
174
  type: PaymentTypes;
201
175
  derivationPath: string;
@@ -273,6 +247,7 @@ declare function getPsbtTxInputs(psbtTx: btc.Transaction): TransactionInput[];
273
247
  declare function getPsbtTxOutputs(psbtTx: btc.Transaction): TransactionOutput[];
274
248
  declare function inferNetworkFromAddress(address: string): BitcoinNetworkModes;
275
249
  declare function inferPaymentTypeFromAddress(address: string): SupportedPaymentType;
250
+ declare function getBitcoinInputValue(input: TransactionInput): number;
276
251
 
277
252
  type AllowedSighashTypes = SignatureHash | SigHash;
278
253
  interface BitcoinAccountKeychain {
@@ -378,6 +353,33 @@ declare function serializeKeyOrigin({ fingerprint, path }: BtcSignerDerivationPa
378
353
  */
379
354
  declare function extractRequiredKeyOrigins(derivation: BtcSignerBip32Derivation[]): string[];
380
355
 
356
+ interface GenerateBitcoinUnsignedTransactionArgs {
357
+ feeRate: number;
358
+ isSendingMax?: boolean;
359
+ payerAddress: string;
360
+ payerPublicKey: string;
361
+ bip32Derivation: BtcSignerDefaultBip32Derivation[];
362
+ network: BtcSignerNetwork;
363
+ recipients: CoinSelectionRecipient[];
364
+ utxos: CoinSelectionUtxo[];
365
+ }
366
+ declare function generateBitcoinUnsignedTransactionNativeSegwit({ feeRate, isSendingMax, payerAddress, payerPublicKey, bip32Derivation, network, recipients, utxos, }: GenerateBitcoinUnsignedTransactionArgs): Promise<{
367
+ tx: btc.Transaction;
368
+ hex: string;
369
+ psbt: Uint8Array;
370
+ inputs: CoinSelectionUtxo[];
371
+ fee: _leather_io_models.Money;
372
+ } | null>;
373
+
374
+ declare enum BitcoinErrorMessage {
375
+ InsufficientFunds = "Insufficient funds",
376
+ NoInputsToSign = "No inputs to sign",
377
+ NoOutputsToSign = "No outputs to sign"
378
+ }
379
+ declare class BitcoinError extends Error {
380
+ constructor(message: string);
381
+ }
382
+
381
383
  declare function makeTaprootAccountDerivationPath(network: BitcoinNetworkModes, accountIndex: number): string;
382
384
  /** @deprecated Use makeTaprootAccountDerivationPath */
383
385
  declare const getTaprootAccountDerivationPath: typeof makeTaprootAccountDerivationPath;
@@ -445,4 +447,74 @@ declare function lookupDerivationByAddress(args: LookUpDerivationByAddressArgs):
445
447
  readonly path?: undefined;
446
448
  };
447
449
 
448
- export { type AllowedSighashTypes, type BitcoinAccount, type BitcoinAccountKeychain, BitcoinError, BitcoinErrorMessage, type BitcoinFees, type BitcoinNativeSegwitPayer, type BitcoinPayer, type BitcoinPayerBase, type BitcoinPayerInfo, type BitcoinSigner, type BitcoinTaprootPayer, type BtcSignerDefaultBip32Derivation, type BtcSignerLibPaymentTypeIdentifers, type BtcSignerNetwork, type BtcSignerTapBip32Derivation, type CoinSelectionOutput, type CoinSelectionRecipient, type CoinSelectionUtxo, type DetermineUtxosForSpendArgs, type GenerateBitcoinUnsignedTransactionArgs, type GetBitcoinFeesArgs, type PaymentTypeMap, type SupportedPaymentType, type SupportedPaymentTypeMap, type WithDerivePayer, bip322TransactionToSignValues, bitcoinNetworkModeToCoreNetworkMode, bitcoinNetworkToCoreNetworkMap, btcSignerLibPaymentTypeToPaymentTypeMap, calculateMaxBitcoinSpend, coinTypeMap, createNativeSegwitBitcoinJsSigner, createTaprootBitcoinJsSigner, createToSpendTx, createWalletIdDecoratedPath, decodeBitcoinTx, decodeCompressedWifPrivateKey, deriveAddressIndexKeychainFromAccount, deriveAddressIndexZeroFromAccount, deriveBitcoinPayerFromAccount, deriveBtcBip49SeedFromMnemonic, deriveNativeSegwitAccountFromRootKeychain, deriveNativeSegwitReceiveAddressIndexZero, deriveRootBtcKeychain, deriveTaprootAccount, deriveTaprootReceiveAddressIndexZero, determineUtxosForSpend, determineUtxosForSpendAll, ecPairFromPrivateKey, ecdsaPublicKeyLength, ecdsaPublicKeyToSchnorr, encodeMessageWitnessData, extractExtendedPublicKeyFromPolicy, extractRequiredKeyOrigins, filterUneconomicalUtxos, generateBitcoinUnsignedTransactionNativeSegwit, getAddressFromOutScript, getBitcoinCoinTypeIndexByNetwork, getBitcoinFees, getBitcoinInputAddress, getBitcoinJsLibNetworkConfigByMode, getBitcoinTransactionFee, getBtcSignerLibNetworkConfigByMode, getHdKeyVersionsFromNetwork, getInputPaymentType, getNativeSegwitAccountDerivationPath, getNativeSegwitAddress, getNativeSegwitAddressIndexDerivationPath, getNativeSegwitPaymentFromAddressIndex, getPsbtTxInputs, getPsbtTxOutputs, getSizeInfo, getSpendableAmount, getTaprootAccountDerivationPath, getTaprootAddress, getTaprootAddressIndexDerivationPath, getTaprootPayment, getTaprootPaymentFromAddressIndex, getUtxoTotal, hashBip322Message, inferNetworkFromAddress, inferNetworkFromPath, inferPaymentTypeFromAddress, inferPaymentTypeFromPath, initBitcoinAccount, initializeBitcoinAccountKeychainFromDescriptor, isBtcSignerLibPaymentType, isSupportedMessageSigningPaymentType, lookUpLedgerKeysByPath, lookupDerivationByAddress, makeNativeSegwitAccountDerivationPath, makeNativeSegwitAddressIndexDerivationPath, makePayToScriptHashAddress, makePayToScriptHashAddressBytes, makePayToScriptHashKeyHash, makeTaprootAccountDerivationPath, makeTaprootAddressIndexDerivationPath, mnemonicToRootNode, parseKnownPaymentType, payToScriptHashTestnetPrefix, payerToBip32Derivation, payerToTapBip32Derivation, paymentTypeMap, publicKeyToPayToScriptHashAddress, serializeKeyOrigin, signBip322MessageSimple, toXOnly, tweakSigner, whenBitcoinNetwork, whenPaymentType, whenSupportedPaymentType };
450
+ interface PsbtInput {
451
+ address: string;
452
+ index?: number;
453
+ inscription?: Inscription;
454
+ isMutable: boolean;
455
+ toSign: boolean;
456
+ txid: string;
457
+ value: number;
458
+ bip32Derivation: TransactionInput['bip32Derivation'];
459
+ tapBip32Derivation: TransactionInput['tapBip32Derivation'];
460
+ }
461
+ interface GetParsedInputsArgs {
462
+ inputs: TransactionInput[];
463
+ indexesToSign?: number[];
464
+ networkMode: BitcoinNetworkModes;
465
+ psbtAddresses: string[];
466
+ }
467
+ interface GetParsedInputsResponse {
468
+ isPsbtMutable: boolean;
469
+ parsedInputs: PsbtInput[];
470
+ }
471
+ declare function getParsedInputs({ inputs, indexesToSign, networkMode, psbtAddresses, }: GetParsedInputsArgs): GetParsedInputsResponse;
472
+
473
+ interface PsbtOutput {
474
+ address: string;
475
+ isMutable: boolean;
476
+ toSign: boolean;
477
+ value: number;
478
+ }
479
+ interface GetParsedOutputsArgs {
480
+ isPsbtMutable: boolean;
481
+ outputs: TransactionOutput[];
482
+ networkMode: BitcoinNetworkModes;
483
+ psbtAddresses: string[];
484
+ }
485
+ declare function getParsedOutputs({ isPsbtMutable, outputs, networkMode, psbtAddresses, }: GetParsedOutputsArgs): PsbtOutput[];
486
+
487
+ interface GetPsbtTotalsProps {
488
+ psbtAddresses: string[];
489
+ parsedInputs: PsbtInput[];
490
+ parsedOutputs: PsbtOutput[];
491
+ }
492
+ declare function getPsbtTotals({ psbtAddresses, parsedInputs, parsedOutputs }: GetPsbtTotalsProps): {
493
+ inputsTotalNativeSegwit: _leather_io_models.Money;
494
+ inputsTotalTaproot: _leather_io_models.Money;
495
+ outputsTotalNativeSegwit: _leather_io_models.Money;
496
+ outputsTotalTaproot: _leather_io_models.Money;
497
+ psbtInputsTotal: _leather_io_models.Money;
498
+ psbtOutputsTotal: _leather_io_models.Money;
499
+ };
500
+
501
+ interface GetPsbtDetailsArgs {
502
+ psbtHex: string;
503
+ psbtAddresses: string[];
504
+ networkMode: BitcoinNetworkModes;
505
+ indexesToSign?: number[];
506
+ }
507
+ declare function getPsbtDetails({ psbtHex, networkMode, indexesToSign, psbtAddresses, }: GetPsbtDetailsArgs): {
508
+ addressNativeSegwitTotal: _leather_io_models.Money;
509
+ addressTaprootTotal: _leather_io_models.Money;
510
+ fee: _leather_io_models.Money;
511
+ isPsbtMutable: boolean;
512
+ psbtInputs: PsbtInput[];
513
+ psbtOutputs: PsbtOutput[];
514
+ };
515
+
516
+ type RawPsbt = ReturnType<typeof RawPSBTV0.decode>;
517
+ declare function getPsbtAsTransaction(psbt: string | Uint8Array): btc.Transaction;
518
+ declare function getRawPsbt(psbt: string | Uint8Array): ReturnType<typeof RawPSBTV0.decode>;
519
+
520
+ export { type AllowedSighashTypes, type BitcoinAccount, type BitcoinAccountKeychain, BitcoinError, BitcoinErrorMessage, type BitcoinFees, type BitcoinNativeSegwitPayer, type BitcoinPayer, type BitcoinPayerBase, type BitcoinPayerInfo, type BitcoinSigner, type BitcoinTaprootPayer, type BtcSignerDefaultBip32Derivation, type BtcSignerLibPaymentTypeIdentifers, type BtcSignerNetwork, type BtcSignerTapBip32Derivation, type CoinSelectionOutput, type CoinSelectionRecipient, type CoinSelectionUtxo, type DetermineUtxosForSpendArgs, type GenerateBitcoinUnsignedTransactionArgs, type GetBitcoinFeesArgs, type PaymentTypeMap, type PsbtInput, type PsbtOutput, type RawPsbt, type SupportedPaymentType, type SupportedPaymentTypeMap, type WithDerivePayer, bip322TransactionToSignValues, bitcoinNetworkModeToCoreNetworkMode, bitcoinNetworkToCoreNetworkMap, btcSignerLibPaymentTypeToPaymentTypeMap, calculateMaxBitcoinSpend, coinTypeMap, createNativeSegwitBitcoinJsSigner, createTaprootBitcoinJsSigner, createToSpendTx, createWalletIdDecoratedPath, decodeBitcoinTx, decodeCompressedWifPrivateKey, deriveAddressIndexKeychainFromAccount, deriveAddressIndexZeroFromAccount, deriveBitcoinPayerFromAccount, deriveBtcBip49SeedFromMnemonic, deriveNativeSegwitAccountFromRootKeychain, deriveNativeSegwitReceiveAddressIndexZero, deriveRootBtcKeychain, deriveTaprootAccount, deriveTaprootReceiveAddressIndexZero, determineUtxosForSpend, determineUtxosForSpendAll, ecPairFromPrivateKey, ecdsaPublicKeyLength, ecdsaPublicKeyToSchnorr, encodeMessageWitnessData, extractExtendedPublicKeyFromPolicy, extractRequiredKeyOrigins, filterUneconomicalUtxos, generateBitcoinUnsignedTransactionNativeSegwit, getAddressFromOutScript, getBitcoinCoinTypeIndexByNetwork, getBitcoinFees, getBitcoinInputAddress, getBitcoinInputValue, getBitcoinJsLibNetworkConfigByMode, getBitcoinTransactionFee, getBtcSignerLibNetworkConfigByMode, getHdKeyVersionsFromNetwork, getInputPaymentType, getNativeSegwitAccountDerivationPath, getNativeSegwitAddress, getNativeSegwitAddressIndexDerivationPath, getNativeSegwitPaymentFromAddressIndex, getParsedInputs, getParsedOutputs, getPsbtAsTransaction, getPsbtDetails, getPsbtTotals, getPsbtTxInputs, getPsbtTxOutputs, getRawPsbt, getSizeInfo, getSpendableAmount, getTaprootAccountDerivationPath, getTaprootAddress, getTaprootAddressIndexDerivationPath, getTaprootPayment, getTaprootPaymentFromAddressIndex, getUtxoTotal, hashBip322Message, inferNetworkFromAddress, inferNetworkFromPath, inferPaymentTypeFromAddress, inferPaymentTypeFromPath, initBitcoinAccount, initializeBitcoinAccountKeychainFromDescriptor, isBtcSignerLibPaymentType, isSupportedMessageSigningPaymentType, lookUpLedgerKeysByPath, lookupDerivationByAddress, makeNativeSegwitAccountDerivationPath, makeNativeSegwitAddressIndexDerivationPath, makePayToScriptHashAddress, makePayToScriptHashAddressBytes, makePayToScriptHashKeyHash, makeTaprootAccountDerivationPath, makeTaprootAddressIndexDerivationPath, mnemonicToRootNode, parseKnownPaymentType, payToScriptHashTestnetPrefix, payerToBip32Derivation, payerToTapBip32Derivation, paymentTypeMap, publicKeyToPayToScriptHashAddress, serializeKeyOrigin, signBip322MessageSimple, toXOnly, tweakSigner, whenBitcoinNetwork, whenPaymentType, whenSupportedPaymentType };
package/dist/index.js CHANGED
@@ -353,6 +353,12 @@ function inferPaymentTypeFromAddress(address2) {
353
353
  return "p2tr";
354
354
  throw new Error("Unable to infer payment type from address");
355
355
  }
356
+ function getBitcoinInputValue(input) {
357
+ if (isDefined(input.witnessUtxo)) return Number(input.witnessUtxo.amount);
358
+ if (isDefined(input.nonWitnessUtxo) && isDefined(input.index))
359
+ return Number(input.nonWitnessUtxo.outputs[input.index]?.amount);
360
+ return 0;
361
+ }
356
362
 
357
363
  // src/bip322/bip322-utils.ts
358
364
  var bip322MessageTag = "BIP0322-signed-message";
@@ -964,6 +970,7 @@ async function generateBitcoinUnsignedTransactionNativeSegwit({
964
970
  isSendingMax,
965
971
  payerAddress,
966
972
  payerPublicKey,
973
+ bip32Derivation,
967
974
  network,
968
975
  recipients,
969
976
  utxos
@@ -980,6 +987,7 @@ async function generateBitcoinUnsignedTransactionNativeSegwit({
980
987
  txid: input.txid,
981
988
  index: input.vout,
982
989
  sequence: 0,
990
+ bip32Derivation,
983
991
  witnessUtxo: {
984
992
  // script = 0014 + pubKeyHash
985
993
  script: p2wpkh3.script,
@@ -1173,6 +1181,169 @@ function lookupDerivationByAddress(args) {
1173
1181
  return { status: "failure" };
1174
1182
  };
1175
1183
  }
1184
+
1185
+ // src/psbt/psbt-totals.ts
1186
+ import { createMoney as createMoney3, sumNumbers as sumNumbers2 } from "@leather.io/utils";
1187
+ function calculateAddressInputsTotal(addresses, inputs) {
1188
+ const sumsByAddress = addresses.map(
1189
+ (address2) => inputs.filter((input) => input.address === address2).map((input) => input.value).reduce((acc, curVal) => acc + curVal, 0)
1190
+ );
1191
+ return createMoney3(sumNumbers2(sumsByAddress), "BTC");
1192
+ }
1193
+ function calculateAddressOutputsTotal(addresses, outputs) {
1194
+ const sumsByAddress = addresses.map(
1195
+ (address2) => outputs.filter((output) => output.address === address2).map((output) => Number(output.value)).reduce((acc, curVal) => acc + curVal, 0)
1196
+ );
1197
+ return createMoney3(sumNumbers2(sumsByAddress), "BTC");
1198
+ }
1199
+ function calculatePsbtInputsTotal(inputs) {
1200
+ return createMoney3(sumNumbers2(inputs.map((input) => input.value)), "BTC");
1201
+ }
1202
+ function calculatePsbtOutputsTotal(outputs) {
1203
+ return createMoney3(sumNumbers2(outputs.map((output) => output.value)), "BTC");
1204
+ }
1205
+ function getPsbtTotals({ psbtAddresses, parsedInputs, parsedOutputs }) {
1206
+ const nativeSegwitAddresses = psbtAddresses.filter(
1207
+ (addr) => inferPaymentTypeFromAddress(addr) === "p2wpkh"
1208
+ );
1209
+ const taprootAddresses = psbtAddresses.filter(
1210
+ (addr) => inferPaymentTypeFromAddress(addr) === "p2tr"
1211
+ );
1212
+ return {
1213
+ inputsTotalNativeSegwit: calculateAddressInputsTotal(nativeSegwitAddresses, parsedInputs),
1214
+ inputsTotalTaproot: calculateAddressInputsTotal(taprootAddresses, parsedInputs),
1215
+ outputsTotalNativeSegwit: calculateAddressOutputsTotal(nativeSegwitAddresses, parsedOutputs),
1216
+ outputsTotalTaproot: calculateAddressOutputsTotal(taprootAddresses, parsedOutputs),
1217
+ psbtInputsTotal: calculatePsbtInputsTotal(parsedInputs),
1218
+ psbtOutputsTotal: calculatePsbtOutputsTotal(parsedOutputs)
1219
+ };
1220
+ }
1221
+
1222
+ // src/psbt/psbt-inputs.ts
1223
+ import { bytesToHex } from "@stacks/common";
1224
+ import { isDefined as isDefined2, isUndefined } from "@leather.io/utils";
1225
+ function getParsedInputs({
1226
+ inputs,
1227
+ indexesToSign,
1228
+ networkMode,
1229
+ psbtAddresses
1230
+ }) {
1231
+ const bitcoinNetwork = getBtcSignerLibNetworkConfigByMode(networkMode);
1232
+ const signAll = isUndefined(indexesToSign);
1233
+ const psbtInputs = inputs.map((input, i) => {
1234
+ const inputAddress = isDefined2(input.index) ? getBitcoinInputAddress(input, bitcoinNetwork) : "";
1235
+ const isCurrentAddress = psbtAddresses.includes(inputAddress);
1236
+ const canChange = isCurrentAddress && !(!input.sighashType || input.sighashType === 0 || input.sighashType === 1);
1237
+ const toSignAll = isCurrentAddress && signAll;
1238
+ const toSignIndex = isCurrentAddress && !signAll && indexesToSign.includes(i);
1239
+ return {
1240
+ address: inputAddress,
1241
+ index: input.index,
1242
+ bip32Derivation: input.bip32Derivation,
1243
+ tapBip32Derivation: input.tapBip32Derivation,
1244
+ // inscription: inscriptions[i],
1245
+ isMutable: canChange,
1246
+ toSign: toSignAll || toSignIndex,
1247
+ txid: input.txid ? bytesToHex(input.txid) : "",
1248
+ value: isDefined2(input.index) ? getBitcoinInputValue(input) : 0
1249
+ };
1250
+ });
1251
+ const isPsbtMutable = psbtInputs.some((input) => input.isMutable);
1252
+ return { isPsbtMutable, parsedInputs: psbtInputs };
1253
+ }
1254
+
1255
+ // src/psbt/psbt-outputs.ts
1256
+ import { isDefined as isDefined3, isUndefined as isUndefined2 } from "@leather.io/utils";
1257
+ function getParsedOutputs({
1258
+ isPsbtMutable,
1259
+ outputs,
1260
+ networkMode,
1261
+ psbtAddresses
1262
+ }) {
1263
+ const bitcoinNetwork = getBtcSignerLibNetworkConfigByMode(networkMode);
1264
+ return outputs.map((output) => {
1265
+ if (isUndefined2(output.script)) {
1266
+ return;
1267
+ }
1268
+ const outputAddress = getAddressFromOutScript(output.script, bitcoinNetwork);
1269
+ const isCurrentAddress = psbtAddresses.includes(outputAddress);
1270
+ return {
1271
+ address: outputAddress,
1272
+ isMutable: isPsbtMutable,
1273
+ toSign: isCurrentAddress,
1274
+ value: Number(output.amount)
1275
+ };
1276
+ }).filter(isDefined3);
1277
+ }
1278
+
1279
+ // src/psbt/psbt-details.ts
1280
+ import { createMoney as createMoney4, subtractMoney } from "@leather.io/utils";
1281
+
1282
+ // src/psbt/utils.ts
1283
+ import { hexToBytes as hexToBytes4 } from "@noble/hashes/utils";
1284
+ import * as btc6 from "@scure/btc-signer";
1285
+ import { RawPSBTV0, RawPSBTV2 } from "@scure/btc-signer/psbt";
1286
+ import { isString as isString2 } from "@leather.io/utils";
1287
+ function getPsbtAsTransaction(psbt) {
1288
+ const bytes = isString2(psbt) ? hexToBytes4(psbt) : psbt;
1289
+ return btc6.Transaction.fromPSBT(bytes);
1290
+ }
1291
+ function getRawPsbt(psbt) {
1292
+ const bytes = isString2(psbt) ? hexToBytes4(psbt) : psbt;
1293
+ try {
1294
+ return RawPSBTV0.decode(bytes);
1295
+ } catch (e1) {
1296
+ try {
1297
+ return RawPSBTV2.decode(bytes);
1298
+ } catch (e2) {
1299
+ throw new Error(`Unable to decode PSBT, ${e1 ?? e2}`);
1300
+ }
1301
+ }
1302
+ }
1303
+
1304
+ // src/psbt/psbt-details.ts
1305
+ function getPsbtDetails({
1306
+ psbtHex,
1307
+ networkMode,
1308
+ indexesToSign,
1309
+ psbtAddresses
1310
+ }) {
1311
+ const tx = getPsbtAsTransaction(psbtHex);
1312
+ const inputs = getPsbtTxInputs(tx);
1313
+ const outputs = getPsbtTxOutputs(tx);
1314
+ const { isPsbtMutable, parsedInputs } = getParsedInputs({
1315
+ inputs,
1316
+ indexesToSign,
1317
+ networkMode,
1318
+ psbtAddresses
1319
+ });
1320
+ const parsedOutputs = getParsedOutputs({ isPsbtMutable, outputs, networkMode, psbtAddresses });
1321
+ const {
1322
+ inputsTotalNativeSegwit,
1323
+ inputsTotalTaproot,
1324
+ outputsTotalNativeSegwit,
1325
+ outputsTotalTaproot,
1326
+ psbtInputsTotal,
1327
+ psbtOutputsTotal
1328
+ } = getPsbtTotals({
1329
+ psbtAddresses,
1330
+ parsedInputs,
1331
+ parsedOutputs
1332
+ });
1333
+ function getFee() {
1334
+ if (psbtInputsTotal.amount.isGreaterThan(psbtOutputsTotal.amount))
1335
+ return subtractMoney(psbtInputsTotal, psbtOutputsTotal);
1336
+ return createMoney4(0, "BTC");
1337
+ }
1338
+ return {
1339
+ addressNativeSegwitTotal: subtractMoney(inputsTotalNativeSegwit, outputsTotalNativeSegwit),
1340
+ addressTaprootTotal: subtractMoney(inputsTotalTaproot, outputsTotalTaproot),
1341
+ fee: getFee(),
1342
+ isPsbtMutable,
1343
+ psbtInputs: parsedInputs,
1344
+ psbtOutputs: parsedOutputs
1345
+ };
1346
+ }
1176
1347
  export {
1177
1348
  BitcoinError,
1178
1349
  BitcoinErrorMessage,
@@ -1211,6 +1382,7 @@ export {
1211
1382
  getBitcoinCoinTypeIndexByNetwork,
1212
1383
  getBitcoinFees,
1213
1384
  getBitcoinInputAddress,
1385
+ getBitcoinInputValue,
1214
1386
  getBitcoinJsLibNetworkConfigByMode,
1215
1387
  getBitcoinTransactionFee,
1216
1388
  getBtcSignerLibNetworkConfigByMode,
@@ -1220,8 +1392,14 @@ export {
1220
1392
  getNativeSegwitAddress,
1221
1393
  getNativeSegwitAddressIndexDerivationPath,
1222
1394
  getNativeSegwitPaymentFromAddressIndex,
1395
+ getParsedInputs,
1396
+ getParsedOutputs,
1397
+ getPsbtAsTransaction,
1398
+ getPsbtDetails,
1399
+ getPsbtTotals,
1223
1400
  getPsbtTxInputs,
1224
1401
  getPsbtTxOutputs,
1402
+ getRawPsbt,
1225
1403
  getSizeInfo,
1226
1404
  getSpendableAmount,
1227
1405
  getTaprootAccountDerivationPath,