@btc-vision/transaction 1.1.1 → 1.1.2

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.
@@ -47,7 +47,7 @@ export declare abstract class TweakedTransaction extends Logger {
47
47
  protected generateTapData(): Payment;
48
48
  protected generateScriptAddress(): Payment;
49
49
  protected getSignerKey(): Signer | ECPairInterface;
50
- protected signInput(transaction: Psbt, _input: PsbtInput, i: number, signer: Signer | ECPairInterface): Promise<void>;
50
+ protected signInput(transaction: Psbt, input: PsbtInput, i: number, signer: Signer | ECPairInterface): Promise<void>;
51
51
  protected splitArray<T>(arr: T[], chunkSize: number): T[][];
52
52
  protected signInputs(transaction: Psbt): Promise<void>;
53
53
  protected internalPubKeyToXOnly(): Buffer;
@@ -64,4 +64,12 @@ export declare abstract class TweakedTransaction extends Logger {
64
64
  finalScriptSig: Buffer | undefined;
65
65
  finalScriptWitness: Buffer | undefined;
66
66
  };
67
+ private isTaprootScriptSpend;
68
+ private isTaprootInput;
69
+ private canSignNonTaprootInput;
70
+ private getInputRelevantScript;
71
+ private pubkeyInScript;
72
+ private pubkeyPositionInScript;
73
+ private signTaprootInput;
74
+ private signNonTaprootInput;
67
75
  }
@@ -1 +1 @@
1
- export declare const version = "1.1.1";
1
+ export declare const version = "1.1.2";
package/build/_version.js CHANGED
@@ -1 +1 @@
1
- export const version = '1.1.1';
1
+ export const version = '1.1.2';
@@ -47,7 +47,7 @@ export declare abstract class TweakedTransaction extends Logger {
47
47
  protected generateTapData(): Payment;
48
48
  protected generateScriptAddress(): Payment;
49
49
  protected getSignerKey(): Signer | ECPairInterface;
50
- protected signInput(transaction: Psbt, _input: PsbtInput, i: number, signer: Signer | ECPairInterface): Promise<void>;
50
+ protected signInput(transaction: Psbt, input: PsbtInput, i: number, signer: Signer | ECPairInterface): Promise<void>;
51
51
  protected splitArray<T>(arr: T[], chunkSize: number): T[][];
52
52
  protected signInputs(transaction: Psbt): Promise<void>;
53
53
  protected internalPubKeyToXOnly(): Buffer;
@@ -64,4 +64,12 @@ export declare abstract class TweakedTransaction extends Logger {
64
64
  finalScriptSig: Buffer | undefined;
65
65
  finalScriptWitness: Buffer | undefined;
66
66
  };
67
+ private isTaprootScriptSpend;
68
+ private isTaprootInput;
69
+ private canSignNonTaprootInput;
70
+ private getInputRelevantScript;
71
+ private pubkeyInScript;
72
+ private pubkeyPositionInScript;
73
+ private signTaprootInput;
74
+ private signNonTaprootInput;
67
75
  }
@@ -4,6 +4,7 @@ import { TweakedSigner } from '../../signer/TweakedSigner.js';
4
4
  import { toXOnly } from '@btc-vision/bitcoin/src/psbt/bip371.js';
5
5
  import { AddressTypes, AddressVerificator } from '../../keypair/AddressVerificator.js';
6
6
  import { varuint } from '@btc-vision/bitcoin/src/bufferutils.js';
7
+ import * as bscript from '@btc-vision/bitcoin/src/script.js';
7
8
  export var TransactionSequence;
8
9
  (function (TransactionSequence) {
9
10
  TransactionSequence[TransactionSequence["REPLACE_BY_FEE"] = 4294967293] = "REPLACE_BY_FEE";
@@ -27,10 +28,7 @@ export class TweakedTransaction extends Logger {
27
28
  const inputDecoded = this.inputs[inputIndex];
28
29
  if (isP2SH && input.partialSig && inputDecoded && inputDecoded.redeemScript) {
29
30
  const signatures = input.partialSig.map((sig) => sig.signature);
30
- const scriptSig = script.compile([
31
- ...signatures,
32
- inputDecoded.redeemScript,
33
- ]);
31
+ const scriptSig = script.compile([...signatures, inputDecoded.redeemScript]);
34
32
  return {
35
33
  finalScriptSig: scriptSig,
36
34
  finalScriptWitness: undefined,
@@ -156,24 +154,59 @@ export class TweakedTransaction extends Logger {
156
154
  getSignerKey() {
157
155
  return this.signer;
158
156
  }
159
- async signInput(transaction, _input, i, signer) {
160
- try {
161
- if ('signInput' in signer) {
162
- return await signer.signInput(transaction, i);
157
+ async signInput(transaction, input, i, signer) {
158
+ const publicKey = signer.publicKey;
159
+ const isTaproot = this.isTaprootInput(input);
160
+ let signed = false;
161
+ if (isTaproot) {
162
+ const isScriptSpend = this.isTaprootScriptSpend(input, publicKey);
163
+ if (isScriptSpend) {
164
+ try {
165
+ await this.signTaprootInput(signer, transaction, i);
166
+ signed = true;
167
+ }
168
+ catch (e) {
169
+ this.error(`Failed to sign Taproot script path input ${i}: ${e}`);
170
+ }
163
171
  }
164
- transaction.signInput(i, signer);
165
- }
166
- catch {
167
- try {
168
- if ('signTaprootInput' in signer) {
169
- return await signer.signTaprootInput(transaction, i);
172
+ else {
173
+ let tweakedSigner;
174
+ if (signer !== this.signer) {
175
+ tweakedSigner = this.getTweakedSigner(true, signer);
176
+ }
177
+ else {
178
+ if (!this.tweakedSigner)
179
+ this.tweakSigner();
180
+ tweakedSigner = this.tweakedSigner;
181
+ }
182
+ if (tweakedSigner) {
183
+ try {
184
+ await this.signTaprootInput(tweakedSigner, transaction, i);
185
+ signed = true;
186
+ }
187
+ catch (e) {
188
+ this.error(`Failed to sign Taproot key path input ${i}: ${e}`);
189
+ }
190
+ }
191
+ else {
192
+ this.error(`Failed to obtain tweaked signer for input ${i}.`);
170
193
  }
171
- transaction.signTaprootInput(i, signer);
172
194
  }
173
- catch {
174
- throw new Error('Failed to sign input');
195
+ }
196
+ else {
197
+ if (this.canSignNonTaprootInput(input, publicKey)) {
198
+ try {
199
+ await this.signNonTaprootInput(signer, transaction, i);
200
+ signed = true;
201
+ }
202
+ catch (e) {
203
+ this.error(`Failed to sign non-Taproot input ${i}: ${e}`);
204
+ }
175
205
  }
176
206
  }
207
+ if (!signed) {
208
+ throw new Error(`Cannot sign input ${i} with the provided signer.`);
209
+ }
177
210
  }
178
211
  splitArray(arr, chunkSize) {
179
212
  if (chunkSize <= 0) {
@@ -332,7 +365,6 @@ export class TweakedTransaction extends Logger {
332
365
  }
333
366
  if (i === 0 && this.nonWitnessUtxo) {
334
367
  input.nonWitnessUtxo = this.nonWitnessUtxo;
335
- this.log(`Using non-witness utxo for input ${i}`);
336
368
  }
337
369
  if (utxo.scriptPubKey.address &&
338
370
  AddressVerificator.isValidP2TRAddress(utxo.scriptPubKey.address, this.network)) {
@@ -341,4 +373,77 @@ export class TweakedTransaction extends Logger {
341
373
  }
342
374
  return input;
343
375
  }
376
+ isTaprootScriptSpend(input, publicKey) {
377
+ if (input.tapLeafScript && input.tapLeafScript.length > 0) {
378
+ for (const tapLeafScript of input.tapLeafScript) {
379
+ if (this.pubkeyInScript(publicKey, tapLeafScript.script)) {
380
+ return true;
381
+ }
382
+ }
383
+ }
384
+ return false;
385
+ }
386
+ isTaprootInput(input) {
387
+ if (input.tapInternalKey || input.tapKeySig || input.tapScriptSig || input.tapLeafScript) {
388
+ return true;
389
+ }
390
+ if (input.witnessUtxo) {
391
+ const script = input.witnessUtxo.script;
392
+ return script.length === 34 && script[0] === opcodes.OP_1 && script[1] === 0x20;
393
+ }
394
+ return false;
395
+ }
396
+ canSignNonTaprootInput(input, publicKey) {
397
+ const script = this.getInputRelevantScript(input);
398
+ if (script) {
399
+ return this.pubkeyInScript(publicKey, script);
400
+ }
401
+ return false;
402
+ }
403
+ getInputRelevantScript(input) {
404
+ if (input.redeemScript) {
405
+ return input.redeemScript;
406
+ }
407
+ if (input.witnessScript) {
408
+ return input.witnessScript;
409
+ }
410
+ if (input.witnessUtxo) {
411
+ return input.witnessUtxo.script;
412
+ }
413
+ if (input.nonWitnessUtxo) {
414
+ return null;
415
+ }
416
+ return null;
417
+ }
418
+ pubkeyInScript(pubkey, script) {
419
+ return this.pubkeyPositionInScript(pubkey, script) !== -1;
420
+ }
421
+ pubkeyPositionInScript(pubkey, script) {
422
+ const pubkeyHash = bitCrypto.hash160(pubkey);
423
+ const pubkeyXOnly = toXOnly(pubkey);
424
+ const decompiled = bscript.decompile(script);
425
+ if (decompiled === null)
426
+ throw new Error('Unknown script error');
427
+ return decompiled.findIndex((element) => {
428
+ if (typeof element === 'number')
429
+ return false;
430
+ return (element.equals(pubkey) || element.equals(pubkeyHash) || element.equals(pubkeyXOnly));
431
+ });
432
+ }
433
+ async signTaprootInput(signer, transaction, i, tapLeafHash) {
434
+ if ('signTaprootInput' in signer) {
435
+ await signer.signTaprootInput(transaction, i, tapLeafHash);
436
+ }
437
+ else {
438
+ transaction.signTaprootInput(i, signer);
439
+ }
440
+ }
441
+ async signNonTaprootInput(signer, transaction, i) {
442
+ if ('signInput' in signer) {
443
+ await signer.signInput(transaction, i);
444
+ }
445
+ else {
446
+ transaction.signInput(i, signer);
447
+ }
448
+ }
344
449
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@btc-vision/transaction",
3
3
  "type": "module",
4
- "version": "1.1.1",
4
+ "version": "1.1.2",
5
5
  "author": "BlobMaster41",
6
6
  "description": "OPNet transaction library allows you to create and sign transactions for the OPNet network.",
7
7
  "engines": {
@@ -63,6 +63,9 @@
63
63
  "browserBuild": "webpack --mode production",
64
64
  "docs": "typedoc --out docs --exclude 'src/tests/*.ts' --tsconfig tsconfig.json --readme README.md --name OPNet --plugin typedoc-material-theme --themeColor '#cb9820' --exclude src/tests/test.ts --exclude src/index.ts src"
65
65
  },
66
+ "peerDependencies": {
67
+ "@btc-vision/bitcoin": "^6.3.0"
68
+ },
66
69
  "devDependencies": {
67
70
  "@babel/core": "^7.26.0",
68
71
  "@babel/plugin-proposal-class-properties": "^7.18.6",
package/src/_version.ts CHANGED
@@ -1 +1 @@
1
- export const version = '1.1.1';
1
+ export const version = '1.1.2';
@@ -14,6 +14,7 @@ import {
14
14
  Signer,
15
15
  Transaction,
16
16
  } from '@btc-vision/bitcoin';
17
+
17
18
  import { TweakedSigner, TweakSettings } from '../../signer/TweakedSigner.js';
18
19
  import { ECPairInterface } from 'ecpair';
19
20
  import { toXOnly } from '@btc-vision/bitcoin/src/psbt/bip371.js';
@@ -22,6 +23,7 @@ import { TapLeafScript } from '../interfaces/Tap.js';
22
23
  import { AddressTypes, AddressVerificator } from '../../keypair/AddressVerificator.js';
23
24
  import { ChainId } from '../../network/ChainId.js';
24
25
  import { varuint } from '@btc-vision/bitcoin/src/bufferutils.js';
26
+ import * as bscript from '@btc-vision/bitcoin/src/script.js';
25
27
 
26
28
  export interface ITweakedTransactionData {
27
29
  readonly signer: Signer | ECPairInterface;
@@ -358,100 +360,67 @@ export abstract class TweakedTransaction extends Logger {
358
360
  /**
359
361
  * Signs an input of the transaction.
360
362
  * @param {Psbt} transaction - The transaction to sign
361
- * @param {PsbtInput} _input - The input to sign
363
+ * @param {PsbtInput} input - The input to sign
362
364
  * @param {number} i - The index of the input
363
365
  * @param {Signer} signer - The signer to use
364
366
  * @protected
365
367
  */
366
368
  protected async signInput(
367
369
  transaction: Psbt,
368
- _input: PsbtInput,
370
+ input: PsbtInput,
369
371
  i: number,
370
372
  signer: Signer | ECPairInterface,
371
373
  ): Promise<void> {
372
- try {
373
- if ('signInput' in signer) {
374
- // @ts-expect-error - we know it's a signer
375
- return await (signer.signInput(transaction, i) as Promise<void>);
376
- }
377
-
378
- transaction.signInput(i, signer);
379
- } catch {
380
- try {
381
- if ('signTaprootInput' in signer) {
382
- // @ts-expect-error - we know it's a taproot signer
383
- return await (signer.signTaprootInput(transaction, i) as Promise<void>);
384
- }
385
-
386
- transaction.signTaprootInput(i, signer);
387
- } catch {
388
- throw new Error('Failed to sign input');
389
- }
390
- }
391
-
392
- /*const signHash =
393
- this.sighashTypes && this.sighashTypes.length
394
- ? [TweakedTransaction.calculateSignHash(this.sighashTypes)]
395
- : undefined;
374
+ const publicKey = signer.publicKey;
375
+ const isTaproot = this.isTaprootInput(input);
396
376
 
397
- signer = signer || this.getSignerKey();
377
+ let signed = false;
398
378
 
399
- let testedTap: boolean = false;
400
- if (input.tapInternalKey) {
401
- if (!this.tweakedSigner) this.tweakSigner();
379
+ if (isTaproot) {
380
+ const isScriptSpend = this.isTaprootScriptSpend(input, publicKey);
402
381
 
403
- let tweakedSigner: ECPairInterface | undefined;
404
- if (signer !== this.signer) {
405
- tweakedSigner = this.getTweakedSigner(true, signer);
382
+ if (isScriptSpend) {
383
+ try {
384
+ await this.signTaprootInput(signer, transaction, i);
385
+ signed = true;
386
+ } catch (e) {
387
+ this.error(`Failed to sign Taproot script path input ${i}: ${e}`);
388
+ }
406
389
  } else {
407
- tweakedSigner = this.tweakedSigner;
408
- }
409
-
410
- if (tweakedSigner) {
411
- testedTap = true;
390
+ let tweakedSigner: ECPairInterface | undefined;
391
+ if (signer !== this.signer) {
392
+ tweakedSigner = this.getTweakedSigner(true, signer);
393
+ } else {
394
+ if (!this.tweakedSigner) this.tweakSigner();
395
+ tweakedSigner = this.tweakedSigner;
396
+ }
412
397
 
413
- try {
414
- if ('signTaprootInput' in signer) {
415
- // @ts-expect-error - we know it's a taproot signer
416
- return await (signer.signTaprootInput(
417
- transaction,
418
- i,
419
- signHash,
420
- ) as Promise<void>);
421
- } else {
422
- transaction.signTaprootInput(i, tweakedSigner, undefined, signHash);
398
+ if (tweakedSigner) {
399
+ try {
400
+ await this.signTaprootInput(tweakedSigner, transaction, i);
401
+ signed = true;
402
+ } catch (e) {
403
+ this.error(`Failed to sign Taproot key path input ${i}: ${e}`);
423
404
  }
424
-
425
- return;
426
- } catch {}
427
- }
428
- }
429
-
430
- try {
431
- if ('signInput' in signer) {
432
- // @ts-expect-error - we know it's a signer
433
- return await (signer.signInput(transaction, i, signHash) as Promise<void>);
434
- } else {
435
- transaction.signInput(i, signer, signHash);
436
- }
437
- } catch (e) {
438
- if (!testedTap) {
439
- // and we try again taproot...
440
-
441
- if ('signTaprootInput' in signer) {
442
- // @ts-expect-error - we know it's a taproot signer
443
- return await (signer.signTaprootInput(
444
- transaction,
445
- i,
446
- signHash,
447
- ) as Promise<void>);
448
- } else if (this.tweakedSigner) {
449
- transaction.signTaprootInput(i, this.tweakedSigner, undefined, signHash);
450
405
  } else {
451
- throw e;
406
+ this.error(`Failed to obtain tweaked signer for input ${i}.`);
407
+ }
408
+ }
409
+ } else {
410
+ // Non-Taproot input
411
+ if (this.canSignNonTaprootInput(input, publicKey)) {
412
+ try {
413
+ await this.signNonTaprootInput(signer, transaction, i);
414
+ signed = true;
415
+ } catch (e) {
416
+ this.error(`Failed to sign non-Taproot input ${i}: ${e}`);
452
417
  }
453
418
  }
454
- }*/
419
+ }
420
+
421
+ if (!signed) {
422
+ throw new Error(`Cannot sign input ${i} with the provided signer.`);
423
+ }
455
424
  }
456
425
 
457
426
  protected splitArray<T>(arr: T[], chunkSize: number): T[][] {
@@ -460,7 +429,6 @@ export abstract class TweakedTransaction extends Logger {
460
429
  }
461
430
 
462
431
  const result: T[][] = [];
463
-
464
432
  for (let i = 0; i < arr.length; i += chunkSize) {
465
433
  result.push(arr.slice(i, i + chunkSize));
466
434
  }
@@ -698,10 +666,9 @@ export abstract class TweakedTransaction extends Logger {
698
666
 
699
667
  if (i === 0 && this.nonWitnessUtxo) {
700
668
  input.nonWitnessUtxo = this.nonWitnessUtxo;
701
- this.log(`Using non-witness utxo for input ${i}`);
702
669
  }
703
670
 
704
- // automatically detect p2tr inputs.
671
+ // Automatically detect P2TR inputs.
705
672
  if (
706
673
  utxo.scriptPubKey.address &&
707
674
  AddressVerificator.isValidP2TRAddress(utxo.scriptPubKey.address, this.network)
@@ -715,11 +682,11 @@ export abstract class TweakedTransaction extends Logger {
715
682
  }
716
683
 
717
684
  protected customFinalizerP2SH = (
718
- inputIndex: number, // Which input is it?
719
- input: PsbtInput, // The PSBT input contents
720
- scriptA: Buffer, // The "meaningful" locking script Buffer (redeemScript for P2SH etc.)
721
- isSegwit: boolean, // Is it segwit?
722
- isP2SH: boolean, // Is it P2SH?
685
+ inputIndex: number,
686
+ input: PsbtInput,
687
+ scriptA: Buffer,
688
+ isSegwit: boolean,
689
+ isP2SH: boolean,
723
690
  isP2WSH: boolean,
724
691
  ): {
725
692
  finalScriptSig: Buffer | undefined;
@@ -728,31 +695,120 @@ export abstract class TweakedTransaction extends Logger {
728
695
  const inputDecoded = this.inputs[inputIndex];
729
696
  if (isP2SH && input.partialSig && inputDecoded && inputDecoded.redeemScript) {
730
697
  const signatures = input.partialSig.map((sig) => sig.signature);
731
-
732
- /*const fakeSignature = Buffer.from([
733
- 0x30,
734
- 0x45, // DER prefix: 0x30 (Compound), 0x45 (length = 69 bytes)
735
- 0x02,
736
- 0x20, // Integer marker: 0x02 (integer), 0x20 (length = 32 bytes)
737
- ...Buffer.alloc(32, 0x00), // 32-byte fake 'r' value (all zeros)
738
- 0x02,
739
- 0x21, // Integer marker: 0x02 (integer), 0x21 (length = 33 bytes)
740
- ...Buffer.alloc(33, 0x00), // 33-byte fake 's' value (all zeros)
741
- 0x01, // SIGHASH_ALL flag (0x01)
742
- ]);*/
743
-
744
- const scriptSig = script.compile([
745
- ...signatures,
746
- //fakeSignature,
747
- inputDecoded.redeemScript,
748
- ]);
698
+ const scriptSig = script.compile([...signatures, inputDecoded.redeemScript]);
749
699
 
750
700
  return {
751
- finalScriptSig: scriptSig, // Manually set the final scriptSig
752
- finalScriptWitness: undefined, // Manually set the final scriptWitness
701
+ finalScriptSig: scriptSig,
702
+ finalScriptWitness: undefined,
753
703
  };
754
704
  }
755
705
 
756
706
  return getFinalScripts(inputIndex, input, scriptA, isSegwit, isP2SH, isP2WSH);
757
707
  };
708
+
709
+ private isTaprootScriptSpend(input: PsbtInput, publicKey: Buffer): boolean {
710
+ if (input.tapLeafScript && input.tapLeafScript.length > 0) {
711
+ // Check if the signer's public key is involved in any tapLeafScript
712
+ for (const tapLeafScript of input.tapLeafScript) {
713
+ if (this.pubkeyInScript(publicKey, tapLeafScript.script)) {
714
+ // The public key is in the script; it's a script spend
715
+ return true;
716
+ }
717
+ }
718
+ }
719
+ return false;
720
+ }
721
+
722
+ // Helper method to determine if an input is Taproot
723
+ private isTaprootInput(input: PsbtInput): boolean {
724
+ if (input.tapInternalKey || input.tapKeySig || input.tapScriptSig || input.tapLeafScript) {
725
+ return true;
726
+ }
727
+
728
+ if (input.witnessUtxo) {
729
+ const script = input.witnessUtxo.script;
730
+ // Check if the script is a P2TR output (OP_1 [32-byte key])
731
+ return script.length === 34 && script[0] === opcodes.OP_1 && script[1] === 0x20;
732
+ }
733
+
734
+ return false;
735
+ }
736
+
737
+ // Check if the signer can sign the non-Taproot input
738
+ private canSignNonTaprootInput(input: PsbtInput, publicKey: Buffer): boolean {
739
+ const script = this.getInputRelevantScript(input);
740
+ if (script) {
741
+ return this.pubkeyInScript(publicKey, script);
742
+ }
743
+ return false;
744
+ }
745
+
746
+ // Helper method to extract the relevant script from the input
747
+ private getInputRelevantScript(input: PsbtInput): Buffer | null {
748
+ if (input.redeemScript) {
749
+ return input.redeemScript;
750
+ }
751
+ if (input.witnessScript) {
752
+ return input.witnessScript;
753
+ }
754
+ if (input.witnessUtxo) {
755
+ return input.witnessUtxo.script;
756
+ }
757
+ if (input.nonWitnessUtxo) {
758
+ // Additional logic can be added to extract script from nonWitnessUtxo
759
+ return null;
760
+ }
761
+ return null;
762
+ }
763
+
764
+ // Helper method to check if a public key is in a script
765
+ private pubkeyInScript(pubkey: Buffer, script: Buffer): boolean {
766
+ return this.pubkeyPositionInScript(pubkey, script) !== -1;
767
+ }
768
+
769
+ private pubkeyPositionInScript(pubkey: Buffer, script: Buffer): number {
770
+ const pubkeyHash = bitCrypto.hash160(pubkey);
771
+ const pubkeyXOnly = toXOnly(pubkey);
772
+
773
+ const decompiled = bscript.decompile(script);
774
+ if (decompiled === null) throw new Error('Unknown script error');
775
+
776
+ return decompiled.findIndex((element) => {
777
+ if (typeof element === 'number') return false;
778
+ return (
779
+ element.equals(pubkey) || element.equals(pubkeyHash) || element.equals(pubkeyXOnly)
780
+ );
781
+ });
782
+ }
783
+
784
+ private async signTaprootInput(
785
+ signer: Signer | ECPairInterface,
786
+ transaction: Psbt,
787
+ i: number,
788
+ tapLeafHash?: Buffer,
789
+ ): Promise<void> {
790
+ if ('signTaprootInput' in signer) {
791
+ await (
792
+ signer.signTaprootInput as (
793
+ tx: Psbt,
794
+ i: number,
795
+ tapLeafHash?: Buffer,
796
+ ) => Promise<void>
797
+ )(transaction, i, tapLeafHash);
798
+ } else {
799
+ transaction.signTaprootInput(i, signer); //tapLeafHash
800
+ }
801
+ }
802
+
803
+ private async signNonTaprootInput(
804
+ signer: Signer | ECPairInterface,
805
+ transaction: Psbt,
806
+ i: number,
807
+ ): Promise<void> {
808
+ if ('signInput' in signer) {
809
+ await (signer.signInput as (tx: Psbt, i: number) => Promise<void>)(transaction, i);
810
+ } else {
811
+ transaction.signInput(i, signer);
812
+ }
813
+ }
758
814
  }