@volr/react 0.1.133 → 0.1.134

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.js CHANGED
@@ -9837,6 +9837,16 @@ var WebAuthnBusyError = class _WebAuthnBusyError extends Error {
9837
9837
  Object.setPrototypeOf(this, _WebAuthnBusyError.prototype);
9838
9838
  }
9839
9839
  };
9840
+ var InAppBrowserNotSupportedError = class _InAppBrowserNotSupportedError extends Error {
9841
+ constructor(message) {
9842
+ super(
9843
+ message || "Passkeys aren't supported in in-app browsers. Please open this page in your device browser (Chrome on Android, Safari on iOS)."
9844
+ );
9845
+ this.code = "INAPP_BROWSER_NOT_SUPPORTED";
9846
+ this.name = "InAppBrowserNotSupportedError";
9847
+ Object.setPrototypeOf(this, _InAppBrowserNotSupportedError.prototype);
9848
+ }
9849
+ };
9840
9850
  function isUserCancelledError(error) {
9841
9851
  if (error instanceof UserCancelledError) {
9842
9852
  return true;
@@ -9867,84 +9877,425 @@ function isWebAuthnBusyError(error) {
9867
9877
  }
9868
9878
  return false;
9869
9879
  }
9870
-
9871
- // src/adapters/passkey.ts
9872
- var pendingWebAuthnPromise = null;
9873
- async function withWebAuthnLock(fn) {
9874
- if (pendingWebAuthnPromise) {
9875
- try {
9876
- await pendingWebAuthnPromise;
9877
- } catch {
9878
- }
9880
+ function isInAppBrowserNotSupportedError(error) {
9881
+ if (error instanceof InAppBrowserNotSupportedError) {
9882
+ return true;
9879
9883
  }
9880
- const promise = fn();
9881
- pendingWebAuthnPromise = promise;
9882
- try {
9883
- const result = await promise;
9884
- return result;
9885
- } finally {
9886
- if (pendingWebAuthnPromise === promise) {
9887
- pendingWebAuthnPromise = null;
9884
+ if (error instanceof Error) {
9885
+ if (error.code === "INAPP_BROWSER_NOT_SUPPORTED") {
9886
+ return true;
9888
9887
  }
9889
9888
  }
9889
+ return false;
9890
9890
  }
9891
- function createPasskeyAdapter(options = {}) {
9892
- const rpId = options.rpId || (typeof window !== "undefined" ? window.location.hostname : "localhost");
9893
- return {
9894
- async getPublicKey() {
9895
- const credential = await navigator.credentials.get({
9896
- publicKey: {
9897
- challenge: new Uint8Array(32),
9898
- // Dummy challenge for getting public key
9899
- allowCredentials: [],
9900
- // Empty = any credential
9901
- userVerification: "required"
9902
- }
9903
- });
9904
- if (!credential || !("response" in credential)) {
9905
- throw new Error("Failed to get passkey credential");
9891
+
9892
+ // src/utils/platform-check.ts
9893
+ function detectPlatform() {
9894
+ if (typeof navigator === "undefined") return "Unknown";
9895
+ const ua = navigator.userAgent;
9896
+ const platform = navigator.platform || "";
9897
+ if (/iPhone|iPad|iPod/.test(ua) || platform === "MacIntel" && navigator.maxTouchPoints > 1) {
9898
+ return "iOS";
9899
+ }
9900
+ if (/Android/.test(ua)) {
9901
+ return "Android";
9902
+ }
9903
+ if (/Mac/.test(platform)) {
9904
+ return "macOS";
9905
+ }
9906
+ if (/Win/.test(platform)) {
9907
+ return "Windows";
9908
+ }
9909
+ if (/CrOS/.test(ua)) {
9910
+ return "ChromeOS";
9911
+ }
9912
+ if (/Linux/.test(platform)) {
9913
+ return "Linux";
9914
+ }
9915
+ return "Unknown";
9916
+ }
9917
+ function detectBrowser() {
9918
+ if (typeof navigator === "undefined") return "Unknown";
9919
+ const ua = navigator.userAgent;
9920
+ if (/KAKAOTALK/i.test(ua)) return "KakaoTalk-InApp";
9921
+ if (/NAVER\(/i.test(ua)) return "Naver-InApp";
9922
+ if (/Line\//i.test(ua)) return "Line-InApp";
9923
+ if (/MetaMaskMobile/i.test(ua)) return "MetaMask-InApp";
9924
+ if (/FB_IAB|FBAN/i.test(ua)) return "Facebook-InApp";
9925
+ if (/Instagram/i.test(ua)) return "Instagram-InApp";
9926
+ if (/Telegram/i.test(ua)) return "Telegram-InApp";
9927
+ if (/SamsungBrowser/i.test(ua)) return "Samsung";
9928
+ if (/Whale/i.test(ua)) return "Whale";
9929
+ if (/Edg/.test(ua)) return "Edge";
9930
+ if (/Chrome/.test(ua) && !/Chromium/.test(ua)) return "Chrome";
9931
+ if (/Safari/.test(ua) && !/Chrome/.test(ua)) return "Safari";
9932
+ if (/Firefox/.test(ua)) return "Firefox";
9933
+ if (/Opera|OPR/.test(ua)) return "Opera";
9934
+ return "Unknown";
9935
+ }
9936
+ function isInAppBrowser() {
9937
+ const browser = detectBrowser();
9938
+ return browser.includes("-InApp");
9939
+ }
9940
+ function getBrowserVersion() {
9941
+ if (typeof navigator === "undefined") return { browser: "Unknown", version: 0 };
9942
+ const ua = navigator.userAgent;
9943
+ const edgeMatch = ua.match(/Edg\/(\d+)/);
9944
+ if (edgeMatch) return { browser: "Edge", version: parseInt(edgeMatch[1]) };
9945
+ const samsungMatch = ua.match(/SamsungBrowser\/(\d+)/);
9946
+ if (samsungMatch) return { browser: "Samsung", version: parseInt(samsungMatch[1]) };
9947
+ const chromeMatch = ua.match(/Chrome\/(\d+)/);
9948
+ if (chromeMatch && !/Edg/.test(ua)) return { browser: "Chrome", version: parseInt(chromeMatch[1]) };
9949
+ const safariMatch = ua.match(/Version\/(\d+)\.(\d+)/);
9950
+ if (safariMatch && /Safari/.test(ua) && !/Chrome/.test(ua)) {
9951
+ return { browser: "Safari", version: parseFloat(`${safariMatch[1]}.${safariMatch[2]}`) };
9952
+ }
9953
+ const firefoxMatch = ua.match(/Firefox\/(\d+)/);
9954
+ if (firefoxMatch) return { browser: "Firefox", version: parseInt(firefoxMatch[1]) };
9955
+ return { browser: "Unknown", version: 0 };
9956
+ }
9957
+ function getIOSVersion() {
9958
+ if (typeof navigator === "undefined") return null;
9959
+ const ua = navigator.userAgent;
9960
+ const match = ua.match(/OS (\d+)_(\d+)/);
9961
+ if (match) {
9962
+ return parseFloat(`${match[1]}.${match[2]}`);
9963
+ }
9964
+ return null;
9965
+ }
9966
+ function checkPrfSupport() {
9967
+ const platform = detectPlatform();
9968
+ const browser = detectBrowser();
9969
+ if (typeof navigator === "undefined" || !navigator.credentials) {
9970
+ return {
9971
+ prfSupported: false,
9972
+ crossDeviceAvailable: false,
9973
+ message: "WebAuthn is not supported in this environment.",
9974
+ platform,
9975
+ browser
9976
+ };
9977
+ }
9978
+ let prfSupported = false;
9979
+ let message;
9980
+ switch (platform) {
9981
+ case "iOS":
9982
+ if (browser === "Safari") {
9983
+ prfSupported = true;
9984
+ } else {
9985
+ prfSupported = true;
9906
9986
  }
9907
- throw new Error(
9908
- "getPublicKey not implemented - use credential creation response"
9909
- );
9910
- },
9911
- async signP256(msgHash32) {
9912
- if (msgHash32.length !== 32) {
9913
- throw new Error("Message hash must be 32 bytes");
9987
+ break;
9988
+ case "Android":
9989
+ if (browser === "Chrome" || browser === "Edge") {
9990
+ prfSupported = true;
9991
+ } else if (browser === "Firefox") {
9992
+ prfSupported = false;
9993
+ message = "Firefox on Android does not support passkey encryption. Please use Chrome.";
9994
+ } else {
9995
+ prfSupported = true;
9914
9996
  }
9915
- const credential = await navigator.credentials.get({
9916
- publicKey: {
9917
- challenge: msgHash32,
9918
- allowCredentials: [],
9919
- // Empty = any credential
9920
- userVerification: "required"
9921
- }
9922
- });
9923
- if (!credential || !("response" in credential)) {
9924
- throw new Error("Failed to get passkey credential for signing");
9997
+ break;
9998
+ case "macOS":
9999
+ if (browser === "Safari" || browser === "Chrome" || browser === "Edge") {
10000
+ prfSupported = true;
10001
+ } else if (browser === "Firefox") {
10002
+ prfSupported = false;
10003
+ message = "Firefox may not support passkey encryption. Please use Safari or Chrome.";
10004
+ } else {
10005
+ prfSupported = true;
9925
10006
  }
9926
- const response = credential.response;
9927
- const signature = response.signature;
9928
- const derSignature = new Uint8Array(signature);
9929
- if (derSignature[0] !== 48) {
9930
- throw new Error("Invalid DER signature format");
10007
+ break;
10008
+ case "Windows":
10009
+ if (browser === "Chrome" || browser === "Edge") {
10010
+ prfSupported = true;
10011
+ message = "If your device does not support passkey encryption, you can use your mobile device by scanning a QR code.";
10012
+ } else {
10013
+ prfSupported = false;
10014
+ message = "Please use Chrome or Edge for passkey encryption support.";
9931
10015
  }
9932
- let offset = 2;
9933
- if (derSignature[offset] !== 2) {
9934
- throw new Error("Invalid DER signature: expected r marker");
10016
+ break;
10017
+ case "ChromeOS":
10018
+ prfSupported = true;
10019
+ break;
10020
+ case "Linux":
10021
+ if (browser === "Chrome" || browser === "Edge") {
10022
+ prfSupported = true;
10023
+ message = "If your device does not support passkey encryption, you can use your mobile device by scanning a QR code.";
10024
+ } else {
10025
+ prfSupported = false;
10026
+ message = "Please use Chrome for passkey encryption support.";
9935
10027
  }
9936
- offset++;
9937
- const rLength = derSignature[offset++];
9938
- const rBytes = derSignature.slice(offset, offset + rLength);
9939
- offset += rLength;
9940
- if (derSignature[offset] !== 2) {
9941
- throw new Error("Invalid DER signature: expected s marker");
10028
+ break;
10029
+ default:
10030
+ prfSupported = false;
10031
+ message = "Unknown platform. Passkey encryption may not be supported.";
10032
+ }
10033
+ const crossDeviceAvailable = true;
10034
+ return {
10035
+ prfSupported,
10036
+ crossDeviceAvailable,
10037
+ message,
10038
+ platform,
10039
+ browser
10040
+ };
10041
+ }
10042
+ function getPasskeyAuthGuidance(passkeyPlatform) {
10043
+ const { platform: currentPlatform, prfSupported } = checkPrfSupport();
10044
+ if (prfSupported && (!passkeyPlatform || passkeyPlatform === currentPlatform)) {
10045
+ return "";
10046
+ }
10047
+ if (passkeyPlatform && passkeyPlatform !== currentPlatform) {
10048
+ const platformDisplayName = getPlatformDisplayName(passkeyPlatform);
10049
+ return `Your passkey was registered on ${platformDisplayName}. You can use your ${platformDisplayName} device to authenticate by scanning a QR code.`;
10050
+ }
10051
+ if (!prfSupported) {
10052
+ return "This device may not support passkey encryption. You can use your mobile device by scanning a QR code.";
10053
+ }
10054
+ return "";
10055
+ }
10056
+ function getPlatformDisplayName(platform) {
10057
+ const displayNames = {
10058
+ iOS: "iPhone/iPad",
10059
+ Android: "Android",
10060
+ macOS: "Mac",
10061
+ Windows: "Windows PC",
10062
+ ChromeOS: "Chromebook",
10063
+ Linux: "Linux"
10064
+ };
10065
+ return displayNames[platform] || platform;
10066
+ }
10067
+ async function checkPrfExtensionAvailable() {
10068
+ if (typeof PublicKeyCredential === "undefined") {
10069
+ return false;
10070
+ }
10071
+ if ("getClientCapabilities" in PublicKeyCredential) {
10072
+ try {
10073
+ const capabilities = await PublicKeyCredential.getClientCapabilities();
10074
+ if (capabilities && typeof capabilities.extensions?.prf === "boolean") {
10075
+ return capabilities.extensions.prf;
9942
10076
  }
9943
- offset++;
9944
- const sLength = derSignature[offset++];
9945
- const sBytes = derSignature.slice(offset, offset + sLength);
9946
- const r = new Uint8Array(32);
9947
- const s = new Uint8Array(32);
10077
+ } catch {
10078
+ }
10079
+ }
10080
+ const { prfSupported } = checkPrfSupport();
10081
+ return prfSupported;
10082
+ }
10083
+ var MIN_BROWSER_VERSIONS = {
10084
+ Chrome: 109,
10085
+ Edge: 109,
10086
+ Safari: 17.4,
10087
+ Samsung: 21
10088
+ // Samsung Internet 21+ is based on Chromium 109+
10089
+ };
10090
+ var MIN_IOS_VERSION = 17.4;
10091
+ function checkPrfCompatibility() {
10092
+ const platform = detectPlatform();
10093
+ const browser = detectBrowser();
10094
+ const { browser: browserName, version: browserVersion } = getBrowserVersion();
10095
+ const baseResult = {
10096
+ platform,
10097
+ browser,
10098
+ browserVersion
10099
+ };
10100
+ if (isInAppBrowser()) {
10101
+ return {
10102
+ ...baseResult,
10103
+ supported: false,
10104
+ reason: "inapp-browser",
10105
+ messageKey: "passkey.compatibility.inAppBrowser",
10106
+ action: "use-external-browser"
10107
+ };
10108
+ }
10109
+ if (browserName === "Firefox") {
10110
+ return {
10111
+ ...baseResult,
10112
+ supported: false,
10113
+ reason: "unsupported-browser",
10114
+ messageKey: "passkey.compatibility.firefoxNotSupported",
10115
+ action: "use-chrome"
10116
+ };
10117
+ }
10118
+ if (browser === "Whale") {
10119
+ return {
10120
+ ...baseResult,
10121
+ supported: false,
10122
+ reason: "unsupported-browser",
10123
+ messageKey: "passkey.compatibility.whaleNotSupported",
10124
+ action: "use-chrome"
10125
+ };
10126
+ }
10127
+ if (browserName === "Chrome" && browserVersion < MIN_BROWSER_VERSIONS.Chrome) {
10128
+ return {
10129
+ ...baseResult,
10130
+ supported: false,
10131
+ reason: "outdated-browser",
10132
+ messageKey: "passkey.compatibility.outdatedChrome",
10133
+ action: "update-browser"
10134
+ };
10135
+ }
10136
+ if (browserName === "Edge" && browserVersion < MIN_BROWSER_VERSIONS.Edge) {
10137
+ return {
10138
+ ...baseResult,
10139
+ supported: false,
10140
+ reason: "outdated-browser",
10141
+ messageKey: "passkey.compatibility.outdatedEdge",
10142
+ action: "update-browser"
10143
+ };
10144
+ }
10145
+ if (browserName === "Safari" && browserVersion < MIN_BROWSER_VERSIONS.Safari) {
10146
+ return {
10147
+ ...baseResult,
10148
+ supported: false,
10149
+ reason: "outdated-browser",
10150
+ messageKey: "passkey.compatibility.outdatedSafari",
10151
+ action: "update-browser"
10152
+ };
10153
+ }
10154
+ if (browserName === "Samsung" && browserVersion < MIN_BROWSER_VERSIONS.Samsung) {
10155
+ return {
10156
+ ...baseResult,
10157
+ supported: false,
10158
+ reason: "outdated-browser",
10159
+ messageKey: "passkey.compatibility.outdatedSamsung",
10160
+ action: "update-browser"
10161
+ };
10162
+ }
10163
+ if (platform === "iOS") {
10164
+ const iosVersion = getIOSVersion();
10165
+ if (iosVersion && iosVersion < MIN_IOS_VERSION) {
10166
+ return {
10167
+ ...baseResult,
10168
+ supported: false,
10169
+ reason: "outdated-os",
10170
+ messageKey: "passkey.compatibility.outdatedIOS",
10171
+ action: "update-os"
10172
+ };
10173
+ }
10174
+ }
10175
+ if (browserName === "Unknown") {
10176
+ return {
10177
+ ...baseResult,
10178
+ supported: true,
10179
+ messageKey: "passkey.compatibility.unknownBrowser"
10180
+ };
10181
+ }
10182
+ return {
10183
+ ...baseResult,
10184
+ supported: true
10185
+ };
10186
+ }
10187
+ function getPlatformHint(platform) {
10188
+ switch (platform) {
10189
+ case "macOS":
10190
+ return {
10191
+ hintKey: "passkey.hint.macOS",
10192
+ noteKey: "passkey.hint.note"
10193
+ };
10194
+ case "iOS":
10195
+ return {
10196
+ hintKey: "passkey.hint.iOS",
10197
+ noteKey: "passkey.hint.note"
10198
+ };
10199
+ case "Android":
10200
+ return {
10201
+ hintKey: "passkey.hint.android",
10202
+ noteKey: "passkey.hint.note"
10203
+ };
10204
+ case "Windows":
10205
+ return {
10206
+ hintKey: "passkey.hint.windows",
10207
+ noteKey: "passkey.hint.windowsNote"
10208
+ };
10209
+ case "Linux":
10210
+ return {
10211
+ hintKey: "passkey.hint.linux",
10212
+ noteKey: "passkey.hint.windowsNote"
10213
+ };
10214
+ default:
10215
+ return {
10216
+ hintKey: "passkey.hint.default",
10217
+ noteKey: "passkey.hint.note"
10218
+ };
10219
+ }
10220
+ }
10221
+
10222
+ // src/adapters/passkey.ts
10223
+ var pendingWebAuthnPromise = null;
10224
+ async function withWebAuthnLock(fn) {
10225
+ if (pendingWebAuthnPromise) {
10226
+ try {
10227
+ await pendingWebAuthnPromise;
10228
+ } catch {
10229
+ }
10230
+ }
10231
+ const promise = fn();
10232
+ pendingWebAuthnPromise = promise;
10233
+ try {
10234
+ const result = await promise;
10235
+ return result;
10236
+ } finally {
10237
+ if (pendingWebAuthnPromise === promise) {
10238
+ pendingWebAuthnPromise = null;
10239
+ }
10240
+ }
10241
+ }
10242
+ function createPasskeyAdapter(options = {}) {
10243
+ const rpId = options.rpId || (typeof window !== "undefined" ? window.location.hostname : "localhost");
10244
+ return {
10245
+ async getPublicKey() {
10246
+ const credential = await navigator.credentials.get({
10247
+ publicKey: {
10248
+ challenge: new Uint8Array(32),
10249
+ // Dummy challenge for getting public key
10250
+ allowCredentials: [],
10251
+ // Empty = any credential
10252
+ userVerification: "required"
10253
+ }
10254
+ });
10255
+ if (!credential || !("response" in credential)) {
10256
+ throw new Error("Failed to get passkey credential");
10257
+ }
10258
+ throw new Error(
10259
+ "getPublicKey not implemented - use credential creation response"
10260
+ );
10261
+ },
10262
+ async signP256(msgHash32) {
10263
+ if (msgHash32.length !== 32) {
10264
+ throw new Error("Message hash must be 32 bytes");
10265
+ }
10266
+ const credential = await navigator.credentials.get({
10267
+ publicKey: {
10268
+ challenge: msgHash32,
10269
+ allowCredentials: [],
10270
+ // Empty = any credential
10271
+ userVerification: "required"
10272
+ }
10273
+ });
10274
+ if (!credential || !("response" in credential)) {
10275
+ throw new Error("Failed to get passkey credential for signing");
10276
+ }
10277
+ const response = credential.response;
10278
+ const signature = response.signature;
10279
+ const derSignature = new Uint8Array(signature);
10280
+ if (derSignature[0] !== 48) {
10281
+ throw new Error("Invalid DER signature format");
10282
+ }
10283
+ let offset = 2;
10284
+ if (derSignature[offset] !== 2) {
10285
+ throw new Error("Invalid DER signature: expected r marker");
10286
+ }
10287
+ offset++;
10288
+ const rLength = derSignature[offset++];
10289
+ const rBytes = derSignature.slice(offset, offset + rLength);
10290
+ offset += rLength;
10291
+ if (derSignature[offset] !== 2) {
10292
+ throw new Error("Invalid DER signature: expected s marker");
10293
+ }
10294
+ offset++;
10295
+ const sLength = derSignature[offset++];
10296
+ const sBytes = derSignature.slice(offset, offset + sLength);
10297
+ const r = new Uint8Array(32);
10298
+ const s = new Uint8Array(32);
9948
10299
  if (rBytes.length > 32 || sBytes.length > 32) {
9949
10300
  throw new Error("Signature r or s exceeds 32 bytes");
9950
10301
  }
@@ -9953,6 +10304,11 @@ function createPasskeyAdapter(options = {}) {
9953
10304
  return { r, s };
9954
10305
  },
9955
10306
  async authenticate(prfInput) {
10307
+ if (isInAppBrowser()) {
10308
+ throw new InAppBrowserNotSupportedError(
10309
+ "Passkeys aren't supported in in-app browsers. Please open this page in your device browser (Chrome on Android, Safari on iOS)."
10310
+ );
10311
+ }
9956
10312
  const allowCredentials = [];
9957
10313
  if (prfInput.credentialId) {
9958
10314
  const hexString = prfInput.credentialId.startsWith("0x") ? prfInput.credentialId.slice(2) : prfInput.credentialId;
@@ -10027,6 +10383,11 @@ function createPasskeyAdapter(options = {}) {
10027
10383
  "Another passkey authentication is in progress. Please wait a moment and try again."
10028
10384
  );
10029
10385
  }
10386
+ if (isInAppBrowser()) {
10387
+ throw new InAppBrowserNotSupportedError(
10388
+ "Passkeys aren't supported in in-app browsers. Please open this page in your device browser (Chrome on Android, Safari on iOS)."
10389
+ );
10390
+ }
10030
10391
  if (error?.name === "NotAllowedError") {
10031
10392
  throw new UserCancelledError(
10032
10393
  "User cancelled the passkey prompt or authentication was denied."
@@ -19622,7 +19983,7 @@ function blobToBase64(blob) {
19622
19983
  reader.readAsDataURL(blob);
19623
19984
  });
19624
19985
  }
19625
- function detectPlatform() {
19986
+ function detectPlatform2() {
19626
19987
  if (typeof navigator === "undefined") return "Unknown";
19627
19988
  const ua = navigator.userAgent;
19628
19989
  const platform = navigator.platform || "";
@@ -19774,7 +20135,7 @@ async function enrollPasskey(params) {
19774
20135
  }
19775
20136
  const keypair = deriveEvmKey({ masterSeed: masterKeyHandle.seed });
19776
20137
  const address = keypair.address;
19777
- const platform = detectPlatform();
20138
+ const platform = detectPlatform2();
19778
20139
  const registerResponse = await client.post("/wallet/provider/register", {
19779
20140
  keyStorageType: "passkey",
19780
20141
  credentialId,
@@ -20600,336 +20961,6 @@ async function debugTransactionFailure(publicClient, failingWallet, workingWalle
20600
20961
  analysis
20601
20962
  };
20602
20963
  }
20603
-
20604
- // src/utils/platform-check.ts
20605
- function detectPlatform2() {
20606
- if (typeof navigator === "undefined") return "Unknown";
20607
- const ua = navigator.userAgent;
20608
- const platform = navigator.platform || "";
20609
- if (/iPhone|iPad|iPod/.test(ua) || platform === "MacIntel" && navigator.maxTouchPoints > 1) {
20610
- return "iOS";
20611
- }
20612
- if (/Android/.test(ua)) {
20613
- return "Android";
20614
- }
20615
- if (/Mac/.test(platform)) {
20616
- return "macOS";
20617
- }
20618
- if (/Win/.test(platform)) {
20619
- return "Windows";
20620
- }
20621
- if (/CrOS/.test(ua)) {
20622
- return "ChromeOS";
20623
- }
20624
- if (/Linux/.test(platform)) {
20625
- return "Linux";
20626
- }
20627
- return "Unknown";
20628
- }
20629
- function detectBrowser() {
20630
- if (typeof navigator === "undefined") return "Unknown";
20631
- const ua = navigator.userAgent;
20632
- if (/KAKAOTALK/i.test(ua)) return "KakaoTalk-InApp";
20633
- if (/NAVER\(/i.test(ua)) return "Naver-InApp";
20634
- if (/Line\//i.test(ua)) return "Line-InApp";
20635
- if (/MetaMaskMobile/i.test(ua)) return "MetaMask-InApp";
20636
- if (/FB_IAB|FBAN/i.test(ua)) return "Facebook-InApp";
20637
- if (/Instagram/i.test(ua)) return "Instagram-InApp";
20638
- if (/Telegram/i.test(ua)) return "Telegram-InApp";
20639
- if (/SamsungBrowser/i.test(ua)) return "Samsung";
20640
- if (/Whale/i.test(ua)) return "Whale";
20641
- if (/Edg/.test(ua)) return "Edge";
20642
- if (/Chrome/.test(ua) && !/Chromium/.test(ua)) return "Chrome";
20643
- if (/Safari/.test(ua) && !/Chrome/.test(ua)) return "Safari";
20644
- if (/Firefox/.test(ua)) return "Firefox";
20645
- if (/Opera|OPR/.test(ua)) return "Opera";
20646
- return "Unknown";
20647
- }
20648
- function isInAppBrowser() {
20649
- const browser = detectBrowser();
20650
- return browser.includes("-InApp");
20651
- }
20652
- function getBrowserVersion() {
20653
- if (typeof navigator === "undefined") return { browser: "Unknown", version: 0 };
20654
- const ua = navigator.userAgent;
20655
- const edgeMatch = ua.match(/Edg\/(\d+)/);
20656
- if (edgeMatch) return { browser: "Edge", version: parseInt(edgeMatch[1]) };
20657
- const samsungMatch = ua.match(/SamsungBrowser\/(\d+)/);
20658
- if (samsungMatch) return { browser: "Samsung", version: parseInt(samsungMatch[1]) };
20659
- const chromeMatch = ua.match(/Chrome\/(\d+)/);
20660
- if (chromeMatch && !/Edg/.test(ua)) return { browser: "Chrome", version: parseInt(chromeMatch[1]) };
20661
- const safariMatch = ua.match(/Version\/(\d+)\.(\d+)/);
20662
- if (safariMatch && /Safari/.test(ua) && !/Chrome/.test(ua)) {
20663
- return { browser: "Safari", version: parseFloat(`${safariMatch[1]}.${safariMatch[2]}`) };
20664
- }
20665
- const firefoxMatch = ua.match(/Firefox\/(\d+)/);
20666
- if (firefoxMatch) return { browser: "Firefox", version: parseInt(firefoxMatch[1]) };
20667
- return { browser: "Unknown", version: 0 };
20668
- }
20669
- function getIOSVersion() {
20670
- if (typeof navigator === "undefined") return null;
20671
- const ua = navigator.userAgent;
20672
- const match = ua.match(/OS (\d+)_(\d+)/);
20673
- if (match) {
20674
- return parseFloat(`${match[1]}.${match[2]}`);
20675
- }
20676
- return null;
20677
- }
20678
- function checkPrfSupport() {
20679
- const platform = detectPlatform2();
20680
- const browser = detectBrowser();
20681
- if (typeof navigator === "undefined" || !navigator.credentials) {
20682
- return {
20683
- prfSupported: false,
20684
- crossDeviceAvailable: false,
20685
- message: "WebAuthn is not supported in this environment.",
20686
- platform,
20687
- browser
20688
- };
20689
- }
20690
- let prfSupported = false;
20691
- let message;
20692
- switch (platform) {
20693
- case "iOS":
20694
- if (browser === "Safari") {
20695
- prfSupported = true;
20696
- } else {
20697
- prfSupported = true;
20698
- }
20699
- break;
20700
- case "Android":
20701
- if (browser === "Chrome" || browser === "Edge") {
20702
- prfSupported = true;
20703
- } else if (browser === "Firefox") {
20704
- prfSupported = false;
20705
- message = "Firefox on Android does not support passkey encryption. Please use Chrome.";
20706
- } else {
20707
- prfSupported = true;
20708
- }
20709
- break;
20710
- case "macOS":
20711
- if (browser === "Safari" || browser === "Chrome" || browser === "Edge") {
20712
- prfSupported = true;
20713
- } else if (browser === "Firefox") {
20714
- prfSupported = false;
20715
- message = "Firefox may not support passkey encryption. Please use Safari or Chrome.";
20716
- } else {
20717
- prfSupported = true;
20718
- }
20719
- break;
20720
- case "Windows":
20721
- if (browser === "Chrome" || browser === "Edge") {
20722
- prfSupported = true;
20723
- message = "If your device does not support passkey encryption, you can use your mobile device by scanning a QR code.";
20724
- } else {
20725
- prfSupported = false;
20726
- message = "Please use Chrome or Edge for passkey encryption support.";
20727
- }
20728
- break;
20729
- case "ChromeOS":
20730
- prfSupported = true;
20731
- break;
20732
- case "Linux":
20733
- if (browser === "Chrome" || browser === "Edge") {
20734
- prfSupported = true;
20735
- message = "If your device does not support passkey encryption, you can use your mobile device by scanning a QR code.";
20736
- } else {
20737
- prfSupported = false;
20738
- message = "Please use Chrome for passkey encryption support.";
20739
- }
20740
- break;
20741
- default:
20742
- prfSupported = false;
20743
- message = "Unknown platform. Passkey encryption may not be supported.";
20744
- }
20745
- const crossDeviceAvailable = true;
20746
- return {
20747
- prfSupported,
20748
- crossDeviceAvailable,
20749
- message,
20750
- platform,
20751
- browser
20752
- };
20753
- }
20754
- function getPasskeyAuthGuidance(passkeyPlatform) {
20755
- const { platform: currentPlatform, prfSupported } = checkPrfSupport();
20756
- if (prfSupported && (!passkeyPlatform || passkeyPlatform === currentPlatform)) {
20757
- return "";
20758
- }
20759
- if (passkeyPlatform && passkeyPlatform !== currentPlatform) {
20760
- const platformDisplayName = getPlatformDisplayName(passkeyPlatform);
20761
- return `Your passkey was registered on ${platformDisplayName}. You can use your ${platformDisplayName} device to authenticate by scanning a QR code.`;
20762
- }
20763
- if (!prfSupported) {
20764
- return "This device may not support passkey encryption. You can use your mobile device by scanning a QR code.";
20765
- }
20766
- return "";
20767
- }
20768
- function getPlatformDisplayName(platform) {
20769
- const displayNames = {
20770
- iOS: "iPhone/iPad",
20771
- Android: "Android",
20772
- macOS: "Mac",
20773
- Windows: "Windows PC",
20774
- ChromeOS: "Chromebook",
20775
- Linux: "Linux"
20776
- };
20777
- return displayNames[platform] || platform;
20778
- }
20779
- async function checkPrfExtensionAvailable() {
20780
- if (typeof PublicKeyCredential === "undefined") {
20781
- return false;
20782
- }
20783
- if ("getClientCapabilities" in PublicKeyCredential) {
20784
- try {
20785
- const capabilities = await PublicKeyCredential.getClientCapabilities();
20786
- if (capabilities && typeof capabilities.extensions?.prf === "boolean") {
20787
- return capabilities.extensions.prf;
20788
- }
20789
- } catch {
20790
- }
20791
- }
20792
- const { prfSupported } = checkPrfSupport();
20793
- return prfSupported;
20794
- }
20795
- var MIN_BROWSER_VERSIONS = {
20796
- Chrome: 109,
20797
- Edge: 109,
20798
- Safari: 17.4,
20799
- Samsung: 21
20800
- // Samsung Internet 21+ is based on Chromium 109+
20801
- };
20802
- var MIN_IOS_VERSION = 17.4;
20803
- function checkPrfCompatibility() {
20804
- const platform = detectPlatform2();
20805
- const browser = detectBrowser();
20806
- const { browser: browserName, version: browserVersion } = getBrowserVersion();
20807
- const baseResult = {
20808
- platform,
20809
- browser,
20810
- browserVersion
20811
- };
20812
- if (isInAppBrowser()) {
20813
- return {
20814
- ...baseResult,
20815
- supported: false,
20816
- reason: "inapp-browser",
20817
- messageKey: "passkey.compatibility.inAppBrowser",
20818
- action: "use-external-browser"
20819
- };
20820
- }
20821
- if (browserName === "Firefox") {
20822
- return {
20823
- ...baseResult,
20824
- supported: false,
20825
- reason: "unsupported-browser",
20826
- messageKey: "passkey.compatibility.firefoxNotSupported",
20827
- action: "use-chrome"
20828
- };
20829
- }
20830
- if (browser === "Whale") {
20831
- return {
20832
- ...baseResult,
20833
- supported: false,
20834
- reason: "unsupported-browser",
20835
- messageKey: "passkey.compatibility.whaleNotSupported",
20836
- action: "use-chrome"
20837
- };
20838
- }
20839
- if (browserName === "Chrome" && browserVersion < MIN_BROWSER_VERSIONS.Chrome) {
20840
- return {
20841
- ...baseResult,
20842
- supported: false,
20843
- reason: "outdated-browser",
20844
- messageKey: "passkey.compatibility.outdatedChrome",
20845
- action: "update-browser"
20846
- };
20847
- }
20848
- if (browserName === "Edge" && browserVersion < MIN_BROWSER_VERSIONS.Edge) {
20849
- return {
20850
- ...baseResult,
20851
- supported: false,
20852
- reason: "outdated-browser",
20853
- messageKey: "passkey.compatibility.outdatedEdge",
20854
- action: "update-browser"
20855
- };
20856
- }
20857
- if (browserName === "Safari" && browserVersion < MIN_BROWSER_VERSIONS.Safari) {
20858
- return {
20859
- ...baseResult,
20860
- supported: false,
20861
- reason: "outdated-browser",
20862
- messageKey: "passkey.compatibility.outdatedSafari",
20863
- action: "update-browser"
20864
- };
20865
- }
20866
- if (browserName === "Samsung" && browserVersion < MIN_BROWSER_VERSIONS.Samsung) {
20867
- return {
20868
- ...baseResult,
20869
- supported: false,
20870
- reason: "outdated-browser",
20871
- messageKey: "passkey.compatibility.outdatedSamsung",
20872
- action: "update-browser"
20873
- };
20874
- }
20875
- if (platform === "iOS") {
20876
- const iosVersion = getIOSVersion();
20877
- if (iosVersion && iosVersion < MIN_IOS_VERSION) {
20878
- return {
20879
- ...baseResult,
20880
- supported: false,
20881
- reason: "outdated-os",
20882
- messageKey: "passkey.compatibility.outdatedIOS",
20883
- action: "update-os"
20884
- };
20885
- }
20886
- }
20887
- if (browserName === "Unknown") {
20888
- return {
20889
- ...baseResult,
20890
- supported: true,
20891
- messageKey: "passkey.compatibility.unknownBrowser"
20892
- };
20893
- }
20894
- return {
20895
- ...baseResult,
20896
- supported: true
20897
- };
20898
- }
20899
- function getPlatformHint(platform) {
20900
- switch (platform) {
20901
- case "macOS":
20902
- return {
20903
- hintKey: "passkey.hint.macOS",
20904
- noteKey: "passkey.hint.note"
20905
- };
20906
- case "iOS":
20907
- return {
20908
- hintKey: "passkey.hint.iOS",
20909
- noteKey: "passkey.hint.note"
20910
- };
20911
- case "Android":
20912
- return {
20913
- hintKey: "passkey.hint.android",
20914
- noteKey: "passkey.hint.note"
20915
- };
20916
- case "Windows":
20917
- return {
20918
- hintKey: "passkey.hint.windows",
20919
- noteKey: "passkey.hint.windowsNote"
20920
- };
20921
- case "Linux":
20922
- return {
20923
- hintKey: "passkey.hint.linux",
20924
- noteKey: "passkey.hint.windowsNote"
20925
- };
20926
- default:
20927
- return {
20928
- hintKey: "passkey.hint.default",
20929
- noteKey: "passkey.hint.note"
20930
- };
20931
- }
20932
- }
20933
20964
  function blobToBase642(blob) {
20934
20965
  return new Promise((resolve, reject) => {
20935
20966
  const reader = new FileReader();
@@ -21309,6 +21340,6 @@ function detectWalletConnector(provider, providerInfo) {
21309
21340
  (*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) *)
21310
21341
  */
21311
21342
 
21312
- export { DEFAULT_EXPIRES_IN_SEC, DEFAULT_MODE, PasskeyNotFoundError, PrfNotSupportedError, UserCancelledError, VolrProvider, WebAuthnBusyError, analyzeContractForEIP7702, buildCall, buildCalls, checkPrfCompatibility, checkPrfExtensionAvailable, checkPrfSupport, compareERC20Balances, compareWalletStates, completeMigration, createGetNetworkInfo, createPasskeyAdapter, debugTransactionFailure, decryptEntropyForMigration, defaultIdempotencyKey, detectWalletConnector, diagnoseTransactionFailure, getBrowserVersion, getERC20Balance, getIOSVersion, getPasskeyAuthGuidance, getPlatformHint, getUserCredentials, getWalletState, isEIP7702Delegated, isInAppBrowser, isUserCancelledError, isWebAuthnBusyError, listenForSeedRequests, normalizeHex, normalizeHexArray, openMigrationPopup, requestMigration, requestSeedFromOpener, sendSeedToPopup, uploadBlobViaPresign, useDepositListener, useEIP6963, useInternalAuth, useMpcConnection, usePasskeyEnrollment, usePrecheck, useRelay, useUserBalances, useVolr, useVolrAuthCallback, useVolrContext, useVolrLogin, useVolrPaymentApi, useWithdraw };
21343
+ export { DEFAULT_EXPIRES_IN_SEC, DEFAULT_MODE, InAppBrowserNotSupportedError, PasskeyNotFoundError, PrfNotSupportedError, UserCancelledError, VolrProvider, WebAuthnBusyError, analyzeContractForEIP7702, buildCall, buildCalls, checkPrfCompatibility, checkPrfExtensionAvailable, checkPrfSupport, compareERC20Balances, compareWalletStates, completeMigration, createGetNetworkInfo, createPasskeyAdapter, debugTransactionFailure, decryptEntropyForMigration, defaultIdempotencyKey, detectWalletConnector, diagnoseTransactionFailure, getBrowserVersion, getERC20Balance, getIOSVersion, getPasskeyAuthGuidance, getPlatformHint, getUserCredentials, getWalletState, isEIP7702Delegated, isInAppBrowser, isInAppBrowserNotSupportedError, isUserCancelledError, isWebAuthnBusyError, listenForSeedRequests, normalizeHex, normalizeHexArray, openMigrationPopup, requestMigration, requestSeedFromOpener, sendSeedToPopup, uploadBlobViaPresign, useDepositListener, useEIP6963, useInternalAuth, useMpcConnection, usePasskeyEnrollment, usePrecheck, useRelay, useUserBalances, useVolr, useVolrAuthCallback, useVolrContext, useVolrLogin, useVolrPaymentApi, useWithdraw };
21313
21344
  //# sourceMappingURL=index.js.map
21314
21345
  //# sourceMappingURL=index.js.map