@qrlwallet/connect 5.1.1 → 5.1.2

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.md CHANGED
@@ -286,6 +286,9 @@ npm run dev
286
286
  # Type-check
287
287
  npm run typecheck
288
288
 
289
+ # Type-check tests
290
+ npm run typecheck:test
291
+
289
292
  # Unit tests (vitest)
290
293
  npm test
291
294
 
@@ -296,6 +299,8 @@ npm run lint
296
299
  node test-e2e.mjs
297
300
  ```
298
301
 
302
+ CI runs `node scripts/audit-gate.mjs` after the SDK install and `node scripts/audit-gate.mjs --dir ui` after the UI install; both read `audit-allowlist.json` at the repository root. The gate blocks high and critical production advisories unless a matching, dated exception in `audit-allowlist.json` explains why the advisory cannot reach users.
303
+
299
304
  ## Running the example dApp
300
305
 
301
306
  The `example/` directory contains a Vite test dApp with QR code generation, transaction sending, message signing, and read-only RPC calls.
package/dist/index.js CHANGED
@@ -121,7 +121,8 @@ var import_ml_kem = require("@noble/post-quantum/ml-kem.js");
121
121
  var import_sha3 = require("@noble/hashes/sha3.js");
122
122
  var mldsa = __toESM(require("@theqrl/mldsa87"));
123
123
  function webCrypto() {
124
- const c = globalThis.crypto;
124
+ const environment = globalThis;
125
+ const c = environment.crypto;
125
126
  if (!c) {
126
127
  throw new Error("crypto: WebCrypto is not available in this environment");
127
128
  }
@@ -641,7 +642,8 @@ var KeyExchange = class extends import_eventemitter3.default {
641
642
  this.lastAck = null;
642
643
  this.isOriginator = isOriginator;
643
644
  if (restored) {
644
- if (restored.protocolVersion !== PROTOCOL_VERSION) {
645
+ const protocolVersion = restored.protocolVersion;
646
+ if (protocolVersion !== PROTOCOL_VERSION) {
645
647
  throw new Error("KeyExchange: cannot restore a pre-v3 session");
646
648
  }
647
649
  this.session = snapshotSession(restored);
@@ -975,7 +977,8 @@ var KeyExchange = class extends import_eventemitter3.default {
975
977
  }
976
978
  /** Rehydrate a Session from its persisted form. */
977
979
  static async sessionFromPersisted(p) {
978
- if (p.protocolVersion !== PROTOCOL_VERSION) {
980
+ const protocolVersion = p.protocolVersion;
981
+ if (protocolVersion !== PROTOCOL_VERSION) {
979
982
  throw new Error("KeyExchange: cannot hydrate a pre-v3 session");
980
983
  }
981
984
  const kAeadRaw = fromBase64Exact(p.kAeadRaw, 32, "persisted AEAD key");
@@ -1553,7 +1556,12 @@ function startsWith(buf, prefix) {
1553
1556
  }
1554
1557
  return true;
1555
1558
  }
1556
- async function parseConnectionURI(uri) {
1559
+ function parseConnectionURI(uri) {
1560
+ return new Promise((resolve) => {
1561
+ resolve(parseURI(uri));
1562
+ });
1563
+ }
1564
+ function parseURI(uri) {
1557
1565
  if (typeof uri !== "string" || uri.length === 0) {
1558
1566
  throw new Error("qrUri: empty URI");
1559
1567
  }
@@ -1598,7 +1606,7 @@ async function parseConnectionURI(uri) {
1598
1606
  blob = base45Decode(q);
1599
1607
  } catch (err) {
1600
1608
  const msg = err instanceof Error ? err.message : String(err);
1601
- throw new Error(`qrUri: base45 decode failed: ${msg}`);
1609
+ throw new Error(`qrUri: base45 decode failed: ${msg}`, { cause: err });
1602
1610
  }
1603
1611
  try {
1604
1612
  if (blob.length !== BLOB_LEN) {
@@ -1671,7 +1679,8 @@ function getBrowserStorage() {
1671
1679
  function getBrowserLockManager() {
1672
1680
  try {
1673
1681
  if (typeof navigator === "undefined") return null;
1674
- return navigator.locks ?? null;
1682
+ const browserNavigator = navigator;
1683
+ return browserNavigator.locks ?? null;
1675
1684
  } catch {
1676
1685
  return null;
1677
1686
  }
@@ -2012,7 +2021,8 @@ var _ConnectionManager = class _ConnectionManager extends import_eventemitter33.
2012
2021
  });
2013
2022
  socketClient.on("participants_changed", (data) => {
2014
2023
  if (!isCurrentSocket()) return;
2015
- if (data.clientType !== "wallet") return;
2024
+ const clientType = data.clientType;
2025
+ if (clientType !== "wallet") return;
2016
2026
  if (data.event === "join" && data.clientType === "wallet") {
2017
2027
  this.walletPresent = true;
2018
2028
  log("ConnectionManager", "Wallet joined channel");
@@ -2179,7 +2189,8 @@ var _ConnectionManager = class _ConnectionManager extends import_eventemitter33.
2179
2189
  log("ConnectionManager", `Generated v3 connection URI for channel ${context.channelId}`);
2180
2190
  return uri;
2181
2191
  } catch (err) {
2182
- if (context ? this.isSessionWorkCurrent(context) : this.keyExchange !== null) {
2192
+ const keyExchange = this.keyExchange;
2193
+ if (context ? this.isSessionWorkCurrent(context) : keyExchange !== null) {
2183
2194
  this.invalidateSessionWork();
2184
2195
  this.keyExchange = null;
2185
2196
  this.socketClient.leaveChannel();
@@ -3001,7 +3012,7 @@ var _ConnectionManager = class _ConnectionManager extends import_eventemitter33.
3001
3012
  const persistedKex = await context.keyExchange.exportPersisted();
3002
3013
  if (!persistedKex) throw new Error("Cannot export established AEAD session");
3003
3014
  this.assertSessionWorkCurrent(context);
3004
- if (!this.sessionOwnership?.isOwned()) {
3015
+ if (!this.sessionOwnership.isOwned()) {
3005
3016
  throw new Error("Browser-tab ownership changed while persisting AEAD counters");
3006
3017
  }
3007
3018
  const session = {
@@ -3020,7 +3031,7 @@ var _ConnectionManager = class _ConnectionManager extends import_eventemitter33.
3020
3031
  this.persistenceBroken = true;
3021
3032
  this.removeStoredSession();
3022
3033
  error("ConnectionManager", "Failed to persist AEAD counters:", err);
3023
- throw new Error("Failed to persist AEAD counters");
3034
+ throw new Error("Failed to persist AEAD counters", { cause: err });
3024
3035
  }
3025
3036
  }
3026
3037
  readStoredSession() {
@@ -3702,7 +3713,8 @@ function canonicalChainId2(value) {
3702
3713
  return `0x${BigInt(value).toString(16)}`;
3703
3714
  }
3704
3715
  function requestedSwitchChainId(params) {
3705
- if (params?.length !== 1) {
3716
+ const parameterCount = params?.length;
3717
+ if (parameterCount !== 1) {
3706
3718
  throw new Error("wallet_switchQrlChain requires one chain configuration object");
3707
3719
  }
3708
3720
  const request = params?.[0];
@@ -3768,7 +3780,7 @@ function snapshotRequestParams(params) {
3768
3780
  return snapshot;
3769
3781
  } catch (error2) {
3770
3782
  const detail = error2 instanceof Error ? error2.message : String(error2);
3771
- throw new Error(`Request params must be JSON-serializable: ${detail}`);
3783
+ throw new Error(`Request params must be JSON-serializable: ${detail}`, { cause: error2 });
3772
3784
  }
3773
3785
  }
3774
3786
  function validateRestrictedRequest(method, params, authorizedAccounts, currentChainId) {
package/dist/index.mjs CHANGED
@@ -12,7 +12,8 @@ import { ml_kem768 } from "@noble/post-quantum/ml-kem.js";
12
12
  import { shake256 } from "@noble/hashes/sha3.js";
13
13
  import * as mldsa from "@theqrl/mldsa87";
14
14
  function webCrypto() {
15
- const c = globalThis.crypto;
15
+ const environment = globalThis;
16
+ const c = environment.crypto;
16
17
  if (!c) {
17
18
  throw new Error("crypto: WebCrypto is not available in this environment");
18
19
  }
@@ -532,7 +533,8 @@ var KeyExchange = class extends EventEmitter {
532
533
  this.lastAck = null;
533
534
  this.isOriginator = isOriginator;
534
535
  if (restored) {
535
- if (restored.protocolVersion !== PROTOCOL_VERSION) {
536
+ const protocolVersion = restored.protocolVersion;
537
+ if (protocolVersion !== PROTOCOL_VERSION) {
536
538
  throw new Error("KeyExchange: cannot restore a pre-v3 session");
537
539
  }
538
540
  this.session = snapshotSession(restored);
@@ -866,7 +868,8 @@ var KeyExchange = class extends EventEmitter {
866
868
  }
867
869
  /** Rehydrate a Session from its persisted form. */
868
870
  static async sessionFromPersisted(p) {
869
- if (p.protocolVersion !== PROTOCOL_VERSION) {
871
+ const protocolVersion = p.protocolVersion;
872
+ if (protocolVersion !== PROTOCOL_VERSION) {
870
873
  throw new Error("KeyExchange: cannot hydrate a pre-v3 session");
871
874
  }
872
875
  const kAeadRaw = fromBase64Exact(p.kAeadRaw, 32, "persisted AEAD key");
@@ -1444,7 +1447,12 @@ function startsWith(buf, prefix) {
1444
1447
  }
1445
1448
  return true;
1446
1449
  }
1447
- async function parseConnectionURI(uri) {
1450
+ function parseConnectionURI(uri) {
1451
+ return new Promise((resolve) => {
1452
+ resolve(parseURI(uri));
1453
+ });
1454
+ }
1455
+ function parseURI(uri) {
1448
1456
  if (typeof uri !== "string" || uri.length === 0) {
1449
1457
  throw new Error("qrUri: empty URI");
1450
1458
  }
@@ -1489,7 +1497,7 @@ async function parseConnectionURI(uri) {
1489
1497
  blob = base45Decode(q);
1490
1498
  } catch (err) {
1491
1499
  const msg = err instanceof Error ? err.message : String(err);
1492
- throw new Error(`qrUri: base45 decode failed: ${msg}`);
1500
+ throw new Error(`qrUri: base45 decode failed: ${msg}`, { cause: err });
1493
1501
  }
1494
1502
  try {
1495
1503
  if (blob.length !== BLOB_LEN) {
@@ -1562,7 +1570,8 @@ function getBrowserStorage() {
1562
1570
  function getBrowserLockManager() {
1563
1571
  try {
1564
1572
  if (typeof navigator === "undefined") return null;
1565
- return navigator.locks ?? null;
1573
+ const browserNavigator = navigator;
1574
+ return browserNavigator.locks ?? null;
1566
1575
  } catch {
1567
1576
  return null;
1568
1577
  }
@@ -1903,7 +1912,8 @@ var _ConnectionManager = class _ConnectionManager extends EventEmitter3 {
1903
1912
  });
1904
1913
  socketClient.on("participants_changed", (data) => {
1905
1914
  if (!isCurrentSocket()) return;
1906
- if (data.clientType !== "wallet") return;
1915
+ const clientType = data.clientType;
1916
+ if (clientType !== "wallet") return;
1907
1917
  if (data.event === "join" && data.clientType === "wallet") {
1908
1918
  this.walletPresent = true;
1909
1919
  log("ConnectionManager", "Wallet joined channel");
@@ -2070,7 +2080,8 @@ var _ConnectionManager = class _ConnectionManager extends EventEmitter3 {
2070
2080
  log("ConnectionManager", `Generated v3 connection URI for channel ${context.channelId}`);
2071
2081
  return uri;
2072
2082
  } catch (err) {
2073
- if (context ? this.isSessionWorkCurrent(context) : this.keyExchange !== null) {
2083
+ const keyExchange = this.keyExchange;
2084
+ if (context ? this.isSessionWorkCurrent(context) : keyExchange !== null) {
2074
2085
  this.invalidateSessionWork();
2075
2086
  this.keyExchange = null;
2076
2087
  this.socketClient.leaveChannel();
@@ -2892,7 +2903,7 @@ var _ConnectionManager = class _ConnectionManager extends EventEmitter3 {
2892
2903
  const persistedKex = await context.keyExchange.exportPersisted();
2893
2904
  if (!persistedKex) throw new Error("Cannot export established AEAD session");
2894
2905
  this.assertSessionWorkCurrent(context);
2895
- if (!this.sessionOwnership?.isOwned()) {
2906
+ if (!this.sessionOwnership.isOwned()) {
2896
2907
  throw new Error("Browser-tab ownership changed while persisting AEAD counters");
2897
2908
  }
2898
2909
  const session = {
@@ -2911,7 +2922,7 @@ var _ConnectionManager = class _ConnectionManager extends EventEmitter3 {
2911
2922
  this.persistenceBroken = true;
2912
2923
  this.removeStoredSession();
2913
2924
  error("ConnectionManager", "Failed to persist AEAD counters:", err);
2914
- throw new Error("Failed to persist AEAD counters");
2925
+ throw new Error("Failed to persist AEAD counters", { cause: err });
2915
2926
  }
2916
2927
  }
2917
2928
  readStoredSession() {
@@ -3593,7 +3604,8 @@ function canonicalChainId2(value) {
3593
3604
  return `0x${BigInt(value).toString(16)}`;
3594
3605
  }
3595
3606
  function requestedSwitchChainId(params) {
3596
- if (params?.length !== 1) {
3607
+ const parameterCount = params?.length;
3608
+ if (parameterCount !== 1) {
3597
3609
  throw new Error("wallet_switchQrlChain requires one chain configuration object");
3598
3610
  }
3599
3611
  const request = params?.[0];
@@ -3659,7 +3671,7 @@ function snapshotRequestParams(params) {
3659
3671
  return snapshot;
3660
3672
  } catch (error2) {
3661
3673
  const detail = error2 instanceof Error ? error2.message : String(error2);
3662
- throw new Error(`Request params must be JSON-serializable: ${detail}`);
3674
+ throw new Error(`Request params must be JSON-serializable: ${detail}`, { cause: error2 });
3663
3675
  }
3664
3676
  }
3665
3677
  function validateRestrictedRequest(method, params, authorizedAccounts, currentChainId) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qrlwallet/connect",
3
- "version": "5.1.1",
3
+ "version": "5.1.2",
4
4
  "packageManager": "npm@10.9.8",
5
5
  "description": "Connect your dApp to QRL Wallet via QR code or deep link",
6
6
  "main": "dist/index.js",
@@ -13,16 +13,19 @@
13
13
  "scripts": {
14
14
  "build": "tsup src/index.ts --format cjs,esm --dts --clean",
15
15
  "dev": "tsup src/index.ts --format cjs,esm --dts --watch",
16
- "typecheck": "tsc --noEmit",
16
+ "typecheck": "tsc --noEmit && npm run typecheck:test",
17
+ "typecheck:test": "tsc --noEmit -p tsconfig.eslint.json",
17
18
  "test": "vitest run",
18
19
  "test:watch": "vitest",
19
- "lint": "eslint src/ test/ --ext .ts",
20
- "lint:fix": "eslint src/ test/ --ext .ts --fix",
20
+ "lint": "eslint --config eslint.config.mjs src test scripts \"*.mjs\" vitest.config.ts --report-unused-disable-directives --max-warnings 0",
21
+ "lint:fix": "eslint --config eslint.config.mjs src test scripts \"*.mjs\" vitest.config.ts --report-unused-disable-directives --max-warnings 0 --fix",
21
22
  "format": "prettier --write src/",
22
23
  "format:check": "prettier --check src/",
23
24
  "size": "size-limit",
24
25
  "size:check": "size-limit --highlight-less",
25
- "prepublishOnly": "npm run lint && npm run typecheck && npm test && npm run build"
26
+ "prepublishOnly": "npm run lint && npm run typecheck && npm test && npm run build",
27
+ "lint:ratchet": "node scripts/lint-ratchet.mjs --check",
28
+ "lint:ratchet:update": "node scripts/lint-ratchet.mjs"
26
29
  },
27
30
  "keywords": [
28
31
  "qrl",
@@ -49,13 +52,15 @@
49
52
  "socket.io-client": "^4.8.1"
50
53
  },
51
54
  "devDependencies": {
55
+ "@eslint/js": "^10.0.1",
52
56
  "@size-limit/file": "^11.0.0",
53
57
  "@theqrl/wallet.js": "^6.3.0",
54
58
  "@types/node": "^25.3.3",
55
59
  "@typescript-eslint/eslint-plugin": "^8.0.0",
56
60
  "@typescript-eslint/parser": "^8.0.0",
57
- "eslint": "^8.57.0",
61
+ "eslint": "^10.12.0",
58
62
  "eslint-config-prettier": "^9.1.0",
63
+ "globals": "^17.13.0",
59
64
  "prettier": "^3.4.0",
60
65
  "size-limit": "^11.0.0",
61
66
  "tsup": "^8.4.0",