@swype-org/react-sdk 0.1.27 → 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 +392 -84
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +105 -75
- package/dist/index.d.ts +105 -75
- package/dist/index.js +394 -87
- 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
|
-
id: crypto.randomUUID(),
|
|
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.");
|
|
@@ -813,6 +802,11 @@ async function createPasskeyCredential(params) {
|
|
|
813
802
|
};
|
|
814
803
|
}
|
|
815
804
|
async function deviceHasPasskey(credentialId) {
|
|
805
|
+
const found = await findDevicePasskey([credentialId]);
|
|
806
|
+
return found != null;
|
|
807
|
+
}
|
|
808
|
+
async function findDevicePasskey(credentialIds) {
|
|
809
|
+
if (credentialIds.length === 0) return null;
|
|
816
810
|
try {
|
|
817
811
|
const challenge = new Uint8Array(32);
|
|
818
812
|
crypto.getRandomValues(challenge);
|
|
@@ -821,17 +815,18 @@ async function deviceHasPasskey(credentialId) {
|
|
|
821
815
|
publicKey: {
|
|
822
816
|
challenge,
|
|
823
817
|
rpId: resolvePasskeyRpId(),
|
|
824
|
-
allowCredentials:
|
|
818
|
+
allowCredentials: credentialIds.map((id) => ({
|
|
825
819
|
type: "public-key",
|
|
826
|
-
id: base64ToBytes(
|
|
827
|
-
}
|
|
820
|
+
id: base64ToBytes(id)
|
|
821
|
+
})),
|
|
828
822
|
userVerification: "discouraged",
|
|
829
823
|
timeout: 3e4
|
|
830
824
|
}
|
|
831
825
|
});
|
|
832
|
-
|
|
826
|
+
if (!assertion) return null;
|
|
827
|
+
return toBase64(assertion.rawId);
|
|
833
828
|
} catch {
|
|
834
|
-
return
|
|
829
|
+
return null;
|
|
835
830
|
}
|
|
836
831
|
}
|
|
837
832
|
function useTransferPolling(intervalMs = 3e3) {
|
|
@@ -2091,6 +2086,46 @@ function AdvancedSettings({
|
|
|
2091
2086
|
] });
|
|
2092
2087
|
}
|
|
2093
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
|
+
|
|
2094
2129
|
// src/processingStatus.ts
|
|
2095
2130
|
var PROCESSING_TIMEOUT_MS = 18e4;
|
|
2096
2131
|
function resolvePreferredTransfer(polledTransfer, localTransfer) {
|
|
@@ -2196,10 +2231,22 @@ function SwypePayment({
|
|
|
2196
2231
|
destination,
|
|
2197
2232
|
onComplete,
|
|
2198
2233
|
onError,
|
|
2199
|
-
useWalletConnector
|
|
2234
|
+
useWalletConnector,
|
|
2235
|
+
idempotencyKey,
|
|
2236
|
+
merchantAuthorization
|
|
2200
2237
|
}) {
|
|
2201
2238
|
const { apiBaseUrl, tokens, depositAmount } = useSwypeConfig();
|
|
2202
|
-
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();
|
|
2203
2250
|
const [step, setStep] = useState("login");
|
|
2204
2251
|
const [error, setError] = useState(null);
|
|
2205
2252
|
const [providers, setProviders] = useState([]);
|
|
@@ -2224,6 +2271,11 @@ function SwypePayment({
|
|
|
2224
2271
|
if (typeof window === "undefined") return null;
|
|
2225
2272
|
return window.localStorage.getItem(ACTIVE_CREDENTIAL_STORAGE_KEY);
|
|
2226
2273
|
});
|
|
2274
|
+
const [authInput, setAuthInput] = useState("");
|
|
2275
|
+
const [verificationTarget, setVerificationTarget] = useState(
|
|
2276
|
+
null
|
|
2277
|
+
);
|
|
2278
|
+
const [otpCode, setOtpCode] = useState("");
|
|
2227
2279
|
const [mobileFlow, setMobileFlow] = useState(false);
|
|
2228
2280
|
const pollingTransferIdRef = useRef(null);
|
|
2229
2281
|
const mobileSigningTransferIdRef = useRef(null);
|
|
@@ -2241,9 +2293,81 @@ function SwypePayment({
|
|
|
2241
2293
|
setAmount(depositAmount.toString());
|
|
2242
2294
|
}
|
|
2243
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
|
+
}, []);
|
|
2244
2366
|
useEffect(() => {
|
|
2245
2367
|
if (!ready || !authenticated || step !== "login") return;
|
|
2246
2368
|
let cancelled = false;
|
|
2369
|
+
setError(null);
|
|
2370
|
+
resetHeadlessLogin();
|
|
2247
2371
|
const checkPasskey = async () => {
|
|
2248
2372
|
try {
|
|
2249
2373
|
const token = await getAccessToken();
|
|
@@ -2263,20 +2387,20 @@ function SwypePayment({
|
|
|
2263
2387
|
}
|
|
2264
2388
|
return;
|
|
2265
2389
|
}
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2390
|
+
if (cancelled) return;
|
|
2391
|
+
const credentialIds = allPasskeys.map((p) => p.credentialId);
|
|
2392
|
+
const matched = await findDevicePasskey(credentialIds);
|
|
2393
|
+
if (cancelled) return;
|
|
2394
|
+
if (matched) {
|
|
2395
|
+
setActiveCredentialId(matched);
|
|
2396
|
+
window.localStorage.setItem(ACTIVE_CREDENTIAL_STORAGE_KEY, matched);
|
|
2397
|
+
if (depositAmount != null && depositAmount > 0) {
|
|
2398
|
+
setStep("ready");
|
|
2399
|
+
} else {
|
|
2400
|
+
setStep("enter-amount");
|
|
2277
2401
|
}
|
|
2402
|
+
return;
|
|
2278
2403
|
}
|
|
2279
|
-
if (cancelled) return;
|
|
2280
2404
|
setStep("register-passkey");
|
|
2281
2405
|
} catch {
|
|
2282
2406
|
if (!cancelled) {
|
|
@@ -2292,7 +2416,16 @@ function SwypePayment({
|
|
|
2292
2416
|
return () => {
|
|
2293
2417
|
cancelled = true;
|
|
2294
2418
|
};
|
|
2295
|
-
}, [
|
|
2419
|
+
}, [
|
|
2420
|
+
ready,
|
|
2421
|
+
authenticated,
|
|
2422
|
+
step,
|
|
2423
|
+
depositAmount,
|
|
2424
|
+
apiBaseUrl,
|
|
2425
|
+
getAccessToken,
|
|
2426
|
+
activeCredentialId,
|
|
2427
|
+
resetHeadlessLogin
|
|
2428
|
+
]);
|
|
2296
2429
|
const loadingDataRef = useRef(false);
|
|
2297
2430
|
useEffect(() => {
|
|
2298
2431
|
if (!authenticated) return;
|
|
@@ -2510,7 +2643,9 @@ function SwypePayment({
|
|
|
2510
2643
|
}
|
|
2511
2644
|
}
|
|
2512
2645
|
const t = await createTransfer(apiBaseUrl, token, {
|
|
2646
|
+
id: idempotencyKey,
|
|
2513
2647
|
credentialId: activeCredentialId,
|
|
2648
|
+
merchantAuthorization,
|
|
2514
2649
|
sourceType: effectiveSourceType,
|
|
2515
2650
|
sourceId: effectiveSourceId,
|
|
2516
2651
|
destination,
|
|
@@ -2600,7 +2735,8 @@ function SwypePayment({
|
|
|
2600
2735
|
processingStartedAtRef.current = null;
|
|
2601
2736
|
pollingTransferIdRef.current = null;
|
|
2602
2737
|
mobileSigningTransferIdRef.current = null;
|
|
2603
|
-
|
|
2738
|
+
resetHeadlessLogin();
|
|
2739
|
+
}, [logout, polling, depositAmount, resetHeadlessLogin]);
|
|
2604
2740
|
const handleConnectNewAccount = (providerId) => {
|
|
2605
2741
|
setSelectedProviderId(providerId);
|
|
2606
2742
|
setSelectedAccountId(null);
|
|
@@ -2637,7 +2773,7 @@ function SwypePayment({
|
|
|
2637
2773
|
cursor: "pointer",
|
|
2638
2774
|
transition: "filter 0.15s ease, transform 0.15s ease",
|
|
2639
2775
|
fontFamily: "inherit",
|
|
2640
|
-
boxShadow: "0 8px 18px rgba(
|
|
2776
|
+
boxShadow: "0 8px 18px rgba(40, 182, 122, 0.28)"
|
|
2641
2777
|
};
|
|
2642
2778
|
const btnDisabled = {
|
|
2643
2779
|
...btnPrimary,
|
|
@@ -2649,6 +2785,33 @@ function SwypePayment({
|
|
|
2649
2785
|
background: tokens.bgCard,
|
|
2650
2786
|
color: tokens.textSecondary,
|
|
2651
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
|
+
};
|
|
2652
2815
|
const errorStyle = {
|
|
2653
2816
|
background: tokens.errorBg,
|
|
2654
2817
|
border: `1px solid ${tokens.error}66`,
|
|
@@ -2709,6 +2872,7 @@ function SwypePayment({
|
|
|
2709
2872
|
]
|
|
2710
2873
|
}
|
|
2711
2874
|
);
|
|
2875
|
+
const placeholderProviders = ["A", "B", "C", "D", "E"];
|
|
2712
2876
|
const displayedSelectSourceChoices = selectSourceChoices.length > 0 ? selectSourceChoices : [
|
|
2713
2877
|
{
|
|
2714
2878
|
chainName: "Base",
|
|
@@ -2744,43 +2908,186 @@ function SwypePayment({
|
|
|
2744
2908
|
return /* @__PURE__ */ jsx("div", { style: cardStyle, children: /* @__PURE__ */ jsx("div", { style: { textAlign: "center", padding: "24px 0" }, children: /* @__PURE__ */ jsx(Spinner, { label: "Initializing..." }) }) });
|
|
2745
2909
|
}
|
|
2746
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;
|
|
2747
2916
|
return /* @__PURE__ */ jsx("div", { style: cardStyle, children: /* @__PURE__ */ jsxs("div", { style: { textAlign: "center" }, children: [
|
|
2748
|
-
/* @__PURE__ */
|
|
2749
|
-
"
|
|
2917
|
+
/* @__PURE__ */ jsx(
|
|
2918
|
+
"div",
|
|
2750
2919
|
{
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
|
|
2759
|
-
|
|
2760
|
-
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
|
|
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."
|
|
2768
2948
|
}
|
|
2769
2949
|
),
|
|
2770
|
-
/* @__PURE__ */ jsx("h2", { style: { ...headingStyle, marginBottom: "8px" }, children: "Pay with Swype" }),
|
|
2771
2950
|
/* @__PURE__ */ jsx(
|
|
2772
2951
|
"p",
|
|
2773
2952
|
{
|
|
2774
2953
|
style: {
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
|
|
2778
|
-
lineHeight: 1.5
|
|
2954
|
+
...authCaptionStyle,
|
|
2955
|
+
margin: "0 0 26px 0",
|
|
2956
|
+
whiteSpace: "pre-line"
|
|
2779
2957
|
},
|
|
2780
|
-
children:
|
|
2958
|
+
children: isAwaitingOtp ? `We sent a 6-digit code to ${maskAuthIdentifier(verificationTarget)}.` : "Protected by Face ID."
|
|
2781
2959
|
}
|
|
2782
2960
|
),
|
|
2783
|
-
/* @__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
|
+
] })
|
|
2784
3091
|
] }) });
|
|
2785
3092
|
}
|
|
2786
3093
|
if (step === "register-passkey") {
|
|
@@ -3543,6 +3850,6 @@ function SwypePayment({
|
|
|
3543
3850
|
return null;
|
|
3544
3851
|
}
|
|
3545
3852
|
|
|
3546
|
-
export { SwypePayment, SwypeProvider, createPasskeyCredential, darkTheme, deviceHasPasskey, getTheme, lightTheme, api_exports as swypeApi, useAuthorizationExecutor, useSwypeConfig, useSwypeDepositAmount, useTransferPolling, useTransferSigning };
|
|
3853
|
+
export { SwypePayment, SwypeProvider, createPasskeyCredential, darkTheme, deviceHasPasskey, findDevicePasskey, getTheme, lightTheme, api_exports as swypeApi, useAuthorizationExecutor, useSwypeConfig, useSwypeDepositAmount, useTransferPolling, useTransferSigning };
|
|
3547
3854
|
//# sourceMappingURL=index.js.map
|
|
3548
3855
|
//# sourceMappingURL=index.js.map
|