@thru/passkey 0.2.21 → 0.2.23

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.
Files changed (80) hide show
  1. package/dist/auth/add-device.cjs +139 -0
  2. package/dist/auth/add-device.cjs.map +1 -0
  3. package/dist/auth/add-device.d.cts +69 -0
  4. package/dist/auth/add-device.d.ts +69 -0
  5. package/dist/auth/add-device.js +7 -0
  6. package/dist/auth/add-device.js.map +1 -0
  7. package/dist/auth.cjs +121 -6
  8. package/dist/auth.cjs.map +1 -1
  9. package/dist/auth.d.cts +2 -0
  10. package/dist/auth.d.ts +2 -0
  11. package/dist/auth.js +10 -4
  12. package/dist/auth.js.map +1 -1
  13. package/dist/chunk-KASTJBBY.js +128 -0
  14. package/dist/chunk-KASTJBBY.js.map +1 -0
  15. package/dist/{chunk-75G2FPYW.js → chunk-OULTQZT7.js} +4 -3
  16. package/dist/chunk-OULTQZT7.js.map +1 -0
  17. package/dist/{chunk-B5SN7AS7.js → chunk-TW7HANJM.js} +99 -49
  18. package/dist/chunk-TW7HANJM.js.map +1 -0
  19. package/dist/{chunk-2JHC7OOH.js → chunk-ZNBMADOM.js} +2 -2
  20. package/dist/chunk-ZNBMADOM.js.map +1 -0
  21. package/dist/index.cjs +102 -50
  22. package/dist/index.cjs.map +1 -1
  23. package/dist/index.d.cts +3 -3
  24. package/dist/index.d.ts +3 -3
  25. package/dist/index.js +4 -2
  26. package/dist/mobile.cjs +2 -2
  27. package/dist/mobile.cjs.map +1 -1
  28. package/dist/mobile.d.cts +2 -2
  29. package/dist/mobile.d.ts +2 -2
  30. package/dist/mobile.js +2 -2
  31. package/dist/mobile.js.map +1 -1
  32. package/dist/popup.cjs +3 -2
  33. package/dist/popup.cjs.map +1 -1
  34. package/dist/popup.d.cts +3 -3
  35. package/dist/popup.d.ts +3 -3
  36. package/dist/popup.js +1 -1
  37. package/dist/server.cjs +54 -66
  38. package/dist/server.cjs.map +1 -1
  39. package/dist/server.d.cts +14 -6
  40. package/dist/server.d.ts +14 -6
  41. package/dist/server.js +58 -69
  42. package/dist/server.js.map +1 -1
  43. package/dist/{types-_HRzmn-j.d.cts → types-BTTlCVrw.d.cts} +25 -2
  44. package/dist/{types-_HRzmn-j.d.ts → types-BTTlCVrw.d.ts} +25 -2
  45. package/dist/web.cjs +99 -48
  46. package/dist/web.cjs.map +1 -1
  47. package/dist/web.d.cts +14 -7
  48. package/dist/web.d.ts +14 -7
  49. package/dist/web.js +3 -1
  50. package/package.json +11 -6
  51. package/src/auth/add-device.ts +236 -0
  52. package/src/auth/execute-tx.ts +1 -1
  53. package/src/auth/index.ts +11 -0
  54. package/src/auth/use-passkey-auth.ts +4 -2
  55. package/src/capabilities.ts +2 -1
  56. package/src/index.ts +4 -0
  57. package/src/label.test.ts +21 -0
  58. package/src/label.ts +14 -0
  59. package/src/mobile/index.ts +1 -1
  60. package/src/mobile/passkey.ts +1 -1
  61. package/src/mobile/storage.ts +1 -1
  62. package/src/mobile/types.ts +2 -2
  63. package/src/popup-service.ts +2 -1
  64. package/src/register.ts +23 -8
  65. package/src/server/challenge.ts +15 -4
  66. package/src/server/create-wallet.test.ts +2 -2
  67. package/src/server/create-wallet.ts +24 -16
  68. package/src/server/handlers.ts +6 -2
  69. package/src/server/submit.test.ts +24 -6
  70. package/src/server/submit.ts +41 -10
  71. package/src/server/types.ts +5 -3
  72. package/src/server/utils.ts +1 -1
  73. package/src/sign.ts +127 -37
  74. package/src/types.ts +27 -2
  75. package/src/web.ts +6 -2
  76. package/tsconfig.json +3 -2
  77. package/tsup.config.ts +1 -0
  78. package/dist/chunk-2JHC7OOH.js.map +0 -1
  79. package/dist/chunk-75G2FPYW.js.map +0 -1
  80. package/dist/chunk-B5SN7AS7.js.map +0 -1
package/dist/web.cjs CHANGED
@@ -32,6 +32,7 @@ __export(web_exports, {
32
32
  bytesToBigIntBE: () => import_passkey_manager3.bytesToBigIntBE,
33
33
  bytesToHex: () => import_passkey_manager4.bytesToHex,
34
34
  compareBytes: () => import_passkey_manager4.compareBytes,
35
+ createDistinctPasskeyLabel: () => createDistinctPasskeyLabel,
35
36
  getCachedPasskeyClientCapabilities: () => getCachedPasskeyClientCapabilities,
36
37
  getPasskeyClientCapabilities: () => getPasskeyClientCapabilities,
37
38
  hexToBytes: () => import_passkey_manager4.hexToBytes,
@@ -51,10 +52,11 @@ __export(web_exports, {
51
52
  module.exports = __toCommonJS(web_exports);
52
53
 
53
54
  // src/register.ts
54
- var import_passkey_manager = require("@thru/passkey-manager");
55
+ var import_passkey_manager = require("@thru/programs/passkey-manager");
55
56
 
56
57
  // src/capabilities.ts
57
- var DEBUG = typeof process !== "undefined" && process.env?.NEXT_PUBLIC_PASSKEY_DEBUG === "1";
58
+ var globalProcess = globalThis.process;
59
+ var DEBUG = globalProcess?.env?.NEXT_PUBLIC_PASSKEY_DEBUG === "1";
58
60
  var cachedClientCapabilities;
59
61
  var clientCapabilitiesPromise = null;
60
62
  function isWebAuthnSupported() {
@@ -381,19 +383,21 @@ async function requestPasskeyPopup(action, payload, preopenedPopup) {
381
383
  }
382
384
 
383
385
  // src/register.ts
384
- async function registerPasskey(alias, userId, rpId) {
386
+ async function registerPasskey(alias, userId, rpId, options = {}) {
385
387
  if (!isWebAuthnSupported()) {
386
388
  throw new Error("WebAuthn is not supported in this browser");
387
389
  }
388
390
  return runWithPromptMode(
389
391
  "create",
390
392
  () => registerPasskeyInline(alias, userId, rpId),
391
- (preopenedPopup) => registerPasskeyViaPopup(alias, userId, rpId, preopenedPopup)
393
+ (preopenedPopup) => registerPasskeyViaPopup(alias, userId, rpId, preopenedPopup),
394
+ options
392
395
  );
393
396
  }
394
- async function runWithPromptMode(action, inlineFn, popupFn) {
395
- const preopenedPopup = maybePreopenPopup(action, openPasskeyPopupWindow);
396
- const promptMode = await getPasskeyPromptMode(action);
397
+ async function runWithPromptMode(action, inlineFn, popupFn, options = {}) {
398
+ const allowPopupFallback = options.allowPopupFallback ?? true;
399
+ const preopenedPopup = allowPopupFallback ? maybePreopenPopup(action, openPasskeyPopupWindow) : null;
400
+ const promptMode = allowPopupFallback ? await getPasskeyPromptMode(action) : "inline";
397
401
  if (promptMode === "popup") {
398
402
  return popupFn(preopenedPopup);
399
403
  }
@@ -401,7 +405,7 @@ async function runWithPromptMode(action, inlineFn, popupFn) {
401
405
  try {
402
406
  return await inlineFn();
403
407
  } catch (error) {
404
- if (shouldFallbackToPopup(error)) {
408
+ if (allowPopupFallback && shouldFallbackToPopup(error)) {
405
409
  return popupFn();
406
410
  }
407
411
  throw error;
@@ -443,11 +447,13 @@ async function registerPasskeyInline(alias, userId, rpId) {
443
447
  }
444
448
  const response = credential.response;
445
449
  const { x, y } = extractP256PublicKey(response);
450
+ const authenticatorAttachment = credential.authenticatorAttachment ?? null;
446
451
  return {
447
452
  credentialId: (0, import_passkey_manager.arrayBufferToBase64Url)(credential.rawId),
448
453
  publicKeyX: (0, import_passkey_manager.bytesToHex)(x),
449
454
  publicKeyY: (0, import_passkey_manager.bytesToHex)(y),
450
- rpId
455
+ rpId,
456
+ authenticatorAttachment
451
457
  };
452
458
  }
453
459
  async function registerPasskeyViaPopup(alias, userId, rpId, preopenedPopup) {
@@ -541,8 +547,14 @@ function extractFromCoseKey(coseKey) {
541
547
  return { x, y };
542
548
  }
543
549
 
550
+ // src/label.ts
551
+ var DEFAULT_LABEL = "Thru Wallet passkey";
552
+ function createDistinctPasskeyLabel(baseLabel, _options = {}) {
553
+ return baseLabel.trim() || DEFAULT_LABEL;
554
+ }
555
+
544
556
  // src/sign.ts
545
- var import_passkey_manager2 = require("@thru/passkey-manager");
557
+ var import_passkey_manager2 = require("@thru/programs/passkey-manager");
546
558
  async function signWithPasskey(credentialId, challenge, rpId) {
547
559
  if (!isWebAuthnSupported()) {
548
560
  throw new Error("WebAuthn is not supported in this browser");
@@ -553,49 +565,51 @@ async function signWithPasskey(credentialId, challenge, rpId) {
553
565
  (preopenedPopup) => signWithPasskeyViaPopup(credentialId, challenge, rpId, preopenedPopup)
554
566
  );
555
567
  }
556
- async function signWithStoredPasskey(challenge, rpId, preferredPasskey, allPasskeys, context) {
568
+ async function signWithStoredPasskey(challenge, rpId, preferredPasskey, allPasskeys, context, options = {}) {
557
569
  if (!isWebAuthnSupported()) {
558
570
  throw new Error("WebAuthn is not supported in this browser");
559
571
  }
560
- const preopenedPopup = maybePreopenPopup("get", openPasskeyPopupWindow);
561
- const promptMode = await getPasskeyPromptMode("get");
572
+ const allowPopupFallback = options.allowPopupFallback ?? true;
573
+ const preopenedPopup = allowPopupFallback ? maybePreopenPopup("get", openPasskeyPopupWindow) : null;
574
+ const promptMode = allowPopupFallback ? await getPasskeyPromptMode("get") : "inline";
562
575
  const storedPasskey = preferredPasskey;
563
- const canUsePopup = isInIframe();
576
+ const canUsePopup = allowPopupFallback && isInIframe();
577
+ if (options.preferDiscoverable) {
578
+ closePopup(preopenedPopup);
579
+ return signWithDiscoverableStoredPasskey(
580
+ challenge,
581
+ storedPasskey?.rpId ?? rpId,
582
+ allPasskeys
583
+ );
584
+ }
564
585
  if (promptMode === "popup" || canUsePopup && !storedPasskey) {
565
586
  return requestStoredPasskeyPopup(challenge, preopenedPopup, context);
566
587
  }
567
588
  closePopup(preopenedPopup);
568
589
  try {
569
590
  if (storedPasskey) {
570
- const result = await signWithPasskeyInline(
571
- storedPasskey.credentialId,
572
- challenge,
573
- storedPasskey.rpId
574
- );
575
- return {
576
- ...result,
577
- passkey: storedPasskey
578
- };
591
+ try {
592
+ const result = await signWithPasskeyInline(
593
+ storedPasskey.credentialId,
594
+ challenge,
595
+ storedPasskey.rpId
596
+ );
597
+ return {
598
+ ...result,
599
+ passkey: storedPasskey
600
+ };
601
+ } catch (error) {
602
+ if (!shouldFallbackToDiscoverable(error)) {
603
+ throw error;
604
+ }
605
+ return signWithDiscoverableStoredPasskey(
606
+ challenge,
607
+ storedPasskey.rpId,
608
+ allPasskeys
609
+ );
610
+ }
579
611
  }
580
- const discoverable = await signWithDiscoverablePasskey(challenge, rpId);
581
- const matchingPasskey = allPasskeys.find((p) => p.credentialId === discoverable.credentialId) ?? null;
582
- const now = (/* @__PURE__ */ new Date()).toISOString();
583
- const passkey = matchingPasskey ?? {
584
- credentialId: discoverable.credentialId,
585
- publicKeyX: "",
586
- publicKeyY: "",
587
- rpId: discoverable.rpId,
588
- createdAt: now,
589
- lastUsedAt: now
590
- };
591
- return {
592
- signature: discoverable.signature,
593
- authenticatorData: discoverable.authenticatorData,
594
- clientDataJSON: discoverable.clientDataJSON,
595
- signatureR: discoverable.signatureR,
596
- signatureS: discoverable.signatureS,
597
- passkey
598
- };
612
+ return signWithDiscoverableStoredPasskey(challenge, rpId, allPasskeys);
599
613
  } catch (error) {
600
614
  if (canUsePopup && shouldFallbackToPopup(error)) {
601
615
  return requestStoredPasskeyPopup(challenge, void 0, context);
@@ -603,6 +617,37 @@ async function signWithStoredPasskey(challenge, rpId, preferredPasskey, allPassk
603
617
  throw error;
604
618
  }
605
619
  }
620
+ async function signWithDiscoverableStoredPasskey(challenge, rpId, allPasskeys) {
621
+ const discoverable = await signWithDiscoverablePasskey(challenge, rpId);
622
+ const matchingPasskey = allPasskeys.find((p) => p.credentialId === discoverable.credentialId) ?? null;
623
+ const now = (/* @__PURE__ */ new Date()).toISOString();
624
+ const passkey = matchingPasskey ?? {
625
+ credentialId: discoverable.credentialId,
626
+ publicKeyX: "",
627
+ publicKeyY: "",
628
+ rpId: discoverable.rpId,
629
+ createdAt: now,
630
+ lastUsedAt: now
631
+ };
632
+ return {
633
+ signature: discoverable.signature,
634
+ authenticatorData: discoverable.authenticatorData,
635
+ clientDataJSON: discoverable.clientDataJSON,
636
+ signatureR: discoverable.signatureR,
637
+ signatureS: discoverable.signatureS,
638
+ authenticatorAttachment: discoverable.authenticatorAttachment,
639
+ passkey
640
+ };
641
+ }
642
+ function shouldFallbackToDiscoverable(error) {
643
+ const name = error && typeof error === "object" && "name" in error ? String(error.name) : "";
644
+ const message = error && typeof error === "object" && "message" in error ? String(error.message) : "";
645
+ const normalized = `${name} ${message}`.toLowerCase();
646
+ if (normalized.includes("user rejected") || normalized.includes("user canceled") || normalized.includes("user cancelled")) {
647
+ return false;
648
+ }
649
+ return normalized.includes("notallowederror") || normalized.includes("invalidstateerror") || normalized.includes("notfounderror") || normalized.includes("not found") || normalized.includes("no passkey") || normalized.includes("no credential") || normalized.includes("saved for this app");
650
+ }
606
651
  async function signWithDiscoverablePasskey(challenge, rpId) {
607
652
  if (!isWebAuthnSupported()) {
608
653
  throw new Error("WebAuthn is not supported in this browser");
@@ -616,7 +661,8 @@ async function signWithDiscoverablePasskey(challenge, rpId) {
616
661
  signatureR: result.signatureR,
617
662
  signatureS: result.signatureS,
618
663
  credentialId: result.credentialId,
619
- rpId: resolvedRpId
664
+ rpId: resolvedRpId,
665
+ authenticatorAttachment: result.authenticatorAttachment
620
666
  };
621
667
  }
622
668
  async function runWithPromptMode2(action, inlineFn, popupFn) {
@@ -642,7 +688,8 @@ async function signWithPasskeyInline(credentialId, challenge, rpId) {
642
688
  authenticatorData: result.authenticatorData,
643
689
  clientDataJSON: result.clientDataJSON,
644
690
  signatureR: result.signatureR,
645
- signatureS: result.signatureS
691
+ signatureS: result.signatureS,
692
+ authenticatorAttachment: result.authenticatorAttachment
646
693
  };
647
694
  }
648
695
  async function signWithPasskeyAssertion(challenge, rpId, credentialId) {
@@ -673,13 +720,15 @@ async function signWithPasskeyAssertion(challenge, rpId, credentialId) {
673
720
  const signature = new Uint8Array(response.signature);
674
721
  let { r, s } = (0, import_passkey_manager2.parseDerSignature)(signature);
675
722
  s = (0, import_passkey_manager2.normalizeLowS)(s);
723
+ const rawAttachment = assertion.authenticatorAttachment ?? null;
676
724
  return {
677
725
  signature: new Uint8Array([...r, ...s]),
678
726
  authenticatorData: new Uint8Array(response.authenticatorData),
679
727
  clientDataJSON: new Uint8Array(response.clientDataJSON),
680
728
  signatureR: r,
681
729
  signatureS: s,
682
- credentialId: (0, import_passkey_manager2.arrayBufferToBase64Url)(assertion.rawId)
730
+ credentialId: (0, import_passkey_manager2.arrayBufferToBase64Url)(assertion.rawId),
731
+ authenticatorAttachment: rawAttachment
683
732
  };
684
733
  }
685
734
  async function signWithPasskeyViaPopup(credentialId, challenge, rpId, preopenedPopup) {
@@ -711,7 +760,8 @@ function decodePopupSigningResult(result) {
711
760
  authenticatorData: (0, import_passkey_manager2.base64UrlToBytes)(result.authenticatorDataBase64Url),
712
761
  clientDataJSON: (0, import_passkey_manager2.base64UrlToBytes)(result.clientDataJSONBase64Url),
713
762
  signatureR: (0, import_passkey_manager2.base64UrlToBytes)(result.signatureRBase64Url),
714
- signatureS: (0, import_passkey_manager2.base64UrlToBytes)(result.signatureSBase64Url)
763
+ signatureS: (0, import_passkey_manager2.base64UrlToBytes)(result.signatureSBase64Url),
764
+ authenticatorAttachment: result.authenticatorAttachment ?? null
715
765
  };
716
766
  }
717
767
  function decodePopupStoredSigningResult(result) {
@@ -723,8 +773,8 @@ function decodePopupStoredSigningResult(result) {
723
773
  }
724
774
 
725
775
  // src/web.ts
726
- var import_passkey_manager3 = require("@thru/passkey-manager");
727
- var import_passkey_manager4 = require("@thru/passkey-manager");
776
+ var import_passkey_manager3 = require("@thru/programs/passkey-manager");
777
+ var import_passkey_manager4 = require("@thru/programs/passkey-manager");
728
778
  // Annotate the CommonJS export names for ESM import in node:
729
779
  0 && (module.exports = {
730
780
  P256_HALF_N,
@@ -739,6 +789,7 @@ var import_passkey_manager4 = require("@thru/passkey-manager");
739
789
  bytesToBigIntBE,
740
790
  bytesToHex,
741
791
  compareBytes,
792
+ createDistinctPasskeyLabel,
742
793
  getCachedPasskeyClientCapabilities,
743
794
  getPasskeyClientCapabilities,
744
795
  hexToBytes,
package/dist/web.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/web.ts","../src/register.ts","../src/capabilities.ts","../src/popup.ts","../src/sign.ts"],"sourcesContent":["export type {\n PasskeyRegistrationResult,\n PasskeySigningResult,\n PasskeyDiscoverableSigningResult,\n PasskeyStoredSigningResult,\n PasskeyMetadata,\n PasskeyClientCapabilities,\n PasskeyPopupContext,\n PasskeyPopupAccount,\n} from './types';\n\nexport { registerPasskey } from './register';\n\nexport {\n signWithPasskey,\n signWithStoredPasskey,\n signWithDiscoverablePasskey,\n} from './sign';\n\nexport {\n parseDerSignature,\n normalizeLowS,\n normalizeSignatureComponent,\n P256_N,\n P256_HALF_N,\n bytesToBigIntBE,\n bigIntToBytesBE,\n} from '@thru/passkey-manager';\n\nexport {\n isWebAuthnSupported,\n preloadPasskeyClientCapabilities,\n getPasskeyClientCapabilities,\n getCachedPasskeyClientCapabilities,\n shouldUsePasskeyPopup,\n isInIframe,\n type PasskeyPromptAction,\n} from './capabilities';\n\nexport {\n arrayBufferToBase64Url,\n base64UrlToArrayBuffer,\n bytesToBase64,\n bytesToBase64Url,\n base64UrlToBytes,\n bytesToHex,\n hexToBytes,\n bytesEqual,\n compareBytes,\n uniqueAccounts,\n} from '@thru/passkey-manager';\n","import type { PasskeyRegistrationResult, PasskeyPopupRegistrationResult } from './types';\nimport { arrayBufferToBase64Url, bytesToHex } from '@thru/passkey-manager';\nimport {\n isWebAuthnSupported,\n getPasskeyPromptMode,\n maybePreopenPopup,\n shouldFallbackToPopup,\n type PasskeyPromptAction,\n} from './capabilities';\nimport { requestPasskeyPopup, openPasskeyPopupWindow, closePopup } from './popup';\n\n/**\n * Register a new passkey for a profile.\n */\nexport async function registerPasskey(\n alias: string,\n userId: string,\n rpId: string\n): Promise<PasskeyRegistrationResult> {\n if (!isWebAuthnSupported()) {\n throw new Error('WebAuthn is not supported in this browser');\n }\n\n return runWithPromptMode(\n 'create',\n () => registerPasskeyInline(alias, userId, rpId),\n (preopenedPopup) => registerPasskeyViaPopup(alias, userId, rpId, preopenedPopup)\n );\n}\n\nasync function runWithPromptMode<T>(\n action: PasskeyPromptAction,\n inlineFn: () => Promise<T>,\n popupFn: (preopenedPopup?: Window | null) => Promise<T>\n): Promise<T> {\n const preopenedPopup = maybePreopenPopup(action, openPasskeyPopupWindow);\n const promptMode = await getPasskeyPromptMode(action);\n if (promptMode === 'popup') {\n return popupFn(preopenedPopup);\n }\n\n closePopup(preopenedPopup);\n\n try {\n return await inlineFn();\n } catch (error) {\n if (shouldFallbackToPopup(error)) {\n return popupFn();\n }\n throw error;\n }\n}\n\nasync function registerPasskeyInline(\n alias: string,\n userId: string,\n rpId: string\n): Promise<PasskeyRegistrationResult> {\n const rpName = 'Thru Wallet';\n\n const userIdBytes = new TextEncoder().encode(userId);\n const userIdBuffer = userIdBytes.slice(0, 64);\n\n const challenge = crypto.getRandomValues(new Uint8Array(32));\n\n const createOptions: PublicKeyCredentialCreationOptions = {\n challenge,\n rp: {\n id: rpId,\n name: rpName,\n },\n user: {\n id: userIdBuffer,\n name: alias,\n displayName: alias,\n },\n pubKeyCredParams: [\n { type: 'public-key', alg: -7 },\n ],\n authenticatorSelection: {\n authenticatorAttachment: 'platform',\n userVerification: 'required',\n residentKey: 'required',\n requireResidentKey: true,\n },\n attestation: 'none',\n timeout: 60000,\n };\n\n const credential = (await navigator.credentials.create({\n publicKey: createOptions,\n })) as PublicKeyCredential | null;\n\n if (!credential) {\n throw new Error('Passkey registration was cancelled');\n }\n\n const response = credential.response as AuthenticatorAttestationResponse;\n const { x, y } = extractP256PublicKey(response);\n\n return {\n credentialId: arrayBufferToBase64Url(credential.rawId),\n publicKeyX: bytesToHex(x),\n publicKeyY: bytesToHex(y),\n rpId,\n };\n}\n\nasync function registerPasskeyViaPopup(\n alias: string,\n userId: string,\n rpId: string,\n preopenedPopup?: Window | null\n): Promise<PasskeyRegistrationResult> {\n const result = await requestPasskeyPopup<PasskeyPopupRegistrationResult>(\n 'create',\n { alias, userId, rpId },\n preopenedPopup\n );\n return result;\n}\n\n// Key extraction helpers\n\nfunction extractP256PublicKey(\n response: AuthenticatorAttestationResponse\n): { x: Uint8Array; y: Uint8Array } {\n if (typeof response.getPublicKey === 'function') {\n const spkiKey = response.getPublicKey();\n if (spkiKey) {\n return extractFromSpki(new Uint8Array(spkiKey));\n }\n }\n\n if (typeof response.getAuthenticatorData === 'function') {\n const authData = new Uint8Array(response.getAuthenticatorData());\n return extractFromAuthenticatorData(authData);\n }\n\n throw new Error('Unable to extract public key: browser does not support required WebAuthn methods');\n}\n\nfunction extractFromSpki(spki: Uint8Array): { x: Uint8Array; y: Uint8Array } {\n const pointStart = spki.length - 65;\n\n if (spki[pointStart] !== 0x04) {\n throw new Error('Invalid SPKI format: expected uncompressed point');\n }\n\n const x = spki.slice(pointStart + 1, pointStart + 33);\n const y = spki.slice(pointStart + 33, pointStart + 65);\n\n if (x.length !== 32 || y.length !== 32) {\n throw new Error('Invalid SPKI format: incorrect coordinate length');\n }\n\n return { x, y };\n}\n\nfunction extractFromAuthenticatorData(authData: Uint8Array): { x: Uint8Array; y: Uint8Array } {\n const rpIdHashLength = 32;\n const flagsLength = 1;\n const counterLength = 4;\n const offset = rpIdHashLength + flagsLength + counterLength;\n const aaguidLength = 16;\n const credIdLenOffset = offset + aaguidLength;\n const credIdLength = (authData[credIdLenOffset] << 8) | authData[credIdLenOffset + 1];\n const coseKeyOffset = credIdLenOffset + 2 + credIdLength;\n const coseKey = authData.slice(coseKeyOffset);\n\n return extractFromCoseKey(coseKey);\n}\n\nfunction extractFromCoseKey(coseKey: Uint8Array): { x: Uint8Array; y: Uint8Array } {\n const mapStart = coseKey[0];\n if (mapStart !== 0xa5 && mapStart !== 0xa4) {\n throw new Error('Invalid COSE key format');\n }\n\n let offset = 1;\n let x: Uint8Array | null = null;\n let y: Uint8Array | null = null;\n\n while (offset < coseKey.length) {\n const key = coseKey[offset++];\n const valueType = coseKey[offset++];\n\n if (key === 0x21) {\n const length = valueType & 0x1f;\n x = coseKey.slice(offset, offset + length);\n offset += length;\n continue;\n }\n\n if (key === 0x22) {\n const length = valueType & 0x1f;\n y = coseKey.slice(offset, offset + length);\n offset += length;\n continue;\n }\n\n if (valueType >= 0x40 && valueType <= 0x5f) {\n const length = valueType & 0x1f;\n offset += length;\n continue;\n }\n\n if (valueType === 0x01 || valueType === 0x02 || valueType === 0x03) {\n continue;\n }\n\n if (valueType >= 0x18 && valueType <= 0x1b) {\n const size = 1 << (valueType - 0x18);\n offset += size;\n continue;\n }\n }\n\n if (!x || !y) {\n throw new Error('Failed to extract P-256 public key from COSE data');\n }\n\n if (x.length !== 32 || y.length !== 32) {\n throw new Error('Invalid COSE key: incorrect coordinate length');\n }\n\n return { x, y };\n}\n","import type { PasskeyClientCapabilities } from './types';\n\nconst DEBUG = typeof process !== 'undefined' && process.env?.NEXT_PUBLIC_PASSKEY_DEBUG === '1';\n\nlet cachedClientCapabilities: PasskeyClientCapabilities | null | undefined;\nlet clientCapabilitiesPromise: Promise<PasskeyClientCapabilities | null> | null = null;\n\nexport function isWebAuthnSupported(): boolean {\n const supported =\n typeof window !== 'undefined' &&\n typeof window.PublicKeyCredential !== 'undefined' &&\n typeof navigator.credentials !== 'undefined';\n\n if (DEBUG) {\n console.log('[Passkey] WebAuthn support check:', {\n window: typeof window !== 'undefined',\n PublicKeyCredential:\n typeof window !== 'undefined' && typeof window.PublicKeyCredential !== 'undefined',\n credentials:\n typeof window !== 'undefined' &&\n typeof navigator !== 'undefined' &&\n typeof navigator.credentials !== 'undefined',\n supported,\n });\n }\n\n return supported;\n}\n\nasync function fetchPasskeyClientCapabilities(): Promise<PasskeyClientCapabilities | null> {\n if (typeof window === 'undefined' || typeof window.PublicKeyCredential === 'undefined') {\n return null;\n }\n\n const getClientCapabilities = (window.PublicKeyCredential as {\n getClientCapabilities?: () => Promise<PasskeyClientCapabilities>;\n }).getClientCapabilities;\n\n if (typeof getClientCapabilities !== 'function') {\n return null;\n }\n\n try {\n const capabilities = await getClientCapabilities.call(window.PublicKeyCredential);\n if (DEBUG) {\n console.log('[Passkey] WebAuthn client capabilities:', capabilities);\n }\n return capabilities ?? null;\n } catch (error) {\n if (DEBUG) {\n console.warn('[Passkey] Failed to read client capabilities:', error);\n }\n return null;\n }\n}\n\nexport function preloadPasskeyClientCapabilities(): void {\n if (cachedClientCapabilities !== undefined || clientCapabilitiesPromise) {\n return;\n }\n\n clientCapabilitiesPromise = fetchPasskeyClientCapabilities().then((capabilities) => {\n cachedClientCapabilities = capabilities;\n return capabilities;\n });\n}\n\nexport async function getPasskeyClientCapabilities(): Promise<PasskeyClientCapabilities | null> {\n if (cachedClientCapabilities !== undefined) {\n return cachedClientCapabilities;\n }\n\n if (!clientCapabilitiesPromise) {\n preloadPasskeyClientCapabilities();\n }\n\n if (!clientCapabilitiesPromise) {\n cachedClientCapabilities = null;\n return null;\n }\n\n const capabilities = await clientCapabilitiesPromise;\n cachedClientCapabilities = capabilities;\n return capabilities;\n}\n\nexport function getCachedPasskeyClientCapabilities(): PasskeyClientCapabilities | null | undefined {\n return cachedClientCapabilities;\n}\n\nexport function isInIframe(): boolean {\n if (typeof window === 'undefined') {\n return false;\n }\n try {\n return window.self !== window.top;\n } catch {\n return true;\n }\n}\n\nexport type PasskeyPromptAction = 'get' | 'create';\n\nexport async function shouldUsePasskeyPopup(action: PasskeyPromptAction): Promise<boolean> {\n if (!isInIframe()) {\n return false;\n }\n const mode = await getPasskeyPromptMode(action);\n return mode === 'popup';\n}\n\ntype PasskeyPromptMode = 'inline' | 'popup';\n\nfunction getPermissionsPolicyAllowsFeature(feature: string): boolean | null {\n if (typeof document === 'undefined') {\n return null;\n }\n\n const policy = (document as { permissionsPolicy?: { allowsFeature?: (name: string) => boolean } })\n .permissionsPolicy;\n const featurePolicy = (document as { featurePolicy?: { allowsFeature?: (name: string) => boolean } })\n .featurePolicy;\n const allowsFeature = policy?.allowsFeature || featurePolicy?.allowsFeature;\n\n if (typeof allowsFeature !== 'function') {\n return null;\n }\n\n try {\n return allowsFeature(feature);\n } catch {\n return null;\n }\n}\n\nfunction getCachedPromptMode(action: PasskeyPromptAction): PasskeyPromptMode | 'unknown' {\n if (!isInIframe()) {\n return 'inline';\n }\n\n if (cachedClientCapabilities === undefined && !clientCapabilitiesPromise) {\n preloadPasskeyClientCapabilities();\n }\n\n const feature =\n action === 'create' ? 'publickey-credentials-create' : 'publickey-credentials-get';\n const policyAllows = getPermissionsPolicyAllowsFeature(feature);\n const capabilities = getCachedPasskeyClientCapabilities();\n const supportsInline =\n capabilities?.passkeyPlatformAuthenticator === true ||\n capabilities?.userVerifyingPlatformAuthenticator === true;\n\n if (policyAllows === false) {\n return 'popup';\n }\n\n if (capabilities === undefined) {\n return 'unknown';\n }\n\n if (!supportsInline) {\n return 'popup';\n }\n\n return 'inline';\n}\n\nexport async function getPasskeyPromptMode(action: PasskeyPromptAction): Promise<PasskeyPromptMode> {\n if (!isInIframe()) {\n return 'inline';\n }\n\n const feature =\n action === 'create' ? 'publickey-credentials-create' : 'publickey-credentials-get';\n const policyAllows = getPermissionsPolicyAllowsFeature(feature);\n const capabilities = await getPasskeyClientCapabilities();\n const supportsInline =\n capabilities?.passkeyPlatformAuthenticator === true ||\n capabilities?.userVerifyingPlatformAuthenticator === true;\n\n if (DEBUG) {\n console.log('[Passkey] Prompt mode check:', {\n action,\n policyAllows,\n supportsInline,\n capabilities,\n });\n }\n\n if (!supportsInline) {\n return 'popup';\n }\n\n if (policyAllows === false) {\n return 'popup';\n }\n\n return 'inline';\n}\n\nexport function maybePreopenPopup(action: PasskeyPromptAction, openPopupFn: () => Window): Window | null {\n const cachedMode = getCachedPromptMode(action);\n if (cachedMode !== 'popup') {\n return null;\n }\n\n try {\n return openPopupFn();\n } catch {\n return null;\n }\n}\n\nexport function shouldFallbackToPopup(error: unknown): boolean {\n if (!isInIframe()) {\n return false;\n }\n\n const name =\n error && typeof error === 'object' && 'name' in error ? String((error as { name?: unknown }).name) : '';\n const message =\n error && typeof error === 'object' && 'message' in error\n ? String((error as { message?: unknown }).message)\n : '';\n const normalized = `${name} ${message}`.toLowerCase();\n\n if (\n normalized.includes('cancel') ||\n normalized.includes('canceled') ||\n normalized.includes('cancelled') ||\n normalized.includes('user canceled') ||\n normalized.includes('user cancelled') ||\n normalized.includes('aborted')\n ) {\n return false;\n }\n\n if (normalized.includes('securityerror')) {\n return true;\n }\n\n if (normalized.includes('notallowederror')) {\n if (\n normalized.includes('permission') ||\n normalized.includes('policy') ||\n normalized.includes('iframe') ||\n normalized.includes('frame')\n ) {\n return true;\n }\n }\n\n return false;\n}\n","import type {\n PasskeyPopupAction,\n PasskeyPopupRequestPayload,\n PasskeyPopupRequest,\n PasskeyPopupResponse,\n} from './types';\n\nexport const PASSKEY_POPUP_PATH = '/passkey/popup';\nexport const PASSKEY_POPUP_READY_EVENT = 'thru:passkey-popup-ready';\nexport const PASSKEY_POPUP_REQUEST_EVENT = 'thru:passkey-popup-request';\nexport const PASSKEY_POPUP_RESPONSE_EVENT = 'thru:passkey-popup-response';\nexport const PASSKEY_POPUP_CHANNEL = 'thru:passkey-popup-channel';\n\nconst PASSKEY_POPUP_TIMEOUT_MS = 60000;\n\nexport function closePopup(popup: Window | null | undefined): void {\n if (popup && !popup.closed) {\n popup.close();\n }\n}\n\nexport function openPasskeyPopupWindow(): Window {\n const popupUrl = new URL(PASSKEY_POPUP_PATH, window.location.origin).toString();\n const popup = window.open(\n popupUrl,\n 'thru_passkey_popup',\n 'popup=yes,width=440,height=640'\n );\n\n if (!popup) {\n throw new Error('Passkey popup was blocked');\n }\n\n return popup;\n}\n\nfunction createPopupRequestId(): string {\n const rand = Math.random().toString(36).slice(2, 10);\n return `passkey_${Date.now()}_${rand}`;\n}\n\nexport async function requestPasskeyPopup<T>(\n action: PasskeyPopupAction,\n payload: PasskeyPopupRequestPayload,\n preopenedPopup?: Window | null\n): Promise<T> {\n if (typeof window === 'undefined') {\n throw new Error('Passkey popup is only available in the browser');\n }\n\n const requestId = createPopupRequestId();\n const targetOrigin = window.location.origin;\n let popup: Window | null = preopenedPopup ?? null;\n const channel =\n typeof BroadcastChannel !== 'undefined' ? new BroadcastChannel(PASSKEY_POPUP_CHANNEL) : null;\n\n return new Promise<T>((resolve, reject) => {\n let timeout: ReturnType<typeof setTimeout> | null = null;\n let closePoll: ReturnType<typeof setInterval> | null = null;\n let requestSent = false;\n\n const cleanup = () => {\n if (timeout) {\n clearTimeout(timeout);\n timeout = null;\n }\n if (closePoll) {\n clearInterval(closePoll);\n closePoll = null;\n }\n window.removeEventListener('message', handleMessage);\n if (channel) {\n channel.removeEventListener('message', handleChannelMessage);\n channel.close();\n }\n };\n\n const sendRequest = (viaChannel: boolean) => {\n if (requestSent) {\n return;\n }\n requestSent = true;\n\n const request: PasskeyPopupRequest = {\n type: PASSKEY_POPUP_REQUEST_EVENT,\n requestId,\n action,\n payload,\n };\n\n if (viaChannel) {\n channel?.postMessage(request);\n return;\n }\n\n popup?.postMessage(request, targetOrigin);\n };\n\n const handleResponse = (data: PasskeyPopupResponse) => {\n if (data.requestId !== requestId) {\n return;\n }\n\n cleanup();\n if (popup && !popup.closed) {\n popup.close();\n }\n\n if (data.success) {\n resolve((data as Extract<PasskeyPopupResponse, { success: true }>).result as T);\n } else {\n const err = new Error(data.error?.message || 'Passkey popup failed');\n if (data.error?.name) {\n (err as { name?: string }).name = data.error.name;\n }\n reject(err);\n }\n };\n\n const handleMessage = (event: MessageEvent) => {\n if (event.origin !== targetOrigin) {\n return;\n }\n\n const data = event.data as PasskeyPopupResponse | { type?: string };\n if (!data || typeof data !== 'object') {\n return;\n }\n\n if (data.type === PASSKEY_POPUP_READY_EVENT) {\n if (popup && event.source !== popup) {\n return;\n }\n sendRequest(false);\n return;\n }\n\n if (data.type === PASSKEY_POPUP_RESPONSE_EVENT && 'requestId' in data) {\n handleResponse(data as PasskeyPopupResponse);\n }\n };\n\n window.addEventListener('message', handleMessage);\n\n const handleChannelMessage = (event: MessageEvent) => {\n const data = event.data as PasskeyPopupResponse | { type?: string };\n if (!data || typeof data !== 'object') {\n return;\n }\n\n if (data.type === PASSKEY_POPUP_READY_EVENT) {\n sendRequest(true);\n return;\n }\n\n if (data.type === PASSKEY_POPUP_RESPONSE_EVENT && 'requestId' in data) {\n handleResponse(data as PasskeyPopupResponse);\n }\n };\n\n if (channel) {\n channel.addEventListener('message', handleChannelMessage);\n }\n\n if (!popup) {\n try {\n popup = openPasskeyPopupWindow();\n } catch (error) {\n cleanup();\n reject(error);\n return;\n }\n }\n\n timeout = setTimeout(() => {\n cleanup();\n try {\n popup?.close();\n } catch {\n /* ignore */\n }\n reject(new Error('Passkey popup timed out'));\n }, PASSKEY_POPUP_TIMEOUT_MS);\n\n closePoll = setInterval(() => {\n if (popup && popup.closed) {\n cleanup();\n reject(new Error('Passkey popup was closed'));\n }\n }, 250);\n });\n}\n","import type {\n PasskeySigningResult,\n PasskeyStoredSigningResult,\n PasskeyDiscoverableSigningResult,\n PasskeyMetadata,\n PasskeyPopupContext,\n PasskeyPopupSigningResult,\n PasskeyPopupStoredSigningResult,\n} from './types';\nimport {\n arrayBufferToBase64Url,\n base64UrlToArrayBuffer,\n bytesToBase64Url,\n base64UrlToBytes,\n parseDerSignature,\n normalizeLowS,\n} from '@thru/passkey-manager';\nimport {\n isWebAuthnSupported,\n getPasskeyPromptMode,\n isInIframe,\n maybePreopenPopup,\n shouldFallbackToPopup,\n type PasskeyPromptAction,\n} from './capabilities';\nimport { requestPasskeyPopup, openPasskeyPopupWindow, closePopup } from './popup';\n\n/**\n * Sign a challenge with an existing passkey (by credential ID).\n */\nexport async function signWithPasskey(\n credentialId: string,\n challenge: Uint8Array,\n rpId: string\n): Promise<PasskeySigningResult> {\n if (!isWebAuthnSupported()) {\n throw new Error('WebAuthn is not supported in this browser');\n }\n\n return runWithPromptMode(\n 'get',\n () => signWithPasskeyInline(credentialId, challenge, rpId),\n (preopenedPopup) => signWithPasskeyViaPopup(credentialId, challenge, rpId, preopenedPopup)\n );\n}\n\n/**\n * Sign with stored passkey (for embedded/popup contexts).\n */\nexport async function signWithStoredPasskey(\n challenge: Uint8Array,\n rpId: string,\n preferredPasskey: PasskeyMetadata | null,\n allPasskeys: PasskeyMetadata[],\n context?: PasskeyPopupContext\n): Promise<PasskeyStoredSigningResult> {\n if (!isWebAuthnSupported()) {\n throw new Error('WebAuthn is not supported in this browser');\n }\n\n const preopenedPopup = maybePreopenPopup('get', openPasskeyPopupWindow);\n const promptMode = await getPasskeyPromptMode('get');\n const storedPasskey = preferredPasskey;\n const canUsePopup = isInIframe();\n\n if (promptMode === 'popup' || (canUsePopup && !storedPasskey)) {\n return requestStoredPasskeyPopup(challenge, preopenedPopup, context);\n }\n\n closePopup(preopenedPopup);\n\n try {\n if (storedPasskey) {\n const result = await signWithPasskeyInline(\n storedPasskey.credentialId,\n challenge,\n storedPasskey.rpId\n );\n return {\n ...result,\n passkey: storedPasskey,\n };\n }\n\n const discoverable = await signWithDiscoverablePasskey(challenge, rpId);\n const matchingPasskey = allPasskeys.find(p => p.credentialId === discoverable.credentialId) ?? null;\n const now = new Date().toISOString();\n const passkey = matchingPasskey ?? {\n credentialId: discoverable.credentialId,\n publicKeyX: '',\n publicKeyY: '',\n rpId: discoverable.rpId,\n createdAt: now,\n lastUsedAt: now,\n };\n\n return {\n signature: discoverable.signature,\n authenticatorData: discoverable.authenticatorData,\n clientDataJSON: discoverable.clientDataJSON,\n signatureR: discoverable.signatureR,\n signatureS: discoverable.signatureS,\n passkey,\n };\n } catch (error) {\n if (canUsePopup && shouldFallbackToPopup(error)) {\n return requestStoredPasskeyPopup(challenge, undefined, context);\n }\n\n throw error;\n }\n}\n\n/**\n * Sign with a discoverable passkey (no credential ID - browser prompts user to select).\n */\nexport async function signWithDiscoverablePasskey(\n challenge: Uint8Array,\n rpId: string\n): Promise<PasskeyDiscoverableSigningResult> {\n if (!isWebAuthnSupported()) {\n throw new Error('WebAuthn is not supported in this browser');\n }\n\n const resolvedRpId = rpId;\n const result = await signWithPasskeyAssertion(challenge, resolvedRpId);\n\n return {\n signature: result.signature,\n authenticatorData: result.authenticatorData,\n clientDataJSON: result.clientDataJSON,\n signatureR: result.signatureR,\n signatureS: result.signatureS,\n credentialId: result.credentialId,\n rpId: resolvedRpId,\n };\n}\n\n// Internal helpers\n\nasync function runWithPromptMode<T>(\n action: PasskeyPromptAction,\n inlineFn: () => Promise<T>,\n popupFn: (preopenedPopup?: Window | null) => Promise<T>\n): Promise<T> {\n const preopenedPopup = maybePreopenPopup(action, openPasskeyPopupWindow);\n const promptMode = await getPasskeyPromptMode(action);\n if (promptMode === 'popup') {\n return popupFn(preopenedPopup);\n }\n\n closePopup(preopenedPopup);\n\n try {\n return await inlineFn();\n } catch (error) {\n if (shouldFallbackToPopup(error)) {\n return popupFn();\n }\n throw error;\n }\n}\n\nasync function signWithPasskeyInline(\n credentialId: string,\n challenge: Uint8Array,\n rpId: string\n): Promise<PasskeySigningResult> {\n const result = await signWithPasskeyAssertion(challenge, rpId, credentialId);\n return {\n signature: result.signature,\n authenticatorData: result.authenticatorData,\n clientDataJSON: result.clientDataJSON,\n signatureR: result.signatureR,\n signatureS: result.signatureS,\n };\n}\n\nasync function signWithPasskeyAssertion(\n challenge: Uint8Array,\n rpId: string,\n credentialId?: string\n): Promise<PasskeySigningResult & { credentialId: string }> {\n const challengeBytes = new Uint8Array(challenge);\n const getOptions: PublicKeyCredentialRequestOptions = {\n challenge: challengeBytes,\n rpId,\n userVerification: 'required',\n timeout: 60000,\n };\n\n if (credentialId) {\n const credentialIdBuffer = base64UrlToArrayBuffer(credentialId);\n getOptions.allowCredentials = [\n {\n type: 'public-key',\n id: credentialIdBuffer,\n transports: ['internal', 'hybrid', 'usb', 'ble', 'nfc'],\n },\n ];\n }\n\n const assertion = (await navigator.credentials.get({\n publicKey: getOptions,\n })) as PublicKeyCredential | null;\n\n if (!assertion) {\n throw new Error('Passkey authentication was cancelled');\n }\n\n const response = assertion.response as AuthenticatorAssertionResponse;\n\n const signature = new Uint8Array(response.signature);\n let { r, s } = parseDerSignature(signature);\n s = normalizeLowS(s);\n\n return {\n signature: new Uint8Array([...r, ...s]),\n authenticatorData: new Uint8Array(response.authenticatorData),\n clientDataJSON: new Uint8Array(response.clientDataJSON),\n signatureR: r,\n signatureS: s,\n credentialId: arrayBufferToBase64Url(assertion.rawId),\n };\n}\n\nasync function signWithPasskeyViaPopup(\n credentialId: string,\n challenge: Uint8Array,\n rpId: string,\n preopenedPopup?: Window | null\n): Promise<PasskeySigningResult> {\n const result = await requestPasskeyPopup<PasskeyPopupSigningResult>(\n 'get',\n {\n credentialId,\n challengeBase64Url: bytesToBase64Url(challenge),\n rpId,\n },\n preopenedPopup\n );\n\n return decodePopupSigningResult(result);\n}\n\nasync function requestStoredPasskeyPopup(\n challenge: Uint8Array,\n preopenedPopup?: Window | null,\n context?: PasskeyPopupContext\n): Promise<PasskeyStoredSigningResult> {\n const result = await requestPasskeyPopup<PasskeyPopupStoredSigningResult>(\n 'getStored',\n {\n challengeBase64Url: bytesToBase64Url(challenge),\n context,\n },\n preopenedPopup\n );\n return decodePopupStoredSigningResult(result);\n}\n\nfunction decodePopupSigningResult(result: PasskeyPopupSigningResult): PasskeySigningResult {\n return {\n signature: base64UrlToBytes(result.signatureBase64Url),\n authenticatorData: base64UrlToBytes(result.authenticatorDataBase64Url),\n clientDataJSON: base64UrlToBytes(result.clientDataJSONBase64Url),\n signatureR: base64UrlToBytes(result.signatureRBase64Url),\n signatureS: base64UrlToBytes(result.signatureSBase64Url),\n };\n}\n\nfunction decodePopupStoredSigningResult(\n result: PasskeyPopupStoredSigningResult\n): PasskeyStoredSigningResult {\n return {\n ...decodePopupSigningResult(result),\n passkey: result.passkey,\n accounts: result.accounts,\n };\n}\n"],"mappings":"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","names":["import_passkey_manager","runWithPromptMode","import_passkey_manager"]}
1
+ {"version":3,"sources":["../src/web.ts","../src/register.ts","../src/capabilities.ts","../src/popup.ts","../src/label.ts","../src/sign.ts"],"sourcesContent":["export type {\n PasskeyRegistrationResult,\n PasskeySigningResult,\n PasskeyDiscoverableSigningResult,\n PasskeyStoredSigningResult,\n PasskeyMetadata,\n PasskeyClientCapabilities,\n PasskeyPopupContext,\n PasskeyPopupAccount,\n PasskeyStoredSigningOptions,\n PasskeyRegistrationOptions,\n} from './types';\n\nexport { registerPasskey } from './register';\nexport { createDistinctPasskeyLabel } from './label';\nexport type { DistinctPasskeyLabelOptions } from './label';\n\nexport {\n signWithPasskey,\n signWithStoredPasskey,\n signWithDiscoverablePasskey,\n} from './sign';\n\nexport {\n parseDerSignature,\n normalizeLowS,\n normalizeSignatureComponent,\n P256_N,\n P256_HALF_N,\n bytesToBigIntBE,\n bigIntToBytesBE,\n} from '@thru/programs/passkey-manager';\n\nexport {\n isWebAuthnSupported,\n preloadPasskeyClientCapabilities,\n getPasskeyClientCapabilities,\n getCachedPasskeyClientCapabilities,\n shouldUsePasskeyPopup,\n isInIframe,\n type PasskeyPromptAction,\n} from './capabilities';\n\nexport {\n arrayBufferToBase64Url,\n base64UrlToArrayBuffer,\n bytesToBase64,\n bytesToBase64Url,\n base64UrlToBytes,\n bytesToHex,\n hexToBytes,\n bytesEqual,\n compareBytes,\n uniqueAccounts,\n} from '@thru/programs/passkey-manager';\n","import type {\n PasskeyRegistrationOptions,\n PasskeyRegistrationResult,\n PasskeyPopupRegistrationResult,\n} from './types';\nimport { arrayBufferToBase64Url, bytesToHex } from '@thru/programs/passkey-manager';\nimport {\n isWebAuthnSupported,\n getPasskeyPromptMode,\n maybePreopenPopup,\n shouldFallbackToPopup,\n type PasskeyPromptAction,\n} from './capabilities';\nimport { requestPasskeyPopup, openPasskeyPopupWindow, closePopup } from './popup';\n\n/**\n * Register a new passkey for a profile.\n */\nexport async function registerPasskey(\n alias: string,\n userId: string,\n rpId: string,\n options: PasskeyRegistrationOptions = {}\n): Promise<PasskeyRegistrationResult> {\n if (!isWebAuthnSupported()) {\n throw new Error('WebAuthn is not supported in this browser');\n }\n\n return runWithPromptMode(\n 'create',\n () => registerPasskeyInline(alias, userId, rpId),\n (preopenedPopup) => registerPasskeyViaPopup(alias, userId, rpId, preopenedPopup),\n options\n );\n}\n\nasync function runWithPromptMode<T>(\n action: PasskeyPromptAction,\n inlineFn: () => Promise<T>,\n popupFn: (preopenedPopup?: Window | null) => Promise<T>,\n options: PasskeyRegistrationOptions = {}\n): Promise<T> {\n const allowPopupFallback = options.allowPopupFallback ?? true;\n const preopenedPopup = allowPopupFallback ? maybePreopenPopup(action, openPasskeyPopupWindow) : null;\n const promptMode = allowPopupFallback ? await getPasskeyPromptMode(action) : 'inline';\n if (promptMode === 'popup') {\n return popupFn(preopenedPopup);\n }\n\n closePopup(preopenedPopup);\n\n try {\n return await inlineFn();\n } catch (error) {\n if (allowPopupFallback && shouldFallbackToPopup(error)) {\n return popupFn();\n }\n throw error;\n }\n}\n\nasync function registerPasskeyInline(\n alias: string,\n userId: string,\n rpId: string\n): Promise<PasskeyRegistrationResult> {\n const rpName = 'Thru Wallet';\n\n const userIdBytes = new TextEncoder().encode(userId);\n const userIdBuffer = userIdBytes.slice(0, 64);\n\n const challenge = crypto.getRandomValues(new Uint8Array(32));\n\n const createOptions: PublicKeyCredentialCreationOptions = {\n challenge,\n rp: {\n id: rpId,\n name: rpName,\n },\n user: {\n id: userIdBuffer,\n name: alias,\n displayName: alias,\n },\n pubKeyCredParams: [\n { type: 'public-key', alg: -7 },\n ],\n authenticatorSelection: {\n authenticatorAttachment: 'platform',\n userVerification: 'required',\n residentKey: 'required',\n requireResidentKey: true,\n },\n attestation: 'none',\n timeout: 60000,\n };\n\n const credential = (await navigator.credentials.create({\n publicKey: createOptions,\n })) as PublicKeyCredential | null;\n\n if (!credential) {\n throw new Error('Passkey registration was cancelled');\n }\n\n const response = credential.response as AuthenticatorAttestationResponse;\n const { x, y } = extractP256PublicKey(response);\n const authenticatorAttachment =\n (\n credential as PublicKeyCredential & {\n authenticatorAttachment?: AuthenticatorAttachment | null;\n }\n ).authenticatorAttachment ?? null;\n\n return {\n credentialId: arrayBufferToBase64Url(credential.rawId),\n publicKeyX: bytesToHex(x),\n publicKeyY: bytesToHex(y),\n rpId,\n authenticatorAttachment,\n };\n}\n\nasync function registerPasskeyViaPopup(\n alias: string,\n userId: string,\n rpId: string,\n preopenedPopup?: Window | null\n): Promise<PasskeyRegistrationResult> {\n const result = await requestPasskeyPopup<PasskeyPopupRegistrationResult>(\n 'create',\n { alias, userId, rpId },\n preopenedPopup\n );\n return result;\n}\n\n// Key extraction helpers\n\nfunction extractP256PublicKey(\n response: AuthenticatorAttestationResponse\n): { x: Uint8Array; y: Uint8Array } {\n if (typeof response.getPublicKey === 'function') {\n const spkiKey = response.getPublicKey();\n if (spkiKey) {\n return extractFromSpki(new Uint8Array(spkiKey));\n }\n }\n\n if (typeof response.getAuthenticatorData === 'function') {\n const authData = new Uint8Array(response.getAuthenticatorData());\n return extractFromAuthenticatorData(authData);\n }\n\n throw new Error('Unable to extract public key: browser does not support required WebAuthn methods');\n}\n\nfunction extractFromSpki(spki: Uint8Array): { x: Uint8Array; y: Uint8Array } {\n const pointStart = spki.length - 65;\n\n if (spki[pointStart] !== 0x04) {\n throw new Error('Invalid SPKI format: expected uncompressed point');\n }\n\n const x = spki.slice(pointStart + 1, pointStart + 33);\n const y = spki.slice(pointStart + 33, pointStart + 65);\n\n if (x.length !== 32 || y.length !== 32) {\n throw new Error('Invalid SPKI format: incorrect coordinate length');\n }\n\n return { x, y };\n}\n\nfunction extractFromAuthenticatorData(authData: Uint8Array): { x: Uint8Array; y: Uint8Array } {\n const rpIdHashLength = 32;\n const flagsLength = 1;\n const counterLength = 4;\n const offset = rpIdHashLength + flagsLength + counterLength;\n const aaguidLength = 16;\n const credIdLenOffset = offset + aaguidLength;\n const credIdLength = (authData[credIdLenOffset] << 8) | authData[credIdLenOffset + 1];\n const coseKeyOffset = credIdLenOffset + 2 + credIdLength;\n const coseKey = authData.slice(coseKeyOffset);\n\n return extractFromCoseKey(coseKey);\n}\n\nfunction extractFromCoseKey(coseKey: Uint8Array): { x: Uint8Array; y: Uint8Array } {\n const mapStart = coseKey[0];\n if (mapStart !== 0xa5 && mapStart !== 0xa4) {\n throw new Error('Invalid COSE key format');\n }\n\n let offset = 1;\n let x: Uint8Array | null = null;\n let y: Uint8Array | null = null;\n\n while (offset < coseKey.length) {\n const key = coseKey[offset++];\n const valueType = coseKey[offset++];\n\n if (key === 0x21) {\n const length = valueType & 0x1f;\n x = coseKey.slice(offset, offset + length);\n offset += length;\n continue;\n }\n\n if (key === 0x22) {\n const length = valueType & 0x1f;\n y = coseKey.slice(offset, offset + length);\n offset += length;\n continue;\n }\n\n if (valueType >= 0x40 && valueType <= 0x5f) {\n const length = valueType & 0x1f;\n offset += length;\n continue;\n }\n\n if (valueType === 0x01 || valueType === 0x02 || valueType === 0x03) {\n continue;\n }\n\n if (valueType >= 0x18 && valueType <= 0x1b) {\n const size = 1 << (valueType - 0x18);\n offset += size;\n continue;\n }\n }\n\n if (!x || !y) {\n throw new Error('Failed to extract P-256 public key from COSE data');\n }\n\n if (x.length !== 32 || y.length !== 32) {\n throw new Error('Invalid COSE key: incorrect coordinate length');\n }\n\n return { x, y };\n}\n","import type { PasskeyClientCapabilities } from './types';\n\nconst globalProcess = (globalThis as { process?: { env?: Record<string, string | undefined> } }).process;\nconst DEBUG = globalProcess?.env?.NEXT_PUBLIC_PASSKEY_DEBUG === '1';\n\nlet cachedClientCapabilities: PasskeyClientCapabilities | null | undefined;\nlet clientCapabilitiesPromise: Promise<PasskeyClientCapabilities | null> | null = null;\n\nexport function isWebAuthnSupported(): boolean {\n const supported =\n typeof window !== 'undefined' &&\n typeof window.PublicKeyCredential !== 'undefined' &&\n typeof navigator.credentials !== 'undefined';\n\n if (DEBUG) {\n console.log('[Passkey] WebAuthn support check:', {\n window: typeof window !== 'undefined',\n PublicKeyCredential:\n typeof window !== 'undefined' && typeof window.PublicKeyCredential !== 'undefined',\n credentials:\n typeof window !== 'undefined' &&\n typeof navigator !== 'undefined' &&\n typeof navigator.credentials !== 'undefined',\n supported,\n });\n }\n\n return supported;\n}\n\nasync function fetchPasskeyClientCapabilities(): Promise<PasskeyClientCapabilities | null> {\n if (typeof window === 'undefined' || typeof window.PublicKeyCredential === 'undefined') {\n return null;\n }\n\n const getClientCapabilities = (window.PublicKeyCredential as {\n getClientCapabilities?: () => Promise<PasskeyClientCapabilities>;\n }).getClientCapabilities;\n\n if (typeof getClientCapabilities !== 'function') {\n return null;\n }\n\n try {\n const capabilities = await getClientCapabilities.call(window.PublicKeyCredential);\n if (DEBUG) {\n console.log('[Passkey] WebAuthn client capabilities:', capabilities);\n }\n return capabilities ?? null;\n } catch (error) {\n if (DEBUG) {\n console.warn('[Passkey] Failed to read client capabilities:', error);\n }\n return null;\n }\n}\n\nexport function preloadPasskeyClientCapabilities(): void {\n if (cachedClientCapabilities !== undefined || clientCapabilitiesPromise) {\n return;\n }\n\n clientCapabilitiesPromise = fetchPasskeyClientCapabilities().then((capabilities) => {\n cachedClientCapabilities = capabilities;\n return capabilities;\n });\n}\n\nexport async function getPasskeyClientCapabilities(): Promise<PasskeyClientCapabilities | null> {\n if (cachedClientCapabilities !== undefined) {\n return cachedClientCapabilities;\n }\n\n if (!clientCapabilitiesPromise) {\n preloadPasskeyClientCapabilities();\n }\n\n if (!clientCapabilitiesPromise) {\n cachedClientCapabilities = null;\n return null;\n }\n\n const capabilities = await clientCapabilitiesPromise;\n cachedClientCapabilities = capabilities;\n return capabilities;\n}\n\nexport function getCachedPasskeyClientCapabilities(): PasskeyClientCapabilities | null | undefined {\n return cachedClientCapabilities;\n}\n\nexport function isInIframe(): boolean {\n if (typeof window === 'undefined') {\n return false;\n }\n try {\n return window.self !== window.top;\n } catch {\n return true;\n }\n}\n\nexport type PasskeyPromptAction = 'get' | 'create';\n\nexport async function shouldUsePasskeyPopup(action: PasskeyPromptAction): Promise<boolean> {\n if (!isInIframe()) {\n return false;\n }\n const mode = await getPasskeyPromptMode(action);\n return mode === 'popup';\n}\n\ntype PasskeyPromptMode = 'inline' | 'popup';\n\nfunction getPermissionsPolicyAllowsFeature(feature: string): boolean | null {\n if (typeof document === 'undefined') {\n return null;\n }\n\n const policy = (document as { permissionsPolicy?: { allowsFeature?: (name: string) => boolean } })\n .permissionsPolicy;\n const featurePolicy = (document as { featurePolicy?: { allowsFeature?: (name: string) => boolean } })\n .featurePolicy;\n const allowsFeature = policy?.allowsFeature || featurePolicy?.allowsFeature;\n\n if (typeof allowsFeature !== 'function') {\n return null;\n }\n\n try {\n return allowsFeature(feature);\n } catch {\n return null;\n }\n}\n\nfunction getCachedPromptMode(action: PasskeyPromptAction): PasskeyPromptMode | 'unknown' {\n if (!isInIframe()) {\n return 'inline';\n }\n\n if (cachedClientCapabilities === undefined && !clientCapabilitiesPromise) {\n preloadPasskeyClientCapabilities();\n }\n\n const feature =\n action === 'create' ? 'publickey-credentials-create' : 'publickey-credentials-get';\n const policyAllows = getPermissionsPolicyAllowsFeature(feature);\n const capabilities = getCachedPasskeyClientCapabilities();\n const supportsInline =\n capabilities?.passkeyPlatformAuthenticator === true ||\n capabilities?.userVerifyingPlatformAuthenticator === true;\n\n if (policyAllows === false) {\n return 'popup';\n }\n\n if (capabilities === undefined) {\n return 'unknown';\n }\n\n if (!supportsInline) {\n return 'popup';\n }\n\n return 'inline';\n}\n\nexport async function getPasskeyPromptMode(action: PasskeyPromptAction): Promise<PasskeyPromptMode> {\n if (!isInIframe()) {\n return 'inline';\n }\n\n const feature =\n action === 'create' ? 'publickey-credentials-create' : 'publickey-credentials-get';\n const policyAllows = getPermissionsPolicyAllowsFeature(feature);\n const capabilities = await getPasskeyClientCapabilities();\n const supportsInline =\n capabilities?.passkeyPlatformAuthenticator === true ||\n capabilities?.userVerifyingPlatformAuthenticator === true;\n\n if (DEBUG) {\n console.log('[Passkey] Prompt mode check:', {\n action,\n policyAllows,\n supportsInline,\n capabilities,\n });\n }\n\n if (!supportsInline) {\n return 'popup';\n }\n\n if (policyAllows === false) {\n return 'popup';\n }\n\n return 'inline';\n}\n\nexport function maybePreopenPopup(action: PasskeyPromptAction, openPopupFn: () => Window): Window | null {\n const cachedMode = getCachedPromptMode(action);\n if (cachedMode !== 'popup') {\n return null;\n }\n\n try {\n return openPopupFn();\n } catch {\n return null;\n }\n}\n\nexport function shouldFallbackToPopup(error: unknown): boolean {\n if (!isInIframe()) {\n return false;\n }\n\n const name =\n error && typeof error === 'object' && 'name' in error ? String((error as { name?: unknown }).name) : '';\n const message =\n error && typeof error === 'object' && 'message' in error\n ? String((error as { message?: unknown }).message)\n : '';\n const normalized = `${name} ${message}`.toLowerCase();\n\n if (\n normalized.includes('cancel') ||\n normalized.includes('canceled') ||\n normalized.includes('cancelled') ||\n normalized.includes('user canceled') ||\n normalized.includes('user cancelled') ||\n normalized.includes('aborted')\n ) {\n return false;\n }\n\n if (normalized.includes('securityerror')) {\n return true;\n }\n\n if (normalized.includes('notallowederror')) {\n if (\n normalized.includes('permission') ||\n normalized.includes('policy') ||\n normalized.includes('iframe') ||\n normalized.includes('frame')\n ) {\n return true;\n }\n }\n\n return false;\n}\n","import type {\n PasskeyPopupAction,\n PasskeyPopupRequestPayload,\n PasskeyPopupRequest,\n PasskeyPopupResponse,\n} from './types';\n\nexport const PASSKEY_POPUP_PATH = '/passkey/popup';\nexport const PASSKEY_POPUP_READY_EVENT = 'thru:passkey-popup-ready';\nexport const PASSKEY_POPUP_REQUEST_EVENT = 'thru:passkey-popup-request';\nexport const PASSKEY_POPUP_RESPONSE_EVENT = 'thru:passkey-popup-response';\nexport const PASSKEY_POPUP_CHANNEL = 'thru:passkey-popup-channel';\n\nconst PASSKEY_POPUP_TIMEOUT_MS = 60000;\n\nexport function closePopup(popup: Window | null | undefined): void {\n if (popup && !popup.closed) {\n popup.close();\n }\n}\n\nexport function openPasskeyPopupWindow(): Window {\n const popupUrl = new URL(PASSKEY_POPUP_PATH, window.location.origin).toString();\n const popup = window.open(\n popupUrl,\n 'thru_passkey_popup',\n 'popup=yes,width=440,height=640'\n );\n\n if (!popup) {\n throw new Error('Passkey popup was blocked');\n }\n\n return popup;\n}\n\nfunction createPopupRequestId(): string {\n const rand = Math.random().toString(36).slice(2, 10);\n return `passkey_${Date.now()}_${rand}`;\n}\n\nexport async function requestPasskeyPopup<T>(\n action: PasskeyPopupAction,\n payload: PasskeyPopupRequestPayload,\n preopenedPopup?: Window | null\n): Promise<T> {\n if (typeof window === 'undefined') {\n throw new Error('Passkey popup is only available in the browser');\n }\n\n const requestId = createPopupRequestId();\n const targetOrigin = window.location.origin;\n let popup: Window | null = preopenedPopup ?? null;\n const channel =\n typeof BroadcastChannel !== 'undefined' ? new BroadcastChannel(PASSKEY_POPUP_CHANNEL) : null;\n\n return new Promise<T>((resolve, reject) => {\n let timeout: ReturnType<typeof setTimeout> | null = null;\n let closePoll: ReturnType<typeof setInterval> | null = null;\n let requestSent = false;\n\n const cleanup = () => {\n if (timeout) {\n clearTimeout(timeout);\n timeout = null;\n }\n if (closePoll) {\n clearInterval(closePoll);\n closePoll = null;\n }\n window.removeEventListener('message', handleMessage);\n if (channel) {\n channel.removeEventListener('message', handleChannelMessage);\n channel.close();\n }\n };\n\n const sendRequest = (viaChannel: boolean) => {\n if (requestSent) {\n return;\n }\n requestSent = true;\n\n const request: PasskeyPopupRequest = {\n type: PASSKEY_POPUP_REQUEST_EVENT,\n requestId,\n action,\n payload,\n };\n\n if (viaChannel) {\n channel?.postMessage(request);\n return;\n }\n\n popup?.postMessage(request, targetOrigin);\n };\n\n const handleResponse = (data: PasskeyPopupResponse) => {\n if (data.requestId !== requestId) {\n return;\n }\n\n cleanup();\n if (popup && !popup.closed) {\n popup.close();\n }\n\n if (data.success) {\n resolve((data as Extract<PasskeyPopupResponse, { success: true }>).result as T);\n } else {\n const err = new Error(data.error?.message || 'Passkey popup failed');\n if (data.error?.name) {\n (err as { name?: string }).name = data.error.name;\n }\n reject(err);\n }\n };\n\n const handleMessage = (event: MessageEvent) => {\n if (event.origin !== targetOrigin) {\n return;\n }\n\n const data = event.data as PasskeyPopupResponse | { type?: string };\n if (!data || typeof data !== 'object') {\n return;\n }\n\n if (data.type === PASSKEY_POPUP_READY_EVENT) {\n if (popup && event.source !== popup) {\n return;\n }\n sendRequest(false);\n return;\n }\n\n if (data.type === PASSKEY_POPUP_RESPONSE_EVENT && 'requestId' in data) {\n handleResponse(data as PasskeyPopupResponse);\n }\n };\n\n window.addEventListener('message', handleMessage);\n\n const handleChannelMessage = (event: MessageEvent) => {\n const data = event.data as PasskeyPopupResponse | { type?: string };\n if (!data || typeof data !== 'object') {\n return;\n }\n\n if (data.type === PASSKEY_POPUP_READY_EVENT) {\n sendRequest(true);\n return;\n }\n\n if (data.type === PASSKEY_POPUP_RESPONSE_EVENT && 'requestId' in data) {\n handleResponse(data as PasskeyPopupResponse);\n }\n };\n\n if (channel) {\n channel.addEventListener('message', handleChannelMessage);\n }\n\n if (!popup) {\n try {\n popup = openPasskeyPopupWindow();\n } catch (error) {\n cleanup();\n reject(error);\n return;\n }\n }\n\n timeout = setTimeout(() => {\n cleanup();\n try {\n popup?.close();\n } catch {\n /* ignore */\n }\n reject(new Error('Passkey popup timed out'));\n }, PASSKEY_POPUP_TIMEOUT_MS);\n\n closePoll = setInterval(() => {\n if (popup && popup.closed) {\n cleanup();\n reject(new Error('Passkey popup was closed'));\n }\n }, 250);\n });\n}\n","const DEFAULT_LABEL = 'Thru Wallet passkey';\n\nexport interface DistinctPasskeyLabelOptions {\n existingLabels?: Iterable<string | null | undefined>;\n maxAttempts?: number;\n suffixFactory?: () => string;\n}\n\nexport function createDistinctPasskeyLabel(\n baseLabel: string,\n _options: DistinctPasskeyLabelOptions = {}\n): string {\n return baseLabel.trim() || DEFAULT_LABEL;\n}\n","import type {\n PasskeySigningResult,\n PasskeyStoredSigningResult,\n PasskeyDiscoverableSigningResult,\n PasskeyMetadata,\n PasskeyPopupContext,\n PasskeyPopupSigningResult,\n PasskeyPopupStoredSigningResult,\n PasskeyStoredSigningOptions,\n} from './types';\nimport {\n arrayBufferToBase64Url,\n base64UrlToArrayBuffer,\n bytesToBase64Url,\n base64UrlToBytes,\n parseDerSignature,\n normalizeLowS,\n} from '@thru/programs/passkey-manager';\nimport {\n isWebAuthnSupported,\n getPasskeyPromptMode,\n isInIframe,\n maybePreopenPopup,\n shouldFallbackToPopup,\n type PasskeyPromptAction,\n} from './capabilities';\nimport {\n requestPasskeyPopup,\n openPasskeyPopupWindow,\n closePopup,\n} from './popup';\n\n/**\n * Sign a challenge with an existing passkey (by credential ID).\n */\nexport async function signWithPasskey(\n credentialId: string,\n challenge: Uint8Array,\n rpId: string\n): Promise<PasskeySigningResult> {\n if (!isWebAuthnSupported()) {\n throw new Error('WebAuthn is not supported in this browser');\n }\n\n return runWithPromptMode(\n 'get',\n () => signWithPasskeyInline(credentialId, challenge, rpId),\n (preopenedPopup) =>\n signWithPasskeyViaPopup(credentialId, challenge, rpId, preopenedPopup)\n );\n}\n\n/**\n * Sign with stored passkey (for embedded/popup contexts).\n */\nexport async function signWithStoredPasskey(\n challenge: Uint8Array,\n rpId: string,\n preferredPasskey: PasskeyMetadata | null,\n allPasskeys: PasskeyMetadata[],\n context?: PasskeyPopupContext,\n options: PasskeyStoredSigningOptions = {}\n): Promise<PasskeyStoredSigningResult> {\n if (!isWebAuthnSupported()) {\n throw new Error('WebAuthn is not supported in this browser');\n }\n\n const allowPopupFallback = options.allowPopupFallback ?? true;\n const preopenedPopup = allowPopupFallback\n ? maybePreopenPopup('get', openPasskeyPopupWindow)\n : null;\n const promptMode = allowPopupFallback\n ? await getPasskeyPromptMode('get')\n : 'inline';\n const storedPasskey = preferredPasskey;\n const canUsePopup = allowPopupFallback && isInIframe();\n\n if (options.preferDiscoverable) {\n closePopup(preopenedPopup);\n return signWithDiscoverableStoredPasskey(\n challenge,\n storedPasskey?.rpId ?? rpId,\n allPasskeys\n );\n }\n\n if (promptMode === 'popup' || (canUsePopup && !storedPasskey)) {\n return requestStoredPasskeyPopup(challenge, preopenedPopup, context);\n }\n\n closePopup(preopenedPopup);\n\n try {\n if (storedPasskey) {\n try {\n const result = await signWithPasskeyInline(\n storedPasskey.credentialId,\n challenge,\n storedPasskey.rpId\n );\n return {\n ...result,\n passkey: storedPasskey,\n };\n } catch (error) {\n if (!shouldFallbackToDiscoverable(error)) {\n throw error;\n }\n return signWithDiscoverableStoredPasskey(\n challenge,\n storedPasskey.rpId,\n allPasskeys\n );\n }\n }\n\n return signWithDiscoverableStoredPasskey(challenge, rpId, allPasskeys);\n } catch (error) {\n if (canUsePopup && shouldFallbackToPopup(error)) {\n return requestStoredPasskeyPopup(challenge, undefined, context);\n }\n\n throw error;\n }\n}\n\nasync function signWithDiscoverableStoredPasskey(\n challenge: Uint8Array,\n rpId: string,\n allPasskeys: PasskeyMetadata[]\n): Promise<PasskeyStoredSigningResult> {\n const discoverable = await signWithDiscoverablePasskey(challenge, rpId);\n const matchingPasskey =\n allPasskeys.find((p) => p.credentialId === discoverable.credentialId) ??\n null;\n const now = new Date().toISOString();\n const passkey = matchingPasskey ?? {\n credentialId: discoverable.credentialId,\n publicKeyX: '',\n publicKeyY: '',\n rpId: discoverable.rpId,\n createdAt: now,\n lastUsedAt: now,\n };\n\n return {\n signature: discoverable.signature,\n authenticatorData: discoverable.authenticatorData,\n clientDataJSON: discoverable.clientDataJSON,\n signatureR: discoverable.signatureR,\n signatureS: discoverable.signatureS,\n authenticatorAttachment: discoverable.authenticatorAttachment,\n passkey,\n };\n}\n\nfunction shouldFallbackToDiscoverable(error: unknown): boolean {\n const name =\n error && typeof error === 'object' && 'name' in error\n ? String((error as { name?: unknown }).name)\n : '';\n const message =\n error && typeof error === 'object' && 'message' in error\n ? String((error as { message?: unknown }).message)\n : '';\n const normalized = `${name} ${message}`.toLowerCase();\n\n if (\n normalized.includes('user rejected') ||\n normalized.includes('user canceled') ||\n normalized.includes('user cancelled')\n ) {\n return false;\n }\n\n return (\n normalized.includes('notallowederror') ||\n normalized.includes('invalidstateerror') ||\n normalized.includes('notfounderror') ||\n normalized.includes('not found') ||\n normalized.includes('no passkey') ||\n normalized.includes('no credential') ||\n normalized.includes('saved for this app')\n );\n}\n\n/**\n * Sign with a discoverable passkey (no credential ID - browser prompts user to select).\n */\nexport async function signWithDiscoverablePasskey(\n challenge: Uint8Array,\n rpId: string\n): Promise<PasskeyDiscoverableSigningResult> {\n if (!isWebAuthnSupported()) {\n throw new Error('WebAuthn is not supported in this browser');\n }\n\n const resolvedRpId = rpId;\n const result = await signWithPasskeyAssertion(challenge, resolvedRpId);\n\n return {\n signature: result.signature,\n authenticatorData: result.authenticatorData,\n clientDataJSON: result.clientDataJSON,\n signatureR: result.signatureR,\n signatureS: result.signatureS,\n credentialId: result.credentialId,\n rpId: resolvedRpId,\n authenticatorAttachment: result.authenticatorAttachment,\n };\n}\n\n// Internal helpers\n\nasync function runWithPromptMode<T>(\n action: PasskeyPromptAction,\n inlineFn: () => Promise<T>,\n popupFn: (preopenedPopup?: Window | null) => Promise<T>\n): Promise<T> {\n const preopenedPopup = maybePreopenPopup(action, openPasskeyPopupWindow);\n const promptMode = await getPasskeyPromptMode(action);\n if (promptMode === 'popup') {\n return popupFn(preopenedPopup);\n }\n\n closePopup(preopenedPopup);\n\n try {\n return await inlineFn();\n } catch (error) {\n if (shouldFallbackToPopup(error)) {\n return popupFn();\n }\n throw error;\n }\n}\n\nasync function signWithPasskeyInline(\n credentialId: string,\n challenge: Uint8Array,\n rpId: string\n): Promise<PasskeySigningResult> {\n const result = await signWithPasskeyAssertion(challenge, rpId, credentialId);\n return {\n signature: result.signature,\n authenticatorData: result.authenticatorData,\n clientDataJSON: result.clientDataJSON,\n signatureR: result.signatureR,\n signatureS: result.signatureS,\n authenticatorAttachment: result.authenticatorAttachment,\n };\n}\n\nasync function signWithPasskeyAssertion(\n challenge: Uint8Array,\n rpId: string,\n credentialId?: string\n): Promise<PasskeySigningResult & { credentialId: string }> {\n const challengeBytes = new Uint8Array(challenge);\n const getOptions: PublicKeyCredentialRequestOptions = {\n challenge: challengeBytes,\n rpId,\n userVerification: 'required',\n timeout: 60000,\n };\n\n if (credentialId) {\n const credentialIdBuffer = base64UrlToArrayBuffer(credentialId);\n getOptions.allowCredentials = [\n {\n type: 'public-key',\n id: credentialIdBuffer,\n transports: ['internal', 'hybrid', 'usb', 'ble', 'nfc'],\n },\n ];\n }\n\n const assertion = (await navigator.credentials.get({\n publicKey: getOptions,\n })) as PublicKeyCredential | null;\n\n if (!assertion) {\n throw new Error('Passkey authentication was cancelled');\n }\n\n const response = assertion.response as AuthenticatorAssertionResponse;\n\n const signature = new Uint8Array(response.signature);\n let { r, s } = parseDerSignature(signature);\n s = normalizeLowS(s);\n\n /* `authenticatorAttachment` distinguishes a same-device passkey\n ('platform') from a cross-device one signed via QR / hybrid\n transport ('cross-platform'). Drives the wallet's add-device\n prompt. Browsers may report null. */\n const rawAttachment =\n (\n assertion as PublicKeyCredential & {\n authenticatorAttachment?: AuthenticatorAttachment | null;\n }\n ).authenticatorAttachment ?? null;\n\n return {\n signature: new Uint8Array([...r, ...s]),\n authenticatorData: new Uint8Array(response.authenticatorData),\n clientDataJSON: new Uint8Array(response.clientDataJSON),\n signatureR: r,\n signatureS: s,\n credentialId: arrayBufferToBase64Url(assertion.rawId),\n authenticatorAttachment: rawAttachment,\n };\n}\n\nasync function signWithPasskeyViaPopup(\n credentialId: string,\n challenge: Uint8Array,\n rpId: string,\n preopenedPopup?: Window | null\n): Promise<PasskeySigningResult> {\n const result = await requestPasskeyPopup<PasskeyPopupSigningResult>(\n 'get',\n {\n credentialId,\n challengeBase64Url: bytesToBase64Url(challenge),\n rpId,\n },\n preopenedPopup\n );\n\n return decodePopupSigningResult(result);\n}\n\nasync function requestStoredPasskeyPopup(\n challenge: Uint8Array,\n preopenedPopup?: Window | null,\n context?: PasskeyPopupContext\n): Promise<PasskeyStoredSigningResult> {\n const result = await requestPasskeyPopup<PasskeyPopupStoredSigningResult>(\n 'getStored',\n {\n challengeBase64Url: bytesToBase64Url(challenge),\n context,\n },\n preopenedPopup\n );\n return decodePopupStoredSigningResult(result);\n}\n\nfunction decodePopupSigningResult(\n result: PasskeyPopupSigningResult\n): PasskeySigningResult {\n return {\n signature: base64UrlToBytes(result.signatureBase64Url),\n authenticatorData: base64UrlToBytes(result.authenticatorDataBase64Url),\n clientDataJSON: base64UrlToBytes(result.clientDataJSONBase64Url),\n signatureR: base64UrlToBytes(result.signatureRBase64Url),\n signatureS: base64UrlToBytes(result.signatureSBase64Url),\n authenticatorAttachment: result.authenticatorAttachment ?? null,\n };\n}\n\nfunction decodePopupStoredSigningResult(\n result: PasskeyPopupStoredSigningResult\n): PasskeyStoredSigningResult {\n return {\n ...decodePopupSigningResult(result),\n passkey: result.passkey,\n accounts: result.accounts,\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACKA,6BAAmD;;;ACHnD,IAAM,gBAAiB,WAA0E;AACjG,IAAM,QAAQ,eAAe,KAAK,8BAA8B;AAEhE,IAAI;AACJ,IAAI,4BAA8E;AAE3E,SAAS,sBAA+B;AAC7C,QAAM,YACJ,OAAO,WAAW,eAClB,OAAO,OAAO,wBAAwB,eACtC,OAAO,UAAU,gBAAgB;AAEnC,MAAI,OAAO;AACT,YAAQ,IAAI,qCAAqC;AAAA,MAC/C,QAAQ,OAAO,WAAW;AAAA,MAC1B,qBACE,OAAO,WAAW,eAAe,OAAO,OAAO,wBAAwB;AAAA,MACzE,aACE,OAAO,WAAW,eAClB,OAAO,cAAc,eACrB,OAAO,UAAU,gBAAgB;AAAA,MACnC;AAAA,IACF,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AAEA,eAAe,iCAA4E;AACzF,MAAI,OAAO,WAAW,eAAe,OAAO,OAAO,wBAAwB,aAAa;AACtF,WAAO;AAAA,EACT;AAEA,QAAM,wBAAyB,OAAO,oBAEnC;AAEH,MAAI,OAAO,0BAA0B,YAAY;AAC/C,WAAO;AAAA,EACT;AAEA,MAAI;AACF,UAAM,eAAe,MAAM,sBAAsB,KAAK,OAAO,mBAAmB;AAChF,QAAI,OAAO;AACT,cAAQ,IAAI,2CAA2C,YAAY;AAAA,IACrE;AACA,WAAO,gBAAgB;AAAA,EACzB,SAAS,OAAO;AACd,QAAI,OAAO;AACT,cAAQ,KAAK,iDAAiD,KAAK;AAAA,IACrE;AACA,WAAO;AAAA,EACT;AACF;AAEO,SAAS,mCAAyC;AACvD,MAAI,6BAA6B,UAAa,2BAA2B;AACvE;AAAA,EACF;AAEA,8BAA4B,+BAA+B,EAAE,KAAK,CAAC,iBAAiB;AAClF,+BAA2B;AAC3B,WAAO;AAAA,EACT,CAAC;AACH;AAEA,eAAsB,+BAA0E;AAC9F,MAAI,6BAA6B,QAAW;AAC1C,WAAO;AAAA,EACT;AAEA,MAAI,CAAC,2BAA2B;AAC9B,qCAAiC;AAAA,EACnC;AAEA,MAAI,CAAC,2BAA2B;AAC9B,+BAA2B;AAC3B,WAAO;AAAA,EACT;AAEA,QAAM,eAAe,MAAM;AAC3B,6BAA2B;AAC3B,SAAO;AACT;AAEO,SAAS,qCAAmF;AACjG,SAAO;AACT;AAEO,SAAS,aAAsB;AACpC,MAAI,OAAO,WAAW,aAAa;AACjC,WAAO;AAAA,EACT;AACA,MAAI;AACF,WAAO,OAAO,SAAS,OAAO;AAAA,EAChC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAIA,eAAsB,sBAAsB,QAA+C;AACzF,MAAI,CAAC,WAAW,GAAG;AACjB,WAAO;AAAA,EACT;AACA,QAAM,OAAO,MAAM,qBAAqB,MAAM;AAC9C,SAAO,SAAS;AAClB;AAIA,SAAS,kCAAkC,SAAiC;AAC1E,MAAI,OAAO,aAAa,aAAa;AACnC,WAAO;AAAA,EACT;AAEA,QAAM,SAAU,SACb;AACH,QAAM,gBAAiB,SACpB;AACH,QAAM,gBAAgB,QAAQ,iBAAiB,eAAe;AAE9D,MAAI,OAAO,kBAAkB,YAAY;AACvC,WAAO;AAAA,EACT;AAEA,MAAI;AACF,WAAO,cAAc,OAAO;AAAA,EAC9B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,oBAAoB,QAA4D;AACvF,MAAI,CAAC,WAAW,GAAG;AACjB,WAAO;AAAA,EACT;AAEA,MAAI,6BAA6B,UAAa,CAAC,2BAA2B;AACxE,qCAAiC;AAAA,EACnC;AAEA,QAAM,UACJ,WAAW,WAAW,iCAAiC;AACzD,QAAM,eAAe,kCAAkC,OAAO;AAC9D,QAAM,eAAe,mCAAmC;AACxD,QAAM,iBACJ,cAAc,iCAAiC,QAC/C,cAAc,uCAAuC;AAEvD,MAAI,iBAAiB,OAAO;AAC1B,WAAO;AAAA,EACT;AAEA,MAAI,iBAAiB,QAAW;AAC9B,WAAO;AAAA,EACT;AAEA,MAAI,CAAC,gBAAgB;AACnB,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAEA,eAAsB,qBAAqB,QAAyD;AAClG,MAAI,CAAC,WAAW,GAAG;AACjB,WAAO;AAAA,EACT;AAEA,QAAM,UACJ,WAAW,WAAW,iCAAiC;AACzD,QAAM,eAAe,kCAAkC,OAAO;AAC9D,QAAM,eAAe,MAAM,6BAA6B;AACxD,QAAM,iBACJ,cAAc,iCAAiC,QAC/C,cAAc,uCAAuC;AAEvD,MAAI,OAAO;AACT,YAAQ,IAAI,gCAAgC;AAAA,MAC1C;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAEA,MAAI,CAAC,gBAAgB;AACnB,WAAO;AAAA,EACT;AAEA,MAAI,iBAAiB,OAAO;AAC1B,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAEO,SAAS,kBAAkB,QAA6B,aAA0C;AACvG,QAAM,aAAa,oBAAoB,MAAM;AAC7C,MAAI,eAAe,SAAS;AAC1B,WAAO;AAAA,EACT;AAEA,MAAI;AACF,WAAO,YAAY;AAAA,EACrB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,SAAS,sBAAsB,OAAyB;AAC7D,MAAI,CAAC,WAAW,GAAG;AACjB,WAAO;AAAA,EACT;AAEA,QAAM,OACJ,SAAS,OAAO,UAAU,YAAY,UAAU,QAAQ,OAAQ,MAA6B,IAAI,IAAI;AACvG,QAAM,UACJ,SAAS,OAAO,UAAU,YAAY,aAAa,QAC/C,OAAQ,MAAgC,OAAO,IAC/C;AACN,QAAM,aAAa,GAAG,IAAI,IAAI,OAAO,GAAG,YAAY;AAEpD,MACE,WAAW,SAAS,QAAQ,KAC5B,WAAW,SAAS,UAAU,KAC9B,WAAW,SAAS,WAAW,KAC/B,WAAW,SAAS,eAAe,KACnC,WAAW,SAAS,gBAAgB,KACpC,WAAW,SAAS,SAAS,GAC7B;AACA,WAAO;AAAA,EACT;AAEA,MAAI,WAAW,SAAS,eAAe,GAAG;AACxC,WAAO;AAAA,EACT;AAEA,MAAI,WAAW,SAAS,iBAAiB,GAAG;AAC1C,QACE,WAAW,SAAS,YAAY,KAChC,WAAW,SAAS,QAAQ,KAC5B,WAAW,SAAS,QAAQ,KAC5B,WAAW,SAAS,OAAO,GAC3B;AACA,aAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO;AACT;;;ACvPO,IAAM,qBAAqB;AAC3B,IAAM,4BAA4B;AAClC,IAAM,8BAA8B;AACpC,IAAM,+BAA+B;AACrC,IAAM,wBAAwB;AAErC,IAAM,2BAA2B;AAE1B,SAAS,WAAW,OAAwC;AACjE,MAAI,SAAS,CAAC,MAAM,QAAQ;AAC1B,UAAM,MAAM;AAAA,EACd;AACF;AAEO,SAAS,yBAAiC;AAC/C,QAAM,WAAW,IAAI,IAAI,oBAAoB,OAAO,SAAS,MAAM,EAAE,SAAS;AAC9E,QAAM,QAAQ,OAAO;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,MAAI,CAAC,OAAO;AACV,UAAM,IAAI,MAAM,2BAA2B;AAAA,EAC7C;AAEA,SAAO;AACT;AAEA,SAAS,uBAA+B;AACtC,QAAM,OAAO,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,GAAG,EAAE;AACnD,SAAO,WAAW,KAAK,IAAI,CAAC,IAAI,IAAI;AACtC;AAEA,eAAsB,oBACpB,QACA,SACA,gBACY;AACZ,MAAI,OAAO,WAAW,aAAa;AACjC,UAAM,IAAI,MAAM,gDAAgD;AAAA,EAClE;AAEA,QAAM,YAAY,qBAAqB;AACvC,QAAM,eAAe,OAAO,SAAS;AACrC,MAAI,QAAuB,kBAAkB;AAC7C,QAAM,UACJ,OAAO,qBAAqB,cAAc,IAAI,iBAAiB,qBAAqB,IAAI;AAE1F,SAAO,IAAI,QAAW,CAAC,SAAS,WAAW;AACzC,QAAI,UAAgD;AACpD,QAAI,YAAmD;AACvD,QAAI,cAAc;AAElB,UAAM,UAAU,MAAM;AACpB,UAAI,SAAS;AACX,qBAAa,OAAO;AACpB,kBAAU;AAAA,MACZ;AACA,UAAI,WAAW;AACb,sBAAc,SAAS;AACvB,oBAAY;AAAA,MACd;AACA,aAAO,oBAAoB,WAAW,aAAa;AACnD,UAAI,SAAS;AACX,gBAAQ,oBAAoB,WAAW,oBAAoB;AAC3D,gBAAQ,MAAM;AAAA,MAChB;AAAA,IACF;AAEA,UAAM,cAAc,CAAC,eAAwB;AAC3C,UAAI,aAAa;AACf;AAAA,MACF;AACA,oBAAc;AAEd,YAAM,UAA+B;AAAA,QACnC,MAAM;AAAA,QACN;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAEA,UAAI,YAAY;AACd,iBAAS,YAAY,OAAO;AAC5B;AAAA,MACF;AAEA,aAAO,YAAY,SAAS,YAAY;AAAA,IAC1C;AAEA,UAAM,iBAAiB,CAAC,SAA+B;AACrD,UAAI,KAAK,cAAc,WAAW;AAChC;AAAA,MACF;AAEA,cAAQ;AACR,UAAI,SAAS,CAAC,MAAM,QAAQ;AAC1B,cAAM,MAAM;AAAA,MACd;AAEA,UAAI,KAAK,SAAS;AAChB,gBAAS,KAA0D,MAAW;AAAA,MAChF,OAAO;AACL,cAAM,MAAM,IAAI,MAAM,KAAK,OAAO,WAAW,sBAAsB;AACnE,YAAI,KAAK,OAAO,MAAM;AACpB,UAAC,IAA0B,OAAO,KAAK,MAAM;AAAA,QAC/C;AACA,eAAO,GAAG;AAAA,MACZ;AAAA,IACF;AAEA,UAAM,gBAAgB,CAAC,UAAwB;AAC7C,UAAI,MAAM,WAAW,cAAc;AACjC;AAAA,MACF;AAEA,YAAM,OAAO,MAAM;AACnB,UAAI,CAAC,QAAQ,OAAO,SAAS,UAAU;AACrC;AAAA,MACF;AAEA,UAAI,KAAK,SAAS,2BAA2B;AAC3C,YAAI,SAAS,MAAM,WAAW,OAAO;AACnC;AAAA,QACF;AACA,oBAAY,KAAK;AACjB;AAAA,MACF;AAEA,UAAI,KAAK,SAAS,gCAAgC,eAAe,MAAM;AACrE,uBAAe,IAA4B;AAAA,MAC7C;AAAA,IACF;AAEA,WAAO,iBAAiB,WAAW,aAAa;AAEhD,UAAM,uBAAuB,CAAC,UAAwB;AACpD,YAAM,OAAO,MAAM;AACnB,UAAI,CAAC,QAAQ,OAAO,SAAS,UAAU;AACrC;AAAA,MACF;AAEA,UAAI,KAAK,SAAS,2BAA2B;AAC3C,oBAAY,IAAI;AAChB;AAAA,MACF;AAEA,UAAI,KAAK,SAAS,gCAAgC,eAAe,MAAM;AACrE,uBAAe,IAA4B;AAAA,MAC7C;AAAA,IACF;AAEA,QAAI,SAAS;AACX,cAAQ,iBAAiB,WAAW,oBAAoB;AAAA,IAC1D;AAEA,QAAI,CAAC,OAAO;AACV,UAAI;AACF,gBAAQ,uBAAuB;AAAA,MACjC,SAAS,OAAO;AACd,gBAAQ;AACR,eAAO,KAAK;AACZ;AAAA,MACF;AAAA,IACF;AAEA,cAAU,WAAW,MAAM;AACzB,cAAQ;AACR,UAAI;AACF,eAAO,MAAM;AAAA,MACf,QAAQ;AAAA,MAER;AACA,aAAO,IAAI,MAAM,yBAAyB,CAAC;AAAA,IAC7C,GAAG,wBAAwB;AAE3B,gBAAY,YAAY,MAAM;AAC5B,UAAI,SAAS,MAAM,QAAQ;AACzB,gBAAQ;AACR,eAAO,IAAI,MAAM,0BAA0B,CAAC;AAAA,MAC9C;AAAA,IACF,GAAG,GAAG;AAAA,EACR,CAAC;AACH;;;AF7KA,eAAsB,gBACpB,OACA,QACA,MACA,UAAsC,CAAC,GACH;AACpC,MAAI,CAAC,oBAAoB,GAAG;AAC1B,UAAM,IAAI,MAAM,2CAA2C;AAAA,EAC7D;AAEA,SAAO;AAAA,IACL;AAAA,IACA,MAAM,sBAAsB,OAAO,QAAQ,IAAI;AAAA,IAC/C,CAAC,mBAAmB,wBAAwB,OAAO,QAAQ,MAAM,cAAc;AAAA,IAC/E;AAAA,EACF;AACF;AAEA,eAAe,kBACb,QACA,UACA,SACA,UAAsC,CAAC,GAC3B;AACZ,QAAM,qBAAqB,QAAQ,sBAAsB;AACzD,QAAM,iBAAiB,qBAAqB,kBAAkB,QAAQ,sBAAsB,IAAI;AAChG,QAAM,aAAa,qBAAqB,MAAM,qBAAqB,MAAM,IAAI;AAC7E,MAAI,eAAe,SAAS;AAC1B,WAAO,QAAQ,cAAc;AAAA,EAC/B;AAEA,aAAW,cAAc;AAEzB,MAAI;AACF,WAAO,MAAM,SAAS;AAAA,EACxB,SAAS,OAAO;AACd,QAAI,sBAAsB,sBAAsB,KAAK,GAAG;AACtD,aAAO,QAAQ;AAAA,IACjB;AACA,UAAM;AAAA,EACR;AACF;AAEA,eAAe,sBACb,OACA,QACA,MACoC;AACpC,QAAM,SAAS;AAEf,QAAM,cAAc,IAAI,YAAY,EAAE,OAAO,MAAM;AACnD,QAAM,eAAe,YAAY,MAAM,GAAG,EAAE;AAE5C,QAAM,YAAY,OAAO,gBAAgB,IAAI,WAAW,EAAE,CAAC;AAE3D,QAAM,gBAAoD;AAAA,IACxD;AAAA,IACA,IAAI;AAAA,MACF,IAAI;AAAA,MACJ,MAAM;AAAA,IACR;AAAA,IACA,MAAM;AAAA,MACJ,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,aAAa;AAAA,IACf;AAAA,IACA,kBAAkB;AAAA,MAChB,EAAE,MAAM,cAAc,KAAK,GAAG;AAAA,IAChC;AAAA,IACA,wBAAwB;AAAA,MACtB,yBAAyB;AAAA,MACzB,kBAAkB;AAAA,MAClB,aAAa;AAAA,MACb,oBAAoB;AAAA,IACtB;AAAA,IACA,aAAa;AAAA,IACb,SAAS;AAAA,EACX;AAEA,QAAM,aAAc,MAAM,UAAU,YAAY,OAAO;AAAA,IACrD,WAAW;AAAA,EACb,CAAC;AAED,MAAI,CAAC,YAAY;AACf,UAAM,IAAI,MAAM,oCAAoC;AAAA,EACtD;AAEA,QAAM,WAAW,WAAW;AAC5B,QAAM,EAAE,GAAG,EAAE,IAAI,qBAAqB,QAAQ;AAC9C,QAAM,0BAEF,WAGA,2BAA2B;AAE/B,SAAO;AAAA,IACL,kBAAc,+CAAuB,WAAW,KAAK;AAAA,IACrD,gBAAY,mCAAW,CAAC;AAAA,IACxB,gBAAY,mCAAW,CAAC;AAAA,IACxB;AAAA,IACA;AAAA,EACF;AACF;AAEA,eAAe,wBACb,OACA,QACA,MACA,gBACoC;AACpC,QAAM,SAAS,MAAM;AAAA,IACnB;AAAA,IACA,EAAE,OAAO,QAAQ,KAAK;AAAA,IACtB;AAAA,EACF;AACA,SAAO;AACT;AAIA,SAAS,qBACP,UACkC;AAClC,MAAI,OAAO,SAAS,iBAAiB,YAAY;AAC/C,UAAM,UAAU,SAAS,aAAa;AACtC,QAAI,SAAS;AACX,aAAO,gBAAgB,IAAI,WAAW,OAAO,CAAC;AAAA,IAChD;AAAA,EACF;AAEA,MAAI,OAAO,SAAS,yBAAyB,YAAY;AACvD,UAAM,WAAW,IAAI,WAAW,SAAS,qBAAqB,CAAC;AAC/D,WAAO,6BAA6B,QAAQ;AAAA,EAC9C;AAEA,QAAM,IAAI,MAAM,kFAAkF;AACpG;AAEA,SAAS,gBAAgB,MAAoD;AAC3E,QAAM,aAAa,KAAK,SAAS;AAEjC,MAAI,KAAK,UAAU,MAAM,GAAM;AAC7B,UAAM,IAAI,MAAM,kDAAkD;AAAA,EACpE;AAEA,QAAM,IAAI,KAAK,MAAM,aAAa,GAAG,aAAa,EAAE;AACpD,QAAM,IAAI,KAAK,MAAM,aAAa,IAAI,aAAa,EAAE;AAErD,MAAI,EAAE,WAAW,MAAM,EAAE,WAAW,IAAI;AACtC,UAAM,IAAI,MAAM,kDAAkD;AAAA,EACpE;AAEA,SAAO,EAAE,GAAG,EAAE;AAChB;AAEA,SAAS,6BAA6B,UAAwD;AAC5F,QAAM,iBAAiB;AACvB,QAAM,cAAc;AACpB,QAAM,gBAAgB;AACtB,QAAM,SAAS,iBAAiB,cAAc;AAC9C,QAAM,eAAe;AACrB,QAAM,kBAAkB,SAAS;AACjC,QAAM,eAAgB,SAAS,eAAe,KAAK,IAAK,SAAS,kBAAkB,CAAC;AACpF,QAAM,gBAAgB,kBAAkB,IAAI;AAC5C,QAAM,UAAU,SAAS,MAAM,aAAa;AAE5C,SAAO,mBAAmB,OAAO;AACnC;AAEA,SAAS,mBAAmB,SAAuD;AACjF,QAAM,WAAW,QAAQ,CAAC;AAC1B,MAAI,aAAa,OAAQ,aAAa,KAAM;AAC1C,UAAM,IAAI,MAAM,yBAAyB;AAAA,EAC3C;AAEA,MAAI,SAAS;AACb,MAAI,IAAuB;AAC3B,MAAI,IAAuB;AAE3B,SAAO,SAAS,QAAQ,QAAQ;AAC9B,UAAM,MAAM,QAAQ,QAAQ;AAC5B,UAAM,YAAY,QAAQ,QAAQ;AAElC,QAAI,QAAQ,IAAM;AAChB,YAAM,SAAS,YAAY;AAC3B,UAAI,QAAQ,MAAM,QAAQ,SAAS,MAAM;AACzC,gBAAU;AACV;AAAA,IACF;AAEA,QAAI,QAAQ,IAAM;AAChB,YAAM,SAAS,YAAY;AAC3B,UAAI,QAAQ,MAAM,QAAQ,SAAS,MAAM;AACzC,gBAAU;AACV;AAAA,IACF;AAEA,QAAI,aAAa,MAAQ,aAAa,IAAM;AAC1C,YAAM,SAAS,YAAY;AAC3B,gBAAU;AACV;AAAA,IACF;AAEA,QAAI,cAAc,KAAQ,cAAc,KAAQ,cAAc,GAAM;AAClE;AAAA,IACF;AAEA,QAAI,aAAa,MAAQ,aAAa,IAAM;AAC1C,YAAM,OAAO,KAAM,YAAY;AAC/B,gBAAU;AACV;AAAA,IACF;AAAA,EACF;AAEA,MAAI,CAAC,KAAK,CAAC,GAAG;AACZ,UAAM,IAAI,MAAM,mDAAmD;AAAA,EACrE;AAEA,MAAI,EAAE,WAAW,MAAM,EAAE,WAAW,IAAI;AACtC,UAAM,IAAI,MAAM,+CAA+C;AAAA,EACjE;AAEA,SAAO,EAAE,GAAG,EAAE;AAChB;;;AGlPA,IAAM,gBAAgB;AAQf,SAAS,2BACd,WACA,WAAwC,CAAC,GACjC;AACR,SAAO,UAAU,KAAK,KAAK;AAC7B;;;ACHA,IAAAA,0BAOO;AAkBP,eAAsB,gBACpB,cACA,WACA,MAC+B;AAC/B,MAAI,CAAC,oBAAoB,GAAG;AAC1B,UAAM,IAAI,MAAM,2CAA2C;AAAA,EAC7D;AAEA,SAAOC;AAAA,IACL;AAAA,IACA,MAAM,sBAAsB,cAAc,WAAW,IAAI;AAAA,IACzD,CAAC,mBACC,wBAAwB,cAAc,WAAW,MAAM,cAAc;AAAA,EACzE;AACF;AAKA,eAAsB,sBACpB,WACA,MACA,kBACA,aACA,SACA,UAAuC,CAAC,GACH;AACrC,MAAI,CAAC,oBAAoB,GAAG;AAC1B,UAAM,IAAI,MAAM,2CAA2C;AAAA,EAC7D;AAEA,QAAM,qBAAqB,QAAQ,sBAAsB;AACzD,QAAM,iBAAiB,qBACnB,kBAAkB,OAAO,sBAAsB,IAC/C;AACJ,QAAM,aAAa,qBACf,MAAM,qBAAqB,KAAK,IAChC;AACJ,QAAM,gBAAgB;AACtB,QAAM,cAAc,sBAAsB,WAAW;AAErD,MAAI,QAAQ,oBAAoB;AAC9B,eAAW,cAAc;AACzB,WAAO;AAAA,MACL;AAAA,MACA,eAAe,QAAQ;AAAA,MACvB;AAAA,IACF;AAAA,EACF;AAEA,MAAI,eAAe,WAAY,eAAe,CAAC,eAAgB;AAC7D,WAAO,0BAA0B,WAAW,gBAAgB,OAAO;AAAA,EACrE;AAEA,aAAW,cAAc;AAEzB,MAAI;AACF,QAAI,eAAe;AACjB,UAAI;AACF,cAAM,SAAS,MAAM;AAAA,UACnB,cAAc;AAAA,UACd;AAAA,UACA,cAAc;AAAA,QAChB;AACA,eAAO;AAAA,UACL,GAAG;AAAA,UACH,SAAS;AAAA,QACX;AAAA,MACF,SAAS,OAAO;AACd,YAAI,CAAC,6BAA6B,KAAK,GAAG;AACxC,gBAAM;AAAA,QACR;AACA,eAAO;AAAA,UACL;AAAA,UACA,cAAc;AAAA,UACd;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,WAAO,kCAAkC,WAAW,MAAM,WAAW;AAAA,EACvE,SAAS,OAAO;AACd,QAAI,eAAe,sBAAsB,KAAK,GAAG;AAC/C,aAAO,0BAA0B,WAAW,QAAW,OAAO;AAAA,IAChE;AAEA,UAAM;AAAA,EACR;AACF;AAEA,eAAe,kCACb,WACA,MACA,aACqC;AACrC,QAAM,eAAe,MAAM,4BAA4B,WAAW,IAAI;AACtE,QAAM,kBACJ,YAAY,KAAK,CAAC,MAAM,EAAE,iBAAiB,aAAa,YAAY,KACpE;AACF,QAAM,OAAM,oBAAI,KAAK,GAAE,YAAY;AACnC,QAAM,UAAU,mBAAmB;AAAA,IACjC,cAAc,aAAa;AAAA,IAC3B,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,MAAM,aAAa;AAAA,IACnB,WAAW;AAAA,IACX,YAAY;AAAA,EACd;AAEA,SAAO;AAAA,IACL,WAAW,aAAa;AAAA,IACxB,mBAAmB,aAAa;AAAA,IAChC,gBAAgB,aAAa;AAAA,IAC7B,YAAY,aAAa;AAAA,IACzB,YAAY,aAAa;AAAA,IACzB,yBAAyB,aAAa;AAAA,IACtC;AAAA,EACF;AACF;AAEA,SAAS,6BAA6B,OAAyB;AAC7D,QAAM,OACJ,SAAS,OAAO,UAAU,YAAY,UAAU,QAC5C,OAAQ,MAA6B,IAAI,IACzC;AACN,QAAM,UACJ,SAAS,OAAO,UAAU,YAAY,aAAa,QAC/C,OAAQ,MAAgC,OAAO,IAC/C;AACN,QAAM,aAAa,GAAG,IAAI,IAAI,OAAO,GAAG,YAAY;AAEpD,MACE,WAAW,SAAS,eAAe,KACnC,WAAW,SAAS,eAAe,KACnC,WAAW,SAAS,gBAAgB,GACpC;AACA,WAAO;AAAA,EACT;AAEA,SACE,WAAW,SAAS,iBAAiB,KACrC,WAAW,SAAS,mBAAmB,KACvC,WAAW,SAAS,eAAe,KACnC,WAAW,SAAS,WAAW,KAC/B,WAAW,SAAS,YAAY,KAChC,WAAW,SAAS,eAAe,KACnC,WAAW,SAAS,oBAAoB;AAE5C;AAKA,eAAsB,4BACpB,WACA,MAC2C;AAC3C,MAAI,CAAC,oBAAoB,GAAG;AAC1B,UAAM,IAAI,MAAM,2CAA2C;AAAA,EAC7D;AAEA,QAAM,eAAe;AACrB,QAAM,SAAS,MAAM,yBAAyB,WAAW,YAAY;AAErE,SAAO;AAAA,IACL,WAAW,OAAO;AAAA,IAClB,mBAAmB,OAAO;AAAA,IAC1B,gBAAgB,OAAO;AAAA,IACvB,YAAY,OAAO;AAAA,IACnB,YAAY,OAAO;AAAA,IACnB,cAAc,OAAO;AAAA,IACrB,MAAM;AAAA,IACN,yBAAyB,OAAO;AAAA,EAClC;AACF;AAIA,eAAeA,mBACb,QACA,UACA,SACY;AACZ,QAAM,iBAAiB,kBAAkB,QAAQ,sBAAsB;AACvE,QAAM,aAAa,MAAM,qBAAqB,MAAM;AACpD,MAAI,eAAe,SAAS;AAC1B,WAAO,QAAQ,cAAc;AAAA,EAC/B;AAEA,aAAW,cAAc;AAEzB,MAAI;AACF,WAAO,MAAM,SAAS;AAAA,EACxB,SAAS,OAAO;AACd,QAAI,sBAAsB,KAAK,GAAG;AAChC,aAAO,QAAQ;AAAA,IACjB;AACA,UAAM;AAAA,EACR;AACF;AAEA,eAAe,sBACb,cACA,WACA,MAC+B;AAC/B,QAAM,SAAS,MAAM,yBAAyB,WAAW,MAAM,YAAY;AAC3E,SAAO;AAAA,IACL,WAAW,OAAO;AAAA,IAClB,mBAAmB,OAAO;AAAA,IAC1B,gBAAgB,OAAO;AAAA,IACvB,YAAY,OAAO;AAAA,IACnB,YAAY,OAAO;AAAA,IACnB,yBAAyB,OAAO;AAAA,EAClC;AACF;AAEA,eAAe,yBACb,WACA,MACA,cAC0D;AAC1D,QAAM,iBAAiB,IAAI,WAAW,SAAS;AAC/C,QAAM,aAAgD;AAAA,IACpD,WAAW;AAAA,IACX;AAAA,IACA,kBAAkB;AAAA,IAClB,SAAS;AAAA,EACX;AAEA,MAAI,cAAc;AAChB,UAAM,yBAAqB,gDAAuB,YAAY;AAC9D,eAAW,mBAAmB;AAAA,MAC5B;AAAA,QACE,MAAM;AAAA,QACN,IAAI;AAAA,QACJ,YAAY,CAAC,YAAY,UAAU,OAAO,OAAO,KAAK;AAAA,MACxD;AAAA,IACF;AAAA,EACF;AAEA,QAAM,YAAa,MAAM,UAAU,YAAY,IAAI;AAAA,IACjD,WAAW;AAAA,EACb,CAAC;AAED,MAAI,CAAC,WAAW;AACd,UAAM,IAAI,MAAM,sCAAsC;AAAA,EACxD;AAEA,QAAM,WAAW,UAAU;AAE3B,QAAM,YAAY,IAAI,WAAW,SAAS,SAAS;AACnD,MAAI,EAAE,GAAG,EAAE,QAAI,2CAAkB,SAAS;AAC1C,UAAI,uCAAc,CAAC;AAMnB,QAAM,gBAEF,UAGA,2BAA2B;AAE/B,SAAO;AAAA,IACL,WAAW,IAAI,WAAW,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC;AAAA,IACtC,mBAAmB,IAAI,WAAW,SAAS,iBAAiB;AAAA,IAC5D,gBAAgB,IAAI,WAAW,SAAS,cAAc;AAAA,IACtD,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,kBAAc,gDAAuB,UAAU,KAAK;AAAA,IACpD,yBAAyB;AAAA,EAC3B;AACF;AAEA,eAAe,wBACb,cACA,WACA,MACA,gBAC+B;AAC/B,QAAM,SAAS,MAAM;AAAA,IACnB;AAAA,IACA;AAAA,MACE;AAAA,MACA,wBAAoB,0CAAiB,SAAS;AAAA,MAC9C;AAAA,IACF;AAAA,IACA;AAAA,EACF;AAEA,SAAO,yBAAyB,MAAM;AACxC;AAEA,eAAe,0BACb,WACA,gBACA,SACqC;AACrC,QAAM,SAAS,MAAM;AAAA,IACnB;AAAA,IACA;AAAA,MACE,wBAAoB,0CAAiB,SAAS;AAAA,MAC9C;AAAA,IACF;AAAA,IACA;AAAA,EACF;AACA,SAAO,+BAA+B,MAAM;AAC9C;AAEA,SAAS,yBACP,QACsB;AACtB,SAAO;AAAA,IACL,eAAW,0CAAiB,OAAO,kBAAkB;AAAA,IACrD,uBAAmB,0CAAiB,OAAO,0BAA0B;AAAA,IACrE,oBAAgB,0CAAiB,OAAO,uBAAuB;AAAA,IAC/D,gBAAY,0CAAiB,OAAO,mBAAmB;AAAA,IACvD,gBAAY,0CAAiB,OAAO,mBAAmB;AAAA,IACvD,yBAAyB,OAAO,2BAA2B;AAAA,EAC7D;AACF;AAEA,SAAS,+BACP,QAC4B;AAC5B,SAAO;AAAA,IACL,GAAG,yBAAyB,MAAM;AAAA,IAClC,SAAS,OAAO;AAAA,IAChB,UAAU,OAAO;AAAA,EACnB;AACF;;;AL1VA,IAAAC,0BAQO;AAYP,IAAAA,0BAWO;","names":["import_passkey_manager","runWithPromptMode","import_passkey_manager"]}
package/dist/web.d.cts CHANGED
@@ -1,12 +1,19 @@
1
- import { b as PasskeyPopupContext, P as PasskeyStoredSigningResult, a as PasskeyClientCapabilities } from './types-_HRzmn-j.cjs';
2
- export { c as PasskeyPopupAccount } from './types-_HRzmn-j.cjs';
3
- import { PasskeyRegistrationResult, PasskeySigningResult, PasskeyMetadata, PasskeyDiscoverableSigningResult } from '@thru/passkey-manager';
4
- export { P256_HALF_N, P256_N, PasskeyDiscoverableSigningResult, PasskeyMetadata, PasskeyRegistrationResult, PasskeySigningResult, arrayBufferToBase64Url, base64UrlToArrayBuffer, base64UrlToBytes, bigIntToBytesBE, bytesEqual, bytesToBase64, bytesToBase64Url, bytesToBigIntBE, bytesToHex, compareBytes, hexToBytes, normalizeLowS, normalizeSignatureComponent, parseDerSignature, uniqueAccounts } from '@thru/passkey-manager';
1
+ import { n as PasskeyRegistrationOptions, c as PasskeyPopupContext, o as PasskeyStoredSigningOptions, p as PasskeyStoredSigningResult, P as PasskeyClientCapabilities } from './types-BTTlCVrw.cjs';
2
+ export { a as PasskeyPopupAccount } from './types-BTTlCVrw.cjs';
3
+ import { PasskeyRegistrationResult, PasskeyDiscoverableSigningResult, PasskeySigningResult, PasskeyMetadata } from '@thru/programs/passkey-manager';
4
+ export { P256_HALF_N, P256_N, PasskeyDiscoverableSigningResult, PasskeyMetadata, PasskeyRegistrationResult, PasskeySigningResult, arrayBufferToBase64Url, base64UrlToArrayBuffer, base64UrlToBytes, bigIntToBytesBE, bytesEqual, bytesToBase64, bytesToBase64Url, bytesToBigIntBE, bytesToHex, compareBytes, hexToBytes, normalizeLowS, normalizeSignatureComponent, parseDerSignature, uniqueAccounts } from '@thru/programs/passkey-manager';
5
5
 
6
6
  /**
7
7
  * Register a new passkey for a profile.
8
8
  */
9
- declare function registerPasskey(alias: string, userId: string, rpId: string): Promise<PasskeyRegistrationResult>;
9
+ declare function registerPasskey(alias: string, userId: string, rpId: string, options?: PasskeyRegistrationOptions): Promise<PasskeyRegistrationResult>;
10
+
11
+ interface DistinctPasskeyLabelOptions {
12
+ existingLabels?: Iterable<string | null | undefined>;
13
+ maxAttempts?: number;
14
+ suffixFactory?: () => string;
15
+ }
16
+ declare function createDistinctPasskeyLabel(baseLabel: string, _options?: DistinctPasskeyLabelOptions): string;
10
17
 
11
18
  /**
12
19
  * Sign a challenge with an existing passkey (by credential ID).
@@ -15,7 +22,7 @@ declare function signWithPasskey(credentialId: string, challenge: Uint8Array, rp
15
22
  /**
16
23
  * Sign with stored passkey (for embedded/popup contexts).
17
24
  */
18
- declare function signWithStoredPasskey(challenge: Uint8Array, rpId: string, preferredPasskey: PasskeyMetadata | null, allPasskeys: PasskeyMetadata[], context?: PasskeyPopupContext): Promise<PasskeyStoredSigningResult>;
25
+ declare function signWithStoredPasskey(challenge: Uint8Array, rpId: string, preferredPasskey: PasskeyMetadata | null, allPasskeys: PasskeyMetadata[], context?: PasskeyPopupContext, options?: PasskeyStoredSigningOptions): Promise<PasskeyStoredSigningResult>;
19
26
  /**
20
27
  * Sign with a discoverable passkey (no credential ID - browser prompts user to select).
21
28
  */
@@ -29,4 +36,4 @@ declare function isInIframe(): boolean;
29
36
  type PasskeyPromptAction = 'get' | 'create';
30
37
  declare function shouldUsePasskeyPopup(action: PasskeyPromptAction): Promise<boolean>;
31
38
 
32
- export { PasskeyClientCapabilities, PasskeyPopupContext, type PasskeyPromptAction, PasskeyStoredSigningResult, getCachedPasskeyClientCapabilities, getPasskeyClientCapabilities, isInIframe, isWebAuthnSupported, preloadPasskeyClientCapabilities, registerPasskey, shouldUsePasskeyPopup, signWithDiscoverablePasskey, signWithPasskey, signWithStoredPasskey };
39
+ export { type DistinctPasskeyLabelOptions, PasskeyClientCapabilities, PasskeyPopupContext, type PasskeyPromptAction, PasskeyRegistrationOptions, PasskeyStoredSigningOptions, PasskeyStoredSigningResult, createDistinctPasskeyLabel, getCachedPasskeyClientCapabilities, getPasskeyClientCapabilities, isInIframe, isWebAuthnSupported, preloadPasskeyClientCapabilities, registerPasskey, shouldUsePasskeyPopup, signWithDiscoverablePasskey, signWithPasskey, signWithStoredPasskey };
package/dist/web.d.ts CHANGED
@@ -1,12 +1,19 @@
1
- import { b as PasskeyPopupContext, P as PasskeyStoredSigningResult, a as PasskeyClientCapabilities } from './types-_HRzmn-j.js';
2
- export { c as PasskeyPopupAccount } from './types-_HRzmn-j.js';
3
- import { PasskeyRegistrationResult, PasskeySigningResult, PasskeyMetadata, PasskeyDiscoverableSigningResult } from '@thru/passkey-manager';
4
- export { P256_HALF_N, P256_N, PasskeyDiscoverableSigningResult, PasskeyMetadata, PasskeyRegistrationResult, PasskeySigningResult, arrayBufferToBase64Url, base64UrlToArrayBuffer, base64UrlToBytes, bigIntToBytesBE, bytesEqual, bytesToBase64, bytesToBase64Url, bytesToBigIntBE, bytesToHex, compareBytes, hexToBytes, normalizeLowS, normalizeSignatureComponent, parseDerSignature, uniqueAccounts } from '@thru/passkey-manager';
1
+ import { n as PasskeyRegistrationOptions, c as PasskeyPopupContext, o as PasskeyStoredSigningOptions, p as PasskeyStoredSigningResult, P as PasskeyClientCapabilities } from './types-BTTlCVrw.js';
2
+ export { a as PasskeyPopupAccount } from './types-BTTlCVrw.js';
3
+ import { PasskeyRegistrationResult, PasskeyDiscoverableSigningResult, PasskeySigningResult, PasskeyMetadata } from '@thru/programs/passkey-manager';
4
+ export { P256_HALF_N, P256_N, PasskeyDiscoverableSigningResult, PasskeyMetadata, PasskeyRegistrationResult, PasskeySigningResult, arrayBufferToBase64Url, base64UrlToArrayBuffer, base64UrlToBytes, bigIntToBytesBE, bytesEqual, bytesToBase64, bytesToBase64Url, bytesToBigIntBE, bytesToHex, compareBytes, hexToBytes, normalizeLowS, normalizeSignatureComponent, parseDerSignature, uniqueAccounts } from '@thru/programs/passkey-manager';
5
5
 
6
6
  /**
7
7
  * Register a new passkey for a profile.
8
8
  */
9
- declare function registerPasskey(alias: string, userId: string, rpId: string): Promise<PasskeyRegistrationResult>;
9
+ declare function registerPasskey(alias: string, userId: string, rpId: string, options?: PasskeyRegistrationOptions): Promise<PasskeyRegistrationResult>;
10
+
11
+ interface DistinctPasskeyLabelOptions {
12
+ existingLabels?: Iterable<string | null | undefined>;
13
+ maxAttempts?: number;
14
+ suffixFactory?: () => string;
15
+ }
16
+ declare function createDistinctPasskeyLabel(baseLabel: string, _options?: DistinctPasskeyLabelOptions): string;
10
17
 
11
18
  /**
12
19
  * Sign a challenge with an existing passkey (by credential ID).
@@ -15,7 +22,7 @@ declare function signWithPasskey(credentialId: string, challenge: Uint8Array, rp
15
22
  /**
16
23
  * Sign with stored passkey (for embedded/popup contexts).
17
24
  */
18
- declare function signWithStoredPasskey(challenge: Uint8Array, rpId: string, preferredPasskey: PasskeyMetadata | null, allPasskeys: PasskeyMetadata[], context?: PasskeyPopupContext): Promise<PasskeyStoredSigningResult>;
25
+ declare function signWithStoredPasskey(challenge: Uint8Array, rpId: string, preferredPasskey: PasskeyMetadata | null, allPasskeys: PasskeyMetadata[], context?: PasskeyPopupContext, options?: PasskeyStoredSigningOptions): Promise<PasskeyStoredSigningResult>;
19
26
  /**
20
27
  * Sign with a discoverable passkey (no credential ID - browser prompts user to select).
21
28
  */
@@ -29,4 +36,4 @@ declare function isInIframe(): boolean;
29
36
  type PasskeyPromptAction = 'get' | 'create';
30
37
  declare function shouldUsePasskeyPopup(action: PasskeyPromptAction): Promise<boolean>;
31
38
 
32
- export { PasskeyClientCapabilities, PasskeyPopupContext, type PasskeyPromptAction, PasskeyStoredSigningResult, getCachedPasskeyClientCapabilities, getPasskeyClientCapabilities, isInIframe, isWebAuthnSupported, preloadPasskeyClientCapabilities, registerPasskey, shouldUsePasskeyPopup, signWithDiscoverablePasskey, signWithPasskey, signWithStoredPasskey };
39
+ export { type DistinctPasskeyLabelOptions, PasskeyClientCapabilities, PasskeyPopupContext, type PasskeyPromptAction, PasskeyRegistrationOptions, PasskeyStoredSigningOptions, PasskeyStoredSigningResult, createDistinctPasskeyLabel, getCachedPasskeyClientCapabilities, getPasskeyClientCapabilities, isInIframe, isWebAuthnSupported, preloadPasskeyClientCapabilities, registerPasskey, shouldUsePasskeyPopup, signWithDiscoverablePasskey, signWithPasskey, signWithStoredPasskey };
package/dist/web.js CHANGED
@@ -11,6 +11,7 @@ import {
11
11
  bytesToBigIntBE,
12
12
  bytesToHex,
13
13
  compareBytes,
14
+ createDistinctPasskeyLabel,
14
15
  getCachedPasskeyClientCapabilities,
15
16
  getPasskeyClientCapabilities,
16
17
  hexToBytes,
@@ -26,7 +27,7 @@ import {
26
27
  signWithPasskey,
27
28
  signWithStoredPasskey,
28
29
  uniqueAccounts
29
- } from "./chunk-B5SN7AS7.js";
30
+ } from "./chunk-TW7HANJM.js";
30
31
  import "./chunk-LNDWK3FA.js";
31
32
  export {
32
33
  P256_HALF_N,
@@ -41,6 +42,7 @@ export {
41
42
  bytesToBigIntBE,
42
43
  bytesToHex,
43
44
  compareBytes,
45
+ createDistinctPasskeyLabel,
44
46
  getCachedPasskeyClientCapabilities,
45
47
  getPasskeyClientCapabilities,
46
48
  hexToBytes,