@swype-org/react-sdk 0.1.79 → 0.1.81
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 +123 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +9 -1
- package/dist/index.d.ts +9 -1
- package/dist/index.js +123 -13
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -701,13 +701,17 @@ var POPUP_RESULT_TIMEOUT_MS = 12e4;
|
|
|
701
701
|
var POPUP_CLOSED_POLL_MS = 500;
|
|
702
702
|
function createPasskeyViaPopup(options) {
|
|
703
703
|
return new Promise((resolve, reject) => {
|
|
704
|
-
const
|
|
704
|
+
const channelId = `swype-pk-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
705
|
+
const payload = { ...options, channelId };
|
|
706
|
+
const encoded = btoa(JSON.stringify(payload));
|
|
705
707
|
const popupUrl = `${window.location.origin}/passkey-register#${encoded}`;
|
|
706
708
|
const popup = window.open(popupUrl, "swype-passkey");
|
|
707
709
|
if (!popup) {
|
|
708
710
|
reject(new Error("Pop-up blocked. Please allow pop-ups for this site and try again."));
|
|
709
711
|
return;
|
|
710
712
|
}
|
|
713
|
+
let settled = false;
|
|
714
|
+
const channel = typeof BroadcastChannel !== "undefined" ? new BroadcastChannel(channelId) : null;
|
|
711
715
|
const timer = setTimeout(() => {
|
|
712
716
|
cleanup();
|
|
713
717
|
reject(new Error("Passkey creation timed out. Please try again."));
|
|
@@ -718,11 +722,11 @@ function createPasskeyViaPopup(options) {
|
|
|
718
722
|
reject(new Error("Passkey setup window was closed before completing."));
|
|
719
723
|
}
|
|
720
724
|
}, POPUP_CLOSED_POLL_MS);
|
|
721
|
-
|
|
722
|
-
if (
|
|
723
|
-
const data = event.data;
|
|
725
|
+
function handleResult(data) {
|
|
726
|
+
if (settled) return;
|
|
724
727
|
if (!data || typeof data !== "object") return;
|
|
725
728
|
if (data.type !== "swype:passkey-popup-result") return;
|
|
729
|
+
settled = true;
|
|
726
730
|
cleanup();
|
|
727
731
|
if (data.error) {
|
|
728
732
|
reject(new Error(data.error));
|
|
@@ -731,13 +735,21 @@ function createPasskeyViaPopup(options) {
|
|
|
731
735
|
} else {
|
|
732
736
|
reject(new Error("Invalid passkey popup response."));
|
|
733
737
|
}
|
|
738
|
+
}
|
|
739
|
+
if (channel) {
|
|
740
|
+
channel.onmessage = (event) => handleResult(event.data);
|
|
741
|
+
}
|
|
742
|
+
const postMessageHandler = (event) => {
|
|
743
|
+
if (event.source !== popup) return;
|
|
744
|
+
handleResult(event.data);
|
|
734
745
|
};
|
|
746
|
+
window.addEventListener("message", postMessageHandler);
|
|
735
747
|
function cleanup() {
|
|
736
748
|
clearTimeout(timer);
|
|
737
749
|
clearInterval(closedPoll);
|
|
738
|
-
window.removeEventListener("message",
|
|
750
|
+
window.removeEventListener("message", postMessageHandler);
|
|
751
|
+
channel?.close();
|
|
739
752
|
}
|
|
740
|
-
window.addEventListener("message", handler);
|
|
741
753
|
});
|
|
742
754
|
}
|
|
743
755
|
|
|
@@ -3247,12 +3259,15 @@ function DepositScreen({
|
|
|
3247
3259
|
onChangeSource,
|
|
3248
3260
|
onSwitchWallet,
|
|
3249
3261
|
onBack,
|
|
3250
|
-
onLogout
|
|
3262
|
+
onLogout,
|
|
3263
|
+
onIncreaseLimit,
|
|
3264
|
+
increasingLimit
|
|
3251
3265
|
}) {
|
|
3252
3266
|
const { tokens } = useSwypeConfig();
|
|
3253
3267
|
const amount = initialAmount;
|
|
3254
3268
|
const isLowBalance = availableBalance < MIN_DEPOSIT;
|
|
3255
|
-
const
|
|
3269
|
+
const exceedsLimit = amount > remainingLimit && !isLowBalance;
|
|
3270
|
+
const canDeposit = amount >= MIN_DEPOSIT && !exceedsLimit && !isLowBalance && !processing;
|
|
3256
3271
|
const headerTitle = merchantName ? `Deposit to ${merchantName}` : "Deposit";
|
|
3257
3272
|
if (isLowBalance) {
|
|
3258
3273
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -3310,11 +3325,22 @@ function DepositScreen({
|
|
|
3310
3325
|
ScreenLayout,
|
|
3311
3326
|
{
|
|
3312
3327
|
footer: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
3313
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
3314
|
-
"
|
|
3315
|
-
|
|
3328
|
+
exceedsLimit && onIncreaseLimit ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
3329
|
+
/* @__PURE__ */ jsxRuntime.jsx(PrimaryButton, { onClick: onIncreaseLimit, loading: increasingLimit, children: "Increase limit" }),
|
|
3330
|
+
/* @__PURE__ */ jsxRuntime.jsxs("p", { style: limitExceededHintStyle(tokens.warning), children: [
|
|
3331
|
+
"Your deposit of $",
|
|
3332
|
+
amount.toFixed(2),
|
|
3333
|
+
" exceeds your One-Tap limit of $",
|
|
3334
|
+
remainingLimit.toFixed(2),
|
|
3335
|
+
". Increase your limit to continue."
|
|
3336
|
+
] })
|
|
3337
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
3338
|
+
/* @__PURE__ */ jsxRuntime.jsxs(PrimaryButton, { onClick: () => onDeposit(amount), disabled: !canDeposit, loading: processing, children: [
|
|
3339
|
+
"Deposit $",
|
|
3340
|
+
amount.toFixed(2)
|
|
3341
|
+
] }),
|
|
3342
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { style: noApprovalStyle(tokens.textMuted), children: "No approval needed \xB7 within your One-Tap limit" })
|
|
3316
3343
|
] }),
|
|
3317
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { style: noApprovalStyle(tokens.textMuted), children: "No approval needed \xB7 within your One-Tap limit" }),
|
|
3318
3344
|
/* @__PURE__ */ jsxRuntime.jsxs("p", { style: routeStyle(tokens.textMuted), children: [
|
|
3319
3345
|
"From ",
|
|
3320
3346
|
sourceName,
|
|
@@ -3462,6 +3488,13 @@ var noApprovalStyle = (color) => ({
|
|
|
3462
3488
|
color,
|
|
3463
3489
|
margin: "12px 0 2px"
|
|
3464
3490
|
});
|
|
3491
|
+
var limitExceededHintStyle = (color) => ({
|
|
3492
|
+
textAlign: "center",
|
|
3493
|
+
fontSize: "0.78rem",
|
|
3494
|
+
color,
|
|
3495
|
+
margin: "12px 0 2px",
|
|
3496
|
+
lineHeight: 1.5
|
|
3497
|
+
});
|
|
3465
3498
|
var routeStyle = (color) => ({
|
|
3466
3499
|
textAlign: "center",
|
|
3467
3500
|
fontSize: "0.75rem",
|
|
@@ -5210,6 +5243,81 @@ function SwypePaymentInner({
|
|
|
5210
5243
|
merchantAuthorization,
|
|
5211
5244
|
transfer
|
|
5212
5245
|
]);
|
|
5246
|
+
const [increasingLimit, setIncreasingLimit] = react.useState(false);
|
|
5247
|
+
const handleIncreaseLimit = react.useCallback(async () => {
|
|
5248
|
+
const parsedAmount = depositAmount ?? 5;
|
|
5249
|
+
if (!sourceId) {
|
|
5250
|
+
setError("No account or provider selected.");
|
|
5251
|
+
return;
|
|
5252
|
+
}
|
|
5253
|
+
if (!activeCredentialId) {
|
|
5254
|
+
setError("Create a passkey on this device before continuing.");
|
|
5255
|
+
setStep("create-passkey");
|
|
5256
|
+
return;
|
|
5257
|
+
}
|
|
5258
|
+
setError(null);
|
|
5259
|
+
setIncreasingLimit(true);
|
|
5260
|
+
try {
|
|
5261
|
+
const token = await getAccessToken();
|
|
5262
|
+
if (!token) throw new Error("Not authenticated");
|
|
5263
|
+
let effectiveSourceType = sourceType;
|
|
5264
|
+
let effectiveSourceId = sourceId;
|
|
5265
|
+
if (effectiveSourceType === "accountId") {
|
|
5266
|
+
const acct = accounts.find((a) => a.id === effectiveSourceId);
|
|
5267
|
+
const activeWallet = acct?.wallets.find((w) => w.status === "ACTIVE");
|
|
5268
|
+
if (activeWallet) {
|
|
5269
|
+
effectiveSourceType = "walletId";
|
|
5270
|
+
effectiveSourceId = activeWallet.id;
|
|
5271
|
+
}
|
|
5272
|
+
}
|
|
5273
|
+
const t = await createTransfer(apiBaseUrl, token, {
|
|
5274
|
+
id: idempotencyKey,
|
|
5275
|
+
credentialId: activeCredentialId,
|
|
5276
|
+
merchantAuthorization,
|
|
5277
|
+
sourceType: effectiveSourceType,
|
|
5278
|
+
sourceId: effectiveSourceId,
|
|
5279
|
+
destination,
|
|
5280
|
+
amount: parsedAmount
|
|
5281
|
+
});
|
|
5282
|
+
setTransfer(t);
|
|
5283
|
+
if (t.authorizationSessions && t.authorizationSessions.length > 0) {
|
|
5284
|
+
const uri = t.authorizationSessions[0].uri;
|
|
5285
|
+
setMobileFlow(true);
|
|
5286
|
+
pollingTransferIdRef.current = t.id;
|
|
5287
|
+
mobileSetupFlowRef.current = true;
|
|
5288
|
+
handlingMobileReturnRef.current = false;
|
|
5289
|
+
polling.startPolling(t.id);
|
|
5290
|
+
setDeeplinkUri(uri);
|
|
5291
|
+
persistMobileFlowState({
|
|
5292
|
+
transferId: t.id,
|
|
5293
|
+
deeplinkUri: uri,
|
|
5294
|
+
providerId: selectedProviderId,
|
|
5295
|
+
isSetup: true
|
|
5296
|
+
});
|
|
5297
|
+
triggerDeeplink(uri);
|
|
5298
|
+
}
|
|
5299
|
+
} catch (err) {
|
|
5300
|
+
const msg = err instanceof Error ? err.message : "Failed to increase limit";
|
|
5301
|
+
setError(msg);
|
|
5302
|
+
onError?.(msg);
|
|
5303
|
+
} finally {
|
|
5304
|
+
setIncreasingLimit(false);
|
|
5305
|
+
}
|
|
5306
|
+
}, [
|
|
5307
|
+
depositAmount,
|
|
5308
|
+
sourceId,
|
|
5309
|
+
sourceType,
|
|
5310
|
+
activeCredentialId,
|
|
5311
|
+
apiBaseUrl,
|
|
5312
|
+
getAccessToken,
|
|
5313
|
+
accounts,
|
|
5314
|
+
polling,
|
|
5315
|
+
onError,
|
|
5316
|
+
idempotencyKey,
|
|
5317
|
+
merchantAuthorization,
|
|
5318
|
+
destination,
|
|
5319
|
+
selectedProviderId
|
|
5320
|
+
]);
|
|
5213
5321
|
const completePasskeyRegistration = react.useCallback(async (credentialId, publicKey) => {
|
|
5214
5322
|
const token = await getAccessToken();
|
|
5215
5323
|
if (!token) throw new Error("Not authenticated");
|
|
@@ -5471,7 +5579,9 @@ function SwypePaymentInner({
|
|
|
5471
5579
|
onChangeSource: () => setStep("wallet-picker"),
|
|
5472
5580
|
onSwitchWallet: () => setStep("wallet-picker"),
|
|
5473
5581
|
onBack: onBack ?? (() => handleLogout()),
|
|
5474
|
-
onLogout: handleLogout
|
|
5582
|
+
onLogout: handleLogout,
|
|
5583
|
+
onIncreaseLimit: handleIncreaseLimit,
|
|
5584
|
+
increasingLimit
|
|
5475
5585
|
}
|
|
5476
5586
|
);
|
|
5477
5587
|
}
|