@swype-org/react-sdk 0.1.83 → 0.1.85
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 +253 -54
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +44 -3
- package/dist/index.d.ts +44 -3
- package/dist/index.js +252 -55
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -716,7 +716,7 @@ function isSafari() {
|
|
|
716
716
|
var POPUP_RESULT_TIMEOUT_MS = 12e4;
|
|
717
717
|
var POPUP_CLOSED_POLL_MS = 500;
|
|
718
718
|
var POPUP_CLOSED_GRACE_MS = 1e3;
|
|
719
|
-
function createPasskeyViaPopup(options) {
|
|
719
|
+
function createPasskeyViaPopup(options, existingCredentialIds = []) {
|
|
720
720
|
return new Promise((resolve, reject) => {
|
|
721
721
|
const channelId = `swype-pk-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
722
722
|
const payload = { ...options, channelId };
|
|
@@ -740,7 +740,19 @@ function createPasskeyViaPopup(options) {
|
|
|
740
740
|
closedGraceTimer = setTimeout(() => {
|
|
741
741
|
if (!settled) {
|
|
742
742
|
cleanup();
|
|
743
|
-
|
|
743
|
+
checkServerForNewPasskey(
|
|
744
|
+
options.authToken,
|
|
745
|
+
options.apiBaseUrl,
|
|
746
|
+
existingCredentialIds
|
|
747
|
+
).then((result) => {
|
|
748
|
+
if (result) {
|
|
749
|
+
resolve(result);
|
|
750
|
+
} else {
|
|
751
|
+
reject(new Error("Passkey setup window was closed before completing."));
|
|
752
|
+
}
|
|
753
|
+
}).catch(() => {
|
|
754
|
+
reject(new Error("Passkey setup window was closed before completing."));
|
|
755
|
+
});
|
|
744
756
|
}
|
|
745
757
|
}, POPUP_CLOSED_GRACE_MS);
|
|
746
758
|
}
|
|
@@ -776,6 +788,78 @@ function createPasskeyViaPopup(options) {
|
|
|
776
788
|
}
|
|
777
789
|
});
|
|
778
790
|
}
|
|
791
|
+
var VERIFY_POPUP_TIMEOUT_MS = 6e4;
|
|
792
|
+
function findDevicePasskeyViaPopup(options) {
|
|
793
|
+
return new Promise((resolve, reject) => {
|
|
794
|
+
const channelId = `swype-pv-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
795
|
+
const payload = { ...options, channelId };
|
|
796
|
+
const encoded = btoa(JSON.stringify(payload));
|
|
797
|
+
const popupUrl = `${window.location.origin}/passkey-verify#${encoded}`;
|
|
798
|
+
const popup = window.open(popupUrl, "swype-passkey-verify");
|
|
799
|
+
if (!popup) {
|
|
800
|
+
reject(new Error("Pop-up blocked. Please allow pop-ups for this site and try again."));
|
|
801
|
+
return;
|
|
802
|
+
}
|
|
803
|
+
let settled = false;
|
|
804
|
+
const channel = typeof BroadcastChannel !== "undefined" ? new BroadcastChannel(channelId) : null;
|
|
805
|
+
const timer = setTimeout(() => {
|
|
806
|
+
cleanup();
|
|
807
|
+
resolve(null);
|
|
808
|
+
}, VERIFY_POPUP_TIMEOUT_MS);
|
|
809
|
+
const closedPoll = setInterval(() => {
|
|
810
|
+
if (popup.closed && !settled) {
|
|
811
|
+
clearInterval(closedPoll);
|
|
812
|
+
setTimeout(() => {
|
|
813
|
+
if (!settled) {
|
|
814
|
+
cleanup();
|
|
815
|
+
resolve(null);
|
|
816
|
+
}
|
|
817
|
+
}, POPUP_CLOSED_GRACE_MS);
|
|
818
|
+
}
|
|
819
|
+
}, POPUP_CLOSED_POLL_MS);
|
|
820
|
+
function handleResult(data) {
|
|
821
|
+
if (settled) return;
|
|
822
|
+
if (!data || typeof data !== "object") return;
|
|
823
|
+
if (data.type !== "swype:passkey-verify-result") return;
|
|
824
|
+
settled = true;
|
|
825
|
+
cleanup();
|
|
826
|
+
if (data.error) {
|
|
827
|
+
resolve(null);
|
|
828
|
+
} else if (data.result && typeof data.result === "object") {
|
|
829
|
+
const result = data.result;
|
|
830
|
+
resolve(result.credentialId ?? null);
|
|
831
|
+
} else {
|
|
832
|
+
resolve(null);
|
|
833
|
+
}
|
|
834
|
+
}
|
|
835
|
+
if (channel) {
|
|
836
|
+
channel.onmessage = (event) => handleResult(event.data);
|
|
837
|
+
}
|
|
838
|
+
const postMessageHandler = (event) => {
|
|
839
|
+
if (event.source !== popup) return;
|
|
840
|
+
handleResult(event.data);
|
|
841
|
+
};
|
|
842
|
+
window.addEventListener("message", postMessageHandler);
|
|
843
|
+
function cleanup() {
|
|
844
|
+
clearTimeout(timer);
|
|
845
|
+
clearInterval(closedPoll);
|
|
846
|
+
window.removeEventListener("message", postMessageHandler);
|
|
847
|
+
channel?.close();
|
|
848
|
+
}
|
|
849
|
+
});
|
|
850
|
+
}
|
|
851
|
+
async function checkServerForNewPasskey(authToken, apiBaseUrl, existingCredentialIds) {
|
|
852
|
+
if (!authToken || !apiBaseUrl) return null;
|
|
853
|
+
const res = await fetch(`${apiBaseUrl}/v1/users/config`, {
|
|
854
|
+
headers: { Authorization: `Bearer ${authToken}` }
|
|
855
|
+
});
|
|
856
|
+
if (!res.ok) return null;
|
|
857
|
+
const body = await res.json();
|
|
858
|
+
const passkeys = body.config.passkeys ?? [];
|
|
859
|
+
const existingSet = new Set(existingCredentialIds);
|
|
860
|
+
const newPasskey = passkeys.find((p) => !existingSet.has(p.credentialId));
|
|
861
|
+
return newPasskey ?? null;
|
|
862
|
+
}
|
|
779
863
|
|
|
780
864
|
// src/hooks.ts
|
|
781
865
|
var WALLET_CLIENT_MAX_ATTEMPTS = 15;
|
|
@@ -970,7 +1054,9 @@ function buildPasskeyPopupOptions(params) {
|
|
|
970
1054
|
residentKey: "preferred",
|
|
971
1055
|
userVerification: "required"
|
|
972
1056
|
},
|
|
973
|
-
timeout: 6e4
|
|
1057
|
+
timeout: 6e4,
|
|
1058
|
+
authToken: params.authToken,
|
|
1059
|
+
apiBaseUrl: params.apiBaseUrl
|
|
974
1060
|
};
|
|
975
1061
|
}
|
|
976
1062
|
async function deviceHasPasskey(credentialId) {
|
|
@@ -2747,6 +2833,72 @@ var errorBannerStyle2 = (tokens) => ({
|
|
|
2747
2833
|
width: "100%",
|
|
2748
2834
|
textAlign: "left"
|
|
2749
2835
|
});
|
|
2836
|
+
function VerifyPasskeyScreen({
|
|
2837
|
+
onVerify,
|
|
2838
|
+
onBack,
|
|
2839
|
+
verifying,
|
|
2840
|
+
error
|
|
2841
|
+
}) {
|
|
2842
|
+
const { tokens } = useSwypeConfig();
|
|
2843
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2844
|
+
ScreenLayout,
|
|
2845
|
+
{
|
|
2846
|
+
footer: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2847
|
+
/* @__PURE__ */ jsxRuntime.jsx(PrimaryButton, { onClick: onVerify, disabled: verifying, loading: verifying, children: "Verify passkey" }),
|
|
2848
|
+
/* @__PURE__ */ jsxRuntime.jsx(PoweredByFooter, {})
|
|
2849
|
+
] }),
|
|
2850
|
+
children: [
|
|
2851
|
+
/* @__PURE__ */ jsxRuntime.jsx(ScreenHeader, { onBack }),
|
|
2852
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: contentStyle4, children: [
|
|
2853
|
+
/* @__PURE__ */ jsxRuntime.jsx(IconCircle, { variant: "accent", size: 64, children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "36", height: "36", viewBox: "0 0 24 24", fill: "none", children: [
|
|
2854
|
+
/* @__PURE__ */ jsxRuntime.jsx("rect", { x: "4", y: "4", width: "16", height: "16", rx: "3", stroke: tokens.accent, strokeWidth: "1.5", strokeDasharray: "3 2" }),
|
|
2855
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "9", cy: "10", r: "1", fill: tokens.accent }),
|
|
2856
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "15", cy: "10", r: "1", fill: tokens.accent }),
|
|
2857
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M9 14c0 1.5 1.34 2.5 3 2.5s3-1 3-2.5", stroke: tokens.accent, strokeWidth: "1.2", strokeLinecap: "round" })
|
|
2858
|
+
] }) }),
|
|
2859
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { style: headingStyle4(tokens.text), children: "Verify your passkey" }),
|
|
2860
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { style: subtitleStyle4(tokens.textSecondary), children: "Your browser requires a separate window to verify your passkey. Tap the button below to continue." }),
|
|
2861
|
+
error && /* @__PURE__ */ jsxRuntime.jsx("div", { style: errorBannerStyle3(tokens), children: error }),
|
|
2862
|
+
/* @__PURE__ */ jsxRuntime.jsx(InfoBanner, { children: "Your passkey is stored securely on your device. Swype never sees your biometric data." })
|
|
2863
|
+
] })
|
|
2864
|
+
]
|
|
2865
|
+
}
|
|
2866
|
+
);
|
|
2867
|
+
}
|
|
2868
|
+
var contentStyle4 = {
|
|
2869
|
+
textAlign: "center",
|
|
2870
|
+
flex: 1,
|
|
2871
|
+
display: "flex",
|
|
2872
|
+
flexDirection: "column",
|
|
2873
|
+
alignItems: "center",
|
|
2874
|
+
paddingTop: 32
|
|
2875
|
+
};
|
|
2876
|
+
var headingStyle4 = (color) => ({
|
|
2877
|
+
fontSize: "1.45rem",
|
|
2878
|
+
fontWeight: 700,
|
|
2879
|
+
letterSpacing: "-0.02em",
|
|
2880
|
+
color,
|
|
2881
|
+
margin: "24px 0 8px"
|
|
2882
|
+
});
|
|
2883
|
+
var subtitleStyle4 = (color) => ({
|
|
2884
|
+
fontSize: "0.9rem",
|
|
2885
|
+
color,
|
|
2886
|
+
margin: "0 0 28px",
|
|
2887
|
+
lineHeight: 1.5,
|
|
2888
|
+
maxWidth: 280
|
|
2889
|
+
});
|
|
2890
|
+
var errorBannerStyle3 = (tokens) => ({
|
|
2891
|
+
background: tokens.errorBg,
|
|
2892
|
+
border: `1px solid ${tokens.error}66`,
|
|
2893
|
+
borderRadius: 16,
|
|
2894
|
+
padding: "11px 14px",
|
|
2895
|
+
color: tokens.error,
|
|
2896
|
+
fontSize: "0.84rem",
|
|
2897
|
+
marginBottom: 14,
|
|
2898
|
+
lineHeight: 1.5,
|
|
2899
|
+
width: "100%",
|
|
2900
|
+
textAlign: "left"
|
|
2901
|
+
});
|
|
2750
2902
|
var WALLET_EMOJIS = {
|
|
2751
2903
|
rabby: "\u{1F430}",
|
|
2752
2904
|
ora: "\u2666\uFE0F",
|
|
@@ -2789,8 +2941,8 @@ function WalletPickerScreen({
|
|
|
2789
2941
|
children: [
|
|
2790
2942
|
/* @__PURE__ */ jsxRuntime.jsx(ScreenHeader, { title: "Set up Swype", onBack }),
|
|
2791
2943
|
hasPending && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2792
|
-
/* @__PURE__ */ jsxRuntime.jsx("h2", { style:
|
|
2793
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { style:
|
|
2944
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { style: headingStyle5(tokens.text), children: "Continue where you left off" }),
|
|
2945
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { style: subtitleStyle5(tokens.textSecondary), children: "You have a wallet that still needs setup" }),
|
|
2794
2946
|
/* @__PURE__ */ jsxRuntime.jsx("div", { style: pendingListStyle, children: pendingConnections.map((acct) => {
|
|
2795
2947
|
const wallet = acct.wallets[0];
|
|
2796
2948
|
const address = wallet ? truncateAddress(wallet.name) : void 0;
|
|
@@ -2830,8 +2982,8 @@ function WalletPickerScreen({
|
|
|
2830
2982
|
/* @__PURE__ */ jsxRuntime.jsx("div", { style: dividerStyle2(tokens.border), children: /* @__PURE__ */ jsxRuntime.jsx("span", { style: dividerTextStyle(tokens.textMuted), children: "Or connect a new wallet" }) })
|
|
2831
2983
|
] }),
|
|
2832
2984
|
!hasPending && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2833
|
-
/* @__PURE__ */ jsxRuntime.jsx("h2", { style:
|
|
2834
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { style:
|
|
2985
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { style: headingStyle5(tokens.text), children: "Where are your stablecoins?" }),
|
|
2986
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { style: subtitleStyle5(tokens.textSecondary), children: "Select the wallet you want to deposit from" })
|
|
2835
2987
|
] }),
|
|
2836
2988
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: gridStyle, children: [
|
|
2837
2989
|
displayProviders.map((p) => {
|
|
@@ -2884,14 +3036,14 @@ function WalletPickerScreen({
|
|
|
2884
3036
|
}
|
|
2885
3037
|
);
|
|
2886
3038
|
}
|
|
2887
|
-
var
|
|
3039
|
+
var headingStyle5 = (color) => ({
|
|
2888
3040
|
fontSize: "1.35rem",
|
|
2889
3041
|
fontWeight: 700,
|
|
2890
3042
|
letterSpacing: "-0.02em",
|
|
2891
3043
|
color,
|
|
2892
3044
|
margin: "8px 0 4px"
|
|
2893
3045
|
});
|
|
2894
|
-
var
|
|
3046
|
+
var subtitleStyle5 = (color) => ({
|
|
2895
3047
|
fontSize: "0.88rem",
|
|
2896
3048
|
color,
|
|
2897
3049
|
margin: "0 0 24px"
|
|
@@ -3067,9 +3219,9 @@ function SetupScreen({
|
|
|
3067
3219
|
] }),
|
|
3068
3220
|
children: [
|
|
3069
3221
|
/* @__PURE__ */ jsxRuntime.jsx(ScreenHeader, { title: "Swype Setup", onBack, right: /* @__PURE__ */ jsxRuntime.jsx(SettingsMenu, { onLogout }) }),
|
|
3070
|
-
/* @__PURE__ */ jsxRuntime.jsx("h2", { style:
|
|
3071
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { style:
|
|
3072
|
-
error && /* @__PURE__ */ jsxRuntime.jsx("div", { style:
|
|
3222
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { style: headingStyle6(tokens.text), children: "Set up One-Tap deposits" }),
|
|
3223
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { style: subtitleStyle6(tokens.textSecondary), children: "Set your limit for instant deposits. Like a contactless card \u2014 you choose the max." }),
|
|
3224
|
+
error && /* @__PURE__ */ jsxRuntime.jsx("div", { style: errorBannerStyle4(tokens), children: error }),
|
|
3073
3225
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: balanceRowStyle, children: [
|
|
3074
3226
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: balanceLeftStyle, children: [
|
|
3075
3227
|
/* @__PURE__ */ jsxRuntime.jsx("div", { style: coinIconStyle(tokens.accent), children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", children: [
|
|
@@ -3147,20 +3299,20 @@ function SetupScreen({
|
|
|
3147
3299
|
}
|
|
3148
3300
|
);
|
|
3149
3301
|
}
|
|
3150
|
-
var
|
|
3302
|
+
var headingStyle6 = (color) => ({
|
|
3151
3303
|
fontSize: "1.3rem",
|
|
3152
3304
|
fontWeight: 700,
|
|
3153
3305
|
letterSpacing: "-0.02em",
|
|
3154
3306
|
color,
|
|
3155
3307
|
margin: "8px 0 4px"
|
|
3156
3308
|
});
|
|
3157
|
-
var
|
|
3309
|
+
var subtitleStyle6 = (color) => ({
|
|
3158
3310
|
fontSize: "0.86rem",
|
|
3159
3311
|
color,
|
|
3160
3312
|
margin: "0 0 24px",
|
|
3161
3313
|
lineHeight: 1.5
|
|
3162
3314
|
});
|
|
3163
|
-
var
|
|
3315
|
+
var errorBannerStyle4 = (tokens) => ({
|
|
3164
3316
|
background: tokens.errorBg,
|
|
3165
3317
|
border: `1px solid ${tokens.error}66`,
|
|
3166
3318
|
borderRadius: 16,
|
|
@@ -3428,7 +3580,7 @@ function DepositScreen({
|
|
|
3428
3580
|
"%)"
|
|
3429
3581
|
] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { style: detailRowStyle(tokens.textMuted), children: "Fees calculated at time of transfer" })
|
|
3430
3582
|
] }),
|
|
3431
|
-
error && /* @__PURE__ */ jsxRuntime.jsx("div", { style:
|
|
3583
|
+
error && /* @__PURE__ */ jsxRuntime.jsx("div", { style: errorBannerStyle5(tokens), children: error })
|
|
3432
3584
|
]
|
|
3433
3585
|
}
|
|
3434
3586
|
);
|
|
@@ -3496,7 +3648,7 @@ var detailRowStyle = (color) => ({
|
|
|
3496
3648
|
color,
|
|
3497
3649
|
marginBottom: 4
|
|
3498
3650
|
});
|
|
3499
|
-
var
|
|
3651
|
+
var errorBannerStyle5 = (tokens) => ({
|
|
3500
3652
|
background: tokens.errorBg,
|
|
3501
3653
|
border: `1px solid ${tokens.error}66`,
|
|
3502
3654
|
borderRadius: 16,
|
|
@@ -3595,22 +3747,22 @@ function SuccessScreen({
|
|
|
3595
3747
|
right: /* @__PURE__ */ jsxRuntime.jsx(SettingsMenu, { onLogout })
|
|
3596
3748
|
}
|
|
3597
3749
|
),
|
|
3598
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
3750
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: contentStyle5, children: [
|
|
3599
3751
|
succeeded ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
3600
3752
|
/* @__PURE__ */ jsxRuntime.jsx(IconCircle, { variant: "success", size: 64, children: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "32", height: "32", viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41L9 16.17z", fill: tokens.success }) }) }),
|
|
3601
|
-
/* @__PURE__ */ jsxRuntime.jsxs("h2", { style:
|
|
3753
|
+
/* @__PURE__ */ jsxRuntime.jsxs("h2", { style: headingStyle7(tokens.text), children: [
|
|
3602
3754
|
"$",
|
|
3603
3755
|
amount.toFixed(2),
|
|
3604
3756
|
" deposited"
|
|
3605
3757
|
] }),
|
|
3606
|
-
merchantName && /* @__PURE__ */ jsxRuntime.jsxs("p", { style:
|
|
3758
|
+
merchantName && /* @__PURE__ */ jsxRuntime.jsxs("p", { style: subtitleStyle7(tokens.textSecondary), children: [
|
|
3607
3759
|
"to ",
|
|
3608
3760
|
merchantName
|
|
3609
3761
|
] })
|
|
3610
3762
|
] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
3611
3763
|
/* @__PURE__ */ jsxRuntime.jsx(IconCircle, { variant: "error", size: 64, children: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "32", height: "32", viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z", fill: tokens.error }) }) }),
|
|
3612
|
-
/* @__PURE__ */ jsxRuntime.jsx("h2", { style:
|
|
3613
|
-
error && /* @__PURE__ */ jsxRuntime.jsx("p", { style:
|
|
3764
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { style: headingStyle7(tokens.text), children: "Transfer failed" }),
|
|
3765
|
+
error && /* @__PURE__ */ jsxRuntime.jsx("p", { style: subtitleStyle7(tokens.error), children: error })
|
|
3614
3766
|
] }),
|
|
3615
3767
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: summaryCardStyle(tokens), children: [
|
|
3616
3768
|
sourceName && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: summaryRowStyle, children: [
|
|
@@ -3642,21 +3794,21 @@ function SuccessScreen({
|
|
|
3642
3794
|
}
|
|
3643
3795
|
);
|
|
3644
3796
|
}
|
|
3645
|
-
var
|
|
3797
|
+
var contentStyle5 = {
|
|
3646
3798
|
flex: 1,
|
|
3647
3799
|
display: "flex",
|
|
3648
3800
|
flexDirection: "column",
|
|
3649
3801
|
alignItems: "center",
|
|
3650
3802
|
paddingTop: 16
|
|
3651
3803
|
};
|
|
3652
|
-
var
|
|
3804
|
+
var headingStyle7 = (color) => ({
|
|
3653
3805
|
fontSize: "1.5rem",
|
|
3654
3806
|
fontWeight: 700,
|
|
3655
3807
|
letterSpacing: "-0.02em",
|
|
3656
3808
|
color,
|
|
3657
3809
|
margin: "20px 0 4px"
|
|
3658
3810
|
});
|
|
3659
|
-
var
|
|
3811
|
+
var subtitleStyle7 = (color) => ({
|
|
3660
3812
|
fontSize: "0.9rem",
|
|
3661
3813
|
color,
|
|
3662
3814
|
margin: "0 0 20px"
|
|
@@ -3762,7 +3914,7 @@ function SelectSourceScreen({
|
|
|
3762
3914
|
right: /* @__PURE__ */ jsxRuntime.jsx(SettingsMenu, { onLogout })
|
|
3763
3915
|
}
|
|
3764
3916
|
),
|
|
3765
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { style:
|
|
3917
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { style: subtitleStyle8(tokens.textMuted), children: "Choose which chain and token to pay from." }),
|
|
3766
3918
|
/* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle2(tokens.textSecondary), children: "Chain" }),
|
|
3767
3919
|
/* @__PURE__ */ jsxRuntime.jsx("div", { style: optionListStyle, children: choices.map((chain) => {
|
|
3768
3920
|
const isSelected = chain.chainName === selectedChainName;
|
|
@@ -3819,7 +3971,7 @@ function SelectSourceScreen({
|
|
|
3819
3971
|
}
|
|
3820
3972
|
);
|
|
3821
3973
|
}
|
|
3822
|
-
var
|
|
3974
|
+
var subtitleStyle8 = (color) => ({
|
|
3823
3975
|
fontSize: "0.85rem",
|
|
3824
3976
|
color,
|
|
3825
3977
|
margin: "0 0 20px",
|
|
@@ -3934,8 +4086,8 @@ function AdvancedSourceScreen({
|
|
|
3934
4086
|
right: /* @__PURE__ */ jsxRuntime.jsx("span", { style: advancedBadgeStyle(tokens.accent), children: "Advanced" })
|
|
3935
4087
|
}
|
|
3936
4088
|
),
|
|
3937
|
-
/* @__PURE__ */ jsxRuntime.jsx("h2", { style:
|
|
3938
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { style:
|
|
4089
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { style: headingStyle8(tokens.text), children: "Set up One-Tap deposits" }),
|
|
4090
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { style: subtitleStyle9(tokens.textSecondary), children: "Select a token source for your One-Tap deposits." }),
|
|
3939
4091
|
/* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle3(tokens.textSecondary), children: "Select tokens to approve" }),
|
|
3940
4092
|
/* @__PURE__ */ jsxRuntime.jsx("div", { style: chainListStyle, children: choices.map((chain) => {
|
|
3941
4093
|
const isExpanded = expandedChain === chain.chainName;
|
|
@@ -3998,14 +4150,14 @@ var advancedBadgeStyle = (color) => ({
|
|
|
3998
4150
|
padding: "3px 10px",
|
|
3999
4151
|
letterSpacing: "0.02em"
|
|
4000
4152
|
});
|
|
4001
|
-
var
|
|
4153
|
+
var headingStyle8 = (color) => ({
|
|
4002
4154
|
fontSize: "1.3rem",
|
|
4003
4155
|
fontWeight: 700,
|
|
4004
4156
|
letterSpacing: "-0.02em",
|
|
4005
4157
|
color,
|
|
4006
4158
|
margin: "8px 0 4px"
|
|
4007
4159
|
});
|
|
4008
|
-
var
|
|
4160
|
+
var subtitleStyle9 = (color) => ({
|
|
4009
4161
|
fontSize: "0.86rem",
|
|
4010
4162
|
color,
|
|
4011
4163
|
margin: "0 0 20px",
|
|
@@ -4133,16 +4285,16 @@ function TransferStatusScreen({
|
|
|
4133
4285
|
const steps = buildSteps(phase);
|
|
4134
4286
|
return /* @__PURE__ */ jsxRuntime.jsxs(ScreenLayout, { children: [
|
|
4135
4287
|
/* @__PURE__ */ jsxRuntime.jsx(ScreenHeader, { right: /* @__PURE__ */ jsxRuntime.jsx(SettingsMenu, { onLogout }) }),
|
|
4136
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
4288
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: contentStyle6, children: [
|
|
4137
4289
|
/* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: 48 }),
|
|
4138
|
-
/* @__PURE__ */ jsxRuntime.jsx("h2", { style:
|
|
4139
|
-
error && /* @__PURE__ */ jsxRuntime.jsx("div", { style:
|
|
4290
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { style: headingStyle9(tokens.text), children: "Processing Transfer..." }),
|
|
4291
|
+
error && /* @__PURE__ */ jsxRuntime.jsx("div", { style: errorBannerStyle6(tokens), children: error }),
|
|
4140
4292
|
/* @__PURE__ */ jsxRuntime.jsx("div", { style: stepsWrapStyle, children: /* @__PURE__ */ jsxRuntime.jsx(StepList, { steps }) }),
|
|
4141
4293
|
/* @__PURE__ */ jsxRuntime.jsx("p", { style: waitHintStyle(tokens.textMuted), children: "Usually takes a few seconds" })
|
|
4142
4294
|
] })
|
|
4143
4295
|
] });
|
|
4144
4296
|
}
|
|
4145
|
-
var
|
|
4297
|
+
var contentStyle6 = {
|
|
4146
4298
|
flex: 1,
|
|
4147
4299
|
display: "flex",
|
|
4148
4300
|
flexDirection: "column",
|
|
@@ -4151,14 +4303,14 @@ var contentStyle5 = {
|
|
|
4151
4303
|
textAlign: "center",
|
|
4152
4304
|
padding: "0 24px"
|
|
4153
4305
|
};
|
|
4154
|
-
var
|
|
4306
|
+
var headingStyle9 = (color) => ({
|
|
4155
4307
|
fontSize: "1.45rem",
|
|
4156
4308
|
fontWeight: 700,
|
|
4157
4309
|
letterSpacing: "-0.02em",
|
|
4158
4310
|
color,
|
|
4159
4311
|
margin: "20px 0 16px"
|
|
4160
4312
|
});
|
|
4161
|
-
var
|
|
4313
|
+
var errorBannerStyle6 = (tokens) => ({
|
|
4162
4314
|
background: tokens.errorBg,
|
|
4163
4315
|
border: `1px solid ${tokens.error}66`,
|
|
4164
4316
|
borderRadius: 16,
|
|
@@ -4218,10 +4370,10 @@ function OpenWalletScreen({
|
|
|
4218
4370
|
] }),
|
|
4219
4371
|
children: [
|
|
4220
4372
|
/* @__PURE__ */ jsxRuntime.jsx(ScreenHeader, { right: /* @__PURE__ */ jsxRuntime.jsx(SettingsMenu, { onLogout }) }),
|
|
4221
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
4373
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: contentStyle7, children: [
|
|
4222
4374
|
logoSrc ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: logoSrc, alt: displayName, style: logoStyle }) : /* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: 48 }),
|
|
4223
|
-
/* @__PURE__ */ jsxRuntime.jsx("h2", { style:
|
|
4224
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { style:
|
|
4375
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { style: headingStyle10(tokens.text), children: loading ? "Connecting..." : `Open ${displayName}` }),
|
|
4376
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { style: subtitleStyle10(tokens.textSecondary), children: loading ? "Creating transfer and preparing your wallet link..." : `Continue in ${displayName} to authorize this connection.` }),
|
|
4225
4377
|
!loading && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: waitingBadgeStyle(tokens), children: [
|
|
4226
4378
|
/* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: 14 }),
|
|
4227
4379
|
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Waiting for authorization..." })
|
|
@@ -4231,7 +4383,7 @@ function OpenWalletScreen({
|
|
|
4231
4383
|
}
|
|
4232
4384
|
);
|
|
4233
4385
|
}
|
|
4234
|
-
var
|
|
4386
|
+
var contentStyle7 = {
|
|
4235
4387
|
flex: 1,
|
|
4236
4388
|
display: "flex",
|
|
4237
4389
|
flexDirection: "column",
|
|
@@ -4251,14 +4403,14 @@ var logoStyle = {
|
|
|
4251
4403
|
borderRadius: 14,
|
|
4252
4404
|
objectFit: "contain"
|
|
4253
4405
|
};
|
|
4254
|
-
var
|
|
4406
|
+
var headingStyle10 = (color) => ({
|
|
4255
4407
|
fontSize: "1.45rem",
|
|
4256
4408
|
fontWeight: 700,
|
|
4257
4409
|
letterSpacing: "-0.02em",
|
|
4258
4410
|
color,
|
|
4259
4411
|
margin: "20px 0 8px"
|
|
4260
4412
|
});
|
|
4261
|
-
var
|
|
4413
|
+
var subtitleStyle10 = (color) => ({
|
|
4262
4414
|
fontSize: "0.9rem",
|
|
4263
4415
|
color,
|
|
4264
4416
|
margin: "0 0 24px",
|
|
@@ -4302,10 +4454,10 @@ function ConfirmSignScreen({
|
|
|
4302
4454
|
] }),
|
|
4303
4455
|
children: [
|
|
4304
4456
|
/* @__PURE__ */ jsxRuntime.jsx(ScreenHeader, { right: /* @__PURE__ */ jsxRuntime.jsx(SettingsMenu, { onLogout }) }),
|
|
4305
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
4457
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: contentStyle8, children: [
|
|
4306
4458
|
logoSrc ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: logoSrc, alt: displayName, style: logoStyle2 }) : /* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: 48 }),
|
|
4307
|
-
/* @__PURE__ */ jsxRuntime.jsx("h2", { style:
|
|
4308
|
-
/* @__PURE__ */ jsxRuntime.jsxs("p", { style:
|
|
4459
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { style: headingStyle11(tokens.text), children: "Wallet authorized" }),
|
|
4460
|
+
/* @__PURE__ */ jsxRuntime.jsxs("p", { style: subtitleStyle11(tokens.textSecondary), children: [
|
|
4309
4461
|
displayName,
|
|
4310
4462
|
" approved the connection. Tap below to confirm your payment."
|
|
4311
4463
|
] }),
|
|
@@ -4318,7 +4470,7 @@ function ConfirmSignScreen({
|
|
|
4318
4470
|
}
|
|
4319
4471
|
);
|
|
4320
4472
|
}
|
|
4321
|
-
var
|
|
4473
|
+
var contentStyle8 = {
|
|
4322
4474
|
flex: 1,
|
|
4323
4475
|
display: "flex",
|
|
4324
4476
|
flexDirection: "column",
|
|
@@ -4333,14 +4485,14 @@ var logoStyle2 = {
|
|
|
4333
4485
|
borderRadius: 14,
|
|
4334
4486
|
objectFit: "contain"
|
|
4335
4487
|
};
|
|
4336
|
-
var
|
|
4488
|
+
var headingStyle11 = (color) => ({
|
|
4337
4489
|
fontSize: "1.45rem",
|
|
4338
4490
|
fontWeight: 700,
|
|
4339
4491
|
letterSpacing: "-0.02em",
|
|
4340
4492
|
color,
|
|
4341
4493
|
margin: "20px 0 8px"
|
|
4342
4494
|
});
|
|
4343
|
-
var
|
|
4495
|
+
var subtitleStyle11 = (color) => ({
|
|
4344
4496
|
fontSize: "0.9rem",
|
|
4345
4497
|
color,
|
|
4346
4498
|
margin: "0 0 24px",
|
|
@@ -4399,7 +4551,7 @@ var PaymentErrorBoundary = class extends react.Component {
|
|
|
4399
4551
|
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M12 8v5", stroke: "#ef4444", strokeWidth: "1.5", strokeLinecap: "round" }),
|
|
4400
4552
|
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "12", cy: "16", r: "0.75", fill: "#ef4444" })
|
|
4401
4553
|
] }) }),
|
|
4402
|
-
/* @__PURE__ */ jsxRuntime.jsx("h2", { style:
|
|
4554
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { style: headingStyle12, children: "Something went wrong" }),
|
|
4403
4555
|
/* @__PURE__ */ jsxRuntime.jsx("p", { style: messageStyle, children: "An unexpected error occurred. Please try again." }),
|
|
4404
4556
|
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", onClick: this.handleReset, style: buttonStyle3, children: "Try again" })
|
|
4405
4557
|
] });
|
|
@@ -4419,7 +4571,7 @@ var containerStyle8 = {
|
|
|
4419
4571
|
var iconStyle4 = {
|
|
4420
4572
|
marginBottom: 20
|
|
4421
4573
|
};
|
|
4422
|
-
var
|
|
4574
|
+
var headingStyle12 = {
|
|
4423
4575
|
fontSize: "1.25rem",
|
|
4424
4576
|
fontWeight: 700,
|
|
4425
4577
|
color: "#1a1a1a",
|
|
@@ -4582,6 +4734,7 @@ function SwypePaymentInner({
|
|
|
4582
4734
|
const [transfer, setTransfer] = react.useState(null);
|
|
4583
4735
|
const [creatingTransfer, setCreatingTransfer] = react.useState(false);
|
|
4584
4736
|
const [registeringPasskey, setRegisteringPasskey] = react.useState(false);
|
|
4737
|
+
const [verifyingPasskeyPopup, setVerifyingPasskeyPopup] = react.useState(false);
|
|
4585
4738
|
const [passkeyPopupNeeded, setPasskeyPopupNeeded] = react.useState(
|
|
4586
4739
|
() => isSafari() && isInCrossOriginIframe()
|
|
4587
4740
|
);
|
|
@@ -4589,6 +4742,7 @@ function SwypePaymentInner({
|
|
|
4589
4742
|
if (typeof window === "undefined") return null;
|
|
4590
4743
|
return window.localStorage.getItem(ACTIVE_CREDENTIAL_STORAGE_KEY);
|
|
4591
4744
|
});
|
|
4745
|
+
const [knownCredentialIds, setKnownCredentialIds] = react.useState([]);
|
|
4592
4746
|
const [authInput, setAuthInput] = react.useState("");
|
|
4593
4747
|
const [verificationTarget, setVerificationTarget] = react.useState(null);
|
|
4594
4748
|
const [otpCode, setOtpCode] = react.useState("");
|
|
@@ -4878,6 +5032,7 @@ function SwypePaymentInner({
|
|
|
4878
5032
|
setOneTapLimit(config.defaultAllowance);
|
|
4879
5033
|
}
|
|
4880
5034
|
const allPasskeys = config.passkeys ?? (config.passkey ? [config.passkey] : []);
|
|
5035
|
+
setKnownCredentialIds(allPasskeys.map((p) => p.credentialId));
|
|
4881
5036
|
if (allPasskeys.length === 0) {
|
|
4882
5037
|
setStep("create-passkey");
|
|
4883
5038
|
return;
|
|
@@ -4888,6 +5043,10 @@ function SwypePaymentInner({
|
|
|
4888
5043
|
}
|
|
4889
5044
|
if (cancelled) return;
|
|
4890
5045
|
const credentialIds = allPasskeys.map((p) => p.credentialId);
|
|
5046
|
+
if (isSafari() && isInCrossOriginIframe()) {
|
|
5047
|
+
setStep("verify-passkey");
|
|
5048
|
+
return;
|
|
5049
|
+
}
|
|
4891
5050
|
const matched = await findDevicePasskey(credentialIds);
|
|
4892
5051
|
if (cancelled) return;
|
|
4893
5052
|
if (matched) {
|
|
@@ -5394,12 +5553,18 @@ function SwypePaymentInner({
|
|
|
5394
5553
|
setRegisteringPasskey(true);
|
|
5395
5554
|
setError(null);
|
|
5396
5555
|
try {
|
|
5556
|
+
const token = await getAccessToken();
|
|
5397
5557
|
const passkeyDisplayName = user?.email?.address ?? user?.google?.name ?? user?.id ?? "Swype User";
|
|
5398
5558
|
const popupOptions = buildPasskeyPopupOptions({
|
|
5399
5559
|
userId: user?.id ?? "unknown",
|
|
5400
|
-
displayName: passkeyDisplayName
|
|
5560
|
+
displayName: passkeyDisplayName,
|
|
5561
|
+
authToken: token ?? void 0,
|
|
5562
|
+
apiBaseUrl
|
|
5401
5563
|
});
|
|
5402
|
-
const { credentialId, publicKey } = await createPasskeyViaPopup(
|
|
5564
|
+
const { credentialId, publicKey } = await createPasskeyViaPopup(
|
|
5565
|
+
popupOptions,
|
|
5566
|
+
knownCredentialIds
|
|
5567
|
+
);
|
|
5403
5568
|
await completePasskeyRegistration(credentialId, publicKey);
|
|
5404
5569
|
} catch (err) {
|
|
5405
5570
|
captureException(err);
|
|
@@ -5407,7 +5572,28 @@ function SwypePaymentInner({
|
|
|
5407
5572
|
} finally {
|
|
5408
5573
|
setRegisteringPasskey(false);
|
|
5409
5574
|
}
|
|
5410
|
-
}, [user, completePasskeyRegistration]);
|
|
5575
|
+
}, [user, completePasskeyRegistration, getAccessToken, apiBaseUrl, knownCredentialIds]);
|
|
5576
|
+
const handleVerifyPasskeyViaPopup = react.useCallback(async () => {
|
|
5577
|
+
setVerifyingPasskeyPopup(true);
|
|
5578
|
+
setError(null);
|
|
5579
|
+
try {
|
|
5580
|
+
const matched = await findDevicePasskeyViaPopup({
|
|
5581
|
+
credentialIds: knownCredentialIds,
|
|
5582
|
+
rpId: resolvePasskeyRpId()
|
|
5583
|
+
});
|
|
5584
|
+
if (matched) {
|
|
5585
|
+
setActiveCredentialId(matched);
|
|
5586
|
+
window.localStorage.setItem(ACTIVE_CREDENTIAL_STORAGE_KEY, matched);
|
|
5587
|
+
setStep("login");
|
|
5588
|
+
} else {
|
|
5589
|
+
setStep("create-passkey");
|
|
5590
|
+
}
|
|
5591
|
+
} catch {
|
|
5592
|
+
setStep("create-passkey");
|
|
5593
|
+
} finally {
|
|
5594
|
+
setVerifyingPasskeyPopup(false);
|
|
5595
|
+
}
|
|
5596
|
+
}, [knownCredentialIds]);
|
|
5411
5597
|
const handleSelectProvider = react.useCallback((providerId) => {
|
|
5412
5598
|
setSelectedProviderId(providerId);
|
|
5413
5599
|
setSelectedAccountId(null);
|
|
@@ -5539,6 +5725,17 @@ function SwypePaymentInner({
|
|
|
5539
5725
|
if ((step === "login" || step === "otp-verify") && authenticated) {
|
|
5540
5726
|
return /* @__PURE__ */ jsxRuntime.jsx(ScreenLayout, { children: /* @__PURE__ */ jsxRuntime.jsx("div", { style: { textAlign: "center", padding: "48px 0", flex: 1, display: "flex", alignItems: "center", justifyContent: "center" }, children: /* @__PURE__ */ jsxRuntime.jsx(Spinner, { label: "Verifying your passkey..." }) }) });
|
|
5541
5727
|
}
|
|
5728
|
+
if (step === "verify-passkey") {
|
|
5729
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
5730
|
+
VerifyPasskeyScreen,
|
|
5731
|
+
{
|
|
5732
|
+
onVerify: handleVerifyPasskeyViaPopup,
|
|
5733
|
+
onBack: handleLogout,
|
|
5734
|
+
verifying: verifyingPasskeyPopup,
|
|
5735
|
+
error
|
|
5736
|
+
}
|
|
5737
|
+
);
|
|
5738
|
+
}
|
|
5542
5739
|
if (step === "create-passkey") {
|
|
5543
5740
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
5544
5741
|
CreatePasskeyScreen,
|
|
@@ -5723,8 +5920,10 @@ exports.createPasskeyViaPopup = createPasskeyViaPopup;
|
|
|
5723
5920
|
exports.darkTheme = darkTheme;
|
|
5724
5921
|
exports.deviceHasPasskey = deviceHasPasskey;
|
|
5725
5922
|
exports.findDevicePasskey = findDevicePasskey;
|
|
5923
|
+
exports.findDevicePasskeyViaPopup = findDevicePasskeyViaPopup;
|
|
5726
5924
|
exports.getTheme = getTheme;
|
|
5727
5925
|
exports.lightTheme = lightTheme;
|
|
5926
|
+
exports.resolvePasskeyRpId = resolvePasskeyRpId;
|
|
5728
5927
|
exports.swypeApi = api_exports;
|
|
5729
5928
|
exports.useAuthorizationExecutor = useAuthorizationExecutor;
|
|
5730
5929
|
exports.useSwypeConfig = useSwypeConfig;
|