decane-connect-kit 2.28.0 → 2.29.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -5519,6 +5519,7 @@ var tokens = {
5519
5519
  accent: "#F5C800",
5520
5520
  accentHover: "#D4A800",
5521
5521
  accentText: "#0D0D0B",
5522
+ accentInk: "#7A5F00",
5522
5523
  badgeEvm: "#1A1917",
5523
5524
  badgeEvmText: "#F5C800",
5524
5525
  badgeSolana: "#F5C800",
@@ -5539,6 +5540,7 @@ var tokens = {
5539
5540
  accent: "#F5C800",
5540
5541
  accentHover: "#FFE04D",
5541
5542
  accentText: "#0D0D0B",
5543
+ accentInk: "#F5C800",
5542
5544
  badgeEvm: "#F5C800",
5543
5545
  badgeEvmText: "#0D0D0B",
5544
5546
  badgeSolana: "#1A1917",
@@ -5564,6 +5566,7 @@ var CSS_VARS = {
5564
5566
  --dc-accent: ${tokens.light.accent};
5565
5567
  --dc-accent-hover: ${tokens.light.accentHover};
5566
5568
  --dc-accent-text: ${tokens.light.accentText};
5569
+ --dc-accent-ink: ${tokens.light.accentInk};
5567
5570
  --dc-badge-evm: ${tokens.light.badgeEvm};
5568
5571
  --dc-badge-evm-text: ${tokens.light.badgeEvmText};
5569
5572
  --dc-badge-sol: ${tokens.light.badgeSolana};
@@ -5585,6 +5588,7 @@ var CSS_VARS = {
5585
5588
  --dc-accent: ${tokens.dark.accent};
5586
5589
  --dc-accent-hover: ${tokens.dark.accentHover};
5587
5590
  --dc-accent-text: ${tokens.dark.accentText};
5591
+ --dc-accent-ink: ${tokens.dark.accentInk};
5588
5592
  --dc-badge-evm: ${tokens.dark.badgeEvm};
5589
5593
  --dc-badge-evm-text: ${tokens.dark.badgeEvmText};
5590
5594
  --dc-badge-sol: ${tokens.dark.badgeSolana};
@@ -5746,6 +5750,54 @@ function XLogo({ size = 14 }) {
5746
5750
  /* @__PURE__ */ React.createElement("path", { d: "M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z" })
5747
5751
  );
5748
5752
  }
5753
+ var line = {
5754
+ fill: "none",
5755
+ stroke: "currentColor",
5756
+ strokeWidth: 1.8,
5757
+ strokeLinecap: "round",
5758
+ strokeLinejoin: "round"
5759
+ };
5760
+ function GoogleMark({ size = 18 }) {
5761
+ return /* @__PURE__ */ React.createElement("svg", { width: size, height: size, viewBox: "0 0 48 48", "aria-hidden": "true", style: { flexShrink: 0 } }, /* @__PURE__ */ React.createElement("path", { fill: "#EA4335", d: "M24 9.5c3.5 0 6 1.5 7.4 2.8l5.4-5.3C33.5 3.9 29.2 2 24 2 15.4 2 8 7 4.7 14.2l6.3 4.9C12.6 13.4 17.8 9.5 24 9.5z" }), /* @__PURE__ */ React.createElement("path", { fill: "#4285F4", d: "M46 24.5c0-1.6-.1-2.8-.4-4H24v7.5h12.6c-.3 2.2-1.7 5.5-4.9 7.7l6.1 4.7C41.5 37 46 31.4 46 24.5z" }), /* @__PURE__ */ React.createElement("path", { fill: "#FBBC05", d: "M11 29.1a13.9 13.9 0 0 1 0-10l-6.3-4.9A22 22 0 0 0 2 24c0 3.5.8 6.9 2.4 9.8L11 29.1z" }), /* @__PURE__ */ React.createElement("path", { fill: "#34A853", d: "M24 46c5.9 0 10.9-2 14.5-5.4l-6.1-4.7c-1.7 1.2-4 2-8.4 2-6.2 0-11.4-4-13.1-9.6l-6.3 4.9C7.9 40.9 15.3 46 24 46z" }));
5762
+ }
5763
+ function MailIcon({ size = 18 }) {
5764
+ return /* @__PURE__ */ React.createElement("svg", { width: size, height: size, viewBox: "0 0 24 24", ...line, "aria-hidden": "true", style: { flexShrink: 0 } }, /* @__PURE__ */ React.createElement("rect", { x: "3", y: "5", width: "18", height: "14", rx: "2.5" }), /* @__PURE__ */ React.createElement("path", { d: "m3.5 7 8.5 6 8.5-6" }));
5765
+ }
5766
+ function PhoneIcon({ size = 18 }) {
5767
+ return /* @__PURE__ */ React.createElement("svg", { width: size, height: size, viewBox: "0 0 24 24", ...line, "aria-hidden": "true", style: { flexShrink: 0 } }, /* @__PURE__ */ React.createElement("rect", { x: "7", y: "2.5", width: "10", height: "19", rx: "2.5" }), /* @__PURE__ */ React.createElement("path", { d: "M11 18h2" }));
5768
+ }
5769
+ function ChatIcon({ size = 18 }) {
5770
+ return /* @__PURE__ */ React.createElement("svg", { width: size, height: size, viewBox: "0 0 24 24", ...line, "aria-hidden": "true", style: { flexShrink: 0 } }, /* @__PURE__ */ React.createElement("path", { d: "M4 6.5A2.5 2.5 0 0 1 6.5 4h11A2.5 2.5 0 0 1 20 6.5v7a2.5 2.5 0 0 1-2.5 2.5H10l-4.2 3.2a.6.6 0 0 1-1-.5V16A2.5 2.5 0 0 1 4 13.5z" }), /* @__PURE__ */ React.createElement("path", { d: "M8.5 9h7M8.5 12.5h4.5" }));
5771
+ }
5772
+ function KeyIcon({ size = 18 }) {
5773
+ return /* @__PURE__ */ React.createElement("svg", { width: size, height: size, viewBox: "0 0 24 24", ...line, "aria-hidden": "true", style: { flexShrink: 0 } }, /* @__PURE__ */ React.createElement("circle", { cx: "8", cy: "12", r: "4" }), /* @__PURE__ */ React.createElement("path", { d: "M12 12h9M18 12v3M15 12v2.5" }));
5774
+ }
5775
+ function UserIcon({ size = 18 }) {
5776
+ return /* @__PURE__ */ React.createElement("svg", { width: size, height: size, viewBox: "0 0 24 24", ...line, "aria-hidden": "true", style: { flexShrink: 0 } }, /* @__PURE__ */ React.createElement("circle", { cx: "12", cy: "8.5", r: "3.8" }), /* @__PURE__ */ React.createElement("path", { d: "M4.5 20a7.5 7.5 0 0 1 15 0" }));
5777
+ }
5778
+ function CopyIcon({ size = 15 }) {
5779
+ return /* @__PURE__ */ React.createElement("svg", { width: size, height: size, viewBox: "0 0 24 24", ...line, "aria-hidden": "true", style: { flexShrink: 0 } }, /* @__PURE__ */ React.createElement("rect", { x: "8.5", y: "8.5", width: "12", height: "12", rx: "2.5" }), /* @__PURE__ */ React.createElement("path", { d: "M15.5 8.5V6A2.5 2.5 0 0 0 13 3.5H6A2.5 2.5 0 0 0 3.5 6v7A2.5 2.5 0 0 0 6 15.5h2.5" }));
5780
+ }
5781
+ function CheckIcon({ size = 15 }) {
5782
+ return /* @__PURE__ */ React.createElement("svg", { width: size, height: size, viewBox: "0 0 24 24", ...line, "aria-hidden": "true", style: { flexShrink: 0 } }, /* @__PURE__ */ React.createElement("path", { d: "m5 12.5 4.5 4.5L19 7.5" }));
5783
+ }
5784
+ function CloseIcon({ size = 16 }) {
5785
+ return /* @__PURE__ */ React.createElement("svg", { width: size, height: size, viewBox: "0 0 24 24", ...line, "aria-hidden": "true", style: { flexShrink: 0 } }, /* @__PURE__ */ React.createElement("path", { d: "M6 6l12 12M18 6 6 18" }));
5786
+ }
5787
+ function ChevronIcon({ size = 16, open = false }) {
5788
+ return /* @__PURE__ */ React.createElement(
5789
+ "svg",
5790
+ {
5791
+ width: size,
5792
+ height: size,
5793
+ viewBox: "0 0 24 24",
5794
+ ...line,
5795
+ "aria-hidden": "true",
5796
+ style: { flexShrink: 0, transition: "transform .2s", transform: open ? "rotate(180deg)" : "none" }
5797
+ },
5798
+ /* @__PURE__ */ React.createElement("path", { d: "m6 9 6 6 6-6" })
5799
+ );
5800
+ }
5749
5801
 
5750
5802
  // src/ui/WalletSelector.tsx
5751
5803
  var FONT_URL = "https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&display=swap";
@@ -6809,33 +6861,6 @@ function downloadJson(data, filename) {
6809
6861
  a.click();
6810
6862
  URL.revokeObjectURL(url);
6811
6863
  }
6812
- function CopyButton({ value }) {
6813
- const [copied, setCopied] = useState2(false);
6814
- async function copy() {
6815
- await navigator.clipboard.writeText(value).catch(() => {
6816
- });
6817
- setCopied(true);
6818
- setTimeout(() => setCopied(false), 1500);
6819
- }
6820
- return /* @__PURE__ */ React3.createElement(
6821
- "button",
6822
- {
6823
- onClick: copy,
6824
- style: {
6825
- background: "none",
6826
- border: "none",
6827
- cursor: "pointer",
6828
- color: copied ? "var(--dc-accent)" : "var(--dc-text-muted)",
6829
- fontSize: 11,
6830
- fontFamily: "inherit",
6831
- padding: "2px 6px",
6832
- borderRadius: 5,
6833
- transition: "color 0.15s"
6834
- }
6835
- },
6836
- copied ? "\u2713" : "copy"
6837
- );
6838
- }
6839
6864
  function useBalance(kind, address, chain, rpcUrls) {
6840
6865
  const [state, setState] = useState2({ loading: false, value: null, symbol: kind === "evm" ? "ETH" : "SOL" });
6841
6866
  useEffect2(() => {
@@ -6853,6 +6878,117 @@ function useBalance(kind, address, chain, rpcUrls) {
6853
6878
  }, [kind, address, chain, rpcUrls]);
6854
6879
  return state;
6855
6880
  }
6881
+ var MODAL_CSS = `
6882
+ .dcm-card { position: relative; width: 100%; max-width: 380px; max-height: calc(100vh - 32px); overflow-y: auto;
6883
+ background: var(--dc-bg); color: var(--dc-text); border: 1px solid var(--dc-border); border-radius: 24px;
6884
+ box-shadow: 0 24px 64px -12px rgba(0,0,0,.35), 0 2px 8px rgba(0,0,0,.08);
6885
+ animation: dcm-in .22s cubic-bezier(.2,.8,.2,1); box-sizing: border-box; }
6886
+ .dcm-card *, .dcm-card *::before, .dcm-card *::after { box-sizing: border-box; }
6887
+ @keyframes dcm-in { from { opacity: 0; transform: translateY(8px) scale(.985); } to { opacity: 1; transform: none; } }
6888
+ @keyframes dcm-fade { from { opacity: 0; } to { opacity: 1; } }
6889
+ @media (prefers-reduced-motion: reduce) { .dcm-card, .dcm-backdrop { animation: none !important; } }
6890
+ .dcm-backdrop { position: absolute; inset: 0; background: var(--dc-bg-overlay);
6891
+ backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); animation: dcm-fade .2s ease; }
6892
+ .dcm-icon-btn { position: absolute; top: 14px; width: 32px; height: 32px; border-radius: 10px; border: 0;
6893
+ background: transparent; color: var(--dc-text-muted); cursor: pointer; display: grid; place-items: center;
6894
+ padding: 0; transition: background .15s, color .15s; z-index: 1; }
6895
+ .dcm-icon-btn:hover { background: var(--dc-surface-hover); color: var(--dc-text); }
6896
+ .dcm-body { padding: 32px 24px 20px; display: flex; flex-direction: column; align-items: center; gap: 14px; text-align: center; }
6897
+ .dcm-title { margin: 4px 0 0; font-size: 20px; font-weight: 600; letter-spacing: -0.02em; line-height: 1.25; color: var(--dc-text); }
6898
+ .dcm-sub { margin: -6px 0 2px; font-size: 13.5px; line-height: 1.5; color: var(--dc-text-secondary); overflow-wrap: anywhere; }
6899
+ .dcm-sub b { color: var(--dc-text); font-weight: 600; }
6900
+ .dcm-methods { width: 100%; display: grid; gap: 8px; margin-top: 4px; }
6901
+ .dcm-method { width: 100%; height: 48px; display: flex; align-items: center; gap: 12px; padding: 0 14px;
6902
+ border-radius: 14px; border: 1px solid var(--dc-border); background: var(--dc-surface); color: var(--dc-text);
6903
+ font-weight: 500; font-size: 14.5px; line-height: 1; font-family: inherit; cursor: pointer; text-align: left;
6904
+ transition: border-color .15s, background .15s; }
6905
+ .dcm-method:hover:not(:disabled) { border-color: var(--dc-text-muted); background: var(--dc-surface-hover); }
6906
+ .dcm-method:disabled { opacity: .6; cursor: default; }
6907
+ .dcm-method:focus-visible, .dcm-primary:focus-visible, .dcm-link:focus-visible, .dcm-icon-btn:focus-visible,
6908
+ .dcm-ghost:focus-visible, .dcm-copy:focus-visible { outline: 2px solid var(--dc-accent); outline-offset: 2px; }
6909
+ .dcm-method > svg { color: var(--dc-text-secondary); }
6910
+ .dcm-method-input { cursor: text; padding-right: 6px; }
6911
+ .dcm-method-input:focus-within { border-color: var(--dc-accent); }
6912
+ .dcm-method-input input { flex: 1; min-width: 0; height: 100%; border: 0; outline: 0; background: transparent;
6913
+ color: var(--dc-text); font-family: inherit; font-size: 14.5px; padding: 0; }
6914
+ .dcm-method-input input::placeholder { color: var(--dc-text-muted); }
6915
+ .dcm-submit { height: 34px; padding: 0 12px; border-radius: 10px; border: 0; background: transparent;
6916
+ color: var(--dc-accent-ink); font-weight: 600; font-size: 13.5px; line-height: 1; font-family: inherit; cursor: pointer; transition: background .15s; }
6917
+ .dcm-submit:hover:not(:disabled) { background: var(--dc-surface-hover); }
6918
+ .dcm-submit:disabled { color: var(--dc-text-muted); cursor: default; }
6919
+ .dcm-form { width: 100%; display: grid; gap: 10px; margin-top: 4px; }
6920
+ .dcm-field { width: 100%; padding: 12px 14px; border-radius: 12px; border: 1px solid var(--dc-border);
6921
+ background: var(--dc-surface); color: var(--dc-text); font-family: inherit; font-size: 15px; outline: none;
6922
+ transition: border-color .15s, box-shadow .15s; }
6923
+ .dcm-field::placeholder { color: var(--dc-text-muted); }
6924
+ .dcm-field:focus { border-color: var(--dc-accent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--dc-accent) 22%, transparent); }
6925
+ .dcm-code { height: 56px; text-align: center; font-family: var(--dc-font-mono); font-size: 24px; letter-spacing: .45em; padding-left: calc(14px + .45em); }
6926
+ .dcm-primary { width: 100%; height: 48px; border-radius: 14px; border: 0; background: var(--dc-accent); color: var(--dc-accent-text);
6927
+ font-weight: 600; font-size: 14.5px; line-height: 1; font-family: inherit; cursor: pointer; display: flex; align-items: center; justify-content: center; gap: 8px;
6928
+ transition: background .15s, opacity .15s; }
6929
+ .dcm-primary:hover:not(:disabled) { background: var(--dc-accent-hover); }
6930
+ .dcm-primary:disabled { opacity: .55; cursor: default; }
6931
+ .dcm-ghost { height: 44px; padding: 0 16px; border-radius: 12px; border: 1px solid var(--dc-border); background: transparent;
6932
+ color: var(--dc-text); font-weight: 500; font-size: 14px; line-height: 1; font-family: inherit; cursor: pointer; transition: background .15s, border-color .15s; white-space: nowrap; }
6933
+ .dcm-ghost:hover:not(:disabled) { background: var(--dc-surface-hover); border-color: var(--dc-text-muted); }
6934
+ .dcm-ghost:disabled { opacity: .55; cursor: default; }
6935
+ .dcm-link { border: 0; background: transparent; color: var(--dc-accent-ink); font-weight: 500; font-size: 13.5px; line-height: 1.4; font-family: inherit;
6936
+ cursor: pointer; padding: 4px; border-radius: 6px; }
6937
+ .dcm-link:hover { text-decoration: underline; text-underline-offset: 3px; }
6938
+ .dcm-badge { width: 52px; height: 52px; border-radius: 16px; display: grid; place-items: center;
6939
+ background: var(--dc-surface); border: 1px solid var(--dc-border); color: var(--dc-text); }
6940
+ .dcm-error { margin: 0; width: 100%; font-size: 13px; line-height: 1.45; color: var(--dc-danger); overflow-wrap: anywhere; }
6941
+ .dcm-protected { width: 100%; display: flex; align-items: center; justify-content: center; gap: 6px;
6942
+ margin-top: 6px; padding-top: 14px; border-top: 1px solid var(--dc-border); font-size: 12.5px; color: var(--dc-text-muted); }
6943
+ .dcm-status { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; font-weight: 500; }
6944
+ .dcm-status i { width: 7px; height: 7px; border-radius: 50%; display: block; }
6945
+ .dcm-addresses { width: 100%; border: 1px solid var(--dc-border); border-radius: 16px; overflow: hidden; text-align: left; }
6946
+ .dcm-address { display: flex; align-items: center; gap: 12px; padding: 12px 14px; background: var(--dc-surface); }
6947
+ .dcm-address + .dcm-address { border-top: 1px solid var(--dc-border); }
6948
+ .dcm-address-main { flex: 1; min-width: 0; display: grid; gap: 3px; }
6949
+ .dcm-address-main span { font-size: 13px; color: var(--dc-text-secondary); }
6950
+ .dcm-address-main code { font-family: var(--dc-font-mono); font-size: 13px; color: var(--dc-text); }
6951
+ .dcm-balance { font-family: var(--dc-font-mono); font-size: 13px; color: var(--dc-text); white-space: nowrap; }
6952
+ .dcm-copy { width: 30px; height: 30px; border-radius: 9px; border: 0; background: transparent; color: var(--dc-text-muted);
6953
+ display: grid; place-items: center; cursor: pointer; padding: 0; transition: background .15s, color .15s; }
6954
+ .dcm-copy:hover { background: var(--dc-surface-hover); color: var(--dc-text); }
6955
+ .dcm-panel { width: 100%; border: 1px solid var(--dc-border); border-radius: 16px; text-align: left; overflow: hidden; }
6956
+ .dcm-panel-head { width: 100%; display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 13px 14px;
6957
+ border: 0; background: var(--dc-surface); color: var(--dc-text); font-weight: 500; font-size: 14px; line-height: 1; font-family: inherit; cursor: pointer; }
6958
+ .dcm-panel-head:hover { background: var(--dc-surface-hover); }
6959
+ .dcm-panel-head svg { color: var(--dc-text-muted); }
6960
+ .dcm-panel-body { padding: 14px; border-top: 1px solid var(--dc-border); display: grid; gap: 10px; }
6961
+ .dcm-note { margin: 0; font-size: 13px; line-height: 1.5; color: var(--dc-text-secondary); }
6962
+ .dcm-warn { padding: 12px; border-radius: 12px; font-size: 13px; line-height: 1.5;
6963
+ background: color-mix(in srgb, var(--dc-danger) 9%, transparent); border: 1px solid color-mix(in srgb, var(--dc-danger) 30%, transparent); color: var(--dc-text); }
6964
+ .dcm-warn strong { display: block; margin-bottom: 2px; color: var(--dc-danger); font-weight: 600; }
6965
+ .dcm-check { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--dc-text); cursor: pointer; }
6966
+ .dcm-check input { width: 16px; height: 16px; margin: 0; accent-color: var(--dc-accent); }
6967
+ .dcm-row { display: flex; gap: 8px; width: 100%; }
6968
+ .dcm-row > .dcm-primary { flex: 1; height: 44px; border-radius: 12px; }
6969
+ .dcm-actions { width: 100%; display: flex; gap: 8px; }
6970
+ .dcm-actions > * { flex: 1; }
6971
+ `;
6972
+ function injectModalCss() {
6973
+ if (document.getElementById("decane-modal-css")) return;
6974
+ const el = document.createElement("style");
6975
+ el.id = "decane-modal-css";
6976
+ el.textContent = MODAL_CSS;
6977
+ document.head.appendChild(el);
6978
+ }
6979
+ function shortAddress(a, head = 6, tail = 4) {
6980
+ return a.length > head + tail + 1 ? `${a.slice(0, head)}\u2026${a.slice(-tail)}` : a;
6981
+ }
6982
+ function CopyButton({ value, label }) {
6983
+ const [copied, setCopied] = useState2(false);
6984
+ async function copy() {
6985
+ await navigator.clipboard.writeText(value).catch(() => {
6986
+ });
6987
+ setCopied(true);
6988
+ setTimeout(() => setCopied(false), 1500);
6989
+ }
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));
6991
+ }
6856
6992
  function AddressRow({
6857
6993
  label,
6858
6994
  address,
@@ -6861,14 +6997,10 @@ function AddressRow({
6861
6997
  rpcUrls
6862
6998
  }) {
6863
6999
  const balance = useBalance(kind, address, chain, rpcUrls);
6864
- const short = `${address.slice(0, 8)}\u2026${address.slice(-6)}`;
6865
- return /* @__PURE__ */ React3.createElement("div", { style: {
6866
- background: "var(--dc-surface)",
6867
- border: "1px solid var(--dc-border)",
6868
- borderRadius: 10,
6869
- padding: "10px 14px",
6870
- marginBottom: 8
6871
- } }, /* @__PURE__ */ React3.createElement("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 5 } }, /* @__PURE__ */ React3.createElement("span", { style: { fontSize: 10, fontWeight: 700, color: "var(--dc-text-muted)", letterSpacing: "0.06em", textTransform: "uppercase" } }, label), /* @__PURE__ */ React3.createElement("span", { style: { fontSize: 11, fontFamily: "monospace", color: "var(--dc-text)" } }, balance.loading ? "\u2026" : `${formatBalanceDisplay(balance.value)} ${balance.symbol}`)), /* @__PURE__ */ React3.createElement("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", gap: 8 } }, /* @__PURE__ */ React3.createElement("span", { style: { fontSize: 13, fontFamily: "monospace", color: "var(--dc-text)", letterSpacing: "0.02em" } }, short), /* @__PURE__ */ React3.createElement(CopyButton, { value: address })));
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 }));
7001
+ }
7002
+ 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 }));
6872
7004
  }
6873
7005
  function SignInView({
6874
7006
  onGoogleSignIn,
@@ -6902,6 +7034,7 @@ function SignInView({
6902
7034
  const [showOtherMethods, setShowOtherMethods] = useState2(false);
6903
7035
  const [error, setError] = useState2("");
6904
7036
  const passkeyFirst = !!canUsePasskey && !!onPasskeySignIn && !showOtherMethods;
7037
+ const busy = googleLoading || kingsChatLoading || xLoading || customLoading || emailLoading || phoneLoading;
6905
7038
  async function handlePasskey() {
6906
7039
  if (!onPasskeySignIn) return;
6907
7040
  setError("");
@@ -6955,7 +7088,7 @@ function SignInView({
6955
7088
  setError("");
6956
7089
  setEmailLoading(true);
6957
7090
  try {
6958
- await onEmailStart(email);
7091
+ await onEmailStart(email.trim());
6959
7092
  setEmailSent(true);
6960
7093
  } catch (e2) {
6961
7094
  setError(e2.message);
@@ -6968,7 +7101,7 @@ function SignInView({
6968
7101
  setError("");
6969
7102
  setEmailLoading(true);
6970
7103
  try {
6971
- await onEmailVerify(email, code);
7104
+ await onEmailVerify(email.trim(), code);
6972
7105
  } catch (e2) {
6973
7106
  setError(e2.message);
6974
7107
  } finally {
@@ -6981,7 +7114,7 @@ function SignInView({
6981
7114
  setError("");
6982
7115
  setPhoneLoading(true);
6983
7116
  try {
6984
- await onPhoneStart(phone);
7117
+ await onPhoneStart(phone.trim());
6985
7118
  setPhoneSent(true);
6986
7119
  } catch (e2) {
6987
7120
  setError(e2.message);
@@ -6995,7 +7128,7 @@ function SignInView({
6995
7128
  setError("");
6996
7129
  setPhoneLoading(true);
6997
7130
  try {
6998
- await onPhoneVerify(phone, phoneCode);
7131
+ await onPhoneVerify(phone.trim(), phoneCode);
6999
7132
  } catch (e2) {
7000
7133
  setError(e2.message);
7001
7134
  } finally {
@@ -7014,226 +7147,67 @@ function SignInView({
7014
7147
  setCustomLoading(false);
7015
7148
  }
7016
7149
  }
7017
- const inputStyle = {
7018
- width: "100%",
7019
- background: "var(--dc-surface)",
7020
- border: "1px solid var(--dc-border)",
7021
- borderRadius: 8,
7022
- color: "var(--dc-text)",
7023
- padding: "9px 12px",
7024
- fontSize: 13,
7025
- outline: "none",
7026
- fontFamily: "inherit",
7027
- boxSizing: "border-box"
7028
- };
7029
- return /* @__PURE__ */ React3.createElement("div", { style: { padding: "0 16px 16px" } }, resumeHint && !passkeyFirst && /* @__PURE__ */ React3.createElement("div", { style: { fontSize: 12, color: "var(--dc-text-muted)", marginBottom: 12, textAlign: "center" } }, "Welcome back \u2014 sign in again to resume ", resumeHint), passkeyFirst && /* @__PURE__ */ React3.createElement("div", null, /* @__PURE__ */ React3.createElement("div", { style: { fontSize: 12, color: "var(--dc-text-muted)", marginBottom: 12, textAlign: "center" } }, "Welcome back \u2014 unlock to resume", passkeyAddress ? ` ${passkeyAddress.slice(0, 6)}\u2026${passkeyAddress.slice(-4)}` : ""), /* @__PURE__ */ React3.createElement(
7030
- "button",
7031
- {
7032
- onClick: handlePasskey,
7033
- disabled: passkeyLoading,
7034
- style: {
7035
- width: "100%",
7036
- padding: "11px 0",
7037
- background: "var(--dc-accent)",
7038
- color: "var(--dc-accent-text)",
7039
- border: "none",
7040
- borderRadius: 10,
7041
- fontSize: 13,
7042
- fontWeight: 700,
7043
- cursor: passkeyLoading ? "not-allowed" : "pointer",
7044
- opacity: passkeyLoading ? 0.7 : 1,
7045
- fontFamily: "inherit",
7046
- display: "flex",
7047
- alignItems: "center",
7048
- justifyContent: "center",
7049
- gap: 7
7050
- }
7051
- },
7052
- passkeyLoading ? "Verifying\u2026" : "\u{1F513} Continue with passkey"
7053
- ), /* @__PURE__ */ React3.createElement(
7054
- "button",
7055
- {
7056
- onClick: () => setShowOtherMethods(true),
7057
- style: {
7058
- width: "100%",
7059
- marginTop: 10,
7060
- background: "none",
7061
- border: "none",
7062
- color: "var(--dc-text-muted)",
7063
- fontSize: 12,
7064
- cursor: "pointer",
7065
- fontFamily: "inherit"
7066
- }
7067
- },
7068
- "Use email or Google instead"
7069
- ), error && /* @__PURE__ */ React3.createElement("div", { style: { marginTop: 10, fontSize: 12, color: "var(--dc-danger, #ff5533)" } }, error)), !passkeyFirst && authMethods.includes("google") && /* @__PURE__ */ React3.createElement(
7070
- "button",
7071
- {
7072
- onClick: handleGoogle,
7073
- disabled: googleLoading,
7074
- style: {
7075
- width: "100%",
7076
- padding: "10px 0",
7077
- marginBottom: 10,
7078
- background: "var(--dc-accent)",
7079
- color: "var(--dc-accent-text)",
7080
- border: "none",
7081
- borderRadius: 10,
7082
- fontSize: 13,
7083
- fontWeight: 700,
7084
- cursor: googleLoading ? "not-allowed" : "pointer",
7085
- opacity: googleLoading ? 0.7 : 1,
7086
- fontFamily: "inherit"
7087
- }
7088
- },
7089
- googleLoading ? "Redirecting\u2026" : "Continue with Google"
7090
- ), !passkeyFirst && authMethods.includes("kingschat") && onKingsChatSignIn && /* @__PURE__ */ React3.createElement(
7091
- "button",
7092
- {
7093
- onClick: handleKingsChat,
7094
- disabled: kingsChatLoading,
7095
- style: {
7096
- width: "100%",
7097
- padding: "10px 0",
7098
- marginBottom: 10,
7099
- background: "var(--dc-surface)",
7100
- color: "var(--dc-text)",
7101
- border: "1px solid var(--dc-border)",
7102
- borderRadius: 10,
7103
- fontSize: 13,
7104
- fontWeight: 700,
7105
- cursor: kingsChatLoading ? "not-allowed" : "pointer",
7106
- opacity: kingsChatLoading ? 0.7 : 1,
7107
- fontFamily: "inherit"
7108
- }
7109
- },
7110
- kingsChatLoading ? "Waiting for KingsChat\u2026" : "Continue with KingsChat"
7111
- ), !passkeyFirst && authMethods.includes("x") && onXSignIn && /* @__PURE__ */ React3.createElement(
7112
- "button",
7113
- {
7114
- onClick: handleX,
7115
- disabled: xLoading,
7116
- style: {
7117
- width: "100%",
7118
- padding: "10px 0",
7119
- marginBottom: 10,
7120
- background: "var(--dc-surface)",
7121
- color: "var(--dc-text)",
7122
- border: "1px solid var(--dc-border)",
7123
- borderRadius: 10,
7124
- fontSize: 13,
7125
- fontWeight: 700,
7126
- cursor: xLoading ? "not-allowed" : "pointer",
7127
- opacity: xLoading ? 0.7 : 1,
7128
- fontFamily: "inherit",
7129
- display: "flex",
7130
- alignItems: "center",
7131
- justifyContent: "center",
7132
- gap: 8
7133
- }
7134
- },
7135
- /* @__PURE__ */ React3.createElement(XLogo, null),
7136
- xLoading ? "Redirecting\u2026" : "Continue with X"
7137
- ), !passkeyFirst && authMethods.includes("email") && /* @__PURE__ */ React3.createElement(React3.Fragment, null, authMethods.includes("google") && /* @__PURE__ */ React3.createElement("div", { style: { textAlign: "center", color: "var(--dc-text-muted)", fontSize: 12, margin: "10px 0" } }, "\u2014 or \u2014"), !emailSent ? /* @__PURE__ */ React3.createElement("form", { onSubmit: handleEmailStart, style: { display: "flex", gap: 8 } }, /* @__PURE__ */ React3.createElement(
7150
+ function backToMethods() {
7151
+ setEmailSent(false);
7152
+ setCode("");
7153
+ setPhoneSent(false);
7154
+ setPhoneCode("");
7155
+ setError("");
7156
+ }
7157
+ const errorLine = error ? /* @__PURE__ */ React3.createElement("p", { className: "dcm-error", role: "alert" }, error) : null;
7158
+ 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: () => {
7160
+ setError("");
7161
+ setShowOtherMethods(true);
7162
+ } }, "Use another sign-in method"), /* @__PURE__ */ React3.createElement(ProtectedBy, null));
7163
+ }
7164
+ if (emailSent || phoneSent) {
7165
+ const isEmail = emailSent;
7166
+ const value = isEmail ? code : phoneCode;
7167
+ const setValue = isEmail ? setCode : setPhoneCode;
7168
+ 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(
7170
+ "input",
7171
+ {
7172
+ className: "dcm-field dcm-code",
7173
+ "aria-label": "6-digit code",
7174
+ placeholder: "000000",
7175
+ value,
7176
+ maxLength: 6,
7177
+ autoFocus: true,
7178
+ inputMode: "numeric",
7179
+ autoComplete: "one-time-code",
7180
+ onChange: (e) => setValue(e.target.value.replace(/\D/g, ""))
7181
+ }
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));
7183
+ }
7184
+ 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(
7138
7186
  "input",
7139
7187
  {
7140
7188
  type: "email",
7141
7189
  required: true,
7142
7190
  placeholder: "your@email.com",
7191
+ "aria-label": "Email address",
7192
+ autoComplete: "email",
7143
7193
  value: email,
7144
- onChange: (e) => setEmail(e.target.value),
7145
- style: { ...inputStyle, flex: 1 }
7146
- }
7147
- ), /* @__PURE__ */ React3.createElement("button", { type: "submit", disabled: emailLoading, style: {
7148
- padding: "0 16px",
7149
- background: "var(--dc-surface)",
7150
- border: "1px solid var(--dc-border)",
7151
- borderRadius: 8,
7152
- color: "var(--dc-text)",
7153
- fontSize: 13,
7154
- cursor: "pointer",
7155
- fontFamily: "inherit"
7156
- } }, emailLoading ? "\u2026" : "Send code")) : /* @__PURE__ */ React3.createElement("form", { onSubmit: handleEmailVerify, style: { display: "flex", gap: 8 } }, /* @__PURE__ */ React3.createElement(
7157
- "input",
7158
- {
7159
- placeholder: "6-digit code",
7160
- value: code,
7161
- maxLength: 6,
7162
- autoFocus: true,
7163
- onChange: (e) => setCode(e.target.value.replace(/\D/g, "")),
7164
- style: { ...inputStyle, flex: 1, letterSpacing: 4, textAlign: "center" }
7165
- }
7166
- ), /* @__PURE__ */ React3.createElement("button", { type: "submit", disabled: emailLoading, style: {
7167
- padding: "0 16px",
7168
- background: "var(--dc-accent)",
7169
- color: "var(--dc-accent-text)",
7170
- border: "none",
7171
- borderRadius: 8,
7172
- fontSize: 13,
7173
- fontWeight: 700,
7174
- cursor: "pointer",
7175
- fontFamily: "inherit"
7176
- } }, emailLoading ? "\u2026" : "Verify"))), !passkeyFirst && authMethods.includes("phone") && onPhoneStart && onPhoneVerify && /* @__PURE__ */ React3.createElement(React3.Fragment, null, (authMethods.includes("google") || authMethods.includes("email")) && /* @__PURE__ */ React3.createElement("div", { style: { textAlign: "center", color: "var(--dc-text-muted)", fontSize: 12, margin: "10px 0" } }, "\u2014 or \u2014"), !phoneSent ? /* @__PURE__ */ React3.createElement("form", { onSubmit: handlePhoneStart, style: { display: "flex", gap: 8 } }, /* @__PURE__ */ React3.createElement(
7194
+ onChange: (e) => setEmail(e.target.value)
7195
+ }
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(
7177
7197
  "input",
7178
7198
  {
7179
7199
  type: "tel",
7180
7200
  required: true,
7181
7201
  placeholder: "+234 801 234 5678",
7202
+ "aria-label": "Phone number",
7203
+ autoComplete: "tel",
7182
7204
  value: phone,
7183
- onChange: (e) => setPhone(e.target.value),
7184
- style: { ...inputStyle, flex: 1 }
7185
- }
7186
- ), /* @__PURE__ */ React3.createElement("button", { type: "submit", disabled: phoneLoading, style: {
7187
- padding: "0 16px",
7188
- background: "var(--dc-surface)",
7189
- border: "1px solid var(--dc-border)",
7190
- borderRadius: 8,
7191
- color: "var(--dc-text)",
7192
- fontSize: 13,
7193
- cursor: "pointer",
7194
- fontFamily: "inherit"
7195
- } }, phoneLoading ? "\u2026" : "Send code")) : /* @__PURE__ */ React3.createElement("form", { onSubmit: handlePhoneVerify, style: { display: "flex", gap: 8 } }, /* @__PURE__ */ React3.createElement(
7196
- "input",
7197
- {
7198
- placeholder: "6-digit code",
7199
- value: phoneCode,
7200
- maxLength: 6,
7201
- autoFocus: true,
7202
- inputMode: "numeric",
7203
- onChange: (e) => setPhoneCode(e.target.value.replace(/\D/g, "")),
7204
- style: { ...inputStyle, flex: 1, letterSpacing: 4, textAlign: "center" }
7205
- }
7206
- ), /* @__PURE__ */ React3.createElement("button", { type: "submit", disabled: phoneLoading, style: {
7207
- padding: "0 16px",
7208
- background: "var(--dc-accent)",
7209
- color: "var(--dc-accent-text)",
7210
- border: "none",
7211
- borderRadius: 8,
7212
- fontSize: 13,
7213
- fontWeight: 700,
7214
- cursor: "pointer",
7215
- fontFamily: "inherit"
7216
- } }, phoneLoading ? "\u2026" : "Verify"))), !passkeyFirst && customAuthLabel && onCustomAuthSignIn && /* @__PURE__ */ React3.createElement(React3.Fragment, null, (authMethods.includes("google") || authMethods.includes("email")) && /* @__PURE__ */ React3.createElement("div", { style: { textAlign: "center", color: "var(--dc-text-muted)", fontSize: 12, margin: "10px 0" } }, "\u2014 or \u2014"), /* @__PURE__ */ React3.createElement(
7217
- "button",
7218
- {
7219
- onClick: handleCustomAuth,
7220
- disabled: customLoading,
7221
- style: {
7222
- width: "100%",
7223
- padding: "10px 0",
7224
- background: "var(--dc-surface)",
7225
- color: "var(--dc-text)",
7226
- border: "1px solid var(--dc-border)",
7227
- borderRadius: 10,
7228
- fontSize: 13,
7229
- fontWeight: 600,
7230
- cursor: customLoading ? "not-allowed" : "pointer",
7231
- opacity: customLoading ? 0.7 : 1,
7232
- fontFamily: "inherit"
7233
- }
7234
- },
7235
- customLoading ? "Connecting\u2026" : customAuthLabel
7236
- )), error && /* @__PURE__ */ React3.createElement("div", { style: { marginTop: 10, fontSize: 12, color: "var(--dc-danger, #ff5533)" } }, error));
7205
+ onChange: (e) => setPhone(e.target.value)
7206
+ }
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: () => {
7208
+ setError("");
7209
+ setShowOtherMethods(false);
7210
+ } }, "Use my passkey instead"), /* @__PURE__ */ React3.createElement(ProtectedBy, null));
7237
7211
  }
7238
7212
  function RecoverySection({
7239
7213
  addresses,
@@ -7284,60 +7258,34 @@ function RecoverySection({
7284
7258
  setBusy(false);
7285
7259
  }
7286
7260
  }
7287
- const inputStyle = {
7288
- width: "100%",
7289
- background: "var(--dc-bg)",
7290
- border: "1px solid var(--dc-border)",
7291
- borderRadius: 8,
7292
- color: "var(--dc-text)",
7293
- padding: "8px 10px",
7294
- fontSize: 12,
7295
- outline: "none",
7296
- fontFamily: "inherit",
7297
- boxSizing: "border-box"
7298
- };
7299
- const btnStyle = {
7300
- padding: "8px 12px",
7301
- borderRadius: 8,
7302
- fontSize: 12,
7303
- fontWeight: 700,
7304
- cursor: "pointer",
7305
- fontFamily: "inherit",
7306
- border: "none"
7307
- };
7308
- return /* @__PURE__ */ React3.createElement("div", { style: { margin: "0 16px 14px", border: "1px solid var(--dc-border)", borderRadius: 10, overflow: "hidden" } }, /* @__PURE__ */ React3.createElement(
7309
- "button",
7261
+ const passwordFields = /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement(
7262
+ "input",
7310
7263
  {
7311
- onClick: () => setExpanded((v) => !v),
7312
- style: {
7313
- width: "100%",
7314
- padding: "10px 14px",
7315
- background: "var(--dc-surface)",
7316
- border: "none",
7317
- display: "flex",
7318
- alignItems: "center",
7319
- justifyContent: "space-between",
7320
- cursor: "pointer",
7321
- fontFamily: "inherit"
7322
- }
7323
- },
7324
- /* @__PURE__ */ React3.createElement("span", { style: { fontSize: 12, fontWeight: 700, color: "var(--dc-text)" } }, "Recovery"),
7325
- /* @__PURE__ */ React3.createElement("span", { style: { fontSize: 11, color: "var(--dc-text-muted)" } }, expanded ? "\u25B2" : "\u25BC")
7326
- ), expanded && /* @__PURE__ */ React3.createElement("div", { style: { padding: "12px 14px", borderTop: "1px solid var(--dc-border)" } }, /* @__PURE__ */ React3.createElement("p", { style: { fontSize: 11, color: "var(--dc-text-muted)", lineHeight: 1.5, margin: "0 0 10px" } }, "Save a recovery file so you can restore this wallet on a new device."), !mode && /* @__PURE__ */ React3.createElement("div", { style: { display: "flex", flexDirection: "column", gap: 8 } }, /* @__PURE__ */ React3.createElement("button", { onClick: () => {
7264
+ className: "dcm-field",
7265
+ type: "password",
7266
+ placeholder: "Password (at least 8 characters)",
7267
+ "aria-label": "Password",
7268
+ autoComplete: "new-password",
7269
+ value: password,
7270
+ onChange: (e) => setPassword(e.target.value)
7271
+ }
7272
+ ), /* @__PURE__ */ React3.createElement(
7273
+ "input",
7274
+ {
7275
+ className: "dcm-field",
7276
+ placeholder: "Password hint (optional)",
7277
+ "aria-label": "Password hint",
7278
+ value: passwordHint,
7279
+ onChange: (e) => setPasswordHint(e.target.value)
7280
+ }
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: () => {
7327
7283
  reset();
7328
7284
  setMode("share");
7329
- }, style: { ...btnStyle, background: "var(--dc-accent)", color: "var(--dc-accent-text)" } }, "Generate recovery-share file"), /* @__PURE__ */ React3.createElement("button", { onClick: () => {
7285
+ } }, "Download recovery-share file"), /* @__PURE__ */ React3.createElement("button", { type: "button", className: "dcm-ghost", onClick: () => {
7330
7286
  reset();
7331
7287
  setMode("portable");
7332
- }, style: { ...btnStyle, background: "transparent", border: "1px solid var(--dc-border)", color: "var(--dc-text)" } }, "Generate full recovery file")), mode === "share" && /* @__PURE__ */ React3.createElement("div", { style: { display: "flex", flexDirection: "column", gap: 8 } }, /* @__PURE__ */ React3.createElement("p", { style: { fontSize: 11, color: "var(--dc-text-muted)", margin: 0 } }, "One share \u2014 useless alone, safe to keep in a password manager or cloud drive. Generating a new one invalidates any previous recovery-share file."), /* @__PURE__ */ React3.createElement("input", { type: "password", placeholder: "Password (min 8 chars)", value: password, onChange: (e) => setPassword(e.target.value), style: inputStyle }), /* @__PURE__ */ React3.createElement("input", { placeholder: "Password hint (optional)", value: passwordHint, onChange: (e) => setPasswordHint(e.target.value), style: inputStyle }), error && /* @__PURE__ */ React3.createElement("div", { style: { fontSize: 11, color: "var(--dc-danger, #ff5533)" } }, error), /* @__PURE__ */ React3.createElement("div", { style: { display: "flex", gap: 8 } }, /* @__PURE__ */ React3.createElement("button", { onClick: handleGenerate, disabled: busy, style: { ...btnStyle, flex: 1, background: "var(--dc-accent)", color: "var(--dc-accent-text)" } }, busy ? "Generating\u2026" : "Generate & download"), /* @__PURE__ */ React3.createElement("button", { onClick: reset, style: { ...btnStyle, background: "transparent", border: "1px solid var(--dc-border)", color: "var(--dc-text-muted)" } }, "Cancel"))), mode === "portable" && /* @__PURE__ */ React3.createElement("div", { style: { display: "flex", flexDirection: "column", gap: 8 } }, /* @__PURE__ */ React3.createElement("div", { style: {
7333
- background: "rgba(255,85,51,0.08)",
7334
- border: "1px solid rgba(255,85,51,0.3)",
7335
- borderRadius: 8,
7336
- padding: "8px 10px",
7337
- fontSize: 11,
7338
- color: "#ff9977",
7339
- lineHeight: 1.5
7340
- } }, /* @__PURE__ */ React3.createElement("strong", { style: { display: "block", marginBottom: 3, color: "#ff5533" } }, "This file controls your wallet"), "Contains two shares \u2014 file plus password gives complete control. Keep it offline, not a cloud drive. This also invalidates your current recovery-share file."), /* @__PURE__ */ React3.createElement("label", { style: { display: "flex", alignItems: "center", gap: 6, fontSize: 11, color: "var(--dc-text)" } }, /* @__PURE__ */ React3.createElement("input", { type: "checkbox", checked: confirmed, onChange: (e) => setConfirmed(e.target.checked), style: { width: "auto" } }), "I understand this is a bearer secret"), /* @__PURE__ */ React3.createElement("input", { type: "password", placeholder: "Password (min 8 chars)", value: password, onChange: (e) => setPassword(e.target.value), style: inputStyle }), /* @__PURE__ */ React3.createElement("input", { placeholder: "Password hint (optional)", value: passwordHint, onChange: (e) => setPasswordHint(e.target.value), style: inputStyle }), error && /* @__PURE__ */ React3.createElement("div", { style: { fontSize: 11, color: "var(--dc-danger, #ff5533)" } }, error), /* @__PURE__ */ React3.createElement("div", { style: { display: "flex", gap: 8 } }, /* @__PURE__ */ React3.createElement("button", { onClick: handleGenerate, disabled: busy || !confirmed, style: { ...btnStyle, flex: 1, background: "var(--dc-accent)", color: "var(--dc-accent-text)" } }, busy ? "Generating\u2026" : "Generate & download"), /* @__PURE__ */ React3.createElement("button", { onClick: reset, style: { ...btnStyle, background: "transparent", border: "1px solid var(--dc-border)", color: "var(--dc-text-muted)" } }, "Cancel"))), result && /* @__PURE__ */ React3.createElement("div", { style: { marginTop: 10, fontSize: 11, color: "var(--dc-text-muted)", lineHeight: 1.5 } }, result.kind === "share" ? "Recovery-share file" : "Full recovery file", " downloaded \u2014 share set is now version ", result.version, ". Any previous recovery file no longer works.")));
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.")));
7341
7289
  }
7342
7290
  function SocialWalletModal({
7343
7291
  open,
@@ -7348,6 +7296,7 @@ function SocialWalletModal({
7348
7296
  onDisconnect,
7349
7297
  onGoogleSignIn,
7350
7298
  onKingsChatSignIn,
7299
+ onXSignIn,
7351
7300
  onEmailStart,
7352
7301
  onEmailVerify,
7353
7302
  onPhoneStart,
@@ -7366,9 +7315,11 @@ function SocialWalletModal({
7366
7315
  const [timer, setTimer] = useState2("");
7367
7316
  const [unlocking, setUnlocking] = useState2(false);
7368
7317
  const [disconnecting, setDisconnecting] = useState2(false);
7318
+ const [actionError, setActionError] = useState2("");
7369
7319
  useEffect2(() => {
7370
7320
  if (!open) return;
7371
7321
  injectTokens2(theme);
7322
+ injectModalCss();
7372
7323
  if (theme !== "auto") return;
7373
7324
  const mq = window.matchMedia("(prefers-color-scheme: dark)");
7374
7325
  const h = () => injectTokens2("auto");
@@ -7395,17 +7346,23 @@ function SocialWalletModal({
7395
7346
  if (!open) return null;
7396
7347
  async function handleUnlock() {
7397
7348
  setUnlocking(true);
7349
+ setActionError("");
7398
7350
  try {
7399
7351
  await onUnlock();
7352
+ } catch (e) {
7353
+ setActionError(e.message);
7400
7354
  } finally {
7401
7355
  setUnlocking(false);
7402
7356
  }
7403
7357
  }
7404
7358
  async function handleDisconnect() {
7405
7359
  setDisconnecting(true);
7360
+ setActionError("");
7406
7361
  try {
7407
7362
  await onDisconnect();
7408
7363
  onClose();
7364
+ } catch (e) {
7365
+ setActionError(e.message);
7409
7366
  } finally {
7410
7367
  setDisconnecting(false);
7411
7368
  }
@@ -7413,12 +7370,13 @@ function SocialWalletModal({
7413
7370
  const evmChain = chains?.find((c) => c.startsWith("evm:")) ?? "evm:11155111";
7414
7371
  const solChain = chains?.find((c) => c.startsWith("solana:")) ?? "solana:mainnet";
7415
7372
  const showSignIn = !socialAuth.addresses || socialAuth.needsReconnect;
7373
+ const unlocked = socialAuth.isUnlocked;
7416
7374
  const modal = /* @__PURE__ */ React3.createElement(
7417
7375
  "div",
7418
7376
  {
7419
7377
  role: "dialog",
7420
7378
  "aria-modal": "true",
7421
- "aria-label": "Social wallet",
7379
+ "aria-label": showSignIn ? "Log in or sign up" : "Your wallet",
7422
7380
  style: {
7423
7381
  position: "fixed",
7424
7382
  inset: 0,
@@ -7427,63 +7385,17 @@ function SocialWalletModal({
7427
7385
  alignItems: "center",
7428
7386
  justifyContent: "center",
7429
7387
  padding: 16,
7430
- fontFamily: "var(--dc-font-sans, system-ui, sans-serif)"
7388
+ fontFamily: "var(--dc-font-sans, system-ui, sans-serif)",
7389
+ WebkitFontSmoothing: "antialiased"
7431
7390
  }
7432
7391
  },
7433
- /* @__PURE__ */ React3.createElement(
7434
- "div",
7435
- {
7436
- onClick: onClose,
7437
- style: {
7438
- position: "absolute",
7439
- inset: 0,
7440
- background: "var(--dc-bg-overlay)",
7441
- backdropFilter: "blur(8px)",
7442
- WebkitBackdropFilter: "blur(8px)"
7443
- }
7444
- }
7445
- ),
7446
- /* @__PURE__ */ React3.createElement("div", { style: {
7447
- position: "relative",
7448
- background: "var(--dc-bg)",
7449
- border: "1px solid var(--dc-border)",
7450
- borderRadius: 20,
7451
- width: "100%",
7452
- maxWidth: 380,
7453
- maxHeight: "90vh",
7454
- overflowY: "auto",
7455
- boxShadow: "0 24px 64px rgba(0,0,0,0.6), 0 0 0 1px rgba(255,255,255,0.04)"
7456
- } }, /* @__PURE__ */ React3.createElement("div", { style: {
7457
- height: 2,
7458
- position: "sticky",
7459
- top: 0,
7460
- zIndex: 1,
7461
- background: "linear-gradient(90deg, transparent, var(--dc-accent) 30%, var(--dc-accent) 70%, transparent)"
7462
- } }), /* @__PURE__ */ React3.createElement("div", { style: { padding: "18px 20px 16px", display: "flex", alignItems: "center", gap: 11 } }, /* @__PURE__ */ React3.createElement(DecaneMark, { size: 38 }), /* @__PURE__ */ React3.createElement("div", { style: { flex: 1 } }, /* @__PURE__ */ React3.createElement("div", { style: { display: "flex", alignItems: "baseline", gap: 6 } }, /* @__PURE__ */ React3.createElement(DecaneWordmark, { size: 15 }), /* @__PURE__ */ React3.createElement("span", { style: { fontSize: 13, fontWeight: 700, color: "var(--dc-text-muted)", letterSpacing: "-0.01em" } }, "wallet")), /* @__PURE__ */ React3.createElement("div", { style: { fontSize: 11, color: "var(--dc-text-muted)", marginTop: 2 } }, "Non-custodial \xB7 key split three ways")), /* @__PURE__ */ React3.createElement(
7463
- "button",
7464
- {
7465
- onClick: onClose,
7466
- style: {
7467
- background: "var(--dc-surface)",
7468
- border: "1px solid var(--dc-border)",
7469
- borderRadius: 8,
7470
- width: 28,
7471
- height: 28,
7472
- cursor: "pointer",
7473
- display: "flex",
7474
- alignItems: "center",
7475
- justifyContent: "center",
7476
- color: "var(--dc-text-muted)",
7477
- flexShrink: 0,
7478
- padding: 0
7479
- }
7480
- },
7481
- /* @__PURE__ */ React3.createElement("svg", { width: "12", height: "12", viewBox: "0 0 12 12", fill: "none" }, /* @__PURE__ */ React3.createElement("path", { d: "M1.5 1.5L10.5 10.5M10.5 1.5L1.5 10.5", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" }))
7482
- )), showSignIn ? /* @__PURE__ */ React3.createElement(
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(
7483
7394
  SignInView,
7484
7395
  {
7485
7396
  onGoogleSignIn,
7486
7397
  onKingsChatSignIn,
7398
+ onXSignIn,
7487
7399
  onEmailStart,
7488
7400
  onEmailVerify,
7489
7401
  onPhoneStart,
@@ -7496,86 +7408,22 @@ function SocialWalletModal({
7496
7408
  passkeyAddress,
7497
7409
  onPasskeySignIn
7498
7410
  }
7499
- ) : /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement("div", { style: {
7500
- margin: "0 16px 14px",
7501
- padding: "8px 14px",
7502
- background: socialAuth.isUnlocked ? "rgba(18,183,106,0.08)" : "rgba(245,200,0,0.08)",
7503
- border: `1px solid ${socialAuth.isUnlocked ? "rgba(18,183,106,0.2)" : "rgba(245,200,0,0.2)"}`,
7504
- borderRadius: 10,
7505
- display: "flex",
7506
- alignItems: "center",
7507
- justifyContent: "space-between"
7508
- } }, /* @__PURE__ */ React3.createElement("div", { style: { display: "flex", alignItems: "center", gap: 8 } }, /* @__PURE__ */ React3.createElement("span", { style: {
7509
- width: 7,
7510
- height: 7,
7511
- borderRadius: "50%",
7512
- flexShrink: 0,
7513
- background: socialAuth.isUnlocked ? "#12b76a" : "var(--dc-accent)",
7514
- boxShadow: `0 0 6px ${socialAuth.isUnlocked ? "#12b76a" : "var(--dc-accent)"}`
7515
- } }), /* @__PURE__ */ React3.createElement("span", { style: {
7516
- fontSize: 12,
7517
- fontWeight: 700,
7518
- color: socialAuth.isUnlocked ? "#12b76a" : "var(--dc-accent)"
7519
- } }, socialAuth.isUnlocked ? "Unlocked" : "Locked")), socialAuth.isUnlocked && timer && /* @__PURE__ */ React3.createElement("span", { style: { fontSize: 11, color: "var(--dc-text-muted)", fontFamily: "monospace" } }, "expires ", timer)), /* @__PURE__ */ React3.createElement("div", { style: { padding: "0 16px 14px" } }, socialAuth.addresses?.evm && /* @__PURE__ */ React3.createElement(AddressRow, { label: "EVM (Ethereum, Base, \u2026)", address: socialAuth.addresses.evm, kind: "evm", chain: evmChain, rpcUrls }), socialAuth.addresses?.solana && /* @__PURE__ */ React3.createElement(AddressRow, { label: "Solana", address: socialAuth.addresses.solana, kind: "solana", chain: solChain, rpcUrls })), socialAuth.isUnlocked && /* @__PURE__ */ React3.createElement(
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(
7412
+ "span",
7413
+ {
7414
+ className: "dcm-status",
7415
+ style: { color: unlocked ? "#12b76a" : "var(--dc-accent-ink)", marginTop: -8 }
7416
+ },
7417
+ /* @__PURE__ */ React3.createElement("i", { style: { background: unlocked ? "#12b76a" : "var(--dc-accent)" } }),
7418
+ 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(
7520
7420
  RecoverySection,
7521
7421
  {
7522
7422
  addresses: socialAuth.addresses,
7523
7423
  onRotateShares,
7524
7424
  onExportPortableBackup
7525
7425
  }
7526
- ), /* @__PURE__ */ React3.createElement("div", { style: {
7527
- padding: "14px 16px",
7528
- borderTop: "1px solid var(--dc-border)",
7529
- display: "flex",
7530
- gap: 8
7531
- } }, !socialAuth.isUnlocked && /* @__PURE__ */ React3.createElement(
7532
- "button",
7533
- {
7534
- onClick: handleUnlock,
7535
- disabled: unlocking,
7536
- style: {
7537
- flex: 1,
7538
- padding: "10px 0",
7539
- background: "var(--dc-accent)",
7540
- color: "var(--dc-accent-text)",
7541
- border: "none",
7542
- borderRadius: 10,
7543
- fontSize: 13,
7544
- fontWeight: 700,
7545
- cursor: unlocking ? "not-allowed" : "pointer",
7546
- fontFamily: "inherit",
7547
- opacity: unlocking ? 0.7 : 1
7548
- }
7549
- },
7550
- unlocking ? "Unlocking\u2026" : "\u{1F513} Unlock wallet"
7551
- ), /* @__PURE__ */ React3.createElement(
7552
- "button",
7553
- {
7554
- onClick: handleDisconnect,
7555
- disabled: disconnecting,
7556
- style: {
7557
- flex: socialAuth.isUnlocked ? 1 : 0,
7558
- padding: "10px 16px",
7559
- background: "transparent",
7560
- border: "1px solid var(--dc-border)",
7561
- borderRadius: 10,
7562
- color: "var(--dc-text-muted)",
7563
- fontSize: 13,
7564
- cursor: disconnecting ? "not-allowed" : "pointer",
7565
- fontFamily: "inherit",
7566
- opacity: disconnecting ? 0.7 : 1,
7567
- whiteSpace: "nowrap"
7568
- }
7569
- },
7570
- disconnecting ? "Signing out\u2026" : "Sign out"
7571
- ))), /* @__PURE__ */ React3.createElement("div", { style: {
7572
- padding: "11px 16px",
7573
- borderTop: "1px solid var(--dc-border)",
7574
- display: "flex",
7575
- alignItems: "center",
7576
- justifyContent: "center",
7577
- gap: 6
7578
- } }, /* @__PURE__ */ React3.createElement("span", { style: { fontSize: 10.5, color: "var(--dc-text-muted)", letterSpacing: "0.02em" } }, "Secured by"), /* @__PURE__ */ React3.createElement(DecaneMark, { size: 13, muted: true }), /* @__PURE__ */ React3.createElement(DecaneWordmark, { size: 11, muted: true })))
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)))
7579
7427
  );
7580
7428
  return createPortal2(modal, document.body);
7581
7429
  }