@swype-org/react-sdk 0.1.14 → 0.1.16
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 +73 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +13 -1
- package/dist/index.d.ts +13 -1
- package/dist/index.js +73 -11
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -308,6 +308,18 @@ declare function createPasskeyCredential(userIdentifier: string): Promise<{
|
|
|
308
308
|
credentialId: string;
|
|
309
309
|
publicKey: string;
|
|
310
310
|
}>;
|
|
311
|
+
/**
|
|
312
|
+
* Checks whether the current device's platform authenticator holds a passkey
|
|
313
|
+
* matching the given credential ID.
|
|
314
|
+
*
|
|
315
|
+
* Uses `navigator.credentials.get()` with a throwaway challenge and a short
|
|
316
|
+
* timeout. If the authenticator responds, the device has the key. If it
|
|
317
|
+
* throws (NotAllowedError, timeout, etc.), the device does not.
|
|
318
|
+
*
|
|
319
|
+
* @param credentialId - Base64-encoded WebAuthn credential ID from the server.
|
|
320
|
+
* @returns `true` if the device can authenticate with this credential.
|
|
321
|
+
*/
|
|
322
|
+
declare function deviceHasPasskey(credentialId: string): Promise<boolean>;
|
|
311
323
|
interface UseTransferPollingResult {
|
|
312
324
|
transfer: Transfer | null;
|
|
313
325
|
error: string | null;
|
|
@@ -449,4 +461,4 @@ declare namespace api {
|
|
|
449
461
|
export { type api_CreateTransferParams as CreateTransferParams, api_createTransfer as createTransfer, api_fetchAccounts as fetchAccounts, api_fetchAuthorizationSession as fetchAuthorizationSession, api_fetchChains as fetchChains, api_fetchProviders as fetchProviders, api_fetchTransfer as fetchTransfer, api_fetchUserConfig as fetchUserConfig, api_registerPasskey as registerPasskey, api_reportActionCompletion as reportActionCompletion, api_signTransfer as signTransfer, api_updateUserConfig as updateUserConfig, api_updateUserConfigBySession as updateUserConfigBySession };
|
|
450
462
|
}
|
|
451
463
|
|
|
452
|
-
export { type Account, type ActionExecutionResult, type AdvancedSettings, type Amount, type AuthorizationAction, type AuthorizationSession, type AuthorizationSessionDetail, type Chain, type Destination, type ErrorResponse, type ListResponse, type PaymentStep, type Provider, type SourceOption, type SourceSelection, type SourceType, SwypePayment, type SwypePaymentProps, SwypeProvider, type SwypeProviderProps, type ThemeMode, type ThemeTokens, type TokenBalance, type Transfer, type TransferDestination, type UserConfig, type Wallet, type WalletSource, type WalletToken, createPasskeyCredential, darkTheme, getTheme, lightTheme, api as swypeApi, useAuthorizationExecutor, useSwypeConfig, useSwypeDepositAmount, useTransferPolling, useTransferSigning };
|
|
464
|
+
export { type Account, type ActionExecutionResult, type AdvancedSettings, type Amount, type AuthorizationAction, type AuthorizationSession, type AuthorizationSessionDetail, type Chain, type Destination, type ErrorResponse, type ListResponse, type PaymentStep, type Provider, type SourceOption, type SourceSelection, type SourceType, SwypePayment, type SwypePaymentProps, SwypeProvider, type SwypeProviderProps, type ThemeMode, type ThemeTokens, type TokenBalance, type Transfer, type TransferDestination, type UserConfig, type Wallet, type WalletSource, type WalletToken, createPasskeyCredential, darkTheme, deviceHasPasskey, getTheme, lightTheme, api as swypeApi, useAuthorizationExecutor, useSwypeConfig, useSwypeDepositAmount, useTransferPolling, useTransferSigning };
|
package/dist/index.d.ts
CHANGED
|
@@ -308,6 +308,18 @@ declare function createPasskeyCredential(userIdentifier: string): Promise<{
|
|
|
308
308
|
credentialId: string;
|
|
309
309
|
publicKey: string;
|
|
310
310
|
}>;
|
|
311
|
+
/**
|
|
312
|
+
* Checks whether the current device's platform authenticator holds a passkey
|
|
313
|
+
* matching the given credential ID.
|
|
314
|
+
*
|
|
315
|
+
* Uses `navigator.credentials.get()` with a throwaway challenge and a short
|
|
316
|
+
* timeout. If the authenticator responds, the device has the key. If it
|
|
317
|
+
* throws (NotAllowedError, timeout, etc.), the device does not.
|
|
318
|
+
*
|
|
319
|
+
* @param credentialId - Base64-encoded WebAuthn credential ID from the server.
|
|
320
|
+
* @returns `true` if the device can authenticate with this credential.
|
|
321
|
+
*/
|
|
322
|
+
declare function deviceHasPasskey(credentialId: string): Promise<boolean>;
|
|
311
323
|
interface UseTransferPollingResult {
|
|
312
324
|
transfer: Transfer | null;
|
|
313
325
|
error: string | null;
|
|
@@ -449,4 +461,4 @@ declare namespace api {
|
|
|
449
461
|
export { type api_CreateTransferParams as CreateTransferParams, api_createTransfer as createTransfer, api_fetchAccounts as fetchAccounts, api_fetchAuthorizationSession as fetchAuthorizationSession, api_fetchChains as fetchChains, api_fetchProviders as fetchProviders, api_fetchTransfer as fetchTransfer, api_fetchUserConfig as fetchUserConfig, api_registerPasskey as registerPasskey, api_reportActionCompletion as reportActionCompletion, api_signTransfer as signTransfer, api_updateUserConfig as updateUserConfig, api_updateUserConfigBySession as updateUserConfigBySession };
|
|
450
462
|
}
|
|
451
463
|
|
|
452
|
-
export { type Account, type ActionExecutionResult, type AdvancedSettings, type Amount, type AuthorizationAction, type AuthorizationSession, type AuthorizationSessionDetail, type Chain, type Destination, type ErrorResponse, type ListResponse, type PaymentStep, type Provider, type SourceOption, type SourceSelection, type SourceType, SwypePayment, type SwypePaymentProps, SwypeProvider, type SwypeProviderProps, type ThemeMode, type ThemeTokens, type TokenBalance, type Transfer, type TransferDestination, type UserConfig, type Wallet, type WalletSource, type WalletToken, createPasskeyCredential, darkTheme, getTheme, lightTheme, api as swypeApi, useAuthorizationExecutor, useSwypeConfig, useSwypeDepositAmount, useTransferPolling, useTransferSigning };
|
|
464
|
+
export { type Account, type ActionExecutionResult, type AdvancedSettings, type Amount, type AuthorizationAction, type AuthorizationSession, type AuthorizationSessionDetail, type Chain, type Destination, type ErrorResponse, type ListResponse, type PaymentStep, type Provider, type SourceOption, type SourceSelection, type SourceType, SwypePayment, type SwypePaymentProps, SwypeProvider, type SwypeProviderProps, type ThemeMode, type ThemeTokens, type TokenBalance, type Transfer, type TransferDestination, type UserConfig, type Wallet, type WalletSource, type WalletToken, createPasskeyCredential, darkTheme, deviceHasPasskey, getTheme, lightTheme, api as swypeApi, useAuthorizationExecutor, useSwypeConfig, useSwypeDepositAmount, useTransferPolling, useTransferSigning };
|
package/dist/index.js
CHANGED
|
@@ -588,6 +588,28 @@ var ACTION_POLL_MAX_RETRIES = 20;
|
|
|
588
588
|
var SIGN_PERMIT2_POLL_MS = 1e3;
|
|
589
589
|
var SIGN_PERMIT2_MAX_POLLS = 15;
|
|
590
590
|
var TRANSFER_SIGN_MAX_POLLS = 60;
|
|
591
|
+
function waitForDocumentFocus(timeoutMs = 5e3, intervalMs = 100) {
|
|
592
|
+
return new Promise((resolve, reject) => {
|
|
593
|
+
if (typeof document === "undefined") {
|
|
594
|
+
resolve();
|
|
595
|
+
return;
|
|
596
|
+
}
|
|
597
|
+
if (document.hasFocus()) {
|
|
598
|
+
resolve();
|
|
599
|
+
return;
|
|
600
|
+
}
|
|
601
|
+
const deadline = Date.now() + timeoutMs;
|
|
602
|
+
const timer = setInterval(() => {
|
|
603
|
+
if (document.hasFocus()) {
|
|
604
|
+
clearInterval(timer);
|
|
605
|
+
resolve();
|
|
606
|
+
} else if (Date.now() >= deadline) {
|
|
607
|
+
clearInterval(timer);
|
|
608
|
+
resolve();
|
|
609
|
+
}
|
|
610
|
+
}, intervalMs);
|
|
611
|
+
});
|
|
612
|
+
}
|
|
591
613
|
function actionSuccess(action, message, data) {
|
|
592
614
|
return { actionId: action.id, type: action.type, status: "success", message, data };
|
|
593
615
|
}
|
|
@@ -679,6 +701,7 @@ async function createPasskeyCredential(userIdentifier) {
|
|
|
679
701
|
const challenge = new Uint8Array(32);
|
|
680
702
|
crypto.getRandomValues(challenge);
|
|
681
703
|
const rpId = resolvePasskeyRpId();
|
|
704
|
+
await waitForDocumentFocus();
|
|
682
705
|
const credential = await navigator.credentials.create({
|
|
683
706
|
publicKey: {
|
|
684
707
|
challenge,
|
|
@@ -712,6 +735,28 @@ async function createPasskeyCredential(userIdentifier) {
|
|
|
712
735
|
publicKey: publicKeyBytes ? toBase64(publicKeyBytes) : ""
|
|
713
736
|
};
|
|
714
737
|
}
|
|
738
|
+
async function deviceHasPasskey(credentialId) {
|
|
739
|
+
try {
|
|
740
|
+
const challenge = new Uint8Array(32);
|
|
741
|
+
crypto.getRandomValues(challenge);
|
|
742
|
+
await waitForDocumentFocus();
|
|
743
|
+
const assertion = await navigator.credentials.get({
|
|
744
|
+
publicKey: {
|
|
745
|
+
challenge,
|
|
746
|
+
rpId: resolvePasskeyRpId(),
|
|
747
|
+
allowCredentials: [{
|
|
748
|
+
type: "public-key",
|
|
749
|
+
id: base64ToBytes(credentialId)
|
|
750
|
+
}],
|
|
751
|
+
userVerification: "required",
|
|
752
|
+
timeout: 3e4
|
|
753
|
+
}
|
|
754
|
+
});
|
|
755
|
+
return assertion != null;
|
|
756
|
+
} catch {
|
|
757
|
+
return false;
|
|
758
|
+
}
|
|
759
|
+
}
|
|
715
760
|
function useTransferPolling(intervalMs = 3e3) {
|
|
716
761
|
const { apiBaseUrl } = useSwypeConfig();
|
|
717
762
|
const { getAccessToken } = usePrivy();
|
|
@@ -1184,6 +1229,7 @@ function useTransferSigning(pollIntervalMs = 2e3, options) {
|
|
|
1184
1229
|
type: "public-key",
|
|
1185
1230
|
id: base64ToBytes(payload.passkeyCredentialId)
|
|
1186
1231
|
}] : void 0;
|
|
1232
|
+
await waitForDocumentFocus();
|
|
1187
1233
|
const assertion = await navigator.credentials.get({
|
|
1188
1234
|
publicKey: {
|
|
1189
1235
|
challenge: hashBytes,
|
|
@@ -1980,6 +2026,7 @@ function buildProcessingTimeoutMessage(status) {
|
|
|
1980
2026
|
return `Payment is taking longer than expected (status: ${status}). Please try again.`;
|
|
1981
2027
|
}
|
|
1982
2028
|
var ACTIVE_CREDENTIAL_STORAGE_KEY = "swype_active_credential_id";
|
|
2029
|
+
var MIN_SEND_AMOUNT_USD = 0.25;
|
|
1983
2030
|
function isMobile() {
|
|
1984
2031
|
if (typeof navigator === "undefined") return false;
|
|
1985
2032
|
return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
|
|
@@ -2113,12 +2160,27 @@ function SwypePayment({
|
|
|
2113
2160
|
if (!token || cancelled) return;
|
|
2114
2161
|
const { config } = await fetchUserConfig(apiBaseUrl, token);
|
|
2115
2162
|
if (cancelled) return;
|
|
2116
|
-
if (
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2163
|
+
if (config.passkey?.credentialId) {
|
|
2164
|
+
const hasKey = activeCredentialId ? activeCredentialId === config.passkey.credentialId : await deviceHasPasskey(config.passkey.credentialId);
|
|
2165
|
+
if (cancelled) return;
|
|
2166
|
+
if (hasKey) {
|
|
2167
|
+
if (!activeCredentialId) {
|
|
2168
|
+
setActiveCredentialId(config.passkey.credentialId);
|
|
2169
|
+
window.localStorage.setItem(
|
|
2170
|
+
ACTIVE_CREDENTIAL_STORAGE_KEY,
|
|
2171
|
+
config.passkey.credentialId
|
|
2172
|
+
);
|
|
2173
|
+
}
|
|
2174
|
+
if (depositAmount != null && depositAmount > 0) {
|
|
2175
|
+
setStep("ready");
|
|
2176
|
+
} else {
|
|
2177
|
+
setStep("enter-amount");
|
|
2178
|
+
}
|
|
2179
|
+
} else {
|
|
2180
|
+
setStep("register-passkey");
|
|
2181
|
+
}
|
|
2120
2182
|
} else {
|
|
2121
|
-
setStep("
|
|
2183
|
+
setStep("register-passkey");
|
|
2122
2184
|
}
|
|
2123
2185
|
} catch {
|
|
2124
2186
|
if (!cancelled) {
|
|
@@ -2305,8 +2367,8 @@ function SwypePayment({
|
|
|
2305
2367
|
}, [pendingSelectSourceAction, selectSourceChoices, selectSourceRecommended]);
|
|
2306
2368
|
const handlePay = useCallback(async () => {
|
|
2307
2369
|
const parsedAmount = parseFloat(amount);
|
|
2308
|
-
if (isNaN(parsedAmount) || parsedAmount
|
|
2309
|
-
setError(
|
|
2370
|
+
if (isNaN(parsedAmount) || parsedAmount < MIN_SEND_AMOUNT_USD) {
|
|
2371
|
+
setError(`Minimum amount is $${MIN_SEND_AMOUNT_USD.toFixed(2)}.`);
|
|
2310
2372
|
return;
|
|
2311
2373
|
}
|
|
2312
2374
|
if (!sourceId) {
|
|
@@ -2682,7 +2744,7 @@ function SwypePayment({
|
|
|
2682
2744
|
}
|
|
2683
2745
|
if (step === "enter-amount") {
|
|
2684
2746
|
const parsedAmount = parseFloat(amount);
|
|
2685
|
-
const canContinue = !isNaN(parsedAmount) && parsedAmount
|
|
2747
|
+
const canContinue = !isNaN(parsedAmount) && parsedAmount >= MIN_SEND_AMOUNT_USD;
|
|
2686
2748
|
let maxSourceBalance = null;
|
|
2687
2749
|
for (const acct of accounts) {
|
|
2688
2750
|
for (const wallet of acct.wallets) {
|
|
@@ -2729,7 +2791,7 @@ function SwypePayment({
|
|
|
2729
2791
|
"input",
|
|
2730
2792
|
{
|
|
2731
2793
|
type: "number",
|
|
2732
|
-
min:
|
|
2794
|
+
min: MIN_SEND_AMOUNT_USD.toFixed(2),
|
|
2733
2795
|
step: "0.01",
|
|
2734
2796
|
value: amount,
|
|
2735
2797
|
onChange: (e) => setAmount(e.target.value),
|
|
@@ -2799,7 +2861,7 @@ function SwypePayment({
|
|
|
2799
2861
|
}
|
|
2800
2862
|
if (step === "ready") {
|
|
2801
2863
|
const parsedAmount = parseFloat(amount);
|
|
2802
|
-
const canPay = !isNaN(parsedAmount) && parsedAmount
|
|
2864
|
+
const canPay = !isNaN(parsedAmount) && parsedAmount >= MIN_SEND_AMOUNT_USD && !!sourceId && !loadingData;
|
|
2803
2865
|
const noAccounts = !loadingData && accounts.length === 0;
|
|
2804
2866
|
return /* @__PURE__ */ jsxs("div", { style: cardStyle, children: [
|
|
2805
2867
|
/* @__PURE__ */ jsxs("div", { style: { position: "relative" }, children: [
|
|
@@ -3430,6 +3492,6 @@ function SwypePayment({
|
|
|
3430
3492
|
return null;
|
|
3431
3493
|
}
|
|
3432
3494
|
|
|
3433
|
-
export { SwypePayment, SwypeProvider, createPasskeyCredential, darkTheme, getTheme, lightTheme, api_exports as swypeApi, useAuthorizationExecutor, useSwypeConfig, useSwypeDepositAmount, useTransferPolling, useTransferSigning };
|
|
3495
|
+
export { SwypePayment, SwypeProvider, createPasskeyCredential, darkTheme, deviceHasPasskey, getTheme, lightTheme, api_exports as swypeApi, useAuthorizationExecutor, useSwypeConfig, useSwypeDepositAmount, useTransferPolling, useTransferSigning };
|
|
3434
3496
|
//# sourceMappingURL=index.js.map
|
|
3435
3497
|
//# sourceMappingURL=index.js.map
|