@btc-vision/transaction 1.1.17 → 1.2.1

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.
Files changed (82) hide show
  1. package/browser/_version.d.ts +1 -1
  2. package/browser/crypto/crypto-browser.d.ts +2 -2
  3. package/browser/index.js +1 -1
  4. package/browser/index.js.LICENSE.txt +2 -0
  5. package/browser/keypair/Address.d.ts +8 -0
  6. package/browser/keypair/Secp256k1PointDeriver.d.ts +16 -0
  7. package/browser/opnet.d.ts +2 -0
  8. package/browser/signer/SignerUtils.d.ts +0 -1
  9. package/browser/transaction/ContractAddress.d.ts +6 -0
  10. package/browser/transaction/builders/CustomScriptTransaction.d.ts +1 -1
  11. package/browser/transaction/builders/InteractionTransaction.d.ts +1 -1
  12. package/browser/transaction/builders/MultiSignTransaction.d.ts +3 -4
  13. package/browser/transaction/builders/SharedInteractionTransaction.d.ts +2 -3
  14. package/browser/verification/TapscriptVerificator.d.ts +1 -2
  15. package/build/_version.d.ts +1 -1
  16. package/build/_version.js +1 -1
  17. package/build/buffer/BinaryReader.js +2 -2
  18. package/build/buffer/BinaryWriter.js +1 -1
  19. package/build/generators/AddressGenerator.js +1 -2
  20. package/build/generators/Generator.js +1 -2
  21. package/build/generators/builders/MultiSignGenerator.js +1 -2
  22. package/build/keypair/Address.d.ts +8 -0
  23. package/build/keypair/Address.js +67 -7
  24. package/build/keypair/AddressVerificator.js +5 -2
  25. package/build/keypair/EcKeyPair.js +3 -4
  26. package/build/keypair/MessageSigner.js +1 -2
  27. package/build/keypair/Secp256k1PointDeriver.d.ts +16 -0
  28. package/build/keypair/Secp256k1PointDeriver.js +80 -0
  29. package/build/keypair/Wallet.js +1 -2
  30. package/build/opnet.d.ts +2 -0
  31. package/build/opnet.js +2 -0
  32. package/build/signer/SignerUtils.d.ts +0 -1
  33. package/build/signer/SignerUtils.js +1 -17
  34. package/build/signer/TweakedSigner.js +1 -3
  35. package/build/transaction/ContractAddress.d.ts +6 -0
  36. package/build/transaction/ContractAddress.js +12 -0
  37. package/build/transaction/browser/extensions/UnisatSigner.js +1 -2
  38. package/build/transaction/browser/extensions/XverseSigner.js +1 -2
  39. package/build/transaction/builders/CustomScriptTransaction.d.ts +1 -1
  40. package/build/transaction/builders/CustomScriptTransaction.js +1 -2
  41. package/build/transaction/builders/DeploymentTransaction.js +2 -2
  42. package/build/transaction/builders/FundingTransaction.js +2 -2
  43. package/build/transaction/builders/InteractionTransaction.d.ts +1 -1
  44. package/build/transaction/builders/MultiSignTransaction.d.ts +3 -4
  45. package/build/transaction/builders/MultiSignTransaction.js +1 -2
  46. package/build/transaction/builders/SharedInteractionTransaction.d.ts +2 -3
  47. package/build/transaction/builders/SharedInteractionTransaction.js +1 -2
  48. package/build/transaction/builders/TransactionBuilder.js +11 -2
  49. package/build/transaction/shared/TweakedTransaction.js +1 -4
  50. package/build/utils/BufferHelper.js +1 -1
  51. package/build/verification/TapscriptVerificator.d.ts +1 -2
  52. package/build/verification/TapscriptVerificator.js +1 -2
  53. package/package.json +9 -9
  54. package/src/_version.ts +1 -1
  55. package/src/buffer/BinaryReader.ts +2 -2
  56. package/src/buffer/BinaryWriter.ts +1 -1
  57. package/src/generators/AddressGenerator.ts +1 -2
  58. package/src/generators/Generator.ts +1 -2
  59. package/src/generators/builders/MultiSignGenerator.ts +1 -2
  60. package/src/keypair/Address.ts +91 -10
  61. package/src/keypair/AddressVerificator.ts +6 -2
  62. package/src/keypair/EcKeyPair.ts +14 -5
  63. package/src/keypair/MessageSigner.ts +1 -2
  64. package/src/keypair/Secp256k1PointDeriver.ts +170 -0
  65. package/src/keypair/Wallet.ts +1 -2
  66. package/src/opnet.ts +2 -0
  67. package/src/signer/SignerUtils.ts +7 -19
  68. package/src/signer/TweakedSigner.ts +1 -3
  69. package/src/transaction/ContractAddress.ts +13 -0
  70. package/src/transaction/TransactionFactory.ts +4 -5
  71. package/src/transaction/browser/extensions/UnisatSigner.ts +1 -1
  72. package/src/transaction/browser/extensions/XverseSigner.ts +1 -2
  73. package/src/transaction/builders/CustomScriptTransaction.ts +10 -3
  74. package/src/transaction/builders/DeploymentTransaction.ts +13 -3
  75. package/src/transaction/builders/FundingTransaction.ts +2 -2
  76. package/src/transaction/builders/InteractionTransaction.ts +1 -1
  77. package/src/transaction/builders/MultiSignTransaction.ts +2 -2
  78. package/src/transaction/builders/SharedInteractionTransaction.ts +1 -3
  79. package/src/transaction/builders/TransactionBuilder.ts +11 -1
  80. package/src/transaction/shared/TweakedTransaction.ts +9 -93
  81. package/src/utils/BufferHelper.ts +1 -1
  82. package/src/verification/TapscriptVerificator.ts +9 -3
@@ -0,0 +1,170 @@
1
+ const P = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2fn;
2
+
3
+ export class Secp256k1PointDeriver {
4
+ /**
5
+ * The maximum increments to try before giving up on deriving a valid x.
6
+ */
7
+ private maxTries: number;
8
+
9
+ constructor(maxTries = 10000) {
10
+ this.maxTries = maxTries;
11
+ }
12
+
13
+ /**
14
+ * Main entry point.
15
+ * Given a 32-byte input, ensures we obtain a "real" x on secp256k1.
16
+ * - If the given x is valid, we use it.
17
+ * - Otherwise, we increment x (mod p) until we find one whose (x^3 + 7) is a quadratic residue.
18
+ * Then we return { x, y1, y2 } for that valid point.
19
+ *
20
+ * @param xBytes A 32-byte Uint8Array for the candidate x
21
+ * @param failOnInvalidX (optional) whether to throw if the given x is not a valid curve point, defaults to true
22
+ * @param maxTries (optional) number of increments to attempt, defaults to this.maxTries
23
+ * @returns An object { x: bigint; y1: bigint; y2: bigint } describing a valid curve point
24
+ * @throws If no valid x found within maxTries
25
+ */
26
+ public findOrDeriveValidPoint(
27
+ xBytes: Uint8Array,
28
+ failOnInvalidX: boolean = true,
29
+ maxTries: number = this.maxTries,
30
+ ): { x: bigint; y1: bigint; y2: bigint } {
31
+ if (xBytes.length !== 32) {
32
+ throw new Error('xBytes must be exactly 32 bytes.');
33
+ }
34
+
35
+ // Convert input to a BigInt in [0, p-1]
36
+ let xCandidate = this.bytesToBigInt(xBytes) % P;
37
+
38
+ // 2. Loop up to maxTries to find a valid x
39
+ let sqrtVal = this.isValidX(xCandidate);
40
+ if (failOnInvalidX && sqrtVal === null) {
41
+ throw new Error(`The given x is not a valid curve point.`);
42
+ }
43
+
44
+ let tries = 0;
45
+ while (sqrtVal === null) {
46
+ xCandidate = (xCandidate + 1n) % P;
47
+ sqrtVal = this.isValidX(xCandidate);
48
+
49
+ tries++;
50
+ if (tries > maxTries) {
51
+ throw new Error(`Could not find a valid X point within ${maxTries} increments.`);
52
+ }
53
+ }
54
+
55
+ // Now, sqrtVal is a valid 'r' for alpha = x^3 + 7
56
+ // The two roots for y are: r and p-r
57
+ const y1 = sqrtVal;
58
+ const y2 = (P - y1) % P;
59
+
60
+ return { x: xCandidate, y1, y2 };
61
+ }
62
+
63
+ /**
64
+ * Given two candidate y values, returns the one with the smaller y-coordinate.
65
+ * @param {bigint} y
66
+ * @param {bigint} y2
67
+ */
68
+ public getCanonicalY(y: bigint, y2: bigint): bigint {
69
+ return y < y2 ? y : y2;
70
+ }
71
+
72
+ /**
73
+ * Creates a 65-byte "hybrid public key" from the specified x and y.
74
+ * - First byte:
75
+ * - 0x06 if y is even
76
+ * - 0x07 if y is odd
77
+ * - Next 32 bytes: x
78
+ * - Last 32 bytes: y
79
+ *
80
+ * @param x X-coordinate as a bigint
81
+ * @param y Y-coordinate as a bigint
82
+ * @returns A Uint8Array of length 65
83
+ */
84
+ public getHybridPublicKey(x: bigint, y: bigint): Uint8Array {
85
+ // Determine prefix based on parity of y
86
+ const prefix = y % 2n === 0n ? 0x06 : 0x07;
87
+
88
+ // Convert x and y to 32-byte big-endian arrays
89
+ const xBytes = this.bigIntTo32Bytes(x);
90
+ const yBytes = this.bigIntTo32Bytes(y);
91
+
92
+ // Allocate 65 bytes: 1 for prefix + 32 for x + 32 for y
93
+ const hybrid = new Uint8Array(65);
94
+ hybrid[0] = prefix;
95
+ hybrid.set(xBytes, 1);
96
+ hybrid.set(yBytes, 33);
97
+
98
+ return hybrid;
99
+ }
100
+
101
+ /**
102
+ * Checks if (x^3 + 7) is a quadratic residue mod p.
103
+ * Returns the square root if it is, or null if not.
104
+ */
105
+ private isValidX(x: bigint): bigint | null {
106
+ // alpha = (x^3 + 7) mod p
107
+ const alpha = (this.modPow(x, 3n, P) + 7n) % P;
108
+ return this.sqrtModP(alpha, P);
109
+ }
110
+
111
+ /**
112
+ * Computes base^exp (mod m) using exponentiation by squaring.
113
+ */
114
+ private modPow(base: bigint, exp: bigint, m: bigint): bigint {
115
+ let result = 1n;
116
+ let cur = base % m;
117
+ let e = exp;
118
+
119
+ while (e > 0) {
120
+ if ((e & 1n) === 1n) {
121
+ result = (result * cur) % m;
122
+ }
123
+ cur = (cur * cur) % m;
124
+ e >>= 1n;
125
+ }
126
+ return result;
127
+ }
128
+
129
+ /**
130
+ * sqrtModP(a, p):
131
+ * Attempts to compute the square root of `a` modulo prime `p`.
132
+ * Returns the root if it exists, or null if `a` is not a quadratic residue.
133
+ *
134
+ * Since p ≡ 3 (mod 4), we can do:
135
+ * sqrt(a) = a^((p+1)/4) mod p
136
+ */
137
+ private sqrtModP(a: bigint, prime: bigint): bigint | null {
138
+ // Candidate root
139
+ const root = this.modPow(a, (prime + 1n) >> 2n, prime);
140
+
141
+ // Check if it's truly a root
142
+ if ((root * root) % prime !== a % prime) {
143
+ return null;
144
+ }
145
+ return root;
146
+ }
147
+
148
+ /**
149
+ * Convert a 32-byte Uint8Array (big-endian) to a BigInt.
150
+ */
151
+ private bytesToBigInt(bytes: Uint8Array): bigint {
152
+ let b = 0n;
153
+ for (const byte of bytes) {
154
+ b = (b << 8n) | BigInt(byte);
155
+ }
156
+ return b;
157
+ }
158
+
159
+ /**
160
+ * Convert a BigInt to a 32-byte array (big-endian).
161
+ */
162
+ private bigIntTo32Bytes(value: bigint): Uint8Array {
163
+ const bytes = new Uint8Array(32);
164
+ for (let i = 31; i >= 0; i--) {
165
+ bytes[i] = Number(value & 0xffn);
166
+ value >>= 8n;
167
+ }
168
+ return bytes;
169
+ }
170
+ }
@@ -1,8 +1,7 @@
1
1
  import { IWallet } from './interfaces/IWallet.js';
2
2
  import { ECPairInterface } from 'ecpair';
3
3
  import { EcKeyPair } from './EcKeyPair.js';
4
- import { Network, networks } from '@btc-vision/bitcoin';
5
- import { toXOnly } from '@btc-vision/bitcoin/src/psbt/bip371.js';
4
+ import { Network, networks, toXOnly } from '@btc-vision/bitcoin';
6
5
  import { Address } from './Address.js';
7
6
 
8
7
  /**
package/src/opnet.ts CHANGED
@@ -91,3 +91,5 @@ export * from './transaction/browser/types/Xverse.js';
91
91
  export * from './metadata/tokens.js';
92
92
  export * from './transaction/browser/Web3Provider.js';
93
93
 
94
+ export * from './transaction/ContractAddress.js';
95
+ export * from './keypair/Secp256k1PointDeriver.js';
@@ -1,8 +1,5 @@
1
1
  // Helper functions
2
- import { crypto as bitCrypto, PsbtInput } from '@btc-vision/bitcoin';
3
- import { isP2TR } from '@btc-vision/bitcoin/src/psbt/psbtutils.js';
4
- import { toXOnly } from '@btc-vision/bitcoin/src/psbt/bip371.js';
5
- import * as bscript from '@btc-vision/bitcoin/src/script.js';
2
+ import { isP2TR, PsbtInput, pubkeyPositionInScript } from '@btc-vision/bitcoin';
6
3
 
7
4
  export function isTaprootInput(input: PsbtInput): boolean {
8
5
  return (
@@ -58,21 +55,12 @@ export function canSignNonTaprootInput(input: PsbtInput, publicKey: Buffer): boo
58
55
  return false;
59
56
  }
60
57
 
61
- export function pubkeyPositionInScript(pubkey: Buffer, script: Buffer): number {
62
- const pubkeyHash = bitCrypto.hash160(pubkey);
63
- const pubkeyXOnly = toXOnly(pubkey);
64
-
65
- const decompiled = bscript.decompile(script);
66
- if (decompiled === null) throw new Error('Unknown script error');
67
-
68
- const a = decompiled.findIndex((element) => {
69
- if (typeof element === 'number') return false;
70
- return element.equals(pubkey) || element.equals(pubkeyHash) || element.equals(pubkeyXOnly);
71
- });
72
-
73
- return a;
74
- }
75
-
58
+ /**
59
+ * Checks if a public key is present in a script.
60
+ * @param pubkey The public key to check.
61
+ * @param script The script to search in.
62
+ * @returns A boolean indicating whether the public key is present in the script.
63
+ */
76
64
  export function pubkeyInScript(pubkey: Buffer, script: Buffer): boolean {
77
65
  return pubkeyPositionInScript(pubkey, script) !== -1;
78
66
  }
@@ -1,7 +1,5 @@
1
1
  import * as ecc from '@bitcoinerlab/secp256k1';
2
- import { initEccLib, Network, Signer } from '@btc-vision/bitcoin';
3
- import { tapTweakHash } from '@btc-vision/bitcoin/src/payments/bip341.js';
4
- import { toXOnly } from '@btc-vision/bitcoin/src/psbt/bip371.js';
2
+ import { initEccLib, Network, Signer, tapTweakHash, toXOnly } from '@btc-vision/bitcoin';
5
3
  import { ECPairInterface } from 'ecpair';
6
4
  import { EcKeyPair } from '../keypair/EcKeyPair.js';
7
5
 
@@ -0,0 +1,13 @@
1
+ import { Secp256k1PointDeriver } from '../keypair/Secp256k1PointDeriver.js';
2
+
3
+ class ContractAddressBase {
4
+ private readonly deriver: Secp256k1PointDeriver = new Secp256k1PointDeriver();
5
+
6
+ public generateHybridKeyFromHash(input: Buffer): Buffer {
7
+ const p = this.deriver.findOrDeriveValidPoint(Buffer.copyBytesFrom(input), false);
8
+ const y = this.deriver.getCanonicalY(p.y1, p.y2);
9
+ return Buffer.from(this.deriver.getHybridPublicKey(p.x, y));
10
+ }
11
+ }
12
+
13
+ export const ContractAddress = new ContractAddressBase();
@@ -1,5 +1,4 @@
1
- import { Transaction } from '@btc-vision/bitcoin';
2
- import { Output } from '@btc-vision/bitcoin/src/transaction.js';
1
+ import { Transaction, TxOutput } from '@btc-vision/bitcoin';
3
2
  import { currentConsensus } from '../consensus/ConsensusConfig.js';
4
3
  import { UTXO } from '../utxo/interfaces/IUTXO.js';
5
4
  import {
@@ -230,7 +229,7 @@ export class TransactionFactory {
230
229
  throw new Error('Could not sign funding transaction.');
231
230
  }
232
231
 
233
- const out: Output = signedTransaction.outs[0];
232
+ const out: TxOutput = signedTransaction.outs[0];
234
233
  const newUtxo: UTXO = {
235
234
  transactionId: signedTransaction.getId(),
236
235
  outputIndex: 0, // always 0
@@ -254,7 +253,7 @@ export class TransactionFactory {
254
253
  // We have to regenerate using the new utxo
255
254
  const outTx: Transaction = await finalTransaction.signTransaction();
256
255
 
257
- const out2: Output = signedTransaction.outs[1];
256
+ const out2: TxOutput = signedTransaction.outs[1];
258
257
  const refundUTXO: UTXO = {
259
258
  transactionId: signedTransaction.getId(),
260
259
  outputIndex: 1, // always 1
@@ -364,7 +363,7 @@ export class TransactionFactory {
364
363
  private getUTXOAsTransaction(tx: Transaction, to: string, index: number): UTXO[] {
365
364
  if (!tx.outs[index]) return [];
366
365
 
367
- const out: Output = tx.outs[index];
366
+ const out: TxOutput = tx.outs[index];
368
367
  const newUtxo: UTXO = {
369
368
  transactionId: tx.getId(),
370
369
  outputIndex: index,
@@ -5,13 +5,13 @@ import {
5
5
  Psbt,
6
6
  script as bitScript,
7
7
  TapScriptSig,
8
+ toXOnly,
8
9
  } from '@btc-vision/bitcoin';
9
10
  import { ECPairInterface } from 'ecpair';
10
11
  import { EcKeyPair } from '../../../keypair/EcKeyPair.js';
11
12
  import { CustomKeypair } from '../BrowserSignerBase.js';
12
13
  import { PsbtSignatureOptions, Unisat, UnisatNetwork } from '../types/Unisat.js';
13
14
  import { PartialSig } from 'bip174/src/lib/interfaces.js';
14
- import { toXOnly } from '@btc-vision/bitcoin/src/psbt/bip371.js';
15
15
  import { canSignNonTaprootInput, isTaprootInput } from '../../../signer/SignerUtils.js';
16
16
 
17
17
  declare global {
@@ -1,5 +1,4 @@
1
- import { Network, networks, Psbt, TapScriptSig } from '@btc-vision/bitcoin';
2
- import { toXOnly } from '@btc-vision/bitcoin/src/psbt/bip371.js';
1
+ import { Network, networks, Psbt, TapScriptSig, toXOnly } from '@btc-vision/bitcoin';
3
2
  import { PartialSig } from 'bip174/src/lib/interfaces.js';
4
3
  import { ECPairInterface } from 'ecpair';
5
4
  import { EcKeyPair } from '../../../keypair/EcKeyPair.js';
@@ -1,14 +1,21 @@
1
- import { Taptree } from '@btc-vision/bitcoin/src/types.js';
1
+ import {
2
+ crypto as bitCrypto,
3
+ Payment,
4
+ Psbt,
5
+ PsbtInput,
6
+ Signer,
7
+ Stack,
8
+ Taptree,
9
+ toXOnly,
10
+ } from '@btc-vision/bitcoin';
2
11
  import { TransactionType } from '../enums/TransactionType.js';
3
12
  import { TapLeafScript } from '../interfaces/Tap.js';
4
13
  import { SharedInteractionParameters } from '../interfaces/ITransactionParameters.js';
5
- import { crypto as bitCrypto, Payment, Psbt, PsbtInput, Signer, Stack } from '@btc-vision/bitcoin';
6
14
  import { TransactionBuilder } from './TransactionBuilder.js';
7
15
  import { CustomGenerator } from '../../generators/builders/CustomGenerator.js';
8
16
  import { BitcoinUtils } from '../../utils/BitcoinUtils.js';
9
17
  import { EcKeyPair } from '../../keypair/EcKeyPair.js';
10
18
  import { AddressGenerator } from '../../generators/AddressGenerator.js';
11
- import { toXOnly } from '@btc-vision/bitcoin/src/psbt/bip371.js';
12
19
  import { ECPairInterface } from 'ecpair';
13
20
 
14
21
  export interface ICustomTransactionParameters extends SharedInteractionParameters {
@@ -1,11 +1,17 @@
1
1
  import { TransactionType } from '../enums/TransactionType.js';
2
2
  import { IDeploymentParameters } from '../interfaces/ITransactionParameters.js';
3
- import { crypto as bitCrypto, Payment, Psbt, PsbtInput, Signer } from '@btc-vision/bitcoin';
3
+ import {
4
+ crypto as bitCrypto,
5
+ Payment,
6
+ Psbt,
7
+ PsbtInput,
8
+ Signer,
9
+ Taptree,
10
+ toXOnly,
11
+ } from '@btc-vision/bitcoin';
4
12
  import { TransactionBuilder } from './TransactionBuilder.js';
5
- import { Taptree } from '@btc-vision/bitcoin/src/types.js';
6
13
  import { TapLeafScript } from '../interfaces/Tap.js';
7
14
  import { DeploymentGenerator } from '../../generators/builders/DeploymentGenerator.js';
8
- import { toXOnly } from '@btc-vision/bitcoin/src/psbt/bip371.js';
9
15
  import { EcKeyPair } from '../../keypair/EcKeyPair.js';
10
16
  import { BitcoinUtils } from '../../utils/BitcoinUtils.js';
11
17
  import { Compressor } from '../../bytecode/Compressor.js';
@@ -14,6 +20,8 @@ import { ECPairInterface } from 'ecpair';
14
20
  import { Address } from '../../keypair/Address.js';
15
21
  import { UnisatSigner } from '../browser/extensions/UnisatSigner.js';
16
22
 
23
+ const p = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2fn;
24
+
17
25
  export class DeploymentTransaction extends TransactionBuilder<TransactionType.DEPLOYMENT> {
18
26
  public static readonly MAXIMUM_CONTRACT_SIZE = 128 * 1024;
19
27
  public type: TransactionType.DEPLOYMENT = TransactionType.DEPLOYMENT;
@@ -90,6 +98,7 @@ export class DeploymentTransaction extends TransactionBuilder<TransactionType.DE
90
98
  private readonly randomBytes: Buffer;
91
99
 
92
100
  public constructor(parameters: IDeploymentParameters) {
101
+ // TODO: Add legacy deployment, this is only p2tr.
93
102
  super(parameters);
94
103
 
95
104
  this.bytecode = Compressor.compress(parameters.bytecode);
@@ -317,6 +326,7 @@ export class DeploymentTransaction extends TransactionBuilder<TransactionType.DE
317
326
  throw new Error('Bytecode is required');
318
327
  }
319
328
 
329
+ // Concatenate deployer pubkey, salt, and sha256(bytecode)
320
330
  const deployerPubKey: Buffer = this.internalPubKeyToXOnly();
321
331
  const salt: Buffer = bitCrypto.hash256(this.randomBytes);
322
332
  const sha256OfBytecode: Buffer = bitCrypto.hash256(this.bytecode);
@@ -29,14 +29,14 @@ export class FundingTransaction extends TransactionBuilder<TransactionType.FUNDI
29
29
  if (this.splitInputsInto > 1) {
30
30
  this.splitInputs(this.amount);
31
31
  } else if (this.isPubKeyDestination) {
32
- const p2pkScript = script.compile([
32
+ const pubKeyScript = script.compile([
33
33
  Buffer.from(this.to.replace('0x', ''), 'hex'),
34
34
  opcodes.OP_CHECKSIG,
35
35
  ]);
36
36
 
37
37
  this.addOutput({
38
38
  value: Number(this.amount),
39
- script: p2pkScript,
39
+ script: pubKeyScript,
40
40
  });
41
41
  } else {
42
42
  this.addOutput({
@@ -1,4 +1,4 @@
1
- import { Taptree } from '@btc-vision/bitcoin/src/types.js';
1
+ import { Taptree } from '@btc-vision/bitcoin';
2
2
  import { TransactionType } from '../enums/TransactionType.js';
3
3
  import { TapLeafScript } from '../interfaces/Tap.js';
4
4
  import { IInteractionParameters } from '../interfaces/ITransactionParameters.js';
@@ -9,14 +9,14 @@ import {
9
9
  script,
10
10
  Signer,
11
11
  TapScriptSig,
12
+ Taptree,
13
+ toXOnly,
12
14
  } from '@btc-vision/bitcoin';
13
- import { Taptree } from '@btc-vision/bitcoin/src/types.js';
14
15
  import { TransactionBuilder } from './TransactionBuilder.js';
15
16
  import { TransactionType } from '../enums/TransactionType.js';
16
17
  import { ITransactionParameters } from '../interfaces/ITransactionParameters.js';
17
18
  import { MultiSignGenerator } from '../../generators/builders/MultiSignGenerator.js';
18
19
  import { UTXO } from '../../utxo/interfaces/IUTXO.js';
19
- import { toXOnly } from '@btc-vision/bitcoin/src/psbt/bip371.js';
20
20
  import { EcKeyPair } from '../../keypair/EcKeyPair.js';
21
21
  import { ECPairInterface } from 'ecpair';
22
22
 
@@ -1,5 +1,4 @@
1
- import { address, Payment, Psbt, PsbtInput, Signer } from '@btc-vision/bitcoin';
2
- import { Taptree } from '@btc-vision/bitcoin/src/types.js';
1
+ import { address, Payment, Psbt, PsbtInput, Signer, Taptree, toXOnly } from '@btc-vision/bitcoin';
3
2
  import { ECPairInterface } from 'ecpair';
4
3
  import { TransactionBuilder } from './TransactionBuilder.js';
5
4
  import { TransactionType } from '../enums/TransactionType.js';
@@ -8,7 +7,6 @@ import { SharedInteractionParameters } from '../interfaces/ITransactionParameter
8
7
  import { Compressor } from '../../bytecode/Compressor.js';
9
8
  import { EcKeyPair } from '../../keypair/EcKeyPair.js';
10
9
  import { BitcoinUtils } from '../../utils/BitcoinUtils.js';
11
- import { toXOnly } from '@btc-vision/bitcoin/src/psbt/bip371.js';
12
10
  import { UnisatSigner } from '../browser/extensions/UnisatSigner.js';
13
11
 
14
12
  /**
@@ -8,8 +8,8 @@ import {
8
8
  script,
9
9
  Signer,
10
10
  Transaction,
11
+ varuint,
11
12
  } from '@btc-vision/bitcoin';
12
- import { varuint } from '@btc-vision/bitcoin/src/bufferutils.js';
13
13
  import * as ecc from '@bitcoinerlab/secp256k1';
14
14
  import { UpdateInput } from '../interfaces/Tap.js';
15
15
  import { TransactionType } from '../enums/TransactionType.js';
@@ -473,6 +473,16 @@ export abstract class TransactionBuilder<T extends TransactionType> extends Twea
473
473
  address: this.from,
474
474
  tapInternalKey: this.internalPubKeyToXOnly(),
475
475
  });
476
+ } else if (AddressVerificator.isValidPublicKey(this.from, this.network)) {
477
+ const pubKeyScript = script.compile([
478
+ Buffer.from(this.from.replace('0x', ''), 'hex'),
479
+ opcodes.OP_CHECKSIG,
480
+ ]);
481
+
482
+ await this.setFeeOutput({
483
+ value: Number(sendBackAmount),
484
+ script: pubKeyScript,
485
+ });
476
486
  } else {
477
487
  await this.setFeeOutput({
478
488
  value: Number(sendBackAmount),
@@ -3,6 +3,13 @@ import {
3
3
  address as bitAddress,
4
4
  crypto as bitCrypto,
5
5
  getFinalScripts,
6
+ isP2MS,
7
+ isP2PK,
8
+ isP2PKH,
9
+ isP2SHScript,
10
+ isP2TR,
11
+ isP2WPKH,
12
+ isP2WSHScript,
6
13
  Network,
7
14
  opcodes,
8
15
  Payment,
@@ -12,31 +19,22 @@ import {
12
19
  PsbtInputExtended,
13
20
  script,
14
21
  Signer,
22
+ toXOnly,
15
23
  Transaction,
24
+ varuint,
16
25
  } from '@btc-vision/bitcoin';
17
26
 
18
27
  import { TweakedSigner, TweakSettings } from '../../signer/TweakedSigner.js';
19
28
  import { ECPairInterface } from 'ecpair';
20
- import { toXOnly } from '@btc-vision/bitcoin/src/psbt/bip371.js';
21
29
  import { UTXO } from '../../utxo/interfaces/IUTXO.js';
22
30
  import { TapLeafScript } from '../interfaces/Tap.js';
23
31
  import { ChainId } from '../../network/ChainId.js';
24
- import { varuint } from '@btc-vision/bitcoin/src/bufferutils.js';
25
32
  import { UnisatSigner } from '../browser/extensions/UnisatSigner.js';
26
33
  import {
27
34
  canSignNonTaprootInput,
28
35
  isTaprootInput,
29
36
  pubkeyInScript,
30
37
  } from '../../signer/SignerUtils.js';
31
- import {
32
- isP2MS,
33
- isP2PK,
34
- isP2PKH,
35
- isP2SHScript,
36
- isP2TR,
37
- isP2WPKH,
38
- isP2WSHScript,
39
- } from '@btc-vision/bitcoin/src/psbt/psbtutils.js';
40
38
 
41
39
  export interface ITweakedTransactionData {
42
40
  readonly signer: Signer | ECPairInterface | UnisatSigner;
@@ -803,88 +801,6 @@ export abstract class TweakedTransaction extends Logger {
803
801
  return input;
804
802
  }
805
803
 
806
- /*protected generatePsbtInputExtended(utxo: UTXO, i: number): PsbtInputExtended {
807
- const input: PsbtInputExtended = {
808
- hash: utxo.transactionId,
809
- index: utxo.outputIndex,
810
- sequence: this.sequence,
811
- witnessUtxo: {
812
- value: Number(utxo.value),
813
- script: Buffer.from(utxo.scriptPubKey.hex, 'hex'),
814
- },
815
- };
816
-
817
- if (utxo.scriptPubKey.address) {
818
- // auto detect for potential p2sh utxos
819
- try {
820
- const addressType: AddressTypes | null = AddressVerificator.detectAddressType(
821
- utxo.scriptPubKey.address,
822
- this.network,
823
- );
824
-
825
- if (addressType === AddressTypes.P2SH_OR_P2SH_P2WPKH) {
826
- // We can automatically reconstruct the redeem script.
827
- const redeemScript = this.generateP2SHRedeemScriptLegacy(
828
- utxo.scriptPubKey.address,
829
- );
830
-
831
- if (!redeemScript) {
832
- throw new Error('Failed to generate redeem script');
833
- }
834
-
835
- input.redeemScript = redeemScript.outputScript;
836
- input.witnessScript = redeemScript.redeemScript;
837
- }
838
- } catch (e) {
839
- this.error(`Failed to detect address type for ${utxo.scriptPubKey.address} - ${e}`);
840
- }
841
- }
842
-
843
- // LEGACY P2SH SUPPORT
844
- if (utxo.nonWitnessUtxo) {
845
- input.nonWitnessUtxo = Buffer.isBuffer(utxo.nonWitnessUtxo)
846
- ? utxo.nonWitnessUtxo
847
- : Buffer.from(utxo.nonWitnessUtxo, 'hex');
848
- }
849
-
850
- // SEGWIT SUPPORT
851
- if (utxo.redeemScript) {
852
- input.redeemScript = Buffer.isBuffer(utxo.redeemScript)
853
- ? utxo.redeemScript
854
- : Buffer.from(utxo.redeemScript, 'hex');
855
-
856
- if (utxo.witnessScript) {
857
- input.witnessScript = Buffer.isBuffer(utxo.witnessScript)
858
- ? utxo.witnessScript
859
- : Buffer.from(utxo.witnessScript, 'hex');
860
- }
861
- }
862
-
863
- // TAPROOT.
864
- if (this.sighashTypes) {
865
- const inputSign = TweakedTransaction.calculateSignHash(this.sighashTypes);
866
- if (inputSign) input.sighashType = inputSign;
867
- }
868
-
869
- if (i === 0 && this.nonWitnessUtxo) {
870
- input.nonWitnessUtxo = this.nonWitnessUtxo;
871
- }
872
-
873
- // Automatically detect P2TR inputs.
874
- if (
875
- utxo.scriptPubKey.address &&
876
- AddressVerificator.isValidP2TRAddress(utxo.scriptPubKey.address, this.network)
877
- ) {
878
- this.tweakSigner();
879
-
880
- input.tapInternalKey = this.internalPubKeyToXOnly();
881
- }
882
-
883
- console.log(input);
884
-
885
- return input;
886
- }*/
887
-
888
804
  protected customFinalizerP2SH = (
889
805
  inputIndex: number,
890
806
  input: PsbtInput,
@@ -21,7 +21,7 @@ export class BufferHelper {
21
21
  }
22
22
 
23
23
  public static uint8ArrayToHex(input: Uint8Array): string {
24
- return Buffer.from(input, 0, input.byteLength).toString('hex');
24
+ return Buffer.from(input.buffer, 0, input.byteLength).toString('hex');
25
25
  }
26
26
 
27
27
  public static hexToUint8Array(input: string): Uint8Array {
@@ -1,6 +1,12 @@
1
- import { crypto as bitCrypto, Network, networks, Payment, payments } from '@btc-vision/bitcoin';
2
- import { toXOnly } from '@btc-vision/bitcoin/src/psbt/bip371.js';
3
- import { Taptree } from '@btc-vision/bitcoin/src/types.js';
1
+ import {
2
+ crypto as bitCrypto,
3
+ Network,
4
+ networks,
5
+ Payment,
6
+ payments,
7
+ Taptree,
8
+ toXOnly,
9
+ } from '@btc-vision/bitcoin';
4
10
  import { DeploymentGenerator } from '../generators/builders/DeploymentGenerator.js';
5
11
  import { TransactionBuilder } from '../transaction/builders/TransactionBuilder.js';
6
12
  import { Address } from '../keypair/Address.js';