@tatchi-xyz/sdk 0.16.0 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (470) hide show
  1. package/dist/cjs/core/EmailRecovery/index.js +12 -5
  2. package/dist/cjs/core/EmailRecovery/index.js.map +1 -1
  3. package/dist/cjs/core/IndexedDBManager/passkeyClientDB.js +35 -36
  4. package/dist/cjs/core/IndexedDBManager/passkeyClientDB.js.map +1 -1
  5. package/dist/cjs/core/NearClient.js +2 -1
  6. package/dist/cjs/core/NearClient.js.map +1 -1
  7. package/dist/cjs/core/TatchiPasskey/emailRecovery.js +136 -27
  8. package/dist/cjs/core/TatchiPasskey/emailRecovery.js.map +1 -1
  9. package/dist/cjs/core/TatchiPasskey/faucets/createAccountRelayServer.js +1 -0
  10. package/dist/cjs/core/TatchiPasskey/faucets/createAccountRelayServer.js.map +1 -1
  11. package/dist/cjs/core/TatchiPasskey/index.js +25 -0
  12. package/dist/cjs/core/TatchiPasskey/index.js.map +1 -1
  13. package/dist/cjs/core/TatchiPasskey/linkDevice.js +2 -0
  14. package/dist/cjs/core/TatchiPasskey/linkDevice.js.map +1 -1
  15. package/dist/cjs/core/TatchiPasskey/login.js +15 -4
  16. package/dist/cjs/core/TatchiPasskey/login.js.map +1 -1
  17. package/dist/cjs/core/TatchiPasskey/recoverAccount.js +1 -0
  18. package/dist/cjs/core/TatchiPasskey/recoverAccount.js.map +1 -1
  19. package/dist/cjs/core/TatchiPasskey/scanDevice.js +1 -0
  20. package/dist/cjs/core/TatchiPasskey/scanDevice.js.map +1 -1
  21. package/dist/cjs/core/WalletIframe/client/IframeTransport.js +10 -0
  22. package/dist/cjs/core/WalletIframe/client/IframeTransport.js.map +1 -1
  23. package/dist/cjs/core/WalletIframe/client/router.js +9 -0
  24. package/dist/cjs/core/WalletIframe/client/router.js.map +1 -1
  25. package/dist/cjs/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-drawer.js +1 -1
  26. package/dist/cjs/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-drawer.js.map +1 -1
  27. package/dist/cjs/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-modal.js +52 -52
  28. package/dist/cjs/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-modal.js.map +1 -1
  29. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/getDeviceNumber.js +10 -1
  30. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/getDeviceNumber.js.map +1 -1
  31. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/checkCanRegisterUser.js +1 -0
  32. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/checkCanRegisterUser.js.map +1 -1
  33. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/decryptPrivateKeyWithPrf.js +1 -0
  34. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/decryptPrivateKeyWithPrf.js.map +1 -1
  35. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/deriveNearKeypairAndEncryptFromSerialized.js +1 -0
  36. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/deriveNearKeypairAndEncryptFromSerialized.js.map +1 -1
  37. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/exportNearKeypairUi.js +1 -0
  38. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/exportNearKeypairUi.js.map +1 -1
  39. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/registerDevice2WithDerivedKey.js +2 -1
  40. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/registerDevice2WithDerivedKey.js.map +1 -1
  41. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/signDelegateAction.js +1 -0
  42. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/signDelegateAction.js.map +1 -1
  43. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/signNep413Message.js +1 -0
  44. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/signNep413Message.js.map +1 -1
  45. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/signTransactionsWithActions.js +1 -0
  46. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/signTransactionsWithActions.js.map +1 -1
  47. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/validation.js +2 -0
  48. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/validation.js.map +1 -1
  49. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/index.js +1 -0
  50. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/index.js.map +1 -1
  51. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/vrf.js +1 -0
  52. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/vrf.js.map +1 -1
  53. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/webauthn.js +6 -0
  54. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/webauthn.js.map +1 -1
  55. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/determineConfirmationConfig.js +2 -1
  56. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/determineConfirmationConfig.js.map +1 -1
  57. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/localOnly.js +1 -0
  58. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/localOnly.js.map +1 -1
  59. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/registration.js +1 -0
  60. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/registration.js.map +1 -1
  61. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/transactions.js +4 -15
  62. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/transactions.js.map +1 -1
  63. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/handlers/deriveVrfKeypairFromPrf.js +1 -0
  64. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/handlers/deriveVrfKeypairFromPrf.js.map +1 -1
  65. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfChallenge.js +1 -0
  66. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfChallenge.js.map +1 -1
  67. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfKeypairBootstrap.js +1 -0
  68. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfKeypairBootstrap.js.map +1 -1
  69. package/dist/cjs/core/WebAuthnManager/WebAuthnFallbacks/index.js +17 -0
  70. package/dist/cjs/core/WebAuthnManager/WebAuthnFallbacks/index.js.map +1 -0
  71. package/dist/cjs/core/WebAuthnManager/WebAuthnFallbacks/safari-fallbacks.js +64 -54
  72. package/dist/cjs/core/WebAuthnManager/WebAuthnFallbacks/safari-fallbacks.js.map +1 -1
  73. package/dist/cjs/core/WebAuthnManager/credentialsHelpers.js +12 -2
  74. package/dist/cjs/core/WebAuthnManager/credentialsHelpers.js.map +1 -1
  75. package/dist/cjs/core/WebAuthnManager/index.js +6 -1
  76. package/dist/cjs/core/WebAuthnManager/index.js.map +1 -1
  77. package/dist/cjs/core/WebAuthnManager/touchIdPrompt.js +209 -201
  78. package/dist/cjs/core/WebAuthnManager/touchIdPrompt.js.map +1 -1
  79. package/dist/cjs/core/WebAuthnManager/userHandle.js +2 -1
  80. package/dist/cjs/core/WebAuthnManager/userHandle.js.map +1 -1
  81. package/dist/cjs/core/defaultConfigs.js +1 -1
  82. package/dist/cjs/core/defaultConfigs.js.map +1 -1
  83. package/dist/cjs/core/types/vrf-worker.js +10 -1
  84. package/dist/cjs/core/types/vrf-worker.js.map +1 -1
  85. package/dist/cjs/react/components/AccountMenuButton/{LinkedDevicesModal-STvIsylA.css → LinkedDevicesModal-B6api181.css} +1 -1
  86. package/dist/{esm/react/components/AccountMenuButton/LinkedDevicesModal-STvIsylA.css.map → cjs/react/components/AccountMenuButton/LinkedDevicesModal-B6api181.css.map} +1 -1
  87. package/dist/cjs/react/components/AccountMenuButton/{ProfileDropdown-iARgUwK1.css → ProfileDropdown-B-DrG_u5.css} +1 -1
  88. package/dist/{esm/react/components/AccountMenuButton/ProfileDropdown-iARgUwK1.css.map → cjs/react/components/AccountMenuButton/ProfileDropdown-B-DrG_u5.css.map} +1 -1
  89. package/dist/cjs/react/components/AccountMenuButton/{Web3AuthProfileButton-Db3NeoAC.css → Web3AuthProfileButton-BnZDUeCL.css} +1 -1
  90. package/dist/cjs/react/components/AccountMenuButton/{Web3AuthProfileButton-Db3NeoAC.css.map → Web3AuthProfileButton-BnZDUeCL.css.map} +1 -1
  91. package/dist/cjs/react/components/AccountMenuButton/icons/{TouchIcon-BXM5NR4A.css → TouchIcon-CAGCi8MY.css} +1 -1
  92. package/dist/cjs/react/components/AccountMenuButton/icons/{TouchIcon-BXM5NR4A.css.map → TouchIcon-CAGCi8MY.css.map} +1 -1
  93. package/dist/cjs/react/components/PasskeyAuthMenu/{PasskeyAuthMenu-De1qTSmU.css → PasskeyAuthMenu-CNNxVj4L.css} +14 -1
  94. package/dist/cjs/react/components/PasskeyAuthMenu/{PasskeyAuthMenu-De1qTSmU.css.map → PasskeyAuthMenu-CNNxVj4L.css.map} +1 -1
  95. package/dist/cjs/react/components/PasskeyAuthMenu/ui/EmailRecoverySlide.js +122 -53
  96. package/dist/cjs/react/components/PasskeyAuthMenu/ui/EmailRecoverySlide.js.map +1 -1
  97. package/dist/cjs/react/components/{ShowQRCode-DCnR__fx.css → ShowQRCode-nZhZSaba.css} +1 -1
  98. package/dist/cjs/react/components/{ShowQRCode-DCnR__fx.css.map → ShowQRCode-nZhZSaba.css.map} +1 -1
  99. package/dist/cjs/react/deviceDetection.js +75 -92
  100. package/dist/cjs/react/deviceDetection.js.map +1 -1
  101. package/dist/cjs/react/hooks/usePreconnectWalletAssets.js +32 -27
  102. package/dist/cjs/react/hooks/usePreconnectWalletAssets.js.map +1 -1
  103. package/dist/cjs/react/hooks/useQRCamera.js +1 -0
  104. package/dist/cjs/react/hooks/useQRCamera.js.map +1 -1
  105. package/dist/cjs/react/sdk/src/core/EmailRecovery/index.js +12 -5
  106. package/dist/cjs/react/sdk/src/core/EmailRecovery/index.js.map +1 -1
  107. package/dist/cjs/react/sdk/src/core/IndexedDBManager/passkeyClientDB.js +35 -36
  108. package/dist/cjs/react/sdk/src/core/IndexedDBManager/passkeyClientDB.js.map +1 -1
  109. package/dist/cjs/react/sdk/src/core/NearClient.js +2 -1
  110. package/dist/cjs/react/sdk/src/core/NearClient.js.map +1 -1
  111. package/dist/cjs/react/sdk/src/core/TatchiPasskey/emailRecovery.js +136 -27
  112. package/dist/cjs/react/sdk/src/core/TatchiPasskey/emailRecovery.js.map +1 -1
  113. package/dist/cjs/react/sdk/src/core/TatchiPasskey/faucets/createAccountRelayServer.js +1 -0
  114. package/dist/cjs/react/sdk/src/core/TatchiPasskey/faucets/createAccountRelayServer.js.map +1 -1
  115. package/dist/cjs/react/sdk/src/core/TatchiPasskey/index.js +25 -0
  116. package/dist/cjs/react/sdk/src/core/TatchiPasskey/index.js.map +1 -1
  117. package/dist/cjs/react/sdk/src/core/TatchiPasskey/linkDevice.js +2 -0
  118. package/dist/cjs/react/sdk/src/core/TatchiPasskey/linkDevice.js.map +1 -1
  119. package/dist/cjs/react/sdk/src/core/TatchiPasskey/login.js +15 -4
  120. package/dist/cjs/react/sdk/src/core/TatchiPasskey/login.js.map +1 -1
  121. package/dist/cjs/react/sdk/src/core/TatchiPasskey/recoverAccount.js +1 -0
  122. package/dist/cjs/react/sdk/src/core/TatchiPasskey/recoverAccount.js.map +1 -1
  123. package/dist/cjs/react/sdk/src/core/TatchiPasskey/scanDevice.js +1 -0
  124. package/dist/cjs/react/sdk/src/core/TatchiPasskey/scanDevice.js.map +1 -1
  125. package/dist/cjs/react/sdk/src/core/WalletIframe/client/IframeTransport.js +10 -0
  126. package/dist/cjs/react/sdk/src/core/WalletIframe/client/IframeTransport.js.map +1 -1
  127. package/dist/cjs/react/sdk/src/core/WalletIframe/client/router.js +9 -0
  128. package/dist/cjs/react/sdk/src/core/WalletIframe/client/router.js.map +1 -1
  129. package/dist/cjs/react/sdk/src/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-drawer.js +1 -1
  130. package/dist/cjs/react/sdk/src/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-drawer.js.map +1 -1
  131. package/dist/cjs/react/sdk/src/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-modal.js +52 -52
  132. package/dist/cjs/react/sdk/src/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-modal.js.map +1 -1
  133. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/getDeviceNumber.js +10 -1
  134. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/getDeviceNumber.js.map +1 -1
  135. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/checkCanRegisterUser.js +1 -0
  136. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/checkCanRegisterUser.js.map +1 -1
  137. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/decryptPrivateKeyWithPrf.js +1 -0
  138. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/decryptPrivateKeyWithPrf.js.map +1 -1
  139. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/deriveNearKeypairAndEncryptFromSerialized.js +1 -0
  140. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/deriveNearKeypairAndEncryptFromSerialized.js.map +1 -1
  141. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/exportNearKeypairUi.js +1 -0
  142. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/exportNearKeypairUi.js.map +1 -1
  143. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/registerDevice2WithDerivedKey.js +2 -1
  144. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/registerDevice2WithDerivedKey.js.map +1 -1
  145. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/signDelegateAction.js +1 -0
  146. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/signDelegateAction.js.map +1 -1
  147. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/signNep413Message.js +1 -0
  148. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/signNep413Message.js.map +1 -1
  149. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/signTransactionsWithActions.js +1 -0
  150. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/signTransactionsWithActions.js.map +1 -1
  151. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/validation.js +2 -0
  152. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/validation.js.map +1 -1
  153. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/index.js +1 -0
  154. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/index.js.map +1 -1
  155. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/vrf.js +1 -0
  156. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/vrf.js.map +1 -1
  157. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/webauthn.js +6 -0
  158. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/webauthn.js.map +1 -1
  159. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/determineConfirmationConfig.js +2 -1
  160. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/determineConfirmationConfig.js.map +1 -1
  161. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/localOnly.js +1 -0
  162. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/localOnly.js.map +1 -1
  163. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/registration.js +1 -0
  164. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/registration.js.map +1 -1
  165. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/transactions.js +4 -15
  166. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/transactions.js.map +1 -1
  167. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/handlers/deriveVrfKeypairFromPrf.js +1 -0
  168. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/handlers/deriveVrfKeypairFromPrf.js.map +1 -1
  169. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfChallenge.js +1 -0
  170. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfChallenge.js.map +1 -1
  171. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfKeypairBootstrap.js +1 -0
  172. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfKeypairBootstrap.js.map +1 -1
  173. package/dist/cjs/react/sdk/src/core/WebAuthnManager/WebAuthnFallbacks/index.js +17 -0
  174. package/dist/cjs/react/sdk/src/core/WebAuthnManager/WebAuthnFallbacks/index.js.map +1 -0
  175. package/dist/cjs/react/sdk/src/core/WebAuthnManager/WebAuthnFallbacks/safari-fallbacks.js +64 -54
  176. package/dist/cjs/react/sdk/src/core/WebAuthnManager/WebAuthnFallbacks/safari-fallbacks.js.map +1 -1
  177. package/dist/cjs/react/sdk/src/core/WebAuthnManager/credentialsHelpers.js +12 -2
  178. package/dist/cjs/react/sdk/src/core/WebAuthnManager/credentialsHelpers.js.map +1 -1
  179. package/dist/cjs/react/sdk/src/core/WebAuthnManager/index.js +6 -1
  180. package/dist/cjs/react/sdk/src/core/WebAuthnManager/index.js.map +1 -1
  181. package/dist/cjs/react/sdk/src/core/WebAuthnManager/touchIdPrompt.js +209 -201
  182. package/dist/cjs/react/sdk/src/core/WebAuthnManager/touchIdPrompt.js.map +1 -1
  183. package/dist/cjs/react/sdk/src/core/WebAuthnManager/userHandle.js +2 -1
  184. package/dist/cjs/react/sdk/src/core/WebAuthnManager/userHandle.js.map +1 -1
  185. package/dist/cjs/react/sdk/src/core/defaultConfigs.js +1 -1
  186. package/dist/cjs/react/sdk/src/core/defaultConfigs.js.map +1 -1
  187. package/dist/cjs/react/sdk/src/core/types/vrf-worker.js +10 -1
  188. package/dist/cjs/react/sdk/src/core/types/vrf-worker.js.map +1 -1
  189. package/dist/cjs/react/sdk/src/utils/index.js +13 -3
  190. package/dist/cjs/server/email-recovery/emailEncryptor.js +11 -0
  191. package/dist/cjs/server/email-recovery/emailEncryptor.js.map +1 -1
  192. package/dist/cjs/server/email-recovery/emailParsers.js +57 -0
  193. package/dist/cjs/server/email-recovery/emailParsers.js.map +1 -1
  194. package/dist/cjs/server/email-recovery/index.js +1 -1
  195. package/dist/cjs/server/email-recovery/index.js.map +1 -1
  196. package/dist/cjs/server/email-recovery/rpcCalls.js +14 -1
  197. package/dist/cjs/server/email-recovery/rpcCalls.js.map +1 -1
  198. package/dist/cjs/server/index.js +1 -0
  199. package/dist/cjs/server/router/cloudflare.js.map +1 -1
  200. package/dist/cjs/server/router/express.js.map +1 -1
  201. package/dist/cjs/server/sdk/src/core/defaultConfigs.js +1 -1
  202. package/dist/cjs/server/sdk/src/core/defaultConfigs.js.map +1 -1
  203. package/dist/cjs/utils/index.js +13 -3
  204. package/dist/esm/core/EmailRecovery/index.js +12 -5
  205. package/dist/esm/core/EmailRecovery/index.js.map +1 -1
  206. package/dist/esm/core/IndexedDBManager/passkeyClientDB.js +35 -36
  207. package/dist/esm/core/IndexedDBManager/passkeyClientDB.js.map +1 -1
  208. package/dist/esm/core/NearClient.js +2 -1
  209. package/dist/esm/core/NearClient.js.map +1 -1
  210. package/dist/esm/core/TatchiPasskey/emailRecovery.js +136 -27
  211. package/dist/esm/core/TatchiPasskey/emailRecovery.js.map +1 -1
  212. package/dist/esm/core/TatchiPasskey/faucets/createAccountRelayServer.js +2 -1
  213. package/dist/esm/core/TatchiPasskey/faucets/createAccountRelayServer.js.map +1 -1
  214. package/dist/esm/core/TatchiPasskey/index.js +26 -1
  215. package/dist/esm/core/TatchiPasskey/index.js.map +1 -1
  216. package/dist/esm/core/TatchiPasskey/linkDevice.js +4 -2
  217. package/dist/esm/core/TatchiPasskey/linkDevice.js.map +1 -1
  218. package/dist/esm/core/TatchiPasskey/login.js +13 -7
  219. package/dist/esm/core/TatchiPasskey/login.js.map +1 -1
  220. package/dist/esm/core/TatchiPasskey/recoverAccount.js +2 -1
  221. package/dist/esm/core/TatchiPasskey/recoverAccount.js.map +1 -1
  222. package/dist/esm/core/TatchiPasskey/scanDevice.js +2 -1
  223. package/dist/esm/core/TatchiPasskey/scanDevice.js.map +1 -1
  224. package/dist/esm/core/WalletIframe/client/IframeTransport.js +11 -1
  225. package/dist/esm/core/WalletIframe/client/IframeTransport.js.map +1 -1
  226. package/dist/esm/core/WalletIframe/client/router.js +9 -0
  227. package/dist/esm/core/WalletIframe/client/router.js.map +1 -1
  228. package/dist/esm/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-drawer.js +1 -1
  229. package/dist/esm/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-drawer.js.map +1 -1
  230. package/dist/esm/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-modal.js +52 -52
  231. package/dist/esm/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-modal.js.map +1 -1
  232. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/getDeviceNumber.js +6 -2
  233. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/checkCanRegisterUser.js +2 -1
  234. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/checkCanRegisterUser.js.map +1 -1
  235. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/decryptPrivateKeyWithPrf.js +2 -1
  236. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/decryptPrivateKeyWithPrf.js.map +1 -1
  237. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/deriveNearKeypairAndEncryptFromSerialized.js +2 -1
  238. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/deriveNearKeypairAndEncryptFromSerialized.js.map +1 -1
  239. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/exportNearKeypairUi.js +2 -1
  240. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/exportNearKeypairUi.js.map +1 -1
  241. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/registerDevice2WithDerivedKey.js +2 -1
  242. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/registerDevice2WithDerivedKey.js.map +1 -1
  243. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/signDelegateAction.js +2 -1
  244. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/signDelegateAction.js.map +1 -1
  245. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/signNep413Message.js +2 -1
  246. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/signNep413Message.js.map +1 -1
  247. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/signTransactionsWithActions.js +2 -1
  248. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/signTransactionsWithActions.js.map +1 -1
  249. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/validation.js +4 -2
  250. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/validation.js.map +1 -1
  251. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/index.js +2 -1
  252. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/index.js.map +1 -1
  253. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/vrf.js +1 -0
  254. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/vrf.js.map +1 -1
  255. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/webauthn.js +8 -2
  256. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/webauthn.js.map +1 -1
  257. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/determineConfirmationConfig.js +2 -1
  258. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/determineConfirmationConfig.js.map +1 -1
  259. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/localOnly.js +2 -1
  260. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/localOnly.js.map +1 -1
  261. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/registration.js +2 -1
  262. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/registration.js.map +1 -1
  263. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/transactions.js +5 -16
  264. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/transactions.js.map +1 -1
  265. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/handlers/deriveVrfKeypairFromPrf.js +2 -1
  266. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/handlers/deriveVrfKeypairFromPrf.js.map +1 -1
  267. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfChallenge.js +2 -1
  268. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfChallenge.js.map +1 -1
  269. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfKeypairBootstrap.js +2 -1
  270. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfKeypairBootstrap.js.map +1 -1
  271. package/dist/esm/core/WebAuthnManager/WebAuthnFallbacks/index.js +12 -0
  272. package/dist/esm/core/WebAuthnManager/WebAuthnFallbacks/index.js.map +1 -0
  273. package/dist/esm/core/WebAuthnManager/WebAuthnFallbacks/safari-fallbacks.js +61 -55
  274. package/dist/esm/core/WebAuthnManager/WebAuthnFallbacks/safari-fallbacks.js.map +1 -1
  275. package/dist/esm/core/WebAuthnManager/credentialsHelpers.js +8 -3
  276. package/dist/esm/core/WebAuthnManager/index.js +8 -3
  277. package/dist/esm/core/WebAuthnManager/index.js.map +1 -1
  278. package/dist/esm/core/WebAuthnManager/touchIdPrompt.js +207 -204
  279. package/dist/esm/core/WebAuthnManager/touchIdPrompt.js.map +1 -1
  280. package/dist/esm/core/WebAuthnManager/userHandle.js +2 -1
  281. package/dist/esm/core/WebAuthnManager/userHandle.js.map +1 -1
  282. package/dist/esm/core/defaultConfigs.js +1 -1
  283. package/dist/esm/core/defaultConfigs.js.map +1 -1
  284. package/dist/esm/core/types/vrf-worker.js +6 -2
  285. package/dist/esm/react/components/AccountMenuButton/{LinkedDevicesModal-STvIsylA.css → LinkedDevicesModal-B6api181.css} +1 -1
  286. package/dist/{cjs/react/components/AccountMenuButton/LinkedDevicesModal-STvIsylA.css.map → esm/react/components/AccountMenuButton/LinkedDevicesModal-B6api181.css.map} +1 -1
  287. package/dist/esm/react/components/AccountMenuButton/{ProfileDropdown-iARgUwK1.css → ProfileDropdown-B-DrG_u5.css} +1 -1
  288. package/dist/{cjs/react/components/AccountMenuButton/ProfileDropdown-iARgUwK1.css.map → esm/react/components/AccountMenuButton/ProfileDropdown-B-DrG_u5.css.map} +1 -1
  289. package/dist/esm/react/components/AccountMenuButton/{Web3AuthProfileButton-Db3NeoAC.css → Web3AuthProfileButton-BnZDUeCL.css} +1 -1
  290. package/dist/esm/react/components/AccountMenuButton/{Web3AuthProfileButton-Db3NeoAC.css.map → Web3AuthProfileButton-BnZDUeCL.css.map} +1 -1
  291. package/dist/esm/react/components/AccountMenuButton/icons/{TouchIcon-BXM5NR4A.css → TouchIcon-CAGCi8MY.css} +1 -1
  292. package/dist/esm/react/components/AccountMenuButton/icons/{TouchIcon-BXM5NR4A.css.map → TouchIcon-CAGCi8MY.css.map} +1 -1
  293. package/dist/esm/react/components/PasskeyAuthMenu/{PasskeyAuthMenu-De1qTSmU.css → PasskeyAuthMenu-CNNxVj4L.css} +14 -1
  294. package/dist/esm/react/components/PasskeyAuthMenu/{PasskeyAuthMenu-De1qTSmU.css.map → PasskeyAuthMenu-CNNxVj4L.css.map} +1 -1
  295. package/dist/esm/react/components/PasskeyAuthMenu/ui/EmailRecoverySlide.js +123 -54
  296. package/dist/esm/react/components/PasskeyAuthMenu/ui/EmailRecoverySlide.js.map +1 -1
  297. package/dist/esm/react/components/{ShowQRCode-DCnR__fx.css → ShowQRCode-nZhZSaba.css} +1 -1
  298. package/dist/esm/react/components/{ShowQRCode-DCnR__fx.css.map → ShowQRCode-nZhZSaba.css.map} +1 -1
  299. package/dist/esm/react/deviceDetection.js +72 -93
  300. package/dist/esm/react/deviceDetection.js.map +1 -1
  301. package/dist/esm/react/hooks/usePreconnectWalletAssets.js +32 -27
  302. package/dist/esm/react/hooks/usePreconnectWalletAssets.js.map +1 -1
  303. package/dist/esm/react/hooks/useQRCamera.js +2 -1
  304. package/dist/esm/react/hooks/useQRCamera.js.map +1 -1
  305. package/dist/esm/react/sdk/src/core/EmailRecovery/index.js +12 -5
  306. package/dist/esm/react/sdk/src/core/EmailRecovery/index.js.map +1 -1
  307. package/dist/esm/react/sdk/src/core/IndexedDBManager/passkeyClientDB.js +35 -36
  308. package/dist/esm/react/sdk/src/core/IndexedDBManager/passkeyClientDB.js.map +1 -1
  309. package/dist/esm/react/sdk/src/core/NearClient.js +2 -1
  310. package/dist/esm/react/sdk/src/core/NearClient.js.map +1 -1
  311. package/dist/esm/react/sdk/src/core/TatchiPasskey/emailRecovery.js +136 -27
  312. package/dist/esm/react/sdk/src/core/TatchiPasskey/emailRecovery.js.map +1 -1
  313. package/dist/esm/react/sdk/src/core/TatchiPasskey/faucets/createAccountRelayServer.js +2 -1
  314. package/dist/esm/react/sdk/src/core/TatchiPasskey/faucets/createAccountRelayServer.js.map +1 -1
  315. package/dist/esm/react/sdk/src/core/TatchiPasskey/index.js +26 -1
  316. package/dist/esm/react/sdk/src/core/TatchiPasskey/index.js.map +1 -1
  317. package/dist/esm/react/sdk/src/core/TatchiPasskey/linkDevice.js +4 -2
  318. package/dist/esm/react/sdk/src/core/TatchiPasskey/linkDevice.js.map +1 -1
  319. package/dist/esm/react/sdk/src/core/TatchiPasskey/login.js +13 -7
  320. package/dist/esm/react/sdk/src/core/TatchiPasskey/login.js.map +1 -1
  321. package/dist/esm/react/sdk/src/core/TatchiPasskey/recoverAccount.js +2 -1
  322. package/dist/esm/react/sdk/src/core/TatchiPasskey/recoverAccount.js.map +1 -1
  323. package/dist/esm/react/sdk/src/core/TatchiPasskey/scanDevice.js +2 -1
  324. package/dist/esm/react/sdk/src/core/TatchiPasskey/scanDevice.js.map +1 -1
  325. package/dist/esm/react/sdk/src/core/WalletIframe/client/IframeTransport.js +11 -1
  326. package/dist/esm/react/sdk/src/core/WalletIframe/client/IframeTransport.js.map +1 -1
  327. package/dist/esm/react/sdk/src/core/WalletIframe/client/router.js +9 -0
  328. package/dist/esm/react/sdk/src/core/WalletIframe/client/router.js.map +1 -1
  329. package/dist/esm/react/sdk/src/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-drawer.js +1 -1
  330. package/dist/esm/react/sdk/src/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-drawer.js.map +1 -1
  331. package/dist/esm/react/sdk/src/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-modal.js +52 -52
  332. package/dist/esm/react/sdk/src/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-modal.js.map +1 -1
  333. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/getDeviceNumber.js +6 -2
  334. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/checkCanRegisterUser.js +2 -1
  335. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/checkCanRegisterUser.js.map +1 -1
  336. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/decryptPrivateKeyWithPrf.js +2 -1
  337. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/decryptPrivateKeyWithPrf.js.map +1 -1
  338. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/deriveNearKeypairAndEncryptFromSerialized.js +2 -1
  339. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/deriveNearKeypairAndEncryptFromSerialized.js.map +1 -1
  340. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/exportNearKeypairUi.js +2 -1
  341. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/exportNearKeypairUi.js.map +1 -1
  342. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/registerDevice2WithDerivedKey.js +2 -1
  343. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/registerDevice2WithDerivedKey.js.map +1 -1
  344. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/signDelegateAction.js +2 -1
  345. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/signDelegateAction.js.map +1 -1
  346. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/signNep413Message.js +2 -1
  347. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/signNep413Message.js.map +1 -1
  348. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/signTransactionsWithActions.js +2 -1
  349. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/signTransactionsWithActions.js.map +1 -1
  350. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/validation.js +4 -2
  351. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/validation.js.map +1 -1
  352. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/index.js +2 -1
  353. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/index.js.map +1 -1
  354. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/vrf.js +1 -0
  355. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/vrf.js.map +1 -1
  356. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/webauthn.js +8 -2
  357. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/webauthn.js.map +1 -1
  358. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/determineConfirmationConfig.js +2 -1
  359. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/determineConfirmationConfig.js.map +1 -1
  360. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/localOnly.js +2 -1
  361. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/localOnly.js.map +1 -1
  362. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/registration.js +2 -1
  363. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/registration.js.map +1 -1
  364. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/transactions.js +5 -16
  365. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/transactions.js.map +1 -1
  366. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/handlers/deriveVrfKeypairFromPrf.js +2 -1
  367. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/handlers/deriveVrfKeypairFromPrf.js.map +1 -1
  368. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfChallenge.js +2 -1
  369. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfChallenge.js.map +1 -1
  370. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfKeypairBootstrap.js +2 -1
  371. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfKeypairBootstrap.js.map +1 -1
  372. package/dist/esm/react/sdk/src/core/WebAuthnManager/WebAuthnFallbacks/index.js +12 -0
  373. package/dist/esm/react/sdk/src/core/WebAuthnManager/WebAuthnFallbacks/index.js.map +1 -0
  374. package/dist/esm/react/sdk/src/core/WebAuthnManager/WebAuthnFallbacks/safari-fallbacks.js +61 -55
  375. package/dist/esm/react/sdk/src/core/WebAuthnManager/WebAuthnFallbacks/safari-fallbacks.js.map +1 -1
  376. package/dist/esm/react/sdk/src/core/WebAuthnManager/credentialsHelpers.js +8 -3
  377. package/dist/esm/react/sdk/src/core/WebAuthnManager/index.js +8 -3
  378. package/dist/esm/react/sdk/src/core/WebAuthnManager/index.js.map +1 -1
  379. package/dist/esm/react/sdk/src/core/WebAuthnManager/touchIdPrompt.js +207 -204
  380. package/dist/esm/react/sdk/src/core/WebAuthnManager/touchIdPrompt.js.map +1 -1
  381. package/dist/esm/react/sdk/src/core/WebAuthnManager/userHandle.js +2 -1
  382. package/dist/esm/react/sdk/src/core/WebAuthnManager/userHandle.js.map +1 -1
  383. package/dist/esm/react/sdk/src/core/defaultConfigs.js +1 -1
  384. package/dist/esm/react/sdk/src/core/defaultConfigs.js.map +1 -1
  385. package/dist/esm/react/sdk/src/core/types/vrf-worker.js +6 -2
  386. package/dist/esm/react/sdk/src/utils/index.js +10 -4
  387. package/dist/esm/react/styles/styles.css +13 -0
  388. package/dist/esm/sdk/{safari-fallbacks-oQKu9xUs.js → WebAuthnFallbacks-Bl4BTsNt.js} +131 -135
  389. package/dist/esm/sdk/{createAdapters-pNiL2KNq.js → createAdapters-BumKM2ft.js} +59 -54
  390. package/dist/esm/sdk/createAdapters-BumKM2ft.js.map +1 -0
  391. package/dist/esm/sdk/{createAdapters-BWLe9Ddo.js → createAdapters-qVGD6i0g.js} +10 -3
  392. package/dist/esm/sdk/{defaultConfigs-VzvDejmy.js → defaultConfigs-DpslkAQd.js} +1 -1
  393. package/dist/esm/sdk/{getDeviceNumber-CkWRT17I.js → getDeviceNumber-fXizNGQl.js} +2 -2
  394. package/dist/esm/sdk/getDeviceNumber-fXizNGQl.js.map +1 -0
  395. package/dist/esm/sdk/{getDeviceNumber-CfmlgfMX.js → getDeviceNumber-zsOHT_Um.js} +6 -3
  396. package/dist/esm/sdk/{localOnly-DnpSyDaF.js → localOnly-Byi3AK7A.js} +2 -2
  397. package/dist/esm/sdk/{localOnly-DnpSyDaF.js.map → localOnly-Byi3AK7A.js.map} +1 -1
  398. package/dist/esm/sdk/{localOnly-BdumO2st.js → localOnly-pXMTqh1m.js} +5 -4
  399. package/dist/esm/sdk/offline-export-app.js +46 -44
  400. package/dist/esm/sdk/offline-export-app.js.map +1 -1
  401. package/dist/esm/sdk/{overlay-BTqPGG-o.js → overlay-ZGbucXIa.js} +2 -0
  402. package/dist/esm/sdk/{registration-C633u6x8.js → registration-CBiS4Ua_.js} +2 -2
  403. package/dist/esm/sdk/{registration-C633u6x8.js.map → registration-CBiS4Ua_.js.map} +1 -1
  404. package/dist/esm/sdk/{registration-xyYUFRqk.js → registration-DLPLsGCz.js} +5 -4
  405. package/dist/esm/sdk/{requestHelpers-DLBGBHMw.js → requestHelpers-Dh1hEYL9.js} +206 -204
  406. package/dist/esm/sdk/{router-BG6KC_p7.js → router-BLFegW7J.js} +20 -2
  407. package/dist/esm/sdk/{rpcCalls-fLObBbbz.js → rpcCalls-DEv9x5-f.js} +2 -2
  408. package/dist/esm/sdk/{rpcCalls-CAU5XYEF.js → rpcCalls-OhgEeFig.js} +1 -1
  409. package/dist/esm/sdk/{transactions-jH38BZ-Q.js → transactions-BIqKZeR0.js} +6 -18
  410. package/dist/esm/sdk/transactions-BIqKZeR0.js.map +1 -0
  411. package/dist/esm/sdk/{transactions-CzZAt1Yn.js → transactions-Bk-VavcV.js} +10 -21
  412. package/dist/esm/sdk/tx-confirm-ui.js +53 -53
  413. package/dist/esm/sdk/{tx-confirmer-wrapper-CqfVBUaA.js → tx-confirmer-wrapper-lHNgz9i4.js} +53 -53
  414. package/dist/esm/sdk/tx-confirmer.css +6 -4
  415. package/dist/esm/sdk/w3a-tx-confirmer.js +1 -1
  416. package/dist/esm/sdk/wallet-iframe-host.js +271 -89
  417. package/dist/esm/server/email-recovery/emailEncryptor.js +11 -1
  418. package/dist/esm/server/email-recovery/emailEncryptor.js.map +1 -1
  419. package/dist/esm/server/email-recovery/emailParsers.js +55 -1
  420. package/dist/esm/server/email-recovery/emailParsers.js.map +1 -1
  421. package/dist/esm/server/email-recovery/index.js +2 -2
  422. package/dist/esm/server/email-recovery/index.js.map +1 -1
  423. package/dist/esm/server/email-recovery/rpcCalls.js +14 -1
  424. package/dist/esm/server/email-recovery/rpcCalls.js.map +1 -1
  425. package/dist/esm/server/index.js +2 -2
  426. package/dist/esm/server/router/cloudflare.js.map +1 -1
  427. package/dist/esm/server/router/express.js.map +1 -1
  428. package/dist/esm/server/sdk/src/core/defaultConfigs.js +1 -1
  429. package/dist/esm/server/sdk/src/core/defaultConfigs.js.map +1 -1
  430. package/dist/esm/utils/index.js +10 -4
  431. package/dist/esm/wasm_vrf_worker/pkg/wasm_vrf_worker.js +3 -0
  432. package/dist/esm/wasm_vrf_worker/pkg/wasm_vrf_worker_bg.wasm +0 -0
  433. package/dist/types/src/core/EmailRecovery/index.d.ts.map +1 -1
  434. package/dist/types/src/core/IndexedDBManager/passkeyClientDB.d.ts +11 -21
  435. package/dist/types/src/core/IndexedDBManager/passkeyClientDB.d.ts.map +1 -1
  436. package/dist/types/src/core/TatchiPasskey/emailRecovery.d.ts +12 -1
  437. package/dist/types/src/core/TatchiPasskey/emailRecovery.d.ts.map +1 -1
  438. package/dist/types/src/core/TatchiPasskey/index.d.ts +8 -0
  439. package/dist/types/src/core/TatchiPasskey/index.d.ts.map +1 -1
  440. package/dist/types/src/core/WalletIframe/TatchiPasskeyIframe.d.ts +4 -0
  441. package/dist/types/src/core/WalletIframe/TatchiPasskeyIframe.d.ts.map +1 -1
  442. package/dist/types/src/core/WalletIframe/client/IframeTransport.d.ts.map +1 -1
  443. package/dist/types/src/core/WalletIframe/client/router.d.ts +4 -0
  444. package/dist/types/src/core/WalletIframe/client/router.d.ts.map +1 -1
  445. package/dist/types/src/core/WalletIframe/host/wallet-iframe-handlers.d.ts.map +1 -1
  446. package/dist/types/src/core/WalletIframe/shared/messages.d.ts +6 -2
  447. package/dist/types/src/core/WalletIframe/shared/messages.d.ts.map +1 -1
  448. package/dist/types/src/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-drawer.d.ts.map +1 -1
  449. package/dist/types/src/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-modal.d.ts.map +1 -1
  450. package/dist/types/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/vrf.d.ts.map +1 -1
  451. package/dist/types/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/webauthn.d.ts.map +1 -1
  452. package/dist/types/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/transactions.d.ts.map +1 -1
  453. package/dist/types/src/core/WebAuthnManager/index.d.ts.map +1 -1
  454. package/dist/types/src/core/defaultConfigs.d.ts.map +1 -1
  455. package/dist/types/src/react/components/PasskeyAuthMenu/ui/EmailRecoverySlide.d.ts.map +1 -1
  456. package/dist/types/src/react/hooks/usePreconnectWalletAssets.d.ts.map +1 -1
  457. package/dist/types/src/server/email-recovery/emailEncryptor.d.ts +4 -0
  458. package/dist/types/src/server/email-recovery/emailEncryptor.d.ts.map +1 -1
  459. package/dist/types/src/server/email-recovery/emailParsers.d.ts +7 -0
  460. package/dist/types/src/server/email-recovery/emailParsers.d.ts.map +1 -1
  461. package/dist/types/src/server/email-recovery/index.d.ts +1 -1
  462. package/dist/types/src/server/email-recovery/rpcCalls.d.ts +1 -1
  463. package/dist/types/src/server/email-recovery/rpcCalls.d.ts.map +1 -1
  464. package/dist/types/src/wasm_vrf_worker/pkg/wasm_vrf_worker.d.ts.map +1 -1
  465. package/dist/workers/wasm_vrf_worker_bg.wasm +0 -0
  466. package/dist/workers/web3authn-vrf.worker.js +3 -0
  467. package/package.json +1 -1
  468. package/dist/esm/sdk/createAdapters-pNiL2KNq.js.map +0 -1
  469. package/dist/esm/sdk/getDeviceNumber-CkWRT17I.js.map +0 -1
  470. package/dist/esm/sdk/transactions-jH38BZ-Q.js.map +0 -1
@@ -2,7 +2,11 @@ import { __esm, __export } from "../../../../_virtual/rolldown_runtime.js";
2
2
  import { init_validation, validateNearAccountId } from "../../utils/validation.js";
3
3
  import { init_accountIds, toAccountId } from "../types/accountIds.js";
4
4
  import { IndexedDBManager, init_IndexedDBManager } from "../IndexedDBManager/index.js";
5
+ import { createRandomVRFChallenge, init_vrf_worker } from "../types/vrf-worker.js";
5
6
  import { EmailRecoveryPhase, EmailRecoveryStatus, init_sdkSentEvents } from "../types/sdkSentEvents.js";
7
+ import { DEFAULT_WAIT_STATUS, init_rpc } from "../types/rpc.js";
8
+ import { init_getDeviceNumber, parseDeviceNumber } from "../WebAuthnManager/SignerWorkerManager/getDeviceNumber.js";
9
+ import { getLoginSession, init_login } from "./login.js";
6
10
 
7
11
  //#region src/core/TatchiPasskey/emailRecovery.ts
8
12
  var emailRecovery_exports = {};
@@ -44,6 +48,10 @@ var init_emailRecovery = __esm({ "src/core/TatchiPasskey/emailRecovery.ts": (()
44
48
  init_validation();
45
49
  init_accountIds();
46
50
  init_sdkSentEvents();
51
+ init_vrf_worker();
52
+ init_rpc();
53
+ init_getDeviceNumber();
54
+ init_login();
47
55
  EmailRecoveryFlow = class {
48
56
  context;
49
57
  options;
@@ -85,6 +93,12 @@ var init_emailRecovery = __esm({ "src/core/TatchiPasskey/emailRecovery.ts": (()
85
93
  getConfig() {
86
94
  return getEmailRecoveryConfig(this.context.configs);
87
95
  }
96
+ getPendingIndexKey(accountId) {
97
+ return `pendingEmailRecovery:${accountId}`;
98
+ }
99
+ getPendingRecordKey(accountId, nearPublicKey) {
100
+ return `${this.getPendingIndexKey(accountId)}:${nearPublicKey}`;
101
+ }
88
102
  async checkVerificationStatus(rec) {
89
103
  const { dkimVerifierAccountId, verificationViewMethod } = this.getConfig();
90
104
  if (!dkimVerifierAccountId) return null;
@@ -103,22 +117,26 @@ var init_emailRecovery = __esm({ "src/core/TatchiPasskey/emailRecovery.ts": (()
103
117
  return {
104
118
  completed: true,
105
119
  success: false,
106
- errorMessage
120
+ errorMessage,
121
+ transactionHash: result.transaction_hash
107
122
  };
108
123
  }
109
124
  if (result.account_id && result.account_id !== rec.accountId) return {
110
125
  completed: true,
111
126
  success: false,
112
- errorMessage: "Email verification account_id does not match requested account."
127
+ errorMessage: "Email verification account_id does not match requested account.",
128
+ transactionHash: result.transaction_hash
113
129
  };
114
130
  if (result.new_public_key && result.new_public_key !== rec.nearPublicKey) return {
115
131
  completed: true,
116
132
  success: false,
117
- errorMessage: "Email verification new_public_key does not match expected recovery key."
133
+ errorMessage: "Email verification new_public_key does not match expected recovery key.",
134
+ transactionHash: result.transaction_hash
118
135
  };
119
136
  return {
120
137
  completed: true,
121
- success: true
138
+ success: true,
139
+ transactionHash: result.transaction_hash
122
140
  };
123
141
  } catch (err) {
124
142
  console.warn("[EmailRecoveryFlow] get_verification_result view failed; falling back to access key polling", err);
@@ -127,25 +145,37 @@ var init_emailRecovery = __esm({ "src/core/TatchiPasskey/emailRecovery.ts": (()
127
145
  }
128
146
  async loadPending(accountId, nearPublicKey) {
129
147
  const { pendingTtlMs } = this.getConfig();
130
- const keyPrefix = `pendingEmailRecovery:${accountId}`;
131
- const key = nearPublicKey ? `${keyPrefix}:${nearPublicKey}` : keyPrefix;
132
- const record = await IndexedDBManager.clientDB.getAppState(key);
133
- if (!record) return null;
148
+ const indexKey = this.getPendingIndexKey(accountId);
149
+ const indexedNearPublicKey = await IndexedDBManager.clientDB.getAppState(indexKey);
150
+ const resolvedNearPublicKey = nearPublicKey ?? indexedNearPublicKey;
151
+ if (!resolvedNearPublicKey) return null;
152
+ const recordKey = this.getPendingRecordKey(accountId, resolvedNearPublicKey);
153
+ const record = await IndexedDBManager.clientDB.getAppState(recordKey);
154
+ const shouldClearIndex = indexedNearPublicKey === resolvedNearPublicKey;
155
+ if (!record) {
156
+ if (shouldClearIndex) await IndexedDBManager.clientDB.setAppState(indexKey, void 0).catch(() => {});
157
+ return null;
158
+ }
134
159
  if (Date.now() - record.createdAt > pendingTtlMs) {
135
- await IndexedDBManager.clientDB.setAppState(key, void 0);
160
+ await IndexedDBManager.clientDB.setAppState(recordKey, void 0).catch(() => {});
161
+ if (shouldClearIndex) await IndexedDBManager.clientDB.setAppState(indexKey, void 0).catch(() => {});
136
162
  return null;
137
163
  }
164
+ await IndexedDBManager.clientDB.setAppState(indexKey, record.nearPublicKey).catch(() => {});
138
165
  return record;
139
166
  }
140
167
  async savePending(rec) {
141
- const key = `pendingEmailRecovery:${rec.accountId}:${rec.nearPublicKey}`;
168
+ const key = this.getPendingRecordKey(rec.accountId, rec.nearPublicKey);
142
169
  await IndexedDBManager.clientDB.setAppState(key, rec);
170
+ await IndexedDBManager.clientDB.setAppState(this.getPendingIndexKey(rec.accountId), rec.nearPublicKey).catch(() => {});
143
171
  this.pending = rec;
144
172
  }
145
173
  async clearPending(accountId, nearPublicKey) {
146
- const keyPrefix = `pendingEmailRecovery:${accountId}`;
147
- const key = nearPublicKey ? `${keyPrefix}:${nearPublicKey}` : keyPrefix;
148
- await IndexedDBManager.clientDB.setAppState(key, void 0);
174
+ const indexKey = this.getPendingIndexKey(accountId);
175
+ const idx = await IndexedDBManager.clientDB.getAppState(indexKey).catch(() => void 0);
176
+ const resolvedNearPublicKey = nearPublicKey || idx || "";
177
+ if (resolvedNearPublicKey) await IndexedDBManager.clientDB.setAppState(this.getPendingRecordKey(accountId, resolvedNearPublicKey), void 0).catch(() => {});
178
+ if (!nearPublicKey || idx === nearPublicKey) await IndexedDBManager.clientDB.setAppState(indexKey, void 0).catch(() => {});
149
179
  if (this.pending && this.pending.accountId === accountId && (!nearPublicKey || this.pending.nearPublicKey === nearPublicKey)) this.pending = null;
150
180
  }
151
181
  getState() {
@@ -266,7 +296,10 @@ var init_emailRecovery = __esm({ "src/core/TatchiPasskey/emailRecovery.ts": (()
266
296
  message: "Collecting passkey for email recovery..."
267
297
  });
268
298
  try {
269
- const confirmerText = this.options?.confirmerText;
299
+ const confirmerText = {
300
+ title: this.options?.confirmerText?.title ?? "Register New Recovery Account",
301
+ body: this.options?.confirmerText?.body ?? "Create a recovery account and send an encrypted email to recover your account."
302
+ };
270
303
  const confirm = await this.context.webAuthnManager.requestRegistrationCredentialConfirmation({
271
304
  nearAccountId,
272
305
  deviceNumber,
@@ -394,6 +427,22 @@ var init_emailRecovery = __esm({ "src/core/TatchiPasskey/emailRecovery.ts": (()
394
427
  this.pollIntervalResolver = void 0;
395
428
  }
396
429
  }
430
+ /**
431
+ * Best-effort cancellation and local state reset so callers can retry.
432
+ * This does not remove any passkey created in the browser/OS (WebAuthn has no delete API),
433
+ * but it will stop polling and clear the pending IndexedDB record for the given key.
434
+ */
435
+ async cancelAndReset(args) {
436
+ this.stopPolling();
437
+ const normalizedAccountId = (args?.accountId || this.pending?.accountId || "").toString().trim();
438
+ const nearPublicKey = (args?.nearPublicKey || this.pending?.nearPublicKey || "").toString().trim();
439
+ if (normalizedAccountId) try {
440
+ await this.clearPending(toAccountId(normalizedAccountId), nearPublicKey);
441
+ } catch {}
442
+ this.pending = null;
443
+ this.error = void 0;
444
+ this.phase = EmailRecoveryPhase.STEP_1_PREPARATION;
445
+ }
397
446
  async finalize(args) {
398
447
  const { accountId, nearPublicKey } = args;
399
448
  this.cancelled = false;
@@ -468,11 +517,12 @@ var init_emailRecovery = __esm({ "src/core/TatchiPasskey/emailRecovery.ts": (()
468
517
  step: 4,
469
518
  phase: EmailRecoveryPhase.STEP_4_POLLING_VERIFICATION_RESULT,
470
519
  status: EmailRecoveryStatus.PROGRESS,
471
- message: completed && success ? `Recovery email verified for request ${rec.requestId}; finalizing registration...` : `Waiting for recovery email verification for request ${rec.requestId}...`,
520
+ message: completed && success ? `Email verified for request ${rec.requestId}; finalizing registration` : `Waiting for email verification for request ${rec.requestId}`,
472
521
  data: {
473
522
  accountId: rec.accountId,
474
523
  requestId: rec.requestId,
475
524
  nearPublicKey: rec.nearPublicKey,
525
+ transactionHash: verification?.transactionHash,
476
526
  elapsedMs: elapsed,
477
527
  pollCount
478
528
  }
@@ -489,6 +539,7 @@ var init_emailRecovery = __esm({ "src/core/TatchiPasskey/emailRecovery.ts": (()
489
539
  await this.savePending(rec);
490
540
  return;
491
541
  }
542
+ if (this.cancelled) break;
492
543
  await new Promise((resolve) => {
493
544
  this.pollIntervalResolver = resolve;
494
545
  this.pollingTimer = setTimeout(() => {
@@ -539,7 +590,51 @@ var init_emailRecovery = __esm({ "src/core/TatchiPasskey/emailRecovery.ts": (()
539
590
  }
540
591
  const signedTx = registrationResult.signedTransaction;
541
592
  try {
542
- await this.context.nearClient.sendTransaction(signedTx);
593
+ const txResult = await this.context.nearClient.sendTransaction(signedTx, DEFAULT_WAIT_STATUS.linkDeviceRegistration);
594
+ try {
595
+ const txHash = txResult?.transaction?.hash || txResult?.transaction_hash;
596
+ if (txHash) {
597
+ this.emit({
598
+ step: 5,
599
+ phase: EmailRecoveryPhase.STEP_5_FINALIZING_REGISTRATION,
600
+ status: EmailRecoveryStatus.PROGRESS,
601
+ message: "Registration transaction confirmed",
602
+ data: {
603
+ accountId: rec.accountId,
604
+ nearPublicKey: rec.nearPublicKey,
605
+ transactionHash: txHash
606
+ }
607
+ });
608
+ try {
609
+ await IndexedDBManager.clientDB.storeWebAuthnUserData({
610
+ nearAccountId: accountId,
611
+ deviceNumber: rec.deviceNumber,
612
+ clientNearPublicKey: rec.nearPublicKey,
613
+ passkeyCredential: {
614
+ id: rec.credential.id,
615
+ rawId: rec.credential.rawId
616
+ },
617
+ encryptedVrfKeypair: rec.encryptedVrfKeypair,
618
+ serverEncryptedVrfKeypair: rec.serverEncryptedVrfKeypair || void 0
619
+ });
620
+ const { syncAuthenticatorsContractCall } = await import("../rpcCalls.js");
621
+ const authenticators = await syncAuthenticatorsContractCall(this.context.nearClient, this.context.configs.contractId, accountId);
622
+ const mappedAuthenticators = authenticators.map(({ authenticator }) => ({
623
+ credentialId: authenticator.credentialId,
624
+ credentialPublicKey: authenticator.credentialPublicKey,
625
+ transports: authenticator.transports,
626
+ name: authenticator.name,
627
+ registered: authenticator.registered.toISOString(),
628
+ vrfPublicKey: authenticator.vrfPublicKeys?.[0] || "",
629
+ deviceNumber: authenticator.deviceNumber
630
+ }));
631
+ await IndexedDBManager.clientDB.syncAuthenticatorsFromContract(accountId, mappedAuthenticators);
632
+ await IndexedDBManager.clientDB.setLastUser(accountId, rec.deviceNumber);
633
+ } catch (syncErr) {
634
+ console.warn("[EmailRecoveryFlow] Failed to sync authenticators after recovery:", syncErr);
635
+ }
636
+ }
637
+ } catch {}
543
638
  } catch (e) {
544
639
  const msg = String(e?.message || "");
545
640
  const err = this.emitError(5, msg || "Failed to broadcast email recovery registration transaction (insufficient funds or RPC error)");
@@ -613,6 +708,8 @@ var init_emailRecovery = __esm({ "src/core/TatchiPasskey/emailRecovery.ts": (()
613
708
  });
614
709
  const { webAuthnManager } = this.context;
615
710
  const accountId = toAccountId(rec.accountId);
711
+ const deviceNumber = parseDeviceNumber(rec.deviceNumber, { min: 1 });
712
+ if (deviceNumber === null) throw new Error(`Invalid deviceNumber for auto-login: ${String(rec.deviceNumber)}`);
616
713
  if (rec.serverEncryptedVrfKeypair && rec.serverEncryptedVrfKeypair.serverKeyId && this.context.configs.vrfWorkerConfigs?.shamir3pass?.relayServerUrl) try {
617
714
  const unlockResult = await webAuthnManager.shamir3PassDecryptVrfKeypair({
618
715
  nearAccountId: accountId,
@@ -621,8 +718,14 @@ var init_emailRecovery = __esm({ "src/core/TatchiPasskey/emailRecovery.ts": (()
621
718
  serverKeyId: rec.serverEncryptedVrfKeypair.serverKeyId
622
719
  });
623
720
  if (unlockResult.success) {
721
+ const vrfStatus$1 = await webAuthnManager.checkVrfStatus();
722
+ const vrfActiveForAccount$1 = vrfStatus$1.active && vrfStatus$1.nearAccountId && String(vrfStatus$1.nearAccountId) === String(accountId);
723
+ if (!vrfActiveForAccount$1) throw new Error("VRF session inactive after Shamir3Pass unlock");
724
+ await webAuthnManager.setLastUser(accountId, deviceNumber);
624
725
  await webAuthnManager.initializeCurrentUser(accountId, this.context.nearClient);
625
- await webAuthnManager.setLastUser(accountId, rec.deviceNumber);
726
+ try {
727
+ await getLoginSession(this.context, accountId);
728
+ } catch {}
626
729
  this.emit({
627
730
  step: 5,
628
731
  phase: EmailRecoveryPhase.STEP_5_FINALIZING_REGISTRATION,
@@ -635,27 +738,30 @@ var init_emailRecovery = __esm({ "src/core/TatchiPasskey/emailRecovery.ts": (()
635
738
  } catch (err) {
636
739
  console.warn("[EmailRecoveryFlow] Shamir 3-pass unlock failed, falling back to TouchID", err);
637
740
  }
638
- const { txBlockHash, txBlockHeight } = await webAuthnManager.getNonceManager().getNonceBlockHashAndHeight(this.context.nearClient);
639
- const authChallenge = await webAuthnManager.generateVrfChallengeOnce({
640
- userId: accountId,
641
- rpId: webAuthnManager.getRpId(),
642
- blockHash: txBlockHash,
643
- blockHeight: txBlockHeight
644
- });
645
- const authenticators = await webAuthnManager.getAuthenticatorsByUser(accountId);
741
+ const authChallenge = createRandomVRFChallenge();
742
+ const storedCredentialId = String(rec.credential?.rawId || rec.credential?.id || "").trim();
743
+ const credentialIds = storedCredentialId ? [storedCredentialId] : [];
744
+ const authenticators = credentialIds.length > 0 ? [] : await webAuthnManager.getAuthenticatorsByUser(accountId);
646
745
  const authCredential = await webAuthnManager.getAuthenticationCredentialsSerializedDualPrf({
647
746
  nearAccountId: accountId,
648
747
  challenge: authChallenge,
649
- credentialIds: authenticators.map((a) => a.credentialId)
748
+ credentialIds: credentialIds.length > 0 ? credentialIds : authenticators.map((a) => a.credentialId)
650
749
  });
750
+ if (storedCredentialId && authCredential.rawId !== storedCredentialId) throw new Error("Wrong passkey selected during recovery auto-login; please use the newly recovered passkey.");
651
751
  const vrfUnlockResult = await webAuthnManager.unlockVRFKeypair({
652
752
  nearAccountId: accountId,
653
753
  encryptedVrfKeypair: rec.encryptedVrfKeypair,
654
754
  credential: authCredential
655
755
  });
656
756
  if (!vrfUnlockResult.success) throw new Error(vrfUnlockResult.error || "VRF unlock failed during auto-login");
757
+ const vrfStatus = await webAuthnManager.checkVrfStatus();
758
+ const vrfActiveForAccount = vrfStatus.active && vrfStatus.nearAccountId && String(vrfStatus.nearAccountId) === String(accountId);
759
+ if (!vrfActiveForAccount) throw new Error("VRF session inactive after TouchID unlock");
760
+ await webAuthnManager.setLastUser(accountId, deviceNumber);
657
761
  await webAuthnManager.initializeCurrentUser(accountId, this.context.nearClient);
658
- await webAuthnManager.setLastUser(accountId, rec.deviceNumber);
762
+ try {
763
+ await getLoginSession(this.context, accountId);
764
+ } catch {}
659
765
  this.emit({
660
766
  step: 5,
661
767
  phase: EmailRecoveryPhase.STEP_5_FINALIZING_REGISTRATION,
@@ -665,6 +771,9 @@ var init_emailRecovery = __esm({ "src/core/TatchiPasskey/emailRecovery.ts": (()
665
771
  });
666
772
  } catch (err) {
667
773
  console.warn("[EmailRecoveryFlow] Auto-login failed after recovery", err);
774
+ try {
775
+ await this.context.webAuthnManager.clearVrfSession();
776
+ } catch {}
668
777
  this.emit({
669
778
  step: 5,
670
779
  phase: EmailRecoveryPhase.STEP_5_FINALIZING_REGISTRATION,
@@ -1 +1 @@
1
- {"version":3,"file":"emailRecovery.js","names":["e: any","rec: PendingEmailRecovery","err","err: any"],"sources":["../../../../../../../src/core/TatchiPasskey/emailRecovery.ts"],"sourcesContent":["import type { PasskeyManagerContext } from './index';\nimport { IndexedDBManager } from '../IndexedDBManager';\nimport { validateNearAccountId } from '../../utils/validation';\nimport { toAccountId, type AccountId } from '../types/accountIds';\nimport {\n EmailRecoveryPhase,\n EmailRecoveryStatus,\n type EmailRecoverySSEEvent,\n type EventCallback,\n type AfterCall,\n} from '../types/sdkSentEvents';\nimport type { TatchiConfigs } from '../types/tatchi';\nimport { authenticatorsToAllowCredentials } from '../WebAuthnManager/touchIdPrompt';\nimport type {\n EncryptedVRFKeypair,\n ServerEncryptedVrfKeypair,\n VRFChallenge,\n} from '../types/vrf-worker';\nimport type { WebAuthnRegistrationCredential } from '../types';\nimport type { ConfirmationConfig } from '../types/signer-worker';\n\nexport type PendingEmailRecoveryStatus =\n | 'awaiting-email'\n | 'awaiting-add-key'\n | 'finalizing'\n | 'complete'\n | 'error';\n\nexport type PendingEmailRecovery = {\n accountId: AccountId;\n recoveryEmail: string;\n deviceNumber: number;\n nearPublicKey: string;\n requestId: string;\n encryptedVrfKeypair: EncryptedVRFKeypair;\n serverEncryptedVrfKeypair: ServerEncryptedVrfKeypair | null;\n vrfPublicKey: string;\n credential: WebAuthnRegistrationCredential;\n vrfChallenge?: VRFChallenge;\n createdAt: number;\n status: PendingEmailRecoveryStatus;\n};\n\nexport interface EmailRecoveryFlowOptions {\n onEvent?: EventCallback<EmailRecoverySSEEvent>;\n onError?: (error: Error) => void;\n afterCall?: AfterCall<void>;\n /**\n * Preferred grouping for per-call confirmer copy.\n */\n confirmerText?: { title?: string; body?: string };\n // Per-call confirmation configuration (non-persistent)\n confirmationConfig?: Partial<ConfirmationConfig>;\n}\n\nfunction getEmailRecoveryConfig(configs: TatchiConfigs): {\n minBalanceYocto: string;\n pollingIntervalMs: number;\n maxPollingDurationMs: number;\n pendingTtlMs: number;\n mailtoAddress: string;\n dkimVerifierAccountId: string;\n verificationViewMethod: string;\n} {\n const relayerEmailCfg = configs.relayer.emailRecovery;\n const minBalanceYocto = String(relayerEmailCfg.minBalanceYocto);\n const pollingIntervalMs = Number(relayerEmailCfg.pollingIntervalMs);\n const maxPollingDurationMs = Number(relayerEmailCfg.maxPollingDurationMs);\n const pendingTtlMs = Number(relayerEmailCfg.pendingTtlMs);\n const mailtoAddress = String(relayerEmailCfg.mailtoAddress);\n const dkimVerifierAccountId = String(relayerEmailCfg.dkimVerifierAccountId);\n const verificationViewMethod = String(relayerEmailCfg.verificationViewMethod);\n return {\n minBalanceYocto,\n pollingIntervalMs,\n maxPollingDurationMs,\n pendingTtlMs,\n mailtoAddress,\n dkimVerifierAccountId,\n verificationViewMethod,\n };\n}\n\nexport function generateEmailRecoveryRequestId(): string {\n // 6-character A–Z0–9 identifier, suitable for short-lived correlation.\n const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';\n const length = 6;\n const bytes = new Uint8Array(length);\n (globalThis.crypto || window.crypto).getRandomValues(bytes);\n let out = '';\n for (let i = 0; i < length; i++) {\n out += alphabet[bytes[i] % alphabet.length];\n }\n return out;\n}\n\nexport class EmailRecoveryFlow {\n private context: PasskeyManagerContext;\n private options?: EmailRecoveryFlowOptions;\n private pending: PendingEmailRecovery | null = null;\n private phase: EmailRecoveryPhase = EmailRecoveryPhase.STEP_1_PREPARATION;\n private pollingTimer: any;\n private pollIntervalResolver?: (value?: void | PromiseLike<void>) => void;\n private pollingStartedAt: number | null = null;\n private cancelled = false;\n private error?: Error;\n\n constructor(context: PasskeyManagerContext, options?: EmailRecoveryFlowOptions) {\n this.context = context;\n this.options = options;\n }\n\n setOptions(options?: EmailRecoveryFlowOptions) {\n if (!options) return;\n this.options = { ...(this.options || {}), ...options };\n }\n private emit(event: EmailRecoverySSEEvent) {\n this.options?.onEvent?.(event);\n }\n\n private emitError(step: number, message: string): Error {\n const err = new Error(message);\n this.phase = EmailRecoveryPhase.ERROR;\n this.error = err;\n this.emit({\n step,\n phase: EmailRecoveryPhase.ERROR,\n status: EmailRecoveryStatus.ERROR,\n message,\n error: message,\n } as EmailRecoverySSEEvent & { error: string });\n this.options?.onError?.(err);\n return err;\n }\n\n private getConfig() {\n return getEmailRecoveryConfig(this.context.configs);\n }\n\n private async checkVerificationStatus(\n rec: PendingEmailRecovery\n ): Promise<{ completed: boolean; success: boolean; errorMessage?: string } | null> {\n const { dkimVerifierAccountId, verificationViewMethod } = this.getConfig();\n if (!dkimVerifierAccountId) return null;\n\n try {\n type VerificationResult = {\n verified: boolean;\n account_id?: string;\n new_public_key?: string;\n error_code?: string;\n error_message?: string;\n };\n\n const result = await this.context.nearClient.view<\n { request_id: string },\n VerificationResult | null\n >({\n account: dkimVerifierAccountId,\n method: verificationViewMethod,\n args: { request_id: rec.requestId },\n });\n\n if (!result) {\n return { completed: false, success: false };\n }\n\n if (!result.verified) {\n const errorMessage = result.error_message || result.error_code || 'Email verification failed on relayer/contract';\n return { completed: true, success: false, errorMessage };\n }\n\n // Optional safety checks: ensure the bound account/key match expectations when available.\n if (result.account_id && result.account_id !== rec.accountId) {\n return {\n completed: true,\n success: false,\n errorMessage: 'Email verification account_id does not match requested account.',\n };\n }\n if (result.new_public_key && result.new_public_key !== rec.nearPublicKey) {\n return {\n completed: true,\n success: false,\n errorMessage: 'Email verification new_public_key does not match expected recovery key.',\n };\n }\n\n return { completed: true, success: true };\n } catch (err) {\n // If the view method is not available or fails, fall back to access key polling.\n // eslint-disable-next-line no-console\n console.warn('[EmailRecoveryFlow] get_verification_result view failed; falling back to access key polling', err);\n return null;\n }\n }\n\n private async loadPending(\n accountId: AccountId,\n nearPublicKey?: string\n ): Promise<PendingEmailRecovery | null> {\n const { pendingTtlMs } = this.getConfig();\n const keyPrefix = `pendingEmailRecovery:${accountId}`;\n const key = nearPublicKey ? `${keyPrefix}:${nearPublicKey}` : keyPrefix;\n const record = await IndexedDBManager.clientDB.getAppState<PendingEmailRecovery | null>(key);\n if (!record) return null;\n if (Date.now() - record.createdAt > pendingTtlMs) {\n await IndexedDBManager.clientDB.setAppState(key, undefined as any);\n return null;\n }\n return record;\n }\n\n private async savePending(rec: PendingEmailRecovery): Promise<void> {\n const key = `pendingEmailRecovery:${rec.accountId}:${rec.nearPublicKey}`;\n await IndexedDBManager.clientDB.setAppState(key, rec);\n this.pending = rec;\n }\n\n private async clearPending(accountId: AccountId, nearPublicKey?: string): Promise<void> {\n const keyPrefix = `pendingEmailRecovery:${accountId}`;\n const key = nearPublicKey ? `${keyPrefix}:${nearPublicKey}` : keyPrefix;\n await IndexedDBManager.clientDB.setAppState(key, undefined as any);\n if (this.pending && this.pending.accountId === accountId && (!nearPublicKey || this.pending.nearPublicKey === nearPublicKey)) {\n this.pending = null;\n }\n }\n\n getState() {\n return {\n phase: this.phase,\n pending: this.pending,\n error: this.error,\n };\n }\n\n async buildMailtoUrl(args: { accountId: string; nearPublicKey?: string }): Promise<string> {\n const { accountId, nearPublicKey } = args;\n this.cancelled = false;\n this.error = undefined;\n\n const validation = validateNearAccountId(accountId as AccountId);\n if (!validation.valid) {\n const err = this.emitError(3, `Invalid NEAR account ID: ${validation.error}`);\n await this.options?.afterCall?.(false);\n throw err;\n }\n\n const nearAccountId = toAccountId(accountId as string);\n let rec = this.pending;\n if (!rec || rec.accountId !== nearAccountId || (nearPublicKey && rec.nearPublicKey !== nearPublicKey)) {\n rec = await this.loadPending(nearAccountId, nearPublicKey);\n this.pending = rec;\n }\n\n if (!rec) {\n const err = this.emitError(3, 'No pending email recovery record found for this account');\n await this.options?.afterCall?.(false);\n throw err;\n }\n\n if (rec.status === 'error') {\n const err = this.emitError(3, 'Pending email recovery is in an error state; please restart the flow');\n await this.options?.afterCall?.(false);\n throw err;\n }\n\n if (rec.status === 'finalizing' || rec.status === 'complete') {\n const err = this.emitError(3, 'Recovery email has already been processed on-chain for this request');\n await this.options?.afterCall?.(false);\n throw err;\n }\n\n const mailtoUrl =\n rec.status === 'awaiting-email'\n ? await this.buildMailtoUrlAndUpdateStatus(rec)\n : this.buildMailtoUrlInternal(rec);\n this.phase = EmailRecoveryPhase.STEP_3_AWAIT_EMAIL;\n this.emit({\n step: 3,\n phase: EmailRecoveryPhase.STEP_3_AWAIT_EMAIL,\n status: EmailRecoveryStatus.PROGRESS,\n message: 'New device key created; please send the recovery email from your registered address.',\n data: {\n accountId: rec.accountId,\n recoveryEmail: rec.recoveryEmail,\n nearPublicKey: rec.nearPublicKey,\n requestId: rec.requestId,\n mailtoUrl,\n },\n } as EmailRecoverySSEEvent & { data: Record<string, unknown> });\n await this.options?.afterCall?.(true, undefined as any);\n return mailtoUrl;\n }\n\n async start(args: { accountId: string; recoveryEmail: string }): Promise<{ mailtoUrl: string; nearPublicKey: string }> {\n const { accountId, recoveryEmail } = args;\n this.cancelled = false;\n this.error = undefined;\n this.phase = EmailRecoveryPhase.STEP_1_PREPARATION;\n\n this.emit({\n step: 1,\n phase: EmailRecoveryPhase.STEP_1_PREPARATION,\n status: EmailRecoveryStatus.PROGRESS,\n message: 'Preparing email recovery...',\n });\n\n const validation = validateNearAccountId(accountId as AccountId);\n if (!validation.valid) {\n const err = this.emitError(1, `Invalid NEAR account ID: ${validation.error}`);\n await this.options?.afterCall?.(false);\n throw err;\n }\n\n const nearAccountId = toAccountId(accountId as string);\n const { minBalanceYocto } = this.getConfig();\n const STORAGE_PRICE_PER_BYTE = BigInt('10000000000000000000'); // 1e19 yocto NEAR per byte\n\n try {\n const accountView = await this.context.nearClient.viewAccount(nearAccountId);\n const amount = BigInt(accountView.amount || '0');\n const locked = BigInt((accountView as any).locked || '0');\n const storageUsage = BigInt((accountView as any).storage_usage || 0);\n const storageCost = storageUsage * STORAGE_PRICE_PER_BYTE;\n const rawAvailable = amount - locked - storageCost;\n const available = rawAvailable > 0 ? rawAvailable : BigInt(0);\n if (available < BigInt(minBalanceYocto)) {\n const err = this.emitError(\n 1,\n `This account does not have enough NEAR to finalize recovery. Available: ${available.toString()} yocto; required: ${String(minBalanceYocto)}. Please top up and try again.`\n );\n await this.options?.afterCall?.(false);\n throw err;\n }\n } catch (e: any) {\n const err = this.emitError(1, e?.message || 'Failed to fetch account balance for recovery');\n await this.options?.afterCall?.(false);\n throw err;\n }\n\n const canonicalEmail = String(recoveryEmail || '').trim().toLowerCase();\n if (!canonicalEmail) {\n const err = this.emitError(1, 'Recovery email is required for email-based account recovery');\n await this.options?.afterCall?.(false);\n throw err;\n }\n\n // Determine deviceNumber from on-chain authenticators\n let deviceNumber = 1;\n try {\n const { syncAuthenticatorsContractCall } = await import('../rpcCalls');\n const authenticators = await syncAuthenticatorsContractCall(\n this.context.nearClient,\n this.context.configs.contractId,\n nearAccountId\n );\n const numbers = authenticators\n .map((a: any) => a?.authenticator?.deviceNumber)\n .filter((n: any) => typeof n === 'number' && Number.isFinite(n)) as number[];\n const max = numbers.length > 0 ? Math.max(...numbers) : 0;\n deviceNumber = max + 1;\n } catch {\n deviceNumber = 1;\n }\n\n this.phase = EmailRecoveryPhase.STEP_2_TOUCH_ID_REGISTRATION;\n this.emit({\n step: 2,\n phase: EmailRecoveryPhase.STEP_2_TOUCH_ID_REGISTRATION,\n status: EmailRecoveryStatus.PROGRESS,\n message: 'Collecting passkey for email recovery...',\n });\n\n try {\n const confirmerText = this.options?.confirmerText;\n const confirm = await this.context.webAuthnManager.requestRegistrationCredentialConfirmation({\n nearAccountId,\n deviceNumber,\n confirmerText,\n confirmationConfigOverride: this.options?.confirmationConfig,\n });\n if (!confirm.confirmed || !confirm.credential) {\n const err = this.emitError(2, 'User cancelled email recovery TouchID confirmation');\n await this.options?.afterCall?.(false);\n throw err;\n }\n\n const vrfDerivationResult = await this.context.webAuthnManager.deriveVrfKeypair({\n credential: confirm.credential,\n nearAccountId,\n });\n\n if (!vrfDerivationResult.success || !vrfDerivationResult.encryptedVrfKeypair) {\n const err = this.emitError(2, 'Failed to derive VRF keypair from PRF for email recovery');\n await this.options?.afterCall?.(false);\n throw err;\n }\n\n const nearKeyResult = await this.context.webAuthnManager.deriveNearKeypairAndEncryptFromSerialized({\n nearAccountId,\n credential: confirm.credential,\n options: { deviceNumber },\n });\n\n if (!nearKeyResult.success || !nearKeyResult.publicKey) {\n const err = this.emitError(2, 'Failed to derive NEAR keypair for email recovery');\n await this.options?.afterCall?.(false);\n throw err;\n }\n\n const rec: PendingEmailRecovery = {\n accountId: nearAccountId,\n recoveryEmail: canonicalEmail,\n deviceNumber,\n nearPublicKey: nearKeyResult.publicKey,\n requestId: generateEmailRecoveryRequestId(),\n encryptedVrfKeypair: vrfDerivationResult.encryptedVrfKeypair,\n serverEncryptedVrfKeypair: vrfDerivationResult.serverEncryptedVrfKeypair || null,\n vrfPublicKey: vrfDerivationResult.vrfPublicKey,\n credential: confirm.credential,\n vrfChallenge: confirm.vrfChallenge || undefined,\n createdAt: Date.now(),\n status: 'awaiting-email',\n };\n\n const mailtoUrl = await this.buildMailtoUrlAndUpdateStatus(rec);\n\n this.phase = EmailRecoveryPhase.STEP_3_AWAIT_EMAIL;\n this.emit({\n step: 3,\n phase: EmailRecoveryPhase.STEP_3_AWAIT_EMAIL,\n status: EmailRecoveryStatus.PROGRESS,\n message: 'New device key created; please send the recovery email from your registered address.',\n data: {\n accountId: rec.accountId,\n recoveryEmail: rec.recoveryEmail,\n nearPublicKey: rec.nearPublicKey,\n requestId: rec.requestId,\n mailtoUrl,\n },\n } as EmailRecoverySSEEvent & { data: Record<string, unknown> });\n\n await this.options?.afterCall?.(true, undefined as any);\n\n return { mailtoUrl, nearPublicKey: rec.nearPublicKey };\n } catch (e: any) {\n const err = this.emitError(2, e?.message || 'Email recovery TouchID/derivation failed');\n await this.options?.afterCall?.(false);\n throw err;\n }\n }\n\n private buildMailtoUrlInternal(rec: PendingEmailRecovery): string {\n const { mailtoAddress } = this.getConfig();\n const to = encodeURIComponent(mailtoAddress);\n const subject = encodeURIComponent(`recover-${rec.requestId} ${rec.accountId} ${rec.nearPublicKey}`);\n const body = encodeURIComponent(`Recovering account ${rec.accountId} with a new passkey.`);\n return `mailto:${to}?subject=${subject}&body=${body}`;\n }\n\n private async buildMailtoUrlAndUpdateStatus(rec: PendingEmailRecovery): Promise<string> {\n rec.status = 'awaiting-add-key';\n await this.savePending(rec);\n return this.buildMailtoUrlInternal(rec);\n }\n\n async startPolling(args: { accountId: string; nearPublicKey?: string }): Promise<void> {\n const { accountId, nearPublicKey } = args;\n this.cancelled = false;\n this.error = undefined;\n\n const validation = validateNearAccountId(accountId as AccountId);\n if (!validation.valid) {\n const err = this.emitError(4, `Invalid NEAR account ID: ${validation.error}`);\n await this.options?.afterCall?.(false);\n throw err;\n }\n const nearAccountId = toAccountId(accountId as string);\n\n let rec = this.pending;\n if (!rec || rec.accountId !== nearAccountId || (nearPublicKey && rec.nearPublicKey !== nearPublicKey)) {\n rec = await this.loadPending(nearAccountId, nearPublicKey);\n this.pending = rec;\n }\n if (!rec) {\n const err = this.emitError(4, 'No pending email recovery record found for this account');\n await this.options?.afterCall?.(false);\n throw err;\n }\n if (rec.status === 'error') {\n const err = this.emitError(4, 'Pending email recovery is in an error state; please restart the flow');\n await this.options?.afterCall?.(false);\n throw err;\n }\n if (rec.status === 'complete' || rec.status === 'finalizing') {\n await this.options?.afterCall?.(true, undefined as any);\n return;\n }\n if (rec.status === 'awaiting-email') {\n await this.buildMailtoUrlAndUpdateStatus(rec);\n }\n\n await this.pollUntilAddKey(rec);\n await this.options?.afterCall?.(true, undefined as any);\n }\n\n stopPolling(): void {\n this.cancelled = true;\n if (this.pollingTimer) {\n clearTimeout(this.pollingTimer);\n this.pollingTimer = undefined;\n }\n if (this.pollIntervalResolver) {\n this.pollIntervalResolver();\n this.pollIntervalResolver = undefined;\n }\n }\n\n async finalize(args: { accountId: string; nearPublicKey?: string }): Promise<void> {\n const { accountId, nearPublicKey } = args;\n this.cancelled = false;\n this.error = undefined;\n\n const validation = validateNearAccountId(accountId as AccountId);\n if (!validation.valid) {\n const err = this.emitError(4, `Invalid NEAR account ID: ${validation.error}`);\n await this.options?.afterCall?.(false);\n throw err;\n }\n const nearAccountId = toAccountId(accountId as string);\n\n let rec = this.pending;\n if (!rec || rec.accountId !== nearAccountId || (nearPublicKey && rec.nearPublicKey !== nearPublicKey)) {\n rec = await this.loadPending(nearAccountId, nearPublicKey);\n this.pending = rec;\n }\n if (!rec) {\n const err = this.emitError(4, 'No pending email recovery record found for this account');\n await this.options?.afterCall?.(false);\n throw err;\n }\n\n this.emit({\n step: 0,\n phase: EmailRecoveryPhase.RESUMED_FROM_PENDING,\n status: EmailRecoveryStatus.PROGRESS,\n message: 'Resuming email recovery from pending state...',\n data: {\n accountId: rec.accountId,\n nearPublicKey: rec.nearPublicKey,\n status: rec.status,\n },\n } as EmailRecoverySSEEvent & { data: Record<string, unknown> });\n\n if (rec.status === 'complete') {\n this.phase = EmailRecoveryPhase.STEP_6_COMPLETE;\n this.emit({\n step: 6,\n phase: EmailRecoveryPhase.STEP_6_COMPLETE,\n status: EmailRecoveryStatus.SUCCESS,\n message: 'Email recovery already completed for this key.',\n });\n await this.options?.afterCall?.(true, undefined as any);\n return;\n }\n\n // Ensure verification has completed successfully before finalizing registration.\n await this.pollUntilAddKey(rec);\n await this.finalizeRegistration(rec);\n await this.options?.afterCall?.(true, undefined as any);\n }\n\n private async pollUntilAddKey(rec: PendingEmailRecovery): Promise<void> {\n const { pollingIntervalMs, maxPollingDurationMs, dkimVerifierAccountId } = this.getConfig();\n if (!dkimVerifierAccountId) {\n const err = this.emitError(4, 'Email recovery verification contract (dkimVerifierAccountId) is not configured');\n await this.options?.afterCall?.(false);\n throw err;\n }\n this.phase = EmailRecoveryPhase.STEP_4_POLLING_VERIFICATION_RESULT;\n this.pollingStartedAt = Date.now();\n let pollCount = 0;\n\n while (!this.cancelled) {\n pollCount += 1;\n const elapsed = Date.now() - (this.pollingStartedAt || 0);\n if (elapsed > maxPollingDurationMs) {\n const err = this.emitError(4, 'Timed out waiting for recovery email to be processed on-chain');\n rec.status = 'error';\n await this.savePending(rec);\n await this.options?.afterCall?.(false);\n throw err;\n }\n\n const verification = await this.checkVerificationStatus(rec);\n const completed = verification?.completed === true;\n const success = verification?.success === true;\n\n this.emit({\n step: 4,\n phase: EmailRecoveryPhase.STEP_4_POLLING_VERIFICATION_RESULT,\n status: EmailRecoveryStatus.PROGRESS,\n message: completed && success\n ? `Recovery email verified for request ${rec.requestId}; finalizing registration...`\n : `Waiting for recovery email verification for request ${rec.requestId}...`,\n data: {\n accountId: rec.accountId,\n requestId: rec.requestId,\n nearPublicKey: rec.nearPublicKey,\n elapsedMs: elapsed,\n pollCount,\n },\n } as EmailRecoverySSEEvent & { data: Record<string, unknown> });\n\n if (completed) {\n if (!success) {\n const err = this.emitError(4, verification?.errorMessage || 'Email verification failed');\n rec.status = 'error';\n await this.savePending(rec);\n await this.options?.afterCall?.(false);\n throw err;\n }\n\n rec.status = 'finalizing';\n await this.savePending(rec);\n return;\n }\n\n await new Promise<void>(resolve => {\n this.pollIntervalResolver = resolve;\n this.pollingTimer = setTimeout(() => {\n this.pollIntervalResolver = undefined;\n this.pollingTimer = undefined;\n resolve();\n }, pollingIntervalMs);\n }).finally(() => {\n this.pollIntervalResolver = undefined;\n });\n }\n\n const err = this.emitError(4, 'Email recovery polling was cancelled');\n await this.options?.afterCall?.(false);\n throw err;\n }\n\n private async finalizeRegistration(rec: PendingEmailRecovery): Promise<void> {\n this.phase = EmailRecoveryPhase.STEP_5_FINALIZING_REGISTRATION;\n this.emit({\n step: 5,\n phase: EmailRecoveryPhase.STEP_5_FINALIZING_REGISTRATION,\n status: EmailRecoveryStatus.PROGRESS,\n message: 'Finalizing email recovery registration...',\n data: {\n accountId: rec.accountId,\n nearPublicKey: rec.nearPublicKey,\n },\n } as EmailRecoverySSEEvent & { data: Record<string, unknown> });\n\n const nonceManager = this.context.webAuthnManager.getNonceManager();\n const accountId = toAccountId(rec.accountId);\n nonceManager.initializeUser(accountId, rec.nearPublicKey);\n\n try {\n if (!rec.vrfChallenge) {\n const err = this.emitError(5, 'Missing VRF challenge for email recovery registration');\n await this.options?.afterCall?.(false);\n throw err;\n }\n\n const registrationResult = await this.context.webAuthnManager.signDevice2RegistrationWithStoredKey({\n nearAccountId: accountId,\n credential: rec.credential,\n vrfChallenge: rec.vrfChallenge,\n deterministicVrfPublicKey: rec.vrfPublicKey,\n deviceNumber: rec.deviceNumber,\n });\n\n if (!registrationResult.success || !registrationResult.signedTransaction) {\n const err = this.emitError(5, registrationResult.error || 'Failed to sign email recovery registration transaction');\n await this.options?.afterCall?.(false);\n throw err;\n }\n\n const signedTx = registrationResult.signedTransaction;\n\n try {\n await this.context.nearClient.sendTransaction(signedTx);\n } catch (e: any) {\n const msg = String(e?.message || '');\n const err = this.emitError(\n 5,\n msg || 'Failed to broadcast email recovery registration transaction (insufficient funds or RPC error)'\n );\n await this.options?.afterCall?.(false);\n throw err;\n }\n\n try {\n const txNonce = (signedTx.transaction as any)?.nonce;\n if (txNonce != null) {\n await nonceManager.updateNonceFromBlockchain(\n this.context.nearClient,\n String(txNonce)\n );\n }\n } catch {\n // best-effort; do not fail flow\n }\n\n const { webAuthnManager } = this.context;\n\n await webAuthnManager.storeUserData({\n nearAccountId: accountId,\n deviceNumber: rec.deviceNumber,\n clientNearPublicKey: rec.nearPublicKey,\n lastUpdated: Date.now(),\n passkeyCredential: {\n id: rec.credential.id,\n rawId: rec.credential.rawId,\n },\n encryptedVrfKeypair: {\n encryptedVrfDataB64u: rec.encryptedVrfKeypair.encryptedVrfDataB64u,\n chacha20NonceB64u: rec.encryptedVrfKeypair.chacha20NonceB64u,\n },\n serverEncryptedVrfKeypair: rec.serverEncryptedVrfKeypair || undefined,\n } as any);\n\n try {\n const attestationB64u = rec.credential.response.attestationObject;\n const credentialPublicKey = await webAuthnManager.extractCosePublicKey(attestationB64u);\n await webAuthnManager.storeAuthenticator({\n nearAccountId: accountId,\n deviceNumber: rec.deviceNumber,\n credentialId: rec.credential.rawId,\n credentialPublicKey,\n transports: ['internal'],\n name: `Device ${rec.deviceNumber} Passkey for ${rec.accountId.split('.')[0]}`,\n registered: new Date().toISOString(),\n syncedAt: new Date().toISOString(),\n vrfPublicKey: rec.vrfPublicKey,\n });\n } catch {\n // best-effort; do not fail flow\n }\n\n await this.attemptAutoLogin(rec);\n\n rec.status = 'complete';\n await this.savePending(rec);\n await this.clearPending(rec.accountId, rec.nearPublicKey);\n\n this.phase = EmailRecoveryPhase.STEP_6_COMPLETE;\n this.emit({\n step: 6,\n phase: EmailRecoveryPhase.STEP_6_COMPLETE,\n status: EmailRecoveryStatus.SUCCESS,\n message: 'Email recovery completed successfully',\n data: {\n accountId: rec.accountId,\n nearPublicKey: rec.nearPublicKey,\n },\n } as EmailRecoverySSEEvent & { data: Record<string, unknown> });\n } catch (e: any) {\n const err = this.emitError(5, e?.message || 'Email recovery finalization failed');\n await this.options?.afterCall?.(false);\n throw err;\n }\n }\n\n private async attemptAutoLogin(rec: PendingEmailRecovery): Promise<void> {\n try {\n this.emit({\n step: 5,\n phase: EmailRecoveryPhase.STEP_5_FINALIZING_REGISTRATION,\n status: EmailRecoveryStatus.PROGRESS,\n message: 'Attempting auto-login with recovered device...',\n data: { autoLogin: 'progress' },\n } as EmailRecoverySSEEvent & { data: Record<string, unknown> });\n\n const { webAuthnManager } = this.context;\n const accountId = toAccountId(rec.accountId);\n\n // Try Shamir 3-pass unlock first if configured and available\n if (\n rec.serverEncryptedVrfKeypair &&\n rec.serverEncryptedVrfKeypair.serverKeyId &&\n this.context.configs.vrfWorkerConfigs?.shamir3pass?.relayServerUrl\n ) {\n try {\n const unlockResult = await webAuthnManager.shamir3PassDecryptVrfKeypair({\n nearAccountId: accountId,\n kek_s_b64u: rec.serverEncryptedVrfKeypair.kek_s_b64u,\n ciphertextVrfB64u: rec.serverEncryptedVrfKeypair.ciphertextVrfB64u,\n serverKeyId: rec.serverEncryptedVrfKeypair.serverKeyId,\n });\n\n if (unlockResult.success) {\n await webAuthnManager.initializeCurrentUser(accountId, this.context.nearClient);\n await webAuthnManager.setLastUser(accountId, rec.deviceNumber);\n this.emit({\n step: 5,\n phase: EmailRecoveryPhase.STEP_5_FINALIZING_REGISTRATION,\n status: EmailRecoveryStatus.SUCCESS,\n message: `Welcome ${accountId}`,\n data: { autoLogin: 'success' },\n } as EmailRecoverySSEEvent & { data: Record<string, unknown> });\n return;\n }\n } catch (err) {\n // fall through to TouchID unlock\n console.warn('[EmailRecoveryFlow] Shamir 3-pass unlock failed, falling back to TouchID', err);\n }\n }\n\n // TouchID fallback unlock\n const { txBlockHash, txBlockHeight } = await webAuthnManager\n .getNonceManager()\n .getNonceBlockHashAndHeight(this.context.nearClient);\n\n const authChallenge = await webAuthnManager.generateVrfChallengeOnce({\n userId: accountId,\n rpId: webAuthnManager.getRpId(),\n blockHash: txBlockHash,\n blockHeight: txBlockHeight,\n });\n\n const authenticators = await webAuthnManager.getAuthenticatorsByUser(accountId);\n const authCredential = await webAuthnManager.getAuthenticationCredentialsSerializedDualPrf({\n nearAccountId: accountId,\n challenge: authChallenge,\n credentialIds: authenticators.map((a) => a.credentialId),\n });\n\n const vrfUnlockResult = await webAuthnManager.unlockVRFKeypair({\n nearAccountId: accountId,\n encryptedVrfKeypair: rec.encryptedVrfKeypair,\n credential: authCredential,\n });\n\n if (!vrfUnlockResult.success) {\n throw new Error(vrfUnlockResult.error || 'VRF unlock failed during auto-login');\n }\n\n await webAuthnManager.initializeCurrentUser(accountId, this.context.nearClient);\n await webAuthnManager.setLastUser(accountId, rec.deviceNumber);\n\n this.emit({\n step: 5,\n phase: EmailRecoveryPhase.STEP_5_FINALIZING_REGISTRATION,\n status: EmailRecoveryStatus.SUCCESS,\n message: `Welcome ${accountId}`,\n data: { autoLogin: 'success' },\n } as EmailRecoverySSEEvent & { data: Record<string, unknown> });\n } catch (err: any) {\n console.warn('[EmailRecoveryFlow] Auto-login failed after recovery', err);\n this.emit({\n step: 5,\n phase: EmailRecoveryPhase.STEP_5_FINALIZING_REGISTRATION,\n status: EmailRecoveryStatus.ERROR,\n message: 'Auto-login failed; please log in manually on this device.',\n data: { error: err?.message || String(err), autoLogin: 'error' },\n } as EmailRecoverySSEEvent & { data: Record<string, unknown> });\n }\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"emailRecovery.js","names":["e: any","rec: PendingEmailRecovery","err","vrfStatus","vrfActiveForAccount","err: any"],"sources":["../../../../../../../src/core/TatchiPasskey/emailRecovery.ts"],"sourcesContent":["import type { PasskeyManagerContext } from './index';\nimport { IndexedDBManager } from '../IndexedDBManager';\nimport { validateNearAccountId } from '../../utils/validation';\nimport { toAccountId, type AccountId } from '../types/accountIds';\nimport {\n EmailRecoveryPhase,\n EmailRecoveryStatus,\n type EmailRecoverySSEEvent,\n type EventCallback,\n type AfterCall,\n} from '../types/sdkSentEvents';\nimport type { TatchiConfigs } from '../types/tatchi';\nimport { authenticatorsToAllowCredentials } from '../WebAuthnManager/touchIdPrompt';\nimport {\n createRandomVRFChallenge,\n type EncryptedVRFKeypair,\n type ServerEncryptedVrfKeypair,\n type VRFChallenge,\n} from '../types/vrf-worker';\nimport type { WebAuthnRegistrationCredential } from '../types';\nimport type { ConfirmationConfig } from '../types/signer-worker';\nimport { DEFAULT_WAIT_STATUS } from '../types/rpc';\nimport { parseDeviceNumber } from '../WebAuthnManager/SignerWorkerManager/getDeviceNumber';\nimport { getLoginSession } from './login';\n\nexport type PendingEmailRecoveryStatus =\n | 'awaiting-email'\n | 'awaiting-add-key'\n | 'finalizing'\n | 'complete'\n | 'error';\n\nexport type PendingEmailRecovery = {\n accountId: AccountId;\n recoveryEmail: string;\n deviceNumber: number;\n nearPublicKey: string;\n requestId: string;\n encryptedVrfKeypair: EncryptedVRFKeypair;\n serverEncryptedVrfKeypair: ServerEncryptedVrfKeypair | null;\n vrfPublicKey: string;\n credential: WebAuthnRegistrationCredential;\n vrfChallenge?: VRFChallenge;\n createdAt: number;\n status: PendingEmailRecoveryStatus;\n};\n\nexport interface EmailRecoveryFlowOptions {\n onEvent?: EventCallback<EmailRecoverySSEEvent>;\n onError?: (error: Error) => void;\n afterCall?: AfterCall<void>;\n /**\n * Preferred grouping for per-call confirmer copy.\n */\n confirmerText?: { title?: string; body?: string };\n // Per-call confirmation configuration (non-persistent)\n confirmationConfig?: Partial<ConfirmationConfig>;\n}\n\nfunction getEmailRecoveryConfig(configs: TatchiConfigs): {\n minBalanceYocto: string;\n pollingIntervalMs: number;\n maxPollingDurationMs: number;\n pendingTtlMs: number;\n mailtoAddress: string;\n dkimVerifierAccountId: string;\n verificationViewMethod: string;\n} {\n const relayerEmailCfg = configs.relayer.emailRecovery;\n const minBalanceYocto = String(relayerEmailCfg.minBalanceYocto);\n const pollingIntervalMs = Number(relayerEmailCfg.pollingIntervalMs);\n const maxPollingDurationMs = Number(relayerEmailCfg.maxPollingDurationMs);\n const pendingTtlMs = Number(relayerEmailCfg.pendingTtlMs);\n const mailtoAddress = String(relayerEmailCfg.mailtoAddress);\n const dkimVerifierAccountId = String(relayerEmailCfg.dkimVerifierAccountId);\n const verificationViewMethod = String(relayerEmailCfg.verificationViewMethod);\n return {\n minBalanceYocto,\n pollingIntervalMs,\n maxPollingDurationMs,\n pendingTtlMs,\n mailtoAddress,\n dkimVerifierAccountId,\n verificationViewMethod,\n };\n}\n\nexport function generateEmailRecoveryRequestId(): string {\n // 6-character A–Z0–9 identifier, suitable for short-lived correlation.\n const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';\n const length = 6;\n const bytes = new Uint8Array(length);\n (globalThis.crypto || window.crypto).getRandomValues(bytes);\n let out = '';\n for (let i = 0; i < length; i++) {\n out += alphabet[bytes[i] % alphabet.length];\n }\n return out;\n}\n\nexport class EmailRecoveryFlow {\n private context: PasskeyManagerContext;\n private options?: EmailRecoveryFlowOptions;\n private pending: PendingEmailRecovery | null = null;\n private phase: EmailRecoveryPhase = EmailRecoveryPhase.STEP_1_PREPARATION;\n private pollingTimer: any;\n private pollIntervalResolver?: (value?: void | PromiseLike<void>) => void;\n private pollingStartedAt: number | null = null;\n private cancelled = false;\n private error?: Error;\n\n constructor(context: PasskeyManagerContext, options?: EmailRecoveryFlowOptions) {\n this.context = context;\n this.options = options;\n }\n\n setOptions(options?: EmailRecoveryFlowOptions) {\n if (!options) return;\n this.options = { ...(this.options || {}), ...options };\n }\n private emit(event: EmailRecoverySSEEvent) {\n this.options?.onEvent?.(event);\n }\n\n private emitError(step: number, message: string): Error {\n const err = new Error(message);\n this.phase = EmailRecoveryPhase.ERROR;\n this.error = err;\n this.emit({\n step,\n phase: EmailRecoveryPhase.ERROR,\n status: EmailRecoveryStatus.ERROR,\n message,\n error: message,\n } as EmailRecoverySSEEvent & { error: string });\n this.options?.onError?.(err);\n return err;\n }\n\n private getConfig() {\n return getEmailRecoveryConfig(this.context.configs);\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 private async checkVerificationStatus(\n rec: PendingEmailRecovery\n ): Promise<{ completed: boolean; success: boolean; errorMessage?: string; transactionHash?: string } | null> {\n const { dkimVerifierAccountId, verificationViewMethod } = this.getConfig();\n if (!dkimVerifierAccountId) return null;\n\n try {\n type VerificationResult = {\n verified: boolean;\n account_id?: string;\n new_public_key?: string;\n transaction_hash?: string;\n error_code?: string;\n error_message?: string;\n };\n\n const result = await this.context.nearClient.view<\n { request_id: string },\n VerificationResult | null\n >({\n account: dkimVerifierAccountId,\n method: verificationViewMethod,\n args: { request_id: rec.requestId },\n });\n\n if (!result) {\n return { completed: false, success: false };\n }\n\n if (!result.verified) {\n const errorMessage = result.error_message || result.error_code || 'Email verification failed on relayer/contract';\n return {\n completed: true,\n success: false,\n errorMessage,\n transactionHash: result.transaction_hash,\n };\n }\n\n // Optional safety checks: ensure the bound account/key match expectations when available.\n if (result.account_id && result.account_id !== rec.accountId) {\n return {\n completed: true,\n success: false,\n errorMessage: 'Email verification account_id does not match requested account.',\n transactionHash: result.transaction_hash,\n };\n }\n if (result.new_public_key && result.new_public_key !== rec.nearPublicKey) {\n return {\n completed: true,\n success: false,\n errorMessage: 'Email verification new_public_key does not match expected recovery key.',\n transactionHash: result.transaction_hash,\n };\n }\n\n return {\n completed: true,\n success: true,\n transactionHash: result.transaction_hash\n };\n } catch (err) {\n // If the view method is not available or fails, fall back to access key polling.\n // eslint-disable-next-line no-console\n console.warn('[EmailRecoveryFlow] get_verification_result view failed; falling back to access key polling', err);\n return null;\n }\n }\n\n private async loadPending(\n accountId: AccountId,\n nearPublicKey?: string\n ): Promise<PendingEmailRecovery | null> {\n const { pendingTtlMs } = this.getConfig();\n\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 (Date.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 // Keep the per-account pointer updated so `finalizeEmailRecovery({ accountId })` can resume.\n await IndexedDBManager.clientDB.setAppState(indexKey, record.nearPublicKey).catch(() => { });\n return record;\n }\n\n private async savePending(rec: PendingEmailRecovery): Promise<void> {\n const key = this.getPendingRecordKey(rec.accountId, rec.nearPublicKey);\n await IndexedDBManager.clientDB.setAppState(key, rec);\n await IndexedDBManager.clientDB.setAppState(this.getPendingIndexKey(rec.accountId), rec.nearPublicKey).catch(() => { });\n this.pending = rec;\n }\n\n private async clearPending(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 if (\n this.pending\n && this.pending.accountId === accountId\n && (!nearPublicKey || this.pending.nearPublicKey === nearPublicKey)\n ) {\n this.pending = null;\n }\n }\n\n getState() {\n return {\n phase: this.phase,\n pending: this.pending,\n error: this.error,\n };\n }\n\n async buildMailtoUrl(args: { accountId: string; nearPublicKey?: string }): Promise<string> {\n const { accountId, nearPublicKey } = args;\n this.cancelled = false;\n this.error = undefined;\n\n const validation = validateNearAccountId(accountId as AccountId);\n if (!validation.valid) {\n const err = this.emitError(3, `Invalid NEAR account ID: ${validation.error}`);\n await this.options?.afterCall?.(false);\n throw err;\n }\n\n const nearAccountId = toAccountId(accountId as string);\n let rec = this.pending;\n if (!rec || rec.accountId !== nearAccountId || (nearPublicKey && rec.nearPublicKey !== nearPublicKey)) {\n rec = await this.loadPending(nearAccountId, nearPublicKey);\n this.pending = rec;\n }\n\n if (!rec) {\n const err = this.emitError(3, 'No pending email recovery record found for this account');\n await this.options?.afterCall?.(false);\n throw err;\n }\n\n if (rec.status === 'error') {\n const err = this.emitError(3, 'Pending email recovery is in an error state; please restart the flow');\n await this.options?.afterCall?.(false);\n throw err;\n }\n\n if (rec.status === 'finalizing' || rec.status === 'complete') {\n const err = this.emitError(3, 'Recovery email has already been processed on-chain for this request');\n await this.options?.afterCall?.(false);\n throw err;\n }\n\n const mailtoUrl =\n rec.status === 'awaiting-email'\n ? await this.buildMailtoUrlAndUpdateStatus(rec)\n : this.buildMailtoUrlInternal(rec);\n this.phase = EmailRecoveryPhase.STEP_3_AWAIT_EMAIL;\n this.emit({\n step: 3,\n phase: EmailRecoveryPhase.STEP_3_AWAIT_EMAIL,\n status: EmailRecoveryStatus.PROGRESS,\n message: 'New device key created; please send the recovery email from your registered address.',\n data: {\n accountId: rec.accountId,\n recoveryEmail: rec.recoveryEmail,\n nearPublicKey: rec.nearPublicKey,\n requestId: rec.requestId,\n mailtoUrl,\n },\n } as EmailRecoverySSEEvent & { data: Record<string, unknown> });\n await this.options?.afterCall?.(true, undefined as any);\n return mailtoUrl;\n }\n\n async start(args: { accountId: string; recoveryEmail: string }): Promise<{ mailtoUrl: string; nearPublicKey: string }> {\n const { accountId, recoveryEmail } = args;\n this.cancelled = false;\n this.error = undefined;\n this.phase = EmailRecoveryPhase.STEP_1_PREPARATION;\n\n this.emit({\n step: 1,\n phase: EmailRecoveryPhase.STEP_1_PREPARATION,\n status: EmailRecoveryStatus.PROGRESS,\n message: 'Preparing email recovery...',\n });\n\n const validation = validateNearAccountId(accountId as AccountId);\n if (!validation.valid) {\n const err = this.emitError(1, `Invalid NEAR account ID: ${validation.error}`);\n await this.options?.afterCall?.(false);\n throw err;\n }\n\n const nearAccountId = toAccountId(accountId as string);\n const { minBalanceYocto } = this.getConfig();\n const STORAGE_PRICE_PER_BYTE = BigInt('10000000000000000000'); // 1e19 yocto NEAR per byte\n\n try {\n const accountView = await this.context.nearClient.viewAccount(nearAccountId);\n const amount = BigInt(accountView.amount || '0');\n const locked = BigInt((accountView as any).locked || '0');\n const storageUsage = BigInt((accountView as any).storage_usage || 0);\n const storageCost = storageUsage * STORAGE_PRICE_PER_BYTE;\n const rawAvailable = amount - locked - storageCost;\n const available = rawAvailable > 0 ? rawAvailable : BigInt(0);\n if (available < BigInt(minBalanceYocto)) {\n const err = this.emitError(\n 1,\n `This account does not have enough NEAR to finalize recovery. Available: ${available.toString()} yocto; required: ${String(minBalanceYocto)}. Please top up and try again.`\n );\n await this.options?.afterCall?.(false);\n throw err;\n }\n } catch (e: any) {\n const err = this.emitError(1, e?.message || 'Failed to fetch account balance for recovery');\n await this.options?.afterCall?.(false);\n throw err;\n }\n\n const canonicalEmail = String(recoveryEmail || '').trim().toLowerCase();\n if (!canonicalEmail) {\n const err = this.emitError(1, 'Recovery email is required for email-based account recovery');\n await this.options?.afterCall?.(false);\n throw err;\n }\n\n // Determine deviceNumber from on-chain authenticators\n let deviceNumber = 1;\n try {\n const { syncAuthenticatorsContractCall } = await import('../rpcCalls');\n const authenticators = await syncAuthenticatorsContractCall(\n this.context.nearClient,\n this.context.configs.contractId,\n nearAccountId\n );\n const numbers = authenticators\n .map((a: any) => a?.authenticator?.deviceNumber)\n .filter((n: any) => typeof n === 'number' && Number.isFinite(n)) as number[];\n const max = numbers.length > 0 ? Math.max(...numbers) : 0;\n deviceNumber = max + 1;\n } catch {\n deviceNumber = 1;\n }\n\n this.phase = EmailRecoveryPhase.STEP_2_TOUCH_ID_REGISTRATION;\n this.emit({\n step: 2,\n phase: EmailRecoveryPhase.STEP_2_TOUCH_ID_REGISTRATION,\n status: EmailRecoveryStatus.PROGRESS,\n message: 'Collecting passkey for email recovery...',\n });\n\n try {\n const confirmerText = {\n title: this.options?.confirmerText?.title ?? 'Register New Recovery Account',\n body: this.options?.confirmerText?.body ?? 'Create a recovery account and send an encrypted email to recover your account.',\n };\n const confirm = await this.context.webAuthnManager.requestRegistrationCredentialConfirmation({\n nearAccountId,\n deviceNumber,\n confirmerText,\n confirmationConfigOverride: this.options?.confirmationConfig,\n });\n if (!confirm.confirmed || !confirm.credential) {\n const err = this.emitError(2, 'User cancelled email recovery TouchID confirmation');\n await this.options?.afterCall?.(false);\n throw err;\n }\n\n const vrfDerivationResult = await this.context.webAuthnManager.deriveVrfKeypair({\n credential: confirm.credential,\n nearAccountId,\n });\n\n if (!vrfDerivationResult.success || !vrfDerivationResult.encryptedVrfKeypair) {\n const err = this.emitError(2, 'Failed to derive VRF keypair from PRF for email recovery');\n await this.options?.afterCall?.(false);\n throw err;\n }\n\n const nearKeyResult = await this.context.webAuthnManager.deriveNearKeypairAndEncryptFromSerialized({\n nearAccountId,\n credential: confirm.credential,\n options: { deviceNumber },\n });\n\n if (!nearKeyResult.success || !nearKeyResult.publicKey) {\n const err = this.emitError(2, 'Failed to derive NEAR keypair for email recovery');\n await this.options?.afterCall?.(false);\n throw err;\n }\n\n const rec: PendingEmailRecovery = {\n accountId: nearAccountId,\n recoveryEmail: canonicalEmail,\n deviceNumber,\n nearPublicKey: nearKeyResult.publicKey,\n requestId: generateEmailRecoveryRequestId(),\n encryptedVrfKeypair: vrfDerivationResult.encryptedVrfKeypair,\n serverEncryptedVrfKeypair: vrfDerivationResult.serverEncryptedVrfKeypair || null,\n vrfPublicKey: vrfDerivationResult.vrfPublicKey,\n credential: confirm.credential,\n vrfChallenge: confirm.vrfChallenge || undefined,\n createdAt: Date.now(),\n status: 'awaiting-email',\n };\n\n const mailtoUrl = await this.buildMailtoUrlAndUpdateStatus(rec);\n\n this.phase = EmailRecoveryPhase.STEP_3_AWAIT_EMAIL;\n this.emit({\n step: 3,\n phase: EmailRecoveryPhase.STEP_3_AWAIT_EMAIL,\n status: EmailRecoveryStatus.PROGRESS,\n message: 'New device key created; please send the recovery email from your registered address.',\n data: {\n accountId: rec.accountId,\n recoveryEmail: rec.recoveryEmail,\n nearPublicKey: rec.nearPublicKey,\n requestId: rec.requestId,\n mailtoUrl,\n },\n } as EmailRecoverySSEEvent & { data: Record<string, unknown> });\n\n await this.options?.afterCall?.(true, undefined as any);\n\n return { mailtoUrl, nearPublicKey: rec.nearPublicKey };\n } catch (e: any) {\n const err = this.emitError(2, e?.message || 'Email recovery TouchID/derivation failed');\n await this.options?.afterCall?.(false);\n throw err;\n }\n }\n\n private buildMailtoUrlInternal(rec: PendingEmailRecovery): string {\n const { mailtoAddress } = this.getConfig();\n const to = encodeURIComponent(mailtoAddress);\n const subject = encodeURIComponent(`recover-${rec.requestId} ${rec.accountId} ${rec.nearPublicKey}`);\n const body = encodeURIComponent(`Recovering account ${rec.accountId} with a new passkey.`);\n return `mailto:${to}?subject=${subject}&body=${body}`;\n }\n\n private async buildMailtoUrlAndUpdateStatus(rec: PendingEmailRecovery): Promise<string> {\n rec.status = 'awaiting-add-key';\n await this.savePending(rec);\n return this.buildMailtoUrlInternal(rec);\n }\n\n async startPolling(args: { accountId: string; nearPublicKey?: string }): Promise<void> {\n const { accountId, nearPublicKey } = args;\n this.cancelled = false;\n this.error = undefined;\n\n const validation = validateNearAccountId(accountId as AccountId);\n if (!validation.valid) {\n const err = this.emitError(4, `Invalid NEAR account ID: ${validation.error}`);\n await this.options?.afterCall?.(false);\n throw err;\n }\n const nearAccountId = toAccountId(accountId as string);\n\n let rec = this.pending;\n if (!rec || rec.accountId !== nearAccountId || (nearPublicKey && rec.nearPublicKey !== nearPublicKey)) {\n rec = await this.loadPending(nearAccountId, nearPublicKey);\n this.pending = rec;\n }\n if (!rec) {\n const err = this.emitError(4, 'No pending email recovery record found for this account');\n await this.options?.afterCall?.(false);\n throw err;\n }\n if (rec.status === 'error') {\n const err = this.emitError(4, 'Pending email recovery is in an error state; please restart the flow');\n await this.options?.afterCall?.(false);\n throw err;\n }\n if (rec.status === 'complete' || rec.status === 'finalizing') {\n await this.options?.afterCall?.(true, undefined as any);\n return;\n }\n if (rec.status === 'awaiting-email') {\n await this.buildMailtoUrlAndUpdateStatus(rec);\n }\n\n await this.pollUntilAddKey(rec);\n await this.options?.afterCall?.(true, undefined as any);\n }\n\n stopPolling(): void {\n this.cancelled = true;\n if (this.pollingTimer) {\n clearTimeout(this.pollingTimer);\n this.pollingTimer = undefined;\n }\n if (this.pollIntervalResolver) {\n this.pollIntervalResolver();\n this.pollIntervalResolver = undefined;\n }\n }\n\n /**\n * Best-effort cancellation and local state reset so callers can retry.\n * This does not remove any passkey created in the browser/OS (WebAuthn has no delete API),\n * but it will stop polling and clear the pending IndexedDB record for the given key.\n */\n async cancelAndReset(args?: { accountId?: string; nearPublicKey?: string }): Promise<void> {\n this.stopPolling();\n\n const normalizedAccountId = (args?.accountId || this.pending?.accountId || '').toString().trim();\n const nearPublicKey = (args?.nearPublicKey || this.pending?.nearPublicKey || '').toString().trim();\n\n if (normalizedAccountId) {\n try {\n await this.clearPending(toAccountId(normalizedAccountId), nearPublicKey);\n } catch {\n // best-effort\n }\n }\n\n this.pending = null;\n this.error = undefined;\n this.phase = EmailRecoveryPhase.STEP_1_PREPARATION;\n }\n\n async finalize(args: { accountId: string; nearPublicKey?: string }): Promise<void> {\n const { accountId, nearPublicKey } = args;\n this.cancelled = false;\n this.error = undefined;\n\n const validation = validateNearAccountId(accountId as AccountId);\n if (!validation.valid) {\n const err = this.emitError(4, `Invalid NEAR account ID: ${validation.error}`);\n await this.options?.afterCall?.(false);\n throw err;\n }\n const nearAccountId = toAccountId(accountId as string);\n\n let rec = this.pending;\n if (!rec || rec.accountId !== nearAccountId || (nearPublicKey && rec.nearPublicKey !== nearPublicKey)) {\n rec = await this.loadPending(nearAccountId, nearPublicKey);\n this.pending = rec;\n }\n if (!rec) {\n const err = this.emitError(4, 'No pending email recovery record found for this account');\n await this.options?.afterCall?.(false);\n throw err;\n }\n\n this.emit({\n step: 0,\n phase: EmailRecoveryPhase.RESUMED_FROM_PENDING,\n status: EmailRecoveryStatus.PROGRESS,\n message: 'Resuming email recovery from pending state...',\n data: {\n accountId: rec.accountId,\n nearPublicKey: rec.nearPublicKey,\n status: rec.status,\n },\n } as EmailRecoverySSEEvent & { data: Record<string, unknown> });\n\n if (rec.status === 'complete') {\n this.phase = EmailRecoveryPhase.STEP_6_COMPLETE;\n this.emit({\n step: 6,\n phase: EmailRecoveryPhase.STEP_6_COMPLETE,\n status: EmailRecoveryStatus.SUCCESS,\n message: 'Email recovery already completed for this key.',\n });\n await this.options?.afterCall?.(true, undefined as any);\n return;\n }\n\n // Ensure verification has completed successfully before finalizing registration.\n await this.pollUntilAddKey(rec);\n await this.finalizeRegistration(rec);\n await this.options?.afterCall?.(true, undefined as any);\n }\n\n private async pollUntilAddKey(rec: PendingEmailRecovery): Promise<void> {\n const { pollingIntervalMs, maxPollingDurationMs, dkimVerifierAccountId } = this.getConfig();\n if (!dkimVerifierAccountId) {\n const err = this.emitError(4, 'Email recovery verification contract (dkimVerifierAccountId) is not configured');\n await this.options?.afterCall?.(false);\n throw err;\n }\n this.phase = EmailRecoveryPhase.STEP_4_POLLING_VERIFICATION_RESULT;\n this.pollingStartedAt = Date.now();\n let pollCount = 0;\n\n while (!this.cancelled) {\n pollCount += 1;\n const elapsed = Date.now() - (this.pollingStartedAt || 0);\n if (elapsed > maxPollingDurationMs) {\n const err = this.emitError(4, 'Timed out waiting for recovery email to be processed on-chain');\n rec.status = 'error';\n await this.savePending(rec);\n await this.options?.afterCall?.(false);\n throw err;\n }\n\n const verification = await this.checkVerificationStatus(rec);\n const completed = verification?.completed === true;\n const success = verification?.success === true;\n\n this.emit({\n step: 4,\n phase: EmailRecoveryPhase.STEP_4_POLLING_VERIFICATION_RESULT,\n status: EmailRecoveryStatus.PROGRESS,\n message: completed && success\n ? `Email verified for request ${rec.requestId}; finalizing registration`\n : `Waiting for email verification for request ${rec.requestId}`,\n data: {\n accountId: rec.accountId,\n requestId: rec.requestId,\n nearPublicKey: rec.nearPublicKey,\n transactionHash: verification?.transactionHash,\n elapsedMs: elapsed,\n pollCount,\n },\n } as EmailRecoverySSEEvent & { data: Record<string, unknown> });\n\n if (completed) {\n if (!success) {\n const err = this.emitError(4, verification?.errorMessage || 'Email verification failed');\n rec.status = 'error';\n await this.savePending(rec);\n await this.options?.afterCall?.(false);\n throw err;\n }\n\n rec.status = 'finalizing';\n await this.savePending(rec);\n return;\n }\n\n // If cancellation happens mid-iteration (e.g. while awaiting a view call),\n // don't wait an extra pollingIntervalMs before unwinding.\n if (this.cancelled) break;\n\n await new Promise<void>(resolve => {\n this.pollIntervalResolver = resolve;\n this.pollingTimer = setTimeout(() => {\n this.pollIntervalResolver = undefined;\n this.pollingTimer = undefined;\n resolve();\n }, pollingIntervalMs);\n }).finally(() => {\n this.pollIntervalResolver = undefined;\n });\n }\n\n const err = this.emitError(4, 'Email recovery polling was cancelled');\n await this.options?.afterCall?.(false);\n throw err;\n }\n\n private async finalizeRegistration(rec: PendingEmailRecovery): Promise<void> {\n this.phase = EmailRecoveryPhase.STEP_5_FINALIZING_REGISTRATION;\n this.emit({\n step: 5,\n phase: EmailRecoveryPhase.STEP_5_FINALIZING_REGISTRATION,\n status: EmailRecoveryStatus.PROGRESS,\n message: 'Finalizing email recovery registration...',\n data: {\n accountId: rec.accountId,\n nearPublicKey: rec.nearPublicKey,\n },\n } as EmailRecoverySSEEvent & { data: Record<string, unknown> });\n\n const nonceManager = this.context.webAuthnManager.getNonceManager();\n const accountId = toAccountId(rec.accountId);\n nonceManager.initializeUser(accountId, rec.nearPublicKey);\n\n try {\n if (!rec.vrfChallenge) {\n const err = this.emitError(5, 'Missing VRF challenge for email recovery registration');\n await this.options?.afterCall?.(false);\n throw err;\n }\n\n const registrationResult = await this.context.webAuthnManager.signDevice2RegistrationWithStoredKey({\n nearAccountId: accountId,\n credential: rec.credential,\n vrfChallenge: rec.vrfChallenge,\n deterministicVrfPublicKey: rec.vrfPublicKey,\n deviceNumber: rec.deviceNumber,\n });\n\n if (!registrationResult.success || !registrationResult.signedTransaction) {\n const err = this.emitError(5, registrationResult.error || 'Failed to sign email recovery registration transaction');\n await this.options?.afterCall?.(false);\n throw err;\n }\n\n const signedTx = registrationResult.signedTransaction;\n\n try {\n // Wait for finality so subsequent contract-gated signing (verify_authentication_response)\n // can reliably see the newly registered device/passkey.\n const txResult = await this.context.nearClient.sendTransaction(signedTx, DEFAULT_WAIT_STATUS.linkDeviceRegistration);\n try {\n const txHash = (txResult as any)?.transaction?.hash || (txResult as any)?.transaction_hash;\n if (txHash) {\n this.emit({\n step: 5,\n phase: EmailRecoveryPhase.STEP_5_FINALIZING_REGISTRATION,\n status: EmailRecoveryStatus.PROGRESS,\n message: 'Registration transaction confirmed',\n data: {\n accountId: rec.accountId,\n nearPublicKey: rec.nearPublicKey,\n transactionHash: txHash,\n },\n } as EmailRecoverySSEEvent & { data: Record<string, unknown> });\n\n // Store the new user record here, so `getLastUser()`\n // is aware of the new device context before any subsequent actions occur.\n try {\n // 1. Store the new user record (Device N) so that `getLastUser()` finds it\n // and `ensureCurrentPasskey` selects the correct credential for operations.\n await IndexedDBManager.clientDB.storeWebAuthnUserData({\n nearAccountId: accountId,\n deviceNumber: rec.deviceNumber,\n clientNearPublicKey: rec.nearPublicKey,\n passkeyCredential: {\n id: rec.credential.id,\n rawId: rec.credential.rawId,\n },\n encryptedVrfKeypair: rec.encryptedVrfKeypair,\n serverEncryptedVrfKeypair: rec.serverEncryptedVrfKeypair || undefined,\n });\n\n // 2. Sync authenticators immediately for allowCredentials list\n const { syncAuthenticatorsContractCall } = await import('../rpcCalls');\n const authenticators = await syncAuthenticatorsContractCall(\n this.context.nearClient,\n this.context.configs.contractId,\n accountId\n );\n\n // Map RPC result to DB schema\n const mappedAuthenticators = authenticators.map(({ authenticator }) => ({\n credentialId: authenticator.credentialId,\n credentialPublicKey: authenticator.credentialPublicKey,\n transports: authenticator.transports,\n name: authenticator.name,\n registered: authenticator.registered.toISOString(),\n vrfPublicKey: authenticator.vrfPublicKeys?.[0] || '',\n deviceNumber: authenticator.deviceNumber,\n }));\n\n await IndexedDBManager.clientDB.syncAuthenticatorsFromContract(accountId, mappedAuthenticators);\n\n // 3. Set as active user\n await IndexedDBManager.clientDB.setLastUser(accountId, rec.deviceNumber);\n } catch (syncErr) {\n console.warn('[EmailRecoveryFlow] Failed to sync authenticators after recovery:', syncErr);\n // Non-fatal; user can still proceed but might need a refresh for some features\n }\n }\n } catch {\n // best-effort; do not fail flow\n }\n } catch (e: any) {\n const msg = String(e?.message || '');\n const err = this.emitError(\n 5,\n msg || 'Failed to broadcast email recovery registration transaction (insufficient funds or RPC error)'\n );\n await this.options?.afterCall?.(false);\n throw err;\n }\n\n try {\n const txNonce = (signedTx.transaction as any)?.nonce;\n if (txNonce != null) {\n await nonceManager.updateNonceFromBlockchain(\n this.context.nearClient,\n String(txNonce)\n );\n }\n } catch {\n // best-effort; do not fail flow\n }\n\n const { webAuthnManager } = this.context;\n\n await webAuthnManager.storeUserData({\n nearAccountId: accountId,\n deviceNumber: rec.deviceNumber,\n clientNearPublicKey: rec.nearPublicKey,\n lastUpdated: Date.now(),\n passkeyCredential: {\n id: rec.credential.id,\n rawId: rec.credential.rawId,\n },\n encryptedVrfKeypair: {\n encryptedVrfDataB64u: rec.encryptedVrfKeypair.encryptedVrfDataB64u,\n chacha20NonceB64u: rec.encryptedVrfKeypair.chacha20NonceB64u,\n },\n serverEncryptedVrfKeypair: rec.serverEncryptedVrfKeypair || undefined,\n } as any);\n\n try {\n const attestationB64u = rec.credential.response.attestationObject;\n const credentialPublicKey = await webAuthnManager.extractCosePublicKey(attestationB64u);\n await webAuthnManager.storeAuthenticator({\n nearAccountId: accountId,\n deviceNumber: rec.deviceNumber,\n credentialId: rec.credential.rawId,\n credentialPublicKey,\n transports: ['internal'],\n name: `Device ${rec.deviceNumber} Passkey for ${rec.accountId.split('.')[0]}`,\n registered: new Date().toISOString(),\n syncedAt: new Date().toISOString(),\n vrfPublicKey: rec.vrfPublicKey,\n });\n } catch {\n // best-effort; do not fail flow\n }\n\n await this.attemptAutoLogin(rec);\n\n rec.status = 'complete';\n await this.savePending(rec);\n await this.clearPending(rec.accountId, rec.nearPublicKey);\n\n this.phase = EmailRecoveryPhase.STEP_6_COMPLETE;\n this.emit({\n step: 6,\n phase: EmailRecoveryPhase.STEP_6_COMPLETE,\n status: EmailRecoveryStatus.SUCCESS,\n message: 'Email recovery completed successfully',\n data: {\n accountId: rec.accountId,\n nearPublicKey: rec.nearPublicKey,\n },\n } as EmailRecoverySSEEvent & { data: Record<string, unknown> });\n } catch (e: any) {\n const err = this.emitError(5, e?.message || 'Email recovery finalization failed');\n await this.options?.afterCall?.(false);\n throw err;\n }\n }\n\n private async attemptAutoLogin(rec: PendingEmailRecovery): Promise<void> {\n try {\n this.emit({\n step: 5,\n phase: EmailRecoveryPhase.STEP_5_FINALIZING_REGISTRATION,\n status: EmailRecoveryStatus.PROGRESS,\n message: 'Attempting auto-login with recovered device...',\n data: { autoLogin: 'progress' },\n } as EmailRecoverySSEEvent & { data: Record<string, unknown> });\n\n const { webAuthnManager } = this.context;\n const accountId = toAccountId(rec.accountId);\n const deviceNumber = parseDeviceNumber(rec.deviceNumber, { min: 1 });\n if (deviceNumber === null) {\n throw new Error(`Invalid deviceNumber for auto-login: ${String(rec.deviceNumber)}`);\n }\n\n // Try Shamir 3-pass unlock first if configured and available\n if (\n rec.serverEncryptedVrfKeypair &&\n rec.serverEncryptedVrfKeypair.serverKeyId &&\n this.context.configs.vrfWorkerConfigs?.shamir3pass?.relayServerUrl\n ) {\n try {\n const unlockResult = await webAuthnManager.shamir3PassDecryptVrfKeypair({\n nearAccountId: accountId,\n kek_s_b64u: rec.serverEncryptedVrfKeypair.kek_s_b64u,\n ciphertextVrfB64u: rec.serverEncryptedVrfKeypair.ciphertextVrfB64u,\n serverKeyId: rec.serverEncryptedVrfKeypair.serverKeyId,\n });\n\n if (unlockResult.success) {\n const vrfStatus = await webAuthnManager.checkVrfStatus();\n const vrfActiveForAccount =\n vrfStatus.active\n && vrfStatus.nearAccountId\n && String(vrfStatus.nearAccountId) === String(accountId);\n if (!vrfActiveForAccount) {\n throw new Error('VRF session inactive after Shamir3Pass unlock');\n }\n\n await webAuthnManager.setLastUser(accountId, deviceNumber);\n await webAuthnManager.initializeCurrentUser(accountId, this.context.nearClient);\n try { await getLoginSession(this.context, accountId); } catch { }\n this.emit({\n step: 5,\n phase: EmailRecoveryPhase.STEP_5_FINALIZING_REGISTRATION,\n status: EmailRecoveryStatus.SUCCESS,\n message: `Welcome ${accountId}`,\n data: { autoLogin: 'success' },\n });\n return;\n }\n } catch (err) {\n // fall through to TouchID unlock\n console.warn('[EmailRecoveryFlow] Shamir 3-pass unlock failed, falling back to TouchID', err);\n }\n }\n\n // TouchID fallback unlock\n // Use a random challenge (no VRF required) to collect PRF outputs and unlock the stored VRF keypair.\n const authChallenge = createRandomVRFChallenge() as VRFChallenge;\n\n const storedCredentialId = String(rec.credential?.rawId || rec.credential?.id || '').trim();\n const credentialIds = storedCredentialId ? [storedCredentialId] : [];\n const authenticators = credentialIds.length > 0\n ? []\n : await webAuthnManager.getAuthenticatorsByUser(accountId);\n const authCredential = await webAuthnManager.getAuthenticationCredentialsSerializedDualPrf({\n nearAccountId: accountId,\n challenge: authChallenge,\n credentialIds: credentialIds.length > 0 ? credentialIds : authenticators.map((a) => a.credentialId),\n });\n\n if (storedCredentialId && authCredential.rawId !== storedCredentialId) {\n throw new Error('Wrong passkey selected during recovery auto-login; please use the newly recovered passkey.');\n }\n\n const vrfUnlockResult = await webAuthnManager.unlockVRFKeypair({\n nearAccountId: accountId,\n encryptedVrfKeypair: rec.encryptedVrfKeypair,\n credential: authCredential,\n });\n\n if (!vrfUnlockResult.success) {\n throw new Error(vrfUnlockResult.error || 'VRF unlock failed during auto-login');\n }\n\n const vrfStatus = await webAuthnManager.checkVrfStatus();\n const vrfActiveForAccount =\n vrfStatus.active\n && vrfStatus.nearAccountId\n && String(vrfStatus.nearAccountId) === String(accountId);\n if (!vrfActiveForAccount) {\n throw new Error('VRF session inactive after TouchID unlock');\n }\n\n await webAuthnManager.setLastUser(accountId, deviceNumber);\n await webAuthnManager.initializeCurrentUser(accountId, this.context.nearClient);\n try { await getLoginSession(this.context, accountId); } catch { }\n\n this.emit({\n step: 5,\n phase: EmailRecoveryPhase.STEP_5_FINALIZING_REGISTRATION,\n status: EmailRecoveryStatus.SUCCESS,\n message: `Welcome ${accountId}`,\n data: { autoLogin: 'success' },\n });\n\n } catch (err: any) {\n console.warn('[EmailRecoveryFlow] Auto-login failed after recovery', err);\n try {\n // Avoid leaving a stale/incompatible VRF keypair in-memory (can surface later as\n // \"Contract verification failed\" during signing). User can still log in manually.\n await this.context.webAuthnManager.clearVrfSession();\n } catch { }\n this.emit({\n step: 5,\n phase: EmailRecoveryPhase.STEP_5_FINALIZING_REGISTRATION,\n status: EmailRecoveryStatus.ERROR,\n message: 'Auto-login failed; please log in manually on this device.',\n data: { error: err?.message || String(err), autoLogin: 'error' },\n } as EmailRecoverySSEEvent & { data: Record<string, unknown> });\n }\n }\n}\n"],"mappings":"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"}
@@ -2,12 +2,13 @@ import { init_validation, isObject } from "../../WalletIframe/validation.js";
2
2
  import { base64UrlDecode } from "../../../utils/base64.js";
3
3
  import { init_encoders } from "../../../utils/encoders.js";
4
4
  import { errorMessage, init_errors } from "../../../utils/errors.js";
5
- import { normalizeRegistrationCredential, removePrfOutputGuard, serializeRegistrationCredential } from "../../WebAuthnManager/credentialsHelpers.js";
5
+ import { init_credentialsHelpers, normalizeRegistrationCredential, removePrfOutputGuard, serializeRegistrationCredential } from "../../WebAuthnManager/credentialsHelpers.js";
6
6
  import { RegistrationPhase, RegistrationStatus, init_sdkSentEvents } from "../../types/sdkSentEvents.js";
7
7
 
8
8
  //#region src/core/TatchiPasskey/faucets/createAccountRelayServer.ts
9
9
  init_sdkSentEvents();
10
10
  init_encoders();
11
+ init_credentialsHelpers();
11
12
  init_validation();
12
13
  init_errors();
13
14
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"createAccountRelayServer.js","names":["serialized: WebAuthnRegistrationCredential","requestData: CreateAccountAndRegisterUserRequest","result: CreateAccountAndRegisterResult","errorMessage","error: unknown"],"sources":["../../../../../../../../src/core/TatchiPasskey/faucets/createAccountRelayServer.ts"],"sourcesContent":["import { VRFChallenge } from '../../types/vrf-worker';\nimport { RegistrationSSEEvent, RegistrationPhase, RegistrationStatus } from '../../types/sdkSentEvents';\nimport { PasskeyManagerContext } from '..';\nimport { base64UrlDecode, base64UrlEncode } from '../../../utils/encoders';\nimport type { SignedTransaction } from '../../NearClient';\nimport { removePrfOutputGuard, serializeRegistrationCredential, normalizeRegistrationCredential } from '../../WebAuthnManager/credentialsHelpers';\nimport type { WebAuthnRegistrationCredential } from '../../types/webauthn';\nimport type { AuthenticatorOptions } from '../../types/authenticatorOptions';\nimport type { CreateAccountAndRegisterResult } from '../../../server/core/types';\nimport { isObject } from '../../WalletIframe/validation';\nimport { errorMessage } from '../../../utils/errors';\n\n/**\n * HTTP Request body for the relay server's /create_account_and_register_user endpoint\n */\nexport interface CreateAccountAndRegisterUserRequest {\n new_account_id: string;\n new_public_key: string;\n device_number: number;\n vrf_data: {\n vrf_input_data: number[];\n vrf_output: number[];\n vrf_proof: number[];\n public_key: number[];\n user_id: string;\n rp_id: string;\n block_height: number;\n block_hash: number[];\n };\n webauthn_registration: WebAuthnRegistrationCredential;\n deterministic_vrf_public_key: number[];\n authenticator_options?: AuthenticatorOptions;\n}\n\n/**\n * Create account and register user using relay-server atomic endpoint\n * Makes a single call to the relay-server's /create_account_and_register_user endpoint\n * which calls the contract's atomic create_account_and_register_user function\n */\nexport async function createAccountAndRegisterWithRelayServer(\n context: PasskeyManagerContext,\n nearAccountId: string,\n publicKey: string,\n credential: WebAuthnRegistrationCredential | PublicKeyCredential,\n vrfChallenge: VRFChallenge,\n deterministicVrfPublicKey: string,\n authenticatorOptions?: AuthenticatorOptions,\n onEvent?: (event: RegistrationSSEEvent) => void,\n): Promise<{\n success: boolean;\n transactionId?: string;\n error?: string;\n}> {\n const { configs } = context;\n\n if (!configs.relayer.url) {\n throw new Error('Relay server URL is required for atomic registration');\n }\n\n try {\n onEvent?.({\n step: 4,\n phase: RegistrationPhase.STEP_4_ACCESS_KEY_ADDITION,\n status: RegistrationStatus.PROGRESS,\n message: 'Creating account and adding access key...',\n });\n\n // Serialize the WebAuthn credential properly for the contract.\n // Accept both live PublicKeyCredential and already-serialized credentials from secureConfirm.\n const isSerialized = isObject(credential)\n && typeof (credential as any)?.response?.attestationObject === 'string';\n\n // Ensure proper serialization + normalization regardless of source\n const serialized: WebAuthnRegistrationCredential = isSerialized\n ? normalizeRegistrationCredential(credential as WebAuthnRegistrationCredential)\n : serializeRegistrationCredential(credential as PublicKeyCredential);\n\n // Strip PRF outputs before sending to relay/contract\n const serializedCredential = removePrfOutputGuard<WebAuthnRegistrationCredential>(serialized);\n // Normalize transports to an array (avoid null)\n if (!Array.isArray(serializedCredential?.response?.transports)) {\n serializedCredential.response.transports = [];\n }\n\n // Prepare data for atomic endpoint\n const requestData: CreateAccountAndRegisterUserRequest = {\n new_account_id: nearAccountId,\n new_public_key: publicKey,\n device_number: 1, // First device gets device number 1 (1-indexed)\n vrf_data: {\n vrf_input_data: Array.from(base64UrlDecode(vrfChallenge.vrfInput)),\n vrf_output: Array.from(base64UrlDecode(vrfChallenge.vrfOutput)),\n vrf_proof: Array.from(base64UrlDecode(vrfChallenge.vrfProof)),\n public_key: Array.from(base64UrlDecode(vrfChallenge.vrfPublicKey)),\n user_id: vrfChallenge.userId,\n rp_id: vrfChallenge.rpId,\n block_height: Number(vrfChallenge.blockHeight),\n block_hash: Array.from(base64UrlDecode(vrfChallenge.blockHash)),\n },\n webauthn_registration: serializedCredential,\n deterministic_vrf_public_key: Array.from(base64UrlDecode(deterministicVrfPublicKey)),\n authenticator_options: authenticatorOptions || context.configs.authenticatorOptions,\n };\n\n onEvent?.({\n step: 5,\n phase: RegistrationPhase.STEP_5_CONTRACT_REGISTRATION,\n status: RegistrationStatus.PROGRESS,\n message: 'Registering user with Web3Authn contract...',\n });\n\n // Call the atomic endpoint\n const response = await fetch(`${configs.relayer.url}/create_account_and_register_user`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(requestData)\n });\n\n // Handle both successful and failed responses\n const result: CreateAccountAndRegisterResult = await response.json();\n\n if (!response.ok) {\n // Extract specific error message from relay server response\n const errorMessage = result.error || result.message || `HTTP ${response.status}: ${response.statusText}`;\n throw new Error(errorMessage);\n }\n\n if (!result.success) {\n throw new Error(result.error || 'Atomic registration failed');\n }\n\n onEvent?.({\n step: 5,\n phase: RegistrationPhase.STEP_5_CONTRACT_REGISTRATION,\n status: RegistrationStatus.SUCCESS,\n message: 'User registered with Web3Authn contract successfully',\n });\n\n return {\n success: true,\n transactionId: result.transactionHash,\n };\n\n } catch (error: unknown) {\n console.error('Atomic registration failed:', error);\n\n onEvent?.({\n step: 0,\n phase: RegistrationPhase.REGISTRATION_ERROR,\n status: RegistrationStatus.ERROR,\n message: 'Registration failed',\n error: errorMessage(error),\n });\n\n return {\n success: false,\n error: errorMessage(error),\n };\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAuCA,eAAsB,wCACpB,SACA,eACA,WACA,YACA,cACA,2BACA,sBACA,SAKC;CACD,MAAM,EAAE,YAAY;AAEpB,KAAI,CAAC,QAAQ,QAAQ,IACnB,OAAM,IAAI,MAAM;AAGlB,KAAI;AACF,YAAU;GACR,MAAM;GACN,OAAO,kBAAkB;GACzB,QAAQ,mBAAmB;GAC3B,SAAS;;EAKX,MAAM,eAAe,SAAS,eACzB,OAAQ,YAAoB,UAAU,sBAAsB;EAGjE,MAAMA,aAA6C,eAC/C,gCAAgC,cAChC,gCAAgC;EAGpC,MAAM,uBAAuB,qBAAqD;AAElF,MAAI,CAAC,MAAM,QAAQ,sBAAsB,UAAU,YACjD,sBAAqB,SAAS,aAAa;EAI7C,MAAMC,cAAmD;GACvD,gBAAgB;GAChB,gBAAgB;GAChB,eAAe;GACf,UAAU;IACR,gBAAgB,MAAM,KAAK,gBAAgB,aAAa;IACxD,YAAY,MAAM,KAAK,gBAAgB,aAAa;IACpD,WAAW,MAAM,KAAK,gBAAgB,aAAa;IACnD,YAAY,MAAM,KAAK,gBAAgB,aAAa;IACpD,SAAS,aAAa;IACtB,OAAO,aAAa;IACpB,cAAc,OAAO,aAAa;IAClC,YAAY,MAAM,KAAK,gBAAgB,aAAa;;GAEtD,uBAAuB;GACvB,8BAA8B,MAAM,KAAK,gBAAgB;GACzD,uBAAuB,wBAAwB,QAAQ,QAAQ;;AAGjE,YAAU;GACR,MAAM;GACN,OAAO,kBAAkB;GACzB,QAAQ,mBAAmB;GAC3B,SAAS;;EAIX,MAAM,WAAW,MAAM,MAAM,GAAG,QAAQ,QAAQ,IAAI,oCAAoC;GACtF,QAAQ;GACR,SAAS,EAAE,gBAAgB;GAC3B,MAAM,KAAK,UAAU;;EAIvB,MAAMC,SAAyC,MAAM,SAAS;AAE9D,MAAI,CAAC,SAAS,IAAI;GAEhB,MAAMC,iBAAe,OAAO,SAAS,OAAO,WAAW,QAAQ,SAAS,OAAO,IAAI,SAAS;AAC5F,SAAM,IAAI,MAAMA;;AAGlB,MAAI,CAAC,OAAO,QACV,OAAM,IAAI,MAAM,OAAO,SAAS;AAGlC,YAAU;GACR,MAAM;GACN,OAAO,kBAAkB;GACzB,QAAQ,mBAAmB;GAC3B,SAAS;;AAGX,SAAO;GACL,SAAS;GACT,eAAe,OAAO;;UAGjBC,OAAgB;AACvB,UAAQ,MAAM,+BAA+B;AAE7C,YAAU;GACR,MAAM;GACN,OAAO,kBAAkB;GACzB,QAAQ,mBAAmB;GAC3B,SAAS;GACT,OAAO,aAAa;;AAGtB,SAAO;GACL,SAAS;GACT,OAAO,aAAa"}
1
+ {"version":3,"file":"createAccountRelayServer.js","names":["serialized: WebAuthnRegistrationCredential","requestData: CreateAccountAndRegisterUserRequest","result: CreateAccountAndRegisterResult","errorMessage","error: unknown"],"sources":["../../../../../../../../src/core/TatchiPasskey/faucets/createAccountRelayServer.ts"],"sourcesContent":["import { VRFChallenge } from '../../types/vrf-worker';\nimport { RegistrationSSEEvent, RegistrationPhase, RegistrationStatus } from '../../types/sdkSentEvents';\nimport { PasskeyManagerContext } from '..';\nimport { base64UrlDecode, base64UrlEncode } from '../../../utils/encoders';\nimport type { SignedTransaction } from '../../NearClient';\nimport { removePrfOutputGuard, serializeRegistrationCredential, normalizeRegistrationCredential } from '../../WebAuthnManager/credentialsHelpers';\nimport type { WebAuthnRegistrationCredential } from '../../types/webauthn';\nimport type { AuthenticatorOptions } from '../../types/authenticatorOptions';\nimport type { CreateAccountAndRegisterResult } from '../../../server/core/types';\nimport { isObject } from '../../WalletIframe/validation';\nimport { errorMessage } from '../../../utils/errors';\n\n/**\n * HTTP Request body for the relay server's /create_account_and_register_user endpoint\n */\nexport interface CreateAccountAndRegisterUserRequest {\n new_account_id: string;\n new_public_key: string;\n device_number: number;\n vrf_data: {\n vrf_input_data: number[];\n vrf_output: number[];\n vrf_proof: number[];\n public_key: number[];\n user_id: string;\n rp_id: string;\n block_height: number;\n block_hash: number[];\n };\n webauthn_registration: WebAuthnRegistrationCredential;\n deterministic_vrf_public_key: number[];\n authenticator_options?: AuthenticatorOptions;\n}\n\n/**\n * Create account and register user using relay-server atomic endpoint\n * Makes a single call to the relay-server's /create_account_and_register_user endpoint\n * which calls the contract's atomic create_account_and_register_user function\n */\nexport async function createAccountAndRegisterWithRelayServer(\n context: PasskeyManagerContext,\n nearAccountId: string,\n publicKey: string,\n credential: WebAuthnRegistrationCredential | PublicKeyCredential,\n vrfChallenge: VRFChallenge,\n deterministicVrfPublicKey: string,\n authenticatorOptions?: AuthenticatorOptions,\n onEvent?: (event: RegistrationSSEEvent) => void,\n): Promise<{\n success: boolean;\n transactionId?: string;\n error?: string;\n}> {\n const { configs } = context;\n\n if (!configs.relayer.url) {\n throw new Error('Relay server URL is required for atomic registration');\n }\n\n try {\n onEvent?.({\n step: 4,\n phase: RegistrationPhase.STEP_4_ACCESS_KEY_ADDITION,\n status: RegistrationStatus.PROGRESS,\n message: 'Creating account and adding access key...',\n });\n\n // Serialize the WebAuthn credential properly for the contract.\n // Accept both live PublicKeyCredential and already-serialized credentials from secureConfirm.\n const isSerialized = isObject(credential)\n && typeof (credential as any)?.response?.attestationObject === 'string';\n\n // Ensure proper serialization + normalization regardless of source\n const serialized: WebAuthnRegistrationCredential = isSerialized\n ? normalizeRegistrationCredential(credential as WebAuthnRegistrationCredential)\n : serializeRegistrationCredential(credential as PublicKeyCredential);\n\n // Strip PRF outputs before sending to relay/contract\n const serializedCredential = removePrfOutputGuard<WebAuthnRegistrationCredential>(serialized);\n // Normalize transports to an array (avoid null)\n if (!Array.isArray(serializedCredential?.response?.transports)) {\n serializedCredential.response.transports = [];\n }\n\n // Prepare data for atomic endpoint\n const requestData: CreateAccountAndRegisterUserRequest = {\n new_account_id: nearAccountId,\n new_public_key: publicKey,\n device_number: 1, // First device gets device number 1 (1-indexed)\n vrf_data: {\n vrf_input_data: Array.from(base64UrlDecode(vrfChallenge.vrfInput)),\n vrf_output: Array.from(base64UrlDecode(vrfChallenge.vrfOutput)),\n vrf_proof: Array.from(base64UrlDecode(vrfChallenge.vrfProof)),\n public_key: Array.from(base64UrlDecode(vrfChallenge.vrfPublicKey)),\n user_id: vrfChallenge.userId,\n rp_id: vrfChallenge.rpId,\n block_height: Number(vrfChallenge.blockHeight),\n block_hash: Array.from(base64UrlDecode(vrfChallenge.blockHash)),\n },\n webauthn_registration: serializedCredential,\n deterministic_vrf_public_key: Array.from(base64UrlDecode(deterministicVrfPublicKey)),\n authenticator_options: authenticatorOptions || context.configs.authenticatorOptions,\n };\n\n onEvent?.({\n step: 5,\n phase: RegistrationPhase.STEP_5_CONTRACT_REGISTRATION,\n status: RegistrationStatus.PROGRESS,\n message: 'Registering user with Web3Authn contract...',\n });\n\n // Call the atomic endpoint\n const response = await fetch(`${configs.relayer.url}/create_account_and_register_user`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(requestData)\n });\n\n // Handle both successful and failed responses\n const result: CreateAccountAndRegisterResult = await response.json();\n\n if (!response.ok) {\n // Extract specific error message from relay server response\n const errorMessage = result.error || result.message || `HTTP ${response.status}: ${response.statusText}`;\n throw new Error(errorMessage);\n }\n\n if (!result.success) {\n throw new Error(result.error || 'Atomic registration failed');\n }\n\n onEvent?.({\n step: 5,\n phase: RegistrationPhase.STEP_5_CONTRACT_REGISTRATION,\n status: RegistrationStatus.SUCCESS,\n message: 'User registered with Web3Authn contract successfully',\n });\n\n return {\n success: true,\n transactionId: result.transactionHash,\n };\n\n } catch (error: unknown) {\n console.error('Atomic registration failed:', error);\n\n onEvent?.({\n step: 0,\n phase: RegistrationPhase.REGISTRATION_ERROR,\n status: RegistrationStatus.ERROR,\n message: 'Registration failed',\n error: errorMessage(error),\n });\n\n return {\n success: false,\n error: errorMessage(error),\n };\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAuCA,eAAsB,wCACpB,SACA,eACA,WACA,YACA,cACA,2BACA,sBACA,SAKC;CACD,MAAM,EAAE,YAAY;AAEpB,KAAI,CAAC,QAAQ,QAAQ,IACnB,OAAM,IAAI,MAAM;AAGlB,KAAI;AACF,YAAU;GACR,MAAM;GACN,OAAO,kBAAkB;GACzB,QAAQ,mBAAmB;GAC3B,SAAS;;EAKX,MAAM,eAAe,SAAS,eACzB,OAAQ,YAAoB,UAAU,sBAAsB;EAGjE,MAAMA,aAA6C,eAC/C,gCAAgC,cAChC,gCAAgC;EAGpC,MAAM,uBAAuB,qBAAqD;AAElF,MAAI,CAAC,MAAM,QAAQ,sBAAsB,UAAU,YACjD,sBAAqB,SAAS,aAAa;EAI7C,MAAMC,cAAmD;GACvD,gBAAgB;GAChB,gBAAgB;GAChB,eAAe;GACf,UAAU;IACR,gBAAgB,MAAM,KAAK,gBAAgB,aAAa;IACxD,YAAY,MAAM,KAAK,gBAAgB,aAAa;IACpD,WAAW,MAAM,KAAK,gBAAgB,aAAa;IACnD,YAAY,MAAM,KAAK,gBAAgB,aAAa;IACpD,SAAS,aAAa;IACtB,OAAO,aAAa;IACpB,cAAc,OAAO,aAAa;IAClC,YAAY,MAAM,KAAK,gBAAgB,aAAa;;GAEtD,uBAAuB;GACvB,8BAA8B,MAAM,KAAK,gBAAgB;GACzD,uBAAuB,wBAAwB,QAAQ,QAAQ;;AAGjE,YAAU;GACR,MAAM;GACN,OAAO,kBAAkB;GACzB,QAAQ,mBAAmB;GAC3B,SAAS;;EAIX,MAAM,WAAW,MAAM,MAAM,GAAG,QAAQ,QAAQ,IAAI,oCAAoC;GACtF,QAAQ;GACR,SAAS,EAAE,gBAAgB;GAC3B,MAAM,KAAK,UAAU;;EAIvB,MAAMC,SAAyC,MAAM,SAAS;AAE9D,MAAI,CAAC,SAAS,IAAI;GAEhB,MAAMC,iBAAe,OAAO,SAAS,OAAO,WAAW,QAAQ,SAAS,OAAO,IAAI,SAAS;AAC5F,SAAM,IAAI,MAAMA;;AAGlB,MAAI,CAAC,OAAO,QACV,OAAM,IAAI,MAAM,OAAO,SAAS;AAGlC,YAAU;GACR,MAAM;GACN,OAAO,kBAAkB;GACzB,QAAQ,mBAAmB;GAC3B,SAAS;;AAGX,SAAO;GACL,SAAS;GACT,eAAe,OAAO;;UAGjBC,OAAgB;AACvB,UAAQ,MAAM,+BAA+B;AAE7C,YAAU;GACR,MAAM;GACN,OAAO,kBAAkB;GACzB,QAAQ,mBAAmB;GAC3B,SAAS;GACT,OAAO,aAAa;;AAGtB,SAAO;GACL,SAAS;GACT,OAAO,aAAa"}