decane-connect-kit 2.28.0 → 2.29.1

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.js CHANGED
@@ -5469,8 +5469,8 @@ async function deriveAddressesFromShares(a, b) {
5469
5469
  init_errors();
5470
5470
 
5471
5471
  // src/ui/WalletSelector.tsx
5472
- import React2, { useEffect, useCallback, useState } from "react";
5473
- import { createPortal } from "react-dom";
5472
+ import React3, { useEffect as useEffect2, useCallback as useCallback2, useState as useState2 } from "react";
5473
+ import { createPortal as createPortal2 } from "react-dom";
5474
5474
 
5475
5475
  // src/ui/styles.ts
5476
5476
  var tokens = {
@@ -5519,6 +5519,7 @@ var tokens = {
5519
5519
  accent: "#F5C800",
5520
5520
  accentHover: "#D4A800",
5521
5521
  accentText: "#0D0D0B",
5522
+ accentInk: "#7A5F00",
5522
5523
  badgeEvm: "#1A1917",
5523
5524
  badgeEvmText: "#F5C800",
5524
5525
  badgeSolana: "#F5C800",
@@ -5539,6 +5540,7 @@ var tokens = {
5539
5540
  accent: "#F5C800",
5540
5541
  accentHover: "#FFE04D",
5541
5542
  accentText: "#0D0D0B",
5543
+ accentInk: "#F5C800",
5542
5544
  badgeEvm: "#F5C800",
5543
5545
  badgeEvmText: "#0D0D0B",
5544
5546
  badgeSolana: "#1A1917",
@@ -5564,6 +5566,7 @@ var CSS_VARS = {
5564
5566
  --dc-accent: ${tokens.light.accent};
5565
5567
  --dc-accent-hover: ${tokens.light.accentHover};
5566
5568
  --dc-accent-text: ${tokens.light.accentText};
5569
+ --dc-accent-ink: ${tokens.light.accentInk};
5567
5570
  --dc-badge-evm: ${tokens.light.badgeEvm};
5568
5571
  --dc-badge-evm-text: ${tokens.light.badgeEvmText};
5569
5572
  --dc-badge-sol: ${tokens.light.badgeSolana};
@@ -5585,6 +5588,7 @@ var CSS_VARS = {
5585
5588
  --dc-accent: ${tokens.dark.accent};
5586
5589
  --dc-accent-hover: ${tokens.dark.accentHover};
5587
5590
  --dc-accent-text: ${tokens.dark.accentText};
5591
+ --dc-accent-ink: ${tokens.dark.accentInk};
5588
5592
  --dc-badge-evm: ${tokens.dark.badgeEvm};
5589
5593
  --dc-badge-evm-text: ${tokens.dark.badgeEvmText};
5590
5594
  --dc-badge-sol: ${tokens.dark.badgeSolana};
@@ -5746,145 +5750,262 @@ function XLogo({ size = 14 }) {
5746
5750
  /* @__PURE__ */ React.createElement("path", { d: "M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z" })
5747
5751
  );
5748
5752
  }
5749
-
5750
- // src/ui/WalletSelector.tsx
5751
- var FONT_URL = "https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&display=swap";
5752
- function injectTokens(theme) {
5753
- let resolved;
5754
- if (theme === "auto") {
5755
- resolved = window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
5756
- } else {
5757
- resolved = theme;
5758
- }
5759
- let styleEl = document.getElementById("decane-tokens");
5760
- if (!styleEl) {
5761
- styleEl = document.createElement("style");
5762
- styleEl.id = "decane-tokens";
5763
- document.head.appendChild(styleEl);
5764
- }
5765
- styleEl.textContent = `:root { ${CSS_VARS[resolved]} }`;
5753
+ var line = {
5754
+ fill: "none",
5755
+ stroke: "currentColor",
5756
+ strokeWidth: 1.8,
5757
+ strokeLinecap: "round",
5758
+ strokeLinejoin: "round"
5759
+ };
5760
+ function GoogleMark({ size = 18 }) {
5761
+ return /* @__PURE__ */ React.createElement("svg", { width: size, height: size, viewBox: "0 0 48 48", "aria-hidden": "true", style: { flexShrink: 0 } }, /* @__PURE__ */ React.createElement("path", { fill: "#EA4335", d: "M24 9.5c3.5 0 6 1.5 7.4 2.8l5.4-5.3C33.5 3.9 29.2 2 24 2 15.4 2 8 7 4.7 14.2l6.3 4.9C12.6 13.4 17.8 9.5 24 9.5z" }), /* @__PURE__ */ React.createElement("path", { fill: "#4285F4", d: "M46 24.5c0-1.6-.1-2.8-.4-4H24v7.5h12.6c-.3 2.2-1.7 5.5-4.9 7.7l6.1 4.7C41.5 37 46 31.4 46 24.5z" }), /* @__PURE__ */ React.createElement("path", { fill: "#FBBC05", d: "M11 29.1a13.9 13.9 0 0 1 0-10l-6.3-4.9A22 22 0 0 0 2 24c0 3.5.8 6.9 2.4 9.8L11 29.1z" }), /* @__PURE__ */ React.createElement("path", { fill: "#34A853", d: "M24 46c5.9 0 10.9-2 14.5-5.4l-6.1-4.7c-1.7 1.2-4 2-8.4 2-6.2 0-11.4-4-13.1-9.6l-6.3 4.9C7.9 40.9 15.3 46 24 46z" }));
5766
5762
  }
5767
- function injectFont() {
5768
- if (document.getElementById("decane-font")) return;
5769
- const link = document.createElement("link");
5770
- link.id = "decane-font";
5771
- link.rel = "stylesheet";
5772
- link.href = FONT_URL;
5773
- document.head.appendChild(link);
5763
+ function MailIcon({ size = 18 }) {
5764
+ return /* @__PURE__ */ React.createElement("svg", { width: size, height: size, viewBox: "0 0 24 24", ...line, "aria-hidden": "true", style: { flexShrink: 0 } }, /* @__PURE__ */ React.createElement("rect", { x: "3", y: "5", width: "18", height: "14", rx: "2.5" }), /* @__PURE__ */ React.createElement("path", { d: "m3.5 7 8.5 6 8.5-6" }));
5774
5765
  }
5775
- function WalletRow({ wallet, onClick }) {
5776
- const [hovered, setHovered] = useState(false);
5777
- const [focused, setFocused] = useState(false);
5778
- return /* @__PURE__ */ React2.createElement(
5779
- "button",
5780
- {
5781
- onClick,
5782
- onMouseEnter: () => setHovered(true),
5783
- onMouseLeave: () => setHovered(false),
5784
- onFocus: () => setFocused(true),
5785
- onBlur: () => setFocused(false),
5786
- style: {
5787
- display: "flex",
5788
- alignItems: "center",
5789
- gap: 12,
5790
- width: "100%",
5791
- padding: "11px 14px",
5792
- background: hovered ? "var(--dc-surface-hover)" : "transparent",
5793
- border: focused ? "1px solid var(--dc-border-accent)" : "1px solid transparent",
5794
- borderRadius: 10,
5795
- cursor: "pointer",
5796
- textAlign: "left",
5797
- transition: "background 0.12s, border-color 0.12s",
5798
- outline: "none",
5799
- fontFamily: "inherit"
5800
- }
5801
- },
5802
- /* @__PURE__ */ React2.createElement(WalletIcon, { src: wallet.icon || void 0, name: wallet.name, size: 38 }),
5803
- /* @__PURE__ */ React2.createElement("span", { style: { flex: 1, fontSize: 14, fontWeight: 600, color: "var(--dc-text)", letterSpacing: "-0.01em" } }, wallet.name),
5804
- /* @__PURE__ */ React2.createElement(ChainIconStack, { support: wallet.chainSupport, size: 16 }),
5805
- /* @__PURE__ */ React2.createElement(
5806
- "svg",
5807
- {
5808
- width: "14",
5809
- height: "14",
5810
- viewBox: "0 0 14 14",
5811
- fill: "none",
5812
- style: { color: hovered ? "var(--dc-text-secondary)" : "var(--dc-text-muted)", flexShrink: 0, transition: "color 0.12s" }
5813
- },
5814
- /* @__PURE__ */ React2.createElement("path", { d: "M5 2.5L9.5 7L5 11.5", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" })
5815
- )
5816
- );
5766
+ function PhoneIcon({ size = 18 }) {
5767
+ return /* @__PURE__ */ React.createElement("svg", { width: size, height: size, viewBox: "0 0 24 24", ...line, "aria-hidden": "true", style: { flexShrink: 0 } }, /* @__PURE__ */ React.createElement("rect", { x: "7", y: "2.5", width: "10", height: "19", rx: "2.5" }), /* @__PURE__ */ React.createElement("path", { d: "M11 18h2" }));
5817
5768
  }
5818
- function FilterTab({ label, active, onClick }) {
5819
- const [hovered, setHovered] = useState(false);
5820
- return /* @__PURE__ */ React2.createElement(
5821
- "button",
5822
- {
5823
- onClick,
5824
- onMouseEnter: () => setHovered(true),
5825
- onMouseLeave: () => setHovered(false),
5826
- style: {
5827
- flex: 1,
5828
- padding: "6px 8px",
5829
- borderRadius: 8,
5830
- border: active ? "1px solid var(--dc-border-accent)" : "1px solid transparent",
5831
- background: active ? "rgba(245,200,0,0.1)" : hovered ? "var(--dc-surface-hover)" : "transparent",
5832
- color: active ? "var(--dc-accent)" : "var(--dc-text-muted)",
5833
- fontSize: 11,
5834
- fontWeight: 700,
5835
- letterSpacing: "0.04em",
5836
- textTransform: "uppercase",
5837
- cursor: "pointer",
5838
- transition: "all 0.12s",
5839
- fontFamily: "inherit",
5840
- outline: "none"
5841
- }
5842
- },
5843
- label
5844
- );
5769
+ function ChatIcon({ size = 18 }) {
5770
+ return /* @__PURE__ */ React.createElement("svg", { width: size, height: size, viewBox: "0 0 24 24", ...line, "aria-hidden": "true", style: { flexShrink: 0 } }, /* @__PURE__ */ React.createElement("path", { d: "M4 6.5A2.5 2.5 0 0 1 6.5 4h11A2.5 2.5 0 0 1 20 6.5v7a2.5 2.5 0 0 1-2.5 2.5H10l-4.2 3.2a.6.6 0 0 1-1-.5V16A2.5 2.5 0 0 1 4 13.5z" }), /* @__PURE__ */ React.createElement("path", { d: "M8.5 9h7M8.5 12.5h4.5" }));
5771
+ }
5772
+ function KeyIcon({ size = 18 }) {
5773
+ return /* @__PURE__ */ React.createElement("svg", { width: size, height: size, viewBox: "0 0 24 24", ...line, "aria-hidden": "true", style: { flexShrink: 0 } }, /* @__PURE__ */ React.createElement("circle", { cx: "8", cy: "12", r: "4" }), /* @__PURE__ */ React.createElement("path", { d: "M12 12h9M18 12v3M15 12v2.5" }));
5774
+ }
5775
+ function UserIcon({ size = 18 }) {
5776
+ return /* @__PURE__ */ React.createElement("svg", { width: size, height: size, viewBox: "0 0 24 24", ...line, "aria-hidden": "true", style: { flexShrink: 0 } }, /* @__PURE__ */ React.createElement("circle", { cx: "12", cy: "8.5", r: "3.8" }), /* @__PURE__ */ React.createElement("path", { d: "M4.5 20a7.5 7.5 0 0 1 15 0" }));
5845
5777
  }
5846
- function ChainOption({ label, description, badges, onClick }) {
5847
- const [hovered, setHovered] = useState(false);
5848
- return /* @__PURE__ */ React2.createElement(
5849
- "button",
5778
+ function CopyIcon({ size = 15 }) {
5779
+ return /* @__PURE__ */ React.createElement("svg", { width: size, height: size, viewBox: "0 0 24 24", ...line, "aria-hidden": "true", style: { flexShrink: 0 } }, /* @__PURE__ */ React.createElement("rect", { x: "8.5", y: "8.5", width: "12", height: "12", rx: "2.5" }), /* @__PURE__ */ React.createElement("path", { d: "M15.5 8.5V6A2.5 2.5 0 0 0 13 3.5H6A2.5 2.5 0 0 0 3.5 6v7A2.5 2.5 0 0 0 6 15.5h2.5" }));
5780
+ }
5781
+ function CheckIcon({ size = 15 }) {
5782
+ return /* @__PURE__ */ React.createElement("svg", { width: size, height: size, viewBox: "0 0 24 24", ...line, "aria-hidden": "true", style: { flexShrink: 0 } }, /* @__PURE__ */ React.createElement("path", { d: "m5 12.5 4.5 4.5L19 7.5" }));
5783
+ }
5784
+ function CloseIcon({ size = 16 }) {
5785
+ return /* @__PURE__ */ React.createElement("svg", { width: size, height: size, viewBox: "0 0 24 24", ...line, "aria-hidden": "true", style: { flexShrink: 0 } }, /* @__PURE__ */ React.createElement("path", { d: "M6 6l12 12M18 6 6 18" }));
5786
+ }
5787
+ function ChevronIcon({ size = 16, open = false }) {
5788
+ return /* @__PURE__ */ React.createElement(
5789
+ "svg",
5850
5790
  {
5851
- onClick,
5852
- onMouseEnter: () => setHovered(true),
5853
- onMouseLeave: () => setHovered(false),
5854
- style: {
5855
- display: "flex",
5856
- flexDirection: "column",
5857
- alignItems: "flex-start",
5858
- gap: 6,
5859
- width: "100%",
5860
- padding: "14px 16px",
5861
- background: hovered ? "var(--dc-surface-hover)" : "var(--dc-surface)",
5862
- border: hovered ? "1px solid var(--dc-border-accent)" : "1px solid var(--dc-border)",
5863
- borderRadius: 12,
5864
- cursor: "pointer",
5865
- textAlign: "left",
5866
- transition: "all 0.12s",
5867
- fontFamily: "inherit",
5868
- outline: "none"
5869
- }
5791
+ width: size,
5792
+ height: size,
5793
+ viewBox: "0 0 24 24",
5794
+ ...line,
5795
+ "aria-hidden": "true",
5796
+ style: { flexShrink: 0, transition: "transform .2s", transform: open ? "rotate(180deg)" : "none" }
5870
5797
  },
5871
- badges,
5872
- /* @__PURE__ */ React2.createElement("span", { style: { fontSize: 13, fontWeight: 700, color: "var(--dc-text)" } }, label),
5873
- /* @__PURE__ */ React2.createElement("span", { style: { fontSize: 11, color: "var(--dc-text-muted)", lineHeight: 1.4 } }, description)
5798
+ /* @__PURE__ */ React.createElement("path", { d: "m6 9 6 6 6-6" })
5874
5799
  );
5875
5800
  }
5876
- function hasSocialMode(mode) {
5877
- return mode === "all" || mode === "social" || mode === "evm+social" || mode === "solana+social" || mode === "tron+social" || mode === "evm+tron+social";
5801
+ function ArrowLeftIcon({ size = 16 }) {
5802
+ return /* @__PURE__ */ React.createElement("svg", { width: size, height: size, viewBox: "0 0 24 24", ...line, "aria-hidden": "true", style: { flexShrink: 0 } }, /* @__PURE__ */ React.createElement("path", { d: "M19 12H5M11 6l-6 6 6 6" }));
5878
5803
  }
5879
- function WalletSelector({
5880
- provider,
5881
- open,
5882
- onClose,
5883
- onConnect,
5884
- theme = "auto",
5885
- networks = "all",
5886
- mode = "wallets",
5887
- socialAuthMethods = ["google", "email"],
5804
+ function WalletLineIcon({ size = 18 }) {
5805
+ return /* @__PURE__ */ React.createElement("svg", { width: size, height: size, viewBox: "0 0 24 24", ...line, "aria-hidden": "true", style: { flexShrink: 0 } }, /* @__PURE__ */ React.createElement("path", { d: "M4 7.5A2.5 2.5 0 0 1 6.5 5H18a1 1 0 0 1 1 1v2" }), /* @__PURE__ */ React.createElement("path", { d: "M4 7.5v9A2.5 2.5 0 0 0 6.5 19H19a1 1 0 0 0 1-1v-9a1 1 0 0 0-1-1H6.5A2.5 2.5 0 0 1 4 7.5z" }), /* @__PURE__ */ React.createElement("circle", { cx: "16", cy: "13.5", r: "1", fill: "currentColor", stroke: "none" }));
5806
+ }
5807
+ function SearchIcon({ size = 16 }) {
5808
+ return /* @__PURE__ */ React.createElement("svg", { width: size, height: size, viewBox: "0 0 24 24", ...line, "aria-hidden": "true", style: { flexShrink: 0 } }, /* @__PURE__ */ React.createElement("circle", { cx: "11", cy: "11", r: "6.5" }), /* @__PURE__ */ React.createElement("path", { d: "m20 20-4.2-4.2" }));
5809
+ }
5810
+ function ChevronRightIcon({ size = 16 }) {
5811
+ return /* @__PURE__ */ React.createElement("svg", { width: size, height: size, viewBox: "0 0 24 24", ...line, "aria-hidden": "true", style: { flexShrink: 0 } }, /* @__PURE__ */ React.createElement("path", { d: "m9 6 6 6-6 6" }));
5812
+ }
5813
+
5814
+ // src/ui/SocialWalletModal.tsx
5815
+ import React2, { useCallback, useEffect, useState } from "react";
5816
+ import { createPortal } from "react-dom";
5817
+ function injectTokens(theme) {
5818
+ const resolved = theme === "auto" ? window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light" : theme;
5819
+ let el = document.getElementById("decane-tokens");
5820
+ if (!el) {
5821
+ el = document.createElement("style");
5822
+ el.id = "decane-tokens";
5823
+ document.head.appendChild(el);
5824
+ }
5825
+ el.textContent = `:root { ${CSS_VARS[resolved]} }`;
5826
+ }
5827
+ function countdown(expiresAt) {
5828
+ const secs = Math.max(0, Math.round((expiresAt - Date.now()) / 1e3));
5829
+ return `${Math.floor(secs / 60)}m ${String(secs % 60).padStart(2, "0")}s`;
5830
+ }
5831
+ function downloadJson(data, filename) {
5832
+ const blob = new Blob([JSON.stringify(data, null, 2)], { type: "application/json" });
5833
+ const url = URL.createObjectURL(blob);
5834
+ const a = document.createElement("a");
5835
+ a.href = url;
5836
+ a.download = filename;
5837
+ a.click();
5838
+ URL.revokeObjectURL(url);
5839
+ }
5840
+ function useBalance(kind, address, chain, rpcUrls) {
5841
+ const [state, setState] = useState({ loading: false, value: null, symbol: kind === "evm" ? "ETH" : "SOL" });
5842
+ useEffect(() => {
5843
+ if (!address || !chain) return;
5844
+ let cancelled = false;
5845
+ setState((s) => ({ ...s, loading: true }));
5846
+ fetchBalance({ kind, address, chain, rpcUrls }).then((b) => {
5847
+ if (!cancelled) setState({ loading: false, value: b.formatted, symbol: b.symbol });
5848
+ }).catch(() => {
5849
+ if (!cancelled) setState({ loading: false, value: null, symbol: kind === "evm" ? "ETH" : "SOL" });
5850
+ });
5851
+ return () => {
5852
+ cancelled = true;
5853
+ };
5854
+ }, [kind, address, chain, rpcUrls]);
5855
+ return state;
5856
+ }
5857
+ var MODAL_CSS = `
5858
+ .dcm-card { position: relative; width: 100%; max-width: 380px; max-height: calc(100vh - 32px); overflow-y: auto;
5859
+ background: var(--dc-bg); color: var(--dc-text); border: 1px solid var(--dc-border); border-radius: 24px;
5860
+ box-shadow: 0 24px 64px -12px rgba(0,0,0,.35), 0 2px 8px rgba(0,0,0,.08);
5861
+ animation: dcm-in .22s cubic-bezier(.2,.8,.2,1); box-sizing: border-box; }
5862
+ .dcm-card *, .dcm-card *::before, .dcm-card *::after { box-sizing: border-box; }
5863
+ @keyframes dcm-in { from { opacity: 0; transform: translateY(8px) scale(.985); } to { opacity: 1; transform: none; } }
5864
+ @keyframes dcm-fade { from { opacity: 0; } to { opacity: 1; } }
5865
+ @media (prefers-reduced-motion: reduce) { .dcm-card, .dcm-backdrop { animation: none !important; } }
5866
+ .dcm-backdrop { position: absolute; inset: 0; background: var(--dc-bg-overlay);
5867
+ backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); animation: dcm-fade .2s ease; }
5868
+ .dcm-icon-btn { position: absolute; top: 14px; width: 32px; height: 32px; border-radius: 10px; border: 0;
5869
+ background: transparent; color: var(--dc-text-muted); cursor: pointer; display: grid; place-items: center;
5870
+ padding: 0; transition: background .15s, color .15s; z-index: 1; }
5871
+ .dcm-icon-btn:hover { background: var(--dc-surface-hover); color: var(--dc-text); }
5872
+ .dcm-body { padding: 32px 24px 20px; display: flex; flex-direction: column; align-items: center; gap: 14px; text-align: center; }
5873
+ .dcm-title { margin: 4px 0 0; font-size: 20px; font-weight: 600; letter-spacing: -0.02em; line-height: 1.25; color: var(--dc-text); }
5874
+ .dcm-sub { margin: -6px 0 2px; font-size: 13.5px; line-height: 1.5; color: var(--dc-text-secondary); overflow-wrap: anywhere; }
5875
+ .dcm-sub b { color: var(--dc-text); font-weight: 600; }
5876
+ .dcm-methods { width: 100%; display: grid; gap: 8px; margin-top: 4px; }
5877
+ .dcm-method { width: 100%; height: 48px; display: flex; align-items: center; gap: 12px; padding: 0 14px;
5878
+ border-radius: 14px; border: 1px solid var(--dc-border); background: var(--dc-surface); color: var(--dc-text);
5879
+ font-weight: 500; font-size: 14.5px; line-height: 1; font-family: inherit; cursor: pointer; text-align: left;
5880
+ transition: border-color .15s, background .15s; }
5881
+ .dcm-method:hover:not(:disabled) { border-color: var(--dc-text-muted); background: var(--dc-surface-hover); }
5882
+ .dcm-method:disabled { opacity: .6; cursor: default; }
5883
+ .dcm-method:focus-visible, .dcm-primary:focus-visible, .dcm-link:focus-visible, .dcm-icon-btn:focus-visible,
5884
+ .dcm-ghost:focus-visible, .dcm-copy:focus-visible { outline: 2px solid var(--dc-accent); outline-offset: 2px; }
5885
+ .dcm-method > svg { color: var(--dc-text-secondary); }
5886
+ .dcm-method-input { cursor: text; padding-right: 6px; }
5887
+ .dcm-method-input:focus-within { border-color: var(--dc-accent); }
5888
+ .dcm-method-input input { flex: 1; min-width: 0; height: 100%; border: 0; outline: 0; background: transparent;
5889
+ color: var(--dc-text); font-family: inherit; font-size: 14.5px; padding: 0; }
5890
+ .dcm-method-input input::placeholder { color: var(--dc-text-muted); }
5891
+ .dcm-submit { height: 34px; padding: 0 12px; border-radius: 10px; border: 0; background: transparent;
5892
+ color: var(--dc-accent-ink); font-weight: 600; font-size: 13.5px; line-height: 1; font-family: inherit; cursor: pointer; transition: background .15s; }
5893
+ .dcm-submit:hover:not(:disabled) { background: var(--dc-surface-hover); }
5894
+ .dcm-submit:disabled { color: var(--dc-text-muted); cursor: default; }
5895
+ .dcm-form { width: 100%; display: grid; gap: 10px; margin-top: 4px; }
5896
+ .dcm-field { width: 100%; padding: 12px 14px; border-radius: 12px; border: 1px solid var(--dc-border);
5897
+ background: var(--dc-surface); color: var(--dc-text); font-family: inherit; font-size: 15px; outline: none;
5898
+ transition: border-color .15s, box-shadow .15s; }
5899
+ .dcm-field::placeholder { color: var(--dc-text-muted); }
5900
+ .dcm-field:focus { border-color: var(--dc-accent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--dc-accent) 22%, transparent); }
5901
+ .dcm-code { height: 56px; text-align: center; font-family: var(--dc-font-mono); font-size: 24px; letter-spacing: .45em; padding-left: calc(14px + .45em); }
5902
+ .dcm-primary { width: 100%; height: 48px; border-radius: 14px; border: 0; background: var(--dc-accent); color: var(--dc-accent-text);
5903
+ font-weight: 600; font-size: 14.5px; line-height: 1; font-family: inherit; cursor: pointer; display: flex; align-items: center; justify-content: center; gap: 8px;
5904
+ transition: background .15s, opacity .15s; }
5905
+ .dcm-primary:hover:not(:disabled) { background: var(--dc-accent-hover); }
5906
+ .dcm-primary:disabled { opacity: .55; cursor: default; }
5907
+ .dcm-ghost { height: 44px; padding: 0 16px; border-radius: 12px; border: 1px solid var(--dc-border); background: transparent;
5908
+ color: var(--dc-text); font-weight: 500; font-size: 14px; line-height: 1; font-family: inherit; cursor: pointer; transition: background .15s, border-color .15s; white-space: nowrap; }
5909
+ .dcm-ghost:hover:not(:disabled) { background: var(--dc-surface-hover); border-color: var(--dc-text-muted); }
5910
+ .dcm-ghost:disabled { opacity: .55; cursor: default; }
5911
+ .dcm-link { border: 0; background: transparent; color: var(--dc-accent-ink); font-weight: 500; font-size: 13.5px; line-height: 1.4; font-family: inherit;
5912
+ cursor: pointer; padding: 4px; border-radius: 6px; }
5913
+ .dcm-link:hover { text-decoration: underline; text-underline-offset: 3px; }
5914
+ .dcm-badge { width: 52px; height: 52px; border-radius: 16px; display: grid; place-items: center;
5915
+ background: var(--dc-surface); border: 1px solid var(--dc-border); color: var(--dc-text); }
5916
+ .dcm-error { margin: 0; width: 100%; font-size: 13px; line-height: 1.45; color: var(--dc-danger); overflow-wrap: anywhere; }
5917
+ .dcm-protected { width: 100%; display: flex; align-items: center; justify-content: center; gap: 6px;
5918
+ margin-top: 6px; padding-top: 14px; border-top: 1px solid var(--dc-border); font-size: 12.5px; color: var(--dc-text-muted); }
5919
+ .dcm-status { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; font-weight: 500; }
5920
+ .dcm-status i { width: 7px; height: 7px; border-radius: 50%; display: block; }
5921
+ .dcm-addresses { width: 100%; border: 1px solid var(--dc-border); border-radius: 16px; overflow: hidden; text-align: left; }
5922
+ .dcm-address { display: flex; align-items: center; gap: 12px; padding: 12px 14px; background: var(--dc-surface); }
5923
+ .dcm-address + .dcm-address { border-top: 1px solid var(--dc-border); }
5924
+ .dcm-address-main { flex: 1; min-width: 0; display: grid; gap: 3px; }
5925
+ .dcm-address-main span { font-size: 13px; color: var(--dc-text-secondary); }
5926
+ .dcm-address-main code { font-family: var(--dc-font-mono); font-size: 13px; color: var(--dc-text); }
5927
+ .dcm-balance { font-family: var(--dc-font-mono); font-size: 13px; color: var(--dc-text); white-space: nowrap; }
5928
+ .dcm-copy { width: 30px; height: 30px; border-radius: 9px; border: 0; background: transparent; color: var(--dc-text-muted);
5929
+ display: grid; place-items: center; cursor: pointer; padding: 0; transition: background .15s, color .15s; }
5930
+ .dcm-copy:hover { background: var(--dc-surface-hover); color: var(--dc-text); }
5931
+ .dcm-panel { width: 100%; border: 1px solid var(--dc-border); border-radius: 16px; text-align: left; overflow: hidden; }
5932
+ .dcm-panel-head { width: 100%; display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 13px 14px;
5933
+ border: 0; background: var(--dc-surface); color: var(--dc-text); font-weight: 500; font-size: 14px; line-height: 1; font-family: inherit; cursor: pointer; }
5934
+ .dcm-panel-head:hover { background: var(--dc-surface-hover); }
5935
+ .dcm-panel-head svg { color: var(--dc-text-muted); }
5936
+ .dcm-panel-body { padding: 14px; border-top: 1px solid var(--dc-border); display: grid; gap: 10px; }
5937
+ .dcm-note { margin: 0; font-size: 13px; line-height: 1.5; color: var(--dc-text-secondary); }
5938
+ .dcm-warn { padding: 12px; border-radius: 12px; font-size: 13px; line-height: 1.5;
5939
+ background: color-mix(in srgb, var(--dc-danger) 9%, transparent); border: 1px solid color-mix(in srgb, var(--dc-danger) 30%, transparent); color: var(--dc-text); }
5940
+ .dcm-warn strong { display: block; margin-bottom: 2px; color: var(--dc-danger); font-weight: 600; }
5941
+ .dcm-check { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--dc-text); cursor: pointer; }
5942
+ .dcm-check input { width: 16px; height: 16px; margin: 0; accent-color: var(--dc-accent); }
5943
+ .dcm-row { display: flex; gap: 8px; width: 100%; }
5944
+ .dcm-row > .dcm-primary { flex: 1; height: 44px; border-radius: 12px; }
5945
+ .dcm-actions { width: 100%; display: flex; gap: 8px; }
5946
+ .dcm-or { width: 100%; display: flex; align-items: center; gap: 10px; font-size: 12.5px; color: var(--dc-text-muted); }
5947
+ .dcm-or::before, .dcm-or::after { content: ""; flex: 1; height: 1px; background: var(--dc-border); }
5948
+ .dcm-method .dcm-trail { margin-left: auto; display: inline-flex; align-items: center; gap: 8px; color: var(--dc-text-muted); font-size: 12.5px; font-weight: 500; }
5949
+ .dcm-stack { display: inline-flex; }
5950
+ .dcm-stack img, .dcm-stack span { width: 22px; height: 22px; border-radius: 7px; border: 2px solid var(--dc-surface); margin-left: -7px; object-fit: cover; background: var(--dc-surface-hover); }
5951
+ .dcm-stack > :first-child { margin-left: 0; }
5952
+ .dcm-method:hover:not(:disabled) .dcm-stack img { border-color: var(--dc-surface-hover); }
5953
+ .dcm-wallet-img { width: 26px; height: 26px; border-radius: 8px; object-fit: cover; flex-shrink: 0; }
5954
+ .dcm-list { width: 100%; display: grid; gap: 8px; max-height: min(380px, 50vh); overflow-y: auto; padding: 2px; margin: -2px; }
5955
+ .dcm-pills { width: 100%; display: flex; gap: 4px; padding: 4px; border-radius: 12px; background: var(--dc-surface); border: 1px solid var(--dc-border); }
5956
+ .dcm-pills button { flex: 1; height: 30px; border: 0; border-radius: 9px; background: transparent; color: var(--dc-text-secondary);
5957
+ font-family: inherit; font-size: 13px; font-weight: 500; cursor: pointer; transition: background .15s, color .15s; }
5958
+ .dcm-pills button:hover { color: var(--dc-text); }
5959
+ .dcm-pills button[aria-pressed="true"] { background: var(--dc-bg); color: var(--dc-text); box-shadow: 0 1px 3px rgba(0,0,0,.12); }
5960
+ .dcm-search { position: relative; width: 100%; }
5961
+ .dcm-search svg { position: absolute; left: 13px; top: 50%; transform: translateY(-50%); color: var(--dc-text-muted); pointer-events: none; }
5962
+ .dcm-search .dcm-field { padding: 10px 14px 10px 38px; font-size: 14px; }
5963
+ .dcm-empty { width: 100%; padding: 28px 12px; font-size: 13.5px; color: var(--dc-text-muted); }
5964
+ .dcm-option { width: 100%; display: flex; align-items: center; gap: 12px; padding: 12px 14px; border-radius: 14px; border: 1px solid var(--dc-border);
5965
+ background: var(--dc-surface); color: var(--dc-text); font-family: inherit; text-align: left; cursor: pointer; transition: border-color .15s, background .15s; }
5966
+ .dcm-option:hover { border-color: var(--dc-text-muted); background: var(--dc-surface-hover); }
5967
+ .dcm-option:focus-visible, .dcm-pills button:focus-visible { outline: 2px solid var(--dc-accent); outline-offset: 2px; }
5968
+ .dcm-option-icons { width: 64px; flex-shrink: 0; display: flex; }
5969
+ .dcm-option-text { flex: 1; min-width: 0; }
5970
+ .dcm-option b { display: block; font-size: 14.5px; font-weight: 500; }
5971
+ .dcm-option small { display: block; margin-top: 2px; font-size: 12.5px; line-height: 1.4; color: var(--dc-text-secondary); }
5972
+ .dcm-option > svg { color: var(--dc-text-muted); }
5973
+ .dcm-actions > * { flex: 1; }
5974
+ `;
5975
+ function injectModalCss() {
5976
+ if (document.getElementById("decane-modal-css")) return;
5977
+ const el = document.createElement("style");
5978
+ el.id = "decane-modal-css";
5979
+ el.textContent = MODAL_CSS;
5980
+ document.head.appendChild(el);
5981
+ }
5982
+ function shortAddress(a, head = 6, tail = 4) {
5983
+ return a.length > head + tail + 1 ? `${a.slice(0, head)}\u2026${a.slice(-tail)}` : a;
5984
+ }
5985
+ function CopyButton({ value, label }) {
5986
+ const [copied, setCopied] = useState(false);
5987
+ async function copy() {
5988
+ await navigator.clipboard.writeText(value).catch(() => {
5989
+ });
5990
+ setCopied(true);
5991
+ setTimeout(() => setCopied(false), 1500);
5992
+ }
5993
+ return /* @__PURE__ */ React2.createElement("button", { type: "button", className: "dcm-copy", onClick: copy, "aria-label": copied ? "Copied" : `Copy ${label} address`, title: copied ? "Copied" : "Copy address" }, copied ? /* @__PURE__ */ React2.createElement(CheckIcon, null) : /* @__PURE__ */ React2.createElement(CopyIcon, null));
5994
+ }
5995
+ function AddressRow({
5996
+ label,
5997
+ address,
5998
+ kind,
5999
+ chain,
6000
+ rpcUrls
6001
+ }) {
6002
+ const balance = useBalance(kind, address, chain, rpcUrls);
6003
+ return /* @__PURE__ */ React2.createElement("div", { className: "dcm-address" }, /* @__PURE__ */ React2.createElement("div", { className: "dcm-address-main" }, /* @__PURE__ */ React2.createElement("span", null, label), /* @__PURE__ */ React2.createElement("code", { title: address }, shortAddress(address, 8, 6))), /* @__PURE__ */ React2.createElement("span", { className: "dcm-balance" }, balance.loading ? "\u2026" : `${formatBalanceDisplay(balance.value)} ${balance.symbol}`), /* @__PURE__ */ React2.createElement(CopyButton, { value: address, label }));
6004
+ }
6005
+ function ProtectedBy() {
6006
+ return /* @__PURE__ */ React2.createElement("div", { className: "dcm-protected" }, /* @__PURE__ */ React2.createElement("span", null, "Protected by"), /* @__PURE__ */ React2.createElement(DecaneMark, { size: 14, muted: true }), /* @__PURE__ */ React2.createElement(DecaneWordmark, { size: 12, muted: true }));
6007
+ }
6008
+ function SignInView({
5888
6009
  onGoogleSignIn,
5889
6010
  onKingsChatSignIn,
5890
6011
  onXSignIn,
@@ -5892,1362 +6013,219 @@ function WalletSelector({
5892
6013
  onEmailVerify,
5893
6014
  onPhoneStart,
5894
6015
  onPhoneVerify,
6016
+ authMethods,
6017
+ resumeHint,
5895
6018
  customAuthLabel,
5896
6019
  onCustomAuthSignIn,
5897
- canUsePasskey = false,
5898
- passkeyAddress = null,
5899
- onPasskeySignIn
6020
+ canUsePasskey,
6021
+ passkeyAddress,
6022
+ onPasskeySignIn,
6023
+ extra
5900
6024
  }) {
5901
- const showSocial = hasSocialMode(mode);
5902
- const showWallets = mode !== "social";
5903
- const [view, setView] = useState(showSocial ? "social" : "wallets");
5904
- const [search, setSearch] = useState("");
5905
- const [filter, setFilter] = useState("all");
5906
- const [pendingWallet, setPendingWallet] = useState(null);
5907
- const [emailStep, setEmailStep] = useState("input");
5908
- const [emailVal, setEmailVal] = useState("");
5909
- const [codeVal, setCodeVal] = useState("");
5910
- const [phoneStep, setPhoneStep] = useState("input");
5911
- const [phoneVal, setPhoneVal] = useState("");
6025
+ const [googleLoading, setGoogleLoading] = useState(false);
6026
+ const [kingsChatLoading, setKingsChatLoading] = useState(false);
6027
+ const [xLoading, setXLoading] = useState(false);
6028
+ const [email, setEmail] = useState("");
6029
+ const [code, setCode] = useState("");
6030
+ const [emailSent, setEmailSent] = useState(false);
6031
+ const [emailLoading, setEmailLoading] = useState(false);
6032
+ const [phone, setPhone] = useState("");
5912
6033
  const [phoneCode, setPhoneCode] = useState("");
5913
- const [socialLoad, setSocialLoad] = useState(false);
5914
- const [socialErr, setSocialErr] = useState("");
6034
+ const [phoneSent, setPhoneSent] = useState(false);
6035
+ const [phoneLoading, setPhoneLoading] = useState(false);
6036
+ const [customLoading, setCustomLoading] = useState(false);
6037
+ const [passkeyLoading, setPasskeyLoading] = useState(false);
5915
6038
  const [showOtherMethods, setShowOtherMethods] = useState(false);
5916
- const passkeyFirst = canUsePasskey && !!onPasskeySignIn && !showOtherMethods;
5917
- useEffect(() => {
5918
- if (!open) return;
5919
- injectFont();
5920
- injectTokens(theme);
5921
- if (theme !== "auto") return;
5922
- const mq = window.matchMedia("(prefers-color-scheme: dark)");
5923
- const handler = () => injectTokens("auto");
5924
- mq.addEventListener("change", handler);
5925
- return () => mq.removeEventListener("change", handler);
5926
- }, [open, theme]);
5927
- useEffect(() => {
5928
- if (!open) {
5929
- setSearch("");
5930
- setFilter("all");
5931
- setPendingWallet(null);
5932
- setView(showSocial ? "social" : "wallets");
5933
- setEmailStep("input");
5934
- setEmailVal("");
5935
- setCodeVal("");
5936
- setSocialErr("");
5937
- setShowOtherMethods(false);
5938
- return;
5939
- }
5940
- return () => {
5941
- document.getElementById("decane-tokens")?.remove();
5942
- };
5943
- }, [open, showWallets]);
5944
- async function handlePasskeySignIn() {
6039
+ const [error, setError] = useState("");
6040
+ const passkeyFirst = !!canUsePasskey && !!onPasskeySignIn && !showOtherMethods;
6041
+ const busy = googleLoading || kingsChatLoading || xLoading || customLoading || emailLoading || phoneLoading;
6042
+ async function handlePasskey() {
5945
6043
  if (!onPasskeySignIn) return;
5946
- setSocialLoad(true);
5947
- setSocialErr("");
6044
+ setError("");
6045
+ setPasskeyLoading(true);
5948
6046
  try {
5949
6047
  await onPasskeySignIn();
5950
6048
  } catch (e) {
5951
6049
  const err = e;
5952
6050
  if (err?.name !== "UserCancelledError") {
5953
- setSocialErr(err?.message ?? "Passkey sign-in failed");
6051
+ setError(err?.message ?? "Passkey sign-in failed");
5954
6052
  setShowOtherMethods(true);
5955
6053
  }
5956
- setSocialLoad(false);
6054
+ setPasskeyLoading(false);
5957
6055
  }
5958
6056
  }
5959
- async function handlePasskeyClick() {
5960
- void handlePasskeySignIn();
5961
- }
5962
- async function handleGoogleClick() {
5963
- if (!onGoogleSignIn) return;
5964
- setSocialLoad(true);
5965
- setSocialErr("");
6057
+ async function handleGoogle() {
6058
+ setError("");
6059
+ setGoogleLoading(true);
5966
6060
  try {
5967
6061
  await onGoogleSignIn();
5968
6062
  } catch (e) {
5969
- setSocialErr(e.message);
5970
- setSocialLoad(false);
6063
+ setError(e.message);
6064
+ setGoogleLoading(false);
5971
6065
  }
5972
6066
  }
5973
- async function handleKingsChatClick() {
6067
+ async function handleKingsChat() {
5974
6068
  if (!onKingsChatSignIn) return;
5975
- setSocialLoad(true);
5976
- setSocialErr("");
6069
+ setError("");
6070
+ setKingsChatLoading(true);
5977
6071
  try {
5978
6072
  await onKingsChatSignIn();
5979
6073
  } catch (e) {
5980
- setSocialErr(e.message);
6074
+ setError(e.message);
5981
6075
  } finally {
5982
- setSocialLoad(false);
6076
+ setKingsChatLoading(false);
5983
6077
  }
5984
6078
  }
5985
- async function handleXClick() {
6079
+ async function handleX() {
5986
6080
  if (!onXSignIn) return;
5987
- setSocialLoad(true);
5988
- setSocialErr("");
6081
+ setError("");
6082
+ setXLoading(true);
5989
6083
  try {
5990
6084
  await onXSignIn();
5991
6085
  } catch (e) {
5992
- setSocialErr(e.message);
5993
- setSocialLoad(false);
5994
- }
5995
- }
5996
- async function handleCustomAuthClick() {
5997
- if (!onCustomAuthSignIn) return;
5998
- setSocialLoad(true);
5999
- setSocialErr("");
6000
- try {
6001
- await onCustomAuthSignIn();
6002
- } catch (e) {
6003
- setSocialErr(e.message);
6004
- setSocialLoad(false);
6086
+ setError(e.message);
6087
+ setXLoading(false);
6005
6088
  }
6006
6089
  }
6007
6090
  async function handleEmailStart(e) {
6008
6091
  e.preventDefault();
6009
- if (!onEmailStart) return;
6010
- setSocialLoad(true);
6011
- setSocialErr("");
6092
+ setError("");
6093
+ setEmailLoading(true);
6012
6094
  try {
6013
- await onEmailStart(emailVal);
6014
- setEmailStep("code");
6095
+ await onEmailStart(email.trim());
6096
+ setEmailSent(true);
6015
6097
  } catch (e2) {
6016
- setSocialErr(e2.message);
6098
+ setError(e2.message);
6017
6099
  } finally {
6018
- setSocialLoad(false);
6100
+ setEmailLoading(false);
6019
6101
  }
6020
6102
  }
6021
6103
  async function handleEmailVerify(e) {
6022
6104
  e.preventDefault();
6023
- if (!onEmailVerify) return;
6024
- setSocialLoad(true);
6025
- setSocialErr("");
6105
+ setError("");
6106
+ setEmailLoading(true);
6026
6107
  try {
6027
- await onEmailVerify(emailVal, codeVal);
6108
+ await onEmailVerify(email.trim(), code);
6028
6109
  } catch (e2) {
6029
- setSocialErr(e2.message);
6110
+ setError(e2.message);
6030
6111
  } finally {
6031
- setSocialLoad(false);
6112
+ setEmailLoading(false);
6032
6113
  }
6033
6114
  }
6034
6115
  async function handlePhoneStart(e) {
6035
6116
  e.preventDefault();
6036
6117
  if (!onPhoneStart) return;
6037
- setSocialLoad(true);
6038
- setSocialErr("");
6118
+ setError("");
6119
+ setPhoneLoading(true);
6039
6120
  try {
6040
- await onPhoneStart(phoneVal);
6041
- setPhoneStep("code");
6121
+ await onPhoneStart(phone.trim());
6122
+ setPhoneSent(true);
6042
6123
  } catch (e2) {
6043
- setSocialErr(e2.message);
6124
+ setError(e2.message);
6044
6125
  } finally {
6045
- setSocialLoad(false);
6126
+ setPhoneLoading(false);
6046
6127
  }
6047
6128
  }
6048
6129
  async function handlePhoneVerify(e) {
6049
6130
  e.preventDefault();
6050
6131
  if (!onPhoneVerify) return;
6051
- setSocialLoad(true);
6052
- setSocialErr("");
6132
+ setError("");
6133
+ setPhoneLoading(true);
6053
6134
  try {
6054
- await onPhoneVerify(phoneVal, phoneCode);
6135
+ await onPhoneVerify(phone.trim(), phoneCode);
6055
6136
  } catch (e2) {
6056
- setSocialErr(e2.message);
6137
+ setError(e2.message);
6057
6138
  } finally {
6058
- setSocialLoad(false);
6139
+ setPhoneLoading(false);
6059
6140
  }
6060
6141
  }
6061
- const handleKey = useCallback(
6062
- (e) => {
6063
- if (e.key === "Escape") {
6064
- if (pendingWallet) {
6065
- setPendingWallet(null);
6066
- } else {
6067
- onClose();
6068
- }
6069
- }
6070
- },
6071
- [onClose, pendingWallet]
6072
- );
6073
- useEffect(() => {
6074
- if (!open) return;
6075
- document.addEventListener("keydown", handleKey);
6076
- return () => document.removeEventListener("keydown", handleKey);
6077
- }, [open, handleKey]);
6078
- if (!open) return null;
6079
- const q = search.toLowerCase();
6080
- const networkWallets = provider.wallets.filter((w) => {
6081
- const cs = w.chainSupport;
6082
- if (networks === "evm") return cs.includes("evm");
6083
- if (networks === "solana") return cs.includes("solana");
6084
- if (networks === "tron") return cs.includes("tron");
6085
- if (networks === "bitcoin") return cs.includes("bitcoin");
6086
- return true;
6087
- });
6088
- const baseWallets = filter === "evm" ? networkWallets.filter((w) => w.chainSupport.includes("evm")) : filter === "solana" ? networkWallets.filter((w) => w.chainSupport.includes("solana")) : filter === "tron" ? networkWallets.filter((w) => w.chainSupport.includes("tron")) : filter === "bitcoin" ? networkWallets.filter((w) => w.chainSupport.includes("bitcoin")) : networkWallets;
6089
- const filtered = q ? baseWallets.filter((w) => w.name.toLowerCase().includes(q)) : baseWallets;
6090
- function handleWalletClick(wallet) {
6091
- const cs = wallet.chainSupport;
6092
- const isMulti = cs.length >= 2;
6093
- if (isMulti && networks === "all") {
6094
- setPendingWallet(wallet);
6095
- } else {
6096
- const preference = networks === "evm" ? "evm" : networks === "solana" ? "solana" : networks === "tron" ? "tron" : networks === "bitcoin" ? "bitcoin" : void 0;
6097
- onConnect(wallet, preference);
6098
- onClose();
6142
+ async function handleCustomAuth() {
6143
+ if (!onCustomAuthSignIn) return;
6144
+ setError("");
6145
+ setCustomLoading(true);
6146
+ try {
6147
+ await onCustomAuthSignIn();
6148
+ } catch (e) {
6149
+ setError(e.message);
6150
+ } finally {
6151
+ setCustomLoading(false);
6099
6152
  }
6100
6153
  }
6101
- function handleChainChoice(preference) {
6102
- if (!pendingWallet) return;
6103
- onConnect(pendingWallet, preference);
6104
- onClose();
6154
+ function backToMethods() {
6155
+ setEmailSent(false);
6156
+ setCode("");
6157
+ setPhoneSent(false);
6158
+ setPhoneCode("");
6159
+ setError("");
6105
6160
  }
6106
- const modal = /* @__PURE__ */ React2.createElement(
6107
- "div",
6108
- {
6109
- role: "dialog",
6110
- "aria-modal": "true",
6111
- "aria-label": "Connect wallet",
6112
- style: {
6113
- position: "fixed",
6114
- inset: 0,
6115
- zIndex: 9999,
6116
- display: "flex",
6117
- alignItems: "center",
6118
- justifyContent: "center",
6119
- padding: "16px",
6120
- // Same fallback chain as SocialWalletModal — without it, this modal
6121
- // drops to the browser default serif whenever the token block hasn't
6122
- // been injected, while the social modal still lands on system-ui.
6123
- fontFamily: "var(--dc-font-sans, system-ui, sans-serif)"
6124
- }
6125
- },
6126
- /* @__PURE__ */ React2.createElement(
6127
- "div",
6161
+ const errorLine = error ? /* @__PURE__ */ React2.createElement("p", { className: "dcm-error", role: "alert" }, error) : null;
6162
+ if (passkeyFirst) {
6163
+ return /* @__PURE__ */ React2.createElement("div", { className: "dcm-body" }, /* @__PURE__ */ React2.createElement("div", { className: "dcm-badge" }, /* @__PURE__ */ React2.createElement(KeyIcon, { size: 22 })), /* @__PURE__ */ React2.createElement("h2", { className: "dcm-title" }, "Welcome back"), /* @__PURE__ */ React2.createElement("p", { className: "dcm-sub" }, passkeyAddress ? /* @__PURE__ */ React2.createElement(React2.Fragment, null, "Unlock ", /* @__PURE__ */ React2.createElement("b", null, shortAddress(passkeyAddress)), " with your passkey.") : "Unlock your wallet with your passkey."), /* @__PURE__ */ React2.createElement("button", { type: "button", className: "dcm-primary", onClick: handlePasskey, disabled: passkeyLoading }, passkeyLoading ? "Waiting for passkey\u2026" : "Continue with passkey"), errorLine, /* @__PURE__ */ React2.createElement("button", { type: "button", className: "dcm-link", onClick: () => {
6164
+ setError("");
6165
+ setShowOtherMethods(true);
6166
+ } }, "Use another sign-in method"), /* @__PURE__ */ React2.createElement(ProtectedBy, null));
6167
+ }
6168
+ if (emailSent || phoneSent) {
6169
+ const isEmail = emailSent;
6170
+ const value = isEmail ? code : phoneCode;
6171
+ const setValue = isEmail ? setCode : setPhoneCode;
6172
+ const loading = isEmail ? emailLoading : phoneLoading;
6173
+ return /* @__PURE__ */ React2.createElement("form", { className: "dcm-body", onSubmit: isEmail ? handleEmailVerify : handlePhoneVerify }, /* @__PURE__ */ React2.createElement("div", { className: "dcm-badge" }, isEmail ? /* @__PURE__ */ React2.createElement(MailIcon, { size: 22 }) : /* @__PURE__ */ React2.createElement(PhoneIcon, { size: 22 })), /* @__PURE__ */ React2.createElement("h2", { className: "dcm-title" }, "Enter your code"), /* @__PURE__ */ React2.createElement("p", { className: "dcm-sub" }, "We sent a 6-digit code to ", /* @__PURE__ */ React2.createElement("b", null, isEmail ? email.trim() : phone.trim())), /* @__PURE__ */ React2.createElement("div", { className: "dcm-form" }, /* @__PURE__ */ React2.createElement(
6174
+ "input",
6128
6175
  {
6129
- onClick: () => {
6130
- if (pendingWallet) {
6131
- setPendingWallet(null);
6132
- } else {
6133
- onClose();
6134
- }
6135
- },
6136
- style: {
6137
- position: "absolute",
6138
- inset: 0,
6139
- background: "var(--dc-bg-overlay)",
6140
- backdropFilter: "blur(8px)",
6141
- WebkitBackdropFilter: "blur(8px)"
6142
- }
6143
- }
6144
- ),
6145
- /* @__PURE__ */ React2.createElement(
6146
- "div",
6147
- {
6148
- style: {
6149
- position: "relative",
6150
- background: "var(--dc-bg)",
6151
- border: "1px solid var(--dc-border)",
6152
- borderRadius: 20,
6153
- width: "100%",
6154
- maxWidth: 400,
6155
- maxHeight: "85vh",
6156
- display: "flex",
6157
- flexDirection: "column",
6158
- boxShadow: "0 24px 64px rgba(0,0,0,0.6), 0 0 0 1px rgba(255,255,255,0.04)",
6159
- overflow: "hidden"
6160
- }
6161
- },
6162
- /* @__PURE__ */ React2.createElement(
6163
- "div",
6164
- {
6165
- style: {
6166
- height: 2,
6167
- background: "linear-gradient(90deg, transparent, var(--dc-accent) 30%, var(--dc-accent) 70%, transparent)"
6168
- }
6169
- }
6170
- ),
6171
- pendingWallet ? (
6172
- /* ── Chain picker step ───────────────────────────────────────── */
6173
- /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement("div", { style: { padding: "18px 20px 16px", display: "flex", alignItems: "center", gap: 10 } }, /* @__PURE__ */ React2.createElement(
6174
- "button",
6175
- {
6176
- onClick: () => setPendingWallet(null),
6177
- "aria-label": "Back",
6178
- style: {
6179
- background: "var(--dc-surface)",
6180
- border: "1px solid var(--dc-border)",
6181
- borderRadius: 8,
6182
- width: 28,
6183
- height: 28,
6184
- display: "flex",
6185
- alignItems: "center",
6186
- justifyContent: "center",
6187
- cursor: "pointer",
6188
- color: "var(--dc-text-muted)",
6189
- flexShrink: 0,
6190
- fontFamily: "inherit",
6191
- padding: 0
6192
- }
6193
- },
6194
- /* @__PURE__ */ React2.createElement("svg", { width: "12", height: "12", viewBox: "0 0 12 12", fill: "none" }, /* @__PURE__ */ React2.createElement("path", { d: "M7.5 2L3 6l4.5 4", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }))
6195
- ), /* @__PURE__ */ React2.createElement("h2", { style: { margin: 0, fontSize: 16, fontWeight: 800, color: "var(--dc-text)", letterSpacing: "-0.02em" } }, "Choose networks"), /* @__PURE__ */ React2.createElement(
6196
- "button",
6197
- {
6198
- onClick: onClose,
6199
- "aria-label": "Close",
6200
- style: {
6201
- marginLeft: "auto",
6202
- background: "var(--dc-surface)",
6203
- border: "1px solid var(--dc-border)",
6204
- borderRadius: 8,
6205
- width: 28,
6206
- height: 28,
6207
- display: "flex",
6208
- alignItems: "center",
6209
- justifyContent: "center",
6210
- cursor: "pointer",
6211
- color: "var(--dc-text-muted)",
6212
- flexShrink: 0,
6213
- fontFamily: "inherit",
6214
- padding: 0
6215
- }
6216
- },
6217
- /* @__PURE__ */ React2.createElement("svg", { width: "12", height: "12", viewBox: "0 0 12 12", fill: "none" }, /* @__PURE__ */ React2.createElement("path", { d: "M1.5 1.5L10.5 10.5M10.5 1.5L1.5 10.5", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" }))
6218
- )), /* @__PURE__ */ React2.createElement(
6219
- "div",
6220
- {
6221
- style: {
6222
- margin: "0 20px 16px",
6223
- padding: "12px 14px",
6224
- background: "var(--dc-surface)",
6225
- border: "1px solid var(--dc-border)",
6226
- borderRadius: 12,
6227
- display: "flex",
6228
- alignItems: "center",
6229
- gap: 12
6230
- }
6231
- },
6232
- /* @__PURE__ */ React2.createElement(WalletIcon, { src: pendingWallet.icon || void 0, name: pendingWallet.name, size: 36 }),
6233
- /* @__PURE__ */ React2.createElement("div", null, /* @__PURE__ */ React2.createElement("div", { style: { fontSize: 14, fontWeight: 700, color: "var(--dc-text)" } }, pendingWallet.name), /* @__PURE__ */ React2.createElement("div", { style: { fontSize: 11, color: "var(--dc-text-muted)", marginTop: 2 } }, "Multi-chain wallet detected"))
6234
- ), /* @__PURE__ */ React2.createElement("div", { style: { padding: "0 12px 20px", display: "flex", flexDirection: "column", gap: 8 } }, pendingWallet.chainSupport.includes("evm") && /* @__PURE__ */ React2.createElement(
6235
- ChainOption,
6236
- {
6237
- label: "EVM networks",
6238
- description: "Connect your Ethereum-compatible address only",
6239
- badges: /* @__PURE__ */ React2.createElement(ChainIconStack, { support: ["evm"], size: 18 }),
6240
- onClick: () => handleChainChoice("evm")
6241
- }
6242
- ), pendingWallet.chainSupport.includes("solana") && /* @__PURE__ */ React2.createElement(
6243
- ChainOption,
6244
- {
6245
- label: "Solana network",
6246
- description: "Connect your Solana address only",
6247
- badges: /* @__PURE__ */ React2.createElement(ChainIconStack, { support: ["solana"], size: 18 }),
6248
- onClick: () => handleChainChoice("solana")
6249
- }
6250
- ), pendingWallet.chainSupport.includes("tron") && /* @__PURE__ */ React2.createElement(
6251
- ChainOption,
6252
- {
6253
- label: "Tron network",
6254
- description: "Connect your Tron address only",
6255
- badges: /* @__PURE__ */ React2.createElement(ChainIconStack, { support: ["tron"], size: 18 }),
6256
- onClick: () => handleChainChoice("tron")
6257
- }
6258
- ), pendingWallet.chainSupport.includes("bitcoin") && /* @__PURE__ */ React2.createElement(
6259
- ChainOption,
6260
- {
6261
- label: "Bitcoin network",
6262
- description: "Connect your Bitcoin address only",
6263
- badges: /* @__PURE__ */ React2.createElement(ChainIconStack, { support: ["bitcoin"], size: 18 }),
6264
- onClick: () => handleChainChoice("bitcoin")
6265
- }
6266
- ), /* @__PURE__ */ React2.createElement(
6267
- ChainOption,
6268
- {
6269
- label: "All networks",
6270
- description: "Connect all supported addresses together",
6271
- badges: /* @__PURE__ */ React2.createElement(ChainIconStack, { support: pendingWallet.chainSupport, size: 18 }),
6272
- onClick: () => handleChainChoice(void 0)
6273
- }
6274
- )))
6275
- ) : (
6276
- /* ── Wallet list / Social sign-in ────────────────────────────── */
6277
- /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement("div", { style: { padding: "18px 20px 0" } }, /* @__PURE__ */ React2.createElement("div", { style: { display: "flex", alignItems: "flex-start", justifyContent: "space-between", marginBottom: 14 } }, /* @__PURE__ */ React2.createElement("div", null, /* @__PURE__ */ React2.createElement("h2", { style: { margin: 0, fontSize: 17, fontWeight: 800, color: "var(--dc-text)", letterSpacing: "-0.02em", lineHeight: 1.2 } }, view === "social" ? "Sign in" : "Connect wallet"), view === "wallets" && networkWallets.length > 0 && /* @__PURE__ */ React2.createElement("p", { style: { margin: "3px 0 0", fontSize: 12, color: "var(--dc-text-muted)" } }, networkWallets.length, " wallet", networkWallets.length !== 1 ? "s" : "", " detected")), /* @__PURE__ */ React2.createElement(
6278
- "button",
6279
- {
6280
- onClick: onClose,
6281
- "aria-label": "Close",
6282
- style: {
6283
- background: "var(--dc-surface)",
6284
- border: "1px solid var(--dc-border)",
6285
- cursor: "pointer",
6286
- padding: 0,
6287
- width: 28,
6288
- height: 28,
6289
- borderRadius: 8,
6290
- display: "flex",
6291
- alignItems: "center",
6292
- justifyContent: "center",
6293
- color: "var(--dc-text-muted)",
6294
- flexShrink: 0,
6295
- transition: "background 0.12s, color 0.12s",
6296
- fontFamily: "inherit"
6297
- },
6298
- onMouseEnter: (e) => {
6299
- e.currentTarget.style.background = "var(--dc-surface-hover)";
6300
- e.currentTarget.style.color = "var(--dc-text)";
6301
- },
6302
- onMouseLeave: (e) => {
6303
- e.currentTarget.style.background = "var(--dc-surface)";
6304
- e.currentTarget.style.color = "var(--dc-text-muted)";
6305
- }
6306
- },
6307
- /* @__PURE__ */ React2.createElement("svg", { width: "12", height: "12", viewBox: "0 0 12 12", fill: "none" }, /* @__PURE__ */ React2.createElement("path", { d: "M1.5 1.5L10.5 10.5M10.5 1.5L1.5 10.5", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" }))
6308
- )), showWallets && showSocial && /* @__PURE__ */ React2.createElement("div", { style: { display: "flex", gap: 4, marginBottom: 14, background: "var(--dc-surface)", borderRadius: 10, padding: 3 } }, ["social", "wallets"].map((v) => /* @__PURE__ */ React2.createElement(
6309
- "button",
6310
- {
6311
- key: v,
6312
- onClick: () => setView(v),
6313
- style: {
6314
- flex: 1,
6315
- padding: "7px 0",
6316
- borderRadius: 8,
6317
- border: "none",
6318
- background: view === v ? "var(--dc-bg)" : "transparent",
6319
- color: view === v ? "var(--dc-text)" : "var(--dc-text-muted)",
6320
- fontSize: 13,
6321
- fontWeight: view === v ? 700 : 500,
6322
- cursor: "pointer",
6323
- fontFamily: "inherit",
6324
- boxShadow: view === v ? "0 1px 4px rgba(0,0,0,0.2)" : "none",
6325
- transition: "all 0.15s"
6326
- }
6327
- },
6328
- v === "wallets" ? "Wallet" : "Sign in"
6329
- ))), view === "wallets" && networks === "all" && /* @__PURE__ */ React2.createElement("div", { style: { display: "flex", gap: 4, marginBottom: 10 } }, /* @__PURE__ */ React2.createElement(FilterTab, { label: "All", active: filter === "all", onClick: () => setFilter("all") }), /* @__PURE__ */ React2.createElement(FilterTab, { label: "EVM", active: filter === "evm", onClick: () => setFilter("evm") }), /* @__PURE__ */ React2.createElement(FilterTab, { label: "Solana", active: filter === "solana", onClick: () => setFilter("solana") }), provider.tronWallets && provider.tronWallets.length > 0 && /* @__PURE__ */ React2.createElement(FilterTab, { label: "Tron", active: filter === "tron", onClick: () => setFilter("tron") }), provider.bitcoinWallets && provider.bitcoinWallets.length > 0 && /* @__PURE__ */ React2.createElement(FilterTab, { label: "Bitcoin", active: filter === "bitcoin", onClick: () => setFilter("bitcoin") })), view === "wallets" && /* @__PURE__ */ React2.createElement("div", { style: { position: "relative", marginBottom: 10 } }, /* @__PURE__ */ React2.createElement(
6330
- "svg",
6331
- {
6332
- width: "14",
6333
- height: "14",
6334
- viewBox: "0 0 14 14",
6335
- fill: "none",
6336
- style: { position: "absolute", left: 10, top: "50%", transform: "translateY(-50%)", color: "var(--dc-text-muted)", pointerEvents: "none" }
6337
- },
6338
- /* @__PURE__ */ React2.createElement("circle", { cx: "6", cy: "6", r: "4", stroke: "currentColor", strokeWidth: "1.4" }),
6339
- /* @__PURE__ */ React2.createElement("path", { d: "M9.5 9.5L12 12", stroke: "currentColor", strokeWidth: "1.4", strokeLinecap: "round" })
6340
- ), /* @__PURE__ */ React2.createElement(
6341
- "input",
6342
- {
6343
- type: "text",
6344
- placeholder: "Search wallets\u2026",
6345
- value: search,
6346
- onChange: (e) => setSearch(e.target.value),
6347
- style: {
6348
- width: "100%",
6349
- background: "var(--dc-surface)",
6350
- border: "1px solid var(--dc-border)",
6351
- borderRadius: 10,
6352
- color: "var(--dc-text)",
6353
- fontSize: 13,
6354
- padding: "8px 12px 8px 32px",
6355
- outline: "none",
6356
- fontFamily: "var(--dc-font-sans, system-ui, sans-serif)",
6357
- transition: "border-color 0.15s",
6358
- boxSizing: "border-box"
6359
- },
6360
- onFocus: (e) => {
6361
- e.currentTarget.style.borderColor = "var(--dc-border-accent)";
6362
- },
6363
- onBlur: (e) => {
6364
- e.currentTarget.style.borderColor = "var(--dc-border)";
6365
- }
6366
- }
6367
- ))), view === "social" && /* @__PURE__ */ React2.createElement("div", { style: { padding: "4px 20px 24px", display: "flex", flexDirection: "column", gap: 10 } }, socialErr && /* @__PURE__ */ React2.createElement("div", { style: { background: "rgba(204,51,0,0.1)", border: "1px solid var(--dc-danger)", borderRadius: 8, padding: "9px 12px", fontSize: 12, color: "var(--dc-danger)" } }, socialErr), passkeyFirst && /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement(
6368
- "button",
6369
- {
6370
- onClick: handlePasskeyClick,
6371
- disabled: socialLoad,
6372
- style: {
6373
- display: "flex",
6374
- alignItems: "center",
6375
- justifyContent: "center",
6376
- gap: 10,
6377
- width: "100%",
6378
- padding: "13px 16px",
6379
- background: "var(--dc-accent)",
6380
- border: "none",
6381
- borderRadius: 10,
6382
- cursor: socialLoad ? "not-allowed" : "pointer",
6383
- color: "var(--dc-accent-text)",
6384
- fontSize: 14,
6385
- fontWeight: 700,
6386
- fontFamily: "inherit",
6387
- opacity: socialLoad ? 0.6 : 1
6388
- }
6389
- },
6390
- /* @__PURE__ */ React2.createElement("svg", { width: "17", height: "17", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" }, /* @__PURE__ */ React2.createElement("circle", { cx: "12", cy: "8", r: "4" }), /* @__PURE__ */ React2.createElement("path", { d: "M6 21v-1a4 4 0 0 1 4-4h1" }), /* @__PURE__ */ React2.createElement("path", { d: "M17 15v6M14.5 18h5" })),
6391
- socialLoad ? "Verifying\u2026" : "Continue with passkey"
6392
- ), passkeyAddress && /* @__PURE__ */ React2.createElement("div", { style: { textAlign: "center", fontSize: 12, color: "var(--dc-text-muted)" } }, "Resuming ", passkeyAddress.slice(0, 6), "\u2026", passkeyAddress.slice(-4)), /* @__PURE__ */ React2.createElement(
6393
- "button",
6394
- {
6395
- onClick: () => {
6396
- setShowOtherMethods(true);
6397
- setSocialErr("");
6398
- },
6399
- disabled: socialLoad,
6400
- style: {
6401
- background: "none",
6402
- border: "none",
6403
- padding: "6px 0",
6404
- color: "var(--dc-text-muted)",
6405
- fontSize: 12.5,
6406
- cursor: socialLoad ? "not-allowed" : "pointer",
6407
- fontFamily: "inherit",
6408
- textDecoration: "underline",
6409
- textUnderlineOffset: 3
6410
- }
6411
- },
6412
- "Use a different account"
6413
- )), !passkeyFirst && socialAuthMethods.includes("google") && /* @__PURE__ */ React2.createElement(
6414
- "button",
6415
- {
6416
- onClick: handleGoogleClick,
6417
- disabled: socialLoad,
6418
- style: {
6419
- display: "flex",
6420
- alignItems: "center",
6421
- justifyContent: "center",
6422
- gap: 10,
6423
- width: "100%",
6424
- padding: "11px 16px",
6425
- background: "var(--dc-surface)",
6426
- border: "1px solid var(--dc-border)",
6427
- borderRadius: 10,
6428
- cursor: socialLoad ? "not-allowed" : "pointer",
6429
- fontSize: 14,
6430
- fontWeight: 600,
6431
- color: "var(--dc-text)",
6432
- fontFamily: "inherit",
6433
- transition: "border-color 0.12s, background 0.12s",
6434
- opacity: socialLoad ? 0.6 : 1
6435
- },
6436
- onMouseEnter: (e) => {
6437
- if (!socialLoad) e.currentTarget.style.borderColor = "var(--dc-border-accent)";
6438
- },
6439
- onMouseLeave: (e) => {
6440
- e.currentTarget.style.borderColor = "var(--dc-border)";
6441
- }
6442
- },
6443
- /* @__PURE__ */ React2.createElement("svg", { width: "18", height: "18", viewBox: "0 0 18 18", fill: "none" }, /* @__PURE__ */ React2.createElement("path", { d: "M17.64 9.2c0-.637-.057-1.251-.164-1.84H9v3.481h4.844c-.209 1.125-.843 2.078-1.796 2.717v2.258h2.908c1.702-1.567 2.684-3.875 2.684-6.615z", fill: "#4285F4" }), /* @__PURE__ */ React2.createElement("path", { d: "M9 18c2.43 0 4.467-.806 5.956-2.18l-2.908-2.259c-.806.54-1.837.86-3.048.86-2.344 0-4.328-1.584-5.036-3.711H.957v2.332A8.997 8.997 0 0 0 9 18z", fill: "#34A853" }), /* @__PURE__ */ React2.createElement("path", { d: "M3.964 10.71A5.41 5.41 0 0 1 3.682 9c0-.593.102-1.17.282-1.71V4.958H.957A8.996 8.996 0 0 0 0 9c0 1.452.348 2.827.957 4.042l3.007-2.332z", fill: "#FBBC05" }), /* @__PURE__ */ React2.createElement("path", { d: "M9 3.58c1.321 0 2.508.454 3.44 1.345l2.582-2.58C13.463.891 11.426 0 9 0A8.997 8.997 0 0 0 .957 4.958L3.964 6.29C4.672 4.163 6.656 3.58 9 3.58z", fill: "#EA4335" })),
6444
- socialLoad ? "Redirecting\u2026" : "Continue with Google"
6445
- ), !passkeyFirst && socialAuthMethods.includes("kingschat") && onKingsChatSignIn && /* @__PURE__ */ React2.createElement(
6446
- "button",
6447
- {
6448
- onClick: handleKingsChatClick,
6449
- disabled: socialLoad,
6450
- style: {
6451
- display: "flex",
6452
- alignItems: "center",
6453
- justifyContent: "center",
6454
- gap: 10,
6455
- width: "100%",
6456
- padding: "11px 16px",
6457
- background: "var(--dc-surface)",
6458
- border: "1px solid var(--dc-border)",
6459
- borderRadius: 10,
6460
- cursor: socialLoad ? "not-allowed" : "pointer",
6461
- fontSize: 14,
6462
- fontWeight: 600,
6463
- color: "var(--dc-text)",
6464
- fontFamily: "inherit",
6465
- transition: "border-color 0.12s, background 0.12s",
6466
- opacity: socialLoad ? 0.6 : 1
6467
- },
6468
- onMouseEnter: (e) => {
6469
- if (!socialLoad) e.currentTarget.style.borderColor = "var(--dc-border-accent)";
6470
- },
6471
- onMouseLeave: (e) => {
6472
- e.currentTarget.style.borderColor = "var(--dc-border)";
6473
- }
6474
- },
6475
- /* @__PURE__ */ React2.createElement("svg", { width: "18", height: "18", viewBox: "0 0 18 18", fill: "none", "aria-hidden": "true" }, /* @__PURE__ */ React2.createElement("circle", { cx: "9", cy: "9", r: "9", fill: "var(--dc-accent)" }), /* @__PURE__ */ React2.createElement("path", { d: "M5.5 4.5h1.9v3.6l3.1-3.6h2.3l-3.3 3.8 3.5 5.2h-2.3l-2.5-3.8-.8.9v2.9H5.5V4.5z", fill: "var(--dc-accent-text)" })),
6476
- socialLoad ? "Waiting for KingsChat\u2026" : "Continue with KingsChat"
6477
- ), !passkeyFirst && socialAuthMethods.includes("x") && onXSignIn && /* @__PURE__ */ React2.createElement(
6478
- "button",
6479
- {
6480
- onClick: handleXClick,
6481
- disabled: socialLoad,
6482
- style: {
6483
- display: "flex",
6484
- alignItems: "center",
6485
- justifyContent: "center",
6486
- gap: 10,
6487
- width: "100%",
6488
- padding: "11px 16px",
6489
- background: "var(--dc-surface)",
6490
- border: "1px solid var(--dc-border)",
6491
- borderRadius: 10,
6492
- cursor: socialLoad ? "not-allowed" : "pointer",
6493
- fontSize: 14,
6494
- fontWeight: 600,
6495
- color: "var(--dc-text)",
6496
- fontFamily: "inherit",
6497
- transition: "border-color 0.12s, background 0.12s",
6498
- opacity: socialLoad ? 0.6 : 1
6499
- },
6500
- onMouseEnter: (e) => {
6501
- if (!socialLoad) e.currentTarget.style.borderColor = "var(--dc-border-accent)";
6502
- },
6503
- onMouseLeave: (e) => {
6504
- e.currentTarget.style.borderColor = "var(--dc-border)";
6505
- }
6506
- },
6507
- /* @__PURE__ */ React2.createElement(XLogo, { size: 16 }),
6508
- socialLoad ? "Redirecting\u2026" : "Continue with X"
6509
- ), !passkeyFirst && socialAuthMethods.includes("google") && socialAuthMethods.includes("email") && /* @__PURE__ */ React2.createElement("div", { style: { display: "flex", alignItems: "center", gap: 10 } }, /* @__PURE__ */ React2.createElement("div", { style: { flex: 1, height: 1, background: "var(--dc-border)" } }), /* @__PURE__ */ React2.createElement("span", { style: { fontSize: 11, color: "var(--dc-text-muted)", whiteSpace: "nowrap" } }, "or continue with email"), /* @__PURE__ */ React2.createElement("div", { style: { flex: 1, height: 1, background: "var(--dc-border)" } })), !passkeyFirst && socialAuthMethods.includes("email") && (emailStep === "input" ? /* @__PURE__ */ React2.createElement("form", { onSubmit: handleEmailStart, style: { display: "flex", flexDirection: "column", gap: 8 } }, /* @__PURE__ */ React2.createElement(
6510
- "input",
6511
- {
6512
- type: "email",
6513
- placeholder: "your@email.com",
6514
- value: emailVal,
6515
- onChange: (e) => setEmailVal(e.target.value),
6516
- required: true,
6517
- style: {
6518
- width: "100%",
6519
- padding: "10px 12px",
6520
- background: "var(--dc-surface)",
6521
- border: "1px solid var(--dc-border)",
6522
- borderRadius: 10,
6523
- color: "var(--dc-text)",
6524
- fontSize: 13,
6525
- fontFamily: "inherit",
6526
- outline: "none",
6527
- boxSizing: "border-box"
6528
- },
6529
- onFocus: (e) => {
6530
- e.currentTarget.style.borderColor = "var(--dc-border-accent)";
6531
- },
6532
- onBlur: (e) => {
6533
- e.currentTarget.style.borderColor = "var(--dc-border)";
6534
- }
6535
- }
6536
- ), /* @__PURE__ */ React2.createElement(
6537
- "button",
6538
- {
6539
- type: "submit",
6540
- disabled: socialLoad || !emailVal,
6541
- style: {
6542
- width: "100%",
6543
- padding: "10px 16px",
6544
- background: "var(--dc-accent)",
6545
- color: "var(--dc-accent-text)",
6546
- border: "none",
6547
- borderRadius: 10,
6548
- fontSize: 14,
6549
- fontWeight: 700,
6550
- cursor: socialLoad ? "not-allowed" : "pointer",
6551
- fontFamily: "inherit",
6552
- opacity: socialLoad || !emailVal ? 0.6 : 1
6553
- }
6554
- },
6555
- socialLoad ? "Sending\u2026" : "Send code"
6556
- )) : /* @__PURE__ */ React2.createElement("form", { onSubmit: handleEmailVerify, style: { display: "flex", flexDirection: "column", gap: 8 } }, /* @__PURE__ */ React2.createElement("p", { style: { margin: 0, fontSize: 12, color: "var(--dc-text-muted)", textAlign: "center" } }, "Code sent to ", /* @__PURE__ */ React2.createElement("strong", { style: { color: "var(--dc-text)" } }, emailVal)), /* @__PURE__ */ React2.createElement(
6557
- "input",
6558
- {
6559
- type: "text",
6560
- placeholder: "6-digit code",
6561
- value: codeVal,
6562
- onChange: (e) => setCodeVal(e.target.value.replace(/\D/g, "").slice(0, 6)),
6563
- autoFocus: true,
6564
- required: true,
6565
- style: {
6566
- width: "100%",
6567
- padding: "10px 12px",
6568
- background: "var(--dc-surface)",
6569
- border: "1px solid var(--dc-border)",
6570
- borderRadius: 10,
6571
- color: "var(--dc-text)",
6572
- fontSize: 20,
6573
- fontFamily: "monospace",
6574
- letterSpacing: 8,
6575
- textAlign: "center",
6576
- outline: "none",
6577
- boxSizing: "border-box"
6578
- },
6579
- onFocus: (e) => {
6580
- e.currentTarget.style.borderColor = "var(--dc-border-accent)";
6581
- },
6582
- onBlur: (e) => {
6583
- e.currentTarget.style.borderColor = "var(--dc-border)";
6584
- }
6585
- }
6586
- ), /* @__PURE__ */ React2.createElement("div", { style: { display: "flex", gap: 8 } }, /* @__PURE__ */ React2.createElement(
6587
- "button",
6588
- {
6589
- type: "button",
6590
- onClick: () => {
6591
- setEmailStep("input");
6592
- setCodeVal("");
6593
- setSocialErr("");
6594
- },
6595
- style: {
6596
- flex: 1,
6597
- padding: "9px 0",
6598
- background: "transparent",
6599
- border: "1px solid var(--dc-border)",
6600
- borderRadius: 10,
6601
- color: "var(--dc-text-muted)",
6602
- fontSize: 13,
6603
- cursor: "pointer",
6604
- fontFamily: "inherit"
6605
- }
6606
- },
6607
- "Back"
6608
- ), /* @__PURE__ */ React2.createElement(
6609
- "button",
6610
- {
6611
- type: "submit",
6612
- disabled: socialLoad || codeVal.length < 6,
6613
- style: {
6614
- flex: 2,
6615
- padding: "9px 0",
6616
- background: "var(--dc-accent)",
6617
- color: "var(--dc-accent-text)",
6618
- border: "none",
6619
- borderRadius: 10,
6620
- fontSize: 13,
6621
- fontWeight: 700,
6622
- cursor: socialLoad || codeVal.length < 6 ? "not-allowed" : "pointer",
6623
- fontFamily: "inherit",
6624
- opacity: socialLoad || codeVal.length < 6 ? 0.6 : 1
6625
- }
6626
- },
6627
- socialLoad ? "Verifying\u2026" : "Verify"
6628
- )))), !passkeyFirst && socialAuthMethods.includes("phone") && onPhoneStart && onPhoneVerify && (phoneStep === "input" ? /* @__PURE__ */ React2.createElement("form", { onSubmit: handlePhoneStart, style: { display: "flex", flexDirection: "column", gap: 8 } }, /* @__PURE__ */ React2.createElement(
6629
- "input",
6630
- {
6631
- type: "tel",
6632
- placeholder: "+234 801 234 5678",
6633
- value: phoneVal,
6634
- onChange: (e) => setPhoneVal(e.target.value),
6635
- required: true,
6636
- style: {
6637
- width: "100%",
6638
- padding: "10px 12px",
6639
- background: "var(--dc-surface)",
6640
- border: "1px solid var(--dc-border)",
6641
- borderRadius: 10,
6642
- color: "var(--dc-text)",
6643
- fontSize: 13,
6644
- fontFamily: "inherit",
6645
- outline: "none",
6646
- boxSizing: "border-box"
6647
- },
6648
- onFocus: (e) => {
6649
- e.currentTarget.style.borderColor = "var(--dc-border-accent)";
6650
- },
6651
- onBlur: (e) => {
6652
- e.currentTarget.style.borderColor = "var(--dc-border)";
6653
- }
6654
- }
6655
- ), /* @__PURE__ */ React2.createElement(
6656
- "button",
6657
- {
6658
- type: "submit",
6659
- disabled: socialLoad || !phoneVal,
6660
- style: {
6661
- width: "100%",
6662
- padding: "10px 16px",
6663
- background: "var(--dc-accent)",
6664
- color: "var(--dc-accent-text)",
6665
- border: "none",
6666
- borderRadius: 10,
6667
- fontSize: 14,
6668
- fontWeight: 700,
6669
- cursor: socialLoad ? "not-allowed" : "pointer",
6670
- fontFamily: "inherit",
6671
- opacity: socialLoad || !phoneVal ? 0.6 : 1
6672
- }
6673
- },
6674
- socialLoad ? "Sending\u2026" : "Send code"
6675
- )) : /* @__PURE__ */ React2.createElement("form", { onSubmit: handlePhoneVerify, style: { display: "flex", flexDirection: "column", gap: 8 } }, /* @__PURE__ */ React2.createElement("p", { style: { margin: 0, fontSize: 12, color: "var(--dc-text-muted)", textAlign: "center" } }, "Code sent to ", /* @__PURE__ */ React2.createElement("strong", { style: { color: "var(--dc-text)" } }, phoneVal)), /* @__PURE__ */ React2.createElement(
6676
- "input",
6677
- {
6678
- type: "text",
6679
- inputMode: "numeric",
6680
- placeholder: "6-digit code",
6681
- value: phoneCode,
6682
- onChange: (e) => setPhoneCode(e.target.value.replace(/\D/g, "").slice(0, 6)),
6683
- autoFocus: true,
6684
- required: true,
6685
- style: {
6686
- width: "100%",
6687
- padding: "10px 12px",
6688
- background: "var(--dc-surface)",
6689
- border: "1px solid var(--dc-border)",
6690
- borderRadius: 10,
6691
- color: "var(--dc-text)",
6692
- fontSize: 20,
6693
- fontFamily: "monospace",
6694
- letterSpacing: 8,
6695
- textAlign: "center",
6696
- outline: "none",
6697
- boxSizing: "border-box"
6698
- },
6699
- onFocus: (e) => {
6700
- e.currentTarget.style.borderColor = "var(--dc-border-accent)";
6701
- },
6702
- onBlur: (e) => {
6703
- e.currentTarget.style.borderColor = "var(--dc-border)";
6704
- }
6705
- }
6706
- ), /* @__PURE__ */ React2.createElement("div", { style: { display: "flex", gap: 8 } }, /* @__PURE__ */ React2.createElement(
6707
- "button",
6708
- {
6709
- type: "button",
6710
- onClick: () => {
6711
- setPhoneStep("input");
6712
- setPhoneCode("");
6713
- setSocialErr("");
6714
- },
6715
- style: {
6716
- flex: 1,
6717
- padding: "9px 0",
6718
- background: "transparent",
6719
- border: "1px solid var(--dc-border)",
6720
- borderRadius: 10,
6721
- color: "var(--dc-text-muted)",
6722
- fontSize: 13,
6723
- cursor: "pointer",
6724
- fontFamily: "inherit"
6725
- }
6726
- },
6727
- "Back"
6728
- ), /* @__PURE__ */ React2.createElement(
6729
- "button",
6730
- {
6731
- type: "submit",
6732
- disabled: socialLoad || phoneCode.length < 6,
6733
- style: {
6734
- flex: 2,
6735
- padding: "9px 0",
6736
- background: "var(--dc-accent)",
6737
- color: "var(--dc-accent-text)",
6738
- border: "none",
6739
- borderRadius: 10,
6740
- fontSize: 13,
6741
- fontWeight: 700,
6742
- cursor: socialLoad || phoneCode.length < 6 ? "not-allowed" : "pointer",
6743
- fontFamily: "inherit",
6744
- opacity: socialLoad || phoneCode.length < 6 ? 0.6 : 1
6745
- }
6746
- },
6747
- socialLoad ? "Verifying\u2026" : "Verify"
6748
- )))), !passkeyFirst && customAuthLabel && onCustomAuthSignIn && /* @__PURE__ */ React2.createElement(React2.Fragment, null, (socialAuthMethods.includes("google") || socialAuthMethods.includes("email")) && /* @__PURE__ */ React2.createElement("div", { style: { display: "flex", alignItems: "center", gap: 10 } }, /* @__PURE__ */ React2.createElement("div", { style: { flex: 1, height: 1, background: "var(--dc-border)" } }), /* @__PURE__ */ React2.createElement("span", { style: { fontSize: 11, color: "var(--dc-text-muted)", whiteSpace: "nowrap" } }, "or"), /* @__PURE__ */ React2.createElement("div", { style: { flex: 1, height: 1, background: "var(--dc-border)" } })), /* @__PURE__ */ React2.createElement(
6749
- "button",
6750
- {
6751
- onClick: handleCustomAuthClick,
6752
- disabled: socialLoad,
6753
- style: {
6754
- display: "flex",
6755
- alignItems: "center",
6756
- justifyContent: "center",
6757
- gap: 10,
6758
- width: "100%",
6759
- padding: "11px 16px",
6760
- background: "var(--dc-surface)",
6761
- border: "1px solid var(--dc-border)",
6762
- borderRadius: 10,
6763
- cursor: socialLoad ? "not-allowed" : "pointer",
6764
- fontSize: 14,
6765
- fontWeight: 600,
6766
- color: "var(--dc-text)",
6767
- fontFamily: "inherit",
6768
- transition: "border-color 0.12s, background 0.12s",
6769
- opacity: socialLoad ? 0.6 : 1
6770
- },
6771
- onMouseEnter: (e) => {
6772
- if (!socialLoad) e.currentTarget.style.borderColor = "var(--dc-border-accent)";
6773
- },
6774
- onMouseLeave: (e) => {
6775
- e.currentTarget.style.borderColor = "var(--dc-border)";
6776
- }
6777
- },
6778
- socialLoad ? "Connecting\u2026" : customAuthLabel
6779
- ))), view === "wallets" && /* @__PURE__ */ React2.createElement("div", { style: { overflowY: "auto", flex: 1, padding: "0 12px 20px" } }, filtered.length > 0 ? /* @__PURE__ */ React2.createElement("div", { style: { display: "flex", flexDirection: "column", gap: 2 } }, filtered.map((w) => /* @__PURE__ */ React2.createElement(WalletRow, { key: w.id, wallet: w, onClick: () => handleWalletClick(w) }))) : /* @__PURE__ */ React2.createElement("div", { style: { textAlign: "center", padding: "32px 16px", color: "var(--dc-text-muted)", fontSize: 13 } }, q ? `No wallets matching "${q}"` : "No wallets detected")), view === "wallets" && /* @__PURE__ */ React2.createElement("div", { style: { padding: "10px 20px 14px", borderTop: "1px solid var(--dc-border)", textAlign: "center", fontSize: 11, color: "var(--dc-text-muted)" } }, "Don't see your wallet? Make sure it's installed and unlocked"))
6780
- )
6781
- )
6782
- );
6783
- return createPortal(modal, document.body);
6784
- }
6785
-
6786
- // src/ui/SocialWalletModal.tsx
6787
- import React3, { useCallback as useCallback2, useEffect as useEffect2, useState as useState2 } from "react";
6788
- import { createPortal as createPortal2 } from "react-dom";
6789
- function injectTokens2(theme) {
6790
- const resolved = theme === "auto" ? window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light" : theme;
6791
- let el = document.getElementById("decane-tokens");
6792
- if (!el) {
6793
- el = document.createElement("style");
6794
- el.id = "decane-tokens";
6795
- document.head.appendChild(el);
6796
- }
6797
- el.textContent = `:root { ${CSS_VARS[resolved]} }`;
6798
- }
6799
- function countdown(expiresAt) {
6800
- const secs = Math.max(0, Math.round((expiresAt - Date.now()) / 1e3));
6801
- return `${Math.floor(secs / 60)}m ${String(secs % 60).padStart(2, "0")}s`;
6802
- }
6803
- function downloadJson(data, filename) {
6804
- const blob = new Blob([JSON.stringify(data, null, 2)], { type: "application/json" });
6805
- const url = URL.createObjectURL(blob);
6806
- const a = document.createElement("a");
6807
- a.href = url;
6808
- a.download = filename;
6809
- a.click();
6810
- URL.revokeObjectURL(url);
6811
- }
6812
- function CopyButton({ value }) {
6813
- const [copied, setCopied] = useState2(false);
6814
- async function copy() {
6815
- await navigator.clipboard.writeText(value).catch(() => {
6816
- });
6817
- setCopied(true);
6818
- setTimeout(() => setCopied(false), 1500);
6819
- }
6820
- return /* @__PURE__ */ React3.createElement(
6821
- "button",
6822
- {
6823
- onClick: copy,
6824
- style: {
6825
- background: "none",
6826
- border: "none",
6827
- cursor: "pointer",
6828
- color: copied ? "var(--dc-accent)" : "var(--dc-text-muted)",
6829
- fontSize: 11,
6830
- fontFamily: "inherit",
6831
- padding: "2px 6px",
6832
- borderRadius: 5,
6833
- transition: "color 0.15s"
6834
- }
6835
- },
6836
- copied ? "\u2713" : "copy"
6837
- );
6838
- }
6839
- function useBalance(kind, address, chain, rpcUrls) {
6840
- const [state, setState] = useState2({ loading: false, value: null, symbol: kind === "evm" ? "ETH" : "SOL" });
6841
- useEffect2(() => {
6842
- if (!address || !chain) return;
6843
- let cancelled = false;
6844
- setState((s) => ({ ...s, loading: true }));
6845
- fetchBalance({ kind, address, chain, rpcUrls }).then((b) => {
6846
- if (!cancelled) setState({ loading: false, value: b.formatted, symbol: b.symbol });
6847
- }).catch(() => {
6848
- if (!cancelled) setState({ loading: false, value: null, symbol: kind === "evm" ? "ETH" : "SOL" });
6849
- });
6850
- return () => {
6851
- cancelled = true;
6852
- };
6853
- }, [kind, address, chain, rpcUrls]);
6854
- return state;
6855
- }
6856
- function AddressRow({
6857
- label,
6858
- address,
6859
- kind,
6860
- chain,
6861
- rpcUrls
6862
- }) {
6863
- const balance = useBalance(kind, address, chain, rpcUrls);
6864
- const short = `${address.slice(0, 8)}\u2026${address.slice(-6)}`;
6865
- return /* @__PURE__ */ React3.createElement("div", { style: {
6866
- background: "var(--dc-surface)",
6867
- border: "1px solid var(--dc-border)",
6868
- borderRadius: 10,
6869
- padding: "10px 14px",
6870
- marginBottom: 8
6871
- } }, /* @__PURE__ */ React3.createElement("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 5 } }, /* @__PURE__ */ React3.createElement("span", { style: { fontSize: 10, fontWeight: 700, color: "var(--dc-text-muted)", letterSpacing: "0.06em", textTransform: "uppercase" } }, label), /* @__PURE__ */ React3.createElement("span", { style: { fontSize: 11, fontFamily: "monospace", color: "var(--dc-text)" } }, balance.loading ? "\u2026" : `${formatBalanceDisplay(balance.value)} ${balance.symbol}`)), /* @__PURE__ */ React3.createElement("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", gap: 8 } }, /* @__PURE__ */ React3.createElement("span", { style: { fontSize: 13, fontFamily: "monospace", color: "var(--dc-text)", letterSpacing: "0.02em" } }, short), /* @__PURE__ */ React3.createElement(CopyButton, { value: address })));
6872
- }
6873
- function SignInView({
6874
- onGoogleSignIn,
6875
- onKingsChatSignIn,
6876
- onXSignIn,
6877
- onEmailStart,
6878
- onEmailVerify,
6879
- onPhoneStart,
6880
- onPhoneVerify,
6881
- authMethods,
6882
- resumeHint,
6883
- customAuthLabel,
6884
- onCustomAuthSignIn,
6885
- canUsePasskey,
6886
- passkeyAddress,
6887
- onPasskeySignIn
6888
- }) {
6889
- const [googleLoading, setGoogleLoading] = useState2(false);
6890
- const [kingsChatLoading, setKingsChatLoading] = useState2(false);
6891
- const [xLoading, setXLoading] = useState2(false);
6892
- const [email, setEmail] = useState2("");
6893
- const [code, setCode] = useState2("");
6894
- const [emailSent, setEmailSent] = useState2(false);
6895
- const [emailLoading, setEmailLoading] = useState2(false);
6896
- const [phone, setPhone] = useState2("");
6897
- const [phoneCode, setPhoneCode] = useState2("");
6898
- const [phoneSent, setPhoneSent] = useState2(false);
6899
- const [phoneLoading, setPhoneLoading] = useState2(false);
6900
- const [customLoading, setCustomLoading] = useState2(false);
6901
- const [passkeyLoading, setPasskeyLoading] = useState2(false);
6902
- const [showOtherMethods, setShowOtherMethods] = useState2(false);
6903
- const [error, setError] = useState2("");
6904
- const passkeyFirst = !!canUsePasskey && !!onPasskeySignIn && !showOtherMethods;
6905
- async function handlePasskey() {
6906
- if (!onPasskeySignIn) return;
6907
- setError("");
6908
- setPasskeyLoading(true);
6909
- try {
6910
- await onPasskeySignIn();
6911
- } catch (e) {
6912
- const err = e;
6913
- if (err?.name !== "UserCancelledError") {
6914
- setError(err?.message ?? "Passkey sign-in failed");
6915
- setShowOtherMethods(true);
6916
- }
6917
- setPasskeyLoading(false);
6918
- }
6919
- }
6920
- async function handleGoogle() {
6921
- setError("");
6922
- setGoogleLoading(true);
6923
- try {
6924
- await onGoogleSignIn();
6925
- } catch (e) {
6926
- setError(e.message);
6927
- setGoogleLoading(false);
6928
- }
6929
- }
6930
- async function handleKingsChat() {
6931
- if (!onKingsChatSignIn) return;
6932
- setError("");
6933
- setKingsChatLoading(true);
6934
- try {
6935
- await onKingsChatSignIn();
6936
- } catch (e) {
6937
- setError(e.message);
6938
- } finally {
6939
- setKingsChatLoading(false);
6940
- }
6941
- }
6942
- async function handleX() {
6943
- if (!onXSignIn) return;
6944
- setError("");
6945
- setXLoading(true);
6946
- try {
6947
- await onXSignIn();
6948
- } catch (e) {
6949
- setError(e.message);
6950
- setXLoading(false);
6951
- }
6952
- }
6953
- async function handleEmailStart(e) {
6954
- e.preventDefault();
6955
- setError("");
6956
- setEmailLoading(true);
6957
- try {
6958
- await onEmailStart(email);
6959
- setEmailSent(true);
6960
- } catch (e2) {
6961
- setError(e2.message);
6962
- } finally {
6963
- setEmailLoading(false);
6964
- }
6965
- }
6966
- async function handleEmailVerify(e) {
6967
- e.preventDefault();
6968
- setError("");
6969
- setEmailLoading(true);
6970
- try {
6971
- await onEmailVerify(email, code);
6972
- } catch (e2) {
6973
- setError(e2.message);
6974
- } finally {
6975
- setEmailLoading(false);
6976
- }
6977
- }
6978
- async function handlePhoneStart(e) {
6979
- e.preventDefault();
6980
- if (!onPhoneStart) return;
6981
- setError("");
6982
- setPhoneLoading(true);
6983
- try {
6984
- await onPhoneStart(phone);
6985
- setPhoneSent(true);
6986
- } catch (e2) {
6987
- setError(e2.message);
6988
- } finally {
6989
- setPhoneLoading(false);
6990
- }
6991
- }
6992
- async function handlePhoneVerify(e) {
6993
- e.preventDefault();
6994
- if (!onPhoneVerify) return;
6995
- setError("");
6996
- setPhoneLoading(true);
6997
- try {
6998
- await onPhoneVerify(phone, phoneCode);
6999
- } catch (e2) {
7000
- setError(e2.message);
7001
- } finally {
7002
- setPhoneLoading(false);
7003
- }
7004
- }
7005
- async function handleCustomAuth() {
7006
- if (!onCustomAuthSignIn) return;
7007
- setError("");
7008
- setCustomLoading(true);
7009
- try {
7010
- await onCustomAuthSignIn();
7011
- } catch (e) {
7012
- setError(e.message);
7013
- } finally {
7014
- setCustomLoading(false);
7015
- }
7016
- }
7017
- const inputStyle = {
7018
- width: "100%",
7019
- background: "var(--dc-surface)",
7020
- border: "1px solid var(--dc-border)",
7021
- borderRadius: 8,
7022
- color: "var(--dc-text)",
7023
- padding: "9px 12px",
7024
- fontSize: 13,
7025
- outline: "none",
7026
- fontFamily: "inherit",
7027
- boxSizing: "border-box"
7028
- };
7029
- return /* @__PURE__ */ React3.createElement("div", { style: { padding: "0 16px 16px" } }, resumeHint && !passkeyFirst && /* @__PURE__ */ React3.createElement("div", { style: { fontSize: 12, color: "var(--dc-text-muted)", marginBottom: 12, textAlign: "center" } }, "Welcome back \u2014 sign in again to resume ", resumeHint), passkeyFirst && /* @__PURE__ */ React3.createElement("div", null, /* @__PURE__ */ React3.createElement("div", { style: { fontSize: 12, color: "var(--dc-text-muted)", marginBottom: 12, textAlign: "center" } }, "Welcome back \u2014 unlock to resume", passkeyAddress ? ` ${passkeyAddress.slice(0, 6)}\u2026${passkeyAddress.slice(-4)}` : ""), /* @__PURE__ */ React3.createElement(
7030
- "button",
7031
- {
7032
- onClick: handlePasskey,
7033
- disabled: passkeyLoading,
7034
- style: {
7035
- width: "100%",
7036
- padding: "11px 0",
7037
- background: "var(--dc-accent)",
7038
- color: "var(--dc-accent-text)",
7039
- border: "none",
7040
- borderRadius: 10,
7041
- fontSize: 13,
7042
- fontWeight: 700,
7043
- cursor: passkeyLoading ? "not-allowed" : "pointer",
7044
- opacity: passkeyLoading ? 0.7 : 1,
7045
- fontFamily: "inherit",
7046
- display: "flex",
7047
- alignItems: "center",
7048
- justifyContent: "center",
7049
- gap: 7
7050
- }
7051
- },
7052
- passkeyLoading ? "Verifying\u2026" : "\u{1F513} Continue with passkey"
7053
- ), /* @__PURE__ */ React3.createElement(
7054
- "button",
7055
- {
7056
- onClick: () => setShowOtherMethods(true),
7057
- style: {
7058
- width: "100%",
7059
- marginTop: 10,
7060
- background: "none",
7061
- border: "none",
7062
- color: "var(--dc-text-muted)",
7063
- fontSize: 12,
7064
- cursor: "pointer",
7065
- fontFamily: "inherit"
7066
- }
7067
- },
7068
- "Use email or Google instead"
7069
- ), error && /* @__PURE__ */ React3.createElement("div", { style: { marginTop: 10, fontSize: 12, color: "var(--dc-danger, #ff5533)" } }, error)), !passkeyFirst && authMethods.includes("google") && /* @__PURE__ */ React3.createElement(
7070
- "button",
7071
- {
7072
- onClick: handleGoogle,
7073
- disabled: googleLoading,
7074
- style: {
7075
- width: "100%",
7076
- padding: "10px 0",
7077
- marginBottom: 10,
7078
- background: "var(--dc-accent)",
7079
- color: "var(--dc-accent-text)",
7080
- border: "none",
7081
- borderRadius: 10,
7082
- fontSize: 13,
7083
- fontWeight: 700,
7084
- cursor: googleLoading ? "not-allowed" : "pointer",
7085
- opacity: googleLoading ? 0.7 : 1,
7086
- fontFamily: "inherit"
7087
- }
7088
- },
7089
- googleLoading ? "Redirecting\u2026" : "Continue with Google"
7090
- ), !passkeyFirst && authMethods.includes("kingschat") && onKingsChatSignIn && /* @__PURE__ */ React3.createElement(
7091
- "button",
7092
- {
7093
- onClick: handleKingsChat,
7094
- disabled: kingsChatLoading,
7095
- style: {
7096
- width: "100%",
7097
- padding: "10px 0",
7098
- marginBottom: 10,
7099
- background: "var(--dc-surface)",
7100
- color: "var(--dc-text)",
7101
- border: "1px solid var(--dc-border)",
7102
- borderRadius: 10,
7103
- fontSize: 13,
7104
- fontWeight: 700,
7105
- cursor: kingsChatLoading ? "not-allowed" : "pointer",
7106
- opacity: kingsChatLoading ? 0.7 : 1,
7107
- fontFamily: "inherit"
7108
- }
7109
- },
7110
- kingsChatLoading ? "Waiting for KingsChat\u2026" : "Continue with KingsChat"
7111
- ), !passkeyFirst && authMethods.includes("x") && onXSignIn && /* @__PURE__ */ React3.createElement(
7112
- "button",
7113
- {
7114
- onClick: handleX,
7115
- disabled: xLoading,
7116
- style: {
7117
- width: "100%",
7118
- padding: "10px 0",
7119
- marginBottom: 10,
7120
- background: "var(--dc-surface)",
7121
- color: "var(--dc-text)",
7122
- border: "1px solid var(--dc-border)",
7123
- borderRadius: 10,
7124
- fontSize: 13,
7125
- fontWeight: 700,
7126
- cursor: xLoading ? "not-allowed" : "pointer",
7127
- opacity: xLoading ? 0.7 : 1,
7128
- fontFamily: "inherit",
7129
- display: "flex",
7130
- alignItems: "center",
7131
- justifyContent: "center",
7132
- gap: 8
7133
- }
7134
- },
7135
- /* @__PURE__ */ React3.createElement(XLogo, null),
7136
- xLoading ? "Redirecting\u2026" : "Continue with X"
7137
- ), !passkeyFirst && authMethods.includes("email") && /* @__PURE__ */ React3.createElement(React3.Fragment, null, authMethods.includes("google") && /* @__PURE__ */ React3.createElement("div", { style: { textAlign: "center", color: "var(--dc-text-muted)", fontSize: 12, margin: "10px 0" } }, "\u2014 or \u2014"), !emailSent ? /* @__PURE__ */ React3.createElement("form", { onSubmit: handleEmailStart, style: { display: "flex", gap: 8 } }, /* @__PURE__ */ React3.createElement(
6176
+ className: "dcm-field dcm-code",
6177
+ "aria-label": "6-digit code",
6178
+ placeholder: "000000",
6179
+ value,
6180
+ maxLength: 6,
6181
+ autoFocus: true,
6182
+ inputMode: "numeric",
6183
+ autoComplete: "one-time-code",
6184
+ onChange: (e) => setValue(e.target.value.replace(/\D/g, ""))
6185
+ }
6186
+ ), /* @__PURE__ */ React2.createElement("button", { type: "submit", className: "dcm-primary", disabled: loading || value.length < 6 }, loading ? "Verifying\u2026" : "Continue")), errorLine, /* @__PURE__ */ React2.createElement("button", { type: "button", className: "dcm-link", onClick: backToMethods }, "Use a different method"), /* @__PURE__ */ React2.createElement(ProtectedBy, null));
6187
+ }
6188
+ const showPhone = authMethods.includes("phone") && !!onPhoneStart && !!onPhoneVerify;
6189
+ return /* @__PURE__ */ React2.createElement("div", { className: "dcm-body" }, /* @__PURE__ */ React2.createElement(DecaneMark, { size: 44 }), /* @__PURE__ */ React2.createElement("h2", { className: "dcm-title" }, resumeHint ? "Welcome back" : "Log in or sign up"), resumeHint && /* @__PURE__ */ React2.createElement("p", { className: "dcm-sub" }, "Sign in again to resume ", resumeHint, "."), /* @__PURE__ */ React2.createElement("div", { className: "dcm-methods" }, authMethods.includes("google") && /* @__PURE__ */ React2.createElement("button", { type: "button", className: "dcm-method", onClick: handleGoogle, disabled: busy }, /* @__PURE__ */ React2.createElement(GoogleMark, { size: 18 }), /* @__PURE__ */ React2.createElement("span", null, googleLoading ? "Redirecting to Google\u2026" : "Google")), authMethods.includes("email") && /* @__PURE__ */ React2.createElement("form", { className: "dcm-method dcm-method-input", onSubmit: handleEmailStart }, /* @__PURE__ */ React2.createElement(MailIcon, { size: 18 }), /* @__PURE__ */ React2.createElement(
7138
6190
  "input",
7139
6191
  {
7140
6192
  type: "email",
7141
6193
  required: true,
7142
6194
  placeholder: "your@email.com",
6195
+ "aria-label": "Email address",
6196
+ autoComplete: "email",
7143
6197
  value: email,
7144
- onChange: (e) => setEmail(e.target.value),
7145
- style: { ...inputStyle, flex: 1 }
7146
- }
7147
- ), /* @__PURE__ */ React3.createElement("button", { type: "submit", disabled: emailLoading, style: {
7148
- padding: "0 16px",
7149
- background: "var(--dc-surface)",
7150
- border: "1px solid var(--dc-border)",
7151
- borderRadius: 8,
7152
- color: "var(--dc-text)",
7153
- fontSize: 13,
7154
- cursor: "pointer",
7155
- fontFamily: "inherit"
7156
- } }, emailLoading ? "\u2026" : "Send code")) : /* @__PURE__ */ React3.createElement("form", { onSubmit: handleEmailVerify, style: { display: "flex", gap: 8 } }, /* @__PURE__ */ React3.createElement(
7157
- "input",
7158
- {
7159
- placeholder: "6-digit code",
7160
- value: code,
7161
- maxLength: 6,
7162
- autoFocus: true,
7163
- onChange: (e) => setCode(e.target.value.replace(/\D/g, "")),
7164
- style: { ...inputStyle, flex: 1, letterSpacing: 4, textAlign: "center" }
7165
- }
7166
- ), /* @__PURE__ */ React3.createElement("button", { type: "submit", disabled: emailLoading, style: {
7167
- padding: "0 16px",
7168
- background: "var(--dc-accent)",
7169
- color: "var(--dc-accent-text)",
7170
- border: "none",
7171
- borderRadius: 8,
7172
- fontSize: 13,
7173
- fontWeight: 700,
7174
- cursor: "pointer",
7175
- fontFamily: "inherit"
7176
- } }, emailLoading ? "\u2026" : "Verify"))), !passkeyFirst && authMethods.includes("phone") && onPhoneStart && onPhoneVerify && /* @__PURE__ */ React3.createElement(React3.Fragment, null, (authMethods.includes("google") || authMethods.includes("email")) && /* @__PURE__ */ React3.createElement("div", { style: { textAlign: "center", color: "var(--dc-text-muted)", fontSize: 12, margin: "10px 0" } }, "\u2014 or \u2014"), !phoneSent ? /* @__PURE__ */ React3.createElement("form", { onSubmit: handlePhoneStart, style: { display: "flex", gap: 8 } }, /* @__PURE__ */ React3.createElement(
6198
+ onChange: (e) => setEmail(e.target.value)
6199
+ }
6200
+ ), /* @__PURE__ */ React2.createElement("button", { type: "submit", className: "dcm-submit", disabled: busy || !email.trim() }, emailLoading ? "Sending\u2026" : "Submit")), showPhone && /* @__PURE__ */ React2.createElement("form", { className: "dcm-method dcm-method-input", onSubmit: handlePhoneStart }, /* @__PURE__ */ React2.createElement(PhoneIcon, { size: 18 }), /* @__PURE__ */ React2.createElement(
7177
6201
  "input",
7178
6202
  {
7179
6203
  type: "tel",
7180
6204
  required: true,
7181
6205
  placeholder: "+234 801 234 5678",
6206
+ "aria-label": "Phone number",
6207
+ autoComplete: "tel",
7182
6208
  value: phone,
7183
- onChange: (e) => setPhone(e.target.value),
7184
- style: { ...inputStyle, flex: 1 }
7185
- }
7186
- ), /* @__PURE__ */ React3.createElement("button", { type: "submit", disabled: phoneLoading, style: {
7187
- padding: "0 16px",
7188
- background: "var(--dc-surface)",
7189
- border: "1px solid var(--dc-border)",
7190
- borderRadius: 8,
7191
- color: "var(--dc-text)",
7192
- fontSize: 13,
7193
- cursor: "pointer",
7194
- fontFamily: "inherit"
7195
- } }, phoneLoading ? "\u2026" : "Send code")) : /* @__PURE__ */ React3.createElement("form", { onSubmit: handlePhoneVerify, style: { display: "flex", gap: 8 } }, /* @__PURE__ */ React3.createElement(
7196
- "input",
7197
- {
7198
- placeholder: "6-digit code",
7199
- value: phoneCode,
7200
- maxLength: 6,
7201
- autoFocus: true,
7202
- inputMode: "numeric",
7203
- onChange: (e) => setPhoneCode(e.target.value.replace(/\D/g, "")),
7204
- style: { ...inputStyle, flex: 1, letterSpacing: 4, textAlign: "center" }
7205
- }
7206
- ), /* @__PURE__ */ React3.createElement("button", { type: "submit", disabled: phoneLoading, style: {
7207
- padding: "0 16px",
7208
- background: "var(--dc-accent)",
7209
- color: "var(--dc-accent-text)",
7210
- border: "none",
7211
- borderRadius: 8,
7212
- fontSize: 13,
7213
- fontWeight: 700,
7214
- cursor: "pointer",
7215
- fontFamily: "inherit"
7216
- } }, phoneLoading ? "\u2026" : "Verify"))), !passkeyFirst && customAuthLabel && onCustomAuthSignIn && /* @__PURE__ */ React3.createElement(React3.Fragment, null, (authMethods.includes("google") || authMethods.includes("email")) && /* @__PURE__ */ React3.createElement("div", { style: { textAlign: "center", color: "var(--dc-text-muted)", fontSize: 12, margin: "10px 0" } }, "\u2014 or \u2014"), /* @__PURE__ */ React3.createElement(
7217
- "button",
7218
- {
7219
- onClick: handleCustomAuth,
7220
- disabled: customLoading,
7221
- style: {
7222
- width: "100%",
7223
- padding: "10px 0",
7224
- background: "var(--dc-surface)",
7225
- color: "var(--dc-text)",
7226
- border: "1px solid var(--dc-border)",
7227
- borderRadius: 10,
7228
- fontSize: 13,
7229
- fontWeight: 600,
7230
- cursor: customLoading ? "not-allowed" : "pointer",
7231
- opacity: customLoading ? 0.7 : 1,
7232
- fontFamily: "inherit"
7233
- }
7234
- },
7235
- customLoading ? "Connecting\u2026" : customAuthLabel
7236
- )), error && /* @__PURE__ */ React3.createElement("div", { style: { marginTop: 10, fontSize: 12, color: "var(--dc-danger, #ff5533)" } }, error));
6209
+ onChange: (e) => setPhone(e.target.value)
6210
+ }
6211
+ ), /* @__PURE__ */ React2.createElement("button", { type: "submit", className: "dcm-submit", disabled: busy || !phone.trim() }, phoneLoading ? "Sending\u2026" : "Submit")), authMethods.includes("x") && onXSignIn && /* @__PURE__ */ React2.createElement("button", { type: "button", className: "dcm-method", onClick: handleX, disabled: busy }, /* @__PURE__ */ React2.createElement(XLogo, { size: 16 }), /* @__PURE__ */ React2.createElement("span", null, xLoading ? "Redirecting to X\u2026" : "X")), authMethods.includes("kingschat") && onKingsChatSignIn && /* @__PURE__ */ React2.createElement("button", { type: "button", className: "dcm-method", onClick: handleKingsChat, disabled: busy }, /* @__PURE__ */ React2.createElement(ChatIcon, { size: 18 }), /* @__PURE__ */ React2.createElement("span", null, kingsChatLoading ? "Waiting for KingsChat\u2026" : "KingsChat")), customAuthLabel && onCustomAuthSignIn && /* @__PURE__ */ React2.createElement("button", { type: "button", className: "dcm-method", onClick: handleCustomAuth, disabled: busy }, /* @__PURE__ */ React2.createElement(UserIcon, { size: 18 }), /* @__PURE__ */ React2.createElement("span", null, customLoading ? "Connecting\u2026" : customAuthLabel))), extra, errorLine, canUsePasskey && onPasskeySignIn && /* @__PURE__ */ React2.createElement("button", { type: "button", className: "dcm-link", onClick: () => {
6212
+ setError("");
6213
+ setShowOtherMethods(false);
6214
+ } }, "Use my passkey instead"), /* @__PURE__ */ React2.createElement(ProtectedBy, null));
7237
6215
  }
7238
6216
  function RecoverySection({
7239
6217
  addresses,
7240
6218
  onRotateShares,
7241
6219
  onExportPortableBackup
7242
6220
  }) {
7243
- const [expanded, setExpanded] = useState2(false);
7244
- const [mode, setMode] = useState2(null);
7245
- const [password, setPassword] = useState2("");
7246
- const [passwordHint, setPasswordHint] = useState2("");
7247
- const [confirmed, setConfirmed] = useState2(false);
7248
- const [busy, setBusy] = useState2(false);
7249
- const [result, setResult] = useState2(null);
7250
- const [error, setError] = useState2("");
6221
+ const [expanded, setExpanded] = useState(false);
6222
+ const [mode, setMode] = useState(null);
6223
+ const [password, setPassword] = useState("");
6224
+ const [passwordHint, setPasswordHint] = useState("");
6225
+ const [confirmed, setConfirmed] = useState(false);
6226
+ const [busy, setBusy] = useState(false);
6227
+ const [result, setResult] = useState(null);
6228
+ const [error, setError] = useState("");
7251
6229
  function reset() {
7252
6230
  setMode(null);
7253
6231
  setPassword("");
@@ -7284,60 +6262,34 @@ function RecoverySection({
7284
6262
  setBusy(false);
7285
6263
  }
7286
6264
  }
7287
- const inputStyle = {
7288
- width: "100%",
7289
- background: "var(--dc-bg)",
7290
- border: "1px solid var(--dc-border)",
7291
- borderRadius: 8,
7292
- color: "var(--dc-text)",
7293
- padding: "8px 10px",
7294
- fontSize: 12,
7295
- outline: "none",
7296
- fontFamily: "inherit",
7297
- boxSizing: "border-box"
7298
- };
7299
- const btnStyle = {
7300
- padding: "8px 12px",
7301
- borderRadius: 8,
7302
- fontSize: 12,
7303
- fontWeight: 700,
7304
- cursor: "pointer",
7305
- fontFamily: "inherit",
7306
- border: "none"
7307
- };
7308
- return /* @__PURE__ */ React3.createElement("div", { style: { margin: "0 16px 14px", border: "1px solid var(--dc-border)", borderRadius: 10, overflow: "hidden" } }, /* @__PURE__ */ React3.createElement(
7309
- "button",
6265
+ const passwordFields = /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement(
6266
+ "input",
7310
6267
  {
7311
- onClick: () => setExpanded((v) => !v),
7312
- style: {
7313
- width: "100%",
7314
- padding: "10px 14px",
7315
- background: "var(--dc-surface)",
7316
- border: "none",
7317
- display: "flex",
7318
- alignItems: "center",
7319
- justifyContent: "space-between",
7320
- cursor: "pointer",
7321
- fontFamily: "inherit"
7322
- }
7323
- },
7324
- /* @__PURE__ */ React3.createElement("span", { style: { fontSize: 12, fontWeight: 700, color: "var(--dc-text)" } }, "Recovery"),
7325
- /* @__PURE__ */ React3.createElement("span", { style: { fontSize: 11, color: "var(--dc-text-muted)" } }, expanded ? "\u25B2" : "\u25BC")
7326
- ), expanded && /* @__PURE__ */ React3.createElement("div", { style: { padding: "12px 14px", borderTop: "1px solid var(--dc-border)" } }, /* @__PURE__ */ React3.createElement("p", { style: { fontSize: 11, color: "var(--dc-text-muted)", lineHeight: 1.5, margin: "0 0 10px" } }, "Save a recovery file so you can restore this wallet on a new device."), !mode && /* @__PURE__ */ React3.createElement("div", { style: { display: "flex", flexDirection: "column", gap: 8 } }, /* @__PURE__ */ React3.createElement("button", { onClick: () => {
6268
+ className: "dcm-field",
6269
+ type: "password",
6270
+ placeholder: "Password (at least 8 characters)",
6271
+ "aria-label": "Password",
6272
+ autoComplete: "new-password",
6273
+ value: password,
6274
+ onChange: (e) => setPassword(e.target.value)
6275
+ }
6276
+ ), /* @__PURE__ */ React2.createElement(
6277
+ "input",
6278
+ {
6279
+ className: "dcm-field",
6280
+ placeholder: "Password hint (optional)",
6281
+ "aria-label": "Password hint",
6282
+ value: passwordHint,
6283
+ onChange: (e) => setPasswordHint(e.target.value)
6284
+ }
6285
+ ), error && /* @__PURE__ */ React2.createElement("p", { className: "dcm-error", role: "alert" }, error));
6286
+ return /* @__PURE__ */ React2.createElement("div", { className: "dcm-panel" }, /* @__PURE__ */ React2.createElement("button", { type: "button", className: "dcm-panel-head", onClick: () => setExpanded((v) => !v), "aria-expanded": expanded }, /* @__PURE__ */ React2.createElement("span", null, "Recovery file"), /* @__PURE__ */ React2.createElement(ChevronIcon, { open: expanded })), expanded && /* @__PURE__ */ React2.createElement("div", { className: "dcm-panel-body" }, !mode && /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement("p", { className: "dcm-note" }, "Save a recovery file so you can restore this wallet on a new device."), /* @__PURE__ */ React2.createElement("button", { type: "button", className: "dcm-primary", style: { height: 44, borderRadius: 12 }, onClick: () => {
7327
6287
  reset();
7328
6288
  setMode("share");
7329
- }, style: { ...btnStyle, background: "var(--dc-accent)", color: "var(--dc-accent-text)" } }, "Generate recovery-share file"), /* @__PURE__ */ React3.createElement("button", { onClick: () => {
6289
+ } }, "Download recovery-share file"), /* @__PURE__ */ React2.createElement("button", { type: "button", className: "dcm-ghost", onClick: () => {
7330
6290
  reset();
7331
6291
  setMode("portable");
7332
- }, style: { ...btnStyle, background: "transparent", border: "1px solid var(--dc-border)", color: "var(--dc-text)" } }, "Generate full recovery file")), mode === "share" && /* @__PURE__ */ React3.createElement("div", { style: { display: "flex", flexDirection: "column", gap: 8 } }, /* @__PURE__ */ React3.createElement("p", { style: { fontSize: 11, color: "var(--dc-text-muted)", margin: 0 } }, "One share \u2014 useless alone, safe to keep in a password manager or cloud drive. Generating a new one invalidates any previous recovery-share file."), /* @__PURE__ */ React3.createElement("input", { type: "password", placeholder: "Password (min 8 chars)", value: password, onChange: (e) => setPassword(e.target.value), style: inputStyle }), /* @__PURE__ */ React3.createElement("input", { placeholder: "Password hint (optional)", value: passwordHint, onChange: (e) => setPasswordHint(e.target.value), style: inputStyle }), error && /* @__PURE__ */ React3.createElement("div", { style: { fontSize: 11, color: "var(--dc-danger, #ff5533)" } }, error), /* @__PURE__ */ React3.createElement("div", { style: { display: "flex", gap: 8 } }, /* @__PURE__ */ React3.createElement("button", { onClick: handleGenerate, disabled: busy, style: { ...btnStyle, flex: 1, background: "var(--dc-accent)", color: "var(--dc-accent-text)" } }, busy ? "Generating\u2026" : "Generate & download"), /* @__PURE__ */ React3.createElement("button", { onClick: reset, style: { ...btnStyle, background: "transparent", border: "1px solid var(--dc-border)", color: "var(--dc-text-muted)" } }, "Cancel"))), mode === "portable" && /* @__PURE__ */ React3.createElement("div", { style: { display: "flex", flexDirection: "column", gap: 8 } }, /* @__PURE__ */ React3.createElement("div", { style: {
7333
- background: "rgba(255,85,51,0.08)",
7334
- border: "1px solid rgba(255,85,51,0.3)",
7335
- borderRadius: 8,
7336
- padding: "8px 10px",
7337
- fontSize: 11,
7338
- color: "#ff9977",
7339
- lineHeight: 1.5
7340
- } }, /* @__PURE__ */ React3.createElement("strong", { style: { display: "block", marginBottom: 3, color: "#ff5533" } }, "This file controls your wallet"), "Contains two shares \u2014 file plus password gives complete control. Keep it offline, not a cloud drive. This also invalidates your current recovery-share file."), /* @__PURE__ */ React3.createElement("label", { style: { display: "flex", alignItems: "center", gap: 6, fontSize: 11, color: "var(--dc-text)" } }, /* @__PURE__ */ React3.createElement("input", { type: "checkbox", checked: confirmed, onChange: (e) => setConfirmed(e.target.checked), style: { width: "auto" } }), "I understand this is a bearer secret"), /* @__PURE__ */ React3.createElement("input", { type: "password", placeholder: "Password (min 8 chars)", value: password, onChange: (e) => setPassword(e.target.value), style: inputStyle }), /* @__PURE__ */ React3.createElement("input", { placeholder: "Password hint (optional)", value: passwordHint, onChange: (e) => setPasswordHint(e.target.value), style: inputStyle }), error && /* @__PURE__ */ React3.createElement("div", { style: { fontSize: 11, color: "var(--dc-danger, #ff5533)" } }, error), /* @__PURE__ */ React3.createElement("div", { style: { display: "flex", gap: 8 } }, /* @__PURE__ */ React3.createElement("button", { onClick: handleGenerate, disabled: busy || !confirmed, style: { ...btnStyle, flex: 1, background: "var(--dc-accent)", color: "var(--dc-accent-text)" } }, busy ? "Generating\u2026" : "Generate & download"), /* @__PURE__ */ React3.createElement("button", { onClick: reset, style: { ...btnStyle, background: "transparent", border: "1px solid var(--dc-border)", color: "var(--dc-text-muted)" } }, "Cancel"))), result && /* @__PURE__ */ React3.createElement("div", { style: { marginTop: 10, fontSize: 11, color: "var(--dc-text-muted)", lineHeight: 1.5 } }, result.kind === "share" ? "Recovery-share file" : "Full recovery file", " downloaded \u2014 share set is now version ", result.version, ". Any previous recovery file no longer works.")));
6292
+ } }, "Download full recovery file")), mode === "share" && /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement("p", { className: "dcm-note" }, "One share. It is useless on its own, so a password manager or cloud drive is a fine place for it. A new file replaces any previous recovery-share file."), passwordFields, /* @__PURE__ */ React2.createElement("div", { className: "dcm-row" }, /* @__PURE__ */ React2.createElement("button", { type: "button", className: "dcm-primary", onClick: handleGenerate, disabled: busy }, busy ? "Preparing\u2026" : "Download"), /* @__PURE__ */ React2.createElement("button", { type: "button", className: "dcm-ghost", onClick: reset }, "Cancel"))), mode === "portable" && /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement("div", { className: "dcm-warn" }, /* @__PURE__ */ React2.createElement("strong", null, "This file controls your wallet"), "It holds two shares, so the file plus its password is full control. Keep it offline, not in a cloud drive. It also replaces your current recovery-share file."), /* @__PURE__ */ React2.createElement("label", { className: "dcm-check" }, /* @__PURE__ */ React2.createElement("input", { type: "checkbox", checked: confirmed, onChange: (e) => setConfirmed(e.target.checked) }), "I understand anyone with this file and password controls the wallet"), passwordFields, /* @__PURE__ */ React2.createElement("div", { className: "dcm-row" }, /* @__PURE__ */ React2.createElement("button", { type: "button", className: "dcm-primary", onClick: handleGenerate, disabled: busy || !confirmed }, busy ? "Preparing\u2026" : "Download"), /* @__PURE__ */ React2.createElement("button", { type: "button", className: "dcm-ghost", onClick: reset }, "Cancel"))), result && /* @__PURE__ */ React2.createElement("p", { className: "dcm-note" }, result.kind === "share" ? "Recovery-share file" : "Full recovery file", " downloaded. The share set is now version ", result.version, ", and any earlier recovery file no longer works.")));
7341
6293
  }
7342
6294
  function SocialWalletModal({
7343
6295
  open,
@@ -7348,6 +6300,7 @@ function SocialWalletModal({
7348
6300
  onDisconnect,
7349
6301
  onGoogleSignIn,
7350
6302
  onKingsChatSignIn,
6303
+ onXSignIn,
7351
6304
  onEmailStart,
7352
6305
  onEmailVerify,
7353
6306
  onPhoneStart,
@@ -7363,19 +6316,21 @@ function SocialWalletModal({
7363
6316
  rpcUrls,
7364
6317
  chains
7365
6318
  }) {
7366
- const [timer, setTimer] = useState2("");
7367
- const [unlocking, setUnlocking] = useState2(false);
7368
- const [disconnecting, setDisconnecting] = useState2(false);
7369
- useEffect2(() => {
6319
+ const [timer, setTimer] = useState("");
6320
+ const [unlocking, setUnlocking] = useState(false);
6321
+ const [disconnecting, setDisconnecting] = useState(false);
6322
+ const [actionError, setActionError] = useState("");
6323
+ useEffect(() => {
7370
6324
  if (!open) return;
7371
- injectTokens2(theme);
6325
+ injectTokens(theme);
6326
+ injectModalCss();
7372
6327
  if (theme !== "auto") return;
7373
6328
  const mq = window.matchMedia("(prefers-color-scheme: dark)");
7374
- const h = () => injectTokens2("auto");
6329
+ const h = () => injectTokens("auto");
7375
6330
  mq.addEventListener("change", h);
7376
6331
  return () => mq.removeEventListener("change", h);
7377
6332
  }, [open, theme]);
7378
- useEffect2(() => {
6333
+ useEffect(() => {
7379
6334
  if (!socialAuth.sessionExpiresAt) {
7380
6335
  setTimer("");
7381
6336
  return;
@@ -7384,10 +6339,10 @@ function SocialWalletModal({
7384
6339
  const id = setInterval(() => setTimer(countdown(socialAuth.sessionExpiresAt)), 1e3);
7385
6340
  return () => clearInterval(id);
7386
6341
  }, [socialAuth.sessionExpiresAt]);
7387
- const handleKey = useCallback2((e) => {
6342
+ const handleKey = useCallback((e) => {
7388
6343
  if (e.key === "Escape") onClose();
7389
6344
  }, [onClose]);
7390
- useEffect2(() => {
6345
+ useEffect(() => {
7391
6346
  if (!open) return;
7392
6347
  document.addEventListener("keydown", handleKey);
7393
6348
  return () => document.removeEventListener("keydown", handleKey);
@@ -7395,17 +6350,23 @@ function SocialWalletModal({
7395
6350
  if (!open) return null;
7396
6351
  async function handleUnlock() {
7397
6352
  setUnlocking(true);
6353
+ setActionError("");
7398
6354
  try {
7399
6355
  await onUnlock();
6356
+ } catch (e) {
6357
+ setActionError(e.message);
7400
6358
  } finally {
7401
6359
  setUnlocking(false);
7402
6360
  }
7403
6361
  }
7404
6362
  async function handleDisconnect() {
7405
6363
  setDisconnecting(true);
6364
+ setActionError("");
7406
6365
  try {
7407
6366
  await onDisconnect();
7408
6367
  onClose();
6368
+ } catch (e) {
6369
+ setActionError(e.message);
7409
6370
  } finally {
7410
6371
  setDisconnecting(false);
7411
6372
  }
@@ -7413,12 +6374,13 @@ function SocialWalletModal({
7413
6374
  const evmChain = chains?.find((c) => c.startsWith("evm:")) ?? "evm:11155111";
7414
6375
  const solChain = chains?.find((c) => c.startsWith("solana:")) ?? "solana:mainnet";
7415
6376
  const showSignIn = !socialAuth.addresses || socialAuth.needsReconnect;
7416
- const modal = /* @__PURE__ */ React3.createElement(
6377
+ const unlocked = socialAuth.isUnlocked;
6378
+ const modal = /* @__PURE__ */ React2.createElement(
7417
6379
  "div",
7418
6380
  {
7419
6381
  role: "dialog",
7420
6382
  "aria-modal": "true",
7421
- "aria-label": "Social wallet",
6383
+ "aria-label": showSignIn ? "Log in or sign up" : "Your wallet",
7422
6384
  style: {
7423
6385
  position: "fixed",
7424
6386
  inset: 0,
@@ -7427,63 +6389,17 @@ function SocialWalletModal({
7427
6389
  alignItems: "center",
7428
6390
  justifyContent: "center",
7429
6391
  padding: 16,
7430
- fontFamily: "var(--dc-font-sans, system-ui, sans-serif)"
6392
+ fontFamily: "var(--dc-font-sans, system-ui, sans-serif)",
6393
+ WebkitFontSmoothing: "antialiased"
7431
6394
  }
7432
6395
  },
7433
- /* @__PURE__ */ React3.createElement(
7434
- "div",
7435
- {
7436
- onClick: onClose,
7437
- style: {
7438
- position: "absolute",
7439
- inset: 0,
7440
- background: "var(--dc-bg-overlay)",
7441
- backdropFilter: "blur(8px)",
7442
- WebkitBackdropFilter: "blur(8px)"
7443
- }
7444
- }
7445
- ),
7446
- /* @__PURE__ */ React3.createElement("div", { style: {
7447
- position: "relative",
7448
- background: "var(--dc-bg)",
7449
- border: "1px solid var(--dc-border)",
7450
- borderRadius: 20,
7451
- width: "100%",
7452
- maxWidth: 380,
7453
- maxHeight: "90vh",
7454
- overflowY: "auto",
7455
- boxShadow: "0 24px 64px rgba(0,0,0,0.6), 0 0 0 1px rgba(255,255,255,0.04)"
7456
- } }, /* @__PURE__ */ React3.createElement("div", { style: {
7457
- height: 2,
7458
- position: "sticky",
7459
- top: 0,
7460
- zIndex: 1,
7461
- background: "linear-gradient(90deg, transparent, var(--dc-accent) 30%, var(--dc-accent) 70%, transparent)"
7462
- } }), /* @__PURE__ */ React3.createElement("div", { style: { padding: "18px 20px 16px", display: "flex", alignItems: "center", gap: 11 } }, /* @__PURE__ */ React3.createElement(DecaneMark, { size: 38 }), /* @__PURE__ */ React3.createElement("div", { style: { flex: 1 } }, /* @__PURE__ */ React3.createElement("div", { style: { display: "flex", alignItems: "baseline", gap: 6 } }, /* @__PURE__ */ React3.createElement(DecaneWordmark, { size: 15 }), /* @__PURE__ */ React3.createElement("span", { style: { fontSize: 13, fontWeight: 700, color: "var(--dc-text-muted)", letterSpacing: "-0.01em" } }, "wallet")), /* @__PURE__ */ React3.createElement("div", { style: { fontSize: 11, color: "var(--dc-text-muted)", marginTop: 2 } }, "Non-custodial \xB7 key split three ways")), /* @__PURE__ */ React3.createElement(
7463
- "button",
7464
- {
7465
- onClick: onClose,
7466
- style: {
7467
- background: "var(--dc-surface)",
7468
- border: "1px solid var(--dc-border)",
7469
- borderRadius: 8,
7470
- width: 28,
7471
- height: 28,
7472
- cursor: "pointer",
7473
- display: "flex",
7474
- alignItems: "center",
7475
- justifyContent: "center",
7476
- color: "var(--dc-text-muted)",
7477
- flexShrink: 0,
7478
- padding: 0
7479
- }
7480
- },
7481
- /* @__PURE__ */ React3.createElement("svg", { width: "12", height: "12", viewBox: "0 0 12 12", fill: "none" }, /* @__PURE__ */ React3.createElement("path", { d: "M1.5 1.5L10.5 10.5M10.5 1.5L1.5 10.5", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" }))
7482
- )), showSignIn ? /* @__PURE__ */ React3.createElement(
6396
+ /* @__PURE__ */ React2.createElement("div", { className: "dcm-backdrop", onClick: onClose }),
6397
+ /* @__PURE__ */ React2.createElement("div", { className: "dcm-card" }, /* @__PURE__ */ React2.createElement("button", { type: "button", className: "dcm-icon-btn", style: { right: 14 }, onClick: onClose, "aria-label": "Close" }, /* @__PURE__ */ React2.createElement(CloseIcon, null)), showSignIn ? /* @__PURE__ */ React2.createElement(
7483
6398
  SignInView,
7484
6399
  {
7485
6400
  onGoogleSignIn,
7486
6401
  onKingsChatSignIn,
6402
+ onXSignIn,
7487
6403
  onEmailStart,
7488
6404
  onEmailVerify,
7489
6405
  onPhoneStart,
@@ -7496,86 +6412,238 @@ function SocialWalletModal({
7496
6412
  passkeyAddress,
7497
6413
  onPasskeySignIn
7498
6414
  }
7499
- ) : /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement("div", { style: {
7500
- margin: "0 16px 14px",
7501
- padding: "8px 14px",
7502
- background: socialAuth.isUnlocked ? "rgba(18,183,106,0.08)" : "rgba(245,200,0,0.08)",
7503
- border: `1px solid ${socialAuth.isUnlocked ? "rgba(18,183,106,0.2)" : "rgba(245,200,0,0.2)"}`,
7504
- borderRadius: 10,
7505
- display: "flex",
7506
- alignItems: "center",
7507
- justifyContent: "space-between"
7508
- } }, /* @__PURE__ */ React3.createElement("div", { style: { display: "flex", alignItems: "center", gap: 8 } }, /* @__PURE__ */ React3.createElement("span", { style: {
7509
- width: 7,
7510
- height: 7,
7511
- borderRadius: "50%",
7512
- flexShrink: 0,
7513
- background: socialAuth.isUnlocked ? "#12b76a" : "var(--dc-accent)",
7514
- boxShadow: `0 0 6px ${socialAuth.isUnlocked ? "#12b76a" : "var(--dc-accent)"}`
7515
- } }), /* @__PURE__ */ React3.createElement("span", { style: {
7516
- fontSize: 12,
7517
- fontWeight: 700,
7518
- color: socialAuth.isUnlocked ? "#12b76a" : "var(--dc-accent)"
7519
- } }, socialAuth.isUnlocked ? "Unlocked" : "Locked")), socialAuth.isUnlocked && timer && /* @__PURE__ */ React3.createElement("span", { style: { fontSize: 11, color: "var(--dc-text-muted)", fontFamily: "monospace" } }, "expires ", timer)), /* @__PURE__ */ React3.createElement("div", { style: { padding: "0 16px 14px" } }, socialAuth.addresses?.evm && /* @__PURE__ */ React3.createElement(AddressRow, { label: "EVM (Ethereum, Base, \u2026)", address: socialAuth.addresses.evm, kind: "evm", chain: evmChain, rpcUrls }), socialAuth.addresses?.solana && /* @__PURE__ */ React3.createElement(AddressRow, { label: "Solana", address: socialAuth.addresses.solana, kind: "solana", chain: solChain, rpcUrls })), socialAuth.isUnlocked && /* @__PURE__ */ React3.createElement(
6415
+ ) : /* @__PURE__ */ React2.createElement("div", { className: "dcm-body" }, /* @__PURE__ */ React2.createElement(DecaneMark, { size: 44 }), /* @__PURE__ */ React2.createElement("h2", { className: "dcm-title" }, "Your wallet"), /* @__PURE__ */ React2.createElement(
6416
+ "span",
6417
+ {
6418
+ className: "dcm-status",
6419
+ style: { color: unlocked ? "#12b76a" : "var(--dc-accent-ink)", marginTop: -8 }
6420
+ },
6421
+ /* @__PURE__ */ React2.createElement("i", { style: { background: unlocked ? "#12b76a" : "var(--dc-accent)" } }),
6422
+ unlocked ? timer ? `Unlocked, expires in ${timer}` : "Unlocked" : "Locked"
6423
+ ), (socialAuth.addresses?.evm || socialAuth.addresses?.solana) && /* @__PURE__ */ React2.createElement("div", { className: "dcm-addresses" }, socialAuth.addresses?.evm && /* @__PURE__ */ React2.createElement(AddressRow, { label: "Ethereum and EVM", address: socialAuth.addresses.evm, kind: "evm", chain: evmChain, rpcUrls }), socialAuth.addresses?.solana && /* @__PURE__ */ React2.createElement(AddressRow, { label: "Solana", address: socialAuth.addresses.solana, kind: "solana", chain: solChain, rpcUrls })), unlocked && /* @__PURE__ */ React2.createElement(
7520
6424
  RecoverySection,
7521
6425
  {
7522
6426
  addresses: socialAuth.addresses,
7523
6427
  onRotateShares,
7524
6428
  onExportPortableBackup
7525
6429
  }
7526
- ), /* @__PURE__ */ React3.createElement("div", { style: {
7527
- padding: "14px 16px",
7528
- borderTop: "1px solid var(--dc-border)",
7529
- display: "flex",
7530
- gap: 8
7531
- } }, !socialAuth.isUnlocked && /* @__PURE__ */ React3.createElement(
7532
- "button",
6430
+ ), actionError && /* @__PURE__ */ React2.createElement("p", { className: "dcm-error", role: "alert" }, actionError), /* @__PURE__ */ React2.createElement("div", { className: "dcm-actions" }, !unlocked && /* @__PURE__ */ React2.createElement("button", { type: "button", className: "dcm-primary", style: { height: 44, borderRadius: 12 }, onClick: handleUnlock, disabled: unlocking }, unlocking ? "Unlocking\u2026" : "Unlock wallet"), /* @__PURE__ */ React2.createElement("button", { type: "button", className: "dcm-ghost", onClick: handleDisconnect, disabled: disconnecting }, disconnecting ? "Signing out\u2026" : "Sign out")), /* @__PURE__ */ React2.createElement(ProtectedBy, null)))
6431
+ );
6432
+ return createPortal(modal, document.body);
6433
+ }
6434
+
6435
+ // src/ui/WalletSelector.tsx
6436
+ var FONT_URL = "https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&display=swap";
6437
+ function injectTokens2(theme) {
6438
+ let resolved;
6439
+ if (theme === "auto") {
6440
+ resolved = window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
6441
+ } else {
6442
+ resolved = theme;
6443
+ }
6444
+ let styleEl = document.getElementById("decane-tokens");
6445
+ if (!styleEl) {
6446
+ styleEl = document.createElement("style");
6447
+ styleEl.id = "decane-tokens";
6448
+ document.head.appendChild(styleEl);
6449
+ }
6450
+ styleEl.textContent = `:root { ${CSS_VARS[resolved]} }`;
6451
+ }
6452
+ function injectFont() {
6453
+ if (document.getElementById("decane-font")) return;
6454
+ const link = document.createElement("link");
6455
+ link.id = "decane-font";
6456
+ link.rel = "stylesheet";
6457
+ link.href = FONT_URL;
6458
+ document.head.appendChild(link);
6459
+ }
6460
+ function hasSocialMode(mode) {
6461
+ return mode === "all" || mode === "social" || mode === "evm+social" || mode === "solana+social" || mode === "tron+social" || mode === "evm+tron+social";
6462
+ }
6463
+ var NETWORK_LABEL = {
6464
+ evm: "EVM networks",
6465
+ solana: "Solana",
6466
+ tron: "Tron",
6467
+ bitcoin: "Bitcoin"
6468
+ };
6469
+ function WalletSelector({
6470
+ provider,
6471
+ open,
6472
+ onClose,
6473
+ onConnect,
6474
+ theme = "auto",
6475
+ networks = "all",
6476
+ mode = "wallets",
6477
+ socialAuthMethods = ["google", "email"],
6478
+ onGoogleSignIn,
6479
+ onKingsChatSignIn,
6480
+ onXSignIn,
6481
+ onEmailStart,
6482
+ onEmailVerify,
6483
+ onPhoneStart,
6484
+ onPhoneVerify,
6485
+ customAuthLabel,
6486
+ onCustomAuthSignIn,
6487
+ canUsePasskey = false,
6488
+ passkeyAddress = null,
6489
+ onPasskeySignIn
6490
+ }) {
6491
+ const showSocial = hasSocialMode(mode);
6492
+ const showWallets = mode !== "social";
6493
+ const [view, setView] = useState2(showSocial ? "social" : "wallets");
6494
+ const [search, setSearch] = useState2("");
6495
+ const [filter, setFilter] = useState2("all");
6496
+ const [pendingWallet, setPendingWallet] = useState2(null);
6497
+ const [session, setSession] = useState2(0);
6498
+ useEffect2(() => {
6499
+ if (!open) return;
6500
+ injectFont();
6501
+ injectTokens2(theme);
6502
+ injectModalCss();
6503
+ if (theme !== "auto") return;
6504
+ const mq = window.matchMedia("(prefers-color-scheme: dark)");
6505
+ const handler = () => injectTokens2("auto");
6506
+ mq.addEventListener("change", handler);
6507
+ return () => mq.removeEventListener("change", handler);
6508
+ }, [open, theme]);
6509
+ useEffect2(() => {
6510
+ if (!open) {
6511
+ setSearch("");
6512
+ setFilter("all");
6513
+ setPendingWallet(null);
6514
+ setView(showSocial ? "social" : "wallets");
6515
+ setSession((n) => n + 1);
6516
+ return;
6517
+ }
6518
+ return () => {
6519
+ document.getElementById("decane-tokens")?.remove();
6520
+ };
6521
+ }, [open, showWallets, showSocial]);
6522
+ const handleKey = useCallback2(
6523
+ (e) => {
6524
+ if (e.key !== "Escape") return;
6525
+ if (pendingWallet) setPendingWallet(null);
6526
+ else onClose();
6527
+ },
6528
+ [onClose, pendingWallet]
6529
+ );
6530
+ useEffect2(() => {
6531
+ if (!open) return;
6532
+ document.addEventListener("keydown", handleKey);
6533
+ return () => document.removeEventListener("keydown", handleKey);
6534
+ }, [open, handleKey]);
6535
+ if (!open) return null;
6536
+ const q = search.trim().toLowerCase();
6537
+ const networkWallets = provider.wallets.filter((w) => {
6538
+ const cs = w.chainSupport;
6539
+ if (networks === "evm") return cs.includes("evm");
6540
+ if (networks === "solana") return cs.includes("solana");
6541
+ if (networks === "tron") return cs.includes("tron");
6542
+ if (networks === "bitcoin") return cs.includes("bitcoin");
6543
+ return true;
6544
+ });
6545
+ const baseWallets = filter === "all" ? networkWallets : networkWallets.filter((w) => w.chainSupport.includes(filter));
6546
+ const filtered = q ? baseWallets.filter((w) => w.name.toLowerCase().includes(q)) : baseWallets;
6547
+ const filters = [
6548
+ { id: "all", label: "All" },
6549
+ { id: "evm", label: "EVM" },
6550
+ { id: "solana", label: "Solana" },
6551
+ ...provider.tronWallets?.length ? [{ id: "tron", label: "Tron" }] : [],
6552
+ ...provider.bitcoinWallets?.length ? [{ id: "bitcoin", label: "Bitcoin" }] : []
6553
+ ];
6554
+ function handleWalletClick(wallet) {
6555
+ const cs = wallet.chainSupport;
6556
+ const isMulti = cs.length >= 2;
6557
+ if (isMulti && networks === "all") {
6558
+ setPendingWallet(wallet);
6559
+ } else {
6560
+ const preference = networks === "evm" ? "evm" : networks === "solana" ? "solana" : networks === "tron" ? "tron" : networks === "bitcoin" ? "bitcoin" : void 0;
6561
+ onConnect(wallet, preference);
6562
+ onClose();
6563
+ }
6564
+ }
6565
+ function handleChainChoice(preference) {
6566
+ if (!pendingWallet) return;
6567
+ onConnect(pendingWallet, preference);
6568
+ onClose();
6569
+ }
6570
+ const signInMethods = socialAuthMethods.filter(
6571
+ (m) => m === "google" ? !!onGoogleSignIn : m === "email" ? !!onEmailStart && !!onEmailVerify : true
6572
+ );
6573
+ const noop = async () => {
6574
+ };
6575
+ const noopStart = async () => ({ codeRequired: true });
6576
+ const walletEntry = showWallets ? /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement("div", { className: "dcm-or" }, "or"), /* @__PURE__ */ React3.createElement("div", { className: "dcm-methods", style: { marginTop: 0 } }, /* @__PURE__ */ React3.createElement("button", { type: "button", className: "dcm-method", onClick: () => setView("wallets") }, /* @__PURE__ */ React3.createElement(WalletLineIcon, { size: 18 }), /* @__PURE__ */ React3.createElement("span", null, "Continue with a wallet"), /* @__PURE__ */ React3.createElement("span", { className: "dcm-trail" }, networkWallets.length > 0 && /* @__PURE__ */ React3.createElement("span", { className: "dcm-stack", "aria-label": `${networkWallets.length} detected` }, networkWallets.slice(0, 3).map(
6577
+ (w) => w.icon ? /* @__PURE__ */ React3.createElement("img", { key: w.id, src: w.icon, alt: "" }) : /* @__PURE__ */ React3.createElement("span", { key: w.id })
6578
+ )), /* @__PURE__ */ React3.createElement(ChevronRightIcon, null))))) : null;
6579
+ const closeButton = /* @__PURE__ */ React3.createElement("button", { type: "button", className: "dcm-icon-btn", style: { right: 14 }, onClick: onClose, "aria-label": "Close" }, /* @__PURE__ */ React3.createElement(CloseIcon, null));
6580
+ let body;
6581
+ if (pendingWallet) {
6582
+ const support = pendingWallet.chainSupport;
6583
+ body = /* @__PURE__ */ React3.createElement("div", { className: "dcm-body" }, /* @__PURE__ */ React3.createElement("button", { type: "button", className: "dcm-icon-btn", style: { left: 14 }, onClick: () => setPendingWallet(null), "aria-label": "Back" }, /* @__PURE__ */ React3.createElement(ArrowLeftIcon, null)), closeButton, /* @__PURE__ */ React3.createElement(WalletIcon, { src: pendingWallet.icon || void 0, name: pendingWallet.name, size: 52 }), /* @__PURE__ */ React3.createElement("h2", { className: "dcm-title" }, "Choose networks"), /* @__PURE__ */ React3.createElement("p", { className: "dcm-sub" }, pendingWallet.name, " works on more than one network. Pick what to connect."), /* @__PURE__ */ React3.createElement("div", { className: "dcm-methods" }, /* @__PURE__ */ React3.createElement("button", { type: "button", className: "dcm-option", onClick: () => handleChainChoice(void 0) }, /* @__PURE__ */ React3.createElement("span", { className: "dcm-option-icons" }, /* @__PURE__ */ React3.createElement(ChainIconStack, { support, size: 20 })), /* @__PURE__ */ React3.createElement("span", { className: "dcm-option-text" }, /* @__PURE__ */ React3.createElement("b", null, "All networks"), /* @__PURE__ */ React3.createElement("small", null, "Every address this wallet has")), /* @__PURE__ */ React3.createElement(ChevronRightIcon, null)), support.map((c) => /* @__PURE__ */ React3.createElement("button", { key: c, type: "button", className: "dcm-option", onClick: () => handleChainChoice(c) }, /* @__PURE__ */ React3.createElement("span", { className: "dcm-option-icons" }, /* @__PURE__ */ React3.createElement(ChainIconStack, { support: [c], size: 20 })), /* @__PURE__ */ React3.createElement("span", { className: "dcm-option-text" }, /* @__PURE__ */ React3.createElement("b", null, NETWORK_LABEL[c] ?? c), /* @__PURE__ */ React3.createElement("small", null, "Only your ", c === "evm" ? "Ethereum-compatible" : NETWORK_LABEL[c] ?? c, " address")), /* @__PURE__ */ React3.createElement(ChevronRightIcon, null)))), /* @__PURE__ */ React3.createElement(ProtectedBy, null));
6584
+ } else if (view === "wallets") {
6585
+ body = /* @__PURE__ */ React3.createElement("div", { className: "dcm-body" }, showSocial && /* @__PURE__ */ React3.createElement("button", { type: "button", className: "dcm-icon-btn", style: { left: 14 }, onClick: () => setView("social"), "aria-label": "Back to sign-in" }, /* @__PURE__ */ React3.createElement(ArrowLeftIcon, null)), closeButton, /* @__PURE__ */ React3.createElement(DecaneMark, { size: 44 }), /* @__PURE__ */ React3.createElement("h2", { className: "dcm-title" }, "Connect a wallet"), /* @__PURE__ */ React3.createElement("p", { className: "dcm-sub" }, networkWallets.length ? `${networkWallets.length} wallet${networkWallets.length === 1 ? "" : "s"} found in this browser` : "No wallets found in this browser"), networks === "all" && networkWallets.length > 0 && filters.length > 1 && /* @__PURE__ */ React3.createElement("div", { className: "dcm-pills", role: "group", "aria-label": "Filter by network" }, filters.map((f) => /* @__PURE__ */ React3.createElement("button", { key: f.id, type: "button", "aria-pressed": filter === f.id, onClick: () => setFilter(f.id) }, f.label))), networkWallets.length > 5 && /* @__PURE__ */ React3.createElement("div", { className: "dcm-search" }, /* @__PURE__ */ React3.createElement(SearchIcon, null), /* @__PURE__ */ React3.createElement(
6586
+ "input",
7533
6587
  {
7534
- onClick: handleUnlock,
7535
- disabled: unlocking,
7536
- style: {
7537
- flex: 1,
7538
- padding: "10px 0",
7539
- background: "var(--dc-accent)",
7540
- color: "var(--dc-accent-text)",
7541
- border: "none",
7542
- borderRadius: 10,
7543
- fontSize: 13,
7544
- fontWeight: 700,
7545
- cursor: unlocking ? "not-allowed" : "pointer",
7546
- fontFamily: "inherit",
7547
- opacity: unlocking ? 0.7 : 1
7548
- }
7549
- },
7550
- unlocking ? "Unlocking\u2026" : "\u{1F513} Unlock wallet"
7551
- ), /* @__PURE__ */ React3.createElement(
7552
- "button",
6588
+ className: "dcm-field",
6589
+ type: "text",
6590
+ placeholder: "Search wallets",
6591
+ "aria-label": "Search wallets",
6592
+ value: search,
6593
+ onChange: (e) => setSearch(e.target.value)
6594
+ }
6595
+ )), filtered.length > 0 ? /* @__PURE__ */ React3.createElement("div", { className: "dcm-list" }, filtered.map((w) => /* @__PURE__ */ React3.createElement("button", { key: w.id, type: "button", className: "dcm-method", onClick: () => handleWalletClick(w) }, /* @__PURE__ */ React3.createElement(WalletIcon, { src: w.icon || void 0, name: w.name, size: 26 }), /* @__PURE__ */ React3.createElement("span", null, w.name), /* @__PURE__ */ React3.createElement("span", { className: "dcm-trail" }, /* @__PURE__ */ React3.createElement(ChainIconStack, { support: w.chainSupport, size: 16 }), /* @__PURE__ */ React3.createElement(ChevronRightIcon, null))))) : /* @__PURE__ */ React3.createElement("p", { className: "dcm-empty" }, q ? `No wallets match "${search.trim()}".` : networkWallets.length ? "No wallets for this network." : "Install a wallet extension, or unlock the one you have, then reopen this window."), /* @__PURE__ */ React3.createElement(ProtectedBy, null));
6596
+ } else {
6597
+ body = /* @__PURE__ */ React3.createElement(React3.Fragment, null, closeButton, /* @__PURE__ */ React3.createElement(
6598
+ SignInView,
7553
6599
  {
7554
- onClick: handleDisconnect,
7555
- disabled: disconnecting,
7556
- style: {
7557
- flex: socialAuth.isUnlocked ? 1 : 0,
7558
- padding: "10px 16px",
7559
- background: "transparent",
7560
- border: "1px solid var(--dc-border)",
7561
- borderRadius: 10,
7562
- color: "var(--dc-text-muted)",
7563
- fontSize: 13,
7564
- cursor: disconnecting ? "not-allowed" : "pointer",
7565
- fontFamily: "inherit",
7566
- opacity: disconnecting ? 0.7 : 1,
7567
- whiteSpace: "nowrap"
7568
- }
7569
- },
7570
- disconnecting ? "Signing out\u2026" : "Sign out"
7571
- ))), /* @__PURE__ */ React3.createElement("div", { style: {
7572
- padding: "11px 16px",
7573
- borderTop: "1px solid var(--dc-border)",
7574
- display: "flex",
7575
- alignItems: "center",
7576
- justifyContent: "center",
7577
- gap: 6
7578
- } }, /* @__PURE__ */ React3.createElement("span", { style: { fontSize: 10.5, color: "var(--dc-text-muted)", letterSpacing: "0.02em" } }, "Secured by"), /* @__PURE__ */ React3.createElement(DecaneMark, { size: 13, muted: true }), /* @__PURE__ */ React3.createElement(DecaneWordmark, { size: 11, muted: true })))
6600
+ key: session,
6601
+ onGoogleSignIn: onGoogleSignIn ?? noop,
6602
+ onKingsChatSignIn,
6603
+ onXSignIn,
6604
+ onEmailStart: onEmailStart ?? noopStart,
6605
+ onEmailVerify: onEmailVerify ?? noop,
6606
+ onPhoneStart,
6607
+ onPhoneVerify,
6608
+ authMethods: signInMethods,
6609
+ customAuthLabel,
6610
+ onCustomAuthSignIn,
6611
+ canUsePasskey,
6612
+ passkeyAddress,
6613
+ onPasskeySignIn,
6614
+ extra: walletEntry
6615
+ }
6616
+ ));
6617
+ }
6618
+ const modal = /* @__PURE__ */ React3.createElement(
6619
+ "div",
6620
+ {
6621
+ role: "dialog",
6622
+ "aria-modal": "true",
6623
+ "aria-label": pendingWallet ? "Choose networks" : view === "wallets" ? "Connect a wallet" : "Log in or sign up",
6624
+ style: {
6625
+ position: "fixed",
6626
+ inset: 0,
6627
+ zIndex: 9999,
6628
+ display: "flex",
6629
+ alignItems: "center",
6630
+ justifyContent: "center",
6631
+ padding: "16px",
6632
+ // Same fallback chain as SocialWalletModal — without it, this modal
6633
+ // drops to the browser default serif whenever the token block hasn't
6634
+ // been injected, while the social modal still lands on system-ui.
6635
+ fontFamily: "var(--dc-font-sans, system-ui, sans-serif)",
6636
+ WebkitFontSmoothing: "antialiased"
6637
+ }
6638
+ },
6639
+ /* @__PURE__ */ React3.createElement(
6640
+ "div",
6641
+ {
6642
+ className: "dcm-backdrop",
6643
+ onClick: () => pendingWallet ? setPendingWallet(null) : onClose()
6644
+ }
6645
+ ),
6646
+ /* @__PURE__ */ React3.createElement("div", { className: "dcm-card" }, body)
7579
6647
  );
7580
6648
  return createPortal2(modal, document.body);
7581
6649
  }