@cheny56/node-client 1.0.8 → 1.0.10
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 +3 -6
- package/src/constants.js +11 -4
- package/src/contract.js +12 -13
- package/src/index.js +53 -10
- package/src/provider.js +6 -2
- package/src/transaction.js +107 -94
- package/src/utils/address.js +10 -4
- package/src/utils/rlp.js +10 -4
- package/src/wallet.js +42 -111
- package/src/zk-transaction.js +7 -3
- package/index.cjs +0 -37
package/package.json
CHANGED
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cheny56/node-client",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.10",
|
|
4
4
|
"description": "Client library for Quorum blockchain with Post-Quantum Cryptography (PQC) and Zero-Knowledge Proof (ZK) support",
|
|
5
|
-
"main": "./index.
|
|
6
|
-
"module": "./src/index.js",
|
|
5
|
+
"main": "./src/index.js",
|
|
7
6
|
"types": "src/index.d.ts",
|
|
8
|
-
"type": "module",
|
|
9
7
|
"exports": {
|
|
10
8
|
".": {
|
|
11
|
-
"require": "./index.
|
|
9
|
+
"require": "./src/index.js",
|
|
12
10
|
"import": "./src/index.js",
|
|
13
11
|
"types": "./src/index.d.ts",
|
|
14
12
|
"default": "./src/index.js"
|
|
@@ -18,7 +16,6 @@
|
|
|
18
16
|
"files": [
|
|
19
17
|
"src/**/*.js",
|
|
20
18
|
"src/**/*.d.ts",
|
|
21
|
-
"index.cjs",
|
|
22
19
|
"package.json",
|
|
23
20
|
"README.md",
|
|
24
21
|
"README-COMMONJS.md",
|
package/src/constants.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Transaction Type Constants
|
|
3
3
|
*/
|
|
4
|
-
|
|
4
|
+
const TX_TYPE = {
|
|
5
5
|
LEGACY: 0,
|
|
6
6
|
ACCESS_LIST: 1,
|
|
7
7
|
DYNAMIC_FEE: 2,
|
|
@@ -11,7 +11,7 @@ export const TX_TYPE = {
|
|
|
11
11
|
/**
|
|
12
12
|
* PQC Signature Type Constants
|
|
13
13
|
*/
|
|
14
|
-
|
|
14
|
+
const PQC_TYPE = {
|
|
15
15
|
NONE: 0,
|
|
16
16
|
DILITHIUM: 1,
|
|
17
17
|
};
|
|
@@ -19,7 +19,7 @@ export const PQC_TYPE = {
|
|
|
19
19
|
/**
|
|
20
20
|
* ZK Proof System Constants
|
|
21
21
|
*/
|
|
22
|
-
|
|
22
|
+
const ZK_PROOF_SYSTEM = {
|
|
23
23
|
GROTH16: 1,
|
|
24
24
|
PLONK: 2,
|
|
25
25
|
STARK: 3,
|
|
@@ -28,4 +28,11 @@ export const ZK_PROOF_SYSTEM = {
|
|
|
28
28
|
/**
|
|
29
29
|
* Default Chain ID for Quorum
|
|
30
30
|
*/
|
|
31
|
-
|
|
31
|
+
const DEFAULT_CHAIN_ID = 1337;
|
|
32
|
+
|
|
33
|
+
module.exports = {
|
|
34
|
+
TX_TYPE,
|
|
35
|
+
PQC_TYPE,
|
|
36
|
+
ZK_PROOF_SYSTEM,
|
|
37
|
+
DEFAULT_CHAIN_ID,
|
|
38
|
+
};
|
package/src/contract.js
CHANGED
|
@@ -3,13 +3,13 @@
|
|
|
3
3
|
* Supports ERC20 token transfers and contract calls
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
const { ethers } = require('ethers');
|
|
7
|
+
const { LegacyTransaction, PQCLegacyTransaction, HybridLegacyTransaction } = require('./transaction.js');
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Contract class for interacting with smart contracts
|
|
11
11
|
*/
|
|
12
|
-
|
|
12
|
+
class Contract {
|
|
13
13
|
constructor(address, abi, provider, wallet = null) {
|
|
14
14
|
this.address = address;
|
|
15
15
|
this.abi = abi;
|
|
@@ -81,7 +81,7 @@ export class Contract {
|
|
|
81
81
|
* ERC20 Token Contract
|
|
82
82
|
* Simplified interface for ERC20 token operations
|
|
83
83
|
*/
|
|
84
|
-
|
|
84
|
+
class ERC20Token extends Contract {
|
|
85
85
|
constructor(address, provider, wallet = null) {
|
|
86
86
|
const erc20Abi = [
|
|
87
87
|
'function name() view returns (string)',
|
|
@@ -160,10 +160,6 @@ export class ERC20Token extends Contract {
|
|
|
160
160
|
*/
|
|
161
161
|
async transferPQC(wallet, provider, to, amount, txOptions = {}) {
|
|
162
162
|
const data = this.encodeFunctionData('transfer', [to, amount]);
|
|
163
|
-
// Ensure wallet has address
|
|
164
|
-
if (!wallet.address) {
|
|
165
|
-
await wallet._ensureKeyPair();
|
|
166
|
-
}
|
|
167
163
|
const nonce = await provider.getTransactionCount(wallet.address, 'pending');
|
|
168
164
|
|
|
169
165
|
const tx = new PQCLegacyTransaction({
|
|
@@ -176,7 +172,7 @@ export class ERC20Token extends Contract {
|
|
|
176
172
|
data: data,
|
|
177
173
|
});
|
|
178
174
|
|
|
179
|
-
|
|
175
|
+
tx.sign(wallet);
|
|
180
176
|
const serialized = tx.getHex();
|
|
181
177
|
return await provider.sendRawTransaction(serialized);
|
|
182
178
|
}
|
|
@@ -192,9 +188,7 @@ export class ERC20Token extends Contract {
|
|
|
192
188
|
*/
|
|
193
189
|
async transferHybrid(wallet, provider, to, amount, txOptions = {}) {
|
|
194
190
|
const data = this.encodeFunctionData('transfer', [to, amount]);
|
|
195
|
-
|
|
196
|
-
const address = await wallet.getAddress();
|
|
197
|
-
const nonce = await provider.getTransactionCount(address, 'pending');
|
|
191
|
+
const nonce = await provider.getTransactionCount(wallet.address, 'pending');
|
|
198
192
|
|
|
199
193
|
const tx = new HybridLegacyTransaction({
|
|
200
194
|
chainId: txOptions.chainId || 1337,
|
|
@@ -206,8 +200,13 @@ export class ERC20Token extends Contract {
|
|
|
206
200
|
data: data,
|
|
207
201
|
});
|
|
208
202
|
|
|
209
|
-
|
|
203
|
+
tx.sign(wallet.ecdsaWallet, wallet.pqcWallet);
|
|
210
204
|
const serialized = tx.getHex();
|
|
211
205
|
return await provider.sendRawTransaction(serialized);
|
|
212
206
|
}
|
|
213
207
|
}
|
|
208
|
+
|
|
209
|
+
module.exports = {
|
|
210
|
+
Contract,
|
|
211
|
+
ERC20Token,
|
|
212
|
+
};
|
package/src/index.js
CHANGED
|
@@ -4,13 +4,13 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
// Providers
|
|
7
|
-
|
|
7
|
+
const { QuorumProvider } = require('./provider.js');
|
|
8
8
|
|
|
9
9
|
// Wallets
|
|
10
|
-
|
|
10
|
+
const { ECDSAWallet, PQCWallet, HybridWallet } = require('./wallet.js');
|
|
11
11
|
|
|
12
12
|
// Transactions
|
|
13
|
-
|
|
13
|
+
const {
|
|
14
14
|
LegacyTransaction,
|
|
15
15
|
PQCLegacyTransaction,
|
|
16
16
|
HybridLegacyTransaction,
|
|
@@ -18,20 +18,63 @@ export {
|
|
|
18
18
|
PQCAccessListTransaction,
|
|
19
19
|
DynamicFeeTransaction,
|
|
20
20
|
PQCDynamicFeeTransaction,
|
|
21
|
-
}
|
|
21
|
+
} = require('./transaction.js');
|
|
22
22
|
|
|
23
23
|
// ZK Transactions
|
|
24
|
-
|
|
24
|
+
const { ZKTransaction } = require('./zk-transaction.js');
|
|
25
25
|
|
|
26
26
|
// Contracts
|
|
27
|
-
|
|
27
|
+
const { Contract, ERC20Token } = require('./contract.js');
|
|
28
28
|
|
|
29
29
|
// Constants
|
|
30
|
-
|
|
30
|
+
const { TX_TYPE, PQC_TYPE, ZK_PROOF_SYSTEM, DEFAULT_CHAIN_ID } = require('./constants.js');
|
|
31
31
|
|
|
32
32
|
// Utilities
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
const { derivePQCAddress, deriveHybridAddress, isValidAddress } = require('./utils/address.js');
|
|
34
|
+
const { encodeUint64, encodeBigInt, encodeSignature } = require('./utils/rlp.js');
|
|
35
35
|
|
|
36
36
|
// Re-export ethers utilities for convenience
|
|
37
|
-
|
|
37
|
+
const { ethers } = require('ethers');
|
|
38
|
+
|
|
39
|
+
module.exports = {
|
|
40
|
+
// Providers
|
|
41
|
+
QuorumProvider,
|
|
42
|
+
|
|
43
|
+
// Wallets
|
|
44
|
+
ECDSAWallet,
|
|
45
|
+
PQCWallet,
|
|
46
|
+
HybridWallet,
|
|
47
|
+
|
|
48
|
+
// Transactions
|
|
49
|
+
LegacyTransaction,
|
|
50
|
+
PQCLegacyTransaction,
|
|
51
|
+
HybridLegacyTransaction,
|
|
52
|
+
AccessListTransaction,
|
|
53
|
+
PQCAccessListTransaction,
|
|
54
|
+
DynamicFeeTransaction,
|
|
55
|
+
PQCDynamicFeeTransaction,
|
|
56
|
+
|
|
57
|
+
// ZK Transactions
|
|
58
|
+
ZKTransaction,
|
|
59
|
+
|
|
60
|
+
// Contracts
|
|
61
|
+
Contract,
|
|
62
|
+
ERC20Token,
|
|
63
|
+
|
|
64
|
+
// Constants
|
|
65
|
+
TX_TYPE,
|
|
66
|
+
PQC_TYPE,
|
|
67
|
+
ZK_PROOF_SYSTEM,
|
|
68
|
+
DEFAULT_CHAIN_ID,
|
|
69
|
+
|
|
70
|
+
// Utilities
|
|
71
|
+
derivePQCAddress,
|
|
72
|
+
deriveHybridAddress,
|
|
73
|
+
isValidAddress,
|
|
74
|
+
encodeUint64,
|
|
75
|
+
encodeBigInt,
|
|
76
|
+
encodeSignature,
|
|
77
|
+
|
|
78
|
+
// Ethers
|
|
79
|
+
ethers,
|
|
80
|
+
};
|
package/src/provider.js
CHANGED
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
* Extends ethers.js JsonRpcProvider with Quorum-specific methods
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
const { ethers } = require('ethers');
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
class QuorumProvider extends ethers.providers.JsonRpcProvider {
|
|
9
9
|
constructor(url, network) {
|
|
10
10
|
super(url, network);
|
|
11
11
|
this.url = url;
|
|
@@ -93,3 +93,7 @@ export class QuorumProvider extends ethers.providers.JsonRpcProvider {
|
|
|
93
93
|
return await super.getBlock(blockNumber);
|
|
94
94
|
}
|
|
95
95
|
}
|
|
96
|
+
|
|
97
|
+
module.exports = {
|
|
98
|
+
QuorumProvider,
|
|
99
|
+
};
|
package/src/transaction.js
CHANGED
|
@@ -3,67 +3,21 @@
|
|
|
3
3
|
* Supports Legacy, AccessList, DynamicFee transactions with ECDSA, PQC, and Hybrid signatures
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
import { encodeUint64, encodeBigInt, encodeSignature } from './utils/rlp.js';
|
|
6
|
+
const { ethers } = require('ethers');
|
|
7
|
+
const { TX_TYPE, PQC_TYPE, DEFAULT_CHAIN_ID } = require('./constants.js');
|
|
8
|
+
const { encodeUint64, encodeBigInt, encodeSignature } = require('./utils/rlp.js');
|
|
10
9
|
|
|
11
10
|
// Import dilithium-crystals package
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
//
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
try {
|
|
24
|
-
// Try ES module import first
|
|
25
|
-
const dilithiumModule = await import('dilithium-crystals');
|
|
26
|
-
dilithiumCache = dilithiumModule.default || dilithiumModule;
|
|
27
|
-
} catch (e) {
|
|
28
|
-
// Fallback to CommonJS require
|
|
29
|
-
try {
|
|
30
|
-
dilithiumCache = require('dilithium-crystals');
|
|
31
|
-
dilithiumCache = dilithiumCache.default || dilithiumCache;
|
|
32
|
-
} catch (e2) {
|
|
33
|
-
throw new Error(
|
|
34
|
-
`Failed to import dilithium-crystals: ${e.message}\n` +
|
|
35
|
-
`Please ensure dilithium-crystals is installed: npm install dilithium-crystals`
|
|
36
|
-
);
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
return dilithiumCache;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// Helper function to sign with dilithium
|
|
44
|
-
async function signWithDilithium(secretKey, hash) {
|
|
45
|
-
const dilithium = await getDilithium();
|
|
46
|
-
if (dilithium.sign) {
|
|
47
|
-
return dilithium.sign(secretKey, hash);
|
|
48
|
-
} else if (dilithium.signWithContext) {
|
|
49
|
-
const ctx = new TextEncoder().encode('ML-DSA-65');
|
|
50
|
-
return dilithium.signWithContext(secretKey, hash, ctx);
|
|
51
|
-
} else {
|
|
52
|
-
throw new Error('dilithium-crystals does not expose sign method');
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// Helper function to verify with dilithium
|
|
57
|
-
async function verifyWithDilithium(publicKey, hash, signature) {
|
|
58
|
-
const dilithium = await getDilithium();
|
|
59
|
-
if (dilithium.verify) {
|
|
60
|
-
return dilithium.verify(publicKey, hash, signature);
|
|
61
|
-
} else if (dilithium.verifyWithContext) {
|
|
62
|
-
const ctx = new TextEncoder().encode('ML-DSA-65');
|
|
63
|
-
return dilithium.verifyWithContext(publicKey, hash, signature, ctx);
|
|
64
|
-
} else {
|
|
65
|
-
throw new Error('dilithium-crystals does not expose verify method');
|
|
66
|
-
}
|
|
11
|
+
let dilithium;
|
|
12
|
+
try {
|
|
13
|
+
dilithium = require('dilithium-crystals');
|
|
14
|
+
// Handle both default export and named export patterns
|
|
15
|
+
dilithium = dilithium.default || dilithium;
|
|
16
|
+
} catch (e) {
|
|
17
|
+
throw new Error(
|
|
18
|
+
`Failed to import dilithium-crystals: ${e.message}\n` +
|
|
19
|
+
`Please ensure dilithium-crystals is installed: npm install dilithium-crystals`
|
|
20
|
+
);
|
|
67
21
|
}
|
|
68
22
|
|
|
69
23
|
/**
|
|
@@ -82,7 +36,7 @@ class BaseTransaction {
|
|
|
82
36
|
/**
|
|
83
37
|
* Legacy ECDSA Transaction (Type 0)
|
|
84
38
|
*/
|
|
85
|
-
|
|
39
|
+
class LegacyTransaction extends BaseTransaction {
|
|
86
40
|
constructor(params) {
|
|
87
41
|
super(params);
|
|
88
42
|
this.type = TX_TYPE.LEGACY;
|
|
@@ -122,7 +76,7 @@ export class LegacyTransaction extends BaseTransaction {
|
|
|
122
76
|
/**
|
|
123
77
|
* Legacy PQC-only Transaction (Type 0 with PQC)
|
|
124
78
|
*/
|
|
125
|
-
|
|
79
|
+
class PQCLegacyTransaction extends BaseTransaction {
|
|
126
80
|
constructor(params) {
|
|
127
81
|
super(params);
|
|
128
82
|
this.type = TX_TYPE.LEGACY;
|
|
@@ -164,22 +118,38 @@ export class PQCLegacyTransaction extends BaseTransaction {
|
|
|
164
118
|
/**
|
|
165
119
|
* Sign with PQC wallet
|
|
166
120
|
* @param {PQCWallet} wallet - PQC wallet
|
|
167
|
-
* @returns {
|
|
121
|
+
* @returns {PQCLegacyTransaction} This transaction
|
|
168
122
|
*/
|
|
169
|
-
|
|
123
|
+
sign(wallet) {
|
|
170
124
|
const hash = ethers.getBytes(this.getSigningHash());
|
|
171
|
-
this.pqcPubKey = wallet.publicKey
|
|
172
|
-
|
|
125
|
+
this.pqcPubKey = wallet.publicKey;
|
|
126
|
+
// dilithium-crystals API: sign(secretKey, message) or signWithContext(secretKey, message, ctx)
|
|
127
|
+
if (dilithium.sign) {
|
|
128
|
+
this.pqcSig = dilithium.sign(wallet.secretKey, hash);
|
|
129
|
+
} else if (dilithium.signWithContext) {
|
|
130
|
+
const ctx = new TextEncoder().encode('ML-DSA-65');
|
|
131
|
+
this.pqcSig = dilithium.signWithContext(wallet.secretKey, hash, ctx);
|
|
132
|
+
} else {
|
|
133
|
+
throw new Error('dilithium-crystals does not expose sign method');
|
|
134
|
+
}
|
|
173
135
|
this.v = Number(this.chainId) * 2 + 35;
|
|
174
136
|
this.r = '0x0';
|
|
175
137
|
this.s = '0x0';
|
|
176
138
|
return this;
|
|
177
139
|
}
|
|
178
140
|
|
|
179
|
-
|
|
141
|
+
verify() {
|
|
180
142
|
if (!this.pqcSig || !this.pqcPubKey) return false;
|
|
181
143
|
const hash = ethers.getBytes(this.getSigningHash());
|
|
182
|
-
|
|
144
|
+
// dilithium-crystals API: verify(publicKey, message, signature) or verifyWithContext
|
|
145
|
+
if (dilithium.verify) {
|
|
146
|
+
return dilithium.verify(this.pqcPubKey, hash, this.pqcSig);
|
|
147
|
+
} else if (dilithium.verifyWithContext) {
|
|
148
|
+
const ctx = new TextEncoder().encode('ML-DSA-65');
|
|
149
|
+
return dilithium.verifyWithContext(this.pqcPubKey, hash, this.pqcSig, ctx);
|
|
150
|
+
} else {
|
|
151
|
+
throw new Error('dilithium-crystals does not expose verify method');
|
|
152
|
+
}
|
|
183
153
|
}
|
|
184
154
|
|
|
185
155
|
serialize() {
|
|
@@ -222,7 +192,7 @@ export class PQCLegacyTransaction extends BaseTransaction {
|
|
|
222
192
|
/**
|
|
223
193
|
* Legacy Hybrid Transaction (Type 0 with ECDSA + PQC)
|
|
224
194
|
*/
|
|
225
|
-
|
|
195
|
+
class HybridLegacyTransaction extends BaseTransaction {
|
|
226
196
|
constructor(params) {
|
|
227
197
|
super(params);
|
|
228
198
|
this.type = TX_TYPE.LEGACY;
|
|
@@ -265,9 +235,9 @@ export class HybridLegacyTransaction extends BaseTransaction {
|
|
|
265
235
|
* Sign with both ECDSA and PQC wallets
|
|
266
236
|
* @param {ECDSAWallet} ecdsaWallet - ECDSA wallet
|
|
267
237
|
* @param {PQCWallet} pqcWallet - PQC wallet
|
|
268
|
-
* @returns {
|
|
238
|
+
* @returns {HybridLegacyTransaction} This transaction
|
|
269
239
|
*/
|
|
270
|
-
|
|
240
|
+
sign(ecdsaWallet, pqcWallet) {
|
|
271
241
|
const hash = this.getSigningHash();
|
|
272
242
|
const hashBytes = ethers.getBytes(hash);
|
|
273
243
|
|
|
@@ -279,19 +249,30 @@ export class HybridLegacyTransaction extends BaseTransaction {
|
|
|
279
249
|
this.s = ecdsaSig.s;
|
|
280
250
|
|
|
281
251
|
// PQC signature
|
|
282
|
-
if (!pqcWallet.publicKey) {
|
|
283
|
-
await pqcWallet._ensureKeyPair();
|
|
284
|
-
}
|
|
285
252
|
this.pqcPubKey = pqcWallet.publicKey;
|
|
286
|
-
|
|
253
|
+
if (dilithium.sign) {
|
|
254
|
+
this.pqcSig = dilithium.sign(pqcWallet.secretKey, hashBytes);
|
|
255
|
+
} else if (dilithium.signWithContext) {
|
|
256
|
+
const ctx = new TextEncoder().encode('ML-DSA-65');
|
|
257
|
+
this.pqcSig = dilithium.signWithContext(pqcWallet.secretKey, hashBytes, ctx);
|
|
258
|
+
} else {
|
|
259
|
+
throw new Error('dilithium-crystals does not expose sign method');
|
|
260
|
+
}
|
|
287
261
|
|
|
288
262
|
return this;
|
|
289
263
|
}
|
|
290
264
|
|
|
291
|
-
|
|
265
|
+
verify() {
|
|
292
266
|
if (!this.pqcSig || !this.pqcPubKey) return false;
|
|
293
267
|
const hash = ethers.getBytes(this.getSigningHash());
|
|
294
|
-
|
|
268
|
+
if (dilithium.verify) {
|
|
269
|
+
return dilithium.verify(this.pqcPubKey, hash, this.pqcSig);
|
|
270
|
+
} else if (dilithium.verifyWithContext) {
|
|
271
|
+
const ctx = new TextEncoder().encode('ML-DSA-65');
|
|
272
|
+
return dilithium.verifyWithContext(this.pqcPubKey, hash, this.pqcSig, ctx);
|
|
273
|
+
} else {
|
|
274
|
+
throw new Error('dilithium-crystals does not expose verify method');
|
|
275
|
+
}
|
|
295
276
|
}
|
|
296
277
|
|
|
297
278
|
serialize() {
|
|
@@ -334,7 +315,7 @@ export class HybridLegacyTransaction extends BaseTransaction {
|
|
|
334
315
|
/**
|
|
335
316
|
* AccessList Transaction (Type 1) - ECDSA
|
|
336
317
|
*/
|
|
337
|
-
|
|
318
|
+
class AccessListTransaction extends BaseTransaction {
|
|
338
319
|
constructor(params) {
|
|
339
320
|
super(params);
|
|
340
321
|
this.type = TX_TYPE.ACCESS_LIST;
|
|
@@ -366,7 +347,7 @@ export class AccessListTransaction extends BaseTransaction {
|
|
|
366
347
|
/**
|
|
367
348
|
* AccessList PQC Transaction (Type 1 with PQC)
|
|
368
349
|
*/
|
|
369
|
-
|
|
350
|
+
class PQCAccessListTransaction extends BaseTransaction {
|
|
370
351
|
constructor(params) {
|
|
371
352
|
super(params);
|
|
372
353
|
this.type = TX_TYPE.ACCESS_LIST;
|
|
@@ -410,20 +391,31 @@ export class PQCAccessListTransaction extends BaseTransaction {
|
|
|
410
391
|
return ethers.keccak256(ethers.hexlify(prefixed));
|
|
411
392
|
}
|
|
412
393
|
|
|
413
|
-
|
|
394
|
+
sign(wallet) {
|
|
414
395
|
const hash = ethers.getBytes(this.getSigningHash());
|
|
415
|
-
if (!wallet.publicKey) {
|
|
416
|
-
await wallet._ensureKeyPair();
|
|
417
|
-
}
|
|
418
396
|
this.pqcPubKey = wallet.publicKey;
|
|
419
|
-
|
|
397
|
+
if (dilithium.sign) {
|
|
398
|
+
this.pqcSig = dilithium.sign(wallet.secretKey, hash);
|
|
399
|
+
} else if (dilithium.signWithContext) {
|
|
400
|
+
const ctx = new TextEncoder().encode('ML-DSA-65');
|
|
401
|
+
this.pqcSig = dilithium.signWithContext(wallet.secretKey, hash, ctx);
|
|
402
|
+
} else {
|
|
403
|
+
throw new Error('dilithium-crystals does not expose sign method');
|
|
404
|
+
}
|
|
420
405
|
return this;
|
|
421
406
|
}
|
|
422
407
|
|
|
423
|
-
|
|
408
|
+
verify() {
|
|
424
409
|
if (!this.pqcSig || !this.pqcPubKey) return false;
|
|
425
410
|
const hash = ethers.getBytes(this.getSigningHash());
|
|
426
|
-
|
|
411
|
+
if (dilithium.verify) {
|
|
412
|
+
return dilithium.verify(this.pqcPubKey, hash, this.pqcSig);
|
|
413
|
+
} else if (dilithium.verifyWithContext) {
|
|
414
|
+
const ctx = new TextEncoder().encode('ML-DSA-65');
|
|
415
|
+
return dilithium.verifyWithContext(this.pqcPubKey, hash, this.pqcSig, ctx);
|
|
416
|
+
} else {
|
|
417
|
+
throw new Error('dilithium-crystals does not expose verify method');
|
|
418
|
+
}
|
|
427
419
|
}
|
|
428
420
|
|
|
429
421
|
serialize() {
|
|
@@ -477,7 +469,7 @@ export class PQCAccessListTransaction extends BaseTransaction {
|
|
|
477
469
|
/**
|
|
478
470
|
* DynamicFee Transaction (Type 2) - ECDSA
|
|
479
471
|
*/
|
|
480
|
-
|
|
472
|
+
class DynamicFeeTransaction extends BaseTransaction {
|
|
481
473
|
constructor(params) {
|
|
482
474
|
super(params);
|
|
483
475
|
this.type = TX_TYPE.DYNAMIC_FEE;
|
|
@@ -511,7 +503,7 @@ export class DynamicFeeTransaction extends BaseTransaction {
|
|
|
511
503
|
/**
|
|
512
504
|
* DynamicFee PQC Transaction (Type 2 with PQC)
|
|
513
505
|
*/
|
|
514
|
-
|
|
506
|
+
class PQCDynamicFeeTransaction extends BaseTransaction {
|
|
515
507
|
constructor(params) {
|
|
516
508
|
super(params);
|
|
517
509
|
this.type = TX_TYPE.DYNAMIC_FEE;
|
|
@@ -558,20 +550,31 @@ export class PQCDynamicFeeTransaction extends BaseTransaction {
|
|
|
558
550
|
return ethers.keccak256(ethers.hexlify(prefixed));
|
|
559
551
|
}
|
|
560
552
|
|
|
561
|
-
|
|
553
|
+
sign(wallet) {
|
|
562
554
|
const hash = ethers.getBytes(this.getSigningHash());
|
|
563
|
-
if (!wallet.publicKey) {
|
|
564
|
-
await wallet._ensureKeyPair();
|
|
565
|
-
}
|
|
566
555
|
this.pqcPubKey = wallet.publicKey;
|
|
567
|
-
|
|
556
|
+
if (dilithium.sign) {
|
|
557
|
+
this.pqcSig = dilithium.sign(wallet.secretKey, hash);
|
|
558
|
+
} else if (dilithium.signWithContext) {
|
|
559
|
+
const ctx = new TextEncoder().encode('ML-DSA-65');
|
|
560
|
+
this.pqcSig = dilithium.signWithContext(wallet.secretKey, hash, ctx);
|
|
561
|
+
} else {
|
|
562
|
+
throw new Error('dilithium-crystals does not expose sign method');
|
|
563
|
+
}
|
|
568
564
|
return this;
|
|
569
565
|
}
|
|
570
566
|
|
|
571
|
-
|
|
567
|
+
verify() {
|
|
572
568
|
if (!this.pqcSig || !this.pqcPubKey) return false;
|
|
573
569
|
const hash = ethers.getBytes(this.getSigningHash());
|
|
574
|
-
|
|
570
|
+
if (dilithium.verify) {
|
|
571
|
+
return dilithium.verify(this.pqcPubKey, hash, this.pqcSig);
|
|
572
|
+
} else if (dilithium.verifyWithContext) {
|
|
573
|
+
const ctx = new TextEncoder().encode('ML-DSA-65');
|
|
574
|
+
return dilithium.verifyWithContext(this.pqcPubKey, hash, this.pqcSig, ctx);
|
|
575
|
+
} else {
|
|
576
|
+
throw new Error('dilithium-crystals does not expose verify method');
|
|
577
|
+
}
|
|
575
578
|
}
|
|
576
579
|
|
|
577
580
|
serialize() {
|
|
@@ -623,3 +626,13 @@ export class PQCDynamicFeeTransaction extends BaseTransaction {
|
|
|
623
626
|
return ethers.hexlify(this.serialize());
|
|
624
627
|
}
|
|
625
628
|
}
|
|
629
|
+
|
|
630
|
+
module.exports = {
|
|
631
|
+
LegacyTransaction,
|
|
632
|
+
PQCLegacyTransaction,
|
|
633
|
+
HybridLegacyTransaction,
|
|
634
|
+
AccessListTransaction,
|
|
635
|
+
PQCAccessListTransaction,
|
|
636
|
+
DynamicFeeTransaction,
|
|
637
|
+
PQCDynamicFeeTransaction,
|
|
638
|
+
};
|
package/src/utils/address.js
CHANGED
|
@@ -3,14 +3,14 @@
|
|
|
3
3
|
* Handles address derivation for PQC and Hybrid addresses
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
const { ethers } = require('ethers');
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Derive PQC address from Dilithium public key
|
|
10
10
|
* @param {Uint8Array} publicKey - Dilithium public key
|
|
11
11
|
* @returns {string} Ethereum address
|
|
12
12
|
*/
|
|
13
|
-
|
|
13
|
+
function derivePQCAddress(publicKey) {
|
|
14
14
|
const hash = ethers.keccak256(publicKey);
|
|
15
15
|
return ethers.getAddress('0x' + hash.slice(-40));
|
|
16
16
|
}
|
|
@@ -21,7 +21,7 @@ export function derivePQCAddress(publicKey) {
|
|
|
21
21
|
* @param {Uint8Array} dilithiumPublicKey - Dilithium public key
|
|
22
22
|
* @returns {string} Hybrid Ethereum address
|
|
23
23
|
*/
|
|
24
|
-
|
|
24
|
+
function deriveHybridAddress(ecdsaPublicKey, dilithiumPublicKey) {
|
|
25
25
|
// Remove 0x04 prefix from ECDSA public key if present
|
|
26
26
|
let ecdsaBytes = ecdsaPublicKey;
|
|
27
27
|
if (ecdsaBytes.length === 65 && ecdsaBytes[0] === 4) {
|
|
@@ -43,6 +43,12 @@ export function deriveHybridAddress(ecdsaPublicKey, dilithiumPublicKey) {
|
|
|
43
43
|
* @param {string} address - Address to validate
|
|
44
44
|
* @returns {boolean}
|
|
45
45
|
*/
|
|
46
|
-
|
|
46
|
+
function isValidAddress(address) {
|
|
47
47
|
return ethers.utils.isAddress(address);
|
|
48
48
|
}
|
|
49
|
+
|
|
50
|
+
module.exports = {
|
|
51
|
+
derivePQCAddress,
|
|
52
|
+
deriveHybridAddress,
|
|
53
|
+
isValidAddress,
|
|
54
|
+
};
|
package/src/utils/rlp.js
CHANGED
|
@@ -3,13 +3,13 @@
|
|
|
3
3
|
* Handles proper encoding for Go RLP compatibility
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
const { ethers } = require('ethers');
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Encode uint64 value for RLP as hex string
|
|
10
10
|
* In Go RLP, uint64(0) encodes as empty bytes, non-zero as canonical bytes
|
|
11
11
|
*/
|
|
12
|
-
|
|
12
|
+
function encodeUint64(value) {
|
|
13
13
|
if (value === 0 || value === 0n || value === null || value === undefined) {
|
|
14
14
|
return '0x';
|
|
15
15
|
}
|
|
@@ -21,7 +21,7 @@ export function encodeUint64(value) {
|
|
|
21
21
|
* Encode *big.Int value for RLP as hex string
|
|
22
22
|
* Go RLP encodes *big.Int(0) as 0x80 (empty bytes), NOT 0x00!
|
|
23
23
|
*/
|
|
24
|
-
|
|
24
|
+
function encodeBigInt(value) {
|
|
25
25
|
if (value === 0 || value === 0n || value === null || value === undefined) {
|
|
26
26
|
return '0x';
|
|
27
27
|
}
|
|
@@ -33,7 +33,7 @@ export function encodeBigInt(value) {
|
|
|
33
33
|
* Encode signature value (R, S) for RLP as hex string
|
|
34
34
|
* Removes leading zeros for canonical form (required for *big.Int in Go RLP)
|
|
35
35
|
*/
|
|
36
|
-
|
|
36
|
+
function encodeSignature(value) {
|
|
37
37
|
if (!value || value === '0x0' || value === '0x' || value === '0x00') {
|
|
38
38
|
return '0x';
|
|
39
39
|
}
|
|
@@ -54,3 +54,9 @@ export function encodeSignature(value) {
|
|
|
54
54
|
bytes = bytes.slice(startIdx);
|
|
55
55
|
return ethers.hexlify(bytes);
|
|
56
56
|
}
|
|
57
|
+
|
|
58
|
+
module.exports = {
|
|
59
|
+
encodeUint64,
|
|
60
|
+
encodeBigInt,
|
|
61
|
+
encodeSignature,
|
|
62
|
+
};
|
package/src/wallet.js
CHANGED
|
@@ -3,47 +3,27 @@
|
|
|
3
3
|
* Supports ECDSA, PQC (Dilithium), and Hybrid wallets
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
import { derivePQCAddress, deriveHybridAddress } from './utils/address.js';
|
|
6
|
+
const { ethers } = require('ethers');
|
|
7
|
+
const { derivePQCAddress, deriveHybridAddress } = require('./utils/address.js');
|
|
9
8
|
|
|
10
9
|
// Import dilithium-crystals package
|
|
11
10
|
// This package provides Dilithium3 (ML-DSA-65 equivalent) implementation
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
//
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
try {
|
|
24
|
-
// Try ES module import first
|
|
25
|
-
const dilithiumModule = await import('dilithium-crystals');
|
|
26
|
-
dilithiumCache = dilithiumModule.default || dilithiumModule;
|
|
27
|
-
} catch (e) {
|
|
28
|
-
// Fallback to CommonJS require
|
|
29
|
-
try {
|
|
30
|
-
dilithiumCache = require('dilithium-crystals');
|
|
31
|
-
dilithiumCache = dilithiumCache.default || dilithiumCache;
|
|
32
|
-
} catch (e2) {
|
|
33
|
-
throw new Error(
|
|
34
|
-
`Failed to import dilithium-crystals: ${e.message}\n` +
|
|
35
|
-
`Please ensure dilithium-crystals is installed: npm install dilithium-crystals`
|
|
36
|
-
);
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
return dilithiumCache;
|
|
11
|
+
let dilithium;
|
|
12
|
+
try {
|
|
13
|
+
dilithium = require('dilithium-crystals');
|
|
14
|
+
// Handle both default export and named export patterns
|
|
15
|
+
dilithium = dilithium.default || dilithium;
|
|
16
|
+
} catch (e) {
|
|
17
|
+
throw new Error(
|
|
18
|
+
`Failed to import dilithium-crystals: ${e.message}\n` +
|
|
19
|
+
`Please ensure dilithium-crystals is installed: npm install dilithium-crystals`
|
|
20
|
+
);
|
|
41
21
|
}
|
|
42
22
|
|
|
43
23
|
/**
|
|
44
24
|
* ECDSA Wallet (standard Ethereum wallet)
|
|
45
25
|
*/
|
|
46
|
-
|
|
26
|
+
class ECDSAWallet {
|
|
47
27
|
constructor(privateKey, provider = null) {
|
|
48
28
|
this.wallet = new ethers.Wallet(privateKey, provider);
|
|
49
29
|
this.address = this.wallet.address;
|
|
@@ -81,35 +61,22 @@ export class ECDSAWallet {
|
|
|
81
61
|
/**
|
|
82
62
|
* PQC Wallet (Dilithium/ML-DSA-65)
|
|
83
63
|
*/
|
|
84
|
-
|
|
64
|
+
class PQCWallet {
|
|
85
65
|
constructor(secretKey = null, publicKey = null) {
|
|
86
66
|
if (secretKey && publicKey) {
|
|
87
67
|
this.secretKey = secretKey instanceof Uint8Array ? secretKey : new Uint8Array(secretKey);
|
|
88
68
|
this.publicKey = publicKey instanceof Uint8Array ? publicKey : new Uint8Array(publicKey);
|
|
89
69
|
} else {
|
|
90
|
-
// Generate new key pair -
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* Initialize key pair if not already done
|
|
100
|
-
*/
|
|
101
|
-
async _ensureKeyPair() {
|
|
102
|
-
if (this._keyPairGenerated) {
|
|
103
|
-
return;
|
|
70
|
+
// Generate new key pair using dilithium-crystals
|
|
71
|
+
// dilithium-crystals uses keygen() which returns { publicKey, secretKey }
|
|
72
|
+
if (!dilithium.keygen) {
|
|
73
|
+
throw new Error('dilithium-crystals does not expose keygen method. Please check the package API.');
|
|
74
|
+
}
|
|
75
|
+
const keyPair = dilithium.keygen();
|
|
76
|
+
this.secretKey = keyPair.secretKey;
|
|
77
|
+
this.publicKey = keyPair.publicKey;
|
|
104
78
|
}
|
|
105
|
-
|
|
106
|
-
const dilithium = await getDilithium();
|
|
107
|
-
// dilithium-crystals typically uses keygen() or generateKeyPair()
|
|
108
|
-
const keyPair = dilithium.keygen ? dilithium.keygen() : dilithium.generateKeyPair();
|
|
109
|
-
this.secretKey = keyPair.secretKey || keyPair.privateKey;
|
|
110
|
-
this.publicKey = keyPair.publicKey;
|
|
111
79
|
this.address = derivePQCAddress(this.publicKey);
|
|
112
|
-
this._keyPairGenerated = true;
|
|
113
80
|
}
|
|
114
81
|
|
|
115
82
|
/**
|
|
@@ -126,24 +93,17 @@ export class PQCWallet {
|
|
|
126
93
|
}
|
|
127
94
|
const secret = secretKey instanceof Uint8Array ? secretKey : ethers.getBytes(secretKey);
|
|
128
95
|
const pub = publicKey instanceof Uint8Array ? publicKey : ethers.getBytes(publicKey);
|
|
129
|
-
|
|
130
|
-
wallet.address = derivePQCAddress(wallet.publicKey);
|
|
131
|
-
wallet._keyPairGenerated = true;
|
|
132
|
-
return wallet;
|
|
96
|
+
return new PQCWallet(secret, pub);
|
|
133
97
|
}
|
|
134
98
|
|
|
135
99
|
/**
|
|
136
100
|
* Sign a message hash
|
|
137
101
|
* @param {Uint8Array} hash - Message hash (32 bytes)
|
|
138
|
-
* @returns {
|
|
102
|
+
* @returns {Uint8Array} Signature
|
|
139
103
|
*/
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
const dilithium = await getDilithium();
|
|
146
|
-
// dilithium-crystals API: sign(secretKey, message) or signWithContext(secretKey, message, ctx)
|
|
104
|
+
sign(hash) {
|
|
105
|
+
// dilithium-crystals API: sign(secretKey, message)
|
|
106
|
+
// Some implementations may require context, but we'll try without first
|
|
147
107
|
if (dilithium.sign) {
|
|
148
108
|
return dilithium.sign(this.secretKey, hash);
|
|
149
109
|
} else if (dilithium.signWithContext) {
|
|
@@ -158,15 +118,10 @@ export class PQCWallet {
|
|
|
158
118
|
* Verify a signature
|
|
159
119
|
* @param {Uint8Array} hash - Message hash
|
|
160
120
|
* @param {Uint8Array} signature - Signature to verify
|
|
161
|
-
* @returns {
|
|
121
|
+
* @returns {boolean} True if signature is valid
|
|
162
122
|
*/
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
throw new Error('Public key not set');
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
const dilithium = await getDilithium();
|
|
169
|
-
// dilithium-crystals API: verify(publicKey, message, signature) or verifyWithContext
|
|
123
|
+
verify(hash, signature) {
|
|
124
|
+
// dilithium-crystals API: verify(publicKey, message, signature)
|
|
170
125
|
if (dilithium.verify) {
|
|
171
126
|
return dilithium.verify(this.publicKey, hash, signature);
|
|
172
127
|
} else if (dilithium.verifyWithContext) {
|
|
@@ -179,23 +134,17 @@ export class PQCWallet {
|
|
|
179
134
|
|
|
180
135
|
/**
|
|
181
136
|
* Get public key as hex string
|
|
182
|
-
* @returns {
|
|
137
|
+
* @returns {string} Public key (hex)
|
|
183
138
|
*/
|
|
184
|
-
|
|
185
|
-
if (!this.publicKey) {
|
|
186
|
-
await this._ensureKeyPair();
|
|
187
|
-
}
|
|
139
|
+
getPublicKeyHex() {
|
|
188
140
|
return ethers.hexlify(this.publicKey);
|
|
189
141
|
}
|
|
190
142
|
|
|
191
143
|
/**
|
|
192
144
|
* Get secret key as hex string (use with caution!)
|
|
193
|
-
* @returns {
|
|
145
|
+
* @returns {string} Secret key (hex)
|
|
194
146
|
*/
|
|
195
|
-
|
|
196
|
-
if (!this.secretKey) {
|
|
197
|
-
await this._ensureKeyPair();
|
|
198
|
-
}
|
|
147
|
+
getSecretKeyHex() {
|
|
199
148
|
return ethers.hexlify(this.secretKey);
|
|
200
149
|
}
|
|
201
150
|
}
|
|
@@ -203,36 +152,17 @@ export class PQCWallet {
|
|
|
203
152
|
/**
|
|
204
153
|
* Hybrid Wallet (ECDSA + PQC)
|
|
205
154
|
*/
|
|
206
|
-
|
|
155
|
+
class HybridWallet {
|
|
207
156
|
constructor(ecdsaWallet, pqcWallet) {
|
|
208
157
|
if (!ecdsaWallet || !pqcWallet) {
|
|
209
158
|
throw new Error('Both ECDSA and PQC wallets are required for Hybrid wallet');
|
|
210
159
|
}
|
|
211
160
|
this.ecdsaWallet = ecdsaWallet instanceof ECDSAWallet ? ecdsaWallet : new ECDSAWallet(ecdsaWallet);
|
|
212
161
|
this.pqcWallet = pqcWallet instanceof PQCWallet ? pqcWallet : new PQCWallet();
|
|
213
|
-
// Address will be computed when PQC wallet is ready
|
|
214
|
-
this.address = null;
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
/**
|
|
218
|
-
* Get the hybrid address (computed from ECDSA + PQC public keys)
|
|
219
|
-
* @returns {Promise<string>} Hybrid address
|
|
220
|
-
*/
|
|
221
|
-
async getAddress() {
|
|
222
|
-
if (this.address) {
|
|
223
|
-
return this.address;
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
// Ensure PQC wallet has keys
|
|
227
|
-
if (!this.pqcWallet.publicKey) {
|
|
228
|
-
await this.pqcWallet._ensureKeyPair();
|
|
229
|
-
}
|
|
230
|
-
|
|
231
162
|
this.address = deriveHybridAddress(
|
|
232
163
|
ethers.getBytes(this.ecdsaWallet.getPublicKey()),
|
|
233
164
|
this.pqcWallet.publicKey
|
|
234
165
|
);
|
|
235
|
-
return this.address;
|
|
236
166
|
}
|
|
237
167
|
|
|
238
168
|
/**
|
|
@@ -245,12 +175,7 @@ export class HybridWallet {
|
|
|
245
175
|
static fromKeys(ecdsaPrivateKey, pqcSecretKey, pqcPublicKey) {
|
|
246
176
|
const ecdsaWallet = new ECDSAWallet(ecdsaPrivateKey);
|
|
247
177
|
const pqcWallet = new PQCWallet(pqcSecretKey, pqcPublicKey);
|
|
248
|
-
|
|
249
|
-
wallet.address = deriveHybridAddress(
|
|
250
|
-
ethers.getBytes(ecdsaWallet.getPublicKey()),
|
|
251
|
-
pqcWallet.publicKey
|
|
252
|
-
);
|
|
253
|
-
return wallet;
|
|
178
|
+
return new HybridWallet(ecdsaWallet, pqcWallet);
|
|
254
179
|
}
|
|
255
180
|
|
|
256
181
|
/**
|
|
@@ -263,3 +188,9 @@ export class HybridWallet {
|
|
|
263
188
|
return new HybridWallet(connectedECDSA, this.pqcWallet);
|
|
264
189
|
}
|
|
265
190
|
}
|
|
191
|
+
|
|
192
|
+
module.exports = {
|
|
193
|
+
ECDSAWallet,
|
|
194
|
+
PQCWallet,
|
|
195
|
+
HybridWallet,
|
|
196
|
+
};
|
package/src/zk-transaction.js
CHANGED
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
* Zero-Knowledge Proof Transaction Support
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
const { ethers } = require('ethers');
|
|
6
|
+
const { TX_TYPE, ZK_PROOF_SYSTEM } = require('./constants.js');
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* ZK Transaction Builder
|
|
10
10
|
* Creates transactions with zero-knowledge proofs
|
|
11
11
|
*/
|
|
12
|
-
|
|
12
|
+
class ZKTransaction {
|
|
13
13
|
constructor(params) {
|
|
14
14
|
this.type = TX_TYPE.ZK_PRIVATE;
|
|
15
15
|
this.chainId = params.chainId || 1337;
|
|
@@ -93,3 +93,7 @@ export class ZKTransaction {
|
|
|
93
93
|
return await provider.send('quorum_sendZKTransaction', [args]);
|
|
94
94
|
}
|
|
95
95
|
}
|
|
96
|
+
|
|
97
|
+
module.exports = {
|
|
98
|
+
ZKTransaction,
|
|
99
|
+
};
|
package/index.cjs
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* CommonJS entry point for @cheny56/node-client
|
|
3
|
-
*
|
|
4
|
-
* NOTE: This library is built as ES modules. For CommonJS compatibility,
|
|
5
|
-
* you need to use dynamic import() instead of require().
|
|
6
|
-
*
|
|
7
|
-
* Example:
|
|
8
|
-
* const { QuorumProvider } = await import('@cheny56/node-client');
|
|
9
|
-
*
|
|
10
|
-
* Or use ES modules in your project:
|
|
11
|
-
* import { QuorumProvider } from '@cheny56/node-client';
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
// Re-export using dynamic import
|
|
15
|
-
// This allows require() to work, but returns a Promise
|
|
16
|
-
const modPromise = import('./src/index.js');
|
|
17
|
-
|
|
18
|
-
// For synchronous require(), we need to throw a helpful error
|
|
19
|
-
// and suggest using import() or ES modules
|
|
20
|
-
module.exports = new Proxy({}, {
|
|
21
|
-
get(target, prop) {
|
|
22
|
-
if (prop === 'then' || prop === 'catch' || prop === 'finally') {
|
|
23
|
-
// Make it thenable so it works with await import()
|
|
24
|
-
return modPromise.then(mod => mod[prop]).bind(modPromise);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
throw new Error(
|
|
28
|
-
`Cannot access '${prop}' synchronously. ` +
|
|
29
|
-
`This package uses ES modules. Please use:\n` +
|
|
30
|
-
` const { ${prop} } = await import('@cheny56/node-client');\n` +
|
|
31
|
-
`Or switch your project to ES modules by adding "type": "module" to package.json`
|
|
32
|
-
);
|
|
33
|
-
}
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
// Also export as a Promise for await import() usage
|
|
37
|
-
module.exports.default = modPromise;
|