quantumcoin 7.0.10 → 7.0.12
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 +16 -5
- package/README.md +14 -3
- 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 +144 -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/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 +1675 -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 +1031 -0
- package/examples/node_modules/quantum-coin-js-sdk/index.js +3144 -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 +1389 -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 +5 -7
- 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 +7 -13
- package/src/wallet/wallet.js +136 -97
- package/test/security/malformed-input.test.js +295 -1
- package/test/unit/address-wallet.test.js +329 -129
- package/test/unit/address-wallet.test.ts +328 -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
- package/SPEC.md +0 -3845
|
@@ -29,7 +29,7 @@ describe("Address + Wallet (offline)", () => {
|
|
|
29
29
|
const TEST_WALLET_ADDRESS = "0x1a846abe71c8b989e8337c55d608be81c28ab3b2e40c83eaa2a68d516049aec6";
|
|
30
30
|
|
|
31
31
|
// ---------------------------------------------------------------------------
|
|
32
|
-
// Hardcoded seed words (generated once via quantum-coin-js-sdk.
|
|
32
|
+
// Hardcoded seed words (generated once via quantum-coin-js-sdk.newWalletSeedWords()).
|
|
33
33
|
// WARNING: test-only seed words; never use for real funds.
|
|
34
34
|
// ---------------------------------------------------------------------------
|
|
35
35
|
const TEST_SEED_WORDS = [
|
|
@@ -174,69 +174,6 @@ describe("Address + Wallet (offline)", () => {
|
|
|
174
174
|
assert.throws(() => qc.Wallet.fromKeys(new Uint8Array(1), new Uint8Array(0)), /publicKey must not be empty/);
|
|
175
175
|
});
|
|
176
176
|
|
|
177
|
-
it("fromKeys wallet can sign messages", async () => {
|
|
178
|
-
await Initialize(null);
|
|
179
|
-
const original = qc.Wallet.fromPhrase(TEST_SEED_WORDS);
|
|
180
|
-
const restored = qc.Wallet.fromKeys(
|
|
181
|
-
original.signingKey.privateKeyBytes,
|
|
182
|
-
original.signingKey.publicKeyBytes,
|
|
183
|
-
);
|
|
184
|
-
assert.equal(restored.address, original.address);
|
|
185
|
-
|
|
186
|
-
const msg = "fromKeys signing test";
|
|
187
|
-
const sig = restored.signMessageSync(msg);
|
|
188
|
-
assert.equal(typeof sig, "string");
|
|
189
|
-
assert.ok(sig.startsWith("0x"));
|
|
190
|
-
const recovered = qc.verifyMessage(msg, sig);
|
|
191
|
-
assert.equal(recovered, original.address.toLowerCase());
|
|
192
|
-
});
|
|
193
|
-
|
|
194
|
-
it("signMessageSync + verifyMessage roundtrip (known wallet)", async () => {
|
|
195
|
-
await Initialize(null);
|
|
196
|
-
const wallet = qc.Wallet.fromEncryptedJsonSync(TEST_WALLET_ENCRYPTED_JSON, TEST_WALLET_PASSPHRASE);
|
|
197
|
-
const sig = wallet.signMessageSync("Hello, QuantumCoin!");
|
|
198
|
-
assert.equal(typeof sig, "string");
|
|
199
|
-
assert.ok(sig.startsWith("0x"));
|
|
200
|
-
const recovered = qc.verifyMessage("Hello, QuantumCoin!", sig);
|
|
201
|
-
assert.equal(recovered, wallet.address.toLowerCase());
|
|
202
|
-
});
|
|
203
|
-
|
|
204
|
-
it("signMessageSync returns combined signature hex and verifyMessage roundtrip (fromPhrase wallet)", async () => {
|
|
205
|
-
await Initialize(null);
|
|
206
|
-
const wallet = qc.Wallet.fromPhrase(TEST_SEED_WORDS);
|
|
207
|
-
const msg = "test message";
|
|
208
|
-
const sig = wallet.signMessageSync(msg);
|
|
209
|
-
assert.equal(typeof sig, "string");
|
|
210
|
-
assert.ok(sig.startsWith("0x"));
|
|
211
|
-
assert.ok(sig.length > 4);
|
|
212
|
-
const recovered = qc.verifyMessage(msg, sig);
|
|
213
|
-
assert.equal(recovered, wallet.address.toLowerCase());
|
|
214
|
-
});
|
|
215
|
-
|
|
216
|
-
it("signMessageSync + verifyMessage roundtrip (32-word phrase wallet)", async () => {
|
|
217
|
-
await Initialize(null);
|
|
218
|
-
const wallet = qc.Wallet.fromPhrase(TEST_SEED_WORDS_32);
|
|
219
|
-
const msg = "hello 32";
|
|
220
|
-
const sig = wallet.signMessageSync(msg);
|
|
221
|
-
assert.equal(typeof sig, "string");
|
|
222
|
-
assert.ok(sig.startsWith("0x"));
|
|
223
|
-
const recovered = qc.verifyMessage(msg, sig);
|
|
224
|
-
assert.equal(recovered, wallet.address.toLowerCase());
|
|
225
|
-
assert.equal(recovered, TEST_SEED_ADDRESS_32.toLowerCase());
|
|
226
|
-
});
|
|
227
|
-
|
|
228
|
-
it("signMessageSync + verifyMessage roundtrip (36-word phrase wallet)", async () => {
|
|
229
|
-
await Initialize(null);
|
|
230
|
-
const wallet = qc.Wallet.fromPhrase(TEST_SEED_WORDS_36);
|
|
231
|
-
const msg = "hello 36";
|
|
232
|
-
const sig = wallet.signMessageSync(msg);
|
|
233
|
-
assert.equal(typeof sig, "string");
|
|
234
|
-
assert.ok(sig.startsWith("0x"));
|
|
235
|
-
const recovered = qc.verifyMessage(msg, sig);
|
|
236
|
-
assert.equal(recovered, wallet.address.toLowerCase());
|
|
237
|
-
assert.equal(recovered, TEST_SEED_ADDRESS_36.toLowerCase());
|
|
238
|
-
});
|
|
239
|
-
|
|
240
177
|
it("signTransaction works offline and returns raw tx hex", async () => {
|
|
241
178
|
await Initialize(null);
|
|
242
179
|
const wallet = qc.Wallet.fromEncryptedJsonSync(TEST_WALLET_ENCRYPTED_JSON, TEST_WALLET_PASSPHRASE);
|
|
@@ -399,22 +336,16 @@ describe("Address + Wallet (offline)", () => {
|
|
|
399
336
|
assert.equal(qc.isAddress(w.address), true);
|
|
400
337
|
});
|
|
401
338
|
|
|
402
|
-
it("createRandom(null, 3) creates wallet with keyType 3
|
|
339
|
+
it("createRandom(null, 3) creates wallet with keyType 3", async () => {
|
|
403
340
|
await Initialize(null);
|
|
404
341
|
const w = qc.Wallet.createRandom(null, 3);
|
|
405
342
|
assert.equal(qc.isAddress(w.address), true);
|
|
406
|
-
const sig = w.signMessageSync("kt3 test");
|
|
407
|
-
assert.ok(sig.startsWith("0x"));
|
|
408
|
-
assert.equal(qc.verifyMessage("kt3 test", sig), w.address.toLowerCase());
|
|
409
343
|
});
|
|
410
344
|
|
|
411
|
-
it("createRandom(null, 5) creates wallet with keyType 5
|
|
345
|
+
it("createRandom(null, 5) creates wallet with keyType 5", async () => {
|
|
412
346
|
await Initialize(null);
|
|
413
347
|
const w = qc.Wallet.createRandom(null, 5);
|
|
414
348
|
assert.equal(qc.isAddress(w.address), true);
|
|
415
|
-
const sig = w.signMessageSync("kt5 test");
|
|
416
|
-
assert.ok(sig.startsWith("0x"));
|
|
417
|
-
assert.equal(qc.verifyMessage("kt5 test", sig), w.address.toLowerCase());
|
|
418
349
|
});
|
|
419
350
|
|
|
420
351
|
it("createRandom(null, 3) signTransaction works offline", async () => {
|
|
@@ -458,70 +389,30 @@ describe("Address + Wallet (offline)", () => {
|
|
|
458
389
|
assert.throws(() => qc.Wallet.createRandom(null, true), /keyType must be null, 3, or 5/);
|
|
459
390
|
});
|
|
460
391
|
|
|
461
|
-
// ---------------------------------------------------------------------------
|
|
462
|
-
// createRandomSeed
|
|
463
|
-
// ---------------------------------------------------------------------------
|
|
464
|
-
|
|
465
|
-
it("createRandomSeed() returns 32-word array (default keyType)", async () => {
|
|
466
|
-
await Initialize(null);
|
|
467
|
-
const words = qc.Wallet.createRandomSeed();
|
|
468
|
-
assert.equal(Array.isArray(words), true);
|
|
469
|
-
assert.equal(words.length, 32);
|
|
470
|
-
assert.ok(words.every((w) => typeof w === "string" && w.length > 0));
|
|
471
|
-
});
|
|
472
|
-
|
|
473
|
-
it("createRandomSeed(3) returns 32-word array", async () => {
|
|
474
|
-
await Initialize(null);
|
|
475
|
-
const words = qc.Wallet.createRandomSeed(3);
|
|
476
|
-
assert.equal(words.length, 32);
|
|
477
|
-
});
|
|
478
|
-
|
|
479
|
-
it("createRandomSeed(5) returns 36-word array", async () => {
|
|
480
|
-
await Initialize(null);
|
|
481
|
-
const words = qc.Wallet.createRandomSeed(5);
|
|
482
|
-
assert.equal(words.length, 36);
|
|
483
|
-
});
|
|
484
|
-
|
|
485
|
-
it("createRandomSeed roundtrip via fromPhrase produces valid signing wallet", async () => {
|
|
486
|
-
await Initialize(null);
|
|
487
|
-
const words = qc.Wallet.createRandomSeed(3);
|
|
488
|
-
const w = qc.Wallet.fromPhrase(words);
|
|
489
|
-
assert.equal(qc.isAddress(w.address), true);
|
|
490
|
-
const sig = w.signMessageSync("seed roundtrip");
|
|
491
|
-
assert.equal(qc.verifyMessage("seed roundtrip", sig), w.address.toLowerCase());
|
|
492
|
-
});
|
|
493
|
-
|
|
494
|
-
it("createRandomSeed rejects invalid keyType", async () => {
|
|
495
|
-
await Initialize(null);
|
|
496
|
-
assert.throws(() => qc.Wallet.createRandomSeed(1), /keyType must be null, 3, or 5/);
|
|
497
|
-
assert.throws(() => qc.Wallet.createRandomSeed(2), /keyType must be null, 3, or 5/);
|
|
498
|
-
assert.throws(() => qc.Wallet.createRandomSeed(4), /keyType must be null, 3, or 5/);
|
|
499
|
-
});
|
|
500
|
-
|
|
501
392
|
// ---------------------------------------------------------------------------
|
|
502
393
|
// fromSeed
|
|
503
394
|
// ---------------------------------------------------------------------------
|
|
504
395
|
|
|
505
|
-
it("fromSeed roundtrip:
|
|
396
|
+
it("fromSeed roundtrip: createRandom(keyType 3) seed -> fromSeed produces same address", async () => {
|
|
506
397
|
await Initialize(null);
|
|
507
|
-
const
|
|
508
|
-
|
|
509
|
-
const
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
const wFromSeed = qc.Wallet.fromSeed(
|
|
513
|
-
assert.equal(wFromSeed.address,
|
|
398
|
+
const w = qc.Wallet.createRandom(null, 3);
|
|
399
|
+
assert.notEqual(w.seed, null);
|
|
400
|
+
const { hexToBytes } = require("../../src/internal/hex");
|
|
401
|
+
const seedBytes = Array.from(hexToBytes(w.seed));
|
|
402
|
+
assert.equal(seedBytes.length, 64);
|
|
403
|
+
const wFromSeed = qc.Wallet.fromSeed(seedBytes);
|
|
404
|
+
assert.equal(wFromSeed.address, w.address);
|
|
514
405
|
});
|
|
515
406
|
|
|
516
|
-
it("fromSeed roundtrip:
|
|
407
|
+
it("fromSeed roundtrip: createRandom(keyType 5) seed -> fromSeed produces same address", async () => {
|
|
517
408
|
await Initialize(null);
|
|
518
|
-
const
|
|
519
|
-
|
|
520
|
-
const
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
const wFromSeed = qc.Wallet.fromSeed(
|
|
524
|
-
assert.equal(wFromSeed.address,
|
|
409
|
+
const w = qc.Wallet.createRandom(null, 5);
|
|
410
|
+
assert.notEqual(w.seed, null);
|
|
411
|
+
const { hexToBytes } = require("../../src/internal/hex");
|
|
412
|
+
const seedBytes = Array.from(hexToBytes(w.seed));
|
|
413
|
+
assert.equal(seedBytes.length, 72);
|
|
414
|
+
const wFromSeed = qc.Wallet.fromSeed(seedBytes);
|
|
415
|
+
assert.equal(wFromSeed.address, w.address);
|
|
525
416
|
});
|
|
526
417
|
|
|
527
418
|
it("fromSeed rejects non-array input", async () => {
|
|
@@ -648,7 +539,316 @@ describe("Address + Wallet (offline)", () => {
|
|
|
648
539
|
it("encryptSeedSync rejects password shorter than 12 characters", async () => {
|
|
649
540
|
await Initialize(null);
|
|
650
541
|
const seed = new Array(64).fill(1);
|
|
651
|
-
assert.throws(() => qc.Wallet.encryptSeedSync(seed, "short"), /
|
|
542
|
+
assert.throws(() => qc.Wallet.encryptSeedSync(seed, "short"), /password must be at least 12 characters/);
|
|
543
|
+
});
|
|
544
|
+
|
|
545
|
+
// ---------------------------------------------------------------------------
|
|
546
|
+
// publicKey getter
|
|
547
|
+
// ---------------------------------------------------------------------------
|
|
548
|
+
|
|
549
|
+
it("publicKey getter returns hex matching signingKey.publicKeyBytes", async () => {
|
|
550
|
+
await Initialize(null);
|
|
551
|
+
const w = qc.Wallet.fromPhrase(TEST_SEED_WORDS_32);
|
|
552
|
+
const expected = "0x" + Buffer.from(w.signingKey.publicKeyBytes).toString("hex");
|
|
553
|
+
assert.equal(w.publicKey, expected);
|
|
554
|
+
assert.equal((w.publicKey.length - 2) / 2, 1408);
|
|
555
|
+
});
|
|
556
|
+
|
|
557
|
+
it("publicKey getter works for keyType 5 (2688-byte public key)", async () => {
|
|
558
|
+
await Initialize(null);
|
|
559
|
+
const w = qc.Wallet.fromPhrase(TEST_SEED_WORDS_36);
|
|
560
|
+
const expected = "0x" + Buffer.from(w.signingKey.publicKeyBytes).toString("hex");
|
|
561
|
+
assert.equal(w.publicKey, expected);
|
|
562
|
+
assert.equal((w.publicKey.length - 2) / 2, 2688);
|
|
563
|
+
});
|
|
564
|
+
|
|
565
|
+
it("publicKey getter works for createRandom wallet", async () => {
|
|
566
|
+
await Initialize(null);
|
|
567
|
+
const w = qc.Wallet.createRandom();
|
|
568
|
+
assert.equal(typeof w.publicKey, "string");
|
|
569
|
+
assert.ok(w.publicKey.startsWith("0x"));
|
|
570
|
+
assert.equal(w.publicKey, "0x" + Buffer.from(w.signingKey.publicKeyBytes).toString("hex"));
|
|
571
|
+
});
|
|
572
|
+
|
|
573
|
+
// ---------------------------------------------------------------------------
|
|
574
|
+
// seed getter
|
|
575
|
+
// ---------------------------------------------------------------------------
|
|
576
|
+
|
|
577
|
+
it("seed is non-null hex for fromPhrase(32-word)", async () => {
|
|
578
|
+
await Initialize(null);
|
|
579
|
+
const w = qc.Wallet.fromPhrase(TEST_SEED_WORDS_32);
|
|
580
|
+
assert.equal(typeof w.seed, "string");
|
|
581
|
+
assert.ok(w.seed.startsWith("0x"));
|
|
582
|
+
assert.equal((w.seed.length - 2) / 2, 64);
|
|
583
|
+
assert.equal(w.seed, "0x319fda8ec642b6b649d805770647d82aa4377ced5c51e4e39c0026bd983ad7b150fc475633d246216ac8b81af68bf929bf68a3fd151a2b6c925ef3cc70ecdb8b");
|
|
584
|
+
});
|
|
585
|
+
|
|
586
|
+
it("seed is non-null hex for fromPhrase(36-word)", async () => {
|
|
587
|
+
await Initialize(null);
|
|
588
|
+
const w = qc.Wallet.fromPhrase(TEST_SEED_WORDS_36);
|
|
589
|
+
assert.equal(typeof w.seed, "string");
|
|
590
|
+
assert.equal((w.seed.length - 2) / 2, 72);
|
|
591
|
+
assert.equal(w.seed, "0x319fda8ec642b6b649d805770647d82aa4377ced5c51e4e39c0026bd983ad7b150fc475633d246216ac8b81af68bf929bf68a3fd151a2b6c925ef3cc70ecdb8bdaf9e0ff4c96cb07");
|
|
592
|
+
});
|
|
593
|
+
|
|
594
|
+
it("seed is non-null hex for fromPhrase(48-word)", async () => {
|
|
595
|
+
await Initialize(null);
|
|
596
|
+
const w = qc.Wallet.fromPhrase(TEST_SEED_WORDS);
|
|
597
|
+
assert.equal(typeof w.seed, "string");
|
|
598
|
+
assert.equal((w.seed.length - 2) / 2, 96);
|
|
599
|
+
assert.equal(w.seed, "0x319fda8ec642b6b649d805770647d82aa4377ced5c51e4e39c0026bd983ad7b150fc475633d246216ac8b81af68bf929bf68a3fd151a2b6c925ef3cc70ecdb8bdaf9e0ff4c96cb076c776546d970e1be70a962a868df0eeba1c076a780cb4c3b");
|
|
600
|
+
});
|
|
601
|
+
|
|
602
|
+
it("seed is non-null for fromSeed() and matches fromPhrase() with same words", async () => {
|
|
603
|
+
await Initialize(null);
|
|
604
|
+
const seedwords = require("seed-words");
|
|
605
|
+
const seedArr = seedwords.getSeedArrayFromWordList(TEST_SEED_WORDS_32);
|
|
606
|
+
const wSeed = qc.Wallet.fromSeed(Array.from(seedArr));
|
|
607
|
+
const wPhrase = qc.Wallet.fromPhrase(TEST_SEED_WORDS_32);
|
|
608
|
+
assert.equal(wSeed.seed, wPhrase.seed);
|
|
609
|
+
assert.equal(wSeed.address, wPhrase.address);
|
|
610
|
+
});
|
|
611
|
+
|
|
612
|
+
it("seed is non-null for createRandom() (seed-derived)", async () => {
|
|
613
|
+
await Initialize(null);
|
|
614
|
+
const w = qc.Wallet.createRandom();
|
|
615
|
+
assert.notEqual(w.seed, null);
|
|
616
|
+
assert.equal(typeof w.seed, "string");
|
|
617
|
+
assert.ok(w.seed.startsWith("0x"));
|
|
618
|
+
assert.equal((w.seed.length - 2) / 2, 64);
|
|
619
|
+
});
|
|
620
|
+
|
|
621
|
+
it("seed is non-null for createRandom(null, 5) (seed-derived, keyType 5)", async () => {
|
|
622
|
+
await Initialize(null);
|
|
623
|
+
const w = qc.Wallet.createRandom(null, 5);
|
|
624
|
+
assert.notEqual(w.seed, null);
|
|
625
|
+
assert.equal((w.seed.length - 2) / 2, 72);
|
|
626
|
+
});
|
|
627
|
+
|
|
628
|
+
it("seed is null for fromKeys()", async () => {
|
|
629
|
+
await Initialize(null);
|
|
630
|
+
const w = qc.Wallet.fromPhrase(TEST_SEED_WORDS_32);
|
|
631
|
+
const wk = qc.Wallet.fromKeys(w.signingKey.privateKeyBytes, w.signingKey.publicKeyBytes);
|
|
632
|
+
assert.equal(wk.seed, null);
|
|
633
|
+
assert.equal(wk.address, w.address);
|
|
634
|
+
});
|
|
635
|
+
|
|
636
|
+
it("seed is null for fromEncryptedJsonSync() with v3 JSON", async () => {
|
|
637
|
+
await Initialize(null);
|
|
638
|
+
const w = qc.Wallet.fromEncryptedJsonSync(TEST_WALLET_ENCRYPTED_JSON, TEST_WALLET_PASSPHRASE);
|
|
639
|
+
assert.equal(w.seed, null);
|
|
640
|
+
});
|
|
641
|
+
|
|
642
|
+
it("seed is null for fromEncryptedJsonSync() with v4 JSON", async () => {
|
|
643
|
+
await Initialize(null);
|
|
644
|
+
const w32 = qc.Wallet.fromEncryptedJsonSync(TEST_ENCRYPTED_JSON_32, PASSPHRASE_PHRASE);
|
|
645
|
+
assert.equal(w32.seed, null);
|
|
646
|
+
const w36 = qc.Wallet.fromEncryptedJsonSync(TEST_ENCRYPTED_JSON_36, PASSPHRASE_PHRASE);
|
|
647
|
+
assert.equal(w36.seed, null);
|
|
648
|
+
const w48 = qc.Wallet.fromEncryptedJsonSync(TEST_ENCRYPTED_JSON_48, PASSPHRASE_PHRASE);
|
|
649
|
+
assert.equal(w48.seed, null);
|
|
650
|
+
});
|
|
651
|
+
|
|
652
|
+
// ---------------------------------------------------------------------------
|
|
653
|
+
// getPhrase()
|
|
654
|
+
// ---------------------------------------------------------------------------
|
|
655
|
+
|
|
656
|
+
it("getPhrase returns 32 words and roundtrips through fromPhrase (same address)", async () => {
|
|
657
|
+
await Initialize(null);
|
|
658
|
+
const w = qc.Wallet.fromPhrase(TEST_SEED_WORDS_32);
|
|
659
|
+
const phrase = w.getPhrase();
|
|
660
|
+
assert.ok(Array.isArray(phrase));
|
|
661
|
+
assert.equal(phrase.length, 32);
|
|
662
|
+
assert.deepEqual(phrase, TEST_SEED_WORDS_32);
|
|
663
|
+
const w2 = qc.Wallet.fromPhrase(phrase);
|
|
664
|
+
assert.equal(w2.address, TEST_SEED_ADDRESS_32);
|
|
665
|
+
assert.equal(w2.address, w.address);
|
|
666
|
+
});
|
|
667
|
+
|
|
668
|
+
it("getPhrase returns 36 words and roundtrips through fromPhrase (same address)", async () => {
|
|
669
|
+
await Initialize(null);
|
|
670
|
+
const w = qc.Wallet.fromPhrase(TEST_SEED_WORDS_36);
|
|
671
|
+
const phrase = w.getPhrase();
|
|
672
|
+
assert.ok(Array.isArray(phrase));
|
|
673
|
+
assert.equal(phrase.length, 36);
|
|
674
|
+
assert.deepEqual(phrase, TEST_SEED_WORDS_36);
|
|
675
|
+
const w2 = qc.Wallet.fromPhrase(phrase);
|
|
676
|
+
assert.equal(w2.address, TEST_SEED_ADDRESS_36);
|
|
677
|
+
assert.equal(w2.address, w.address);
|
|
678
|
+
});
|
|
679
|
+
|
|
680
|
+
it("getPhrase returns 48 words and roundtrips through fromPhrase (same address)", async () => {
|
|
681
|
+
await Initialize(null);
|
|
682
|
+
const w = qc.Wallet.fromPhrase(TEST_SEED_WORDS);
|
|
683
|
+
const phrase = w.getPhrase();
|
|
684
|
+
assert.ok(Array.isArray(phrase));
|
|
685
|
+
assert.equal(phrase.length, 48);
|
|
686
|
+
assert.deepEqual(phrase, TEST_SEED_WORDS);
|
|
687
|
+
const w2 = qc.Wallet.fromPhrase(phrase);
|
|
688
|
+
assert.equal(w2.address, TEST_SEED_ADDRESS);
|
|
689
|
+
assert.equal(w2.address, w.address);
|
|
690
|
+
});
|
|
691
|
+
|
|
692
|
+
it("getPhrase on fromSeed(32-word seed) returns the matching 32 words", async () => {
|
|
693
|
+
await Initialize(null);
|
|
694
|
+
const seedwords = require("seed-words");
|
|
695
|
+
const seedArr = seedwords.getSeedArrayFromWordList(TEST_SEED_WORDS_32);
|
|
696
|
+
const w = qc.Wallet.fromSeed(Array.from(seedArr));
|
|
697
|
+
assert.deepEqual(w.getPhrase(), TEST_SEED_WORDS_32);
|
|
698
|
+
const w2 = qc.Wallet.fromPhrase(w.getPhrase());
|
|
699
|
+
assert.equal(w2.address, TEST_SEED_ADDRESS_32);
|
|
700
|
+
assert.equal(w2.address, w.address);
|
|
701
|
+
});
|
|
702
|
+
|
|
703
|
+
it("getPhrase on fromSeed(36-word seed) returns the matching 36 words", async () => {
|
|
704
|
+
await Initialize(null);
|
|
705
|
+
const seedwords = require("seed-words");
|
|
706
|
+
const seedArr = seedwords.getSeedArrayFromWordList(TEST_SEED_WORDS_36);
|
|
707
|
+
const w = qc.Wallet.fromSeed(Array.from(seedArr));
|
|
708
|
+
assert.deepEqual(w.getPhrase(), TEST_SEED_WORDS_36);
|
|
709
|
+
const w2 = qc.Wallet.fromPhrase(w.getPhrase());
|
|
710
|
+
assert.equal(w2.address, TEST_SEED_ADDRESS_36);
|
|
711
|
+
assert.equal(w2.address, w.address);
|
|
712
|
+
});
|
|
713
|
+
|
|
714
|
+
it("getPhrase on fromSeed(48-word seed) returns the matching 48 words", async () => {
|
|
715
|
+
await Initialize(null);
|
|
716
|
+
const seedwords = require("seed-words");
|
|
717
|
+
const seedArr = seedwords.getSeedArrayFromWordList(TEST_SEED_WORDS);
|
|
718
|
+
const w = qc.Wallet.fromSeed(Array.from(seedArr));
|
|
719
|
+
assert.deepEqual(w.getPhrase(), TEST_SEED_WORDS);
|
|
720
|
+
const w2 = qc.Wallet.fromPhrase(w.getPhrase());
|
|
721
|
+
assert.equal(w2.address, TEST_SEED_ADDRESS);
|
|
722
|
+
assert.equal(w2.address, w.address);
|
|
723
|
+
});
|
|
724
|
+
|
|
725
|
+
it("seed and getPhrase survive encryptSync + fromEncryptedJsonSync (32-word)", async () => {
|
|
726
|
+
await Initialize(null);
|
|
727
|
+
const w = qc.Wallet.fromPhrase(TEST_SEED_WORDS_32);
|
|
728
|
+
const json = w.encryptSync(PASSPHRASE_PHRASE);
|
|
729
|
+
assert.equal(JSON.parse(json).version, 5);
|
|
730
|
+
const restored = qc.Wallet.fromEncryptedJsonSync(json, PASSPHRASE_PHRASE);
|
|
731
|
+
assert.equal(restored.seed, w.seed);
|
|
732
|
+
assert.deepEqual(restored.getPhrase(), TEST_SEED_WORDS_32);
|
|
733
|
+
assert.equal(restored.address, TEST_SEED_ADDRESS_32);
|
|
734
|
+
});
|
|
735
|
+
|
|
736
|
+
it("seed and getPhrase survive encryptSync + fromEncryptedJsonSync (36-word)", async () => {
|
|
737
|
+
await Initialize(null);
|
|
738
|
+
const w = qc.Wallet.fromPhrase(TEST_SEED_WORDS_36);
|
|
739
|
+
const json = w.encryptSync(PASSPHRASE_PHRASE);
|
|
740
|
+
assert.equal(JSON.parse(json).version, 5);
|
|
741
|
+
const restored = qc.Wallet.fromEncryptedJsonSync(json, PASSPHRASE_PHRASE);
|
|
742
|
+
assert.equal(restored.seed, w.seed);
|
|
743
|
+
assert.deepEqual(restored.getPhrase(), TEST_SEED_WORDS_36);
|
|
744
|
+
assert.equal(restored.address, TEST_SEED_ADDRESS_36);
|
|
745
|
+
});
|
|
746
|
+
|
|
747
|
+
it("seed and getPhrase survive encryptSync + fromEncryptedJsonSync (48-word)", async () => {
|
|
748
|
+
await Initialize(null);
|
|
749
|
+
const w = qc.Wallet.fromPhrase(TEST_SEED_WORDS);
|
|
750
|
+
const json = w.encryptSync(PASSPHRASE_PHRASE);
|
|
751
|
+
assert.equal(JSON.parse(json).version, 5);
|
|
752
|
+
const restored = qc.Wallet.fromEncryptedJsonSync(json, PASSPHRASE_PHRASE);
|
|
753
|
+
assert.equal(restored.seed, w.seed);
|
|
754
|
+
assert.deepEqual(restored.getPhrase(), TEST_SEED_WORDS);
|
|
755
|
+
assert.equal(restored.address, TEST_SEED_ADDRESS);
|
|
756
|
+
});
|
|
757
|
+
|
|
758
|
+
it("getPhrase on createRandom returns 32 words that recreate the same wallet", async () => {
|
|
759
|
+
await Initialize(null);
|
|
760
|
+
const w = qc.Wallet.createRandom();
|
|
761
|
+
const phrase = w.getPhrase();
|
|
762
|
+
assert.ok(Array.isArray(phrase));
|
|
763
|
+
assert.equal(phrase.length, 32);
|
|
764
|
+
const w2 = qc.Wallet.fromPhrase(phrase);
|
|
765
|
+
assert.equal(w2.address, w.address);
|
|
766
|
+
});
|
|
767
|
+
|
|
768
|
+
it("getPhrase on createRandom(null, 5) returns 36 words that recreate the same wallet", async () => {
|
|
769
|
+
await Initialize(null);
|
|
770
|
+
const w = qc.Wallet.createRandom(null, 5);
|
|
771
|
+
const phrase = w.getPhrase();
|
|
772
|
+
assert.ok(Array.isArray(phrase));
|
|
773
|
+
assert.equal(phrase.length, 36);
|
|
774
|
+
const w2 = qc.Wallet.fromPhrase(phrase);
|
|
775
|
+
assert.equal(w2.address, w.address);
|
|
776
|
+
});
|
|
777
|
+
|
|
778
|
+
it("getPhrase returns null when seed is null (fromKeys wallet)", async () => {
|
|
779
|
+
await Initialize(null);
|
|
780
|
+
const ref = qc.Wallet.fromPhrase(TEST_SEED_WORDS_32);
|
|
781
|
+
const w = qc.Wallet.fromKeys(ref.signingKey.privateKeyBytes, ref.signingKey.publicKeyBytes);
|
|
782
|
+
assert.equal(w.seed, null);
|
|
783
|
+
assert.equal(w.getPhrase(), null);
|
|
784
|
+
});
|
|
785
|
+
|
|
786
|
+
it("getPhrase returns null for v3 encrypted-JSON wallet (no preExpansionSeed)", async () => {
|
|
787
|
+
await Initialize(null);
|
|
788
|
+
const w = qc.Wallet.fromEncryptedJsonSync(TEST_WALLET_ENCRYPTED_JSON, TEST_WALLET_PASSPHRASE);
|
|
789
|
+
assert.equal(w.seed, null);
|
|
790
|
+
assert.equal(w.getPhrase(), null);
|
|
791
|
+
});
|
|
792
|
+
|
|
793
|
+
// ---------------------------------------------------------------------------
|
|
794
|
+
// seed roundtrip through encryptSync / fromEncryptedJsonSync
|
|
795
|
+
// ---------------------------------------------------------------------------
|
|
796
|
+
|
|
797
|
+
it("seed roundtrips through encryptSync + fromEncryptedJsonSync for fromPhrase wallet", async () => {
|
|
798
|
+
await Initialize(null);
|
|
799
|
+
const w = qc.Wallet.fromPhrase(TEST_SEED_WORDS_32);
|
|
800
|
+
const json = w.encryptSync(PASSPHRASE_PHRASE);
|
|
801
|
+
assert.equal(JSON.parse(json).version, 5);
|
|
802
|
+
const restored = qc.Wallet.fromEncryptedJsonSync(json, PASSPHRASE_PHRASE);
|
|
803
|
+
assert.equal(restored.seed, w.seed);
|
|
804
|
+
assert.equal(restored.address, w.address);
|
|
805
|
+
assert.equal(restored.privateKey, w.privateKey);
|
|
806
|
+
assert.equal(restored.publicKey, w.publicKey);
|
|
807
|
+
});
|
|
808
|
+
|
|
809
|
+
it("seed roundtrips through encryptSync + fromEncryptedJsonSync for createRandom wallet", async () => {
|
|
810
|
+
await Initialize(null);
|
|
811
|
+
const w = qc.Wallet.createRandom();
|
|
812
|
+
const json = w.encryptSync(PASSPHRASE_PHRASE);
|
|
813
|
+
assert.equal(JSON.parse(json).version, 5);
|
|
814
|
+
const restored = qc.Wallet.fromEncryptedJsonSync(json, PASSPHRASE_PHRASE);
|
|
815
|
+
assert.equal(restored.seed, w.seed);
|
|
816
|
+
assert.equal(restored.address, w.address);
|
|
817
|
+
});
|
|
818
|
+
|
|
819
|
+
it("seed roundtrips through encryptSeedSync + fromEncryptedJsonSync", async () => {
|
|
820
|
+
await Initialize(null);
|
|
821
|
+
const seedwords = require("seed-words");
|
|
822
|
+
const seedArr = seedwords.getSeedArrayFromWordList(TEST_SEED_WORDS_32);
|
|
823
|
+
const seedHex = "0x" + Buffer.from(new Uint8Array(seedArr)).toString("hex");
|
|
824
|
+
const json = qc.Wallet.encryptSeedSync(Array.from(seedArr), PASSPHRASE_PHRASE);
|
|
825
|
+
const restored = qc.Wallet.fromEncryptedJsonSync(json, PASSPHRASE_PHRASE);
|
|
826
|
+
assert.equal(restored.seed, seedHex);
|
|
827
|
+
assert.equal(restored.address, TEST_SEED_ADDRESS_32);
|
|
828
|
+
});
|
|
829
|
+
|
|
830
|
+
// ---------------------------------------------------------------------------
|
|
831
|
+
// encryptSync version behavior
|
|
832
|
+
// ---------------------------------------------------------------------------
|
|
833
|
+
|
|
834
|
+
it("encryptSync on seed-bearing wallet produces version 5 JSON", async () => {
|
|
835
|
+
await Initialize(null);
|
|
836
|
+
const w = qc.Wallet.fromPhrase(TEST_SEED_WORDS_32);
|
|
837
|
+
assert.notEqual(w.seed, null);
|
|
838
|
+
const json = w.encryptSync(PASSPHRASE_PHRASE);
|
|
839
|
+
assert.equal(JSON.parse(json).version, 5);
|
|
840
|
+
});
|
|
841
|
+
|
|
842
|
+
it("encryptSync on non-seed wallet (fromKeys) uses fallback path", async () => {
|
|
843
|
+
await Initialize(null);
|
|
844
|
+
const w = qc.Wallet.fromPhrase(TEST_SEED_WORDS_32);
|
|
845
|
+
const wk = qc.Wallet.fromKeys(w.signingKey.privateKeyBytes, w.signingKey.publicKeyBytes);
|
|
846
|
+
assert.equal(wk.seed, null);
|
|
847
|
+
const json = wk.encryptSync(PASSPHRASE_PHRASE);
|
|
848
|
+
const parsed = JSON.parse(json);
|
|
849
|
+
assert.ok(parsed.version === 3 || parsed.version === 4);
|
|
850
|
+
const restored = qc.Wallet.fromEncryptedJsonSync(json, PASSPHRASE_PHRASE);
|
|
851
|
+
assert.equal(restored.address, wk.address);
|
|
652
852
|
});
|
|
653
853
|
|
|
654
854
|
// ---------------------------------------------------------------------------
|