decane-connect-kit 2.24.1 → 2.25.0

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/dist/index.cjs CHANGED
@@ -2416,6 +2416,54 @@ var import_browser = require("@simplewebauthn/browser");
2416
2416
 
2417
2417
  // src/social/attestation.ts
2418
2418
  var import_dcap_qvl = require("@phala/dcap-qvl");
2419
+
2420
+ // src/social/collateralCache.ts
2421
+ var CACHE_PREFIX = "decane:collateral:v1:";
2422
+ var COLLATERAL_TTL_MS = 12 * 60 * 60 * 1e3;
2423
+ function storage() {
2424
+ try {
2425
+ return typeof localStorage !== "undefined" ? localStorage : null;
2426
+ } catch {
2427
+ return null;
2428
+ }
2429
+ }
2430
+ function keyFor(teeUrl) {
2431
+ return `${CACHE_PREFIX}${teeUrl}`;
2432
+ }
2433
+ function readCollateral(teeUrl) {
2434
+ const store = storage();
2435
+ if (!store) return null;
2436
+ try {
2437
+ const raw = store.getItem(keyFor(teeUrl));
2438
+ if (!raw) return null;
2439
+ const entry = JSON.parse(raw);
2440
+ if (!entry?.at || Date.now() - entry.at > COLLATERAL_TTL_MS) {
2441
+ store.removeItem(keyFor(teeUrl));
2442
+ return null;
2443
+ }
2444
+ return entry.collateral ?? null;
2445
+ } catch {
2446
+ return null;
2447
+ }
2448
+ }
2449
+ function writeCollateral(teeUrl, collateral) {
2450
+ const store = storage();
2451
+ if (!store) return;
2452
+ try {
2453
+ store.setItem(keyFor(teeUrl), JSON.stringify({ at: Date.now(), collateral }));
2454
+ } catch {
2455
+ }
2456
+ }
2457
+ function dropCollateral(teeUrl) {
2458
+ const store = storage();
2459
+ if (!store) return;
2460
+ try {
2461
+ store.removeItem(keyFor(teeUrl));
2462
+ } catch {
2463
+ }
2464
+ }
2465
+
2466
+ // src/social/attestation.ts
2419
2467
  init_errors();
2420
2468
 
2421
2469
  // ../../infra/tee-measurement.json
@@ -2443,6 +2491,9 @@ function hexToBytes(hex) {
2443
2491
  function bytesToHex(bytes) {
2444
2492
  return Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
2445
2493
  }
2494
+ function nowSeconds() {
2495
+ return Math.floor(Date.now() / 1e3);
2496
+ }
2446
2497
  async function verifyTeeAttestation(teeUrl, nonce) {
2447
2498
  const res = await fetch(`${teeUrl}/attestation`, {
2448
2499
  method: "POST",
@@ -2452,9 +2503,22 @@ async function verifyTeeAttestation(teeUrl, nonce) {
2452
2503
  if (!res.ok) throw new AttestationError("quote fetch failed");
2453
2504
  const { quote, measurement } = await res.json();
2454
2505
  let verified;
2506
+ const cached = readCollateral(teeUrl);
2455
2507
  try {
2456
- verified = await (0, import_dcap_qvl.getCollateralAndVerify)(hexToBytes(quote));
2457
- } catch {
2508
+ if (cached) {
2509
+ try {
2510
+ verified = await (0, import_dcap_qvl.verify)(hexToBytes(quote), cached, nowSeconds());
2511
+ } catch {
2512
+ dropCollateral(teeUrl);
2513
+ verified = await (0, import_dcap_qvl.getCollateralAndVerify)(hexToBytes(quote));
2514
+ }
2515
+ } else {
2516
+ const collateral = await (0, import_dcap_qvl.getCollateral)(import_dcap_qvl.PHALA_PCCS_URL, hexToBytes(quote));
2517
+ verified = await (0, import_dcap_qvl.verify)(hexToBytes(quote), collateral, nowSeconds());
2518
+ writeCollateral(teeUrl, collateral);
2519
+ }
2520
+ } catch (e) {
2521
+ if (e instanceof AttestationError) throw e;
2458
2522
  throw new AttestationError("quote signature invalid");
2459
2523
  }
2460
2524
  if (verified.status === "Revoked") {
@@ -2496,14 +2560,51 @@ async function teeFetch(url, init) {
2496
2560
  }
2497
2561
  var ATTESTATION_TTL_MS = 10 * 6e4;
2498
2562
  var attestationCache = /* @__PURE__ */ new Map();
2563
+ var ATTESTATION_PERSIST_PREFIX = "decane:attested:v1:";
2564
+ function persistedAt(teeUrl) {
2565
+ try {
2566
+ if (typeof sessionStorage === "undefined") return null;
2567
+ const raw = sessionStorage.getItem(ATTESTATION_PERSIST_PREFIX + teeUrl);
2568
+ const at = raw ? Number(raw) : NaN;
2569
+ return Number.isFinite(at) ? at : null;
2570
+ } catch {
2571
+ return null;
2572
+ }
2573
+ }
2574
+ function rememberAttested(teeUrl, at) {
2575
+ try {
2576
+ if (typeof sessionStorage !== "undefined") {
2577
+ sessionStorage.setItem(ATTESTATION_PERSIST_PREFIX + teeUrl, String(at));
2578
+ }
2579
+ } catch {
2580
+ }
2581
+ }
2582
+ function forgetAttested(teeUrl) {
2583
+ try {
2584
+ if (typeof sessionStorage !== "undefined") {
2585
+ sessionStorage.removeItem(ATTESTATION_PERSIST_PREFIX + teeUrl);
2586
+ }
2587
+ } catch {
2588
+ }
2589
+ }
2499
2590
  function attestOnce(teeUrl, verify) {
2500
2591
  const hit = attestationCache.get(teeUrl);
2501
2592
  if (hit && Date.now() - hit.at < ATTESTATION_TTL_MS) return hit.promise;
2502
- const promise = verify().catch((e) => {
2593
+ const at = persistedAt(teeUrl);
2594
+ if (at && Date.now() - at < ATTESTATION_TTL_MS) {
2595
+ const resolved = Promise.resolve();
2596
+ attestationCache.set(teeUrl, { at, promise: resolved });
2597
+ return resolved;
2598
+ }
2599
+ const startedAt = Date.now();
2600
+ const promise = verify().then(() => {
2601
+ rememberAttested(teeUrl, startedAt);
2602
+ }).catch((e) => {
2503
2603
  attestationCache.delete(teeUrl);
2604
+ forgetAttested(teeUrl);
2504
2605
  throw e;
2505
2606
  });
2506
- attestationCache.set(teeUrl, { at: Date.now(), promise });
2607
+ attestationCache.set(teeUrl, { at: startedAt, promise });
2507
2608
  return promise;
2508
2609
  }
2509
2610
  function prewarmAttestation(teeUrl) {
@@ -3775,29 +3876,44 @@ function clearLastUser(key) {
3775
3876
  function sessionPersistKey(apiKey) {
3776
3877
  return `decane:sess:${apiKey.slice(0, 20)}`;
3777
3878
  }
3879
+ var sessionStore = () => typeof sessionStorage !== "undefined" ? sessionStorage : null;
3880
+ function useCrossTabSessionStore(enabled) {
3881
+ sessionStore = enabled ? () => typeof localStorage !== "undefined" ? localStorage : null : () => typeof sessionStorage !== "undefined" ? sessionStorage : null;
3882
+ }
3778
3883
  function loadSession(key) {
3779
3884
  try {
3780
- const raw = typeof sessionStorage !== "undefined" ? sessionStorage.getItem(key) : null;
3781
- return raw ? JSON.parse(raw) : null;
3885
+ const raw = sessionStore()?.getItem(key) ?? (typeof sessionStorage !== "undefined" ? sessionStorage.getItem(key) : null) ?? (typeof localStorage !== "undefined" ? localStorage.getItem(key) : null);
3886
+ if (!raw) return null;
3887
+ const parsed = JSON.parse(raw);
3888
+ if (parsed?.expiresAt && parsed.expiresAt <= Date.now()) {
3889
+ clearSessionPersist(key);
3890
+ return null;
3891
+ }
3892
+ return parsed;
3782
3893
  } catch {
3783
3894
  return null;
3784
3895
  }
3785
3896
  }
3786
3897
  function saveSession(key, s) {
3787
3898
  try {
3788
- sessionStorage.setItem(key, JSON.stringify(s));
3899
+ sessionStore()?.setItem(key, JSON.stringify(s));
3789
3900
  } catch {
3790
3901
  }
3791
3902
  }
3792
3903
  function clearSessionPersist(key) {
3793
3904
  try {
3794
- sessionStorage.removeItem(key);
3905
+ if (typeof sessionStorage !== "undefined") sessionStorage.removeItem(key);
3906
+ } catch {
3907
+ }
3908
+ try {
3909
+ if (typeof localStorage !== "undefined") localStorage.removeItem(key);
3795
3910
  } catch {
3796
3911
  }
3797
3912
  }
3798
3913
  async function createDecaneConnect(config) {
3799
3914
  if (!config.appId) throw new Error("decane-connect-kit: appId is required");
3800
3915
  if (!config.apiKey) throw new Error("decane-connect-kit: apiKey is required");
3916
+ useCrossTabSessionStore(config.resumeSessionAcrossTabs === true);
3801
3917
  if (!config.chains?.length)
3802
3918
  throw new Error("decane-connect-kit: at least one chain is required");
3803
3919
  if (config.rotateOnNewDeviceRecovery && !config.onRecoveryRotated) {
@@ -3816,7 +3932,7 @@ async function createDecaneConnect(config) {
3816
3932
  const teeUrl = config.teeUrl ?? DEFAULT_TEE_URL;
3817
3933
  const events = new EventEmitter();
3818
3934
  const api = new ApiClient(baseUrl, config.apiKey, config.appId);
3819
- const storage = new Storage();
3935
+ const storage2 = new Storage();
3820
3936
  const session = new SessionManager(
3821
3937
  events,
3822
3938
  durationMs,
@@ -3959,7 +4075,7 @@ async function createDecaneConnect(config) {
3959
4075
  }
3960
4076
  async function attachUnlockToken(userId, jwt, tokenKey) {
3961
4077
  try {
3962
- const stored = await storage.getShare(userId);
4078
+ const stored = await storage2.getShare(userId);
3963
4079
  if (!stored) return;
3964
4080
  const { token } = await api.issueUnlockToken(jwt);
3965
4081
  const unlockTokenIv = generateRandomBytes(12);
@@ -3968,13 +4084,13 @@ async function createDecaneConnect(config) {
3968
4084
  new TextEncoder().encode(token),
3969
4085
  unlockTokenIv
3970
4086
  );
3971
- await storage.putShare({ ...stored, wrappedUnlockToken, unlockTokenIv });
4087
+ await storage2.putShare({ ...stored, wrappedUnlockToken, unlockTokenIv });
3972
4088
  } catch (e) {
3973
4089
  console.warn("decane-connect-kit: could not store an unlock token for this device.", e);
3974
4090
  }
3975
4091
  }
3976
4092
  async function persistRotatedDeviceShare(userId, deviceShare) {
3977
- const stored = await storage.getShare(userId);
4093
+ const stored = await storage2.getShare(userId);
3978
4094
  if (!stored) {
3979
4095
  throw new CallSequenceError(
3980
4096
  "Share set was rotated but this device has no stored share to update. Recover the wallet on this device before rotating."
@@ -3983,21 +4099,21 @@ async function createDecaneConnect(config) {
3983
4099
  const wrappingKey = await getWrappingKey(stored);
3984
4100
  const iv = generateRandomBytes(12);
3985
4101
  const wrappedDeviceShare = await aesGcmEncrypt(wrappingKey, deviceShare, iv);
3986
- await storage.putShare({ ...stored, wrappedDeviceShare, iv });
4102
+ await storage2.putShare({ ...stored, wrappedDeviceShare, iv });
3987
4103
  }
3988
4104
  function hasPasswordUnlock(stored) {
3989
4105
  return !!stored && stored.unlockMethod === "password" && !!stored.passwordSalt && !!stored.wrappedUnlockToken && !!stored.unlockTokenIv;
3990
4106
  }
3991
4107
  async function passwordDeviceCandidate() {
3992
4108
  if (persisted?.userId) {
3993
- const stored = await storage.getShare(persisted.userId);
4109
+ const stored = await storage2.getShare(persisted.userId);
3994
4110
  return hasPasswordUnlock(stored) ? stored : null;
3995
4111
  }
3996
4112
  if (lastUserId) {
3997
- const stored = await storage.getShare(lastUserId);
4113
+ const stored = await storage2.getShare(lastUserId);
3998
4114
  return hasPasswordUnlock(stored) ? stored : null;
3999
4115
  }
4000
- const candidates = (await storage.listShares()).filter(hasPasswordUnlock);
4116
+ const candidates = (await storage2.listShares()).filter(hasPasswordUnlock);
4001
4117
  return candidates.length === 1 ? candidates[0] : null;
4002
4118
  }
4003
4119
  async function getWrappingKey(stored) {
@@ -4025,7 +4141,7 @@ async function createDecaneConnect(config) {
4025
4141
  let credentialId;
4026
4142
  let prfOutput;
4027
4143
  try {
4028
- const label = (await storage.getShare(userId))?.profile?.email;
4144
+ const label = (await storage2.getShare(userId))?.profile?.email;
4029
4145
  ({ credentialId, prfOutput } = await registerWebAuthnCredential({
4030
4146
  api,
4031
4147
  jwt,
@@ -4057,8 +4173,8 @@ async function createDecaneConnect(config) {
4057
4173
  const wrappingKey = await importAesKey(prfOutput);
4058
4174
  const iv = generateRandomBytes(12);
4059
4175
  const wrappedDeviceShare = await aesGcmEncrypt(wrappingKey, deviceShare, iv);
4060
- const existing = await storage.getShare(userId);
4061
- await storage.putShare({
4176
+ const existing = await storage2.getShare(userId);
4177
+ await storage2.putShare({
4062
4178
  ...existing,
4063
4179
  userId,
4064
4180
  wrappedDeviceShare,
@@ -4142,7 +4258,7 @@ async function createDecaneConnect(config) {
4142
4258
  const { wrappingKey, tokenKey, meta } = await passwordSetup();
4143
4259
  const iv = generateRandomBytes(12);
4144
4260
  const wrappedDeviceShare = await aesGcmEncrypt(wrappingKey, deviceShare, iv);
4145
- await storage.putShare({
4261
+ await storage2.putShare({
4146
4262
  userId,
4147
4263
  wrappedDeviceShare,
4148
4264
  iv,
@@ -4216,7 +4332,7 @@ async function createDecaneConnect(config) {
4216
4332
  shareSet.device,
4217
4333
  iv
4218
4334
  );
4219
- await storage.putShare({
4335
+ await storage2.putShare({
4220
4336
  userId,
4221
4337
  wrappedDeviceShare,
4222
4338
  iv,
@@ -4320,7 +4436,7 @@ async function createDecaneConnect(config) {
4320
4436
  async function returningUserUnlock(userId, jwt) {
4321
4437
  const rawAddresses = await api.getAddresses(jwt);
4322
4438
  const recordedAddresses = rawAddresses.evm && rawAddresses.solana ? { evm: rawAddresses.evm, solana: rawAddresses.solana, tron: rawAddresses.tron ?? evmToTronAddress2(rawAddresses.evm) } : null;
4323
- const stored = await storage.getShare(userId);
4439
+ const stored = await storage2.getShare(userId);
4324
4440
  let deviceShare;
4325
4441
  let joinedViaPasskeySync = false;
4326
4442
  if (!stored) {
@@ -4359,7 +4475,7 @@ async function createDecaneConnect(config) {
4359
4475
  rpId,
4360
4476
  teeUrl,
4361
4477
  api,
4362
- storage,
4478
+ storage: storage2,
4363
4479
  onProgress: config.onRecoveryProgress,
4364
4480
  promptForRecoveryFile: config.promptForRecoveryFile,
4365
4481
  onNewRecoveryShare: async (recoveryShare, shareSetVersion) => {
@@ -4373,7 +4489,7 @@ async function createDecaneConnect(config) {
4373
4489
  });
4374
4490
  deviceShare = recovered.deviceShare;
4375
4491
  joinedViaPasskeySync = recovered.flow === "passkey-sync";
4376
- if (!deferDeviceProtection && !await storage.getShare(userId) && isPasskeySupported()) {
4492
+ if (!deferDeviceProtection && !await storage2.getShare(userId) && isPasskeySupported()) {
4377
4493
  await registerPasskeyAndBackup(userId, jwt, deviceShare);
4378
4494
  }
4379
4495
  } else {
@@ -4394,7 +4510,7 @@ async function createDecaneConnect(config) {
4394
4510
  } catch (e) {
4395
4511
  if (e instanceof StaleDeviceShareError) {
4396
4512
  zeroize(deviceShare);
4397
- await storage.deleteShare(userId);
4513
+ await storage2.deleteShare(userId);
4398
4514
  if (stored) return returningUserUnlock(userId, jwt);
4399
4515
  } else {
4400
4516
  zeroize(deviceShare);
@@ -4418,7 +4534,7 @@ async function createDecaneConnect(config) {
4418
4534
  const result = await tee.rotateShares(jwt);
4419
4535
  try {
4420
4536
  await persistRotatedDeviceShare(userId, result.deviceShare);
4421
- const refreshed = await storage.getShare(userId);
4537
+ const refreshed = await storage2.getShare(userId);
4422
4538
  if (refreshed?.unlockMethod === "passkey" && refreshed.credentialId && refreshed.prfSalt) {
4423
4539
  await api.putRecoveryBackup(jwt, {
4424
4540
  wrappedDeviceShare: refreshed.wrappedDeviceShare,
@@ -4451,13 +4567,13 @@ async function createDecaneConnect(config) {
4451
4567
  }
4452
4568
  async function passkeyLoginCandidate() {
4453
4569
  if (!persisted?.userId || !isPasskeySupported()) return null;
4454
- return usablePasskeyShare(await storage.getShare(persisted.userId));
4570
+ return usablePasskeyShare(await storage2.getShare(persisted.userId));
4455
4571
  }
4456
4572
  async function passkeyDeviceCandidate() {
4457
4573
  if (!isPasskeySupported()) return null;
4458
4574
  if (persisted?.userId) return passkeyLoginCandidate();
4459
- if (lastUserId) return usablePasskeyShare(await storage.getShare(lastUserId));
4460
- const candidates = (await storage.listShares()).map(usablePasskeyShare).filter(Boolean);
4575
+ if (lastUserId) return usablePasskeyShare(await storage2.getShare(lastUserId));
4576
+ const candidates = (await storage2.listShares()).map(usablePasskeyShare).filter(Boolean);
4461
4577
  return candidates.length === 1 ? candidates[0] : null;
4462
4578
  }
4463
4579
  async function canOfferPasskey() {
@@ -4465,15 +4581,15 @@ async function createDecaneConnect(config) {
4465
4581
  if (await passkeyDeviceCandidate()) return true;
4466
4582
  const known = persisted?.userId ?? lastUserId;
4467
4583
  if (!known) return false;
4468
- return await storage.getShare(known) == null;
4584
+ return await storage2.getShare(known) == null;
4469
4585
  }
4470
4586
  async function rememberProfile(userId, profile) {
4471
4587
  const incoming = Object.fromEntries(Object.entries(profile).filter(([, v]) => v));
4472
4588
  if (!Object.keys(incoming).length) return;
4473
4589
  try {
4474
- const stored = await storage.getShare(userId);
4590
+ const stored = await storage2.getShare(userId);
4475
4591
  if (!stored) return;
4476
- await storage.putShare({ ...stored, profile: { ...stored.profile, ...incoming } });
4592
+ await storage2.putShare({ ...stored, profile: { ...stored.profile, ...incoming } });
4477
4593
  } catch {
4478
4594
  }
4479
4595
  }
@@ -4497,7 +4613,7 @@ async function createDecaneConnect(config) {
4497
4613
  savePersisted(PERSIST_KEY, persisted);
4498
4614
  events.emit("connected");
4499
4615
  persistLiveSession();
4500
- const stored = await storage.getShare(userId);
4616
+ const stored = await storage2.getShare(userId);
4501
4617
  return {
4502
4618
  addresses,
4503
4619
  isNewUser: false,
@@ -4670,7 +4786,7 @@ async function createDecaneConnect(config) {
4670
4786
  events.emit("connected");
4671
4787
  persistLiveSession();
4672
4788
  scheduleAccessTokenExpiry(token, claims.expiresAt);
4673
- const stored = await storage.getShare(claims.userId);
4789
+ const stored = await storage2.getShare(claims.userId);
4674
4790
  return {
4675
4791
  addresses,
4676
4792
  isNewUser: false,
@@ -4700,7 +4816,7 @@ async function createDecaneConnect(config) {
4700
4816
  const candidate = await passkeyDeviceCandidate();
4701
4817
  if (candidate) return passkeyLogin(candidate);
4702
4818
  const known = persisted?.userId ?? lastUserId;
4703
- if (isPasskeySupported() && known && await storage.getShare(known) == null) {
4819
+ if (isPasskeySupported() && known && await storage2.getShare(known) == null) {
4704
4820
  return passkeyLoginWithoutShare(known);
4705
4821
  }
4706
4822
  throw new NewDeviceError();
@@ -4719,7 +4835,7 @@ async function createDecaneConnect(config) {
4719
4835
  async setUnlockPassword(password) {
4720
4836
  if (!auth) throw new ReconnectRequiredError();
4721
4837
  validateUnlockPassword(password);
4722
- const stored = await storage.getShare(auth.userId);
4838
+ const stored = await storage2.getShare(auth.userId);
4723
4839
  if (!stored) throw new NewDeviceError();
4724
4840
  const deviceShare = await aesGcmDecrypt(
4725
4841
  await getWrappingKey(stored),
@@ -4738,7 +4854,7 @@ async function createDecaneConnect(config) {
4738
4854
  );
4739
4855
  const iv = generateRandomBytes(12);
4740
4856
  const wrappedDeviceShare = await aesGcmEncrypt(shareKey, deviceShare, iv);
4741
- await storage.putShare({
4857
+ await storage2.putShare({
4742
4858
  ...stored,
4743
4859
  unlockMethod: "password",
4744
4860
  wrappedDeviceShare,
@@ -4818,9 +4934,9 @@ async function createDecaneConnect(config) {
4818
4934
  async removeUnlockPassword() {
4819
4935
  if (!auth) throw new ReconnectRequiredError();
4820
4936
  await api.revokeUnlockTokens(auth.jwt);
4821
- const stored = await storage.getShare(auth.userId);
4937
+ const stored = await storage2.getShare(auth.userId);
4822
4938
  if (!stored || stored.unlockMethod !== "password") return;
4823
- await storage.putShare({
4939
+ await storage2.putShare({
4824
4940
  ...stored,
4825
4941
  wrappedUnlockToken: void 0,
4826
4942
  unlockTokenIv: void 0
@@ -4828,13 +4944,13 @@ async function createDecaneConnect(config) {
4828
4944
  },
4829
4945
  async hasPasskey() {
4830
4946
  if (!auth) return false;
4831
- const stored = await storage.getShare(auth.userId);
4947
+ const stored = await storage2.getShare(auth.userId);
4832
4948
  return stored?.unlockMethod === "passkey";
4833
4949
  },
4834
4950
  async addPasskey() {
4835
4951
  if (!auth) throw new ReconnectRequiredError();
4836
4952
  if (!isPasskeySupported()) throw new WebAuthnNotSupportedError();
4837
- const stored = await storage.getShare(auth.userId);
4953
+ const stored = await storage2.getShare(auth.userId);
4838
4954
  if (stored?.unlockMethod === "passkey") return;
4839
4955
  if (!stored) {
4840
4956
  if (!serverAssistedRecovery) throw new NewDeviceError();
@@ -4867,11 +4983,11 @@ async function createDecaneConnect(config) {
4867
4983
  },
4868
4984
  async deviceProtected() {
4869
4985
  if (!auth) return false;
4870
- return await storage.getShare(auth.userId) !== null;
4986
+ return await storage2.getShare(auth.userId) !== null;
4871
4987
  },
4872
4988
  async protectDevice() {
4873
4989
  if (!auth) throw new ReconnectRequiredError();
4874
- if (await storage.getShare(auth.userId)) return true;
4990
+ if (await storage2.getShare(auth.userId)) return true;
4875
4991
  if (!serverAssistedRecovery) throw new NewDeviceError();
4876
4992
  const tee = new TeeClient(teeUrl);
4877
4993
  const provisioned = await tee.provisionDeviceShare(auth.jwt);
@@ -4881,7 +4997,7 @@ async function createDecaneConnect(config) {
4881
4997
  } finally {
4882
4998
  zeroize(provisioned);
4883
4999
  }
4884
- return await storage.getShare(auth.userId) !== null;
5000
+ return await storage2.getShare(auth.userId) !== null;
4885
5001
  },
4886
5002
  async unlock() {
4887
5003
  if (!auth) {