@swype-org/react-sdk 0.1.28 → 0.1.29
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 +365 -66
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +85 -68
- package/dist/index.d.ts +85 -68
- package/dist/index.js +367 -68
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { createContext, useRef,
|
|
2
|
-
import { PrivyProvider, usePrivy } from '@privy-io/react-auth';
|
|
1
|
+
import { createContext, useRef, useState, useCallback, useMemo, useContext, useEffect } from 'react';
|
|
2
|
+
import { PrivyProvider, usePrivy, useLoginWithEmail, useLoginWithSms } from '@privy-io/react-auth';
|
|
3
3
|
import { createConfig, http, WagmiProvider, useConfig, useConnect, useSwitchChain } from 'wagmi';
|
|
4
4
|
import { mainnet, arbitrum, base } from 'wagmi/chains';
|
|
5
5
|
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
@@ -25,9 +25,9 @@ var darkTheme = {
|
|
|
25
25
|
textMuted: "#7fa4b0",
|
|
26
26
|
textInverse: "#052027",
|
|
27
27
|
border: "#2b4551",
|
|
28
|
-
borderFocus: "#
|
|
29
|
-
accent: "#
|
|
30
|
-
accentHover: "#
|
|
28
|
+
borderFocus: "#28b67a",
|
|
29
|
+
accent: "#28b67a",
|
|
30
|
+
accentHover: "#219866",
|
|
31
31
|
accentText: "#ffffff",
|
|
32
32
|
success: "#0f9d73",
|
|
33
33
|
successBg: "#0f2f2a",
|
|
@@ -49,9 +49,9 @@ var lightTheme = {
|
|
|
49
49
|
textMuted: "#7d97a1",
|
|
50
50
|
textInverse: "#ffffff",
|
|
51
51
|
border: "#d2e4ea",
|
|
52
|
-
borderFocus: "#
|
|
53
|
-
accent: "#
|
|
54
|
-
accentHover: "#
|
|
52
|
+
borderFocus: "#28b67a",
|
|
53
|
+
accent: "#28b67a",
|
|
54
|
+
accentHover: "#219866",
|
|
55
55
|
accentText: "#ffffff",
|
|
56
56
|
success: "#0f9d73",
|
|
57
57
|
successBg: "#e6f7f1",
|
|
@@ -74,26 +74,6 @@ var wagmiConfig = createConfig({
|
|
|
74
74
|
[base.id]: http()
|
|
75
75
|
}
|
|
76
76
|
});
|
|
77
|
-
var PRIVY_MODAL_CENTER_CSS = `
|
|
78
|
-
@media (max-width: 440px) {
|
|
79
|
-
#privy-dialog [data-headlessui-state] {
|
|
80
|
-
position: static !important;
|
|
81
|
-
bottom: auto !important;
|
|
82
|
-
margin: auto !important;
|
|
83
|
-
width: 360px !important;
|
|
84
|
-
max-width: calc(100vw - 32px) !important;
|
|
85
|
-
box-shadow: 0px 8px 36px rgba(55, 65, 81, 0.15) !important;
|
|
86
|
-
border-radius: var(--privy-border-radius-lg) !important;
|
|
87
|
-
transform: none !important;
|
|
88
|
-
transition: opacity 100ms ease-in !important;
|
|
89
|
-
}
|
|
90
|
-
#privy-dialog [data-headlessui-state].entering,
|
|
91
|
-
#privy-dialog [data-headlessui-state].leaving {
|
|
92
|
-
opacity: 0 !important;
|
|
93
|
-
transform: none !important;
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
`;
|
|
97
77
|
var SwypeContext = createContext(null);
|
|
98
78
|
function SwypeProvider({
|
|
99
79
|
apiBaseUrl,
|
|
@@ -104,15 +84,6 @@ function SwypeProvider({
|
|
|
104
84
|
if (!queryClientRef.current) {
|
|
105
85
|
queryClientRef.current = new QueryClient();
|
|
106
86
|
}
|
|
107
|
-
useEffect(() => {
|
|
108
|
-
const style = document.createElement("style");
|
|
109
|
-
style.setAttribute("data-swype", "privy-modal-center");
|
|
110
|
-
style.textContent = PRIVY_MODAL_CENTER_CSS;
|
|
111
|
-
document.head.appendChild(style);
|
|
112
|
-
return () => {
|
|
113
|
-
style.remove();
|
|
114
|
-
};
|
|
115
|
-
}, []);
|
|
116
87
|
const [depositAmount, setDepositAmountRaw] = useState(null);
|
|
117
88
|
const setDepositAmount = useCallback((amount) => {
|
|
118
89
|
setDepositAmountRaw(amount);
|
|
@@ -135,6 +106,12 @@ function SwypeProvider({
|
|
|
135
106
|
appearance: {
|
|
136
107
|
theme,
|
|
137
108
|
accentColor: getTheme(theme).accent
|
|
109
|
+
},
|
|
110
|
+
intl: {
|
|
111
|
+
defaultCountry: "US"
|
|
112
|
+
},
|
|
113
|
+
embeddedWallets: {
|
|
114
|
+
showWalletUIs: false
|
|
138
115
|
}
|
|
139
116
|
},
|
|
140
117
|
children: /* @__PURE__ */ jsx(SwypeContext.Provider, { value, children })
|
|
@@ -173,6 +150,7 @@ __export(api_exports, {
|
|
|
173
150
|
fetchAccounts: () => fetchAccounts,
|
|
174
151
|
fetchAuthorizationSession: () => fetchAuthorizationSession,
|
|
175
152
|
fetchChains: () => fetchChains,
|
|
153
|
+
fetchMerchantPublicKey: () => fetchMerchantPublicKey,
|
|
176
154
|
fetchProviders: () => fetchProviders,
|
|
177
155
|
fetchTransfer: () => fetchTransfer,
|
|
178
156
|
fetchUserConfig: () => fetchUserConfig,
|
|
@@ -215,9 +193,13 @@ async function fetchAccounts(apiBaseUrl, token, credentialId) {
|
|
|
215
193
|
return data.items;
|
|
216
194
|
}
|
|
217
195
|
async function createTransfer(apiBaseUrl, token, params) {
|
|
196
|
+
if (!params.merchantAuthorization) {
|
|
197
|
+
throw new Error("merchantAuthorization is required for transfer creation.");
|
|
198
|
+
}
|
|
218
199
|
const body = {
|
|
219
200
|
id: params.id ?? crypto.randomUUID(),
|
|
220
201
|
credentialId: params.credentialId,
|
|
202
|
+
merchantAuthorization: params.merchantAuthorization,
|
|
221
203
|
sources: [{ [params.sourceType]: params.sourceId }],
|
|
222
204
|
destinations: [
|
|
223
205
|
{
|
|
@@ -242,6 +224,13 @@ async function createTransfer(apiBaseUrl, token, params) {
|
|
|
242
224
|
if (!res.ok) await throwApiError(res);
|
|
243
225
|
return await res.json();
|
|
244
226
|
}
|
|
227
|
+
async function fetchMerchantPublicKey(apiBaseUrl, merchantId) {
|
|
228
|
+
const res = await fetch(
|
|
229
|
+
`${apiBaseUrl}/v1/merchants/${encodeURIComponent(merchantId)}/public-key`
|
|
230
|
+
);
|
|
231
|
+
if (!res.ok) await throwApiError(res);
|
|
232
|
+
return await res.json();
|
|
233
|
+
}
|
|
245
234
|
async function fetchTransfer(apiBaseUrl, token, transferId, authorizationSessionToken) {
|
|
246
235
|
if (!token && !authorizationSessionToken) {
|
|
247
236
|
throw new Error("Missing auth credentials for transfer fetch.");
|
|
@@ -2097,6 +2086,46 @@ function AdvancedSettings({
|
|
|
2097
2086
|
] });
|
|
2098
2087
|
}
|
|
2099
2088
|
|
|
2089
|
+
// src/auth.ts
|
|
2090
|
+
var EMAIL_PATTERN = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
2091
|
+
var PHONE_DIGIT_PATTERN = /^\d{7,15}$/;
|
|
2092
|
+
function normalizePhoneNumber(rawValue) {
|
|
2093
|
+
const trimmed = rawValue.trim();
|
|
2094
|
+
if (!trimmed) return null;
|
|
2095
|
+
const hasExplicitCountryCode = trimmed.startsWith("+");
|
|
2096
|
+
const digits = trimmed.replace(/\D/g, "");
|
|
2097
|
+
if (!PHONE_DIGIT_PATTERN.test(digits)) return null;
|
|
2098
|
+
return hasExplicitCountryCode ? `+${digits}` : digits;
|
|
2099
|
+
}
|
|
2100
|
+
function normalizeAuthIdentifier(rawValue) {
|
|
2101
|
+
const trimmed = rawValue.trim();
|
|
2102
|
+
if (!trimmed) return null;
|
|
2103
|
+
if (EMAIL_PATTERN.test(trimmed)) {
|
|
2104
|
+
return {
|
|
2105
|
+
kind: "email",
|
|
2106
|
+
value: trimmed.toLowerCase()
|
|
2107
|
+
};
|
|
2108
|
+
}
|
|
2109
|
+
const normalizedPhoneNumber = normalizePhoneNumber(trimmed);
|
|
2110
|
+
if (normalizedPhoneNumber) {
|
|
2111
|
+
return {
|
|
2112
|
+
kind: "phone",
|
|
2113
|
+
value: normalizedPhoneNumber
|
|
2114
|
+
};
|
|
2115
|
+
}
|
|
2116
|
+
return null;
|
|
2117
|
+
}
|
|
2118
|
+
function maskAuthIdentifier(identifier) {
|
|
2119
|
+
if (identifier.kind === "email") {
|
|
2120
|
+
const [localPart, domain = ""] = identifier.value.split("@");
|
|
2121
|
+
const localPrefix = localPart.slice(0, 2);
|
|
2122
|
+
return `${localPrefix}${"*".repeat(Math.max(localPart.length - 2, 0))}@${domain}`;
|
|
2123
|
+
}
|
|
2124
|
+
const digits = identifier.value.replace(/\D/g, "");
|
|
2125
|
+
const visibleSuffix = digits.slice(-4);
|
|
2126
|
+
return `***-***-${visibleSuffix}`;
|
|
2127
|
+
}
|
|
2128
|
+
|
|
2100
2129
|
// src/processingStatus.ts
|
|
2101
2130
|
var PROCESSING_TIMEOUT_MS = 18e4;
|
|
2102
2131
|
function resolvePreferredTransfer(polledTransfer, localTransfer) {
|
|
@@ -2203,10 +2232,21 @@ function SwypePayment({
|
|
|
2203
2232
|
onComplete,
|
|
2204
2233
|
onError,
|
|
2205
2234
|
useWalletConnector,
|
|
2206
|
-
idempotencyKey
|
|
2235
|
+
idempotencyKey,
|
|
2236
|
+
merchantAuthorization
|
|
2207
2237
|
}) {
|
|
2208
2238
|
const { apiBaseUrl, tokens, depositAmount } = useSwypeConfig();
|
|
2209
|
-
const { ready, authenticated, user,
|
|
2239
|
+
const { ready, authenticated, user, logout, getAccessToken } = usePrivy();
|
|
2240
|
+
const {
|
|
2241
|
+
sendCode: sendEmailCode,
|
|
2242
|
+
loginWithCode: loginWithEmailCode,
|
|
2243
|
+
state: emailLoginState
|
|
2244
|
+
} = useLoginWithEmail();
|
|
2245
|
+
const {
|
|
2246
|
+
sendCode: sendSmsCode,
|
|
2247
|
+
loginWithCode: loginWithSmsCode,
|
|
2248
|
+
state: smsLoginState
|
|
2249
|
+
} = useLoginWithSms();
|
|
2210
2250
|
const [step, setStep] = useState("login");
|
|
2211
2251
|
const [error, setError] = useState(null);
|
|
2212
2252
|
const [providers, setProviders] = useState([]);
|
|
@@ -2231,6 +2271,11 @@ function SwypePayment({
|
|
|
2231
2271
|
if (typeof window === "undefined") return null;
|
|
2232
2272
|
return window.localStorage.getItem(ACTIVE_CREDENTIAL_STORAGE_KEY);
|
|
2233
2273
|
});
|
|
2274
|
+
const [authInput, setAuthInput] = useState("");
|
|
2275
|
+
const [verificationTarget, setVerificationTarget] = useState(
|
|
2276
|
+
null
|
|
2277
|
+
);
|
|
2278
|
+
const [otpCode, setOtpCode] = useState("");
|
|
2234
2279
|
const [mobileFlow, setMobileFlow] = useState(false);
|
|
2235
2280
|
const pollingTransferIdRef = useRef(null);
|
|
2236
2281
|
const mobileSigningTransferIdRef = useRef(null);
|
|
@@ -2248,9 +2293,81 @@ function SwypePayment({
|
|
|
2248
2293
|
setAmount(depositAmount.toString());
|
|
2249
2294
|
}
|
|
2250
2295
|
}, [depositAmount]);
|
|
2296
|
+
const resetHeadlessLogin = useCallback(() => {
|
|
2297
|
+
setAuthInput("");
|
|
2298
|
+
setVerificationTarget(null);
|
|
2299
|
+
setOtpCode("");
|
|
2300
|
+
}, []);
|
|
2301
|
+
const activeOtpStatus = verificationTarget?.kind === "email" ? emailLoginState.status : verificationTarget?.kind === "phone" ? smsLoginState.status : "initial";
|
|
2302
|
+
const activeOtpErrorMessage = verificationTarget?.kind === "email" && emailLoginState.status === "error" ? emailLoginState.error?.message ?? "Failed to continue with email." : verificationTarget?.kind === "phone" && smsLoginState.status === "error" ? smsLoginState.error?.message ?? "Failed to continue with phone number." : null;
|
|
2303
|
+
useEffect(() => {
|
|
2304
|
+
if (activeOtpErrorMessage) {
|
|
2305
|
+
setError(activeOtpErrorMessage);
|
|
2306
|
+
}
|
|
2307
|
+
}, [activeOtpErrorMessage]);
|
|
2308
|
+
const handleSendLoginCode = useCallback(async () => {
|
|
2309
|
+
const normalizedIdentifier = normalizeAuthIdentifier(authInput);
|
|
2310
|
+
if (!normalizedIdentifier) {
|
|
2311
|
+
setError("Enter a valid email address or phone number.");
|
|
2312
|
+
return;
|
|
2313
|
+
}
|
|
2314
|
+
setError(null);
|
|
2315
|
+
setOtpCode("");
|
|
2316
|
+
try {
|
|
2317
|
+
if (normalizedIdentifier.kind === "email") {
|
|
2318
|
+
await sendEmailCode({ email: normalizedIdentifier.value });
|
|
2319
|
+
} else {
|
|
2320
|
+
await sendSmsCode({ phoneNumber: normalizedIdentifier.value });
|
|
2321
|
+
}
|
|
2322
|
+
setVerificationTarget(normalizedIdentifier);
|
|
2323
|
+
} catch (err) {
|
|
2324
|
+
const msg = err instanceof Error ? err.message : "Failed to send verification code";
|
|
2325
|
+
setError(msg);
|
|
2326
|
+
}
|
|
2327
|
+
}, [authInput, sendEmailCode, sendSmsCode]);
|
|
2328
|
+
const handleVerifyLoginCode = useCallback(async () => {
|
|
2329
|
+
if (!verificationTarget) return;
|
|
2330
|
+
const trimmedCode = otpCode.trim();
|
|
2331
|
+
if (!/^\d{6}$/.test(trimmedCode)) {
|
|
2332
|
+
setError("Enter the 6-digit verification code.");
|
|
2333
|
+
return;
|
|
2334
|
+
}
|
|
2335
|
+
setError(null);
|
|
2336
|
+
try {
|
|
2337
|
+
if (verificationTarget.kind === "email") {
|
|
2338
|
+
await loginWithEmailCode({ code: trimmedCode });
|
|
2339
|
+
} else {
|
|
2340
|
+
await loginWithSmsCode({ code: trimmedCode });
|
|
2341
|
+
}
|
|
2342
|
+
} catch (err) {
|
|
2343
|
+
const msg = err instanceof Error ? err.message : "Failed to verify code";
|
|
2344
|
+
setError(msg);
|
|
2345
|
+
}
|
|
2346
|
+
}, [verificationTarget, otpCode, loginWithEmailCode, loginWithSmsCode]);
|
|
2347
|
+
const handleResendLoginCode = useCallback(async () => {
|
|
2348
|
+
if (!verificationTarget) return;
|
|
2349
|
+
setError(null);
|
|
2350
|
+
try {
|
|
2351
|
+
if (verificationTarget.kind === "email") {
|
|
2352
|
+
await sendEmailCode({ email: verificationTarget.value });
|
|
2353
|
+
} else {
|
|
2354
|
+
await sendSmsCode({ phoneNumber: verificationTarget.value });
|
|
2355
|
+
}
|
|
2356
|
+
} catch (err) {
|
|
2357
|
+
const msg = err instanceof Error ? err.message : "Failed to resend code";
|
|
2358
|
+
setError(msg);
|
|
2359
|
+
}
|
|
2360
|
+
}, [verificationTarget, sendEmailCode, sendSmsCode]);
|
|
2361
|
+
const handleEditIdentifier = useCallback(() => {
|
|
2362
|
+
setError(null);
|
|
2363
|
+
setVerificationTarget(null);
|
|
2364
|
+
setOtpCode("");
|
|
2365
|
+
}, []);
|
|
2251
2366
|
useEffect(() => {
|
|
2252
2367
|
if (!ready || !authenticated || step !== "login") return;
|
|
2253
2368
|
let cancelled = false;
|
|
2369
|
+
setError(null);
|
|
2370
|
+
resetHeadlessLogin();
|
|
2254
2371
|
const checkPasskey = async () => {
|
|
2255
2372
|
try {
|
|
2256
2373
|
const token = await getAccessToken();
|
|
@@ -2299,7 +2416,16 @@ function SwypePayment({
|
|
|
2299
2416
|
return () => {
|
|
2300
2417
|
cancelled = true;
|
|
2301
2418
|
};
|
|
2302
|
-
}, [
|
|
2419
|
+
}, [
|
|
2420
|
+
ready,
|
|
2421
|
+
authenticated,
|
|
2422
|
+
step,
|
|
2423
|
+
depositAmount,
|
|
2424
|
+
apiBaseUrl,
|
|
2425
|
+
getAccessToken,
|
|
2426
|
+
activeCredentialId,
|
|
2427
|
+
resetHeadlessLogin
|
|
2428
|
+
]);
|
|
2303
2429
|
const loadingDataRef = useRef(false);
|
|
2304
2430
|
useEffect(() => {
|
|
2305
2431
|
if (!authenticated) return;
|
|
@@ -2519,6 +2645,7 @@ function SwypePayment({
|
|
|
2519
2645
|
const t = await createTransfer(apiBaseUrl, token, {
|
|
2520
2646
|
id: idempotencyKey,
|
|
2521
2647
|
credentialId: activeCredentialId,
|
|
2648
|
+
merchantAuthorization,
|
|
2522
2649
|
sourceType: effectiveSourceType,
|
|
2523
2650
|
sourceId: effectiveSourceId,
|
|
2524
2651
|
destination,
|
|
@@ -2608,7 +2735,8 @@ function SwypePayment({
|
|
|
2608
2735
|
processingStartedAtRef.current = null;
|
|
2609
2736
|
pollingTransferIdRef.current = null;
|
|
2610
2737
|
mobileSigningTransferIdRef.current = null;
|
|
2611
|
-
|
|
2738
|
+
resetHeadlessLogin();
|
|
2739
|
+
}, [logout, polling, depositAmount, resetHeadlessLogin]);
|
|
2612
2740
|
const handleConnectNewAccount = (providerId) => {
|
|
2613
2741
|
setSelectedProviderId(providerId);
|
|
2614
2742
|
setSelectedAccountId(null);
|
|
@@ -2645,7 +2773,7 @@ function SwypePayment({
|
|
|
2645
2773
|
cursor: "pointer",
|
|
2646
2774
|
transition: "filter 0.15s ease, transform 0.15s ease",
|
|
2647
2775
|
fontFamily: "inherit",
|
|
2648
|
-
boxShadow: "0 8px 18px rgba(
|
|
2776
|
+
boxShadow: "0 8px 18px rgba(40, 182, 122, 0.28)"
|
|
2649
2777
|
};
|
|
2650
2778
|
const btnDisabled = {
|
|
2651
2779
|
...btnPrimary,
|
|
@@ -2657,6 +2785,33 @@ function SwypePayment({
|
|
|
2657
2785
|
background: tokens.bgCard,
|
|
2658
2786
|
color: tokens.textSecondary,
|
|
2659
2787
|
border: `1px solid ${tokens.border}`});
|
|
2788
|
+
const textFieldStyle = {
|
|
2789
|
+
width: "100%",
|
|
2790
|
+
padding: "15px 16px",
|
|
2791
|
+
borderRadius: "16px",
|
|
2792
|
+
border: `1px solid ${tokens.border}`,
|
|
2793
|
+
background: tokens.bgInput,
|
|
2794
|
+
color: tokens.text,
|
|
2795
|
+
fontSize: "0.98rem",
|
|
2796
|
+
fontFamily: "inherit",
|
|
2797
|
+
outline: "none",
|
|
2798
|
+
boxSizing: "border-box"
|
|
2799
|
+
};
|
|
2800
|
+
const authCaptionStyle = {
|
|
2801
|
+
fontSize: "0.84rem",
|
|
2802
|
+
color: tokens.textSecondary,
|
|
2803
|
+
margin: 0,
|
|
2804
|
+
lineHeight: 1.5
|
|
2805
|
+
};
|
|
2806
|
+
const authTertiaryButtonStyle = {
|
|
2807
|
+
background: "transparent",
|
|
2808
|
+
border: "none",
|
|
2809
|
+
color: tokens.textMuted,
|
|
2810
|
+
cursor: "pointer",
|
|
2811
|
+
fontFamily: "inherit",
|
|
2812
|
+
fontSize: "0.84rem",
|
|
2813
|
+
padding: 0
|
|
2814
|
+
};
|
|
2660
2815
|
const errorStyle = {
|
|
2661
2816
|
background: tokens.errorBg,
|
|
2662
2817
|
border: `1px solid ${tokens.error}66`,
|
|
@@ -2717,6 +2872,7 @@ function SwypePayment({
|
|
|
2717
2872
|
]
|
|
2718
2873
|
}
|
|
2719
2874
|
);
|
|
2875
|
+
const placeholderProviders = ["A", "B", "C", "D", "E"];
|
|
2720
2876
|
const displayedSelectSourceChoices = selectSourceChoices.length > 0 ? selectSourceChoices : [
|
|
2721
2877
|
{
|
|
2722
2878
|
chainName: "Base",
|
|
@@ -2752,43 +2908,186 @@ function SwypePayment({
|
|
|
2752
2908
|
return /* @__PURE__ */ jsx("div", { style: cardStyle, children: /* @__PURE__ */ jsx("div", { style: { textAlign: "center", padding: "24px 0" }, children: /* @__PURE__ */ jsx(Spinner, { label: "Initializing..." }) }) });
|
|
2753
2909
|
}
|
|
2754
2910
|
if (step === "login" && !authenticated) {
|
|
2911
|
+
const isAwaitingOtp = verificationTarget !== null;
|
|
2912
|
+
const isSendingCode = activeOtpStatus === "sending-code";
|
|
2913
|
+
const isSubmittingCode = activeOtpStatus === "submitting-code";
|
|
2914
|
+
const continueDisabled = authInput.trim().length === 0 || isSendingCode || isSubmittingCode;
|
|
2915
|
+
const verifyDisabled = otpCode.trim().length !== 6 || isSubmittingCode;
|
|
2755
2916
|
return /* @__PURE__ */ jsx("div", { style: cardStyle, children: /* @__PURE__ */ jsxs("div", { style: { textAlign: "center" }, children: [
|
|
2756
|
-
/* @__PURE__ */
|
|
2757
|
-
"
|
|
2917
|
+
/* @__PURE__ */ jsx(
|
|
2918
|
+
"div",
|
|
2758
2919
|
{
|
|
2759
|
-
|
|
2760
|
-
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
|
|
2920
|
+
style: {
|
|
2921
|
+
width: 56,
|
|
2922
|
+
height: 56,
|
|
2923
|
+
borderRadius: 14,
|
|
2924
|
+
background: tokens.accent,
|
|
2925
|
+
color: tokens.accentText,
|
|
2926
|
+
display: "flex",
|
|
2927
|
+
alignItems: "center",
|
|
2928
|
+
justifyContent: "center",
|
|
2929
|
+
fontWeight: 700,
|
|
2930
|
+
fontSize: "1.35rem",
|
|
2931
|
+
margin: "0 auto 24px",
|
|
2932
|
+
boxShadow: "0 10px 20px rgba(40, 182, 122, 0.22)"
|
|
2933
|
+
},
|
|
2934
|
+
children: "S"
|
|
2935
|
+
}
|
|
2936
|
+
),
|
|
2937
|
+
/* @__PURE__ */ jsx(
|
|
2938
|
+
"h2",
|
|
2939
|
+
{
|
|
2940
|
+
style: {
|
|
2941
|
+
...headingStyle,
|
|
2942
|
+
fontSize: "2.05rem",
|
|
2943
|
+
lineHeight: 1.15,
|
|
2944
|
+
marginBottom: "10px",
|
|
2945
|
+
whiteSpace: "pre-line"
|
|
2946
|
+
},
|
|
2947
|
+
children: isAwaitingOtp ? "Enter your code." : "One-time setup.\nOne-tap deposits after."
|
|
2776
2948
|
}
|
|
2777
2949
|
),
|
|
2778
|
-
/* @__PURE__ */ jsx("h2", { style: { ...headingStyle, marginBottom: "8px" }, children: "Pay with Swype" }),
|
|
2779
2950
|
/* @__PURE__ */ jsx(
|
|
2780
2951
|
"p",
|
|
2781
2952
|
{
|
|
2782
2953
|
style: {
|
|
2783
|
-
|
|
2784
|
-
|
|
2785
|
-
|
|
2786
|
-
lineHeight: 1.5
|
|
2954
|
+
...authCaptionStyle,
|
|
2955
|
+
margin: "0 0 26px 0",
|
|
2956
|
+
whiteSpace: "pre-line"
|
|
2787
2957
|
},
|
|
2788
|
-
children:
|
|
2958
|
+
children: isAwaitingOtp ? `We sent a 6-digit code to ${maskAuthIdentifier(verificationTarget)}.` : "Protected by Face ID."
|
|
2789
2959
|
}
|
|
2790
2960
|
),
|
|
2791
|
-
/* @__PURE__ */ jsx("
|
|
2961
|
+
error && /* @__PURE__ */ jsx("div", { style: errorStyle, children: error }),
|
|
2962
|
+
isAwaitingOtp ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2963
|
+
/* @__PURE__ */ jsx(
|
|
2964
|
+
"input",
|
|
2965
|
+
{
|
|
2966
|
+
id: "swype-login-code",
|
|
2967
|
+
type: "text",
|
|
2968
|
+
inputMode: "numeric",
|
|
2969
|
+
autoComplete: "one-time-code",
|
|
2970
|
+
placeholder: "Verification code",
|
|
2971
|
+
value: otpCode,
|
|
2972
|
+
onChange: (event) => {
|
|
2973
|
+
setOtpCode(event.target.value.replace(/\D/g, "").slice(0, 6));
|
|
2974
|
+
},
|
|
2975
|
+
style: {
|
|
2976
|
+
...textFieldStyle,
|
|
2977
|
+
textAlign: "center",
|
|
2978
|
+
letterSpacing: "0.24em",
|
|
2979
|
+
marginBottom: "14px"
|
|
2980
|
+
}
|
|
2981
|
+
}
|
|
2982
|
+
),
|
|
2983
|
+
/* @__PURE__ */ jsx(
|
|
2984
|
+
"button",
|
|
2985
|
+
{
|
|
2986
|
+
style: verifyDisabled ? btnDisabled : btnPrimary,
|
|
2987
|
+
disabled: verifyDisabled,
|
|
2988
|
+
onClick: handleVerifyLoginCode,
|
|
2989
|
+
children: isSubmittingCode ? "Verifying..." : "Continue"
|
|
2990
|
+
}
|
|
2991
|
+
),
|
|
2992
|
+
/* @__PURE__ */ jsxs(
|
|
2993
|
+
"div",
|
|
2994
|
+
{
|
|
2995
|
+
style: {
|
|
2996
|
+
display: "flex",
|
|
2997
|
+
justifyContent: "space-between",
|
|
2998
|
+
gap: "12px",
|
|
2999
|
+
marginTop: "14px"
|
|
3000
|
+
},
|
|
3001
|
+
children: [
|
|
3002
|
+
/* @__PURE__ */ jsx("button", { type: "button", style: authTertiaryButtonStyle, onClick: handleEditIdentifier, children: "Use a different email or phone" }),
|
|
3003
|
+
/* @__PURE__ */ jsx(
|
|
3004
|
+
"button",
|
|
3005
|
+
{
|
|
3006
|
+
type: "button",
|
|
3007
|
+
style: authTertiaryButtonStyle,
|
|
3008
|
+
onClick: handleResendLoginCode,
|
|
3009
|
+
disabled: isSendingCode || isSubmittingCode,
|
|
3010
|
+
children: isSendingCode ? "Sending..." : "Resend code"
|
|
3011
|
+
}
|
|
3012
|
+
)
|
|
3013
|
+
]
|
|
3014
|
+
}
|
|
3015
|
+
)
|
|
3016
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3017
|
+
/* @__PURE__ */ jsx(
|
|
3018
|
+
"input",
|
|
3019
|
+
{
|
|
3020
|
+
id: "swype-login-identifier",
|
|
3021
|
+
type: "text",
|
|
3022
|
+
inputMode: "text",
|
|
3023
|
+
autoComplete: "username",
|
|
3024
|
+
placeholder: "Email or phone number",
|
|
3025
|
+
value: authInput,
|
|
3026
|
+
onChange: (event) => setAuthInput(event.target.value),
|
|
3027
|
+
style: { ...textFieldStyle, marginBottom: "14px" }
|
|
3028
|
+
}
|
|
3029
|
+
),
|
|
3030
|
+
/* @__PURE__ */ jsx(
|
|
3031
|
+
"button",
|
|
3032
|
+
{
|
|
3033
|
+
style: continueDisabled ? btnDisabled : btnPrimary,
|
|
3034
|
+
disabled: continueDisabled,
|
|
3035
|
+
onClick: handleSendLoginCode,
|
|
3036
|
+
children: isSendingCode ? "Sending code..." : "Continue"
|
|
3037
|
+
}
|
|
3038
|
+
),
|
|
3039
|
+
/* @__PURE__ */ jsxs(
|
|
3040
|
+
"div",
|
|
3041
|
+
{
|
|
3042
|
+
style: {
|
|
3043
|
+
display: "flex",
|
|
3044
|
+
alignItems: "center",
|
|
3045
|
+
gap: "10px",
|
|
3046
|
+
margin: "22px 0 14px",
|
|
3047
|
+
color: tokens.textMuted,
|
|
3048
|
+
fontSize: "0.82rem"
|
|
3049
|
+
},
|
|
3050
|
+
children: [
|
|
3051
|
+
/* @__PURE__ */ jsx("div", { style: { flex: 1, height: 1, background: tokens.border } }),
|
|
3052
|
+
/* @__PURE__ */ jsx("span", { children: "works with" }),
|
|
3053
|
+
/* @__PURE__ */ jsx("div", { style: { flex: 1, height: 1, background: tokens.border } })
|
|
3054
|
+
]
|
|
3055
|
+
}
|
|
3056
|
+
),
|
|
3057
|
+
/* @__PURE__ */ jsx(
|
|
3058
|
+
"div",
|
|
3059
|
+
{
|
|
3060
|
+
"aria-label": "Works with placeholder providers",
|
|
3061
|
+
style: {
|
|
3062
|
+
display: "flex",
|
|
3063
|
+
justifyContent: "center",
|
|
3064
|
+
gap: "12px",
|
|
3065
|
+
marginBottom: "18px"
|
|
3066
|
+
},
|
|
3067
|
+
children: placeholderProviders.map((providerLabel) => /* @__PURE__ */ jsx(
|
|
3068
|
+
"div",
|
|
3069
|
+
{
|
|
3070
|
+
style: {
|
|
3071
|
+
width: 34,
|
|
3072
|
+
height: 34,
|
|
3073
|
+
borderRadius: 999,
|
|
3074
|
+
border: `1px solid ${tokens.border}`,
|
|
3075
|
+
background: tokens.bgInput,
|
|
3076
|
+
color: tokens.textMuted,
|
|
3077
|
+
display: "flex",
|
|
3078
|
+
alignItems: "center",
|
|
3079
|
+
justifyContent: "center",
|
|
3080
|
+
fontSize: "0.78rem",
|
|
3081
|
+
fontWeight: 600
|
|
3082
|
+
},
|
|
3083
|
+
children: providerLabel
|
|
3084
|
+
},
|
|
3085
|
+
providerLabel
|
|
3086
|
+
))
|
|
3087
|
+
}
|
|
3088
|
+
),
|
|
3089
|
+
/* @__PURE__ */ jsx("p", { style: { ...authCaptionStyle, color: tokens.textMuted }, children: "Powered by Swype. Non-custodial." })
|
|
3090
|
+
] })
|
|
2792
3091
|
] }) });
|
|
2793
3092
|
}
|
|
2794
3093
|
if (step === "register-passkey") {
|