decane-connect-kit 2.27.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.cjs +314 -443
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +14 -2
- package/dist/index.d.ts +14 -2
- package/dist/index.js +313 -443
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -59,11 +59,12 @@ __export(errors_exports, {
|
|
|
59
59
|
UnlockTokenRejectedError: () => UnlockTokenRejectedError,
|
|
60
60
|
UserCancelledError: () => UserCancelledError,
|
|
61
61
|
WalletEnrolmentError: () => WalletEnrolmentError,
|
|
62
|
+
WalletExistsError: () => WalletExistsError,
|
|
62
63
|
WebAuthnNotSupportedError: () => WebAuthnNotSupportedError,
|
|
63
64
|
WrongPasswordError: () => WrongPasswordError,
|
|
64
65
|
WrongUnlockPasswordError: () => WrongUnlockPasswordError
|
|
65
66
|
});
|
|
66
|
-
var DecaneConnectError, InvalidApiKeyError, OriginNotAllowedError, SessionExpiredError, UnlockRequiredError, ReconnectRequiredError, UserCancelledError, WebAuthnNotSupportedError, InvalidPinError, CallSequenceError, NetworkError, ShareCorruptedError, ProvisioningTimeoutError, NewDeviceError, StaleDeviceShareError, PromptPinNotConfiguredError, PromptPasswordNotConfiguredError, WrongUnlockPasswordError, InvalidAccessTokenError, UnlockTokenRejectedError, AttestationError, RecoveryFailedError, InvalidRecoveryFileError, WrongPasswordError, RecoveryWalletMismatchError, ExportNotAuthorizedError, WalletEnrolmentError, ProvisioningRateLimitedError, EnclaveHttpError;
|
|
67
|
+
var DecaneConnectError, InvalidApiKeyError, OriginNotAllowedError, SessionExpiredError, UnlockRequiredError, ReconnectRequiredError, UserCancelledError, WebAuthnNotSupportedError, InvalidPinError, CallSequenceError, NetworkError, ShareCorruptedError, ProvisioningTimeoutError, NewDeviceError, StaleDeviceShareError, PromptPinNotConfiguredError, PromptPasswordNotConfiguredError, WrongUnlockPasswordError, InvalidAccessTokenError, UnlockTokenRejectedError, AttestationError, RecoveryFailedError, InvalidRecoveryFileError, WrongPasswordError, RecoveryWalletMismatchError, ExportNotAuthorizedError, WalletExistsError, WalletEnrolmentError, ProvisioningRateLimitedError, EnclaveHttpError;
|
|
67
68
|
var init_errors = __esm({
|
|
68
69
|
"src/social/errors.ts"() {
|
|
69
70
|
"use strict";
|
|
@@ -212,6 +213,11 @@ var init_errors = __esm({
|
|
|
212
213
|
super("EXPORT_NOT_AUTHORIZED", "Export requires a fresh security check", true);
|
|
213
214
|
}
|
|
214
215
|
};
|
|
216
|
+
WalletExistsError = class extends DecaneConnectError {
|
|
217
|
+
constructor() {
|
|
218
|
+
super("WALLET_EXISTS", "This account already has a wallet; opening it instead.", true);
|
|
219
|
+
}
|
|
220
|
+
};
|
|
215
221
|
WalletEnrolmentError = class extends DecaneConnectError {
|
|
216
222
|
constructor(cause) {
|
|
217
223
|
super(
|
|
@@ -279,6 +285,7 @@ __export(index_exports, {
|
|
|
279
285
|
UnlockTokenRejectedError: () => UnlockTokenRejectedError,
|
|
280
286
|
UserCancelledError: () => UserCancelledError,
|
|
281
287
|
WalletEnrolmentError: () => WalletEnrolmentError,
|
|
288
|
+
WalletExistsError: () => WalletExistsError,
|
|
282
289
|
WalletSelector: () => WalletSelector,
|
|
283
290
|
WeakPasswordError: () => WeakPasswordError,
|
|
284
291
|
WebAuthnNotSupportedError: () => WebAuthnNotSupportedError,
|
|
@@ -2109,7 +2116,9 @@ var ERROR_MAP = {
|
|
|
2109
2116
|
// The backend's authMiddleware code for an expired/revoked JWT. Surfacing it
|
|
2110
2117
|
// as ReconnectRequiredError routes callers to the sign-in UI instead of a
|
|
2111
2118
|
// generic failure message.
|
|
2112
|
-
UNAUTHORIZED: ReconnectRequiredError
|
|
2119
|
+
UNAUTHORIZED: ReconnectRequiredError,
|
|
2120
|
+
// A restorable wallet already exists: the client provisions instead of creating.
|
|
2121
|
+
WALLET_EXISTS: WalletExistsError
|
|
2113
2122
|
};
|
|
2114
2123
|
var REQUEST_TIMEOUT_MS = 3e4;
|
|
2115
2124
|
var ApiClient = class {
|
|
@@ -2509,7 +2518,7 @@ function dropCollateral(teeUrl) {
|
|
|
2509
2518
|
// src/social/attestation.ts
|
|
2510
2519
|
init_errors();
|
|
2511
2520
|
|
|
2512
|
-
//
|
|
2521
|
+
// ../infra/tee-measurement.json
|
|
2513
2522
|
var tee_measurement_default = {
|
|
2514
2523
|
signerVersion: "0.2.10",
|
|
2515
2524
|
acceptedMrtd: [
|
|
@@ -4471,24 +4480,37 @@ async function createDecaneConnect(config) {
|
|
|
4471
4480
|
if (unlockTokenKey) await attachUnlockToken(userId, jwt, unlockTokenKey);
|
|
4472
4481
|
}
|
|
4473
4482
|
const serverIv = generateRandomBytes(12);
|
|
4474
|
-
|
|
4475
|
-
|
|
4476
|
-
|
|
4477
|
-
|
|
4478
|
-
|
|
4479
|
-
|
|
4480
|
-
|
|
4481
|
-
|
|
4482
|
-
|
|
4483
|
-
|
|
4484
|
-
|
|
4485
|
-
|
|
4486
|
-
|
|
4487
|
-
|
|
4488
|
-
|
|
4489
|
-
|
|
4490
|
-
|
|
4491
|
-
|
|
4483
|
+
try {
|
|
4484
|
+
await withDeadline(api.putShare(jwt, {
|
|
4485
|
+
ciphertext: shareSet.server,
|
|
4486
|
+
iv: serverIv,
|
|
4487
|
+
wrappedShareMeta: {
|
|
4488
|
+
// The server records this on the wallet_created event and nothing else.
|
|
4489
|
+
unlockMethod: identityTier ? "identity" : unlockMethod
|
|
4490
|
+
// credential IDs, prfSalt, pinSalt stay on-device — never sent to server
|
|
4491
|
+
},
|
|
4492
|
+
evmAddress,
|
|
4493
|
+
solanaAddress,
|
|
4494
|
+
tronAddress,
|
|
4495
|
+
// Provisional until the enclave has sealed the auth share, just below. A
|
|
4496
|
+
// backend that knows the flag keeps this row invisible to hasShare until
|
|
4497
|
+
// then, so a creation that fails past this point leaves no wallet behind
|
|
4498
|
+
// and the next sign-in simply creates again — with a new key, which is
|
|
4499
|
+
// why the backend also replaces the recorded addresses outright.
|
|
4500
|
+
pendingEnrolment: true
|
|
4501
|
+
}), remainingBudget(), "storing your wallet");
|
|
4502
|
+
} catch (e) {
|
|
4503
|
+
if (e instanceof WalletExistsError) {
|
|
4504
|
+
zeroize(shareSet.server);
|
|
4505
|
+
zeroize(shareSet.device);
|
|
4506
|
+
zeroize(shareSet.recovery);
|
|
4507
|
+
if (wrappingKey) await storage2.deleteShare(userId).catch(() => {
|
|
4508
|
+
});
|
|
4509
|
+
events.emit("wallet-unlocking");
|
|
4510
|
+
return returningUserUnlock(userId, jwt);
|
|
4511
|
+
}
|
|
4512
|
+
throw e;
|
|
4513
|
+
}
|
|
4492
4514
|
zeroize(shareSet.server);
|
|
4493
4515
|
try {
|
|
4494
4516
|
await enrolBlocking(jwt, new Uint8Array(shareSet.recovery), remainingBudget());
|
|
@@ -5579,6 +5601,7 @@ var tokens = {
|
|
|
5579
5601
|
accent: "#F5C800",
|
|
5580
5602
|
accentHover: "#D4A800",
|
|
5581
5603
|
accentText: "#0D0D0B",
|
|
5604
|
+
accentInk: "#7A5F00",
|
|
5582
5605
|
badgeEvm: "#1A1917",
|
|
5583
5606
|
badgeEvmText: "#F5C800",
|
|
5584
5607
|
badgeSolana: "#F5C800",
|
|
@@ -5599,6 +5622,7 @@ var tokens = {
|
|
|
5599
5622
|
accent: "#F5C800",
|
|
5600
5623
|
accentHover: "#FFE04D",
|
|
5601
5624
|
accentText: "#0D0D0B",
|
|
5625
|
+
accentInk: "#F5C800",
|
|
5602
5626
|
badgeEvm: "#F5C800",
|
|
5603
5627
|
badgeEvmText: "#0D0D0B",
|
|
5604
5628
|
badgeSolana: "#1A1917",
|
|
@@ -5624,6 +5648,7 @@ var CSS_VARS = {
|
|
|
5624
5648
|
--dc-accent: ${tokens.light.accent};
|
|
5625
5649
|
--dc-accent-hover: ${tokens.light.accentHover};
|
|
5626
5650
|
--dc-accent-text: ${tokens.light.accentText};
|
|
5651
|
+
--dc-accent-ink: ${tokens.light.accentInk};
|
|
5627
5652
|
--dc-badge-evm: ${tokens.light.badgeEvm};
|
|
5628
5653
|
--dc-badge-evm-text: ${tokens.light.badgeEvmText};
|
|
5629
5654
|
--dc-badge-sol: ${tokens.light.badgeSolana};
|
|
@@ -5645,6 +5670,7 @@ var CSS_VARS = {
|
|
|
5645
5670
|
--dc-accent: ${tokens.dark.accent};
|
|
5646
5671
|
--dc-accent-hover: ${tokens.dark.accentHover};
|
|
5647
5672
|
--dc-accent-text: ${tokens.dark.accentText};
|
|
5673
|
+
--dc-accent-ink: ${tokens.dark.accentInk};
|
|
5648
5674
|
--dc-badge-evm: ${tokens.dark.badgeEvm};
|
|
5649
5675
|
--dc-badge-evm-text: ${tokens.dark.badgeEvmText};
|
|
5650
5676
|
--dc-badge-sol: ${tokens.dark.badgeSolana};
|
|
@@ -5806,6 +5832,54 @@ function XLogo({ size = 14 }) {
|
|
|
5806
5832
|
/* @__PURE__ */ import_react.default.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" })
|
|
5807
5833
|
);
|
|
5808
5834
|
}
|
|
5835
|
+
var line = {
|
|
5836
|
+
fill: "none",
|
|
5837
|
+
stroke: "currentColor",
|
|
5838
|
+
strokeWidth: 1.8,
|
|
5839
|
+
strokeLinecap: "round",
|
|
5840
|
+
strokeLinejoin: "round"
|
|
5841
|
+
};
|
|
5842
|
+
function GoogleMark({ size = 18 }) {
|
|
5843
|
+
return /* @__PURE__ */ import_react.default.createElement("svg", { width: size, height: size, viewBox: "0 0 48 48", "aria-hidden": "true", style: { flexShrink: 0 } }, /* @__PURE__ */ import_react.default.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__ */ import_react.default.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__ */ import_react.default.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__ */ import_react.default.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" }));
|
|
5844
|
+
}
|
|
5845
|
+
function MailIcon({ size = 18 }) {
|
|
5846
|
+
return /* @__PURE__ */ import_react.default.createElement("svg", { width: size, height: size, viewBox: "0 0 24 24", ...line, "aria-hidden": "true", style: { flexShrink: 0 } }, /* @__PURE__ */ import_react.default.createElement("rect", { x: "3", y: "5", width: "18", height: "14", rx: "2.5" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "m3.5 7 8.5 6 8.5-6" }));
|
|
5847
|
+
}
|
|
5848
|
+
function PhoneIcon({ size = 18 }) {
|
|
5849
|
+
return /* @__PURE__ */ import_react.default.createElement("svg", { width: size, height: size, viewBox: "0 0 24 24", ...line, "aria-hidden": "true", style: { flexShrink: 0 } }, /* @__PURE__ */ import_react.default.createElement("rect", { x: "7", y: "2.5", width: "10", height: "19", rx: "2.5" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M11 18h2" }));
|
|
5850
|
+
}
|
|
5851
|
+
function ChatIcon({ size = 18 }) {
|
|
5852
|
+
return /* @__PURE__ */ import_react.default.createElement("svg", { width: size, height: size, viewBox: "0 0 24 24", ...line, "aria-hidden": "true", style: { flexShrink: 0 } }, /* @__PURE__ */ import_react.default.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__ */ import_react.default.createElement("path", { d: "M8.5 9h7M8.5 12.5h4.5" }));
|
|
5853
|
+
}
|
|
5854
|
+
function KeyIcon({ size = 18 }) {
|
|
5855
|
+
return /* @__PURE__ */ import_react.default.createElement("svg", { width: size, height: size, viewBox: "0 0 24 24", ...line, "aria-hidden": "true", style: { flexShrink: 0 } }, /* @__PURE__ */ import_react.default.createElement("circle", { cx: "8", cy: "12", r: "4" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M12 12h9M18 12v3M15 12v2.5" }));
|
|
5856
|
+
}
|
|
5857
|
+
function UserIcon({ size = 18 }) {
|
|
5858
|
+
return /* @__PURE__ */ import_react.default.createElement("svg", { width: size, height: size, viewBox: "0 0 24 24", ...line, "aria-hidden": "true", style: { flexShrink: 0 } }, /* @__PURE__ */ import_react.default.createElement("circle", { cx: "12", cy: "8.5", r: "3.8" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M4.5 20a7.5 7.5 0 0 1 15 0" }));
|
|
5859
|
+
}
|
|
5860
|
+
function CopyIcon({ size = 15 }) {
|
|
5861
|
+
return /* @__PURE__ */ import_react.default.createElement("svg", { width: size, height: size, viewBox: "0 0 24 24", ...line, "aria-hidden": "true", style: { flexShrink: 0 } }, /* @__PURE__ */ import_react.default.createElement("rect", { x: "8.5", y: "8.5", width: "12", height: "12", rx: "2.5" }), /* @__PURE__ */ import_react.default.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" }));
|
|
5862
|
+
}
|
|
5863
|
+
function CheckIcon({ size = 15 }) {
|
|
5864
|
+
return /* @__PURE__ */ import_react.default.createElement("svg", { width: size, height: size, viewBox: "0 0 24 24", ...line, "aria-hidden": "true", style: { flexShrink: 0 } }, /* @__PURE__ */ import_react.default.createElement("path", { d: "m5 12.5 4.5 4.5L19 7.5" }));
|
|
5865
|
+
}
|
|
5866
|
+
function CloseIcon({ size = 16 }) {
|
|
5867
|
+
return /* @__PURE__ */ import_react.default.createElement("svg", { width: size, height: size, viewBox: "0 0 24 24", ...line, "aria-hidden": "true", style: { flexShrink: 0 } }, /* @__PURE__ */ import_react.default.createElement("path", { d: "M6 6l12 12M18 6 6 18" }));
|
|
5868
|
+
}
|
|
5869
|
+
function ChevronIcon({ size = 16, open = false }) {
|
|
5870
|
+
return /* @__PURE__ */ import_react.default.createElement(
|
|
5871
|
+
"svg",
|
|
5872
|
+
{
|
|
5873
|
+
width: size,
|
|
5874
|
+
height: size,
|
|
5875
|
+
viewBox: "0 0 24 24",
|
|
5876
|
+
...line,
|
|
5877
|
+
"aria-hidden": "true",
|
|
5878
|
+
style: { flexShrink: 0, transition: "transform .2s", transform: open ? "rotate(180deg)" : "none" }
|
|
5879
|
+
},
|
|
5880
|
+
/* @__PURE__ */ import_react.default.createElement("path", { d: "m6 9 6 6 6-6" })
|
|
5881
|
+
);
|
|
5882
|
+
}
|
|
5809
5883
|
|
|
5810
5884
|
// src/ui/WalletSelector.tsx
|
|
5811
5885
|
var FONT_URL = "https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&display=swap";
|
|
@@ -6869,33 +6943,6 @@ function downloadJson(data, filename) {
|
|
|
6869
6943
|
a.click();
|
|
6870
6944
|
URL.revokeObjectURL(url);
|
|
6871
6945
|
}
|
|
6872
|
-
function CopyButton({ value }) {
|
|
6873
|
-
const [copied, setCopied] = (0, import_react3.useState)(false);
|
|
6874
|
-
async function copy() {
|
|
6875
|
-
await navigator.clipboard.writeText(value).catch(() => {
|
|
6876
|
-
});
|
|
6877
|
-
setCopied(true);
|
|
6878
|
-
setTimeout(() => setCopied(false), 1500);
|
|
6879
|
-
}
|
|
6880
|
-
return /* @__PURE__ */ import_react3.default.createElement(
|
|
6881
|
-
"button",
|
|
6882
|
-
{
|
|
6883
|
-
onClick: copy,
|
|
6884
|
-
style: {
|
|
6885
|
-
background: "none",
|
|
6886
|
-
border: "none",
|
|
6887
|
-
cursor: "pointer",
|
|
6888
|
-
color: copied ? "var(--dc-accent)" : "var(--dc-text-muted)",
|
|
6889
|
-
fontSize: 11,
|
|
6890
|
-
fontFamily: "inherit",
|
|
6891
|
-
padding: "2px 6px",
|
|
6892
|
-
borderRadius: 5,
|
|
6893
|
-
transition: "color 0.15s"
|
|
6894
|
-
}
|
|
6895
|
-
},
|
|
6896
|
-
copied ? "\u2713" : "copy"
|
|
6897
|
-
);
|
|
6898
|
-
}
|
|
6899
6946
|
function useBalance(kind, address, chain, rpcUrls) {
|
|
6900
6947
|
const [state, setState] = (0, import_react3.useState)({ loading: false, value: null, symbol: kind === "evm" ? "ETH" : "SOL" });
|
|
6901
6948
|
(0, import_react3.useEffect)(() => {
|
|
@@ -6913,6 +6960,117 @@ function useBalance(kind, address, chain, rpcUrls) {
|
|
|
6913
6960
|
}, [kind, address, chain, rpcUrls]);
|
|
6914
6961
|
return state;
|
|
6915
6962
|
}
|
|
6963
|
+
var MODAL_CSS = `
|
|
6964
|
+
.dcm-card { position: relative; width: 100%; max-width: 380px; max-height: calc(100vh - 32px); overflow-y: auto;
|
|
6965
|
+
background: var(--dc-bg); color: var(--dc-text); border: 1px solid var(--dc-border); border-radius: 24px;
|
|
6966
|
+
box-shadow: 0 24px 64px -12px rgba(0,0,0,.35), 0 2px 8px rgba(0,0,0,.08);
|
|
6967
|
+
animation: dcm-in .22s cubic-bezier(.2,.8,.2,1); box-sizing: border-box; }
|
|
6968
|
+
.dcm-card *, .dcm-card *::before, .dcm-card *::after { box-sizing: border-box; }
|
|
6969
|
+
@keyframes dcm-in { from { opacity: 0; transform: translateY(8px) scale(.985); } to { opacity: 1; transform: none; } }
|
|
6970
|
+
@keyframes dcm-fade { from { opacity: 0; } to { opacity: 1; } }
|
|
6971
|
+
@media (prefers-reduced-motion: reduce) { .dcm-card, .dcm-backdrop { animation: none !important; } }
|
|
6972
|
+
.dcm-backdrop { position: absolute; inset: 0; background: var(--dc-bg-overlay);
|
|
6973
|
+
backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); animation: dcm-fade .2s ease; }
|
|
6974
|
+
.dcm-icon-btn { position: absolute; top: 14px; width: 32px; height: 32px; border-radius: 10px; border: 0;
|
|
6975
|
+
background: transparent; color: var(--dc-text-muted); cursor: pointer; display: grid; place-items: center;
|
|
6976
|
+
padding: 0; transition: background .15s, color .15s; z-index: 1; }
|
|
6977
|
+
.dcm-icon-btn:hover { background: var(--dc-surface-hover); color: var(--dc-text); }
|
|
6978
|
+
.dcm-body { padding: 32px 24px 20px; display: flex; flex-direction: column; align-items: center; gap: 14px; text-align: center; }
|
|
6979
|
+
.dcm-title { margin: 4px 0 0; font-size: 20px; font-weight: 600; letter-spacing: -0.02em; line-height: 1.25; color: var(--dc-text); }
|
|
6980
|
+
.dcm-sub { margin: -6px 0 2px; font-size: 13.5px; line-height: 1.5; color: var(--dc-text-secondary); overflow-wrap: anywhere; }
|
|
6981
|
+
.dcm-sub b { color: var(--dc-text); font-weight: 600; }
|
|
6982
|
+
.dcm-methods { width: 100%; display: grid; gap: 8px; margin-top: 4px; }
|
|
6983
|
+
.dcm-method { width: 100%; height: 48px; display: flex; align-items: center; gap: 12px; padding: 0 14px;
|
|
6984
|
+
border-radius: 14px; border: 1px solid var(--dc-border); background: var(--dc-surface); color: var(--dc-text);
|
|
6985
|
+
font-weight: 500; font-size: 14.5px; line-height: 1; font-family: inherit; cursor: pointer; text-align: left;
|
|
6986
|
+
transition: border-color .15s, background .15s; }
|
|
6987
|
+
.dcm-method:hover:not(:disabled) { border-color: var(--dc-text-muted); background: var(--dc-surface-hover); }
|
|
6988
|
+
.dcm-method:disabled { opacity: .6; cursor: default; }
|
|
6989
|
+
.dcm-method:focus-visible, .dcm-primary:focus-visible, .dcm-link:focus-visible, .dcm-icon-btn:focus-visible,
|
|
6990
|
+
.dcm-ghost:focus-visible, .dcm-copy:focus-visible { outline: 2px solid var(--dc-accent); outline-offset: 2px; }
|
|
6991
|
+
.dcm-method > svg { color: var(--dc-text-secondary); }
|
|
6992
|
+
.dcm-method-input { cursor: text; padding-right: 6px; }
|
|
6993
|
+
.dcm-method-input:focus-within { border-color: var(--dc-accent); }
|
|
6994
|
+
.dcm-method-input input { flex: 1; min-width: 0; height: 100%; border: 0; outline: 0; background: transparent;
|
|
6995
|
+
color: var(--dc-text); font-family: inherit; font-size: 14.5px; padding: 0; }
|
|
6996
|
+
.dcm-method-input input::placeholder { color: var(--dc-text-muted); }
|
|
6997
|
+
.dcm-submit { height: 34px; padding: 0 12px; border-radius: 10px; border: 0; background: transparent;
|
|
6998
|
+
color: var(--dc-accent-ink); font-weight: 600; font-size: 13.5px; line-height: 1; font-family: inherit; cursor: pointer; transition: background .15s; }
|
|
6999
|
+
.dcm-submit:hover:not(:disabled) { background: var(--dc-surface-hover); }
|
|
7000
|
+
.dcm-submit:disabled { color: var(--dc-text-muted); cursor: default; }
|
|
7001
|
+
.dcm-form { width: 100%; display: grid; gap: 10px; margin-top: 4px; }
|
|
7002
|
+
.dcm-field { width: 100%; padding: 12px 14px; border-radius: 12px; border: 1px solid var(--dc-border);
|
|
7003
|
+
background: var(--dc-surface); color: var(--dc-text); font-family: inherit; font-size: 15px; outline: none;
|
|
7004
|
+
transition: border-color .15s, box-shadow .15s; }
|
|
7005
|
+
.dcm-field::placeholder { color: var(--dc-text-muted); }
|
|
7006
|
+
.dcm-field:focus { border-color: var(--dc-accent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--dc-accent) 22%, transparent); }
|
|
7007
|
+
.dcm-code { height: 56px; text-align: center; font-family: var(--dc-font-mono); font-size: 24px; letter-spacing: .45em; padding-left: calc(14px + .45em); }
|
|
7008
|
+
.dcm-primary { width: 100%; height: 48px; border-radius: 14px; border: 0; background: var(--dc-accent); color: var(--dc-accent-text);
|
|
7009
|
+
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;
|
|
7010
|
+
transition: background .15s, opacity .15s; }
|
|
7011
|
+
.dcm-primary:hover:not(:disabled) { background: var(--dc-accent-hover); }
|
|
7012
|
+
.dcm-primary:disabled { opacity: .55; cursor: default; }
|
|
7013
|
+
.dcm-ghost { height: 44px; padding: 0 16px; border-radius: 12px; border: 1px solid var(--dc-border); background: transparent;
|
|
7014
|
+
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; }
|
|
7015
|
+
.dcm-ghost:hover:not(:disabled) { background: var(--dc-surface-hover); border-color: var(--dc-text-muted); }
|
|
7016
|
+
.dcm-ghost:disabled { opacity: .55; cursor: default; }
|
|
7017
|
+
.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;
|
|
7018
|
+
cursor: pointer; padding: 4px; border-radius: 6px; }
|
|
7019
|
+
.dcm-link:hover { text-decoration: underline; text-underline-offset: 3px; }
|
|
7020
|
+
.dcm-badge { width: 52px; height: 52px; border-radius: 16px; display: grid; place-items: center;
|
|
7021
|
+
background: var(--dc-surface); border: 1px solid var(--dc-border); color: var(--dc-text); }
|
|
7022
|
+
.dcm-error { margin: 0; width: 100%; font-size: 13px; line-height: 1.45; color: var(--dc-danger); overflow-wrap: anywhere; }
|
|
7023
|
+
.dcm-protected { width: 100%; display: flex; align-items: center; justify-content: center; gap: 6px;
|
|
7024
|
+
margin-top: 6px; padding-top: 14px; border-top: 1px solid var(--dc-border); font-size: 12.5px; color: var(--dc-text-muted); }
|
|
7025
|
+
.dcm-status { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; font-weight: 500; }
|
|
7026
|
+
.dcm-status i { width: 7px; height: 7px; border-radius: 50%; display: block; }
|
|
7027
|
+
.dcm-addresses { width: 100%; border: 1px solid var(--dc-border); border-radius: 16px; overflow: hidden; text-align: left; }
|
|
7028
|
+
.dcm-address { display: flex; align-items: center; gap: 12px; padding: 12px 14px; background: var(--dc-surface); }
|
|
7029
|
+
.dcm-address + .dcm-address { border-top: 1px solid var(--dc-border); }
|
|
7030
|
+
.dcm-address-main { flex: 1; min-width: 0; display: grid; gap: 3px; }
|
|
7031
|
+
.dcm-address-main span { font-size: 13px; color: var(--dc-text-secondary); }
|
|
7032
|
+
.dcm-address-main code { font-family: var(--dc-font-mono); font-size: 13px; color: var(--dc-text); }
|
|
7033
|
+
.dcm-balance { font-family: var(--dc-font-mono); font-size: 13px; color: var(--dc-text); white-space: nowrap; }
|
|
7034
|
+
.dcm-copy { width: 30px; height: 30px; border-radius: 9px; border: 0; background: transparent; color: var(--dc-text-muted);
|
|
7035
|
+
display: grid; place-items: center; cursor: pointer; padding: 0; transition: background .15s, color .15s; }
|
|
7036
|
+
.dcm-copy:hover { background: var(--dc-surface-hover); color: var(--dc-text); }
|
|
7037
|
+
.dcm-panel { width: 100%; border: 1px solid var(--dc-border); border-radius: 16px; text-align: left; overflow: hidden; }
|
|
7038
|
+
.dcm-panel-head { width: 100%; display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 13px 14px;
|
|
7039
|
+
border: 0; background: var(--dc-surface); color: var(--dc-text); font-weight: 500; font-size: 14px; line-height: 1; font-family: inherit; cursor: pointer; }
|
|
7040
|
+
.dcm-panel-head:hover { background: var(--dc-surface-hover); }
|
|
7041
|
+
.dcm-panel-head svg { color: var(--dc-text-muted); }
|
|
7042
|
+
.dcm-panel-body { padding: 14px; border-top: 1px solid var(--dc-border); display: grid; gap: 10px; }
|
|
7043
|
+
.dcm-note { margin: 0; font-size: 13px; line-height: 1.5; color: var(--dc-text-secondary); }
|
|
7044
|
+
.dcm-warn { padding: 12px; border-radius: 12px; font-size: 13px; line-height: 1.5;
|
|
7045
|
+
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); }
|
|
7046
|
+
.dcm-warn strong { display: block; margin-bottom: 2px; color: var(--dc-danger); font-weight: 600; }
|
|
7047
|
+
.dcm-check { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--dc-text); cursor: pointer; }
|
|
7048
|
+
.dcm-check input { width: 16px; height: 16px; margin: 0; accent-color: var(--dc-accent); }
|
|
7049
|
+
.dcm-row { display: flex; gap: 8px; width: 100%; }
|
|
7050
|
+
.dcm-row > .dcm-primary { flex: 1; height: 44px; border-radius: 12px; }
|
|
7051
|
+
.dcm-actions { width: 100%; display: flex; gap: 8px; }
|
|
7052
|
+
.dcm-actions > * { flex: 1; }
|
|
7053
|
+
`;
|
|
7054
|
+
function injectModalCss() {
|
|
7055
|
+
if (document.getElementById("decane-modal-css")) return;
|
|
7056
|
+
const el = document.createElement("style");
|
|
7057
|
+
el.id = "decane-modal-css";
|
|
7058
|
+
el.textContent = MODAL_CSS;
|
|
7059
|
+
document.head.appendChild(el);
|
|
7060
|
+
}
|
|
7061
|
+
function shortAddress(a, head = 6, tail = 4) {
|
|
7062
|
+
return a.length > head + tail + 1 ? `${a.slice(0, head)}\u2026${a.slice(-tail)}` : a;
|
|
7063
|
+
}
|
|
7064
|
+
function CopyButton({ value, label }) {
|
|
7065
|
+
const [copied, setCopied] = (0, import_react3.useState)(false);
|
|
7066
|
+
async function copy() {
|
|
7067
|
+
await navigator.clipboard.writeText(value).catch(() => {
|
|
7068
|
+
});
|
|
7069
|
+
setCopied(true);
|
|
7070
|
+
setTimeout(() => setCopied(false), 1500);
|
|
7071
|
+
}
|
|
7072
|
+
return /* @__PURE__ */ import_react3.default.createElement("button", { type: "button", className: "dcm-copy", onClick: copy, "aria-label": copied ? "Copied" : `Copy ${label} address`, title: copied ? "Copied" : "Copy address" }, copied ? /* @__PURE__ */ import_react3.default.createElement(CheckIcon, null) : /* @__PURE__ */ import_react3.default.createElement(CopyIcon, null));
|
|
7073
|
+
}
|
|
6916
7074
|
function AddressRow({
|
|
6917
7075
|
label,
|
|
6918
7076
|
address,
|
|
@@ -6921,14 +7079,10 @@ function AddressRow({
|
|
|
6921
7079
|
rpcUrls
|
|
6922
7080
|
}) {
|
|
6923
7081
|
const balance = useBalance(kind, address, chain, rpcUrls);
|
|
6924
|
-
|
|
6925
|
-
|
|
6926
|
-
|
|
6927
|
-
|
|
6928
|
-
borderRadius: 10,
|
|
6929
|
-
padding: "10px 14px",
|
|
6930
|
-
marginBottom: 8
|
|
6931
|
-
} }, /* @__PURE__ */ import_react3.default.createElement("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 5 } }, /* @__PURE__ */ import_react3.default.createElement("span", { style: { fontSize: 10, fontWeight: 700, color: "var(--dc-text-muted)", letterSpacing: "0.06em", textTransform: "uppercase" } }, label), /* @__PURE__ */ import_react3.default.createElement("span", { style: { fontSize: 11, fontFamily: "monospace", color: "var(--dc-text)" } }, balance.loading ? "\u2026" : `${formatBalanceDisplay(balance.value)} ${balance.symbol}`)), /* @__PURE__ */ import_react3.default.createElement("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", gap: 8 } }, /* @__PURE__ */ import_react3.default.createElement("span", { style: { fontSize: 13, fontFamily: "monospace", color: "var(--dc-text)", letterSpacing: "0.02em" } }, short), /* @__PURE__ */ import_react3.default.createElement(CopyButton, { value: address })));
|
|
7082
|
+
return /* @__PURE__ */ import_react3.default.createElement("div", { className: "dcm-address" }, /* @__PURE__ */ import_react3.default.createElement("div", { className: "dcm-address-main" }, /* @__PURE__ */ import_react3.default.createElement("span", null, label), /* @__PURE__ */ import_react3.default.createElement("code", { title: address }, shortAddress(address, 8, 6))), /* @__PURE__ */ import_react3.default.createElement("span", { className: "dcm-balance" }, balance.loading ? "\u2026" : `${formatBalanceDisplay(balance.value)} ${balance.symbol}`), /* @__PURE__ */ import_react3.default.createElement(CopyButton, { value: address, label }));
|
|
7083
|
+
}
|
|
7084
|
+
function ProtectedBy() {
|
|
7085
|
+
return /* @__PURE__ */ import_react3.default.createElement("div", { className: "dcm-protected" }, /* @__PURE__ */ import_react3.default.createElement("span", null, "Protected by"), /* @__PURE__ */ import_react3.default.createElement(DecaneMark, { size: 14, muted: true }), /* @__PURE__ */ import_react3.default.createElement(DecaneWordmark, { size: 12, muted: true }));
|
|
6932
7086
|
}
|
|
6933
7087
|
function SignInView({
|
|
6934
7088
|
onGoogleSignIn,
|
|
@@ -6962,6 +7116,7 @@ function SignInView({
|
|
|
6962
7116
|
const [showOtherMethods, setShowOtherMethods] = (0, import_react3.useState)(false);
|
|
6963
7117
|
const [error, setError] = (0, import_react3.useState)("");
|
|
6964
7118
|
const passkeyFirst = !!canUsePasskey && !!onPasskeySignIn && !showOtherMethods;
|
|
7119
|
+
const busy = googleLoading || kingsChatLoading || xLoading || customLoading || emailLoading || phoneLoading;
|
|
6965
7120
|
async function handlePasskey() {
|
|
6966
7121
|
if (!onPasskeySignIn) return;
|
|
6967
7122
|
setError("");
|
|
@@ -7015,7 +7170,7 @@ function SignInView({
|
|
|
7015
7170
|
setError("");
|
|
7016
7171
|
setEmailLoading(true);
|
|
7017
7172
|
try {
|
|
7018
|
-
await onEmailStart(email);
|
|
7173
|
+
await onEmailStart(email.trim());
|
|
7019
7174
|
setEmailSent(true);
|
|
7020
7175
|
} catch (e2) {
|
|
7021
7176
|
setError(e2.message);
|
|
@@ -7028,7 +7183,7 @@ function SignInView({
|
|
|
7028
7183
|
setError("");
|
|
7029
7184
|
setEmailLoading(true);
|
|
7030
7185
|
try {
|
|
7031
|
-
await onEmailVerify(email, code);
|
|
7186
|
+
await onEmailVerify(email.trim(), code);
|
|
7032
7187
|
} catch (e2) {
|
|
7033
7188
|
setError(e2.message);
|
|
7034
7189
|
} finally {
|
|
@@ -7041,7 +7196,7 @@ function SignInView({
|
|
|
7041
7196
|
setError("");
|
|
7042
7197
|
setPhoneLoading(true);
|
|
7043
7198
|
try {
|
|
7044
|
-
await onPhoneStart(phone);
|
|
7199
|
+
await onPhoneStart(phone.trim());
|
|
7045
7200
|
setPhoneSent(true);
|
|
7046
7201
|
} catch (e2) {
|
|
7047
7202
|
setError(e2.message);
|
|
@@ -7055,7 +7210,7 @@ function SignInView({
|
|
|
7055
7210
|
setError("");
|
|
7056
7211
|
setPhoneLoading(true);
|
|
7057
7212
|
try {
|
|
7058
|
-
await onPhoneVerify(phone, phoneCode);
|
|
7213
|
+
await onPhoneVerify(phone.trim(), phoneCode);
|
|
7059
7214
|
} catch (e2) {
|
|
7060
7215
|
setError(e2.message);
|
|
7061
7216
|
} finally {
|
|
@@ -7074,226 +7229,67 @@ function SignInView({
|
|
|
7074
7229
|
setCustomLoading(false);
|
|
7075
7230
|
}
|
|
7076
7231
|
}
|
|
7077
|
-
|
|
7078
|
-
|
|
7079
|
-
|
|
7080
|
-
|
|
7081
|
-
|
|
7082
|
-
|
|
7083
|
-
|
|
7084
|
-
|
|
7085
|
-
|
|
7086
|
-
|
|
7087
|
-
|
|
7088
|
-
|
|
7089
|
-
|
|
7090
|
-
|
|
7091
|
-
|
|
7092
|
-
|
|
7093
|
-
|
|
7094
|
-
|
|
7095
|
-
|
|
7096
|
-
|
|
7097
|
-
|
|
7098
|
-
|
|
7099
|
-
|
|
7100
|
-
|
|
7101
|
-
|
|
7102
|
-
|
|
7103
|
-
|
|
7104
|
-
|
|
7105
|
-
|
|
7106
|
-
|
|
7107
|
-
|
|
7108
|
-
|
|
7109
|
-
|
|
7110
|
-
|
|
7111
|
-
|
|
7112
|
-
|
|
7113
|
-
), /* @__PURE__ */ import_react3.default.createElement(
|
|
7114
|
-
"button",
|
|
7115
|
-
{
|
|
7116
|
-
onClick: () => setShowOtherMethods(true),
|
|
7117
|
-
style: {
|
|
7118
|
-
width: "100%",
|
|
7119
|
-
marginTop: 10,
|
|
7120
|
-
background: "none",
|
|
7121
|
-
border: "none",
|
|
7122
|
-
color: "var(--dc-text-muted)",
|
|
7123
|
-
fontSize: 12,
|
|
7124
|
-
cursor: "pointer",
|
|
7125
|
-
fontFamily: "inherit"
|
|
7126
|
-
}
|
|
7127
|
-
},
|
|
7128
|
-
"Use email or Google instead"
|
|
7129
|
-
), error && /* @__PURE__ */ import_react3.default.createElement("div", { style: { marginTop: 10, fontSize: 12, color: "var(--dc-danger, #ff5533)" } }, error)), !passkeyFirst && authMethods.includes("google") && /* @__PURE__ */ import_react3.default.createElement(
|
|
7130
|
-
"button",
|
|
7131
|
-
{
|
|
7132
|
-
onClick: handleGoogle,
|
|
7133
|
-
disabled: googleLoading,
|
|
7134
|
-
style: {
|
|
7135
|
-
width: "100%",
|
|
7136
|
-
padding: "10px 0",
|
|
7137
|
-
marginBottom: 10,
|
|
7138
|
-
background: "var(--dc-accent)",
|
|
7139
|
-
color: "var(--dc-accent-text)",
|
|
7140
|
-
border: "none",
|
|
7141
|
-
borderRadius: 10,
|
|
7142
|
-
fontSize: 13,
|
|
7143
|
-
fontWeight: 700,
|
|
7144
|
-
cursor: googleLoading ? "not-allowed" : "pointer",
|
|
7145
|
-
opacity: googleLoading ? 0.7 : 1,
|
|
7146
|
-
fontFamily: "inherit"
|
|
7147
|
-
}
|
|
7148
|
-
},
|
|
7149
|
-
googleLoading ? "Redirecting\u2026" : "Continue with Google"
|
|
7150
|
-
), !passkeyFirst && authMethods.includes("kingschat") && onKingsChatSignIn && /* @__PURE__ */ import_react3.default.createElement(
|
|
7151
|
-
"button",
|
|
7152
|
-
{
|
|
7153
|
-
onClick: handleKingsChat,
|
|
7154
|
-
disabled: kingsChatLoading,
|
|
7155
|
-
style: {
|
|
7156
|
-
width: "100%",
|
|
7157
|
-
padding: "10px 0",
|
|
7158
|
-
marginBottom: 10,
|
|
7159
|
-
background: "var(--dc-surface)",
|
|
7160
|
-
color: "var(--dc-text)",
|
|
7161
|
-
border: "1px solid var(--dc-border)",
|
|
7162
|
-
borderRadius: 10,
|
|
7163
|
-
fontSize: 13,
|
|
7164
|
-
fontWeight: 700,
|
|
7165
|
-
cursor: kingsChatLoading ? "not-allowed" : "pointer",
|
|
7166
|
-
opacity: kingsChatLoading ? 0.7 : 1,
|
|
7167
|
-
fontFamily: "inherit"
|
|
7168
|
-
}
|
|
7169
|
-
},
|
|
7170
|
-
kingsChatLoading ? "Waiting for KingsChat\u2026" : "Continue with KingsChat"
|
|
7171
|
-
), !passkeyFirst && authMethods.includes("x") && onXSignIn && /* @__PURE__ */ import_react3.default.createElement(
|
|
7172
|
-
"button",
|
|
7173
|
-
{
|
|
7174
|
-
onClick: handleX,
|
|
7175
|
-
disabled: xLoading,
|
|
7176
|
-
style: {
|
|
7177
|
-
width: "100%",
|
|
7178
|
-
padding: "10px 0",
|
|
7179
|
-
marginBottom: 10,
|
|
7180
|
-
background: "var(--dc-surface)",
|
|
7181
|
-
color: "var(--dc-text)",
|
|
7182
|
-
border: "1px solid var(--dc-border)",
|
|
7183
|
-
borderRadius: 10,
|
|
7184
|
-
fontSize: 13,
|
|
7185
|
-
fontWeight: 700,
|
|
7186
|
-
cursor: xLoading ? "not-allowed" : "pointer",
|
|
7187
|
-
opacity: xLoading ? 0.7 : 1,
|
|
7188
|
-
fontFamily: "inherit",
|
|
7189
|
-
display: "flex",
|
|
7190
|
-
alignItems: "center",
|
|
7191
|
-
justifyContent: "center",
|
|
7192
|
-
gap: 8
|
|
7193
|
-
}
|
|
7194
|
-
},
|
|
7195
|
-
/* @__PURE__ */ import_react3.default.createElement(XLogo, null),
|
|
7196
|
-
xLoading ? "Redirecting\u2026" : "Continue with X"
|
|
7197
|
-
), !passkeyFirst && authMethods.includes("email") && /* @__PURE__ */ import_react3.default.createElement(import_react3.default.Fragment, null, authMethods.includes("google") && /* @__PURE__ */ import_react3.default.createElement("div", { style: { textAlign: "center", color: "var(--dc-text-muted)", fontSize: 12, margin: "10px 0" } }, "\u2014 or \u2014"), !emailSent ? /* @__PURE__ */ import_react3.default.createElement("form", { onSubmit: handleEmailStart, style: { display: "flex", gap: 8 } }, /* @__PURE__ */ import_react3.default.createElement(
|
|
7232
|
+
function backToMethods() {
|
|
7233
|
+
setEmailSent(false);
|
|
7234
|
+
setCode("");
|
|
7235
|
+
setPhoneSent(false);
|
|
7236
|
+
setPhoneCode("");
|
|
7237
|
+
setError("");
|
|
7238
|
+
}
|
|
7239
|
+
const errorLine = error ? /* @__PURE__ */ import_react3.default.createElement("p", { className: "dcm-error", role: "alert" }, error) : null;
|
|
7240
|
+
if (passkeyFirst) {
|
|
7241
|
+
return /* @__PURE__ */ import_react3.default.createElement("div", { className: "dcm-body" }, /* @__PURE__ */ import_react3.default.createElement("div", { className: "dcm-badge" }, /* @__PURE__ */ import_react3.default.createElement(KeyIcon, { size: 22 })), /* @__PURE__ */ import_react3.default.createElement("h2", { className: "dcm-title" }, "Welcome back"), /* @__PURE__ */ import_react3.default.createElement("p", { className: "dcm-sub" }, passkeyAddress ? /* @__PURE__ */ import_react3.default.createElement(import_react3.default.Fragment, null, "Unlock ", /* @__PURE__ */ import_react3.default.createElement("b", null, shortAddress(passkeyAddress)), " with your passkey.") : "Unlock your wallet with your passkey."), /* @__PURE__ */ import_react3.default.createElement("button", { type: "button", className: "dcm-primary", onClick: handlePasskey, disabled: passkeyLoading }, passkeyLoading ? "Waiting for passkey\u2026" : "Continue with passkey"), errorLine, /* @__PURE__ */ import_react3.default.createElement("button", { type: "button", className: "dcm-link", onClick: () => {
|
|
7242
|
+
setError("");
|
|
7243
|
+
setShowOtherMethods(true);
|
|
7244
|
+
} }, "Use another sign-in method"), /* @__PURE__ */ import_react3.default.createElement(ProtectedBy, null));
|
|
7245
|
+
}
|
|
7246
|
+
if (emailSent || phoneSent) {
|
|
7247
|
+
const isEmail = emailSent;
|
|
7248
|
+
const value = isEmail ? code : phoneCode;
|
|
7249
|
+
const setValue = isEmail ? setCode : setPhoneCode;
|
|
7250
|
+
const loading = isEmail ? emailLoading : phoneLoading;
|
|
7251
|
+
return /* @__PURE__ */ import_react3.default.createElement("form", { className: "dcm-body", onSubmit: isEmail ? handleEmailVerify : handlePhoneVerify }, /* @__PURE__ */ import_react3.default.createElement("div", { className: "dcm-badge" }, isEmail ? /* @__PURE__ */ import_react3.default.createElement(MailIcon, { size: 22 }) : /* @__PURE__ */ import_react3.default.createElement(PhoneIcon, { size: 22 })), /* @__PURE__ */ import_react3.default.createElement("h2", { className: "dcm-title" }, "Enter your code"), /* @__PURE__ */ import_react3.default.createElement("p", { className: "dcm-sub" }, "We sent a 6-digit code to ", /* @__PURE__ */ import_react3.default.createElement("b", null, isEmail ? email.trim() : phone.trim())), /* @__PURE__ */ import_react3.default.createElement("div", { className: "dcm-form" }, /* @__PURE__ */ import_react3.default.createElement(
|
|
7252
|
+
"input",
|
|
7253
|
+
{
|
|
7254
|
+
className: "dcm-field dcm-code",
|
|
7255
|
+
"aria-label": "6-digit code",
|
|
7256
|
+
placeholder: "000000",
|
|
7257
|
+
value,
|
|
7258
|
+
maxLength: 6,
|
|
7259
|
+
autoFocus: true,
|
|
7260
|
+
inputMode: "numeric",
|
|
7261
|
+
autoComplete: "one-time-code",
|
|
7262
|
+
onChange: (e) => setValue(e.target.value.replace(/\D/g, ""))
|
|
7263
|
+
}
|
|
7264
|
+
), /* @__PURE__ */ import_react3.default.createElement("button", { type: "submit", className: "dcm-primary", disabled: loading || value.length < 6 }, loading ? "Verifying\u2026" : "Continue")), errorLine, /* @__PURE__ */ import_react3.default.createElement("button", { type: "button", className: "dcm-link", onClick: backToMethods }, "Use a different method"), /* @__PURE__ */ import_react3.default.createElement(ProtectedBy, null));
|
|
7265
|
+
}
|
|
7266
|
+
const showPhone = authMethods.includes("phone") && !!onPhoneStart && !!onPhoneVerify;
|
|
7267
|
+
return /* @__PURE__ */ import_react3.default.createElement("div", { className: "dcm-body" }, /* @__PURE__ */ import_react3.default.createElement(DecaneMark, { size: 44 }), /* @__PURE__ */ import_react3.default.createElement("h2", { className: "dcm-title" }, resumeHint ? "Welcome back" : "Log in or sign up"), resumeHint && /* @__PURE__ */ import_react3.default.createElement("p", { className: "dcm-sub" }, "Sign in again to resume ", resumeHint, "."), /* @__PURE__ */ import_react3.default.createElement("div", { className: "dcm-methods" }, authMethods.includes("google") && /* @__PURE__ */ import_react3.default.createElement("button", { type: "button", className: "dcm-method", onClick: handleGoogle, disabled: busy }, /* @__PURE__ */ import_react3.default.createElement(GoogleMark, { size: 18 }), /* @__PURE__ */ import_react3.default.createElement("span", null, googleLoading ? "Redirecting to Google\u2026" : "Google")), authMethods.includes("email") && /* @__PURE__ */ import_react3.default.createElement("form", { className: "dcm-method dcm-method-input", onSubmit: handleEmailStart }, /* @__PURE__ */ import_react3.default.createElement(MailIcon, { size: 18 }), /* @__PURE__ */ import_react3.default.createElement(
|
|
7198
7268
|
"input",
|
|
7199
7269
|
{
|
|
7200
7270
|
type: "email",
|
|
7201
7271
|
required: true,
|
|
7202
7272
|
placeholder: "your@email.com",
|
|
7273
|
+
"aria-label": "Email address",
|
|
7274
|
+
autoComplete: "email",
|
|
7203
7275
|
value: email,
|
|
7204
|
-
onChange: (e) => setEmail(e.target.value)
|
|
7205
|
-
|
|
7206
|
-
|
|
7207
|
-
), /* @__PURE__ */ import_react3.default.createElement("button", { type: "submit", disabled: emailLoading, style: {
|
|
7208
|
-
padding: "0 16px",
|
|
7209
|
-
background: "var(--dc-surface)",
|
|
7210
|
-
border: "1px solid var(--dc-border)",
|
|
7211
|
-
borderRadius: 8,
|
|
7212
|
-
color: "var(--dc-text)",
|
|
7213
|
-
fontSize: 13,
|
|
7214
|
-
cursor: "pointer",
|
|
7215
|
-
fontFamily: "inherit"
|
|
7216
|
-
} }, emailLoading ? "\u2026" : "Send code")) : /* @__PURE__ */ import_react3.default.createElement("form", { onSubmit: handleEmailVerify, style: { display: "flex", gap: 8 } }, /* @__PURE__ */ import_react3.default.createElement(
|
|
7217
|
-
"input",
|
|
7218
|
-
{
|
|
7219
|
-
placeholder: "6-digit code",
|
|
7220
|
-
value: code,
|
|
7221
|
-
maxLength: 6,
|
|
7222
|
-
autoFocus: true,
|
|
7223
|
-
onChange: (e) => setCode(e.target.value.replace(/\D/g, "")),
|
|
7224
|
-
style: { ...inputStyle, flex: 1, letterSpacing: 4, textAlign: "center" }
|
|
7225
|
-
}
|
|
7226
|
-
), /* @__PURE__ */ import_react3.default.createElement("button", { type: "submit", disabled: emailLoading, style: {
|
|
7227
|
-
padding: "0 16px",
|
|
7228
|
-
background: "var(--dc-accent)",
|
|
7229
|
-
color: "var(--dc-accent-text)",
|
|
7230
|
-
border: "none",
|
|
7231
|
-
borderRadius: 8,
|
|
7232
|
-
fontSize: 13,
|
|
7233
|
-
fontWeight: 700,
|
|
7234
|
-
cursor: "pointer",
|
|
7235
|
-
fontFamily: "inherit"
|
|
7236
|
-
} }, emailLoading ? "\u2026" : "Verify"))), !passkeyFirst && authMethods.includes("phone") && onPhoneStart && onPhoneVerify && /* @__PURE__ */ import_react3.default.createElement(import_react3.default.Fragment, null, (authMethods.includes("google") || authMethods.includes("email")) && /* @__PURE__ */ import_react3.default.createElement("div", { style: { textAlign: "center", color: "var(--dc-text-muted)", fontSize: 12, margin: "10px 0" } }, "\u2014 or \u2014"), !phoneSent ? /* @__PURE__ */ import_react3.default.createElement("form", { onSubmit: handlePhoneStart, style: { display: "flex", gap: 8 } }, /* @__PURE__ */ import_react3.default.createElement(
|
|
7276
|
+
onChange: (e) => setEmail(e.target.value)
|
|
7277
|
+
}
|
|
7278
|
+
), /* @__PURE__ */ import_react3.default.createElement("button", { type: "submit", className: "dcm-submit", disabled: busy || !email.trim() }, emailLoading ? "Sending\u2026" : "Submit")), showPhone && /* @__PURE__ */ import_react3.default.createElement("form", { className: "dcm-method dcm-method-input", onSubmit: handlePhoneStart }, /* @__PURE__ */ import_react3.default.createElement(PhoneIcon, { size: 18 }), /* @__PURE__ */ import_react3.default.createElement(
|
|
7237
7279
|
"input",
|
|
7238
7280
|
{
|
|
7239
7281
|
type: "tel",
|
|
7240
7282
|
required: true,
|
|
7241
7283
|
placeholder: "+234 801 234 5678",
|
|
7284
|
+
"aria-label": "Phone number",
|
|
7285
|
+
autoComplete: "tel",
|
|
7242
7286
|
value: phone,
|
|
7243
|
-
onChange: (e) => setPhone(e.target.value)
|
|
7244
|
-
|
|
7245
|
-
|
|
7246
|
-
|
|
7247
|
-
|
|
7248
|
-
|
|
7249
|
-
border: "1px solid var(--dc-border)",
|
|
7250
|
-
borderRadius: 8,
|
|
7251
|
-
color: "var(--dc-text)",
|
|
7252
|
-
fontSize: 13,
|
|
7253
|
-
cursor: "pointer",
|
|
7254
|
-
fontFamily: "inherit"
|
|
7255
|
-
} }, phoneLoading ? "\u2026" : "Send code")) : /* @__PURE__ */ import_react3.default.createElement("form", { onSubmit: handlePhoneVerify, style: { display: "flex", gap: 8 } }, /* @__PURE__ */ import_react3.default.createElement(
|
|
7256
|
-
"input",
|
|
7257
|
-
{
|
|
7258
|
-
placeholder: "6-digit code",
|
|
7259
|
-
value: phoneCode,
|
|
7260
|
-
maxLength: 6,
|
|
7261
|
-
autoFocus: true,
|
|
7262
|
-
inputMode: "numeric",
|
|
7263
|
-
onChange: (e) => setPhoneCode(e.target.value.replace(/\D/g, "")),
|
|
7264
|
-
style: { ...inputStyle, flex: 1, letterSpacing: 4, textAlign: "center" }
|
|
7265
|
-
}
|
|
7266
|
-
), /* @__PURE__ */ import_react3.default.createElement("button", { type: "submit", disabled: phoneLoading, style: {
|
|
7267
|
-
padding: "0 16px",
|
|
7268
|
-
background: "var(--dc-accent)",
|
|
7269
|
-
color: "var(--dc-accent-text)",
|
|
7270
|
-
border: "none",
|
|
7271
|
-
borderRadius: 8,
|
|
7272
|
-
fontSize: 13,
|
|
7273
|
-
fontWeight: 700,
|
|
7274
|
-
cursor: "pointer",
|
|
7275
|
-
fontFamily: "inherit"
|
|
7276
|
-
} }, phoneLoading ? "\u2026" : "Verify"))), !passkeyFirst && customAuthLabel && onCustomAuthSignIn && /* @__PURE__ */ import_react3.default.createElement(import_react3.default.Fragment, null, (authMethods.includes("google") || authMethods.includes("email")) && /* @__PURE__ */ import_react3.default.createElement("div", { style: { textAlign: "center", color: "var(--dc-text-muted)", fontSize: 12, margin: "10px 0" } }, "\u2014 or \u2014"), /* @__PURE__ */ import_react3.default.createElement(
|
|
7277
|
-
"button",
|
|
7278
|
-
{
|
|
7279
|
-
onClick: handleCustomAuth,
|
|
7280
|
-
disabled: customLoading,
|
|
7281
|
-
style: {
|
|
7282
|
-
width: "100%",
|
|
7283
|
-
padding: "10px 0",
|
|
7284
|
-
background: "var(--dc-surface)",
|
|
7285
|
-
color: "var(--dc-text)",
|
|
7286
|
-
border: "1px solid var(--dc-border)",
|
|
7287
|
-
borderRadius: 10,
|
|
7288
|
-
fontSize: 13,
|
|
7289
|
-
fontWeight: 600,
|
|
7290
|
-
cursor: customLoading ? "not-allowed" : "pointer",
|
|
7291
|
-
opacity: customLoading ? 0.7 : 1,
|
|
7292
|
-
fontFamily: "inherit"
|
|
7293
|
-
}
|
|
7294
|
-
},
|
|
7295
|
-
customLoading ? "Connecting\u2026" : customAuthLabel
|
|
7296
|
-
)), error && /* @__PURE__ */ import_react3.default.createElement("div", { style: { marginTop: 10, fontSize: 12, color: "var(--dc-danger, #ff5533)" } }, error));
|
|
7287
|
+
onChange: (e) => setPhone(e.target.value)
|
|
7288
|
+
}
|
|
7289
|
+
), /* @__PURE__ */ import_react3.default.createElement("button", { type: "submit", className: "dcm-submit", disabled: busy || !phone.trim() }, phoneLoading ? "Sending\u2026" : "Submit")), authMethods.includes("x") && onXSignIn && /* @__PURE__ */ import_react3.default.createElement("button", { type: "button", className: "dcm-method", onClick: handleX, disabled: busy }, /* @__PURE__ */ import_react3.default.createElement(XLogo, { size: 16 }), /* @__PURE__ */ import_react3.default.createElement("span", null, xLoading ? "Redirecting to X\u2026" : "X")), authMethods.includes("kingschat") && onKingsChatSignIn && /* @__PURE__ */ import_react3.default.createElement("button", { type: "button", className: "dcm-method", onClick: handleKingsChat, disabled: busy }, /* @__PURE__ */ import_react3.default.createElement(ChatIcon, { size: 18 }), /* @__PURE__ */ import_react3.default.createElement("span", null, kingsChatLoading ? "Waiting for KingsChat\u2026" : "KingsChat")), customAuthLabel && onCustomAuthSignIn && /* @__PURE__ */ import_react3.default.createElement("button", { type: "button", className: "dcm-method", onClick: handleCustomAuth, disabled: busy }, /* @__PURE__ */ import_react3.default.createElement(UserIcon, { size: 18 }), /* @__PURE__ */ import_react3.default.createElement("span", null, customLoading ? "Connecting\u2026" : customAuthLabel))), errorLine, canUsePasskey && onPasskeySignIn && /* @__PURE__ */ import_react3.default.createElement("button", { type: "button", className: "dcm-link", onClick: () => {
|
|
7290
|
+
setError("");
|
|
7291
|
+
setShowOtherMethods(false);
|
|
7292
|
+
} }, "Use my passkey instead"), /* @__PURE__ */ import_react3.default.createElement(ProtectedBy, null));
|
|
7297
7293
|
}
|
|
7298
7294
|
function RecoverySection({
|
|
7299
7295
|
addresses,
|
|
@@ -7344,60 +7340,34 @@ function RecoverySection({
|
|
|
7344
7340
|
setBusy(false);
|
|
7345
7341
|
}
|
|
7346
7342
|
}
|
|
7347
|
-
const
|
|
7348
|
-
|
|
7349
|
-
background: "var(--dc-bg)",
|
|
7350
|
-
border: "1px solid var(--dc-border)",
|
|
7351
|
-
borderRadius: 8,
|
|
7352
|
-
color: "var(--dc-text)",
|
|
7353
|
-
padding: "8px 10px",
|
|
7354
|
-
fontSize: 12,
|
|
7355
|
-
outline: "none",
|
|
7356
|
-
fontFamily: "inherit",
|
|
7357
|
-
boxSizing: "border-box"
|
|
7358
|
-
};
|
|
7359
|
-
const btnStyle = {
|
|
7360
|
-
padding: "8px 12px",
|
|
7361
|
-
borderRadius: 8,
|
|
7362
|
-
fontSize: 12,
|
|
7363
|
-
fontWeight: 700,
|
|
7364
|
-
cursor: "pointer",
|
|
7365
|
-
fontFamily: "inherit",
|
|
7366
|
-
border: "none"
|
|
7367
|
-
};
|
|
7368
|
-
return /* @__PURE__ */ import_react3.default.createElement("div", { style: { margin: "0 16px 14px", border: "1px solid var(--dc-border)", borderRadius: 10, overflow: "hidden" } }, /* @__PURE__ */ import_react3.default.createElement(
|
|
7369
|
-
"button",
|
|
7343
|
+
const passwordFields = /* @__PURE__ */ import_react3.default.createElement(import_react3.default.Fragment, null, /* @__PURE__ */ import_react3.default.createElement(
|
|
7344
|
+
"input",
|
|
7370
7345
|
{
|
|
7371
|
-
|
|
7372
|
-
|
|
7373
|
-
|
|
7374
|
-
|
|
7375
|
-
|
|
7376
|
-
|
|
7377
|
-
|
|
7378
|
-
|
|
7379
|
-
|
|
7380
|
-
|
|
7381
|
-
|
|
7382
|
-
|
|
7383
|
-
|
|
7384
|
-
|
|
7385
|
-
|
|
7386
|
-
|
|
7346
|
+
className: "dcm-field",
|
|
7347
|
+
type: "password",
|
|
7348
|
+
placeholder: "Password (at least 8 characters)",
|
|
7349
|
+
"aria-label": "Password",
|
|
7350
|
+
autoComplete: "new-password",
|
|
7351
|
+
value: password,
|
|
7352
|
+
onChange: (e) => setPassword(e.target.value)
|
|
7353
|
+
}
|
|
7354
|
+
), /* @__PURE__ */ import_react3.default.createElement(
|
|
7355
|
+
"input",
|
|
7356
|
+
{
|
|
7357
|
+
className: "dcm-field",
|
|
7358
|
+
placeholder: "Password hint (optional)",
|
|
7359
|
+
"aria-label": "Password hint",
|
|
7360
|
+
value: passwordHint,
|
|
7361
|
+
onChange: (e) => setPasswordHint(e.target.value)
|
|
7362
|
+
}
|
|
7363
|
+
), error && /* @__PURE__ */ import_react3.default.createElement("p", { className: "dcm-error", role: "alert" }, error));
|
|
7364
|
+
return /* @__PURE__ */ import_react3.default.createElement("div", { className: "dcm-panel" }, /* @__PURE__ */ import_react3.default.createElement("button", { type: "button", className: "dcm-panel-head", onClick: () => setExpanded((v) => !v), "aria-expanded": expanded }, /* @__PURE__ */ import_react3.default.createElement("span", null, "Recovery file"), /* @__PURE__ */ import_react3.default.createElement(ChevronIcon, { open: expanded })), expanded && /* @__PURE__ */ import_react3.default.createElement("div", { className: "dcm-panel-body" }, !mode && /* @__PURE__ */ import_react3.default.createElement(import_react3.default.Fragment, null, /* @__PURE__ */ import_react3.default.createElement("p", { className: "dcm-note" }, "Save a recovery file so you can restore this wallet on a new device."), /* @__PURE__ */ import_react3.default.createElement("button", { type: "button", className: "dcm-primary", style: { height: 44, borderRadius: 12 }, onClick: () => {
|
|
7387
7365
|
reset();
|
|
7388
7366
|
setMode("share");
|
|
7389
|
-
}
|
|
7367
|
+
} }, "Download recovery-share file"), /* @__PURE__ */ import_react3.default.createElement("button", { type: "button", className: "dcm-ghost", onClick: () => {
|
|
7390
7368
|
reset();
|
|
7391
7369
|
setMode("portable");
|
|
7392
|
-
}
|
|
7393
|
-
background: "rgba(255,85,51,0.08)",
|
|
7394
|
-
border: "1px solid rgba(255,85,51,0.3)",
|
|
7395
|
-
borderRadius: 8,
|
|
7396
|
-
padding: "8px 10px",
|
|
7397
|
-
fontSize: 11,
|
|
7398
|
-
color: "#ff9977",
|
|
7399
|
-
lineHeight: 1.5
|
|
7400
|
-
} }, /* @__PURE__ */ import_react3.default.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__ */ import_react3.default.createElement("label", { style: { display: "flex", alignItems: "center", gap: 6, fontSize: 11, color: "var(--dc-text)" } }, /* @__PURE__ */ import_react3.default.createElement("input", { type: "checkbox", checked: confirmed, onChange: (e) => setConfirmed(e.target.checked), style: { width: "auto" } }), "I understand this is a bearer secret"), /* @__PURE__ */ import_react3.default.createElement("input", { type: "password", placeholder: "Password (min 8 chars)", value: password, onChange: (e) => setPassword(e.target.value), style: inputStyle }), /* @__PURE__ */ import_react3.default.createElement("input", { placeholder: "Password hint (optional)", value: passwordHint, onChange: (e) => setPasswordHint(e.target.value), style: inputStyle }), error && /* @__PURE__ */ import_react3.default.createElement("div", { style: { fontSize: 11, color: "var(--dc-danger, #ff5533)" } }, error), /* @__PURE__ */ import_react3.default.createElement("div", { style: { display: "flex", gap: 8 } }, /* @__PURE__ */ import_react3.default.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__ */ import_react3.default.createElement("button", { onClick: reset, style: { ...btnStyle, background: "transparent", border: "1px solid var(--dc-border)", color: "var(--dc-text-muted)" } }, "Cancel"))), result && /* @__PURE__ */ import_react3.default.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.")));
|
|
7370
|
+
} }, "Download full recovery file")), mode === "share" && /* @__PURE__ */ import_react3.default.createElement(import_react3.default.Fragment, null, /* @__PURE__ */ import_react3.default.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__ */ import_react3.default.createElement("div", { className: "dcm-row" }, /* @__PURE__ */ import_react3.default.createElement("button", { type: "button", className: "dcm-primary", onClick: handleGenerate, disabled: busy }, busy ? "Preparing\u2026" : "Download"), /* @__PURE__ */ import_react3.default.createElement("button", { type: "button", className: "dcm-ghost", onClick: reset }, "Cancel"))), mode === "portable" && /* @__PURE__ */ import_react3.default.createElement(import_react3.default.Fragment, null, /* @__PURE__ */ import_react3.default.createElement("div", { className: "dcm-warn" }, /* @__PURE__ */ import_react3.default.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__ */ import_react3.default.createElement("label", { className: "dcm-check" }, /* @__PURE__ */ import_react3.default.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__ */ import_react3.default.createElement("div", { className: "dcm-row" }, /* @__PURE__ */ import_react3.default.createElement("button", { type: "button", className: "dcm-primary", onClick: handleGenerate, disabled: busy || !confirmed }, busy ? "Preparing\u2026" : "Download"), /* @__PURE__ */ import_react3.default.createElement("button", { type: "button", className: "dcm-ghost", onClick: reset }, "Cancel"))), result && /* @__PURE__ */ import_react3.default.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.")));
|
|
7401
7371
|
}
|
|
7402
7372
|
function SocialWalletModal({
|
|
7403
7373
|
open,
|
|
@@ -7408,6 +7378,7 @@ function SocialWalletModal({
|
|
|
7408
7378
|
onDisconnect,
|
|
7409
7379
|
onGoogleSignIn,
|
|
7410
7380
|
onKingsChatSignIn,
|
|
7381
|
+
onXSignIn,
|
|
7411
7382
|
onEmailStart,
|
|
7412
7383
|
onEmailVerify,
|
|
7413
7384
|
onPhoneStart,
|
|
@@ -7426,9 +7397,11 @@ function SocialWalletModal({
|
|
|
7426
7397
|
const [timer, setTimer] = (0, import_react3.useState)("");
|
|
7427
7398
|
const [unlocking, setUnlocking] = (0, import_react3.useState)(false);
|
|
7428
7399
|
const [disconnecting, setDisconnecting] = (0, import_react3.useState)(false);
|
|
7400
|
+
const [actionError, setActionError] = (0, import_react3.useState)("");
|
|
7429
7401
|
(0, import_react3.useEffect)(() => {
|
|
7430
7402
|
if (!open) return;
|
|
7431
7403
|
injectTokens2(theme);
|
|
7404
|
+
injectModalCss();
|
|
7432
7405
|
if (theme !== "auto") return;
|
|
7433
7406
|
const mq = window.matchMedia("(prefers-color-scheme: dark)");
|
|
7434
7407
|
const h = () => injectTokens2("auto");
|
|
@@ -7455,17 +7428,23 @@ function SocialWalletModal({
|
|
|
7455
7428
|
if (!open) return null;
|
|
7456
7429
|
async function handleUnlock() {
|
|
7457
7430
|
setUnlocking(true);
|
|
7431
|
+
setActionError("");
|
|
7458
7432
|
try {
|
|
7459
7433
|
await onUnlock();
|
|
7434
|
+
} catch (e) {
|
|
7435
|
+
setActionError(e.message);
|
|
7460
7436
|
} finally {
|
|
7461
7437
|
setUnlocking(false);
|
|
7462
7438
|
}
|
|
7463
7439
|
}
|
|
7464
7440
|
async function handleDisconnect() {
|
|
7465
7441
|
setDisconnecting(true);
|
|
7442
|
+
setActionError("");
|
|
7466
7443
|
try {
|
|
7467
7444
|
await onDisconnect();
|
|
7468
7445
|
onClose();
|
|
7446
|
+
} catch (e) {
|
|
7447
|
+
setActionError(e.message);
|
|
7469
7448
|
} finally {
|
|
7470
7449
|
setDisconnecting(false);
|
|
7471
7450
|
}
|
|
@@ -7473,12 +7452,13 @@ function SocialWalletModal({
|
|
|
7473
7452
|
const evmChain = chains?.find((c) => c.startsWith("evm:")) ?? "evm:11155111";
|
|
7474
7453
|
const solChain = chains?.find((c) => c.startsWith("solana:")) ?? "solana:mainnet";
|
|
7475
7454
|
const showSignIn = !socialAuth.addresses || socialAuth.needsReconnect;
|
|
7455
|
+
const unlocked = socialAuth.isUnlocked;
|
|
7476
7456
|
const modal = /* @__PURE__ */ import_react3.default.createElement(
|
|
7477
7457
|
"div",
|
|
7478
7458
|
{
|
|
7479
7459
|
role: "dialog",
|
|
7480
7460
|
"aria-modal": "true",
|
|
7481
|
-
"aria-label": "
|
|
7461
|
+
"aria-label": showSignIn ? "Log in or sign up" : "Your wallet",
|
|
7482
7462
|
style: {
|
|
7483
7463
|
position: "fixed",
|
|
7484
7464
|
inset: 0,
|
|
@@ -7487,63 +7467,17 @@ function SocialWalletModal({
|
|
|
7487
7467
|
alignItems: "center",
|
|
7488
7468
|
justifyContent: "center",
|
|
7489
7469
|
padding: 16,
|
|
7490
|
-
fontFamily: "var(--dc-font-sans, system-ui, sans-serif)"
|
|
7470
|
+
fontFamily: "var(--dc-font-sans, system-ui, sans-serif)",
|
|
7471
|
+
WebkitFontSmoothing: "antialiased"
|
|
7491
7472
|
}
|
|
7492
7473
|
},
|
|
7493
|
-
/* @__PURE__ */ import_react3.default.createElement(
|
|
7494
|
-
|
|
7495
|
-
{
|
|
7496
|
-
onClick: onClose,
|
|
7497
|
-
style: {
|
|
7498
|
-
position: "absolute",
|
|
7499
|
-
inset: 0,
|
|
7500
|
-
background: "var(--dc-bg-overlay)",
|
|
7501
|
-
backdropFilter: "blur(8px)",
|
|
7502
|
-
WebkitBackdropFilter: "blur(8px)"
|
|
7503
|
-
}
|
|
7504
|
-
}
|
|
7505
|
-
),
|
|
7506
|
-
/* @__PURE__ */ import_react3.default.createElement("div", { style: {
|
|
7507
|
-
position: "relative",
|
|
7508
|
-
background: "var(--dc-bg)",
|
|
7509
|
-
border: "1px solid var(--dc-border)",
|
|
7510
|
-
borderRadius: 20,
|
|
7511
|
-
width: "100%",
|
|
7512
|
-
maxWidth: 380,
|
|
7513
|
-
maxHeight: "90vh",
|
|
7514
|
-
overflowY: "auto",
|
|
7515
|
-
boxShadow: "0 24px 64px rgba(0,0,0,0.6), 0 0 0 1px rgba(255,255,255,0.04)"
|
|
7516
|
-
} }, /* @__PURE__ */ import_react3.default.createElement("div", { style: {
|
|
7517
|
-
height: 2,
|
|
7518
|
-
position: "sticky",
|
|
7519
|
-
top: 0,
|
|
7520
|
-
zIndex: 1,
|
|
7521
|
-
background: "linear-gradient(90deg, transparent, var(--dc-accent) 30%, var(--dc-accent) 70%, transparent)"
|
|
7522
|
-
} }), /* @__PURE__ */ import_react3.default.createElement("div", { style: { padding: "18px 20px 16px", display: "flex", alignItems: "center", gap: 11 } }, /* @__PURE__ */ import_react3.default.createElement(DecaneMark, { size: 38 }), /* @__PURE__ */ import_react3.default.createElement("div", { style: { flex: 1 } }, /* @__PURE__ */ import_react3.default.createElement("div", { style: { display: "flex", alignItems: "baseline", gap: 6 } }, /* @__PURE__ */ import_react3.default.createElement(DecaneWordmark, { size: 15 }), /* @__PURE__ */ import_react3.default.createElement("span", { style: { fontSize: 13, fontWeight: 700, color: "var(--dc-text-muted)", letterSpacing: "-0.01em" } }, "wallet")), /* @__PURE__ */ import_react3.default.createElement("div", { style: { fontSize: 11, color: "var(--dc-text-muted)", marginTop: 2 } }, "Non-custodial \xB7 key split three ways")), /* @__PURE__ */ import_react3.default.createElement(
|
|
7523
|
-
"button",
|
|
7524
|
-
{
|
|
7525
|
-
onClick: onClose,
|
|
7526
|
-
style: {
|
|
7527
|
-
background: "var(--dc-surface)",
|
|
7528
|
-
border: "1px solid var(--dc-border)",
|
|
7529
|
-
borderRadius: 8,
|
|
7530
|
-
width: 28,
|
|
7531
|
-
height: 28,
|
|
7532
|
-
cursor: "pointer",
|
|
7533
|
-
display: "flex",
|
|
7534
|
-
alignItems: "center",
|
|
7535
|
-
justifyContent: "center",
|
|
7536
|
-
color: "var(--dc-text-muted)",
|
|
7537
|
-
flexShrink: 0,
|
|
7538
|
-
padding: 0
|
|
7539
|
-
}
|
|
7540
|
-
},
|
|
7541
|
-
/* @__PURE__ */ import_react3.default.createElement("svg", { width: "12", height: "12", viewBox: "0 0 12 12", fill: "none" }, /* @__PURE__ */ import_react3.default.createElement("path", { d: "M1.5 1.5L10.5 10.5M10.5 1.5L1.5 10.5", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" }))
|
|
7542
|
-
)), showSignIn ? /* @__PURE__ */ import_react3.default.createElement(
|
|
7474
|
+
/* @__PURE__ */ import_react3.default.createElement("div", { className: "dcm-backdrop", onClick: onClose }),
|
|
7475
|
+
/* @__PURE__ */ import_react3.default.createElement("div", { className: "dcm-card" }, /* @__PURE__ */ import_react3.default.createElement("button", { type: "button", className: "dcm-icon-btn", style: { right: 14 }, onClick: onClose, "aria-label": "Close" }, /* @__PURE__ */ import_react3.default.createElement(CloseIcon, null)), showSignIn ? /* @__PURE__ */ import_react3.default.createElement(
|
|
7543
7476
|
SignInView,
|
|
7544
7477
|
{
|
|
7545
7478
|
onGoogleSignIn,
|
|
7546
7479
|
onKingsChatSignIn,
|
|
7480
|
+
onXSignIn,
|
|
7547
7481
|
onEmailStart,
|
|
7548
7482
|
onEmailVerify,
|
|
7549
7483
|
onPhoneStart,
|
|
@@ -7556,86 +7490,22 @@ function SocialWalletModal({
|
|
|
7556
7490
|
passkeyAddress,
|
|
7557
7491
|
onPasskeySignIn
|
|
7558
7492
|
}
|
|
7559
|
-
) : /* @__PURE__ */ import_react3.default.createElement(import_react3.default.
|
|
7560
|
-
|
|
7561
|
-
|
|
7562
|
-
|
|
7563
|
-
|
|
7564
|
-
|
|
7565
|
-
|
|
7566
|
-
|
|
7567
|
-
|
|
7568
|
-
} }, /* @__PURE__ */ import_react3.default.createElement("div", { style: { display: "flex", alignItems: "center", gap: 8 } }, /* @__PURE__ */ import_react3.default.createElement("span", { style: {
|
|
7569
|
-
width: 7,
|
|
7570
|
-
height: 7,
|
|
7571
|
-
borderRadius: "50%",
|
|
7572
|
-
flexShrink: 0,
|
|
7573
|
-
background: socialAuth.isUnlocked ? "#12b76a" : "var(--dc-accent)",
|
|
7574
|
-
boxShadow: `0 0 6px ${socialAuth.isUnlocked ? "#12b76a" : "var(--dc-accent)"}`
|
|
7575
|
-
} }), /* @__PURE__ */ import_react3.default.createElement("span", { style: {
|
|
7576
|
-
fontSize: 12,
|
|
7577
|
-
fontWeight: 700,
|
|
7578
|
-
color: socialAuth.isUnlocked ? "#12b76a" : "var(--dc-accent)"
|
|
7579
|
-
} }, socialAuth.isUnlocked ? "Unlocked" : "Locked")), socialAuth.isUnlocked && timer && /* @__PURE__ */ import_react3.default.createElement("span", { style: { fontSize: 11, color: "var(--dc-text-muted)", fontFamily: "monospace" } }, "expires ", timer)), /* @__PURE__ */ import_react3.default.createElement("div", { style: { padding: "0 16px 14px" } }, socialAuth.addresses?.evm && /* @__PURE__ */ import_react3.default.createElement(AddressRow, { label: "EVM (Ethereum, Base, \u2026)", address: socialAuth.addresses.evm, kind: "evm", chain: evmChain, rpcUrls }), socialAuth.addresses?.solana && /* @__PURE__ */ import_react3.default.createElement(AddressRow, { label: "Solana", address: socialAuth.addresses.solana, kind: "solana", chain: solChain, rpcUrls })), socialAuth.isUnlocked && /* @__PURE__ */ import_react3.default.createElement(
|
|
7493
|
+
) : /* @__PURE__ */ import_react3.default.createElement("div", { className: "dcm-body" }, /* @__PURE__ */ import_react3.default.createElement(DecaneMark, { size: 44 }), /* @__PURE__ */ import_react3.default.createElement("h2", { className: "dcm-title" }, "Your wallet"), /* @__PURE__ */ import_react3.default.createElement(
|
|
7494
|
+
"span",
|
|
7495
|
+
{
|
|
7496
|
+
className: "dcm-status",
|
|
7497
|
+
style: { color: unlocked ? "#12b76a" : "var(--dc-accent-ink)", marginTop: -8 }
|
|
7498
|
+
},
|
|
7499
|
+
/* @__PURE__ */ import_react3.default.createElement("i", { style: { background: unlocked ? "#12b76a" : "var(--dc-accent)" } }),
|
|
7500
|
+
unlocked ? timer ? `Unlocked, expires in ${timer}` : "Unlocked" : "Locked"
|
|
7501
|
+
), (socialAuth.addresses?.evm || socialAuth.addresses?.solana) && /* @__PURE__ */ import_react3.default.createElement("div", { className: "dcm-addresses" }, socialAuth.addresses?.evm && /* @__PURE__ */ import_react3.default.createElement(AddressRow, { label: "Ethereum and EVM", address: socialAuth.addresses.evm, kind: "evm", chain: evmChain, rpcUrls }), socialAuth.addresses?.solana && /* @__PURE__ */ import_react3.default.createElement(AddressRow, { label: "Solana", address: socialAuth.addresses.solana, kind: "solana", chain: solChain, rpcUrls })), unlocked && /* @__PURE__ */ import_react3.default.createElement(
|
|
7580
7502
|
RecoverySection,
|
|
7581
7503
|
{
|
|
7582
7504
|
addresses: socialAuth.addresses,
|
|
7583
7505
|
onRotateShares,
|
|
7584
7506
|
onExportPortableBackup
|
|
7585
7507
|
}
|
|
7586
|
-
), /* @__PURE__ */ import_react3.default.createElement("div", { style: {
|
|
7587
|
-
padding: "14px 16px",
|
|
7588
|
-
borderTop: "1px solid var(--dc-border)",
|
|
7589
|
-
display: "flex",
|
|
7590
|
-
gap: 8
|
|
7591
|
-
} }, !socialAuth.isUnlocked && /* @__PURE__ */ import_react3.default.createElement(
|
|
7592
|
-
"button",
|
|
7593
|
-
{
|
|
7594
|
-
onClick: handleUnlock,
|
|
7595
|
-
disabled: unlocking,
|
|
7596
|
-
style: {
|
|
7597
|
-
flex: 1,
|
|
7598
|
-
padding: "10px 0",
|
|
7599
|
-
background: "var(--dc-accent)",
|
|
7600
|
-
color: "var(--dc-accent-text)",
|
|
7601
|
-
border: "none",
|
|
7602
|
-
borderRadius: 10,
|
|
7603
|
-
fontSize: 13,
|
|
7604
|
-
fontWeight: 700,
|
|
7605
|
-
cursor: unlocking ? "not-allowed" : "pointer",
|
|
7606
|
-
fontFamily: "inherit",
|
|
7607
|
-
opacity: unlocking ? 0.7 : 1
|
|
7608
|
-
}
|
|
7609
|
-
},
|
|
7610
|
-
unlocking ? "Unlocking\u2026" : "\u{1F513} Unlock wallet"
|
|
7611
|
-
), /* @__PURE__ */ import_react3.default.createElement(
|
|
7612
|
-
"button",
|
|
7613
|
-
{
|
|
7614
|
-
onClick: handleDisconnect,
|
|
7615
|
-
disabled: disconnecting,
|
|
7616
|
-
style: {
|
|
7617
|
-
flex: socialAuth.isUnlocked ? 1 : 0,
|
|
7618
|
-
padding: "10px 16px",
|
|
7619
|
-
background: "transparent",
|
|
7620
|
-
border: "1px solid var(--dc-border)",
|
|
7621
|
-
borderRadius: 10,
|
|
7622
|
-
color: "var(--dc-text-muted)",
|
|
7623
|
-
fontSize: 13,
|
|
7624
|
-
cursor: disconnecting ? "not-allowed" : "pointer",
|
|
7625
|
-
fontFamily: "inherit",
|
|
7626
|
-
opacity: disconnecting ? 0.7 : 1,
|
|
7627
|
-
whiteSpace: "nowrap"
|
|
7628
|
-
}
|
|
7629
|
-
},
|
|
7630
|
-
disconnecting ? "Signing out\u2026" : "Sign out"
|
|
7631
|
-
))), /* @__PURE__ */ import_react3.default.createElement("div", { style: {
|
|
7632
|
-
padding: "11px 16px",
|
|
7633
|
-
borderTop: "1px solid var(--dc-border)",
|
|
7634
|
-
display: "flex",
|
|
7635
|
-
alignItems: "center",
|
|
7636
|
-
justifyContent: "center",
|
|
7637
|
-
gap: 6
|
|
7638
|
-
} }, /* @__PURE__ */ import_react3.default.createElement("span", { style: { fontSize: 10.5, color: "var(--dc-text-muted)", letterSpacing: "0.02em" } }, "Secured by"), /* @__PURE__ */ import_react3.default.createElement(DecaneMark, { size: 13, muted: true }), /* @__PURE__ */ import_react3.default.createElement(DecaneWordmark, { size: 11, muted: true })))
|
|
7508
|
+
), actionError && /* @__PURE__ */ import_react3.default.createElement("p", { className: "dcm-error", role: "alert" }, actionError), /* @__PURE__ */ import_react3.default.createElement("div", { className: "dcm-actions" }, !unlocked && /* @__PURE__ */ import_react3.default.createElement("button", { type: "button", className: "dcm-primary", style: { height: 44, borderRadius: 12 }, onClick: handleUnlock, disabled: unlocking }, unlocking ? "Unlocking\u2026" : "Unlock wallet"), /* @__PURE__ */ import_react3.default.createElement("button", { type: "button", className: "dcm-ghost", onClick: handleDisconnect, disabled: disconnecting }, disconnecting ? "Signing out\u2026" : "Sign out")), /* @__PURE__ */ import_react3.default.createElement(ProtectedBy, null)))
|
|
7639
7509
|
);
|
|
7640
7510
|
return (0, import_react_dom2.createPortal)(modal, document.body);
|
|
7641
7511
|
}
|
|
@@ -9052,6 +8922,7 @@ function useSignTypedData() {
|
|
|
9052
8922
|
UnlockTokenRejectedError,
|
|
9053
8923
|
UserCancelledError,
|
|
9054
8924
|
WalletEnrolmentError,
|
|
8925
|
+
WalletExistsError,
|
|
9055
8926
|
WalletSelector,
|
|
9056
8927
|
WeakPasswordError,
|
|
9057
8928
|
WebAuthnNotSupportedError,
|