quantumcoin 7.0.10 → 7.0.11
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/README-SDK.md +0 -5
- package/README.md +1 -3
- package/SPEC.md +2 -63
- package/config.js +10 -2
- package/examples/example.js +0 -5
- package/examples/example.ts +0 -5
- package/examples/node_modules/.bin/esbuild +16 -0
- package/examples/node_modules/.bin/esbuild.cmd +17 -0
- package/examples/node_modules/.bin/esbuild.ps1 +28 -0
- package/examples/node_modules/.bin/sdkgen +16 -0
- package/examples/node_modules/.bin/sdkgen.cmd +17 -0
- package/examples/node_modules/.bin/sdkgen.ps1 +28 -0
- package/examples/node_modules/.bin/tsx +16 -0
- package/examples/node_modules/.bin/tsx.cmd +17 -0
- package/examples/node_modules/.bin/tsx.ps1 +28 -0
- package/examples/node_modules/.package-lock.json +235 -0
- package/examples/node_modules/@esbuild/win32-x64/README.md +3 -0
- package/examples/node_modules/@esbuild/win32-x64/esbuild.exe +0 -0
- package/examples/node_modules/@esbuild/win32-x64/package.json +20 -0
- package/examples/node_modules/esbuild/LICENSE.md +21 -0
- package/examples/node_modules/esbuild/README.md +3 -0
- package/examples/node_modules/esbuild/bin/esbuild +223 -0
- package/examples/node_modules/esbuild/install.js +289 -0
- package/examples/node_modules/esbuild/lib/main.d.ts +716 -0
- package/examples/node_modules/esbuild/lib/main.js +2532 -0
- package/examples/node_modules/esbuild/package.json +49 -0
- package/examples/node_modules/get-tsconfig/LICENSE +21 -0
- package/examples/node_modules/get-tsconfig/README.md +235 -0
- package/examples/node_modules/get-tsconfig/dist/index.cjs +7 -0
- package/examples/node_modules/get-tsconfig/dist/index.d.cts +2088 -0
- package/examples/node_modules/get-tsconfig/dist/index.d.mts +2088 -0
- package/examples/node_modules/get-tsconfig/dist/index.mjs +7 -0
- package/examples/node_modules/get-tsconfig/package.json +46 -0
- package/examples/node_modules/quantum-coin-js-sdk/.github/workflows/publish-npmjs.yaml +22 -0
- package/examples/node_modules/quantum-coin-js-sdk/LICENSE +21 -0
- package/examples/node_modules/quantum-coin-js-sdk/LICENSE-wasm_exec.js.txt +30 -0
- package/examples/node_modules/quantum-coin-js-sdk/README.md +1665 -0
- package/examples/node_modules/quantum-coin-js-sdk/example/README.md +14 -0
- package/examples/node_modules/quantum-coin-js-sdk/example/conversion-example.js +19 -0
- package/examples/node_modules/quantum-coin-js-sdk/example/example-create-contract.js +396 -0
- package/examples/node_modules/quantum-coin-js-sdk/example/example-encode-decode-rlp.js +225 -0
- package/examples/node_modules/quantum-coin-js-sdk/example/example-event-pack-unpack.js +391 -0
- package/examples/node_modules/quantum-coin-js-sdk/example/example-misc.js +101 -0
- package/examples/node_modules/quantum-coin-js-sdk/example/example-rpc-send-signRawTransaction.js +318 -0
- package/examples/node_modules/quantum-coin-js-sdk/example/example-rpc-send.js +116 -0
- package/examples/node_modules/quantum-coin-js-sdk/example/example-send.js +70 -0
- package/examples/node_modules/quantum-coin-js-sdk/example/example-token-pack-unpack.js +961 -0
- package/examples/node_modules/quantum-coin-js-sdk/example/example-wallet-version4.js +35 -0
- package/examples/node_modules/quantum-coin-js-sdk/example/example-wallet.js +43 -0
- package/examples/node_modules/quantum-coin-js-sdk/example/example.js +405 -0
- package/examples/node_modules/quantum-coin-js-sdk/example/package-lock.json +134 -0
- package/examples/node_modules/quantum-coin-js-sdk/example/package.json +15 -0
- package/examples/node_modules/quantum-coin-js-sdk/index.d.ts +1024 -0
- package/examples/node_modules/quantum-coin-js-sdk/index.js +3062 -0
- package/examples/node_modules/quantum-coin-js-sdk/package.json +34 -0
- package/examples/node_modules/quantum-coin-js-sdk/tests/encrypted-32.json +1 -0
- package/examples/node_modules/quantum-coin-js-sdk/tests/encrypted-36.json +1 -0
- package/examples/node_modules/quantum-coin-js-sdk/tests/encrypted-48.json +1 -0
- package/examples/node_modules/quantum-coin-js-sdk/tests/generate-verify-vectors.js +91 -0
- package/examples/node_modules/quantum-coin-js-sdk/tests/non-transactional.preinit.test.js +41 -0
- package/examples/node_modules/quantum-coin-js-sdk/tests/non-transactional.test.js +686 -0
- package/examples/node_modules/quantum-coin-js-sdk/tests/sign-raw-keytype5-context-null.test.js +107 -0
- package/examples/node_modules/quantum-coin-js-sdk/tests/sign-raw-transaction.test.js +196 -0
- package/examples/node_modules/quantum-coin-js-sdk/tests/sign-verify.test.js +311 -0
- package/examples/node_modules/quantum-coin-js-sdk/tests/transactional.relay.test.js +131 -0
- package/examples/node_modules/quantum-coin-js-sdk/tests/transactional.rpc.test.js +103 -0
- package/examples/node_modules/quantum-coin-js-sdk/tests/verify-vectors.json +95035 -0
- package/examples/node_modules/quantum-coin-js-sdk/wasmBase64.d.ts +9 -0
- package/examples/node_modules/quantum-coin-js-sdk/wasmBase64.js +16 -0
- package/examples/node_modules/quantum-coin-js-sdk/wasm_exec.d.ts +0 -0
- package/examples/node_modules/quantum-coin-js-sdk/wasm_exec.js +587 -0
- package/examples/node_modules/resolve-pkg-maps/LICENSE +21 -0
- package/examples/node_modules/resolve-pkg-maps/README.md +216 -0
- package/examples/node_modules/resolve-pkg-maps/dist/index.cjs +1 -0
- package/examples/node_modules/resolve-pkg-maps/dist/index.d.cts +11 -0
- package/examples/node_modules/resolve-pkg-maps/dist/index.d.mts +11 -0
- package/examples/node_modules/resolve-pkg-maps/dist/index.mjs +1 -0
- package/examples/node_modules/resolve-pkg-maps/package.json +42 -0
- package/examples/node_modules/seed-words/.github/workflows/publish-npmjs.yaml +22 -0
- package/examples/node_modules/seed-words/BUILD.md +7 -0
- package/examples/node_modules/seed-words/LICENSE +121 -0
- package/examples/node_modules/seed-words/README.md +67 -0
- package/examples/node_modules/seed-words/dist/seedwords.d.ts +39 -0
- package/examples/node_modules/seed-words/package.json +27 -0
- package/examples/node_modules/seed-words/seedwords.js +315 -0
- package/examples/node_modules/seed-words/seedwords.txt +65536 -0
- package/examples/node_modules/seed-words/tsconfig.json +21 -0
- package/examples/node_modules/tsx/LICENSE +21 -0
- package/examples/node_modules/tsx/README.md +32 -0
- package/examples/node_modules/tsx/dist/cjs/api/index.cjs +1 -0
- package/examples/node_modules/tsx/dist/cjs/api/index.d.cts +35 -0
- package/examples/node_modules/tsx/dist/cjs/api/index.d.mts +35 -0
- package/examples/node_modules/tsx/dist/cjs/api/index.mjs +1 -0
- package/examples/node_modules/tsx/dist/cjs/index.cjs +1 -0
- package/examples/node_modules/tsx/dist/cjs/index.mjs +1 -0
- package/examples/node_modules/tsx/dist/cli.cjs +54 -0
- package/examples/node_modules/tsx/dist/cli.mjs +55 -0
- package/examples/node_modules/tsx/dist/client-BQVF1NaW.mjs +1 -0
- package/examples/node_modules/tsx/dist/client-D6NvIMSC.cjs +1 -0
- package/examples/node_modules/tsx/dist/esm/api/index.cjs +1 -0
- package/examples/node_modules/tsx/dist/esm/api/index.d.cts +35 -0
- package/examples/node_modules/tsx/dist/esm/api/index.d.mts +35 -0
- package/examples/node_modules/tsx/dist/esm/api/index.mjs +1 -0
- package/examples/node_modules/tsx/dist/esm/index.cjs +2 -0
- package/examples/node_modules/tsx/dist/esm/index.mjs +2 -0
- package/examples/node_modules/tsx/dist/get-pipe-path-BHW2eJdv.mjs +1 -0
- package/examples/node_modules/tsx/dist/get-pipe-path-BoR10qr8.cjs +1 -0
- package/examples/node_modules/tsx/dist/index-7AaEi15b.mjs +14 -0
- package/examples/node_modules/tsx/dist/index-BWFBUo6r.cjs +1 -0
- package/examples/node_modules/tsx/dist/index-gbaejti9.mjs +1 -0
- package/examples/node_modules/tsx/dist/index-gckBtVBf.cjs +14 -0
- package/examples/node_modules/tsx/dist/lexer-DQCqS3nf.mjs +3 -0
- package/examples/node_modules/tsx/dist/lexer-DgIbo0BU.cjs +3 -0
- package/examples/node_modules/tsx/dist/loader.cjs +1 -0
- package/examples/node_modules/tsx/dist/loader.mjs +1 -0
- package/examples/node_modules/tsx/dist/node-features-_8ZFwP_x.mjs +1 -0
- package/examples/node_modules/tsx/dist/node-features-roYmp9jK.cjs +1 -0
- package/examples/node_modules/tsx/dist/package-CeBgXWuR.mjs +1 -0
- package/examples/node_modules/tsx/dist/package-Dxt5kIHw.cjs +1 -0
- package/examples/node_modules/tsx/dist/patch-repl.cjs +1 -0
- package/examples/node_modules/tsx/dist/patch-repl.mjs +1 -0
- package/examples/node_modules/tsx/dist/preflight.cjs +1 -0
- package/examples/node_modules/tsx/dist/preflight.mjs +1 -0
- package/examples/node_modules/tsx/dist/register-2sWVXuRQ.cjs +1 -0
- package/examples/node_modules/tsx/dist/register-B7jrtLTO.mjs +1 -0
- package/examples/node_modules/tsx/dist/register-CFH5oNdT.mjs +4 -0
- package/examples/node_modules/tsx/dist/register-D46fvsV_.cjs +4 -0
- package/examples/node_modules/tsx/dist/repl.cjs +3 -0
- package/examples/node_modules/tsx/dist/repl.mjs +3 -0
- package/examples/node_modules/tsx/dist/require-D4F1Lv60.cjs +1 -0
- package/examples/node_modules/tsx/dist/require-DQxpCAr4.mjs +1 -0
- package/examples/node_modules/tsx/dist/suppress-warnings.cjs +1 -0
- package/examples/node_modules/tsx/dist/suppress-warnings.mjs +1 -0
- package/examples/node_modules/tsx/dist/temporary-directory-B83uKxJF.cjs +1 -0
- package/examples/node_modules/tsx/dist/temporary-directory-CwHp0_NW.mjs +1 -0
- package/examples/node_modules/tsx/dist/types-Cxp8y2TL.d.ts +5 -0
- package/examples/node_modules/tsx/package.json +68 -0
- package/examples/offline-signing.js +0 -2
- package/examples/offline-signing.ts +0 -1
- package/examples/package-lock.json +422 -73
- package/examples/package.json +1 -1
- package/examples/wallet-offline.js +1 -9
- package/examples/wallet-offline.ts +1 -9
- package/generate-sdk.js +4 -6
- package/package.json +2 -2
- package/src/abi/interface.js +13 -7
- package/src/abi/js-abi-coder.js +23 -18
- package/src/constants.d.ts +0 -5
- package/src/constants.js +0 -7
- package/src/contract/contract-factory.js +9 -3
- package/src/contract/contract.js +9 -3
- package/src/errors/index.js +12 -0
- package/src/index.d.ts +0 -3
- package/src/providers/extra-providers.js +20 -6
- package/src/providers/json-rpc-provider.js +15 -5
- package/src/providers/provider.d.ts +0 -2
- package/src/providers/provider.js +1 -3
- package/src/utils/address.d.ts +0 -14
- package/src/utils/address.js +12 -49
- package/src/utils/hashing.d.ts +0 -6
- package/src/utils/hashing.js +8 -23
- package/src/utils/index.d.ts +0 -3
- package/src/utils/rlp.js +7 -4
- package/src/wallet/wallet.d.ts +2 -13
- package/src/wallet/wallet.js +116 -97
- package/test/security/malformed-input.test.js +295 -1
- package/test/unit/address-wallet.test.js +188 -129
- package/test/unit/address-wallet.test.ts +187 -128
- package/test/unit/hashing.test.js +0 -11
- package/test/unit/hashing.test.ts +0 -11
- package/test/unit/providers.test.js +3 -1
- package/test/unit/providers.test.ts +3 -1
|
@@ -165,69 +165,6 @@ describe("Address + Wallet (offline)", () => {
|
|
|
165
165
|
assert.throws(() => qc.Wallet.fromKeys(new Uint8Array(1), new Uint8Array(0)), /publicKey must not be empty/);
|
|
166
166
|
});
|
|
167
167
|
|
|
168
|
-
it("fromKeys wallet can sign messages", async () => {
|
|
169
|
-
await Initialize(null);
|
|
170
|
-
const original = qc.Wallet.fromPhrase(TEST_SEED_WORDS);
|
|
171
|
-
const restored = qc.Wallet.fromKeys(
|
|
172
|
-
original.signingKey.privateKeyBytes,
|
|
173
|
-
original.signingKey.publicKeyBytes,
|
|
174
|
-
);
|
|
175
|
-
assert.equal(restored.address, original.address);
|
|
176
|
-
|
|
177
|
-
const msg = "fromKeys signing test";
|
|
178
|
-
const sig = restored.signMessageSync(msg);
|
|
179
|
-
assert.equal(typeof sig, "string");
|
|
180
|
-
assert.ok(sig.startsWith("0x"));
|
|
181
|
-
const recovered = qc.verifyMessage(msg, sig);
|
|
182
|
-
assert.equal(recovered, original.address.toLowerCase());
|
|
183
|
-
});
|
|
184
|
-
|
|
185
|
-
it("signMessageSync + verifyMessage roundtrip (known wallet)", async () => {
|
|
186
|
-
await Initialize(null);
|
|
187
|
-
const wallet = qc.Wallet.fromEncryptedJsonSync(TEST_WALLET_ENCRYPTED_JSON, TEST_WALLET_PASSPHRASE);
|
|
188
|
-
const sig = wallet.signMessageSync("Hello, QuantumCoin!");
|
|
189
|
-
assert.equal(typeof sig, "string");
|
|
190
|
-
assert.ok(sig.startsWith("0x"));
|
|
191
|
-
const recovered = qc.verifyMessage("Hello, QuantumCoin!", sig);
|
|
192
|
-
assert.equal(recovered, wallet.address.toLowerCase());
|
|
193
|
-
});
|
|
194
|
-
|
|
195
|
-
it("signMessageSync returns combined signature hex and verifyMessage roundtrip (fromPhrase wallet)", async () => {
|
|
196
|
-
await Initialize(null);
|
|
197
|
-
const wallet = qc.Wallet.fromPhrase(TEST_SEED_WORDS);
|
|
198
|
-
const msg = "test message";
|
|
199
|
-
const sig = wallet.signMessageSync(msg);
|
|
200
|
-
assert.equal(typeof sig, "string");
|
|
201
|
-
assert.ok(sig.startsWith("0x"));
|
|
202
|
-
assert.ok(sig.length > 4);
|
|
203
|
-
const recovered = qc.verifyMessage(msg, sig);
|
|
204
|
-
assert.equal(recovered, wallet.address.toLowerCase());
|
|
205
|
-
});
|
|
206
|
-
|
|
207
|
-
it("signMessageSync + verifyMessage roundtrip (32-word phrase wallet)", async () => {
|
|
208
|
-
await Initialize(null);
|
|
209
|
-
const wallet = qc.Wallet.fromPhrase(TEST_SEED_WORDS_32);
|
|
210
|
-
const msg = "hello 32";
|
|
211
|
-
const sig = wallet.signMessageSync(msg);
|
|
212
|
-
assert.equal(typeof sig, "string");
|
|
213
|
-
assert.ok(sig.startsWith("0x"));
|
|
214
|
-
const recovered = qc.verifyMessage(msg, sig);
|
|
215
|
-
assert.equal(recovered, wallet.address.toLowerCase());
|
|
216
|
-
assert.equal(recovered, TEST_SEED_ADDRESS_32.toLowerCase());
|
|
217
|
-
});
|
|
218
|
-
|
|
219
|
-
it("signMessageSync + verifyMessage roundtrip (36-word phrase wallet)", async () => {
|
|
220
|
-
await Initialize(null);
|
|
221
|
-
const wallet = qc.Wallet.fromPhrase(TEST_SEED_WORDS_36);
|
|
222
|
-
const msg = "hello 36";
|
|
223
|
-
const sig = wallet.signMessageSync(msg);
|
|
224
|
-
assert.equal(typeof sig, "string");
|
|
225
|
-
assert.ok(sig.startsWith("0x"));
|
|
226
|
-
const recovered = qc.verifyMessage(msg, sig);
|
|
227
|
-
assert.equal(recovered, wallet.address.toLowerCase());
|
|
228
|
-
assert.equal(recovered, TEST_SEED_ADDRESS_36.toLowerCase());
|
|
229
|
-
});
|
|
230
|
-
|
|
231
168
|
it("signTransaction works offline and returns raw tx hex", async () => {
|
|
232
169
|
await Initialize(null);
|
|
233
170
|
const wallet = qc.Wallet.fromEncryptedJsonSync(TEST_WALLET_ENCRYPTED_JSON, TEST_WALLET_PASSPHRASE);
|
|
@@ -387,22 +324,16 @@ describe("Address + Wallet (offline)", () => {
|
|
|
387
324
|
assert.equal(qc.isAddress(w.address), true);
|
|
388
325
|
});
|
|
389
326
|
|
|
390
|
-
it("createRandom(null, 3) creates wallet with keyType 3
|
|
327
|
+
it("createRandom(null, 3) creates wallet with keyType 3", async () => {
|
|
391
328
|
await Initialize(null);
|
|
392
329
|
const w = qc.Wallet.createRandom(undefined, 3);
|
|
393
330
|
assert.equal(qc.isAddress(w.address), true);
|
|
394
|
-
const sig = w.signMessageSync("kt3 test");
|
|
395
|
-
assert.ok(sig.startsWith("0x"));
|
|
396
|
-
assert.equal(qc.verifyMessage("kt3 test", sig), w.address.toLowerCase());
|
|
397
331
|
});
|
|
398
332
|
|
|
399
|
-
it("createRandom(null, 5) creates wallet with keyType 5
|
|
333
|
+
it("createRandom(null, 5) creates wallet with keyType 5", async () => {
|
|
400
334
|
await Initialize(null);
|
|
401
335
|
const w = qc.Wallet.createRandom(undefined, 5);
|
|
402
336
|
assert.equal(qc.isAddress(w.address), true);
|
|
403
|
-
const sig = w.signMessageSync("kt5 test");
|
|
404
|
-
assert.ok(sig.startsWith("0x"));
|
|
405
|
-
assert.equal(qc.verifyMessage("kt5 test", sig), w.address.toLowerCase());
|
|
406
337
|
});
|
|
407
338
|
|
|
408
339
|
it("createRandom(null, 3) signTransaction works offline", async () => {
|
|
@@ -444,70 +375,30 @@ describe("Address + Wallet (offline)", () => {
|
|
|
444
375
|
assert.throws(() => qc.Wallet.createRandom(undefined, 4), /keyType must be null, 3, or 5/);
|
|
445
376
|
});
|
|
446
377
|
|
|
447
|
-
// ---------------------------------------------------------------------------
|
|
448
|
-
// createRandomSeed
|
|
449
|
-
// ---------------------------------------------------------------------------
|
|
450
|
-
|
|
451
|
-
it("createRandomSeed() returns 32-word array (default keyType)", async () => {
|
|
452
|
-
await Initialize(null);
|
|
453
|
-
const words = qc.Wallet.createRandomSeed();
|
|
454
|
-
assert.equal(Array.isArray(words), true);
|
|
455
|
-
assert.equal(words.length, 32);
|
|
456
|
-
assert.ok(words.every((w: string) => typeof w === "string" && w.length > 0));
|
|
457
|
-
});
|
|
458
|
-
|
|
459
|
-
it("createRandomSeed(3) returns 32-word array", async () => {
|
|
460
|
-
await Initialize(null);
|
|
461
|
-
const words = qc.Wallet.createRandomSeed(3);
|
|
462
|
-
assert.equal(words.length, 32);
|
|
463
|
-
});
|
|
464
|
-
|
|
465
|
-
it("createRandomSeed(5) returns 36-word array", async () => {
|
|
466
|
-
await Initialize(null);
|
|
467
|
-
const words = qc.Wallet.createRandomSeed(5);
|
|
468
|
-
assert.equal(words.length, 36);
|
|
469
|
-
});
|
|
470
|
-
|
|
471
|
-
it("createRandomSeed roundtrip via fromPhrase produces valid signing wallet", async () => {
|
|
472
|
-
await Initialize(null);
|
|
473
|
-
const words = qc.Wallet.createRandomSeed(3);
|
|
474
|
-
const w = qc.Wallet.fromPhrase(words);
|
|
475
|
-
assert.equal(qc.isAddress(w.address), true);
|
|
476
|
-
const sig = w.signMessageSync("seed roundtrip");
|
|
477
|
-
assert.equal(qc.verifyMessage("seed roundtrip", sig), w.address.toLowerCase());
|
|
478
|
-
});
|
|
479
|
-
|
|
480
|
-
it("createRandomSeed rejects invalid keyType", async () => {
|
|
481
|
-
await Initialize(null);
|
|
482
|
-
assert.throws(() => qc.Wallet.createRandomSeed(1), /keyType must be null, 3, or 5/);
|
|
483
|
-
assert.throws(() => qc.Wallet.createRandomSeed(2), /keyType must be null, 3, or 5/);
|
|
484
|
-
assert.throws(() => qc.Wallet.createRandomSeed(4), /keyType must be null, 3, or 5/);
|
|
485
|
-
});
|
|
486
|
-
|
|
487
378
|
// ---------------------------------------------------------------------------
|
|
488
379
|
// fromSeed
|
|
489
380
|
// ---------------------------------------------------------------------------
|
|
490
381
|
|
|
491
|
-
it("fromSeed roundtrip:
|
|
382
|
+
it("fromSeed roundtrip: createRandom(keyType 3) seed -> fromSeed produces same address", async () => {
|
|
492
383
|
await Initialize(null);
|
|
493
|
-
const
|
|
494
|
-
|
|
495
|
-
const
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
const wFromSeed = qc.Wallet.fromSeed(
|
|
499
|
-
assert.equal(wFromSeed.address,
|
|
384
|
+
const w = qc.Wallet.createRandom(undefined, 3);
|
|
385
|
+
assert.notEqual(w.seed, null);
|
|
386
|
+
const { hexToBytes } = require("../../src/internal/hex");
|
|
387
|
+
const seedBytes = Array.from(hexToBytes(w.seed as string));
|
|
388
|
+
assert.equal(seedBytes.length, 64);
|
|
389
|
+
const wFromSeed = qc.Wallet.fromSeed(seedBytes);
|
|
390
|
+
assert.equal(wFromSeed.address, w.address);
|
|
500
391
|
});
|
|
501
392
|
|
|
502
|
-
it("fromSeed roundtrip:
|
|
393
|
+
it("fromSeed roundtrip: createRandom(keyType 5) seed -> fromSeed produces same address", async () => {
|
|
503
394
|
await Initialize(null);
|
|
504
|
-
const
|
|
505
|
-
|
|
506
|
-
const
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
const wFromSeed = qc.Wallet.fromSeed(
|
|
510
|
-
assert.equal(wFromSeed.address,
|
|
395
|
+
const w = qc.Wallet.createRandom(undefined, 5);
|
|
396
|
+
assert.notEqual(w.seed, null);
|
|
397
|
+
const { hexToBytes } = require("../../src/internal/hex");
|
|
398
|
+
const seedBytes = Array.from(hexToBytes(w.seed as string));
|
|
399
|
+
assert.equal(seedBytes.length, 72);
|
|
400
|
+
const wFromSeed = qc.Wallet.fromSeed(seedBytes);
|
|
401
|
+
assert.equal(wFromSeed.address, w.address);
|
|
511
402
|
});
|
|
512
403
|
|
|
513
404
|
it("fromSeed rejects non-array input", async () => {
|
|
@@ -634,7 +525,175 @@ describe("Address + Wallet (offline)", () => {
|
|
|
634
525
|
it("encryptSeedSync rejects password shorter than 12 characters", async () => {
|
|
635
526
|
await Initialize(null);
|
|
636
527
|
const seed = new Array(64).fill(1);
|
|
637
|
-
assert.throws(() => qc.Wallet.encryptSeedSync(seed, "short"), /
|
|
528
|
+
assert.throws(() => qc.Wallet.encryptSeedSync(seed, "short"), /password must be at least 12 characters/);
|
|
529
|
+
});
|
|
530
|
+
|
|
531
|
+
// ---------------------------------------------------------------------------
|
|
532
|
+
// publicKey getter
|
|
533
|
+
// ---------------------------------------------------------------------------
|
|
534
|
+
|
|
535
|
+
it("publicKey getter returns hex matching signingKey.publicKeyBytes", async () => {
|
|
536
|
+
await Initialize(null);
|
|
537
|
+
const w = qc.Wallet.fromPhrase(TEST_SEED_WORDS_32);
|
|
538
|
+
const expected = "0x" + Buffer.from(w.signingKey.publicKeyBytes).toString("hex");
|
|
539
|
+
assert.equal(w.publicKey, expected);
|
|
540
|
+
assert.equal((w.publicKey.length - 2) / 2, 1408);
|
|
541
|
+
});
|
|
542
|
+
|
|
543
|
+
it("publicKey getter works for keyType 5 (2688-byte public key)", async () => {
|
|
544
|
+
await Initialize(null);
|
|
545
|
+
const w = qc.Wallet.fromPhrase(TEST_SEED_WORDS_36);
|
|
546
|
+
const expected = "0x" + Buffer.from(w.signingKey.publicKeyBytes).toString("hex");
|
|
547
|
+
assert.equal(w.publicKey, expected);
|
|
548
|
+
assert.equal((w.publicKey.length - 2) / 2, 2688);
|
|
549
|
+
});
|
|
550
|
+
|
|
551
|
+
it("publicKey getter works for createRandom wallet", async () => {
|
|
552
|
+
await Initialize(null);
|
|
553
|
+
const w = qc.Wallet.createRandom();
|
|
554
|
+
assert.equal(typeof w.publicKey, "string");
|
|
555
|
+
assert.ok(w.publicKey.startsWith("0x"));
|
|
556
|
+
assert.equal(w.publicKey, "0x" + Buffer.from(w.signingKey.publicKeyBytes).toString("hex"));
|
|
557
|
+
});
|
|
558
|
+
|
|
559
|
+
// ---------------------------------------------------------------------------
|
|
560
|
+
// seed getter
|
|
561
|
+
// ---------------------------------------------------------------------------
|
|
562
|
+
|
|
563
|
+
it("seed is non-null hex for fromPhrase(32-word)", async () => {
|
|
564
|
+
await Initialize(null);
|
|
565
|
+
const w = qc.Wallet.fromPhrase(TEST_SEED_WORDS_32);
|
|
566
|
+
assert.equal(typeof w.seed, "string");
|
|
567
|
+
assert.ok((w.seed as string).startsWith("0x"));
|
|
568
|
+
assert.equal(((w.seed as string).length - 2) / 2, 64);
|
|
569
|
+
assert.equal(w.seed, "0x319fda8ec642b6b649d805770647d82aa4377ced5c51e4e39c0026bd983ad7b150fc475633d246216ac8b81af68bf929bf68a3fd151a2b6c925ef3cc70ecdb8b");
|
|
570
|
+
});
|
|
571
|
+
|
|
572
|
+
it("seed is non-null hex for fromPhrase(36-word)", async () => {
|
|
573
|
+
await Initialize(null);
|
|
574
|
+
const w = qc.Wallet.fromPhrase(TEST_SEED_WORDS_36);
|
|
575
|
+
assert.equal(typeof w.seed, "string");
|
|
576
|
+
assert.equal(((w.seed as string).length - 2) / 2, 72);
|
|
577
|
+
assert.equal(w.seed, "0x319fda8ec642b6b649d805770647d82aa4377ced5c51e4e39c0026bd983ad7b150fc475633d246216ac8b81af68bf929bf68a3fd151a2b6c925ef3cc70ecdb8bdaf9e0ff4c96cb07");
|
|
578
|
+
});
|
|
579
|
+
|
|
580
|
+
it("seed is non-null hex for fromPhrase(48-word)", async () => {
|
|
581
|
+
await Initialize(null);
|
|
582
|
+
const w = qc.Wallet.fromPhrase(TEST_SEED_WORDS);
|
|
583
|
+
assert.equal(typeof w.seed, "string");
|
|
584
|
+
assert.equal(((w.seed as string).length - 2) / 2, 96);
|
|
585
|
+
assert.equal(w.seed, "0x319fda8ec642b6b649d805770647d82aa4377ced5c51e4e39c0026bd983ad7b150fc475633d246216ac8b81af68bf929bf68a3fd151a2b6c925ef3cc70ecdb8bdaf9e0ff4c96cb076c776546d970e1be70a962a868df0eeba1c076a780cb4c3b");
|
|
586
|
+
});
|
|
587
|
+
|
|
588
|
+
it("seed is non-null for fromSeed() and matches fromPhrase() with same words", async () => {
|
|
589
|
+
await Initialize(null);
|
|
590
|
+
const seedwords = require("seed-words");
|
|
591
|
+
const seedArr = seedwords.getSeedArrayFromWordList(TEST_SEED_WORDS_32);
|
|
592
|
+
const wSeed = qc.Wallet.fromSeed(Array.from(seedArr));
|
|
593
|
+
const wPhrase = qc.Wallet.fromPhrase(TEST_SEED_WORDS_32);
|
|
594
|
+
assert.equal(wSeed.seed, wPhrase.seed);
|
|
595
|
+
assert.equal(wSeed.address, wPhrase.address);
|
|
596
|
+
});
|
|
597
|
+
|
|
598
|
+
it("seed is non-null for createRandom() (seed-derived)", async () => {
|
|
599
|
+
await Initialize(null);
|
|
600
|
+
const w = qc.Wallet.createRandom();
|
|
601
|
+
assert.notEqual(w.seed, null);
|
|
602
|
+
assert.equal(typeof w.seed, "string");
|
|
603
|
+
assert.ok((w.seed as string).startsWith("0x"));
|
|
604
|
+
assert.equal(((w.seed as string).length - 2) / 2, 64);
|
|
605
|
+
});
|
|
606
|
+
|
|
607
|
+
it("seed is non-null for createRandom(undefined, 5) (seed-derived, keyType 5)", async () => {
|
|
608
|
+
await Initialize(null);
|
|
609
|
+
const w = qc.Wallet.createRandom(undefined, 5);
|
|
610
|
+
assert.notEqual(w.seed, null);
|
|
611
|
+
assert.equal(((w.seed as string).length - 2) / 2, 72);
|
|
612
|
+
});
|
|
613
|
+
|
|
614
|
+
it("seed is null for fromKeys()", async () => {
|
|
615
|
+
await Initialize(null);
|
|
616
|
+
const w = qc.Wallet.fromPhrase(TEST_SEED_WORDS_32);
|
|
617
|
+
const wk = qc.Wallet.fromKeys(w.signingKey.privateKeyBytes, w.signingKey.publicKeyBytes);
|
|
618
|
+
assert.equal(wk.seed, null);
|
|
619
|
+
assert.equal(wk.address, w.address);
|
|
620
|
+
});
|
|
621
|
+
|
|
622
|
+
it("seed is null for fromEncryptedJsonSync() with v3 JSON", async () => {
|
|
623
|
+
await Initialize(null);
|
|
624
|
+
const w = qc.Wallet.fromEncryptedJsonSync(TEST_WALLET_ENCRYPTED_JSON, TEST_WALLET_PASSPHRASE);
|
|
625
|
+
assert.equal(w.seed, null);
|
|
626
|
+
});
|
|
627
|
+
|
|
628
|
+
it("seed is null for fromEncryptedJsonSync() with v4 JSON", async () => {
|
|
629
|
+
await Initialize(null);
|
|
630
|
+
const w32 = qc.Wallet.fromEncryptedJsonSync(TEST_ENCRYPTED_JSON_32, PASSPHRASE_PHRASE);
|
|
631
|
+
assert.equal(w32.seed, null);
|
|
632
|
+
const w36 = qc.Wallet.fromEncryptedJsonSync(TEST_ENCRYPTED_JSON_36, PASSPHRASE_PHRASE);
|
|
633
|
+
assert.equal(w36.seed, null);
|
|
634
|
+
const w48 = qc.Wallet.fromEncryptedJsonSync(TEST_ENCRYPTED_JSON_48, PASSPHRASE_PHRASE);
|
|
635
|
+
assert.equal(w48.seed, null);
|
|
636
|
+
});
|
|
637
|
+
|
|
638
|
+
// ---------------------------------------------------------------------------
|
|
639
|
+
// seed roundtrip through encryptSync / fromEncryptedJsonSync
|
|
640
|
+
// ---------------------------------------------------------------------------
|
|
641
|
+
|
|
642
|
+
it("seed roundtrips through encryptSync + fromEncryptedJsonSync for fromPhrase wallet", async () => {
|
|
643
|
+
await Initialize(null);
|
|
644
|
+
const w = qc.Wallet.fromPhrase(TEST_SEED_WORDS_32);
|
|
645
|
+
const json = w.encryptSync(PASSPHRASE_PHRASE);
|
|
646
|
+
assert.equal(JSON.parse(json).version, 5);
|
|
647
|
+
const restored = qc.Wallet.fromEncryptedJsonSync(json, PASSPHRASE_PHRASE);
|
|
648
|
+
assert.equal(restored.seed, w.seed);
|
|
649
|
+
assert.equal(restored.address, w.address);
|
|
650
|
+
assert.equal(restored.privateKey, w.privateKey);
|
|
651
|
+
assert.equal(restored.publicKey, w.publicKey);
|
|
652
|
+
});
|
|
653
|
+
|
|
654
|
+
it("seed roundtrips through encryptSync + fromEncryptedJsonSync for createRandom wallet", async () => {
|
|
655
|
+
await Initialize(null);
|
|
656
|
+
const w = qc.Wallet.createRandom();
|
|
657
|
+
const json = w.encryptSync(PASSPHRASE_PHRASE);
|
|
658
|
+
assert.equal(JSON.parse(json).version, 5);
|
|
659
|
+
const restored = qc.Wallet.fromEncryptedJsonSync(json, PASSPHRASE_PHRASE);
|
|
660
|
+
assert.equal(restored.seed, w.seed);
|
|
661
|
+
assert.equal(restored.address, w.address);
|
|
662
|
+
});
|
|
663
|
+
|
|
664
|
+
it("seed roundtrips through encryptSeedSync + fromEncryptedJsonSync", async () => {
|
|
665
|
+
await Initialize(null);
|
|
666
|
+
const seedwords = require("seed-words");
|
|
667
|
+
const seedArr = seedwords.getSeedArrayFromWordList(TEST_SEED_WORDS_32);
|
|
668
|
+
const seedHex = "0x" + Buffer.from(new Uint8Array(seedArr)).toString("hex");
|
|
669
|
+
const json = qc.Wallet.encryptSeedSync(Array.from(seedArr), PASSPHRASE_PHRASE);
|
|
670
|
+
const restored = qc.Wallet.fromEncryptedJsonSync(json, PASSPHRASE_PHRASE);
|
|
671
|
+
assert.equal(restored.seed, seedHex);
|
|
672
|
+
assert.equal(restored.address, TEST_SEED_ADDRESS_32);
|
|
673
|
+
});
|
|
674
|
+
|
|
675
|
+
// ---------------------------------------------------------------------------
|
|
676
|
+
// encryptSync version behavior
|
|
677
|
+
// ---------------------------------------------------------------------------
|
|
678
|
+
|
|
679
|
+
it("encryptSync on seed-bearing wallet produces version 5 JSON", async () => {
|
|
680
|
+
await Initialize(null);
|
|
681
|
+
const w = qc.Wallet.fromPhrase(TEST_SEED_WORDS_32);
|
|
682
|
+
assert.notEqual(w.seed, null);
|
|
683
|
+
const json = w.encryptSync(PASSPHRASE_PHRASE);
|
|
684
|
+
assert.equal(JSON.parse(json).version, 5);
|
|
685
|
+
});
|
|
686
|
+
|
|
687
|
+
it("encryptSync on non-seed wallet (fromKeys) uses fallback path", async () => {
|
|
688
|
+
await Initialize(null);
|
|
689
|
+
const w = qc.Wallet.fromPhrase(TEST_SEED_WORDS_32);
|
|
690
|
+
const wk = qc.Wallet.fromKeys(w.signingKey.privateKeyBytes, w.signingKey.publicKeyBytes);
|
|
691
|
+
assert.equal(wk.seed, null);
|
|
692
|
+
const json = wk.encryptSync(PASSPHRASE_PHRASE);
|
|
693
|
+
const parsed = JSON.parse(json);
|
|
694
|
+
assert.ok(parsed.version === 3 || parsed.version === 4);
|
|
695
|
+
const restored = qc.Wallet.fromEncryptedJsonSync(json, PASSPHRASE_PHRASE);
|
|
696
|
+
assert.equal(restored.address, wk.address);
|
|
638
697
|
});
|
|
639
698
|
|
|
640
699
|
// ---------------------------------------------------------------------------
|
|
@@ -54,17 +54,6 @@
|
|
|
54
54
|
assert.ok(typeof out === "string" && out.startsWith("0x") && out.length === 66);
|
|
55
55
|
});
|
|
56
56
|
|
|
57
|
-
it("hashMessage follows EIP-191 / ethers.js pattern (prefix + length + message, keccak256)", () => {
|
|
58
|
-
// Known digest from ethers.js hashMessage("Hello World")
|
|
59
|
-
const expectedHelloWorld = "0xa1de988600a42c4b4ab089b619297c17d53cffae5d5120d82d8a92d0bb3b78f2";
|
|
60
|
-
assert.equal(qc.hashMessage("Hello World"), expectedHelloWorld);
|
|
61
|
-
// String and UTF-8 bytes of same content produce the same digest
|
|
62
|
-
assert.equal(qc.hashMessage("Hello World"), qc.hashMessage(qc.toUtf8Bytes("Hello World")));
|
|
63
|
-
// Empty message
|
|
64
|
-
const emptyDigest = qc.hashMessage("");
|
|
65
|
-
assert.ok(emptyDigest.startsWith("0x") && emptyDigest.length === 66);
|
|
66
|
-
});
|
|
67
|
-
|
|
68
57
|
it("scryptSync with N=262144, r=8, p=1 produces expected hardcoded output", () => {
|
|
69
58
|
const pw = qc.toUtf8Bytes("password");
|
|
70
59
|
const salt = qc.toUtf8Bytes("salt");
|
|
@@ -54,17 +54,6 @@ describe("Hashing", () => {
|
|
|
54
54
|
assert.ok(typeof out === "string" && out.startsWith("0x") && out.length === 66);
|
|
55
55
|
});
|
|
56
56
|
|
|
57
|
-
it("hashMessage follows EIP-191 / ethers.js pattern (prefix + length + message, keccak256)", () => {
|
|
58
|
-
// Known digest from ethers.js hashMessage("Hello World")
|
|
59
|
-
const expectedHelloWorld = "0xa1de988600a42c4b4ab089b619297c17d53cffae5d5120d82d8a92d0bb3b78f2";
|
|
60
|
-
assert.equal(qc.hashMessage("Hello World"), expectedHelloWorld);
|
|
61
|
-
// String and UTF-8 bytes of same content produce the same digest
|
|
62
|
-
assert.equal(qc.hashMessage("Hello World"), qc.hashMessage(qc.toUtf8Bytes("Hello World")));
|
|
63
|
-
// Empty message
|
|
64
|
-
const emptyDigest = qc.hashMessage("");
|
|
65
|
-
assert.ok(emptyDigest.startsWith("0x") && emptyDigest.length === 66);
|
|
66
|
-
});
|
|
67
|
-
|
|
68
57
|
it("scryptSync with N=262144, r=8, p=1 produces expected hardcoded output", () => {
|
|
69
58
|
const pw = qc.toUtf8Bytes("password");
|
|
70
59
|
const salt = qc.toUtf8Bytes("salt");
|
|
@@ -41,9 +41,11 @@
|
|
|
41
41
|
global.fetch = async (_url, init) => {
|
|
42
42
|
const body = JSON.parse(init.body);
|
|
43
43
|
seen.push(body.params);
|
|
44
|
+
const responseBody = JSON.stringify({ jsonrpc: "2.0", id: body.id, result: "0x1" });
|
|
44
45
|
return {
|
|
45
46
|
ok: true,
|
|
46
|
-
|
|
47
|
+
text: async () => responseBody,
|
|
48
|
+
json: async () => JSON.parse(responseBody),
|
|
47
49
|
};
|
|
48
50
|
};
|
|
49
51
|
|
|
@@ -39,9 +39,11 @@ describe("JsonRpcProvider", () => {
|
|
|
39
39
|
(globalThis as unknown as { fetch: typeof fetch }).fetch = async (_url: string, init: RequestInit) => {
|
|
40
40
|
const body = JSON.parse(init.body as string);
|
|
41
41
|
seen.push(body.params);
|
|
42
|
+
const responseBody = JSON.stringify({ jsonrpc: "2.0", id: body.id, result: "0x1" });
|
|
42
43
|
return {
|
|
43
44
|
ok: true,
|
|
44
|
-
|
|
45
|
+
text: async () => responseBody,
|
|
46
|
+
json: async () => JSON.parse(responseBody),
|
|
45
47
|
} as Response;
|
|
46
48
|
};
|
|
47
49
|
|