@btc-vision/transaction 1.7.7 → 1.7.11

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 (174) hide show
  1. package/browser/_version.d.ts +1 -0
  2. package/browser/chain/ChainData.d.ts +4 -0
  3. package/browser/{src/epoch → epoch}/interfaces/IChallengeSolution.d.ts +4 -4
  4. package/browser/{src/generators → generators}/Features.d.ts +6 -1
  5. package/browser/{src/generators → generators}/Generator.d.ts +1 -0
  6. package/browser/generators/MLDSAData.d.ts +15 -0
  7. package/browser/index.js +1 -1
  8. package/browser/{src/keypair → keypair}/Address.d.ts +9 -3
  9. package/browser/{src/keypair → keypair}/MessageSigner.d.ts +9 -0
  10. package/browser/{src/opnet.d.ts → opnet.d.ts} +1 -0
  11. package/browser/{src/transaction → transaction}/browser/Web3Provider.d.ts +15 -4
  12. package/browser/transaction/browser/types/OPWallet.d.ts +6 -0
  13. package/browser/{src/transaction → transaction}/builders/CustomScriptTransaction.d.ts +1 -0
  14. package/browser/{src/transaction → transaction}/builders/DeploymentTransaction.d.ts +1 -0
  15. package/browser/{src/transaction → transaction}/builders/TransactionBuilder.d.ts +4 -0
  16. package/browser/{src/transaction → transaction}/interfaces/ITransactionParameters.d.ts +3 -0
  17. package/browser/{src/transaction → transaction}/shared/TweakedTransaction.d.ts +6 -0
  18. package/browser/{src/utxo → utxo}/OPNetLimitedProvider.d.ts +1 -0
  19. package/build/_version.d.ts +1 -1
  20. package/build/_version.js +1 -1
  21. package/build/chain/ChainData.d.ts +4 -0
  22. package/build/chain/ChainData.js +20 -0
  23. package/build/epoch/ChallengeSolution.js +4 -4
  24. package/build/epoch/interfaces/IChallengeSolution.d.ts +4 -4
  25. package/build/generators/Features.d.ts +6 -1
  26. package/build/generators/Features.js +1 -0
  27. package/build/generators/Generator.d.ts +1 -0
  28. package/build/generators/Generator.js +24 -2
  29. package/build/generators/MLDSAData.d.ts +15 -0
  30. package/build/generators/MLDSAData.js +19 -0
  31. package/build/generators/builders/CalldataGenerator.js +1 -1
  32. package/build/generators/builders/DeploymentGenerator.js +1 -1
  33. package/build/generators/builders/P2WDAGenerator.js +1 -1
  34. package/build/keypair/Address.d.ts +9 -3
  35. package/build/keypair/Address.js +63 -38
  36. package/build/keypair/MessageSigner.d.ts +9 -0
  37. package/build/keypair/MessageSigner.js +101 -3
  38. package/build/opnet.d.ts +1 -0
  39. package/build/opnet.js +1 -0
  40. package/build/transaction/TransactionFactory.js +3 -0
  41. package/build/transaction/browser/Web3Provider.d.ts +15 -4
  42. package/build/transaction/browser/types/OPWallet.d.ts +2 -10
  43. package/build/transaction/browser/types/OPWallet.js +4 -2
  44. package/build/transaction/builders/CustomScriptTransaction.d.ts +1 -0
  45. package/build/transaction/builders/CustomScriptTransaction.js +3 -0
  46. package/build/transaction/builders/DeploymentTransaction.d.ts +1 -0
  47. package/build/transaction/builders/DeploymentTransaction.js +26 -1
  48. package/build/transaction/builders/InteractionTransaction.js +14 -1
  49. package/build/transaction/builders/InteractionTransactionP2WDA.js +14 -1
  50. package/build/transaction/builders/TransactionBuilder.d.ts +4 -0
  51. package/build/transaction/builders/TransactionBuilder.js +77 -0
  52. package/build/transaction/interfaces/ITransactionParameters.d.ts +3 -0
  53. package/build/transaction/shared/P2TR_MS.js +1 -0
  54. package/build/transaction/shared/TweakedTransaction.d.ts +6 -0
  55. package/build/transaction/shared/TweakedTransaction.js +19 -1
  56. package/build/utxo/OPNetLimitedProvider.d.ts +1 -0
  57. package/build/utxo/OPNetLimitedProvider.js +11 -1
  58. package/eslint.config.js +2 -1
  59. package/package.json +2 -1
  60. package/src/_version.ts +1 -1
  61. package/src/chain/ChainData.ts +32 -0
  62. package/src/deterministic/DeterministicSet.ts +2 -1
  63. package/src/epoch/ChallengeSolution.ts +4 -4
  64. package/src/epoch/interfaces/IChallengeSolution.ts +4 -4
  65. package/src/generators/Features.ts +8 -2
  66. package/src/generators/Generator.ts +35 -2
  67. package/src/generators/MLDSAData.ts +30 -0
  68. package/src/generators/builders/CalldataGenerator.ts +1 -1
  69. package/src/generators/builders/DeploymentGenerator.ts +2 -1
  70. package/src/generators/builders/LegacyCalldataGenerator.ts +1 -0
  71. package/src/generators/builders/P2WDAGenerator.ts +5 -1
  72. package/src/keypair/Address.ts +78 -38
  73. package/src/keypair/MessageSigner.ts +214 -15
  74. package/src/opnet.ts +2 -0
  75. package/src/transaction/TransactionFactory.ts +3 -0
  76. package/src/transaction/browser/Web3Provider.ts +64 -4
  77. package/src/transaction/browser/types/OPWallet.ts +6 -53
  78. package/src/transaction/builders/CustomScriptTransaction.ts +4 -0
  79. package/src/transaction/builders/DeploymentTransaction.ts +36 -8
  80. package/src/transaction/builders/InteractionTransaction.ts +17 -7
  81. package/src/transaction/builders/InteractionTransactionP2WDA.ts +17 -7
  82. package/src/transaction/builders/TransactionBuilder.ts +107 -0
  83. package/src/transaction/interfaces/ITransactionParameters.ts +12 -0
  84. package/src/transaction/shared/P2TR_MS.ts +1 -0
  85. package/src/transaction/shared/TweakedTransaction.ts +35 -2
  86. package/src/utxo/OPNetLimitedProvider.ts +19 -2
  87. package/test/address.test.ts +18 -20
  88. package/test/addressmap.test.ts +783 -0
  89. package/test/addressverificator-mldsa.test.ts +40 -16
  90. package/test/messagesigner-mldsa.test.ts +50 -50
  91. package/test/messagesigner-schnorr.test.ts +40 -40
  92. package/tsconfig.webpack.json +2 -6
  93. package/webpack.config.js +1 -1
  94. package/browser/src/_version.d.ts +0 -1
  95. package/browser/src/transaction/browser/types/OPWallet.d.ts +0 -14
  96. package/browser/test/address.test.d.ts +0 -1
  97. package/browser/test/addressverificator-mldsa.test.d.ts +0 -1
  98. package/browser/test/derivePath.test.d.ts +0 -1
  99. package/browser/test/fastmap-setall.test.d.ts +0 -1
  100. package/browser/test/fastmap.test.d.ts +0 -1
  101. package/browser/test/messagesigner-mldsa.test.d.ts +0 -1
  102. package/browser/test/messagesigner-schnorr.test.d.ts +0 -1
  103. package/browser/test/network-awareness.test.d.ts +0 -1
  104. package/browser/test/old/FastBigIntMap.d.ts +0 -18
  105. package/browser/test/oldfastmap.test.d.ts +0 -1
  106. /package/browser/{src/abi → abi}/ABICoder.d.ts +0 -0
  107. /package/browser/{src/buffer → buffer}/BinaryReader.d.ts +0 -0
  108. /package/browser/{src/buffer → buffer}/BinaryWriter.d.ts +0 -0
  109. /package/browser/{src/bytecode → bytecode}/Compressor.d.ts +0 -0
  110. /package/browser/{src/consensus → consensus}/Consensus.d.ts +0 -0
  111. /package/browser/{src/consensus → consensus}/ConsensusConfig.d.ts +0 -0
  112. /package/browser/{src/consensus → consensus}/metadata/RoswellConsensus.d.ts +0 -0
  113. /package/browser/{src/crypto → crypto}/crypto-browser.d.ts +0 -0
  114. /package/browser/{src/crypto → crypto}/crypto.d.ts +0 -0
  115. /package/browser/{src/deterministic → deterministic}/AddressMap.d.ts +0 -0
  116. /package/browser/{src/deterministic → deterministic}/AddressSet.d.ts +0 -0
  117. /package/browser/{src/deterministic → deterministic}/CustomMap.d.ts +0 -0
  118. /package/browser/{src/deterministic → deterministic}/DeterministicMap.d.ts +0 -0
  119. /package/browser/{src/deterministic → deterministic}/DeterministicSet.d.ts +0 -0
  120. /package/browser/{src/deterministic → deterministic}/FastMap.d.ts +0 -0
  121. /package/browser/{src/epoch → epoch}/ChallengeSolution.d.ts +0 -0
  122. /package/browser/{src/epoch → epoch}/validator/EpochValidator.d.ts +0 -0
  123. /package/browser/{src/event → event}/NetEvent.d.ts +0 -0
  124. /package/browser/{src/generators → generators}/AddressGenerator.d.ts +0 -0
  125. /package/browser/{src/generators → generators}/builders/CalldataGenerator.d.ts +0 -0
  126. /package/browser/{src/generators → generators}/builders/CustomGenerator.d.ts +0 -0
  127. /package/browser/{src/generators → generators}/builders/DeploymentGenerator.d.ts +0 -0
  128. /package/browser/{src/generators → generators}/builders/LegacyCalldataGenerator.d.ts +0 -0
  129. /package/browser/{src/generators → generators}/builders/MultiSignGenerator.d.ts +0 -0
  130. /package/browser/{src/generators → generators}/builders/P2WDAGenerator.d.ts +0 -0
  131. /package/browser/{src/index.d.ts → index.d.ts} +0 -0
  132. /package/browser/{src/keypair → keypair}/AddressVerificator.d.ts +0 -0
  133. /package/browser/{src/keypair → keypair}/EcKeyPair.d.ts +0 -0
  134. /package/browser/{src/keypair → keypair}/Secp256k1PointDeriver.d.ts +0 -0
  135. /package/browser/{src/keypair → keypair}/Wallet.d.ts +0 -0
  136. /package/browser/{src/keypair → keypair}/interfaces/IWallet.d.ts +0 -0
  137. /package/browser/{src/metadata → metadata}/ContractBaseMetadata.d.ts +0 -0
  138. /package/browser/{src/metadata → metadata}/tokens.d.ts +0 -0
  139. /package/browser/{src/mnemonic → mnemonic}/BIPStandard.d.ts +0 -0
  140. /package/browser/{src/mnemonic → mnemonic}/Mnemonic.d.ts +0 -0
  141. /package/browser/{src/mnemonic → mnemonic}/MnemonicStrength.d.ts +0 -0
  142. /package/browser/{src/network → network}/ChainId.d.ts +0 -0
  143. /package/browser/{src/p2wda → p2wda}/P2WDADetector.d.ts +0 -0
  144. /package/browser/{src/signer → signer}/SignerUtils.d.ts +0 -0
  145. /package/browser/{src/signer → signer}/TweakedSigner.d.ts +0 -0
  146. /package/browser/{src/transaction → transaction}/ContractAddress.d.ts +0 -0
  147. /package/browser/{src/transaction → transaction}/TransactionFactory.d.ts +0 -0
  148. /package/browser/{src/transaction → transaction}/browser/BrowserSignerBase.d.ts +0 -0
  149. /package/browser/{src/transaction → transaction}/browser/extensions/UnisatSigner.d.ts +0 -0
  150. /package/browser/{src/transaction → transaction}/browser/extensions/XverseSigner.d.ts +0 -0
  151. /package/browser/{src/transaction → transaction}/browser/types/Unisat.d.ts +0 -0
  152. /package/browser/{src/transaction → transaction}/browser/types/Xverse.d.ts +0 -0
  153. /package/browser/{src/transaction → transaction}/builders/CancelTransaction.d.ts +0 -0
  154. /package/browser/{src/transaction → transaction}/builders/ChallengeSolutionTransaction.d.ts +0 -0
  155. /package/browser/{src/transaction → transaction}/builders/FundingTransaction.d.ts +0 -0
  156. /package/browser/{src/transaction → transaction}/builders/InteractionTransaction.d.ts +0 -0
  157. /package/browser/{src/transaction → transaction}/builders/InteractionTransactionP2WDA.d.ts +0 -0
  158. /package/browser/{src/transaction → transaction}/builders/MultiSignTransaction.d.ts +0 -0
  159. /package/browser/{src/transaction → transaction}/builders/SharedInteractionTransaction.d.ts +0 -0
  160. /package/browser/{src/transaction → transaction}/enums/TransactionType.d.ts +0 -0
  161. /package/browser/{src/transaction → transaction}/interfaces/Tap.d.ts +0 -0
  162. /package/browser/{src/transaction → transaction}/mineable/IP2WSHAddress.d.ts +0 -0
  163. /package/browser/{src/transaction → transaction}/mineable/TimelockGenerator.d.ts +0 -0
  164. /package/browser/{src/transaction → transaction}/processor/PsbtTransaction.d.ts +0 -0
  165. /package/browser/{src/transaction → transaction}/psbt/PSBTTypes.d.ts +0 -0
  166. /package/browser/{src/transaction → transaction}/shared/P2TR_MS.d.ts +0 -0
  167. /package/browser/{src/utils → utils}/BitcoinUtils.d.ts +0 -0
  168. /package/browser/{src/utils → utils}/BufferHelper.d.ts +0 -0
  169. /package/browser/{src/utils → utils}/StringToBuffer.d.ts +0 -0
  170. /package/browser/{src/utils → utils}/lengths.d.ts +0 -0
  171. /package/browser/{src/utils → utils}/types.d.ts +0 -0
  172. /package/browser/{src/utxo → utxo}/interfaces/BroadcastResponse.d.ts +0 -0
  173. /package/browser/{src/utxo → utxo}/interfaces/IUTXO.d.ts +0 -0
  174. /package/browser/{src/verification → verification}/TapscriptVerificator.d.ts +0 -0
@@ -6,25 +6,26 @@ import { UTXO } from '../../utxo/interfaces/IUTXO.js';
6
6
  import { CancelledTransaction, DeploymentResult, InteractionResponse } from '../TransactionFactory';
7
7
  import { ICustomTransactionParameters } from '../builders/CustomScriptTransaction.js';
8
8
  import { ICancelTransactionParameters } from '../builders/CancelTransaction.js';
9
+ import { MLDSASecurityLevel } from '@btc-vision/bip32';
9
10
 
10
11
  export type InteractionParametersWithoutSigner = Omit<
11
12
  IInteractionParameters,
12
- 'signer' | 'challenge'
13
+ 'signer' | 'challenge' | 'mldsaSigner'
13
14
  >;
14
15
 
15
16
  export type IDeploymentParametersWithoutSigner = Omit<
16
17
  IDeploymentParameters,
17
- 'signer' | 'network' | 'challenge'
18
+ 'signer' | 'network' | 'challenge' | 'mldsaSigner'
18
19
  >;
19
20
 
20
21
  export type ICustomTransactionWithoutSigner = Omit<
21
22
  ICustomTransactionParameters,
22
- 'signer' | 'challenge'
23
+ 'signer' | 'challenge' | 'mldsaSigner'
23
24
  >;
24
25
 
25
26
  export type ICancelTransactionParametersWithoutSigner = Omit<
26
27
  ICancelTransactionParameters,
27
- 'signer' | 'challenge' | 'network'
28
+ 'signer' | 'challenge' | 'network' | 'mldsaSigner'
28
29
  >;
29
30
 
30
31
  export interface BroadcastTransactionOptions {
@@ -52,6 +53,31 @@ export interface BroadcastedTransaction {
52
53
  readonly peers?: number;
53
54
  }
54
55
 
56
+ /**
57
+ * ML-DSA signature result
58
+ */
59
+ export interface MLDSASignature {
60
+ /**
61
+ * The ML-DSA signature in hex format
62
+ */
63
+ readonly signature: string;
64
+
65
+ /**
66
+ * The ML-DSA public key used for signing in hex format
67
+ */
68
+ readonly publicKey: string;
69
+
70
+ /**
71
+ * The security level used (44, 65, or 87)
72
+ */
73
+ readonly securityLevel: MLDSASecurityLevel;
74
+
75
+ /**
76
+ * The message hash that was signed
77
+ */
78
+ readonly messageHash: string;
79
+ }
80
+
55
81
  export interface Web3Provider {
56
82
  signInteraction(
57
83
  interactionParameters: InteractionParametersWithoutSigner,
@@ -70,4 +96,38 @@ export interface Web3Provider {
70
96
  deployContract(params: IDeploymentParametersWithoutSigner): Promise<DeploymentResult>;
71
97
 
72
98
  broadcast(transactions: BroadcastTransactionOptions[]): Promise<BroadcastedTransaction[]>;
99
+
100
+ /**
101
+ * Sign a message using Schnorr signature
102
+ * @param message - Hexadecimal string message to sign
103
+ * @returns The Schnorr signature in hex format
104
+ * @throws {Error} If signing fails or wallet is not connected
105
+ */
106
+ signSchnorr(message: string): Promise<string>;
107
+
108
+ /**
109
+ * Get the ML-DSA public key for the current account
110
+ *
111
+ * @returns The ML-DSA public key in hex format (never exposes private keys)
112
+ * @throws {Error} If the wallet is not connected
113
+ */
114
+ getMLDSAPublicKey(): Promise<string>;
115
+
116
+ /**
117
+ * Sign a message using ML-DSA signature
118
+ *
119
+ * @param message - The message to sign as a hexadecimal string
120
+ * @returns The ML-DSA signature
121
+ * @throws {Error} If signing fails or wallet is not connected
122
+ */
123
+ signMLDSAMessage(message: string): Promise<MLDSASignature>;
124
+
125
+ /**
126
+ * Verify an ML-DSA signature
127
+ *
128
+ * @param message - The original message, hexadecimal string
129
+ * @param signature - The ML-DSA signature to verify
130
+ * @returns True if the signature is valid
131
+ */
132
+ verifyMLDSASignature(message: string, signature: MLDSASignature): Promise<boolean>;
73
133
  }
@@ -1,30 +1,5 @@
1
1
  import { Unisat } from './Unisat.js';
2
- import { MLDSASecurityLevel } from '@btc-vision/bip32';
3
-
4
- /**
5
- * ML-DSA signature result
6
- */
7
- export interface MLDSASignature {
8
- /**
9
- * The ML-DSA signature in hex format
10
- */
11
- readonly signature: string;
12
-
13
- /**
14
- * The ML-DSA public key used for signing in hex format
15
- */
16
- readonly publicKey: string;
17
-
18
- /**
19
- * The security level used (44, 65, or 87)
20
- */
21
- readonly securityLevel: MLDSASecurityLevel;
22
-
23
- /**
24
- * The message hash that was signed
25
- */
26
- readonly messageHash: string;
27
- }
2
+ import { Web3Provider } from '../Web3Provider.js';
28
3
 
29
4
  /**
30
5
  * OPWallet interface extending Unisat with ML-DSA (FIPS 204) support
@@ -33,31 +8,7 @@ export interface MLDSASignature {
33
8
  * Private keys are NEVER exposed through this interface.
34
9
  */
35
10
  export interface OPWallet extends Unisat {
36
- /**
37
- * Get the ML-DSA public key for the current account
38
- *
39
- * @returns The ML-DSA public key in hex format (never exposes private keys)
40
- * @throws {Error} If the wallet is not connected
41
- */
42
- getMLDSAPublicKey(): Promise<string>;
43
-
44
- /**
45
- * Sign a message using ML-DSA signature
46
- *
47
- * @param message - The message to sign
48
- * @returns The ML-DSA signature
49
- * @throws {Error} If signing fails or wallet is not connected
50
- */
51
- signMLDSAMessage(message: string): Promise<MLDSASignature>;
52
-
53
- /**
54
- * Verify an ML-DSA signature
55
- *
56
- * @param message - The original message
57
- * @param signature - The ML-DSA signature to verify
58
- * @returns True if the signature is valid
59
- */
60
- verifyMLDSASignature(message: string, signature: MLDSASignature): Promise<boolean>;
11
+ web3: Web3Provider;
61
12
  }
62
13
 
63
14
  /**
@@ -67,7 +18,9 @@ export function isOPWallet(wallet: unknown): wallet is OPWallet {
67
18
  return (
68
19
  typeof wallet === 'object' &&
69
20
  wallet !== null &&
70
- 'getMLDSAPublicKey' in wallet &&
71
- 'signMLDSAMessage' in wallet
21
+ 'web3' in wallet &&
22
+ typeof wallet.web3 === 'object' &&
23
+ 'getMLDSAPublicKey' in (wallet.web3 as Web3Provider) &&
24
+ 'signMLDSAMessage' in (wallet.web3 as Web3Provider)
72
25
  );
73
26
  }
@@ -137,6 +137,10 @@ export class CustomScriptTransaction extends TransactionBuilder<TransactionType.
137
137
  return this.to || this.getScriptAddress();
138
138
  }
139
139
 
140
+ public exportCompiledTargetScript(): Buffer {
141
+ return this.compiledTargetScript;
142
+ }
143
+
140
144
  /**
141
145
  * Get the random bytes used for the interaction
142
146
  * @returns {Buffer} The random bytes
@@ -113,6 +113,10 @@ export class DeploymentTransaction extends TransactionBuilder<TransactionType.DE
113
113
  public constructor(parameters: IDeploymentParameters) {
114
114
  super(parameters);
115
115
 
116
+ if (!this.hashedPublicKey) {
117
+ throw new Error('MLDSA signer must be defined to deploy a contract.');
118
+ }
119
+
116
120
  this.bytecode = Compressor.compress(Buffer.concat([versionBuffer, parameters.bytecode]));
117
121
 
118
122
  this.verifyBytecode();
@@ -142,14 +146,24 @@ export class DeploymentTransaction extends TransactionBuilder<TransactionType.DE
142
146
  this.network,
143
147
  );
144
148
 
145
- this.compiledTargetScript = this.deploymentGenerator.compile(
146
- this.bytecode,
147
- this.randomBytes,
148
- this.challenge,
149
- this.priorityFee,
150
- this.calldata,
151
- this.generateFeatures(parameters),
152
- );
149
+ if (parameters.compiledTargetScript) {
150
+ if (Buffer.isBuffer(parameters.compiledTargetScript)) {
151
+ this.compiledTargetScript = parameters.compiledTargetScript;
152
+ } else if (typeof parameters.compiledTargetScript === 'string') {
153
+ this.compiledTargetScript = Buffer.from(parameters.compiledTargetScript, 'hex');
154
+ } else {
155
+ throw new Error('Invalid compiled target script format.');
156
+ }
157
+ } else {
158
+ this.compiledTargetScript = this.deploymentGenerator.compile(
159
+ this.bytecode,
160
+ this.randomBytes,
161
+ this.challenge,
162
+ this.priorityFee,
163
+ this.calldata,
164
+ this.generateFeatures(parameters),
165
+ );
166
+ }
153
167
 
154
168
  this.scriptTree = this.getScriptTree();
155
169
 
@@ -180,6 +194,10 @@ export class DeploymentTransaction extends TransactionBuilder<TransactionType.DE
180
194
  return this.to || this.getScriptAddress();
181
195
  }
182
196
 
197
+ public exportCompiledTargetScript(): Buffer {
198
+ return this.compiledTargetScript;
199
+ }
200
+
183
201
  /**
184
202
  * Get the random bytes used for the interaction
185
203
  * @returns {Buffer} The random bytes
@@ -366,6 +384,16 @@ export class DeploymentTransaction extends TransactionBuilder<TransactionType.DE
366
384
  });
367
385
  }
368
386
 
387
+ if (parameters.revealMLDSAPublicKey && !parameters.linkMLDSAPublicKeyToAddress) {
388
+ throw new Error(
389
+ 'To reveal the MLDSA public key, you must set linkMLDSAPublicKeyToAddress to true.',
390
+ );
391
+ }
392
+
393
+ if (parameters.linkMLDSAPublicKeyToAddress) {
394
+ this.generateMLDSALinkRequest(parameters, features);
395
+ }
396
+
369
397
  return features;
370
398
  }
371
399
 
@@ -36,13 +36,23 @@ export class InteractionTransaction extends SharedInteractionTransaction<Transac
36
36
  throw new Error('Invalid contract secret length. Expected 32 bytes.');
37
37
  }
38
38
 
39
- this.compiledTargetScript = this.calldataGenerator.compile(
40
- this.calldata,
41
- this.contractSecret,
42
- this.challenge,
43
- this.priorityFee,
44
- this.generateFeatures(parameters),
45
- );
39
+ if (parameters.compiledTargetScript) {
40
+ if (Buffer.isBuffer(parameters.compiledTargetScript)) {
41
+ this.compiledTargetScript = parameters.compiledTargetScript;
42
+ } else if (typeof parameters.compiledTargetScript === 'string') {
43
+ this.compiledTargetScript = Buffer.from(parameters.compiledTargetScript, 'hex');
44
+ } else {
45
+ throw new Error('Invalid compiled target script format.');
46
+ }
47
+ } else {
48
+ this.compiledTargetScript = this.calldataGenerator.compile(
49
+ this.calldata,
50
+ this.contractSecret,
51
+ this.challenge,
52
+ this.priorityFee,
53
+ this.generateFeatures(parameters),
54
+ );
55
+ }
46
56
 
47
57
  this.scriptTree = this.getScriptTree();
48
58
  this.internalInit();
@@ -97,13 +97,23 @@ export class InteractionTransactionP2WDA extends TransactionBuilder<TransactionT
97
97
  // Validate P2WDA inputs
98
98
  this.validateP2WDAInputs();
99
99
 
100
- this.compiledOperationData = this.p2wdaGenerator.compile(
101
- this.calldata,
102
- this.contractSecret,
103
- this.challenge,
104
- this.priorityFee,
105
- this.generateFeatures(parameters),
106
- );
100
+ if (parameters.compiledTargetScript) {
101
+ if (Buffer.isBuffer(parameters.compiledTargetScript)) {
102
+ this.compiledOperationData = parameters.compiledTargetScript;
103
+ } else if (typeof parameters.compiledTargetScript === 'string') {
104
+ this.compiledOperationData = Buffer.from(parameters.compiledTargetScript, 'hex');
105
+ } else {
106
+ throw new Error('Invalid compiled target script format.');
107
+ }
108
+ } else {
109
+ this.compiledOperationData = this.p2wdaGenerator.compile(
110
+ this.calldata,
111
+ this.contractSecret,
112
+ this.challenge,
113
+ this.priorityFee,
114
+ this.generateFeatures(parameters),
115
+ );
116
+ }
107
117
 
108
118
  // Validate size early
109
119
  this.validateOperationDataSize();
@@ -27,6 +27,12 @@ import { TweakedTransaction } from '../shared/TweakedTransaction.js';
27
27
  import { UnisatSigner } from '../browser/extensions/UnisatSigner.js';
28
28
  import { IP2WSHAddress } from '../mineable/IP2WSHAddress.js';
29
29
  import { P2WDADetector } from '../../p2wda/P2WDADetector.js';
30
+ import { Feature, Features, MLDSALinkRequest } from '../../generators/Features.js';
31
+ import { BITCOIN_PROTOCOL_ID, getChainId } from '../../chain/ChainData.js';
32
+ import { BinaryWriter } from '../../buffer/BinaryWriter.js';
33
+ import { MLDSASecurityLevel } from '@btc-vision/bip32';
34
+ import { MessageSigner } from '../../keypair/MessageSigner.js';
35
+ import { getLevelFromPublicKeyLength } from '../../generators/MLDSAData.js';
30
36
 
31
37
  initEccLib(ecc);
32
38
 
@@ -288,6 +294,7 @@ export abstract class TransactionBuilder<T extends TransactionType> extends Twea
288
294
  amount: this.estimatedFees,
289
295
  optionalOutputs: this.optionalOutputs,
290
296
  optionalInputs: this.optionalInputs,
297
+ mldsaSigner: null,
291
298
  };
292
299
  }
293
300
 
@@ -874,6 +881,106 @@ export abstract class TransactionBuilder<T extends TransactionType> extends Twea
874
881
  throw new Error('Output not found');
875
882
  }
876
883
 
884
+ protected generateLegacySignature(): Buffer {
885
+ this.tweakSigner();
886
+
887
+ if (!this.tweakedSigner) {
888
+ throw new Error('Tweaked signer is not defined');
889
+ }
890
+
891
+ const tweakedKey = toXOnly(this.tweakedSigner.publicKey);
892
+ const chainId = getChainId(this.network);
893
+
894
+ const writer = new BinaryWriter();
895
+
896
+ // ONLY SUPPORT MLDSA-44 FOR NOW.
897
+ writer.writeU8(MLDSASecurityLevel.LEVEL2);
898
+ writer.writeBytes(this.hashedPublicKey);
899
+ writer.writeBytes(tweakedKey);
900
+ writer.writeBytes(BITCOIN_PROTOCOL_ID);
901
+ writer.writeBytes(chainId);
902
+
903
+ const message = writer.getBuffer();
904
+ const signature = MessageSigner.signMessage(this.tweakedSigner, message);
905
+ const isValid = MessageSigner.verifySignature(tweakedKey, message, signature.signature);
906
+
907
+ if (!isValid) {
908
+ throw new Error('Could not verify generated legacy signature for MLDSA link request');
909
+ }
910
+
911
+ return Buffer.from(signature.signature);
912
+ }
913
+
914
+ protected generateMLDSASignature(): Buffer {
915
+ if (!this.mldsaSigner) {
916
+ throw new Error('MLDSA signer is not defined');
917
+ }
918
+
919
+ this.tweakSigner();
920
+
921
+ if (!this.tweakedSigner) {
922
+ throw new Error('Tweaked signer is not defined');
923
+ }
924
+
925
+ const tweakedKey = toXOnly(this.tweakedSigner.publicKey);
926
+ const chainId = getChainId(this.network);
927
+ const level = getLevelFromPublicKeyLength(this.mldsaSigner.publicKey.length);
928
+
929
+ if (level !== MLDSASecurityLevel.LEVEL2) {
930
+ throw new Error('Only MLDSA level 2 is supported for link requests');
931
+ }
932
+
933
+ const writer = new BinaryWriter();
934
+ writer.writeU8(level);
935
+ writer.writeBytes(this.hashedPublicKey);
936
+ writer.writeBytes(this.mldsaSigner.publicKey);
937
+ writer.writeBytes(tweakedKey);
938
+ writer.writeBytes(BITCOIN_PROTOCOL_ID);
939
+ writer.writeBytes(chainId);
940
+
941
+ const message = writer.getBuffer();
942
+ const signature = MessageSigner.signMLDSAMessage(this.mldsaSigner, message);
943
+
944
+ const isValid = MessageSigner.verifyMLDSASignature(
945
+ this.mldsaSigner,
946
+ message,
947
+ signature.signature,
948
+ );
949
+
950
+ if (!isValid) {
951
+ throw new Error('Could not verify generated MLDSA signature for link request');
952
+ }
953
+
954
+ return Buffer.from(signature.signature);
955
+ }
956
+
957
+ protected generateMLDSALinkRequest(
958
+ parameters: ITransactionParameters,
959
+ features: Feature<Features>[],
960
+ ): void {
961
+ const mldsaSigner = this.mldsaSigner;
962
+ const legacySignature = this.generateLegacySignature();
963
+
964
+ let mldsaSignature: Buffer | null = null;
965
+ if (parameters.revealMLDSAPublicKey) {
966
+ mldsaSignature = this.generateMLDSASignature();
967
+ }
968
+
969
+ const mldsaRequest: MLDSALinkRequest = {
970
+ opcode: Features.MLDSA_LINK_PUBKEY,
971
+ data: {
972
+ verifyRequest: !!parameters.revealMLDSAPublicKey,
973
+ publicKey: mldsaSigner.publicKey,
974
+ hashedPublicKey: this.hashedPublicKey,
975
+ level: getLevelFromPublicKeyLength(mldsaSigner.publicKey.length),
976
+ legacySignature: legacySignature,
977
+ mldsaSignature: mldsaSignature,
978
+ },
979
+ };
980
+
981
+ features.push(mldsaRequest);
982
+ }
983
+
877
984
  /**
878
985
  * @description Returns the transaction opnet fee
879
986
  * @protected
@@ -13,6 +13,16 @@ export interface ITransactionParameters extends ITweakedTransactionData {
13
13
  readonly to?: string;
14
14
  readonly debugFees?: boolean;
15
15
 
16
+ /**
17
+ * Reveal this user's MLDSA public key in the transaction features.
18
+ */
19
+ readonly revealMLDSAPublicKey?: boolean;
20
+
21
+ /**
22
+ * Link the user MLDSA public key to their legacy public key.
23
+ */
24
+ readonly linkMLDSAPublicKeyToAddress?: boolean;
25
+
16
26
  utxos: UTXO[];
17
27
 
18
28
  nonWitnessUtxo?: Buffer;
@@ -30,6 +40,8 @@ export interface ITransactionParameters extends ITweakedTransactionData {
30
40
  readonly feeRate: number;
31
41
  readonly priorityFee: bigint;
32
42
  readonly gasSatFee: bigint;
43
+
44
+ readonly compiledTargetScript?: Buffer | string;
33
45
  }
34
46
 
35
47
  export interface IFundingTransactionParameters extends ITransactionParameters {
@@ -29,6 +29,7 @@ export class P2TR_MS {
29
29
  receiver: 'a',
30
30
  requestedAmount: 1n,
31
31
  refundVault: 'a',
32
+ mldsaSigner: null,
32
33
  };
33
34
 
34
35
  const address = new MultiSignTransaction(multiSignParams).getScriptAddress();
@@ -41,10 +41,13 @@ import {
41
41
  import { TransactionBuilder } from '../builders/TransactionBuilder.js';
42
42
  import { Buffer } from 'buffer';
43
43
  import { P2WDADetector } from '../../p2wda/P2WDADetector.js';
44
+ import { QuantumBIP32Interface } from '@btc-vision/bip32';
45
+ import { MessageSigner } from '../../keypair/MessageSigner.js';
44
46
 
45
47
  export type SupportedTransactionVersion = 1 | 2 | 3;
46
48
 
47
49
  export interface ITweakedTransactionData {
50
+ readonly mldsaSigner: QuantumBIP32Interface | null;
48
51
  readonly signer: Signer | ECPairInterface | UnisatSigner;
49
52
  readonly network: Network;
50
53
  readonly chainId?: ChainId;
@@ -67,8 +70,6 @@ export enum CSVModes {
67
70
  TIMESTAMPS = 1,
68
71
  }
69
72
 
70
- const CSV_ENABLED_BLOCKS_MASK = 0x3fffffff;
71
-
72
73
  /**
73
74
  * @description PSBT Transaction processor.
74
75
  * */
@@ -161,6 +162,9 @@ export abstract class TweakedTransaction extends Logger {
161
162
 
162
163
  protected txVersion: SupportedTransactionVersion = 2;
163
164
 
165
+ protected readonly _mldsaSigner: QuantumBIP32Interface | null = null;
166
+ protected readonly _hashedPublicKey: Buffer | null = null;
167
+
164
168
  protected constructor(data: ITweakedTransactionData) {
165
169
  super();
166
170
 
@@ -176,6 +180,35 @@ export abstract class TweakedTransaction extends Logger {
176
180
  if (data.txVersion) {
177
181
  this.txVersion = data.txVersion;
178
182
  }
183
+
184
+ if (data.mldsaSigner) {
185
+ this._mldsaSigner = data.mldsaSigner;
186
+ this._hashedPublicKey = MessageSigner.sha256(this._mldsaSigner.publicKey);
187
+ }
188
+ }
189
+
190
+ /**
191
+ * Get the MLDSA signer
192
+ * @protected
193
+ */
194
+ protected get mldsaSigner(): QuantumBIP32Interface {
195
+ if (!this._mldsaSigner) {
196
+ throw new Error('MLDSA Signer is not set');
197
+ }
198
+
199
+ return this._mldsaSigner;
200
+ }
201
+
202
+ /**
203
+ * Get the hashed public key
204
+ * @protected
205
+ */
206
+ protected get hashedPublicKey(): Buffer {
207
+ if (!this._hashedPublicKey) {
208
+ throw new Error('Hashed public key is not set');
209
+ }
210
+
211
+ return this._hashedPublicKey;
179
212
  }
180
213
 
181
214
  /**
@@ -12,6 +12,7 @@ export interface WalletUTXOs {
12
12
  readonly confirmed: RawUTXOResponse[];
13
13
  readonly pending: RawUTXOResponse[];
14
14
  readonly spentTransactions: RawUTXOResponse[];
15
+ readonly raw: string[];
15
16
  }
16
17
 
17
18
  /**
@@ -53,6 +54,8 @@ export class OPNetLimitedProvider {
53
54
  }
54
55
 
55
56
  const fetchedData: WalletUTXOs = (await resp.json()) as WalletUTXOs;
57
+ const rawTransactions = fetchedData.raw ?? [];
58
+
56
59
  const allUtxos = settings.usePendingUTXO
57
60
  ? [...fetchedData.confirmed, ...fetchedData.pending]
58
61
  : fetchedData.confirmed;
@@ -91,18 +94,31 @@ export class OPNetLimitedProvider {
91
94
  for (const utxo of meetCriteria) {
92
95
  const utxoValue: bigint = BigInt(utxo.value);
93
96
 
94
- // check if value is greater than 0
95
97
  if (utxoValue <= 0n) {
96
98
  continue;
97
99
  }
98
100
 
101
+ const rawIndex = utxo.raw as unknown as number;
102
+ if (rawIndex === undefined || rawIndex === null) {
103
+ throw new Error(
104
+ `Missing raw index for UTXO ${utxo.transactionId}:${utxo.outputIndex}`,
105
+ );
106
+ }
107
+
108
+ const rawHex = rawTransactions[rawIndex];
109
+ if (!rawHex) {
110
+ throw new Error(
111
+ `Invalid raw index ${rawIndex} - not found in raw transactions array`,
112
+ );
113
+ }
114
+
99
115
  currentAmount += utxoValue;
100
116
  finalUTXOs.push({
101
117
  transactionId: utxo.transactionId,
102
118
  outputIndex: utxo.outputIndex,
103
119
  value: utxoValue,
104
120
  scriptPubKey: utxo.scriptPubKey,
105
- nonWitnessUtxo: Buffer.from(utxo.raw, 'base64'),
121
+ nonWitnessUtxo: Buffer.from(rawHex, 'base64'),
106
122
  });
107
123
 
108
124
  if (currentAmount > amountRequested) {
@@ -213,6 +229,7 @@ export class OPNetLimitedProvider {
213
229
  splitInputsInto,
214
230
  priorityFee: 0n,
215
231
  gasSatFee: 330n,
232
+ mldsaSigner: null,
216
233
  };
217
234
 
218
235
  const transactionFactory = new TransactionFactory();