quantumcoin 7.0.3 → 7.0.5
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/.github/workflows/publish-npmjs.yaml +22 -22
- package/.gitignore +15 -15
- package/LICENSE +21 -21
- package/README-SDK.md +758 -754
- package/README.md +165 -150
- package/SPEC.md +3845 -3843
- package/config.d.ts +50 -50
- package/config.js +115 -115
- package/examples/AllSolidityTypes.sol +184 -184
- package/examples/SimpleIERC20.sol +74 -74
- package/examples/events.js +41 -35
- package/examples/events.ts +35 -0
- package/examples/example-generator-sdk-js.js +100 -95
- package/examples/example-generator-sdk-js.ts +77 -0
- package/examples/example-generator-sdk-ts.js +100 -95
- package/examples/example-generator-sdk-ts.ts +77 -0
- package/examples/example.js +72 -61
- package/examples/example.ts +61 -0
- package/examples/offline-signing.js +79 -73
- package/examples/offline-signing.ts +66 -0
- package/examples/package-lock.json +596 -57
- package/examples/package.json +32 -16
- package/examples/read-operations.js +32 -27
- package/examples/read-operations.ts +31 -0
- package/examples/sdk-generator-erc20.inline.json +251 -251
- package/examples/solidity-types.ts +43 -43
- package/examples/wallet-offline.js +35 -29
- package/examples/wallet-offline.ts +34 -0
- package/generate-sdk.js +1824 -1490
- package/index.js +12 -12
- package/package.json +95 -75
- package/scripts/copy-declarations.js +31 -0
- package/scripts/run-all-one-by-one.js +151 -0
- package/src/abi/fragments.d.ts +42 -42
- package/src/abi/fragments.js +63 -63
- package/src/abi/index.d.ts +13 -13
- package/src/abi/index.js +9 -9
- package/src/abi/interface.d.ts +128 -132
- package/src/abi/interface.js +590 -590
- package/src/abi/js-abi-coder.d.ts +8 -0
- package/src/abi/js-abi-coder.js +474 -474
- package/src/constants.d.ts +66 -61
- package/src/constants.js +101 -94
- package/src/contract/contract-factory.d.ts +28 -28
- package/src/contract/contract-factory.js +105 -105
- package/src/contract/contract.d.ts +113 -114
- package/src/contract/contract.js +354 -354
- package/src/contract/index.d.ts +9 -9
- package/src/contract/index.js +9 -9
- package/src/errors/index.d.ts +92 -92
- package/src/errors/index.js +188 -188
- package/src/generator/index.d.ts +74 -0
- package/src/generator/index.js +1404 -1404
- package/src/index.d.ts +125 -127
- package/src/index.js +41 -41
- package/src/internal/hex.d.ts +61 -61
- package/src/internal/hex.js +144 -144
- package/src/providers/extra-providers.d.ts +139 -128
- package/src/providers/extra-providers.js +600 -575
- package/src/providers/index.d.ts +17 -16
- package/src/providers/index.js +10 -10
- package/src/providers/json-rpc-provider.d.ts +12 -12
- package/src/providers/json-rpc-provider.js +79 -79
- package/src/providers/provider.d.ts +208 -203
- package/src/providers/provider.js +393 -371
- package/src/types/index.d.ts +214 -462
- package/src/types/index.js +9 -9
- package/src/utils/address.d.ts +72 -72
- package/src/utils/address.js +181 -182
- package/src/utils/encoding.d.ts +120 -120
- package/src/utils/encoding.js +306 -306
- package/src/utils/hashing.d.ts +82 -76
- package/src/utils/hashing.js +313 -298
- package/src/utils/index.d.ts +65 -55
- package/src/utils/index.js +13 -13
- package/src/utils/result.d.ts +57 -57
- package/src/utils/result.js +128 -128
- package/src/utils/rlp.d.ts +12 -12
- package/src/utils/rlp.js +200 -200
- package/src/utils/units.d.ts +29 -29
- package/src/utils/units.js +107 -107
- package/src/wallet/index.d.ts +10 -10
- package/src/wallet/index.js +8 -8
- package/src/wallet/wallet.d.ts +168 -160
- package/src/wallet/wallet.js +500 -489
- package/test/e2e/all-solidity-types.dynamic.test.js +207 -200
- package/test/e2e/all-solidity-types.dynamic.test.ts +191 -0
- package/test/e2e/all-solidity-types.fixtures.js +231 -231
- package/test/e2e/all-solidity-types.generated-sdks.e2e.test.js +387 -368
- package/test/e2e/all-solidity-types.generated-sdks.e2e.test.ts +350 -0
- package/test/e2e/helpers.js +59 -47
- package/test/e2e/signing-context-and-fee.e2e.test.js +141 -0
- package/test/e2e/signing-context-and-fee.e2e.test.ts +128 -0
- package/test/e2e/simple-erc20.generated-sdks.e2e.test.js +168 -151
- package/test/e2e/simple-erc20.generated-sdks.e2e.test.ts +141 -0
- package/test/e2e/transactional.test.js +245 -191
- package/test/e2e/transactional.test.ts +208 -0
- package/test/e2e/typed-generator.e2e.test.js +407 -404
- package/test/e2e/typed-generator.e2e.test.ts +337 -0
- package/test/fixtures/ConstructorParam.sol +23 -23
- package/test/fixtures/MultiContracts.sol +37 -37
- package/test/fixtures/SimpleStorage.sol +18 -18
- package/test/fixtures/StakingContract.abi.json +1 -1
- package/test/integration/ipc-provider.test.js +49 -44
- package/test/integration/ipc-provider.test.ts +44 -0
- package/test/integration/provider.test.js +88 -72
- package/test/integration/provider.test.ts +85 -0
- package/test/integration/ws-provider.test.js +41 -33
- package/test/integration/ws-provider.test.ts +38 -0
- package/test/security/malformed-input.test.js +37 -31
- package/test/security/malformed-input.test.ts +35 -0
- package/test/unit/_encrypted-output.txt +6 -0
- package/test/unit/_log-encrypted-jsons.js +45 -0
- package/test/unit/_write-keystore-fixture.js +16 -0
- package/test/unit/abi-interface.test.js +103 -98
- package/test/unit/abi-interface.test.ts +102 -0
- package/test/unit/address-wallet.test.js +392 -257
- package/test/unit/address-wallet.test.ts +379 -0
- package/test/unit/browser-provider.test.js +85 -82
- package/test/unit/browser-provider.test.ts +79 -0
- package/test/unit/contract.test.js +85 -82
- package/test/unit/contract.test.ts +83 -0
- package/test/unit/encoding-units-rlp.test.js +92 -89
- package/test/unit/encoding-units-rlp.test.ts +91 -0
- package/test/unit/errors.test.js +77 -74
- package/test/unit/errors.test.ts +76 -0
- package/test/unit/filter-by-blockhash.test.js +55 -52
- package/test/unit/filter-by-blockhash.test.ts +54 -0
- package/test/unit/fixtures/encrypted-keystores-48-32-36.js +9 -0
- package/test/unit/generate-contract-cli.test.js +42 -39
- package/test/unit/generate-contract-cli.test.ts +41 -0
- package/test/unit/generate-sdk-artifacts-json.test.js +113 -110
- package/test/unit/generate-sdk-artifacts-json.test.ts +110 -0
- package/test/unit/generator.test.js +102 -99
- package/test/unit/generator.test.ts +101 -0
- package/test/unit/hashing.test.js +68 -54
- package/test/unit/hashing.test.ts +67 -0
- package/test/unit/init.test.js +39 -36
- package/test/unit/init.test.ts +38 -0
- package/test/unit/interface.test.js +56 -53
- package/test/unit/interface.test.ts +54 -0
- package/test/unit/internal-hex.test.js +50 -47
- package/test/unit/internal-hex.test.ts +49 -0
- package/test/unit/populate-transaction.test.js +65 -62
- package/test/unit/populate-transaction.test.ts +64 -0
- package/test/unit/providers.test.js +200 -144
- package/test/unit/providers.test.ts +196 -0
- package/test/unit/result.test.js +80 -77
- package/test/unit/result.test.ts +79 -0
- package/test/unit/solidity-types.test.js +49 -46
- package/test/unit/solidity-types.test.ts +39 -0
- package/test/unit/utils.test.js +57 -54
- package/test/unit/utils.test.ts +56 -0
- package/test/verbose-logger.js +74 -0
- package/tsconfig.build.json +14 -0
package/src/wallet/wallet.js
CHANGED
|
@@ -1,489 +1,500 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview Wallet and signer implementations.
|
|
3
|
-
*
|
|
4
|
-
* The QuantumCoin.js wallet model mirrors ethers.js v6:
|
|
5
|
-
* - AbstractSigner -> BaseWallet -> Wallet
|
|
6
|
-
* - NonceManager wrapper
|
|
7
|
-
*
|
|
8
|
-
* Cryptographic operations are delegated to `quantum-coin-js-sdk
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
const
|
|
13
|
-
const
|
|
14
|
-
const {
|
|
15
|
-
const {
|
|
16
|
-
const {
|
|
17
|
-
const {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
* @param {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
);
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
}
|
|
226
|
-
const raw =
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
*
|
|
294
|
-
* @
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
*
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
*
|
|
316
|
-
* @
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
return
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
/**
|
|
336
|
-
* Creates a
|
|
337
|
-
* @param {
|
|
338
|
-
* @
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
*
|
|
351
|
-
* @param {
|
|
352
|
-
* @
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
//
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
this._nonce =
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
return
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
this._nonce
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
this.
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
this.
|
|
461
|
-
}
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
}
|
|
489
|
-
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Wallet and signer implementations.
|
|
3
|
+
*
|
|
4
|
+
* The QuantumCoin.js wallet model mirrors ethers.js v6:
|
|
5
|
+
* - AbstractSigner -> BaseWallet -> Wallet
|
|
6
|
+
* - NonceManager wrapper
|
|
7
|
+
*
|
|
8
|
+
* Cryptographic operations are delegated to `quantum-coin-js-sdk`.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
const qcsdk = require("quantum-coin-js-sdk");
|
|
12
|
+
const { JsonRpcProvider } = require("../providers/json-rpc-provider");
|
|
13
|
+
const { assertArgument, makeError } = require("../errors");
|
|
14
|
+
const { arrayify, bytesToHex, hexToBytes, isHexString, normalizeHex } = require("../internal/hex");
|
|
15
|
+
const { hashMessage } = require("../utils/hashing");
|
|
16
|
+
const { getAddress } = require("../utils/address");
|
|
17
|
+
const { WeiPerEther } = require("../constants");
|
|
18
|
+
|
|
19
|
+
function _requireInitialized() {
|
|
20
|
+
// eslint-disable-next-line global-require
|
|
21
|
+
const { isInitialized } = require("../../config");
|
|
22
|
+
if (!isInitialized()) {
|
|
23
|
+
throw makeError("QuantumCoin SDK not initialized. Call Initialize() first.", "UNKNOWN_ERROR", { operation: "wallet" });
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function _bytesToNumberArray(bytes) {
|
|
28
|
+
return Array.from(bytes);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* SigningKey wrapper (PQC private/public key bytes).
|
|
33
|
+
*/
|
|
34
|
+
class SigningKey {
|
|
35
|
+
/**
|
|
36
|
+
* @param {Uint8Array} privateKeyBytes
|
|
37
|
+
* @param {Uint8Array} publicKeyBytes
|
|
38
|
+
*/
|
|
39
|
+
constructor(privateKeyBytes, publicKeyBytes) {
|
|
40
|
+
this.privateKeyBytes = new Uint8Array(privateKeyBytes);
|
|
41
|
+
this.publicKeyBytes = new Uint8Array(publicKeyBytes);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* AbstractSigner base (minimal).
|
|
47
|
+
*/
|
|
48
|
+
class AbstractSigner {
|
|
49
|
+
/**
|
|
50
|
+
* @param {import("../providers/provider").AbstractProvider|null} provider
|
|
51
|
+
*/
|
|
52
|
+
constructor(provider) {
|
|
53
|
+
this.provider = provider || null;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
async getAddress() {
|
|
57
|
+
throw makeError("getAddress not implemented", "NOT_IMPLEMENTED", {});
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* BaseWallet - core signing implementation.
|
|
63
|
+
*/
|
|
64
|
+
class BaseWallet extends AbstractSigner {
|
|
65
|
+
/**
|
|
66
|
+
* @param {SigningKey} signingKey
|
|
67
|
+
* @param {import("../providers/provider").AbstractProvider|null=} provider
|
|
68
|
+
* @param {{ address: string }=} precomputed
|
|
69
|
+
* @param {any=} qcWallet Internal quantum-coin-js-sdk Wallet (optional)
|
|
70
|
+
*/
|
|
71
|
+
constructor(signingKey, provider, precomputed, qcWallet) {
|
|
72
|
+
super(provider || null);
|
|
73
|
+
_requireInitialized();
|
|
74
|
+
this.signingKey = signingKey;
|
|
75
|
+
this._qcWallet = qcWallet || null;
|
|
76
|
+
|
|
77
|
+
/** @type {string} */
|
|
78
|
+
this.address = precomputed?.address || "";
|
|
79
|
+
|
|
80
|
+
Object.defineProperty(this, "privateKey", {
|
|
81
|
+
enumerable: true,
|
|
82
|
+
get: () => bytesToHex(this.signingKey.privateKeyBytes),
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
async getAddress() {
|
|
87
|
+
return this.address;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Sign a message synchronously.
|
|
92
|
+
* Signature format: combined publicKey+signature as a hex string.
|
|
93
|
+
* @param {string|Uint8Array} message
|
|
94
|
+
* @returns {string}
|
|
95
|
+
*/
|
|
96
|
+
signMessageSync(message) {
|
|
97
|
+
_requireInitialized();
|
|
98
|
+
const digestHex = hashMessage(message);
|
|
99
|
+
const digest = hexToBytes(digestHex);
|
|
100
|
+
const signResult = qcsdk.sign(this.signingKey.privateKeyBytes, digest, null);
|
|
101
|
+
if (signResult.resultCode !== 0) {
|
|
102
|
+
throw makeError("sign failed", "UNKNOWN_ERROR", { resultCode: signResult.resultCode });
|
|
103
|
+
}
|
|
104
|
+
const sigBytes = signResult.signature;
|
|
105
|
+
if (!sigBytes) throw makeError("sign returned no signature", "UNKNOWN_ERROR", {});
|
|
106
|
+
const sigArr = Array.from(sigBytes instanceof Uint8Array ? sigBytes : sigBytes);
|
|
107
|
+
let combined = qcsdk.combinePublicKeySignature(
|
|
108
|
+
_bytesToNumberArray(this.signingKey.publicKeyBytes),
|
|
109
|
+
sigArr,
|
|
110
|
+
);
|
|
111
|
+
if (combined != null && typeof combined === "object") {
|
|
112
|
+
if (typeof combined.String === "function") combined = combined.String();
|
|
113
|
+
else if (combined instanceof Uint8Array) combined = bytesToHex(combined);
|
|
114
|
+
else if (Array.isArray(combined)) combined = bytesToHex(new Uint8Array(combined));
|
|
115
|
+
else if (typeof combined.length === "number" && combined.length >= 0) combined = bytesToHex(new Uint8Array(Array.from(combined)));
|
|
116
|
+
}
|
|
117
|
+
if (combined == null || typeof combined !== "string") {
|
|
118
|
+
throw makeError("combinePublicKeySignature failed (SDK may not support this key type for message signing)", "UNKNOWN_ERROR", {
|
|
119
|
+
combinedType: typeof combined,
|
|
120
|
+
sigLength: sigArr.length,
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
return normalizeHex(combined);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Sign a transaction using quantum-coin-js-sdk signRawTransaction().
|
|
128
|
+
* @param {import("../providers/provider").TransactionRequest} tx
|
|
129
|
+
* @returns {Promise<string>}
|
|
130
|
+
*/
|
|
131
|
+
async signTransaction(tx) {
|
|
132
|
+
_requireInitialized();
|
|
133
|
+
assertArgument(tx && typeof tx === "object", "invalid tx", "tx", tx);
|
|
134
|
+
|
|
135
|
+
const toAddress = tx.to == null ? null : getAddress(tx.to);
|
|
136
|
+
const valueInWei =
|
|
137
|
+
tx.value == null
|
|
138
|
+
? 0n
|
|
139
|
+
: typeof tx.value === "bigint"
|
|
140
|
+
? tx.value
|
|
141
|
+
: typeof tx.value === "number"
|
|
142
|
+
? BigInt(tx.value)
|
|
143
|
+
: typeof tx.value === "string"
|
|
144
|
+
? BigInt(tx.value.startsWith("0x") ? tx.value : tx.value)
|
|
145
|
+
: 0n;
|
|
146
|
+
|
|
147
|
+
const gasLimit =
|
|
148
|
+
tx.gasLimit == null
|
|
149
|
+
? 21000
|
|
150
|
+
: typeof tx.gasLimit === "bigint"
|
|
151
|
+
? Number(tx.gasLimit)
|
|
152
|
+
: typeof tx.gasLimit === "number"
|
|
153
|
+
? tx.gasLimit
|
|
154
|
+
: typeof tx.gasLimit === "string"
|
|
155
|
+
? Number(BigInt(tx.gasLimit))
|
|
156
|
+
: 21000;
|
|
157
|
+
|
|
158
|
+
const data = tx.data == null ? null : normalizeHex(tx.data);
|
|
159
|
+
const remarks = tx.remarks == null ? null : normalizeHex(tx.remarks);
|
|
160
|
+
|
|
161
|
+
if (remarks != null) {
|
|
162
|
+
assertArgument(isHexString(remarks), "remarks must be hex string", "remarks", remarks);
|
|
163
|
+
const remarkBytes = hexToBytes(remarks);
|
|
164
|
+
assertArgument(remarkBytes.length <= 32, "remarks too long (max 32 bytes)", "remarks", remarks);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// Nonce must be provided or resolved from provider.
|
|
168
|
+
let nonce = tx.nonce;
|
|
169
|
+
if (nonce == null) {
|
|
170
|
+
if (!this.provider) throw makeError("missing provider to resolve nonce", "UNKNOWN_ERROR", { operation: "signTransaction" });
|
|
171
|
+
// Prefer pending to avoid nonce collisions with in-flight transactions.
|
|
172
|
+
try {
|
|
173
|
+
nonce = await this.provider.getTransactionCount(this.address, "pending");
|
|
174
|
+
} catch {
|
|
175
|
+
nonce = await this.provider.getTransactionCount(this.address, "latest");
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
assertArgument(Number.isInteger(nonce) && nonce >= 0, "invalid nonce", "nonce", nonce);
|
|
179
|
+
|
|
180
|
+
const chainId = tx.chainId != null ? tx.chainId : (this.provider && this.provider.chainId != null ? this.provider.chainId : null);
|
|
181
|
+
const signingContext = tx.signingContext ?? null;
|
|
182
|
+
|
|
183
|
+
/** @type {any} */
|
|
184
|
+
const qcWallet =
|
|
185
|
+
this._qcWallet ||
|
|
186
|
+
new qcsdk.Wallet(
|
|
187
|
+
this.address,
|
|
188
|
+
_bytesToNumberArray(this.signingKey.privateKeyBytes),
|
|
189
|
+
_bytesToNumberArray(this.signingKey.publicKeyBytes),
|
|
190
|
+
);
|
|
191
|
+
|
|
192
|
+
const req = new qcsdk.TransactionSigningRequest(
|
|
193
|
+
qcWallet,
|
|
194
|
+
toAddress,
|
|
195
|
+
valueInWei,
|
|
196
|
+
nonce,
|
|
197
|
+
data,
|
|
198
|
+
gasLimit,
|
|
199
|
+
remarks,
|
|
200
|
+
chainId,
|
|
201
|
+
signingContext,
|
|
202
|
+
);
|
|
203
|
+
const signResult = qcsdk.signRawTransaction(req);
|
|
204
|
+
// quantum-coin-js-sdk returns a SignResult object: { resultCode, txnHash, txnData }
|
|
205
|
+
if (!signResult || typeof signResult !== "object") {
|
|
206
|
+
throw makeError("signRawTransaction failed", "UNKNOWN_ERROR", {});
|
|
207
|
+
}
|
|
208
|
+
if (typeof signResult.resultCode === "number" && signResult.resultCode !== 0) {
|
|
209
|
+
throw makeError("signRawTransaction failed", "UNKNOWN_ERROR", {
|
|
210
|
+
resultCode: signResult.resultCode,
|
|
211
|
+
hash: signResult.txnHash || null,
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
const raw = signResult.txnData;
|
|
215
|
+
if (typeof raw !== "string") throw makeError("signRawTransaction did not return txnData", "UNKNOWN_ERROR", {});
|
|
216
|
+
return normalizeHex(raw);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Signs and sends a transaction.
|
|
221
|
+
* @param {import("../providers/provider").TransactionRequest} tx
|
|
222
|
+
* @returns {Promise<import("../providers/provider").TransactionResponse>}
|
|
223
|
+
*/
|
|
224
|
+
async sendTransaction(tx) {
|
|
225
|
+
if (!this.provider) throw makeError("missing provider", "UNKNOWN_ERROR", { operation: "sendTransaction" });
|
|
226
|
+
const raw = await this.signTransaction({ ...tx, from: this.address });
|
|
227
|
+
return this.provider.sendTransaction(raw);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Wallet - convenience methods around BaseWallet.
|
|
233
|
+
*/
|
|
234
|
+
class Wallet extends BaseWallet {
|
|
235
|
+
/**
|
|
236
|
+
* @param {string|Uint8Array|SigningKey} key
|
|
237
|
+
* @param {import("../providers/provider").AbstractProvider=} provider
|
|
238
|
+
*/
|
|
239
|
+
constructor(key, provider) {
|
|
240
|
+
_requireInitialized();
|
|
241
|
+
|
|
242
|
+
let signingKey;
|
|
243
|
+
let qcAddress;
|
|
244
|
+
|
|
245
|
+
if (key instanceof SigningKey) {
|
|
246
|
+
signingKey = key;
|
|
247
|
+
// Compute address from public key
|
|
248
|
+
const addr = qcsdk.addressFromPublicKey(_bytesToNumberArray(signingKey.publicKeyBytes));
|
|
249
|
+
if (typeof addr !== "string") throw makeError("addressFromPublicKey failed", "UNKNOWN_ERROR", {});
|
|
250
|
+
qcAddress = normalizeHex(addr);
|
|
251
|
+
} else {
|
|
252
|
+
const privBytes = typeof key === "string" ? hexToBytes(key) : arrayify(key);
|
|
253
|
+
const pubHex = qcsdk.publicKeyFromPrivateKey(_bytesToNumberArray(privBytes));
|
|
254
|
+
if (typeof pubHex !== "string") throw makeError("publicKeyFromPrivateKey failed", "UNKNOWN_ERROR", {});
|
|
255
|
+
const pubBytes = hexToBytes(pubHex);
|
|
256
|
+
const addr = qcsdk.addressFromPublicKey(_bytesToNumberArray(pubBytes));
|
|
257
|
+
if (typeof addr !== "string") throw makeError("addressFromPublicKey failed", "UNKNOWN_ERROR", {});
|
|
258
|
+
qcAddress = normalizeHex(addr);
|
|
259
|
+
signingKey = new SigningKey(privBytes, pubBytes);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/** @type {any} */
|
|
263
|
+
const qcWallet = new qcsdk.Wallet(
|
|
264
|
+
qcAddress,
|
|
265
|
+
_bytesToNumberArray(signingKey.privateKeyBytes),
|
|
266
|
+
_bytesToNumberArray(signingKey.publicKeyBytes),
|
|
267
|
+
);
|
|
268
|
+
|
|
269
|
+
super(signingKey, provider || null, { address: qcAddress }, qcWallet);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Returns wallet address (sync).
|
|
274
|
+
* @returns {string}
|
|
275
|
+
*/
|
|
276
|
+
getAddress() {
|
|
277
|
+
return this.address;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* Returns wallet balance.
|
|
282
|
+
* @param {string=} blockTag
|
|
283
|
+
* @returns {Promise<bigint>}
|
|
284
|
+
*/
|
|
285
|
+
async getBalance(blockTag) {
|
|
286
|
+
if (!this.provider) throw makeError("missing provider", "UNKNOWN_ERROR", { operation: "getBalance" });
|
|
287
|
+
void blockTag;
|
|
288
|
+
return this.provider.getBalance(this.address);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* Returns wallet nonce.
|
|
293
|
+
* @param {string=} blockTag
|
|
294
|
+
* @returns {Promise<number>}
|
|
295
|
+
*/
|
|
296
|
+
async getTransactionCount(blockTag) {
|
|
297
|
+
if (!this.provider) throw makeError("missing provider", "UNKNOWN_ERROR", { operation: "getTransactionCount" });
|
|
298
|
+
return this.provider.getTransactionCount(this.address, blockTag);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Encrypts and serializes this wallet to JSON.
|
|
303
|
+
* @param {string|Uint8Array} password
|
|
304
|
+
* @returns {string}
|
|
305
|
+
*/
|
|
306
|
+
encryptSync(password) {
|
|
307
|
+
_requireInitialized();
|
|
308
|
+
const pw = typeof password === "string" ? password : Buffer.from(arrayify(password)).toString("utf8");
|
|
309
|
+
const json = qcsdk.serializeEncryptedWallet(this._qcWallet, pw);
|
|
310
|
+
if (typeof json !== "string") throw makeError("serializeEncryptedWallet failed", "UNKNOWN_ERROR", {});
|
|
311
|
+
return json;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* Returns a new wallet connected to a provider.
|
|
316
|
+
* @param {import("../providers/provider").AbstractProvider} provider
|
|
317
|
+
* @returns {Wallet}
|
|
318
|
+
*/
|
|
319
|
+
connect(provider) {
|
|
320
|
+
return new Wallet(this.signingKey, provider);
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* Creates a new random wallet.
|
|
325
|
+
* @param {import("../providers/provider").AbstractProvider=} provider
|
|
326
|
+
* @returns {Wallet}
|
|
327
|
+
*/
|
|
328
|
+
static createRandom(provider) {
|
|
329
|
+
_requireInitialized();
|
|
330
|
+
const qcWallet = qcsdk.newWallet();
|
|
331
|
+
if (!qcWallet) throw makeError("newWallet failed", "UNKNOWN_ERROR", {});
|
|
332
|
+
return Wallet._fromQcWallet(qcWallet, provider || null);
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* Creates a wallet from an encrypted JSON string.
|
|
337
|
+
* @param {string} json
|
|
338
|
+
* @param {string} password
|
|
339
|
+
* @param {import("../providers/provider").AbstractProvider=} provider
|
|
340
|
+
* @returns {Wallet}
|
|
341
|
+
*/
|
|
342
|
+
static fromEncryptedJsonSync(json, password, provider) {
|
|
343
|
+
_requireInitialized();
|
|
344
|
+
const qcWallet = qcsdk.deserializeEncryptedWallet(json, password);
|
|
345
|
+
if (!qcWallet) throw makeError("deserializeEncryptedWallet failed", "UNKNOWN_ERROR", {});
|
|
346
|
+
return Wallet._fromQcWallet(qcWallet, provider || null);
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* Creates a wallet from a seed phrase (32, 36, or 48 words).
|
|
351
|
+
* @param {string|string[]} phrase
|
|
352
|
+
* @param {import("../providers/provider").AbstractProvider=} provider
|
|
353
|
+
* @returns {Wallet}
|
|
354
|
+
*/
|
|
355
|
+
static fromPhrase(phrase, provider) {
|
|
356
|
+
_requireInitialized();
|
|
357
|
+
let words = phrase;
|
|
358
|
+
if (typeof phrase === "string") {
|
|
359
|
+
words = phrase
|
|
360
|
+
.split(/[,\s]+/g)
|
|
361
|
+
.map((w) => w.trim())
|
|
362
|
+
.filter(Boolean);
|
|
363
|
+
}
|
|
364
|
+
assertArgument(Array.isArray(words), "phrase must be a string or string[]", "phrase", phrase);
|
|
365
|
+
const allowedLengths = [32, 36, 48];
|
|
366
|
+
assertArgument(
|
|
367
|
+
allowedLengths.includes(words.length),
|
|
368
|
+
"seed phrase must contain 32, 36, or 48 words",
|
|
369
|
+
"phrase",
|
|
370
|
+
words.length,
|
|
371
|
+
);
|
|
372
|
+
const qcWallet = qcsdk.openWalletFromSeedWords(words);
|
|
373
|
+
if (!qcWallet) throw makeError("openWalletFromSeedWords failed", "UNKNOWN_ERROR", {});
|
|
374
|
+
return Wallet._fromQcWallet(qcWallet, provider || null);
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
/**
|
|
378
|
+
* Creates a wallet from raw private and public key bytes.
|
|
379
|
+
* @param {Uint8Array|string} privateKey Private key bytes or hex string
|
|
380
|
+
* @param {Uint8Array|string} publicKey Public key bytes or hex string
|
|
381
|
+
* @param {import("../providers/provider").AbstractProvider=} provider
|
|
382
|
+
* @returns {Wallet}
|
|
383
|
+
*/
|
|
384
|
+
static fromKeys(privateKey, publicKey, provider) {
|
|
385
|
+
_requireInitialized();
|
|
386
|
+
const privBytes = typeof privateKey === "string" ? hexToBytes(privateKey) : arrayify(privateKey);
|
|
387
|
+
const pubBytes = typeof publicKey === "string" ? hexToBytes(publicKey) : arrayify(publicKey);
|
|
388
|
+
assertArgument(privBytes.length > 0, "privateKey must not be empty", "privateKey", privateKey);
|
|
389
|
+
assertArgument(pubBytes.length > 0, "publicKey must not be empty", "publicKey", publicKey);
|
|
390
|
+
const key = new SigningKey(privBytes, pubBytes);
|
|
391
|
+
return new Wallet(key, provider || null);
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
/**
|
|
395
|
+
* Internal helper: build a Wallet from a quantum-coin-js-sdk Wallet object.
|
|
396
|
+
* @param {any} qcWallet
|
|
397
|
+
* @param {import("../providers/provider").AbstractProvider|null} provider
|
|
398
|
+
* @returns {Wallet}
|
|
399
|
+
*/
|
|
400
|
+
static _fromQcWallet(qcWallet, provider) {
|
|
401
|
+
// Preserve key material from quantum-coin-js-sdk Wallet.
|
|
402
|
+
// newWallet() returns Uint8Array keys; other constructors may return number[].
|
|
403
|
+
const privSrc = qcWallet.privateKey;
|
|
404
|
+
const pubSrc = qcWallet.publicKey;
|
|
405
|
+
|
|
406
|
+
const privBytes =
|
|
407
|
+
privSrc instanceof Uint8Array ? new Uint8Array(privSrc) : Uint8Array.from(Array.from(privSrc || []).map((n) => (Number(n) & 0xff)));
|
|
408
|
+
const pubBytes =
|
|
409
|
+
pubSrc instanceof Uint8Array ? new Uint8Array(pubSrc) : Uint8Array.from(Array.from(pubSrc || []).map((n) => (Number(n) & 0xff)));
|
|
410
|
+
const key = new SigningKey(privBytes, pubBytes);
|
|
411
|
+
|
|
412
|
+
const w = new Wallet(key, provider || null);
|
|
413
|
+
// Ensure we keep the exact underlying qcWallet for operations like encrypt/signRawTransaction.
|
|
414
|
+
w._qcWallet = qcWallet;
|
|
415
|
+
if (typeof qcWallet.address === "string") {
|
|
416
|
+
w.address = normalizeHex(qcWallet.address);
|
|
417
|
+
}
|
|
418
|
+
return w;
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
/**
|
|
423
|
+
* NonceManager wrapper.
|
|
424
|
+
*/
|
|
425
|
+
class NonceManager extends AbstractSigner {
|
|
426
|
+
/**
|
|
427
|
+
* @param {AbstractSigner} signer
|
|
428
|
+
*/
|
|
429
|
+
constructor(signer) {
|
|
430
|
+
super(signer.provider || null);
|
|
431
|
+
this.signer = signer;
|
|
432
|
+
this._nonce = null;
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
async getAddress() {
|
|
436
|
+
return this.signer.getAddress();
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
async getTransactionCount(blockTag) {
|
|
440
|
+
if (this._nonce != null) return this._nonce;
|
|
441
|
+
if (!this.provider) throw makeError("missing provider", "UNKNOWN_ERROR", { operation: "getTransactionCount" });
|
|
442
|
+
const address = await this.getAddress();
|
|
443
|
+
this._nonce = await this.provider.getTransactionCount(address, blockTag);
|
|
444
|
+
return this._nonce;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
async sendTransaction(tx) {
|
|
448
|
+
const nonce = await this.getTransactionCount("latest");
|
|
449
|
+
const result = await this.signer.sendTransaction({ ...tx, nonce });
|
|
450
|
+
this._nonce = nonce + 1;
|
|
451
|
+
return result;
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
reset() {
|
|
455
|
+
this._nonce = null;
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
increment() {
|
|
459
|
+
if (this._nonce == null) this._nonce = 0;
|
|
460
|
+
this._nonce++;
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
/**
|
|
465
|
+
* JsonRpcSigner placeholder (ethers-like).
|
|
466
|
+
* This SDK encourages using Wallet directly for signing.
|
|
467
|
+
*/
|
|
468
|
+
class JsonRpcSigner extends AbstractSigner {
|
|
469
|
+
constructor(provider, address) {
|
|
470
|
+
super(provider);
|
|
471
|
+
this._address = address;
|
|
472
|
+
}
|
|
473
|
+
async getAddress() {
|
|
474
|
+
return this._address;
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
/**
|
|
479
|
+
* VoidSigner (cannot sign, only provides address).
|
|
480
|
+
*/
|
|
481
|
+
class VoidSigner extends AbstractSigner {
|
|
482
|
+
constructor(address, provider) {
|
|
483
|
+
super(provider || null);
|
|
484
|
+
this._address = getAddress(address);
|
|
485
|
+
}
|
|
486
|
+
async getAddress() {
|
|
487
|
+
return this._address;
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
module.exports = {
|
|
492
|
+
SigningKey,
|
|
493
|
+
AbstractSigner,
|
|
494
|
+
BaseWallet,
|
|
495
|
+
Wallet,
|
|
496
|
+
NonceManager,
|
|
497
|
+
JsonRpcSigner,
|
|
498
|
+
VoidSigner,
|
|
499
|
+
};
|
|
500
|
+
|