@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.d.cts
CHANGED
|
@@ -387,8 +387,9 @@ declare function useTransferSigning(pollIntervalMs?: number, options?: UseTransf
|
|
|
387
387
|
|
|
388
388
|
declare function fetchProviders(apiBaseUrl: string, token: string): Promise<Provider[]>;
|
|
389
389
|
declare function fetchChains(apiBaseUrl: string, token: string): Promise<Chain[]>;
|
|
390
|
-
declare function fetchAccounts(apiBaseUrl: string, token: string): Promise<Account[]>;
|
|
390
|
+
declare function fetchAccounts(apiBaseUrl: string, token: string, credentialId: string): Promise<Account[]>;
|
|
391
391
|
interface CreateTransferParams {
|
|
392
|
+
credentialId: string;
|
|
392
393
|
sourceType: SourceType;
|
|
393
394
|
sourceId: string;
|
|
394
395
|
destination: Destination;
|
package/dist/index.d.ts
CHANGED
|
@@ -387,8 +387,9 @@ declare function useTransferSigning(pollIntervalMs?: number, options?: UseTransf
|
|
|
387
387
|
|
|
388
388
|
declare function fetchProviders(apiBaseUrl: string, token: string): Promise<Provider[]>;
|
|
389
389
|
declare function fetchChains(apiBaseUrl: string, token: string): Promise<Chain[]>;
|
|
390
|
-
declare function fetchAccounts(apiBaseUrl: string, token: string): Promise<Account[]>;
|
|
390
|
+
declare function fetchAccounts(apiBaseUrl: string, token: string, credentialId: string): Promise<Account[]>;
|
|
391
391
|
interface CreateTransferParams {
|
|
392
|
+
credentialId: string;
|
|
392
393
|
sourceType: SourceType;
|
|
393
394
|
sourceId: string;
|
|
394
395
|
destination: Destination;
|
package/dist/index.js
CHANGED
|
@@ -175,8 +175,9 @@ async function fetchChains(apiBaseUrl, token) {
|
|
|
175
175
|
const data = await res.json();
|
|
176
176
|
return data.items;
|
|
177
177
|
}
|
|
178
|
-
async function fetchAccounts(apiBaseUrl, token) {
|
|
179
|
-
const
|
|
178
|
+
async function fetchAccounts(apiBaseUrl, token, credentialId) {
|
|
179
|
+
const params = new URLSearchParams({ credentialId });
|
|
180
|
+
const res = await fetch(`${apiBaseUrl}/v1/accounts?${params.toString()}`, {
|
|
180
181
|
headers: { Authorization: `Bearer ${token}` }
|
|
181
182
|
});
|
|
182
183
|
if (!res.ok) await throwApiError(res);
|
|
@@ -186,6 +187,7 @@ async function fetchAccounts(apiBaseUrl, token) {
|
|
|
186
187
|
async function createTransfer(apiBaseUrl, token, params) {
|
|
187
188
|
const body = {
|
|
188
189
|
id: crypto.randomUUID(),
|
|
190
|
+
credentialId: params.credentialId,
|
|
189
191
|
sources: [{ [params.sourceType]: params.sourceId }],
|
|
190
192
|
destinations: [
|
|
191
193
|
{
|
|
@@ -558,6 +560,27 @@ async function getWalletClient(config, parameters = {}) {
|
|
|
558
560
|
const client = await getConnectorClient(config, parameters);
|
|
559
561
|
return client.extend(walletActions);
|
|
560
562
|
}
|
|
563
|
+
|
|
564
|
+
// src/passkeyRpId.ts
|
|
565
|
+
function normalizeConfiguredDomain(value) {
|
|
566
|
+
return value.replace(/^https?:\/\//, "").replace(/\/.*$/, "").replace(/^\./, "").trim();
|
|
567
|
+
}
|
|
568
|
+
function resolveRootDomainFromHostname(hostname) {
|
|
569
|
+
const trimmedHostname = hostname.trim().toLowerCase();
|
|
570
|
+
if (!trimmedHostname) {
|
|
571
|
+
return "localhost";
|
|
572
|
+
}
|
|
573
|
+
if (trimmedHostname === "localhost" || /^\d{1,3}(?:\.\d{1,3}){3}$/.test(trimmedHostname)) {
|
|
574
|
+
return trimmedHostname;
|
|
575
|
+
}
|
|
576
|
+
const parts = trimmedHostname.split(".").filter(Boolean);
|
|
577
|
+
if (parts.length < 2) {
|
|
578
|
+
return trimmedHostname;
|
|
579
|
+
}
|
|
580
|
+
return parts.slice(-2).join(".");
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
// src/hooks.ts
|
|
561
584
|
var WALLET_CLIENT_MAX_ATTEMPTS = 15;
|
|
562
585
|
var WALLET_CLIENT_POLL_MS = 200;
|
|
563
586
|
var ACTION_POLL_INTERVAL_MS = 500;
|
|
@@ -608,10 +631,10 @@ function readEnvValue(name) {
|
|
|
608
631
|
function resolvePasskeyRpId() {
|
|
609
632
|
const configuredDomain = readEnvValue("VITE_DOMAIN") ?? readEnvValue("SWYPE_DOMAIN");
|
|
610
633
|
if (configuredDomain) {
|
|
611
|
-
return configuredDomain
|
|
634
|
+
return normalizeConfiguredDomain(configuredDomain);
|
|
612
635
|
}
|
|
613
636
|
if (typeof window !== "undefined") {
|
|
614
|
-
return window.location.hostname;
|
|
637
|
+
return resolveRootDomainFromHostname(window.location.hostname);
|
|
615
638
|
}
|
|
616
639
|
return "localhost";
|
|
617
640
|
}
|
|
@@ -1931,6 +1954,7 @@ function AdvancedSettings({
|
|
|
1931
1954
|
)
|
|
1932
1955
|
] });
|
|
1933
1956
|
}
|
|
1957
|
+
var ACTIVE_CREDENTIAL_STORAGE_KEY = "swype_active_credential_id";
|
|
1934
1958
|
function isMobile() {
|
|
1935
1959
|
if (typeof navigator === "undefined") return false;
|
|
1936
1960
|
return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
|
|
@@ -2034,8 +2058,13 @@ function SwypePayment({
|
|
|
2034
2058
|
const [transfer, setTransfer] = useState(null);
|
|
2035
2059
|
const [creatingTransfer, setCreatingTransfer] = useState(false);
|
|
2036
2060
|
const [registeringPasskey, setRegisteringPasskey] = useState(false);
|
|
2061
|
+
const [activeCredentialId, setActiveCredentialId] = useState(() => {
|
|
2062
|
+
if (typeof window === "undefined") return null;
|
|
2063
|
+
return window.localStorage.getItem(ACTIVE_CREDENTIAL_STORAGE_KEY);
|
|
2064
|
+
});
|
|
2037
2065
|
const [mobileFlow, setMobileFlow] = useState(false);
|
|
2038
2066
|
const pollingTransferIdRef = useRef(null);
|
|
2067
|
+
const mobileSigningTransferIdRef = useRef(null);
|
|
2039
2068
|
const [selectSourceChainName, setSelectSourceChainName] = useState("");
|
|
2040
2069
|
const [selectSourceTokenSymbol, setSelectSourceTokenSymbol] = useState("");
|
|
2041
2070
|
const initializedSelectSourceActionRef = useRef(null);
|
|
@@ -2058,7 +2087,7 @@ function SwypePayment({
|
|
|
2058
2087
|
if (!token || cancelled) return;
|
|
2059
2088
|
const { config } = await fetchUserConfig(apiBaseUrl, token);
|
|
2060
2089
|
if (cancelled) return;
|
|
2061
|
-
if (!config.passkey) {
|
|
2090
|
+
if (!config.passkey || !activeCredentialId) {
|
|
2062
2091
|
setStep("register-passkey");
|
|
2063
2092
|
} else if (depositAmount != null && depositAmount > 0) {
|
|
2064
2093
|
setStep("ready");
|
|
@@ -2079,7 +2108,7 @@ function SwypePayment({
|
|
|
2079
2108
|
return () => {
|
|
2080
2109
|
cancelled = true;
|
|
2081
2110
|
};
|
|
2082
|
-
}, [ready, authenticated, step, depositAmount, apiBaseUrl, getAccessToken]);
|
|
2111
|
+
}, [ready, authenticated, step, depositAmount, apiBaseUrl, getAccessToken, activeCredentialId]);
|
|
2083
2112
|
const loadingDataRef = useRef(false);
|
|
2084
2113
|
useEffect(() => {
|
|
2085
2114
|
if (!authenticated) return;
|
|
@@ -2090,11 +2119,15 @@ function SwypePayment({
|
|
|
2090
2119
|
setLoadingData(true);
|
|
2091
2120
|
setError(null);
|
|
2092
2121
|
try {
|
|
2122
|
+
if (!activeCredentialId) {
|
|
2123
|
+
setStep("register-passkey");
|
|
2124
|
+
return;
|
|
2125
|
+
}
|
|
2093
2126
|
const token = await getAccessToken();
|
|
2094
2127
|
if (!token) throw new Error("Not authenticated");
|
|
2095
2128
|
const [prov, accts, chn] = await Promise.all([
|
|
2096
2129
|
fetchProviders(apiBaseUrl, token),
|
|
2097
|
-
fetchAccounts(apiBaseUrl, token),
|
|
2130
|
+
fetchAccounts(apiBaseUrl, token, activeCredentialId),
|
|
2098
2131
|
fetchChains(apiBaseUrl, token)
|
|
2099
2132
|
]);
|
|
2100
2133
|
if (cancelled) return;
|
|
@@ -2126,7 +2159,7 @@ function SwypePayment({
|
|
|
2126
2159
|
cancelled = true;
|
|
2127
2160
|
loadingDataRef.current = false;
|
|
2128
2161
|
};
|
|
2129
|
-
}, [authenticated, accounts.length, apiBaseUrl, getAccessToken]);
|
|
2162
|
+
}, [authenticated, accounts.length, apiBaseUrl, getAccessToken, activeCredentialId]);
|
|
2130
2163
|
useEffect(() => {
|
|
2131
2164
|
if (!polling.transfer) return;
|
|
2132
2165
|
if (polling.transfer.status === "COMPLETED") {
|
|
@@ -2139,6 +2172,27 @@ function SwypePayment({
|
|
|
2139
2172
|
setError("Transfer failed.");
|
|
2140
2173
|
}
|
|
2141
2174
|
}, [polling.transfer, onComplete]);
|
|
2175
|
+
useEffect(() => {
|
|
2176
|
+
if (!mobileFlow) return;
|
|
2177
|
+
const polledTransfer = polling.transfer;
|
|
2178
|
+
if (!polledTransfer) return;
|
|
2179
|
+
if (polledTransfer.status !== "AUTHORIZED") return;
|
|
2180
|
+
if (transferSigning.signing) return;
|
|
2181
|
+
if (mobileSigningTransferIdRef.current === polledTransfer.id) return;
|
|
2182
|
+
mobileSigningTransferIdRef.current = polledTransfer.id;
|
|
2183
|
+
const sign = async () => {
|
|
2184
|
+
try {
|
|
2185
|
+
const signedTransfer = await transferSigning.signTransfer(polledTransfer.id);
|
|
2186
|
+
setTransfer(signedTransfer);
|
|
2187
|
+
} catch (err) {
|
|
2188
|
+
mobileSigningTransferIdRef.current = null;
|
|
2189
|
+
const msg = err instanceof Error ? err.message : "Failed to sign transfer";
|
|
2190
|
+
setError(msg);
|
|
2191
|
+
onError?.(msg);
|
|
2192
|
+
}
|
|
2193
|
+
};
|
|
2194
|
+
void sign();
|
|
2195
|
+
}, [mobileFlow, polling.transfer, transferSigning, onError]);
|
|
2142
2196
|
useEffect(() => {
|
|
2143
2197
|
if (!mobileFlow || !polling.isPolling) return;
|
|
2144
2198
|
const handleVisibility = () => {
|
|
@@ -2200,6 +2254,11 @@ function SwypePayment({
|
|
|
2200
2254
|
setError("No account or provider selected.");
|
|
2201
2255
|
return;
|
|
2202
2256
|
}
|
|
2257
|
+
if (!activeCredentialId) {
|
|
2258
|
+
setError("Create a passkey on this device before continuing.");
|
|
2259
|
+
setStep("register-passkey");
|
|
2260
|
+
return;
|
|
2261
|
+
}
|
|
2203
2262
|
setStep("processing");
|
|
2204
2263
|
setError(null);
|
|
2205
2264
|
setCreatingTransfer(true);
|
|
@@ -2235,6 +2294,7 @@ function SwypePayment({
|
|
|
2235
2294
|
}
|
|
2236
2295
|
}
|
|
2237
2296
|
const t = await createTransfer(apiBaseUrl, token, {
|
|
2297
|
+
credentialId: activeCredentialId,
|
|
2238
2298
|
sourceType: effectiveSourceType,
|
|
2239
2299
|
sourceId: effectiveSourceId,
|
|
2240
2300
|
destination,
|
|
@@ -2268,6 +2328,7 @@ function SwypePayment({
|
|
|
2268
2328
|
amount,
|
|
2269
2329
|
sourceId,
|
|
2270
2330
|
sourceType,
|
|
2331
|
+
activeCredentialId,
|
|
2271
2332
|
destination,
|
|
2272
2333
|
apiBaseUrl,
|
|
2273
2334
|
getAccessToken,
|
|
@@ -2285,6 +2346,7 @@ function SwypePayment({
|
|
|
2285
2346
|
setAmount(depositAmount != null ? depositAmount.toString() : "");
|
|
2286
2347
|
setMobileFlow(false);
|
|
2287
2348
|
pollingTransferIdRef.current = null;
|
|
2349
|
+
mobileSigningTransferIdRef.current = null;
|
|
2288
2350
|
setConnectingNewAccount(false);
|
|
2289
2351
|
setSelectedWalletId(null);
|
|
2290
2352
|
setAdvancedSettings({ asset: null, chain: null });
|
|
@@ -2465,6 +2527,8 @@ function SwypePayment({
|
|
|
2465
2527
|
if (!token) throw new Error("Not authenticated");
|
|
2466
2528
|
const { credentialId, publicKey } = await createPasskeyCredential("Swype User");
|
|
2467
2529
|
await registerPasskey(apiBaseUrl, token, credentialId, publicKey);
|
|
2530
|
+
setActiveCredentialId(credentialId);
|
|
2531
|
+
window.localStorage.setItem(ACTIVE_CREDENTIAL_STORAGE_KEY, credentialId);
|
|
2468
2532
|
if (depositAmount != null && depositAmount > 0) {
|
|
2469
2533
|
setStep("ready");
|
|
2470
2534
|
} else {
|