@swype-org/react-sdk 0.1.49 → 0.1.52
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 +163 -138
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +63 -1
- package/dist/index.d.ts +63 -1
- package/dist/index.js +161 -139
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -658,6 +658,12 @@ function normalizeSignature(sig) {
|
|
|
658
658
|
}
|
|
659
659
|
|
|
660
660
|
// src/passkey-delegation.ts
|
|
661
|
+
var PasskeyIframeBlockedError = class extends Error {
|
|
662
|
+
constructor(message = "Passkey creation is not supported in this browser context.") {
|
|
663
|
+
super(message);
|
|
664
|
+
this.name = "PasskeyIframeBlockedError";
|
|
665
|
+
}
|
|
666
|
+
};
|
|
661
667
|
function isInCrossOriginIframe() {
|
|
662
668
|
if (typeof window === "undefined") return false;
|
|
663
669
|
if (window.parent === window) return false;
|
|
@@ -668,57 +674,47 @@ function isInCrossOriginIframe() {
|
|
|
668
674
|
return true;
|
|
669
675
|
}
|
|
670
676
|
}
|
|
671
|
-
var
|
|
672
|
-
var
|
|
673
|
-
|
|
674
|
-
function delegatePasskeyCreate(options) {
|
|
677
|
+
var POPUP_RESULT_TIMEOUT_MS = 12e4;
|
|
678
|
+
var POPUP_CLOSED_POLL_MS = 500;
|
|
679
|
+
function createPasskeyViaPopup(options) {
|
|
675
680
|
return new Promise((resolve, reject) => {
|
|
676
|
-
const
|
|
681
|
+
const encoded = btoa(JSON.stringify(options));
|
|
682
|
+
const popupUrl = `${window.location.origin}/passkey-register#${encoded}`;
|
|
683
|
+
const popup = window.open(popupUrl, "swype-passkey", "width=460,height=600");
|
|
684
|
+
if (!popup) {
|
|
685
|
+
reject(new Error("Pop-up blocked. Please allow pop-ups for this site and try again."));
|
|
686
|
+
return;
|
|
687
|
+
}
|
|
677
688
|
const timer = setTimeout(() => {
|
|
678
|
-
|
|
689
|
+
cleanup();
|
|
679
690
|
reject(new Error("Passkey creation timed out. Please try again."));
|
|
680
|
-
},
|
|
691
|
+
}, POPUP_RESULT_TIMEOUT_MS);
|
|
692
|
+
const closedPoll = setInterval(() => {
|
|
693
|
+
if (popup.closed) {
|
|
694
|
+
cleanup();
|
|
695
|
+
reject(new Error("Passkey setup window was closed before completing."));
|
|
696
|
+
}
|
|
697
|
+
}, POPUP_CLOSED_POLL_MS);
|
|
681
698
|
const handler = (event) => {
|
|
699
|
+
if (event.source !== popup) return;
|
|
682
700
|
const data = event.data;
|
|
683
701
|
if (!data || typeof data !== "object") return;
|
|
684
|
-
if (data.type !== "swype:passkey-
|
|
685
|
-
|
|
686
|
-
window.removeEventListener("message", handler);
|
|
702
|
+
if (data.type !== "swype:passkey-popup-result") return;
|
|
703
|
+
cleanup();
|
|
687
704
|
if (data.error) {
|
|
688
705
|
reject(new Error(data.error));
|
|
689
706
|
} else if (data.result) {
|
|
690
707
|
resolve(data.result);
|
|
691
708
|
} else {
|
|
692
|
-
reject(new Error("Invalid passkey
|
|
709
|
+
reject(new Error("Invalid passkey popup response."));
|
|
693
710
|
}
|
|
694
711
|
};
|
|
695
|
-
|
|
696
|
-
window.parent.postMessage({ type: "swype:passkey-create-request", id, options }, "*");
|
|
697
|
-
});
|
|
698
|
-
}
|
|
699
|
-
function delegatePasskeyGet(options) {
|
|
700
|
-
return new Promise((resolve, reject) => {
|
|
701
|
-
const id = `pg-${++delegationCounter}-${Date.now()}`;
|
|
702
|
-
const timer = setTimeout(() => {
|
|
703
|
-
window.removeEventListener("message", handler);
|
|
704
|
-
reject(new Error("Passkey verification timed out. Please try again."));
|
|
705
|
-
}, DELEGATION_GET_TIMEOUT_MS);
|
|
706
|
-
const handler = (event) => {
|
|
707
|
-
const data = event.data;
|
|
708
|
-
if (!data || typeof data !== "object") return;
|
|
709
|
-
if (data.type !== "swype:passkey-get-response" || data.id !== id) return;
|
|
712
|
+
function cleanup() {
|
|
710
713
|
clearTimeout(timer);
|
|
714
|
+
clearInterval(closedPoll);
|
|
711
715
|
window.removeEventListener("message", handler);
|
|
712
|
-
|
|
713
|
-
reject(new Error(data.error));
|
|
714
|
-
} else if (data.result) {
|
|
715
|
-
resolve(data.result);
|
|
716
|
-
} else {
|
|
717
|
-
reject(new Error("Invalid passkey get response."));
|
|
718
|
-
}
|
|
719
|
-
};
|
|
716
|
+
}
|
|
720
717
|
window.addEventListener("message", handler);
|
|
721
|
-
window.parent.postMessage({ type: "swype:passkey-get-request", id, options }, "*");
|
|
722
718
|
});
|
|
723
719
|
}
|
|
724
720
|
|
|
@@ -843,53 +839,51 @@ async function createPasskeyCredential(params) {
|
|
|
843
839
|
const challenge = new Uint8Array(32);
|
|
844
840
|
crypto.getRandomValues(challenge);
|
|
845
841
|
const rpId = resolvePasskeyRpId();
|
|
842
|
+
const publicKeyOptions = {
|
|
843
|
+
challenge,
|
|
844
|
+
rp: { name: "Swype", id: rpId },
|
|
845
|
+
user: {
|
|
846
|
+
id: new TextEncoder().encode(params.userId),
|
|
847
|
+
name: params.displayName,
|
|
848
|
+
displayName: params.displayName
|
|
849
|
+
},
|
|
850
|
+
pubKeyCredParams: [
|
|
851
|
+
{ alg: -7, type: "public-key" },
|
|
852
|
+
{ alg: -257, type: "public-key" }
|
|
853
|
+
],
|
|
854
|
+
authenticatorSelection: {
|
|
855
|
+
authenticatorAttachment: "platform",
|
|
856
|
+
residentKey: "preferred",
|
|
857
|
+
userVerification: "required"
|
|
858
|
+
},
|
|
859
|
+
timeout: 6e4
|
|
860
|
+
};
|
|
846
861
|
if (isInCrossOriginIframe()) {
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
userVerification: "required"
|
|
862
|
-
},
|
|
863
|
-
timeout: 6e4
|
|
864
|
-
});
|
|
862
|
+
try {
|
|
863
|
+
await waitForDocumentFocus();
|
|
864
|
+
const credential2 = await navigator.credentials.create({
|
|
865
|
+
publicKey: publicKeyOptions
|
|
866
|
+
});
|
|
867
|
+
if (!credential2) {
|
|
868
|
+
throw new Error("Passkey creation was cancelled.");
|
|
869
|
+
}
|
|
870
|
+
return extractPasskeyResult(credential2);
|
|
871
|
+
} catch (err) {
|
|
872
|
+
if (err instanceof PasskeyIframeBlockedError) throw err;
|
|
873
|
+
if (err instanceof Error && err.message === "Passkey creation was cancelled.") throw err;
|
|
874
|
+
throw new PasskeyIframeBlockedError();
|
|
875
|
+
}
|
|
865
876
|
}
|
|
866
877
|
await waitForDocumentFocus();
|
|
867
878
|
const credential = await navigator.credentials.create({
|
|
868
|
-
publicKey:
|
|
869
|
-
challenge,
|
|
870
|
-
rp: { name: "Swype", id: rpId },
|
|
871
|
-
user: {
|
|
872
|
-
id: new TextEncoder().encode(params.userId),
|
|
873
|
-
name: params.displayName,
|
|
874
|
-
displayName: params.displayName
|
|
875
|
-
},
|
|
876
|
-
pubKeyCredParams: [
|
|
877
|
-
{ alg: -7, type: "public-key" },
|
|
878
|
-
// ES256 (P-256)
|
|
879
|
-
{ alg: -257, type: "public-key" }
|
|
880
|
-
// RS256
|
|
881
|
-
],
|
|
882
|
-
authenticatorSelection: {
|
|
883
|
-
authenticatorAttachment: "platform",
|
|
884
|
-
residentKey: "preferred",
|
|
885
|
-
userVerification: "required"
|
|
886
|
-
},
|
|
887
|
-
timeout: 6e4
|
|
888
|
-
}
|
|
879
|
+
publicKey: publicKeyOptions
|
|
889
880
|
});
|
|
890
881
|
if (!credential) {
|
|
891
882
|
throw new Error("Passkey creation was cancelled.");
|
|
892
883
|
}
|
|
884
|
+
return extractPasskeyResult(credential);
|
|
885
|
+
}
|
|
886
|
+
function extractPasskeyResult(credential) {
|
|
893
887
|
const response = credential.response;
|
|
894
888
|
const publicKeyBytes = response.getPublicKey?.();
|
|
895
889
|
return {
|
|
@@ -897,6 +891,29 @@ async function createPasskeyCredential(params) {
|
|
|
897
891
|
publicKey: publicKeyBytes ? toBase64(publicKeyBytes) : ""
|
|
898
892
|
};
|
|
899
893
|
}
|
|
894
|
+
function buildPasskeyPopupOptions(params) {
|
|
895
|
+
const challenge = new Uint8Array(32);
|
|
896
|
+
crypto.getRandomValues(challenge);
|
|
897
|
+
const rpId = resolvePasskeyRpId();
|
|
898
|
+
return {
|
|
899
|
+
challenge: toBase64(challenge),
|
|
900
|
+
rpId,
|
|
901
|
+
rpName: "Swype",
|
|
902
|
+
userId: toBase64(new TextEncoder().encode(params.userId)),
|
|
903
|
+
userName: params.displayName,
|
|
904
|
+
userDisplayName: params.displayName,
|
|
905
|
+
pubKeyCredParams: [
|
|
906
|
+
{ alg: -7, type: "public-key" },
|
|
907
|
+
{ alg: -257, type: "public-key" }
|
|
908
|
+
],
|
|
909
|
+
authenticatorSelection: {
|
|
910
|
+
authenticatorAttachment: "platform",
|
|
911
|
+
residentKey: "preferred",
|
|
912
|
+
userVerification: "required"
|
|
913
|
+
},
|
|
914
|
+
timeout: 6e4
|
|
915
|
+
};
|
|
916
|
+
}
|
|
900
917
|
async function deviceHasPasskey(credentialId) {
|
|
901
918
|
const found = await findDevicePasskey([credentialId]);
|
|
902
919
|
return found != null;
|
|
@@ -906,16 +923,6 @@ async function findDevicePasskey(credentialIds) {
|
|
|
906
923
|
try {
|
|
907
924
|
const challenge = new Uint8Array(32);
|
|
908
925
|
crypto.getRandomValues(challenge);
|
|
909
|
-
if (isInCrossOriginIframe()) {
|
|
910
|
-
const result = await delegatePasskeyGet({
|
|
911
|
-
challenge: toBase64(challenge),
|
|
912
|
-
rpId: resolvePasskeyRpId(),
|
|
913
|
-
allowCredentials: credentialIds.map((id) => ({ type: "public-key", id })),
|
|
914
|
-
userVerification: "discouraged",
|
|
915
|
-
timeout: 3e4
|
|
916
|
-
});
|
|
917
|
-
return result.credentialId;
|
|
918
|
-
}
|
|
919
926
|
await waitForDocumentFocus();
|
|
920
927
|
const assertion = await navigator.credentials.get({
|
|
921
928
|
publicKey: {
|
|
@@ -1414,48 +1421,31 @@ function useTransferSigning(pollIntervalMs = 2e3, options) {
|
|
|
1414
1421
|
}
|
|
1415
1422
|
const hashBytes = hexToBytes(payload.userOpHash);
|
|
1416
1423
|
let signedUserOp;
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1424
|
+
const allowCredentials = payload.passkeyCredentialId ? [{
|
|
1425
|
+
type: "public-key",
|
|
1426
|
+
id: base64ToBytes(payload.passkeyCredentialId)
|
|
1427
|
+
}] : void 0;
|
|
1428
|
+
await waitForDocumentFocus();
|
|
1429
|
+
const assertion = await navigator.credentials.get({
|
|
1430
|
+
publicKey: {
|
|
1431
|
+
challenge: hashBytes,
|
|
1420
1432
|
rpId: resolvePasskeyRpId(),
|
|
1421
|
-
allowCredentials
|
|
1433
|
+
allowCredentials,
|
|
1422
1434
|
userVerification: "required",
|
|
1423
1435
|
timeout: 6e4
|
|
1424
|
-
});
|
|
1425
|
-
signedUserOp = {
|
|
1426
|
-
...payload.userOp,
|
|
1427
|
-
credentialId: delegatedResult.credentialId,
|
|
1428
|
-
signature: delegatedResult.signature,
|
|
1429
|
-
authenticatorData: delegatedResult.authenticatorData,
|
|
1430
|
-
clientDataJSON: delegatedResult.clientDataJSON
|
|
1431
|
-
};
|
|
1432
|
-
} else {
|
|
1433
|
-
const allowCredentials = payload.passkeyCredentialId ? [{
|
|
1434
|
-
type: "public-key",
|
|
1435
|
-
id: base64ToBytes(payload.passkeyCredentialId)
|
|
1436
|
-
}] : void 0;
|
|
1437
|
-
await waitForDocumentFocus();
|
|
1438
|
-
const assertion = await navigator.credentials.get({
|
|
1439
|
-
publicKey: {
|
|
1440
|
-
challenge: hashBytes,
|
|
1441
|
-
rpId: resolvePasskeyRpId(),
|
|
1442
|
-
allowCredentials,
|
|
1443
|
-
userVerification: "required",
|
|
1444
|
-
timeout: 6e4
|
|
1445
|
-
}
|
|
1446
|
-
});
|
|
1447
|
-
if (!assertion) {
|
|
1448
|
-
throw new Error("Passkey authentication was cancelled.");
|
|
1449
1436
|
}
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
credentialId: toBase64(assertion.rawId),
|
|
1454
|
-
signature: toBase64(response.signature),
|
|
1455
|
-
authenticatorData: toBase64(response.authenticatorData),
|
|
1456
|
-
clientDataJSON: toBase64(response.clientDataJSON)
|
|
1457
|
-
};
|
|
1437
|
+
});
|
|
1438
|
+
if (!assertion) {
|
|
1439
|
+
throw new Error("Passkey authentication was cancelled.");
|
|
1458
1440
|
}
|
|
1441
|
+
const response = assertion.response;
|
|
1442
|
+
signedUserOp = {
|
|
1443
|
+
...payload.userOp,
|
|
1444
|
+
credentialId: toBase64(assertion.rawId),
|
|
1445
|
+
signature: toBase64(response.signature),
|
|
1446
|
+
authenticatorData: toBase64(response.authenticatorData),
|
|
1447
|
+
clientDataJSON: toBase64(response.clientDataJSON)
|
|
1448
|
+
};
|
|
1459
1449
|
return await signTransfer(
|
|
1460
1450
|
apiBaseUrl,
|
|
1461
1451
|
token ?? "",
|
|
@@ -2661,14 +2651,18 @@ function CreatePasskeyScreen({
|
|
|
2661
2651
|
onCreatePasskey,
|
|
2662
2652
|
onBack,
|
|
2663
2653
|
creating,
|
|
2664
|
-
error
|
|
2654
|
+
error,
|
|
2655
|
+
popupFallback = false,
|
|
2656
|
+
onCreatePasskeyViaPopup
|
|
2665
2657
|
}) {
|
|
2666
2658
|
const { tokens } = useSwypeConfig();
|
|
2659
|
+
const handleCreate = popupFallback && onCreatePasskeyViaPopup ? onCreatePasskeyViaPopup : onCreatePasskey;
|
|
2660
|
+
const buttonLabel = popupFallback ? "Open passkey setup" : "Create passkey";
|
|
2667
2661
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2668
2662
|
ScreenLayout,
|
|
2669
2663
|
{
|
|
2670
2664
|
footer: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2671
|
-
/* @__PURE__ */ jsxRuntime.jsx(PrimaryButton, { onClick:
|
|
2665
|
+
/* @__PURE__ */ jsxRuntime.jsx(PrimaryButton, { onClick: handleCreate, disabled: creating, loading: creating, children: buttonLabel }),
|
|
2672
2666
|
/* @__PURE__ */ jsxRuntime.jsx(PoweredByFooter, {})
|
|
2673
2667
|
] }),
|
|
2674
2668
|
children: [
|
|
@@ -2681,7 +2675,7 @@ function CreatePasskeyScreen({
|
|
|
2681
2675
|
/* @__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" })
|
|
2682
2676
|
] }) }),
|
|
2683
2677
|
/* @__PURE__ */ jsxRuntime.jsx("h2", { style: headingStyle3(tokens.text), children: "Create your passkey" }),
|
|
2684
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { style: subtitleStyle3(tokens.textSecondary), children: "Use Face ID to sign in instantly \u2014 no passwords, no codes." }),
|
|
2678
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { style: subtitleStyle3(tokens.textSecondary), children: popupFallback ? "Your browser requires a separate window for passkey setup. Tap the button below to continue." : "Use Face ID to sign in instantly \u2014 no passwords, no codes." }),
|
|
2685
2679
|
error && /* @__PURE__ */ jsxRuntime.jsx("div", { style: errorBannerStyle2(tokens), children: error }),
|
|
2686
2680
|
/* @__PURE__ */ jsxRuntime.jsx(InfoBanner, { children: "Your passkey is stored securely on your device. Swype never sees your biometric data." })
|
|
2687
2681
|
] })
|
|
@@ -3866,7 +3860,7 @@ function OpenWalletScreen({
|
|
|
3866
3860
|
const logoSrc = walletName ? KNOWN_LOGOS[walletName.toLowerCase()] : void 0;
|
|
3867
3861
|
const handleOpen = react.useCallback(() => {
|
|
3868
3862
|
const opened = window.open(deeplinkUri, "_blank");
|
|
3869
|
-
if (!opened) {
|
|
3863
|
+
if (!opened && window === window.parent) {
|
|
3870
3864
|
window.location.href = deeplinkUri;
|
|
3871
3865
|
}
|
|
3872
3866
|
}, [deeplinkUri]);
|
|
@@ -4134,6 +4128,7 @@ function SwypePaymentInner({
|
|
|
4134
4128
|
const [transfer, setTransfer] = react.useState(null);
|
|
4135
4129
|
const [creatingTransfer, setCreatingTransfer] = react.useState(false);
|
|
4136
4130
|
const [registeringPasskey, setRegisteringPasskey] = react.useState(false);
|
|
4131
|
+
const [passkeyPopupNeeded, setPasskeyPopupNeeded] = react.useState(false);
|
|
4137
4132
|
const [activeCredentialId, setActiveCredentialId] = react.useState(() => {
|
|
4138
4133
|
if (typeof window === "undefined") return null;
|
|
4139
4134
|
return window.localStorage.getItem(ACTIVE_CREDENTIAL_STORAGE_KEY);
|
|
@@ -4636,34 +4631,59 @@ function SwypePaymentInner({
|
|
|
4636
4631
|
merchantAuthorization,
|
|
4637
4632
|
transfer
|
|
4638
4633
|
]);
|
|
4634
|
+
const completePasskeyRegistration = react.useCallback(async (credentialId, publicKey) => {
|
|
4635
|
+
const token = await getAccessToken();
|
|
4636
|
+
if (!token) throw new Error("Not authenticated");
|
|
4637
|
+
await registerPasskey(apiBaseUrl, token, credentialId, publicKey);
|
|
4638
|
+
setActiveCredentialId(credentialId);
|
|
4639
|
+
window.localStorage.setItem(ACTIVE_CREDENTIAL_STORAGE_KEY, credentialId);
|
|
4640
|
+
setPasskeyPopupNeeded(false);
|
|
4641
|
+
const hasActiveWallet = accounts.some(
|
|
4642
|
+
(a) => a.wallets.some((w) => w.status === "ACTIVE")
|
|
4643
|
+
);
|
|
4644
|
+
if (accounts.length === 0 || !hasActiveWallet) {
|
|
4645
|
+
setStep("wallet-picker");
|
|
4646
|
+
} else {
|
|
4647
|
+
setStep("deposit");
|
|
4648
|
+
}
|
|
4649
|
+
}, [getAccessToken, apiBaseUrl, accounts]);
|
|
4639
4650
|
const handleRegisterPasskey = react.useCallback(async () => {
|
|
4640
4651
|
setRegisteringPasskey(true);
|
|
4641
4652
|
setError(null);
|
|
4642
4653
|
try {
|
|
4643
|
-
const token = await getAccessToken();
|
|
4644
|
-
if (!token) throw new Error("Not authenticated");
|
|
4645
4654
|
const passkeyDisplayName = user?.email?.address ?? user?.google?.name ?? user?.id ?? "Swype User";
|
|
4646
4655
|
const { credentialId, publicKey } = await createPasskeyCredential({
|
|
4647
4656
|
userId: user?.id ?? "unknown",
|
|
4648
4657
|
displayName: passkeyDisplayName
|
|
4649
4658
|
});
|
|
4650
|
-
await
|
|
4651
|
-
|
|
4652
|
-
|
|
4653
|
-
|
|
4654
|
-
(a) => a.wallets.some((w) => w.status === "ACTIVE")
|
|
4655
|
-
);
|
|
4656
|
-
if (accounts.length === 0 || !hasActiveWallet) {
|
|
4657
|
-
setStep("wallet-picker");
|
|
4659
|
+
await completePasskeyRegistration(credentialId, publicKey);
|
|
4660
|
+
} catch (err) {
|
|
4661
|
+
if (err instanceof PasskeyIframeBlockedError) {
|
|
4662
|
+
setPasskeyPopupNeeded(true);
|
|
4658
4663
|
} else {
|
|
4659
|
-
|
|
4664
|
+
setError(err instanceof Error ? err.message : "Failed to register passkey");
|
|
4660
4665
|
}
|
|
4666
|
+
} finally {
|
|
4667
|
+
setRegisteringPasskey(false);
|
|
4668
|
+
}
|
|
4669
|
+
}, [user, completePasskeyRegistration]);
|
|
4670
|
+
const handleCreatePasskeyViaPopup = react.useCallback(async () => {
|
|
4671
|
+
setRegisteringPasskey(true);
|
|
4672
|
+
setError(null);
|
|
4673
|
+
try {
|
|
4674
|
+
const passkeyDisplayName = user?.email?.address ?? user?.google?.name ?? user?.id ?? "Swype User";
|
|
4675
|
+
const popupOptions = buildPasskeyPopupOptions({
|
|
4676
|
+
userId: user?.id ?? "unknown",
|
|
4677
|
+
displayName: passkeyDisplayName
|
|
4678
|
+
});
|
|
4679
|
+
const { credentialId, publicKey } = await createPasskeyViaPopup(popupOptions);
|
|
4680
|
+
await completePasskeyRegistration(credentialId, publicKey);
|
|
4661
4681
|
} catch (err) {
|
|
4662
4682
|
setError(err instanceof Error ? err.message : "Failed to register passkey");
|
|
4663
4683
|
} finally {
|
|
4664
4684
|
setRegisteringPasskey(false);
|
|
4665
4685
|
}
|
|
4666
|
-
}, [
|
|
4686
|
+
}, [user, completePasskeyRegistration]);
|
|
4667
4687
|
const handleSelectProvider = react.useCallback((providerId) => {
|
|
4668
4688
|
setSelectedProviderId(providerId);
|
|
4669
4689
|
setSelectedAccountId(null);
|
|
@@ -4781,7 +4801,9 @@ function SwypePaymentInner({
|
|
|
4781
4801
|
onCreatePasskey: handleRegisterPasskey,
|
|
4782
4802
|
onBack: handleLogout,
|
|
4783
4803
|
creating: registeringPasskey,
|
|
4784
|
-
error
|
|
4804
|
+
error,
|
|
4805
|
+
popupFallback: passkeyPopupNeeded,
|
|
4806
|
+
onCreatePasskeyViaPopup: handleCreatePasskeyViaPopup
|
|
4785
4807
|
}
|
|
4786
4808
|
);
|
|
4787
4809
|
}
|
|
@@ -4916,6 +4938,7 @@ function SwypePaymentInner({
|
|
|
4916
4938
|
|
|
4917
4939
|
exports.IconCircle = IconCircle;
|
|
4918
4940
|
exports.OutlineButton = OutlineButton;
|
|
4941
|
+
exports.PasskeyIframeBlockedError = PasskeyIframeBlockedError;
|
|
4919
4942
|
exports.PoweredByFooter = PoweredByFooter;
|
|
4920
4943
|
exports.PrimaryButton = PrimaryButton;
|
|
4921
4944
|
exports.ScreenHeader = ScreenHeader;
|
|
@@ -4927,7 +4950,9 @@ exports.Spinner = Spinner;
|
|
|
4927
4950
|
exports.StepList = StepList;
|
|
4928
4951
|
exports.SwypePayment = SwypePayment;
|
|
4929
4952
|
exports.SwypeProvider = SwypeProvider;
|
|
4953
|
+
exports.buildPasskeyPopupOptions = buildPasskeyPopupOptions;
|
|
4930
4954
|
exports.createPasskeyCredential = createPasskeyCredential;
|
|
4955
|
+
exports.createPasskeyViaPopup = createPasskeyViaPopup;
|
|
4931
4956
|
exports.darkTheme = darkTheme;
|
|
4932
4957
|
exports.deviceHasPasskey = deviceHasPasskey;
|
|
4933
4958
|
exports.findDevicePasskey = findDevicePasskey;
|