decane-connect-kit 2.29.0 → 2.29.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -3828,7 +3828,7 @@ async function buildPortableBackup(deviceShare, recoveryShare, password, address
3828
3828
  // src/social/client.ts
3829
3829
  var DEFAULT_API_BASE = "https://backend.decane.app";
3830
3830
  var DEFAULT_TEE_URL = "https://4405742df08d19abc549a05ade2a7154d98bd87f-8443.dstack-pha-prod9.phala.network";
3831
- var DEFAULT_SESSION_MINUTES = 120;
3831
+ var DEFAULT_SESSION_MINUTES = 480;
3832
3832
  function makePersistKey(apiKey) {
3833
3833
  return `decane:social:${apiKey.slice(0, 20)}`;
3834
3834
  }
@@ -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 = {
@@ -5798,1047 +5798,23 @@ function ChevronIcon({ size = 16, open = false }) {
5798
5798
  /* @__PURE__ */ React.createElement("path", { d: "m6 9 6 6 6-6" })
5799
5799
  );
5800
5800
  }
5801
-
5802
- // src/ui/WalletSelector.tsx
5803
- var FONT_URL = "https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&display=swap";
5804
- function injectTokens(theme) {
5805
- let resolved;
5806
- if (theme === "auto") {
5807
- resolved = window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
5808
- } else {
5809
- resolved = theme;
5810
- }
5811
- let styleEl = document.getElementById("decane-tokens");
5812
- if (!styleEl) {
5813
- styleEl = document.createElement("style");
5814
- styleEl.id = "decane-tokens";
5815
- document.head.appendChild(styleEl);
5816
- }
5817
- styleEl.textContent = `:root { ${CSS_VARS[resolved]} }`;
5818
- }
5819
- function injectFont() {
5820
- if (document.getElementById("decane-font")) return;
5821
- const link = document.createElement("link");
5822
- link.id = "decane-font";
5823
- link.rel = "stylesheet";
5824
- link.href = FONT_URL;
5825
- document.head.appendChild(link);
5826
- }
5827
- function WalletRow({ wallet, onClick }) {
5828
- const [hovered, setHovered] = useState(false);
5829
- const [focused, setFocused] = useState(false);
5830
- return /* @__PURE__ */ React2.createElement(
5831
- "button",
5832
- {
5833
- onClick,
5834
- onMouseEnter: () => setHovered(true),
5835
- onMouseLeave: () => setHovered(false),
5836
- onFocus: () => setFocused(true),
5837
- onBlur: () => setFocused(false),
5838
- style: {
5839
- display: "flex",
5840
- alignItems: "center",
5841
- gap: 12,
5842
- width: "100%",
5843
- padding: "11px 14px",
5844
- background: hovered ? "var(--dc-surface-hover)" : "transparent",
5845
- border: focused ? "1px solid var(--dc-border-accent)" : "1px solid transparent",
5846
- borderRadius: 10,
5847
- cursor: "pointer",
5848
- textAlign: "left",
5849
- transition: "background 0.12s, border-color 0.12s",
5850
- outline: "none",
5851
- fontFamily: "inherit"
5852
- }
5853
- },
5854
- /* @__PURE__ */ React2.createElement(WalletIcon, { src: wallet.icon || void 0, name: wallet.name, size: 38 }),
5855
- /* @__PURE__ */ React2.createElement("span", { style: { flex: 1, fontSize: 14, fontWeight: 600, color: "var(--dc-text)", letterSpacing: "-0.01em" } }, wallet.name),
5856
- /* @__PURE__ */ React2.createElement(ChainIconStack, { support: wallet.chainSupport, size: 16 }),
5857
- /* @__PURE__ */ React2.createElement(
5858
- "svg",
5859
- {
5860
- width: "14",
5861
- height: "14",
5862
- viewBox: "0 0 14 14",
5863
- fill: "none",
5864
- style: { color: hovered ? "var(--dc-text-secondary)" : "var(--dc-text-muted)", flexShrink: 0, transition: "color 0.12s" }
5865
- },
5866
- /* @__PURE__ */ React2.createElement("path", { d: "M5 2.5L9.5 7L5 11.5", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" })
5867
- )
5868
- );
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" }));
5869
5803
  }
5870
- function FilterTab({ label, active, onClick }) {
5871
- const [hovered, setHovered] = useState(false);
5872
- return /* @__PURE__ */ React2.createElement(
5873
- "button",
5874
- {
5875
- onClick,
5876
- onMouseEnter: () => setHovered(true),
5877
- onMouseLeave: () => setHovered(false),
5878
- style: {
5879
- flex: 1,
5880
- padding: "6px 8px",
5881
- borderRadius: 8,
5882
- border: active ? "1px solid var(--dc-border-accent)" : "1px solid transparent",
5883
- background: active ? "rgba(245,200,0,0.1)" : hovered ? "var(--dc-surface-hover)" : "transparent",
5884
- color: active ? "var(--dc-accent)" : "var(--dc-text-muted)",
5885
- fontSize: 11,
5886
- fontWeight: 700,
5887
- letterSpacing: "0.04em",
5888
- textTransform: "uppercase",
5889
- cursor: "pointer",
5890
- transition: "all 0.12s",
5891
- fontFamily: "inherit",
5892
- outline: "none"
5893
- }
5894
- },
5895
- label
5896
- );
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" }));
5897
5806
  }
5898
- function ChainOption({ label, description, badges, onClick }) {
5899
- const [hovered, setHovered] = useState(false);
5900
- return /* @__PURE__ */ React2.createElement(
5901
- "button",
5902
- {
5903
- onClick,
5904
- onMouseEnter: () => setHovered(true),
5905
- onMouseLeave: () => setHovered(false),
5906
- style: {
5907
- display: "flex",
5908
- flexDirection: "column",
5909
- alignItems: "flex-start",
5910
- gap: 6,
5911
- width: "100%",
5912
- padding: "14px 16px",
5913
- background: hovered ? "var(--dc-surface-hover)" : "var(--dc-surface)",
5914
- border: hovered ? "1px solid var(--dc-border-accent)" : "1px solid var(--dc-border)",
5915
- borderRadius: 12,
5916
- cursor: "pointer",
5917
- textAlign: "left",
5918
- transition: "all 0.12s",
5919
- fontFamily: "inherit",
5920
- outline: "none"
5921
- }
5922
- },
5923
- badges,
5924
- /* @__PURE__ */ React2.createElement("span", { style: { fontSize: 13, fontWeight: 700, color: "var(--dc-text)" } }, label),
5925
- /* @__PURE__ */ React2.createElement("span", { style: { fontSize: 11, color: "var(--dc-text-muted)", lineHeight: 1.4 } }, description)
5926
- );
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" }));
5927
5809
  }
5928
- function hasSocialMode(mode) {
5929
- return mode === "all" || mode === "social" || mode === "evm+social" || mode === "solana+social" || mode === "tron+social" || mode === "evm+tron+social";
5930
- }
5931
- function WalletSelector({
5932
- provider,
5933
- open,
5934
- onClose,
5935
- onConnect,
5936
- theme = "auto",
5937
- networks = "all",
5938
- mode = "wallets",
5939
- socialAuthMethods = ["google", "email"],
5940
- onGoogleSignIn,
5941
- onKingsChatSignIn,
5942
- onXSignIn,
5943
- onEmailStart,
5944
- onEmailVerify,
5945
- onPhoneStart,
5946
- onPhoneVerify,
5947
- customAuthLabel,
5948
- onCustomAuthSignIn,
5949
- canUsePasskey = false,
5950
- passkeyAddress = null,
5951
- onPasskeySignIn
5952
- }) {
5953
- const showSocial = hasSocialMode(mode);
5954
- const showWallets = mode !== "social";
5955
- const [view, setView] = useState(showSocial ? "social" : "wallets");
5956
- const [search, setSearch] = useState("");
5957
- const [filter, setFilter] = useState("all");
5958
- const [pendingWallet, setPendingWallet] = useState(null);
5959
- const [emailStep, setEmailStep] = useState("input");
5960
- const [emailVal, setEmailVal] = useState("");
5961
- const [codeVal, setCodeVal] = useState("");
5962
- const [phoneStep, setPhoneStep] = useState("input");
5963
- const [phoneVal, setPhoneVal] = useState("");
5964
- const [phoneCode, setPhoneCode] = useState("");
5965
- const [socialLoad, setSocialLoad] = useState(false);
5966
- const [socialErr, setSocialErr] = useState("");
5967
- const [showOtherMethods, setShowOtherMethods] = useState(false);
5968
- const passkeyFirst = canUsePasskey && !!onPasskeySignIn && !showOtherMethods;
5969
- useEffect(() => {
5970
- if (!open) return;
5971
- injectFont();
5972
- injectTokens(theme);
5973
- if (theme !== "auto") return;
5974
- const mq = window.matchMedia("(prefers-color-scheme: dark)");
5975
- const handler = () => injectTokens("auto");
5976
- mq.addEventListener("change", handler);
5977
- return () => mq.removeEventListener("change", handler);
5978
- }, [open, theme]);
5979
- useEffect(() => {
5980
- if (!open) {
5981
- setSearch("");
5982
- setFilter("all");
5983
- setPendingWallet(null);
5984
- setView(showSocial ? "social" : "wallets");
5985
- setEmailStep("input");
5986
- setEmailVal("");
5987
- setCodeVal("");
5988
- setSocialErr("");
5989
- setShowOtherMethods(false);
5990
- return;
5991
- }
5992
- return () => {
5993
- document.getElementById("decane-tokens")?.remove();
5994
- };
5995
- }, [open, showWallets]);
5996
- async function handlePasskeySignIn() {
5997
- if (!onPasskeySignIn) return;
5998
- setSocialLoad(true);
5999
- setSocialErr("");
6000
- try {
6001
- await onPasskeySignIn();
6002
- } catch (e) {
6003
- const err = e;
6004
- if (err?.name !== "UserCancelledError") {
6005
- setSocialErr(err?.message ?? "Passkey sign-in failed");
6006
- setShowOtherMethods(true);
6007
- }
6008
- setSocialLoad(false);
6009
- }
6010
- }
6011
- async function handlePasskeyClick() {
6012
- void handlePasskeySignIn();
6013
- }
6014
- async function handleGoogleClick() {
6015
- if (!onGoogleSignIn) return;
6016
- setSocialLoad(true);
6017
- setSocialErr("");
6018
- try {
6019
- await onGoogleSignIn();
6020
- } catch (e) {
6021
- setSocialErr(e.message);
6022
- setSocialLoad(false);
6023
- }
6024
- }
6025
- async function handleKingsChatClick() {
6026
- if (!onKingsChatSignIn) return;
6027
- setSocialLoad(true);
6028
- setSocialErr("");
6029
- try {
6030
- await onKingsChatSignIn();
6031
- } catch (e) {
6032
- setSocialErr(e.message);
6033
- } finally {
6034
- setSocialLoad(false);
6035
- }
6036
- }
6037
- async function handleXClick() {
6038
- if (!onXSignIn) return;
6039
- setSocialLoad(true);
6040
- setSocialErr("");
6041
- try {
6042
- await onXSignIn();
6043
- } catch (e) {
6044
- setSocialErr(e.message);
6045
- setSocialLoad(false);
6046
- }
6047
- }
6048
- async function handleCustomAuthClick() {
6049
- if (!onCustomAuthSignIn) return;
6050
- setSocialLoad(true);
6051
- setSocialErr("");
6052
- try {
6053
- await onCustomAuthSignIn();
6054
- } catch (e) {
6055
- setSocialErr(e.message);
6056
- setSocialLoad(false);
6057
- }
6058
- }
6059
- async function handleEmailStart(e) {
6060
- e.preventDefault();
6061
- if (!onEmailStart) return;
6062
- setSocialLoad(true);
6063
- setSocialErr("");
6064
- try {
6065
- await onEmailStart(emailVal);
6066
- setEmailStep("code");
6067
- } catch (e2) {
6068
- setSocialErr(e2.message);
6069
- } finally {
6070
- setSocialLoad(false);
6071
- }
6072
- }
6073
- async function handleEmailVerify(e) {
6074
- e.preventDefault();
6075
- if (!onEmailVerify) return;
6076
- setSocialLoad(true);
6077
- setSocialErr("");
6078
- try {
6079
- await onEmailVerify(emailVal, codeVal);
6080
- } catch (e2) {
6081
- setSocialErr(e2.message);
6082
- } finally {
6083
- setSocialLoad(false);
6084
- }
6085
- }
6086
- async function handlePhoneStart(e) {
6087
- e.preventDefault();
6088
- if (!onPhoneStart) return;
6089
- setSocialLoad(true);
6090
- setSocialErr("");
6091
- try {
6092
- await onPhoneStart(phoneVal);
6093
- setPhoneStep("code");
6094
- } catch (e2) {
6095
- setSocialErr(e2.message);
6096
- } finally {
6097
- setSocialLoad(false);
6098
- }
6099
- }
6100
- async function handlePhoneVerify(e) {
6101
- e.preventDefault();
6102
- if (!onPhoneVerify) return;
6103
- setSocialLoad(true);
6104
- setSocialErr("");
6105
- try {
6106
- await onPhoneVerify(phoneVal, phoneCode);
6107
- } catch (e2) {
6108
- setSocialErr(e2.message);
6109
- } finally {
6110
- setSocialLoad(false);
6111
- }
6112
- }
6113
- const handleKey = useCallback(
6114
- (e) => {
6115
- if (e.key === "Escape") {
6116
- if (pendingWallet) {
6117
- setPendingWallet(null);
6118
- } else {
6119
- onClose();
6120
- }
6121
- }
6122
- },
6123
- [onClose, pendingWallet]
6124
- );
6125
- useEffect(() => {
6126
- if (!open) return;
6127
- document.addEventListener("keydown", handleKey);
6128
- return () => document.removeEventListener("keydown", handleKey);
6129
- }, [open, handleKey]);
6130
- if (!open) return null;
6131
- const q = search.toLowerCase();
6132
- const networkWallets = provider.wallets.filter((w) => {
6133
- const cs = w.chainSupport;
6134
- if (networks === "evm") return cs.includes("evm");
6135
- if (networks === "solana") return cs.includes("solana");
6136
- if (networks === "tron") return cs.includes("tron");
6137
- if (networks === "bitcoin") return cs.includes("bitcoin");
6138
- return true;
6139
- });
6140
- 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;
6141
- const filtered = q ? baseWallets.filter((w) => w.name.toLowerCase().includes(q)) : baseWallets;
6142
- function handleWalletClick(wallet) {
6143
- const cs = wallet.chainSupport;
6144
- const isMulti = cs.length >= 2;
6145
- if (isMulti && networks === "all") {
6146
- setPendingWallet(wallet);
6147
- } else {
6148
- const preference = networks === "evm" ? "evm" : networks === "solana" ? "solana" : networks === "tron" ? "tron" : networks === "bitcoin" ? "bitcoin" : void 0;
6149
- onConnect(wallet, preference);
6150
- onClose();
6151
- }
6152
- }
6153
- function handleChainChoice(preference) {
6154
- if (!pendingWallet) return;
6155
- onConnect(pendingWallet, preference);
6156
- onClose();
6157
- }
6158
- const modal = /* @__PURE__ */ React2.createElement(
6159
- "div",
6160
- {
6161
- role: "dialog",
6162
- "aria-modal": "true",
6163
- "aria-label": "Connect wallet",
6164
- style: {
6165
- position: "fixed",
6166
- inset: 0,
6167
- zIndex: 9999,
6168
- display: "flex",
6169
- alignItems: "center",
6170
- justifyContent: "center",
6171
- padding: "16px",
6172
- // Same fallback chain as SocialWalletModal — without it, this modal
6173
- // drops to the browser default serif whenever the token block hasn't
6174
- // been injected, while the social modal still lands on system-ui.
6175
- fontFamily: "var(--dc-font-sans, system-ui, sans-serif)"
6176
- }
6177
- },
6178
- /* @__PURE__ */ React2.createElement(
6179
- "div",
6180
- {
6181
- onClick: () => {
6182
- if (pendingWallet) {
6183
- setPendingWallet(null);
6184
- } else {
6185
- onClose();
6186
- }
6187
- },
6188
- style: {
6189
- position: "absolute",
6190
- inset: 0,
6191
- background: "var(--dc-bg-overlay)",
6192
- backdropFilter: "blur(8px)",
6193
- WebkitBackdropFilter: "blur(8px)"
6194
- }
6195
- }
6196
- ),
6197
- /* @__PURE__ */ React2.createElement(
6198
- "div",
6199
- {
6200
- style: {
6201
- position: "relative",
6202
- background: "var(--dc-bg)",
6203
- border: "1px solid var(--dc-border)",
6204
- borderRadius: 20,
6205
- width: "100%",
6206
- maxWidth: 400,
6207
- maxHeight: "85vh",
6208
- display: "flex",
6209
- flexDirection: "column",
6210
- boxShadow: "0 24px 64px rgba(0,0,0,0.6), 0 0 0 1px rgba(255,255,255,0.04)",
6211
- overflow: "hidden"
6212
- }
6213
- },
6214
- /* @__PURE__ */ React2.createElement(
6215
- "div",
6216
- {
6217
- style: {
6218
- height: 2,
6219
- background: "linear-gradient(90deg, transparent, var(--dc-accent) 30%, var(--dc-accent) 70%, transparent)"
6220
- }
6221
- }
6222
- ),
6223
- pendingWallet ? (
6224
- /* ── Chain picker step ───────────────────────────────────────── */
6225
- /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement("div", { style: { padding: "18px 20px 16px", display: "flex", alignItems: "center", gap: 10 } }, /* @__PURE__ */ React2.createElement(
6226
- "button",
6227
- {
6228
- onClick: () => setPendingWallet(null),
6229
- "aria-label": "Back",
6230
- style: {
6231
- background: "var(--dc-surface)",
6232
- border: "1px solid var(--dc-border)",
6233
- borderRadius: 8,
6234
- width: 28,
6235
- height: 28,
6236
- display: "flex",
6237
- alignItems: "center",
6238
- justifyContent: "center",
6239
- cursor: "pointer",
6240
- color: "var(--dc-text-muted)",
6241
- flexShrink: 0,
6242
- fontFamily: "inherit",
6243
- padding: 0
6244
- }
6245
- },
6246
- /* @__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" }))
6247
- ), /* @__PURE__ */ React2.createElement("h2", { style: { margin: 0, fontSize: 16, fontWeight: 800, color: "var(--dc-text)", letterSpacing: "-0.02em" } }, "Choose networks"), /* @__PURE__ */ React2.createElement(
6248
- "button",
6249
- {
6250
- onClick: onClose,
6251
- "aria-label": "Close",
6252
- style: {
6253
- marginLeft: "auto",
6254
- background: "var(--dc-surface)",
6255
- border: "1px solid var(--dc-border)",
6256
- borderRadius: 8,
6257
- width: 28,
6258
- height: 28,
6259
- display: "flex",
6260
- alignItems: "center",
6261
- justifyContent: "center",
6262
- cursor: "pointer",
6263
- color: "var(--dc-text-muted)",
6264
- flexShrink: 0,
6265
- fontFamily: "inherit",
6266
- padding: 0
6267
- }
6268
- },
6269
- /* @__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" }))
6270
- )), /* @__PURE__ */ React2.createElement(
6271
- "div",
6272
- {
6273
- style: {
6274
- margin: "0 20px 16px",
6275
- padding: "12px 14px",
6276
- background: "var(--dc-surface)",
6277
- border: "1px solid var(--dc-border)",
6278
- borderRadius: 12,
6279
- display: "flex",
6280
- alignItems: "center",
6281
- gap: 12
6282
- }
6283
- },
6284
- /* @__PURE__ */ React2.createElement(WalletIcon, { src: pendingWallet.icon || void 0, name: pendingWallet.name, size: 36 }),
6285
- /* @__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"))
6286
- ), /* @__PURE__ */ React2.createElement("div", { style: { padding: "0 12px 20px", display: "flex", flexDirection: "column", gap: 8 } }, pendingWallet.chainSupport.includes("evm") && /* @__PURE__ */ React2.createElement(
6287
- ChainOption,
6288
- {
6289
- label: "EVM networks",
6290
- description: "Connect your Ethereum-compatible address only",
6291
- badges: /* @__PURE__ */ React2.createElement(ChainIconStack, { support: ["evm"], size: 18 }),
6292
- onClick: () => handleChainChoice("evm")
6293
- }
6294
- ), pendingWallet.chainSupport.includes("solana") && /* @__PURE__ */ React2.createElement(
6295
- ChainOption,
6296
- {
6297
- label: "Solana network",
6298
- description: "Connect your Solana address only",
6299
- badges: /* @__PURE__ */ React2.createElement(ChainIconStack, { support: ["solana"], size: 18 }),
6300
- onClick: () => handleChainChoice("solana")
6301
- }
6302
- ), pendingWallet.chainSupport.includes("tron") && /* @__PURE__ */ React2.createElement(
6303
- ChainOption,
6304
- {
6305
- label: "Tron network",
6306
- description: "Connect your Tron address only",
6307
- badges: /* @__PURE__ */ React2.createElement(ChainIconStack, { support: ["tron"], size: 18 }),
6308
- onClick: () => handleChainChoice("tron")
6309
- }
6310
- ), pendingWallet.chainSupport.includes("bitcoin") && /* @__PURE__ */ React2.createElement(
6311
- ChainOption,
6312
- {
6313
- label: "Bitcoin network",
6314
- description: "Connect your Bitcoin address only",
6315
- badges: /* @__PURE__ */ React2.createElement(ChainIconStack, { support: ["bitcoin"], size: 18 }),
6316
- onClick: () => handleChainChoice("bitcoin")
6317
- }
6318
- ), /* @__PURE__ */ React2.createElement(
6319
- ChainOption,
6320
- {
6321
- label: "All networks",
6322
- description: "Connect all supported addresses together",
6323
- badges: /* @__PURE__ */ React2.createElement(ChainIconStack, { support: pendingWallet.chainSupport, size: 18 }),
6324
- onClick: () => handleChainChoice(void 0)
6325
- }
6326
- )))
6327
- ) : (
6328
- /* ── Wallet list / Social sign-in ────────────────────────────── */
6329
- /* @__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(
6330
- "button",
6331
- {
6332
- onClick: onClose,
6333
- "aria-label": "Close",
6334
- style: {
6335
- background: "var(--dc-surface)",
6336
- border: "1px solid var(--dc-border)",
6337
- cursor: "pointer",
6338
- padding: 0,
6339
- width: 28,
6340
- height: 28,
6341
- borderRadius: 8,
6342
- display: "flex",
6343
- alignItems: "center",
6344
- justifyContent: "center",
6345
- color: "var(--dc-text-muted)",
6346
- flexShrink: 0,
6347
- transition: "background 0.12s, color 0.12s",
6348
- fontFamily: "inherit"
6349
- },
6350
- onMouseEnter: (e) => {
6351
- e.currentTarget.style.background = "var(--dc-surface-hover)";
6352
- e.currentTarget.style.color = "var(--dc-text)";
6353
- },
6354
- onMouseLeave: (e) => {
6355
- e.currentTarget.style.background = "var(--dc-surface)";
6356
- e.currentTarget.style.color = "var(--dc-text-muted)";
6357
- }
6358
- },
6359
- /* @__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" }))
6360
- )), 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(
6361
- "button",
6362
- {
6363
- key: v,
6364
- onClick: () => setView(v),
6365
- style: {
6366
- flex: 1,
6367
- padding: "7px 0",
6368
- borderRadius: 8,
6369
- border: "none",
6370
- background: view === v ? "var(--dc-bg)" : "transparent",
6371
- color: view === v ? "var(--dc-text)" : "var(--dc-text-muted)",
6372
- fontSize: 13,
6373
- fontWeight: view === v ? 700 : 500,
6374
- cursor: "pointer",
6375
- fontFamily: "inherit",
6376
- boxShadow: view === v ? "0 1px 4px rgba(0,0,0,0.2)" : "none",
6377
- transition: "all 0.15s"
6378
- }
6379
- },
6380
- v === "wallets" ? "Wallet" : "Sign in"
6381
- ))), 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(
6382
- "svg",
6383
- {
6384
- width: "14",
6385
- height: "14",
6386
- viewBox: "0 0 14 14",
6387
- fill: "none",
6388
- style: { position: "absolute", left: 10, top: "50%", transform: "translateY(-50%)", color: "var(--dc-text-muted)", pointerEvents: "none" }
6389
- },
6390
- /* @__PURE__ */ React2.createElement("circle", { cx: "6", cy: "6", r: "4", stroke: "currentColor", strokeWidth: "1.4" }),
6391
- /* @__PURE__ */ React2.createElement("path", { d: "M9.5 9.5L12 12", stroke: "currentColor", strokeWidth: "1.4", strokeLinecap: "round" })
6392
- ), /* @__PURE__ */ React2.createElement(
6393
- "input",
6394
- {
6395
- type: "text",
6396
- placeholder: "Search wallets\u2026",
6397
- value: search,
6398
- onChange: (e) => setSearch(e.target.value),
6399
- style: {
6400
- width: "100%",
6401
- background: "var(--dc-surface)",
6402
- border: "1px solid var(--dc-border)",
6403
- borderRadius: 10,
6404
- color: "var(--dc-text)",
6405
- fontSize: 13,
6406
- padding: "8px 12px 8px 32px",
6407
- outline: "none",
6408
- fontFamily: "var(--dc-font-sans, system-ui, sans-serif)",
6409
- transition: "border-color 0.15s",
6410
- boxSizing: "border-box"
6411
- },
6412
- onFocus: (e) => {
6413
- e.currentTarget.style.borderColor = "var(--dc-border-accent)";
6414
- },
6415
- onBlur: (e) => {
6416
- e.currentTarget.style.borderColor = "var(--dc-border)";
6417
- }
6418
- }
6419
- ))), 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(
6420
- "button",
6421
- {
6422
- onClick: handlePasskeyClick,
6423
- disabled: socialLoad,
6424
- style: {
6425
- display: "flex",
6426
- alignItems: "center",
6427
- justifyContent: "center",
6428
- gap: 10,
6429
- width: "100%",
6430
- padding: "13px 16px",
6431
- background: "var(--dc-accent)",
6432
- border: "none",
6433
- borderRadius: 10,
6434
- cursor: socialLoad ? "not-allowed" : "pointer",
6435
- color: "var(--dc-accent-text)",
6436
- fontSize: 14,
6437
- fontWeight: 700,
6438
- fontFamily: "inherit",
6439
- opacity: socialLoad ? 0.6 : 1
6440
- }
6441
- },
6442
- /* @__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" })),
6443
- socialLoad ? "Verifying\u2026" : "Continue with passkey"
6444
- ), 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(
6445
- "button",
6446
- {
6447
- onClick: () => {
6448
- setShowOtherMethods(true);
6449
- setSocialErr("");
6450
- },
6451
- disabled: socialLoad,
6452
- style: {
6453
- background: "none",
6454
- border: "none",
6455
- padding: "6px 0",
6456
- color: "var(--dc-text-muted)",
6457
- fontSize: 12.5,
6458
- cursor: socialLoad ? "not-allowed" : "pointer",
6459
- fontFamily: "inherit",
6460
- textDecoration: "underline",
6461
- textUnderlineOffset: 3
6462
- }
6463
- },
6464
- "Use a different account"
6465
- )), !passkeyFirst && socialAuthMethods.includes("google") && /* @__PURE__ */ React2.createElement(
6466
- "button",
6467
- {
6468
- onClick: handleGoogleClick,
6469
- disabled: socialLoad,
6470
- style: {
6471
- display: "flex",
6472
- alignItems: "center",
6473
- justifyContent: "center",
6474
- gap: 10,
6475
- width: "100%",
6476
- padding: "11px 16px",
6477
- background: "var(--dc-surface)",
6478
- border: "1px solid var(--dc-border)",
6479
- borderRadius: 10,
6480
- cursor: socialLoad ? "not-allowed" : "pointer",
6481
- fontSize: 14,
6482
- fontWeight: 600,
6483
- color: "var(--dc-text)",
6484
- fontFamily: "inherit",
6485
- transition: "border-color 0.12s, background 0.12s",
6486
- opacity: socialLoad ? 0.6 : 1
6487
- },
6488
- onMouseEnter: (e) => {
6489
- if (!socialLoad) e.currentTarget.style.borderColor = "var(--dc-border-accent)";
6490
- },
6491
- onMouseLeave: (e) => {
6492
- e.currentTarget.style.borderColor = "var(--dc-border)";
6493
- }
6494
- },
6495
- /* @__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" })),
6496
- socialLoad ? "Redirecting\u2026" : "Continue with Google"
6497
- ), !passkeyFirst && socialAuthMethods.includes("kingschat") && onKingsChatSignIn && /* @__PURE__ */ React2.createElement(
6498
- "button",
6499
- {
6500
- onClick: handleKingsChatClick,
6501
- disabled: socialLoad,
6502
- style: {
6503
- display: "flex",
6504
- alignItems: "center",
6505
- justifyContent: "center",
6506
- gap: 10,
6507
- width: "100%",
6508
- padding: "11px 16px",
6509
- background: "var(--dc-surface)",
6510
- border: "1px solid var(--dc-border)",
6511
- borderRadius: 10,
6512
- cursor: socialLoad ? "not-allowed" : "pointer",
6513
- fontSize: 14,
6514
- fontWeight: 600,
6515
- color: "var(--dc-text)",
6516
- fontFamily: "inherit",
6517
- transition: "border-color 0.12s, background 0.12s",
6518
- opacity: socialLoad ? 0.6 : 1
6519
- },
6520
- onMouseEnter: (e) => {
6521
- if (!socialLoad) e.currentTarget.style.borderColor = "var(--dc-border-accent)";
6522
- },
6523
- onMouseLeave: (e) => {
6524
- e.currentTarget.style.borderColor = "var(--dc-border)";
6525
- }
6526
- },
6527
- /* @__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)" })),
6528
- socialLoad ? "Waiting for KingsChat\u2026" : "Continue with KingsChat"
6529
- ), !passkeyFirst && socialAuthMethods.includes("x") && onXSignIn && /* @__PURE__ */ React2.createElement(
6530
- "button",
6531
- {
6532
- onClick: handleXClick,
6533
- disabled: socialLoad,
6534
- style: {
6535
- display: "flex",
6536
- alignItems: "center",
6537
- justifyContent: "center",
6538
- gap: 10,
6539
- width: "100%",
6540
- padding: "11px 16px",
6541
- background: "var(--dc-surface)",
6542
- border: "1px solid var(--dc-border)",
6543
- borderRadius: 10,
6544
- cursor: socialLoad ? "not-allowed" : "pointer",
6545
- fontSize: 14,
6546
- fontWeight: 600,
6547
- color: "var(--dc-text)",
6548
- fontFamily: "inherit",
6549
- transition: "border-color 0.12s, background 0.12s",
6550
- opacity: socialLoad ? 0.6 : 1
6551
- },
6552
- onMouseEnter: (e) => {
6553
- if (!socialLoad) e.currentTarget.style.borderColor = "var(--dc-border-accent)";
6554
- },
6555
- onMouseLeave: (e) => {
6556
- e.currentTarget.style.borderColor = "var(--dc-border)";
6557
- }
6558
- },
6559
- /* @__PURE__ */ React2.createElement(XLogo, { size: 16 }),
6560
- socialLoad ? "Redirecting\u2026" : "Continue with X"
6561
- ), !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(
6562
- "input",
6563
- {
6564
- type: "email",
6565
- placeholder: "your@email.com",
6566
- value: emailVal,
6567
- onChange: (e) => setEmailVal(e.target.value),
6568
- required: true,
6569
- style: {
6570
- width: "100%",
6571
- padding: "10px 12px",
6572
- background: "var(--dc-surface)",
6573
- border: "1px solid var(--dc-border)",
6574
- borderRadius: 10,
6575
- color: "var(--dc-text)",
6576
- fontSize: 13,
6577
- fontFamily: "inherit",
6578
- outline: "none",
6579
- boxSizing: "border-box"
6580
- },
6581
- onFocus: (e) => {
6582
- e.currentTarget.style.borderColor = "var(--dc-border-accent)";
6583
- },
6584
- onBlur: (e) => {
6585
- e.currentTarget.style.borderColor = "var(--dc-border)";
6586
- }
6587
- }
6588
- ), /* @__PURE__ */ React2.createElement(
6589
- "button",
6590
- {
6591
- type: "submit",
6592
- disabled: socialLoad || !emailVal,
6593
- style: {
6594
- width: "100%",
6595
- padding: "10px 16px",
6596
- background: "var(--dc-accent)",
6597
- color: "var(--dc-accent-text)",
6598
- border: "none",
6599
- borderRadius: 10,
6600
- fontSize: 14,
6601
- fontWeight: 700,
6602
- cursor: socialLoad ? "not-allowed" : "pointer",
6603
- fontFamily: "inherit",
6604
- opacity: socialLoad || !emailVal ? 0.6 : 1
6605
- }
6606
- },
6607
- socialLoad ? "Sending\u2026" : "Send code"
6608
- )) : /* @__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(
6609
- "input",
6610
- {
6611
- type: "text",
6612
- placeholder: "6-digit code",
6613
- value: codeVal,
6614
- onChange: (e) => setCodeVal(e.target.value.replace(/\D/g, "").slice(0, 6)),
6615
- autoFocus: true,
6616
- required: true,
6617
- style: {
6618
- width: "100%",
6619
- padding: "10px 12px",
6620
- background: "var(--dc-surface)",
6621
- border: "1px solid var(--dc-border)",
6622
- borderRadius: 10,
6623
- color: "var(--dc-text)",
6624
- fontSize: 20,
6625
- fontFamily: "monospace",
6626
- letterSpacing: 8,
6627
- textAlign: "center",
6628
- outline: "none",
6629
- boxSizing: "border-box"
6630
- },
6631
- onFocus: (e) => {
6632
- e.currentTarget.style.borderColor = "var(--dc-border-accent)";
6633
- },
6634
- onBlur: (e) => {
6635
- e.currentTarget.style.borderColor = "var(--dc-border)";
6636
- }
6637
- }
6638
- ), /* @__PURE__ */ React2.createElement("div", { style: { display: "flex", gap: 8 } }, /* @__PURE__ */ React2.createElement(
6639
- "button",
6640
- {
6641
- type: "button",
6642
- onClick: () => {
6643
- setEmailStep("input");
6644
- setCodeVal("");
6645
- setSocialErr("");
6646
- },
6647
- style: {
6648
- flex: 1,
6649
- padding: "9px 0",
6650
- background: "transparent",
6651
- border: "1px solid var(--dc-border)",
6652
- borderRadius: 10,
6653
- color: "var(--dc-text-muted)",
6654
- fontSize: 13,
6655
- cursor: "pointer",
6656
- fontFamily: "inherit"
6657
- }
6658
- },
6659
- "Back"
6660
- ), /* @__PURE__ */ React2.createElement(
6661
- "button",
6662
- {
6663
- type: "submit",
6664
- disabled: socialLoad || codeVal.length < 6,
6665
- style: {
6666
- flex: 2,
6667
- padding: "9px 0",
6668
- background: "var(--dc-accent)",
6669
- color: "var(--dc-accent-text)",
6670
- border: "none",
6671
- borderRadius: 10,
6672
- fontSize: 13,
6673
- fontWeight: 700,
6674
- cursor: socialLoad || codeVal.length < 6 ? "not-allowed" : "pointer",
6675
- fontFamily: "inherit",
6676
- opacity: socialLoad || codeVal.length < 6 ? 0.6 : 1
6677
- }
6678
- },
6679
- socialLoad ? "Verifying\u2026" : "Verify"
6680
- )))), !passkeyFirst && socialAuthMethods.includes("phone") && onPhoneStart && onPhoneVerify && (phoneStep === "input" ? /* @__PURE__ */ React2.createElement("form", { onSubmit: handlePhoneStart, style: { display: "flex", flexDirection: "column", gap: 8 } }, /* @__PURE__ */ React2.createElement(
6681
- "input",
6682
- {
6683
- type: "tel",
6684
- placeholder: "+234 801 234 5678",
6685
- value: phoneVal,
6686
- onChange: (e) => setPhoneVal(e.target.value),
6687
- required: true,
6688
- style: {
6689
- width: "100%",
6690
- padding: "10px 12px",
6691
- background: "var(--dc-surface)",
6692
- border: "1px solid var(--dc-border)",
6693
- borderRadius: 10,
6694
- color: "var(--dc-text)",
6695
- fontSize: 13,
6696
- fontFamily: "inherit",
6697
- outline: "none",
6698
- boxSizing: "border-box"
6699
- },
6700
- onFocus: (e) => {
6701
- e.currentTarget.style.borderColor = "var(--dc-border-accent)";
6702
- },
6703
- onBlur: (e) => {
6704
- e.currentTarget.style.borderColor = "var(--dc-border)";
6705
- }
6706
- }
6707
- ), /* @__PURE__ */ React2.createElement(
6708
- "button",
6709
- {
6710
- type: "submit",
6711
- disabled: socialLoad || !phoneVal,
6712
- style: {
6713
- width: "100%",
6714
- padding: "10px 16px",
6715
- background: "var(--dc-accent)",
6716
- color: "var(--dc-accent-text)",
6717
- border: "none",
6718
- borderRadius: 10,
6719
- fontSize: 14,
6720
- fontWeight: 700,
6721
- cursor: socialLoad ? "not-allowed" : "pointer",
6722
- fontFamily: "inherit",
6723
- opacity: socialLoad || !phoneVal ? 0.6 : 1
6724
- }
6725
- },
6726
- socialLoad ? "Sending\u2026" : "Send code"
6727
- )) : /* @__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(
6728
- "input",
6729
- {
6730
- type: "text",
6731
- inputMode: "numeric",
6732
- placeholder: "6-digit code",
6733
- value: phoneCode,
6734
- onChange: (e) => setPhoneCode(e.target.value.replace(/\D/g, "").slice(0, 6)),
6735
- autoFocus: true,
6736
- required: true,
6737
- style: {
6738
- width: "100%",
6739
- padding: "10px 12px",
6740
- background: "var(--dc-surface)",
6741
- border: "1px solid var(--dc-border)",
6742
- borderRadius: 10,
6743
- color: "var(--dc-text)",
6744
- fontSize: 20,
6745
- fontFamily: "monospace",
6746
- letterSpacing: 8,
6747
- textAlign: "center",
6748
- outline: "none",
6749
- boxSizing: "border-box"
6750
- },
6751
- onFocus: (e) => {
6752
- e.currentTarget.style.borderColor = "var(--dc-border-accent)";
6753
- },
6754
- onBlur: (e) => {
6755
- e.currentTarget.style.borderColor = "var(--dc-border)";
6756
- }
6757
- }
6758
- ), /* @__PURE__ */ React2.createElement("div", { style: { display: "flex", gap: 8 } }, /* @__PURE__ */ React2.createElement(
6759
- "button",
6760
- {
6761
- type: "button",
6762
- onClick: () => {
6763
- setPhoneStep("input");
6764
- setPhoneCode("");
6765
- setSocialErr("");
6766
- },
6767
- style: {
6768
- flex: 1,
6769
- padding: "9px 0",
6770
- background: "transparent",
6771
- border: "1px solid var(--dc-border)",
6772
- borderRadius: 10,
6773
- color: "var(--dc-text-muted)",
6774
- fontSize: 13,
6775
- cursor: "pointer",
6776
- fontFamily: "inherit"
6777
- }
6778
- },
6779
- "Back"
6780
- ), /* @__PURE__ */ React2.createElement(
6781
- "button",
6782
- {
6783
- type: "submit",
6784
- disabled: socialLoad || phoneCode.length < 6,
6785
- style: {
6786
- flex: 2,
6787
- padding: "9px 0",
6788
- background: "var(--dc-accent)",
6789
- color: "var(--dc-accent-text)",
6790
- border: "none",
6791
- borderRadius: 10,
6792
- fontSize: 13,
6793
- fontWeight: 700,
6794
- cursor: socialLoad || phoneCode.length < 6 ? "not-allowed" : "pointer",
6795
- fontFamily: "inherit",
6796
- opacity: socialLoad || phoneCode.length < 6 ? 0.6 : 1
6797
- }
6798
- },
6799
- socialLoad ? "Verifying\u2026" : "Verify"
6800
- )))), !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(
6801
- "button",
6802
- {
6803
- onClick: handleCustomAuthClick,
6804
- disabled: socialLoad,
6805
- style: {
6806
- display: "flex",
6807
- alignItems: "center",
6808
- justifyContent: "center",
6809
- gap: 10,
6810
- width: "100%",
6811
- padding: "11px 16px",
6812
- background: "var(--dc-surface)",
6813
- border: "1px solid var(--dc-border)",
6814
- borderRadius: 10,
6815
- cursor: socialLoad ? "not-allowed" : "pointer",
6816
- fontSize: 14,
6817
- fontWeight: 600,
6818
- color: "var(--dc-text)",
6819
- fontFamily: "inherit",
6820
- transition: "border-color 0.12s, background 0.12s",
6821
- opacity: socialLoad ? 0.6 : 1
6822
- },
6823
- onMouseEnter: (e) => {
6824
- if (!socialLoad) e.currentTarget.style.borderColor = "var(--dc-border-accent)";
6825
- },
6826
- onMouseLeave: (e) => {
6827
- e.currentTarget.style.borderColor = "var(--dc-border)";
6828
- }
6829
- },
6830
- socialLoad ? "Connecting\u2026" : customAuthLabel
6831
- ))), 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"))
6832
- )
6833
- )
6834
- );
6835
- return createPortal(modal, document.body);
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" }));
6836
5812
  }
6837
5813
 
6838
5814
  // src/ui/SocialWalletModal.tsx
6839
- import React3, { useCallback as useCallback2, useEffect as useEffect2, useState as useState2 } from "react";
6840
- import { createPortal as createPortal2 } from "react-dom";
6841
- function injectTokens2(theme) {
5815
+ import React2, { useCallback, useEffect, useState } from "react";
5816
+ import { createPortal } from "react-dom";
5817
+ function injectTokens(theme) {
6842
5818
  const resolved = theme === "auto" ? window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light" : theme;
6843
5819
  let el = document.getElementById("decane-tokens");
6844
5820
  if (!el) {
@@ -6862,8 +5838,8 @@ function downloadJson(data, filename) {
6862
5838
  URL.revokeObjectURL(url);
6863
5839
  }
6864
5840
  function useBalance(kind, address, chain, rpcUrls) {
6865
- const [state, setState] = useState2({ loading: false, value: null, symbol: kind === "evm" ? "ETH" : "SOL" });
6866
- useEffect2(() => {
5841
+ const [state, setState] = useState({ loading: false, value: null, symbol: kind === "evm" ? "ETH" : "SOL" });
5842
+ useEffect(() => {
6867
5843
  if (!address || !chain) return;
6868
5844
  let cancelled = false;
6869
5845
  setState((s) => ({ ...s, loading: true }));
@@ -6967,6 +5943,33 @@ var MODAL_CSS = `
6967
5943
  .dcm-row { display: flex; gap: 8px; width: 100%; }
6968
5944
  .dcm-row > .dcm-primary { flex: 1; height: 44px; border-radius: 12px; }
6969
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); }
6970
5973
  .dcm-actions > * { flex: 1; }
6971
5974
  `;
6972
5975
  function injectModalCss() {
@@ -6980,14 +5983,14 @@ function shortAddress(a, head = 6, tail = 4) {
6980
5983
  return a.length > head + tail + 1 ? `${a.slice(0, head)}\u2026${a.slice(-tail)}` : a;
6981
5984
  }
6982
5985
  function CopyButton({ value, label }) {
6983
- const [copied, setCopied] = useState2(false);
5986
+ const [copied, setCopied] = useState(false);
6984
5987
  async function copy() {
6985
5988
  await navigator.clipboard.writeText(value).catch(() => {
6986
5989
  });
6987
5990
  setCopied(true);
6988
5991
  setTimeout(() => setCopied(false), 1500);
6989
5992
  }
6990
- return /* @__PURE__ */ React3.createElement("button", { type: "button", className: "dcm-copy", onClick: copy, "aria-label": copied ? "Copied" : `Copy ${label} address`, title: copied ? "Copied" : "Copy address" }, copied ? /* @__PURE__ */ React3.createElement(CheckIcon, null) : /* @__PURE__ */ React3.createElement(CopyIcon, null));
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));
6991
5994
  }
6992
5995
  function AddressRow({
6993
5996
  label,
@@ -6997,10 +6000,10 @@ function AddressRow({
6997
6000
  rpcUrls
6998
6001
  }) {
6999
6002
  const balance = useBalance(kind, address, chain, rpcUrls);
7000
- return /* @__PURE__ */ React3.createElement("div", { className: "dcm-address" }, /* @__PURE__ */ React3.createElement("div", { className: "dcm-address-main" }, /* @__PURE__ */ React3.createElement("span", null, label), /* @__PURE__ */ React3.createElement("code", { title: address }, shortAddress(address, 8, 6))), /* @__PURE__ */ React3.createElement("span", { className: "dcm-balance" }, balance.loading ? "\u2026" : `${formatBalanceDisplay(balance.value)} ${balance.symbol}`), /* @__PURE__ */ React3.createElement(CopyButton, { value: address, label }));
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 }));
7001
6004
  }
7002
6005
  function ProtectedBy() {
7003
- return /* @__PURE__ */ React3.createElement("div", { className: "dcm-protected" }, /* @__PURE__ */ React3.createElement("span", null, "Protected by"), /* @__PURE__ */ React3.createElement(DecaneMark, { size: 14, muted: true }), /* @__PURE__ */ React3.createElement(DecaneWordmark, { size: 12, muted: true }));
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 }));
7004
6007
  }
7005
6008
  function SignInView({
7006
6009
  onGoogleSignIn,
@@ -7016,23 +6019,24 @@ function SignInView({
7016
6019
  onCustomAuthSignIn,
7017
6020
  canUsePasskey,
7018
6021
  passkeyAddress,
7019
- onPasskeySignIn
6022
+ onPasskeySignIn,
6023
+ extra
7020
6024
  }) {
7021
- const [googleLoading, setGoogleLoading] = useState2(false);
7022
- const [kingsChatLoading, setKingsChatLoading] = useState2(false);
7023
- const [xLoading, setXLoading] = useState2(false);
7024
- const [email, setEmail] = useState2("");
7025
- const [code, setCode] = useState2("");
7026
- const [emailSent, setEmailSent] = useState2(false);
7027
- const [emailLoading, setEmailLoading] = useState2(false);
7028
- const [phone, setPhone] = useState2("");
7029
- const [phoneCode, setPhoneCode] = useState2("");
7030
- const [phoneSent, setPhoneSent] = useState2(false);
7031
- const [phoneLoading, setPhoneLoading] = useState2(false);
7032
- const [customLoading, setCustomLoading] = useState2(false);
7033
- const [passkeyLoading, setPasskeyLoading] = useState2(false);
7034
- const [showOtherMethods, setShowOtherMethods] = useState2(false);
7035
- const [error, setError] = useState2("");
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("");
6033
+ const [phoneCode, setPhoneCode] = 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);
6038
+ const [showOtherMethods, setShowOtherMethods] = useState(false);
6039
+ const [error, setError] = useState("");
7036
6040
  const passkeyFirst = !!canUsePasskey && !!onPasskeySignIn && !showOtherMethods;
7037
6041
  const busy = googleLoading || kingsChatLoading || xLoading || customLoading || emailLoading || phoneLoading;
7038
6042
  async function handlePasskey() {
@@ -7154,19 +6158,19 @@ function SignInView({
7154
6158
  setPhoneCode("");
7155
6159
  setError("");
7156
6160
  }
7157
- const errorLine = error ? /* @__PURE__ */ React3.createElement("p", { className: "dcm-error", role: "alert" }, error) : null;
6161
+ const errorLine = error ? /* @__PURE__ */ React2.createElement("p", { className: "dcm-error", role: "alert" }, error) : null;
7158
6162
  if (passkeyFirst) {
7159
- return /* @__PURE__ */ React3.createElement("div", { className: "dcm-body" }, /* @__PURE__ */ React3.createElement("div", { className: "dcm-badge" }, /* @__PURE__ */ React3.createElement(KeyIcon, { size: 22 })), /* @__PURE__ */ React3.createElement("h2", { className: "dcm-title" }, "Welcome back"), /* @__PURE__ */ React3.createElement("p", { className: "dcm-sub" }, passkeyAddress ? /* @__PURE__ */ React3.createElement(React3.Fragment, null, "Unlock ", /* @__PURE__ */ React3.createElement("b", null, shortAddress(passkeyAddress)), " with your passkey.") : "Unlock your wallet with your passkey."), /* @__PURE__ */ React3.createElement("button", { type: "button", className: "dcm-primary", onClick: handlePasskey, disabled: passkeyLoading }, passkeyLoading ? "Waiting for passkey\u2026" : "Continue with passkey"), errorLine, /* @__PURE__ */ React3.createElement("button", { type: "button", className: "dcm-link", onClick: () => {
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: () => {
7160
6164
  setError("");
7161
6165
  setShowOtherMethods(true);
7162
- } }, "Use another sign-in method"), /* @__PURE__ */ React3.createElement(ProtectedBy, null));
6166
+ } }, "Use another sign-in method"), /* @__PURE__ */ React2.createElement(ProtectedBy, null));
7163
6167
  }
7164
6168
  if (emailSent || phoneSent) {
7165
6169
  const isEmail = emailSent;
7166
6170
  const value = isEmail ? code : phoneCode;
7167
6171
  const setValue = isEmail ? setCode : setPhoneCode;
7168
6172
  const loading = isEmail ? emailLoading : phoneLoading;
7169
- return /* @__PURE__ */ React3.createElement("form", { className: "dcm-body", onSubmit: isEmail ? handleEmailVerify : handlePhoneVerify }, /* @__PURE__ */ React3.createElement("div", { className: "dcm-badge" }, isEmail ? /* @__PURE__ */ React3.createElement(MailIcon, { size: 22 }) : /* @__PURE__ */ React3.createElement(PhoneIcon, { size: 22 })), /* @__PURE__ */ React3.createElement("h2", { className: "dcm-title" }, "Enter your code"), /* @__PURE__ */ React3.createElement("p", { className: "dcm-sub" }, "We sent a 6-digit code to ", /* @__PURE__ */ React3.createElement("b", null, isEmail ? email.trim() : phone.trim())), /* @__PURE__ */ React3.createElement("div", { className: "dcm-form" }, /* @__PURE__ */ React3.createElement(
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(
7170
6174
  "input",
7171
6175
  {
7172
6176
  className: "dcm-field dcm-code",
@@ -7179,10 +6183,10 @@ function SignInView({
7179
6183
  autoComplete: "one-time-code",
7180
6184
  onChange: (e) => setValue(e.target.value.replace(/\D/g, ""))
7181
6185
  }
7182
- ), /* @__PURE__ */ React3.createElement("button", { type: "submit", className: "dcm-primary", disabled: loading || value.length < 6 }, loading ? "Verifying\u2026" : "Continue")), errorLine, /* @__PURE__ */ React3.createElement("button", { type: "button", className: "dcm-link", onClick: backToMethods }, "Use a different method"), /* @__PURE__ */ React3.createElement(ProtectedBy, null));
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));
7183
6187
  }
7184
6188
  const showPhone = authMethods.includes("phone") && !!onPhoneStart && !!onPhoneVerify;
7185
- return /* @__PURE__ */ React3.createElement("div", { className: "dcm-body" }, /* @__PURE__ */ React3.createElement(DecaneMark, { size: 44 }), /* @__PURE__ */ React3.createElement("h2", { className: "dcm-title" }, resumeHint ? "Welcome back" : "Log in or sign up"), resumeHint && /* @__PURE__ */ React3.createElement("p", { className: "dcm-sub" }, "Sign in again to resume ", resumeHint, "."), /* @__PURE__ */ React3.createElement("div", { className: "dcm-methods" }, authMethods.includes("google") && /* @__PURE__ */ React3.createElement("button", { type: "button", className: "dcm-method", onClick: handleGoogle, disabled: busy }, /* @__PURE__ */ React3.createElement(GoogleMark, { size: 18 }), /* @__PURE__ */ React3.createElement("span", null, googleLoading ? "Redirecting to Google\u2026" : "Google")), authMethods.includes("email") && /* @__PURE__ */ React3.createElement("form", { className: "dcm-method dcm-method-input", onSubmit: handleEmailStart }, /* @__PURE__ */ React3.createElement(MailIcon, { size: 18 }), /* @__PURE__ */ React3.createElement(
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(
7186
6190
  "input",
7187
6191
  {
7188
6192
  type: "email",
@@ -7193,7 +6197,7 @@ function SignInView({
7193
6197
  value: email,
7194
6198
  onChange: (e) => setEmail(e.target.value)
7195
6199
  }
7196
- ), /* @__PURE__ */ React3.createElement("button", { type: "submit", className: "dcm-submit", disabled: busy || !email.trim() }, emailLoading ? "Sending\u2026" : "Submit")), showPhone && /* @__PURE__ */ React3.createElement("form", { className: "dcm-method dcm-method-input", onSubmit: handlePhoneStart }, /* @__PURE__ */ React3.createElement(PhoneIcon, { size: 18 }), /* @__PURE__ */ React3.createElement(
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(
7197
6201
  "input",
7198
6202
  {
7199
6203
  type: "tel",
@@ -7204,24 +6208,24 @@ function SignInView({
7204
6208
  value: phone,
7205
6209
  onChange: (e) => setPhone(e.target.value)
7206
6210
  }
7207
- ), /* @__PURE__ */ React3.createElement("button", { type: "submit", className: "dcm-submit", disabled: busy || !phone.trim() }, phoneLoading ? "Sending\u2026" : "Submit")), authMethods.includes("x") && onXSignIn && /* @__PURE__ */ React3.createElement("button", { type: "button", className: "dcm-method", onClick: handleX, disabled: busy }, /* @__PURE__ */ React3.createElement(XLogo, { size: 16 }), /* @__PURE__ */ React3.createElement("span", null, xLoading ? "Redirecting to X\u2026" : "X")), authMethods.includes("kingschat") && onKingsChatSignIn && /* @__PURE__ */ React3.createElement("button", { type: "button", className: "dcm-method", onClick: handleKingsChat, disabled: busy }, /* @__PURE__ */ React3.createElement(ChatIcon, { size: 18 }), /* @__PURE__ */ React3.createElement("span", null, kingsChatLoading ? "Waiting for KingsChat\u2026" : "KingsChat")), customAuthLabel && onCustomAuthSignIn && /* @__PURE__ */ React3.createElement("button", { type: "button", className: "dcm-method", onClick: handleCustomAuth, disabled: busy }, /* @__PURE__ */ React3.createElement(UserIcon, { size: 18 }), /* @__PURE__ */ React3.createElement("span", null, customLoading ? "Connecting\u2026" : customAuthLabel))), errorLine, canUsePasskey && onPasskeySignIn && /* @__PURE__ */ React3.createElement("button", { type: "button", className: "dcm-link", onClick: () => {
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: () => {
7208
6212
  setError("");
7209
6213
  setShowOtherMethods(false);
7210
- } }, "Use my passkey instead"), /* @__PURE__ */ React3.createElement(ProtectedBy, null));
6214
+ } }, "Use my passkey instead"), /* @__PURE__ */ React2.createElement(ProtectedBy, null));
7211
6215
  }
7212
6216
  function RecoverySection({
7213
6217
  addresses,
7214
6218
  onRotateShares,
7215
6219
  onExportPortableBackup
7216
6220
  }) {
7217
- const [expanded, setExpanded] = useState2(false);
7218
- const [mode, setMode] = useState2(null);
7219
- const [password, setPassword] = useState2("");
7220
- const [passwordHint, setPasswordHint] = useState2("");
7221
- const [confirmed, setConfirmed] = useState2(false);
7222
- const [busy, setBusy] = useState2(false);
7223
- const [result, setResult] = useState2(null);
7224
- 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("");
7225
6229
  function reset() {
7226
6230
  setMode(null);
7227
6231
  setPassword("");
@@ -7258,7 +6262,7 @@ function RecoverySection({
7258
6262
  setBusy(false);
7259
6263
  }
7260
6264
  }
7261
- const passwordFields = /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement(
6265
+ const passwordFields = /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement(
7262
6266
  "input",
7263
6267
  {
7264
6268
  className: "dcm-field",
@@ -7269,7 +6273,7 @@ function RecoverySection({
7269
6273
  value: password,
7270
6274
  onChange: (e) => setPassword(e.target.value)
7271
6275
  }
7272
- ), /* @__PURE__ */ React3.createElement(
6276
+ ), /* @__PURE__ */ React2.createElement(
7273
6277
  "input",
7274
6278
  {
7275
6279
  className: "dcm-field",
@@ -7278,14 +6282,14 @@ function RecoverySection({
7278
6282
  value: passwordHint,
7279
6283
  onChange: (e) => setPasswordHint(e.target.value)
7280
6284
  }
7281
- ), error && /* @__PURE__ */ React3.createElement("p", { className: "dcm-error", role: "alert" }, error));
7282
- return /* @__PURE__ */ React3.createElement("div", { className: "dcm-panel" }, /* @__PURE__ */ React3.createElement("button", { type: "button", className: "dcm-panel-head", onClick: () => setExpanded((v) => !v), "aria-expanded": expanded }, /* @__PURE__ */ React3.createElement("span", null, "Recovery file"), /* @__PURE__ */ React3.createElement(ChevronIcon, { open: expanded })), expanded && /* @__PURE__ */ React3.createElement("div", { className: "dcm-panel-body" }, !mode && /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement("p", { className: "dcm-note" }, "Save a recovery file so you can restore this wallet on a new device."), /* @__PURE__ */ React3.createElement("button", { type: "button", className: "dcm-primary", style: { height: 44, borderRadius: 12 }, onClick: () => {
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: () => {
7283
6287
  reset();
7284
6288
  setMode("share");
7285
- } }, "Download recovery-share file"), /* @__PURE__ */ React3.createElement("button", { type: "button", className: "dcm-ghost", onClick: () => {
6289
+ } }, "Download recovery-share file"), /* @__PURE__ */ React2.createElement("button", { type: "button", className: "dcm-ghost", onClick: () => {
7286
6290
  reset();
7287
6291
  setMode("portable");
7288
- } }, "Download full recovery file")), mode === "share" && /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.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__ */ React3.createElement("div", { className: "dcm-row" }, /* @__PURE__ */ React3.createElement("button", { type: "button", className: "dcm-primary", onClick: handleGenerate, disabled: busy }, busy ? "Preparing\u2026" : "Download"), /* @__PURE__ */ React3.createElement("button", { type: "button", className: "dcm-ghost", onClick: reset }, "Cancel"))), mode === "portable" && /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement("div", { className: "dcm-warn" }, /* @__PURE__ */ React3.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__ */ React3.createElement("label", { className: "dcm-check" }, /* @__PURE__ */ React3.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__ */ React3.createElement("div", { className: "dcm-row" }, /* @__PURE__ */ React3.createElement("button", { type: "button", className: "dcm-primary", onClick: handleGenerate, disabled: busy || !confirmed }, busy ? "Preparing\u2026" : "Download"), /* @__PURE__ */ React3.createElement("button", { type: "button", className: "dcm-ghost", onClick: reset }, "Cancel"))), result && /* @__PURE__ */ React3.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.")));
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.")));
7289
6293
  }
7290
6294
  function SocialWalletModal({
7291
6295
  open,
@@ -7312,21 +6316,21 @@ function SocialWalletModal({
7312
6316
  rpcUrls,
7313
6317
  chains
7314
6318
  }) {
7315
- const [timer, setTimer] = useState2("");
7316
- const [unlocking, setUnlocking] = useState2(false);
7317
- const [disconnecting, setDisconnecting] = useState2(false);
7318
- const [actionError, setActionError] = useState2("");
7319
- 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(() => {
7320
6324
  if (!open) return;
7321
- injectTokens2(theme);
6325
+ injectTokens(theme);
7322
6326
  injectModalCss();
7323
6327
  if (theme !== "auto") return;
7324
6328
  const mq = window.matchMedia("(prefers-color-scheme: dark)");
7325
- const h = () => injectTokens2("auto");
6329
+ const h = () => injectTokens("auto");
7326
6330
  mq.addEventListener("change", h);
7327
6331
  return () => mq.removeEventListener("change", h);
7328
6332
  }, [open, theme]);
7329
- useEffect2(() => {
6333
+ useEffect(() => {
7330
6334
  if (!socialAuth.sessionExpiresAt) {
7331
6335
  setTimer("");
7332
6336
  return;
@@ -7335,10 +6339,10 @@ function SocialWalletModal({
7335
6339
  const id = setInterval(() => setTimer(countdown(socialAuth.sessionExpiresAt)), 1e3);
7336
6340
  return () => clearInterval(id);
7337
6341
  }, [socialAuth.sessionExpiresAt]);
7338
- const handleKey = useCallback2((e) => {
6342
+ const handleKey = useCallback((e) => {
7339
6343
  if (e.key === "Escape") onClose();
7340
6344
  }, [onClose]);
7341
- useEffect2(() => {
6345
+ useEffect(() => {
7342
6346
  if (!open) return;
7343
6347
  document.addEventListener("keydown", handleKey);
7344
6348
  return () => document.removeEventListener("keydown", handleKey);
@@ -7371,7 +6375,7 @@ function SocialWalletModal({
7371
6375
  const solChain = chains?.find((c) => c.startsWith("solana:")) ?? "solana:mainnet";
7372
6376
  const showSignIn = !socialAuth.addresses || socialAuth.needsReconnect;
7373
6377
  const unlocked = socialAuth.isUnlocked;
7374
- const modal = /* @__PURE__ */ React3.createElement(
6378
+ const modal = /* @__PURE__ */ React2.createElement(
7375
6379
  "div",
7376
6380
  {
7377
6381
  role: "dialog",
@@ -7389,8 +6393,8 @@ function SocialWalletModal({
7389
6393
  WebkitFontSmoothing: "antialiased"
7390
6394
  }
7391
6395
  },
7392
- /* @__PURE__ */ React3.createElement("div", { className: "dcm-backdrop", onClick: onClose }),
7393
- /* @__PURE__ */ React3.createElement("div", { className: "dcm-card" }, /* @__PURE__ */ React3.createElement("button", { type: "button", className: "dcm-icon-btn", style: { right: 14 }, onClick: onClose, "aria-label": "Close" }, /* @__PURE__ */ React3.createElement(CloseIcon, null)), 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(
7394
6398
  SignInView,
7395
6399
  {
7396
6400
  onGoogleSignIn,
@@ -7408,22 +6412,238 @@ function SocialWalletModal({
7408
6412
  passkeyAddress,
7409
6413
  onPasskeySignIn
7410
6414
  }
7411
- ) : /* @__PURE__ */ React3.createElement("div", { className: "dcm-body" }, /* @__PURE__ */ React3.createElement(DecaneMark, { size: 44 }), /* @__PURE__ */ React3.createElement("h2", { className: "dcm-title" }, "Your wallet"), /* @__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(
7412
6416
  "span",
7413
6417
  {
7414
6418
  className: "dcm-status",
7415
6419
  style: { color: unlocked ? "#12b76a" : "var(--dc-accent-ink)", marginTop: -8 }
7416
6420
  },
7417
- /* @__PURE__ */ React3.createElement("i", { style: { background: unlocked ? "#12b76a" : "var(--dc-accent)" } }),
6421
+ /* @__PURE__ */ React2.createElement("i", { style: { background: unlocked ? "#12b76a" : "var(--dc-accent)" } }),
7418
6422
  unlocked ? timer ? `Unlocked, expires in ${timer}` : "Unlocked" : "Locked"
7419
- ), (socialAuth.addresses?.evm || socialAuth.addresses?.solana) && /* @__PURE__ */ React3.createElement("div", { className: "dcm-addresses" }, socialAuth.addresses?.evm && /* @__PURE__ */ React3.createElement(AddressRow, { label: "Ethereum and EVM", 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 })), unlocked && /* @__PURE__ */ React3.createElement(
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(
7420
6424
  RecoverySection,
7421
6425
  {
7422
6426
  addresses: socialAuth.addresses,
7423
6427
  onRotateShares,
7424
6428
  onExportPortableBackup
7425
6429
  }
7426
- ), actionError && /* @__PURE__ */ React3.createElement("p", { className: "dcm-error", role: "alert" }, actionError), /* @__PURE__ */ React3.createElement("div", { className: "dcm-actions" }, !unlocked && /* @__PURE__ */ React3.createElement("button", { type: "button", className: "dcm-primary", style: { height: 44, borderRadius: 12 }, onClick: handleUnlock, disabled: unlocking }, unlocking ? "Unlocking\u2026" : "Unlock wallet"), /* @__PURE__ */ React3.createElement("button", { type: "button", className: "dcm-ghost", onClick: handleDisconnect, disabled: disconnecting }, disconnecting ? "Signing out\u2026" : "Sign out")), /* @__PURE__ */ React3.createElement(ProtectedBy, null)))
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",
6587
+ {
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,
6599
+ {
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)
7427
6647
  );
7428
6648
  return createPortal2(modal, document.body);
7429
6649
  }
@@ -7592,6 +6812,7 @@ function DecaneKit({ config, children }) {
7592
6812
  protection,
7593
6813
  deferDeviceProtection,
7594
6814
  resumeSessionAcrossTabs,
6815
+ sessionDurationMinutes,
7595
6816
  // Recovery callbacks. Forwarding these is what makes recovery
7596
6817
  // configurable at all from <DecaneKit>; before, they were silently
7597
6818
  // dropped and the headless client was constructed without them.
@@ -7615,6 +6836,7 @@ function DecaneKit({ config, children }) {
7615
6836
  protection,
7616
6837
  deferDeviceProtection,
7617
6838
  resumeSessionAcrossTabs,
6839
+ sessionDurationMinutes,
7618
6840
  offerRecoveryAtSignup,
7619
6841
  onRecoveryShareOffer,
7620
6842
  onRecoveryFileReady,