@btc-vision/transaction 1.0.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.
Files changed (270) hide show
  1. package/.babelrc +7 -0
  2. package/.gitattributes +2 -0
  3. package/.github/workflows/node.js.yml +22 -0
  4. package/.idea/codeStyles/Project.xml +56 -0
  5. package/.idea/codeStyles/codeStyleConfig.xml +5 -0
  6. package/.idea/inspectionProfiles/Project_Default.xml +6 -0
  7. package/.idea/jsLibraryMappings.xml +6 -0
  8. package/.idea/modules.xml +8 -0
  9. package/.idea/prettier.xml +6 -0
  10. package/.idea/transaction.iml +16 -0
  11. package/.idea/vcs.xml +6 -0
  12. package/.prettierrc.json +12 -0
  13. package/CONTRIBUTING.md +71 -0
  14. package/LICENSE.md +16 -0
  15. package/README.md +213 -0
  16. package/browser/873e754d6c7c6e9361f1.module.wasm +0 -0
  17. package/browser/_version.d.ts +1 -0
  18. package/browser/bytecode/Compressor.d.ts +6 -0
  19. package/browser/crypto/crypto-browser.d.ts +40 -0
  20. package/browser/crypto/crypto.d.ts +2 -0
  21. package/browser/generators/Generator.d.ts +12 -0
  22. package/browser/generators/builders/CalldataGenerator.d.ts +8 -0
  23. package/browser/generators/builders/DeploymentGenerator.d.ts +7 -0
  24. package/browser/index.d.ts +3 -0
  25. package/browser/index.js +2 -0
  26. package/browser/index.js.LICENSE.txt +23 -0
  27. package/browser/keypair/EcKeyPair.d.ts +24 -0
  28. package/browser/keypair/Wallet.d.ts +16 -0
  29. package/browser/keypair/interfaces/IWallet.d.ts +5 -0
  30. package/browser/metadata/ContractBaseMetadata.d.ts +9 -0
  31. package/browser/metadata/ContractMetadataManager.d.ts +1 -0
  32. package/browser/metadata/contracts/wBTC.d.ts +12 -0
  33. package/browser/network/NetworkInformation.d.ts +6 -0
  34. package/browser/opnet.d.ts +22 -0
  35. package/browser/scripts/Regtest.d.ts +2 -0
  36. package/browser/scripts/test.d.ts +1 -0
  37. package/browser/signer/TweakedSigner.d.ts +9 -0
  38. package/browser/transaction/TransactionBuilder.d.ts +1 -0
  39. package/browser/transaction/TransactionFactory.d.ts +4 -0
  40. package/browser/transaction/builders/FundingTransaction.d.ts +11 -0
  41. package/browser/transaction/builders/InteractionTransaction.d.ts +47 -0
  42. package/browser/transaction/builders/TransactionBuilder.d.ts +64 -0
  43. package/browser/transaction/enums/TransactionType.d.ts +7 -0
  44. package/browser/transaction/interfaces/ITransactionParameters.d.ts +33 -0
  45. package/browser/transaction/interfaces/Tap.d.ts +22 -0
  46. package/browser/utils/BitcoinUtils.d.ts +5 -0
  47. package/browser/utxo/UTXOManager.d.ts +7 -0
  48. package/browser/utxo/interfaces/IUTXO.d.ts +19 -0
  49. package/build/Utils.d.ts +0 -0
  50. package/build/Utils.js +1 -0
  51. package/build/_version.d.ts +1 -0
  52. package/build/_version.js +1 -0
  53. package/build/bytecode/Compressor.d.ts +6 -0
  54. package/build/bytecode/Compressor.js +13 -0
  55. package/build/contracts/ContractMetadataManager.d.ts +0 -0
  56. package/build/contracts/ContractMetadataManager.js +1 -0
  57. package/build/crypto/crypto.d.ts +2 -0
  58. package/build/crypto/crypto.js +1 -0
  59. package/build/generators/Generator.d.ts +12 -0
  60. package/build/generators/Generator.js +25 -0
  61. package/build/generators/builders/CalldataGenerator.d.ts +8 -0
  62. package/build/generators/builders/CalldataGenerator.js +79 -0
  63. package/build/generators/builders/DeploymentGenerator.d.ts +7 -0
  64. package/build/generators/builders/DeploymentGenerator.js +38 -0
  65. package/build/index.d.ts +3 -0
  66. package/build/index.js +3 -0
  67. package/build/keypair/EcKeyPair.d.ts +24 -0
  68. package/build/keypair/EcKeyPair.js +107 -0
  69. package/build/keypair/Wallet.d.ts +16 -0
  70. package/build/keypair/Wallet.js +30 -0
  71. package/build/keypair/interfaces/GeneratedWallet.d.ts +5 -0
  72. package/build/keypair/interfaces/GeneratedWallet.js +1 -0
  73. package/build/keypair/interfaces/IWallet.d.ts +5 -0
  74. package/build/keypair/interfaces/IWallet.js +1 -0
  75. package/build/metadata/ContractBaseMetadata.d.ts +9 -0
  76. package/build/metadata/ContractBaseMetadata.js +13 -0
  77. package/build/metadata/ContractMetadataManager.d.ts +1 -0
  78. package/build/metadata/ContractMetadataManager.js +9 -0
  79. package/build/metadata/contracts/ContractBase.d.ts +9 -0
  80. package/build/metadata/contracts/ContractBase.js +13 -0
  81. package/build/metadata/contracts/ContractBaseMetadata.d.ts +9 -0
  82. package/build/metadata/contracts/ContractBaseMetadata.js +13 -0
  83. package/build/metadata/contracts/ContractMetadataManager.d.ts +0 -0
  84. package/build/metadata/contracts/ContractMetadataManager.js +1 -0
  85. package/build/metadata/contracts/wBTC.d.ts +12 -0
  86. package/build/metadata/contracts/wBTC.js +26 -0
  87. package/build/network/NetworkConverter.d.ts +0 -0
  88. package/build/network/NetworkConverter.js +14 -0
  89. package/build/network/NetworkInformation.d.ts +6 -0
  90. package/build/network/NetworkInformation.js +1 -0
  91. package/build/opnet.d.ts +22 -0
  92. package/build/opnet.js +22 -0
  93. package/build/scripts/Regtest.d.ts +2 -0
  94. package/build/scripts/Regtest.js +15 -0
  95. package/build/scripts/test.d.ts +1 -0
  96. package/build/scripts/test.js +74 -0
  97. package/build/signer/Regtest.d.ts +2 -0
  98. package/build/signer/Regtest.js +15 -0
  99. package/build/signer/TweakedSigner.d.ts +9 -0
  100. package/build/signer/TweakedSigner.js +22 -0
  101. package/build/transaction/TransactionBuilder.d.ts +60 -0
  102. package/build/transaction/TransactionBuilder.js +244 -0
  103. package/build/transaction/TransactionFactory.d.ts +4 -0
  104. package/build/transaction/TransactionFactory.js +32 -0
  105. package/build/transaction/builders/FundingTransaction.d.ts +11 -0
  106. package/build/transaction/builders/FundingTransaction.js +23 -0
  107. package/build/transaction/builders/GenericTransaction.d.ts +11 -0
  108. package/build/transaction/builders/GenericTransaction.js +23 -0
  109. package/build/transaction/builders/InteractionTransaction.d.ts +47 -0
  110. package/build/transaction/builders/InteractionTransaction.js +219 -0
  111. package/build/transaction/builders/TransactionBuilder.d.ts +64 -0
  112. package/build/transaction/builders/TransactionBuilder.js +288 -0
  113. package/build/transaction/enums/TransactionType.d.ts +7 -0
  114. package/build/transaction/enums/TransactionType.js +8 -0
  115. package/build/transaction/interfaces/ITransactionParameters.d.ts +33 -0
  116. package/build/transaction/interfaces/ITransactionParameters.js +1 -0
  117. package/build/transaction/interfaces/ITransactions.d.ts +32 -0
  118. package/build/transaction/interfaces/ITransactions.js +1 -0
  119. package/build/transaction/interfaces/Tap.d.ts +22 -0
  120. package/build/transaction/interfaces/Tap.js +1 -0
  121. package/build/utils/BitcoinUtils.d.ts +5 -0
  122. package/build/utils/BitcoinUtils.js +9 -0
  123. package/build/utxo/IUTXO.d.ts +0 -0
  124. package/build/utxo/IUTXO.js +1 -0
  125. package/build/utxo/UTXOManager.d.ts +7 -0
  126. package/build/utxo/UTXOManager.js +47 -0
  127. package/build/utxo/interfaces/IUTXO.d.ts +19 -0
  128. package/build/utxo/interfaces/IUTXO.js +1 -0
  129. package/cjs/_version.d.ts +1 -0
  130. package/cjs/_version.js +4 -0
  131. package/cjs/bytecode/Compressor.d.ts +6 -0
  132. package/cjs/bytecode/Compressor.js +20 -0
  133. package/cjs/crypto/crypto.d.ts +2 -0
  134. package/cjs/crypto/crypto.js +8 -0
  135. package/cjs/generators/Generator.d.ts +13 -0
  136. package/cjs/generators/Generator.js +31 -0
  137. package/cjs/generators/builders/CalldataGenerator.d.ts +8 -0
  138. package/cjs/generators/builders/CalldataGenerator.js +83 -0
  139. package/cjs/generators/builders/DeploymentGenerator.d.ts +7 -0
  140. package/cjs/generators/builders/DeploymentGenerator.js +42 -0
  141. package/cjs/index.d.ts +3 -0
  142. package/cjs/index.js +32 -0
  143. package/cjs/keypair/EcKeyPair.d.ts +24 -0
  144. package/cjs/keypair/EcKeyPair.js +137 -0
  145. package/cjs/keypair/Wallet.d.ts +16 -0
  146. package/cjs/keypair/Wallet.js +34 -0
  147. package/cjs/keypair/interfaces/IWallet.d.ts +5 -0
  148. package/cjs/keypair/interfaces/IWallet.js +2 -0
  149. package/cjs/metadata/ContractBaseMetadata.d.ts +9 -0
  150. package/cjs/metadata/ContractBaseMetadata.js +17 -0
  151. package/cjs/metadata/ContractMetadataManager.d.ts +0 -0
  152. package/cjs/metadata/ContractMetadataManager.js +1 -0
  153. package/cjs/metadata/contracts/wBTC.d.ts +12 -0
  154. package/cjs/metadata/contracts/wBTC.js +30 -0
  155. package/cjs/network/NetworkInformation.d.ts +6 -0
  156. package/cjs/network/NetworkInformation.js +2 -0
  157. package/cjs/opnet.d.ts +1 -0
  158. package/cjs/opnet.js +5 -0
  159. package/cjs/scripts/Regtest.d.ts +2 -0
  160. package/cjs/scripts/Regtest.js +18 -0
  161. package/cjs/scripts/test.d.ts +1 -0
  162. package/cjs/scripts/test.js +44 -0
  163. package/cjs/signer/TweakedSigner.d.ts +9 -0
  164. package/cjs/signer/TweakedSigner.js +49 -0
  165. package/cjs/transaction/TransactionBuilder.d.ts +0 -0
  166. package/cjs/transaction/TransactionBuilder.js +1 -0
  167. package/cjs/transaction/TransactionFactory.d.ts +4 -0
  168. package/cjs/transaction/TransactionFactory.js +33 -0
  169. package/cjs/transaction/builders/FundingTransaction.d.ts +11 -0
  170. package/cjs/transaction/builders/FundingTransaction.js +27 -0
  171. package/cjs/transaction/builders/InteractionTransaction.d.ts +45 -0
  172. package/cjs/transaction/builders/InteractionTransaction.js +214 -0
  173. package/cjs/transaction/builders/TransactionBuilder.d.ts +64 -0
  174. package/cjs/transaction/builders/TransactionBuilder.js +304 -0
  175. package/cjs/transaction/enums/TransactionType.d.ts +7 -0
  176. package/cjs/transaction/enums/TransactionType.js +11 -0
  177. package/cjs/transaction/interfaces/ITransactionParameters.d.ts +32 -0
  178. package/cjs/transaction/interfaces/ITransactionParameters.js +2 -0
  179. package/cjs/transaction/interfaces/Tap.d.ts +22 -0
  180. package/cjs/transaction/interfaces/Tap.js +2 -0
  181. package/cjs/utils/BitcoinUtils.d.ts +5 -0
  182. package/cjs/utils/BitcoinUtils.js +13 -0
  183. package/cjs/utxo/UTXOManager.d.ts +7 -0
  184. package/cjs/utxo/UTXOManager.js +51 -0
  185. package/cjs/utxo/interfaces/IUTXO.d.ts +19 -0
  186. package/cjs/utxo/interfaces/IUTXO.js +2 -0
  187. package/docs/.nojekyll +1 -0
  188. package/docs/assets/highlight.css +92 -0
  189. package/docs/assets/icons.js +15 -0
  190. package/docs/assets/icons.svg +1 -0
  191. package/docs/assets/main.js +59 -0
  192. package/docs/assets/material-style.css +247 -0
  193. package/docs/assets/navigation.js +1 -0
  194. package/docs/assets/search.js +1 -0
  195. package/docs/assets/style.css +1412 -0
  196. package/docs/classes/BitcoinUtils.html +183 -0
  197. package/docs/classes/CalldataGenerator.html +211 -0
  198. package/docs/classes/Compressor.html +185 -0
  199. package/docs/classes/ContractBaseMetadata.html +182 -0
  200. package/docs/classes/DeploymentGenerator.html +200 -0
  201. package/docs/classes/EcKeyPair.html +280 -0
  202. package/docs/classes/FundingTransaction.html +293 -0
  203. package/docs/classes/Generator.html +199 -0
  204. package/docs/classes/InteractionTransaction.html +365 -0
  205. package/docs/classes/TransactionBuilder.html +303 -0
  206. package/docs/classes/TransactionFactory.html +180 -0
  207. package/docs/classes/TweakedSigner.html +181 -0
  208. package/docs/classes/UTXOManager.html +187 -0
  209. package/docs/classes/Wallet.html +191 -0
  210. package/docs/classes/wBTC.html +189 -0
  211. package/docs/enums/TransactionType.html +179 -0
  212. package/docs/hierarchy.html +174 -0
  213. package/docs/index.html +237 -0
  214. package/docs/interfaces/FetchUTXOParams.html +178 -0
  215. package/docs/interfaces/IFundingTransactionParameters.html +182 -0
  216. package/docs/interfaces/IInteractionParameters.html +185 -0
  217. package/docs/interfaces/ITransactionDataContractDeployment.html +184 -0
  218. package/docs/interfaces/ITransactionDataContractInteractionWrap.html +186 -0
  219. package/docs/interfaces/ITransactionParameters.html +181 -0
  220. package/docs/interfaces/IWallet.html +181 -0
  221. package/docs/interfaces/NetworkInformation.html +176 -0
  222. package/docs/interfaces/PsbtInputExtended.html +194 -0
  223. package/docs/interfaces/PsbtOutputExtendedAddress.html +183 -0
  224. package/docs/interfaces/PsbtOutputExtendedScript.html +183 -0
  225. package/docs/interfaces/RawUTXOResponse.html +178 -0
  226. package/docs/interfaces/TapLeafScript.html +177 -0
  227. package/docs/interfaces/TweakSettings.html +179 -0
  228. package/docs/interfaces/UTXO.html +178 -0
  229. package/docs/interfaces/UpdateInput.html +175 -0
  230. package/docs/modules.html +208 -0
  231. package/docs/types/PsbtOutputExtended.html +174 -0
  232. package/docs/variables/version.html +174 -0
  233. package/gulpfile.js +152 -0
  234. package/jest.config.ts +52 -0
  235. package/package.json +116 -0
  236. package/src/_version.ts +1 -0
  237. package/src/bytecode/Compressor.ts +27 -0
  238. package/src/crypto/crypto-browser.js +71 -0
  239. package/src/crypto/crypto.ts +1 -0
  240. package/src/generators/Generator.ts +75 -0
  241. package/src/generators/builders/CalldataGenerator.ts +143 -0
  242. package/src/generators/builders/DeploymentGenerator.ts +63 -0
  243. package/src/index.ts +4 -0
  244. package/src/keypair/EcKeyPair.ts +265 -0
  245. package/src/keypair/Wallet.ts +75 -0
  246. package/src/keypair/interfaces/IWallet.ts +19 -0
  247. package/src/metadata/ContractBaseMetadata.ts +23 -0
  248. package/src/metadata/contracts/wBTC.ts +44 -0
  249. package/src/network/NetworkInformation.ts +7 -0
  250. package/src/opnet.ts +42 -0
  251. package/src/scripts/Regtest.ts +19 -0
  252. package/src/scripts/test.ts +98 -0
  253. package/src/signer/TweakedSigner.ts +57 -0
  254. package/src/transaction/TransactionFactory.ts +57 -0
  255. package/src/transaction/builders/FundingTransaction.ts +36 -0
  256. package/src/transaction/builders/InteractionTransaction.ts +439 -0
  257. package/src/transaction/builders/TransactionBuilder.ts +603 -0
  258. package/src/transaction/enums/TransactionType.ts +7 -0
  259. package/src/transaction/interfaces/ITransactionParameters.ts +41 -0
  260. package/src/transaction/interfaces/Tap.ts +26 -0
  261. package/src/utils/BitcoinUtils.ts +24 -0
  262. package/src/utxo/UTXOManager.ts +67 -0
  263. package/src/utxo/interfaces/IUTXO.ts +22 -0
  264. package/tests/TransactionBuilder.test.ts +58 -0
  265. package/tests/contracts/wbtc.wasm +0 -0
  266. package/tsconfig.base.json +43 -0
  267. package/tsconfig.cjs.json +9 -0
  268. package/tsconfig.json +8 -0
  269. package/tsconfig.webpack.json +11 -0
  270. package/webpack.config.js +77 -0
@@ -0,0 +1,439 @@
1
+ import { PsbtInput } from 'bip174/src/lib/interfaces.js';
2
+ import { address, Payment, Psbt, Signer } from 'bitcoinjs-lib';
3
+ import { Taptree } from 'bitcoinjs-lib/src/types.js';
4
+ import { ECPairInterface } from 'ecpair';
5
+ import { TransactionBuilder } from './TransactionBuilder.js';
6
+ import { TransactionType } from '../enums/TransactionType.js';
7
+ import { PsbtInputExtended, TapLeafScript } from '../interfaces/Tap.js';
8
+ import { CalldataGenerator } from '../../generators/builders/CalldataGenerator.js';
9
+ import { IInteractionParameters } from '../interfaces/ITransactionParameters.js';
10
+ import { Compressor } from '../../bytecode/Compressor.js';
11
+ import { EcKeyPair } from '../../keypair/EcKeyPair.js';
12
+ import { BitcoinUtils } from '../../utils/BitcoinUtils.js';
13
+ import { toXOnly } from 'bitcoinjs-lib/src/psbt/bip371.js';
14
+ import { TweakedSigner, TweakSettings } from '../../signer/TweakedSigner.js';
15
+
16
+ /**
17
+ * Class for interaction transactions
18
+ * @class InteractionTransaction
19
+ */
20
+ export class InteractionTransaction extends TransactionBuilder<TransactionType.INTERACTION> {
21
+ public type: TransactionType.INTERACTION = TransactionType.INTERACTION;
22
+
23
+ /**
24
+ * Random salt for the interaction
25
+ * @type {Buffer}
26
+ */
27
+ public readonly randomBytes: Buffer;
28
+
29
+ protected targetScriptRedeem: Payment | null = null;
30
+ protected leftOverFundsScriptRedeem: Payment | null = null;
31
+
32
+ protected readonly compiledTargetScript: Buffer;
33
+ protected readonly scriptTree: Taptree;
34
+
35
+ protected tapLeafScript: TapLeafScript | null = null;
36
+ protected calldataGenerator: CalldataGenerator;
37
+
38
+ /**
39
+ * Calldata for the interaction
40
+ * @protected
41
+ */
42
+ protected readonly calldata: Buffer;
43
+
44
+ /**
45
+ * Contract secret for the interaction
46
+ * @protected
47
+ */
48
+ protected readonly contractSecret: Buffer = this.generateSecret();
49
+
50
+ /**
51
+ * The tweaked signer for the interaction (if any)
52
+ * @protected
53
+ */
54
+ protected tweakedSigner?: Signer;
55
+
56
+ /**
57
+ * Script signer for the interaction
58
+ * @protected
59
+ */
60
+ protected readonly scriptSigner: Signer;
61
+
62
+ /**
63
+ * Public keys specified in the interaction
64
+ * @protected
65
+ */
66
+ protected readonly interactionPubKeys: Buffer[];
67
+
68
+ /**
69
+ * Minimum signatures required for the interaction
70
+ * @protected
71
+ */
72
+ protected readonly minimumSignatures: number;
73
+
74
+ public constructor(parameters: IInteractionParameters) {
75
+ super(parameters);
76
+
77
+ if (!parameters.calldata) {
78
+ throw new Error('Calldata is required');
79
+ }
80
+
81
+ this.calldata = Compressor.compress(parameters.calldata);
82
+ this.interactionPubKeys = parameters.pubKeys || [];
83
+ this.minimumSignatures = parameters.minimumSignatures || 0;
84
+
85
+ this.randomBytes = parameters.randomBytes || BitcoinUtils.rndBytes();
86
+ this.scriptSigner = this.generateKeyPairFromSeed();
87
+
88
+ this.calldataGenerator = new CalldataGenerator(
89
+ this.internalPubKeyToXOnly(),
90
+ this.scriptSignerXOnlyPubKey(),
91
+ this.network,
92
+ );
93
+
94
+ this.compiledTargetScript = this.calldataGenerator.compile(
95
+ this.calldata,
96
+ this.contractSecret,
97
+ this.interactionPubKeys,
98
+ this.minimumSignatures,
99
+ );
100
+
101
+ this.scriptTree = this.getScriptTree();
102
+ this.internalInit();
103
+ }
104
+
105
+ /**
106
+ * Get the contract secret
107
+ * @returns {Buffer} The contract secret
108
+ */
109
+ public getContractSecret(): Buffer {
110
+ return this.contractSecret;
111
+ }
112
+
113
+ /**
114
+ * Get the random bytes used for the interaction
115
+ * @returns {Buffer} The random bytes
116
+ */
117
+ public getRndBytes(): Buffer {
118
+ return this.randomBytes;
119
+ }
120
+
121
+ /**
122
+ * Generate the secret for the interaction
123
+ * @protected
124
+ * @returns {Buffer} The secret
125
+ * @throws {Error} If the to address is invalid
126
+ */
127
+ protected generateSecret(): Buffer {
128
+ return address.fromBech32(this.to).data;
129
+ }
130
+
131
+ /**
132
+ * Tweak the signer for the interaction
133
+ * @protected
134
+ */
135
+ protected tweakSigner(): void {
136
+ this.tweakedSigner = this.getTweakedSigner();
137
+ }
138
+
139
+ /**
140
+ * Get the internal pubkey as an x-only key
141
+ * @protected
142
+ * @returns {Buffer} The internal pubkey as an x-only key
143
+ */
144
+ protected scriptSignerXOnlyPubKey(): Buffer {
145
+ return toXOnly(this.scriptSigner.publicKey);
146
+ }
147
+
148
+ /**
149
+ * Generate a key pair from the seed
150
+ * @protected
151
+ *
152
+ * @returns {ECPairInterface} The key pair
153
+ */
154
+ protected generateKeyPairFromSeed(): ECPairInterface {
155
+ return EcKeyPair.fromSeedKeyPair(this.randomBytes, this.network);
156
+ }
157
+
158
+ /**
159
+ * Add inputs from the UTXO
160
+ * @protected
161
+ *
162
+ * @throws {Error} If the tap leaf script is required
163
+ */
164
+ protected override addInputsFromUTXO(): void {
165
+ if (!this.tapLeafScript) throw new Error('Tap leaf script is required');
166
+
167
+ for (let utxo of this.utxos) {
168
+ const input: PsbtInputExtended = {
169
+ hash: utxo.transactionId,
170
+ index: utxo.outputIndex,
171
+ witnessUtxo: {
172
+ value: Number(utxo.value),
173
+ script: this.getTapOutput(),
174
+ },
175
+ tapLeafScript: [this.tapLeafScript],
176
+ sequence: 0xfffffffd,
177
+ };
178
+
179
+ this.addInput(input);
180
+ }
181
+ }
182
+
183
+ /**
184
+ * Build the transaction
185
+ * @protected
186
+ *
187
+ * @throws {Error} If the left over funds script redeem is required
188
+ * @throws {Error} If the left over funds script redeem version is required
189
+ * @throws {Error} If the left over funds script redeem output is required
190
+ */
191
+ protected override buildTransaction(): void {
192
+ const selectedRedeem = !!this.scriptSigner
193
+ ? this.targetScriptRedeem
194
+ : this.leftOverFundsScriptRedeem;
195
+
196
+ if (!selectedRedeem) {
197
+ throw new Error('Left over funds script redeem is required');
198
+ }
199
+
200
+ if (!selectedRedeem.redeemVersion) {
201
+ throw new Error('Left over funds script redeem version is required');
202
+ }
203
+
204
+ if (!selectedRedeem.output) {
205
+ throw new Error('Left over funds script redeem output is required');
206
+ }
207
+
208
+ this.tapLeafScript = {
209
+ leafVersion: selectedRedeem.redeemVersion,
210
+ script: selectedRedeem.output,
211
+ controlBlock: this.getWitness(),
212
+ };
213
+
214
+ this.addInputsFromUTXO();
215
+
216
+ const amountSpent: bigint = this.getTransactionOPNetFee();
217
+ this.addOutput({
218
+ value: Number(amountSpent),
219
+ address: this.to,
220
+ });
221
+
222
+ this.addRefundOutput(amountSpent);
223
+ }
224
+
225
+ /**
226
+ * Sign the inputs
227
+ * @param {Psbt} transaction The transaction to sign
228
+ * @protected
229
+ */
230
+ protected signInputs(transaction: Psbt): void {
231
+ if (!this.scriptSigner) {
232
+ super.signInputs(transaction);
233
+
234
+ return;
235
+ }
236
+
237
+ transaction.signInput(0, this.scriptSigner);
238
+ transaction.signInput(0, this.getSignerKey());
239
+
240
+ transaction.finalizeInput(0, this.customFinalizer);
241
+ }
242
+
243
+ /**
244
+ * Get the signer
245
+ * @protected
246
+ *
247
+ * @returns {Signer} The signer
248
+ */
249
+ protected getSignerKey(): Signer {
250
+ if (this.tweakedSigner) {
251
+ return this.tweakedSigner;
252
+ }
253
+
254
+ return this.signer;
255
+ }
256
+
257
+ protected override generateScriptAddress(): Payment {
258
+ return {
259
+ internalPubkey: this.internalPubKeyToXOnly(),
260
+ network: this.network,
261
+ scriptTree: this.scriptTree,
262
+ };
263
+ }
264
+
265
+ protected override generateTapData(): Payment {
266
+ const selectedRedeem = !!this.scriptSigner
267
+ ? this.targetScriptRedeem
268
+ : this.leftOverFundsScriptRedeem;
269
+
270
+ if (!selectedRedeem) {
271
+ throw new Error('Left over funds script redeem is required');
272
+ }
273
+
274
+ if (!this.scriptTree) {
275
+ throw new Error('Script tree is required');
276
+ }
277
+
278
+ return {
279
+ internalPubkey: this.internalPubKeyToXOnly(),
280
+ network: this.network,
281
+ scriptTree: this.scriptTree,
282
+ redeem: selectedRedeem,
283
+ };
284
+ }
285
+
286
+ /**
287
+ * Generate the script solution
288
+ * @param {PsbtInput} input The input
289
+ * @protected
290
+ *
291
+ * @returns {Buffer[]} The script solution
292
+ */
293
+ protected getScriptSolution(input: PsbtInput): Buffer[] {
294
+ if (!input.tapScriptSig) {
295
+ throw new Error('Tap script signature is required');
296
+ }
297
+
298
+ return [
299
+ this.contractSecret,
300
+ this.internalPubKeyToXOnly(),
301
+ input.tapScriptSig[0].signature,
302
+ input.tapScriptSig[1].signature,
303
+ ];
304
+ }
305
+
306
+ /**
307
+ * Get the public keys
308
+ * @private
309
+ *
310
+ * @returns {Buffer[]} The public keys
311
+ */
312
+ private getPubKeys(): Buffer[] {
313
+ const pubkeys = [this.signer.publicKey];
314
+
315
+ if (this.scriptSigner) {
316
+ pubkeys.push(this.scriptSigner.publicKey);
317
+ }
318
+
319
+ return pubkeys;
320
+ }
321
+
322
+ /**
323
+ * Transaction finalizer
324
+ * @param {number} _inputIndex The input index
325
+ * @param {PsbtInput} input The input
326
+ */
327
+ private customFinalizer = (_inputIndex: number, input: PsbtInput) => {
328
+ if (!this.tapLeafScript) {
329
+ throw new Error('Tap leaf script is required');
330
+ }
331
+
332
+ if (!input.tapScriptSig) {
333
+ throw new Error('Tap script signature is required');
334
+ }
335
+
336
+ if (!this.contractSecret) {
337
+ throw new Error('Contract secret is required');
338
+ }
339
+
340
+ const scriptSolution = this.getScriptSolution(input);
341
+
342
+ const witness = scriptSolution
343
+ .concat(this.tapLeafScript.script)
344
+ .concat(this.tapLeafScript.controlBlock);
345
+
346
+ return {
347
+ finalScriptWitness: this.witnessStackToScriptWitness(witness),
348
+ };
349
+ };
350
+
351
+ /**
352
+ * Get the tweaked hash
353
+ * @private
354
+ *
355
+ * @returns {Buffer | undefined} The tweaked hash
356
+ */
357
+ private getTweakerHash(): Buffer | undefined {
358
+ return this.tapData?.hash;
359
+ }
360
+
361
+ /**
362
+ * Get the tweaked signer
363
+ * @param {boolean} useTweakedHash Whether to use the tweaked hash
364
+ * @private
365
+ *
366
+ * @returns {Signer} The tweaked signer
367
+ */
368
+ private getTweakedSigner(useTweakedHash: boolean = false): Signer {
369
+ const settings: TweakSettings = {
370
+ network: this.network,
371
+ };
372
+
373
+ if (useTweakedHash) {
374
+ settings.tweakHash = this.getTweakerHash();
375
+ }
376
+
377
+ return TweakedSigner.tweakSigner(this.signer, settings);
378
+ }
379
+
380
+ /**
381
+ * Generate the redeem scripts
382
+ * @private
383
+ *
384
+ * @throws {Error} If the public keys are required
385
+ * @throws {Error} If the leaf script is required
386
+ * @throws {Error} If the leaf script version is required
387
+ * @throws {Error} If the leaf script output is required
388
+ * @throws {Error} If the target script redeem is required
389
+ */
390
+ private generateRedeemScripts(): void {
391
+ this.targetScriptRedeem = {
392
+ pubkeys: this.getPubKeys(),
393
+ output: this.compiledTargetScript,
394
+ redeemVersion: 192,
395
+ };
396
+
397
+ this.leftOverFundsScriptRedeem = {
398
+ pubkeys: this.getPubKeys(),
399
+ output: this.getLeafScript(),
400
+ redeemVersion: 192,
401
+ };
402
+ }
403
+
404
+ /**
405
+ * Get the second leaf script
406
+ * @private
407
+ *
408
+ * @returns {Buffer} The leaf script
409
+ */
410
+ private getLeafScript(): Buffer {
411
+ // For now, we disable this.
412
+ return InteractionTransaction.LOCK_LEAF_SCRIPT;
413
+ }
414
+
415
+ /**
416
+ * Get the script tree
417
+ * @private
418
+ *
419
+ * @returns {Taptree} The script tree
420
+ */
421
+ private getScriptTree(): Taptree {
422
+ if (!this.calldata) {
423
+ throw new Error('Calldata is required');
424
+ }
425
+
426
+ this.generateRedeemScripts();
427
+
428
+ return [
429
+ {
430
+ output: this.compiledTargetScript,
431
+ version: 192,
432
+ },
433
+ {
434
+ output: this.getLeafScript(),
435
+ version: 192,
436
+ },
437
+ ];
438
+ }
439
+ }