@btc-vision/transaction 1.0.6 → 1.0.8

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 (179) hide show
  1. package/Deploy.md +186 -0
  2. package/README.md +5 -0
  3. package/Wrap.md +192 -0
  4. package/browser/_version.d.ts +1 -1
  5. package/browser/index.js +1 -1
  6. package/browser/index.js.LICENSE.txt +9 -0
  7. package/browser/opnet.d.ts +6 -1
  8. package/browser/tests/deploy.d.ts +1 -0
  9. package/browser/tests/wrap.d.ts +1 -0
  10. package/browser/tests/wrapTest.d.ts +1 -0
  11. package/browser/transaction/TransactionFactory.d.ts +15 -1
  12. package/browser/transaction/builders/DeploymentTransaction.d.ts +40 -0
  13. package/browser/transaction/builders/InteractionTransaction.d.ts +2 -35
  14. package/browser/transaction/builders/SharedInteractionTransaction.d.ts +46 -0
  15. package/browser/transaction/builders/TransactionBuilder.d.ts +8 -1
  16. package/browser/transaction/builders/WrapTransaction.d.ts +27 -0
  17. package/browser/transaction/interfaces/ITransactionParameters.d.ts +16 -12
  18. package/browser/utils/BitcoinUtils.d.ts +1 -0
  19. package/browser/utxo/OPNetLimitedProvider.d.ts +10 -0
  20. package/browser/wbtc/Generate.d.ts +13 -0
  21. package/browser/wbtc/WrappedGenerationParameters.d.ts +11 -0
  22. package/build/_version.d.ts +1 -1
  23. package/build/_version.js +1 -1
  24. package/build/bytecode/Compressor.js +4 -3
  25. package/build/generators/AddressGenerator.js +1 -1
  26. package/build/keypair/EcKeyPair.js +1 -1
  27. package/build/opnet.d.ts +6 -1
  28. package/build/opnet.js +6 -1
  29. package/build/signer/TweakedSigner.js +1 -1
  30. package/build/tests/deploy.d.ts +1 -0
  31. package/build/tests/deploy.js +60 -0
  32. package/build/tests/test.js +3 -3
  33. package/build/tests/transfer.js +2 -2
  34. package/build/tests/wrap.d.ts +1 -0
  35. package/build/tests/wrap.js +64 -0
  36. package/build/tests/wrapTest.d.ts +1 -0
  37. package/build/tests/wrapTest.js +64 -0
  38. package/build/tests/wrapTestg.d.ts +1 -0
  39. package/build/tests/wrapTestg.js +66 -0
  40. package/build/transaction/TransactionFactory.d.ts +15 -1
  41. package/build/transaction/TransactionFactory.js +68 -0
  42. package/build/transaction/builders/DeploymentTransaction.d.ts +40 -0
  43. package/build/transaction/builders/DeploymentTransaction.js +216 -0
  44. package/build/transaction/builders/FundingTransaction.js +4 -1
  45. package/build/transaction/builders/InteractionTransaction.d.ts +2 -35
  46. package/build/transaction/builders/InteractionTransaction.js +4 -207
  47. package/build/transaction/builders/SharedInteractionTransaction.d.ts +46 -0
  48. package/build/transaction/builders/SharedInteractionTransaction.js +213 -0
  49. package/build/transaction/builders/TransactionBuilder.d.ts +8 -1
  50. package/build/transaction/builders/TransactionBuilder.js +20 -12
  51. package/build/transaction/builders/WrapTransaction.d.ts +27 -0
  52. package/build/transaction/builders/WrapTransaction.js +132 -0
  53. package/build/transaction/interfaces/ITransactionParameters.d.ts +16 -12
  54. package/build/utils/BitcoinUtils.d.ts +1 -0
  55. package/build/utils/BitcoinUtils.js +7 -0
  56. package/build/utxo/OPNetLimitedProvider.d.ts +10 -0
  57. package/build/utxo/OPNetLimitedProvider.js +85 -0
  58. package/build/utxo/OPNetUtils.d.ts +7 -0
  59. package/build/utxo/OPNetUtils.js +47 -0
  60. package/build/verification/TapscriptVerificator.js +3 -3
  61. package/build/wbtc/Generate.d.ts +13 -0
  62. package/build/wbtc/Generate.js +1 -0
  63. package/build/wbtc/WrappedGenerationParameters.d.ts +11 -0
  64. package/build/wbtc/WrappedGenerationParameters.js +16 -0
  65. package/bytecode/contract.wasm +0 -0
  66. package/cjs/_version.d.ts +1 -1
  67. package/cjs/_version.js +1 -1
  68. package/cjs/bytecode/Compressor.js +1 -1
  69. package/cjs/generators/AddressGenerator.d.ts +7 -0
  70. package/cjs/generators/AddressGenerator.js +48 -0
  71. package/cjs/generators/Generator.d.ts +1 -2
  72. package/cjs/generators/Generator.js +1 -3
  73. package/cjs/generators/builders/DeploymentGenerator.d.ts +1 -0
  74. package/cjs/generators/builders/DeploymentGenerator.js +10 -7
  75. package/cjs/keypair/Wallet.d.ts +1 -0
  76. package/cjs/keypair/Wallet.js +6 -0
  77. package/cjs/opnet.d.ts +23 -0
  78. package/cjs/opnet.js +37 -0
  79. package/cjs/tests/Regtest.d.ts +3 -0
  80. package/cjs/tests/Regtest.js +32 -0
  81. package/cjs/tests/gen.d.ts +1 -0
  82. package/cjs/tests/gen.js +17 -0
  83. package/cjs/tests/test.d.ts +1 -0
  84. package/cjs/tests/test.js +53 -0
  85. package/cjs/tests/transfer.d.ts +1 -0
  86. package/cjs/tests/transfer.js +76 -0
  87. package/cjs/transaction/TransactionFactory.js +7 -4
  88. package/cjs/transaction/builders/FundingTransaction.js +1 -1
  89. package/cjs/transaction/builders/InteractionTransaction.d.ts +2 -0
  90. package/cjs/transaction/builders/InteractionTransaction.js +11 -2
  91. package/cjs/transaction/builders/TransactionBuilder.d.ts +3 -2
  92. package/cjs/transaction/builders/TransactionBuilder.js +22 -7
  93. package/cjs/transaction/interfaces/ITransactionParameters.d.ts +1 -0
  94. package/cjs/verification/TapscriptVerificator.d.ts +17 -0
  95. package/cjs/verification/TapscriptVerificator.js +70 -0
  96. package/docs/assets/navigation.js +1 -1
  97. package/docs/assets/search.js +1 -1
  98. package/docs/classes/AddressGenerator.html +2 -2
  99. package/docs/classes/BitcoinUtils.html +7 -3
  100. package/docs/classes/CalldataGenerator.html +10 -10
  101. package/docs/classes/Compressor.html +4 -4
  102. package/docs/classes/ContractBaseMetadata.html +4 -4
  103. package/docs/classes/DeploymentGenerator.html +9 -9
  104. package/docs/classes/DeploymentTransaction.html +368 -0
  105. package/docs/classes/EcKeyPair.html +16 -16
  106. package/docs/classes/FundingTransaction.html +50 -47
  107. package/docs/classes/Generator.html +9 -9
  108. package/docs/classes/InteractionTransaction.html +89 -109
  109. package/docs/classes/OPNetLimitedProvider.html +197 -0
  110. package/docs/classes/SharedInteractionTransaction.html +392 -0
  111. package/docs/classes/TapscriptVerificator.html +2 -2
  112. package/docs/classes/TransactionBuilder.html +53 -50
  113. package/docs/classes/TransactionFactory.html +11 -4
  114. package/docs/classes/TweakedSigner.html +2 -2
  115. package/docs/classes/Wallet.html +10 -10
  116. package/docs/classes/WrapTransaction.html +404 -0
  117. package/docs/classes/WrappedGeneration.html +187 -0
  118. package/docs/classes/wBTC.html +7 -7
  119. package/docs/enums/TransactionSequence.html +177 -0
  120. package/docs/enums/TransactionType.html +2 -2
  121. package/docs/hierarchy.html +1 -1
  122. package/docs/index.html +3 -1
  123. package/docs/interfaces/ContractAddressVerificationParams.html +2 -2
  124. package/docs/interfaces/DeploymentResult.html +177 -0
  125. package/docs/interfaces/FetchUTXOParams.html +2 -2
  126. package/docs/interfaces/GenerationConstraints.html +182 -0
  127. package/docs/interfaces/IDeploymentParameters.html +183 -0
  128. package/docs/interfaces/IFundingTransactionParameters.html +3 -3
  129. package/docs/interfaces/IInteractionParameters.html +4 -6
  130. package/docs/interfaces/ITransactionParameters.html +3 -3
  131. package/docs/interfaces/IWallet.html +4 -4
  132. package/docs/interfaces/IWrapParameters.html +186 -0
  133. package/docs/interfaces/NetworkInformation.html +2 -2
  134. package/docs/interfaces/PsbtInputExtended.html +1 -1
  135. package/docs/interfaces/PsbtOutputExtendedAddress.html +2 -2
  136. package/docs/interfaces/PsbtOutputExtendedScript.html +2 -2
  137. package/docs/interfaces/RawUTXOResponse.html +2 -2
  138. package/docs/interfaces/SharedInteractionParameters.html +183 -0
  139. package/docs/interfaces/TapLeafScript.html +2 -2
  140. package/docs/interfaces/TweakSettings.html +3 -3
  141. package/docs/interfaces/UTXO.html +2 -2
  142. package/docs/interfaces/UpdateInput.html +2 -2
  143. package/docs/interfaces/WrapResult.html +178 -0
  144. package/docs/interfaces/WrappedGenerationParameters.html +184 -0
  145. package/docs/modules.html +14 -4
  146. package/docs/types/PsbtOutputExtended.html +1 -1
  147. package/docs/variables/version.html +1 -1
  148. package/package.json +4 -5
  149. package/src/_version.ts +1 -1
  150. package/src/bytecode/Compressor.ts +27 -26
  151. package/src/generators/AddressGenerator.ts +1 -1
  152. package/src/keypair/EcKeyPair.ts +1 -1
  153. package/src/opnet.ts +8 -1
  154. package/src/signer/TweakedSigner.ts +1 -1
  155. package/src/tests/deploy.ts +81 -0
  156. package/src/tests/test.ts +3 -3
  157. package/src/tests/transfer.ts +2 -2
  158. package/src/tests/wrap.ts +89 -0
  159. package/src/tests/wrapTest.ts +88 -0
  160. package/src/transaction/TransactionFactory.ts +119 -1
  161. package/src/transaction/builders/DeploymentTransaction.ts +418 -0
  162. package/src/transaction/builders/FundingTransaction.ts +5 -1
  163. package/src/transaction/builders/InteractionTransaction.ts +5 -404
  164. package/src/transaction/builders/SharedInteractionTransaction.ts +432 -0
  165. package/src/transaction/builders/TransactionBuilder.ts +41 -16
  166. package/src/transaction/builders/WrapTransaction.ts +286 -0
  167. package/src/transaction/interfaces/ITransactionParameters.ts +20 -13
  168. package/src/utils/BitcoinUtils.ts +16 -0
  169. package/src/utxo/{UTXOManager.ts → OPNetLimitedProvider.ts} +53 -2
  170. package/src/verification/TapscriptVerificator.ts +3 -3
  171. package/src/wbtc/Generate.ts +30 -0
  172. package/src/wbtc/WrappedGenerationParameters.ts +33 -0
  173. package/tests/TransactionBuilder.test.ts +58 -58
  174. package/tsconfig.webpack.json +7 -1
  175. package/webpack.config.js +3 -1
  176. package/browser/873e754d6c7c6e9361f1.module.wasm +0 -0
  177. package/docs/classes/UTXOManager.html +0 -187
  178. package/docs/interfaces/ITransactionDataContractDeployment.html +0 -184
  179. package/docs/interfaces/ITransactionDataContractInteractionWrap.html +0 -186
@@ -1,219 +1,16 @@
1
- import { address } from 'bitcoinjs-lib';
2
- import { TransactionBuilder } from './TransactionBuilder.js';
3
1
  import { TransactionType } from '../enums/TransactionType.js';
4
- import { CalldataGenerator } from '../../generators/builders/CalldataGenerator.js';
5
- import { Compressor } from '../../bytecode/Compressor.js';
6
- import { EcKeyPair } from '../../keypair/EcKeyPair.js';
7
- import { BitcoinUtils } from '../../utils/BitcoinUtils.js';
8
- import { toXOnly } from 'bitcoinjs-lib/src/psbt/bip371.js';
9
- import { TweakedSigner } from '../../signer/TweakedSigner.js';
10
- export class InteractionTransaction extends TransactionBuilder {
2
+ import { SharedInteractionTransaction } from './SharedInteractionTransaction.js';
3
+ export class InteractionTransaction extends SharedInteractionTransaction {
11
4
  type = TransactionType.INTERACTION;
12
- randomBytes;
13
- targetScriptRedeem = null;
14
- leftOverFundsScriptRedeem = null;
15
5
  compiledTargetScript;
16
6
  scriptTree;
17
7
  tapLeafScript = null;
18
- calldataGenerator;
19
- calldata;
20
- contractSecret = this.generateSecret();
21
- tweakedSigner;
22
- scriptSigner;
23
- interactionPubKeys;
24
- minimumSignatures;
8
+ contractSecret;
25
9
  constructor(parameters) {
26
10
  super(parameters);
27
- if (!parameters.calldata) {
28
- throw new Error('Calldata is required');
29
- }
30
- this.calldata = Compressor.compress(parameters.calldata);
31
- this.interactionPubKeys = parameters.pubKeys || [];
32
- this.minimumSignatures = parameters.minimumSignatures || 0;
33
- this.randomBytes = parameters.randomBytes || BitcoinUtils.rndBytes();
34
- this.scriptSigner = this.generateKeyPairFromSeed();
35
- this.calldataGenerator = new CalldataGenerator(this.internalPubKeyToXOnly(), this.scriptSignerXOnlyPubKey(), this.network);
11
+ this.contractSecret = this.generateSecret();
36
12
  this.compiledTargetScript = this.calldataGenerator.compile(this.calldata, this.contractSecret, this.interactionPubKeys, this.minimumSignatures);
37
13
  this.scriptTree = this.getScriptTree();
38
14
  this.internalInit();
39
15
  }
40
- getContractSecret() {
41
- return this.contractSecret;
42
- }
43
- getRndBytes() {
44
- return this.randomBytes;
45
- }
46
- generateSecret() {
47
- return address.fromBech32(this.to).data;
48
- }
49
- tweakSigner() {
50
- this.tweakedSigner = this.getTweakedSigner();
51
- }
52
- scriptSignerXOnlyPubKey() {
53
- return toXOnly(this.scriptSigner.publicKey);
54
- }
55
- generateKeyPairFromSeed() {
56
- return EcKeyPair.fromSeedKeyPair(this.randomBytes, this.network);
57
- }
58
- addInputsFromUTXO() {
59
- if (!this.tapLeafScript)
60
- throw new Error('Tap leaf script is required');
61
- for (let utxo of this.utxos) {
62
- const input = {
63
- hash: utxo.transactionId,
64
- index: utxo.outputIndex,
65
- witnessUtxo: {
66
- value: Number(utxo.value),
67
- script: this.getTapOutput(),
68
- },
69
- tapLeafScript: [this.tapLeafScript],
70
- sequence: 0xfffffffd,
71
- };
72
- this.addInput(input);
73
- }
74
- }
75
- buildTransaction() {
76
- const selectedRedeem = !!this.scriptSigner
77
- ? this.targetScriptRedeem
78
- : this.leftOverFundsScriptRedeem;
79
- if (!selectedRedeem) {
80
- throw new Error('Left over funds script redeem is required');
81
- }
82
- if (!selectedRedeem.redeemVersion) {
83
- throw new Error('Left over funds script redeem version is required');
84
- }
85
- if (!selectedRedeem.output) {
86
- throw new Error('Left over funds script redeem output is required');
87
- }
88
- this.tapLeafScript = {
89
- leafVersion: selectedRedeem.redeemVersion,
90
- script: selectedRedeem.output,
91
- controlBlock: this.getWitness(),
92
- };
93
- this.addInputsFromUTXO();
94
- const amountSpent = this.getTransactionOPNetFee();
95
- this.addOutput({
96
- value: Number(amountSpent),
97
- address: this.to,
98
- });
99
- this.addRefundOutput(amountSpent);
100
- }
101
- signInputs(transaction) {
102
- if (!this.scriptSigner) {
103
- super.signInputs(transaction);
104
- return;
105
- }
106
- transaction.signInput(0, this.scriptSigner);
107
- transaction.signInput(0, this.getSignerKey());
108
- transaction.finalizeInput(0, this.customFinalizer);
109
- }
110
- getSignerKey() {
111
- if (this.tweakedSigner) {
112
- return this.tweakedSigner;
113
- }
114
- return this.signer;
115
- }
116
- generateScriptAddress() {
117
- return {
118
- internalPubkey: this.internalPubKeyToXOnly(),
119
- network: this.network,
120
- scriptTree: this.scriptTree,
121
- };
122
- }
123
- generateTapData() {
124
- const selectedRedeem = !!this.scriptSigner
125
- ? this.targetScriptRedeem
126
- : this.leftOverFundsScriptRedeem;
127
- if (!selectedRedeem) {
128
- throw new Error('Left over funds script redeem is required');
129
- }
130
- if (!this.scriptTree) {
131
- throw new Error('Script tree is required');
132
- }
133
- return {
134
- internalPubkey: this.internalPubKeyToXOnly(),
135
- network: this.network,
136
- scriptTree: this.scriptTree,
137
- redeem: selectedRedeem,
138
- };
139
- }
140
- getScriptSolution(input) {
141
- if (!input.tapScriptSig) {
142
- throw new Error('Tap script signature is required');
143
- }
144
- return [
145
- this.contractSecret,
146
- this.internalPubKeyToXOnly(),
147
- input.tapScriptSig[0].signature,
148
- input.tapScriptSig[1].signature,
149
- ];
150
- }
151
- getPubKeys() {
152
- const pubkeys = [this.signer.publicKey];
153
- if (this.scriptSigner) {
154
- pubkeys.push(this.scriptSigner.publicKey);
155
- }
156
- return pubkeys;
157
- }
158
- customFinalizer = (_inputIndex, input) => {
159
- if (!this.tapLeafScript) {
160
- throw new Error('Tap leaf script is required');
161
- }
162
- if (!input.tapScriptSig) {
163
- throw new Error('Tap script signature is required');
164
- }
165
- if (!this.contractSecret) {
166
- throw new Error('Contract secret is required');
167
- }
168
- const scriptSolution = this.getScriptSolution(input);
169
- const witness = scriptSolution
170
- .concat(this.tapLeafScript.script)
171
- .concat(this.tapLeafScript.controlBlock);
172
- return {
173
- finalScriptWitness: this.witnessStackToScriptWitness(witness),
174
- };
175
- };
176
- getTweakerHash() {
177
- return this.tapData?.hash;
178
- }
179
- getTweakedSigner(useTweakedHash = false) {
180
- const settings = {
181
- network: this.network,
182
- };
183
- if (useTweakedHash) {
184
- settings.tweakHash = this.getTweakerHash();
185
- }
186
- return TweakedSigner.tweakSigner(this.signer, settings);
187
- }
188
- generateRedeemScripts() {
189
- this.targetScriptRedeem = {
190
- pubkeys: this.getPubKeys(),
191
- output: this.compiledTargetScript,
192
- redeemVersion: 192,
193
- };
194
- this.leftOverFundsScriptRedeem = {
195
- pubkeys: this.getPubKeys(),
196
- output: this.getLeafScript(),
197
- redeemVersion: 192,
198
- };
199
- }
200
- getLeafScript() {
201
- return InteractionTransaction.LOCK_LEAF_SCRIPT;
202
- }
203
- getScriptTree() {
204
- if (!this.calldata) {
205
- throw new Error('Calldata is required');
206
- }
207
- this.generateRedeemScripts();
208
- return [
209
- {
210
- output: this.compiledTargetScript,
211
- version: 192,
212
- },
213
- {
214
- output: this.getLeafScript(),
215
- version: 192,
216
- },
217
- ];
218
- }
219
16
  }
@@ -0,0 +1,46 @@
1
+ /// <reference types="node" />
2
+ import { PsbtInput } from 'bip174/src/lib/interfaces.js';
3
+ import { Payment, Psbt, Signer } from 'bitcoinjs-lib';
4
+ import { Taptree } from 'bitcoinjs-lib/src/types.js';
5
+ import { ECPairInterface } from 'ecpair';
6
+ import { TransactionBuilder } from './TransactionBuilder.js';
7
+ import { TransactionType } from '../enums/TransactionType.js';
8
+ import { TapLeafScript } from '../interfaces/Tap.js';
9
+ import { CalldataGenerator } from '../../generators/builders/CalldataGenerator.js';
10
+ import { SharedInteractionParameters } from '../interfaces/ITransactionParameters.js';
11
+ export declare abstract class SharedInteractionTransaction<T extends TransactionType> extends TransactionBuilder<T> {
12
+ readonly randomBytes: Buffer;
13
+ protected targetScriptRedeem: Payment | null;
14
+ protected leftOverFundsScriptRedeem: Payment | null;
15
+ protected abstract readonly compiledTargetScript: Buffer;
16
+ protected abstract readonly scriptTree: Taptree;
17
+ protected tapLeafScript: TapLeafScript | null;
18
+ protected readonly calldataGenerator: CalldataGenerator;
19
+ protected readonly calldata: Buffer;
20
+ protected abstract readonly contractSecret: Buffer;
21
+ protected tweakedSigner?: Signer;
22
+ protected readonly scriptSigner: Signer;
23
+ protected readonly interactionPubKeys: Buffer[];
24
+ protected readonly minimumSignatures: number;
25
+ protected constructor(parameters: SharedInteractionParameters);
26
+ getContractSecret(): Buffer;
27
+ getRndBytes(): Buffer;
28
+ protected generateSecret(): Buffer;
29
+ protected tweakSigner(): void;
30
+ protected scriptSignerXOnlyPubKey(): Buffer;
31
+ protected generateKeyPairFromSeed(): ECPairInterface;
32
+ protected addInputsFromUTXO(): void;
33
+ protected buildTransaction(): void;
34
+ protected signInputs(transaction: Psbt): void;
35
+ protected getSignerKey(): Signer;
36
+ protected generateScriptAddress(): Payment;
37
+ protected generateTapData(): Payment;
38
+ protected getScriptSolution(input: PsbtInput): Buffer[];
39
+ protected getScriptTree(): Taptree;
40
+ private getPubKeys;
41
+ private customFinalizer;
42
+ private getTweakerHash;
43
+ private getTweakedSigner;
44
+ private generateRedeemScripts;
45
+ private getLeafScript;
46
+ }
@@ -0,0 +1,213 @@
1
+ import { address } from 'bitcoinjs-lib';
2
+ import { TransactionBuilder } from './TransactionBuilder.js';
3
+ import { CalldataGenerator } from '../../generators/builders/CalldataGenerator.js';
4
+ import { Compressor } from '../../bytecode/Compressor.js';
5
+ import { EcKeyPair } from '../../keypair/EcKeyPair.js';
6
+ import { BitcoinUtils } from '../../utils/BitcoinUtils.js';
7
+ import { toXOnly } from 'bitcoinjs-lib/src/psbt/bip371.js';
8
+ import { TweakedSigner } from '../../signer/TweakedSigner.js';
9
+ export class SharedInteractionTransaction extends TransactionBuilder {
10
+ randomBytes;
11
+ targetScriptRedeem = null;
12
+ leftOverFundsScriptRedeem = null;
13
+ tapLeafScript = null;
14
+ calldataGenerator;
15
+ calldata;
16
+ tweakedSigner;
17
+ scriptSigner;
18
+ interactionPubKeys = [];
19
+ minimumSignatures = 0;
20
+ constructor(parameters) {
21
+ super(parameters);
22
+ if (!parameters.calldata) {
23
+ throw new Error('Calldata is required');
24
+ }
25
+ this.calldata = Compressor.compress(parameters.calldata);
26
+ this.randomBytes = parameters.randomBytes || BitcoinUtils.rndBytes();
27
+ this.scriptSigner = this.generateKeyPairFromSeed();
28
+ this.calldataGenerator = new CalldataGenerator(this.internalPubKeyToXOnly(), this.scriptSignerXOnlyPubKey(), this.network);
29
+ }
30
+ getContractSecret() {
31
+ return this.contractSecret;
32
+ }
33
+ getRndBytes() {
34
+ return this.randomBytes;
35
+ }
36
+ generateSecret() {
37
+ if (!this.to)
38
+ throw new Error('To address is required');
39
+ return address.fromBech32(this.to).data;
40
+ }
41
+ tweakSigner() {
42
+ this.tweakedSigner = this.getTweakedSigner();
43
+ }
44
+ scriptSignerXOnlyPubKey() {
45
+ return toXOnly(this.scriptSigner.publicKey);
46
+ }
47
+ generateKeyPairFromSeed() {
48
+ return EcKeyPair.fromSeedKeyPair(this.randomBytes, this.network);
49
+ }
50
+ addInputsFromUTXO() {
51
+ if (!this.tapLeafScript)
52
+ throw new Error('Tap leaf script is required');
53
+ for (let utxo of this.utxos) {
54
+ const input = {
55
+ hash: utxo.transactionId,
56
+ index: utxo.outputIndex,
57
+ witnessUtxo: {
58
+ value: Number(utxo.value),
59
+ script: this.getTapOutput(),
60
+ },
61
+ tapLeafScript: [this.tapLeafScript],
62
+ sequence: this.sequence,
63
+ };
64
+ this.addInput(input);
65
+ }
66
+ }
67
+ buildTransaction() {
68
+ if (!this.to)
69
+ throw new Error('To address is required');
70
+ const selectedRedeem = !!this.scriptSigner
71
+ ? this.targetScriptRedeem
72
+ : this.leftOverFundsScriptRedeem;
73
+ if (!selectedRedeem) {
74
+ throw new Error('Left over funds script redeem is required');
75
+ }
76
+ if (!selectedRedeem.redeemVersion) {
77
+ throw new Error('Left over funds script redeem version is required');
78
+ }
79
+ if (!selectedRedeem.output) {
80
+ throw new Error('Left over funds script redeem output is required');
81
+ }
82
+ this.tapLeafScript = {
83
+ leafVersion: selectedRedeem.redeemVersion,
84
+ script: selectedRedeem.output,
85
+ controlBlock: this.getWitness(),
86
+ };
87
+ this.addInputsFromUTXO();
88
+ const amountSpent = this.getTransactionOPNetFee();
89
+ this.addOutput({
90
+ value: Number(amountSpent),
91
+ address: this.to,
92
+ });
93
+ this.addRefundOutput(amountSpent);
94
+ }
95
+ signInputs(transaction) {
96
+ if (!this.scriptSigner) {
97
+ super.signInputs(transaction);
98
+ return;
99
+ }
100
+ transaction.signInput(0, this.scriptSigner);
101
+ transaction.signInput(0, this.getSignerKey());
102
+ transaction.finalizeInput(0, this.customFinalizer);
103
+ }
104
+ getSignerKey() {
105
+ if (this.tweakedSigner) {
106
+ return this.tweakedSigner;
107
+ }
108
+ return this.signer;
109
+ }
110
+ generateScriptAddress() {
111
+ return {
112
+ internalPubkey: this.internalPubKeyToXOnly(),
113
+ network: this.network,
114
+ scriptTree: this.scriptTree,
115
+ };
116
+ }
117
+ generateTapData() {
118
+ const selectedRedeem = !!this.scriptSigner
119
+ ? this.targetScriptRedeem
120
+ : this.leftOverFundsScriptRedeem;
121
+ if (!selectedRedeem) {
122
+ throw new Error('Left over funds script redeem is required');
123
+ }
124
+ if (!this.scriptTree) {
125
+ throw new Error('Script tree is required');
126
+ }
127
+ return {
128
+ internalPubkey: this.internalPubKeyToXOnly(),
129
+ network: this.network,
130
+ scriptTree: this.scriptTree,
131
+ redeem: selectedRedeem,
132
+ };
133
+ }
134
+ getScriptSolution(input) {
135
+ if (!input.tapScriptSig) {
136
+ throw new Error('Tap script signature is required');
137
+ }
138
+ return [
139
+ this.contractSecret,
140
+ this.internalPubKeyToXOnly(),
141
+ input.tapScriptSig[0].signature,
142
+ input.tapScriptSig[1].signature,
143
+ ];
144
+ }
145
+ getScriptTree() {
146
+ if (!this.calldata) {
147
+ throw new Error('Calldata is required');
148
+ }
149
+ this.generateRedeemScripts();
150
+ return [
151
+ {
152
+ output: this.compiledTargetScript,
153
+ version: 192,
154
+ },
155
+ {
156
+ output: this.getLeafScript(),
157
+ version: 192,
158
+ },
159
+ ];
160
+ }
161
+ getPubKeys() {
162
+ const pubkeys = [this.signer.publicKey];
163
+ if (this.scriptSigner) {
164
+ pubkeys.push(this.scriptSigner.publicKey);
165
+ }
166
+ return pubkeys;
167
+ }
168
+ customFinalizer = (_inputIndex, input) => {
169
+ if (!this.tapLeafScript) {
170
+ throw new Error('Tap leaf script is required');
171
+ }
172
+ if (!input.tapScriptSig) {
173
+ throw new Error('Tap script signature is required');
174
+ }
175
+ if (!this.contractSecret) {
176
+ throw new Error('Contract secret is required');
177
+ }
178
+ const scriptSolution = this.getScriptSolution(input);
179
+ const witness = scriptSolution
180
+ .concat(this.tapLeafScript.script)
181
+ .concat(this.tapLeafScript.controlBlock);
182
+ return {
183
+ finalScriptWitness: this.witnessStackToScriptWitness(witness),
184
+ };
185
+ };
186
+ getTweakerHash() {
187
+ return this.tapData?.hash;
188
+ }
189
+ getTweakedSigner(useTweakedHash = false) {
190
+ const settings = {
191
+ network: this.network,
192
+ };
193
+ if (useTweakedHash) {
194
+ settings.tweakHash = this.getTweakerHash();
195
+ }
196
+ return TweakedSigner.tweakSigner(this.signer, settings);
197
+ }
198
+ generateRedeemScripts() {
199
+ this.targetScriptRedeem = {
200
+ pubkeys: this.getPubKeys(),
201
+ output: this.compiledTargetScript,
202
+ redeemVersion: 192,
203
+ };
204
+ this.leftOverFundsScriptRedeem = {
205
+ pubkeys: this.getPubKeys(),
206
+ output: this.getLeafScript(),
207
+ redeemVersion: 192,
208
+ };
209
+ }
210
+ getLeafScript() {
211
+ return SharedInteractionTransaction.LOCK_LEAF_SCRIPT;
212
+ }
213
+ }
@@ -5,13 +5,19 @@ import { TransactionType } from '../enums/TransactionType.js';
5
5
  import { IFundingTransactionParameters, ITransactionParameters } from '../interfaces/ITransactionParameters.js';
6
6
  import { Address } from '@btc-vision/bsi-binary';
7
7
  import { UTXO } from '../../utxo/interfaces/IUTXO.js';
8
+ import { ECPairInterface } from 'ecpair';
8
9
  import { Logger } from '@btc-vision/logger';
10
+ export declare enum TransactionSequence {
11
+ REPLACE_BY_FEE = 4294967293,
12
+ FINAL = 4294967295
13
+ }
9
14
  export declare abstract class TransactionBuilder<T extends TransactionType> extends Logger {
10
15
  static readonly LOCK_LEAF_SCRIPT: Buffer;
11
16
  static readonly MINIMUM_DUST: bigint;
12
17
  abstract readonly type: T;
13
18
  readonly logColor: string;
14
19
  transactionFee: bigint;
20
+ protected sequence: number;
15
21
  protected readonly transaction: Psbt;
16
22
  protected readonly inputs: PsbtInputExtended[];
17
23
  protected readonly updateInputs: UpdateInput[];
@@ -26,10 +32,11 @@ export declare abstract class TransactionBuilder<T extends TransactionType> exte
26
32
  protected readonly feeRate: number;
27
33
  protected readonly priorityFee: bigint;
28
34
  protected utxos: UTXO[];
29
- protected to: Address;
35
+ protected to: Address | undefined;
30
36
  protected from: Address;
31
37
  private _maximumFeeRate;
32
38
  protected constructor(parameters: ITransactionParameters);
39
+ static getFrom(from: string | undefined, keypair: ECPairInterface, network: Network): Address;
33
40
  getFundingTransactionParameters(): IFundingTransactionParameters;
34
41
  setDestinationAddress(address: Address): void;
35
42
  setMaximumFeeRate(feeRate: number): void;
@@ -1,9 +1,14 @@
1
1
  import { initEccLib, opcodes, payments, Psbt, script } from 'bitcoinjs-lib';
2
2
  import { varuint } from 'bitcoinjs-lib/src/bufferutils.js';
3
3
  import { toXOnly } from 'bitcoinjs-lib/src/psbt/bip371.js';
4
- import * as ecc from 'tiny-secp256k1';
4
+ import * as ecc from '@bitcoinerlab/secp256k1';
5
5
  import { EcKeyPair } from '../../keypair/EcKeyPair.js';
6
6
  import { Logger } from '@btc-vision/logger';
7
+ export var TransactionSequence;
8
+ (function (TransactionSequence) {
9
+ TransactionSequence[TransactionSequence["REPLACE_BY_FEE"] = 4294967293] = "REPLACE_BY_FEE";
10
+ TransactionSequence[TransactionSequence["FINAL"] = 4294967295] = "FINAL";
11
+ })(TransactionSequence || (TransactionSequence = {}));
7
12
  export class TransactionBuilder extends Logger {
8
13
  static LOCK_LEAF_SCRIPT = script.compile([
9
14
  opcodes.OP_0,
@@ -11,6 +16,7 @@ export class TransactionBuilder extends Logger {
11
16
  static MINIMUM_DUST = 330n;
12
17
  logColor = '#785def';
13
18
  transactionFee = 0n;
19
+ sequence = TransactionSequence.REPLACE_BY_FEE;
14
20
  transaction;
15
21
  inputs = [];
16
22
  updateInputs = [];
@@ -35,10 +41,8 @@ export class TransactionBuilder extends Logger {
35
41
  this.feeRate = parameters.feeRate;
36
42
  this.priorityFee = parameters.priorityFee;
37
43
  this.utxos = parameters.utxos;
38
- this.to = parameters.to;
39
- this.from =
40
- parameters.from ||
41
- EcKeyPair.getTaprootAddress(this.signer, this.network);
44
+ this.to = parameters.to || undefined;
45
+ this.from = TransactionBuilder.getFrom(parameters.from, this.signer, this.network);
42
46
  this.totalInputAmount = this.calculateTotalUTXOAmount();
43
47
  const totalVOut = this.calculateTotalVOutAmount();
44
48
  if (totalVOut < this.totalInputAmount) {
@@ -51,6 +55,9 @@ export class TransactionBuilder extends Logger {
51
55
  network: this.network,
52
56
  });
53
57
  }
58
+ static getFrom(from, keypair, network) {
59
+ return from || EcKeyPair.getTaprootAddress(keypair, network);
60
+ }
54
61
  getFundingTransactionParameters() {
55
62
  return {
56
63
  utxos: this.utxos,
@@ -60,7 +67,7 @@ export class TransactionBuilder extends Logger {
60
67
  feeRate: this.feeRate,
61
68
  priorityFee: this.priorityFee,
62
69
  from: this.from,
63
- childTransactionRequiredFees: this.transactionFee,
70
+ childTransactionRequiredValue: this.transactionFee,
64
71
  };
65
72
  }
66
73
  setDestinationAddress(address) {
@@ -70,10 +77,10 @@ export class TransactionBuilder extends Logger {
70
77
  this._maximumFeeRate = feeRate;
71
78
  }
72
79
  signTransaction() {
73
- if (!this.to)
74
- throw new Error('Transaction must have a recipient');
75
- if (!EcKeyPair.verifyContractAddress(this.to, this.network)) {
76
- throw new Error('Invalid contract address. The contract address must be a taproot address.');
80
+ if (this.to) {
81
+ if (!EcKeyPair.verifyContractAddress(this.to, this.network)) {
82
+ throw new Error('Invalid contract address. The contract address must be a taproot address.');
83
+ }
77
84
  }
78
85
  if (this.signed)
79
86
  throw new Error('Transaction is already signed');
@@ -97,8 +104,9 @@ export class TransactionBuilder extends Logger {
97
104
  disableRBF() {
98
105
  if (this.signed)
99
106
  throw new Error('Transaction is already signed');
107
+ this.sequence = TransactionSequence.FINAL;
100
108
  for (let input of this.inputs) {
101
- input.sequence = 0xffffffff;
109
+ input.sequence = TransactionSequence.FINAL;
102
110
  }
103
111
  }
104
112
  getTapAddress() {
@@ -156,7 +164,7 @@ export class TransactionBuilder extends Logger {
156
164
  value: Number(utxo.value),
157
165
  script: Buffer.from(utxo.scriptPubKey.hex, 'hex'),
158
166
  },
159
- sequence: 0xfffffffd,
167
+ sequence: this.sequence,
160
168
  };
161
169
  this.addInput(input);
162
170
  }
@@ -0,0 +1,27 @@
1
+ /// <reference types="node" />
2
+ import { Taptree } from 'bitcoinjs-lib/src/types.js';
3
+ import { TransactionType } from '../enums/TransactionType.js';
4
+ import { TapLeafScript } from '../interfaces/Tap.js';
5
+ import { IWrapParameters } from '../interfaces/ITransactionParameters.js';
6
+ import { SharedInteractionTransaction } from './SharedInteractionTransaction.js';
7
+ import { Address } from '@btc-vision/bsi-binary';
8
+ import { WrappedGeneration } from '../../wbtc/WrappedGenerationParameters.js';
9
+ export declare class WrapTransaction extends SharedInteractionTransaction<TransactionType.WBTC_WRAP> {
10
+ private static readonly WRAP_SELECTOR;
11
+ type: TransactionType.WBTC_WRAP;
12
+ readonly vault: Address;
13
+ readonly amount: bigint;
14
+ readonly receiver: Address;
15
+ protected readonly compiledTargetScript: Buffer;
16
+ protected readonly scriptTree: Taptree;
17
+ protected tapLeafScript: TapLeafScript | null;
18
+ protected readonly contractSecret: Buffer;
19
+ private readonly wbtc;
20
+ constructor(parameters: IWrapParameters);
21
+ private static generateMintCalldata;
22
+ verifyPublicKeysConstraints(generation: WrappedGeneration): boolean;
23
+ protected buildTransaction(): void;
24
+ private addVaultOutput;
25
+ private generateVaultAddress;
26
+ private generateChecksumSalt;
27
+ }