@btc-vision/transaction 1.8.0-rc.1 → 1.8.0-rc.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.
Files changed (166) hide show
  1. package/browser/_version.d.ts +1 -1
  2. package/browser/_version.d.ts.map +1 -1
  3. package/browser/btc-vision-bitcoin.js +3560 -3170
  4. package/browser/buffer/BinaryWriter.d.ts +1 -1
  5. package/browser/buffer/BinaryWriter.d.ts.map +1 -1
  6. package/browser/bytecode/Compressor.d.ts +6 -6
  7. package/browser/bytecode/Compressor.d.ts.map +1 -1
  8. package/browser/epoch/ChallengeSolution.d.ts +14 -14
  9. package/browser/epoch/ChallengeSolution.d.ts.map +1 -1
  10. package/browser/generators/MLDSAData.d.ts +4 -4
  11. package/browser/generators/MLDSAData.d.ts.map +1 -1
  12. package/browser/index.js +966 -967
  13. package/browser/noble-curves.js +1 -1
  14. package/browser/noble-hashes.js +867 -1758
  15. package/browser/transaction/browser/types/Unisat.d.ts +1 -1
  16. package/browser/transaction/browser/types/Unisat.d.ts.map +1 -1
  17. package/browser/transaction/builders/CustomScriptTransaction.d.ts +1 -1
  18. package/browser/transaction/builders/DeploymentTransaction.d.ts +2 -2
  19. package/browser/transaction/builders/MultiSignTransaction.d.ts +5 -5
  20. package/browser/transaction/builders/SharedInteractionTransaction.d.ts +5 -5
  21. package/browser/transaction/builders/TransactionBuilder.d.ts +4 -4
  22. package/browser/transaction/offline/OfflineTransactionManager.d.ts +1 -1
  23. package/browser/transaction/shared/P2TR_MS.d.ts +1 -1
  24. package/browser/transaction/shared/TweakedTransaction.d.ts +2 -2
  25. package/browser/transaction/shared/TweakedTransaction.d.ts.map +1 -1
  26. package/browser/utils/BitcoinUtils.d.ts +5 -5
  27. package/browser/utils/BitcoinUtils.d.ts.map +1 -1
  28. package/browser/utils/BufferHelper.d.ts +1 -1
  29. package/browser/utils/BufferHelper.d.ts.map +1 -1
  30. package/browser/utils/StringToBuffer.d.ts +1 -1
  31. package/browser/utils/StringToBuffer.d.ts.map +1 -1
  32. package/browser/utils/types.d.ts +1 -1
  33. package/browser/utils/types.d.ts.map +1 -1
  34. package/browser/utxo/OPNetLimitedProvider.d.ts.map +1 -1
  35. package/browser/vendors.js +7732 -13160
  36. package/build/_version.d.ts +1 -1
  37. package/build/_version.d.ts.map +1 -1
  38. package/build/_version.js +1 -1
  39. package/build/_version.js.map +1 -1
  40. package/build/abi/ABICoder.js +3 -3
  41. package/build/abi/ABICoder.js.map +1 -1
  42. package/build/buffer/BinaryReader.js +1 -1
  43. package/build/buffer/BinaryReader.js.map +1 -1
  44. package/build/buffer/BinaryWriter.d.ts +1 -1
  45. package/build/buffer/BinaryWriter.d.ts.map +1 -1
  46. package/build/buffer/BinaryWriter.js.map +1 -1
  47. package/build/bytecode/Compressor.d.ts +6 -6
  48. package/build/bytecode/Compressor.d.ts.map +1 -1
  49. package/build/bytecode/Compressor.js +6 -6
  50. package/build/bytecode/Compressor.js.map +1 -1
  51. package/build/epoch/ChallengeSolution.d.ts +14 -14
  52. package/build/epoch/ChallengeSolution.d.ts.map +1 -1
  53. package/build/epoch/ChallengeSolution.js +11 -10
  54. package/build/epoch/ChallengeSolution.js.map +1 -1
  55. package/build/generators/MLDSAData.d.ts +4 -4
  56. package/build/generators/MLDSAData.d.ts.map +1 -1
  57. package/build/transaction/browser/types/Unisat.d.ts +1 -1
  58. package/build/transaction/browser/types/Unisat.d.ts.map +1 -1
  59. package/build/transaction/builders/CancelTransaction.js +1 -1
  60. package/build/transaction/builders/CancelTransaction.js.map +1 -1
  61. package/build/transaction/builders/ChallengeSolutionTransaction.js +5 -5
  62. package/build/transaction/builders/CustomScriptTransaction.d.ts +1 -1
  63. package/build/transaction/builders/CustomScriptTransaction.js +1 -1
  64. package/build/transaction/builders/DeploymentTransaction.d.ts +2 -2
  65. package/build/transaction/builders/DeploymentTransaction.js +2 -2
  66. package/build/transaction/builders/MultiSignTransaction.d.ts +5 -5
  67. package/build/transaction/builders/MultiSignTransaction.js +5 -5
  68. package/build/transaction/builders/SharedInteractionTransaction.d.ts +5 -5
  69. package/build/transaction/builders/SharedInteractionTransaction.js +5 -5
  70. package/build/transaction/builders/TransactionBuilder.d.ts +4 -4
  71. package/build/transaction/builders/TransactionBuilder.js +4 -4
  72. package/build/transaction/offline/OfflineTransactionManager.d.ts +1 -1
  73. package/build/transaction/offline/OfflineTransactionManager.js +1 -1
  74. package/build/transaction/shared/P2TR_MS.d.ts +1 -1
  75. package/build/transaction/shared/P2TR_MS.js +1 -1
  76. package/build/transaction/shared/TweakedTransaction.d.ts +2 -2
  77. package/build/transaction/shared/TweakedTransaction.d.ts.map +1 -1
  78. package/build/transaction/shared/TweakedTransaction.js +2 -13
  79. package/build/transaction/shared/TweakedTransaction.js.map +1 -1
  80. package/build/tsconfig.build.tsbuildinfo +1 -1
  81. package/build/utils/BitcoinUtils.d.ts +5 -5
  82. package/build/utils/BitcoinUtils.d.ts.map +1 -1
  83. package/build/utils/BitcoinUtils.js +7 -7
  84. package/build/utils/BitcoinUtils.js.map +1 -1
  85. package/build/utils/BufferHelper.d.ts +1 -1
  86. package/build/utils/BufferHelper.d.ts.map +1 -1
  87. package/build/utils/BufferHelper.js.map +1 -1
  88. package/build/utils/StringToBuffer.d.ts +1 -1
  89. package/build/utils/StringToBuffer.d.ts.map +1 -1
  90. package/build/utils/StringToBuffer.js +2 -1
  91. package/build/utils/StringToBuffer.js.map +1 -1
  92. package/build/utils/types.d.ts +1 -1
  93. package/build/utils/types.d.ts.map +1 -1
  94. package/build/utxo/OPNetLimitedProvider.d.ts +1 -1
  95. package/build/utxo/OPNetLimitedProvider.d.ts.map +1 -1
  96. package/build/utxo/OPNetLimitedProvider.js +2 -1
  97. package/build/utxo/OPNetLimitedProvider.js.map +1 -1
  98. package/documentation/README.md +322 -25
  99. package/documentation/abi/abi-coder.md +440 -0
  100. package/documentation/addresses/address-types.md +459 -0
  101. package/documentation/api-reference/interfaces.md +806 -0
  102. package/documentation/api-reference/response-types.md +480 -0
  103. package/documentation/api-reference/transaction-types.md +348 -0
  104. package/documentation/binary/binary-reader.md +526 -0
  105. package/documentation/binary/binary-writer.md +484 -0
  106. package/documentation/browser/wallet-extensions.md +278 -0
  107. package/documentation/browser/web3-provider.md +300 -0
  108. package/documentation/deterministic/deterministic-collections.md +489 -0
  109. package/documentation/epoch/challenge-solution.md +462 -0
  110. package/documentation/epoch/epoch-validator.md +316 -0
  111. package/documentation/generators/generators.md +636 -0
  112. package/documentation/getting-started/installation.md +256 -0
  113. package/documentation/getting-started/overview.md +348 -0
  114. package/documentation/getting-started/quick-start.md +582 -0
  115. package/documentation/keypair/address-verificator.md +459 -0
  116. package/documentation/keypair/address.md +702 -0
  117. package/documentation/keypair/ec-keypair.md +558 -0
  118. package/documentation/keypair/message-signer.md +840 -0
  119. package/documentation/keypair/mnemonic.md +560 -0
  120. package/documentation/keypair/wallet.md +401 -0
  121. package/documentation/offline/offline-transaction-signing.md +819 -0
  122. package/documentation/quantum-support/04-message-signing.md +244 -10
  123. package/documentation/signer/address-rotation.md +419 -0
  124. package/documentation/signer/parallel-signer.md +245 -0
  125. package/documentation/signer/tweaked-signer.md +214 -0
  126. package/documentation/transaction-building/cancel-transactions.md +285 -0
  127. package/documentation/transaction-building/consolidated-transactions.md +441 -0
  128. package/documentation/transaction-building/custom-script-transactions.md +280 -0
  129. package/documentation/transaction-building/deployment-transactions.md +241 -0
  130. package/documentation/transaction-building/funding-transactions.md +282 -0
  131. package/documentation/transaction-building/interaction-transactions.md +292 -0
  132. package/documentation/transaction-building/multisig-transactions.md +340 -0
  133. package/documentation/transaction-building/transaction-factory-interfaces.md +726 -0
  134. package/documentation/transaction-building/transaction-factory.md +746 -0
  135. package/documentation/utils/bitcoin-utils.md +196 -0
  136. package/documentation/utils/buffer-helper.md +259 -0
  137. package/documentation/utils/compressor.md +182 -0
  138. package/documentation/utils/types-and-constants.md +259 -0
  139. package/documentation/utxo/opnet-limited-provider.md +363 -0
  140. package/package.json +4 -4
  141. package/src/_version.ts +1 -1
  142. package/src/abi/ABICoder.ts +4 -4
  143. package/src/buffer/BinaryReader.ts +1 -1
  144. package/src/buffer/BinaryWriter.ts +1 -1
  145. package/src/bytecode/Compressor.ts +8 -8
  146. package/src/epoch/ChallengeSolution.ts +23 -22
  147. package/src/generators/MLDSAData.ts +4 -4
  148. package/src/shims/zlib-browser.js +4 -4
  149. package/src/transaction/browser/types/Unisat.ts +1 -1
  150. package/src/transaction/builders/CancelTransaction.ts +1 -1
  151. package/src/transaction/builders/ChallengeSolutionTransaction.ts +5 -5
  152. package/src/transaction/builders/CustomScriptTransaction.ts +1 -1
  153. package/src/transaction/builders/DeploymentTransaction.ts +2 -2
  154. package/src/transaction/builders/MultiSignTransaction.ts +5 -5
  155. package/src/transaction/builders/SharedInteractionTransaction.ts +5 -5
  156. package/src/transaction/builders/TransactionBuilder.ts +4 -4
  157. package/src/transaction/offline/OfflineTransactionManager.ts +1 -1
  158. package/src/transaction/shared/P2TR_MS.ts +1 -1
  159. package/src/transaction/shared/TweakedTransaction.ts +3 -15
  160. package/src/utils/BitcoinUtils.ts +11 -11
  161. package/src/utils/BufferHelper.ts +1 -1
  162. package/src/utils/StringToBuffer.ts +4 -2
  163. package/src/utils/types.ts +1 -1
  164. package/src/utxo/OPNetLimitedProvider.ts +2 -2
  165. package/documentation/offline-transaction-signing.md +0 -652
  166. package/documentation/transaction-building.md +0 -603
@@ -0,0 +1,282 @@
1
+ # Funding Transactions (BTC Transfers)
2
+
3
+ Simple Bitcoin transfers using `FundingTransaction`.
4
+
5
+ ## Overview
6
+
7
+ A `FundingTransaction` creates a standard Bitcoin transfer from one address to another. It handles UTXO selection, fee calculation, change outputs, and optional output splitting.
8
+
9
+ ```mermaid
10
+ flowchart LR
11
+ subgraph Inputs["Input UTXOs"]
12
+ U1["UTXO 1"]
13
+ U2["UTXO 2"]
14
+ end
15
+
16
+ subgraph FundingTx["FundingTransaction"]
17
+ direction TB
18
+ Select["Select inputs"]
19
+ Calc["Calculate fees"]
20
+ Build["Build outputs"]
21
+ Sign["Sign & finalize"]
22
+ Select --> Calc --> Build --> Sign
23
+ end
24
+
25
+ subgraph Outputs
26
+ O1["Recipient Output<br/>(amount)"]
27
+ O2["Change Output<br/>(leftover - fees)"]
28
+ end
29
+
30
+ U1 --> FundingTx
31
+ U2 --> FundingTx
32
+ FundingTx --> O1
33
+ FundingTx --> O2
34
+ ```
35
+
36
+ ## Factory Methods
37
+
38
+ Funding transactions are created through `TransactionFactory`:
39
+
40
+ | Method | Description |
41
+ |--------|-------------|
42
+ | `TransactionFactory.createBTCTransfer()` | Create and sign a BTC transfer, returning the hex-encoded transaction |
43
+
44
+ ```typescript
45
+ import { TransactionFactory } from '@btc-vision/transaction';
46
+
47
+ const factory = new TransactionFactory();
48
+ const result = await factory.createBTCTransfer(parameters);
49
+ ```
50
+
51
+ ## Parameters
52
+
53
+ `IFundingTransactionParameters` extends the base `ITransactionParameters`:
54
+
55
+ | Parameter | Type | Required | Default | Description |
56
+ |-----------|------|----------|---------|-------------|
57
+ | `signer` | `Signer \| UniversalSigner` | Yes | - | Key pair used to sign inputs |
58
+ | `network` | `Network` | Yes | - | Bitcoin network (`networks.bitcoin`, `networks.testnet`, `networks.regtest`) |
59
+ | `utxos` | `UTXO[]` | Yes | - | Available UTXOs to spend |
60
+ | `from` | `string` | Yes | - | Sender address (for change output) |
61
+ | `to` | `string` | Yes | - | Recipient address |
62
+ | `feeRate` | `number` | Yes | - | Fee rate in sat/vB |
63
+ | `priorityFee` | `bigint` | Yes | - | OPNet priority fee (use `0n` for plain BTC transfers) |
64
+ | `gasSatFee` | `bigint` | Yes | - | OPNet gas fee (use `0n` for plain BTC transfers) |
65
+ | `amount` | `bigint` | Yes | - | Amount to send in satoshis |
66
+ | `splitInputsInto` | `number` | No | `1` | Split the output into N equal UTXOs |
67
+ | `autoAdjustAmount` | `boolean` | No | `false` | Deduct fees from output (send-max mode) |
68
+ | `feeUtxos` | `UTXO[]` | No | `undefined` | Separate UTXOs used exclusively to cover fees |
69
+ | `mldsaSigner` | `QuantumBIP32Interface \| null` | No | - | ML-DSA (quantum-resistant) signer |
70
+ | `optionalOutputs` | `PsbtOutputExtended[]` | No | - | Additional outputs (e.g., OP_RETURN notes) |
71
+ | `note` | `string \| Uint8Array` | No | - | Embed an OP_RETURN note in the transaction |
72
+
73
+ ## Response Type
74
+
75
+ `BitcoinTransferResponse`:
76
+
77
+ | Field | Type | Description |
78
+ |-------|------|-------------|
79
+ | `tx` | `string` | Signed transaction in hex format, ready to broadcast |
80
+ | `estimatedFees` | `bigint` | Total fees paid in satoshis |
81
+ | `nextUTXOs` | `UTXO[]` | Change UTXOs belonging to the sender, for use in subsequent transactions |
82
+ | `inputUtxos` | `UTXO[]` | The UTXOs that were consumed as inputs |
83
+ | `original` | `FundingTransaction` | The underlying `FundingTransaction` instance |
84
+
85
+ ## Send-Max Mode
86
+
87
+ Setting `autoAdjustAmount: true` sends the entire balance minus fees. When the requested `amount` equals or exceeds the total UTXO value, the builder estimates fees first, then reduces the output amount accordingly.
88
+
89
+ ```mermaid
90
+ flowchart TB
91
+ Start["amount >= totalInputAmount?"]
92
+ Start -->|"Yes"| Estimate["Estimate fee with<br/>temporary output"]
93
+ Estimate --> Adjust["adjustedAmount =<br/>totalInput - estimatedFee"]
94
+ Adjust --> Check{"adjustedAmount<br/>< dust?"}
95
+ Check -->|"Yes"| Error["Error: Insufficient funds"]
96
+ Check -->|"No"| Build["Build transaction<br/>with adjusted amount"]
97
+ Start -->|"No"| Normal["Build transaction<br/>with original amount"]
98
+ ```
99
+
100
+ ```typescript
101
+ // Send entire balance
102
+ const result = await factory.createBTCTransfer({
103
+ signer,
104
+ mldsaSigner: null,
105
+ network,
106
+ utxos,
107
+ from: myAddress,
108
+ to: recipientAddress,
109
+ feeRate: 10,
110
+ priorityFee: 0n,
111
+ gasSatFee: 0n,
112
+ amount: totalBalance, // Set to total UTXO value
113
+ autoAdjustAmount: true, // Fees deducted from output
114
+ });
115
+
116
+ // result.tx contains the full balance minus fees
117
+ ```
118
+
119
+ ## Output Splitting
120
+
121
+ Use `splitInputsInto` to divide the output amount across multiple equal UTXOs at the same address. This is useful for preparing UTXOs for future parallel transactions.
122
+
123
+ ```typescript
124
+ const result = await factory.createBTCTransfer({
125
+ signer,
126
+ mldsaSigner: null,
127
+ network,
128
+ utxos,
129
+ from: myAddress,
130
+ to: recipientAddress,
131
+ feeRate: 10,
132
+ priorityFee: 0n,
133
+ gasSatFee: 0n,
134
+ amount: 100000n,
135
+ splitInputsInto: 4, // Creates 4 outputs of 25,000 sat each
136
+ });
137
+ ```
138
+
139
+ ## Fee UTXOs
140
+
141
+ Use `feeUtxos` to pay transaction fees from a separate set of UTXOs. The output amount stays exact and fees are drawn from the fee UTXOs. Any leftover becomes the change output.
142
+
143
+ ```typescript
144
+ const result = await factory.createBTCTransfer({
145
+ signer,
146
+ mldsaSigner: null,
147
+ network,
148
+ utxos: [paymentUtxo], // Used for the payment output
149
+ feeUtxos: [feeOnlyUtxo], // Used exclusively to cover fees
150
+ from: myAddress,
151
+ to: recipientAddress,
152
+ feeRate: 10,
153
+ priorityFee: 0n,
154
+ gasSatFee: 0n,
155
+ amount: 50000n,
156
+ });
157
+ ```
158
+
159
+ Internally, `feeUtxos` are merged into the input set:
160
+
161
+ ```typescript
162
+ // From FundingTransaction constructor:
163
+ const mergedParams = parameters.feeUtxos?.length
164
+ ? { ...parameters, utxos: [...parameters.utxos, ...parameters.feeUtxos] }
165
+ : parameters;
166
+ ```
167
+
168
+ ## Complete Example
169
+
170
+ ```typescript
171
+ import { TransactionFactory, EcKeyPair, UTXO } from '@btc-vision/transaction';
172
+ import { networks } from '@btc-vision/bitcoin';
173
+
174
+ async function transferBTC() {
175
+ const network = networks.bitcoin;
176
+ const factory = new TransactionFactory();
177
+
178
+ // Create signer
179
+ const signer = EcKeyPair.fromWIF(process.env.PRIVATE_KEY!, network);
180
+ const address = EcKeyPair.getTaprootAddress(signer, network);
181
+
182
+ // Fetch your UTXOs (from a provider or local state)
183
+ const utxos: UTXO[] = [
184
+ {
185
+ transactionId: 'abcd1234...'.padEnd(64, '0'),
186
+ outputIndex: 0,
187
+ value: 100000n,
188
+ scriptPubKey: {
189
+ hex: '5120...',
190
+ address: address,
191
+ },
192
+ },
193
+ ];
194
+
195
+ // Send 50,000 sats
196
+ const result = await factory.createBTCTransfer({
197
+ signer,
198
+ mldsaSigner: null,
199
+ network,
200
+ utxos,
201
+ from: address,
202
+ to: 'bc1p...recipient',
203
+ feeRate: 10,
204
+ priorityFee: 0n,
205
+ gasSatFee: 0n,
206
+ amount: 50000n,
207
+ });
208
+
209
+ console.log('Transaction hex:', result.tx);
210
+ console.log('Fees paid:', result.estimatedFees, 'sats');
211
+ console.log('Change UTXOs:', result.nextUTXOs);
212
+
213
+ // Broadcast the transaction
214
+ await broadcastTransaction(result.tx);
215
+
216
+ // Track the change UTXOs for your next transaction
217
+ const availableUtxos = result.nextUTXOs;
218
+ }
219
+ ```
220
+
221
+ ## UTXO Tracking
222
+
223
+ Always track the `nextUTXOs` returned from each transaction. These are your new spendable outputs and must be used as inputs for subsequent transactions.
224
+
225
+ ```mermaid
226
+ flowchart LR
227
+ TX1["Transfer 1"] -->|"nextUTXOs"| TX2["Transfer 2"]
228
+ TX2 -->|"nextUTXOs"| TX3["Transfer 3"]
229
+ ```
230
+
231
+ ```typescript
232
+ let currentUtxos = initialUtxos;
233
+
234
+ // First transfer
235
+ const result1 = await factory.createBTCTransfer({
236
+ ...params,
237
+ utxos: currentUtxos,
238
+ amount: 30000n,
239
+ });
240
+ currentUtxos = result1.nextUTXOs;
241
+
242
+ // Second transfer (uses change from first)
243
+ const result2 = await factory.createBTCTransfer({
244
+ ...params,
245
+ utxos: currentUtxos,
246
+ amount: 20000n,
247
+ });
248
+ currentUtxos = result2.nextUTXOs;
249
+ ```
250
+
251
+ ## Error Handling
252
+
253
+ ```typescript
254
+ try {
255
+ const result = await factory.createBTCTransfer(params);
256
+ } catch (error) {
257
+ const message = (error as Error).message;
258
+
259
+ if (message.includes('Recipient address is required')) {
260
+ // The 'to' field is missing
261
+ } else if (message.includes('Insufficient funds')) {
262
+ // UTXOs do not cover amount + fees (thrown during autoAdjust)
263
+ } else if (message.includes('below minimum dust')) {
264
+ // After fee deduction, remaining amount is below 330 sats
265
+ } else if (message.includes('Field "from" not provided')) {
266
+ // The 'from' field is missing (thrown by TransactionFactory)
267
+ }
268
+ }
269
+ ```
270
+
271
+ ## Best Practices
272
+
273
+ 1. **Set realistic fee rates.** Query mempool fee estimates before building a transaction.
274
+ 2. **Track change UTXOs.** Always use `nextUTXOs` as inputs for follow-up transactions to avoid double-spending.
275
+ 3. **Use `autoAdjustAmount` for sweeps.** When sending the entire balance, let the builder subtract fees automatically.
276
+ 4. **Use `feeUtxos` for exact amounts.** When the recipient must receive an exact amount, pay fees from separate UTXOs.
277
+ 5. **Consolidate dust.** Periodically combine many small UTXOs into fewer larger ones to reduce future transaction sizes and fees.
278
+ 6. **Set OPNet fees to `0n` for plain transfers.** The `priorityFee` and `gasSatFee` fields are only relevant for OPNet contract operations.
279
+
280
+ ---
281
+
282
+ [< Back to README](../README.md) | [Deployment Transactions >](./deployment-transactions.md)
@@ -0,0 +1,292 @@
1
+ # Interaction Transactions
2
+
3
+ Call smart contract functions using `InteractionTransaction`.
4
+
5
+ ## Overview
6
+
7
+ An `InteractionTransaction` calls a function on a deployed OPNet smart contract. Like deployments, interactions use a **two-transaction model**: a funding transaction sends BTC to a derived Taproot script address, and the interaction transaction spends that UTXO while embedding the calldata in the Taproot witness.
8
+
9
+ ```mermaid
10
+ flowchart LR
11
+ subgraph TX1["Transaction 1: Funding"]
12
+ U["User UTXOs"] --> SA["Script Address<br/>(P2TR)"]
13
+ U --> Change["Change Output"]
14
+ end
15
+
16
+ subgraph TX2["Transaction 2: Interaction"]
17
+ SA2["Script UTXO"] --> EP["Epoch Reward<br/>(Challenge)"]
18
+ SA2 --> RF["Refund"]
19
+ end
20
+
21
+ SA -->|"creates UTXO"| SA2
22
+
23
+ subgraph Contract["OPNet Execution"]
24
+ CD["Calldata decoded<br/>by validators"]
25
+ ST["State updated<br/>on-chain"]
26
+ end
27
+
28
+ TX2 --> Contract
29
+ ```
30
+
31
+ ## Factory Method
32
+
33
+ Interactions are created through `TransactionFactory.signInteraction()`:
34
+
35
+ ```typescript
36
+ import { TransactionFactory } from '@btc-vision/transaction';
37
+
38
+ const factory = new TransactionFactory();
39
+ const result = await factory.signInteraction(parameters);
40
+ ```
41
+
42
+ ## Architecture
43
+
44
+ `InteractionTransaction` extends `SharedInteractionTransaction`, which provides the common logic for calldata compression, script-path signing, and reward outputs. The class hierarchy is:
45
+
46
+ ```mermaid
47
+ flowchart TB
48
+ TT["TweakedTransaction"]
49
+ TB["TransactionBuilder&lt;T&gt;"]
50
+ SIT["SharedInteractionTransaction&lt;T&gt;<br/>(calldata, script signer, rewards)"]
51
+ IT["InteractionTransaction<br/>(contract secret, access list)"]
52
+
53
+ TT --> TB --> SIT --> IT
54
+ ```
55
+
56
+ `SharedInteractionTransaction` handles:
57
+ - Calldata compression via `Compressor`
58
+ - Script signer generation from random bytes
59
+ - Taproot script tree construction (target script + lock leaf)
60
+ - Epoch reward output creation
61
+ - Dual-signature signing (script signer + wallet signer)
62
+
63
+ `InteractionTransaction` adds:
64
+ - Contract secret (derived from the contract's public key)
65
+ - Access list support for gas optimization
66
+ - Feature generation (epoch submission, ML-DSA linking)
67
+
68
+ ## Parameters
69
+
70
+ `IInteractionParameters` extends `SharedInteractionParameters`:
71
+
72
+ | Parameter | Type | Required | Default | Description |
73
+ |-----------|------|----------|---------|-------------|
74
+ | `signer` | `Signer \| UniversalSigner` | Yes | - | Key pair used to sign inputs |
75
+ | `mldsaSigner` | `QuantumBIP32Interface \| null` | No | - | ML-DSA (quantum-resistant) signer |
76
+ | `network` | `Network` | Yes | - | Bitcoin network |
77
+ | `utxos` | `UTXO[]` | Yes | - | Available UTXOs to fund the interaction |
78
+ | `from` | `string` | Yes | - | Sender address |
79
+ | `to` | `string` | Yes | - | Contract's P2TR address |
80
+ | `feeRate` | `number` | Yes | - | Fee rate in sat/vB |
81
+ | `priorityFee` | `bigint` | Yes | - | OPNet priority fee in satoshis |
82
+ | `gasSatFee` | `bigint` | Yes | - | OPNet gas fee in satoshis |
83
+ | `calldata` | `Uint8Array` | Yes | - | ABI-encoded function call |
84
+ | `contract` | `string` | Yes | - | Contract public key (hex, `0x`-prefixed, 32 bytes) |
85
+ | `challenge` | `IChallengeSolution` | Yes | - | Epoch challenge solution |
86
+ | `randomBytes` | `Uint8Array` | No | Auto-generated | 32-byte random salt |
87
+ | `loadedStorage` | `LoadedStorage` | No | - | Access list for gas optimization |
88
+ | `disableAutoRefund` | `boolean` | No | `false` | Skip the automatic refund output |
89
+
90
+ ### Constraints
91
+
92
+ | Constraint | Value | Description |
93
+ |------------|-------|-------------|
94
+ | Maximum calldata size | **1 MB** (`1024 * 1024` bytes) | Before compression. Enforced by `SharedInteractionTransaction.MAXIMUM_CALLDATA_SIZE`. |
95
+ | Contract secret length | **32 bytes** | The `contract` parameter must decode to exactly 32 bytes. |
96
+
97
+ ## Response Type
98
+
99
+ `InteractionResponse`:
100
+
101
+ | Field | Type | Description |
102
+ |-------|------|-------------|
103
+ | `fundingTransaction` | `string \| null` | Funding transaction hex (`null` for P2WDA interactions) |
104
+ | `interactionTransaction` | `string` | Interaction transaction hex |
105
+ | `estimatedFees` | `bigint` | Total fees in satoshis |
106
+ | `nextUTXOs` | `UTXO[]` | Change UTXOs for subsequent transactions |
107
+ | `fundingUTXOs` | `UTXO[]` | The UTXO(s) created by the funding transaction |
108
+ | `fundingInputUtxos` | `UTXO[]` | Original UTXOs consumed as inputs |
109
+ | `challenge` | `RawChallenge` | The raw epoch challenge used |
110
+ | `interactionAddress` | `string \| null` | The Taproot script address used for the interaction |
111
+ | `compiledTargetScript` | `string \| null` | The compiled target script (hex) for cancellation recovery |
112
+
113
+ ## Access List Support
114
+
115
+ The access list (`loadedStorage`) pre-declares which contract storage slots the interaction will read. This allows validators to optimize gas costs by pre-loading the required state.
116
+
117
+ ```typescript
118
+ const loadedStorage: LoadedStorage = {
119
+ // contract address -> array of storage slot keys
120
+ 'bc1p...contractAddress': [
121
+ '0x0000...storageSlot1',
122
+ '0x0000...storageSlot2',
123
+ ],
124
+ };
125
+
126
+ const result = await factory.signInteraction({
127
+ // ... other params
128
+ loadedStorage,
129
+ });
130
+ ```
131
+
132
+ The access list is encoded as a transaction feature with `Features.ACCESS_LIST` priority:
133
+
134
+ ```mermaid
135
+ flowchart LR
136
+ AL["loadedStorage<br/>{addr: [slots]}"] --> F["Feature<br/>ACCESS_LIST"]
137
+ F --> CS["Compiled into<br/>target script"]
138
+ ```
139
+
140
+ ## Two-Transaction Flow
141
+
142
+ The factory handles the complete two-transaction flow:
143
+
144
+ ```mermaid
145
+ sequenceDiagram
146
+ participant App
147
+ participant Factory as TransactionFactory
148
+ participant FT as FundingTransaction
149
+ participant IT as InteractionTransaction
150
+
151
+ App->>Factory: signInteraction(params)
152
+ Factory->>Factory: Iterate funding amount<br/>(simulate & converge)
153
+ Factory->>FT: Create & sign funding tx
154
+ FT-->>Factory: Signed funding tx + script UTXO
155
+ Factory->>IT: Create interaction tx<br/>(uses funding UTXO)
156
+ Factory->>IT: Sign interaction tx<br/>(script signer + wallet signer)
157
+ IT-->>Factory: Signed interaction tx
158
+ Factory-->>App: InteractionResponse
159
+ ```
160
+
161
+ 1. The factory iteratively estimates the required funding amount.
162
+ 2. A `FundingTransaction` sends BTC to the derived Taproot script address.
163
+ 3. An `InteractionTransaction` spends that UTXO, revealing the calldata in the witness.
164
+ 4. Both transactions are returned for sequential broadcast.
165
+
166
+ ## Signing Process
167
+
168
+ Interaction transactions use a dual-signature scheme. Input 0 (the script-path input) requires two signatures:
169
+
170
+ ```mermaid
171
+ flowchart TB
172
+ subgraph Input0["Input 0 (Script Path)"]
173
+ SS["Script Signer<br/>(derived from randomBytes)"]
174
+ WS["Wallet Signer<br/>(user's key)"]
175
+ SS --> CF["Custom Finalizer<br/>[contractSecret, sig1, sig2,<br/>script, controlBlock]"]
176
+ WS --> CF
177
+ end
178
+
179
+ subgraph InputN["Inputs 1+ (Key Path)"]
180
+ WS2["Wallet Signer"] --> SF["Standard Finalizer"]
181
+ end
182
+ ```
183
+
184
+ The witness stack for the script-path input contains:
185
+ 1. The contract secret (32 bytes)
186
+ 2. Script signer's Schnorr signature
187
+ 3. Wallet signer's Schnorr signature
188
+ 4. The compiled target script
189
+ 5. The Taproot control block
190
+
191
+ ## Complete Example
192
+
193
+ ```typescript
194
+ import {
195
+ TransactionFactory,
196
+ EcKeyPair,
197
+ ABICoder,
198
+ ChallengeSolution,
199
+ UTXO,
200
+ } from '@btc-vision/transaction';
201
+ import { networks } from '@btc-vision/bitcoin';
202
+
203
+ async function callContract() {
204
+ const network = networks.bitcoin;
205
+ const factory = new TransactionFactory();
206
+
207
+ // Create signer
208
+ const signer = EcKeyPair.fromWIF(process.env.PRIVATE_KEY!, network);
209
+ const address = EcKeyPair.getTaprootAddress(signer, network);
210
+
211
+ // Fetch UTXOs
212
+ const utxos: UTXO[] = await fetchUTXOs(address);
213
+
214
+ // Encode the function call
215
+ const coder = new ABICoder();
216
+ const calldata = coder.encodeSelector('transfer')
217
+ .addAddress('bc1p...recipientAddress')
218
+ .addUint256(1000000n)
219
+ .compile();
220
+
221
+ // Obtain epoch challenge
222
+ const challenge: ChallengeSolution = await solveEpochChallenge(/* ... */);
223
+
224
+ // Contract details
225
+ const contractAddress = 'bc1p...contractP2TR';
226
+ const contractPubKey = '0x...contractPubKey'; // 32 bytes hex
227
+
228
+ // Execute interaction
229
+ const result = await factory.signInteraction({
230
+ signer,
231
+ mldsaSigner: null,
232
+ network,
233
+ utxos,
234
+ from: address,
235
+ to: contractAddress,
236
+ feeRate: 10,
237
+ priorityFee: 10000n,
238
+ gasSatFee: 5000n,
239
+ calldata,
240
+ contract: contractPubKey,
241
+ challenge,
242
+ });
243
+
244
+ // Broadcast both transactions in order
245
+ await broadcastTransaction(result.fundingTransaction!);
246
+ await broadcastTransaction(result.interactionTransaction);
247
+
248
+ console.log('Interaction sent!');
249
+ console.log('Fees:', result.estimatedFees, 'sats');
250
+ console.log('Change UTXOs:', result.nextUTXOs);
251
+
252
+ // Save compiledTargetScript for potential cancellation
253
+ const compiledScript = result.compiledTargetScript;
254
+ }
255
+ ```
256
+
257
+ ## Error Handling
258
+
259
+ ```typescript
260
+ try {
261
+ const result = await factory.signInteraction(params);
262
+ } catch (error) {
263
+ const message = (error as Error).message;
264
+
265
+ if (message.includes('parameters.contract is required')) {
266
+ // The 'contract' parameter is missing
267
+ } else if (message.includes('Invalid contract secret length')) {
268
+ // Contract public key does not decode to 32 bytes
269
+ } else if (message.includes('Calldata is required')) {
270
+ // The calldata parameter is missing
271
+ } else if (message.includes('Challenge solution is required')) {
272
+ // The challenge parameter is missing
273
+ } else if (message.includes('Field "to" not provided')) {
274
+ // Contract address (to) is missing
275
+ } else if (message.includes('Could not sign funding transaction')) {
276
+ // Insufficient UTXOs or funding step failed
277
+ }
278
+ }
279
+ ```
280
+
281
+ ## Best Practices
282
+
283
+ 1. **Save the `compiledTargetScript`.** If the interaction gets stuck, you need this script to create a `CancelTransaction` for recovery.
284
+ 2. **Use access lists when possible.** Pre-declaring storage slots via `loadedStorage` reduces gas costs for the validator.
285
+ 3. **Broadcast sequentially.** The funding transaction must reach the mempool before the interaction transaction.
286
+ 4. **Track change UTXOs.** Use `result.nextUTXOs` for subsequent transactions.
287
+ 5. **Set appropriate fees.** Both `priorityFee` and `gasSatFee` affect how validators prioritize your interaction.
288
+ 6. **Handle P2WDA automatically.** If your UTXOs are P2WDA type, the factory automatically uses the single-transaction P2WDA path (no funding transaction needed).
289
+
290
+ ---
291
+
292
+ [< Deployment Transactions](./deployment-transactions.md) | [MultiSig Transactions >](./multisig-transactions.md)