@btc-vision/transaction 1.8.7 → 1.8.9
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.
- package/browser/btc-vision-bitcoin.js +705 -703
- package/browser/index.js +116 -108
- package/browser/noble-curves.js +4 -4
- package/browser/noble-hashes.js +88 -88
- package/browser/rolldown-runtime.js +26 -19
- package/browser/src/epoch/validator/EpochValidator.d.ts +28 -6
- package/browser/vendors.js +3065 -3027
- package/build/epoch/validator/EpochValidator.d.ts +28 -6
- package/build/epoch/validator/EpochValidator.js +44 -10
- package/build/transaction/builders/TransactionBuilder.js +18 -2
- package/package.json +1 -1
- package/src/epoch/validator/EpochValidator.ts +67 -6
- package/src/transaction/builders/TransactionBuilder.ts +19 -2
- package/tsconfig.build.tsbuildinfo +1 -1
|
@@ -6,9 +6,31 @@ export declare class EpochValidator {
|
|
|
6
6
|
*/
|
|
7
7
|
static sha1(data: Uint8Array): Uint8Array;
|
|
8
8
|
/**
|
|
9
|
-
* Calculate mining preimage
|
|
9
|
+
* Calculate mining preimage.
|
|
10
|
+
*
|
|
11
|
+
* When useConcatenatedPreimage is false the legacy XOR construction is used
|
|
12
|
+
* (checksumRoot ^ publicKey ^ salt). That construction is malleable: a
|
|
13
|
+
* miner can set salt == publicKey to force preimage == checksumRoot (max
|
|
14
|
+
* difficulty for free), or transform any solution to another key via
|
|
15
|
+
* salt' = publicKey' ^ publicKey ^ salt. When useConcatenatedPreimage is true
|
|
16
|
+
* the preimage is the 96-byte concatenation checksumRoot || publicKey || salt,
|
|
17
|
+
* which removes both (the SHA-1 proof-of-work over it is unchanged).
|
|
18
|
+
*
|
|
19
|
+
* The switch is a consensus rule: callers pass useConcatenatedPreimage =
|
|
20
|
+
* (epochBlockHeight >= activationHeight) using the activation height for the
|
|
21
|
+
* network they are on (opnet-node exposes it as
|
|
22
|
+
* consensusEpochPatches.PREIMAGE_CONCAT_PATCH_BLOCK_HEIGHT). The value MUST be
|
|
23
|
+
* identical across opnet-node, this library and the mining pool.
|
|
10
24
|
*/
|
|
11
|
-
static calculatePreimage(checksumRoot: Uint8Array, publicKey: Uint8Array, salt: Uint8Array): Uint8Array;
|
|
25
|
+
static calculatePreimage(checksumRoot: Uint8Array, publicKey: Uint8Array, salt: Uint8Array, useConcatenatedPreimage?: boolean): Uint8Array;
|
|
26
|
+
/**
|
|
27
|
+
* Non-malleable mining preimage: the 96-byte concatenation
|
|
28
|
+
* checksumRoot || publicKey || salt. The public key sits in its own segment,
|
|
29
|
+
* so a miner-chosen salt can neither cancel it nor be transformed to
|
|
30
|
+
* re-attribute another miner's solution. The SHA-1 proof-of-work over it is
|
|
31
|
+
* unchanged.
|
|
32
|
+
*/
|
|
33
|
+
static concatenatePreimage(checksumRoot: Uint8Array, publicKey: Uint8Array, salt: Uint8Array): Uint8Array;
|
|
12
34
|
/**
|
|
13
35
|
* Count matching bits between two hashes
|
|
14
36
|
*/
|
|
@@ -16,7 +38,7 @@ export declare class EpochValidator {
|
|
|
16
38
|
/**
|
|
17
39
|
* Verify an epoch solution using IPreimage
|
|
18
40
|
*/
|
|
19
|
-
static verifySolution(challenge: IChallengeSolution, log?: boolean): boolean;
|
|
41
|
+
static verifySolution(challenge: IChallengeSolution, log?: boolean, useConcatenatedPreimage?: boolean): boolean;
|
|
20
42
|
/**
|
|
21
43
|
* Get the mining target block for an epoch
|
|
22
44
|
*/
|
|
@@ -24,11 +46,11 @@ export declare class EpochValidator {
|
|
|
24
46
|
/**
|
|
25
47
|
* Validate epoch winner from raw data
|
|
26
48
|
*/
|
|
27
|
-
static validateEpochWinner(epochData: RawChallenge): boolean;
|
|
49
|
+
static validateEpochWinner(epochData: RawChallenge, useConcatenatedPreimage?: boolean): boolean;
|
|
28
50
|
/**
|
|
29
51
|
* Validate epoch winner from Preimage instance
|
|
30
52
|
*/
|
|
31
|
-
static validateChallengeSolution(challenge: IChallengeSolution): boolean;
|
|
53
|
+
static validateChallengeSolution(challenge: IChallengeSolution, useConcatenatedPreimage?: boolean): boolean;
|
|
32
54
|
/**
|
|
33
55
|
* Calculate solution hash from preimage components
|
|
34
56
|
* @param targetChecksum The target checksum (32 bytes)
|
|
@@ -36,7 +58,7 @@ export declare class EpochValidator {
|
|
|
36
58
|
* @param salt The salt buffer (32 bytes)
|
|
37
59
|
* @returns The SHA-1 hash of the preimage
|
|
38
60
|
*/
|
|
39
|
-
static calculateSolution(targetChecksum: Uint8Array, publicKey: Uint8Array, salt: Uint8Array): Uint8Array;
|
|
61
|
+
static calculateSolution(targetChecksum: Uint8Array, publicKey: Uint8Array, salt: Uint8Array, useConcatenatedPreimage?: boolean): Uint8Array;
|
|
40
62
|
/**
|
|
41
63
|
* Check if a solution meets the minimum difficulty requirement
|
|
42
64
|
*/
|
|
@@ -10,13 +10,30 @@ export class EpochValidator {
|
|
|
10
10
|
return crypto.sha1(data);
|
|
11
11
|
}
|
|
12
12
|
/**
|
|
13
|
-
* Calculate mining preimage
|
|
13
|
+
* Calculate mining preimage.
|
|
14
|
+
*
|
|
15
|
+
* When useConcatenatedPreimage is false the legacy XOR construction is used
|
|
16
|
+
* (checksumRoot ^ publicKey ^ salt). That construction is malleable: a
|
|
17
|
+
* miner can set salt == publicKey to force preimage == checksumRoot (max
|
|
18
|
+
* difficulty for free), or transform any solution to another key via
|
|
19
|
+
* salt' = publicKey' ^ publicKey ^ salt. When useConcatenatedPreimage is true
|
|
20
|
+
* the preimage is the 96-byte concatenation checksumRoot || publicKey || salt,
|
|
21
|
+
* which removes both (the SHA-1 proof-of-work over it is unchanged).
|
|
22
|
+
*
|
|
23
|
+
* The switch is a consensus rule: callers pass useConcatenatedPreimage =
|
|
24
|
+
* (epochBlockHeight >= activationHeight) using the activation height for the
|
|
25
|
+
* network they are on (opnet-node exposes it as
|
|
26
|
+
* consensusEpochPatches.PREIMAGE_CONCAT_PATCH_BLOCK_HEIGHT). The value MUST be
|
|
27
|
+
* identical across opnet-node, this library and the mining pool.
|
|
14
28
|
*/
|
|
15
|
-
static calculatePreimage(checksumRoot, publicKey, salt) {
|
|
29
|
+
static calculatePreimage(checksumRoot, publicKey, salt, useConcatenatedPreimage = false) {
|
|
16
30
|
// Ensure all are 32 bytes
|
|
17
31
|
if (checksumRoot.length !== 32 || publicKey.length !== 32 || salt.length !== 32) {
|
|
18
32
|
throw new Error('All inputs must be 32 bytes');
|
|
19
33
|
}
|
|
34
|
+
if (useConcatenatedPreimage) {
|
|
35
|
+
return this.concatenatePreimage(checksumRoot, publicKey, salt);
|
|
36
|
+
}
|
|
20
37
|
const preimage = new Uint8Array(32);
|
|
21
38
|
for (let i = 0; i < 32; i++) {
|
|
22
39
|
preimage[i] =
|
|
@@ -24,6 +41,23 @@ export class EpochValidator {
|
|
|
24
41
|
}
|
|
25
42
|
return preimage;
|
|
26
43
|
}
|
|
44
|
+
/**
|
|
45
|
+
* Non-malleable mining preimage: the 96-byte concatenation
|
|
46
|
+
* checksumRoot || publicKey || salt. The public key sits in its own segment,
|
|
47
|
+
* so a miner-chosen salt can neither cancel it nor be transformed to
|
|
48
|
+
* re-attribute another miner's solution. The SHA-1 proof-of-work over it is
|
|
49
|
+
* unchanged.
|
|
50
|
+
*/
|
|
51
|
+
static concatenatePreimage(checksumRoot, publicKey, salt) {
|
|
52
|
+
if (checksumRoot.length !== 32 || publicKey.length !== 32 || salt.length !== 32) {
|
|
53
|
+
throw new Error('All inputs must be 32 bytes');
|
|
54
|
+
}
|
|
55
|
+
const message = new Uint8Array(96);
|
|
56
|
+
message.set(checksumRoot, 0);
|
|
57
|
+
message.set(publicKey, 32);
|
|
58
|
+
message.set(salt, 64);
|
|
59
|
+
return message;
|
|
60
|
+
}
|
|
27
61
|
/**
|
|
28
62
|
* Count matching bits between two hashes
|
|
29
63
|
*/
|
|
@@ -56,10 +90,10 @@ export class EpochValidator {
|
|
|
56
90
|
/**
|
|
57
91
|
* Verify an epoch solution using IPreimage
|
|
58
92
|
*/
|
|
59
|
-
static verifySolution(challenge, log = false) {
|
|
93
|
+
static verifySolution(challenge, log = false, useConcatenatedPreimage = false) {
|
|
60
94
|
try {
|
|
61
95
|
const verification = challenge.verification;
|
|
62
|
-
const calculatedPreimage = this.calculatePreimage(verification.targetChecksum, challenge.publicKey.toBuffer(), challenge.salt);
|
|
96
|
+
const calculatedPreimage = this.calculatePreimage(verification.targetChecksum, challenge.publicKey.toBuffer(), challenge.salt, useConcatenatedPreimage);
|
|
63
97
|
const computedSolution = this.sha1(calculatedPreimage);
|
|
64
98
|
if (!equals(computedSolution, challenge.solution)) {
|
|
65
99
|
return false;
|
|
@@ -92,7 +126,7 @@ export class EpochValidator {
|
|
|
92
126
|
/**
|
|
93
127
|
* Validate epoch winner from raw data
|
|
94
128
|
*/
|
|
95
|
-
static validateEpochWinner(epochData) {
|
|
129
|
+
static validateEpochWinner(epochData, useConcatenatedPreimage = false) {
|
|
96
130
|
try {
|
|
97
131
|
const epochNumber = BigInt(epochData.epochNumber);
|
|
98
132
|
const publicKey = Address.fromString(epochData.mldsaPublicKey, epochData.legacyPublicKey);
|
|
@@ -108,7 +142,7 @@ export class EpochValidator {
|
|
|
108
142
|
endBlock: BigInt(epochData.verification.endBlock),
|
|
109
143
|
proofs: Object.freeze(epochData.verification.proofs.map((p) => stringToBuffer(p))),
|
|
110
144
|
};
|
|
111
|
-
const calculatedPreimage = this.calculatePreimage(verification.targetChecksum, publicKey.toBuffer(), salt);
|
|
145
|
+
const calculatedPreimage = this.calculatePreimage(verification.targetChecksum, publicKey.toBuffer(), salt, useConcatenatedPreimage);
|
|
112
146
|
const computedSolution = this.sha1(calculatedPreimage);
|
|
113
147
|
if (!equals(computedSolution, solution)) {
|
|
114
148
|
return false;
|
|
@@ -129,8 +163,8 @@ export class EpochValidator {
|
|
|
129
163
|
/**
|
|
130
164
|
* Validate epoch winner from Preimage instance
|
|
131
165
|
*/
|
|
132
|
-
static validateChallengeSolution(challenge) {
|
|
133
|
-
return this.verifySolution(challenge);
|
|
166
|
+
static validateChallengeSolution(challenge, useConcatenatedPreimage = false) {
|
|
167
|
+
return this.verifySolution(challenge, false, useConcatenatedPreimage);
|
|
134
168
|
}
|
|
135
169
|
/**
|
|
136
170
|
* Calculate solution hash from preimage components
|
|
@@ -139,8 +173,8 @@ export class EpochValidator {
|
|
|
139
173
|
* @param salt The salt buffer (32 bytes)
|
|
140
174
|
* @returns The SHA-1 hash of the preimage
|
|
141
175
|
*/
|
|
142
|
-
static calculateSolution(targetChecksum, publicKey, salt) {
|
|
143
|
-
const preimage = this.calculatePreimage(targetChecksum, publicKey, salt);
|
|
176
|
+
static calculateSolution(targetChecksum, publicKey, salt, useConcatenatedPreimage = false) {
|
|
177
|
+
const preimage = this.calculatePreimage(targetChecksum, publicKey, salt, useConcatenatedPreimage);
|
|
144
178
|
return this.sha1(preimage);
|
|
145
179
|
}
|
|
146
180
|
/**
|
|
@@ -744,15 +744,31 @@ export class TransactionBuilder extends TweakedTransaction {
|
|
|
744
744
|
generateMLDSALinkRequest(parameters, features) {
|
|
745
745
|
const mldsaSigner = this.mldsaSigner;
|
|
746
746
|
const legacySignature = this.generateLegacySignature();
|
|
747
|
+
// Reveal by default. The legacy Schnorr signature only proves ownership of
|
|
748
|
+
// the Bitcoin key being linked; it says nothing about the claimed
|
|
749
|
+
// hashedPublicKey. Without the ML-DSA public key and a signature over it,
|
|
750
|
+
// a link request carries no proof that the sender knows a preimage for
|
|
751
|
+
// that hash, so a node cannot safely create a NEW identity from it.
|
|
752
|
+
//
|
|
753
|
+
// Defaulting to false made every caller responsible for remembering, and
|
|
754
|
+
// callers do forget: opwallet never set this anywhere, and its deployment
|
|
755
|
+
// screen calls signDeployment() directly, bypassing any controller-level
|
|
756
|
+
// fix. Revealing when it was not needed only costs bytes (ML-DSA-44:
|
|
757
|
+
// 1312-byte key + 2420-byte signature); not revealing when it was needed
|
|
758
|
+
// gets the transaction rejected.
|
|
759
|
+
//
|
|
760
|
+
// Callers that KNOW the key is already linked on-chain should pass false
|
|
761
|
+
// explicitly to avoid paying for the reveal on every interaction.
|
|
762
|
+
const shouldReveal = parameters.revealMLDSAPublicKey ?? true;
|
|
747
763
|
let mldsaSignature = null;
|
|
748
|
-
if (
|
|
764
|
+
if (shouldReveal) {
|
|
749
765
|
mldsaSignature = this.generateMLDSASignature();
|
|
750
766
|
}
|
|
751
767
|
const mldsaRequest = {
|
|
752
768
|
priority: FeaturePriority.MLDSA_LINK_PUBKEY,
|
|
753
769
|
opcode: Features.MLDSA_LINK_PUBKEY,
|
|
754
770
|
data: {
|
|
755
|
-
verifyRequest:
|
|
771
|
+
verifyRequest: shouldReveal,
|
|
756
772
|
publicKey: mldsaSigner.publicKey,
|
|
757
773
|
hashedPublicKey: this.hashedPublicKey,
|
|
758
774
|
level: getLevelFromPublicKeyLength(mldsaSigner.publicKey.length),
|
package/package.json
CHANGED
|
@@ -14,18 +14,37 @@ export class EpochValidator {
|
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
|
-
* Calculate mining preimage
|
|
17
|
+
* Calculate mining preimage.
|
|
18
|
+
*
|
|
19
|
+
* When useConcatenatedPreimage is false the legacy XOR construction is used
|
|
20
|
+
* (checksumRoot ^ publicKey ^ salt). That construction is malleable: a
|
|
21
|
+
* miner can set salt == publicKey to force preimage == checksumRoot (max
|
|
22
|
+
* difficulty for free), or transform any solution to another key via
|
|
23
|
+
* salt' = publicKey' ^ publicKey ^ salt. When useConcatenatedPreimage is true
|
|
24
|
+
* the preimage is the 96-byte concatenation checksumRoot || publicKey || salt,
|
|
25
|
+
* which removes both (the SHA-1 proof-of-work over it is unchanged).
|
|
26
|
+
*
|
|
27
|
+
* The switch is a consensus rule: callers pass useConcatenatedPreimage =
|
|
28
|
+
* (epochBlockHeight >= activationHeight) using the activation height for the
|
|
29
|
+
* network they are on (opnet-node exposes it as
|
|
30
|
+
* consensusEpochPatches.PREIMAGE_CONCAT_PATCH_BLOCK_HEIGHT). The value MUST be
|
|
31
|
+
* identical across opnet-node, this library and the mining pool.
|
|
18
32
|
*/
|
|
19
33
|
public static calculatePreimage(
|
|
20
34
|
checksumRoot: Uint8Array,
|
|
21
35
|
publicKey: Uint8Array,
|
|
22
36
|
salt: Uint8Array,
|
|
37
|
+
useConcatenatedPreimage: boolean = false,
|
|
23
38
|
): Uint8Array {
|
|
24
39
|
// Ensure all are 32 bytes
|
|
25
40
|
if (checksumRoot.length !== 32 || publicKey.length !== 32 || salt.length !== 32) {
|
|
26
41
|
throw new Error('All inputs must be 32 bytes');
|
|
27
42
|
}
|
|
28
43
|
|
|
44
|
+
if (useConcatenatedPreimage) {
|
|
45
|
+
return this.concatenatePreimage(checksumRoot, publicKey, salt);
|
|
46
|
+
}
|
|
47
|
+
|
|
29
48
|
const preimage = new Uint8Array(32);
|
|
30
49
|
for (let i = 0; i < 32; i++) {
|
|
31
50
|
preimage[i] =
|
|
@@ -35,6 +54,30 @@ export class EpochValidator {
|
|
|
35
54
|
return preimage;
|
|
36
55
|
}
|
|
37
56
|
|
|
57
|
+
/**
|
|
58
|
+
* Non-malleable mining preimage: the 96-byte concatenation
|
|
59
|
+
* checksumRoot || publicKey || salt. The public key sits in its own segment,
|
|
60
|
+
* so a miner-chosen salt can neither cancel it nor be transformed to
|
|
61
|
+
* re-attribute another miner's solution. The SHA-1 proof-of-work over it is
|
|
62
|
+
* unchanged.
|
|
63
|
+
*/
|
|
64
|
+
public static concatenatePreimage(
|
|
65
|
+
checksumRoot: Uint8Array,
|
|
66
|
+
publicKey: Uint8Array,
|
|
67
|
+
salt: Uint8Array,
|
|
68
|
+
): Uint8Array {
|
|
69
|
+
if (checksumRoot.length !== 32 || publicKey.length !== 32 || salt.length !== 32) {
|
|
70
|
+
throw new Error('All inputs must be 32 bytes');
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const message = new Uint8Array(96);
|
|
74
|
+
message.set(checksumRoot, 0);
|
|
75
|
+
message.set(publicKey, 32);
|
|
76
|
+
message.set(salt, 64);
|
|
77
|
+
|
|
78
|
+
return message;
|
|
79
|
+
}
|
|
80
|
+
|
|
38
81
|
/**
|
|
39
82
|
* Count matching bits between two hashes
|
|
40
83
|
*/
|
|
@@ -69,13 +112,18 @@ export class EpochValidator {
|
|
|
69
112
|
/**
|
|
70
113
|
* Verify an epoch solution using IPreimage
|
|
71
114
|
*/
|
|
72
|
-
public static verifySolution(
|
|
115
|
+
public static verifySolution(
|
|
116
|
+
challenge: IChallengeSolution,
|
|
117
|
+
log: boolean = false,
|
|
118
|
+
useConcatenatedPreimage: boolean = false,
|
|
119
|
+
): boolean {
|
|
73
120
|
try {
|
|
74
121
|
const verification = challenge.verification;
|
|
75
122
|
const calculatedPreimage = this.calculatePreimage(
|
|
76
123
|
verification.targetChecksum,
|
|
77
124
|
challenge.publicKey.toBuffer(),
|
|
78
125
|
challenge.salt,
|
|
126
|
+
useConcatenatedPreimage,
|
|
79
127
|
);
|
|
80
128
|
|
|
81
129
|
const computedSolution = this.sha1(calculatedPreimage);
|
|
@@ -118,7 +166,10 @@ export class EpochValidator {
|
|
|
118
166
|
/**
|
|
119
167
|
* Validate epoch winner from raw data
|
|
120
168
|
*/
|
|
121
|
-
public static validateEpochWinner(
|
|
169
|
+
public static validateEpochWinner(
|
|
170
|
+
epochData: RawChallenge,
|
|
171
|
+
useConcatenatedPreimage: boolean = false,
|
|
172
|
+
): boolean {
|
|
122
173
|
try {
|
|
123
174
|
const epochNumber = BigInt(epochData.epochNumber);
|
|
124
175
|
const publicKey = Address.fromString(
|
|
@@ -143,6 +194,7 @@ export class EpochValidator {
|
|
|
143
194
|
verification.targetChecksum,
|
|
144
195
|
publicKey.toBuffer(),
|
|
145
196
|
salt,
|
|
197
|
+
useConcatenatedPreimage,
|
|
146
198
|
);
|
|
147
199
|
|
|
148
200
|
const computedSolution = this.sha1(calculatedPreimage);
|
|
@@ -172,8 +224,11 @@ export class EpochValidator {
|
|
|
172
224
|
/**
|
|
173
225
|
* Validate epoch winner from Preimage instance
|
|
174
226
|
*/
|
|
175
|
-
public static validateChallengeSolution(
|
|
176
|
-
|
|
227
|
+
public static validateChallengeSolution(
|
|
228
|
+
challenge: IChallengeSolution,
|
|
229
|
+
useConcatenatedPreimage: boolean = false,
|
|
230
|
+
): boolean {
|
|
231
|
+
return this.verifySolution(challenge, false, useConcatenatedPreimage);
|
|
177
232
|
}
|
|
178
233
|
|
|
179
234
|
/**
|
|
@@ -187,8 +242,14 @@ export class EpochValidator {
|
|
|
187
242
|
targetChecksum: Uint8Array,
|
|
188
243
|
publicKey: Uint8Array,
|
|
189
244
|
salt: Uint8Array,
|
|
245
|
+
useConcatenatedPreimage: boolean = false,
|
|
190
246
|
): Uint8Array {
|
|
191
|
-
const preimage = this.calculatePreimage(
|
|
247
|
+
const preimage = this.calculatePreimage(
|
|
248
|
+
targetChecksum,
|
|
249
|
+
publicKey,
|
|
250
|
+
salt,
|
|
251
|
+
useConcatenatedPreimage,
|
|
252
|
+
);
|
|
192
253
|
return this.sha1(preimage);
|
|
193
254
|
}
|
|
194
255
|
|
|
@@ -983,8 +983,25 @@ export abstract class TransactionBuilder<T extends TransactionType> extends Twea
|
|
|
983
983
|
const mldsaSigner = this.mldsaSigner;
|
|
984
984
|
const legacySignature = this.generateLegacySignature();
|
|
985
985
|
|
|
986
|
+
// Reveal by default. The legacy Schnorr signature only proves ownership of
|
|
987
|
+
// the Bitcoin key being linked; it says nothing about the claimed
|
|
988
|
+
// hashedPublicKey. Without the ML-DSA public key and a signature over it,
|
|
989
|
+
// a link request carries no proof that the sender knows a preimage for
|
|
990
|
+
// that hash, so a node cannot safely create a NEW identity from it.
|
|
991
|
+
//
|
|
992
|
+
// Defaulting to false made every caller responsible for remembering, and
|
|
993
|
+
// callers do forget: opwallet never set this anywhere, and its deployment
|
|
994
|
+
// screen calls signDeployment() directly, bypassing any controller-level
|
|
995
|
+
// fix. Revealing when it was not needed only costs bytes (ML-DSA-44:
|
|
996
|
+
// 1312-byte key + 2420-byte signature); not revealing when it was needed
|
|
997
|
+
// gets the transaction rejected.
|
|
998
|
+
//
|
|
999
|
+
// Callers that KNOW the key is already linked on-chain should pass false
|
|
1000
|
+
// explicitly to avoid paying for the reveal on every interaction.
|
|
1001
|
+
const shouldReveal = parameters.revealMLDSAPublicKey ?? true;
|
|
1002
|
+
|
|
986
1003
|
let mldsaSignature: Uint8Array | null = null;
|
|
987
|
-
if (
|
|
1004
|
+
if (shouldReveal) {
|
|
988
1005
|
mldsaSignature = this.generateMLDSASignature();
|
|
989
1006
|
}
|
|
990
1007
|
|
|
@@ -992,7 +1009,7 @@ export abstract class TransactionBuilder<T extends TransactionType> extends Twea
|
|
|
992
1009
|
priority: FeaturePriority.MLDSA_LINK_PUBKEY,
|
|
993
1010
|
opcode: Features.MLDSA_LINK_PUBKEY,
|
|
994
1011
|
data: {
|
|
995
|
-
verifyRequest:
|
|
1012
|
+
verifyRequest: shouldReveal,
|
|
996
1013
|
publicKey: mldsaSigner.publicKey,
|
|
997
1014
|
hashedPublicKey: this.hashedPublicKey,
|
|
998
1015
|
level: getLevelFromPublicKeyLength(mldsaSigner.publicKey.length),
|