@tatchi-xyz/sdk 0.16.0 → 0.17.0

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 (470) hide show
  1. package/dist/cjs/core/EmailRecovery/index.js +12 -5
  2. package/dist/cjs/core/EmailRecovery/index.js.map +1 -1
  3. package/dist/cjs/core/IndexedDBManager/passkeyClientDB.js +35 -36
  4. package/dist/cjs/core/IndexedDBManager/passkeyClientDB.js.map +1 -1
  5. package/dist/cjs/core/NearClient.js +2 -1
  6. package/dist/cjs/core/NearClient.js.map +1 -1
  7. package/dist/cjs/core/TatchiPasskey/emailRecovery.js +136 -27
  8. package/dist/cjs/core/TatchiPasskey/emailRecovery.js.map +1 -1
  9. package/dist/cjs/core/TatchiPasskey/faucets/createAccountRelayServer.js +1 -0
  10. package/dist/cjs/core/TatchiPasskey/faucets/createAccountRelayServer.js.map +1 -1
  11. package/dist/cjs/core/TatchiPasskey/index.js +25 -0
  12. package/dist/cjs/core/TatchiPasskey/index.js.map +1 -1
  13. package/dist/cjs/core/TatchiPasskey/linkDevice.js +2 -0
  14. package/dist/cjs/core/TatchiPasskey/linkDevice.js.map +1 -1
  15. package/dist/cjs/core/TatchiPasskey/login.js +15 -4
  16. package/dist/cjs/core/TatchiPasskey/login.js.map +1 -1
  17. package/dist/cjs/core/TatchiPasskey/recoverAccount.js +1 -0
  18. package/dist/cjs/core/TatchiPasskey/recoverAccount.js.map +1 -1
  19. package/dist/cjs/core/TatchiPasskey/scanDevice.js +1 -0
  20. package/dist/cjs/core/TatchiPasskey/scanDevice.js.map +1 -1
  21. package/dist/cjs/core/WalletIframe/client/IframeTransport.js +10 -0
  22. package/dist/cjs/core/WalletIframe/client/IframeTransport.js.map +1 -1
  23. package/dist/cjs/core/WalletIframe/client/router.js +9 -0
  24. package/dist/cjs/core/WalletIframe/client/router.js.map +1 -1
  25. package/dist/cjs/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-drawer.js +1 -1
  26. package/dist/cjs/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-drawer.js.map +1 -1
  27. package/dist/cjs/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-modal.js +52 -52
  28. package/dist/cjs/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-modal.js.map +1 -1
  29. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/getDeviceNumber.js +10 -1
  30. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/getDeviceNumber.js.map +1 -1
  31. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/checkCanRegisterUser.js +1 -0
  32. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/checkCanRegisterUser.js.map +1 -1
  33. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/decryptPrivateKeyWithPrf.js +1 -0
  34. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/decryptPrivateKeyWithPrf.js.map +1 -1
  35. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/deriveNearKeypairAndEncryptFromSerialized.js +1 -0
  36. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/deriveNearKeypairAndEncryptFromSerialized.js.map +1 -1
  37. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/exportNearKeypairUi.js +1 -0
  38. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/exportNearKeypairUi.js.map +1 -1
  39. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/registerDevice2WithDerivedKey.js +2 -1
  40. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/registerDevice2WithDerivedKey.js.map +1 -1
  41. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/signDelegateAction.js +1 -0
  42. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/signDelegateAction.js.map +1 -1
  43. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/signNep413Message.js +1 -0
  44. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/signNep413Message.js.map +1 -1
  45. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/signTransactionsWithActions.js +1 -0
  46. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/signTransactionsWithActions.js.map +1 -1
  47. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/validation.js +2 -0
  48. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/validation.js.map +1 -1
  49. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/index.js +1 -0
  50. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/index.js.map +1 -1
  51. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/vrf.js +1 -0
  52. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/vrf.js.map +1 -1
  53. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/webauthn.js +6 -0
  54. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/webauthn.js.map +1 -1
  55. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/determineConfirmationConfig.js +2 -1
  56. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/determineConfirmationConfig.js.map +1 -1
  57. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/localOnly.js +1 -0
  58. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/localOnly.js.map +1 -1
  59. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/registration.js +1 -0
  60. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/registration.js.map +1 -1
  61. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/transactions.js +4 -15
  62. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/transactions.js.map +1 -1
  63. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/handlers/deriveVrfKeypairFromPrf.js +1 -0
  64. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/handlers/deriveVrfKeypairFromPrf.js.map +1 -1
  65. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfChallenge.js +1 -0
  66. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfChallenge.js.map +1 -1
  67. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfKeypairBootstrap.js +1 -0
  68. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfKeypairBootstrap.js.map +1 -1
  69. package/dist/cjs/core/WebAuthnManager/WebAuthnFallbacks/index.js +17 -0
  70. package/dist/cjs/core/WebAuthnManager/WebAuthnFallbacks/index.js.map +1 -0
  71. package/dist/cjs/core/WebAuthnManager/WebAuthnFallbacks/safari-fallbacks.js +64 -54
  72. package/dist/cjs/core/WebAuthnManager/WebAuthnFallbacks/safari-fallbacks.js.map +1 -1
  73. package/dist/cjs/core/WebAuthnManager/credentialsHelpers.js +12 -2
  74. package/dist/cjs/core/WebAuthnManager/credentialsHelpers.js.map +1 -1
  75. package/dist/cjs/core/WebAuthnManager/index.js +6 -1
  76. package/dist/cjs/core/WebAuthnManager/index.js.map +1 -1
  77. package/dist/cjs/core/WebAuthnManager/touchIdPrompt.js +209 -201
  78. package/dist/cjs/core/WebAuthnManager/touchIdPrompt.js.map +1 -1
  79. package/dist/cjs/core/WebAuthnManager/userHandle.js +2 -1
  80. package/dist/cjs/core/WebAuthnManager/userHandle.js.map +1 -1
  81. package/dist/cjs/core/defaultConfigs.js +1 -1
  82. package/dist/cjs/core/defaultConfigs.js.map +1 -1
  83. package/dist/cjs/core/types/vrf-worker.js +10 -1
  84. package/dist/cjs/core/types/vrf-worker.js.map +1 -1
  85. package/dist/cjs/react/components/AccountMenuButton/{LinkedDevicesModal-STvIsylA.css → LinkedDevicesModal-B6api181.css} +1 -1
  86. package/dist/{esm/react/components/AccountMenuButton/LinkedDevicesModal-STvIsylA.css.map → cjs/react/components/AccountMenuButton/LinkedDevicesModal-B6api181.css.map} +1 -1
  87. package/dist/cjs/react/components/AccountMenuButton/{ProfileDropdown-iARgUwK1.css → ProfileDropdown-B-DrG_u5.css} +1 -1
  88. package/dist/{esm/react/components/AccountMenuButton/ProfileDropdown-iARgUwK1.css.map → cjs/react/components/AccountMenuButton/ProfileDropdown-B-DrG_u5.css.map} +1 -1
  89. package/dist/cjs/react/components/AccountMenuButton/{Web3AuthProfileButton-Db3NeoAC.css → Web3AuthProfileButton-BnZDUeCL.css} +1 -1
  90. package/dist/cjs/react/components/AccountMenuButton/{Web3AuthProfileButton-Db3NeoAC.css.map → Web3AuthProfileButton-BnZDUeCL.css.map} +1 -1
  91. package/dist/cjs/react/components/AccountMenuButton/icons/{TouchIcon-BXM5NR4A.css → TouchIcon-CAGCi8MY.css} +1 -1
  92. package/dist/cjs/react/components/AccountMenuButton/icons/{TouchIcon-BXM5NR4A.css.map → TouchIcon-CAGCi8MY.css.map} +1 -1
  93. package/dist/cjs/react/components/PasskeyAuthMenu/{PasskeyAuthMenu-De1qTSmU.css → PasskeyAuthMenu-CNNxVj4L.css} +14 -1
  94. package/dist/cjs/react/components/PasskeyAuthMenu/{PasskeyAuthMenu-De1qTSmU.css.map → PasskeyAuthMenu-CNNxVj4L.css.map} +1 -1
  95. package/dist/cjs/react/components/PasskeyAuthMenu/ui/EmailRecoverySlide.js +122 -53
  96. package/dist/cjs/react/components/PasskeyAuthMenu/ui/EmailRecoverySlide.js.map +1 -1
  97. package/dist/cjs/react/components/{ShowQRCode-DCnR__fx.css → ShowQRCode-nZhZSaba.css} +1 -1
  98. package/dist/cjs/react/components/{ShowQRCode-DCnR__fx.css.map → ShowQRCode-nZhZSaba.css.map} +1 -1
  99. package/dist/cjs/react/deviceDetection.js +75 -92
  100. package/dist/cjs/react/deviceDetection.js.map +1 -1
  101. package/dist/cjs/react/hooks/usePreconnectWalletAssets.js +32 -27
  102. package/dist/cjs/react/hooks/usePreconnectWalletAssets.js.map +1 -1
  103. package/dist/cjs/react/hooks/useQRCamera.js +1 -0
  104. package/dist/cjs/react/hooks/useQRCamera.js.map +1 -1
  105. package/dist/cjs/react/sdk/src/core/EmailRecovery/index.js +12 -5
  106. package/dist/cjs/react/sdk/src/core/EmailRecovery/index.js.map +1 -1
  107. package/dist/cjs/react/sdk/src/core/IndexedDBManager/passkeyClientDB.js +35 -36
  108. package/dist/cjs/react/sdk/src/core/IndexedDBManager/passkeyClientDB.js.map +1 -1
  109. package/dist/cjs/react/sdk/src/core/NearClient.js +2 -1
  110. package/dist/cjs/react/sdk/src/core/NearClient.js.map +1 -1
  111. package/dist/cjs/react/sdk/src/core/TatchiPasskey/emailRecovery.js +136 -27
  112. package/dist/cjs/react/sdk/src/core/TatchiPasskey/emailRecovery.js.map +1 -1
  113. package/dist/cjs/react/sdk/src/core/TatchiPasskey/faucets/createAccountRelayServer.js +1 -0
  114. package/dist/cjs/react/sdk/src/core/TatchiPasskey/faucets/createAccountRelayServer.js.map +1 -1
  115. package/dist/cjs/react/sdk/src/core/TatchiPasskey/index.js +25 -0
  116. package/dist/cjs/react/sdk/src/core/TatchiPasskey/index.js.map +1 -1
  117. package/dist/cjs/react/sdk/src/core/TatchiPasskey/linkDevice.js +2 -0
  118. package/dist/cjs/react/sdk/src/core/TatchiPasskey/linkDevice.js.map +1 -1
  119. package/dist/cjs/react/sdk/src/core/TatchiPasskey/login.js +15 -4
  120. package/dist/cjs/react/sdk/src/core/TatchiPasskey/login.js.map +1 -1
  121. package/dist/cjs/react/sdk/src/core/TatchiPasskey/recoverAccount.js +1 -0
  122. package/dist/cjs/react/sdk/src/core/TatchiPasskey/recoverAccount.js.map +1 -1
  123. package/dist/cjs/react/sdk/src/core/TatchiPasskey/scanDevice.js +1 -0
  124. package/dist/cjs/react/sdk/src/core/TatchiPasskey/scanDevice.js.map +1 -1
  125. package/dist/cjs/react/sdk/src/core/WalletIframe/client/IframeTransport.js +10 -0
  126. package/dist/cjs/react/sdk/src/core/WalletIframe/client/IframeTransport.js.map +1 -1
  127. package/dist/cjs/react/sdk/src/core/WalletIframe/client/router.js +9 -0
  128. package/dist/cjs/react/sdk/src/core/WalletIframe/client/router.js.map +1 -1
  129. package/dist/cjs/react/sdk/src/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-drawer.js +1 -1
  130. package/dist/cjs/react/sdk/src/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-drawer.js.map +1 -1
  131. package/dist/cjs/react/sdk/src/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-modal.js +52 -52
  132. package/dist/cjs/react/sdk/src/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-modal.js.map +1 -1
  133. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/getDeviceNumber.js +10 -1
  134. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/getDeviceNumber.js.map +1 -1
  135. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/checkCanRegisterUser.js +1 -0
  136. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/checkCanRegisterUser.js.map +1 -1
  137. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/decryptPrivateKeyWithPrf.js +1 -0
  138. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/decryptPrivateKeyWithPrf.js.map +1 -1
  139. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/deriveNearKeypairAndEncryptFromSerialized.js +1 -0
  140. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/deriveNearKeypairAndEncryptFromSerialized.js.map +1 -1
  141. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/exportNearKeypairUi.js +1 -0
  142. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/exportNearKeypairUi.js.map +1 -1
  143. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/registerDevice2WithDerivedKey.js +2 -1
  144. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/registerDevice2WithDerivedKey.js.map +1 -1
  145. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/signDelegateAction.js +1 -0
  146. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/signDelegateAction.js.map +1 -1
  147. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/signNep413Message.js +1 -0
  148. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/signNep413Message.js.map +1 -1
  149. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/signTransactionsWithActions.js +1 -0
  150. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/signTransactionsWithActions.js.map +1 -1
  151. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/validation.js +2 -0
  152. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/validation.js.map +1 -1
  153. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/index.js +1 -0
  154. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/index.js.map +1 -1
  155. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/vrf.js +1 -0
  156. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/vrf.js.map +1 -1
  157. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/webauthn.js +6 -0
  158. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/webauthn.js.map +1 -1
  159. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/determineConfirmationConfig.js +2 -1
  160. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/determineConfirmationConfig.js.map +1 -1
  161. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/localOnly.js +1 -0
  162. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/localOnly.js.map +1 -1
  163. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/registration.js +1 -0
  164. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/registration.js.map +1 -1
  165. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/transactions.js +4 -15
  166. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/transactions.js.map +1 -1
  167. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/handlers/deriveVrfKeypairFromPrf.js +1 -0
  168. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/handlers/deriveVrfKeypairFromPrf.js.map +1 -1
  169. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfChallenge.js +1 -0
  170. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfChallenge.js.map +1 -1
  171. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfKeypairBootstrap.js +1 -0
  172. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfKeypairBootstrap.js.map +1 -1
  173. package/dist/cjs/react/sdk/src/core/WebAuthnManager/WebAuthnFallbacks/index.js +17 -0
  174. package/dist/cjs/react/sdk/src/core/WebAuthnManager/WebAuthnFallbacks/index.js.map +1 -0
  175. package/dist/cjs/react/sdk/src/core/WebAuthnManager/WebAuthnFallbacks/safari-fallbacks.js +64 -54
  176. package/dist/cjs/react/sdk/src/core/WebAuthnManager/WebAuthnFallbacks/safari-fallbacks.js.map +1 -1
  177. package/dist/cjs/react/sdk/src/core/WebAuthnManager/credentialsHelpers.js +12 -2
  178. package/dist/cjs/react/sdk/src/core/WebAuthnManager/credentialsHelpers.js.map +1 -1
  179. package/dist/cjs/react/sdk/src/core/WebAuthnManager/index.js +6 -1
  180. package/dist/cjs/react/sdk/src/core/WebAuthnManager/index.js.map +1 -1
  181. package/dist/cjs/react/sdk/src/core/WebAuthnManager/touchIdPrompt.js +209 -201
  182. package/dist/cjs/react/sdk/src/core/WebAuthnManager/touchIdPrompt.js.map +1 -1
  183. package/dist/cjs/react/sdk/src/core/WebAuthnManager/userHandle.js +2 -1
  184. package/dist/cjs/react/sdk/src/core/WebAuthnManager/userHandle.js.map +1 -1
  185. package/dist/cjs/react/sdk/src/core/defaultConfigs.js +1 -1
  186. package/dist/cjs/react/sdk/src/core/defaultConfigs.js.map +1 -1
  187. package/dist/cjs/react/sdk/src/core/types/vrf-worker.js +10 -1
  188. package/dist/cjs/react/sdk/src/core/types/vrf-worker.js.map +1 -1
  189. package/dist/cjs/react/sdk/src/utils/index.js +13 -3
  190. package/dist/cjs/server/email-recovery/emailEncryptor.js +11 -0
  191. package/dist/cjs/server/email-recovery/emailEncryptor.js.map +1 -1
  192. package/dist/cjs/server/email-recovery/emailParsers.js +57 -0
  193. package/dist/cjs/server/email-recovery/emailParsers.js.map +1 -1
  194. package/dist/cjs/server/email-recovery/index.js +1 -1
  195. package/dist/cjs/server/email-recovery/index.js.map +1 -1
  196. package/dist/cjs/server/email-recovery/rpcCalls.js +14 -1
  197. package/dist/cjs/server/email-recovery/rpcCalls.js.map +1 -1
  198. package/dist/cjs/server/index.js +1 -0
  199. package/dist/cjs/server/router/cloudflare.js.map +1 -1
  200. package/dist/cjs/server/router/express.js.map +1 -1
  201. package/dist/cjs/server/sdk/src/core/defaultConfigs.js +1 -1
  202. package/dist/cjs/server/sdk/src/core/defaultConfigs.js.map +1 -1
  203. package/dist/cjs/utils/index.js +13 -3
  204. package/dist/esm/core/EmailRecovery/index.js +12 -5
  205. package/dist/esm/core/EmailRecovery/index.js.map +1 -1
  206. package/dist/esm/core/IndexedDBManager/passkeyClientDB.js +35 -36
  207. package/dist/esm/core/IndexedDBManager/passkeyClientDB.js.map +1 -1
  208. package/dist/esm/core/NearClient.js +2 -1
  209. package/dist/esm/core/NearClient.js.map +1 -1
  210. package/dist/esm/core/TatchiPasskey/emailRecovery.js +136 -27
  211. package/dist/esm/core/TatchiPasskey/emailRecovery.js.map +1 -1
  212. package/dist/esm/core/TatchiPasskey/faucets/createAccountRelayServer.js +2 -1
  213. package/dist/esm/core/TatchiPasskey/faucets/createAccountRelayServer.js.map +1 -1
  214. package/dist/esm/core/TatchiPasskey/index.js +26 -1
  215. package/dist/esm/core/TatchiPasskey/index.js.map +1 -1
  216. package/dist/esm/core/TatchiPasskey/linkDevice.js +4 -2
  217. package/dist/esm/core/TatchiPasskey/linkDevice.js.map +1 -1
  218. package/dist/esm/core/TatchiPasskey/login.js +13 -7
  219. package/dist/esm/core/TatchiPasskey/login.js.map +1 -1
  220. package/dist/esm/core/TatchiPasskey/recoverAccount.js +2 -1
  221. package/dist/esm/core/TatchiPasskey/recoverAccount.js.map +1 -1
  222. package/dist/esm/core/TatchiPasskey/scanDevice.js +2 -1
  223. package/dist/esm/core/TatchiPasskey/scanDevice.js.map +1 -1
  224. package/dist/esm/core/WalletIframe/client/IframeTransport.js +11 -1
  225. package/dist/esm/core/WalletIframe/client/IframeTransport.js.map +1 -1
  226. package/dist/esm/core/WalletIframe/client/router.js +9 -0
  227. package/dist/esm/core/WalletIframe/client/router.js.map +1 -1
  228. package/dist/esm/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-drawer.js +1 -1
  229. package/dist/esm/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-drawer.js.map +1 -1
  230. package/dist/esm/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-modal.js +52 -52
  231. package/dist/esm/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-modal.js.map +1 -1
  232. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/getDeviceNumber.js +6 -2
  233. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/checkCanRegisterUser.js +2 -1
  234. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/checkCanRegisterUser.js.map +1 -1
  235. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/decryptPrivateKeyWithPrf.js +2 -1
  236. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/decryptPrivateKeyWithPrf.js.map +1 -1
  237. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/deriveNearKeypairAndEncryptFromSerialized.js +2 -1
  238. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/deriveNearKeypairAndEncryptFromSerialized.js.map +1 -1
  239. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/exportNearKeypairUi.js +2 -1
  240. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/exportNearKeypairUi.js.map +1 -1
  241. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/registerDevice2WithDerivedKey.js +2 -1
  242. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/registerDevice2WithDerivedKey.js.map +1 -1
  243. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/signDelegateAction.js +2 -1
  244. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/signDelegateAction.js.map +1 -1
  245. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/signNep413Message.js +2 -1
  246. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/signNep413Message.js.map +1 -1
  247. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/signTransactionsWithActions.js +2 -1
  248. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/signTransactionsWithActions.js.map +1 -1
  249. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/validation.js +4 -2
  250. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/validation.js.map +1 -1
  251. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/index.js +2 -1
  252. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/index.js.map +1 -1
  253. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/vrf.js +1 -0
  254. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/vrf.js.map +1 -1
  255. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/webauthn.js +8 -2
  256. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/webauthn.js.map +1 -1
  257. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/determineConfirmationConfig.js +2 -1
  258. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/determineConfirmationConfig.js.map +1 -1
  259. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/localOnly.js +2 -1
  260. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/localOnly.js.map +1 -1
  261. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/registration.js +2 -1
  262. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/registration.js.map +1 -1
  263. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/transactions.js +5 -16
  264. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/transactions.js.map +1 -1
  265. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/handlers/deriveVrfKeypairFromPrf.js +2 -1
  266. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/handlers/deriveVrfKeypairFromPrf.js.map +1 -1
  267. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfChallenge.js +2 -1
  268. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfChallenge.js.map +1 -1
  269. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfKeypairBootstrap.js +2 -1
  270. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfKeypairBootstrap.js.map +1 -1
  271. package/dist/esm/core/WebAuthnManager/WebAuthnFallbacks/index.js +12 -0
  272. package/dist/esm/core/WebAuthnManager/WebAuthnFallbacks/index.js.map +1 -0
  273. package/dist/esm/core/WebAuthnManager/WebAuthnFallbacks/safari-fallbacks.js +61 -55
  274. package/dist/esm/core/WebAuthnManager/WebAuthnFallbacks/safari-fallbacks.js.map +1 -1
  275. package/dist/esm/core/WebAuthnManager/credentialsHelpers.js +8 -3
  276. package/dist/esm/core/WebAuthnManager/index.js +8 -3
  277. package/dist/esm/core/WebAuthnManager/index.js.map +1 -1
  278. package/dist/esm/core/WebAuthnManager/touchIdPrompt.js +207 -204
  279. package/dist/esm/core/WebAuthnManager/touchIdPrompt.js.map +1 -1
  280. package/dist/esm/core/WebAuthnManager/userHandle.js +2 -1
  281. package/dist/esm/core/WebAuthnManager/userHandle.js.map +1 -1
  282. package/dist/esm/core/defaultConfigs.js +1 -1
  283. package/dist/esm/core/defaultConfigs.js.map +1 -1
  284. package/dist/esm/core/types/vrf-worker.js +6 -2
  285. package/dist/esm/react/components/AccountMenuButton/{LinkedDevicesModal-STvIsylA.css → LinkedDevicesModal-B6api181.css} +1 -1
  286. package/dist/{cjs/react/components/AccountMenuButton/LinkedDevicesModal-STvIsylA.css.map → esm/react/components/AccountMenuButton/LinkedDevicesModal-B6api181.css.map} +1 -1
  287. package/dist/esm/react/components/AccountMenuButton/{ProfileDropdown-iARgUwK1.css → ProfileDropdown-B-DrG_u5.css} +1 -1
  288. package/dist/{cjs/react/components/AccountMenuButton/ProfileDropdown-iARgUwK1.css.map → esm/react/components/AccountMenuButton/ProfileDropdown-B-DrG_u5.css.map} +1 -1
  289. package/dist/esm/react/components/AccountMenuButton/{Web3AuthProfileButton-Db3NeoAC.css → Web3AuthProfileButton-BnZDUeCL.css} +1 -1
  290. package/dist/esm/react/components/AccountMenuButton/{Web3AuthProfileButton-Db3NeoAC.css.map → Web3AuthProfileButton-BnZDUeCL.css.map} +1 -1
  291. package/dist/esm/react/components/AccountMenuButton/icons/{TouchIcon-BXM5NR4A.css → TouchIcon-CAGCi8MY.css} +1 -1
  292. package/dist/esm/react/components/AccountMenuButton/icons/{TouchIcon-BXM5NR4A.css.map → TouchIcon-CAGCi8MY.css.map} +1 -1
  293. package/dist/esm/react/components/PasskeyAuthMenu/{PasskeyAuthMenu-De1qTSmU.css → PasskeyAuthMenu-CNNxVj4L.css} +14 -1
  294. package/dist/esm/react/components/PasskeyAuthMenu/{PasskeyAuthMenu-De1qTSmU.css.map → PasskeyAuthMenu-CNNxVj4L.css.map} +1 -1
  295. package/dist/esm/react/components/PasskeyAuthMenu/ui/EmailRecoverySlide.js +123 -54
  296. package/dist/esm/react/components/PasskeyAuthMenu/ui/EmailRecoverySlide.js.map +1 -1
  297. package/dist/esm/react/components/{ShowQRCode-DCnR__fx.css → ShowQRCode-nZhZSaba.css} +1 -1
  298. package/dist/esm/react/components/{ShowQRCode-DCnR__fx.css.map → ShowQRCode-nZhZSaba.css.map} +1 -1
  299. package/dist/esm/react/deviceDetection.js +72 -93
  300. package/dist/esm/react/deviceDetection.js.map +1 -1
  301. package/dist/esm/react/hooks/usePreconnectWalletAssets.js +32 -27
  302. package/dist/esm/react/hooks/usePreconnectWalletAssets.js.map +1 -1
  303. package/dist/esm/react/hooks/useQRCamera.js +2 -1
  304. package/dist/esm/react/hooks/useQRCamera.js.map +1 -1
  305. package/dist/esm/react/sdk/src/core/EmailRecovery/index.js +12 -5
  306. package/dist/esm/react/sdk/src/core/EmailRecovery/index.js.map +1 -1
  307. package/dist/esm/react/sdk/src/core/IndexedDBManager/passkeyClientDB.js +35 -36
  308. package/dist/esm/react/sdk/src/core/IndexedDBManager/passkeyClientDB.js.map +1 -1
  309. package/dist/esm/react/sdk/src/core/NearClient.js +2 -1
  310. package/dist/esm/react/sdk/src/core/NearClient.js.map +1 -1
  311. package/dist/esm/react/sdk/src/core/TatchiPasskey/emailRecovery.js +136 -27
  312. package/dist/esm/react/sdk/src/core/TatchiPasskey/emailRecovery.js.map +1 -1
  313. package/dist/esm/react/sdk/src/core/TatchiPasskey/faucets/createAccountRelayServer.js +2 -1
  314. package/dist/esm/react/sdk/src/core/TatchiPasskey/faucets/createAccountRelayServer.js.map +1 -1
  315. package/dist/esm/react/sdk/src/core/TatchiPasskey/index.js +26 -1
  316. package/dist/esm/react/sdk/src/core/TatchiPasskey/index.js.map +1 -1
  317. package/dist/esm/react/sdk/src/core/TatchiPasskey/linkDevice.js +4 -2
  318. package/dist/esm/react/sdk/src/core/TatchiPasskey/linkDevice.js.map +1 -1
  319. package/dist/esm/react/sdk/src/core/TatchiPasskey/login.js +13 -7
  320. package/dist/esm/react/sdk/src/core/TatchiPasskey/login.js.map +1 -1
  321. package/dist/esm/react/sdk/src/core/TatchiPasskey/recoverAccount.js +2 -1
  322. package/dist/esm/react/sdk/src/core/TatchiPasskey/recoverAccount.js.map +1 -1
  323. package/dist/esm/react/sdk/src/core/TatchiPasskey/scanDevice.js +2 -1
  324. package/dist/esm/react/sdk/src/core/TatchiPasskey/scanDevice.js.map +1 -1
  325. package/dist/esm/react/sdk/src/core/WalletIframe/client/IframeTransport.js +11 -1
  326. package/dist/esm/react/sdk/src/core/WalletIframe/client/IframeTransport.js.map +1 -1
  327. package/dist/esm/react/sdk/src/core/WalletIframe/client/router.js +9 -0
  328. package/dist/esm/react/sdk/src/core/WalletIframe/client/router.js.map +1 -1
  329. package/dist/esm/react/sdk/src/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-drawer.js +1 -1
  330. package/dist/esm/react/sdk/src/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-drawer.js.map +1 -1
  331. package/dist/esm/react/sdk/src/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-modal.js +52 -52
  332. package/dist/esm/react/sdk/src/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-modal.js.map +1 -1
  333. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/getDeviceNumber.js +6 -2
  334. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/checkCanRegisterUser.js +2 -1
  335. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/checkCanRegisterUser.js.map +1 -1
  336. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/decryptPrivateKeyWithPrf.js +2 -1
  337. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/decryptPrivateKeyWithPrf.js.map +1 -1
  338. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/deriveNearKeypairAndEncryptFromSerialized.js +2 -1
  339. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/deriveNearKeypairAndEncryptFromSerialized.js.map +1 -1
  340. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/exportNearKeypairUi.js +2 -1
  341. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/exportNearKeypairUi.js.map +1 -1
  342. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/registerDevice2WithDerivedKey.js +2 -1
  343. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/registerDevice2WithDerivedKey.js.map +1 -1
  344. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/signDelegateAction.js +2 -1
  345. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/signDelegateAction.js.map +1 -1
  346. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/signNep413Message.js +2 -1
  347. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/signNep413Message.js.map +1 -1
  348. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/signTransactionsWithActions.js +2 -1
  349. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/signTransactionsWithActions.js.map +1 -1
  350. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/validation.js +4 -2
  351. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/validation.js.map +1 -1
  352. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/index.js +2 -1
  353. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/index.js.map +1 -1
  354. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/vrf.js +1 -0
  355. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/vrf.js.map +1 -1
  356. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/webauthn.js +8 -2
  357. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/webauthn.js.map +1 -1
  358. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/determineConfirmationConfig.js +2 -1
  359. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/determineConfirmationConfig.js.map +1 -1
  360. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/localOnly.js +2 -1
  361. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/localOnly.js.map +1 -1
  362. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/registration.js +2 -1
  363. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/registration.js.map +1 -1
  364. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/transactions.js +5 -16
  365. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/transactions.js.map +1 -1
  366. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/handlers/deriveVrfKeypairFromPrf.js +2 -1
  367. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/handlers/deriveVrfKeypairFromPrf.js.map +1 -1
  368. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfChallenge.js +2 -1
  369. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfChallenge.js.map +1 -1
  370. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfKeypairBootstrap.js +2 -1
  371. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfKeypairBootstrap.js.map +1 -1
  372. package/dist/esm/react/sdk/src/core/WebAuthnManager/WebAuthnFallbacks/index.js +12 -0
  373. package/dist/esm/react/sdk/src/core/WebAuthnManager/WebAuthnFallbacks/index.js.map +1 -0
  374. package/dist/esm/react/sdk/src/core/WebAuthnManager/WebAuthnFallbacks/safari-fallbacks.js +61 -55
  375. package/dist/esm/react/sdk/src/core/WebAuthnManager/WebAuthnFallbacks/safari-fallbacks.js.map +1 -1
  376. package/dist/esm/react/sdk/src/core/WebAuthnManager/credentialsHelpers.js +8 -3
  377. package/dist/esm/react/sdk/src/core/WebAuthnManager/index.js +8 -3
  378. package/dist/esm/react/sdk/src/core/WebAuthnManager/index.js.map +1 -1
  379. package/dist/esm/react/sdk/src/core/WebAuthnManager/touchIdPrompt.js +207 -204
  380. package/dist/esm/react/sdk/src/core/WebAuthnManager/touchIdPrompt.js.map +1 -1
  381. package/dist/esm/react/sdk/src/core/WebAuthnManager/userHandle.js +2 -1
  382. package/dist/esm/react/sdk/src/core/WebAuthnManager/userHandle.js.map +1 -1
  383. package/dist/esm/react/sdk/src/core/defaultConfigs.js +1 -1
  384. package/dist/esm/react/sdk/src/core/defaultConfigs.js.map +1 -1
  385. package/dist/esm/react/sdk/src/core/types/vrf-worker.js +6 -2
  386. package/dist/esm/react/sdk/src/utils/index.js +10 -4
  387. package/dist/esm/react/styles/styles.css +13 -0
  388. package/dist/esm/sdk/{safari-fallbacks-oQKu9xUs.js → WebAuthnFallbacks-Bl4BTsNt.js} +131 -135
  389. package/dist/esm/sdk/{createAdapters-pNiL2KNq.js → createAdapters-BumKM2ft.js} +59 -54
  390. package/dist/esm/sdk/createAdapters-BumKM2ft.js.map +1 -0
  391. package/dist/esm/sdk/{createAdapters-BWLe9Ddo.js → createAdapters-qVGD6i0g.js} +10 -3
  392. package/dist/esm/sdk/{defaultConfigs-VzvDejmy.js → defaultConfigs-DpslkAQd.js} +1 -1
  393. package/dist/esm/sdk/{getDeviceNumber-CkWRT17I.js → getDeviceNumber-fXizNGQl.js} +2 -2
  394. package/dist/esm/sdk/getDeviceNumber-fXizNGQl.js.map +1 -0
  395. package/dist/esm/sdk/{getDeviceNumber-CfmlgfMX.js → getDeviceNumber-zsOHT_Um.js} +6 -3
  396. package/dist/esm/sdk/{localOnly-DnpSyDaF.js → localOnly-Byi3AK7A.js} +2 -2
  397. package/dist/esm/sdk/{localOnly-DnpSyDaF.js.map → localOnly-Byi3AK7A.js.map} +1 -1
  398. package/dist/esm/sdk/{localOnly-BdumO2st.js → localOnly-pXMTqh1m.js} +5 -4
  399. package/dist/esm/sdk/offline-export-app.js +46 -44
  400. package/dist/esm/sdk/offline-export-app.js.map +1 -1
  401. package/dist/esm/sdk/{overlay-BTqPGG-o.js → overlay-ZGbucXIa.js} +2 -0
  402. package/dist/esm/sdk/{registration-C633u6x8.js → registration-CBiS4Ua_.js} +2 -2
  403. package/dist/esm/sdk/{registration-C633u6x8.js.map → registration-CBiS4Ua_.js.map} +1 -1
  404. package/dist/esm/sdk/{registration-xyYUFRqk.js → registration-DLPLsGCz.js} +5 -4
  405. package/dist/esm/sdk/{requestHelpers-DLBGBHMw.js → requestHelpers-Dh1hEYL9.js} +206 -204
  406. package/dist/esm/sdk/{router-BG6KC_p7.js → router-BLFegW7J.js} +20 -2
  407. package/dist/esm/sdk/{rpcCalls-fLObBbbz.js → rpcCalls-DEv9x5-f.js} +2 -2
  408. package/dist/esm/sdk/{rpcCalls-CAU5XYEF.js → rpcCalls-OhgEeFig.js} +1 -1
  409. package/dist/esm/sdk/{transactions-jH38BZ-Q.js → transactions-BIqKZeR0.js} +6 -18
  410. package/dist/esm/sdk/transactions-BIqKZeR0.js.map +1 -0
  411. package/dist/esm/sdk/{transactions-CzZAt1Yn.js → transactions-Bk-VavcV.js} +10 -21
  412. package/dist/esm/sdk/tx-confirm-ui.js +53 -53
  413. package/dist/esm/sdk/{tx-confirmer-wrapper-CqfVBUaA.js → tx-confirmer-wrapper-lHNgz9i4.js} +53 -53
  414. package/dist/esm/sdk/tx-confirmer.css +6 -4
  415. package/dist/esm/sdk/w3a-tx-confirmer.js +1 -1
  416. package/dist/esm/sdk/wallet-iframe-host.js +271 -89
  417. package/dist/esm/server/email-recovery/emailEncryptor.js +11 -1
  418. package/dist/esm/server/email-recovery/emailEncryptor.js.map +1 -1
  419. package/dist/esm/server/email-recovery/emailParsers.js +55 -1
  420. package/dist/esm/server/email-recovery/emailParsers.js.map +1 -1
  421. package/dist/esm/server/email-recovery/index.js +2 -2
  422. package/dist/esm/server/email-recovery/index.js.map +1 -1
  423. package/dist/esm/server/email-recovery/rpcCalls.js +14 -1
  424. package/dist/esm/server/email-recovery/rpcCalls.js.map +1 -1
  425. package/dist/esm/server/index.js +2 -2
  426. package/dist/esm/server/router/cloudflare.js.map +1 -1
  427. package/dist/esm/server/router/express.js.map +1 -1
  428. package/dist/esm/server/sdk/src/core/defaultConfigs.js +1 -1
  429. package/dist/esm/server/sdk/src/core/defaultConfigs.js.map +1 -1
  430. package/dist/esm/utils/index.js +10 -4
  431. package/dist/esm/wasm_vrf_worker/pkg/wasm_vrf_worker.js +3 -0
  432. package/dist/esm/wasm_vrf_worker/pkg/wasm_vrf_worker_bg.wasm +0 -0
  433. package/dist/types/src/core/EmailRecovery/index.d.ts.map +1 -1
  434. package/dist/types/src/core/IndexedDBManager/passkeyClientDB.d.ts +11 -21
  435. package/dist/types/src/core/IndexedDBManager/passkeyClientDB.d.ts.map +1 -1
  436. package/dist/types/src/core/TatchiPasskey/emailRecovery.d.ts +12 -1
  437. package/dist/types/src/core/TatchiPasskey/emailRecovery.d.ts.map +1 -1
  438. package/dist/types/src/core/TatchiPasskey/index.d.ts +8 -0
  439. package/dist/types/src/core/TatchiPasskey/index.d.ts.map +1 -1
  440. package/dist/types/src/core/WalletIframe/TatchiPasskeyIframe.d.ts +4 -0
  441. package/dist/types/src/core/WalletIframe/TatchiPasskeyIframe.d.ts.map +1 -1
  442. package/dist/types/src/core/WalletIframe/client/IframeTransport.d.ts.map +1 -1
  443. package/dist/types/src/core/WalletIframe/client/router.d.ts +4 -0
  444. package/dist/types/src/core/WalletIframe/client/router.d.ts.map +1 -1
  445. package/dist/types/src/core/WalletIframe/host/wallet-iframe-handlers.d.ts.map +1 -1
  446. package/dist/types/src/core/WalletIframe/shared/messages.d.ts +6 -2
  447. package/dist/types/src/core/WalletIframe/shared/messages.d.ts.map +1 -1
  448. package/dist/types/src/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-drawer.d.ts.map +1 -1
  449. package/dist/types/src/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-modal.d.ts.map +1 -1
  450. package/dist/types/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/vrf.d.ts.map +1 -1
  451. package/dist/types/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/webauthn.d.ts.map +1 -1
  452. package/dist/types/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/transactions.d.ts.map +1 -1
  453. package/dist/types/src/core/WebAuthnManager/index.d.ts.map +1 -1
  454. package/dist/types/src/core/defaultConfigs.d.ts.map +1 -1
  455. package/dist/types/src/react/components/PasskeyAuthMenu/ui/EmailRecoverySlide.d.ts.map +1 -1
  456. package/dist/types/src/react/hooks/usePreconnectWalletAssets.d.ts.map +1 -1
  457. package/dist/types/src/server/email-recovery/emailEncryptor.d.ts +4 -0
  458. package/dist/types/src/server/email-recovery/emailEncryptor.d.ts.map +1 -1
  459. package/dist/types/src/server/email-recovery/emailParsers.d.ts +7 -0
  460. package/dist/types/src/server/email-recovery/emailParsers.d.ts.map +1 -1
  461. package/dist/types/src/server/email-recovery/index.d.ts +1 -1
  462. package/dist/types/src/server/email-recovery/rpcCalls.d.ts +1 -1
  463. package/dist/types/src/server/email-recovery/rpcCalls.d.ts.map +1 -1
  464. package/dist/types/src/wasm_vrf_worker/pkg/wasm_vrf_worker.d.ts.map +1 -1
  465. package/dist/workers/wasm_vrf_worker_bg.wasm +0 -0
  466. package/dist/workers/web3authn-vrf.worker.js +3 -0
  467. package/package.json +1 -1
  468. package/dist/esm/sdk/createAdapters-pNiL2KNq.js.map +0 -1
  469. package/dist/esm/sdk/getDeviceNumber-CkWRT17I.js.map +0 -1
  470. package/dist/esm/sdk/transactions-jH38BZ-Q.js.map +0 -1
@@ -1,103 +1,86 @@
1
1
  const require_rolldown_runtime = require('./_virtual/rolldown_runtime.js');
2
2
 
3
3
  //#region src/react/deviceDetection.ts
4
- /**
5
- * Detects the current device type based on multiple indicators
6
- */
7
- const detectDeviceType = () => {
8
- const userAgent = navigator.userAgent.toLowerCase();
9
- const isMobileUA = /android|iphone|ipod|blackberry|iemobile|opera mini/i.test(userAgent);
10
- const isTabletUA = /ipad|tablet|kindle|playbook|silk/i.test(userAgent);
11
- const isTouchDevice = navigator.maxTouchPoints > 0;
12
- const screenWidth = window.screen.width;
13
- const isSmallScreen = screenWidth <= 480;
14
- const isMediumScreen = screenWidth <= 1024;
15
- const hasOrientation = "orientation" in window;
16
- if (isMobileUA || isTouchDevice && isSmallScreen) return "mobile";
17
- if (isTabletUA || isTouchDevice && isMediumScreen && hasOrientation) return "tablet";
18
- return "desktop";
19
- };
20
- /**
21
- * Basic Safari detection (desktop Safari). Note: all iOS browsers use WebKit,
22
- * so use isIOS() to capture iOS Safari-like restrictions.
23
- */
24
- const isSafari = () => {
25
- try {
26
- const ua = navigator.userAgent;
27
- const isSafariEngine = /safari/i.test(ua) && !/chrome|crios|crmo|chromium|edg|edge|opr|opera|brave/i.test(ua);
28
- return isSafariEngine;
29
- } catch {
30
- return false;
31
- }
32
- };
33
- /**
34
- * Detect iOS (covers iPhone/iPad/iPod and iPadOS with desktop UA).
35
- * iOS has WebAuthn user-activation quirks that are shared by all iOS browsers.
36
- */
37
- const isIOS = () => {
38
- try {
39
- const ua = navigator.userAgent;
40
- const platform = navigator.platform || "";
41
- const maxTouch = Number(navigator.maxTouchPoints || 0);
42
- const iOSUA = /iPad|iPhone|iPod/.test(ua);
43
- const iPadOSMacLike = /Macintosh/.test(ua) && maxTouch > 1;
44
- const iOSPlatform = /iPad|iPhone|iPod/.test(platform);
45
- return iOSUA || iPadOSMacLike || iOSPlatform;
46
- } catch {
47
- return false;
48
- }
49
- };
50
- /**
51
- * Returns true when the page currently has a transient user activation
52
- * (click/tap/key within the allowed time window).
53
- */
54
- const hasActiveUserActivation = () => {
55
- try {
56
- const ua = navigator.userActivation;
57
- return !!(ua && typeof ua.isActive === "boolean" && ua.isActive);
58
- } catch {
59
- return false;
60
- }
61
- };
62
- /**
63
- * Heuristic: when on Safari/iOS or on a mobile device AND no active user
64
- * activation, we should surface a clickable UI to capture activation.
65
- */
66
- const needsExplicitActivation = () => {
67
- try {
68
- if (hasActiveUserActivation()) return false;
69
- return isIOS() || isMobileDevice() || isSafari();
70
- } catch {
71
- return false;
72
- }
73
- };
74
- /**
75
- * Determines optimal camera facing mode based on device type
76
- * - Mobile/Tablet: Back camera (environment) for QR scanning
77
- * - Desktop/Laptop: Front camera (user) for video calls/selfies
78
- */
79
- const getOptimalCameraFacingMode = () => {
80
- const deviceType = detectDeviceType();
81
- switch (deviceType) {
82
- case "mobile":
83
- case "tablet":
84
- console.log(`${deviceType} device detected - using back camera (environment)`);
85
- return "environment";
86
- case "desktop":
87
- default: return "user";
88
- }
89
- };
90
- /**
91
- * Check if the current device is likely mobile
92
- */
93
- const isMobileDevice = () => {
94
- return detectDeviceType() === "mobile";
95
- };
4
+ var detectDeviceType, isSafari, isIOS, hasActiveUserActivation, needsExplicitActivation, getOptimalCameraFacingMode, isMobileDevice;
5
+ var init_deviceDetection = require_rolldown_runtime.__esm({ "src/react/deviceDetection.ts": (() => {
6
+ detectDeviceType = () => {
7
+ const userAgent = navigator.userAgent.toLowerCase();
8
+ const isMobileUA = /android|iphone|ipod|blackberry|iemobile|opera mini/i.test(userAgent);
9
+ const isTabletUA = /ipad|tablet|kindle|playbook|silk/i.test(userAgent);
10
+ const isTouchDevice = navigator.maxTouchPoints > 0;
11
+ const screenWidth = window.screen.width;
12
+ const isSmallScreen = screenWidth <= 480;
13
+ const isMediumScreen = screenWidth <= 1024;
14
+ const hasOrientation = "orientation" in window;
15
+ if (isMobileUA || isTouchDevice && isSmallScreen) return "mobile";
16
+ if (isTabletUA || isTouchDevice && isMediumScreen && hasOrientation) return "tablet";
17
+ return "desktop";
18
+ };
19
+ isSafari = () => {
20
+ try {
21
+ const ua = navigator.userAgent;
22
+ const isSafariEngine = /safari/i.test(ua) && !/chrome|crios|crmo|chromium|edg|edge|opr|opera|brave/i.test(ua);
23
+ return isSafariEngine;
24
+ } catch {
25
+ return false;
26
+ }
27
+ };
28
+ isIOS = () => {
29
+ try {
30
+ const ua = navigator.userAgent;
31
+ const platform = navigator.platform || "";
32
+ const maxTouch = Number(navigator.maxTouchPoints || 0);
33
+ const iOSUA = /iPad|iPhone|iPod/.test(ua);
34
+ const iPadOSMacLike = /Macintosh/.test(ua) && maxTouch > 1;
35
+ const iOSPlatform = /iPad|iPhone|iPod/.test(platform);
36
+ return iOSUA || iPadOSMacLike || iOSPlatform;
37
+ } catch {
38
+ return false;
39
+ }
40
+ };
41
+ hasActiveUserActivation = () => {
42
+ try {
43
+ const ua = navigator.userActivation;
44
+ return !!(ua && typeof ua.isActive === "boolean" && ua.isActive);
45
+ } catch {
46
+ return false;
47
+ }
48
+ };
49
+ needsExplicitActivation = () => {
50
+ try {
51
+ if (hasActiveUserActivation()) return false;
52
+ return isIOS() || isMobileDevice() || isSafari();
53
+ } catch {
54
+ return false;
55
+ }
56
+ };
57
+ getOptimalCameraFacingMode = () => {
58
+ const deviceType = detectDeviceType();
59
+ switch (deviceType) {
60
+ case "mobile":
61
+ case "tablet":
62
+ console.log(`${deviceType} device detected - using back camera (environment)`);
63
+ return "environment";
64
+ case "desktop":
65
+ default: return "user";
66
+ }
67
+ };
68
+ isMobileDevice = () => {
69
+ return detectDeviceType() === "mobile";
70
+ };
71
+ }) });
96
72
 
97
73
  //#endregion
74
+ init_deviceDetection();
98
75
  exports.detectDeviceType = detectDeviceType;
99
76
  exports.getOptimalCameraFacingMode = getOptimalCameraFacingMode;
100
77
  exports.hasActiveUserActivation = hasActiveUserActivation;
78
+ Object.defineProperty(exports, 'init_deviceDetection', {
79
+ enumerable: true,
80
+ get: function () {
81
+ return init_deviceDetection;
82
+ }
83
+ });
101
84
  exports.isIOS = isIOS;
102
85
  exports.isMobileDevice = isMobileDevice;
103
86
  exports.isSafari = isSafari;
@@ -1 +1 @@
1
- {"version":3,"file":"deviceDetection.js","names":[],"sources":["../../../src/react/deviceDetection.ts"],"sourcesContent":["/**\n * Device detection utilities for camera and UI optimization\n */\n\nexport type DeviceType = 'mobile' | 'tablet' | 'desktop';\nexport type CameraFacingMode = 'user' | 'environment';\n\n/**\n * Detects the current device type based on multiple indicators\n */\nexport const detectDeviceType = (): DeviceType => {\n // Method 1: User agent detection\n const userAgent = navigator.userAgent.toLowerCase();\n const isMobileUA = /android|iphone|ipod|blackberry|iemobile|opera mini/i.test(userAgent);\n const isTabletUA = /ipad|tablet|kindle|playbook|silk/i.test(userAgent);\n\n // Method 2: Touch and screen size detection\n const isTouchDevice = navigator.maxTouchPoints > 0;\n const screenWidth = window.screen.width;\n const isSmallScreen = screenWidth <= 480;\n const isMediumScreen = screenWidth <= 1024;\n\n // Method 3: Orientation support (mobile/tablet indicator)\n const hasOrientation = 'orientation' in window;\n\n // Determine device type with priority: mobile > tablet > desktop\n if (isMobileUA || (isTouchDevice && isSmallScreen)) {\n return 'mobile';\n }\n\n if (isTabletUA || (isTouchDevice && isMediumScreen && hasOrientation)) {\n return 'tablet';\n }\n\n return 'desktop';\n};\n\n/**\n * Basic Safari detection (desktop Safari). Note: all iOS browsers use WebKit,\n * so use isIOS() to capture iOS Safari-like restrictions.\n */\nexport const isSafari = (): boolean => {\n try {\n const ua = navigator.userAgent;\n const isSafariEngine = /safari/i.test(ua) && !/chrome|crios|crmo|chromium|edg|edge|opr|opera|brave/i.test(ua);\n return isSafariEngine;\n } catch {\n return false;\n }\n};\n\n/**\n * Detect iOS (covers iPhone/iPad/iPod and iPadOS with desktop UA).\n * iOS has WebAuthn user-activation quirks that are shared by all iOS browsers.\n */\nexport const isIOS = (): boolean => {\n try {\n const ua = navigator.userAgent;\n const platform = (navigator as any).platform || '';\n const maxTouch = Number(navigator.maxTouchPoints || 0);\n const iOSUA = /iPad|iPhone|iPod/.test(ua);\n const iPadOSMacLike = /Macintosh/.test(ua) && maxTouch > 1; // iPadOS masquerading as Mac\n const iOSPlatform = /iPad|iPhone|iPod/.test(platform);\n return iOSUA || iPadOSMacLike || iOSPlatform;\n } catch {\n return false;\n }\n};\n\n/**\n * Detect Mobile Safari (iOS Safari specifically). Chrome/Firefox on iOS still use WebKit,\n * so for WebAuthn activation rules, prefer checking isIOS() as well.\n */\nexport const isMobileSafari = (): boolean => {\n try {\n const ua = navigator.userAgent;\n if (!isIOS()) return false;\n // Exclude Chrome/Firefox/Edge branded iOS browsers (still WebKit underneath)\n const branded = /crios|fxios|edgios|opios|mercury/i.test(ua);\n const safariToken = /safari/i.test(ua);\n return safariToken && !branded;\n } catch {\n return false;\n }\n};\n\n/**\n * Returns true when the page currently has a transient user activation\n * (click/tap/key within the allowed time window).\n */\nexport const hasActiveUserActivation = (): boolean => {\n try {\n const ua = (navigator as any).userActivation;\n return !!(ua && typeof ua.isActive === 'boolean' && ua.isActive);\n } catch {\n return false;\n }\n};\n\n/**\n * Heuristic: when on Safari/iOS or on a mobile device AND no active user\n * activation, we should surface a clickable UI to capture activation.\n */\nexport const needsExplicitActivation = (): boolean => {\n try {\n if (hasActiveUserActivation()) return false;\n return isIOS() || isMobileDevice() || isSafari();\n } catch {\n // In non-browser or SSR/test environments, avoid forcing UI changes\n return false;\n }\n};\n\n/**\n * Determines optimal camera facing mode based on device type\n * - Mobile/Tablet: Back camera (environment) for QR scanning\n * - Desktop/Laptop: Front camera (user) for video calls/selfies\n */\nexport const getOptimalCameraFacingMode = (): CameraFacingMode => {\n const deviceType = detectDeviceType();\n\n switch (deviceType) {\n case 'mobile':\n case 'tablet':\n console.log(`${deviceType} device detected - using back camera (environment)`);\n return 'environment';\n\n case 'desktop':\n default:\n return 'user';\n }\n};\n\n/**\n * Check if the current device is likely mobile\n */\nexport const isMobileDevice = (): boolean => {\n return detectDeviceType() === 'mobile';\n};\n\n/**\n * Check if the current device supports touch\n */\nexport const isTouchDevice = (): boolean => {\n return navigator.maxTouchPoints > 0;\n};\n\n/**\n * Get device capabilities for camera constraints\n */\nexport const getDeviceCapabilities = () => {\n const deviceType = detectDeviceType();\n const isTouch = isTouchDevice();\n const facingMode = getOptimalCameraFacingMode();\n\n return {\n deviceType,\n isTouch,\n recommendedFacingMode: facingMode,\n // Recommended camera constraints based on device\n cameraConstraints: {\n video: {\n facingMode,\n width: deviceType === 'mobile' ? { ideal: 720, min: 480 } : { ideal: 1280, min: 720 },\n height: deviceType === 'mobile' ? { ideal: 720, min: 480 } : { ideal: 720, min: 480 },\n aspectRatio: deviceType === 'mobile' ? { ideal: 1.0 } : { ideal: 16/9 }\n }\n }\n };\n};\n"],"mappings":";;;;;;AAUA,MAAa,yBAAqC;CAEhD,MAAM,YAAY,UAAU,UAAU;CACtC,MAAM,aAAa,sDAAsD,KAAK;CAC9E,MAAM,aAAa,oCAAoC,KAAK;CAG5D,MAAM,gBAAgB,UAAU,iBAAiB;CACjD,MAAM,cAAc,OAAO,OAAO;CAClC,MAAM,gBAAgB,eAAe;CACrC,MAAM,iBAAiB,eAAe;CAGtC,MAAM,iBAAiB,iBAAiB;AAGxC,KAAI,cAAe,iBAAiB,cAClC,QAAO;AAGT,KAAI,cAAe,iBAAiB,kBAAkB,eACpD,QAAO;AAGT,QAAO;;;;;;AAOT,MAAa,iBAA0B;AACrC,KAAI;EACF,MAAM,KAAK,UAAU;EACrB,MAAM,iBAAiB,UAAU,KAAK,OAAO,CAAC,uDAAuD,KAAK;AAC1G,SAAO;SACD;AACN,SAAO;;;;;;;AAQX,MAAa,cAAuB;AAClC,KAAI;EACF,MAAM,KAAK,UAAU;EACrB,MAAM,WAAY,UAAkB,YAAY;EAChD,MAAM,WAAW,OAAO,UAAU,kBAAkB;EACpD,MAAM,QAAQ,mBAAmB,KAAK;EACtC,MAAM,gBAAgB,YAAY,KAAK,OAAO,WAAW;EACzD,MAAM,cAAc,mBAAmB,KAAK;AAC5C,SAAO,SAAS,iBAAiB;SAC3B;AACN,SAAO;;;;;;;AAyBX,MAAa,gCAAyC;AACpD,KAAI;EACF,MAAM,KAAM,UAAkB;AAC9B,SAAO,CAAC,EAAE,MAAM,OAAO,GAAG,aAAa,aAAa,GAAG;SACjD;AACN,SAAO;;;;;;;AAQX,MAAa,gCAAyC;AACpD,KAAI;AACF,MAAI,0BAA2B,QAAO;AACtC,SAAO,WAAW,oBAAoB;SAChC;AAEN,SAAO;;;;;;;;AASX,MAAa,mCAAqD;CAChE,MAAM,aAAa;AAEnB,SAAQ,YAAR;EACE,KAAK;EACL,KAAK;AACH,WAAQ,IAAI,GAAG,WAAW;AAC1B,UAAO;EAET,KAAK;EACL,QACE,QAAO;;;;;;AAOb,MAAa,uBAAgC;AAC3C,QAAO,uBAAuB"}
1
+ {"version":3,"file":"deviceDetection.js","names":[],"sources":["../../../src/react/deviceDetection.ts"],"sourcesContent":["/**\n * Device detection utilities for camera and UI optimization\n */\n\nexport type DeviceType = 'mobile' | 'tablet' | 'desktop';\nexport type CameraFacingMode = 'user' | 'environment';\n\n/**\n * Detects the current device type based on multiple indicators\n */\nexport const detectDeviceType = (): DeviceType => {\n // Method 1: User agent detection\n const userAgent = navigator.userAgent.toLowerCase();\n const isMobileUA = /android|iphone|ipod|blackberry|iemobile|opera mini/i.test(userAgent);\n const isTabletUA = /ipad|tablet|kindle|playbook|silk/i.test(userAgent);\n\n // Method 2: Touch and screen size detection\n const isTouchDevice = navigator.maxTouchPoints > 0;\n const screenWidth = window.screen.width;\n const isSmallScreen = screenWidth <= 480;\n const isMediumScreen = screenWidth <= 1024;\n\n // Method 3: Orientation support (mobile/tablet indicator)\n const hasOrientation = 'orientation' in window;\n\n // Determine device type with priority: mobile > tablet > desktop\n if (isMobileUA || (isTouchDevice && isSmallScreen)) {\n return 'mobile';\n }\n\n if (isTabletUA || (isTouchDevice && isMediumScreen && hasOrientation)) {\n return 'tablet';\n }\n\n return 'desktop';\n};\n\n/**\n * Basic Safari detection (desktop Safari). Note: all iOS browsers use WebKit,\n * so use isIOS() to capture iOS Safari-like restrictions.\n */\nexport const isSafari = (): boolean => {\n try {\n const ua = navigator.userAgent;\n const isSafariEngine = /safari/i.test(ua) && !/chrome|crios|crmo|chromium|edg|edge|opr|opera|brave/i.test(ua);\n return isSafariEngine;\n } catch {\n return false;\n }\n};\n\n/**\n * Detect iOS (covers iPhone/iPad/iPod and iPadOS with desktop UA).\n * iOS has WebAuthn user-activation quirks that are shared by all iOS browsers.\n */\nexport const isIOS = (): boolean => {\n try {\n const ua = navigator.userAgent;\n const platform = (navigator as any).platform || '';\n const maxTouch = Number(navigator.maxTouchPoints || 0);\n const iOSUA = /iPad|iPhone|iPod/.test(ua);\n const iPadOSMacLike = /Macintosh/.test(ua) && maxTouch > 1; // iPadOS masquerading as Mac\n const iOSPlatform = /iPad|iPhone|iPod/.test(platform);\n return iOSUA || iPadOSMacLike || iOSPlatform;\n } catch {\n return false;\n }\n};\n\n/**\n * Detect Mobile Safari (iOS Safari specifically). Chrome/Firefox on iOS still use WebKit,\n * so for WebAuthn activation rules, prefer checking isIOS() as well.\n */\nexport const isMobileSafari = (): boolean => {\n try {\n const ua = navigator.userAgent;\n if (!isIOS()) return false;\n // Exclude Chrome/Firefox/Edge branded iOS browsers (still WebKit underneath)\n const branded = /crios|fxios|edgios|opios|mercury/i.test(ua);\n const safariToken = /safari/i.test(ua);\n return safariToken && !branded;\n } catch {\n return false;\n }\n};\n\n/**\n * Returns true when the page currently has a transient user activation\n * (click/tap/key within the allowed time window).\n */\nexport const hasActiveUserActivation = (): boolean => {\n try {\n const ua = (navigator as any).userActivation;\n return !!(ua && typeof ua.isActive === 'boolean' && ua.isActive);\n } catch {\n return false;\n }\n};\n\n/**\n * Heuristic: when on Safari/iOS or on a mobile device AND no active user\n * activation, we should surface a clickable UI to capture activation.\n */\nexport const needsExplicitActivation = (): boolean => {\n try {\n if (hasActiveUserActivation()) return false;\n return isIOS() || isMobileDevice() || isSafari();\n } catch {\n // In non-browser or SSR/test environments, avoid forcing UI changes\n return false;\n }\n};\n\n/**\n * Determines optimal camera facing mode based on device type\n * - Mobile/Tablet: Back camera (environment) for QR scanning\n * - Desktop/Laptop: Front camera (user) for video calls/selfies\n */\nexport const getOptimalCameraFacingMode = (): CameraFacingMode => {\n const deviceType = detectDeviceType();\n\n switch (deviceType) {\n case 'mobile':\n case 'tablet':\n console.log(`${deviceType} device detected - using back camera (environment)`);\n return 'environment';\n\n case 'desktop':\n default:\n return 'user';\n }\n};\n\n/**\n * Check if the current device is likely mobile\n */\nexport const isMobileDevice = (): boolean => {\n return detectDeviceType() === 'mobile';\n};\n\n/**\n * Check if the current device supports touch\n */\nexport const isTouchDevice = (): boolean => {\n return navigator.maxTouchPoints > 0;\n};\n\n/**\n * Get device capabilities for camera constraints\n */\nexport const getDeviceCapabilities = () => {\n const deviceType = detectDeviceType();\n const isTouch = isTouchDevice();\n const facingMode = getOptimalCameraFacingMode();\n\n return {\n deviceType,\n isTouch,\n recommendedFacingMode: facingMode,\n // Recommended camera constraints based on device\n cameraConstraints: {\n video: {\n facingMode,\n width: deviceType === 'mobile' ? { ideal: 720, min: 480 } : { ideal: 1280, min: 720 },\n height: deviceType === 'mobile' ? { ideal: 720, min: 480 } : { ideal: 720, min: 480 },\n aspectRatio: deviceType === 'mobile' ? { ideal: 1.0 } : { ideal: 16/9 }\n }\n }\n };\n};\n"],"mappings":";;;;;CAUa,yBAAqC;EAEhD,MAAM,YAAY,UAAU,UAAU;EACtC,MAAM,aAAa,sDAAsD,KAAK;EAC9E,MAAM,aAAa,oCAAoC,KAAK;EAG5D,MAAM,gBAAgB,UAAU,iBAAiB;EACjD,MAAM,cAAc,OAAO,OAAO;EAClC,MAAM,gBAAgB,eAAe;EACrC,MAAM,iBAAiB,eAAe;EAGtC,MAAM,iBAAiB,iBAAiB;AAGxC,MAAI,cAAe,iBAAiB,cAClC,QAAO;AAGT,MAAI,cAAe,iBAAiB,kBAAkB,eACpD,QAAO;AAGT,SAAO;;CAOI,iBAA0B;AACrC,MAAI;GACF,MAAM,KAAK,UAAU;GACrB,MAAM,iBAAiB,UAAU,KAAK,OAAO,CAAC,uDAAuD,KAAK;AAC1G,UAAO;UACD;AACN,UAAO;;;CAQE,cAAuB;AAClC,MAAI;GACF,MAAM,KAAK,UAAU;GACrB,MAAM,WAAY,UAAkB,YAAY;GAChD,MAAM,WAAW,OAAO,UAAU,kBAAkB;GACpD,MAAM,QAAQ,mBAAmB,KAAK;GACtC,MAAM,gBAAgB,YAAY,KAAK,OAAO,WAAW;GACzD,MAAM,cAAc,mBAAmB,KAAK;AAC5C,UAAO,SAAS,iBAAiB;UAC3B;AACN,UAAO;;;CAyBE,gCAAyC;AACpD,MAAI;GACF,MAAM,KAAM,UAAkB;AAC9B,UAAO,CAAC,EAAE,MAAM,OAAO,GAAG,aAAa,aAAa,GAAG;UACjD;AACN,UAAO;;;CAQE,gCAAyC;AACpD,MAAI;AACF,OAAI,0BAA2B,QAAO;AACtC,UAAO,WAAW,oBAAoB;UAChC;AAEN,UAAO;;;CASE,mCAAqD;EAChE,MAAM,aAAa;AAEnB,UAAQ,YAAR;GACE,KAAK;GACL,KAAK;AACH,YAAQ,IAAI,GAAG,WAAW;AAC1B,WAAO;GAET,KAAK;GACL,QACE,QAAO;;;CAOA,uBAAgC;AAC3C,SAAO,uBAAuB"}
@@ -14,9 +14,12 @@ function usePreconnectWalletAssets(config) {
14
14
  if (typeof document === "undefined") return;
15
15
  let isCrossOrigin = false;
16
16
  let walletOriginOrigin = void 0;
17
+ let walletIsHttp = false;
17
18
  try {
18
19
  if (walletOrigin) {
19
- walletOriginOrigin = new URL(walletOrigin, window.location.href).origin;
20
+ const url = new URL(walletOrigin, window.location.href);
21
+ walletOriginOrigin = url.origin;
22
+ walletIsHttp = url.protocol === "http:" || url.protocol === "https:";
20
23
  const parentOrigin = window.location.origin;
21
24
  isCrossOrigin = walletOriginOrigin !== parentOrigin;
22
25
  if (isCrossOrigin) {
@@ -44,35 +47,37 @@ function usePreconnectWalletAssets(config) {
44
47
  } catch {}
45
48
  };
46
49
  if (walletOrigin) {
47
- ensureLink("dns-prefetch", walletOrigin);
48
- ensureLink("preconnect", walletOrigin, { crossorigin: "" });
49
- if (!isCrossOrigin) try {
50
- const serviceUrl = new URL(servicePath, walletOrigin).toString();
51
- ensureLink("prefetch", serviceUrl, { as: "document" });
52
- } catch {}
53
- try {
54
- const sdkPath = sdkBasePath || "/sdk";
55
- const withSlash = sdkPath.endsWith("/") ? sdkPath : sdkPath + "/";
56
- const base = new URL(withSlash, walletOrigin);
57
- const hostJs = new URL("wallet-iframe-host.js", base).toString();
58
- ensureLink("modulepreload", hostJs, { crossorigin: "" });
59
- try {
60
- const signerWasm = new URL("workers/wasm_signer_worker_bg.wasm", base).toString();
61
- ensureLink("prefetch", signerWasm, {
62
- as: "fetch",
63
- crossorigin: "",
64
- type: "application/wasm"
65
- });
50
+ if (walletIsHttp && walletOriginOrigin) {
51
+ ensureLink("dns-prefetch", walletOriginOrigin);
52
+ ensureLink("preconnect", walletOriginOrigin, { crossorigin: "" });
53
+ if (!isCrossOrigin) try {
54
+ const serviceUrl = new URL(servicePath, walletOriginOrigin).toString();
55
+ ensureLink("prefetch", serviceUrl, { as: "document" });
66
56
  } catch {}
67
57
  try {
68
- const vrfWasm = new URL("workers/wasm_vrf_worker_bg.wasm", base).toString();
69
- ensureLink("prefetch", vrfWasm, {
70
- as: "fetch",
71
- crossorigin: "",
72
- type: "application/wasm"
73
- });
58
+ const sdkPath = sdkBasePath || "/sdk";
59
+ const withSlash = sdkPath.endsWith("/") ? sdkPath : sdkPath + "/";
60
+ const base = new URL(withSlash, walletOriginOrigin);
61
+ const hostJs = new URL("wallet-iframe-host.js", base).toString();
62
+ ensureLink("modulepreload", hostJs, { crossorigin: "" });
63
+ try {
64
+ const signerWasm = new URL("workers/wasm_signer_worker_bg.wasm", base).toString();
65
+ ensureLink("prefetch", signerWasm, {
66
+ as: "fetch",
67
+ crossorigin: "",
68
+ type: "application/wasm"
69
+ });
70
+ } catch {}
71
+ try {
72
+ const vrfWasm = new URL("workers/wasm_vrf_worker_bg.wasm", base).toString();
73
+ ensureLink("prefetch", vrfWasm, {
74
+ as: "fetch",
75
+ crossorigin: "",
76
+ type: "application/wasm"
77
+ });
78
+ } catch {}
74
79
  } catch {}
75
- } catch {}
80
+ }
76
81
  }
77
82
  if (relayerUrl) {
78
83
  ensureLink("dns-prefetch", relayerUrl);
@@ -1 +1 @@
1
- {"version":3,"file":"usePreconnectWalletAssets.js","names":["walletOriginOrigin: string | undefined"],"sources":["../../../../src/react/hooks/usePreconnectWalletAssets.ts"],"sourcesContent":["import React from 'react';\nimport type { TatchiContextProviderProps } from '../types';\nimport { setEmbeddedBase } from '../../core/sdkPaths';\n\n// Internal: Add preconnect/prefetch hints for wallet service + relayer and\n// expose an absolute embedded asset base for srcdoc iframes.\n//\n// What this hook does\n// - Adds resource hints for the configured wallet origin (dns‑prefetch, preconnect, prefetch)\n// and modulepreload for the wallet host script.\n// - Sets `window.__W3A_WALLET_SDK_BASE__` to an absolute `${walletOrigin}${sdkBasePath}/` so\n// any embedded srcdoc iframes created by the SDK load ESM bundles from the wallet origin,\n// not from the host app origin.\n//\n// Requirements\n// - `config.iframeWallet.walletOrigin` points to the wallet site (e.g. https://web3authn.org)\n// - `config.iframeWallet.sdkBasePath` (default '/sdk') is served on that wallet site\n// - `config.iframeWallet.walletServicePath` (default '/wallet-service') is reachable\n//\n// Gotchas\n// - Always resolve `${sdkBasePath}/...` with a trailing slash; otherwise `new URL('file', '/sdk')`\n// becomes `/file` instead of `/sdk/file`.\n// - For cross‑origin module/worker imports, ensure the wallet site sends CORS headers for\n// `/sdk/*` and `/sdk/workers/*` (e.g. `Access-Control-Allow-Origin: *`) and `.wasm` has\n// `Content-Type: application/wasm`.\n// - `/wallet-service` may 308 → `/wallet-service/` on Pages; both are fine.\nexport function usePreconnectWalletAssets(config: TatchiContextProviderProps['config']): void {\n // Derive stable primitives to avoid re-running the effect on object identity changes.\n const walletOrigin = config?.iframeWallet?.walletOrigin as string | undefined;\n const servicePath = config?.iframeWallet?.walletServicePath || '/wallet-service';\n const sdkBasePath = config?.iframeWallet?.sdkBasePath || '/sdk';\n const relayerUrl = config?.relayer?.url as string | undefined;\n\n React.useEffect(() => {\n try {\n if (typeof document === 'undefined') return;\n // Determine cross‑origin once per effect and expose absolute embedded base\n // for srcdoc iframes ONLY when wallet is cross‑origin.\n let isCrossOrigin = false;\n let walletOriginOrigin: string | undefined = undefined;\n try {\n if (walletOrigin) {\n walletOriginOrigin = new URL(walletOrigin, window.location.href).origin;\n const parentOrigin = window.location.origin;\n isCrossOrigin = walletOriginOrigin !== parentOrigin;\n if (isCrossOrigin) {\n const sdkPath = (sdkBasePath || '/sdk') as string;\n const withSlash = sdkPath.endsWith('/') ? sdkPath : sdkPath + '/';\n const abs = new URL(withSlash, walletOriginOrigin).toString();\n setEmbeddedBase(abs);\n }\n }\n } catch {}\n const ensureLink = (rel: string, href?: string, attrs?: Record<string, string>) => {\n try {\n if (!href) return;\n const head = document.head || document.getElementsByTagName('head')[0];\n if (!head) return;\n const selector = `link[rel=\"${rel}\"][href=\"${href}\"]`;\n if (head.querySelector(selector)) return;\n const link = document.createElement('link');\n link.rel = rel;\n link.href = href;\n if (attrs) {\n for (const [k, v] of Object.entries(attrs)) {\n try { link.setAttribute(k, v); } catch {}\n }\n }\n head.appendChild(link);\n } catch {}\n };\n\n if (walletOrigin) {\n // Reduce DNS/TLS handshake and fetch delays for the wallet origin\n ensureLink('dns-prefetch', walletOrigin);\n ensureLink('preconnect', walletOrigin, { crossorigin: '' });\n\n // Prefetch the service HTML document only in same‑origin dev.\n // Cross‑origin prefetch would require ACAO on the HTML, which we purposely avoid.\n if (!isCrossOrigin) {\n try {\n const serviceUrl = new URL(servicePath, walletOrigin).toString();\n ensureLink('prefetch', serviceUrl, { as: 'document' });\n } catch {}\n }\n\n // Preload the wallet host script module so the iframe boots faster\n // Ensure the base URL ends with a trailing slash; otherwise new URL('file', base)\n // would replace the last path segment (\"/sdk\") and yield \"/wallet-iframe-host.js\".\n try {\n const sdkPath = (sdkBasePath || '/sdk') as string;\n const withSlash = sdkPath.endsWith('/') ? sdkPath : sdkPath + '/';\n const base = new URL(withSlash, walletOrigin);\n const hostJs = new URL('wallet-iframe-host.js', base).toString();\n ensureLink('modulepreload', hostJs, { crossorigin: '' });\n\n // Optionally prefetch WASM binaries to accelerate first-use while avoiding preload warnings\n // Requires CORS + correct MIME (application/wasm) on the wallet origin\n try {\n const signerWasm = new URL('workers/wasm_signer_worker_bg.wasm', base).toString();\n ensureLink('prefetch', signerWasm, { as: 'fetch', crossorigin: '', type: 'application/wasm' } as any);\n } catch {}\n try {\n const vrfWasm = new URL('workers/wasm_vrf_worker_bg.wasm', base).toString();\n ensureLink('prefetch', vrfWasm, { as: 'fetch', crossorigin: '', type: 'application/wasm' } as any);\n } catch {}\n\n // // Preload core CSS used by confirmer to reduce first-paint FOUC\n // const tokensCss = new URL('w3a-components.css', base).toString();\n // const txTreeCss = new URL('tx-tree.css', base).toString();\n // const txConfirmerCss = new URL('tx-confirmer.css', base).toString();\n // const drawerCss = new URL('drawer.css', base).toString();\n // ensureLink('preload', tokensCss, { as: 'style', crossorigin: '' });\n // ensureLink('preload', txTreeCss, { as: 'style', crossorigin: '' });\n // ensureLink('preload', modalCss, { as: 'style', crossorigin: '' });\n // ensureLink('preload', drawerCss, { as: 'style', crossorigin: '' });\n } catch {}\n }\n\n if (relayerUrl) {\n ensureLink('dns-prefetch', relayerUrl);\n ensureLink('preconnect', relayerUrl, { crossorigin: '' });\n }\n } catch {}\n }, [walletOrigin, servicePath, sdkBasePath, relayerUrl]);\n}\n\nexport default usePreconnectWalletAssets;\n"],"mappings":";;;;;;AA0BA,SAAgB,0BAA0B,QAAoD;CAE5F,MAAM,eAAe,QAAQ,cAAc;CAC3C,MAAM,cAAc,QAAQ,cAAc,qBAAqB;CAC/D,MAAM,cAAc,QAAQ,cAAc,eAAe;CACzD,MAAM,aAAa,QAAQ,SAAS;AAEpC,eAAM,gBAAgB;AACpB,MAAI;AACF,OAAI,OAAO,aAAa,YAAa;GAGrC,IAAI,gBAAgB;GACpB,IAAIA,qBAAyC;AAC7C,OAAI;AACF,QAAI,cAAc;AAChB,0BAAqB,IAAI,IAAI,cAAc,OAAO,SAAS,MAAM;KACjE,MAAM,eAAe,OAAO,SAAS;AACrC,qBAAgB,uBAAuB;AACvC,SAAI,eAAe;MACjB,MAAM,UAAW,eAAe;MAChC,MAAM,YAAY,QAAQ,SAAS,OAAO,UAAU,UAAU;MAC9D,MAAM,MAAM,IAAI,IAAI,WAAW,oBAAoB;AACnD,mCAAgB;;;WAGd;GACR,MAAM,cAAc,KAAa,MAAe,UAAmC;AACjF,QAAI;AACF,SAAI,CAAC,KAAM;KACX,MAAM,OAAO,SAAS,QAAQ,SAAS,qBAAqB,QAAQ;AACpE,SAAI,CAAC,KAAM;KACX,MAAM,WAAW,aAAa,IAAI,WAAW,KAAK;AAClD,SAAI,KAAK,cAAc,UAAW;KAClC,MAAM,OAAO,SAAS,cAAc;AACpC,UAAK,MAAM;AACX,UAAK,OAAO;AACZ,SAAI,MACF,MAAK,MAAM,CAAC,GAAG,MAAM,OAAO,QAAQ,OAClC,KAAI;AAAE,WAAK,aAAa,GAAG;aAAY;AAG3C,UAAK,YAAY;YACX;;AAGV,OAAI,cAAc;AAEhB,eAAW,gBAAgB;AAC3B,eAAW,cAAc,cAAc,EAAE,aAAa;AAItD,QAAI,CAAC,cACH,KAAI;KACF,MAAM,aAAa,IAAI,IAAI,aAAa,cAAc;AACtD,gBAAW,YAAY,YAAY,EAAE,IAAI;YACnC;AAMV,QAAI;KACF,MAAM,UAAW,eAAe;KAChC,MAAM,YAAY,QAAQ,SAAS,OAAO,UAAU,UAAU;KAC9D,MAAM,OAAO,IAAI,IAAI,WAAW;KAChC,MAAM,SAAS,IAAI,IAAI,yBAAyB,MAAM;AACtD,gBAAW,iBAAiB,QAAQ,EAAE,aAAa;AAInD,SAAI;MACF,MAAM,aAAa,IAAI,IAAI,sCAAsC,MAAM;AACvE,iBAAW,YAAY,YAAY;OAAE,IAAI;OAAS,aAAa;OAAI,MAAM;;aACnE;AACR,SAAI;MACF,MAAM,UAAU,IAAI,IAAI,mCAAmC,MAAM;AACjE,iBAAW,YAAY,SAAS;OAAE,IAAI;OAAS,aAAa;OAAI,MAAM;;aAChE;YAWF;;AAGV,OAAI,YAAY;AACd,eAAW,gBAAgB;AAC3B,eAAW,cAAc,YAAY,EAAE,aAAa;;UAEhD;IACP;EAAC;EAAc;EAAa;EAAa"}
1
+ {"version":3,"file":"usePreconnectWalletAssets.js","names":["walletOriginOrigin: string | undefined"],"sources":["../../../../src/react/hooks/usePreconnectWalletAssets.ts"],"sourcesContent":["import React from 'react';\nimport type { TatchiContextProviderProps } from '../types';\nimport { setEmbeddedBase } from '../../core/sdkPaths';\n\n// Internal: Add preconnect/prefetch hints for wallet service + relayer and\n// expose an absolute embedded asset base for srcdoc iframes.\n//\n// What this hook does\n// - Adds resource hints for the configured wallet origin (dns‑prefetch, preconnect, prefetch)\n// and modulepreload for the wallet host script.\n// - Sets `window.__W3A_WALLET_SDK_BASE__` to an absolute `${walletOrigin}${sdkBasePath}/` so\n// any embedded srcdoc iframes created by the SDK load ESM bundles from the wallet origin,\n// not from the host app origin.\n//\n// Requirements\n// - `config.iframeWallet.walletOrigin` points to the wallet site (e.g. https://web3authn.org)\n// - `config.iframeWallet.sdkBasePath` (default '/sdk') is served on that wallet site\n// - `config.iframeWallet.walletServicePath` (default '/wallet-service') is reachable\n//\n// Gotchas\n// - Always resolve `${sdkBasePath}/...` with a trailing slash; otherwise `new URL('file', '/sdk')`\n// becomes `/file` instead of `/sdk/file`.\n// - For cross‑origin module/worker imports, ensure the wallet site sends CORS headers for\n// `/sdk/*` and `/sdk/workers/*` (e.g. `Access-Control-Allow-Origin: *`) and `.wasm` has\n// `Content-Type: application/wasm`.\n// - `/wallet-service` may 308 → `/wallet-service/` on Pages; both are fine.\nexport function usePreconnectWalletAssets(config: TatchiContextProviderProps['config']): void {\n // Derive stable primitives to avoid re-running the effect on object identity changes.\n const walletOrigin = config?.iframeWallet?.walletOrigin as string | undefined;\n const servicePath = config?.iframeWallet?.walletServicePath || '/wallet-service';\n const sdkBasePath = config?.iframeWallet?.sdkBasePath || '/sdk';\n const relayerUrl = config?.relayer?.url as string | undefined;\n\n React.useEffect(() => {\n try {\n if (typeof document === 'undefined') return;\n // Determine cross‑origin once per effect and expose absolute embedded base\n // for srcdoc iframes ONLY when wallet is cross‑origin.\n let isCrossOrigin = false;\n let walletOriginOrigin: string | undefined = undefined;\n let walletIsHttp = false;\n try {\n if (walletOrigin) {\n const url = new URL(walletOrigin, window.location.href);\n walletOriginOrigin = url.origin;\n walletIsHttp = url.protocol === 'http:' || url.protocol === 'https:';\n const parentOrigin = window.location.origin;\n isCrossOrigin = walletOriginOrigin !== parentOrigin;\n if (isCrossOrigin) {\n const sdkPath = (sdkBasePath || '/sdk') as string;\n const withSlash = sdkPath.endsWith('/') ? sdkPath : sdkPath + '/';\n const abs = new URL(withSlash, walletOriginOrigin).toString();\n setEmbeddedBase(abs);\n }\n }\n } catch {}\n const ensureLink = (rel: string, href?: string, attrs?: Record<string, string>) => {\n try {\n if (!href) return;\n const head = document.head || document.getElementsByTagName('head')[0];\n if (!head) return;\n const selector = `link[rel=\"${rel}\"][href=\"${href}\"]`;\n if (head.querySelector(selector)) return;\n const link = document.createElement('link');\n link.rel = rel;\n link.href = href;\n if (attrs) {\n for (const [k, v] of Object.entries(attrs)) {\n try { link.setAttribute(k, v); } catch {}\n }\n }\n head.appendChild(link);\n } catch {}\n };\n\n if (walletOrigin) {\n // Resource hints only work for network origins; skip for schemes like chrome-extension://\n // (which can cause confusing console errors and does not benefit DNS/TLS preconnect).\n if (walletIsHttp && walletOriginOrigin) {\n // Reduce DNS/TLS handshake and fetch delays for the wallet origin\n ensureLink('dns-prefetch', walletOriginOrigin);\n ensureLink('preconnect', walletOriginOrigin, { crossorigin: '' });\n\n // Prefetch the service HTML document only in same‑origin dev.\n // Cross‑origin prefetch would require ACAO on the HTML, which we purposely avoid.\n if (!isCrossOrigin) {\n try {\n const serviceUrl = new URL(servicePath, walletOriginOrigin).toString();\n ensureLink('prefetch', serviceUrl, { as: 'document' });\n } catch {}\n }\n\n // Preload the wallet host script module so the iframe boots faster\n // Ensure the base URL ends with a trailing slash; otherwise new URL('file', base)\n // would replace the last path segment (\"/sdk\") and yield \"/wallet-iframe-host.js\".\n try {\n const sdkPath = (sdkBasePath || '/sdk') as string;\n const withSlash = sdkPath.endsWith('/') ? sdkPath : sdkPath + '/';\n const base = new URL(withSlash, walletOriginOrigin);\n const hostJs = new URL('wallet-iframe-host.js', base).toString();\n ensureLink('modulepreload', hostJs, { crossorigin: '' });\n\n // Optionally prefetch WASM binaries to accelerate first-use while avoiding preload warnings\n // Requires CORS + correct MIME (application/wasm) on the wallet origin\n try {\n const signerWasm = new URL('workers/wasm_signer_worker_bg.wasm', base).toString();\n ensureLink('prefetch', signerWasm, { as: 'fetch', crossorigin: '', type: 'application/wasm' } as any);\n } catch {}\n try {\n const vrfWasm = new URL('workers/wasm_vrf_worker_bg.wasm', base).toString();\n ensureLink('prefetch', vrfWasm, { as: 'fetch', crossorigin: '', type: 'application/wasm' } as any);\n } catch {}\n\n // // Preload core CSS used by confirmer to reduce first-paint FOUC\n // const tokensCss = new URL('w3a-components.css', base).toString();\n // const txTreeCss = new URL('tx-tree.css', base).toString();\n // const txConfirmerCss = new URL('tx-confirmer.css', base).toString();\n // const drawerCss = new URL('drawer.css', base).toString();\n // ensureLink('preload', tokensCss, { as: 'style', crossorigin: '' });\n // ensureLink('preload', txTreeCss, { as: 'style', crossorigin: '' });\n // ensureLink('preload', modalCss, { as: 'style', crossorigin: '' });\n // ensureLink('preload', drawerCss, { as: 'style', crossorigin: '' });\n } catch {}\n }\n }\n\n if (relayerUrl) {\n ensureLink('dns-prefetch', relayerUrl);\n ensureLink('preconnect', relayerUrl, { crossorigin: '' });\n }\n } catch {}\n }, [walletOrigin, servicePath, sdkBasePath, relayerUrl]);\n}\n\nexport default usePreconnectWalletAssets;\n"],"mappings":";;;;;;AA0BA,SAAgB,0BAA0B,QAAoD;CAE5F,MAAM,eAAe,QAAQ,cAAc;CAC3C,MAAM,cAAc,QAAQ,cAAc,qBAAqB;CAC/D,MAAM,cAAc,QAAQ,cAAc,eAAe;CACzD,MAAM,aAAa,QAAQ,SAAS;AAEpC,eAAM,gBAAgB;AACpB,MAAI;AACF,OAAI,OAAO,aAAa,YAAa;GAGrC,IAAI,gBAAgB;GACpB,IAAIA,qBAAyC;GAC7C,IAAI,eAAe;AACnB,OAAI;AACF,QAAI,cAAc;KAChB,MAAM,MAAM,IAAI,IAAI,cAAc,OAAO,SAAS;AAClD,0BAAqB,IAAI;AACzB,oBAAe,IAAI,aAAa,WAAW,IAAI,aAAa;KAC5D,MAAM,eAAe,OAAO,SAAS;AACrC,qBAAgB,uBAAuB;AACvC,SAAI,eAAe;MACjB,MAAM,UAAW,eAAe;MAChC,MAAM,YAAY,QAAQ,SAAS,OAAO,UAAU,UAAU;MAC9D,MAAM,MAAM,IAAI,IAAI,WAAW,oBAAoB;AACnD,mCAAgB;;;WAGd;GACR,MAAM,cAAc,KAAa,MAAe,UAAmC;AACjF,QAAI;AACF,SAAI,CAAC,KAAM;KACX,MAAM,OAAO,SAAS,QAAQ,SAAS,qBAAqB,QAAQ;AACpE,SAAI,CAAC,KAAM;KACX,MAAM,WAAW,aAAa,IAAI,WAAW,KAAK;AAClD,SAAI,KAAK,cAAc,UAAW;KAClC,MAAM,OAAO,SAAS,cAAc;AACpC,UAAK,MAAM;AACX,UAAK,OAAO;AACZ,SAAI,MACF,MAAK,MAAM,CAAC,GAAG,MAAM,OAAO,QAAQ,OAClC,KAAI;AAAE,WAAK,aAAa,GAAG;aAAY;AAG3C,UAAK,YAAY;YACX;;AAGV,OAAI,cAGF;QAAI,gBAAgB,oBAAoB;AAEtC,gBAAW,gBAAgB;AAC3B,gBAAW,cAAc,oBAAoB,EAAE,aAAa;AAI5D,SAAI,CAAC,cACH,KAAI;MACF,MAAM,aAAa,IAAI,IAAI,aAAa,oBAAoB;AAC5D,iBAAW,YAAY,YAAY,EAAE,IAAI;aACnC;AAMV,SAAI;MACF,MAAM,UAAW,eAAe;MAChC,MAAM,YAAY,QAAQ,SAAS,OAAO,UAAU,UAAU;MAC9D,MAAM,OAAO,IAAI,IAAI,WAAW;MAChC,MAAM,SAAS,IAAI,IAAI,yBAAyB,MAAM;AACtD,iBAAW,iBAAiB,QAAQ,EAAE,aAAa;AAInD,UAAI;OACF,MAAM,aAAa,IAAI,IAAI,sCAAsC,MAAM;AACvE,kBAAW,YAAY,YAAY;QAAE,IAAI;QAAS,aAAa;QAAI,MAAM;;cACnE;AACR,UAAI;OACF,MAAM,UAAU,IAAI,IAAI,mCAAmC,MAAM;AACjE,kBAAW,YAAY,SAAS;QAAE,IAAI;QAAS,aAAa;QAAI,MAAM;;cAChE;aAWF;;;AAIZ,OAAI,YAAY;AACd,eAAW,gBAAgB;AAC3B,eAAW,cAAc,YAAY,EAAE,aAAa;;UAEhD;IACP;EAAC;EAAc;EAAa;EAAa"}
@@ -5,6 +5,7 @@ let react = require("react");
5
5
  react = require_rolldown_runtime.__toESM(react);
6
6
 
7
7
  //#region src/react/hooks/useQRCamera.ts
8
+ require_deviceDetection.init_deviceDetection();
8
9
  /**
9
10
  * QR Camera Scanning Hook
10
11
  *
@@ -1 +1 @@
1
- {"version":3,"file":"useQRCamera.js","names":["ScanQRCodeFlow","getOptimalCameraFacingMode","enumerateVideoDevices","detectFrontCamera","error: any","error"],"sources":["../../../../src/react/hooks/useQRCamera.ts"],"sourcesContent":["import { useEffect, useRef, useState, useCallback } from 'react';\nimport { getOptimalCameraFacingMode } from '../deviceDetection';\nimport type { DeviceLinkingQRData } from '@/index';\nimport { ScanQRCodeFlow, enumerateVideoDevices, detectFrontCamera } from '../../utils/qrScanner';\n\n/**\n * QR Camera Scanning Hook\n *\n * Provides camera-based QR code scanning functionality for device linking.\n *\n * **Important:** This hook should be used with the TatchiPasskey provider.\n * Wrap your app with PasskeyProvider so useTatchi is available when needed.\n *\n * @example\n * ```tsx\n * import { PasskeyProvider } from '@tatchi-xyz/sdk/react';\n * import { useQRCamera } from '@tatchi-xyz/sdk/react';\n *\n * function QRScanner() {\n * const qrCamera = useQRCamera({\n * onQRDetected: (qrData) => console.log('QR detected:', qrData),\n * onError: (error) => console.error('Error:', error)\n * });\n *\n * return <video ref={qrCamera.videoRef} />;\n * }\n * ```\n */\nexport enum QRScanMode {\n CAMERA = 'camera',\n FILE = 'file',\n AUTO = 'auto'\n}\n\nexport interface UseQRCameraOptions {\n onQRDetected?: (qrData: DeviceLinkingQRData) => void;\n onError?: (error: Error) => void;\n isOpen?: boolean;\n cameraId?: string;\n}\n\nexport interface UseQRCameraReturn {\n // State\n isScanning: boolean;\n isProcessing: boolean;\n error: string | null;\n cameras: MediaDeviceInfo[];\n selectedCamera: string;\n scanMode: QRScanMode;\n isFrontCamera: boolean;\n scanDurationMs: number;\n\n // Refs for UI\n videoRef: React.RefObject<HTMLVideoElement | null>;\n canvasRef: React.RefObject<HTMLCanvasElement | null>;\n\n // Controls\n startScanning: () => Promise<void>;\n stopScanning: () => void;\n handleCameraChange: (deviceId: string) => void;\n setScanMode: (mode: QRScanMode) => void;\n setError: (error: string | null) => void;\n\n // Utilities\n getOptimalFacingMode: () => 'user' | 'environment';\n}\n\nexport const useQRCamera = (options: UseQRCameraOptions): UseQRCameraReturn => {\n const {\n onQRDetected,\n onError,\n isOpen = true,\n cameraId\n } = options;\n\n // Refs\n const videoRef = useRef<HTMLVideoElement>(null);\n const canvasRef = useRef<HTMLCanvasElement>(null);\n const flowRef = useRef<ScanQRCodeFlow | null>(null);\n\n // State\n const [isScanning, setIsScanning] = useState(false);\n const [isProcessing, setIsProcessing] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [cameras, setCameras] = useState<MediaDeviceInfo[]>([]);\n const [selectedCamera, setSelectedCamera] = useState<string>(cameraId || '');\n const [scanMode, setScanMode] = useState<QRScanMode>(QRScanMode.CAMERA);\n const [isFrontCamera, setIsFrontCamera] = useState<boolean>(false);\n const [scanDurationMs, setScanDurationMs] = useState<number>(0);\n\n // Create ScanQRCodeFlow instance\n // This is the core scanning engine that handles camera access and QR detection\n useEffect(() => {\n flowRef.current = new ScanQRCodeFlow(\n {\n cameraId: selectedCamera,\n cameraConfigs: {\n facingMode: getOptimalCameraFacingMode()\n },\n timeout: 60000 // 60 seconds\n },\n {\n onQRDetected: (qrData) => {\n console.log('useQRCamera: Valid QR data detected -', {\n devicePublicKey: qrData.device2PublicKey,\n accountId: qrData.accountId,\n timestamp: new Date(qrData.timestamp || 0).toISOString()\n });\n setIsProcessing(false);\n setIsScanning(false);\n setScanDurationMs(0);\n onQRDetected?.(qrData);\n },\n onError: (err) => {\n console.error('useQRCamera: QR scan error -', err);\n setError(err.message);\n setIsProcessing(false);\n setIsScanning(false);\n setScanDurationMs(0);\n onError?.(err);\n },\n onCameraReady: (stream) => {\n // Camera stream is ready, but video element attachment is handled separately\n console.log('useQRCamera: Camera stream ready');\n },\n onScanProgress: (duration) => {\n setScanDurationMs(duration);\n }\n }\n );\n\n return () => {\n if (flowRef.current) {\n // Hook Cleanup Point 1: Stop scanning and cleanup\n flowRef.current.stop();\n flowRef.current = null;\n }\n };\n }, []); // Only initialize once\n\n // Load cameras on mount\n useEffect(() => {\n const loadCameras = async () => {\n try {\n const videoDevices = await enumerateVideoDevices();\n setCameras(videoDevices);\n\n if (videoDevices.length > 0 && !selectedCamera) {\n const firstCamera = videoDevices[0];\n setSelectedCamera(firstCamera.deviceId);\n setIsFrontCamera(detectFrontCamera(firstCamera));\n }\n } catch (error: any) {\n setError(error.message);\n }\n };\n\n loadCameras();\n }, []);\n\n // Update flow camera when selectedCamera changes\n useEffect(() => {\n if (flowRef.current && selectedCamera) {\n flowRef.current.switchCamera(selectedCamera);\n }\n }, [selectedCamera]);\n\n // Attach/detach video element when ref changes\n useEffect(() => {\n if (videoRef.current && flowRef.current) {\n flowRef.current.attachVideoElement(videoRef.current);\n }\n\n return () => {\n if (flowRef.current) {\n flowRef.current.detachVideoElement();\n }\n };\n }, [videoRef.current]);\n\n // Hook Cleanup Point 2: (when modal closes or scan mode changes from camera to file)\n useEffect(() => {\n const flow = flowRef.current;\n if (!flow) return;\n\n if (isOpen && scanMode === QRScanMode.CAMERA) {\n setError(null);\n setIsProcessing(true);\n setIsScanning(true);\n setScanDurationMs(0);\n flow.startQRScanner();\n } else {\n flow.stop();\n setIsScanning(false);\n setIsProcessing(false);\n setScanDurationMs(0);\n }\n }, [isOpen, scanMode]);\n\n // Manual controls\n const startScanning = useCallback(async () => {\n if (flowRef.current) {\n setError(null);\n setIsProcessing(true);\n setIsScanning(true);\n setScanDurationMs(0);\n await flowRef.current.startQRScanner();\n }\n }, []);\n\n // Hook Cleanup Point 3: called when user explicitly stops scanning\n const stopScanning = useCallback(() => {\n if (flowRef.current) {\n flowRef.current.stop();\n setIsScanning(false);\n setIsProcessing(false);\n setScanDurationMs(0);\n }\n }, []);\n\n // Handle camera change\n const handleCameraChange = useCallback(async (deviceId: string) => {\n setSelectedCamera(deviceId);\n\n const selectedCameraDevice = cameras.find(camera => camera.deviceId === deviceId);\n if (selectedCameraDevice) {\n setIsFrontCamera(detectFrontCamera(selectedCameraDevice));\n }\n\n // The useEffect will handle updating the flow\n }, [cameras]);\n\n const getOptimalFacingMode = useCallback(() => getOptimalCameraFacingMode(), []);\n\n return {\n // State\n isScanning,\n isProcessing,\n error,\n cameras,\n selectedCamera,\n scanMode,\n isFrontCamera,\n scanDurationMs,\n\n // Refs for UI\n videoRef,\n canvasRef,\n\n // Controls\n startScanning,\n stopScanning,\n handleCameraChange,\n setScanMode,\n setError,\n\n // Utilities\n getOptimalFacingMode\n };\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BA,IAAY,oDAAL;AACL;AACA;AACA;;;AAoCF,MAAa,eAAe,YAAmD;CAC7E,MAAM,EACJ,cACA,SACA,SAAS,MACT,aACE;CAGJ,MAAM,6BAAoC;CAC1C,MAAM,8BAAsC;CAC5C,MAAM,4BAAwC;CAG9C,MAAM,CAAC,YAAY,qCAA0B;CAC7C,MAAM,CAAC,cAAc,uCAA4B;CACjD,MAAM,CAAC,OAAO,gCAAoC;CAClD,MAAM,CAAC,SAAS,kCAA0C;CAC1D,MAAM,CAAC,gBAAgB,yCAAsC,YAAY;CACzE,MAAM,CAAC,UAAU,mCAAoC,WAAW;CAChE,MAAM,CAAC,eAAe,wCAAsC;CAC5D,MAAM,CAAC,gBAAgB,yCAAsC;AAI7D,4BAAgB;AACd,UAAQ,UAAU,IAAIA,iCACpB;GACE,UAAU;GACV,eAAe,EACb,YAAYC;GAEd,SAAS;KAEX;GACE,eAAe,WAAW;AACxB,YAAQ,IAAI,yCAAyC;KACnD,iBAAiB,OAAO;KACxB,WAAW,OAAO;KAClB,WAAW,IAAI,KAAK,OAAO,aAAa,GAAG;;AAE7C,oBAAgB;AAChB,kBAAc;AACd,sBAAkB;AAClB,mBAAe;;GAEjB,UAAU,QAAQ;AAChB,YAAQ,MAAM,gCAAgC;AAC9C,aAAS,IAAI;AACb,oBAAgB;AAChB,kBAAc;AACd,sBAAkB;AAClB,cAAU;;GAEZ,gBAAgB,WAAW;AAEzB,YAAQ,IAAI;;GAEd,iBAAiB,aAAa;AAC5B,sBAAkB;;;AAKxB,eAAa;AACX,OAAI,QAAQ,SAAS;AAEnB,YAAQ,QAAQ;AAChB,YAAQ,UAAU;;;IAGrB;AAGH,4BAAgB;EACd,MAAM,cAAc,YAAY;AAC9B,OAAI;IACF,MAAM,eAAe,MAAMC;AAC3B,eAAW;AAEX,QAAI,aAAa,SAAS,KAAK,CAAC,gBAAgB;KAC9C,MAAM,cAAc,aAAa;AACjC,uBAAkB,YAAY;AAC9B,sBAAiBC,oCAAkB;;YAE9BC,SAAY;AACnB,aAASC,QAAM;;;AAInB;IACC;AAGH,4BAAgB;AACd,MAAI,QAAQ,WAAW,eACrB,SAAQ,QAAQ,aAAa;IAE9B,CAAC;AAGJ,4BAAgB;AACd,MAAI,SAAS,WAAW,QAAQ,QAC9B,SAAQ,QAAQ,mBAAmB,SAAS;AAG9C,eAAa;AACX,OAAI,QAAQ,QACV,SAAQ,QAAQ;;IAGnB,CAAC,SAAS;AAGb,4BAAgB;EACd,MAAM,OAAO,QAAQ;AACrB,MAAI,CAAC,KAAM;AAEX,MAAI,UAAU,aAAa,WAAW,QAAQ;AAC5C,YAAS;AACT,mBAAgB;AAChB,iBAAc;AACd,qBAAkB;AAClB,QAAK;SACA;AACL,QAAK;AACL,iBAAc;AACd,mBAAgB;AAChB,qBAAkB;;IAEnB,CAAC,QAAQ;CAGZ,MAAM,uCAA4B,YAAY;AAC5C,MAAI,QAAQ,SAAS;AACnB,YAAS;AACT,mBAAgB;AAChB,iBAAc;AACd,qBAAkB;AAClB,SAAM,QAAQ,QAAQ;;IAEvB;CAGH,MAAM,4CAAiC;AACrC,MAAI,QAAQ,SAAS;AACnB,WAAQ,QAAQ;AAChB,iBAAc;AACd,mBAAgB;AAChB,qBAAkB;;IAEnB;CAGH,MAAM,4CAAiC,OAAO,aAAqB;AACjE,oBAAkB;EAElB,MAAM,uBAAuB,QAAQ,MAAK,WAAU,OAAO,aAAa;AACxE,MAAI,qBACF,kBAAiBF,oCAAkB;IAIpC,CAAC;CAEJ,MAAM,oDAAyCF,sDAA8B;AAE7E,QAAO;EAEL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAGA;EACA;EAGA;EACA;EACA;EACA;EACA;EAGA"}
1
+ {"version":3,"file":"useQRCamera.js","names":["ScanQRCodeFlow","getOptimalCameraFacingMode","enumerateVideoDevices","detectFrontCamera","error: any","error"],"sources":["../../../../src/react/hooks/useQRCamera.ts"],"sourcesContent":["import { useEffect, useRef, useState, useCallback } from 'react';\nimport { getOptimalCameraFacingMode } from '../deviceDetection';\nimport type { DeviceLinkingQRData } from '@/index';\nimport { ScanQRCodeFlow, enumerateVideoDevices, detectFrontCamera } from '../../utils/qrScanner';\n\n/**\n * QR Camera Scanning Hook\n *\n * Provides camera-based QR code scanning functionality for device linking.\n *\n * **Important:** This hook should be used with the TatchiPasskey provider.\n * Wrap your app with PasskeyProvider so useTatchi is available when needed.\n *\n * @example\n * ```tsx\n * import { PasskeyProvider } from '@tatchi-xyz/sdk/react';\n * import { useQRCamera } from '@tatchi-xyz/sdk/react';\n *\n * function QRScanner() {\n * const qrCamera = useQRCamera({\n * onQRDetected: (qrData) => console.log('QR detected:', qrData),\n * onError: (error) => console.error('Error:', error)\n * });\n *\n * return <video ref={qrCamera.videoRef} />;\n * }\n * ```\n */\nexport enum QRScanMode {\n CAMERA = 'camera',\n FILE = 'file',\n AUTO = 'auto'\n}\n\nexport interface UseQRCameraOptions {\n onQRDetected?: (qrData: DeviceLinkingQRData) => void;\n onError?: (error: Error) => void;\n isOpen?: boolean;\n cameraId?: string;\n}\n\nexport interface UseQRCameraReturn {\n // State\n isScanning: boolean;\n isProcessing: boolean;\n error: string | null;\n cameras: MediaDeviceInfo[];\n selectedCamera: string;\n scanMode: QRScanMode;\n isFrontCamera: boolean;\n scanDurationMs: number;\n\n // Refs for UI\n videoRef: React.RefObject<HTMLVideoElement | null>;\n canvasRef: React.RefObject<HTMLCanvasElement | null>;\n\n // Controls\n startScanning: () => Promise<void>;\n stopScanning: () => void;\n handleCameraChange: (deviceId: string) => void;\n setScanMode: (mode: QRScanMode) => void;\n setError: (error: string | null) => void;\n\n // Utilities\n getOptimalFacingMode: () => 'user' | 'environment';\n}\n\nexport const useQRCamera = (options: UseQRCameraOptions): UseQRCameraReturn => {\n const {\n onQRDetected,\n onError,\n isOpen = true,\n cameraId\n } = options;\n\n // Refs\n const videoRef = useRef<HTMLVideoElement>(null);\n const canvasRef = useRef<HTMLCanvasElement>(null);\n const flowRef = useRef<ScanQRCodeFlow | null>(null);\n\n // State\n const [isScanning, setIsScanning] = useState(false);\n const [isProcessing, setIsProcessing] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [cameras, setCameras] = useState<MediaDeviceInfo[]>([]);\n const [selectedCamera, setSelectedCamera] = useState<string>(cameraId || '');\n const [scanMode, setScanMode] = useState<QRScanMode>(QRScanMode.CAMERA);\n const [isFrontCamera, setIsFrontCamera] = useState<boolean>(false);\n const [scanDurationMs, setScanDurationMs] = useState<number>(0);\n\n // Create ScanQRCodeFlow instance\n // This is the core scanning engine that handles camera access and QR detection\n useEffect(() => {\n flowRef.current = new ScanQRCodeFlow(\n {\n cameraId: selectedCamera,\n cameraConfigs: {\n facingMode: getOptimalCameraFacingMode()\n },\n timeout: 60000 // 60 seconds\n },\n {\n onQRDetected: (qrData) => {\n console.log('useQRCamera: Valid QR data detected -', {\n devicePublicKey: qrData.device2PublicKey,\n accountId: qrData.accountId,\n timestamp: new Date(qrData.timestamp || 0).toISOString()\n });\n setIsProcessing(false);\n setIsScanning(false);\n setScanDurationMs(0);\n onQRDetected?.(qrData);\n },\n onError: (err) => {\n console.error('useQRCamera: QR scan error -', err);\n setError(err.message);\n setIsProcessing(false);\n setIsScanning(false);\n setScanDurationMs(0);\n onError?.(err);\n },\n onCameraReady: (stream) => {\n // Camera stream is ready, but video element attachment is handled separately\n console.log('useQRCamera: Camera stream ready');\n },\n onScanProgress: (duration) => {\n setScanDurationMs(duration);\n }\n }\n );\n\n return () => {\n if (flowRef.current) {\n // Hook Cleanup Point 1: Stop scanning and cleanup\n flowRef.current.stop();\n flowRef.current = null;\n }\n };\n }, []); // Only initialize once\n\n // Load cameras on mount\n useEffect(() => {\n const loadCameras = async () => {\n try {\n const videoDevices = await enumerateVideoDevices();\n setCameras(videoDevices);\n\n if (videoDevices.length > 0 && !selectedCamera) {\n const firstCamera = videoDevices[0];\n setSelectedCamera(firstCamera.deviceId);\n setIsFrontCamera(detectFrontCamera(firstCamera));\n }\n } catch (error: any) {\n setError(error.message);\n }\n };\n\n loadCameras();\n }, []);\n\n // Update flow camera when selectedCamera changes\n useEffect(() => {\n if (flowRef.current && selectedCamera) {\n flowRef.current.switchCamera(selectedCamera);\n }\n }, [selectedCamera]);\n\n // Attach/detach video element when ref changes\n useEffect(() => {\n if (videoRef.current && flowRef.current) {\n flowRef.current.attachVideoElement(videoRef.current);\n }\n\n return () => {\n if (flowRef.current) {\n flowRef.current.detachVideoElement();\n }\n };\n }, [videoRef.current]);\n\n // Hook Cleanup Point 2: (when modal closes or scan mode changes from camera to file)\n useEffect(() => {\n const flow = flowRef.current;\n if (!flow) return;\n\n if (isOpen && scanMode === QRScanMode.CAMERA) {\n setError(null);\n setIsProcessing(true);\n setIsScanning(true);\n setScanDurationMs(0);\n flow.startQRScanner();\n } else {\n flow.stop();\n setIsScanning(false);\n setIsProcessing(false);\n setScanDurationMs(0);\n }\n }, [isOpen, scanMode]);\n\n // Manual controls\n const startScanning = useCallback(async () => {\n if (flowRef.current) {\n setError(null);\n setIsProcessing(true);\n setIsScanning(true);\n setScanDurationMs(0);\n await flowRef.current.startQRScanner();\n }\n }, []);\n\n // Hook Cleanup Point 3: called when user explicitly stops scanning\n const stopScanning = useCallback(() => {\n if (flowRef.current) {\n flowRef.current.stop();\n setIsScanning(false);\n setIsProcessing(false);\n setScanDurationMs(0);\n }\n }, []);\n\n // Handle camera change\n const handleCameraChange = useCallback(async (deviceId: string) => {\n setSelectedCamera(deviceId);\n\n const selectedCameraDevice = cameras.find(camera => camera.deviceId === deviceId);\n if (selectedCameraDevice) {\n setIsFrontCamera(detectFrontCamera(selectedCameraDevice));\n }\n\n // The useEffect will handle updating the flow\n }, [cameras]);\n\n const getOptimalFacingMode = useCallback(() => getOptimalCameraFacingMode(), []);\n\n return {\n // State\n isScanning,\n isProcessing,\n error,\n cameras,\n selectedCamera,\n scanMode,\n isFrontCamera,\n scanDurationMs,\n\n // Refs for UI\n videoRef,\n canvasRef,\n\n // Controls\n startScanning,\n stopScanning,\n handleCameraChange,\n setScanMode,\n setError,\n\n // Utilities\n getOptimalFacingMode\n };\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BA,IAAY,oDAAL;AACL;AACA;AACA;;;AAoCF,MAAa,eAAe,YAAmD;CAC7E,MAAM,EACJ,cACA,SACA,SAAS,MACT,aACE;CAGJ,MAAM,6BAAoC;CAC1C,MAAM,8BAAsC;CAC5C,MAAM,4BAAwC;CAG9C,MAAM,CAAC,YAAY,qCAA0B;CAC7C,MAAM,CAAC,cAAc,uCAA4B;CACjD,MAAM,CAAC,OAAO,gCAAoC;CAClD,MAAM,CAAC,SAAS,kCAA0C;CAC1D,MAAM,CAAC,gBAAgB,yCAAsC,YAAY;CACzE,MAAM,CAAC,UAAU,mCAAoC,WAAW;CAChE,MAAM,CAAC,eAAe,wCAAsC;CAC5D,MAAM,CAAC,gBAAgB,yCAAsC;AAI7D,4BAAgB;AACd,UAAQ,UAAU,IAAIA,iCACpB;GACE,UAAU;GACV,eAAe,EACb,YAAYC;GAEd,SAAS;KAEX;GACE,eAAe,WAAW;AACxB,YAAQ,IAAI,yCAAyC;KACnD,iBAAiB,OAAO;KACxB,WAAW,OAAO;KAClB,WAAW,IAAI,KAAK,OAAO,aAAa,GAAG;;AAE7C,oBAAgB;AAChB,kBAAc;AACd,sBAAkB;AAClB,mBAAe;;GAEjB,UAAU,QAAQ;AAChB,YAAQ,MAAM,gCAAgC;AAC9C,aAAS,IAAI;AACb,oBAAgB;AAChB,kBAAc;AACd,sBAAkB;AAClB,cAAU;;GAEZ,gBAAgB,WAAW;AAEzB,YAAQ,IAAI;;GAEd,iBAAiB,aAAa;AAC5B,sBAAkB;;;AAKxB,eAAa;AACX,OAAI,QAAQ,SAAS;AAEnB,YAAQ,QAAQ;AAChB,YAAQ,UAAU;;;IAGrB;AAGH,4BAAgB;EACd,MAAM,cAAc,YAAY;AAC9B,OAAI;IACF,MAAM,eAAe,MAAMC;AAC3B,eAAW;AAEX,QAAI,aAAa,SAAS,KAAK,CAAC,gBAAgB;KAC9C,MAAM,cAAc,aAAa;AACjC,uBAAkB,YAAY;AAC9B,sBAAiBC,oCAAkB;;YAE9BC,SAAY;AACnB,aAASC,QAAM;;;AAInB;IACC;AAGH,4BAAgB;AACd,MAAI,QAAQ,WAAW,eACrB,SAAQ,QAAQ,aAAa;IAE9B,CAAC;AAGJ,4BAAgB;AACd,MAAI,SAAS,WAAW,QAAQ,QAC9B,SAAQ,QAAQ,mBAAmB,SAAS;AAG9C,eAAa;AACX,OAAI,QAAQ,QACV,SAAQ,QAAQ;;IAGnB,CAAC,SAAS;AAGb,4BAAgB;EACd,MAAM,OAAO,QAAQ;AACrB,MAAI,CAAC,KAAM;AAEX,MAAI,UAAU,aAAa,WAAW,QAAQ;AAC5C,YAAS;AACT,mBAAgB;AAChB,iBAAc;AACd,qBAAkB;AAClB,QAAK;SACA;AACL,QAAK;AACL,iBAAc;AACd,mBAAgB;AAChB,qBAAkB;;IAEnB,CAAC,QAAQ;CAGZ,MAAM,uCAA4B,YAAY;AAC5C,MAAI,QAAQ,SAAS;AACnB,YAAS;AACT,mBAAgB;AAChB,iBAAc;AACd,qBAAkB;AAClB,SAAM,QAAQ,QAAQ;;IAEvB;CAGH,MAAM,4CAAiC;AACrC,MAAI,QAAQ,SAAS;AACnB,WAAQ,QAAQ;AAChB,iBAAc;AACd,mBAAgB;AAChB,qBAAkB;;IAEnB;CAGH,MAAM,4CAAiC,OAAO,aAAqB;AACjE,oBAAkB;EAElB,MAAM,uBAAuB,QAAQ,MAAK,WAAU,OAAO,aAAa;AACxE,MAAI,qBACF,kBAAiBF,oCAAkB;IAIpC,CAAC;CAEJ,MAAM,oDAAyCF,sDAA8B;AAE7E,QAAO;EAEL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAGA;EACA;EAGA;EACA;EACA;EACA;EACA;EAGA"}
@@ -6,11 +6,18 @@ const require_index = require('../IndexedDBManager/index.js');
6
6
  require_accountIds.init_accountIds();
7
7
  require_index.init_IndexedDBManager();
8
8
  const canonicalizeEmail = (email) => {
9
- let addr = email;
10
- const angleStart = email.indexOf("<");
11
- const angleEnd = email.indexOf(">");
12
- if (angleStart !== -1 && angleEnd > angleStart) addr = email.slice(angleStart + 1, angleEnd);
13
- return addr.trim().toLowerCase();
9
+ const raw = String(email || "").trim();
10
+ if (!raw) return "";
11
+ const withoutHeaderName = raw.replace(/^[a-z0-9-]+\s*:\s*/i, "").trim();
12
+ const emailRegex = /([a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*)/;
13
+ const angleMatch = withoutHeaderName.match(/<([^>]+)>/);
14
+ const candidates = [angleMatch?.[1], withoutHeaderName].filter((v) => typeof v === "string" && v.length > 0);
15
+ for (const candidate of candidates) {
16
+ const cleaned = candidate.replace(/^mailto:\s*/i, "");
17
+ const match = cleaned.match(emailRegex);
18
+ if (match?.[1]) return match[1].trim().toLowerCase();
19
+ }
20
+ return withoutHeaderName.toLowerCase();
14
21
  };
15
22
  const bytesToHex = (bytes) => {
16
23
  const arr = bytes instanceof Uint8Array ? bytes : Uint8Array.from(bytes);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["hashed: number[][]","toAccountId","pairs: RecoveryEmailEntry[]","IndexedDBManager"],"sources":["../../../../../../../src/core/EmailRecovery/index.ts"],"sourcesContent":["import type { AccountId } from '../types/accountIds';\nimport { toAccountId } from '../types/accountIds';\nimport { IndexedDBManager, type RecoveryEmailRecord } from '../IndexedDBManager';\n\nexport type RecoveryEmailEntry = {\n hashHex: string;\n email: string;\n};\n\nexport { type RecoveryEmailRecord };\n\nexport const canonicalizeEmail = (email: string): string => {\n let addr = email;\n const angleStart = email.indexOf('<');\n const angleEnd = email.indexOf('>');\n if (angleStart !== -1 && angleEnd > angleStart) {\n addr = email.slice(angleStart + 1, angleEnd);\n }\n return addr.trim().toLowerCase();\n};\n\nexport const bytesToHex = (bytes: number[] | Uint8Array): string => {\n const arr = bytes instanceof Uint8Array ? bytes : Uint8Array.from(bytes);\n return `0x${Array.from(arr)\n .map(b => b.toString(16).padStart(2, '0'))\n .join('')}`;\n};\n\nasync function hashRecoveryEmails(emails: string[], accountId: AccountId): Promise<number[][]> {\n const encoder = new TextEncoder();\n const salt = (accountId || '').trim().toLowerCase();\n const normalized = (emails || [])\n .map(e => e.trim())\n .filter(e => e.length > 0);\n\n const hashed: number[][] = [];\n\n for (const email of normalized) {\n try {\n const canonicalEmail = canonicalizeEmail(email);\n const input = `${canonicalEmail}|${salt}`;\n const data = encoder.encode(input);\n const digest = await crypto.subtle.digest('SHA-256', data);\n const bytes = new Uint8Array(digest);\n hashed.push(Array.from(bytes));\n } catch {\n const bytes = encoder.encode(email.toLowerCase());\n hashed.push(Array.from(bytes));\n }\n }\n\n return hashed;\n}\n\n/**\n * Canonicalize and hash recovery emails for an account, and persist the mapping\n * (hashHex → canonical email) in IndexedDB on a best-effort basis.\n */\nexport async function prepareRecoveryEmails(nearAccountId: AccountId, recoveryEmails: string[]): Promise<{\n hashes: number[][];\n pairs: RecoveryEmailEntry[];\n}> {\n const accountId = toAccountId(nearAccountId);\n\n const trimmedEmails = (recoveryEmails || []).map(e => e.trim()).filter(e => e.length > 0);\n const canonicalEmails = trimmedEmails.map(canonicalizeEmail);\n const recoveryEmailHashes = await hashRecoveryEmails(recoveryEmails, accountId);\n\n const pairs: RecoveryEmailEntry[] = recoveryEmailHashes.map((hashBytes, idx) => ({\n hashHex: bytesToHex(hashBytes),\n email: canonicalEmails[idx],\n }));\n\n void (async () => {\n try {\n await IndexedDBManager.upsertRecoveryEmails(accountId, pairs);\n } catch (error) {\n console.warn('[EmailRecovery] Failed to persist local recovery emails', error);\n }\n })();\n\n return { hashes: recoveryEmailHashes, pairs };\n}\n\nexport async function getLocalRecoveryEmails(nearAccountId: AccountId): Promise<RecoveryEmailRecord[]> {\n return IndexedDBManager.getRecoveryEmails(nearAccountId);\n}\n"],"mappings":";;;;;;;AAWA,MAAa,qBAAqB,UAA0B;CAC1D,IAAI,OAAO;CACX,MAAM,aAAa,MAAM,QAAQ;CACjC,MAAM,WAAW,MAAM,QAAQ;AAC/B,KAAI,eAAe,MAAM,WAAW,WAClC,QAAO,MAAM,MAAM,aAAa,GAAG;AAErC,QAAO,KAAK,OAAO;;AAGrB,MAAa,cAAc,UAAyC;CAClE,MAAM,MAAM,iBAAiB,aAAa,QAAQ,WAAW,KAAK;AAClE,QAAO,KAAK,MAAM,KAAK,KACpB,KAAI,MAAK,EAAE,SAAS,IAAI,SAAS,GAAG,MACpC,KAAK;;AAGV,eAAe,mBAAmB,QAAkB,WAA2C;CAC7F,MAAM,UAAU,IAAI;CACpB,MAAM,QAAQ,aAAa,IAAI,OAAO;CACtC,MAAM,cAAc,UAAU,IAC3B,KAAI,MAAK,EAAE,QACX,QAAO,MAAK,EAAE,SAAS;CAE1B,MAAMA,SAAqB;AAE3B,MAAK,MAAM,SAAS,WAClB,KAAI;EACF,MAAM,iBAAiB,kBAAkB;EACzC,MAAM,QAAQ,GAAG,eAAe,GAAG;EACnC,MAAM,OAAO,QAAQ,OAAO;EAC5B,MAAM,SAAS,MAAM,OAAO,OAAO,OAAO,WAAW;EACrD,MAAM,QAAQ,IAAI,WAAW;AAC7B,SAAO,KAAK,MAAM,KAAK;SACjB;EACN,MAAM,QAAQ,QAAQ,OAAO,MAAM;AACnC,SAAO,KAAK,MAAM,KAAK;;AAI3B,QAAO;;;;;;AAOT,eAAsB,sBAAsB,eAA0B,gBAGnE;CACD,MAAM,YAAYC,+BAAY;CAE9B,MAAM,iBAAiB,kBAAkB,IAAI,KAAI,MAAK,EAAE,QAAQ,QAAO,MAAK,EAAE,SAAS;CACvF,MAAM,kBAAkB,cAAc,IAAI;CAC1C,MAAM,sBAAsB,MAAM,mBAAmB,gBAAgB;CAErE,MAAMC,QAA8B,oBAAoB,KAAK,WAAW,SAAS;EAC/E,SAAS,WAAW;EACpB,OAAO,gBAAgB;;AAGzB,EAAM,YAAY;AAChB,MAAI;AACF,SAAMC,+BAAiB,qBAAqB,WAAW;WAChD,OAAO;AACd,WAAQ,KAAK,2DAA2D;;;AAI5E,QAAO;EAAE,QAAQ;EAAqB;;;AAGxC,eAAsB,uBAAuB,eAA0D;AACrG,QAAOA,+BAAiB,kBAAkB"}
1
+ {"version":3,"file":"index.js","names":["hashed: number[][]","toAccountId","pairs: RecoveryEmailEntry[]","IndexedDBManager"],"sources":["../../../../../../../src/core/EmailRecovery/index.ts"],"sourcesContent":["import type { AccountId } from '../types/accountIds';\nimport { toAccountId } from '../types/accountIds';\nimport { IndexedDBManager, type RecoveryEmailRecord } from '../IndexedDBManager';\n\nexport type RecoveryEmailEntry = {\n hashHex: string;\n email: string;\n};\n\nexport { type RecoveryEmailRecord };\n\nexport const canonicalizeEmail = (email: string): string => {\n const raw = String(email || '').trim();\n if (!raw) return '';\n\n // Handle cases where a full header line is passed in (e.g. \"From: ...\").\n const withoutHeaderName = raw.replace(/^[a-z0-9-]+\\s*:\\s*/i, '').trim();\n\n const emailRegex =\n /([a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\\.[a-zA-Z0-9-]+)*)/;\n\n // Prefer the common \"Name <email@domain>\" format when present, but still\n // validate/extract the actual address via regex.\n const angleMatch = withoutHeaderName.match(/<([^>]+)>/);\n const candidates = [\n angleMatch?.[1],\n withoutHeaderName,\n ].filter((v): v is string => typeof v === 'string' && v.length > 0);\n\n for (const candidate of candidates) {\n const cleaned = candidate.replace(/^mailto:\\s*/i, '');\n const match = cleaned.match(emailRegex);\n if (match?.[1]) {\n return match[1].trim().toLowerCase();\n }\n }\n\n return withoutHeaderName.toLowerCase();\n};\n\nexport const bytesToHex = (bytes: number[] | Uint8Array): string => {\n const arr = bytes instanceof Uint8Array ? bytes : Uint8Array.from(bytes);\n return `0x${Array.from(arr)\n .map(b => b.toString(16).padStart(2, '0'))\n .join('')}`;\n};\n\nasync function hashRecoveryEmails(emails: string[], accountId: AccountId): Promise<number[][]> {\n const encoder = new TextEncoder();\n const salt = (accountId || '').trim().toLowerCase();\n const normalized = (emails || [])\n .map(e => e.trim())\n .filter(e => e.length > 0);\n\n const hashed: number[][] = [];\n\n for (const email of normalized) {\n try {\n const canonicalEmail = canonicalizeEmail(email);\n const input = `${canonicalEmail}|${salt}`;\n const data = encoder.encode(input);\n const digest = await crypto.subtle.digest('SHA-256', data);\n const bytes = new Uint8Array(digest);\n hashed.push(Array.from(bytes));\n } catch {\n const bytes = encoder.encode(email.toLowerCase());\n hashed.push(Array.from(bytes));\n }\n }\n\n return hashed;\n}\n\n/**\n * Canonicalize and hash recovery emails for an account, and persist the mapping\n * (hashHex → canonical email) in IndexedDB on a best-effort basis.\n */\nexport async function prepareRecoveryEmails(nearAccountId: AccountId, recoveryEmails: string[]): Promise<{\n hashes: number[][];\n pairs: RecoveryEmailEntry[];\n}> {\n const accountId = toAccountId(nearAccountId);\n\n const trimmedEmails = (recoveryEmails || []).map(e => e.trim()).filter(e => e.length > 0);\n const canonicalEmails = trimmedEmails.map(canonicalizeEmail);\n const recoveryEmailHashes = await hashRecoveryEmails(recoveryEmails, accountId);\n\n const pairs: RecoveryEmailEntry[] = recoveryEmailHashes.map((hashBytes, idx) => ({\n hashHex: bytesToHex(hashBytes),\n email: canonicalEmails[idx],\n }));\n\n void (async () => {\n try {\n await IndexedDBManager.upsertRecoveryEmails(accountId, pairs);\n } catch (error) {\n console.warn('[EmailRecovery] Failed to persist local recovery emails', error);\n }\n })();\n\n return { hashes: recoveryEmailHashes, pairs };\n}\n\nexport async function getLocalRecoveryEmails(nearAccountId: AccountId): Promise<RecoveryEmailRecord[]> {\n return IndexedDBManager.getRecoveryEmails(nearAccountId);\n}\n"],"mappings":";;;;;;;AAWA,MAAa,qBAAqB,UAA0B;CAC1D,MAAM,MAAM,OAAO,SAAS,IAAI;AAChC,KAAI,CAAC,IAAK,QAAO;CAGjB,MAAM,oBAAoB,IAAI,QAAQ,uBAAuB,IAAI;CAEjE,MAAM,aACJ;CAIF,MAAM,aAAa,kBAAkB,MAAM;CAC3C,MAAM,aAAa,CACjB,aAAa,IACb,mBACA,QAAQ,MAAmB,OAAO,MAAM,YAAY,EAAE,SAAS;AAEjE,MAAK,MAAM,aAAa,YAAY;EAClC,MAAM,UAAU,UAAU,QAAQ,gBAAgB;EAClD,MAAM,QAAQ,QAAQ,MAAM;AAC5B,MAAI,QAAQ,GACV,QAAO,MAAM,GAAG,OAAO;;AAI3B,QAAO,kBAAkB;;AAG3B,MAAa,cAAc,UAAyC;CAClE,MAAM,MAAM,iBAAiB,aAAa,QAAQ,WAAW,KAAK;AAClE,QAAO,KAAK,MAAM,KAAK,KACpB,KAAI,MAAK,EAAE,SAAS,IAAI,SAAS,GAAG,MACpC,KAAK;;AAGV,eAAe,mBAAmB,QAAkB,WAA2C;CAC7F,MAAM,UAAU,IAAI;CACpB,MAAM,QAAQ,aAAa,IAAI,OAAO;CACtC,MAAM,cAAc,UAAU,IAC3B,KAAI,MAAK,EAAE,QACX,QAAO,MAAK,EAAE,SAAS;CAE1B,MAAMA,SAAqB;AAE3B,MAAK,MAAM,SAAS,WAClB,KAAI;EACF,MAAM,iBAAiB,kBAAkB;EACzC,MAAM,QAAQ,GAAG,eAAe,GAAG;EACnC,MAAM,OAAO,QAAQ,OAAO;EAC5B,MAAM,SAAS,MAAM,OAAO,OAAO,OAAO,WAAW;EACrD,MAAM,QAAQ,IAAI,WAAW;AAC7B,SAAO,KAAK,MAAM,KAAK;SACjB;EACN,MAAM,QAAQ,QAAQ,OAAO,MAAM;AACnC,SAAO,KAAK,MAAM,KAAK;;AAI3B,QAAO;;;;;;AAOT,eAAsB,sBAAsB,eAA0B,gBAGnE;CACD,MAAM,YAAYC,+BAAY;CAE9B,MAAM,iBAAiB,kBAAkB,IAAI,KAAI,MAAK,EAAE,QAAQ,QAAO,MAAK,EAAE,SAAS;CACvF,MAAM,kBAAkB,cAAc,IAAI;CAC1C,MAAM,sBAAsB,MAAM,mBAAmB,gBAAgB;CAErE,MAAMC,QAA8B,oBAAoB,KAAK,WAAW,SAAS;EAC/E,SAAS,WAAW;EACpB,OAAO,gBAAgB;;AAGzB,EAAM,YAAY;AAChB,MAAI;AACF,SAAMC,+BAAiB,qBAAqB,WAAW;WAChD,OAAO;AACd,WAAQ,KAAK,2DAA2D;;;AAI5E,QAAO;EAAE,QAAQ;EAAqB;;;AAGxC,eAAsB,uBAAuB,eAA0D;AACrG,QAAOA,+BAAiB,kBAAkB"}
@@ -260,22 +260,17 @@ var init_passkeyClientDB = require_rolldown_runtime.__esm({ "src/core/IndexedDBM
260
260
  * @returns filtered authenticators for allowCredentials, plus optional wrongPasskeyError
261
261
  */
262
262
  async ensureCurrentPasskey(nearAccountId, authenticators, selectedCredentialRawId) {
263
- let authenticatorsForPrompt = authenticators;
264
- let wrongPasskeyError;
265
- if (authenticators.length > 1) {
266
- const accountIdNormalized = require_accountIds.toAccountId(nearAccountId);
267
- const lastUser = await this.getLastUser().catch(() => null);
268
- const expectedAccountId = lastUser?.nearAccountId;
269
- const expectedDeviceNumber = lastUser?.deviceNumber;
270
- if (expectedAccountId && expectedDeviceNumber && expectedAccountId === accountIdNormalized) {
271
- const filtered = authenticators.filter((a) => a.deviceNumber === expectedDeviceNumber);
272
- if (filtered.length > 0) authenticatorsForPrompt = filtered;
273
- if (selectedCredentialRawId) {
274
- const matched = authenticators.find((a) => a.credentialId === selectedCredentialRawId);
275
- if (matched && matched.deviceNumber !== expectedDeviceNumber) wrongPasskeyError = `You have multiple passkeys (deviceNumbers) for account ${accountIdNormalized}, but used a passkey from a different device. Please use the passkey for the most recently logged-in device.`;
276
- }
277
- }
278
- }
263
+ if (authenticators.length <= 1) return { authenticatorsForPrompt: authenticators };
264
+ const accountIdNormalized = require_accountIds.toAccountId(nearAccountId);
265
+ const lastUser = await this.getLastUser().catch(() => null);
266
+ if (!lastUser || lastUser.nearAccountId !== accountIdNormalized) return { authenticatorsForPrompt: authenticators };
267
+ const expectedDeviceNumber = lastUser.deviceNumber;
268
+ const byDeviceNumber = authenticators.filter((a) => a.deviceNumber === expectedDeviceNumber);
269
+ let expectedCredentialId = lastUser.passkeyCredential.rawId;
270
+ if (byDeviceNumber.length > 0 && !byDeviceNumber.some((a) => a.credentialId === expectedCredentialId)) expectedCredentialId = byDeviceNumber[0].credentialId;
271
+ const byCredentialId = authenticators.filter((a) => a.credentialId === expectedCredentialId);
272
+ const authenticatorsForPrompt = byCredentialId.length > 0 ? byCredentialId : byDeviceNumber.length > 0 ? byDeviceNumber : authenticators;
273
+ const wrongPasskeyError = selectedCredentialRawId && selectedCredentialRawId !== expectedCredentialId ? `You have multiple passkeys (deviceNumbers) for account ${accountIdNormalized}, but used a different passkey than the most recently logged-in one. Please use the passkey for the most recently logged-in device.` : void 0;
279
274
  return {
280
275
  authenticatorsForPrompt,
281
276
  wrongPasskeyError
@@ -386,30 +381,34 @@ var init_passkeyClientDB = require_rolldown_runtime.__esm({ "src/core/IndexedDBM
386
381
  * @param userData - User data with nearAccountId as primary identifier
387
382
  */
388
383
  async storeWebAuthnUserData(userData) {
389
- if (userData.deviceNumber === void 0) console.warn("WARNING: deviceNumber is undefined in storeWebAuthnUserData, will default to 1");
390
384
  const validation = this.validateNearAccountId(userData.nearAccountId);
391
385
  if (!validation.valid) throw new Error(`Cannot store WebAuthn data for invalid account ID: ${validation.error}`);
392
- let existingUser = await this.getUser(userData.nearAccountId);
393
- if (!existingUser) {
394
- const deviceNumberToUse = userData.deviceNumber || 1;
395
- existingUser = await this.registerUser({
396
- nearAccountId: userData.nearAccountId,
397
- deviceNumber: deviceNumberToUse,
398
- clientNearPublicKey: userData.clientNearPublicKey,
399
- passkeyCredential: userData.passkeyCredential,
400
- encryptedVrfKeypair: userData.encryptedVrfKeypair,
401
- version: userData.version || 2,
402
- serverEncryptedVrfKeypair: userData.serverEncryptedVrfKeypair
403
- });
404
- }
405
- const finalDeviceNumber = userData.deviceNumber || existingUser.deviceNumber;
406
- await this.updateUser(userData.nearAccountId, {
386
+ const accountId = require_accountIds.toAccountId(userData.nearAccountId);
387
+ const deviceNumber = userData.deviceNumber;
388
+ let user = await this.getUser(accountId, deviceNumber);
389
+ if (!user) user = await this.registerUser({
390
+ nearAccountId: accountId,
391
+ deviceNumber,
407
392
  clientNearPublicKey: userData.clientNearPublicKey,
393
+ passkeyCredential: userData.passkeyCredential,
408
394
  encryptedVrfKeypair: userData.encryptedVrfKeypair,
409
- serverEncryptedVrfKeypair: userData.serverEncryptedVrfKeypair,
410
- version: userData.version || existingUser.version,
411
- deviceNumber: finalDeviceNumber,
412
- lastUpdated: userData.lastUpdated || Date.now()
395
+ version: userData.version || 2,
396
+ serverEncryptedVrfKeypair: userData.serverEncryptedVrfKeypair
397
+ });
398
+ const updatedUser = {
399
+ ...user,
400
+ clientNearPublicKey: userData.clientNearPublicKey,
401
+ passkeyCredential: userData.passkeyCredential,
402
+ encryptedVrfKeypair: userData.encryptedVrfKeypair,
403
+ serverEncryptedVrfKeypair: userData.serverEncryptedVrfKeypair ?? user.serverEncryptedVrfKeypair,
404
+ version: userData.version ?? user.version,
405
+ lastUpdated: userData.lastUpdated ?? Date.now()
406
+ };
407
+ await this.storeUser(updatedUser);
408
+ this.emitEvent({
409
+ type: "user-updated",
410
+ accountId,
411
+ data: { updatedUser }
413
412
  });
414
413
  }
415
414
  async getAllUsers() {