@swype-org/react-sdk 0.1.9 → 0.1.11
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 +72 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +72 -8
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -178,8 +178,9 @@ async function fetchChains(apiBaseUrl, token) {
|
|
|
178
178
|
const data = await res.json();
|
|
179
179
|
return data.items;
|
|
180
180
|
}
|
|
181
|
-
async function fetchAccounts(apiBaseUrl, token) {
|
|
182
|
-
const
|
|
181
|
+
async function fetchAccounts(apiBaseUrl, token, credentialId) {
|
|
182
|
+
const params = new URLSearchParams({ credentialId });
|
|
183
|
+
const res = await fetch(`${apiBaseUrl}/v1/accounts?${params.toString()}`, {
|
|
183
184
|
headers: { Authorization: `Bearer ${token}` }
|
|
184
185
|
});
|
|
185
186
|
if (!res.ok) await throwApiError(res);
|
|
@@ -189,6 +190,7 @@ async function fetchAccounts(apiBaseUrl, token) {
|
|
|
189
190
|
async function createTransfer(apiBaseUrl, token, params) {
|
|
190
191
|
const body = {
|
|
191
192
|
id: crypto.randomUUID(),
|
|
193
|
+
credentialId: params.credentialId,
|
|
192
194
|
sources: [{ [params.sourceType]: params.sourceId }],
|
|
193
195
|
destinations: [
|
|
194
196
|
{
|
|
@@ -561,6 +563,27 @@ async function getWalletClient(config, parameters = {}) {
|
|
|
561
563
|
const client = await getConnectorClient(config, parameters);
|
|
562
564
|
return client.extend(viem.walletActions);
|
|
563
565
|
}
|
|
566
|
+
|
|
567
|
+
// src/passkeyRpId.ts
|
|
568
|
+
function normalizeConfiguredDomain(value) {
|
|
569
|
+
return value.replace(/^https?:\/\//, "").replace(/\/.*$/, "").replace(/^\./, "").trim();
|
|
570
|
+
}
|
|
571
|
+
function resolveRootDomainFromHostname(hostname) {
|
|
572
|
+
const trimmedHostname = hostname.trim().toLowerCase();
|
|
573
|
+
if (!trimmedHostname) {
|
|
574
|
+
return "localhost";
|
|
575
|
+
}
|
|
576
|
+
if (trimmedHostname === "localhost" || /^\d{1,3}(?:\.\d{1,3}){3}$/.test(trimmedHostname)) {
|
|
577
|
+
return trimmedHostname;
|
|
578
|
+
}
|
|
579
|
+
const parts = trimmedHostname.split(".").filter(Boolean);
|
|
580
|
+
if (parts.length < 2) {
|
|
581
|
+
return trimmedHostname;
|
|
582
|
+
}
|
|
583
|
+
return parts.slice(-2).join(".");
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
// src/hooks.ts
|
|
564
587
|
var WALLET_CLIENT_MAX_ATTEMPTS = 15;
|
|
565
588
|
var WALLET_CLIENT_POLL_MS = 200;
|
|
566
589
|
var ACTION_POLL_INTERVAL_MS = 500;
|
|
@@ -611,10 +634,10 @@ function readEnvValue(name) {
|
|
|
611
634
|
function resolvePasskeyRpId() {
|
|
612
635
|
const configuredDomain = readEnvValue("VITE_DOMAIN") ?? readEnvValue("SWYPE_DOMAIN");
|
|
613
636
|
if (configuredDomain) {
|
|
614
|
-
return configuredDomain
|
|
637
|
+
return normalizeConfiguredDomain(configuredDomain);
|
|
615
638
|
}
|
|
616
639
|
if (typeof window !== "undefined") {
|
|
617
|
-
return window.location.hostname;
|
|
640
|
+
return resolveRootDomainFromHostname(window.location.hostname);
|
|
618
641
|
}
|
|
619
642
|
return "localhost";
|
|
620
643
|
}
|
|
@@ -1934,6 +1957,7 @@ function AdvancedSettings({
|
|
|
1934
1957
|
)
|
|
1935
1958
|
] });
|
|
1936
1959
|
}
|
|
1960
|
+
var ACTIVE_CREDENTIAL_STORAGE_KEY = "swype_active_credential_id";
|
|
1937
1961
|
function isMobile() {
|
|
1938
1962
|
if (typeof navigator === "undefined") return false;
|
|
1939
1963
|
return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
|
|
@@ -2037,8 +2061,13 @@ function SwypePayment({
|
|
|
2037
2061
|
const [transfer, setTransfer] = react.useState(null);
|
|
2038
2062
|
const [creatingTransfer, setCreatingTransfer] = react.useState(false);
|
|
2039
2063
|
const [registeringPasskey, setRegisteringPasskey] = react.useState(false);
|
|
2064
|
+
const [activeCredentialId, setActiveCredentialId] = react.useState(() => {
|
|
2065
|
+
if (typeof window === "undefined") return null;
|
|
2066
|
+
return window.localStorage.getItem(ACTIVE_CREDENTIAL_STORAGE_KEY);
|
|
2067
|
+
});
|
|
2040
2068
|
const [mobileFlow, setMobileFlow] = react.useState(false);
|
|
2041
2069
|
const pollingTransferIdRef = react.useRef(null);
|
|
2070
|
+
const mobileSigningTransferIdRef = react.useRef(null);
|
|
2042
2071
|
const [selectSourceChainName, setSelectSourceChainName] = react.useState("");
|
|
2043
2072
|
const [selectSourceTokenSymbol, setSelectSourceTokenSymbol] = react.useState("");
|
|
2044
2073
|
const initializedSelectSourceActionRef = react.useRef(null);
|
|
@@ -2061,7 +2090,7 @@ function SwypePayment({
|
|
|
2061
2090
|
if (!token || cancelled) return;
|
|
2062
2091
|
const { config } = await fetchUserConfig(apiBaseUrl, token);
|
|
2063
2092
|
if (cancelled) return;
|
|
2064
|
-
if (!config.passkey) {
|
|
2093
|
+
if (!config.passkey || !activeCredentialId) {
|
|
2065
2094
|
setStep("register-passkey");
|
|
2066
2095
|
} else if (depositAmount != null && depositAmount > 0) {
|
|
2067
2096
|
setStep("ready");
|
|
@@ -2082,7 +2111,7 @@ function SwypePayment({
|
|
|
2082
2111
|
return () => {
|
|
2083
2112
|
cancelled = true;
|
|
2084
2113
|
};
|
|
2085
|
-
}, [ready, authenticated, step, depositAmount, apiBaseUrl, getAccessToken]);
|
|
2114
|
+
}, [ready, authenticated, step, depositAmount, apiBaseUrl, getAccessToken, activeCredentialId]);
|
|
2086
2115
|
const loadingDataRef = react.useRef(false);
|
|
2087
2116
|
react.useEffect(() => {
|
|
2088
2117
|
if (!authenticated) return;
|
|
@@ -2093,11 +2122,15 @@ function SwypePayment({
|
|
|
2093
2122
|
setLoadingData(true);
|
|
2094
2123
|
setError(null);
|
|
2095
2124
|
try {
|
|
2125
|
+
if (!activeCredentialId) {
|
|
2126
|
+
setStep("register-passkey");
|
|
2127
|
+
return;
|
|
2128
|
+
}
|
|
2096
2129
|
const token = await getAccessToken();
|
|
2097
2130
|
if (!token) throw new Error("Not authenticated");
|
|
2098
2131
|
const [prov, accts, chn] = await Promise.all([
|
|
2099
2132
|
fetchProviders(apiBaseUrl, token),
|
|
2100
|
-
fetchAccounts(apiBaseUrl, token),
|
|
2133
|
+
fetchAccounts(apiBaseUrl, token, activeCredentialId),
|
|
2101
2134
|
fetchChains(apiBaseUrl, token)
|
|
2102
2135
|
]);
|
|
2103
2136
|
if (cancelled) return;
|
|
@@ -2129,7 +2162,7 @@ function SwypePayment({
|
|
|
2129
2162
|
cancelled = true;
|
|
2130
2163
|
loadingDataRef.current = false;
|
|
2131
2164
|
};
|
|
2132
|
-
}, [authenticated, accounts.length, apiBaseUrl, getAccessToken]);
|
|
2165
|
+
}, [authenticated, accounts.length, apiBaseUrl, getAccessToken, activeCredentialId]);
|
|
2133
2166
|
react.useEffect(() => {
|
|
2134
2167
|
if (!polling.transfer) return;
|
|
2135
2168
|
if (polling.transfer.status === "COMPLETED") {
|
|
@@ -2142,6 +2175,27 @@ function SwypePayment({
|
|
|
2142
2175
|
setError("Transfer failed.");
|
|
2143
2176
|
}
|
|
2144
2177
|
}, [polling.transfer, onComplete]);
|
|
2178
|
+
react.useEffect(() => {
|
|
2179
|
+
if (!mobileFlow) return;
|
|
2180
|
+
const polledTransfer = polling.transfer;
|
|
2181
|
+
if (!polledTransfer) return;
|
|
2182
|
+
if (polledTransfer.status !== "AUTHORIZED") return;
|
|
2183
|
+
if (transferSigning.signing) return;
|
|
2184
|
+
if (mobileSigningTransferIdRef.current === polledTransfer.id) return;
|
|
2185
|
+
mobileSigningTransferIdRef.current = polledTransfer.id;
|
|
2186
|
+
const sign = async () => {
|
|
2187
|
+
try {
|
|
2188
|
+
const signedTransfer = await transferSigning.signTransfer(polledTransfer.id);
|
|
2189
|
+
setTransfer(signedTransfer);
|
|
2190
|
+
} catch (err) {
|
|
2191
|
+
mobileSigningTransferIdRef.current = null;
|
|
2192
|
+
const msg = err instanceof Error ? err.message : "Failed to sign transfer";
|
|
2193
|
+
setError(msg);
|
|
2194
|
+
onError?.(msg);
|
|
2195
|
+
}
|
|
2196
|
+
};
|
|
2197
|
+
void sign();
|
|
2198
|
+
}, [mobileFlow, polling.transfer, transferSigning, onError]);
|
|
2145
2199
|
react.useEffect(() => {
|
|
2146
2200
|
if (!mobileFlow || !polling.isPolling) return;
|
|
2147
2201
|
const handleVisibility = () => {
|
|
@@ -2203,6 +2257,11 @@ function SwypePayment({
|
|
|
2203
2257
|
setError("No account or provider selected.");
|
|
2204
2258
|
return;
|
|
2205
2259
|
}
|
|
2260
|
+
if (!activeCredentialId) {
|
|
2261
|
+
setError("Create a passkey on this device before continuing.");
|
|
2262
|
+
setStep("register-passkey");
|
|
2263
|
+
return;
|
|
2264
|
+
}
|
|
2206
2265
|
setStep("processing");
|
|
2207
2266
|
setError(null);
|
|
2208
2267
|
setCreatingTransfer(true);
|
|
@@ -2238,6 +2297,7 @@ function SwypePayment({
|
|
|
2238
2297
|
}
|
|
2239
2298
|
}
|
|
2240
2299
|
const t = await createTransfer(apiBaseUrl, token, {
|
|
2300
|
+
credentialId: activeCredentialId,
|
|
2241
2301
|
sourceType: effectiveSourceType,
|
|
2242
2302
|
sourceId: effectiveSourceId,
|
|
2243
2303
|
destination,
|
|
@@ -2271,6 +2331,7 @@ function SwypePayment({
|
|
|
2271
2331
|
amount,
|
|
2272
2332
|
sourceId,
|
|
2273
2333
|
sourceType,
|
|
2334
|
+
activeCredentialId,
|
|
2274
2335
|
destination,
|
|
2275
2336
|
apiBaseUrl,
|
|
2276
2337
|
getAccessToken,
|
|
@@ -2288,6 +2349,7 @@ function SwypePayment({
|
|
|
2288
2349
|
setAmount(depositAmount != null ? depositAmount.toString() : "");
|
|
2289
2350
|
setMobileFlow(false);
|
|
2290
2351
|
pollingTransferIdRef.current = null;
|
|
2352
|
+
mobileSigningTransferIdRef.current = null;
|
|
2291
2353
|
setConnectingNewAccount(false);
|
|
2292
2354
|
setSelectedWalletId(null);
|
|
2293
2355
|
setAdvancedSettings({ asset: null, chain: null });
|
|
@@ -2468,6 +2530,8 @@ function SwypePayment({
|
|
|
2468
2530
|
if (!token) throw new Error("Not authenticated");
|
|
2469
2531
|
const { credentialId, publicKey } = await createPasskeyCredential("Swype User");
|
|
2470
2532
|
await registerPasskey(apiBaseUrl, token, credentialId, publicKey);
|
|
2533
|
+
setActiveCredentialId(credentialId);
|
|
2534
|
+
window.localStorage.setItem(ACTIVE_CREDENTIAL_STORAGE_KEY, credentialId);
|
|
2471
2535
|
if (depositAmount != null && depositAmount > 0) {
|
|
2472
2536
|
setStep("ready");
|
|
2473
2537
|
} else {
|