@tatchi-xyz/sdk 0.16.0 → 0.18.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 (501) hide show
  1. package/dist/cjs/core/EmailRecovery/emailRecoveryPendingStore.js +69 -0
  2. package/dist/cjs/core/EmailRecovery/emailRecoveryPendingStore.js.map +1 -0
  3. package/dist/cjs/core/EmailRecovery/index.js +32 -13
  4. package/dist/cjs/core/EmailRecovery/index.js.map +1 -1
  5. package/dist/cjs/core/IndexedDBManager/passkeyClientDB.js +35 -36
  6. package/dist/cjs/core/IndexedDBManager/passkeyClientDB.js.map +1 -1
  7. package/dist/cjs/core/NearClient.js +2 -1
  8. package/dist/cjs/core/NearClient.js.map +1 -1
  9. package/dist/cjs/core/TatchiPasskey/emailRecovery.js +557 -377
  10. package/dist/cjs/core/TatchiPasskey/emailRecovery.js.map +1 -1
  11. package/dist/cjs/core/TatchiPasskey/faucets/createAccountRelayServer.js +1 -0
  12. package/dist/cjs/core/TatchiPasskey/faucets/createAccountRelayServer.js.map +1 -1
  13. package/dist/cjs/core/TatchiPasskey/index.js +26 -0
  14. package/dist/cjs/core/TatchiPasskey/index.js.map +1 -1
  15. package/dist/cjs/core/TatchiPasskey/linkDevice.js +2 -0
  16. package/dist/cjs/core/TatchiPasskey/linkDevice.js.map +1 -1
  17. package/dist/cjs/core/TatchiPasskey/login.js +15 -4
  18. package/dist/cjs/core/TatchiPasskey/login.js.map +1 -1
  19. package/dist/cjs/core/TatchiPasskey/recoverAccount.js +1 -0
  20. package/dist/cjs/core/TatchiPasskey/recoverAccount.js.map +1 -1
  21. package/dist/cjs/core/TatchiPasskey/relay.js +23 -1
  22. package/dist/cjs/core/TatchiPasskey/relay.js.map +1 -1
  23. package/dist/cjs/core/TatchiPasskey/scanDevice.js +1 -0
  24. package/dist/cjs/core/TatchiPasskey/scanDevice.js.map +1 -1
  25. package/dist/cjs/core/WalletIframe/client/IframeTransport.js +3 -0
  26. package/dist/cjs/core/WalletIframe/client/IframeTransport.js.map +1 -1
  27. package/dist/cjs/core/WalletIframe/client/router.js +15 -2
  28. package/dist/cjs/core/WalletIframe/client/router.js.map +1 -1
  29. package/dist/cjs/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-drawer.js +1 -1
  30. package/dist/cjs/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-drawer.js.map +1 -1
  31. package/dist/cjs/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-modal.js +52 -52
  32. package/dist/cjs/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-modal.js.map +1 -1
  33. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/getDeviceNumber.js +10 -1
  34. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/getDeviceNumber.js.map +1 -1
  35. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/checkCanRegisterUser.js +1 -0
  36. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/checkCanRegisterUser.js.map +1 -1
  37. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/decryptPrivateKeyWithPrf.js +1 -0
  38. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/decryptPrivateKeyWithPrf.js.map +1 -1
  39. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/deriveNearKeypairAndEncryptFromSerialized.js +1 -0
  40. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/deriveNearKeypairAndEncryptFromSerialized.js.map +1 -1
  41. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/exportNearKeypairUi.js +1 -0
  42. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/exportNearKeypairUi.js.map +1 -1
  43. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/registerDevice2WithDerivedKey.js +2 -1
  44. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/registerDevice2WithDerivedKey.js.map +1 -1
  45. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/signDelegateAction.js +1 -0
  46. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/signDelegateAction.js.map +1 -1
  47. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/signNep413Message.js +1 -0
  48. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/signNep413Message.js.map +1 -1
  49. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/signTransactionsWithActions.js +1 -0
  50. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/signTransactionsWithActions.js.map +1 -1
  51. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/validation.js +2 -0
  52. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/validation.js.map +1 -1
  53. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/index.js +1 -0
  54. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/index.js.map +1 -1
  55. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/vrf.js +1 -0
  56. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/vrf.js.map +1 -1
  57. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/webauthn.js +6 -0
  58. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/webauthn.js.map +1 -1
  59. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/determineConfirmationConfig.js +2 -1
  60. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/determineConfirmationConfig.js.map +1 -1
  61. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/localOnly.js +1 -0
  62. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/localOnly.js.map +1 -1
  63. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/registration.js +1 -0
  64. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/registration.js.map +1 -1
  65. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/transactions.js +4 -15
  66. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/transactions.js.map +1 -1
  67. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/handlers/deriveVrfKeypairFromPrf.js +1 -0
  68. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/handlers/deriveVrfKeypairFromPrf.js.map +1 -1
  69. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfChallenge.js +1 -0
  70. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfChallenge.js.map +1 -1
  71. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfKeypairBootstrap.js +1 -0
  72. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfKeypairBootstrap.js.map +1 -1
  73. package/dist/cjs/core/WebAuthnManager/WebAuthnFallbacks/index.js +17 -0
  74. package/dist/cjs/core/WebAuthnManager/WebAuthnFallbacks/index.js.map +1 -0
  75. package/dist/cjs/core/WebAuthnManager/WebAuthnFallbacks/safari-fallbacks.js +64 -54
  76. package/dist/cjs/core/WebAuthnManager/WebAuthnFallbacks/safari-fallbacks.js.map +1 -1
  77. package/dist/cjs/core/WebAuthnManager/credentialsHelpers.js +12 -2
  78. package/dist/cjs/core/WebAuthnManager/credentialsHelpers.js.map +1 -1
  79. package/dist/cjs/core/WebAuthnManager/index.js +6 -1
  80. package/dist/cjs/core/WebAuthnManager/index.js.map +1 -1
  81. package/dist/cjs/core/WebAuthnManager/touchIdPrompt.js +209 -201
  82. package/dist/cjs/core/WebAuthnManager/touchIdPrompt.js.map +1 -1
  83. package/dist/cjs/core/WebAuthnManager/userHandle.js +2 -1
  84. package/dist/cjs/core/WebAuthnManager/userHandle.js.map +1 -1
  85. package/dist/cjs/core/defaultConfigs.js +1 -1
  86. package/dist/cjs/core/defaultConfigs.js.map +1 -1
  87. package/dist/cjs/core/rpcCalls.js +8 -0
  88. package/dist/cjs/core/rpcCalls.js.map +1 -1
  89. package/dist/cjs/core/types/vrf-worker.js +10 -1
  90. package/dist/cjs/core/types/vrf-worker.js.map +1 -1
  91. package/dist/cjs/index.js +6 -2
  92. package/dist/cjs/index.js.map +1 -1
  93. package/dist/cjs/react/components/AccountMenuButton/{LinkedDevicesModal-STvIsylA.css → LinkedDevicesModal-CSSowiHP.css} +1 -1
  94. package/dist/{esm/react/components/AccountMenuButton/LinkedDevicesModal-STvIsylA.css.map → cjs/react/components/AccountMenuButton/LinkedDevicesModal-CSSowiHP.css.map} +1 -1
  95. package/dist/cjs/react/components/AccountMenuButton/{ProfileDropdown-iARgUwK1.css → ProfileDropdown-CEPMZ1gY.css} +1 -1
  96. package/dist/{esm/react/components/AccountMenuButton/ProfileDropdown-iARgUwK1.css.map → cjs/react/components/AccountMenuButton/ProfileDropdown-CEPMZ1gY.css.map} +1 -1
  97. package/dist/cjs/react/components/AccountMenuButton/{Web3AuthProfileButton-Db3NeoAC.css → Web3AuthProfileButton-DopOg7Xc.css} +1 -1
  98. package/dist/cjs/react/components/AccountMenuButton/{Web3AuthProfileButton-Db3NeoAC.css.map → Web3AuthProfileButton-DopOg7Xc.css.map} +1 -1
  99. package/dist/cjs/react/components/AccountMenuButton/icons/{TouchIcon-BXM5NR4A.css → TouchIcon-BQWentvJ.css} +1 -1
  100. package/dist/cjs/react/components/AccountMenuButton/icons/{TouchIcon-BXM5NR4A.css.map → TouchIcon-BQWentvJ.css.map} +1 -1
  101. package/dist/cjs/react/components/PasskeyAuthMenu/{PasskeyAuthMenu-De1qTSmU.css → PasskeyAuthMenu-DwrzWMYx.css} +14 -1
  102. package/dist/cjs/react/components/PasskeyAuthMenu/{PasskeyAuthMenu-De1qTSmU.css.map → PasskeyAuthMenu-DwrzWMYx.css.map} +1 -1
  103. package/dist/cjs/react/components/PasskeyAuthMenu/ui/EmailRecoverySlide.js +122 -53
  104. package/dist/cjs/react/components/PasskeyAuthMenu/ui/EmailRecoverySlide.js.map +1 -1
  105. package/dist/cjs/react/components/{ShowQRCode-DCnR__fx.css → ShowQRCode-CCN4h6Uv.css} +1 -1
  106. package/dist/cjs/react/components/{ShowQRCode-DCnR__fx.css.map → ShowQRCode-CCN4h6Uv.css.map} +1 -1
  107. package/dist/cjs/react/deviceDetection.js +75 -92
  108. package/dist/cjs/react/deviceDetection.js.map +1 -1
  109. package/dist/cjs/react/hooks/useQRCamera.js +1 -0
  110. package/dist/cjs/react/hooks/useQRCamera.js.map +1 -1
  111. package/dist/cjs/react/sdk/src/core/EmailRecovery/emailRecoveryPendingStore.js +69 -0
  112. package/dist/cjs/react/sdk/src/core/EmailRecovery/emailRecoveryPendingStore.js.map +1 -0
  113. package/dist/cjs/react/sdk/src/core/EmailRecovery/index.js +32 -13
  114. package/dist/cjs/react/sdk/src/core/EmailRecovery/index.js.map +1 -1
  115. package/dist/cjs/react/sdk/src/core/IndexedDBManager/passkeyClientDB.js +35 -36
  116. package/dist/cjs/react/sdk/src/core/IndexedDBManager/passkeyClientDB.js.map +1 -1
  117. package/dist/cjs/react/sdk/src/core/NearClient.js +2 -1
  118. package/dist/cjs/react/sdk/src/core/NearClient.js.map +1 -1
  119. package/dist/cjs/react/sdk/src/core/TatchiPasskey/emailRecovery.js +557 -377
  120. package/dist/cjs/react/sdk/src/core/TatchiPasskey/emailRecovery.js.map +1 -1
  121. package/dist/cjs/react/sdk/src/core/TatchiPasskey/faucets/createAccountRelayServer.js +1 -0
  122. package/dist/cjs/react/sdk/src/core/TatchiPasskey/faucets/createAccountRelayServer.js.map +1 -1
  123. package/dist/cjs/react/sdk/src/core/TatchiPasskey/index.js +26 -0
  124. package/dist/cjs/react/sdk/src/core/TatchiPasskey/index.js.map +1 -1
  125. package/dist/cjs/react/sdk/src/core/TatchiPasskey/linkDevice.js +2 -0
  126. package/dist/cjs/react/sdk/src/core/TatchiPasskey/linkDevice.js.map +1 -1
  127. package/dist/cjs/react/sdk/src/core/TatchiPasskey/login.js +15 -4
  128. package/dist/cjs/react/sdk/src/core/TatchiPasskey/login.js.map +1 -1
  129. package/dist/cjs/react/sdk/src/core/TatchiPasskey/recoverAccount.js +1 -0
  130. package/dist/cjs/react/sdk/src/core/TatchiPasskey/recoverAccount.js.map +1 -1
  131. package/dist/cjs/react/sdk/src/core/TatchiPasskey/relay.js +23 -1
  132. package/dist/cjs/react/sdk/src/core/TatchiPasskey/relay.js.map +1 -1
  133. package/dist/cjs/react/sdk/src/core/TatchiPasskey/scanDevice.js +1 -0
  134. package/dist/cjs/react/sdk/src/core/TatchiPasskey/scanDevice.js.map +1 -1
  135. package/dist/cjs/react/sdk/src/core/WalletIframe/client/IframeTransport.js +3 -0
  136. package/dist/cjs/react/sdk/src/core/WalletIframe/client/IframeTransport.js.map +1 -1
  137. package/dist/cjs/react/sdk/src/core/WalletIframe/client/router.js +15 -2
  138. package/dist/cjs/react/sdk/src/core/WalletIframe/client/router.js.map +1 -1
  139. package/dist/cjs/react/sdk/src/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-drawer.js +1 -1
  140. package/dist/cjs/react/sdk/src/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-drawer.js.map +1 -1
  141. package/dist/cjs/react/sdk/src/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-modal.js +52 -52
  142. package/dist/cjs/react/sdk/src/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-modal.js.map +1 -1
  143. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/getDeviceNumber.js +10 -1
  144. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/getDeviceNumber.js.map +1 -1
  145. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/checkCanRegisterUser.js +1 -0
  146. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/checkCanRegisterUser.js.map +1 -1
  147. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/decryptPrivateKeyWithPrf.js +1 -0
  148. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/decryptPrivateKeyWithPrf.js.map +1 -1
  149. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/deriveNearKeypairAndEncryptFromSerialized.js +1 -0
  150. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/deriveNearKeypairAndEncryptFromSerialized.js.map +1 -1
  151. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/exportNearKeypairUi.js +1 -0
  152. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/exportNearKeypairUi.js.map +1 -1
  153. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/registerDevice2WithDerivedKey.js +2 -1
  154. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/registerDevice2WithDerivedKey.js.map +1 -1
  155. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/signDelegateAction.js +1 -0
  156. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/signDelegateAction.js.map +1 -1
  157. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/signNep413Message.js +1 -0
  158. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/signNep413Message.js.map +1 -1
  159. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/signTransactionsWithActions.js +1 -0
  160. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/signTransactionsWithActions.js.map +1 -1
  161. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/validation.js +2 -0
  162. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/validation.js.map +1 -1
  163. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/index.js +1 -0
  164. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/index.js.map +1 -1
  165. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/vrf.js +1 -0
  166. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/vrf.js.map +1 -1
  167. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/webauthn.js +6 -0
  168. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/webauthn.js.map +1 -1
  169. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/determineConfirmationConfig.js +2 -1
  170. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/determineConfirmationConfig.js.map +1 -1
  171. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/localOnly.js +1 -0
  172. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/localOnly.js.map +1 -1
  173. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/registration.js +1 -0
  174. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/registration.js.map +1 -1
  175. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/transactions.js +4 -15
  176. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/transactions.js.map +1 -1
  177. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/handlers/deriveVrfKeypairFromPrf.js +1 -0
  178. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/handlers/deriveVrfKeypairFromPrf.js.map +1 -1
  179. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfChallenge.js +1 -0
  180. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfChallenge.js.map +1 -1
  181. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfKeypairBootstrap.js +1 -0
  182. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfKeypairBootstrap.js.map +1 -1
  183. package/dist/cjs/react/sdk/src/core/WebAuthnManager/WebAuthnFallbacks/index.js +17 -0
  184. package/dist/cjs/react/sdk/src/core/WebAuthnManager/WebAuthnFallbacks/index.js.map +1 -0
  185. package/dist/cjs/react/sdk/src/core/WebAuthnManager/WebAuthnFallbacks/safari-fallbacks.js +64 -54
  186. package/dist/cjs/react/sdk/src/core/WebAuthnManager/WebAuthnFallbacks/safari-fallbacks.js.map +1 -1
  187. package/dist/cjs/react/sdk/src/core/WebAuthnManager/credentialsHelpers.js +12 -2
  188. package/dist/cjs/react/sdk/src/core/WebAuthnManager/credentialsHelpers.js.map +1 -1
  189. package/dist/cjs/react/sdk/src/core/WebAuthnManager/index.js +6 -1
  190. package/dist/cjs/react/sdk/src/core/WebAuthnManager/index.js.map +1 -1
  191. package/dist/cjs/react/sdk/src/core/WebAuthnManager/touchIdPrompt.js +209 -201
  192. package/dist/cjs/react/sdk/src/core/WebAuthnManager/touchIdPrompt.js.map +1 -1
  193. package/dist/cjs/react/sdk/src/core/WebAuthnManager/userHandle.js +2 -1
  194. package/dist/cjs/react/sdk/src/core/WebAuthnManager/userHandle.js.map +1 -1
  195. package/dist/cjs/react/sdk/src/core/defaultConfigs.js +1 -1
  196. package/dist/cjs/react/sdk/src/core/defaultConfigs.js.map +1 -1
  197. package/dist/cjs/react/sdk/src/core/rpcCalls.js +8 -0
  198. package/dist/cjs/react/sdk/src/core/rpcCalls.js.map +1 -1
  199. package/dist/cjs/react/sdk/src/core/types/vrf-worker.js +10 -1
  200. package/dist/cjs/react/sdk/src/core/types/vrf-worker.js.map +1 -1
  201. package/dist/cjs/react/sdk/src/utils/index.js +13 -3
  202. package/dist/cjs/server/email-recovery/emailEncryptor.js +11 -0
  203. package/dist/cjs/server/email-recovery/emailEncryptor.js.map +1 -1
  204. package/dist/cjs/server/email-recovery/emailParsers.js +57 -0
  205. package/dist/cjs/server/email-recovery/emailParsers.js.map +1 -1
  206. package/dist/cjs/server/email-recovery/index.js +1 -1
  207. package/dist/cjs/server/email-recovery/index.js.map +1 -1
  208. package/dist/cjs/server/email-recovery/rpcCalls.js +14 -1
  209. package/dist/cjs/server/email-recovery/rpcCalls.js.map +1 -1
  210. package/dist/cjs/server/index.js +1 -0
  211. package/dist/cjs/server/router/cloudflare.js.map +1 -1
  212. package/dist/cjs/server/router/express.js.map +1 -1
  213. package/dist/cjs/server/sdk/src/core/defaultConfigs.js +1 -1
  214. package/dist/cjs/server/sdk/src/core/defaultConfigs.js.map +1 -1
  215. package/dist/cjs/utils/index.js +13 -3
  216. package/dist/esm/core/EmailRecovery/emailRecoveryPendingStore.js +63 -0
  217. package/dist/esm/core/EmailRecovery/emailRecoveryPendingStore.js.map +1 -0
  218. package/dist/esm/core/EmailRecovery/index.js +28 -14
  219. package/dist/esm/core/EmailRecovery/index.js.map +1 -1
  220. package/dist/esm/core/IndexedDBManager/passkeyClientDB.js +35 -36
  221. package/dist/esm/core/IndexedDBManager/passkeyClientDB.js.map +1 -1
  222. package/dist/esm/core/NearClient.js +2 -1
  223. package/dist/esm/core/NearClient.js.map +1 -1
  224. package/dist/esm/core/TatchiPasskey/emailRecovery.js +557 -377
  225. package/dist/esm/core/TatchiPasskey/emailRecovery.js.map +1 -1
  226. package/dist/esm/core/TatchiPasskey/faucets/createAccountRelayServer.js +2 -1
  227. package/dist/esm/core/TatchiPasskey/faucets/createAccountRelayServer.js.map +1 -1
  228. package/dist/esm/core/TatchiPasskey/index.js +28 -2
  229. package/dist/esm/core/TatchiPasskey/index.js.map +1 -1
  230. package/dist/esm/core/TatchiPasskey/linkDevice.js +4 -2
  231. package/dist/esm/core/TatchiPasskey/linkDevice.js.map +1 -1
  232. package/dist/esm/core/TatchiPasskey/login.js +13 -7
  233. package/dist/esm/core/TatchiPasskey/login.js.map +1 -1
  234. package/dist/esm/core/TatchiPasskey/recoverAccount.js +2 -1
  235. package/dist/esm/core/TatchiPasskey/recoverAccount.js.map +1 -1
  236. package/dist/esm/core/TatchiPasskey/relay.js +23 -1
  237. package/dist/esm/core/TatchiPasskey/relay.js.map +1 -1
  238. package/dist/esm/core/TatchiPasskey/scanDevice.js +2 -1
  239. package/dist/esm/core/TatchiPasskey/scanDevice.js.map +1 -1
  240. package/dist/esm/core/WalletIframe/client/IframeTransport.js +4 -1
  241. package/dist/esm/core/WalletIframe/client/IframeTransport.js.map +1 -1
  242. package/dist/esm/core/WalletIframe/client/router.js +16 -3
  243. package/dist/esm/core/WalletIframe/client/router.js.map +1 -1
  244. package/dist/esm/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-drawer.js +1 -1
  245. package/dist/esm/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-drawer.js.map +1 -1
  246. package/dist/esm/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-modal.js +52 -52
  247. package/dist/esm/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-modal.js.map +1 -1
  248. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/getDeviceNumber.js +6 -2
  249. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/checkCanRegisterUser.js +2 -1
  250. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/checkCanRegisterUser.js.map +1 -1
  251. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/decryptPrivateKeyWithPrf.js +2 -1
  252. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/decryptPrivateKeyWithPrf.js.map +1 -1
  253. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/deriveNearKeypairAndEncryptFromSerialized.js +2 -1
  254. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/deriveNearKeypairAndEncryptFromSerialized.js.map +1 -1
  255. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/exportNearKeypairUi.js +2 -1
  256. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/exportNearKeypairUi.js.map +1 -1
  257. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/registerDevice2WithDerivedKey.js +2 -1
  258. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/registerDevice2WithDerivedKey.js.map +1 -1
  259. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/signDelegateAction.js +2 -1
  260. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/signDelegateAction.js.map +1 -1
  261. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/signNep413Message.js +2 -1
  262. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/signNep413Message.js.map +1 -1
  263. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/signTransactionsWithActions.js +2 -1
  264. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/signTransactionsWithActions.js.map +1 -1
  265. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/validation.js +4 -2
  266. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/validation.js.map +1 -1
  267. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/index.js +2 -1
  268. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/index.js.map +1 -1
  269. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/vrf.js +1 -0
  270. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/vrf.js.map +1 -1
  271. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/webauthn.js +8 -2
  272. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/webauthn.js.map +1 -1
  273. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/determineConfirmationConfig.js +2 -1
  274. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/determineConfirmationConfig.js.map +1 -1
  275. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/localOnly.js +2 -1
  276. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/localOnly.js.map +1 -1
  277. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/registration.js +2 -1
  278. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/registration.js.map +1 -1
  279. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/transactions.js +5 -16
  280. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/transactions.js.map +1 -1
  281. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/handlers/deriveVrfKeypairFromPrf.js +2 -1
  282. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/handlers/deriveVrfKeypairFromPrf.js.map +1 -1
  283. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfChallenge.js +2 -1
  284. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfChallenge.js.map +1 -1
  285. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfKeypairBootstrap.js +2 -1
  286. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfKeypairBootstrap.js.map +1 -1
  287. package/dist/esm/core/WebAuthnManager/WebAuthnFallbacks/index.js +12 -0
  288. package/dist/esm/core/WebAuthnManager/WebAuthnFallbacks/index.js.map +1 -0
  289. package/dist/esm/core/WebAuthnManager/WebAuthnFallbacks/safari-fallbacks.js +61 -55
  290. package/dist/esm/core/WebAuthnManager/WebAuthnFallbacks/safari-fallbacks.js.map +1 -1
  291. package/dist/esm/core/WebAuthnManager/credentialsHelpers.js +8 -3
  292. package/dist/esm/core/WebAuthnManager/index.js +8 -3
  293. package/dist/esm/core/WebAuthnManager/index.js.map +1 -1
  294. package/dist/esm/core/WebAuthnManager/touchIdPrompt.js +207 -204
  295. package/dist/esm/core/WebAuthnManager/touchIdPrompt.js.map +1 -1
  296. package/dist/esm/core/WebAuthnManager/userHandle.js +2 -1
  297. package/dist/esm/core/WebAuthnManager/userHandle.js.map +1 -1
  298. package/dist/esm/core/defaultConfigs.js +1 -1
  299. package/dist/esm/core/defaultConfigs.js.map +1 -1
  300. package/dist/esm/core/rpcCalls.js +8 -1
  301. package/dist/esm/core/rpcCalls.js.map +1 -1
  302. package/dist/esm/core/types/vrf-worker.js +6 -2
  303. package/dist/esm/index.js +4 -1
  304. package/dist/esm/index.js.map +1 -1
  305. package/dist/esm/react/components/AccountMenuButton/{LinkedDevicesModal-STvIsylA.css → LinkedDevicesModal-CSSowiHP.css} +1 -1
  306. package/dist/{cjs/react/components/AccountMenuButton/LinkedDevicesModal-STvIsylA.css.map → esm/react/components/AccountMenuButton/LinkedDevicesModal-CSSowiHP.css.map} +1 -1
  307. package/dist/esm/react/components/AccountMenuButton/{ProfileDropdown-iARgUwK1.css → ProfileDropdown-CEPMZ1gY.css} +1 -1
  308. package/dist/{cjs/react/components/AccountMenuButton/ProfileDropdown-iARgUwK1.css.map → esm/react/components/AccountMenuButton/ProfileDropdown-CEPMZ1gY.css.map} +1 -1
  309. package/dist/esm/react/components/AccountMenuButton/{Web3AuthProfileButton-Db3NeoAC.css → Web3AuthProfileButton-DopOg7Xc.css} +1 -1
  310. package/dist/esm/react/components/AccountMenuButton/{Web3AuthProfileButton-Db3NeoAC.css.map → Web3AuthProfileButton-DopOg7Xc.css.map} +1 -1
  311. package/dist/esm/react/components/AccountMenuButton/icons/{TouchIcon-BXM5NR4A.css → TouchIcon-BQWentvJ.css} +1 -1
  312. package/dist/esm/react/components/AccountMenuButton/icons/{TouchIcon-BXM5NR4A.css.map → TouchIcon-BQWentvJ.css.map} +1 -1
  313. package/dist/esm/react/components/PasskeyAuthMenu/{PasskeyAuthMenu-De1qTSmU.css → PasskeyAuthMenu-DwrzWMYx.css} +14 -1
  314. package/dist/esm/react/components/PasskeyAuthMenu/{PasskeyAuthMenu-De1qTSmU.css.map → PasskeyAuthMenu-DwrzWMYx.css.map} +1 -1
  315. package/dist/esm/react/components/PasskeyAuthMenu/ui/EmailRecoverySlide.js +123 -54
  316. package/dist/esm/react/components/PasskeyAuthMenu/ui/EmailRecoverySlide.js.map +1 -1
  317. package/dist/esm/react/components/{ShowQRCode-DCnR__fx.css → ShowQRCode-CCN4h6Uv.css} +1 -1
  318. package/dist/esm/react/components/{ShowQRCode-DCnR__fx.css.map → ShowQRCode-CCN4h6Uv.css.map} +1 -1
  319. package/dist/esm/react/deviceDetection.js +72 -93
  320. package/dist/esm/react/deviceDetection.js.map +1 -1
  321. package/dist/esm/react/hooks/useQRCamera.js +2 -1
  322. package/dist/esm/react/hooks/useQRCamera.js.map +1 -1
  323. package/dist/esm/react/sdk/src/core/EmailRecovery/emailRecoveryPendingStore.js +63 -0
  324. package/dist/esm/react/sdk/src/core/EmailRecovery/emailRecoveryPendingStore.js.map +1 -0
  325. package/dist/esm/react/sdk/src/core/EmailRecovery/index.js +28 -14
  326. package/dist/esm/react/sdk/src/core/EmailRecovery/index.js.map +1 -1
  327. package/dist/esm/react/sdk/src/core/IndexedDBManager/passkeyClientDB.js +35 -36
  328. package/dist/esm/react/sdk/src/core/IndexedDBManager/passkeyClientDB.js.map +1 -1
  329. package/dist/esm/react/sdk/src/core/NearClient.js +2 -1
  330. package/dist/esm/react/sdk/src/core/NearClient.js.map +1 -1
  331. package/dist/esm/react/sdk/src/core/TatchiPasskey/emailRecovery.js +557 -377
  332. package/dist/esm/react/sdk/src/core/TatchiPasskey/emailRecovery.js.map +1 -1
  333. package/dist/esm/react/sdk/src/core/TatchiPasskey/faucets/createAccountRelayServer.js +2 -1
  334. package/dist/esm/react/sdk/src/core/TatchiPasskey/faucets/createAccountRelayServer.js.map +1 -1
  335. package/dist/esm/react/sdk/src/core/TatchiPasskey/index.js +28 -2
  336. package/dist/esm/react/sdk/src/core/TatchiPasskey/index.js.map +1 -1
  337. package/dist/esm/react/sdk/src/core/TatchiPasskey/linkDevice.js +4 -2
  338. package/dist/esm/react/sdk/src/core/TatchiPasskey/linkDevice.js.map +1 -1
  339. package/dist/esm/react/sdk/src/core/TatchiPasskey/login.js +13 -7
  340. package/dist/esm/react/sdk/src/core/TatchiPasskey/login.js.map +1 -1
  341. package/dist/esm/react/sdk/src/core/TatchiPasskey/recoverAccount.js +2 -1
  342. package/dist/esm/react/sdk/src/core/TatchiPasskey/recoverAccount.js.map +1 -1
  343. package/dist/esm/react/sdk/src/core/TatchiPasskey/relay.js +23 -1
  344. package/dist/esm/react/sdk/src/core/TatchiPasskey/relay.js.map +1 -1
  345. package/dist/esm/react/sdk/src/core/TatchiPasskey/scanDevice.js +2 -1
  346. package/dist/esm/react/sdk/src/core/TatchiPasskey/scanDevice.js.map +1 -1
  347. package/dist/esm/react/sdk/src/core/WalletIframe/client/IframeTransport.js +4 -1
  348. package/dist/esm/react/sdk/src/core/WalletIframe/client/IframeTransport.js.map +1 -1
  349. package/dist/esm/react/sdk/src/core/WalletIframe/client/router.js +16 -3
  350. package/dist/esm/react/sdk/src/core/WalletIframe/client/router.js.map +1 -1
  351. package/dist/esm/react/sdk/src/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-drawer.js +1 -1
  352. package/dist/esm/react/sdk/src/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-drawer.js.map +1 -1
  353. package/dist/esm/react/sdk/src/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-modal.js +52 -52
  354. package/dist/esm/react/sdk/src/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-modal.js.map +1 -1
  355. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/getDeviceNumber.js +6 -2
  356. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/checkCanRegisterUser.js +2 -1
  357. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/checkCanRegisterUser.js.map +1 -1
  358. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/decryptPrivateKeyWithPrf.js +2 -1
  359. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/decryptPrivateKeyWithPrf.js.map +1 -1
  360. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/deriveNearKeypairAndEncryptFromSerialized.js +2 -1
  361. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/deriveNearKeypairAndEncryptFromSerialized.js.map +1 -1
  362. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/exportNearKeypairUi.js +2 -1
  363. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/exportNearKeypairUi.js.map +1 -1
  364. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/registerDevice2WithDerivedKey.js +2 -1
  365. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/registerDevice2WithDerivedKey.js.map +1 -1
  366. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/signDelegateAction.js +2 -1
  367. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/signDelegateAction.js.map +1 -1
  368. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/signNep413Message.js +2 -1
  369. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/signNep413Message.js.map +1 -1
  370. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/signTransactionsWithActions.js +2 -1
  371. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/signTransactionsWithActions.js.map +1 -1
  372. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/validation.js +4 -2
  373. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/validation.js.map +1 -1
  374. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/index.js +2 -1
  375. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/index.js.map +1 -1
  376. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/vrf.js +1 -0
  377. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/vrf.js.map +1 -1
  378. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/webauthn.js +8 -2
  379. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/webauthn.js.map +1 -1
  380. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/determineConfirmationConfig.js +2 -1
  381. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/determineConfirmationConfig.js.map +1 -1
  382. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/localOnly.js +2 -1
  383. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/localOnly.js.map +1 -1
  384. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/registration.js +2 -1
  385. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/registration.js.map +1 -1
  386. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/transactions.js +5 -16
  387. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/transactions.js.map +1 -1
  388. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/handlers/deriveVrfKeypairFromPrf.js +2 -1
  389. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/handlers/deriveVrfKeypairFromPrf.js.map +1 -1
  390. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfChallenge.js +2 -1
  391. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfChallenge.js.map +1 -1
  392. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfKeypairBootstrap.js +2 -1
  393. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfKeypairBootstrap.js.map +1 -1
  394. package/dist/esm/react/sdk/src/core/WebAuthnManager/WebAuthnFallbacks/index.js +12 -0
  395. package/dist/esm/react/sdk/src/core/WebAuthnManager/WebAuthnFallbacks/index.js.map +1 -0
  396. package/dist/esm/react/sdk/src/core/WebAuthnManager/WebAuthnFallbacks/safari-fallbacks.js +61 -55
  397. package/dist/esm/react/sdk/src/core/WebAuthnManager/WebAuthnFallbacks/safari-fallbacks.js.map +1 -1
  398. package/dist/esm/react/sdk/src/core/WebAuthnManager/credentialsHelpers.js +8 -3
  399. package/dist/esm/react/sdk/src/core/WebAuthnManager/index.js +8 -3
  400. package/dist/esm/react/sdk/src/core/WebAuthnManager/index.js.map +1 -1
  401. package/dist/esm/react/sdk/src/core/WebAuthnManager/touchIdPrompt.js +207 -204
  402. package/dist/esm/react/sdk/src/core/WebAuthnManager/touchIdPrompt.js.map +1 -1
  403. package/dist/esm/react/sdk/src/core/WebAuthnManager/userHandle.js +2 -1
  404. package/dist/esm/react/sdk/src/core/WebAuthnManager/userHandle.js.map +1 -1
  405. package/dist/esm/react/sdk/src/core/defaultConfigs.js +1 -1
  406. package/dist/esm/react/sdk/src/core/defaultConfigs.js.map +1 -1
  407. package/dist/esm/react/sdk/src/core/rpcCalls.js +8 -1
  408. package/dist/esm/react/sdk/src/core/rpcCalls.js.map +1 -1
  409. package/dist/esm/react/sdk/src/core/types/vrf-worker.js +6 -2
  410. package/dist/esm/react/sdk/src/utils/index.js +10 -4
  411. package/dist/esm/react/styles/styles.css +13 -0
  412. package/dist/esm/sdk/{safari-fallbacks-oQKu9xUs.js → WebAuthnFallbacks-Bl4BTsNt.js} +131 -135
  413. package/dist/esm/sdk/{createAdapters-pNiL2KNq.js → createAdapters-BumKM2ft.js} +59 -54
  414. package/dist/esm/sdk/createAdapters-BumKM2ft.js.map +1 -0
  415. package/dist/esm/sdk/{createAdapters-BWLe9Ddo.js → createAdapters-qVGD6i0g.js} +10 -3
  416. package/dist/esm/sdk/{defaultConfigs-VzvDejmy.js → defaultConfigs-DpslkAQd.js} +1 -1
  417. package/dist/esm/sdk/{getDeviceNumber-CkWRT17I.js → getDeviceNumber-fXizNGQl.js} +2 -2
  418. package/dist/esm/sdk/getDeviceNumber-fXizNGQl.js.map +1 -0
  419. package/dist/esm/sdk/{getDeviceNumber-CfmlgfMX.js → getDeviceNumber-zsOHT_Um.js} +6 -3
  420. package/dist/esm/sdk/{localOnly-DnpSyDaF.js → localOnly-Byi3AK7A.js} +2 -2
  421. package/dist/esm/sdk/{localOnly-DnpSyDaF.js.map → localOnly-Byi3AK7A.js.map} +1 -1
  422. package/dist/esm/sdk/{localOnly-BdumO2st.js → localOnly-pXMTqh1m.js} +5 -4
  423. package/dist/esm/sdk/offline-export-app.js +46 -44
  424. package/dist/esm/sdk/offline-export-app.js.map +1 -1
  425. package/dist/esm/sdk/{overlay-BTqPGG-o.js → overlay-ZGbucXIa.js} +2 -0
  426. package/dist/esm/sdk/{registration-C633u6x8.js → registration-CBiS4Ua_.js} +2 -2
  427. package/dist/esm/sdk/{registration-C633u6x8.js.map → registration-CBiS4Ua_.js.map} +1 -1
  428. package/dist/esm/sdk/{registration-xyYUFRqk.js → registration-DLPLsGCz.js} +5 -4
  429. package/dist/esm/sdk/{requestHelpers-DLBGBHMw.js → requestHelpers-Dh1hEYL9.js} +206 -204
  430. package/dist/esm/sdk/{router-BG6KC_p7.js → router-DuGYOd3G.js} +19 -4
  431. package/dist/esm/sdk/{rpcCalls-fLObBbbz.js → rpcCalls-BQrJMTdg.js} +3 -3
  432. package/dist/esm/sdk/{rpcCalls-CAU5XYEF.js → rpcCalls-YVeUVMk2.js} +9 -2
  433. package/dist/esm/sdk/{transactions-jH38BZ-Q.js → transactions-BIqKZeR0.js} +6 -18
  434. package/dist/esm/sdk/transactions-BIqKZeR0.js.map +1 -0
  435. package/dist/esm/sdk/{transactions-CzZAt1Yn.js → transactions-Bk-VavcV.js} +10 -21
  436. package/dist/esm/sdk/tx-confirm-ui.js +53 -53
  437. package/dist/esm/sdk/{tx-confirmer-wrapper-CqfVBUaA.js → tx-confirmer-wrapper-lHNgz9i4.js} +53 -53
  438. package/dist/esm/sdk/tx-confirmer.css +6 -4
  439. package/dist/esm/sdk/w3a-tx-confirmer.js +1 -1
  440. package/dist/esm/sdk/wallet-iframe-host.js +782 -447
  441. package/dist/esm/server/email-recovery/emailEncryptor.js +11 -1
  442. package/dist/esm/server/email-recovery/emailEncryptor.js.map +1 -1
  443. package/dist/esm/server/email-recovery/emailParsers.js +55 -1
  444. package/dist/esm/server/email-recovery/emailParsers.js.map +1 -1
  445. package/dist/esm/server/email-recovery/index.js +2 -2
  446. package/dist/esm/server/email-recovery/index.js.map +1 -1
  447. package/dist/esm/server/email-recovery/rpcCalls.js +14 -1
  448. package/dist/esm/server/email-recovery/rpcCalls.js.map +1 -1
  449. package/dist/esm/server/index.js +2 -2
  450. package/dist/esm/server/router/cloudflare.js.map +1 -1
  451. package/dist/esm/server/router/express.js.map +1 -1
  452. package/dist/esm/server/sdk/src/core/defaultConfigs.js +1 -1
  453. package/dist/esm/server/sdk/src/core/defaultConfigs.js.map +1 -1
  454. package/dist/esm/utils/index.js +10 -4
  455. package/dist/esm/wasm_vrf_worker/pkg/wasm_vrf_worker.js +3 -0
  456. package/dist/esm/wasm_vrf_worker/pkg/wasm_vrf_worker_bg.wasm +0 -0
  457. package/dist/types/src/core/EmailRecovery/emailRecoveryPendingStore.d.ts +25 -0
  458. package/dist/types/src/core/EmailRecovery/emailRecoveryPendingStore.d.ts.map +1 -0
  459. package/dist/types/src/core/EmailRecovery/index.d.ts +1 -0
  460. package/dist/types/src/core/EmailRecovery/index.d.ts.map +1 -1
  461. package/dist/types/src/core/IndexedDBManager/passkeyClientDB.d.ts +11 -21
  462. package/dist/types/src/core/IndexedDBManager/passkeyClientDB.d.ts.map +1 -1
  463. package/dist/types/src/core/TatchiPasskey/emailRecovery.d.ts +45 -5
  464. package/dist/types/src/core/TatchiPasskey/emailRecovery.d.ts.map +1 -1
  465. package/dist/types/src/core/TatchiPasskey/index.d.ts +10 -2
  466. package/dist/types/src/core/TatchiPasskey/index.d.ts.map +1 -1
  467. package/dist/types/src/core/TatchiPasskey/relay.d.ts +2 -1
  468. package/dist/types/src/core/TatchiPasskey/relay.d.ts.map +1 -1
  469. package/dist/types/src/core/WalletIframe/TatchiPasskeyIframe.d.ts +4 -0
  470. package/dist/types/src/core/WalletIframe/TatchiPasskeyIframe.d.ts.map +1 -1
  471. package/dist/types/src/core/WalletIframe/client/router.d.ts +7 -3
  472. package/dist/types/src/core/WalletIframe/client/router.d.ts.map +1 -1
  473. package/dist/types/src/core/WalletIframe/host/wallet-iframe-handlers.d.ts.map +1 -1
  474. package/dist/types/src/core/WalletIframe/shared/messages.d.ts +6 -2
  475. package/dist/types/src/core/WalletIframe/shared/messages.d.ts.map +1 -1
  476. package/dist/types/src/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-drawer.d.ts.map +1 -1
  477. package/dist/types/src/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-modal.d.ts.map +1 -1
  478. package/dist/types/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/vrf.d.ts.map +1 -1
  479. package/dist/types/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/webauthn.d.ts.map +1 -1
  480. package/dist/types/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/transactions.d.ts.map +1 -1
  481. package/dist/types/src/core/WebAuthnManager/index.d.ts.map +1 -1
  482. package/dist/types/src/core/defaultConfigs.d.ts.map +1 -1
  483. package/dist/types/src/core/rpcCalls.d.ts +9 -0
  484. package/dist/types/src/core/rpcCalls.d.ts.map +1 -1
  485. package/dist/types/src/index.d.ts +1 -0
  486. package/dist/types/src/index.d.ts.map +1 -1
  487. package/dist/types/src/react/components/PasskeyAuthMenu/ui/EmailRecoverySlide.d.ts.map +1 -1
  488. package/dist/types/src/server/email-recovery/emailEncryptor.d.ts +4 -0
  489. package/dist/types/src/server/email-recovery/emailEncryptor.d.ts.map +1 -1
  490. package/dist/types/src/server/email-recovery/emailParsers.d.ts +7 -0
  491. package/dist/types/src/server/email-recovery/emailParsers.d.ts.map +1 -1
  492. package/dist/types/src/server/email-recovery/index.d.ts +1 -1
  493. package/dist/types/src/server/email-recovery/rpcCalls.d.ts +1 -1
  494. package/dist/types/src/server/email-recovery/rpcCalls.d.ts.map +1 -1
  495. package/dist/types/src/wasm_vrf_worker/pkg/wasm_vrf_worker.d.ts.map +1 -1
  496. package/dist/workers/wasm_vrf_worker_bg.wasm +0 -0
  497. package/dist/workers/web3authn-vrf.worker.js +3 -0
  498. package/package.json +1 -1
  499. package/dist/esm/sdk/createAdapters-pNiL2KNq.js.map +0 -1
  500. package/dist/esm/sdk/getDeviceNumber-CkWRT17I.js.map +0 -1
  501. package/dist/esm/sdk/transactions-jH38BZ-Q.js.map +0 -1
@@ -1,97 +1,76 @@
1
+ import { __esm } from "./_virtual/rolldown_runtime.js";
2
+
1
3
  //#region src/react/deviceDetection.ts
2
- /**
3
- * Detects the current device type based on multiple indicators
4
- */
5
- const detectDeviceType = () => {
6
- const userAgent = navigator.userAgent.toLowerCase();
7
- const isMobileUA = /android|iphone|ipod|blackberry|iemobile|opera mini/i.test(userAgent);
8
- const isTabletUA = /ipad|tablet|kindle|playbook|silk/i.test(userAgent);
9
- const isTouchDevice = navigator.maxTouchPoints > 0;
10
- const screenWidth = window.screen.width;
11
- const isSmallScreen = screenWidth <= 480;
12
- const isMediumScreen = screenWidth <= 1024;
13
- const hasOrientation = "orientation" in window;
14
- if (isMobileUA || isTouchDevice && isSmallScreen) return "mobile";
15
- if (isTabletUA || isTouchDevice && isMediumScreen && hasOrientation) return "tablet";
16
- return "desktop";
17
- };
18
- /**
19
- * Basic Safari detection (desktop Safari). Note: all iOS browsers use WebKit,
20
- * so use isIOS() to capture iOS Safari-like restrictions.
21
- */
22
- const isSafari = () => {
23
- try {
24
- const ua = navigator.userAgent;
25
- const isSafariEngine = /safari/i.test(ua) && !/chrome|crios|crmo|chromium|edg|edge|opr|opera|brave/i.test(ua);
26
- return isSafariEngine;
27
- } catch {
28
- return false;
29
- }
30
- };
31
- /**
32
- * Detect iOS (covers iPhone/iPad/iPod and iPadOS with desktop UA).
33
- * iOS has WebAuthn user-activation quirks that are shared by all iOS browsers.
34
- */
35
- const isIOS = () => {
36
- try {
37
- const ua = navigator.userAgent;
38
- const platform = navigator.platform || "";
39
- const maxTouch = Number(navigator.maxTouchPoints || 0);
40
- const iOSUA = /iPad|iPhone|iPod/.test(ua);
41
- const iPadOSMacLike = /Macintosh/.test(ua) && maxTouch > 1;
42
- const iOSPlatform = /iPad|iPhone|iPod/.test(platform);
43
- return iOSUA || iPadOSMacLike || iOSPlatform;
44
- } catch {
45
- return false;
46
- }
47
- };
48
- /**
49
- * Returns true when the page currently has a transient user activation
50
- * (click/tap/key within the allowed time window).
51
- */
52
- const hasActiveUserActivation = () => {
53
- try {
54
- const ua = navigator.userActivation;
55
- return !!(ua && typeof ua.isActive === "boolean" && ua.isActive);
56
- } catch {
57
- return false;
58
- }
59
- };
60
- /**
61
- * Heuristic: when on Safari/iOS or on a mobile device AND no active user
62
- * activation, we should surface a clickable UI to capture activation.
63
- */
64
- const needsExplicitActivation = () => {
65
- try {
66
- if (hasActiveUserActivation()) return false;
67
- return isIOS() || isMobileDevice() || isSafari();
68
- } catch {
69
- return false;
70
- }
71
- };
72
- /**
73
- * Determines optimal camera facing mode based on device type
74
- * - Mobile/Tablet: Back camera (environment) for QR scanning
75
- * - Desktop/Laptop: Front camera (user) for video calls/selfies
76
- */
77
- const getOptimalCameraFacingMode = () => {
78
- const deviceType = detectDeviceType();
79
- switch (deviceType) {
80
- case "mobile":
81
- case "tablet":
82
- console.log(`${deviceType} device detected - using back camera (environment)`);
83
- return "environment";
84
- case "desktop":
85
- default: return "user";
86
- }
87
- };
88
- /**
89
- * Check if the current device is likely mobile
90
- */
91
- const isMobileDevice = () => {
92
- return detectDeviceType() === "mobile";
93
- };
4
+ var detectDeviceType, isSafari, isIOS, hasActiveUserActivation, needsExplicitActivation, getOptimalCameraFacingMode, isMobileDevice;
5
+ var init_deviceDetection = __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
+ }) });
94
72
 
95
73
  //#endregion
96
- export { detectDeviceType, getOptimalCameraFacingMode, hasActiveUserActivation, isIOS, isMobileDevice, isSafari, needsExplicitActivation };
74
+ init_deviceDetection();
75
+ export { detectDeviceType, getOptimalCameraFacingMode, hasActiveUserActivation, init_deviceDetection, isIOS, isMobileDevice, isSafari, needsExplicitActivation };
97
76
  //# sourceMappingURL=deviceDetection.js.map
@@ -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"}
@@ -1,8 +1,9 @@
1
- import { getOptimalCameraFacingMode } from "../deviceDetection.js";
1
+ import { getOptimalCameraFacingMode, init_deviceDetection } from "../deviceDetection.js";
2
2
  import { ScanQRCodeFlow, detectFrontCamera, enumerateVideoDevices } from "../sdk/src/utils/qrScanner.js";
3
3
  import { useCallback, useEffect, useRef, useState } from "react";
4
4
 
5
5
  //#region src/react/hooks/useQRCamera.ts
6
+ init_deviceDetection();
6
7
  /**
7
8
  * QR Camera Scanning Hook
8
9
  *
@@ -1 +1 @@
1
- {"version":3,"file":"useQRCamera.js","names":["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,WAAW,OAAyB;CAC1C,MAAM,YAAY,OAA0B;CAC5C,MAAM,UAAU,OAA8B;CAG9C,MAAM,CAAC,YAAY,iBAAiB,SAAS;CAC7C,MAAM,CAAC,cAAc,mBAAmB,SAAS;CACjD,MAAM,CAAC,OAAO,YAAY,SAAwB;CAClD,MAAM,CAAC,SAAS,cAAc,SAA4B;CAC1D,MAAM,CAAC,gBAAgB,qBAAqB,SAAiB,YAAY;CACzE,MAAM,CAAC,UAAU,eAAe,SAAqB,WAAW;CAChE,MAAM,CAAC,eAAe,oBAAoB,SAAkB;CAC5D,MAAM,CAAC,gBAAgB,qBAAqB,SAAiB;AAI7D,iBAAgB;AACd,UAAQ,UAAU,IAAI,eACpB;GACE,UAAU;GACV,eAAe,EACb,YAAY;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,iBAAgB;EACd,MAAM,cAAc,YAAY;AAC9B,OAAI;IACF,MAAM,eAAe,MAAM;AAC3B,eAAW;AAEX,QAAI,aAAa,SAAS,KAAK,CAAC,gBAAgB;KAC9C,MAAM,cAAc,aAAa;AACjC,uBAAkB,YAAY;AAC9B,sBAAiB,kBAAkB;;YAE9BA,SAAY;AACnB,aAASC,QAAM;;;AAInB;IACC;AAGH,iBAAgB;AACd,MAAI,QAAQ,WAAW,eACrB,SAAQ,QAAQ,aAAa;IAE9B,CAAC;AAGJ,iBAAgB;AACd,MAAI,SAAS,WAAW,QAAQ,QAC9B,SAAQ,QAAQ,mBAAmB,SAAS;AAG9C,eAAa;AACX,OAAI,QAAQ,QACV,SAAQ,QAAQ;;IAGnB,CAAC,SAAS;AAGb,iBAAgB;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,gBAAgB,YAAY,YAAY;AAC5C,MAAI,QAAQ,SAAS;AACnB,YAAS;AACT,mBAAgB;AAChB,iBAAc;AACd,qBAAkB;AAClB,SAAM,QAAQ,QAAQ;;IAEvB;CAGH,MAAM,eAAe,kBAAkB;AACrC,MAAI,QAAQ,SAAS;AACnB,WAAQ,QAAQ;AAChB,iBAAc;AACd,mBAAgB;AAChB,qBAAkB;;IAEnB;CAGH,MAAM,qBAAqB,YAAY,OAAO,aAAqB;AACjE,oBAAkB;EAElB,MAAM,uBAAuB,QAAQ,MAAK,WAAU,OAAO,aAAa;AACxE,MAAI,qBACF,kBAAiB,kBAAkB;IAIpC,CAAC;CAEJ,MAAM,uBAAuB,kBAAkB,8BAA8B;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":["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,WAAW,OAAyB;CAC1C,MAAM,YAAY,OAA0B;CAC5C,MAAM,UAAU,OAA8B;CAG9C,MAAM,CAAC,YAAY,iBAAiB,SAAS;CAC7C,MAAM,CAAC,cAAc,mBAAmB,SAAS;CACjD,MAAM,CAAC,OAAO,YAAY,SAAwB;CAClD,MAAM,CAAC,SAAS,cAAc,SAA4B;CAC1D,MAAM,CAAC,gBAAgB,qBAAqB,SAAiB,YAAY;CACzE,MAAM,CAAC,UAAU,eAAe,SAAqB,WAAW;CAChE,MAAM,CAAC,eAAe,oBAAoB,SAAkB;CAC5D,MAAM,CAAC,gBAAgB,qBAAqB,SAAiB;AAI7D,iBAAgB;AACd,UAAQ,UAAU,IAAI,eACpB;GACE,UAAU;GACV,eAAe,EACb,YAAY;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,iBAAgB;EACd,MAAM,cAAc,YAAY;AAC9B,OAAI;IACF,MAAM,eAAe,MAAM;AAC3B,eAAW;AAEX,QAAI,aAAa,SAAS,KAAK,CAAC,gBAAgB;KAC9C,MAAM,cAAc,aAAa;AACjC,uBAAkB,YAAY;AAC9B,sBAAiB,kBAAkB;;YAE9BA,SAAY;AACnB,aAASC,QAAM;;;AAInB;IACC;AAGH,iBAAgB;AACd,MAAI,QAAQ,WAAW,eACrB,SAAQ,QAAQ,aAAa;IAE9B,CAAC;AAGJ,iBAAgB;AACd,MAAI,SAAS,WAAW,QAAQ,QAC9B,SAAQ,QAAQ,mBAAmB,SAAS;AAG9C,eAAa;AACX,OAAI,QAAQ,QACV,SAAQ,QAAQ;;IAGnB,CAAC,SAAS;AAGb,iBAAgB;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,gBAAgB,YAAY,YAAY;AAC5C,MAAI,QAAQ,SAAS;AACnB,YAAS;AACT,mBAAgB;AAChB,iBAAc;AACd,qBAAkB;AAClB,SAAM,QAAQ,QAAQ;;IAEvB;CAGH,MAAM,eAAe,kBAAkB;AACrC,MAAI,QAAQ,SAAS;AACnB,WAAQ,QAAQ;AAChB,iBAAc;AACd,mBAAgB;AAChB,qBAAkB;;IAEnB;CAGH,MAAM,qBAAqB,YAAY,OAAO,aAAqB;AACjE,oBAAkB;EAElB,MAAM,uBAAuB,QAAQ,MAAK,WAAU,OAAO,aAAa;AACxE,MAAI,qBACF,kBAAiB,kBAAkB;IAIpC,CAAC;CAEJ,MAAM,uBAAuB,kBAAkB,8BAA8B;AAE7E,QAAO;EAEL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAGA;EACA;EAGA;EACA;EACA;EACA;EACA;EAGA"}
@@ -0,0 +1,63 @@
1
+ import { __esm } from "../../../../_virtual/rolldown_runtime.js";
2
+ import { IndexedDBManager, init_IndexedDBManager } from "../IndexedDBManager/index.js";
3
+
4
+ //#region src/core/EmailRecovery/emailRecoveryPendingStore.ts
5
+ var EmailRecoveryPendingStore;
6
+ var init_emailRecoveryPendingStore = __esm({ "src/core/EmailRecovery/emailRecoveryPendingStore.ts": (() => {
7
+ init_IndexedDBManager();
8
+ EmailRecoveryPendingStore = class {
9
+ getPendingTtlMs;
10
+ now;
11
+ constructor(options) {
12
+ this.getPendingTtlMs = options.getPendingTtlMs;
13
+ this.now = options.now ?? Date.now;
14
+ }
15
+ getPendingIndexKey(accountId) {
16
+ return `pendingEmailRecovery:${accountId}`;
17
+ }
18
+ getPendingRecordKey(accountId, nearPublicKey) {
19
+ return `${this.getPendingIndexKey(accountId)}:${nearPublicKey}`;
20
+ }
21
+ async get(accountId, nearPublicKey) {
22
+ const pendingTtlMs = this.getPendingTtlMs();
23
+ const indexKey = this.getPendingIndexKey(accountId);
24
+ const indexedNearPublicKey = await IndexedDBManager.clientDB.getAppState(indexKey);
25
+ const resolvedNearPublicKey = nearPublicKey ?? indexedNearPublicKey;
26
+ if (!resolvedNearPublicKey) return null;
27
+ const recordKey = this.getPendingRecordKey(accountId, resolvedNearPublicKey);
28
+ const record = await IndexedDBManager.clientDB.getAppState(recordKey);
29
+ const shouldClearIndex = indexedNearPublicKey === resolvedNearPublicKey;
30
+ if (!record) {
31
+ if (shouldClearIndex) await IndexedDBManager.clientDB.setAppState(indexKey, void 0).catch(() => {});
32
+ return null;
33
+ }
34
+ if (this.now() - record.createdAt > pendingTtlMs) {
35
+ await IndexedDBManager.clientDB.setAppState(recordKey, void 0).catch(() => {});
36
+ if (shouldClearIndex) await IndexedDBManager.clientDB.setAppState(indexKey, void 0).catch(() => {});
37
+ return null;
38
+ }
39
+ await this.touchIndex(accountId, record.nearPublicKey);
40
+ return record;
41
+ }
42
+ async set(record) {
43
+ const key = this.getPendingRecordKey(record.accountId, record.nearPublicKey);
44
+ await IndexedDBManager.clientDB.setAppState(key, record);
45
+ await this.touchIndex(record.accountId, record.nearPublicKey);
46
+ }
47
+ async clear(accountId, nearPublicKey) {
48
+ const indexKey = this.getPendingIndexKey(accountId);
49
+ const idx = await IndexedDBManager.clientDB.getAppState(indexKey).catch(() => void 0);
50
+ const resolvedNearPublicKey = nearPublicKey || idx || "";
51
+ if (resolvedNearPublicKey) await IndexedDBManager.clientDB.setAppState(this.getPendingRecordKey(accountId, resolvedNearPublicKey), void 0).catch(() => {});
52
+ if (!nearPublicKey || idx === nearPublicKey) await IndexedDBManager.clientDB.setAppState(indexKey, void 0).catch(() => {});
53
+ }
54
+ async touchIndex(accountId, nearPublicKey) {
55
+ await IndexedDBManager.clientDB.setAppState(this.getPendingIndexKey(accountId), nearPublicKey).catch(() => {});
56
+ }
57
+ };
58
+ }) });
59
+
60
+ //#endregion
61
+ init_emailRecoveryPendingStore();
62
+ export { EmailRecoveryPendingStore, init_emailRecoveryPendingStore };
63
+ //# sourceMappingURL=emailRecoveryPendingStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emailRecoveryPendingStore.js","names":[],"sources":["../../../../../../../src/core/EmailRecovery/emailRecoveryPendingStore.ts"],"sourcesContent":["import { IndexedDBManager } from '../IndexedDBManager';\nimport type { AccountId } from '../types/accountIds';\nimport type { PendingEmailRecovery } from '../TatchiPasskey/emailRecovery';\n\nexport interface PendingStore {\n get(accountId: AccountId, nearPublicKey?: string): Promise<PendingEmailRecovery | null>;\n set(record: PendingEmailRecovery): Promise<void>;\n clear(accountId: AccountId, nearPublicKey?: string): Promise<void>;\n touchIndex(accountId: AccountId, nearPublicKey: string): Promise<void>;\n}\n\ntype EmailRecoveryPendingStoreOptions = {\n getPendingTtlMs: () => number;\n now?: () => number;\n};\n\nexport class EmailRecoveryPendingStore implements PendingStore {\n private getPendingTtlMs: () => number;\n private now: () => number;\n\n constructor(options: EmailRecoveryPendingStoreOptions) {\n this.getPendingTtlMs = options.getPendingTtlMs;\n this.now = options.now ?? Date.now;\n }\n\n private getPendingIndexKey(accountId: AccountId): string {\n return `pendingEmailRecovery:${accountId}`;\n }\n\n private getPendingRecordKey(accountId: AccountId, nearPublicKey: string): string {\n return `${this.getPendingIndexKey(accountId)}:${nearPublicKey}`;\n }\n\n async get(accountId: AccountId, nearPublicKey?: string): Promise<PendingEmailRecovery | null> {\n const pendingTtlMs = this.getPendingTtlMs();\n const indexKey = this.getPendingIndexKey(accountId);\n const indexedNearPublicKey = await IndexedDBManager.clientDB.getAppState<string>(indexKey);\n const resolvedNearPublicKey = nearPublicKey ?? indexedNearPublicKey;\n if (!resolvedNearPublicKey) {\n return null;\n }\n\n const recordKey = this.getPendingRecordKey(accountId, resolvedNearPublicKey);\n const record = await IndexedDBManager.clientDB.getAppState<PendingEmailRecovery>(recordKey);\n const shouldClearIndex = indexedNearPublicKey === resolvedNearPublicKey;\n if (!record) {\n if (shouldClearIndex) {\n await IndexedDBManager.clientDB.setAppState(indexKey, undefined as any).catch(() => { });\n }\n return null;\n }\n\n if (this.now() - record.createdAt > pendingTtlMs) {\n await IndexedDBManager.clientDB.setAppState(recordKey, undefined as any).catch(() => { });\n if (shouldClearIndex) {\n await IndexedDBManager.clientDB.setAppState(indexKey, undefined as any).catch(() => { });\n }\n return null;\n }\n\n await this.touchIndex(accountId, record.nearPublicKey);\n return record;\n }\n\n async set(record: PendingEmailRecovery): Promise<void> {\n const key = this.getPendingRecordKey(record.accountId, record.nearPublicKey);\n await IndexedDBManager.clientDB.setAppState(key, record);\n await this.touchIndex(record.accountId, record.nearPublicKey);\n }\n\n async clear(accountId: AccountId, nearPublicKey?: string): Promise<void> {\n const indexKey = this.getPendingIndexKey(accountId);\n const idx = await IndexedDBManager.clientDB.getAppState<string>(indexKey).catch(() => undefined);\n\n const resolvedNearPublicKey = nearPublicKey || idx || '';\n if (resolvedNearPublicKey) {\n await IndexedDBManager.clientDB\n .setAppState(this.getPendingRecordKey(accountId, resolvedNearPublicKey), undefined as any)\n .catch(() => { });\n }\n\n if (!nearPublicKey || idx === nearPublicKey) {\n await IndexedDBManager.clientDB.setAppState(indexKey, undefined as any).catch(() => { });\n }\n }\n\n async touchIndex(accountId: AccountId, nearPublicKey: string): Promise<void> {\n await IndexedDBManager.clientDB.setAppState(this.getPendingIndexKey(accountId), nearPublicKey).catch(() => { });\n }\n}\n"],"mappings":";;;;;;;CAgBa,4BAAb,MAA+D;EAC7D,AAAQ;EACR,AAAQ;EAER,YAAY,SAA2C;AACrD,QAAK,kBAAkB,QAAQ;AAC/B,QAAK,MAAM,QAAQ,OAAO,KAAK;;EAGjC,AAAQ,mBAAmB,WAA8B;AACvD,UAAO,wBAAwB;;EAGjC,AAAQ,oBAAoB,WAAsB,eAA+B;AAC/E,UAAO,GAAG,KAAK,mBAAmB,WAAW,GAAG;;EAGlD,MAAM,IAAI,WAAsB,eAA8D;GAC5F,MAAM,eAAe,KAAK;GAC1B,MAAM,WAAW,KAAK,mBAAmB;GACzC,MAAM,uBAAuB,MAAM,iBAAiB,SAAS,YAAoB;GACjF,MAAM,wBAAwB,iBAAiB;AAC/C,OAAI,CAAC,sBACH,QAAO;GAGT,MAAM,YAAY,KAAK,oBAAoB,WAAW;GACtD,MAAM,SAAS,MAAM,iBAAiB,SAAS,YAAkC;GACjF,MAAM,mBAAmB,yBAAyB;AAClD,OAAI,CAAC,QAAQ;AACX,QAAI,iBACF,OAAM,iBAAiB,SAAS,YAAY,UAAU,QAAkB,YAAY;AAEtF,WAAO;;AAGT,OAAI,KAAK,QAAQ,OAAO,YAAY,cAAc;AAChD,UAAM,iBAAiB,SAAS,YAAY,WAAW,QAAkB,YAAY;AACrF,QAAI,iBACF,OAAM,iBAAiB,SAAS,YAAY,UAAU,QAAkB,YAAY;AAEtF,WAAO;;AAGT,SAAM,KAAK,WAAW,WAAW,OAAO;AACxC,UAAO;;EAGT,MAAM,IAAI,QAA6C;GACrD,MAAM,MAAM,KAAK,oBAAoB,OAAO,WAAW,OAAO;AAC9D,SAAM,iBAAiB,SAAS,YAAY,KAAK;AACjD,SAAM,KAAK,WAAW,OAAO,WAAW,OAAO;;EAGjD,MAAM,MAAM,WAAsB,eAAuC;GACvE,MAAM,WAAW,KAAK,mBAAmB;GACzC,MAAM,MAAM,MAAM,iBAAiB,SAAS,YAAoB,UAAU,YAAY;GAEtF,MAAM,wBAAwB,iBAAiB,OAAO;AACtD,OAAI,sBACF,OAAM,iBAAiB,SACpB,YAAY,KAAK,oBAAoB,WAAW,wBAAwB,QACxE,YAAY;AAGjB,OAAI,CAAC,iBAAiB,QAAQ,cAC5B,OAAM,iBAAiB,SAAS,YAAY,UAAU,QAAkB,YAAY;;EAIxF,MAAM,WAAW,WAAsB,eAAsC;AAC3E,SAAM,iBAAiB,SAAS,YAAY,KAAK,mBAAmB,YAAY,eAAe,YAAY"}
@@ -1,20 +1,9 @@
1
+ import { __esm } from "../../../../_virtual/rolldown_runtime.js";
1
2
  import { init_accountIds, toAccountId } from "../types/accountIds.js";
2
3
  import { IndexedDBManager, init_IndexedDBManager } from "../IndexedDBManager/index.js";
4
+ import { EmailRecoveryPendingStore, init_emailRecoveryPendingStore } from "./emailRecoveryPendingStore.js";
3
5
 
4
6
  //#region src/core/EmailRecovery/index.ts
5
- init_accountIds();
6
- init_IndexedDBManager();
7
- const canonicalizeEmail = (email) => {
8
- let addr = email;
9
- const angleStart = email.indexOf("<");
10
- const angleEnd = email.indexOf(">");
11
- if (angleStart !== -1 && angleEnd > angleStart) addr = email.slice(angleStart + 1, angleEnd);
12
- return addr.trim().toLowerCase();
13
- };
14
- const bytesToHex = (bytes) => {
15
- const arr = bytes instanceof Uint8Array ? bytes : Uint8Array.from(bytes);
16
- return `0x${Array.from(arr).map((b) => b.toString(16).padStart(2, "0")).join("")}`;
17
- };
18
7
  async function hashRecoveryEmails(emails, accountId) {
19
8
  const encoder = new TextEncoder();
20
9
  const salt = (accountId || "").trim().toLowerCase();
@@ -61,7 +50,32 @@ async function prepareRecoveryEmails(nearAccountId, recoveryEmails) {
61
50
  async function getLocalRecoveryEmails(nearAccountId) {
62
51
  return IndexedDBManager.getRecoveryEmails(nearAccountId);
63
52
  }
53
+ var canonicalizeEmail, bytesToHex;
54
+ var init_EmailRecovery = __esm({ "src/core/EmailRecovery/index.ts": (() => {
55
+ init_accountIds();
56
+ init_IndexedDBManager();
57
+ init_emailRecoveryPendingStore();
58
+ canonicalizeEmail = (email) => {
59
+ const raw = String(email || "").trim();
60
+ if (!raw) return "";
61
+ const withoutHeaderName = raw.replace(/^[a-z0-9-]+\s*:\s*/i, "").trim();
62
+ const emailRegex = /([a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*)/;
63
+ const angleMatch = withoutHeaderName.match(/<([^>]+)>/);
64
+ const candidates = [angleMatch?.[1], withoutHeaderName].filter((v) => typeof v === "string" && v.length > 0);
65
+ for (const candidate of candidates) {
66
+ const cleaned = candidate.replace(/^mailto:\s*/i, "");
67
+ const match = cleaned.match(emailRegex);
68
+ if (match?.[1]) return match[1].trim().toLowerCase();
69
+ }
70
+ return withoutHeaderName.toLowerCase();
71
+ };
72
+ bytesToHex = (bytes) => {
73
+ const arr = bytes instanceof Uint8Array ? bytes : Uint8Array.from(bytes);
74
+ return `0x${Array.from(arr).map((b) => b.toString(16).padStart(2, "0")).join("")}`;
75
+ };
76
+ }) });
64
77
 
65
78
  //#endregion
66
- export { bytesToHex, getLocalRecoveryEmails, prepareRecoveryEmails };
79
+ init_EmailRecovery();
80
+ export { bytesToHex, getLocalRecoveryEmails, init_EmailRecovery, prepareRecoveryEmails };
67
81
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["hashed: number[][]","pairs: RecoveryEmailEntry[]"],"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,YAAY,YAAY;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,SAAM,iBAAiB,qBAAqB,WAAW;WAChD,OAAO;AACd,WAAQ,KAAK,2DAA2D;;;AAI5E,QAAO;EAAE,QAAQ;EAAqB;;;AAGxC,eAAsB,uBAAuB,eAA0D;AACrG,QAAO,iBAAiB,kBAAkB"}
1
+ {"version":3,"file":"index.js","names":["hashed: number[][]","pairs: RecoveryEmailEntry[]"],"sources":["../../../../../../../src/core/EmailRecovery/index.ts"],"sourcesContent":["import type { AccountId } from '../types/accountIds';\nimport { toAccountId } from '../types/accountIds';\nimport { IndexedDBManager, type RecoveryEmailRecord } from '../IndexedDBManager';\nexport { EmailRecoveryPendingStore, type PendingStore } from './emailRecoveryPendingStore';\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":";;;;;;AAgDA,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,YAAY,YAAY;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,SAAM,iBAAiB,qBAAqB,WAAW;WAChD,OAAO;AACd,WAAQ,KAAK,2DAA2D;;;AAI5E,QAAO;EAAE,QAAQ;EAAqB;;;AAGxC,eAAsB,uBAAuB,eAA0D;AACrG,QAAO,iBAAiB,kBAAkB;;;;;;;CA7F/B,qBAAqB,UAA0B;EAC1D,MAAM,MAAM,OAAO,SAAS,IAAI;AAChC,MAAI,CAAC,IAAK,QAAO;EAGjB,MAAM,oBAAoB,IAAI,QAAQ,uBAAuB,IAAI;EAEjE,MAAM,aACJ;EAIF,MAAM,aAAa,kBAAkB,MAAM;EAC3C,MAAM,aAAa,CACjB,aAAa,IACb,mBACA,QAAQ,MAAmB,OAAO,MAAM,YAAY,EAAE,SAAS;AAEjE,OAAK,MAAM,aAAa,YAAY;GAClC,MAAM,UAAU,UAAU,QAAQ,gBAAgB;GAClD,MAAM,QAAQ,QAAQ,MAAM;AAC5B,OAAI,QAAQ,GACV,QAAO,MAAM,GAAG,OAAO;;AAI3B,SAAO,kBAAkB;;CAGd,cAAc,UAAyC;EAClE,MAAM,MAAM,iBAAiB,aAAa,QAAQ,WAAW,KAAK;AAClE,SAAO,KAAK,MAAM,KAAK,KACpB,KAAI,MAAK,EAAE,SAAS,IAAI,SAAS,GAAG,MACpC,KAAK"}
@@ -259,22 +259,17 @@ var init_passkeyClientDB = __esm({ "src/core/IndexedDBManager/passkeyClientDB.ts
259
259
  * @returns filtered authenticators for allowCredentials, plus optional wrongPasskeyError
260
260
  */
261
261
  async ensureCurrentPasskey(nearAccountId, authenticators, selectedCredentialRawId) {
262
- let authenticatorsForPrompt = authenticators;
263
- let wrongPasskeyError;
264
- if (authenticators.length > 1) {
265
- const accountIdNormalized = toAccountId(nearAccountId);
266
- const lastUser = await this.getLastUser().catch(() => null);
267
- const expectedAccountId = lastUser?.nearAccountId;
268
- const expectedDeviceNumber = lastUser?.deviceNumber;
269
- if (expectedAccountId && expectedDeviceNumber && expectedAccountId === accountIdNormalized) {
270
- const filtered = authenticators.filter((a) => a.deviceNumber === expectedDeviceNumber);
271
- if (filtered.length > 0) authenticatorsForPrompt = filtered;
272
- if (selectedCredentialRawId) {
273
- const matched = authenticators.find((a) => a.credentialId === selectedCredentialRawId);
274
- 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.`;
275
- }
276
- }
277
- }
262
+ if (authenticators.length <= 1) return { authenticatorsForPrompt: authenticators };
263
+ const accountIdNormalized = toAccountId(nearAccountId);
264
+ const lastUser = await this.getLastUser().catch(() => null);
265
+ if (!lastUser || lastUser.nearAccountId !== accountIdNormalized) return { authenticatorsForPrompt: authenticators };
266
+ const expectedDeviceNumber = lastUser.deviceNumber;
267
+ const byDeviceNumber = authenticators.filter((a) => a.deviceNumber === expectedDeviceNumber);
268
+ let expectedCredentialId = lastUser.passkeyCredential.rawId;
269
+ if (byDeviceNumber.length > 0 && !byDeviceNumber.some((a) => a.credentialId === expectedCredentialId)) expectedCredentialId = byDeviceNumber[0].credentialId;
270
+ const byCredentialId = authenticators.filter((a) => a.credentialId === expectedCredentialId);
271
+ const authenticatorsForPrompt = byCredentialId.length > 0 ? byCredentialId : byDeviceNumber.length > 0 ? byDeviceNumber : authenticators;
272
+ 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;
278
273
  return {
279
274
  authenticatorsForPrompt,
280
275
  wrongPasskeyError
@@ -385,30 +380,34 @@ var init_passkeyClientDB = __esm({ "src/core/IndexedDBManager/passkeyClientDB.ts
385
380
  * @param userData - User data with nearAccountId as primary identifier
386
381
  */
387
382
  async storeWebAuthnUserData(userData) {
388
- if (userData.deviceNumber === void 0) console.warn("WARNING: deviceNumber is undefined in storeWebAuthnUserData, will default to 1");
389
383
  const validation = this.validateNearAccountId(userData.nearAccountId);
390
384
  if (!validation.valid) throw new Error(`Cannot store WebAuthn data for invalid account ID: ${validation.error}`);
391
- let existingUser = await this.getUser(userData.nearAccountId);
392
- if (!existingUser) {
393
- const deviceNumberToUse = userData.deviceNumber || 1;
394
- existingUser = await this.registerUser({
395
- nearAccountId: userData.nearAccountId,
396
- deviceNumber: deviceNumberToUse,
397
- clientNearPublicKey: userData.clientNearPublicKey,
398
- passkeyCredential: userData.passkeyCredential,
399
- encryptedVrfKeypair: userData.encryptedVrfKeypair,
400
- version: userData.version || 2,
401
- serverEncryptedVrfKeypair: userData.serverEncryptedVrfKeypair
402
- });
403
- }
404
- const finalDeviceNumber = userData.deviceNumber || existingUser.deviceNumber;
405
- await this.updateUser(userData.nearAccountId, {
385
+ const accountId = toAccountId(userData.nearAccountId);
386
+ const deviceNumber = userData.deviceNumber;
387
+ let user = await this.getUser(accountId, deviceNumber);
388
+ if (!user) user = await this.registerUser({
389
+ nearAccountId: accountId,
390
+ deviceNumber,
406
391
  clientNearPublicKey: userData.clientNearPublicKey,
392
+ passkeyCredential: userData.passkeyCredential,
407
393
  encryptedVrfKeypair: userData.encryptedVrfKeypair,
408
- serverEncryptedVrfKeypair: userData.serverEncryptedVrfKeypair,
409
- version: userData.version || existingUser.version,
410
- deviceNumber: finalDeviceNumber,
411
- lastUpdated: userData.lastUpdated || Date.now()
394
+ version: userData.version || 2,
395
+ serverEncryptedVrfKeypair: userData.serverEncryptedVrfKeypair
396
+ });
397
+ const updatedUser = {
398
+ ...user,
399
+ clientNearPublicKey: userData.clientNearPublicKey,
400
+ passkeyCredential: userData.passkeyCredential,
401
+ encryptedVrfKeypair: userData.encryptedVrfKeypair,
402
+ serverEncryptedVrfKeypair: userData.serverEncryptedVrfKeypair ?? user.serverEncryptedVrfKeypair,
403
+ version: userData.version ?? user.version,
404
+ lastUpdated: userData.lastUpdated ?? Date.now()
405
+ };
406
+ await this.storeUser(updatedUser);
407
+ this.emitEvent({
408
+ type: "user-updated",
409
+ accountId,
410
+ data: { updatedUser }
412
411
  });
413
412
  }
414
413
  async getAllUsers() {