@cheny56/node-client 1.0.11 → 1.0.14
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/package.json +1 -1
- package/src/contract.js +1 -3
- package/src/transaction.js +47 -55
- package/src/utils/address.js +4 -4
- package/src/utils/rlp.js +4 -4
- package/src/wallet.js +51 -21
- package/src/zk-transaction.js +8 -8
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cheny56/node-client",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.14",
|
|
4
4
|
"description": "Client library for Quorum blockchain with Post-Quantum Cryptography (PQC) and Zero-Knowledge Proof (ZK) support",
|
|
5
5
|
"main": "./src/index.js",
|
|
6
6
|
"types": "src/index.d.ts",
|
package/src/contract.js
CHANGED
|
@@ -161,9 +161,7 @@ class ERC20Token extends Contract {
|
|
|
161
161
|
async transferPQC(wallet, provider, to, amount, txOptions = {}) {
|
|
162
162
|
const data = this.encodeFunctionData('transfer', [to, amount]);
|
|
163
163
|
// Ensure wallet is initialized
|
|
164
|
-
|
|
165
|
-
await wallet._ensureKeyPair();
|
|
166
|
-
}
|
|
164
|
+
await wallet._initPromise;
|
|
167
165
|
const nonce = await provider.getTransactionCount(wallet.address, 'pending');
|
|
168
166
|
|
|
169
167
|
const tx = new PQCLegacyTransaction({
|
package/src/transaction.js
CHANGED
|
@@ -93,15 +93,15 @@ class PQCLegacyTransaction extends BaseTransaction {
|
|
|
93
93
|
getSigningHash() {
|
|
94
94
|
const nonceBytes = this.nonce === 0n || this.nonce === 0
|
|
95
95
|
? new Uint8Array(0)
|
|
96
|
-
: ethers.
|
|
96
|
+
: ethers.utils.arrayify(ethers.utils.hexlify(this.nonce));
|
|
97
97
|
const gasLimitBytes = this.gasLimit === 0n || this.gasLimit === 0
|
|
98
98
|
? new Uint8Array(0)
|
|
99
|
-
: ethers.
|
|
99
|
+
: ethers.utils.arrayify(ethers.utils.hexlify(this.gasLimit));
|
|
100
100
|
const chainIdBytes = this.chainId === 0n || this.chainId === 0
|
|
101
101
|
? new Uint8Array(0)
|
|
102
|
-
: ethers.
|
|
102
|
+
: ethers.utils.arrayify(ethers.utils.hexlify(this.chainId));
|
|
103
103
|
|
|
104
|
-
const encoded = ethers.
|
|
104
|
+
const encoded = ethers.utils.RLP.encode([
|
|
105
105
|
nonceBytes,
|
|
106
106
|
this.gasPrice === 0n ? new Uint8Array(0) : ethers.getBytes(ethers.toBeHex(this.gasPrice)),
|
|
107
107
|
gasLimitBytes,
|
|
@@ -112,7 +112,7 @@ class PQCLegacyTransaction extends BaseTransaction {
|
|
|
112
112
|
new Uint8Array(0),
|
|
113
113
|
new Uint8Array(0),
|
|
114
114
|
]);
|
|
115
|
-
return ethers.keccak256(encoded);
|
|
115
|
+
return ethers.utils.keccak256(encoded);
|
|
116
116
|
}
|
|
117
117
|
|
|
118
118
|
/**
|
|
@@ -122,11 +122,9 @@ class PQCLegacyTransaction extends BaseTransaction {
|
|
|
122
122
|
*/
|
|
123
123
|
async sign(wallet) {
|
|
124
124
|
// Ensure wallet is initialized
|
|
125
|
-
|
|
126
|
-
await wallet._ensureKeyPair();
|
|
127
|
-
}
|
|
125
|
+
await wallet._initPromise;
|
|
128
126
|
|
|
129
|
-
const hash = ethers.
|
|
127
|
+
const hash = ethers.utils.arrayify(this.getSigningHash());
|
|
130
128
|
this.pqcPubKey = wallet.publicKey;
|
|
131
129
|
// Use wallet's sign method which handles the async properly
|
|
132
130
|
this.pqcSig = await wallet.sign(hash);
|
|
@@ -138,7 +136,7 @@ class PQCLegacyTransaction extends BaseTransaction {
|
|
|
138
136
|
|
|
139
137
|
async verify() {
|
|
140
138
|
if (!this.pqcSig || !this.pqcPubKey) return false;
|
|
141
|
-
const hash = ethers.
|
|
139
|
+
const hash = ethers.utils.arrayify(this.getSigningHash());
|
|
142
140
|
// Use dilithium verify directly
|
|
143
141
|
if (dilithium.verify) {
|
|
144
142
|
return dilithium.verify(this.pqcPubKey, hash, this.pqcSig);
|
|
@@ -165,7 +163,7 @@ class PQCLegacyTransaction extends BaseTransaction {
|
|
|
165
163
|
const sHex = encodeSignature(this.s || '0x0');
|
|
166
164
|
const pqcTypeHex = encodeUint64(this.pqcType);
|
|
167
165
|
|
|
168
|
-
const encoded = ethers.
|
|
166
|
+
const encoded = ethers.utils.RLP.encode([
|
|
169
167
|
nonceHex,
|
|
170
168
|
gasPriceHex,
|
|
171
169
|
gasLimitHex,
|
|
@@ -179,11 +177,11 @@ class PQCLegacyTransaction extends BaseTransaction {
|
|
|
179
177
|
this.pqcPubKey,
|
|
180
178
|
this.pqcSig,
|
|
181
179
|
]);
|
|
182
|
-
return ethers.
|
|
180
|
+
return ethers.utils.arrayify(encoded);
|
|
183
181
|
}
|
|
184
182
|
|
|
185
183
|
getHex() {
|
|
186
|
-
return ethers.hexlify(this.serialize());
|
|
184
|
+
return ethers.utils.hexlify(this.serialize());
|
|
187
185
|
}
|
|
188
186
|
}
|
|
189
187
|
|
|
@@ -207,15 +205,15 @@ class HybridLegacyTransaction extends BaseTransaction {
|
|
|
207
205
|
getSigningHash() {
|
|
208
206
|
const nonceBytes = this.nonce === 0n || this.nonce === 0
|
|
209
207
|
? new Uint8Array(0)
|
|
210
|
-
: ethers.
|
|
208
|
+
: ethers.utils.arrayify(ethers.utils.hexlify(this.nonce));
|
|
211
209
|
const gasLimitBytes = this.gasLimit === 0n || this.gasLimit === 0
|
|
212
210
|
? new Uint8Array(0)
|
|
213
|
-
: ethers.
|
|
211
|
+
: ethers.utils.arrayify(ethers.utils.hexlify(this.gasLimit));
|
|
214
212
|
const chainIdBytes = this.chainId === 0n || this.chainId === 0
|
|
215
213
|
? new Uint8Array(0)
|
|
216
|
-
: ethers.
|
|
214
|
+
: ethers.utils.arrayify(ethers.utils.hexlify(this.chainId));
|
|
217
215
|
|
|
218
|
-
const encoded = ethers.
|
|
216
|
+
const encoded = ethers.utils.RLP.encode([
|
|
219
217
|
nonceBytes,
|
|
220
218
|
this.gasPrice === 0n ? new Uint8Array(0) : ethers.getBytes(ethers.toBeHex(this.gasPrice)),
|
|
221
219
|
gasLimitBytes,
|
|
@@ -226,7 +224,7 @@ class HybridLegacyTransaction extends BaseTransaction {
|
|
|
226
224
|
new Uint8Array(0),
|
|
227
225
|
new Uint8Array(0),
|
|
228
226
|
]);
|
|
229
|
-
return ethers.keccak256(encoded);
|
|
227
|
+
return ethers.utils.keccak256(encoded);
|
|
230
228
|
}
|
|
231
229
|
|
|
232
230
|
/**
|
|
@@ -237,12 +235,10 @@ class HybridLegacyTransaction extends BaseTransaction {
|
|
|
237
235
|
*/
|
|
238
236
|
async sign(ecdsaWallet, pqcWallet) {
|
|
239
237
|
// Ensure PQC wallet is initialized
|
|
240
|
-
|
|
241
|
-
await pqcWallet._ensureKeyPair();
|
|
242
|
-
}
|
|
238
|
+
await pqcWallet._initPromise;
|
|
243
239
|
|
|
244
240
|
const hash = this.getSigningHash();
|
|
245
|
-
const hashBytes = ethers.
|
|
241
|
+
const hashBytes = ethers.utils.arrayify(hash);
|
|
246
242
|
|
|
247
243
|
// ECDSA signature
|
|
248
244
|
const ecdsaSig = ecdsaWallet.wallet.signingKey.sign(hash);
|
|
@@ -260,7 +256,7 @@ class HybridLegacyTransaction extends BaseTransaction {
|
|
|
260
256
|
|
|
261
257
|
verify() {
|
|
262
258
|
if (!this.pqcSig || !this.pqcPubKey) return false;
|
|
263
|
-
const hash = ethers.
|
|
259
|
+
const hash = ethers.utils.arrayify(this.getSigningHash());
|
|
264
260
|
if (dilithium.verify) {
|
|
265
261
|
return dilithium.verify(this.pqcPubKey, hash, this.pqcSig);
|
|
266
262
|
} else if (dilithium.verifyWithContext) {
|
|
@@ -286,7 +282,7 @@ class HybridLegacyTransaction extends BaseTransaction {
|
|
|
286
282
|
const sHex = encodeSignature(this.s);
|
|
287
283
|
const pqcTypeHex = encodeUint64(this.pqcType);
|
|
288
284
|
|
|
289
|
-
const encoded = ethers.
|
|
285
|
+
const encoded = ethers.utils.RLP.encode([
|
|
290
286
|
nonceHex,
|
|
291
287
|
gasPriceHex,
|
|
292
288
|
gasLimitHex,
|
|
@@ -300,11 +296,11 @@ class HybridLegacyTransaction extends BaseTransaction {
|
|
|
300
296
|
this.pqcPubKey,
|
|
301
297
|
this.pqcSig,
|
|
302
298
|
]);
|
|
303
|
-
return ethers.
|
|
299
|
+
return ethers.utils.arrayify(encoded);
|
|
304
300
|
}
|
|
305
301
|
|
|
306
302
|
getHex() {
|
|
307
|
-
return ethers.hexlify(this.serialize());
|
|
303
|
+
return ethers.utils.hexlify(this.serialize());
|
|
308
304
|
}
|
|
309
305
|
}
|
|
310
306
|
|
|
@@ -359,11 +355,11 @@ class PQCAccessListTransaction extends BaseTransaction {
|
|
|
359
355
|
}
|
|
360
356
|
|
|
361
357
|
getSigningHash() {
|
|
362
|
-
const chainIdHex = this.chainId === 0n || this.chainId === 0 ? '0x' : ethers.
|
|
363
|
-
const nonceHex = this.nonce === 0n || this.nonce === 0 ? '0x' : ethers.
|
|
364
|
-
const gasPriceHex = this.gasPrice === 0n || this.gasPrice === 0 ? '0x' : ethers.
|
|
365
|
-
const gasHex = this.gasLimit === 0n || this.gasLimit === 0 ? '0x' : ethers.
|
|
366
|
-
const valueHex = this.value === 0n || this.value === 0 ? '0x' : ethers.
|
|
358
|
+
const chainIdHex = this.chainId === 0n || this.chainId === 0 ? '0x' : ethers.utils.hexlify(this.chainId);
|
|
359
|
+
const nonceHex = this.nonce === 0n || this.nonce === 0 ? '0x' : ethers.utils.hexlify(this.nonce);
|
|
360
|
+
const gasPriceHex = this.gasPrice === 0n || this.gasPrice === 0 ? '0x' : ethers.utils.hexlify(this.gasPrice);
|
|
361
|
+
const gasHex = this.gasLimit === 0n || this.gasLimit === 0 ? '0x' : ethers.utils.hexlify(this.gasLimit);
|
|
362
|
+
const valueHex = this.value === 0n || this.value === 0 ? '0x' : ethers.utils.hexlify(this.value);
|
|
367
363
|
|
|
368
364
|
const rlpData = [
|
|
369
365
|
chainIdHex,
|
|
@@ -376,24 +372,22 @@ class PQCAccessListTransaction extends BaseTransaction {
|
|
|
376
372
|
this.accessList || [],
|
|
377
373
|
];
|
|
378
374
|
|
|
379
|
-
const encodedHex = ethers.
|
|
380
|
-
const encoded = ethers.
|
|
375
|
+
const encodedHex = ethers.utils.RLP.encode(rlpData);
|
|
376
|
+
const encoded = ethers.utils.arrayify(encodedHex);
|
|
381
377
|
|
|
382
378
|
const typeByte = TX_TYPE.ACCESS_LIST;
|
|
383
379
|
const prefixed = new Uint8Array(1 + encoded.length);
|
|
384
380
|
prefixed[0] = typeByte;
|
|
385
381
|
prefixed.set(encoded, 1);
|
|
386
382
|
|
|
387
|
-
return ethers.keccak256(ethers.hexlify(prefixed));
|
|
383
|
+
return ethers.utils.keccak256(ethers.utils.hexlify(prefixed));
|
|
388
384
|
}
|
|
389
385
|
|
|
390
386
|
async sign(wallet) {
|
|
391
387
|
// Ensure wallet is initialized
|
|
392
|
-
|
|
393
|
-
await wallet._ensureKeyPair();
|
|
394
|
-
}
|
|
388
|
+
await wallet._initPromise;
|
|
395
389
|
|
|
396
|
-
const hash = ethers.
|
|
390
|
+
const hash = ethers.utils.arrayify(this.getSigningHash());
|
|
397
391
|
this.pqcPubKey = wallet.publicKey;
|
|
398
392
|
this.pqcSig = await wallet.sign(hash);
|
|
399
393
|
return this;
|
|
@@ -401,7 +395,7 @@ class PQCAccessListTransaction extends BaseTransaction {
|
|
|
401
395
|
|
|
402
396
|
async verify() {
|
|
403
397
|
if (!this.pqcSig || !this.pqcPubKey) return false;
|
|
404
|
-
const hash = ethers.
|
|
398
|
+
const hash = ethers.utils.arrayify(this.getSigningHash());
|
|
405
399
|
if (dilithium.verify) {
|
|
406
400
|
return dilithium.verify(this.pqcPubKey, hash, this.pqcSig);
|
|
407
401
|
} else if (dilithium.verifyWithContext) {
|
|
@@ -429,7 +423,7 @@ class PQCAccessListTransaction extends BaseTransaction {
|
|
|
429
423
|
const sHex = encodeSignature(this.s || '0x0');
|
|
430
424
|
const pqcTypeHex = encodeUint64(this.pqcType);
|
|
431
425
|
|
|
432
|
-
const encoded = ethers.
|
|
426
|
+
const encoded = ethers.utils.RLP.encode([
|
|
433
427
|
chainIdHex,
|
|
434
428
|
nonceHex,
|
|
435
429
|
gasPriceHex,
|
|
@@ -446,7 +440,7 @@ class PQCAccessListTransaction extends BaseTransaction {
|
|
|
446
440
|
this.pqcSig,
|
|
447
441
|
]);
|
|
448
442
|
|
|
449
|
-
const encodedBytes = ethers.
|
|
443
|
+
const encodedBytes = ethers.utils.arrayify(encoded);
|
|
450
444
|
const typeByte = new Uint8Array([TX_TYPE.ACCESS_LIST]);
|
|
451
445
|
const prefixed = new Uint8Array(typeByte.length + encodedBytes.length);
|
|
452
446
|
prefixed.set(typeByte, 0);
|
|
@@ -456,7 +450,7 @@ class PQCAccessListTransaction extends BaseTransaction {
|
|
|
456
450
|
}
|
|
457
451
|
|
|
458
452
|
getHex() {
|
|
459
|
-
return ethers.hexlify(this.serialize());
|
|
453
|
+
return ethers.utils.hexlify(this.serialize());
|
|
460
454
|
}
|
|
461
455
|
}
|
|
462
456
|
|
|
@@ -516,8 +510,8 @@ class PQCDynamicFeeTransaction extends BaseTransaction {
|
|
|
516
510
|
getSigningHash() {
|
|
517
511
|
const chainIdHex = this.chainId === 0n || this.chainId === 0 ? '0x' : ethers.toBeHex(this.chainId);
|
|
518
512
|
const nonceHex = this.nonce === 0n || this.nonce === 0 ? '0x' : ethers.toBeHex(this.nonce);
|
|
519
|
-
const gasTipCapHex = this.maxPriorityFeePerGas === 0n || this.maxPriorityFeePerGas === 0 ? '0x' : ethers.
|
|
520
|
-
const gasFeeCapHex = this.maxFeePerGas === 0n || this.maxFeePerGas === 0 ? '0x' : ethers.
|
|
513
|
+
const gasTipCapHex = this.maxPriorityFeePerGas === 0n || this.maxPriorityFeePerGas === 0 ? '0x' : ethers.utils.hexlify(this.maxPriorityFeePerGas);
|
|
514
|
+
const gasFeeCapHex = this.maxFeePerGas === 0n || this.maxFeePerGas === 0 ? '0x' : ethers.utils.hexlify(this.maxFeePerGas);
|
|
521
515
|
const gasHex = this.gasLimit === 0n || this.gasLimit === 0 ? '0x' : ethers.toBeHex(this.gasLimit);
|
|
522
516
|
const valueHex = this.value === 0n || this.value === 0 ? '0x' : ethers.toBeHex(this.value);
|
|
523
517
|
|
|
@@ -533,24 +527,22 @@ class PQCDynamicFeeTransaction extends BaseTransaction {
|
|
|
533
527
|
this.accessList || [],
|
|
534
528
|
];
|
|
535
529
|
|
|
536
|
-
const encodedHex = ethers.
|
|
537
|
-
const encoded = ethers.
|
|
530
|
+
const encodedHex = ethers.utils.RLP.encode(rlpData);
|
|
531
|
+
const encoded = ethers.utils.arrayify(encodedHex);
|
|
538
532
|
|
|
539
533
|
const typeByte = TX_TYPE.DYNAMIC_FEE;
|
|
540
534
|
const prefixed = new Uint8Array(1 + encoded.length);
|
|
541
535
|
prefixed[0] = typeByte;
|
|
542
536
|
prefixed.set(encoded, 1);
|
|
543
537
|
|
|
544
|
-
return ethers.keccak256(ethers.hexlify(prefixed));
|
|
538
|
+
return ethers.utils.keccak256(ethers.utils.hexlify(prefixed));
|
|
545
539
|
}
|
|
546
540
|
|
|
547
541
|
async sign(wallet) {
|
|
548
542
|
// Ensure wallet is initialized
|
|
549
|
-
|
|
550
|
-
await wallet._ensureKeyPair();
|
|
551
|
-
}
|
|
543
|
+
await wallet._initPromise;
|
|
552
544
|
|
|
553
|
-
const hash = ethers.
|
|
545
|
+
const hash = ethers.utils.arrayify(this.getSigningHash());
|
|
554
546
|
this.pqcPubKey = wallet.publicKey;
|
|
555
547
|
this.pqcSig = await wallet.sign(hash);
|
|
556
548
|
return this;
|
|
@@ -558,7 +550,7 @@ class PQCDynamicFeeTransaction extends BaseTransaction {
|
|
|
558
550
|
|
|
559
551
|
async verify() {
|
|
560
552
|
if (!this.pqcSig || !this.pqcPubKey) return false;
|
|
561
|
-
const hash = ethers.
|
|
553
|
+
const hash = ethers.utils.arrayify(this.getSigningHash());
|
|
562
554
|
if (dilithium.verify) {
|
|
563
555
|
return dilithium.verify(this.pqcPubKey, hash, this.pqcSig);
|
|
564
556
|
} else if (dilithium.verifyWithContext) {
|
|
@@ -587,7 +579,7 @@ class PQCDynamicFeeTransaction extends BaseTransaction {
|
|
|
587
579
|
const sHex = encodeSignature(this.s || '0x0');
|
|
588
580
|
const pqcTypeHex = encodeUint64(this.pqcType);
|
|
589
581
|
|
|
590
|
-
const encoded = ethers.
|
|
582
|
+
const encoded = ethers.utils.RLP.encode([
|
|
591
583
|
chainIdHex,
|
|
592
584
|
nonceHex,
|
|
593
585
|
gasTipCapHex,
|
|
@@ -605,7 +597,7 @@ class PQCDynamicFeeTransaction extends BaseTransaction {
|
|
|
605
597
|
this.pqcSig,
|
|
606
598
|
]);
|
|
607
599
|
|
|
608
|
-
const encodedBytes = ethers.
|
|
600
|
+
const encodedBytes = ethers.utils.arrayify(encoded);
|
|
609
601
|
const typeByte = new Uint8Array([TX_TYPE.DYNAMIC_FEE]);
|
|
610
602
|
const prefixed = new Uint8Array(typeByte.length + encodedBytes.length);
|
|
611
603
|
prefixed.set(typeByte, 0);
|
|
@@ -615,7 +607,7 @@ class PQCDynamicFeeTransaction extends BaseTransaction {
|
|
|
615
607
|
}
|
|
616
608
|
|
|
617
609
|
getHex() {
|
|
618
|
-
return ethers.hexlify(this.serialize());
|
|
610
|
+
return ethers.utils.hexlify(this.serialize());
|
|
619
611
|
}
|
|
620
612
|
}
|
|
621
613
|
|
package/src/utils/address.js
CHANGED
|
@@ -11,8 +11,8 @@ const { ethers } = require('ethers');
|
|
|
11
11
|
* @returns {string} Ethereum address
|
|
12
12
|
*/
|
|
13
13
|
function derivePQCAddress(publicKey) {
|
|
14
|
-
const hash = ethers.keccak256(publicKey);
|
|
15
|
-
return ethers.getAddress('0x' + hash.slice(-40));
|
|
14
|
+
const hash = ethers.utils.keccak256(publicKey);
|
|
15
|
+
return ethers.utils.getAddress('0x' + hash.slice(-40));
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
/**
|
|
@@ -34,8 +34,8 @@ function deriveHybridAddress(ecdsaPublicKey, dilithiumPublicKey) {
|
|
|
34
34
|
concat.set(dilithiumPublicKey, ecdsaBytes.length);
|
|
35
35
|
|
|
36
36
|
// Hash and derive address
|
|
37
|
-
const hash = ethers.keccak256(concat);
|
|
38
|
-
return ethers.getAddress('0x' + hash.slice(-40));
|
|
37
|
+
const hash = ethers.utils.keccak256(concat);
|
|
38
|
+
return ethers.utils.getAddress('0x' + hash.slice(-40));
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
/**
|
package/src/utils/rlp.js
CHANGED
|
@@ -14,7 +14,7 @@ function encodeUint64(value) {
|
|
|
14
14
|
return '0x';
|
|
15
15
|
}
|
|
16
16
|
const bigValue = typeof value === 'bigint' ? value : BigInt(value);
|
|
17
|
-
return ethers.
|
|
17
|
+
return ethers.utils.hexlify(bigValue);
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
/**
|
|
@@ -26,7 +26,7 @@ function encodeBigInt(value) {
|
|
|
26
26
|
return '0x';
|
|
27
27
|
}
|
|
28
28
|
const bigValue = typeof value === 'bigint' ? value : BigInt(value);
|
|
29
|
-
return ethers.
|
|
29
|
+
return ethers.utils.hexlify(bigValue);
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
/**
|
|
@@ -39,7 +39,7 @@ function encodeSignature(value) {
|
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
const hex = value.startsWith('0x') ? value : '0x' + value;
|
|
42
|
-
let bytes = ethers.
|
|
42
|
+
let bytes = ethers.utils.arrayify(hex);
|
|
43
43
|
|
|
44
44
|
// Remove leading zeros for canonical form
|
|
45
45
|
let startIdx = 0;
|
|
@@ -52,7 +52,7 @@ function encodeSignature(value) {
|
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
bytes = bytes.slice(startIdx);
|
|
55
|
-
return ethers.hexlify(bytes);
|
|
55
|
+
return ethers.utils.hexlify(bytes);
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
module.exports = {
|
package/src/wallet.js
CHANGED
|
@@ -68,6 +68,7 @@ class PQCWallet {
|
|
|
68
68
|
this.publicKey = publicKey instanceof Uint8Array ? publicKey : new Uint8Array(publicKey);
|
|
69
69
|
this.address = derivePQCAddress(this.publicKey);
|
|
70
70
|
this._initialized = true;
|
|
71
|
+
this._initPromise = Promise.resolve();
|
|
71
72
|
} else {
|
|
72
73
|
// Generate new key pair using dilithium-crystals
|
|
73
74
|
// dilithium-crystals uses keyPair() which is async and returns { publicKey, secretKey }
|
|
@@ -75,9 +76,21 @@ class PQCWallet {
|
|
|
75
76
|
this.publicKey = null;
|
|
76
77
|
this.address = null;
|
|
77
78
|
this._initialized = false;
|
|
79
|
+
// Start initialization immediately
|
|
80
|
+
this._initPromise = this._ensureKeyPair();
|
|
78
81
|
}
|
|
79
82
|
}
|
|
80
83
|
|
|
84
|
+
/**
|
|
85
|
+
* Create a new PQC wallet with initialized keys (static factory method)
|
|
86
|
+
* @returns {Promise<PQCWallet>} Initialized wallet
|
|
87
|
+
*/
|
|
88
|
+
static async create() {
|
|
89
|
+
const wallet = new PQCWallet();
|
|
90
|
+
await wallet._initPromise;
|
|
91
|
+
return wallet;
|
|
92
|
+
}
|
|
93
|
+
|
|
81
94
|
/**
|
|
82
95
|
* Initialize key pair if not already done (async)
|
|
83
96
|
* @private
|
|
@@ -98,6 +111,15 @@ class PQCWallet {
|
|
|
98
111
|
this._initialized = true;
|
|
99
112
|
}
|
|
100
113
|
|
|
114
|
+
/**
|
|
115
|
+
* Get address (will initialize keys if needed)
|
|
116
|
+
* @returns {Promise<string>} Wallet address
|
|
117
|
+
*/
|
|
118
|
+
async getAddress() {
|
|
119
|
+
await this._initPromise;
|
|
120
|
+
return this.address;
|
|
121
|
+
}
|
|
122
|
+
|
|
101
123
|
/**
|
|
102
124
|
* Create wallet from secret key
|
|
103
125
|
* Note: In practice, you would derive the public key from the secret key.
|
|
@@ -110,8 +132,8 @@ class PQCWallet {
|
|
|
110
132
|
if (!secretKey || !publicKey) {
|
|
111
133
|
throw new Error('Both secretKey and publicKey are required');
|
|
112
134
|
}
|
|
113
|
-
const secret = secretKey instanceof Uint8Array ? secretKey : ethers.
|
|
114
|
-
const pub = publicKey instanceof Uint8Array ? publicKey : ethers.
|
|
135
|
+
const secret = secretKey instanceof Uint8Array ? secretKey : ethers.utils.arrayify(secretKey);
|
|
136
|
+
const pub = publicKey instanceof Uint8Array ? publicKey : ethers.utils.arrayify(publicKey);
|
|
115
137
|
return new PQCWallet(secret, pub);
|
|
116
138
|
}
|
|
117
139
|
|
|
@@ -122,9 +144,7 @@ class PQCWallet {
|
|
|
122
144
|
*/
|
|
123
145
|
async sign(hash) {
|
|
124
146
|
// Ensure key pair is initialized
|
|
125
|
-
|
|
126
|
-
await this._ensureKeyPair();
|
|
127
|
-
}
|
|
147
|
+
await this._initPromise;
|
|
128
148
|
|
|
129
149
|
// dilithium-crystals API: sign(secretKey, message)
|
|
130
150
|
// Some implementations may require context, but we'll try without first
|
|
@@ -146,9 +166,7 @@ class PQCWallet {
|
|
|
146
166
|
*/
|
|
147
167
|
async verify(hash, signature) {
|
|
148
168
|
// Ensure key pair is initialized
|
|
149
|
-
|
|
150
|
-
await this._ensureKeyPair();
|
|
151
|
-
}
|
|
169
|
+
await this._initPromise;
|
|
152
170
|
|
|
153
171
|
// dilithium-crystals API: verify(publicKey, message, signature)
|
|
154
172
|
if (dilithium.verify) {
|
|
@@ -166,10 +184,8 @@ class PQCWallet {
|
|
|
166
184
|
* @returns {Promise<string>} Public key (hex)
|
|
167
185
|
*/
|
|
168
186
|
async getPublicKeyHex() {
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
}
|
|
172
|
-
return ethers.hexlify(this.publicKey);
|
|
187
|
+
await this._initPromise;
|
|
188
|
+
return ethers.utils.hexlify(this.publicKey);
|
|
173
189
|
}
|
|
174
190
|
|
|
175
191
|
/**
|
|
@@ -177,10 +193,8 @@ class PQCWallet {
|
|
|
177
193
|
* @returns {Promise<string>} Secret key (hex)
|
|
178
194
|
*/
|
|
179
195
|
async getSecretKeyHex() {
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
}
|
|
183
|
-
return ethers.hexlify(this.secretKey);
|
|
196
|
+
await this._initPromise;
|
|
197
|
+
return ethers.utils.hexlify(this.secretKey);
|
|
184
198
|
}
|
|
185
199
|
}
|
|
186
200
|
|
|
@@ -198,6 +212,24 @@ class HybridWallet {
|
|
|
198
212
|
this._initialized = false;
|
|
199
213
|
}
|
|
200
214
|
|
|
215
|
+
/**
|
|
216
|
+
* Create a new Hybrid wallet with initialized keys (static factory method)
|
|
217
|
+
* @param {ECDSAWallet|string} ecdsaWallet - ECDSA wallet or private key
|
|
218
|
+
* @returns {Promise<HybridWallet>} Initialized hybrid wallet
|
|
219
|
+
*/
|
|
220
|
+
static async create(ecdsaWallet) {
|
|
221
|
+
const ecdsa = ecdsaWallet instanceof ECDSAWallet ? ecdsaWallet : new ECDSAWallet(ecdsaWallet);
|
|
222
|
+
const pqc = new PQCWallet();
|
|
223
|
+
await pqc._initPromise; // Wait for PQC keys to be generated
|
|
224
|
+
const wallet = new HybridWallet(ecdsa, pqc);
|
|
225
|
+
wallet.address = deriveHybridAddress(
|
|
226
|
+
ethers.utils.arrayify(ecdsa.getPublicKey()),
|
|
227
|
+
pqc.publicKey
|
|
228
|
+
);
|
|
229
|
+
wallet._initialized = true;
|
|
230
|
+
return wallet;
|
|
231
|
+
}
|
|
232
|
+
|
|
201
233
|
/**
|
|
202
234
|
* Get the hybrid address (computed from ECDSA + PQC public keys)
|
|
203
235
|
* @returns {Promise<string>} Hybrid address
|
|
@@ -208,12 +240,10 @@ class HybridWallet {
|
|
|
208
240
|
}
|
|
209
241
|
|
|
210
242
|
// Ensure PQC wallet has keys
|
|
211
|
-
|
|
212
|
-
await this.pqcWallet._ensureKeyPair();
|
|
213
|
-
}
|
|
243
|
+
await this.pqcWallet._initPromise;
|
|
214
244
|
|
|
215
245
|
this.address = deriveHybridAddress(
|
|
216
|
-
ethers.
|
|
246
|
+
ethers.utils.arrayify(this.ecdsaWallet.getPublicKey()),
|
|
217
247
|
this.pqcWallet.publicKey
|
|
218
248
|
);
|
|
219
249
|
this._initialized = true;
|
|
@@ -232,7 +262,7 @@ class HybridWallet {
|
|
|
232
262
|
const pqcWallet = new PQCWallet(pqcSecretKey, pqcPublicKey);
|
|
233
263
|
const wallet = new HybridWallet(ecdsaWallet, pqcWallet);
|
|
234
264
|
wallet.address = deriveHybridAddress(
|
|
235
|
-
ethers.
|
|
265
|
+
ethers.utils.arrayify(ecdsaWallet.getPublicKey()),
|
|
236
266
|
pqcWallet.publicKey
|
|
237
267
|
);
|
|
238
268
|
wallet._initialized = true;
|
package/src/zk-transaction.js
CHANGED
|
@@ -51,27 +51,27 @@ class ZKTransaction {
|
|
|
51
51
|
};
|
|
52
52
|
|
|
53
53
|
if (this.to) args.to = this.to;
|
|
54
|
-
if (this.value) args.value = ethers.
|
|
55
|
-
if (this.gasLimit) args.gas = ethers.
|
|
56
|
-
if (this.gasPrice) args.gasPrice = ethers.
|
|
54
|
+
if (this.value) args.value = ethers.utils.hexlify(this.value);
|
|
55
|
+
if (this.gasLimit) args.gas = ethers.utils.hexlify(this.gasLimit);
|
|
56
|
+
if (this.gasPrice) args.gasPrice = ethers.utils.hexlify(this.gasPrice);
|
|
57
57
|
if (this.data) args.data = this.data;
|
|
58
|
-
if (this.nonce) args.nonce = ethers.
|
|
59
|
-
if (this.chainId) args.chainId = ethers.
|
|
58
|
+
if (this.nonce) args.nonce = ethers.utils.hexlify(this.nonce);
|
|
59
|
+
if (this.chainId) args.chainId = ethers.utils.hexlify(this.chainId);
|
|
60
60
|
if (this.accessList && this.accessList.length > 0) args.accessList = this.accessList;
|
|
61
61
|
if (this.zkPublicInputs && this.zkPublicInputs.length > 0) {
|
|
62
62
|
args.zkPublicInputs = this.zkPublicInputs.map(pi =>
|
|
63
|
-
typeof pi === 'string' ? pi : ethers.hexlify(pi)
|
|
63
|
+
typeof pi === 'string' ? pi : ethers.utils.hexlify(pi)
|
|
64
64
|
);
|
|
65
65
|
}
|
|
66
66
|
if (this.zkVerificationKeyHash) {
|
|
67
67
|
args.zkVerificationKeyHash = typeof this.zkVerificationKeyHash === 'string'
|
|
68
68
|
? this.zkVerificationKeyHash
|
|
69
|
-
: ethers.hexlify(this.zkVerificationKeyHash);
|
|
69
|
+
: ethers.utils.hexlify(this.zkVerificationKeyHash);
|
|
70
70
|
}
|
|
71
71
|
if (this.encryptedPayload) {
|
|
72
72
|
args.encryptedPayload = typeof this.encryptedPayload === 'string'
|
|
73
73
|
? this.encryptedPayload
|
|
74
|
-
: ethers.hexlify(this.encryptedPayload);
|
|
74
|
+
: ethers.utils.hexlify(this.encryptedPayload);
|
|
75
75
|
}
|
|
76
76
|
if (this.recipients && this.recipients.length > 0) {
|
|
77
77
|
args.recipients = this.recipients;
|