quantumcoin 7.0.7 → 7.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README-SDK.md CHANGED
@@ -399,6 +399,7 @@ User-facing wallet class.
399
399
  - `getTransactionCount(blockTag?: string): Promise<number>`
400
400
  - `encryptSync(password: string | Uint8Array): string`
401
401
  - `connect(provider: AbstractProvider): Wallet`
402
+ - `getSigningContext(fullSign?: boolean | null): number` — returns the recommended signing context for this wallet (based on public key type). Setting `fullSign` to `true` may incur additional gas cost.
402
403
 
403
404
  **Example(s):**
404
405
  - `examples/wallet-offline.js`
@@ -18,7 +18,7 @@
18
18
  },
19
19
  "..": {
20
20
  "name": "quantumcoin",
21
- "version": "7.0.7",
21
+ "version": "7.0.9",
22
22
  "license": "MIT",
23
23
  "dependencies": {
24
24
  "quantum-coin-js-sdk": "1.0.32",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "quantumcoin",
3
- "version": "7.0.7",
4
- "description": "QuantumCoin SDK - a complete SDK for dapps",
3
+ "version": "7.0.9",
4
+ "description": "QuantumCoin.js - a post quantum cryptography SDK for QuantumCoin",
5
5
  "main": "index.js",
6
6
  "types": "src/index.d.ts",
7
7
  "typesVersions": {
@@ -293,7 +293,7 @@ function scrypt(password, salt, N, r, p, dkLen) {
293
293
  function scryptSync(password, salt, N, r, p, dkLen) {
294
294
  const pw = arrayify(password);
295
295
  const sa = arrayify(salt);
296
- const out = crypto.scryptSync(Buffer.from(pw), Buffer.from(sa), dkLen, { N, r, p, maxmem: 128 * 1024 * 1024 });
296
+ const out = crypto.scryptSync(Buffer.from(pw), Buffer.from(sa), dkLen, { N, r, p, maxmem: 257 * 1024 * 1024 }); //257 instead of 256 for buffer for compat for N=262144, r=8, p=1
297
297
  return bytesToHex(new Uint8Array(out));
298
298
  }
299
299
 
@@ -63,6 +63,13 @@ export class BaseWallet extends AbstractSigner {
63
63
  * Wallet - convenience methods around BaseWallet.
64
64
  */
65
65
  export class Wallet extends BaseWallet {
66
+ /**
67
+ * Returns the recommended signing context for this wallet.
68
+ * Setting fullSign to true may incur additional gas cost.
69
+ * @param {boolean|null=} fullSign Defaults to false when null or omitted.
70
+ * @returns {number}
71
+ */
72
+ getSigningContext(fullSign?: boolean | null): number;
66
73
  /**
67
74
  * Creates a new random wallet.
68
75
  * @param {import("../providers/provider").AbstractProvider=} provider
@@ -311,6 +311,24 @@ class Wallet extends BaseWallet {
311
311
  return json;
312
312
  }
313
313
 
314
+ /**
315
+ * Returns the recommended signing context for this wallet.
316
+ * Setting fullSign to true may incur additional gas cost.
317
+ * @param {boolean|null=} fullSign Defaults to false when null or omitted.
318
+ * @returns {number}
319
+ */
320
+ getSigningContext(fullSign) {
321
+ const fs = fullSign ?? false;
322
+ const pubLen = this.signingKey.publicKeyBytes.length;
323
+ if (pubLen === 1408) {
324
+ return fs ? 2 : 0;
325
+ }
326
+ if (pubLen === 2688) {
327
+ return 1;
328
+ }
329
+ throw makeError("unsupported public key size", "UNSUPPORTED_OPERATION", { publicKeyLength: pubLen });
330
+ }
331
+
314
332
  /**
315
333
  * Returns a new wallet connected to a provider.
316
334
  * @param {import("../providers/provider").AbstractProvider} provider
@@ -92,11 +92,11 @@ describe("SigningContext and fee E2E", () => {
92
92
 
93
93
  // --- Phase 2: Send back with signingContext (36: null, 1; 32: null, 0, 2) ---
94
94
  const cases = [
95
- { wallet: wallet36, signingContext: null, label: "36_null" },
96
- { wallet: wallet36, signingContext: 1, label: "36_1" },
97
- { wallet: wallet32, signingContext: null, label: "32_null" },
98
- { wallet: wallet32, signingContext: 0, label: "32_0" },
99
- { wallet: wallet32, signingContext: 2, label: "32_2" },
95
+ { wallet: wallet36, signingContext: wallet36.getSigningContext(), label: "36_null" },
96
+ { wallet: wallet36, signingContext: wallet36.getSigningContext(true), label: "36_1" },
97
+ { wallet: wallet32, signingContext: wallet32.getSigningContext(), label: "32_null" },
98
+ { wallet: wallet32, signingContext: wallet32.getSigningContext(), label: "32_0" },
99
+ { wallet: wallet32, signingContext: wallet32.getSigningContext(true), label: "32_2" },
100
100
  ];
101
101
 
102
102
  const expectedFees = {
@@ -83,11 +83,11 @@ describe("SigningContext and fee E2E", () => {
83
83
  const sendBackValue = SEND_AMOUNT - qc.parseEther("10000");
84
84
 
85
85
  const cases = [
86
- { wallet: wallet36, signingContext: null as number | null, label: "36_null" },
87
- { wallet: wallet36, signingContext: 1, label: "36_1" },
88
- { wallet: wallet32, signingContext: null as number | null, label: "32_null" },
89
- { wallet: wallet32, signingContext: 0, label: "32_0" },
90
- { wallet: wallet32, signingContext: 2, label: "32_2" },
86
+ { wallet: wallet36, signingContext: wallet36.getSigningContext(), label: "36_null" },
87
+ { wallet: wallet36, signingContext: wallet36.getSigningContext(true), label: "36_1" },
88
+ { wallet: wallet32, signingContext: wallet32.getSigningContext(), label: "32_null" },
89
+ { wallet: wallet32, signingContext: wallet32.getSigningContext(), label: "32_0" },
90
+ { wallet: wallet32, signingContext: wallet32.getSigningContext(true), label: "32_2" },
91
91
  ];
92
92
 
93
93
  const expectedFees: Record<string, bigint> = {
@@ -560,5 +560,43 @@ describe("Address + Wallet (offline)", () => {
560
560
  assert.equal(w.address, addr5);
561
561
  assert.equal(qc.isAddress(w.address), true);
562
562
  });
563
+
564
+ // ---------------------------------------------------------------------------
565
+ // getSigningContext
566
+ // ---------------------------------------------------------------------------
567
+
568
+ it("getSigningContext: 32-word wallet (pubKey 1408) returns 0 by default, 2 with fullSign", async () => {
569
+ await Initialize(null);
570
+ const w = qc.Wallet.fromPhrase(TEST_SEED_WORDS_32);
571
+ assert.strictEqual(w.getSigningContext(), 0);
572
+ assert.strictEqual(w.getSigningContext(null), 0);
573
+ assert.strictEqual(w.getSigningContext(false), 0);
574
+ assert.strictEqual(w.getSigningContext(true), 2);
575
+ });
576
+
577
+ it("getSigningContext: 48-word wallet (pubKey 1408) returns 0 by default, 2 with fullSign", async () => {
578
+ await Initialize(null);
579
+ const w = qc.Wallet.fromPhrase(TEST_SEED_WORDS);
580
+ assert.strictEqual(w.getSigningContext(), 0);
581
+ assert.strictEqual(w.getSigningContext(null), 0);
582
+ assert.strictEqual(w.getSigningContext(false), 0);
583
+ assert.strictEqual(w.getSigningContext(true), 2);
584
+ });
585
+
586
+ it("getSigningContext: 36-word wallet (pubKey 2688) returns 1 for all fullSign values", async () => {
587
+ await Initialize(null);
588
+ const w = qc.Wallet.fromPhrase(TEST_SEED_WORDS_36);
589
+ assert.strictEqual(w.getSigningContext(), 1);
590
+ assert.strictEqual(w.getSigningContext(null), 1);
591
+ assert.strictEqual(w.getSigningContext(false), 1);
592
+ assert.strictEqual(w.getSigningContext(true), 1);
593
+ });
594
+
595
+ it("getSigningContext: throws for unsupported public key size", async () => {
596
+ await Initialize(null);
597
+ const w = qc.Wallet.fromPhrase(TEST_SEED_WORDS_32);
598
+ w.signingKey.publicKeyBytes = new Uint8Array(100);
599
+ assert.throws(() => w.getSigningContext(), /unsupported public key size/);
600
+ });
563
601
  });
564
602
 
@@ -546,4 +546,42 @@ describe("Address + Wallet (offline)", () => {
546
546
  assert.equal(w.address, addr5);
547
547
  assert.equal(qc.isAddress(w.address), true);
548
548
  });
549
+
550
+ // ---------------------------------------------------------------------------
551
+ // getSigningContext
552
+ // ---------------------------------------------------------------------------
553
+
554
+ it("getSigningContext: 32-word wallet (pubKey 1408) returns 0 by default, 2 with fullSign", async () => {
555
+ await Initialize(null);
556
+ const w = qc.Wallet.fromPhrase(TEST_SEED_WORDS_32);
557
+ assert.strictEqual(w.getSigningContext(), 0);
558
+ assert.strictEqual(w.getSigningContext(null), 0);
559
+ assert.strictEqual(w.getSigningContext(false), 0);
560
+ assert.strictEqual(w.getSigningContext(true), 2);
561
+ });
562
+
563
+ it("getSigningContext: 48-word wallet (pubKey 1408) returns 0 by default, 2 with fullSign", async () => {
564
+ await Initialize(null);
565
+ const w = qc.Wallet.fromPhrase(TEST_SEED_WORDS);
566
+ assert.strictEqual(w.getSigningContext(), 0);
567
+ assert.strictEqual(w.getSigningContext(null), 0);
568
+ assert.strictEqual(w.getSigningContext(false), 0);
569
+ assert.strictEqual(w.getSigningContext(true), 2);
570
+ });
571
+
572
+ it("getSigningContext: 36-word wallet (pubKey 2688) returns 1 for all fullSign values", async () => {
573
+ await Initialize(null);
574
+ const w = qc.Wallet.fromPhrase(TEST_SEED_WORDS_36);
575
+ assert.strictEqual(w.getSigningContext(), 1);
576
+ assert.strictEqual(w.getSigningContext(null), 1);
577
+ assert.strictEqual(w.getSigningContext(false), 1);
578
+ assert.strictEqual(w.getSigningContext(true), 1);
579
+ });
580
+
581
+ it("getSigningContext: throws for unsupported public key size", async () => {
582
+ await Initialize(null);
583
+ const w = qc.Wallet.fromPhrase(TEST_SEED_WORDS_32);
584
+ (w.signingKey as any).publicKeyBytes = new Uint8Array(100);
585
+ assert.throws(() => w.getSigningContext(), /unsupported public key size/);
586
+ });
549
587
  });
@@ -64,5 +64,12 @@
64
64
  const emptyDigest = qc.hashMessage("");
65
65
  assert.ok(emptyDigest.startsWith("0x") && emptyDigest.length === 66);
66
66
  });
67
+
68
+ it("scryptSync with N=262144, r=8, p=1 produces expected hardcoded output", () => {
69
+ const pw = qc.toUtf8Bytes("password");
70
+ const salt = qc.toUtf8Bytes("salt");
71
+ const out = qc.scryptSync(pw, salt, 262144, 8, 1, 32);
72
+ assert.equal(out, "0xd36e883d93698af49daa529419bb1d97da262bbaa225c12fcf05651268659f42");
73
+ });
67
74
  });
68
75
 
@@ -64,4 +64,11 @@ describe("Hashing", () => {
64
64
  const emptyDigest = qc.hashMessage("");
65
65
  assert.ok(emptyDigest.startsWith("0x") && emptyDigest.length === 66);
66
66
  });
67
+
68
+ it("scryptSync with N=262144, r=8, p=1 produces expected hardcoded output", () => {
69
+ const pw = qc.toUtf8Bytes("password");
70
+ const salt = qc.toUtf8Bytes("salt");
71
+ const out = qc.scryptSync(pw, salt, 262144, 8, 1, 32);
72
+ assert.equal(out, "0xd36e883d93698af49daa529419bb1d97da262bbaa225c12fcf05651268659f42");
73
+ });
67
74
  });