@btc-vision/transaction 1.7.18 → 1.7.22

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 (92) hide show
  1. package/LICENSE +190 -21
  2. package/README.md +1 -1
  3. package/browser/_version.d.ts +1 -1
  4. package/browser/generators/builders/HashCommitmentGenerator.d.ts +49 -0
  5. package/browser/index.js +1 -1
  6. package/browser/keypair/Address.d.ts +3 -1
  7. package/browser/opnet.d.ts +6 -1
  8. package/browser/signer/AddressRotation.d.ts +12 -0
  9. package/browser/transaction/TransactionFactory.d.ts +14 -0
  10. package/browser/transaction/builders/ConsolidatedInteractionTransaction.d.ts +44 -0
  11. package/browser/transaction/enums/TransactionType.d.ts +3 -1
  12. package/browser/transaction/interfaces/IConsolidatedTransactionParameters.d.ts +31 -0
  13. package/browser/transaction/interfaces/ITransactionParameters.d.ts +2 -0
  14. package/browser/transaction/offline/OfflineTransactionManager.d.ts +69 -0
  15. package/browser/transaction/offline/TransactionReconstructor.d.ts +28 -0
  16. package/browser/transaction/offline/TransactionSerializer.d.ts +50 -0
  17. package/browser/transaction/offline/TransactionStateCapture.d.ts +52 -0
  18. package/browser/transaction/offline/index.d.ts +5 -0
  19. package/browser/transaction/offline/interfaces/ISerializableState.d.ts +62 -0
  20. package/browser/transaction/offline/interfaces/ITypeSpecificData.d.ts +62 -0
  21. package/browser/transaction/offline/interfaces/index.d.ts +2 -0
  22. package/browser/transaction/shared/TweakedTransaction.d.ts +12 -1
  23. package/browser/utxo/interfaces/IUTXO.d.ts +2 -0
  24. package/build/_version.d.ts +1 -1
  25. package/build/_version.js +1 -1
  26. package/build/generators/builders/HashCommitmentGenerator.d.ts +49 -0
  27. package/build/generators/builders/HashCommitmentGenerator.js +229 -0
  28. package/build/keypair/Address.d.ts +3 -1
  29. package/build/keypair/Address.js +87 -54
  30. package/build/opnet.d.ts +6 -1
  31. package/build/opnet.js +6 -1
  32. package/build/signer/AddressRotation.d.ts +12 -0
  33. package/build/signer/AddressRotation.js +16 -0
  34. package/build/transaction/TransactionFactory.d.ts +14 -0
  35. package/build/transaction/TransactionFactory.js +36 -0
  36. package/build/transaction/builders/ConsolidatedInteractionTransaction.d.ts +44 -0
  37. package/build/transaction/builders/ConsolidatedInteractionTransaction.js +259 -0
  38. package/build/transaction/builders/TransactionBuilder.js +2 -0
  39. package/build/transaction/enums/TransactionType.d.ts +3 -1
  40. package/build/transaction/enums/TransactionType.js +2 -0
  41. package/build/transaction/interfaces/IConsolidatedTransactionParameters.d.ts +31 -0
  42. package/build/transaction/interfaces/IConsolidatedTransactionParameters.js +1 -0
  43. package/build/transaction/interfaces/ITransactionParameters.d.ts +2 -0
  44. package/build/transaction/offline/OfflineTransactionManager.d.ts +69 -0
  45. package/build/transaction/offline/OfflineTransactionManager.js +255 -0
  46. package/build/transaction/offline/TransactionReconstructor.d.ts +28 -0
  47. package/build/transaction/offline/TransactionReconstructor.js +243 -0
  48. package/build/transaction/offline/TransactionSerializer.d.ts +50 -0
  49. package/build/transaction/offline/TransactionSerializer.js +700 -0
  50. package/build/transaction/offline/TransactionStateCapture.d.ts +52 -0
  51. package/build/transaction/offline/TransactionStateCapture.js +275 -0
  52. package/build/transaction/offline/index.d.ts +5 -0
  53. package/build/transaction/offline/index.js +5 -0
  54. package/build/transaction/offline/interfaces/ISerializableState.d.ts +62 -0
  55. package/build/transaction/offline/interfaces/ISerializableState.js +2 -0
  56. package/build/transaction/offline/interfaces/ITypeSpecificData.d.ts +62 -0
  57. package/build/transaction/offline/interfaces/ITypeSpecificData.js +19 -0
  58. package/build/transaction/offline/interfaces/index.d.ts +2 -0
  59. package/build/transaction/offline/interfaces/index.js +2 -0
  60. package/build/transaction/shared/TweakedTransaction.d.ts +12 -1
  61. package/build/transaction/shared/TweakedTransaction.js +75 -8
  62. package/build/utxo/interfaces/IUTXO.d.ts +2 -0
  63. package/documentation/README.md +5 -0
  64. package/documentation/offline-transaction-signing.md +650 -0
  65. package/documentation/transaction-building.md +603 -0
  66. package/package.json +2 -2
  67. package/src/_version.ts +1 -1
  68. package/src/generators/builders/HashCommitmentGenerator.ts +495 -0
  69. package/src/keypair/Address.ts +123 -70
  70. package/src/opnet.ts +8 -1
  71. package/src/signer/AddressRotation.ts +72 -0
  72. package/src/transaction/TransactionFactory.ts +94 -1
  73. package/src/transaction/builders/CancelTransaction.ts +4 -2
  74. package/src/transaction/builders/ConsolidatedInteractionTransaction.ts +568 -0
  75. package/src/transaction/builders/CustomScriptTransaction.ts +4 -2
  76. package/src/transaction/builders/MultiSignTransaction.ts +4 -2
  77. package/src/transaction/builders/TransactionBuilder.ts +8 -2
  78. package/src/transaction/enums/TransactionType.ts +2 -0
  79. package/src/transaction/interfaces/IConsolidatedTransactionParameters.ts +78 -0
  80. package/src/transaction/interfaces/ITransactionParameters.ts +8 -0
  81. package/src/transaction/offline/OfflineTransactionManager.ts +630 -0
  82. package/src/transaction/offline/TransactionReconstructor.ts +402 -0
  83. package/src/transaction/offline/TransactionSerializer.ts +920 -0
  84. package/src/transaction/offline/TransactionStateCapture.ts +469 -0
  85. package/src/transaction/offline/index.ts +8 -0
  86. package/src/transaction/offline/interfaces/ISerializableState.ts +141 -0
  87. package/src/transaction/offline/interfaces/ITypeSpecificData.ts +172 -0
  88. package/src/transaction/offline/interfaces/index.ts +2 -0
  89. package/src/transaction/shared/TweakedTransaction.ts +156 -9
  90. package/src/utxo/interfaces/IUTXO.ts +8 -0
  91. package/test/address-rotation.test.ts +553 -0
  92. package/test/offline-transaction.test.ts +2065 -0
@@ -0,0 +1,469 @@
1
+ import { Network, PsbtOutputExtended } from '@btc-vision/bitcoin';
2
+ import { UTXO } from '../../utxo/interfaces/IUTXO.js';
3
+ import { ChainId } from '../../network/ChainId.js';
4
+ import { currentConsensus } from '../../consensus/ConsensusConfig.js';
5
+ import { TransactionType } from '../enums/TransactionType.js';
6
+ import {
7
+ ISerializableTransactionState,
8
+ PrecomputedData,
9
+ SERIALIZATION_FORMAT_VERSION,
10
+ SerializationHeader,
11
+ SerializedBaseParams,
12
+ SerializedOutput,
13
+ SerializedSignerMapping,
14
+ SerializedUTXO,
15
+ } from './interfaces/ISerializableState.js';
16
+ import {
17
+ CancelSpecificData,
18
+ CustomScriptSpecificData,
19
+ DeploymentSpecificData,
20
+ FundingSpecificData,
21
+ InteractionSpecificData,
22
+ MultiSigSpecificData,
23
+ SerializedScriptElement,
24
+ TypeSpecificData,
25
+ } from './interfaces/ITypeSpecificData.js';
26
+ import {
27
+ IDeploymentParameters,
28
+ IFundingTransactionParameters,
29
+ IInteractionParameters,
30
+ ITransactionParameters,
31
+ } from '../interfaces/ITransactionParameters.js';
32
+
33
+ /**
34
+ * Parameters required to capture state from any transaction builder
35
+ */
36
+ export interface CaptureParams {
37
+ /** The original transaction parameters */
38
+ params: ITransactionParameters;
39
+ /** The transaction type */
40
+ type: TransactionType;
41
+ /** Pre-computed data from the builder */
42
+ precomputed?: Partial<PrecomputedData>;
43
+ }
44
+
45
+ /**
46
+ * Captures transaction state from builders for offline signing.
47
+ * This class creates serializable state objects from transaction parameters.
48
+ */
49
+ export class TransactionStateCapture {
50
+ /**
51
+ * Capture state from a FundingTransaction
52
+ */
53
+ public static fromFunding(
54
+ params: IFundingTransactionParameters,
55
+ precomputed?: Partial<PrecomputedData>,
56
+ ): ISerializableTransactionState {
57
+ return this.captureState({
58
+ params,
59
+ type: TransactionType.FUNDING,
60
+ precomputed,
61
+ });
62
+ }
63
+
64
+ /**
65
+ * Capture state from a DeploymentTransaction
66
+ */
67
+ public static fromDeployment(
68
+ params: IDeploymentParameters,
69
+ precomputed: Partial<PrecomputedData> & {
70
+ compiledTargetScript: string;
71
+ randomBytes: string;
72
+ },
73
+ ): ISerializableTransactionState {
74
+ return this.captureState({
75
+ params: params as ITransactionParameters,
76
+ type: TransactionType.DEPLOYMENT,
77
+ precomputed,
78
+ });
79
+ }
80
+
81
+ /**
82
+ * Capture state from an InteractionTransaction
83
+ */
84
+ public static fromInteraction(
85
+ params: IInteractionParameters,
86
+ precomputed: Partial<PrecomputedData> & {
87
+ compiledTargetScript: string;
88
+ randomBytes: string;
89
+ },
90
+ ): ISerializableTransactionState {
91
+ return this.captureState({
92
+ params,
93
+ type: TransactionType.INTERACTION,
94
+ precomputed,
95
+ });
96
+ }
97
+
98
+ /**
99
+ * Capture state from a MultiSignTransaction
100
+ */
101
+ public static fromMultiSig(
102
+ params: ITransactionParameters & {
103
+ pubkeys: Buffer[];
104
+ minimumSignatures: number;
105
+ receiver: string;
106
+ requestedAmount: bigint;
107
+ refundVault: string;
108
+ originalInputCount?: number;
109
+ existingPsbtBase64?: string;
110
+ },
111
+ precomputed?: Partial<PrecomputedData>,
112
+ ): ISerializableTransactionState {
113
+ return this.captureState({
114
+ params,
115
+ type: TransactionType.MULTI_SIG,
116
+ precomputed,
117
+ });
118
+ }
119
+
120
+ /**
121
+ * Capture state from a CustomScriptTransaction
122
+ */
123
+ public static fromCustomScript(
124
+ params: ITransactionParameters & {
125
+ scriptElements: (Buffer | number)[];
126
+ witnesses: Buffer[];
127
+ annex?: Buffer;
128
+ },
129
+ precomputed?: Partial<PrecomputedData>,
130
+ ): ISerializableTransactionState {
131
+ return this.captureState({
132
+ params,
133
+ type: TransactionType.CUSTOM_CODE,
134
+ precomputed,
135
+ });
136
+ }
137
+
138
+ /**
139
+ * Capture state from a CancelTransaction
140
+ */
141
+ public static fromCancel(
142
+ params: ITransactionParameters & {
143
+ compiledTargetScript: Buffer | string;
144
+ },
145
+ precomputed?: Partial<PrecomputedData>,
146
+ ): ISerializableTransactionState {
147
+ return this.captureState({
148
+ params,
149
+ type: TransactionType.CANCEL,
150
+ precomputed,
151
+ });
152
+ }
153
+
154
+ /**
155
+ * Main state capture method
156
+ */
157
+ private static captureState(capture: CaptureParams): ISerializableTransactionState {
158
+ const { params, type, precomputed } = capture;
159
+
160
+ return {
161
+ header: this.createHeader(type, params.network, params.chainId),
162
+ baseParams: this.extractBaseParams(params),
163
+ utxos: this.serializeUTXOs(params.utxos),
164
+ optionalInputs: this.serializeUTXOs(params.optionalInputs || []),
165
+ optionalOutputs: this.serializeOutputs(params.optionalOutputs || []),
166
+ addressRotationEnabled: params.addressRotation?.enabled ?? false,
167
+ signerMappings: this.extractSignerMappings(params),
168
+ typeSpecificData: this.extractTypeSpecificData(type, params),
169
+ precomputedData: this.buildPrecomputedData(precomputed),
170
+ };
171
+ }
172
+
173
+ /**
174
+ * Create serialization header
175
+ */
176
+ private static createHeader(
177
+ type: TransactionType,
178
+ network: Network,
179
+ chainId?: ChainId,
180
+ ): SerializationHeader {
181
+ return {
182
+ formatVersion: SERIALIZATION_FORMAT_VERSION,
183
+ consensusVersion: currentConsensus,
184
+ transactionType: type,
185
+ chainId: chainId ?? this.networkToChainId(network),
186
+ timestamp: Date.now(),
187
+ };
188
+ }
189
+
190
+ /**
191
+ * Extract base parameters common to all transaction types
192
+ */
193
+ private static extractBaseParams(params: ITransactionParameters): SerializedBaseParams {
194
+ const note = params.note
195
+ ? Buffer.isBuffer(params.note)
196
+ ? params.note.toString('hex')
197
+ : Buffer.from(params.note).toString('hex')
198
+ : undefined;
199
+
200
+ // Handle optional priorityFee and gasSatFee (not present in MultiSig)
201
+ const priorityFee = params.priorityFee ?? 0n;
202
+ const gasSatFee = params.gasSatFee ?? 0n;
203
+
204
+ return {
205
+ from: params.from || '',
206
+ to: params.to,
207
+ feeRate: params.feeRate,
208
+ priorityFee: priorityFee.toString(),
209
+ gasSatFee: gasSatFee.toString(),
210
+ networkName: this.networkToName(params.network),
211
+ txVersion: params.txVersion ?? 2,
212
+ note,
213
+ anchor: params.anchor ?? false,
214
+ debugFees: params.debugFees,
215
+ };
216
+ }
217
+
218
+ /**
219
+ * Extract signer mappings for address rotation mode
220
+ */
221
+ private static extractSignerMappings(
222
+ params: ITransactionParameters,
223
+ ): SerializedSignerMapping[] {
224
+ if (!params.addressRotation?.enabled) {
225
+ return [];
226
+ }
227
+
228
+ const mappings: SerializedSignerMapping[] = [];
229
+ const addressToIndices = new Map<string, number[]>();
230
+
231
+ // Build mapping from UTXOs
232
+ params.utxos.forEach((utxo, index) => {
233
+ const address = utxo.scriptPubKey?.address;
234
+ if (address) {
235
+ const existing = addressToIndices.get(address);
236
+ if (existing) {
237
+ existing.push(index);
238
+ } else {
239
+ addressToIndices.set(address, [index]);
240
+ }
241
+ }
242
+ });
243
+
244
+ // Add optional inputs
245
+ const utxoCount = params.utxos.length;
246
+ (params.optionalInputs || []).forEach((utxo, index) => {
247
+ const address = utxo.scriptPubKey?.address;
248
+ if (address) {
249
+ const existing = addressToIndices.get(address);
250
+ if (existing) {
251
+ existing.push(utxoCount + index);
252
+ } else {
253
+ addressToIndices.set(address, [utxoCount + index]);
254
+ }
255
+ }
256
+ });
257
+
258
+ // Convert to serializable format
259
+ addressToIndices.forEach((indices, address) => {
260
+ mappings.push({ address, inputIndices: indices });
261
+ });
262
+
263
+ return mappings;
264
+ }
265
+
266
+ /**
267
+ * Extract type-specific data based on transaction type
268
+ */
269
+ private static extractTypeSpecificData(
270
+ type: TransactionType,
271
+ params: ITransactionParameters,
272
+ ): TypeSpecificData {
273
+ switch (type) {
274
+ case TransactionType.FUNDING:
275
+ return this.extractFundingData(params as IFundingTransactionParameters);
276
+ case TransactionType.DEPLOYMENT:
277
+ return this.extractDeploymentData(params as unknown as IDeploymentParameters);
278
+ case TransactionType.INTERACTION:
279
+ return this.extractInteractionData(params as IInteractionParameters);
280
+ case TransactionType.MULTI_SIG:
281
+ return this.extractMultiSigData(params);
282
+ case TransactionType.CUSTOM_CODE:
283
+ return this.extractCustomScriptData(params);
284
+ case TransactionType.CANCEL:
285
+ return this.extractCancelData(params);
286
+ default:
287
+ throw new Error(`Unsupported transaction type: ${type}`);
288
+ }
289
+ }
290
+
291
+ private static extractFundingData(params: IFundingTransactionParameters): FundingSpecificData {
292
+ return {
293
+ type: TransactionType.FUNDING,
294
+ amount: params.amount.toString(),
295
+ splitInputsInto: params.splitInputsInto ?? 1,
296
+ };
297
+ }
298
+
299
+ private static extractDeploymentData(params: IDeploymentParameters): DeploymentSpecificData {
300
+ return {
301
+ type: TransactionType.DEPLOYMENT,
302
+ bytecode: params.bytecode.toString('hex'),
303
+ calldata: params.calldata?.toString('hex'),
304
+ challenge: params.challenge.toRaw(),
305
+ revealMLDSAPublicKey: params.revealMLDSAPublicKey,
306
+ linkMLDSAPublicKeyToAddress: params.linkMLDSAPublicKeyToAddress,
307
+ };
308
+ }
309
+
310
+ private static extractInteractionData(params: IInteractionParameters): InteractionSpecificData {
311
+ return {
312
+ type: TransactionType.INTERACTION,
313
+ calldata: params.calldata.toString('hex'),
314
+ contract: params.contract,
315
+ challenge: params.challenge.toRaw(),
316
+ loadedStorage: params.loadedStorage,
317
+ isCancellation: params.isCancellation,
318
+ disableAutoRefund: params.disableAutoRefund,
319
+ revealMLDSAPublicKey: params.revealMLDSAPublicKey,
320
+ linkMLDSAPublicKeyToAddress: params.linkMLDSAPublicKeyToAddress,
321
+ };
322
+ }
323
+
324
+ private static extractMultiSigData(
325
+ params: ITransactionParameters & {
326
+ pubkeys?: Buffer[];
327
+ minimumSignatures?: number;
328
+ receiver?: string;
329
+ requestedAmount?: bigint;
330
+ refundVault?: string;
331
+ originalInputCount?: number;
332
+ existingPsbtBase64?: string;
333
+ },
334
+ ): MultiSigSpecificData {
335
+ return {
336
+ type: TransactionType.MULTI_SIG,
337
+ pubkeys: (params.pubkeys || []).map((pk) => pk.toString('hex')),
338
+ minimumSignatures: params.minimumSignatures || 0,
339
+ receiver: params.receiver || '',
340
+ requestedAmount: (params.requestedAmount || 0n).toString(),
341
+ refundVault: params.refundVault || '',
342
+ originalInputCount: params.originalInputCount || params.utxos.length,
343
+ existingPsbtBase64: params.existingPsbtBase64,
344
+ };
345
+ }
346
+
347
+ private static extractCustomScriptData(
348
+ params: ITransactionParameters & {
349
+ scriptElements?: (Buffer | number)[];
350
+ witnesses?: Buffer[];
351
+ annex?: Buffer;
352
+ },
353
+ ): CustomScriptSpecificData {
354
+ const scriptElements: SerializedScriptElement[] = (params.scriptElements || []).map(
355
+ (element) => {
356
+ if (Buffer.isBuffer(element)) {
357
+ return {
358
+ elementType: 'buffer' as const,
359
+ value: element.toString('hex'),
360
+ };
361
+ } else {
362
+ return {
363
+ elementType: 'opcode' as const,
364
+ value: element,
365
+ };
366
+ }
367
+ },
368
+ );
369
+
370
+ return {
371
+ type: TransactionType.CUSTOM_CODE,
372
+ scriptElements,
373
+ witnesses: (params.witnesses || []).map((w) => w.toString('hex')),
374
+ annex: params.annex?.toString('hex'),
375
+ };
376
+ }
377
+
378
+ private static extractCancelData(
379
+ params: ITransactionParameters & {
380
+ compiledTargetScript?: Buffer | string;
381
+ },
382
+ ): CancelSpecificData {
383
+ const script = params.compiledTargetScript;
384
+ const scriptHex = script ? (Buffer.isBuffer(script) ? script.toString('hex') : script) : '';
385
+
386
+ return {
387
+ type: TransactionType.CANCEL,
388
+ compiledTargetScript: scriptHex,
389
+ };
390
+ }
391
+
392
+ /**
393
+ * Build precomputed data object
394
+ */
395
+ private static buildPrecomputedData(precomputed?: Partial<PrecomputedData>): PrecomputedData {
396
+ return {
397
+ compiledTargetScript: precomputed?.compiledTargetScript,
398
+ randomBytes: precomputed?.randomBytes,
399
+ estimatedFees: precomputed?.estimatedFees,
400
+ contractSeed: precomputed?.contractSeed,
401
+ contractAddress: precomputed?.contractAddress,
402
+ };
403
+ }
404
+
405
+ /**
406
+ * Serialize UTXOs array
407
+ */
408
+ private static serializeUTXOs(utxos: UTXO[]): SerializedUTXO[] {
409
+ return utxos.map((utxo) => ({
410
+ transactionId: utxo.transactionId,
411
+ outputIndex: utxo.outputIndex,
412
+ value: utxo.value.toString(),
413
+ scriptPubKeyHex: utxo.scriptPubKey.hex,
414
+ scriptPubKeyAddress: utxo.scriptPubKey.address,
415
+ redeemScript: utxo.redeemScript
416
+ ? Buffer.isBuffer(utxo.redeemScript)
417
+ ? utxo.redeemScript.toString('hex')
418
+ : utxo.redeemScript
419
+ : undefined,
420
+ witnessScript: utxo.witnessScript
421
+ ? Buffer.isBuffer(utxo.witnessScript)
422
+ ? utxo.witnessScript.toString('hex')
423
+ : utxo.witnessScript
424
+ : undefined,
425
+ nonWitnessUtxo: utxo.nonWitnessUtxo
426
+ ? Buffer.isBuffer(utxo.nonWitnessUtxo)
427
+ ? utxo.nonWitnessUtxo.toString('hex')
428
+ : utxo.nonWitnessUtxo
429
+ : undefined,
430
+ }));
431
+ }
432
+
433
+ /**
434
+ * Serialize outputs array
435
+ */
436
+ private static serializeOutputs(outputs: PsbtOutputExtended[]): SerializedOutput[] {
437
+ return outputs.map((output) => {
438
+ // PsbtOutputExtended is a union - handle both address and script variants
439
+ const address = 'address' in output ? output.address : undefined;
440
+ const script = 'script' in output ? output.script : undefined;
441
+
442
+ return {
443
+ value: output.value,
444
+ address,
445
+ script: script ? script.toString('hex') : undefined,
446
+ tapInternalKey: output.tapInternalKey
447
+ ? output.tapInternalKey.toString('hex')
448
+ : undefined,
449
+ };
450
+ });
451
+ }
452
+
453
+ /**
454
+ * Convert network to name string
455
+ */
456
+ private static networkToName(network: Network): 'mainnet' | 'testnet' | 'regtest' {
457
+ if (network.bech32 === 'bc') return 'mainnet';
458
+ if (network.bech32 === 'tb') return 'testnet';
459
+ return 'regtest';
460
+ }
461
+
462
+ /**
463
+ * Convert network to chain ID
464
+ */
465
+ private static networkToChainId(network: Network): ChainId {
466
+ // Default to Bitcoin chain
467
+ return ChainId.Bitcoin;
468
+ }
469
+ }
@@ -0,0 +1,8 @@
1
+ // Interfaces
2
+ export * from './interfaces/index.js';
3
+
4
+ // Core classes
5
+ export { TransactionSerializer } from './TransactionSerializer.js';
6
+ export { TransactionStateCapture, CaptureParams } from './TransactionStateCapture.js';
7
+ export { TransactionReconstructor, ReconstructionOptions } from './TransactionReconstructor.js';
8
+ export { OfflineTransactionManager, ExportOptions } from './OfflineTransactionManager.js';
@@ -0,0 +1,141 @@
1
+ import { TransactionType } from '../../enums/TransactionType.js';
2
+ import { ChainId } from '../../../network/ChainId.js';
3
+ import { TypeSpecificData } from './ITypeSpecificData.js';
4
+
5
+ /**
6
+ * Format version for serialization compatibility
7
+ */
8
+ export const SERIALIZATION_FORMAT_VERSION = 1;
9
+
10
+ /**
11
+ * Magic byte for identifying serialized transaction state
12
+ */
13
+ export const SERIALIZATION_MAGIC_BYTE = 0x42; // 'B' for Bitcoin
14
+
15
+ /**
16
+ * Version header for forward compatibility
17
+ */
18
+ export interface SerializationHeader {
19
+ /** Format version for migration support */
20
+ readonly formatVersion: number;
21
+ /** Consensus version at serialization time */
22
+ readonly consensusVersion: number;
23
+ /** Transaction type discriminant */
24
+ readonly transactionType: TransactionType;
25
+ /** Chain identifier */
26
+ readonly chainId: ChainId;
27
+ /** Timestamp of serialization (Unix epoch ms) */
28
+ readonly timestamp: number;
29
+ }
30
+
31
+ /**
32
+ * Serialized UTXO representation
33
+ */
34
+ export interface SerializedUTXO {
35
+ /** Transaction ID (32 bytes hex) */
36
+ readonly transactionId: string;
37
+ /** Output index (vout) */
38
+ readonly outputIndex: number;
39
+ /** Value in satoshis */
40
+ readonly value: string; // bigint as string for JSON compatibility
41
+ /** Script pubkey hex */
42
+ readonly scriptPubKeyHex: string;
43
+ /** Address derived from script (for signer lookup in rotation mode) */
44
+ readonly scriptPubKeyAddress?: string;
45
+ /** P2SH redeem script (hex) */
46
+ readonly redeemScript?: string;
47
+ /** P2WSH witness script (hex) */
48
+ readonly witnessScript?: string;
49
+ /** Full previous transaction for legacy scripts (hex) */
50
+ readonly nonWitnessUtxo?: string;
51
+ }
52
+
53
+ /**
54
+ * Serialized output representation
55
+ */
56
+ export interface SerializedOutput {
57
+ /** Value in satoshis */
58
+ readonly value: number;
59
+ /** Destination address */
60
+ readonly address?: string;
61
+ /** Output script (hex) */
62
+ readonly script?: string;
63
+ /** Taproot internal key (hex) */
64
+ readonly tapInternalKey?: string;
65
+ }
66
+
67
+ /**
68
+ * Serialized address-to-input-index mapping for address rotation
69
+ */
70
+ export interface SerializedSignerMapping {
71
+ /** Address that should sign these inputs */
72
+ readonly address: string;
73
+ /** Input indices this address should sign */
74
+ readonly inputIndices: number[];
75
+ }
76
+
77
+ /**
78
+ * Base transaction parameters (common to all types)
79
+ */
80
+ export interface SerializedBaseParams {
81
+ /** Sender address */
82
+ readonly from: string;
83
+ /** Recipient address (optional for some tx types) */
84
+ readonly to?: string;
85
+ /** Fee rate in sat/vB */
86
+ readonly feeRate: number;
87
+ /** OPNet priority fee */
88
+ readonly priorityFee: string; // bigint as string
89
+ /** OPNet gas sat fee */
90
+ readonly gasSatFee: string; // bigint as string
91
+ /** Network identifier */
92
+ readonly networkName: 'mainnet' | 'testnet' | 'regtest';
93
+ /** Transaction version (1, 2, or 3) */
94
+ readonly txVersion: number;
95
+ /** Optional note data (hex) */
96
+ readonly note?: string;
97
+ /** Whether to include anchor output */
98
+ readonly anchor: boolean;
99
+ /** Debug fee logging */
100
+ readonly debugFees?: boolean;
101
+ }
102
+
103
+ /**
104
+ * Pre-computed data that must be preserved for deterministic rebuild
105
+ */
106
+ export interface PrecomputedData {
107
+ /** Compiled target script (hex) - saves recomputation */
108
+ readonly compiledTargetScript?: string;
109
+ /** Random bytes used (hex) - MUST be preserved for determinism */
110
+ readonly randomBytes?: string;
111
+ /** Estimated fees from initial build */
112
+ readonly estimatedFees?: string; // bigint as string
113
+ /** Contract seed for deployment (hex) */
114
+ readonly contractSeed?: string;
115
+ /** Contract address for deployment */
116
+ readonly contractAddress?: string;
117
+ }
118
+
119
+ /**
120
+ * Complete serializable transaction state
121
+ */
122
+ export interface ISerializableTransactionState {
123
+ /** Version and type header */
124
+ readonly header: SerializationHeader;
125
+ /** Base transaction parameters */
126
+ readonly baseParams: SerializedBaseParams;
127
+ /** Primary UTXOs */
128
+ readonly utxos: SerializedUTXO[];
129
+ /** Optional additional inputs */
130
+ readonly optionalInputs: SerializedUTXO[];
131
+ /** Optional additional outputs */
132
+ readonly optionalOutputs: SerializedOutput[];
133
+ /** Whether address rotation mode is enabled */
134
+ readonly addressRotationEnabled: boolean;
135
+ /** Address to input indices mapping for rotation mode */
136
+ readonly signerMappings: SerializedSignerMapping[];
137
+ /** Type-specific data (discriminated by header.transactionType) */
138
+ readonly typeSpecificData: TypeSpecificData;
139
+ /** Pre-computed data for deterministic rebuild */
140
+ readonly precomputedData: PrecomputedData;
141
+ }