decane-connect-kit 2.2.5 → 2.2.7

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.d.cts CHANGED
@@ -387,7 +387,7 @@ interface SignTypedDataRequest {
387
387
  message: Record<string, unknown>;
388
388
  primaryType?: string;
389
389
  }
390
- type SdkEvent = 'connected' | 'disconnected' | 'session-expired' | 'session-started';
390
+ type SdkEvent = 'connected' | 'disconnected' | 'session-expired' | 'session-started' | 'wallet-creating' | 'wallet-unlocking';
391
391
  interface DecaneConnect {
392
392
  connect(): Promise<ConnectResult>;
393
393
  connectWithGoogle(): Promise<ConnectResult>;
@@ -730,6 +730,12 @@ interface SocialAuthState {
730
730
  * user, so signing back in costs one passkey prompt and nothing else.
731
731
  */
732
732
  canUsePasskey: boolean;
733
+ /**
734
+ * Long-running work in progress, so the UI can show a status screen instead
735
+ * of appearing frozen. 'creating' = first-time key generation (several
736
+ * seconds); 'unlocking' = reopening the TEE session for a returning user.
737
+ */
738
+ phase: "creating" | "unlocking" | null;
733
739
  }
734
740
  interface DecaneKitProps {
735
741
  config?: DecaneConfig;
@@ -791,6 +797,8 @@ declare function useSocialAuth(): {
791
797
  } | null;
792
798
  sessionExpiresAt: number | null;
793
799
  canUsePasskey: boolean;
800
+ phase: "creating" | "unlocking" | null;
801
+ isCreatingWallet: boolean;
794
802
  needsReconnect: boolean;
795
803
  googleLoading: boolean;
796
804
  emailLoading: boolean;
@@ -822,6 +830,8 @@ declare function useSocialWallet(): {
822
830
  } | null;
823
831
  sessionExpiresAt: number | null;
824
832
  needsReconnect: boolean;
833
+ phase: "creating" | "unlocking" | null;
834
+ isCreatingWallet: boolean;
825
835
  modalOpen: boolean;
826
836
  openModal: () => void;
827
837
  closeModal: () => void;
package/dist/index.d.ts CHANGED
@@ -387,7 +387,7 @@ interface SignTypedDataRequest {
387
387
  message: Record<string, unknown>;
388
388
  primaryType?: string;
389
389
  }
390
- type SdkEvent = 'connected' | 'disconnected' | 'session-expired' | 'session-started';
390
+ type SdkEvent = 'connected' | 'disconnected' | 'session-expired' | 'session-started' | 'wallet-creating' | 'wallet-unlocking';
391
391
  interface DecaneConnect {
392
392
  connect(): Promise<ConnectResult>;
393
393
  connectWithGoogle(): Promise<ConnectResult>;
@@ -730,6 +730,12 @@ interface SocialAuthState {
730
730
  * user, so signing back in costs one passkey prompt and nothing else.
731
731
  */
732
732
  canUsePasskey: boolean;
733
+ /**
734
+ * Long-running work in progress, so the UI can show a status screen instead
735
+ * of appearing frozen. 'creating' = first-time key generation (several
736
+ * seconds); 'unlocking' = reopening the TEE session for a returning user.
737
+ */
738
+ phase: "creating" | "unlocking" | null;
733
739
  }
734
740
  interface DecaneKitProps {
735
741
  config?: DecaneConfig;
@@ -791,6 +797,8 @@ declare function useSocialAuth(): {
791
797
  } | null;
792
798
  sessionExpiresAt: number | null;
793
799
  canUsePasskey: boolean;
800
+ phase: "creating" | "unlocking" | null;
801
+ isCreatingWallet: boolean;
794
802
  needsReconnect: boolean;
795
803
  googleLoading: boolean;
796
804
  emailLoading: boolean;
@@ -822,6 +830,8 @@ declare function useSocialWallet(): {
822
830
  } | null;
823
831
  sessionExpiresAt: number | null;
824
832
  needsReconnect: boolean;
833
+ phase: "creating" | "unlocking" | null;
834
+ isCreatingWallet: boolean;
825
835
  modalOpen: boolean;
826
836
  openModal: () => void;
827
837
  closeModal: () => void;
package/dist/index.js CHANGED
@@ -2548,9 +2548,6 @@ function validatePin(pin) {
2548
2548
  // src/social/crypto/passkey.ts
2549
2549
  init_errors();
2550
2550
  import { startRegistration, startAuthentication as startAuthentication2 } from "@simplewebauthn/browser";
2551
- function b64u(u) {
2552
- return btoa(String.fromCharCode(...u)).replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
2553
- }
2554
2551
  function fromB64u(s) {
2555
2552
  return Uint8Array.from(atob(s.replace(/-/g, "+").replace(/_/g, "/")), (c) => c.charCodeAt(0));
2556
2553
  }
@@ -2585,7 +2582,7 @@ async function authenticateWithPasskey(opts) {
2585
2582
  ...opts.optionsJSON,
2586
2583
  extensions: {
2587
2584
  ...opts.optionsJSON.extensions,
2588
- prf: { eval: { first: b64u(opts.prfSalt) } }
2585
+ prf: { eval: { first: buf3(opts.prfSalt) } }
2589
2586
  }
2590
2587
  };
2591
2588
  let response;
@@ -2968,7 +2965,7 @@ function formatBalanceDisplay(value) {
2968
2965
  // src/social/client.ts
2969
2966
  var DEFAULT_API_BASE = "https://backend.decane.app";
2970
2967
  var DEFAULT_TEE_URL = "https://4405742df08d19abc549a05ade2a7154d98bd87f-8443.dstack-pha-prod9.phala.network";
2971
- var DEFAULT_SESSION_MINUTES = 30;
2968
+ var DEFAULT_SESSION_MINUTES = 120;
2972
2969
  function makePersistKey(apiKey) {
2973
2970
  return `decane:social:${apiKey.slice(0, 20)}`;
2974
2971
  }
@@ -3268,6 +3265,7 @@ async function createDecaneConnect(config) {
3268
3265
  }
3269
3266
  async function passkeyLogin(stored) {
3270
3267
  const userId = stored.userId;
3268
+ events.emit("wallet-unlocking");
3271
3269
  const options = await api.getWebAuthnLoginOptions(userId, rpId);
3272
3270
  if (!options) {
3273
3271
  throw new NewDeviceError();
@@ -3301,8 +3299,10 @@ async function createDecaneConnect(config) {
3301
3299
  async function handleAuthResult(result) {
3302
3300
  let addresses;
3303
3301
  if (!result.hasShare) {
3302
+ events.emit("wallet-creating");
3304
3303
  addresses = await firstTimeSetup(result.userId, result.jwt);
3305
3304
  } else {
3305
+ events.emit("wallet-unlocking");
3306
3306
  addresses = await returningUserUnlock(result.userId, result.jwt);
3307
3307
  }
3308
3308
  auth = { jwt: result.jwt, userId: result.userId, addresses };
@@ -3641,8 +3641,8 @@ async function createDecaneConnect(config) {
3641
3641
  function bufferToB64u(buf6) {
3642
3642
  return btoa(String.fromCharCode(...buf6)).replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
3643
3643
  }
3644
- function b64uToBuffer(b64u2) {
3645
- const b644 = b64u2.replace(/-/g, "+").replace(/_/g, "/");
3644
+ function b64uToBuffer(b64u) {
3645
+ const b644 = b64u.replace(/-/g, "+").replace(/_/g, "/");
3646
3646
  return Uint8Array.from(atob(b644), (c) => c.charCodeAt(0));
3647
3647
  }
3648
3648
  function toHex(bytes) {
@@ -5368,21 +5368,103 @@ function SocialWalletModal({
5368
5368
  }
5369
5369
 
5370
5370
  // src/ui/context.tsx
5371
- import React4, {
5371
+ import React5, {
5372
5372
  createContext,
5373
5373
  useCallback as useCallback3,
5374
5374
  useContext,
5375
- useEffect as useEffect3,
5375
+ useEffect as useEffect4,
5376
5376
  useRef,
5377
5377
  useState as useState3
5378
5378
  } from "react";
5379
+
5380
+ // src/ui/StatusOverlay.tsx
5381
+ import React4, { useEffect as useEffect3 } from "react";
5382
+ import { createPortal as createPortal3 } from "react-dom";
5383
+ function injectTokens3(theme) {
5384
+ if (typeof document === "undefined") return;
5385
+ const resolved = theme === "auto" ? window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light" : theme;
5386
+ let el = document.getElementById("decane-tokens");
5387
+ if (!el) {
5388
+ el = document.createElement("style");
5389
+ el.id = "decane-tokens";
5390
+ document.head.appendChild(el);
5391
+ }
5392
+ el.textContent = `:root { ${CSS_VARS[resolved]} }`;
5393
+ }
5394
+ function WalletStatusOverlay({
5395
+ phase,
5396
+ theme = "auto"
5397
+ }) {
5398
+ useEffect3(() => {
5399
+ if (!phase) return;
5400
+ injectTokens3(theme);
5401
+ if (theme !== "auto") return;
5402
+ const mq = window.matchMedia("(prefers-color-scheme: dark)");
5403
+ const h = () => injectTokens3("auto");
5404
+ mq.addEventListener("change", h);
5405
+ return () => mq.removeEventListener("change", h);
5406
+ }, [phase, theme]);
5407
+ if (!phase || typeof document === "undefined") return null;
5408
+ const title = phase === "creating" ? "Creating your wallet" : "Unlocking your wallet";
5409
+ const sub = phase === "creating" ? "Generating your keys and splitting them across three shares so no single party ever holds your wallet. This takes a few seconds \u2014 please keep this tab open." : "Reopening your secure session\u2026";
5410
+ return createPortal3(
5411
+ /* @__PURE__ */ React4.createElement(
5412
+ "div",
5413
+ {
5414
+ role: "dialog",
5415
+ "aria-modal": "true",
5416
+ "aria-label": title,
5417
+ style: {
5418
+ position: "fixed",
5419
+ inset: 0,
5420
+ zIndex: 1e4,
5421
+ display: "flex",
5422
+ alignItems: "center",
5423
+ justifyContent: "center",
5424
+ padding: 16,
5425
+ fontFamily: "var(--dc-font-sans, system-ui, sans-serif)"
5426
+ }
5427
+ },
5428
+ /* @__PURE__ */ React4.createElement("div", { style: {
5429
+ position: "absolute",
5430
+ inset: 0,
5431
+ background: "var(--dc-bg-overlay, rgba(0,0,0,0.75))",
5432
+ backdropFilter: "blur(8px)",
5433
+ WebkitBackdropFilter: "blur(8px)"
5434
+ } }),
5435
+ /* @__PURE__ */ React4.createElement("div", { style: {
5436
+ position: "relative",
5437
+ background: "var(--dc-bg, #0D0D0B)",
5438
+ border: "1px solid var(--dc-border, #3D3C39)",
5439
+ borderRadius: 20,
5440
+ width: "100%",
5441
+ maxWidth: 340,
5442
+ padding: "30px 26px",
5443
+ textAlign: "center",
5444
+ boxShadow: "0 24px 64px rgba(0,0,0,0.6)"
5445
+ } }, /* @__PURE__ */ React4.createElement("div", { style: { display: "flex", justifyContent: "center", marginBottom: 18 } }, /* @__PURE__ */ React4.createElement("div", { style: { position: "relative", width: 60, height: 60, display: "flex", alignItems: "center", justifyContent: "center" } }, /* @__PURE__ */ React4.createElement("span", { style: {
5446
+ position: "absolute",
5447
+ inset: 0,
5448
+ borderRadius: "50%",
5449
+ border: "2px solid var(--dc-border, #3D3C39)",
5450
+ borderTopColor: "var(--dc-accent, #F5C800)",
5451
+ animation: "dc-status-spin 0.8s linear infinite"
5452
+ } }), /* @__PURE__ */ React4.createElement(DecaneMark, { size: 32 }))), /* @__PURE__ */ React4.createElement("div", { style: { fontSize: 16, fontWeight: 800, color: "var(--dc-text, #F9F9F7)", letterSpacing: "-0.02em", marginBottom: 7 } }, title), /* @__PURE__ */ React4.createElement("div", { style: { fontSize: 12, color: "var(--dc-text-muted, #8A8884)", lineHeight: 1.55 } }, sub), /* @__PURE__ */ React4.createElement("div", { style: { marginTop: 20, paddingTop: 14, borderTop: "1px solid var(--dc-border, #3D3C39)", display: "flex", alignItems: "center", justifyContent: "center", gap: 6 } }, /* @__PURE__ */ React4.createElement(DecaneMark, { size: 13, muted: true }), /* @__PURE__ */ React4.createElement(DecaneWordmark, { size: 11, muted: true }))),
5453
+ /* @__PURE__ */ React4.createElement("style", null, `@keyframes dc-status-spin { to { transform: rotate(360deg); } }`)
5454
+ ),
5455
+ document.body
5456
+ );
5457
+ }
5458
+
5459
+ // src/ui/context.tsx
5379
5460
  var DEFAULT_SOCIAL = {
5380
5461
  addresses: null,
5381
5462
  isNewUser: false,
5382
5463
  isUnlocked: false,
5383
5464
  sessionExpiresAt: null,
5384
5465
  needsReconnect: false,
5385
- canUsePasskey: false
5466
+ canUsePasskey: false,
5467
+ phase: null
5386
5468
  };
5387
5469
  var DecaneContext = createContext(null);
5388
5470
  function hasSocial(mode) {
@@ -5419,7 +5501,7 @@ function DecaneKit({ config, children }) {
5419
5501
  const closeSelector = useCallback3(() => setSelectorOpen(false), []);
5420
5502
  const openSocialModal = useCallback3(() => setSocialModalOpen(true), []);
5421
5503
  const closeSocialModal = useCallback3(() => setSocialModalOpen(false), []);
5422
- useEffect3(() => {
5504
+ useEffect4(() => {
5423
5505
  if (!socialAuth.isUnlocked) return;
5424
5506
  const id = setInterval(() => {
5425
5507
  const sdk = socialRef.current;
@@ -5432,7 +5514,7 @@ function DecaneKit({ config, children }) {
5432
5514
  }, 1e4);
5433
5515
  return () => clearInterval(id);
5434
5516
  }, [socialAuth.isUnlocked]);
5435
- useEffect3(() => {
5517
+ useEffect4(() => {
5436
5518
  if (!hasSocial(mode) || !config?.social || socialInitialized.current) return;
5437
5519
  socialInitialized.current = true;
5438
5520
  const {
@@ -5460,6 +5542,9 @@ function DecaneKit({ config, children }) {
5460
5542
  () => setSocialAuth((p) => ({ ...p, isUnlocked: false, sessionExpiresAt: null }))
5461
5543
  );
5462
5544
  sdk.on("disconnected", () => setSocialAuth(DEFAULT_SOCIAL));
5545
+ sdk.on("wallet-creating", () => setSocialAuth((p) => ({ ...p, phase: "creating" })));
5546
+ sdk.on("wallet-unlocking", () => setSocialAuth((p) => ({ ...p, phase: "unlocking" })));
5547
+ sdk.on("connected", () => setSocialAuth((p) => ({ ...p, phase: null })));
5463
5548
  const saved = sdk.getAddresses();
5464
5549
  if (saved) {
5465
5550
  setSocialAuth((p) => ({ ...p, addresses: saved, isUnlocked: false, needsReconnect: true }));
@@ -5468,7 +5553,10 @@ function DecaneKit({ config, children }) {
5468
5553
  });
5469
5554
  const params = new URLSearchParams(window.location.search);
5470
5555
  if (params.has("decane_jwt") || params.has("decane_error")) {
5471
- sdk.connectWithGoogle().then(applyResult).catch(console.error);
5556
+ sdk.connectWithGoogle().then(applyResult).catch((e) => {
5557
+ setSocialAuth((p) => p.phase ? { ...p, phase: null } : p);
5558
+ console.error(e);
5559
+ });
5472
5560
  }
5473
5561
  }).catch(console.error);
5474
5562
  }, []);
@@ -5480,19 +5568,26 @@ function DecaneKit({ config, children }) {
5480
5568
  isUnlocked: sdk?.isUnlocked() ?? false,
5481
5569
  sessionExpiresAt: sdk?.sessionExpiresAt() ?? null,
5482
5570
  needsReconnect: false,
5483
- canUsePasskey: false
5571
+ canUsePasskey: false,
5572
+ phase: null
5484
5573
  });
5485
5574
  sdk?.canSignInWithPasskey().then((can) => setSocialAuth((p) => ({ ...p, canUsePasskey: can }))).catch(() => {
5486
5575
  });
5487
5576
  }
5577
+ const clearPhase = useCallback3(() => setSocialAuth((p) => p.phase ? { ...p, phase: null } : p), []);
5488
5578
  const signInWithPasskey = useCallback3(async () => {
5489
5579
  const sdk = socialRef.current;
5490
5580
  if (!sdk) throw new Error("Social sign-in not configured");
5491
- const result = await sdk.signInWithPasskey();
5492
- applyResult(result);
5493
- setSelectorOpen(false);
5494
- return result;
5495
- }, []);
5581
+ try {
5582
+ const result = await sdk.signInWithPasskey();
5583
+ applyResult(result);
5584
+ setSelectorOpen(false);
5585
+ return result;
5586
+ } catch (e) {
5587
+ clearPhase();
5588
+ throw e;
5589
+ }
5590
+ }, [clearPhase]);
5496
5591
  const connectWithGoogle = useCallback3(async () => {
5497
5592
  const sdk = socialRef.current;
5498
5593
  if (!sdk) throw new Error("Social sign-in not configured");
@@ -5506,17 +5601,27 @@ function DecaneKit({ config, children }) {
5506
5601
  const verifyEmailCode2 = useCallback3(async (email, code) => {
5507
5602
  const sdk = socialRef.current;
5508
5603
  if (!sdk) throw new Error("Social sign-in not configured");
5509
- const result = await sdk.verifyEmailCode(email, code);
5510
- applyResult(result);
5511
- setSelectorOpen(false);
5512
- }, []);
5604
+ try {
5605
+ const result = await sdk.verifyEmailCode(email, code);
5606
+ applyResult(result);
5607
+ setSelectorOpen(false);
5608
+ } catch (e) {
5609
+ clearPhase();
5610
+ throw e;
5611
+ }
5612
+ }, [clearPhase]);
5513
5613
  const connectWithToken = useCallback3(async (token, opts) => {
5514
5614
  const sdk = socialRef.current;
5515
5615
  if (!sdk) throw new Error("Social sign-in not configured");
5516
- const result = await sdk.connectWithToken(token, opts);
5517
- applyResult(result);
5518
- setSelectorOpen(false);
5519
- }, []);
5616
+ try {
5617
+ const result = await sdk.connectWithToken(token, opts);
5618
+ applyResult(result);
5619
+ setSelectorOpen(false);
5620
+ } catch (e) {
5621
+ clearPhase();
5622
+ throw e;
5623
+ }
5624
+ }, [clearPhase]);
5520
5625
  const customAuthConfig = config?.social?.customAuth;
5521
5626
  const connectWithCustomAuth = useCallback3(async () => {
5522
5627
  if (!customAuthConfig) throw new Error("Custom auth not configured");
@@ -5526,14 +5631,21 @@ function DecaneKit({ config, children }) {
5526
5631
  const socialUnlock = useCallback3(async () => {
5527
5632
  const sdk = socialRef.current;
5528
5633
  if (!sdk) return;
5529
- await sdk.unlock();
5530
- setSocialAuth((p) => ({
5531
- ...p,
5532
- isUnlocked: sdk.isUnlocked(),
5533
- sessionExpiresAt: sdk.sessionExpiresAt(),
5534
- needsReconnect: false
5535
- }));
5536
- }, []);
5634
+ setSocialAuth((p) => ({ ...p, phase: "unlocking" }));
5635
+ try {
5636
+ await sdk.unlock();
5637
+ setSocialAuth((p) => ({
5638
+ ...p,
5639
+ isUnlocked: sdk.isUnlocked(),
5640
+ sessionExpiresAt: sdk.sessionExpiresAt(),
5641
+ needsReconnect: false,
5642
+ phase: null
5643
+ }));
5644
+ } catch (e) {
5645
+ clearPhase();
5646
+ throw e;
5647
+ }
5648
+ }, [clearPhase]);
5537
5649
  const socialDisconnect = useCallback3(async () => {
5538
5650
  const sdk = socialRef.current;
5539
5651
  if (!sdk) return;
@@ -5602,7 +5714,7 @@ function DecaneKit({ config, children }) {
5602
5714
  []
5603
5715
  );
5604
5716
  const networks = deriveNetworks(mode, config?.networks);
5605
- return /* @__PURE__ */ React4.createElement(
5717
+ return /* @__PURE__ */ React5.createElement(
5606
5718
  DecaneContext.Provider,
5607
5719
  {
5608
5720
  value: {
@@ -5640,7 +5752,7 @@ function DecaneKit({ config, children }) {
5640
5752
  }
5641
5753
  },
5642
5754
  children,
5643
- /* @__PURE__ */ React4.createElement(
5755
+ /* @__PURE__ */ React5.createElement(
5644
5756
  WalletSelector,
5645
5757
  {
5646
5758
  provider: walletRef.current,
@@ -5661,7 +5773,7 @@ function DecaneKit({ config, children }) {
5661
5773
  onCustomAuthSignIn: customAuthConfig ? connectWithCustomAuth : void 0
5662
5774
  }
5663
5775
  ),
5664
- /* @__PURE__ */ React4.createElement(
5776
+ /* @__PURE__ */ React5.createElement(
5665
5777
  SocialWalletModal,
5666
5778
  {
5667
5779
  open: socialModalOpen,
@@ -5684,7 +5796,8 @@ function DecaneKit({ config, children }) {
5684
5796
  rpcUrls: config?.social?.rpcUrls,
5685
5797
  chains: config?.social?.chains
5686
5798
  }
5687
- )
5799
+ ),
5800
+ /* @__PURE__ */ React5.createElement(WalletStatusOverlay, { phase: socialAuth.phase, theme })
5688
5801
  );
5689
5802
  }
5690
5803
  function useDecaneContext() {
@@ -5698,7 +5811,7 @@ function useDecaneContext() {
5698
5811
  }
5699
5812
 
5700
5813
  // src/ui/hooks.ts
5701
- import { useState as useState4, useEffect as useEffect4, useCallback as useCallback4 } from "react";
5814
+ import { useState as useState4, useEffect as useEffect5, useCallback as useCallback4 } from "react";
5702
5815
  function useSocialAuth() {
5703
5816
  const {
5704
5817
  socialAuth,
@@ -5812,6 +5925,9 @@ function useSocialAuth() {
5812
5925
  sessionExpiresAt: socialAuth.sessionExpiresAt,
5813
5926
  // True when this device can skip the full sign-in and resume with a passkey.
5814
5927
  canUsePasskey: socialAuth.canUsePasskey,
5928
+ // Long-running work in progress, for driving your own status UI.
5929
+ phase: socialAuth.phase,
5930
+ isCreatingWallet: socialAuth.phase === "creating",
5815
5931
  // True when addresses are known (from a previous visit) but there's no
5816
5932
  // live session — unlock() will always throw in this state (every
5817
5933
  // unlock requires a fresh JWT, and JWTs are never persisted). Route
@@ -5943,6 +6059,10 @@ function useSocialWallet() {
5943
6059
  // unlock requires a fresh JWT, and JWTs are never persisted). Route
5944
6060
  // this into a real reconnect (signInWithGoogle / sendEmailCode), not unlock().
5945
6061
  needsReconnect: socialAuth.needsReconnect,
6062
+ // Long-running work in progress ('creating' | 'unlocking' | null), for
6063
+ // driving your own status UI in addition to the SDK's built-in overlay.
6064
+ phase: socialAuth.phase,
6065
+ isCreatingWallet: socialAuth.phase === "creating",
5946
6066
  // Modal
5947
6067
  modalOpen: socialModalOpen,
5948
6068
  openModal: openSocialModal,
@@ -5991,7 +6111,7 @@ function useSocialBalance(chain) {
5991
6111
  setLoading(false);
5992
6112
  }
5993
6113
  }, [socialGetBalance, chain, socialAuth.addresses]);
5994
- useEffect4(() => {
6114
+ useEffect5(() => {
5995
6115
  let cancelled = false;
5996
6116
  if (!socialAuth.addresses) {
5997
6117
  setBalance(null);
@@ -6023,7 +6143,7 @@ function toDecaneError(err) {
6023
6143
  function useDecane() {
6024
6144
  const { provider, theme, setTheme } = useDecaneContext();
6025
6145
  const [, forceUpdate] = useState4(0);
6026
- useEffect4(() => {
6146
+ useEffect5(() => {
6027
6147
  const refresh = () => forceUpdate((n) => n + 1);
6028
6148
  const events = [
6029
6149
  "connect",
@@ -6065,7 +6185,7 @@ function useChainSwitch() {
6065
6185
  const [, forceUpdate] = useState4(0);
6066
6186
  const [loading, setLoading] = useState4(false);
6067
6187
  const [error, setError] = useState4(null);
6068
- useEffect4(() => {
6188
+ useEffect5(() => {
6069
6189
  const refresh = () => forceUpdate((n) => n + 1);
6070
6190
  provider.on("connect", refresh);
6071
6191
  provider.on("disconnect", refresh);