@cheny56/node-client 1.0.8 → 1.0.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/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 +39 -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.9",
|
|
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,19 @@ 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
|
-
this.
|
|
94
|
-
|
|
95
|
-
this.address = null; // Will be set after key generation
|
|
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 typically uses keygen() or generateKeyPair()
|
|
72
|
+
const keyPair = dilithium.keygen ? dilithium.keygen() : dilithium.generateKeyPair();
|
|
73
|
+
this.secretKey = keyPair.secretKey || keyPair.privateKey;
|
|
74
|
+
this.publicKey = keyPair.publicKey;
|
|
104
75
|
}
|
|
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
76
|
this.address = derivePQCAddress(this.publicKey);
|
|
112
|
-
this._keyPairGenerated = true;
|
|
113
77
|
}
|
|
114
78
|
|
|
115
79
|
/**
|
|
@@ -126,24 +90,17 @@ export class PQCWallet {
|
|
|
126
90
|
}
|
|
127
91
|
const secret = secretKey instanceof Uint8Array ? secretKey : ethers.getBytes(secretKey);
|
|
128
92
|
const pub = publicKey instanceof Uint8Array ? publicKey : ethers.getBytes(publicKey);
|
|
129
|
-
|
|
130
|
-
wallet.address = derivePQCAddress(wallet.publicKey);
|
|
131
|
-
wallet._keyPairGenerated = true;
|
|
132
|
-
return wallet;
|
|
93
|
+
return new PQCWallet(secret, pub);
|
|
133
94
|
}
|
|
134
95
|
|
|
135
96
|
/**
|
|
136
97
|
* Sign a message hash
|
|
137
98
|
* @param {Uint8Array} hash - Message hash (32 bytes)
|
|
138
|
-
* @returns {
|
|
99
|
+
* @returns {Uint8Array} Signature
|
|
139
100
|
*/
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
const dilithium = await getDilithium();
|
|
146
|
-
// dilithium-crystals API: sign(secretKey, message) or signWithContext(secretKey, message, ctx)
|
|
101
|
+
sign(hash) {
|
|
102
|
+
// dilithium-crystals API: sign(secretKey, message)
|
|
103
|
+
// Some implementations may require context, but we'll try without first
|
|
147
104
|
if (dilithium.sign) {
|
|
148
105
|
return dilithium.sign(this.secretKey, hash);
|
|
149
106
|
} else if (dilithium.signWithContext) {
|
|
@@ -158,15 +115,10 @@ export class PQCWallet {
|
|
|
158
115
|
* Verify a signature
|
|
159
116
|
* @param {Uint8Array} hash - Message hash
|
|
160
117
|
* @param {Uint8Array} signature - Signature to verify
|
|
161
|
-
* @returns {
|
|
118
|
+
* @returns {boolean} True if signature is valid
|
|
162
119
|
*/
|
|
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
|
|
120
|
+
verify(hash, signature) {
|
|
121
|
+
// dilithium-crystals API: verify(publicKey, message, signature)
|
|
170
122
|
if (dilithium.verify) {
|
|
171
123
|
return dilithium.verify(this.publicKey, hash, signature);
|
|
172
124
|
} else if (dilithium.verifyWithContext) {
|
|
@@ -179,23 +131,17 @@ export class PQCWallet {
|
|
|
179
131
|
|
|
180
132
|
/**
|
|
181
133
|
* Get public key as hex string
|
|
182
|
-
* @returns {
|
|
134
|
+
* @returns {string} Public key (hex)
|
|
183
135
|
*/
|
|
184
|
-
|
|
185
|
-
if (!this.publicKey) {
|
|
186
|
-
await this._ensureKeyPair();
|
|
187
|
-
}
|
|
136
|
+
getPublicKeyHex() {
|
|
188
137
|
return ethers.hexlify(this.publicKey);
|
|
189
138
|
}
|
|
190
139
|
|
|
191
140
|
/**
|
|
192
141
|
* Get secret key as hex string (use with caution!)
|
|
193
|
-
* @returns {
|
|
142
|
+
* @returns {string} Secret key (hex)
|
|
194
143
|
*/
|
|
195
|
-
|
|
196
|
-
if (!this.secretKey) {
|
|
197
|
-
await this._ensureKeyPair();
|
|
198
|
-
}
|
|
144
|
+
getSecretKeyHex() {
|
|
199
145
|
return ethers.hexlify(this.secretKey);
|
|
200
146
|
}
|
|
201
147
|
}
|
|
@@ -203,36 +149,17 @@ export class PQCWallet {
|
|
|
203
149
|
/**
|
|
204
150
|
* Hybrid Wallet (ECDSA + PQC)
|
|
205
151
|
*/
|
|
206
|
-
|
|
152
|
+
class HybridWallet {
|
|
207
153
|
constructor(ecdsaWallet, pqcWallet) {
|
|
208
154
|
if (!ecdsaWallet || !pqcWallet) {
|
|
209
155
|
throw new Error('Both ECDSA and PQC wallets are required for Hybrid wallet');
|
|
210
156
|
}
|
|
211
157
|
this.ecdsaWallet = ecdsaWallet instanceof ECDSAWallet ? ecdsaWallet : new ECDSAWallet(ecdsaWallet);
|
|
212
158
|
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
159
|
this.address = deriveHybridAddress(
|
|
232
160
|
ethers.getBytes(this.ecdsaWallet.getPublicKey()),
|
|
233
161
|
this.pqcWallet.publicKey
|
|
234
162
|
);
|
|
235
|
-
return this.address;
|
|
236
163
|
}
|
|
237
164
|
|
|
238
165
|
/**
|
|
@@ -245,12 +172,7 @@ export class HybridWallet {
|
|
|
245
172
|
static fromKeys(ecdsaPrivateKey, pqcSecretKey, pqcPublicKey) {
|
|
246
173
|
const ecdsaWallet = new ECDSAWallet(ecdsaPrivateKey);
|
|
247
174
|
const pqcWallet = new PQCWallet(pqcSecretKey, pqcPublicKey);
|
|
248
|
-
|
|
249
|
-
wallet.address = deriveHybridAddress(
|
|
250
|
-
ethers.getBytes(ecdsaWallet.getPublicKey()),
|
|
251
|
-
pqcWallet.publicKey
|
|
252
|
-
);
|
|
253
|
-
return wallet;
|
|
175
|
+
return new HybridWallet(ecdsaWallet, pqcWallet);
|
|
254
176
|
}
|
|
255
177
|
|
|
256
178
|
/**
|
|
@@ -263,3 +185,9 @@ export class HybridWallet {
|
|
|
263
185
|
return new HybridWallet(connectedECDSA, this.pqcWallet);
|
|
264
186
|
}
|
|
265
187
|
}
|
|
188
|
+
|
|
189
|
+
module.exports = {
|
|
190
|
+
ECDSAWallet,
|
|
191
|
+
PQCWallet,
|
|
192
|
+
HybridWallet,
|
|
193
|
+
};
|
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;
|