@tatchi-xyz/sdk 0.16.0 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (470) hide show
  1. package/dist/cjs/core/EmailRecovery/index.js +12 -5
  2. package/dist/cjs/core/EmailRecovery/index.js.map +1 -1
  3. package/dist/cjs/core/IndexedDBManager/passkeyClientDB.js +35 -36
  4. package/dist/cjs/core/IndexedDBManager/passkeyClientDB.js.map +1 -1
  5. package/dist/cjs/core/NearClient.js +2 -1
  6. package/dist/cjs/core/NearClient.js.map +1 -1
  7. package/dist/cjs/core/TatchiPasskey/emailRecovery.js +136 -27
  8. package/dist/cjs/core/TatchiPasskey/emailRecovery.js.map +1 -1
  9. package/dist/cjs/core/TatchiPasskey/faucets/createAccountRelayServer.js +1 -0
  10. package/dist/cjs/core/TatchiPasskey/faucets/createAccountRelayServer.js.map +1 -1
  11. package/dist/cjs/core/TatchiPasskey/index.js +25 -0
  12. package/dist/cjs/core/TatchiPasskey/index.js.map +1 -1
  13. package/dist/cjs/core/TatchiPasskey/linkDevice.js +2 -0
  14. package/dist/cjs/core/TatchiPasskey/linkDevice.js.map +1 -1
  15. package/dist/cjs/core/TatchiPasskey/login.js +15 -4
  16. package/dist/cjs/core/TatchiPasskey/login.js.map +1 -1
  17. package/dist/cjs/core/TatchiPasskey/recoverAccount.js +1 -0
  18. package/dist/cjs/core/TatchiPasskey/recoverAccount.js.map +1 -1
  19. package/dist/cjs/core/TatchiPasskey/scanDevice.js +1 -0
  20. package/dist/cjs/core/TatchiPasskey/scanDevice.js.map +1 -1
  21. package/dist/cjs/core/WalletIframe/client/IframeTransport.js +10 -0
  22. package/dist/cjs/core/WalletIframe/client/IframeTransport.js.map +1 -1
  23. package/dist/cjs/core/WalletIframe/client/router.js +9 -0
  24. package/dist/cjs/core/WalletIframe/client/router.js.map +1 -1
  25. package/dist/cjs/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-drawer.js +1 -1
  26. package/dist/cjs/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-drawer.js.map +1 -1
  27. package/dist/cjs/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-modal.js +52 -52
  28. package/dist/cjs/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-modal.js.map +1 -1
  29. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/getDeviceNumber.js +10 -1
  30. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/getDeviceNumber.js.map +1 -1
  31. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/checkCanRegisterUser.js +1 -0
  32. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/checkCanRegisterUser.js.map +1 -1
  33. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/decryptPrivateKeyWithPrf.js +1 -0
  34. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/decryptPrivateKeyWithPrf.js.map +1 -1
  35. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/deriveNearKeypairAndEncryptFromSerialized.js +1 -0
  36. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/deriveNearKeypairAndEncryptFromSerialized.js.map +1 -1
  37. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/exportNearKeypairUi.js +1 -0
  38. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/exportNearKeypairUi.js.map +1 -1
  39. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/registerDevice2WithDerivedKey.js +2 -1
  40. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/registerDevice2WithDerivedKey.js.map +1 -1
  41. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/signDelegateAction.js +1 -0
  42. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/signDelegateAction.js.map +1 -1
  43. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/signNep413Message.js +1 -0
  44. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/signNep413Message.js.map +1 -1
  45. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/signTransactionsWithActions.js +1 -0
  46. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/signTransactionsWithActions.js.map +1 -1
  47. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/validation.js +2 -0
  48. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/validation.js.map +1 -1
  49. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/index.js +1 -0
  50. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/index.js.map +1 -1
  51. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/vrf.js +1 -0
  52. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/vrf.js.map +1 -1
  53. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/webauthn.js +6 -0
  54. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/webauthn.js.map +1 -1
  55. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/determineConfirmationConfig.js +2 -1
  56. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/determineConfirmationConfig.js.map +1 -1
  57. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/localOnly.js +1 -0
  58. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/localOnly.js.map +1 -1
  59. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/registration.js +1 -0
  60. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/registration.js.map +1 -1
  61. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/transactions.js +4 -15
  62. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/transactions.js.map +1 -1
  63. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/handlers/deriveVrfKeypairFromPrf.js +1 -0
  64. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/handlers/deriveVrfKeypairFromPrf.js.map +1 -1
  65. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfChallenge.js +1 -0
  66. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfChallenge.js.map +1 -1
  67. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfKeypairBootstrap.js +1 -0
  68. package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfKeypairBootstrap.js.map +1 -1
  69. package/dist/cjs/core/WebAuthnManager/WebAuthnFallbacks/index.js +17 -0
  70. package/dist/cjs/core/WebAuthnManager/WebAuthnFallbacks/index.js.map +1 -0
  71. package/dist/cjs/core/WebAuthnManager/WebAuthnFallbacks/safari-fallbacks.js +64 -54
  72. package/dist/cjs/core/WebAuthnManager/WebAuthnFallbacks/safari-fallbacks.js.map +1 -1
  73. package/dist/cjs/core/WebAuthnManager/credentialsHelpers.js +12 -2
  74. package/dist/cjs/core/WebAuthnManager/credentialsHelpers.js.map +1 -1
  75. package/dist/cjs/core/WebAuthnManager/index.js +6 -1
  76. package/dist/cjs/core/WebAuthnManager/index.js.map +1 -1
  77. package/dist/cjs/core/WebAuthnManager/touchIdPrompt.js +209 -201
  78. package/dist/cjs/core/WebAuthnManager/touchIdPrompt.js.map +1 -1
  79. package/dist/cjs/core/WebAuthnManager/userHandle.js +2 -1
  80. package/dist/cjs/core/WebAuthnManager/userHandle.js.map +1 -1
  81. package/dist/cjs/core/defaultConfigs.js +1 -1
  82. package/dist/cjs/core/defaultConfigs.js.map +1 -1
  83. package/dist/cjs/core/types/vrf-worker.js +10 -1
  84. package/dist/cjs/core/types/vrf-worker.js.map +1 -1
  85. package/dist/cjs/react/components/AccountMenuButton/{LinkedDevicesModal-STvIsylA.css → LinkedDevicesModal-B6api181.css} +1 -1
  86. package/dist/{esm/react/components/AccountMenuButton/LinkedDevicesModal-STvIsylA.css.map → cjs/react/components/AccountMenuButton/LinkedDevicesModal-B6api181.css.map} +1 -1
  87. package/dist/cjs/react/components/AccountMenuButton/{ProfileDropdown-iARgUwK1.css → ProfileDropdown-B-DrG_u5.css} +1 -1
  88. package/dist/{esm/react/components/AccountMenuButton/ProfileDropdown-iARgUwK1.css.map → cjs/react/components/AccountMenuButton/ProfileDropdown-B-DrG_u5.css.map} +1 -1
  89. package/dist/cjs/react/components/AccountMenuButton/{Web3AuthProfileButton-Db3NeoAC.css → Web3AuthProfileButton-BnZDUeCL.css} +1 -1
  90. package/dist/cjs/react/components/AccountMenuButton/{Web3AuthProfileButton-Db3NeoAC.css.map → Web3AuthProfileButton-BnZDUeCL.css.map} +1 -1
  91. package/dist/cjs/react/components/AccountMenuButton/icons/{TouchIcon-BXM5NR4A.css → TouchIcon-CAGCi8MY.css} +1 -1
  92. package/dist/cjs/react/components/AccountMenuButton/icons/{TouchIcon-BXM5NR4A.css.map → TouchIcon-CAGCi8MY.css.map} +1 -1
  93. package/dist/cjs/react/components/PasskeyAuthMenu/{PasskeyAuthMenu-De1qTSmU.css → PasskeyAuthMenu-CNNxVj4L.css} +14 -1
  94. package/dist/cjs/react/components/PasskeyAuthMenu/{PasskeyAuthMenu-De1qTSmU.css.map → PasskeyAuthMenu-CNNxVj4L.css.map} +1 -1
  95. package/dist/cjs/react/components/PasskeyAuthMenu/ui/EmailRecoverySlide.js +122 -53
  96. package/dist/cjs/react/components/PasskeyAuthMenu/ui/EmailRecoverySlide.js.map +1 -1
  97. package/dist/cjs/react/components/{ShowQRCode-DCnR__fx.css → ShowQRCode-nZhZSaba.css} +1 -1
  98. package/dist/cjs/react/components/{ShowQRCode-DCnR__fx.css.map → ShowQRCode-nZhZSaba.css.map} +1 -1
  99. package/dist/cjs/react/deviceDetection.js +75 -92
  100. package/dist/cjs/react/deviceDetection.js.map +1 -1
  101. package/dist/cjs/react/hooks/usePreconnectWalletAssets.js +32 -27
  102. package/dist/cjs/react/hooks/usePreconnectWalletAssets.js.map +1 -1
  103. package/dist/cjs/react/hooks/useQRCamera.js +1 -0
  104. package/dist/cjs/react/hooks/useQRCamera.js.map +1 -1
  105. package/dist/cjs/react/sdk/src/core/EmailRecovery/index.js +12 -5
  106. package/dist/cjs/react/sdk/src/core/EmailRecovery/index.js.map +1 -1
  107. package/dist/cjs/react/sdk/src/core/IndexedDBManager/passkeyClientDB.js +35 -36
  108. package/dist/cjs/react/sdk/src/core/IndexedDBManager/passkeyClientDB.js.map +1 -1
  109. package/dist/cjs/react/sdk/src/core/NearClient.js +2 -1
  110. package/dist/cjs/react/sdk/src/core/NearClient.js.map +1 -1
  111. package/dist/cjs/react/sdk/src/core/TatchiPasskey/emailRecovery.js +136 -27
  112. package/dist/cjs/react/sdk/src/core/TatchiPasskey/emailRecovery.js.map +1 -1
  113. package/dist/cjs/react/sdk/src/core/TatchiPasskey/faucets/createAccountRelayServer.js +1 -0
  114. package/dist/cjs/react/sdk/src/core/TatchiPasskey/faucets/createAccountRelayServer.js.map +1 -1
  115. package/dist/cjs/react/sdk/src/core/TatchiPasskey/index.js +25 -0
  116. package/dist/cjs/react/sdk/src/core/TatchiPasskey/index.js.map +1 -1
  117. package/dist/cjs/react/sdk/src/core/TatchiPasskey/linkDevice.js +2 -0
  118. package/dist/cjs/react/sdk/src/core/TatchiPasskey/linkDevice.js.map +1 -1
  119. package/dist/cjs/react/sdk/src/core/TatchiPasskey/login.js +15 -4
  120. package/dist/cjs/react/sdk/src/core/TatchiPasskey/login.js.map +1 -1
  121. package/dist/cjs/react/sdk/src/core/TatchiPasskey/recoverAccount.js +1 -0
  122. package/dist/cjs/react/sdk/src/core/TatchiPasskey/recoverAccount.js.map +1 -1
  123. package/dist/cjs/react/sdk/src/core/TatchiPasskey/scanDevice.js +1 -0
  124. package/dist/cjs/react/sdk/src/core/TatchiPasskey/scanDevice.js.map +1 -1
  125. package/dist/cjs/react/sdk/src/core/WalletIframe/client/IframeTransport.js +10 -0
  126. package/dist/cjs/react/sdk/src/core/WalletIframe/client/IframeTransport.js.map +1 -1
  127. package/dist/cjs/react/sdk/src/core/WalletIframe/client/router.js +9 -0
  128. package/dist/cjs/react/sdk/src/core/WalletIframe/client/router.js.map +1 -1
  129. package/dist/cjs/react/sdk/src/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-drawer.js +1 -1
  130. package/dist/cjs/react/sdk/src/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-drawer.js.map +1 -1
  131. package/dist/cjs/react/sdk/src/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-modal.js +52 -52
  132. package/dist/cjs/react/sdk/src/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-modal.js.map +1 -1
  133. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/getDeviceNumber.js +10 -1
  134. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/getDeviceNumber.js.map +1 -1
  135. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/checkCanRegisterUser.js +1 -0
  136. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/checkCanRegisterUser.js.map +1 -1
  137. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/decryptPrivateKeyWithPrf.js +1 -0
  138. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/decryptPrivateKeyWithPrf.js.map +1 -1
  139. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/deriveNearKeypairAndEncryptFromSerialized.js +1 -0
  140. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/deriveNearKeypairAndEncryptFromSerialized.js.map +1 -1
  141. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/exportNearKeypairUi.js +1 -0
  142. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/exportNearKeypairUi.js.map +1 -1
  143. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/registerDevice2WithDerivedKey.js +2 -1
  144. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/registerDevice2WithDerivedKey.js.map +1 -1
  145. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/signDelegateAction.js +1 -0
  146. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/signDelegateAction.js.map +1 -1
  147. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/signNep413Message.js +1 -0
  148. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/signNep413Message.js.map +1 -1
  149. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/signTransactionsWithActions.js +1 -0
  150. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/signTransactionsWithActions.js.map +1 -1
  151. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/validation.js +2 -0
  152. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/validation.js.map +1 -1
  153. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/index.js +1 -0
  154. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/index.js.map +1 -1
  155. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/vrf.js +1 -0
  156. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/vrf.js.map +1 -1
  157. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/webauthn.js +6 -0
  158. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/webauthn.js.map +1 -1
  159. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/determineConfirmationConfig.js +2 -1
  160. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/determineConfirmationConfig.js.map +1 -1
  161. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/localOnly.js +1 -0
  162. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/localOnly.js.map +1 -1
  163. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/registration.js +1 -0
  164. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/registration.js.map +1 -1
  165. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/transactions.js +4 -15
  166. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/transactions.js.map +1 -1
  167. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/handlers/deriveVrfKeypairFromPrf.js +1 -0
  168. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/handlers/deriveVrfKeypairFromPrf.js.map +1 -1
  169. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfChallenge.js +1 -0
  170. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfChallenge.js.map +1 -1
  171. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfKeypairBootstrap.js +1 -0
  172. package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfKeypairBootstrap.js.map +1 -1
  173. package/dist/cjs/react/sdk/src/core/WebAuthnManager/WebAuthnFallbacks/index.js +17 -0
  174. package/dist/cjs/react/sdk/src/core/WebAuthnManager/WebAuthnFallbacks/index.js.map +1 -0
  175. package/dist/cjs/react/sdk/src/core/WebAuthnManager/WebAuthnFallbacks/safari-fallbacks.js +64 -54
  176. package/dist/cjs/react/sdk/src/core/WebAuthnManager/WebAuthnFallbacks/safari-fallbacks.js.map +1 -1
  177. package/dist/cjs/react/sdk/src/core/WebAuthnManager/credentialsHelpers.js +12 -2
  178. package/dist/cjs/react/sdk/src/core/WebAuthnManager/credentialsHelpers.js.map +1 -1
  179. package/dist/cjs/react/sdk/src/core/WebAuthnManager/index.js +6 -1
  180. package/dist/cjs/react/sdk/src/core/WebAuthnManager/index.js.map +1 -1
  181. package/dist/cjs/react/sdk/src/core/WebAuthnManager/touchIdPrompt.js +209 -201
  182. package/dist/cjs/react/sdk/src/core/WebAuthnManager/touchIdPrompt.js.map +1 -1
  183. package/dist/cjs/react/sdk/src/core/WebAuthnManager/userHandle.js +2 -1
  184. package/dist/cjs/react/sdk/src/core/WebAuthnManager/userHandle.js.map +1 -1
  185. package/dist/cjs/react/sdk/src/core/defaultConfigs.js +1 -1
  186. package/dist/cjs/react/sdk/src/core/defaultConfigs.js.map +1 -1
  187. package/dist/cjs/react/sdk/src/core/types/vrf-worker.js +10 -1
  188. package/dist/cjs/react/sdk/src/core/types/vrf-worker.js.map +1 -1
  189. package/dist/cjs/react/sdk/src/utils/index.js +13 -3
  190. package/dist/cjs/server/email-recovery/emailEncryptor.js +11 -0
  191. package/dist/cjs/server/email-recovery/emailEncryptor.js.map +1 -1
  192. package/dist/cjs/server/email-recovery/emailParsers.js +57 -0
  193. package/dist/cjs/server/email-recovery/emailParsers.js.map +1 -1
  194. package/dist/cjs/server/email-recovery/index.js +1 -1
  195. package/dist/cjs/server/email-recovery/index.js.map +1 -1
  196. package/dist/cjs/server/email-recovery/rpcCalls.js +14 -1
  197. package/dist/cjs/server/email-recovery/rpcCalls.js.map +1 -1
  198. package/dist/cjs/server/index.js +1 -0
  199. package/dist/cjs/server/router/cloudflare.js.map +1 -1
  200. package/dist/cjs/server/router/express.js.map +1 -1
  201. package/dist/cjs/server/sdk/src/core/defaultConfigs.js +1 -1
  202. package/dist/cjs/server/sdk/src/core/defaultConfigs.js.map +1 -1
  203. package/dist/cjs/utils/index.js +13 -3
  204. package/dist/esm/core/EmailRecovery/index.js +12 -5
  205. package/dist/esm/core/EmailRecovery/index.js.map +1 -1
  206. package/dist/esm/core/IndexedDBManager/passkeyClientDB.js +35 -36
  207. package/dist/esm/core/IndexedDBManager/passkeyClientDB.js.map +1 -1
  208. package/dist/esm/core/NearClient.js +2 -1
  209. package/dist/esm/core/NearClient.js.map +1 -1
  210. package/dist/esm/core/TatchiPasskey/emailRecovery.js +136 -27
  211. package/dist/esm/core/TatchiPasskey/emailRecovery.js.map +1 -1
  212. package/dist/esm/core/TatchiPasskey/faucets/createAccountRelayServer.js +2 -1
  213. package/dist/esm/core/TatchiPasskey/faucets/createAccountRelayServer.js.map +1 -1
  214. package/dist/esm/core/TatchiPasskey/index.js +26 -1
  215. package/dist/esm/core/TatchiPasskey/index.js.map +1 -1
  216. package/dist/esm/core/TatchiPasskey/linkDevice.js +4 -2
  217. package/dist/esm/core/TatchiPasskey/linkDevice.js.map +1 -1
  218. package/dist/esm/core/TatchiPasskey/login.js +13 -7
  219. package/dist/esm/core/TatchiPasskey/login.js.map +1 -1
  220. package/dist/esm/core/TatchiPasskey/recoverAccount.js +2 -1
  221. package/dist/esm/core/TatchiPasskey/recoverAccount.js.map +1 -1
  222. package/dist/esm/core/TatchiPasskey/scanDevice.js +2 -1
  223. package/dist/esm/core/TatchiPasskey/scanDevice.js.map +1 -1
  224. package/dist/esm/core/WalletIframe/client/IframeTransport.js +11 -1
  225. package/dist/esm/core/WalletIframe/client/IframeTransport.js.map +1 -1
  226. package/dist/esm/core/WalletIframe/client/router.js +9 -0
  227. package/dist/esm/core/WalletIframe/client/router.js.map +1 -1
  228. package/dist/esm/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-drawer.js +1 -1
  229. package/dist/esm/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-drawer.js.map +1 -1
  230. package/dist/esm/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-modal.js +52 -52
  231. package/dist/esm/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-modal.js.map +1 -1
  232. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/getDeviceNumber.js +6 -2
  233. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/checkCanRegisterUser.js +2 -1
  234. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/checkCanRegisterUser.js.map +1 -1
  235. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/decryptPrivateKeyWithPrf.js +2 -1
  236. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/decryptPrivateKeyWithPrf.js.map +1 -1
  237. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/deriveNearKeypairAndEncryptFromSerialized.js +2 -1
  238. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/deriveNearKeypairAndEncryptFromSerialized.js.map +1 -1
  239. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/exportNearKeypairUi.js +2 -1
  240. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/exportNearKeypairUi.js.map +1 -1
  241. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/registerDevice2WithDerivedKey.js +2 -1
  242. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/registerDevice2WithDerivedKey.js.map +1 -1
  243. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/signDelegateAction.js +2 -1
  244. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/signDelegateAction.js.map +1 -1
  245. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/signNep413Message.js +2 -1
  246. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/signNep413Message.js.map +1 -1
  247. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/signTransactionsWithActions.js +2 -1
  248. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/signTransactionsWithActions.js.map +1 -1
  249. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/validation.js +4 -2
  250. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/validation.js.map +1 -1
  251. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/index.js +2 -1
  252. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/index.js.map +1 -1
  253. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/vrf.js +1 -0
  254. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/vrf.js.map +1 -1
  255. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/webauthn.js +8 -2
  256. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/webauthn.js.map +1 -1
  257. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/determineConfirmationConfig.js +2 -1
  258. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/determineConfirmationConfig.js.map +1 -1
  259. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/localOnly.js +2 -1
  260. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/localOnly.js.map +1 -1
  261. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/registration.js +2 -1
  262. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/registration.js.map +1 -1
  263. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/transactions.js +5 -16
  264. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/transactions.js.map +1 -1
  265. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/handlers/deriveVrfKeypairFromPrf.js +2 -1
  266. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/handlers/deriveVrfKeypairFromPrf.js.map +1 -1
  267. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfChallenge.js +2 -1
  268. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfChallenge.js.map +1 -1
  269. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfKeypairBootstrap.js +2 -1
  270. package/dist/esm/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfKeypairBootstrap.js.map +1 -1
  271. package/dist/esm/core/WebAuthnManager/WebAuthnFallbacks/index.js +12 -0
  272. package/dist/esm/core/WebAuthnManager/WebAuthnFallbacks/index.js.map +1 -0
  273. package/dist/esm/core/WebAuthnManager/WebAuthnFallbacks/safari-fallbacks.js +61 -55
  274. package/dist/esm/core/WebAuthnManager/WebAuthnFallbacks/safari-fallbacks.js.map +1 -1
  275. package/dist/esm/core/WebAuthnManager/credentialsHelpers.js +8 -3
  276. package/dist/esm/core/WebAuthnManager/index.js +8 -3
  277. package/dist/esm/core/WebAuthnManager/index.js.map +1 -1
  278. package/dist/esm/core/WebAuthnManager/touchIdPrompt.js +207 -204
  279. package/dist/esm/core/WebAuthnManager/touchIdPrompt.js.map +1 -1
  280. package/dist/esm/core/WebAuthnManager/userHandle.js +2 -1
  281. package/dist/esm/core/WebAuthnManager/userHandle.js.map +1 -1
  282. package/dist/esm/core/defaultConfigs.js +1 -1
  283. package/dist/esm/core/defaultConfigs.js.map +1 -1
  284. package/dist/esm/core/types/vrf-worker.js +6 -2
  285. package/dist/esm/react/components/AccountMenuButton/{LinkedDevicesModal-STvIsylA.css → LinkedDevicesModal-B6api181.css} +1 -1
  286. package/dist/{cjs/react/components/AccountMenuButton/LinkedDevicesModal-STvIsylA.css.map → esm/react/components/AccountMenuButton/LinkedDevicesModal-B6api181.css.map} +1 -1
  287. package/dist/esm/react/components/AccountMenuButton/{ProfileDropdown-iARgUwK1.css → ProfileDropdown-B-DrG_u5.css} +1 -1
  288. package/dist/{cjs/react/components/AccountMenuButton/ProfileDropdown-iARgUwK1.css.map → esm/react/components/AccountMenuButton/ProfileDropdown-B-DrG_u5.css.map} +1 -1
  289. package/dist/esm/react/components/AccountMenuButton/{Web3AuthProfileButton-Db3NeoAC.css → Web3AuthProfileButton-BnZDUeCL.css} +1 -1
  290. package/dist/esm/react/components/AccountMenuButton/{Web3AuthProfileButton-Db3NeoAC.css.map → Web3AuthProfileButton-BnZDUeCL.css.map} +1 -1
  291. package/dist/esm/react/components/AccountMenuButton/icons/{TouchIcon-BXM5NR4A.css → TouchIcon-CAGCi8MY.css} +1 -1
  292. package/dist/esm/react/components/AccountMenuButton/icons/{TouchIcon-BXM5NR4A.css.map → TouchIcon-CAGCi8MY.css.map} +1 -1
  293. package/dist/esm/react/components/PasskeyAuthMenu/{PasskeyAuthMenu-De1qTSmU.css → PasskeyAuthMenu-CNNxVj4L.css} +14 -1
  294. package/dist/esm/react/components/PasskeyAuthMenu/{PasskeyAuthMenu-De1qTSmU.css.map → PasskeyAuthMenu-CNNxVj4L.css.map} +1 -1
  295. package/dist/esm/react/components/PasskeyAuthMenu/ui/EmailRecoverySlide.js +123 -54
  296. package/dist/esm/react/components/PasskeyAuthMenu/ui/EmailRecoverySlide.js.map +1 -1
  297. package/dist/esm/react/components/{ShowQRCode-DCnR__fx.css → ShowQRCode-nZhZSaba.css} +1 -1
  298. package/dist/esm/react/components/{ShowQRCode-DCnR__fx.css.map → ShowQRCode-nZhZSaba.css.map} +1 -1
  299. package/dist/esm/react/deviceDetection.js +72 -93
  300. package/dist/esm/react/deviceDetection.js.map +1 -1
  301. package/dist/esm/react/hooks/usePreconnectWalletAssets.js +32 -27
  302. package/dist/esm/react/hooks/usePreconnectWalletAssets.js.map +1 -1
  303. package/dist/esm/react/hooks/useQRCamera.js +2 -1
  304. package/dist/esm/react/hooks/useQRCamera.js.map +1 -1
  305. package/dist/esm/react/sdk/src/core/EmailRecovery/index.js +12 -5
  306. package/dist/esm/react/sdk/src/core/EmailRecovery/index.js.map +1 -1
  307. package/dist/esm/react/sdk/src/core/IndexedDBManager/passkeyClientDB.js +35 -36
  308. package/dist/esm/react/sdk/src/core/IndexedDBManager/passkeyClientDB.js.map +1 -1
  309. package/dist/esm/react/sdk/src/core/NearClient.js +2 -1
  310. package/dist/esm/react/sdk/src/core/NearClient.js.map +1 -1
  311. package/dist/esm/react/sdk/src/core/TatchiPasskey/emailRecovery.js +136 -27
  312. package/dist/esm/react/sdk/src/core/TatchiPasskey/emailRecovery.js.map +1 -1
  313. package/dist/esm/react/sdk/src/core/TatchiPasskey/faucets/createAccountRelayServer.js +2 -1
  314. package/dist/esm/react/sdk/src/core/TatchiPasskey/faucets/createAccountRelayServer.js.map +1 -1
  315. package/dist/esm/react/sdk/src/core/TatchiPasskey/index.js +26 -1
  316. package/dist/esm/react/sdk/src/core/TatchiPasskey/index.js.map +1 -1
  317. package/dist/esm/react/sdk/src/core/TatchiPasskey/linkDevice.js +4 -2
  318. package/dist/esm/react/sdk/src/core/TatchiPasskey/linkDevice.js.map +1 -1
  319. package/dist/esm/react/sdk/src/core/TatchiPasskey/login.js +13 -7
  320. package/dist/esm/react/sdk/src/core/TatchiPasskey/login.js.map +1 -1
  321. package/dist/esm/react/sdk/src/core/TatchiPasskey/recoverAccount.js +2 -1
  322. package/dist/esm/react/sdk/src/core/TatchiPasskey/recoverAccount.js.map +1 -1
  323. package/dist/esm/react/sdk/src/core/TatchiPasskey/scanDevice.js +2 -1
  324. package/dist/esm/react/sdk/src/core/TatchiPasskey/scanDevice.js.map +1 -1
  325. package/dist/esm/react/sdk/src/core/WalletIframe/client/IframeTransport.js +11 -1
  326. package/dist/esm/react/sdk/src/core/WalletIframe/client/IframeTransport.js.map +1 -1
  327. package/dist/esm/react/sdk/src/core/WalletIframe/client/router.js +9 -0
  328. package/dist/esm/react/sdk/src/core/WalletIframe/client/router.js.map +1 -1
  329. package/dist/esm/react/sdk/src/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-drawer.js +1 -1
  330. package/dist/esm/react/sdk/src/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-drawer.js.map +1 -1
  331. package/dist/esm/react/sdk/src/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-modal.js +52 -52
  332. package/dist/esm/react/sdk/src/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-modal.js.map +1 -1
  333. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/getDeviceNumber.js +6 -2
  334. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/checkCanRegisterUser.js +2 -1
  335. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/checkCanRegisterUser.js.map +1 -1
  336. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/decryptPrivateKeyWithPrf.js +2 -1
  337. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/decryptPrivateKeyWithPrf.js.map +1 -1
  338. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/deriveNearKeypairAndEncryptFromSerialized.js +2 -1
  339. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/deriveNearKeypairAndEncryptFromSerialized.js.map +1 -1
  340. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/exportNearKeypairUi.js +2 -1
  341. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/exportNearKeypairUi.js.map +1 -1
  342. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/registerDevice2WithDerivedKey.js +2 -1
  343. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/registerDevice2WithDerivedKey.js.map +1 -1
  344. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/signDelegateAction.js +2 -1
  345. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/signDelegateAction.js.map +1 -1
  346. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/signNep413Message.js +2 -1
  347. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/signNep413Message.js.map +1 -1
  348. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/signTransactionsWithActions.js +2 -1
  349. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/signTransactionsWithActions.js.map +1 -1
  350. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/validation.js +4 -2
  351. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/validation.js.map +1 -1
  352. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/index.js +2 -1
  353. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/index.js.map +1 -1
  354. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/vrf.js +1 -0
  355. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/vrf.js.map +1 -1
  356. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/webauthn.js +8 -2
  357. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/webauthn.js.map +1 -1
  358. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/determineConfirmationConfig.js +2 -1
  359. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/determineConfirmationConfig.js.map +1 -1
  360. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/localOnly.js +2 -1
  361. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/localOnly.js.map +1 -1
  362. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/registration.js +2 -1
  363. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/registration.js.map +1 -1
  364. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/transactions.js +5 -16
  365. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/transactions.js.map +1 -1
  366. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/handlers/deriveVrfKeypairFromPrf.js +2 -1
  367. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/handlers/deriveVrfKeypairFromPrf.js.map +1 -1
  368. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfChallenge.js +2 -1
  369. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfChallenge.js.map +1 -1
  370. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfKeypairBootstrap.js +2 -1
  371. package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfKeypairBootstrap.js.map +1 -1
  372. package/dist/esm/react/sdk/src/core/WebAuthnManager/WebAuthnFallbacks/index.js +12 -0
  373. package/dist/esm/react/sdk/src/core/WebAuthnManager/WebAuthnFallbacks/index.js.map +1 -0
  374. package/dist/esm/react/sdk/src/core/WebAuthnManager/WebAuthnFallbacks/safari-fallbacks.js +61 -55
  375. package/dist/esm/react/sdk/src/core/WebAuthnManager/WebAuthnFallbacks/safari-fallbacks.js.map +1 -1
  376. package/dist/esm/react/sdk/src/core/WebAuthnManager/credentialsHelpers.js +8 -3
  377. package/dist/esm/react/sdk/src/core/WebAuthnManager/index.js +8 -3
  378. package/dist/esm/react/sdk/src/core/WebAuthnManager/index.js.map +1 -1
  379. package/dist/esm/react/sdk/src/core/WebAuthnManager/touchIdPrompt.js +207 -204
  380. package/dist/esm/react/sdk/src/core/WebAuthnManager/touchIdPrompt.js.map +1 -1
  381. package/dist/esm/react/sdk/src/core/WebAuthnManager/userHandle.js +2 -1
  382. package/dist/esm/react/sdk/src/core/WebAuthnManager/userHandle.js.map +1 -1
  383. package/dist/esm/react/sdk/src/core/defaultConfigs.js +1 -1
  384. package/dist/esm/react/sdk/src/core/defaultConfigs.js.map +1 -1
  385. package/dist/esm/react/sdk/src/core/types/vrf-worker.js +6 -2
  386. package/dist/esm/react/sdk/src/utils/index.js +10 -4
  387. package/dist/esm/react/styles/styles.css +13 -0
  388. package/dist/esm/sdk/{safari-fallbacks-oQKu9xUs.js → WebAuthnFallbacks-Bl4BTsNt.js} +131 -135
  389. package/dist/esm/sdk/{createAdapters-pNiL2KNq.js → createAdapters-BumKM2ft.js} +59 -54
  390. package/dist/esm/sdk/createAdapters-BumKM2ft.js.map +1 -0
  391. package/dist/esm/sdk/{createAdapters-BWLe9Ddo.js → createAdapters-qVGD6i0g.js} +10 -3
  392. package/dist/esm/sdk/{defaultConfigs-VzvDejmy.js → defaultConfigs-DpslkAQd.js} +1 -1
  393. package/dist/esm/sdk/{getDeviceNumber-CkWRT17I.js → getDeviceNumber-fXizNGQl.js} +2 -2
  394. package/dist/esm/sdk/getDeviceNumber-fXizNGQl.js.map +1 -0
  395. package/dist/esm/sdk/{getDeviceNumber-CfmlgfMX.js → getDeviceNumber-zsOHT_Um.js} +6 -3
  396. package/dist/esm/sdk/{localOnly-DnpSyDaF.js → localOnly-Byi3AK7A.js} +2 -2
  397. package/dist/esm/sdk/{localOnly-DnpSyDaF.js.map → localOnly-Byi3AK7A.js.map} +1 -1
  398. package/dist/esm/sdk/{localOnly-BdumO2st.js → localOnly-pXMTqh1m.js} +5 -4
  399. package/dist/esm/sdk/offline-export-app.js +46 -44
  400. package/dist/esm/sdk/offline-export-app.js.map +1 -1
  401. package/dist/esm/sdk/{overlay-BTqPGG-o.js → overlay-ZGbucXIa.js} +2 -0
  402. package/dist/esm/sdk/{registration-C633u6x8.js → registration-CBiS4Ua_.js} +2 -2
  403. package/dist/esm/sdk/{registration-C633u6x8.js.map → registration-CBiS4Ua_.js.map} +1 -1
  404. package/dist/esm/sdk/{registration-xyYUFRqk.js → registration-DLPLsGCz.js} +5 -4
  405. package/dist/esm/sdk/{requestHelpers-DLBGBHMw.js → requestHelpers-Dh1hEYL9.js} +206 -204
  406. package/dist/esm/sdk/{router-BG6KC_p7.js → router-BLFegW7J.js} +20 -2
  407. package/dist/esm/sdk/{rpcCalls-fLObBbbz.js → rpcCalls-DEv9x5-f.js} +2 -2
  408. package/dist/esm/sdk/{rpcCalls-CAU5XYEF.js → rpcCalls-OhgEeFig.js} +1 -1
  409. package/dist/esm/sdk/{transactions-jH38BZ-Q.js → transactions-BIqKZeR0.js} +6 -18
  410. package/dist/esm/sdk/transactions-BIqKZeR0.js.map +1 -0
  411. package/dist/esm/sdk/{transactions-CzZAt1Yn.js → transactions-Bk-VavcV.js} +10 -21
  412. package/dist/esm/sdk/tx-confirm-ui.js +53 -53
  413. package/dist/esm/sdk/{tx-confirmer-wrapper-CqfVBUaA.js → tx-confirmer-wrapper-lHNgz9i4.js} +53 -53
  414. package/dist/esm/sdk/tx-confirmer.css +6 -4
  415. package/dist/esm/sdk/w3a-tx-confirmer.js +1 -1
  416. package/dist/esm/sdk/wallet-iframe-host.js +271 -89
  417. package/dist/esm/server/email-recovery/emailEncryptor.js +11 -1
  418. package/dist/esm/server/email-recovery/emailEncryptor.js.map +1 -1
  419. package/dist/esm/server/email-recovery/emailParsers.js +55 -1
  420. package/dist/esm/server/email-recovery/emailParsers.js.map +1 -1
  421. package/dist/esm/server/email-recovery/index.js +2 -2
  422. package/dist/esm/server/email-recovery/index.js.map +1 -1
  423. package/dist/esm/server/email-recovery/rpcCalls.js +14 -1
  424. package/dist/esm/server/email-recovery/rpcCalls.js.map +1 -1
  425. package/dist/esm/server/index.js +2 -2
  426. package/dist/esm/server/router/cloudflare.js.map +1 -1
  427. package/dist/esm/server/router/express.js.map +1 -1
  428. package/dist/esm/server/sdk/src/core/defaultConfigs.js +1 -1
  429. package/dist/esm/server/sdk/src/core/defaultConfigs.js.map +1 -1
  430. package/dist/esm/utils/index.js +10 -4
  431. package/dist/esm/wasm_vrf_worker/pkg/wasm_vrf_worker.js +3 -0
  432. package/dist/esm/wasm_vrf_worker/pkg/wasm_vrf_worker_bg.wasm +0 -0
  433. package/dist/types/src/core/EmailRecovery/index.d.ts.map +1 -1
  434. package/dist/types/src/core/IndexedDBManager/passkeyClientDB.d.ts +11 -21
  435. package/dist/types/src/core/IndexedDBManager/passkeyClientDB.d.ts.map +1 -1
  436. package/dist/types/src/core/TatchiPasskey/emailRecovery.d.ts +12 -1
  437. package/dist/types/src/core/TatchiPasskey/emailRecovery.d.ts.map +1 -1
  438. package/dist/types/src/core/TatchiPasskey/index.d.ts +8 -0
  439. package/dist/types/src/core/TatchiPasskey/index.d.ts.map +1 -1
  440. package/dist/types/src/core/WalletIframe/TatchiPasskeyIframe.d.ts +4 -0
  441. package/dist/types/src/core/WalletIframe/TatchiPasskeyIframe.d.ts.map +1 -1
  442. package/dist/types/src/core/WalletIframe/client/IframeTransport.d.ts.map +1 -1
  443. package/dist/types/src/core/WalletIframe/client/router.d.ts +4 -0
  444. package/dist/types/src/core/WalletIframe/client/router.d.ts.map +1 -1
  445. package/dist/types/src/core/WalletIframe/host/wallet-iframe-handlers.d.ts.map +1 -1
  446. package/dist/types/src/core/WalletIframe/shared/messages.d.ts +6 -2
  447. package/dist/types/src/core/WalletIframe/shared/messages.d.ts.map +1 -1
  448. package/dist/types/src/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-drawer.d.ts.map +1 -1
  449. package/dist/types/src/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-modal.d.ts.map +1 -1
  450. package/dist/types/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/vrf.d.ts.map +1 -1
  451. package/dist/types/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/webauthn.d.ts.map +1 -1
  452. package/dist/types/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/transactions.d.ts.map +1 -1
  453. package/dist/types/src/core/WebAuthnManager/index.d.ts.map +1 -1
  454. package/dist/types/src/core/defaultConfigs.d.ts.map +1 -1
  455. package/dist/types/src/react/components/PasskeyAuthMenu/ui/EmailRecoverySlide.d.ts.map +1 -1
  456. package/dist/types/src/react/hooks/usePreconnectWalletAssets.d.ts.map +1 -1
  457. package/dist/types/src/server/email-recovery/emailEncryptor.d.ts +4 -0
  458. package/dist/types/src/server/email-recovery/emailEncryptor.d.ts.map +1 -1
  459. package/dist/types/src/server/email-recovery/emailParsers.d.ts +7 -0
  460. package/dist/types/src/server/email-recovery/emailParsers.d.ts.map +1 -1
  461. package/dist/types/src/server/email-recovery/index.d.ts +1 -1
  462. package/dist/types/src/server/email-recovery/rpcCalls.d.ts +1 -1
  463. package/dist/types/src/server/email-recovery/rpcCalls.d.ts.map +1 -1
  464. package/dist/types/src/wasm_vrf_worker/pkg/wasm_vrf_worker.d.ts.map +1 -1
  465. package/dist/workers/wasm_vrf_worker_bg.wasm +0 -0
  466. package/dist/workers/web3authn-vrf.worker.js +3 -0
  467. package/package.json +1 -1
  468. package/dist/esm/sdk/createAdapters-pNiL2KNq.js.map +0 -1
  469. package/dist/esm/sdk/getDeviceNumber-CkWRT17I.js.map +0 -1
  470. package/dist/esm/sdk/transactions-jH38BZ-Q.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"linkDevice.js","names":["DEVICE_LINKING_CONFIG","DeviceLinkingPhase","qrData: DeviceLinkingQRData","DeviceLinkingStatus","error: any","DeviceLinkingError","DeviceLinkingErrorCode","createNearKeypair","getDeviceLinkingAccountContractCall","parseDeviceNumber","DEFAULT_WAIT_STATUS","getLoginSession","unlockError: any","loginError: any","IndexedDBManager","actions: ActionArgsWasm[]","ActionType"],"sources":["../../../../src/core/TatchiPasskey/linkDevice.ts"],"sourcesContent":["import { DEVICE_LINKING_CONFIG } from '../../config';\nimport { createNearKeypair } from '../nearCrypto';\nimport { IndexedDBManager } from '../IndexedDBManager';\nimport { ActionType, type ActionArgsWasm } from '../types/actions';\nimport { toAccountId, type AccountId } from '../types/accountIds';\nimport {\n VRFChallenge,\n type EncryptedVRFKeypair,\n type ServerEncryptedVrfKeypair\n} from '../types/vrf-worker';\nimport { getLoginSession } from './login';\nimport type { PasskeyManagerContext } from './index';\nimport type { WebAuthnRegistrationCredential } from '../types';\nimport { DEFAULT_WAIT_STATUS } from \"../types/rpc\";\nimport { getDeviceLinkingAccountContractCall } from \"../rpcCalls\";\n\n// Lazy-load QRCode to keep it an optional peer and reduce baseline bundle size\nasync function generateQRCodeDataURL(data: string): Promise<string> {\n const { default: QRCode } = await import('qrcode');\n return QRCode.toDataURL(data, {\n width: 256,\n margin: 2,\n color: {\n dark: '#000000',\n light: '#ffffff'\n },\n errorCorrectionLevel: 'M'\n });\n}\nimport type {\n DeviceLinkingQRData,\n DeviceLinkingSession,\n StartDeviceLinkingOptionsDevice2\n} from '../types/linkDevice';\nimport { DeviceLinkingError, DeviceLinkingErrorCode } from '../types/linkDevice';\nimport { DeviceLinkingPhase, DeviceLinkingStatus } from '../types/sdkSentEvents';\nimport type { DeviceLinkingSSEEvent } from '../types/sdkSentEvents';\nimport { authenticatorsToAllowCredentials } from '../WebAuthnManager/touchIdPrompt';\nimport { parseDeviceNumber } from '../WebAuthnManager/SignerWorkerManager/getDeviceNumber';\n\n\n/**\n * Device linking flow class - manages the complete device linking process\n *\n * Usage:\n * ```typescript\n * // Device2: Generate QR and start polling\n * const flow = new LinkDeviceFlow(context, options);\n * const { qrData, qrCodeDataURL } = await flow.generateQR(accountId);\n *\n * // Device1: Scan and authorize\n * const result = await LinkDeviceFlow.scanAndLink(context, options);\n *\n * // Device2: Flow automatically completes when AddKey is detected\n * const state = flow.getState();\n * ```\n */\nexport class LinkDeviceFlow {\n private context: PasskeyManagerContext;\n private options: StartDeviceLinkingOptionsDevice2;\n private session: DeviceLinkingSession | null = null;\n private error?: Error;\n // Track explicit cancellation to short-circuit in-flight ops and logs\n private cancelled: boolean = false;\n // AddKey polling\n private pollingInterval?: NodeJS.Timeout;\n private pollGeneration = 0; // invalidate late ticks when stopping/restarting\n private readonly KEY_POLLING_INTERVAL = DEVICE_LINKING_CONFIG.TIMEOUTS.POLLING_INTERVAL_MS;\n // Registration retries\n private registrationRetryTimeout?: NodeJS.Timeout;\n private registrationRetryCount = 0;\n private readonly MAX_REGISTRATION_RETRIES = DEVICE_LINKING_CONFIG.RETRY.MAX_REGISTRATION_ATTEMPTS;\n private readonly RETRY_DELAY_MS = DEVICE_LINKING_CONFIG.TIMEOUTS.REGISTRATION_RETRY_DELAY_MS;\n // Temporary key cleanup\n private tempKeyCleanupTimer?: NodeJS.Timeout;\n private readonly TEMP_KEY_CLEANUP_DELAY_MS = DEVICE_LINKING_CONFIG.TIMEOUTS.TEMP_KEY_CLEANUP_MS;\n\n private get hookOptions() {\n return this.options?.options;\n }\n\n constructor(\n context: PasskeyManagerContext,\n options: StartDeviceLinkingOptionsDevice2\n ) {\n this.context = context;\n this.options = options;\n }\n\n // Guard helpers\n private ifActive<T>(fn: () => T): T | undefined {\n if (this.cancelled) return;\n return fn();\n }\n\n private safeOnEvent(evt: DeviceLinkingSSEEvent) {\n this.ifActive(() => this.hookOptions?.onEvent?.(evt));\n }\n\n /**\n * Device2 (companion device): Generate QR code and start polling for AddKey transaction\n *\n * Single flow:\n * - Generate a temporary NEAR keypair, discover the real account via AddKey mapping,\n * then swap the temporary key for a deterministic key derived from a passkey.\n */\n async generateQR(): Promise<{ qrData: DeviceLinkingQRData; qrCodeDataURL: string }> {\n try {\n // Generate temporary NEAR keypair WITHOUT TouchID/VRF (just for QR generation)\n const tempNearKeyResult = await this.generateTemporaryNearKeypair();\n\n // Create session with null accountId (will be discovered from polling)\n this.session = {\n accountId: null, // Will be discovered from contract polling\n deviceNumber: undefined, // Will be discovered from contract polling\n nearPublicKey: tempNearKeyResult.publicKey,\n credential: null, // Will be generated later when we know real account\n vrfChallenge: null, // Will be generated later\n phase: DeviceLinkingPhase.IDLE,\n createdAt: Date.now(),\n expiresAt: Date.now() + DEVICE_LINKING_CONFIG.TIMEOUTS.SESSION_EXPIRATION_MS,\n tempPrivateKey: tempNearKeyResult.privateKey // Store temp private key for signing later\n };\n\n // Generate QR data (works for both options)\n const qrData: DeviceLinkingQRData = {\n device2PublicKey: this.session.nearPublicKey,\n accountId: this.session.accountId || undefined, // Convert null to undefined for optional field\n timestamp: Date.now(),\n version: '1.0'\n };\n\n // Create QR code data URL\n const qrDataString = JSON.stringify(qrData);\n const qrCodeDataURL = await generateQRCodeDataURL(qrDataString);\n this.safeOnEvent({\n step: 1,\n phase: DeviceLinkingPhase.STEP_1_QR_CODE_GENERATED,\n status: DeviceLinkingStatus.PROGRESS,\n message: `QR code generated for device linking, waiting for Device1 to scan and authorize...`\n });\n\n // Start polling for AddKey transaction (guard if cancelled before reaching here)\n if (!this.cancelled) {\n this.startPolling();\n }\n this.safeOnEvent({\n step: 4,\n phase: DeviceLinkingPhase.STEP_4_POLLING,\n status: DeviceLinkingStatus.PROGRESS,\n message: `Polling contract for linked account...`\n });\n\n return { qrData, qrCodeDataURL };\n\n } catch (error: any) {\n this.error = error;\n this.safeOnEvent({\n step: 0,\n phase: DeviceLinkingPhase.DEVICE_LINKING_ERROR,\n status: DeviceLinkingStatus.ERROR,\n error: error.message,\n message: error.message,\n });\n throw new DeviceLinkingError(\n `Failed to generate device linking QR: ${error.message}`,\n DeviceLinkingErrorCode.REGISTRATION_FAILED,\n 'generation'\n );\n }\n }\n\n /**\n * Generate temporary NEAR keypair without TouchID/VRF for Option F flow\n * This creates a proper Ed25519 keypair that can be used for the QR code\n * Includes memory cleanup and automatic expiration\n */\n private async generateTemporaryNearKeypair(): Promise<{ publicKey: string; privateKey: string }> {\n // Generate a temporary random NEAR Ed25519 keypair (browser-safe)\n const { publicKey: publicKeyNear, privateKey: privateKeyNear } = await createNearKeypair();\n // Schedule automatic cleanup of the temporary key from memory\n this.scheduleTemporaryKeyCleanup(publicKeyNear);\n return {\n publicKey: publicKeyNear,\n privateKey: privateKeyNear\n };\n }\n\n /**\n * Schedule automatic cleanup of temporary private key from memory\n * This provides defense-in-depth against memory exposure\n */\n private scheduleTemporaryKeyCleanup(publicKey: string): void {\n // Clear any existing cleanup timer\n if (this.tempKeyCleanupTimer) {\n clearTimeout(this.tempKeyCleanupTimer);\n }\n this.tempKeyCleanupTimer = setTimeout(() => {\n this.cleanupTemporaryKeyFromMemory();\n }, this.TEMP_KEY_CLEANUP_DELAY_MS);\n }\n\n /**\n * Immediately clean up temporary private key from memory\n * Called on successful completion, cancellation, or timeout\n */\n private cleanupTemporaryKeyFromMemory(): void {\n if (this.session?.tempPrivateKey) {\n // Overwrite the private key string with zeros\n const keyLength = this.session.tempPrivateKey.length;\n this.session.tempPrivateKey = '0'.repeat(keyLength);\n // Then set to empty string to release memory\n this.session.tempPrivateKey = '';\n }\n // Clear the cleanup timer\n if (this.tempKeyCleanupTimer) {\n clearTimeout(this.tempKeyCleanupTimer);\n this.tempKeyCleanupTimer = undefined;\n }\n }\n\n /**\n * Device2: Start polling blockchain for AddKey transaction\n */\n private startPolling(): void {\n if (!this.session || this.cancelled) return;\n\n // Stop any existing schedule and invalidate late ticks\n this.stopPolling();\n const myGen = ++this.pollGeneration;\n\n const tick = async () => {\n if (this.cancelled || this.pollGeneration !== myGen) return;\n\n if (!this.shouldContinuePolling()) {\n this.stopPolling();\n return;\n }\n try {\n const hasKeyAdded = await this.checkForDeviceKeyAdded();\n if (this.cancelled || this.pollGeneration !== myGen) return;\n if (hasKeyAdded && this.session) {\n this.stopPolling();\n this.safeOnEvent({\n step: 5,\n phase: DeviceLinkingPhase.STEP_5_ADDKEY_DETECTED,\n status: DeviceLinkingStatus.PROGRESS,\n message: 'AddKey transaction detected, starting registration...'\n });\n this.session.phase = DeviceLinkingPhase.STEP_5_ADDKEY_DETECTED;\n this.startRegistrationWithRetries();\n return;\n }\n } catch (error: any) {\n if (this.cancelled || this.pollGeneration !== myGen) return;\n console.error('Polling error:', error);\n if (error.message?.includes('Account not found')) {\n console.warn('Account not found - stopping polling');\n this.stopPolling();\n return;\n }\n }\n\n if (!this.cancelled && this.pollGeneration === myGen) {\n this.pollingInterval = setTimeout(tick, this.KEY_POLLING_INTERVAL) as any as NodeJS.Timeout;\n }\n };\n\n this.pollingInterval = setTimeout(tick, this.KEY_POLLING_INTERVAL) as any as NodeJS.Timeout;\n }\n\n private shouldContinuePolling(): boolean {\n if (!this.session) return false;\n\n // Stop polling if we've detected AddKey and moved to registration\n if (this.session.phase === DeviceLinkingPhase.STEP_5_ADDKEY_DETECTED) {\n return false;\n }\n // Stop polling if we've completed successfully\n if (this.session.phase === DeviceLinkingPhase.STEP_7_LINKING_COMPLETE) {\n return false;\n }\n if (Date.now() > this.session.expiresAt) {\n this.error = new Error('Session expired');\n this.safeOnEvent({\n step: 0,\n phase: DeviceLinkingPhase.DEVICE_LINKING_ERROR,\n status: DeviceLinkingStatus.ERROR,\n error: this.error?.message,\n message: 'Device linking session expired',\n });\n\n return false;\n }\n\n return true;\n }\n\n /**\n * Device2: Check if device key has been added by polling contract HashMap\n */\n private async checkForDeviceKeyAdded(): Promise<boolean> {\n // If polling was cancelled or cleared, bail out early to avoid noisy logs\n if (this.cancelled || !this.pollingInterval) {\n return false;\n }\n if (!this.session?.nearPublicKey) {\n console.error(`LinkDeviceFlow: No session or public key available for polling`);\n return false;\n }\n\n try {\n const linkingResult = await getDeviceLinkingAccountContractCall(\n this.context.nearClient,\n this.context.configs.contractId,\n this.session.nearPublicKey\n );\n\n // Check again after RPC returns in case cancel happened mid-flight\n if (this.cancelled || !this.pollingInterval) {\n return false;\n }\n\n this.safeOnEvent({\n step: 4,\n phase: DeviceLinkingPhase.STEP_4_POLLING,\n status: DeviceLinkingStatus.PROGRESS,\n message: 'Polling contract for linked account...'\n });\n\n if (\n linkingResult\n && linkingResult.linkedAccountId\n && linkingResult.deviceNumber !== undefined\n ) {\n // contract returns current deviceNumber, device should be assigned next number\n const currentCounter = parseDeviceNumber(linkingResult.deviceNumber, { min: 0 });\n if (currentCounter === null) {\n console.warn(\n 'LinkDeviceFlow: Invalid deviceNumber counter returned from contract:',\n linkingResult.deviceNumber\n );\n return false;\n }\n const nextDeviceNumber = currentCounter + 1;\n console.debug(`LinkDeviceFlow: Success! Discovered linked account:`, {\n linkedAccountId: linkingResult.linkedAccountId,\n currentCounter,\n nextDeviceNumber: nextDeviceNumber,\n });\n this.session.accountId = linkingResult.linkedAccountId as AccountId;\n this.session.deviceNumber = nextDeviceNumber;\n // Store the next device number for this device\n return true;\n } else {\n if (!this.cancelled) {\n console.log(`LinkDeviceFlow: No mapping found yet...`);\n }\n }\n\n return false;\n } catch (error: any) {\n console.error(`LinkDeviceFlow: Error checking for device key addition:`, {\n error: error.message,\n stack: error.stack,\n name: error.name,\n code: error.code\n });\n\n return false;\n }\n }\n\n /**\n * Device2: Start registration process with retry logic\n */\n private startRegistrationWithRetries(): void {\n this.registrationRetryCount = 0;\n this.attemptRegistration();\n }\n\n /**\n * Device2: Attempt registration with retry logic\n */\n private attemptRegistration(): void {\n this.swapKeysAndRegisterAccount().catch((error: any) => {\n // Check if this is a retryable error\n if (this.isRetryableError(error)) {\n this.registrationRetryCount++;\n\n if (this.registrationRetryCount > this.MAX_REGISTRATION_RETRIES) {\n console.error('LinkDeviceFlow: Max registration retries exceeded, failing permanently');\n // Non-retryable error - fail permanently\n this.session!.phase = DeviceLinkingPhase.REGISTRATION_ERROR;\n this.error = error;\n this.hookOptions?.onEvent?.({\n step: 0,\n phase: DeviceLinkingPhase.REGISTRATION_ERROR,\n status: DeviceLinkingStatus.ERROR,\n error: error.message,\n message: error.message,\n });\n } else {\n console.warn(`LinkDeviceFlow: Registration failed with retryable error (attempt ${this.registrationRetryCount}/${this.MAX_REGISTRATION_RETRIES}), will retry in ${this.RETRY_DELAY_MS}ms:`, error.message);\n this.hookOptions?.onEvent?.({\n step: 5,\n phase: DeviceLinkingPhase.STEP_5_ADDKEY_DETECTED,\n status: DeviceLinkingStatus.PROGRESS,\n message: `Registration failed (${error.message}), retrying in ${this.RETRY_DELAY_MS}ms... (${this.registrationRetryCount}/${this.MAX_REGISTRATION_RETRIES})`\n });\n // Schedule retry with setTimeout\n this.registrationRetryTimeout = setTimeout(() => {\n this.attemptRegistration();\n }, this.RETRY_DELAY_MS);\n }\n } else {\n // Non-retryable error - fail permanently\n this.session!.phase = DeviceLinkingPhase.REGISTRATION_ERROR;\n this.error = error;\n this.hookOptions?.onEvent?.({\n step: 0,\n phase: DeviceLinkingPhase.REGISTRATION_ERROR,\n status: DeviceLinkingStatus.ERROR,\n error: error.message,\n message: error.message,\n });\n }\n });\n }\n\n /**\n * Device2: Complete device linking\n * 1. Derives deterministic VRF and NEAR keys using real accountID (instead of temporary keys)\n * 2. Executes Key Replacement transaction to replace temporary key with the real key\n * 3. Stores authenticator and VRF data locally, performs on-chain Device2 registration, and then auto-login.\n */\n private async swapKeysAndRegisterAccount(): Promise<void> {\n if (!this.session || !this.session.accountId) {\n throw new Error('AccountID not available for registration');\n }\n\n const realAccountId = this.session.accountId;\n\n this.safeOnEvent({\n step: 6,\n phase: DeviceLinkingPhase.STEP_6_REGISTRATION,\n status: DeviceLinkingStatus.PROGRESS,\n message: 'Storing device authenticator data locally...'\n });\n\n // Migrate/generate deterministic VRF credentials for the real account\n const deterministicKeysResult = await this.deriveDeterministicKeysAndRegisterAccount();\n\n if (!deterministicKeysResult) {\n throw new Error('Failed to derive deterministic keys');\n }\n\n if (!deterministicKeysResult.vrfChallenge) {\n throw new Error('Missing VRF challenge from deterministic key derivation');\n }\n\n // Store authenticator data locally on Device2\n await this.storeDeviceAuthenticator(deterministicKeysResult);\n\n // === NEW: Sign Device2 registration WITHOUT new prompt ===\n // Use the credential we already collected to sign the registration transaction\n // This reuses PRF outputs from the stored credential to re-derive WrapKeySeed and sign\n const registrationResult = await this.context.webAuthnManager.signDevice2RegistrationWithStoredKey({\n nearAccountId: realAccountId,\n credential: deterministicKeysResult.credential,\n vrfChallenge: deterministicKeysResult.vrfChallenge,\n deterministicVrfPublicKey: deterministicKeysResult.vrfPublicKey,\n deviceNumber: this.session.deviceNumber!,\n });\n\n if (!registrationResult.success || !registrationResult.signedTransaction) {\n throw new Error(registrationResult.error || 'Device2 registration failed');\n }\n\n // Send the signed registration transaction to NEAR\n await this.context.nearClient.sendTransaction(\n registrationResult.signedTransaction,\n DEFAULT_WAIT_STATUS.linkDeviceRegistration,\n );\n\n this.session.phase = DeviceLinkingPhase.STEP_7_LINKING_COMPLETE;\n this.registrationRetryCount = 0; // Reset retry counter on success\n this.safeOnEvent({\n step: 7,\n phase: DeviceLinkingPhase.STEP_7_LINKING_COMPLETE,\n status: DeviceLinkingStatus.SUCCESS,\n message: 'Device linking completed successfully'\n });\n\n // Auto-login for Device2 after successful device linking\n await this.attemptAutoLogin(deterministicKeysResult, this.options);\n }\n\n /**\n * Check if an error is retryable (temporary issues that can be resolved)\n */\n private isRetryableError(error: any): boolean {\n const retryableErrorMessages = [\n 'page does not have focus',\n 'a request is already pending',\n 'request is already pending',\n 'operationerror',\n 'notallowederror',\n 'the operation is not allowed at this time',\n 'network error',\n 'timeout',\n 'temporary',\n 'transient'\n ];\n\n const errorMessage = error.message?.toLowerCase() || '';\n const errorName = error.name?.toLowerCase() || '';\n\n return retryableErrorMessages.some(msg =>\n errorMessage.includes(msg.toLowerCase()) ||\n errorName.includes(msg.toLowerCase())\n );\n }\n\n /**\n * Device2: Attempt auto-login after successful device linking\n */\n private async attemptAutoLogin(\n deterministicKeysResult?: {\n encryptedVrfKeypair: EncryptedVRFKeypair;\n serverEncryptedVrfKeypair: ServerEncryptedVrfKeypair | null;\n vrfPublicKey: string;\n nearPublicKey: string;\n credential: WebAuthnRegistrationCredential;\n vrfChallenge?: VRFChallenge;\n },\n options?: StartDeviceLinkingOptionsDevice2\n ): Promise<void> {\n try {\n if (this.cancelled) {\n console.warn('LinkDeviceFlow: Auto-login aborted because flow was cancelled');\n return;\n }\n\n const sessionSnapshot = this.session;\n\n // Send additional event after successful auto-login to update React state\n options?.options?.onEvent?.({\n step: 8,\n phase: DeviceLinkingPhase.STEP_8_AUTO_LOGIN,\n status: DeviceLinkingStatus.PROGRESS,\n message: 'Logging in...'\n });\n\n if (\n !sessionSnapshot || !sessionSnapshot.accountId ||\n !sessionSnapshot.credential || !deterministicKeysResult\n ) {\n const missing = [];\n if (!sessionSnapshot) missing.push('session');\n if (!sessionSnapshot?.accountId) missing.push('accountId');\n if (!sessionSnapshot?.credential) missing.push('credential');\n if (!deterministicKeysResult) missing.push('deterministicKeysResult');\n throw new Error(`Missing required data for auto-login: ${missing.join(', ')}`);\n }\n\n const { accountId } = sessionSnapshot;\n const deviceNumberRaw = sessionSnapshot.deviceNumber;\n\n if (deviceNumberRaw == null) {\n throw new Error('Device number missing for auto-login');\n }\n\n const deviceNumber = parseDeviceNumber(deviceNumberRaw, { min: 1 });\n if (deviceNumber === null) {\n throw new Error(`Invalid device number for auto-login: ${String(deviceNumberRaw)}`);\n }\n\n // Try Shamir 3-pass unlock first if available\n if (\n deterministicKeysResult.serverEncryptedVrfKeypair &&\n deterministicKeysResult.serverEncryptedVrfKeypair.serverKeyId &&\n this.context.configs.vrfWorkerConfigs?.shamir3pass?.relayServerUrl\n ) {\n try {\n const unlockResult = await this.context.webAuthnManager.shamir3PassDecryptVrfKeypair({\n nearAccountId: accountId,\n kek_s_b64u: deterministicKeysResult.serverEncryptedVrfKeypair.kek_s_b64u,\n ciphertextVrfB64u: deterministicKeysResult.serverEncryptedVrfKeypair.ciphertextVrfB64u,\n serverKeyId: deterministicKeysResult.serverEncryptedVrfKeypair.serverKeyId,\n });\n\n if (unlockResult.success) {\n console.log('LinkDeviceFlow: Shamir 3-pass unlock successful for auto-login');\n\n if (this.cancelled) {\n console.warn('LinkDeviceFlow: Auto-login aborted after Shamir unlock because flow was cancelled');\n return;\n }\n\n // Initialize current user after successful VRF unlock\n await this.context.webAuthnManager.initializeCurrentUser(accountId, this.context.nearClient);\n // Ensure last-user device number reflects Device2 for future lookups\n await this.context.webAuthnManager.setLastUser(accountId, deviceNumber);\n\n this.hookOptions?.onEvent?.({\n step: 8,\n phase: DeviceLinkingPhase.STEP_8_AUTO_LOGIN,\n status: DeviceLinkingStatus.SUCCESS,\n message: `Welcome ${accountId}`\n });\n return; // Success, no need to try TouchID\n } else {\n console.log('LinkDeviceFlow: Shamir 3-pass unlock failed, falling back to TouchID');\n }\n } catch (error) {\n console.log('LinkDeviceFlow: Shamir 3-pass unlock error, falling back to TouchID:', error);\n }\n }\n\n // TouchID fallback unlock (no Shamir): unlock VRF keypair directly using the\n // encrypted VRF key from deterministicKeysResult. This ensures that the VRF\n // session in WASM is bound to the correct deterministic VRF key for this device.\n try {\n const nonceManager = this.context.webAuthnManager.getNonceManager();\n const {\n nextNonce: _nextNonce,\n txBlockHash,\n txBlockHeight\n } = await nonceManager.getNonceBlockHashAndHeight(this.context.nearClient);\n\n const authChallenge = await this.context.webAuthnManager.generateVrfChallengeOnce({\n userId: accountId,\n rpId: this.context.webAuthnManager.getRpId(),\n blockHash: txBlockHash,\n blockHeight: txBlockHeight,\n });\n\n const authenticators = await this.context.webAuthnManager.getAuthenticatorsByUser(accountId);\n const authCredential = await this.context.webAuthnManager.getAuthenticationCredentialsSerializedDualPrf({\n nearAccountId: accountId,\n challenge: authChallenge,\n credentialIds: authenticators.map((a) => a.credentialId),\n });\n\n const vrfUnlockResult = await this.context.webAuthnManager.unlockVRFKeypair({\n nearAccountId: accountId,\n encryptedVrfKeypair: deterministicKeysResult.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 // Initialize current user after successful VRF unlock\n await this.context.webAuthnManager.initializeCurrentUser(accountId, this.context.nearClient);\n // Ensure last-user device number reflects Device2 for future lookups\n await this.context.webAuthnManager.setLastUser(accountId, deviceNumber);\n\n this.hookOptions?.onEvent?.({\n step: 8,\n phase: DeviceLinkingPhase.STEP_8_AUTO_LOGIN,\n status: DeviceLinkingStatus.SUCCESS,\n message: `Welcome ${accountId}`\n });\n // Refresh local login state so downstream consumers pick up the device-specific\n // public key without requiring a manual re-login.\n try { await getLoginSession(this.context, accountId); } catch {}\n } catch (unlockError: any) {\n console.warn('LinkDeviceFlow: TouchID VRF unlock failed during auto-login:', unlockError);\n // Initialize current user even if VRF unlock fails; transactions will surface\n // a clearer error if VRF session is missing.\n await this.context.webAuthnManager.initializeCurrentUser(accountId, this.context.nearClient);\n await this.context.webAuthnManager.setLastUser(accountId, deviceNumber);\n\n this.hookOptions?.onEvent?.({\n step: 0,\n phase: DeviceLinkingPhase.LOGIN_ERROR,\n status: DeviceLinkingStatus.ERROR,\n error: unlockError.message,\n message: unlockError.message,\n });\n }\n } catch(loginError: any) {\n console.warn('Login failed after device linking:', loginError);\n // Don't fail the whole linking process if auto-login fails\n options?.options?.onEvent?.({\n step: 0,\n phase: DeviceLinkingPhase.LOGIN_ERROR,\n status: DeviceLinkingStatus.ERROR,\n error: loginError.message,\n message: loginError.message,\n });\n }\n }\n\n /**\n * Device2: Store authenticator data locally on Device2\n */\n private async storeDeviceAuthenticator(deterministicKeysResult: {\n encryptedVrfKeypair: EncryptedVRFKeypair;\n serverEncryptedVrfKeypair: ServerEncryptedVrfKeypair | null;\n vrfPublicKey: string;\n nearPublicKey: string;\n credential: WebAuthnRegistrationCredential;\n vrfChallenge?: VRFChallenge;\n } | undefined): Promise<void> {\n if (!this.session || !this.session.accountId) {\n throw new Error('Session or account ID not available for storing authenticator');\n }\n\n try {\n const { webAuthnManager } = this.context;\n const { credential, accountId } = this.session;\n\n // check for credential after migration (should be available for both Option E and F)\n if (!credential) {\n throw new Error('WebAuthn credential not available after VRF migration');\n }\n if (!deterministicKeysResult?.encryptedVrfKeypair) {\n throw new Error('VRF credentials not available after migration');\n }\n\n if (this.session.deviceNumber === undefined || this.session.deviceNumber === null) {\n throw new Error('Device number not available - cannot determine device-specific account ID');\n }\n\n const deviceNumber = parseDeviceNumber(this.session.deviceNumber, { min: 1 });\n if (deviceNumber === null) {\n throw new Error(`Invalid device number in session: ${String(this.session.deviceNumber)}`);\n }\n // Normalize to a number in case something wrote a numeric string.\n this.session.deviceNumber = deviceNumber;\n\n console.debug(\"Storing device authenticator data with device number: \", deviceNumber);\n // Generate device-specific account ID for storage with deviceNumber\n await webAuthnManager.storeUserData({\n nearAccountId: accountId,\n deviceNumber,\n clientNearPublicKey: deterministicKeysResult.nearPublicKey,\n lastUpdated: Date.now(),\n passkeyCredential: {\n id: credential.id,\n rawId: credential.rawId\n },\n encryptedVrfKeypair: {\n encryptedVrfDataB64u: deterministicKeysResult.encryptedVrfKeypair.encryptedVrfDataB64u,\n chacha20NonceB64u: deterministicKeysResult.encryptedVrfKeypair.chacha20NonceB64u,\n },\n serverEncryptedVrfKeypair: deterministicKeysResult.serverEncryptedVrfKeypair || undefined, // Device linking now uses Shamir 3-pass encryption\n });\n\n // Store authenticator with deviceNumber\n const attestationB64u = credential.response.attestationObject;\n const credentialPublicKey = await webAuthnManager.extractCosePublicKey(attestationB64u);\n await webAuthnManager.storeAuthenticator({\n nearAccountId: accountId,\n deviceNumber,\n credentialId: credential.rawId,\n credentialPublicKey,\n transports: ['internal'],\n name: `Device ${deviceNumber} Passkey for ${accountId.split('.')[0]}`,\n registered: new Date().toISOString(),\n syncedAt: new Date().toISOString(),\n vrfPublicKey: deterministicKeysResult.vrfPublicKey,\n });\n\n } catch (error) {\n console.error(`LinkDeviceFlow: Failed to store authenticator data:`, error);\n // Clean up any partial data on failure\n await this.cleanupFailedLinkingAttempt();\n throw error;\n }\n }\n\n /**\n * 1. Derives deterministic VRF and NEAR keys using real accountID (instead of temporary keys)\n * 2. Executes Key Replacement transaction to replace temporary key with the real key\n * 3. Stores authenticator and VRF data; on-chain registration is handled separately via VRF-driven flow.\n */\n private async deriveDeterministicKeysAndRegisterAccount(): Promise<{\n encryptedVrfKeypair: EncryptedVRFKeypair;\n serverEncryptedVrfKeypair: ServerEncryptedVrfKeypair | null;\n vrfPublicKey: string;\n nearPublicKey: string;\n credential: WebAuthnRegistrationCredential;\n vrfChallenge?: VRFChallenge;\n } | undefined> {\n\n if (!this.session || !this.session.accountId) {\n throw new Error('Session account ID not available for migration');\n };\n const realAccountId = this.session.accountId;\n\n // Use secureConfirm to collect passkey with device number inside wallet iframe\n const confirmerText = this.hookOptions?.confirmerText;\n const confirmationConfigOverride = this.hookOptions?.confirmationConfig;\n const confirm = await this.context.webAuthnManager.requestRegistrationCredentialConfirmation({\n nearAccountId: realAccountId,\n deviceNumber: this.session.deviceNumber!,\n confirmerText,\n confirmationConfigOverride,\n });\n if (!confirm.confirmed || !confirm.credential) {\n throw new Error('User cancelled link-device confirmation');\n }\n\n // Store serialized credential and vrf challenge in session\n this.session.credential = confirm.credential;\n this.session.vrfChallenge = confirm.vrfChallenge || null;\n\n // Derive deterministic VRF keypair from PRF output embedded in the credential.\n // This also loads the VRF keypair into the worker's memory (saveInMemory=true by default)\n // and automatically tracks the account ID at the TypeScript level.\n const vrfDerivationResult = await this.context.webAuthnManager.deriveVrfKeypair({\n credential: confirm.credential,\n nearAccountId: realAccountId,\n });\n\n if (!vrfDerivationResult.success || !vrfDerivationResult.encryptedVrfKeypair) {\n throw new Error('Failed to derive VRF keypair from PRF for real account');\n }\n\n // === STEP 1: Generate NEAR keypair (deterministic, no transaction signing) ===\n // Use base account ID for consistent keypair derivation across devices\n const nearKeyResultStep1 = await this.context.webAuthnManager.deriveNearKeypairAndEncryptFromSerialized({\n nearAccountId: realAccountId, // Use base account ID for consistency\n credential: confirm.credential,\n options: { deviceNumber: this.session.deviceNumber },\n // No options - just generate the keypair, don't sign registration tx yet.\n // We need the deterministic NEAR public key to get the nonce for the key replacement transaction first\n // Then once the key replacement transaction is executed, we use the deterministic key\n // to sign the registration transaction\n });\n\n if (!nearKeyResultStep1.success || !nearKeyResultStep1.publicKey) {\n throw new Error('Failed to derive NEAR keypair in step 1');\n }\n\n // === STEP 2: Execute Key Replacement Transaction ===\n this.context.webAuthnManager.getNonceManager().initializeUser(realAccountId, this.session!.nearPublicKey);\n // Initialize NonceManager with current (temporary) on-chain key\n const {\n nextNonce,\n txBlockHash\n } = await this.context.webAuthnManager.getNonceManager()\n .getNonceBlockHashAndHeight(this.context.nearClient);\n\n await this.executeKeySwapTransaction(\n nearKeyResultStep1.publicKey,\n nextNonce,\n txBlockHash\n );\n\n // After the key swap, initialize NonceManager with the newly added deterministic key\n // so future transactions and VRF flows use the correct on-chain key.\n this.context.webAuthnManager.getNonceManager().initializeUser(\n realAccountId,\n nearKeyResultStep1.publicKey\n );\n\n // Clean up any temp account VRF data.\n if (this.session?.tempPrivateKey) {\n try {\n await IndexedDBManager.nearKeysDB.deleteEncryptedKey('temp-device-linking.testnet');\n } catch {}\n // Clean up temporary private key from memory after successful completion\n this.cleanupTemporaryKeyFromMemory();\n }\n\n if (!this.session.credential) {\n throw new Error('WebAuthn credential not available after VRF migration');\n }\n\n // Return all derived values.\n const result = {\n encryptedVrfKeypair: vrfDerivationResult.encryptedVrfKeypair,\n serverEncryptedVrfKeypair: vrfDerivationResult.serverEncryptedVrfKeypair,\n vrfPublicKey: vrfDerivationResult.vrfPublicKey,\n nearPublicKey: nearKeyResultStep1.publicKey,\n credential: this.session.credential,\n vrfChallenge: this.session.vrfChallenge!\n };\n\n return result;\n }\n\n /**\n * Execute key replacement transaction for Option F flow\n * Replace temporary key with properly derived key using AddKey + DeleteKey\n */\n private async executeKeySwapTransaction(\n newPublicKey: string,\n nextNonce: string,\n txBlockHash: string\n ): Promise<void> {\n if (!this.session?.tempPrivateKey || !this.session?.accountId) {\n throw new Error('Missing temporary private key or account ID for key replacement');\n }\n\n const { tempPrivateKey, accountId, nearPublicKey: oldPublicKey } = this.session;\n\n try {\n // Build actions: AddKey new + DeleteKey old\n const actions: ActionArgsWasm[] = [\n {\n action_type: ActionType.AddKey,\n public_key: newPublicKey,\n access_key: JSON.stringify({\n // NEAR-style AccessKey JSON shape: { nonce, permission: { FullAccess: {} } }\n nonce: 0,\n permission: { FullAccess: {} },\n })\n },\n {\n action_type: ActionType.DeleteKey,\n public_key: oldPublicKey\n }\n ];\n\n // Use the webAuthnManager to sign with the temporary private key\n const keySwapResult = await this.context.webAuthnManager.signTransactionWithKeyPair({\n nearPrivateKey: tempPrivateKey,\n signerAccountId: accountId,\n receiverId: accountId,\n nonce: nextNonce,\n blockHash: txBlockHash,\n actions\n });\n\n // Broadcast the transaction\n const txResult = await this.context.nearClient.sendTransaction(\n keySwapResult.signedTransaction,\n DEFAULT_WAIT_STATUS.linkDeviceSwapKey\n );\n // Keep NonceManager in sync for the temporary key that signed this swap\n try {\n await this.context.webAuthnManager.getNonceManager().updateNonceFromBlockchain(\n this.context.nearClient,\n nextNonce\n );\n } catch (e) {\n console.warn('[LinkDeviceFlow]: Failed to update nonce after key swap broadcast:', e);\n }\n\n } catch (error) {\n console.error(`LinkDeviceFlow: Key replacement transaction failed:`, error);\n throw new Error(`Key replacement failed: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n }\n\n /**\n * Clean up failed linking attempts - remove any partially stored data\n */\n private async cleanupFailedLinkingAttempt(): Promise<void> {\n if (!this.session) {\n return;\n }\n try {\n const { credential, accountId, nearPublicKey } = this.session;\n // Clean up temporary private key from memory first\n this.cleanupTemporaryKeyFromMemory();\n // Remove any authenticator data for both base and device-specific accounts (if they were discovered)\n if (accountId && credential) {\n try { await IndexedDBManager.clientDB.deleteAllAuthenticatorsForUser(accountId); } catch {}\n try { await IndexedDBManager.clientDB.deleteUser(accountId); } catch {}\n try { await IndexedDBManager.nearKeysDB.deleteEncryptedKey(accountId); } catch {}\n }\n // Always clean up temp account VRF data (this is where initial QR generation stores data)\n try { await IndexedDBManager.nearKeysDB.deleteEncryptedKey('temp-device-linking.testnet'); } catch {}\n } catch (error) {\n console.error(`LinkDeviceFlow: Error during cleanup:`, error);\n }\n }\n\n /**\n * Stop polling - guaranteed to clear any existing interval\n */\n private stopPolling(): void {\n if (this.pollingInterval) {\n clearTimeout(this.pollingInterval);\n this.pollingInterval = undefined;\n }\n this.pollGeneration++;\n }\n\n /**\n * Stop registration retry timeout\n */\n private stopRegistrationRetry(): void {\n if (this.registrationRetryTimeout) {\n clearTimeout(this.registrationRetryTimeout);\n this.registrationRetryTimeout = undefined;\n }\n }\n\n /**\n * Get current flow state\n */\n getState() {\n return {\n phase: this.session?.phase,\n session: this.session,\n error: this.error,\n };\n }\n\n /**\n * Cancel the flow and cleanup\n */\n cancel(): void {\n this.cancelled = true;\n this.stopPolling();\n this.stopRegistrationRetry();\n this.cleanupTemporaryKeyFromMemory(); // Clean up temporary private key\n this.session = null;\n this.error = undefined;\n this.registrationRetryCount = 0;\n }\n\n /**\n * Reset flow to initial state\n */\n reset(): void {\n this.cancel();\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"linkDevice.js","names":["DEVICE_LINKING_CONFIG","DeviceLinkingPhase","qrData: DeviceLinkingQRData","DeviceLinkingStatus","error: any","DeviceLinkingError","DeviceLinkingErrorCode","createNearKeypair","getDeviceLinkingAccountContractCall","parseDeviceNumber","DEFAULT_WAIT_STATUS","getLoginSession","unlockError: any","loginError: any","IndexedDBManager","actions: ActionArgsWasm[]","ActionType"],"sources":["../../../../src/core/TatchiPasskey/linkDevice.ts"],"sourcesContent":["import { DEVICE_LINKING_CONFIG } from '../../config';\nimport { createNearKeypair } from '../nearCrypto';\nimport { IndexedDBManager } from '../IndexedDBManager';\nimport { ActionType, type ActionArgsWasm } from '../types/actions';\nimport { toAccountId, type AccountId } from '../types/accountIds';\nimport {\n VRFChallenge,\n type EncryptedVRFKeypair,\n type ServerEncryptedVrfKeypair\n} from '../types/vrf-worker';\nimport { getLoginSession } from './login';\nimport type { PasskeyManagerContext } from './index';\nimport type { WebAuthnRegistrationCredential } from '../types';\nimport { DEFAULT_WAIT_STATUS } from \"../types/rpc\";\nimport { getDeviceLinkingAccountContractCall } from \"../rpcCalls\";\n\n// Lazy-load QRCode to keep it an optional peer and reduce baseline bundle size\nasync function generateQRCodeDataURL(data: string): Promise<string> {\n const { default: QRCode } = await import('qrcode');\n return QRCode.toDataURL(data, {\n width: 256,\n margin: 2,\n color: {\n dark: '#000000',\n light: '#ffffff'\n },\n errorCorrectionLevel: 'M'\n });\n}\nimport type {\n DeviceLinkingQRData,\n DeviceLinkingSession,\n StartDeviceLinkingOptionsDevice2\n} from '../types/linkDevice';\nimport { DeviceLinkingError, DeviceLinkingErrorCode } from '../types/linkDevice';\nimport { DeviceLinkingPhase, DeviceLinkingStatus } from '../types/sdkSentEvents';\nimport type { DeviceLinkingSSEEvent } from '../types/sdkSentEvents';\nimport { authenticatorsToAllowCredentials } from '../WebAuthnManager/touchIdPrompt';\nimport { parseDeviceNumber } from '../WebAuthnManager/SignerWorkerManager/getDeviceNumber';\n\n\n/**\n * Device linking flow class - manages the complete device linking process\n *\n * Usage:\n * ```typescript\n * // Device2: Generate QR and start polling\n * const flow = new LinkDeviceFlow(context, options);\n * const { qrData, qrCodeDataURL } = await flow.generateQR(accountId);\n *\n * // Device1: Scan and authorize\n * const result = await LinkDeviceFlow.scanAndLink(context, options);\n *\n * // Device2: Flow automatically completes when AddKey is detected\n * const state = flow.getState();\n * ```\n */\nexport class LinkDeviceFlow {\n private context: PasskeyManagerContext;\n private options: StartDeviceLinkingOptionsDevice2;\n private session: DeviceLinkingSession | null = null;\n private error?: Error;\n // Track explicit cancellation to short-circuit in-flight ops and logs\n private cancelled: boolean = false;\n // AddKey polling\n private pollingInterval?: NodeJS.Timeout;\n private pollGeneration = 0; // invalidate late ticks when stopping/restarting\n private readonly KEY_POLLING_INTERVAL = DEVICE_LINKING_CONFIG.TIMEOUTS.POLLING_INTERVAL_MS;\n // Registration retries\n private registrationRetryTimeout?: NodeJS.Timeout;\n private registrationRetryCount = 0;\n private readonly MAX_REGISTRATION_RETRIES = DEVICE_LINKING_CONFIG.RETRY.MAX_REGISTRATION_ATTEMPTS;\n private readonly RETRY_DELAY_MS = DEVICE_LINKING_CONFIG.TIMEOUTS.REGISTRATION_RETRY_DELAY_MS;\n // Temporary key cleanup\n private tempKeyCleanupTimer?: NodeJS.Timeout;\n private readonly TEMP_KEY_CLEANUP_DELAY_MS = DEVICE_LINKING_CONFIG.TIMEOUTS.TEMP_KEY_CLEANUP_MS;\n\n private get hookOptions() {\n return this.options?.options;\n }\n\n constructor(\n context: PasskeyManagerContext,\n options: StartDeviceLinkingOptionsDevice2\n ) {\n this.context = context;\n this.options = options;\n }\n\n // Guard helpers\n private ifActive<T>(fn: () => T): T | undefined {\n if (this.cancelled) return;\n return fn();\n }\n\n private safeOnEvent(evt: DeviceLinkingSSEEvent) {\n this.ifActive(() => this.hookOptions?.onEvent?.(evt));\n }\n\n /**\n * Device2 (companion device): Generate QR code and start polling for AddKey transaction\n *\n * Single flow:\n * - Generate a temporary NEAR keypair, discover the real account via AddKey mapping,\n * then swap the temporary key for a deterministic key derived from a passkey.\n */\n async generateQR(): Promise<{ qrData: DeviceLinkingQRData; qrCodeDataURL: string }> {\n try {\n // Generate temporary NEAR keypair WITHOUT TouchID/VRF (just for QR generation)\n const tempNearKeyResult = await this.generateTemporaryNearKeypair();\n\n // Create session with null accountId (will be discovered from polling)\n this.session = {\n accountId: null, // Will be discovered from contract polling\n deviceNumber: undefined, // Will be discovered from contract polling\n nearPublicKey: tempNearKeyResult.publicKey,\n credential: null, // Will be generated later when we know real account\n vrfChallenge: null, // Will be generated later\n phase: DeviceLinkingPhase.IDLE,\n createdAt: Date.now(),\n expiresAt: Date.now() + DEVICE_LINKING_CONFIG.TIMEOUTS.SESSION_EXPIRATION_MS,\n tempPrivateKey: tempNearKeyResult.privateKey // Store temp private key for signing later\n };\n\n // Generate QR data (works for both options)\n const qrData: DeviceLinkingQRData = {\n device2PublicKey: this.session.nearPublicKey,\n accountId: this.session.accountId || undefined, // Convert null to undefined for optional field\n timestamp: Date.now(),\n version: '1.0'\n };\n\n // Create QR code data URL\n const qrDataString = JSON.stringify(qrData);\n const qrCodeDataURL = await generateQRCodeDataURL(qrDataString);\n this.safeOnEvent({\n step: 1,\n phase: DeviceLinkingPhase.STEP_1_QR_CODE_GENERATED,\n status: DeviceLinkingStatus.PROGRESS,\n message: `QR code generated for device linking, waiting for Device1 to scan and authorize...`\n });\n\n // Start polling for AddKey transaction (guard if cancelled before reaching here)\n if (!this.cancelled) {\n this.startPolling();\n }\n this.safeOnEvent({\n step: 4,\n phase: DeviceLinkingPhase.STEP_4_POLLING,\n status: DeviceLinkingStatus.PROGRESS,\n message: `Polling contract for linked account...`\n });\n\n return { qrData, qrCodeDataURL };\n\n } catch (error: any) {\n this.error = error;\n this.safeOnEvent({\n step: 0,\n phase: DeviceLinkingPhase.DEVICE_LINKING_ERROR,\n status: DeviceLinkingStatus.ERROR,\n error: error.message,\n message: error.message,\n });\n throw new DeviceLinkingError(\n `Failed to generate device linking QR: ${error.message}`,\n DeviceLinkingErrorCode.REGISTRATION_FAILED,\n 'generation'\n );\n }\n }\n\n /**\n * Generate temporary NEAR keypair without TouchID/VRF for Option F flow\n * This creates a proper Ed25519 keypair that can be used for the QR code\n * Includes memory cleanup and automatic expiration\n */\n private async generateTemporaryNearKeypair(): Promise<{ publicKey: string; privateKey: string }> {\n // Generate a temporary random NEAR Ed25519 keypair (browser-safe)\n const { publicKey: publicKeyNear, privateKey: privateKeyNear } = await createNearKeypair();\n // Schedule automatic cleanup of the temporary key from memory\n this.scheduleTemporaryKeyCleanup(publicKeyNear);\n return {\n publicKey: publicKeyNear,\n privateKey: privateKeyNear\n };\n }\n\n /**\n * Schedule automatic cleanup of temporary private key from memory\n * This provides defense-in-depth against memory exposure\n */\n private scheduleTemporaryKeyCleanup(publicKey: string): void {\n // Clear any existing cleanup timer\n if (this.tempKeyCleanupTimer) {\n clearTimeout(this.tempKeyCleanupTimer);\n }\n this.tempKeyCleanupTimer = setTimeout(() => {\n this.cleanupTemporaryKeyFromMemory();\n }, this.TEMP_KEY_CLEANUP_DELAY_MS);\n }\n\n /**\n * Immediately clean up temporary private key from memory\n * Called on successful completion, cancellation, or timeout\n */\n private cleanupTemporaryKeyFromMemory(): void {\n if (this.session?.tempPrivateKey) {\n // Overwrite the private key string with zeros\n const keyLength = this.session.tempPrivateKey.length;\n this.session.tempPrivateKey = '0'.repeat(keyLength);\n // Then set to empty string to release memory\n this.session.tempPrivateKey = '';\n }\n // Clear the cleanup timer\n if (this.tempKeyCleanupTimer) {\n clearTimeout(this.tempKeyCleanupTimer);\n this.tempKeyCleanupTimer = undefined;\n }\n }\n\n /**\n * Device2: Start polling blockchain for AddKey transaction\n */\n private startPolling(): void {\n if (!this.session || this.cancelled) return;\n\n // Stop any existing schedule and invalidate late ticks\n this.stopPolling();\n const myGen = ++this.pollGeneration;\n\n const tick = async () => {\n if (this.cancelled || this.pollGeneration !== myGen) return;\n\n if (!this.shouldContinuePolling()) {\n this.stopPolling();\n return;\n }\n try {\n const hasKeyAdded = await this.checkForDeviceKeyAdded();\n if (this.cancelled || this.pollGeneration !== myGen) return;\n if (hasKeyAdded && this.session) {\n this.stopPolling();\n this.safeOnEvent({\n step: 5,\n phase: DeviceLinkingPhase.STEP_5_ADDKEY_DETECTED,\n status: DeviceLinkingStatus.PROGRESS,\n message: 'AddKey transaction detected, starting registration...'\n });\n this.session.phase = DeviceLinkingPhase.STEP_5_ADDKEY_DETECTED;\n this.startRegistrationWithRetries();\n return;\n }\n } catch (error: any) {\n if (this.cancelled || this.pollGeneration !== myGen) return;\n console.error('Polling error:', error);\n if (error.message?.includes('Account not found')) {\n console.warn('Account not found - stopping polling');\n this.stopPolling();\n return;\n }\n }\n\n if (!this.cancelled && this.pollGeneration === myGen) {\n this.pollingInterval = setTimeout(tick, this.KEY_POLLING_INTERVAL) as any as NodeJS.Timeout;\n }\n };\n\n this.pollingInterval = setTimeout(tick, this.KEY_POLLING_INTERVAL) as any as NodeJS.Timeout;\n }\n\n private shouldContinuePolling(): boolean {\n if (!this.session) return false;\n\n // Stop polling if we've detected AddKey and moved to registration\n if (this.session.phase === DeviceLinkingPhase.STEP_5_ADDKEY_DETECTED) {\n return false;\n }\n // Stop polling if we've completed successfully\n if (this.session.phase === DeviceLinkingPhase.STEP_7_LINKING_COMPLETE) {\n return false;\n }\n if (Date.now() > this.session.expiresAt) {\n this.error = new Error('Session expired');\n this.safeOnEvent({\n step: 0,\n phase: DeviceLinkingPhase.DEVICE_LINKING_ERROR,\n status: DeviceLinkingStatus.ERROR,\n error: this.error?.message,\n message: 'Device linking session expired',\n });\n\n return false;\n }\n\n return true;\n }\n\n /**\n * Device2: Check if device key has been added by polling contract HashMap\n */\n private async checkForDeviceKeyAdded(): Promise<boolean> {\n // If polling was cancelled or cleared, bail out early to avoid noisy logs\n if (this.cancelled || !this.pollingInterval) {\n return false;\n }\n if (!this.session?.nearPublicKey) {\n console.error(`LinkDeviceFlow: No session or public key available for polling`);\n return false;\n }\n\n try {\n const linkingResult = await getDeviceLinkingAccountContractCall(\n this.context.nearClient,\n this.context.configs.contractId,\n this.session.nearPublicKey\n );\n\n // Check again after RPC returns in case cancel happened mid-flight\n if (this.cancelled || !this.pollingInterval) {\n return false;\n }\n\n this.safeOnEvent({\n step: 4,\n phase: DeviceLinkingPhase.STEP_4_POLLING,\n status: DeviceLinkingStatus.PROGRESS,\n message: 'Polling contract for linked account...'\n });\n\n if (\n linkingResult\n && linkingResult.linkedAccountId\n && linkingResult.deviceNumber !== undefined\n ) {\n // contract returns current deviceNumber, device should be assigned next number\n const currentCounter = parseDeviceNumber(linkingResult.deviceNumber, { min: 0 });\n if (currentCounter === null) {\n console.warn(\n 'LinkDeviceFlow: Invalid deviceNumber counter returned from contract:',\n linkingResult.deviceNumber\n );\n return false;\n }\n const nextDeviceNumber = currentCounter + 1;\n console.debug(`LinkDeviceFlow: Success! Discovered linked account:`, {\n linkedAccountId: linkingResult.linkedAccountId,\n currentCounter,\n nextDeviceNumber: nextDeviceNumber,\n });\n this.session.accountId = linkingResult.linkedAccountId as AccountId;\n this.session.deviceNumber = nextDeviceNumber;\n // Store the next device number for this device\n return true;\n } else {\n if (!this.cancelled) {\n console.log(`LinkDeviceFlow: No mapping found yet...`);\n }\n }\n\n return false;\n } catch (error: any) {\n console.error(`LinkDeviceFlow: Error checking for device key addition:`, {\n error: error.message,\n stack: error.stack,\n name: error.name,\n code: error.code\n });\n\n return false;\n }\n }\n\n /**\n * Device2: Start registration process with retry logic\n */\n private startRegistrationWithRetries(): void {\n this.registrationRetryCount = 0;\n this.attemptRegistration();\n }\n\n /**\n * Device2: Attempt registration with retry logic\n */\n private attemptRegistration(): void {\n this.swapKeysAndRegisterAccount().catch((error: any) => {\n // Check if this is a retryable error\n if (this.isRetryableError(error)) {\n this.registrationRetryCount++;\n\n if (this.registrationRetryCount > this.MAX_REGISTRATION_RETRIES) {\n console.error('LinkDeviceFlow: Max registration retries exceeded, failing permanently');\n // Non-retryable error - fail permanently\n this.session!.phase = DeviceLinkingPhase.REGISTRATION_ERROR;\n this.error = error;\n this.hookOptions?.onEvent?.({\n step: 0,\n phase: DeviceLinkingPhase.REGISTRATION_ERROR,\n status: DeviceLinkingStatus.ERROR,\n error: error.message,\n message: error.message,\n });\n } else {\n console.warn(`LinkDeviceFlow: Registration failed with retryable error (attempt ${this.registrationRetryCount}/${this.MAX_REGISTRATION_RETRIES}), will retry in ${this.RETRY_DELAY_MS}ms:`, error.message);\n this.hookOptions?.onEvent?.({\n step: 5,\n phase: DeviceLinkingPhase.STEP_5_ADDKEY_DETECTED,\n status: DeviceLinkingStatus.PROGRESS,\n message: `Registration failed (${error.message}), retrying in ${this.RETRY_DELAY_MS}ms... (${this.registrationRetryCount}/${this.MAX_REGISTRATION_RETRIES})`\n });\n // Schedule retry with setTimeout\n this.registrationRetryTimeout = setTimeout(() => {\n this.attemptRegistration();\n }, this.RETRY_DELAY_MS);\n }\n } else {\n // Non-retryable error - fail permanently\n this.session!.phase = DeviceLinkingPhase.REGISTRATION_ERROR;\n this.error = error;\n this.hookOptions?.onEvent?.({\n step: 0,\n phase: DeviceLinkingPhase.REGISTRATION_ERROR,\n status: DeviceLinkingStatus.ERROR,\n error: error.message,\n message: error.message,\n });\n }\n });\n }\n\n /**\n * Device2: Complete device linking\n * 1. Derives deterministic VRF and NEAR keys using real accountID (instead of temporary keys)\n * 2. Executes Key Replacement transaction to replace temporary key with the real key\n * 3. Stores authenticator and VRF data locally, performs on-chain Device2 registration, and then auto-login.\n */\n private async swapKeysAndRegisterAccount(): Promise<void> {\n if (!this.session || !this.session.accountId) {\n throw new Error('AccountID not available for registration');\n }\n\n const realAccountId = this.session.accountId;\n\n this.safeOnEvent({\n step: 6,\n phase: DeviceLinkingPhase.STEP_6_REGISTRATION,\n status: DeviceLinkingStatus.PROGRESS,\n message: 'Storing device authenticator data locally...'\n });\n\n // Migrate/generate deterministic VRF credentials for the real account\n const deterministicKeysResult = await this.deriveDeterministicKeysAndRegisterAccount();\n\n if (!deterministicKeysResult) {\n throw new Error('Failed to derive deterministic keys');\n }\n\n if (!deterministicKeysResult.vrfChallenge) {\n throw new Error('Missing VRF challenge from deterministic key derivation');\n }\n\n // Store authenticator data locally on Device2\n await this.storeDeviceAuthenticator(deterministicKeysResult);\n\n // === NEW: Sign Device2 registration WITHOUT new prompt ===\n // Use the credential we already collected to sign the registration transaction\n // This reuses PRF outputs from the stored credential to re-derive WrapKeySeed and sign\n const registrationResult = await this.context.webAuthnManager.signDevice2RegistrationWithStoredKey({\n nearAccountId: realAccountId,\n credential: deterministicKeysResult.credential,\n vrfChallenge: deterministicKeysResult.vrfChallenge,\n deterministicVrfPublicKey: deterministicKeysResult.vrfPublicKey,\n deviceNumber: this.session.deviceNumber!,\n });\n\n if (!registrationResult.success || !registrationResult.signedTransaction) {\n throw new Error(registrationResult.error || 'Device2 registration failed');\n }\n\n // Send the signed registration transaction to NEAR\n await this.context.nearClient.sendTransaction(\n registrationResult.signedTransaction,\n DEFAULT_WAIT_STATUS.linkDeviceRegistration,\n );\n\n this.session.phase = DeviceLinkingPhase.STEP_7_LINKING_COMPLETE;\n this.registrationRetryCount = 0; // Reset retry counter on success\n this.safeOnEvent({\n step: 7,\n phase: DeviceLinkingPhase.STEP_7_LINKING_COMPLETE,\n status: DeviceLinkingStatus.SUCCESS,\n message: 'Device linking completed successfully'\n });\n\n // Auto-login for Device2 after successful device linking\n await this.attemptAutoLogin(deterministicKeysResult, this.options);\n }\n\n /**\n * Check if an error is retryable (temporary issues that can be resolved)\n */\n private isRetryableError(error: any): boolean {\n const retryableErrorMessages = [\n 'page does not have focus',\n 'a request is already pending',\n 'request is already pending',\n 'operationerror',\n 'notallowederror',\n 'the operation is not allowed at this time',\n 'network error',\n 'timeout',\n 'temporary',\n 'transient'\n ];\n\n const errorMessage = error.message?.toLowerCase() || '';\n const errorName = error.name?.toLowerCase() || '';\n\n return retryableErrorMessages.some(msg =>\n errorMessage.includes(msg.toLowerCase()) ||\n errorName.includes(msg.toLowerCase())\n );\n }\n\n /**\n * Device2: Attempt auto-login after successful device linking\n */\n private async attemptAutoLogin(\n deterministicKeysResult?: {\n encryptedVrfKeypair: EncryptedVRFKeypair;\n serverEncryptedVrfKeypair: ServerEncryptedVrfKeypair | null;\n vrfPublicKey: string;\n nearPublicKey: string;\n credential: WebAuthnRegistrationCredential;\n vrfChallenge?: VRFChallenge;\n },\n options?: StartDeviceLinkingOptionsDevice2\n ): Promise<void> {\n try {\n if (this.cancelled) {\n console.warn('LinkDeviceFlow: Auto-login aborted because flow was cancelled');\n return;\n }\n\n const sessionSnapshot = this.session;\n\n // Send additional event after successful auto-login to update React state\n options?.options?.onEvent?.({\n step: 8,\n phase: DeviceLinkingPhase.STEP_8_AUTO_LOGIN,\n status: DeviceLinkingStatus.PROGRESS,\n message: 'Logging in...'\n });\n\n if (\n !sessionSnapshot || !sessionSnapshot.accountId ||\n !sessionSnapshot.credential || !deterministicKeysResult\n ) {\n const missing = [];\n if (!sessionSnapshot) missing.push('session');\n if (!sessionSnapshot?.accountId) missing.push('accountId');\n if (!sessionSnapshot?.credential) missing.push('credential');\n if (!deterministicKeysResult) missing.push('deterministicKeysResult');\n throw new Error(`Missing required data for auto-login: ${missing.join(', ')}`);\n }\n\n const { accountId } = sessionSnapshot;\n const deviceNumberRaw = sessionSnapshot.deviceNumber;\n\n if (deviceNumberRaw == null) {\n throw new Error('Device number missing for auto-login');\n }\n\n const deviceNumber = parseDeviceNumber(deviceNumberRaw, { min: 1 });\n if (deviceNumber === null) {\n throw new Error(`Invalid device number for auto-login: ${String(deviceNumberRaw)}`);\n }\n\n // Try Shamir 3-pass unlock first if available\n if (\n deterministicKeysResult.serverEncryptedVrfKeypair &&\n deterministicKeysResult.serverEncryptedVrfKeypair.serverKeyId &&\n this.context.configs.vrfWorkerConfigs?.shamir3pass?.relayServerUrl\n ) {\n try {\n const unlockResult = await this.context.webAuthnManager.shamir3PassDecryptVrfKeypair({\n nearAccountId: accountId,\n kek_s_b64u: deterministicKeysResult.serverEncryptedVrfKeypair.kek_s_b64u,\n ciphertextVrfB64u: deterministicKeysResult.serverEncryptedVrfKeypair.ciphertextVrfB64u,\n serverKeyId: deterministicKeysResult.serverEncryptedVrfKeypair.serverKeyId,\n });\n\n if (unlockResult.success) {\n console.log('LinkDeviceFlow: Shamir 3-pass unlock successful for auto-login');\n\n if (this.cancelled) {\n console.warn('LinkDeviceFlow: Auto-login aborted after Shamir unlock because flow was cancelled');\n return;\n }\n\n // Initialize current user after successful VRF unlock\n await this.context.webAuthnManager.initializeCurrentUser(accountId, this.context.nearClient);\n // Ensure last-user device number reflects Device2 for future lookups\n await this.context.webAuthnManager.setLastUser(accountId, deviceNumber);\n\n this.hookOptions?.onEvent?.({\n step: 8,\n phase: DeviceLinkingPhase.STEP_8_AUTO_LOGIN,\n status: DeviceLinkingStatus.SUCCESS,\n message: `Welcome ${accountId}`\n });\n return; // Success, no need to try TouchID\n } else {\n console.log('LinkDeviceFlow: Shamir 3-pass unlock failed, falling back to TouchID');\n }\n } catch (error) {\n console.log('LinkDeviceFlow: Shamir 3-pass unlock error, falling back to TouchID:', error);\n }\n }\n\n // TouchID fallback unlock (no Shamir): unlock VRF keypair directly using the\n // encrypted VRF key from deterministicKeysResult. This ensures that the VRF\n // session in WASM is bound to the correct deterministic VRF key for this device.\n try {\n const nonceManager = this.context.webAuthnManager.getNonceManager();\n const {\n nextNonce: _nextNonce,\n txBlockHash,\n txBlockHeight\n } = await nonceManager.getNonceBlockHashAndHeight(this.context.nearClient);\n\n const authChallenge = await this.context.webAuthnManager.generateVrfChallengeOnce({\n userId: accountId,\n rpId: this.context.webAuthnManager.getRpId(),\n blockHash: txBlockHash,\n blockHeight: txBlockHeight,\n });\n\n const authenticators = await this.context.webAuthnManager.getAuthenticatorsByUser(accountId);\n const authCredential = await this.context.webAuthnManager.getAuthenticationCredentialsSerializedDualPrf({\n nearAccountId: accountId,\n challenge: authChallenge,\n credentialIds: authenticators.map((a) => a.credentialId),\n });\n\n const vrfUnlockResult = await this.context.webAuthnManager.unlockVRFKeypair({\n nearAccountId: accountId,\n encryptedVrfKeypair: deterministicKeysResult.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 // Initialize current user after successful VRF unlock\n await this.context.webAuthnManager.initializeCurrentUser(accountId, this.context.nearClient);\n // Ensure last-user device number reflects Device2 for future lookups\n await this.context.webAuthnManager.setLastUser(accountId, deviceNumber);\n\n this.hookOptions?.onEvent?.({\n step: 8,\n phase: DeviceLinkingPhase.STEP_8_AUTO_LOGIN,\n status: DeviceLinkingStatus.SUCCESS,\n message: `Welcome ${accountId}`\n });\n // Refresh local login state so downstream consumers pick up the device-specific\n // public key without requiring a manual re-login.\n try { await getLoginSession(this.context, accountId); } catch {}\n } catch (unlockError: any) {\n console.warn('LinkDeviceFlow: TouchID VRF unlock failed during auto-login:', unlockError);\n // Initialize current user even if VRF unlock fails; transactions will surface\n // a clearer error if VRF session is missing.\n await this.context.webAuthnManager.initializeCurrentUser(accountId, this.context.nearClient);\n await this.context.webAuthnManager.setLastUser(accountId, deviceNumber);\n\n this.hookOptions?.onEvent?.({\n step: 0,\n phase: DeviceLinkingPhase.LOGIN_ERROR,\n status: DeviceLinkingStatus.ERROR,\n error: unlockError.message,\n message: unlockError.message,\n });\n }\n } catch(loginError: any) {\n console.warn('Login failed after device linking:', loginError);\n // Don't fail the whole linking process if auto-login fails\n options?.options?.onEvent?.({\n step: 0,\n phase: DeviceLinkingPhase.LOGIN_ERROR,\n status: DeviceLinkingStatus.ERROR,\n error: loginError.message,\n message: loginError.message,\n });\n }\n }\n\n /**\n * Device2: Store authenticator data locally on Device2\n */\n private async storeDeviceAuthenticator(deterministicKeysResult: {\n encryptedVrfKeypair: EncryptedVRFKeypair;\n serverEncryptedVrfKeypair: ServerEncryptedVrfKeypair | null;\n vrfPublicKey: string;\n nearPublicKey: string;\n credential: WebAuthnRegistrationCredential;\n vrfChallenge?: VRFChallenge;\n } | undefined): Promise<void> {\n if (!this.session || !this.session.accountId) {\n throw new Error('Session or account ID not available for storing authenticator');\n }\n\n try {\n const { webAuthnManager } = this.context;\n const { credential, accountId } = this.session;\n\n // check for credential after migration (should be available for both Option E and F)\n if (!credential) {\n throw new Error('WebAuthn credential not available after VRF migration');\n }\n if (!deterministicKeysResult?.encryptedVrfKeypair) {\n throw new Error('VRF credentials not available after migration');\n }\n\n if (this.session.deviceNumber === undefined || this.session.deviceNumber === null) {\n throw new Error('Device number not available - cannot determine device-specific account ID');\n }\n\n const deviceNumber = parseDeviceNumber(this.session.deviceNumber, { min: 1 });\n if (deviceNumber === null) {\n throw new Error(`Invalid device number in session: ${String(this.session.deviceNumber)}`);\n }\n // Normalize to a number in case something wrote a numeric string.\n this.session.deviceNumber = deviceNumber;\n\n console.debug(\"Storing device authenticator data with device number: \", deviceNumber);\n // Generate device-specific account ID for storage with deviceNumber\n await webAuthnManager.storeUserData({\n nearAccountId: accountId,\n deviceNumber,\n clientNearPublicKey: deterministicKeysResult.nearPublicKey,\n lastUpdated: Date.now(),\n passkeyCredential: {\n id: credential.id,\n rawId: credential.rawId\n },\n encryptedVrfKeypair: {\n encryptedVrfDataB64u: deterministicKeysResult.encryptedVrfKeypair.encryptedVrfDataB64u,\n chacha20NonceB64u: deterministicKeysResult.encryptedVrfKeypair.chacha20NonceB64u,\n },\n serverEncryptedVrfKeypair: deterministicKeysResult.serverEncryptedVrfKeypair || undefined, // Device linking now uses Shamir 3-pass encryption\n });\n\n // Store authenticator with deviceNumber\n const attestationB64u = credential.response.attestationObject;\n const credentialPublicKey = await webAuthnManager.extractCosePublicKey(attestationB64u);\n await webAuthnManager.storeAuthenticator({\n nearAccountId: accountId,\n deviceNumber,\n credentialId: credential.rawId,\n credentialPublicKey,\n transports: ['internal'],\n name: `Device ${deviceNumber} Passkey for ${accountId.split('.')[0]}`,\n registered: new Date().toISOString(),\n syncedAt: new Date().toISOString(),\n vrfPublicKey: deterministicKeysResult.vrfPublicKey,\n });\n\n } catch (error) {\n console.error(`LinkDeviceFlow: Failed to store authenticator data:`, error);\n // Clean up any partial data on failure\n await this.cleanupFailedLinkingAttempt();\n throw error;\n }\n }\n\n /**\n * 1. Derives deterministic VRF and NEAR keys using real accountID (instead of temporary keys)\n * 2. Executes Key Replacement transaction to replace temporary key with the real key\n * 3. Stores authenticator and VRF data; on-chain registration is handled separately via VRF-driven flow.\n */\n private async deriveDeterministicKeysAndRegisterAccount(): Promise<{\n encryptedVrfKeypair: EncryptedVRFKeypair;\n serverEncryptedVrfKeypair: ServerEncryptedVrfKeypair | null;\n vrfPublicKey: string;\n nearPublicKey: string;\n credential: WebAuthnRegistrationCredential;\n vrfChallenge?: VRFChallenge;\n } | undefined> {\n\n if (!this.session || !this.session.accountId) {\n throw new Error('Session account ID not available for migration');\n };\n const realAccountId = this.session.accountId;\n\n // Use secureConfirm to collect passkey with device number inside wallet iframe\n const confirmerText = this.hookOptions?.confirmerText;\n const confirmationConfigOverride = this.hookOptions?.confirmationConfig;\n const confirm = await this.context.webAuthnManager.requestRegistrationCredentialConfirmation({\n nearAccountId: realAccountId,\n deviceNumber: this.session.deviceNumber!,\n confirmerText,\n confirmationConfigOverride,\n });\n if (!confirm.confirmed || !confirm.credential) {\n throw new Error('User cancelled link-device confirmation');\n }\n\n // Store serialized credential and vrf challenge in session\n this.session.credential = confirm.credential;\n this.session.vrfChallenge = confirm.vrfChallenge || null;\n\n // Derive deterministic VRF keypair from PRF output embedded in the credential.\n // This also loads the VRF keypair into the worker's memory (saveInMemory=true by default)\n // and automatically tracks the account ID at the TypeScript level.\n const vrfDerivationResult = await this.context.webAuthnManager.deriveVrfKeypair({\n credential: confirm.credential,\n nearAccountId: realAccountId,\n });\n\n if (!vrfDerivationResult.success || !vrfDerivationResult.encryptedVrfKeypair) {\n throw new Error('Failed to derive VRF keypair from PRF for real account');\n }\n\n // === STEP 1: Generate NEAR keypair (deterministic, no transaction signing) ===\n // Use base account ID for consistent keypair derivation across devices\n const nearKeyResultStep1 = await this.context.webAuthnManager.deriveNearKeypairAndEncryptFromSerialized({\n nearAccountId: realAccountId, // Use base account ID for consistency\n credential: confirm.credential,\n options: { deviceNumber: this.session.deviceNumber },\n // No options - just generate the keypair, don't sign registration tx yet.\n // We need the deterministic NEAR public key to get the nonce for the key replacement transaction first\n // Then once the key replacement transaction is executed, we use the deterministic key\n // to sign the registration transaction\n });\n\n if (!nearKeyResultStep1.success || !nearKeyResultStep1.publicKey) {\n throw new Error('Failed to derive NEAR keypair in step 1');\n }\n\n // === STEP 2: Execute Key Replacement Transaction ===\n this.context.webAuthnManager.getNonceManager().initializeUser(realAccountId, this.session!.nearPublicKey);\n // Initialize NonceManager with current (temporary) on-chain key\n const {\n nextNonce,\n txBlockHash\n } = await this.context.webAuthnManager.getNonceManager()\n .getNonceBlockHashAndHeight(this.context.nearClient);\n\n await this.executeKeySwapTransaction(\n nearKeyResultStep1.publicKey,\n nextNonce,\n txBlockHash\n );\n\n // After the key swap, initialize NonceManager with the newly added deterministic key\n // so future transactions and VRF flows use the correct on-chain key.\n this.context.webAuthnManager.getNonceManager().initializeUser(\n realAccountId,\n nearKeyResultStep1.publicKey\n );\n\n // Clean up any temp account VRF data.\n if (this.session?.tempPrivateKey) {\n try {\n await IndexedDBManager.nearKeysDB.deleteEncryptedKey('temp-device-linking.testnet');\n } catch {}\n // Clean up temporary private key from memory after successful completion\n this.cleanupTemporaryKeyFromMemory();\n }\n\n if (!this.session.credential) {\n throw new Error('WebAuthn credential not available after VRF migration');\n }\n\n // Return all derived values.\n const result = {\n encryptedVrfKeypair: vrfDerivationResult.encryptedVrfKeypair,\n serverEncryptedVrfKeypair: vrfDerivationResult.serverEncryptedVrfKeypair,\n vrfPublicKey: vrfDerivationResult.vrfPublicKey,\n nearPublicKey: nearKeyResultStep1.publicKey,\n credential: this.session.credential,\n vrfChallenge: this.session.vrfChallenge!\n };\n\n return result;\n }\n\n /**\n * Execute key replacement transaction for Option F flow\n * Replace temporary key with properly derived key using AddKey + DeleteKey\n */\n private async executeKeySwapTransaction(\n newPublicKey: string,\n nextNonce: string,\n txBlockHash: string\n ): Promise<void> {\n if (!this.session?.tempPrivateKey || !this.session?.accountId) {\n throw new Error('Missing temporary private key or account ID for key replacement');\n }\n\n const { tempPrivateKey, accountId, nearPublicKey: oldPublicKey } = this.session;\n\n try {\n // Build actions: AddKey new + DeleteKey old\n const actions: ActionArgsWasm[] = [\n {\n action_type: ActionType.AddKey,\n public_key: newPublicKey,\n access_key: JSON.stringify({\n // NEAR-style AccessKey JSON shape: { nonce, permission: { FullAccess: {} } }\n nonce: 0,\n permission: { FullAccess: {} },\n })\n },\n {\n action_type: ActionType.DeleteKey,\n public_key: oldPublicKey\n }\n ];\n\n // Use the webAuthnManager to sign with the temporary private key\n const keySwapResult = await this.context.webAuthnManager.signTransactionWithKeyPair({\n nearPrivateKey: tempPrivateKey,\n signerAccountId: accountId,\n receiverId: accountId,\n nonce: nextNonce,\n blockHash: txBlockHash,\n actions\n });\n\n // Broadcast the transaction\n const txResult = await this.context.nearClient.sendTransaction(\n keySwapResult.signedTransaction,\n DEFAULT_WAIT_STATUS.linkDeviceSwapKey\n );\n // Keep NonceManager in sync for the temporary key that signed this swap\n try {\n await this.context.webAuthnManager.getNonceManager().updateNonceFromBlockchain(\n this.context.nearClient,\n nextNonce\n );\n } catch (e) {\n console.warn('[LinkDeviceFlow]: Failed to update nonce after key swap broadcast:', e);\n }\n\n } catch (error) {\n console.error(`LinkDeviceFlow: Key replacement transaction failed:`, error);\n throw new Error(`Key replacement failed: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n }\n\n /**\n * Clean up failed linking attempts - remove any partially stored data\n */\n private async cleanupFailedLinkingAttempt(): Promise<void> {\n if (!this.session) {\n return;\n }\n try {\n const { credential, accountId, nearPublicKey } = this.session;\n // Clean up temporary private key from memory first\n this.cleanupTemporaryKeyFromMemory();\n // Remove any authenticator data for both base and device-specific accounts (if they were discovered)\n if (accountId && credential) {\n try { await IndexedDBManager.clientDB.deleteAllAuthenticatorsForUser(accountId); } catch {}\n try { await IndexedDBManager.clientDB.deleteUser(accountId); } catch {}\n try { await IndexedDBManager.nearKeysDB.deleteEncryptedKey(accountId); } catch {}\n }\n // Always clean up temp account VRF data (this is where initial QR generation stores data)\n try { await IndexedDBManager.nearKeysDB.deleteEncryptedKey('temp-device-linking.testnet'); } catch {}\n } catch (error) {\n console.error(`LinkDeviceFlow: Error during cleanup:`, error);\n }\n }\n\n /**\n * Stop polling - guaranteed to clear any existing interval\n */\n private stopPolling(): void {\n if (this.pollingInterval) {\n clearTimeout(this.pollingInterval);\n this.pollingInterval = undefined;\n }\n this.pollGeneration++;\n }\n\n /**\n * Stop registration retry timeout\n */\n private stopRegistrationRetry(): void {\n if (this.registrationRetryTimeout) {\n clearTimeout(this.registrationRetryTimeout);\n this.registrationRetryTimeout = undefined;\n }\n }\n\n /**\n * Get current flow state\n */\n getState() {\n return {\n phase: this.session?.phase,\n session: this.session,\n error: this.error,\n };\n }\n\n /**\n * Cancel the flow and cleanup\n */\n cancel(): void {\n this.cancelled = true;\n this.stopPolling();\n this.stopRegistrationRetry();\n this.cleanupTemporaryKeyFromMemory(); // Clean up temporary private key\n this.session = null;\n this.error = undefined;\n this.registrationRetryCount = 0;\n }\n\n /**\n * Reset flow to initial state\n */\n reset(): void {\n this.cancel();\n }\n}\n"],"mappings":"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"}
@@ -7,10 +7,6 @@ const require_sdkSentEvents = require('../types/sdkSentEvents.js');
7
7
  const require_rpcCalls = require('../rpcCalls.js');
8
8
 
9
9
  //#region src/core/TatchiPasskey/login.ts
10
- require_sdkSentEvents.init_sdkSentEvents();
11
- require_errors.init_errors();
12
- require_index.init_IndexedDBManager();
13
- require_rpcCalls.init_rpcCalls();
14
10
  /**
15
11
  * Core login function that handles passkey authentication without React dependencies.
16
12
  *
@@ -558,10 +554,25 @@ async function logoutAndClearSession(context) {
558
554
  webAuthnManager.getNonceManager().clear();
559
555
  } catch {}
560
556
  }
557
+ var init_login = require_rolldown_runtime.__esm({ "src/core/TatchiPasskey/login.ts": (() => {
558
+ require_sdkSentEvents.init_sdkSentEvents();
559
+ require_errors.init_errors();
560
+ require_vrf_worker.init_vrf_worker();
561
+ require_touchIdPrompt.init_touchIdPrompt();
562
+ require_index.init_IndexedDBManager();
563
+ require_rpcCalls.init_rpcCalls();
564
+ }) });
561
565
 
562
566
  //#endregion
567
+ init_login();
563
568
  exports.getLoginSession = getLoginSession;
564
569
  exports.getRecentLogins = getRecentLogins;
570
+ Object.defineProperty(exports, 'init_login', {
571
+ enumerable: true,
572
+ get: function () {
573
+ return init_login;
574
+ }
575
+ });
565
576
  exports.loginAndCreateSession = loginAndCreateSession;
566
577
  exports.logoutAndClearSession = logoutAndClearSession;
567
578
  //# sourceMappingURL=login.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"login.js","names":["LoginPhase","LoginStatus","signingSession: SigningSessionStatus","finalResult","authenticatorsToAllowCredentials","verifyAuthenticationResponse","e: any","getUserFriendlyErrorMessage","err: any","createRandomVRFChallenge","IndexedDBManager","unlockResult: { success: boolean; error?: string }","unlockCredential: WebAuthnAuthenticationCredential | undefined","error: any","relayerUrl","refreshErr: any","result: LoginResult"],"sources":["../../../../src/core/TatchiPasskey/login.ts"],"sourcesContent":["import type {\n AfterCall,\n LoginHooksOptions,\n LoginSSEvent,\n} from '../types/sdkSentEvents';\nimport { LoginPhase, LoginStatus } from '../types/sdkSentEvents';\nimport type {\n GetRecentLoginsResult,\n LoginAndCreateSessionResult,\n LoginResult,\n LoginSession,\n LoginState,\n SigningSessionStatus,\n} from '../types/tatchi';\nimport type { PasskeyManagerContext } from './index';\nimport type { AccountId } from '../types/accountIds';\nimport type { WebAuthnAuthenticationCredential } from '../types/webauthn';\nimport { getUserFriendlyErrorMessage } from '../../utils/errors';\nimport { createRandomVRFChallenge, ServerEncryptedVrfKeypair, VRFChallenge } from '../types/vrf-worker';\nimport { authenticatorsToAllowCredentials } from '../WebAuthnManager/touchIdPrompt';\nimport { IndexedDBManager } from '../IndexedDBManager';\nimport type { ClientAuthenticatorData, ClientUserData } from '../IndexedDBManager';\nimport { verifyAuthenticationResponse } from '../rpcCalls';\n\n/**\n * Core login function that handles passkey authentication without React dependencies.\n *\n * - Unlocks the VRF keypair (Shamir 3‑pass auto‑unlock when possible; falls back to TouchID).\n * - Updates local login state and returns success with account/public key info.\n * - Optional: mints a server session when `options.session` is provided.\n * - Generates a fresh, chain‑anchored VRF challenge (using latest block).\n * - Collects a WebAuthn assertion over the VRF output and posts to the relay route\n * (defaults to `/verify-authentication-response`).\n * - When `kind: 'jwt'`, returns the token in `result.jwt`.\n * - When `kind: 'cookie'`, the server sets an HttpOnly cookie and no JWT is returned.\n */\nexport async function loginAndCreateSession(\n context: PasskeyManagerContext,\n nearAccountId: AccountId,\n options?: LoginHooksOptions\n): Promise<LoginAndCreateSessionResult> {\n\n const { onEvent, onError, afterCall } = options || {};\n const { webAuthnManager } = context;\n\n onEvent?.({\n step: 1,\n phase: LoginPhase.STEP_1_PREPARATION,\n status: LoginStatus.PROGRESS,\n message: `Starting login for ${nearAccountId}`\n });\n\n const prevStatus = await webAuthnManager.checkVrfStatus();\n const prevVrfAccountId = prevStatus?.active ? prevStatus.nearAccountId : null;\n\n // If this call activates VRF then fails, clear the partial session.\n const rollbackVrfOnFailure = async () => {\n const status = await webAuthnManager.checkVrfStatus();\n const current = status?.active ? status.nearAccountId : null;\n if (current && current !== prevVrfAccountId) {\n await logoutAndClearSession(context);\n }\n };\n\n try {\n // Validation\n if (!window.isSecureContext) {\n const errorMessage = 'Passkey operations require a secure context (HTTPS or localhost).';\n const error = new Error(errorMessage);\n onError?.(error);\n onEvent?.({\n step: 0,\n phase: LoginPhase.LOGIN_ERROR,\n status: LoginStatus.ERROR,\n message: errorMessage,\n error: errorMessage\n });\n const result = { success: false, error: errorMessage };\n return result;\n }\n\n // Handle login and unlock VRF keypair in VRF WASM worker for WebAuthn challenge generation\n const wantsSession = options?.session?.kind == 'jwt' || options?.session?.kind == 'cookie';\n const base = await handleLoginUnlockVRF(\n context,\n nearAccountId,\n onEvent,\n onError,\n afterCall,\n // Defer final 'login-complete' event & afterCall until warm signing session is minted\n true\n );\n // If base login failed, just return\n if (!base.result.success) return base.result;\n\n const attachSigningSession = async (result: LoginResult): Promise<LoginAndCreateSessionResult> => {\n if (!result?.success) return result;\n try {\n const signingSession: SigningSessionStatus = await webAuthnManager.getWarmSigningSessionStatus(nearAccountId);\n return { ...result, signingSession };\n } catch {\n return result;\n }\n };\n\n // Resolve default warm signing session policy from configs.\n const ttlMsDefault = context.configs.signingSessionDefaults.ttlMs;\n const remainingUsesDefault = context.configs.signingSessionDefaults.remainingUses;\n const ttlMs = options?.signingSession?.ttlMs ?? ttlMsDefault;\n const remainingUses = options?.signingSession?.remainingUses ?? remainingUsesDefault;\n\n // Optionally mint a server session (JWT or HttpOnly cookie).\n // When requested, we also mint the warm signing session using the same WebAuthn prompt\n // so Shamir auto-unlock remains a single-prompt login UX.\n if (wantsSession) {\n const { kind, relayUrl: relayUrlOverride, route: routeOverride } = options!.session!;\n const relayUrl = (relayUrlOverride || context.configs.relayer.url).trim();\n const route = (routeOverride || '/verify-authentication-response').trim();\n if (!relayUrl) {\n // No relay; return base result without session\n console.warn(\"No relayUrl provided for session\");\n // Ensure a warm signing session is minted for local signing UX.\n await mintWarmSigningSession({\n context,\n nearAccountId,\n onEvent,\n credential: base.unlockCredential,\n ttlMs,\n remainingUses,\n });\n\n const finalResult = await attachSigningSession(base.result);\n // Emit completion now since we deferred it\n onEvent?.({\n step: 4,\n phase: LoginPhase.STEP_4_LOGIN_COMPLETE,\n status: LoginStatus.SUCCESS,\n message: 'Login completed successfully',\n nearAccountId: nearAccountId,\n clientNearPublicKey: base.result?.clientNearPublicKey || ''\n } as unknown as LoginSSEvent);\n await afterCall?.(true, finalResult);\n return finalResult;\n }\n try {\n // Build a fresh VRF challenge using current block\n const blockInfo = await context.nearClient.viewBlock({ finality: 'final' });\n const txBlockHash = blockInfo?.header?.hash;\n const txBlockHeight = String(blockInfo.header?.height ?? '');\n const vrfChallenge = await webAuthnManager.generateVrfChallengeOnce({\n userId: nearAccountId,\n rpId: webAuthnManager.getRpId(),\n blockHash: txBlockHash,\n blockHeight: txBlockHeight,\n });\n const authenticators = await webAuthnManager.getAuthenticatorsByUser(nearAccountId);\n const credential = await webAuthnManager.getAuthenticationCredentialsSerialized({\n nearAccountId,\n challenge: vrfChallenge,\n allowCredentials: authenticatorsToAllowCredentials(authenticators),\n });\n\n // Align lastUser deviceNumber with the passkey actually chosen for session minting.\n try {\n if (authenticators.length > 1) {\n const rawId = credential.rawId;\n const matched = authenticators.find((a) => a.credentialId === rawId);\n if (matched && typeof matched.deviceNumber === 'number') {\n await context.webAuthnManager.setLastUser(nearAccountId, matched.deviceNumber);\n }\n }\n } catch {\n // Non-fatal; session minting can proceed even if last-user update fails here.\n }\n\n // Mint the warm signing session using the same prompt used for server-session verification.\n await mintWarmSigningSession({\n context,\n nearAccountId,\n onEvent,\n credential,\n ttlMs,\n remainingUses,\n });\n\n const v = await verifyAuthenticationResponse(relayUrl, route, kind as 'jwt' | 'cookie', vrfChallenge, credential);\n if (v.success && v.verified) {\n const finalResult = await attachSigningSession({ ...base.result, jwt: v.jwt });\n // Now fire completion event and afterCall since we deferred them\n onEvent?.({\n step: 4,\n phase: LoginPhase.STEP_4_LOGIN_COMPLETE,\n status: LoginStatus.SUCCESS,\n message: 'Login completed successfully',\n nearAccountId: nearAccountId,\n clientNearPublicKey: base.result?.clientNearPublicKey || ''\n } as unknown as LoginSSEvent);\n await afterCall?.(true, finalResult);\n return finalResult;\n }\n // Session verification returned an error; surface error and afterCall(false)\n const errMsg = v.error || 'Session verification failed';\n await rollbackVrfOnFailure();\n onEvent?.({\n step: 0,\n phase: LoginPhase.LOGIN_ERROR,\n status: LoginStatus.ERROR,\n message: errMsg,\n error: errMsg\n } as unknown as LoginSSEvent);\n await afterCall?.(false as any);\n return { success: false, error: errMsg };\n } catch (e: any) {\n console.error(\"Failed to start session: \", e);\n const errMsg = getUserFriendlyErrorMessage(e, 'login') || (e?.message || 'Session verification failed');\n await rollbackVrfOnFailure();\n onError?.(e);\n onEvent?.({\n step: 0,\n phase: LoginPhase.LOGIN_ERROR,\n status: LoginStatus.ERROR,\n message: errMsg,\n error: errMsg\n } as unknown as LoginSSEvent);\n await afterCall?.(false as any);\n return { success: false, error: errMsg };\n }\n }\n\n // No server session requested: mint/refresh the warm signing session.\n await mintWarmSigningSession({\n context,\n nearAccountId,\n onEvent,\n credential: base.unlockCredential,\n ttlMs,\n remainingUses,\n });\n\n const finalResult = await attachSigningSession(base.result);\n // Fire completion event and afterCall since we deferred them.\n onEvent?.({\n step: 4,\n phase: LoginPhase.STEP_4_LOGIN_COMPLETE,\n status: LoginStatus.SUCCESS,\n message: 'Login completed successfully',\n nearAccountId: nearAccountId,\n clientNearPublicKey: base.result?.clientNearPublicKey || ''\n } as unknown as LoginSSEvent);\n await afterCall?.(true, finalResult);\n return finalResult;\n\n } catch (err: any) {\n\n await rollbackVrfOnFailure();\n onError?.(err);\n const errorMessage = getUserFriendlyErrorMessage(err, 'login') || err?.message || 'Login failed';\n onEvent?.({\n step: 0,\n phase: LoginPhase.LOGIN_ERROR,\n status: LoginStatus.ERROR,\n message: errorMessage,\n error: errorMessage\n });\n const result = { success: false, error: errorMessage };\n afterCall?.(false);\n return result;\n }\n}\n\n/**\n * Mint or refresh a \"warm signing session\" in the VRF worker.\n *\n * Notes:\n * - Reuses a previously collected WebAuthn credential when provided (e.g. TouchID fallback),\n * to avoid prompting the user twice in a single login flow.\n * - Session TTL/remainingUses policy is enforced by the VRF worker.\n */\nasync function mintWarmSigningSession(args: {\n context: PasskeyManagerContext;\n nearAccountId: AccountId;\n onEvent?: (event: LoginSSEvent) => void;\n credential?: WebAuthnAuthenticationCredential;\n ttlMs: number;\n remainingUses: number;\n}): Promise<void> {\n const { context, nearAccountId, onEvent, credential, ttlMs, remainingUses } = args;\n const { webAuthnManager } = context;\n\n onEvent?.({\n step: 3,\n phase: LoginPhase.STEP_3_VRF_UNLOCK,\n status: LoginStatus.PROGRESS,\n message: 'Unlocking warm signing session...'\n });\n\n // If we already performed a TouchID ceremony (e.g., VRF unlock fallback),\n // reuse that credential to avoid a second prompt.\n let effectiveCredential = credential;\n if (!effectiveCredential) {\n const challenge = createRandomVRFChallenge();\n const authenticators = await webAuthnManager.getAuthenticatorsByUser(nearAccountId);\n const { authenticatorsForPrompt } = await IndexedDBManager.clientDB.ensureCurrentPasskey(\n nearAccountId,\n authenticators,\n );\n effectiveCredential = await webAuthnManager.getAuthenticationCredentialsSerialized({\n nearAccountId,\n challenge: challenge as VRFChallenge,\n allowCredentials: authenticatorsToAllowCredentials(authenticatorsForPrompt),\n });\n }\n\n await webAuthnManager.mintSigningSessionFromCredential({\n nearAccountId,\n credential: effectiveCredential,\n ttlMs,\n remainingUses,\n });\n\n onEvent?.({\n step: 3,\n phase: LoginPhase.STEP_3_VRF_UNLOCK,\n status: LoginStatus.SUCCESS,\n message: 'Warm signing session unlocked'\n });\n}\n\n/**\n * Handle onchain (serverless) login using VRF flow per docs/vrf_challenges.md\n *\n * VRF AUTHENTICATION FLOW:\n * 1. Unlock VRF keypair in VRF Worker memory, either\n * - Decrypt via Shamir 3-pass (when Relayer is present), or\n * - Re-derive the VRF via credentials inside VRF worker dynamically\n * 2. Generate VRF challenge using stored VRF keypair + NEAR block data (no TouchID needed)\n * 3. Use VRF output as WebAuthn challenge for authentication\n * 4. Verify VRF proof and WebAuthn response on contract simultaneously\n * - VRF proof assures WebAuthn challenge is fresh and valid (replay protection)\n * - WebAuthn verification for origin + biometric credentials + device authenticity\n */\nasync function handleLoginUnlockVRF(\n context: PasskeyManagerContext,\n nearAccountId: AccountId,\n onEvent?: (event: LoginSSEvent) => void,\n onError?: (error: Error) => void,\n afterCall?: AfterCall<any>,\n deferCompletionHooks?: boolean,\n): Promise<{\n result: LoginResult;\n usedFallbackTouchId: boolean;\n unlockCredential?: WebAuthnAuthenticationCredential;\n}> {\n const { webAuthnManager } = context;\n\n try {\n // Step 1: Get VRF credentials and authenticators, and validate them\n const [lastUser, latestByAccount, authenticators] = await Promise.all([\n webAuthnManager.getLastUser(),\n IndexedDBManager.clientDB.getLastDBUpdatedUser(nearAccountId),\n webAuthnManager.getAuthenticatorsByUser(nearAccountId),\n ]);\n\n // Prefer the most recently updated record for this account; fall back to lastUser pointer.\n let userData = null as (typeof lastUser) | null;\n if (latestByAccount && latestByAccount.nearAccountId === nearAccountId) {\n userData = latestByAccount;\n } else if (lastUser && lastUser.nearAccountId === nearAccountId) {\n userData = lastUser;\n } else {\n userData = await webAuthnManager.getUserByDevice(nearAccountId, 1);\n }\n\n // Validate user data and authenticators\n if (!userData) {\n throw new Error(`User data not found for ${nearAccountId} in IndexedDB. Please register an account.`);\n }\n if (!userData.clientNearPublicKey) {\n throw new Error(`No NEAR public key found for ${nearAccountId}. Please register an account.`);\n }\n if (\n !userData.encryptedVrfKeypair?.encryptedVrfDataB64u ||\n !userData.encryptedVrfKeypair?.chacha20NonceB64u\n ) {\n throw new Error('No VRF credentials found. Please register an account.');\n }\n if (authenticators.length === 0) {\n throw new Error(`No authenticators found for account ${nearAccountId}. Please register.`);\n }\n\n // Step 2: Try Shamir 3-pass commutative unlock first (no TouchID required), fallback to TouchID\n onEvent?.({\n step: 2,\n phase: LoginPhase.STEP_2_WEBAUTHN_ASSERTION,\n status: LoginStatus.PROGRESS,\n message: 'Unlocking VRF keys...'\n });\n\n let unlockResult: { success: boolean; error?: string } = { success: false };\n let usedFallbackTouchId = false;\n let unlockCredential: WebAuthnAuthenticationCredential | undefined;\n let activeDeviceNumber = userData.deviceNumber;\n // Effective user row whose VRF/NEAR keys are actually used for this login.\n // May be switched when multiple devices exist and the user picks a different passkey.\n let effectiveUserData = userData;\n\n const hasServerEncrypted = !!userData.serverEncryptedVrfKeypair;\n const relayerUrl = context.configs.relayer?.url;\n const useShamir3PassVRFKeyUnlock = hasServerEncrypted && !!relayerUrl && !!userData.serverEncryptedVrfKeypair?.serverKeyId;\n\n if (useShamir3PassVRFKeyUnlock) {\n try {\n const shamir = userData.serverEncryptedVrfKeypair as ServerEncryptedVrfKeypair;\n if (!shamir.ciphertextVrfB64u || !shamir.kek_s_b64u) {\n throw new Error('Missing Shamir3Pass fields (ciphertextVrfB64u/kek_s_b64u)');\n }\n\n unlockResult = await webAuthnManager.shamir3PassDecryptVrfKeypair({\n nearAccountId,\n kek_s_b64u: shamir.kek_s_b64u,\n ciphertextVrfB64u: shamir.ciphertextVrfB64u,\n serverKeyId: shamir.serverKeyId,\n });\n\n if (unlockResult.success) {\n const vrfStatus = await webAuthnManager.checkVrfStatus();\n const active = vrfStatus.active && vrfStatus.nearAccountId === nearAccountId;\n if (!active) {\n unlockResult = { success: false, error: 'VRF session inactive after Shamir3Pass' };\n }\n if (active) {\n // Proactive rotation if serverKeyId changed and we unlocked via Shamir\n await webAuthnManager.maybeProactiveShamirRefresh(nearAccountId);\n }\n } else {\n throw new Error(`Shamir3Pass auto-unlock failed: ${unlockResult.error}`);\n }\n } catch (error: any) {\n unlockResult = { success: false, error: error.message };\n }\n }\n\n // Fallback to TouchID if Shamir3Pass decryption failed\n if (!unlockResult.success) {\n const fallback = await fallbackUnlockVrfKeypairWithTouchId({\n webAuthnManager,\n nearAccountId,\n authenticators,\n userData,\n onEvent,\n });\n unlockResult = fallback.unlockResult;\n usedFallbackTouchId = fallback.usedFallbackTouchId;\n unlockCredential = fallback.unlockCredential;\n effectiveUserData = fallback.effectiveUserData;\n activeDeviceNumber = fallback.activeDeviceNumber;\n }\n\n if (!unlockResult.success) {\n throw new Error(`Failed to unlock VRF keypair: ${unlockResult.error}`);\n }\n\n onEvent?.({\n step: 3,\n phase: LoginPhase.STEP_3_VRF_UNLOCK,\n status: LoginStatus.SUCCESS,\n message: 'VRF keypair unlocked successfully'\n });\n\n // Proactive refresh: if Shamir3Pass failed and we used TouchID, re-encrypt under current server key\n try {\n const relayerUrl = context.configs.relayer?.url;\n if (usedFallbackTouchId && relayerUrl) {\n const refreshed = await webAuthnManager.shamir3PassEncryptCurrentVrfKeypair();\n await webAuthnManager.updateServerEncryptedVrfKeypair(nearAccountId, refreshed);\n }\n } catch (refreshErr: any) {\n console.warn('Non-fatal: Failed to refresh serverEncryptedVrfKeypair:', refreshErr?.message || refreshErr);\n }\n\n // Step 3: Update local data and return success\n // Ensure last-user deviceNumber reflects the passkey actually used for login.\n try {\n if (typeof activeDeviceNumber === 'number' && Number.isFinite(activeDeviceNumber)) {\n await webAuthnManager.setLastUser(nearAccountId, activeDeviceNumber);\n } else if (typeof userData.deviceNumber === 'number') {\n await webAuthnManager.setLastUser(nearAccountId, userData.deviceNumber);\n }\n } catch {\n // Non-fatal; continue even if last-user update fails.\n }\n await webAuthnManager.updateLastLogin(nearAccountId);\n\n const result: LoginResult = {\n success: true,\n loggedInNearAccountId: nearAccountId,\n // Ensure the clientNearPublicKey reflects the device whose VRF credentials\n // are actually active for this login.\n clientNearPublicKey: effectiveUserData?.clientNearPublicKey!, // non-null, validated above\n nearAccountId: nearAccountId\n };\n\n if (!deferCompletionHooks) {\n onEvent?.({\n step: 4,\n phase: LoginPhase.STEP_4_LOGIN_COMPLETE,\n status: LoginStatus.SUCCESS,\n message: 'Login completed successfully',\n nearAccountId: nearAccountId,\n clientNearPublicKey: effectiveUserData?.clientNearPublicKey || ''\n });\n afterCall?.(true, result);\n }\n return { result, usedFallbackTouchId, unlockCredential };\n\n } catch (error: any) {\n // Use centralized error handling\n const errorMessage = getUserFriendlyErrorMessage(error, 'login');\n\n onError?.(error);\n onEvent?.({\n step: 0,\n phase: LoginPhase.LOGIN_ERROR,\n status: LoginStatus.ERROR,\n message: errorMessage,\n error: errorMessage\n });\n\n const result: LoginResult = { success: false, error: errorMessage };\n afterCall?.(false);\n return { result, usedFallbackTouchId: false };\n }\n}\n\n/**\n * TouchID fallback path for VRF unlock.\n *\n * Used when Shamir 3-pass auto-unlock fails/unavailable:\n * - Prompts WebAuthn to obtain a serialized credential with PRF.first + PRF.second.\n * - Aligns the local encrypted VRF keypair blob with the passkey the user actually chose\n * (important when multiple devices/passkeys exist for the same account).\n * - Unlocks the VRF keypair inside the VRF worker and returns updated effective user context.\n */\nasync function fallbackUnlockVrfKeypairWithTouchId(args: {\n webAuthnManager: PasskeyManagerContext['webAuthnManager'];\n nearAccountId: AccountId;\n authenticators: ClientAuthenticatorData[];\n userData: ClientUserData;\n onEvent?: (event: LoginSSEvent) => void;\n}): Promise<{\n unlockResult: { success: boolean; error?: string };\n usedFallbackTouchId: boolean;\n unlockCredential: WebAuthnAuthenticationCredential;\n effectiveUserData: ClientUserData;\n activeDeviceNumber: number;\n}> {\n const { webAuthnManager, nearAccountId, authenticators, userData, onEvent } = args;\n\n onEvent?.({\n step: 2,\n phase: LoginPhase.STEP_2_WEBAUTHN_ASSERTION,\n status: LoginStatus.PROGRESS,\n message: 'Logging in, unlocking VRF credentials...'\n });\n\n const challenge = createRandomVRFChallenge();\n const credential = await webAuthnManager.getAuthenticationCredentialsSerializedDualPrf({\n nearAccountId,\n challenge: challenge as VRFChallenge,\n credentialIds: authenticators.map((a) => a.credentialId),\n });\n\n let effectiveUserData = userData;\n let activeDeviceNumber = userData.deviceNumber;\n\n // If multiple authenticators exist, align VRF credentials with the passkey\n // the user actually chose, based on credentialId → deviceNumber.\n if (authenticators.length > 1) {\n const rawId = credential.rawId;\n const matched = authenticators.find(a => a.credentialId === rawId);\n if (matched) {\n try {\n const byDevice = await IndexedDBManager.clientDB.getUserByDevice(nearAccountId, matched.deviceNumber);\n if (byDevice) {\n effectiveUserData = byDevice;\n activeDeviceNumber = matched.deviceNumber;\n }\n } catch {\n // If lookup by device fails, fall back to the base userData.\n }\n }\n }\n\n const unlockResult = await webAuthnManager.unlockVRFKeypair({\n nearAccountId: nearAccountId,\n encryptedVrfKeypair: {\n encryptedVrfDataB64u: effectiveUserData.encryptedVrfKeypair.encryptedVrfDataB64u,\n chacha20NonceB64u: effectiveUserData.encryptedVrfKeypair.chacha20NonceB64u,\n },\n credential: credential,\n });\n\n return {\n unlockResult,\n usedFallbackTouchId: unlockResult.success,\n unlockCredential: credential,\n effectiveUserData,\n activeDeviceNumber,\n };\n}\n\n/**\n * High-level login snapshot used by React contexts/UI.\n *\n * Returns:\n * - `login`: derived from IndexedDB last-user pointer + VRF worker status\n * - `signingSession`: warm signing session status when available\n *\n * The `nearAccountId` argument is treated as a \"query hint\" and must match the\n * last logged-in account to be considered logged in (prevents accidental cross-account reads).\n */\nexport async function getLoginSession(\n context: PasskeyManagerContext,\n nearAccountId?: AccountId\n): Promise<LoginSession> {\n const login = await getLoginStateInternal(context, nearAccountId);\n if (!login?.isLoggedIn || !login.nearAccountId) return { login, signingSession: null };\n try {\n const signingSession = await context.webAuthnManager.getWarmSigningSessionStatus(login.nearAccountId);\n return { login, signingSession };\n } catch {\n return { login, signingSession: null };\n }\n}\n\n/**\n * Internal helper for computing `LoginState`.\n *\n * Implementation detail:\n * - Trusts the IndexedDB last-user pointer for account selection, then confirms\n * that the VRF worker is actually active for that same account.\n */\nasync function getLoginStateInternal(\n context: PasskeyManagerContext,\n nearAccountId?: AccountId\n): Promise<LoginState> {\n const { webAuthnManager } = context;\n try {\n // Determine target account strictly from the last logged-in device.\n const lastUser = await webAuthnManager.getLastUser();\n const targetAccountId = nearAccountId ?? lastUser?.nearAccountId ?? null;\n\n // If caller requested a specific account, it must match the last logged-in account.\n if (!lastUser || (targetAccountId && lastUser.nearAccountId !== targetAccountId)) {\n return {\n isLoggedIn: false,\n nearAccountId: targetAccountId || null,\n publicKey: null,\n vrfActive: false,\n userData: null\n };\n }\n\n const userData = lastUser;\n const publicKey = userData?.clientNearPublicKey || null;\n\n // Check actual VRF worker status\n const vrfStatus = await webAuthnManager.checkVrfStatus();\n const vrfActive = vrfStatus.active && vrfStatus.nearAccountId === targetAccountId;\n\n // Determine if user is considered \"logged in\"\n // User is logged in if they have user data and VRF is active\n const isLoggedIn = !!(userData && userData.clientNearPublicKey && vrfActive);\n\n return {\n isLoggedIn,\n nearAccountId: targetAccountId,\n publicKey,\n vrfActive,\n userData,\n vrfSessionDuration: vrfStatus.sessionDuration || 0\n };\n\n } catch (error: any) {\n console.warn('Error getting login state:', error);\n return {\n isLoggedIn: false,\n nearAccountId: nearAccountId || null,\n publicKey: null,\n vrfActive: false,\n userData: null\n };\n }\n}\n\n/**\n * List recently used accounts from IndexedDB.\n *\n * Used for account picker UIs and initial app bootstrap state.\n */\nexport async function getRecentLogins(\n context: PasskeyManagerContext\n): Promise<GetRecentLoginsResult> {\n const { webAuthnManager } = context;\n // Get all user accounts from IndexDB\n const allUsersData = await webAuthnManager.getAllUsers();\n const accountIds = allUsersData.map(user => user.nearAccountId);\n // Get last used account for initial state\n const lastUsedAccount = await webAuthnManager.getLastUser();\n return {\n accountIds,\n lastUsedAccount,\n };\n}\n\n/**\n * Clear the active VRF session and any client-side nonce caches.\n *\n * This is the canonical \"logout\" operation for the SDK (does not delete accounts).\n */\nexport async function logoutAndClearSession(context: PasskeyManagerContext): Promise<void> {\n const { webAuthnManager } = context;\n await webAuthnManager.clearVrfSession();\n try { webAuthnManager.getNonceManager().clear(); } catch {}\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"login.js","names":["LoginPhase","LoginStatus","signingSession: SigningSessionStatus","finalResult","authenticatorsToAllowCredentials","verifyAuthenticationResponse","e: any","getUserFriendlyErrorMessage","err: any","createRandomVRFChallenge","IndexedDBManager","unlockResult: { success: boolean; error?: string }","unlockCredential: WebAuthnAuthenticationCredential | undefined","error: any","relayerUrl","refreshErr: any","result: LoginResult"],"sources":["../../../../src/core/TatchiPasskey/login.ts"],"sourcesContent":["import type {\n AfterCall,\n LoginHooksOptions,\n LoginSSEvent,\n} from '../types/sdkSentEvents';\nimport { LoginPhase, LoginStatus } from '../types/sdkSentEvents';\nimport type {\n GetRecentLoginsResult,\n LoginAndCreateSessionResult,\n LoginResult,\n LoginSession,\n LoginState,\n SigningSessionStatus,\n} from '../types/tatchi';\nimport type { PasskeyManagerContext } from './index';\nimport type { AccountId } from '../types/accountIds';\nimport type { WebAuthnAuthenticationCredential } from '../types/webauthn';\nimport { getUserFriendlyErrorMessage } from '../../utils/errors';\nimport { createRandomVRFChallenge, ServerEncryptedVrfKeypair, VRFChallenge } from '../types/vrf-worker';\nimport { authenticatorsToAllowCredentials } from '../WebAuthnManager/touchIdPrompt';\nimport { IndexedDBManager } from '../IndexedDBManager';\nimport type { ClientAuthenticatorData, ClientUserData } from '../IndexedDBManager';\nimport { verifyAuthenticationResponse } from '../rpcCalls';\n\n/**\n * Core login function that handles passkey authentication without React dependencies.\n *\n * - Unlocks the VRF keypair (Shamir 3‑pass auto‑unlock when possible; falls back to TouchID).\n * - Updates local login state and returns success with account/public key info.\n * - Optional: mints a server session when `options.session` is provided.\n * - Generates a fresh, chain‑anchored VRF challenge (using latest block).\n * - Collects a WebAuthn assertion over the VRF output and posts to the relay route\n * (defaults to `/verify-authentication-response`).\n * - When `kind: 'jwt'`, returns the token in `result.jwt`.\n * - When `kind: 'cookie'`, the server sets an HttpOnly cookie and no JWT is returned.\n */\nexport async function loginAndCreateSession(\n context: PasskeyManagerContext,\n nearAccountId: AccountId,\n options?: LoginHooksOptions\n): Promise<LoginAndCreateSessionResult> {\n\n const { onEvent, onError, afterCall } = options || {};\n const { webAuthnManager } = context;\n\n onEvent?.({\n step: 1,\n phase: LoginPhase.STEP_1_PREPARATION,\n status: LoginStatus.PROGRESS,\n message: `Starting login for ${nearAccountId}`\n });\n\n const prevStatus = await webAuthnManager.checkVrfStatus();\n const prevVrfAccountId = prevStatus?.active ? prevStatus.nearAccountId : null;\n\n // If this call activates VRF then fails, clear the partial session.\n const rollbackVrfOnFailure = async () => {\n const status = await webAuthnManager.checkVrfStatus();\n const current = status?.active ? status.nearAccountId : null;\n if (current && current !== prevVrfAccountId) {\n await logoutAndClearSession(context);\n }\n };\n\n try {\n // Validation\n if (!window.isSecureContext) {\n const errorMessage = 'Passkey operations require a secure context (HTTPS or localhost).';\n const error = new Error(errorMessage);\n onError?.(error);\n onEvent?.({\n step: 0,\n phase: LoginPhase.LOGIN_ERROR,\n status: LoginStatus.ERROR,\n message: errorMessage,\n error: errorMessage\n });\n const result = { success: false, error: errorMessage };\n return result;\n }\n\n // Handle login and unlock VRF keypair in VRF WASM worker for WebAuthn challenge generation\n const wantsSession = options?.session?.kind == 'jwt' || options?.session?.kind == 'cookie';\n const base = await handleLoginUnlockVRF(\n context,\n nearAccountId,\n onEvent,\n onError,\n afterCall,\n // Defer final 'login-complete' event & afterCall until warm signing session is minted\n true\n );\n // If base login failed, just return\n if (!base.result.success) return base.result;\n\n const attachSigningSession = async (result: LoginResult): Promise<LoginAndCreateSessionResult> => {\n if (!result?.success) return result;\n try {\n const signingSession: SigningSessionStatus = await webAuthnManager.getWarmSigningSessionStatus(nearAccountId);\n return { ...result, signingSession };\n } catch {\n return result;\n }\n };\n\n // Resolve default warm signing session policy from configs.\n const ttlMsDefault = context.configs.signingSessionDefaults.ttlMs;\n const remainingUsesDefault = context.configs.signingSessionDefaults.remainingUses;\n const ttlMs = options?.signingSession?.ttlMs ?? ttlMsDefault;\n const remainingUses = options?.signingSession?.remainingUses ?? remainingUsesDefault;\n\n // Optionally mint a server session (JWT or HttpOnly cookie).\n // When requested, we also mint the warm signing session using the same WebAuthn prompt\n // so Shamir auto-unlock remains a single-prompt login UX.\n if (wantsSession) {\n const { kind, relayUrl: relayUrlOverride, route: routeOverride } = options!.session!;\n const relayUrl = (relayUrlOverride || context.configs.relayer.url).trim();\n const route = (routeOverride || '/verify-authentication-response').trim();\n if (!relayUrl) {\n // No relay; return base result without session\n console.warn(\"No relayUrl provided for session\");\n // Ensure a warm signing session is minted for local signing UX.\n await mintWarmSigningSession({\n context,\n nearAccountId,\n onEvent,\n credential: base.unlockCredential,\n ttlMs,\n remainingUses,\n });\n\n const finalResult = await attachSigningSession(base.result);\n // Emit completion now since we deferred it\n onEvent?.({\n step: 4,\n phase: LoginPhase.STEP_4_LOGIN_COMPLETE,\n status: LoginStatus.SUCCESS,\n message: 'Login completed successfully',\n nearAccountId: nearAccountId,\n clientNearPublicKey: base.result?.clientNearPublicKey || ''\n } as unknown as LoginSSEvent);\n await afterCall?.(true, finalResult);\n return finalResult;\n }\n try {\n // Build a fresh VRF challenge using current block\n const blockInfo = await context.nearClient.viewBlock({ finality: 'final' });\n const txBlockHash = blockInfo?.header?.hash;\n const txBlockHeight = String(blockInfo.header?.height ?? '');\n const vrfChallenge = await webAuthnManager.generateVrfChallengeOnce({\n userId: nearAccountId,\n rpId: webAuthnManager.getRpId(),\n blockHash: txBlockHash,\n blockHeight: txBlockHeight,\n });\n const authenticators = await webAuthnManager.getAuthenticatorsByUser(nearAccountId);\n const credential = await webAuthnManager.getAuthenticationCredentialsSerialized({\n nearAccountId,\n challenge: vrfChallenge,\n allowCredentials: authenticatorsToAllowCredentials(authenticators),\n });\n\n // Align lastUser deviceNumber with the passkey actually chosen for session minting.\n try {\n if (authenticators.length > 1) {\n const rawId = credential.rawId;\n const matched = authenticators.find((a) => a.credentialId === rawId);\n if (matched && typeof matched.deviceNumber === 'number') {\n await context.webAuthnManager.setLastUser(nearAccountId, matched.deviceNumber);\n }\n }\n } catch {\n // Non-fatal; session minting can proceed even if last-user update fails here.\n }\n\n // Mint the warm signing session using the same prompt used for server-session verification.\n await mintWarmSigningSession({\n context,\n nearAccountId,\n onEvent,\n credential,\n ttlMs,\n remainingUses,\n });\n\n const v = await verifyAuthenticationResponse(relayUrl, route, kind as 'jwt' | 'cookie', vrfChallenge, credential);\n if (v.success && v.verified) {\n const finalResult = await attachSigningSession({ ...base.result, jwt: v.jwt });\n // Now fire completion event and afterCall since we deferred them\n onEvent?.({\n step: 4,\n phase: LoginPhase.STEP_4_LOGIN_COMPLETE,\n status: LoginStatus.SUCCESS,\n message: 'Login completed successfully',\n nearAccountId: nearAccountId,\n clientNearPublicKey: base.result?.clientNearPublicKey || ''\n } as unknown as LoginSSEvent);\n await afterCall?.(true, finalResult);\n return finalResult;\n }\n // Session verification returned an error; surface error and afterCall(false)\n const errMsg = v.error || 'Session verification failed';\n await rollbackVrfOnFailure();\n onEvent?.({\n step: 0,\n phase: LoginPhase.LOGIN_ERROR,\n status: LoginStatus.ERROR,\n message: errMsg,\n error: errMsg\n } as unknown as LoginSSEvent);\n await afterCall?.(false as any);\n return { success: false, error: errMsg };\n } catch (e: any) {\n console.error(\"Failed to start session: \", e);\n const errMsg = getUserFriendlyErrorMessage(e, 'login') || (e?.message || 'Session verification failed');\n await rollbackVrfOnFailure();\n onError?.(e);\n onEvent?.({\n step: 0,\n phase: LoginPhase.LOGIN_ERROR,\n status: LoginStatus.ERROR,\n message: errMsg,\n error: errMsg\n } as unknown as LoginSSEvent);\n await afterCall?.(false as any);\n return { success: false, error: errMsg };\n }\n }\n\n // No server session requested: mint/refresh the warm signing session.\n await mintWarmSigningSession({\n context,\n nearAccountId,\n onEvent,\n credential: base.unlockCredential,\n ttlMs,\n remainingUses,\n });\n\n const finalResult = await attachSigningSession(base.result);\n // Fire completion event and afterCall since we deferred them.\n onEvent?.({\n step: 4,\n phase: LoginPhase.STEP_4_LOGIN_COMPLETE,\n status: LoginStatus.SUCCESS,\n message: 'Login completed successfully',\n nearAccountId: nearAccountId,\n clientNearPublicKey: base.result?.clientNearPublicKey || ''\n } as unknown as LoginSSEvent);\n await afterCall?.(true, finalResult);\n return finalResult;\n\n } catch (err: any) {\n\n await rollbackVrfOnFailure();\n onError?.(err);\n const errorMessage = getUserFriendlyErrorMessage(err, 'login') || err?.message || 'Login failed';\n onEvent?.({\n step: 0,\n phase: LoginPhase.LOGIN_ERROR,\n status: LoginStatus.ERROR,\n message: errorMessage,\n error: errorMessage\n });\n const result = { success: false, error: errorMessage };\n afterCall?.(false);\n return result;\n }\n}\n\n/**\n * Mint or refresh a \"warm signing session\" in the VRF worker.\n *\n * Notes:\n * - Reuses a previously collected WebAuthn credential when provided (e.g. TouchID fallback),\n * to avoid prompting the user twice in a single login flow.\n * - Session TTL/remainingUses policy is enforced by the VRF worker.\n */\nasync function mintWarmSigningSession(args: {\n context: PasskeyManagerContext;\n nearAccountId: AccountId;\n onEvent?: (event: LoginSSEvent) => void;\n credential?: WebAuthnAuthenticationCredential;\n ttlMs: number;\n remainingUses: number;\n}): Promise<void> {\n const { context, nearAccountId, onEvent, credential, ttlMs, remainingUses } = args;\n const { webAuthnManager } = context;\n\n onEvent?.({\n step: 3,\n phase: LoginPhase.STEP_3_VRF_UNLOCK,\n status: LoginStatus.PROGRESS,\n message: 'Unlocking warm signing session...'\n });\n\n // If we already performed a TouchID ceremony (e.g., VRF unlock fallback),\n // reuse that credential to avoid a second prompt.\n let effectiveCredential = credential;\n if (!effectiveCredential) {\n const challenge = createRandomVRFChallenge();\n const authenticators = await webAuthnManager.getAuthenticatorsByUser(nearAccountId);\n const { authenticatorsForPrompt } = await IndexedDBManager.clientDB.ensureCurrentPasskey(\n nearAccountId,\n authenticators,\n );\n effectiveCredential = await webAuthnManager.getAuthenticationCredentialsSerialized({\n nearAccountId,\n challenge: challenge as VRFChallenge,\n allowCredentials: authenticatorsToAllowCredentials(authenticatorsForPrompt),\n });\n }\n\n await webAuthnManager.mintSigningSessionFromCredential({\n nearAccountId,\n credential: effectiveCredential,\n ttlMs,\n remainingUses,\n });\n\n onEvent?.({\n step: 3,\n phase: LoginPhase.STEP_3_VRF_UNLOCK,\n status: LoginStatus.SUCCESS,\n message: 'Warm signing session unlocked'\n });\n}\n\n/**\n * Handle onchain (serverless) login using VRF flow per docs/vrf_challenges.md\n *\n * VRF AUTHENTICATION FLOW:\n * 1. Unlock VRF keypair in VRF Worker memory, either\n * - Decrypt via Shamir 3-pass (when Relayer is present), or\n * - Re-derive the VRF via credentials inside VRF worker dynamically\n * 2. Generate VRF challenge using stored VRF keypair + NEAR block data (no TouchID needed)\n * 3. Use VRF output as WebAuthn challenge for authentication\n * 4. Verify VRF proof and WebAuthn response on contract simultaneously\n * - VRF proof assures WebAuthn challenge is fresh and valid (replay protection)\n * - WebAuthn verification for origin + biometric credentials + device authenticity\n */\nasync function handleLoginUnlockVRF(\n context: PasskeyManagerContext,\n nearAccountId: AccountId,\n onEvent?: (event: LoginSSEvent) => void,\n onError?: (error: Error) => void,\n afterCall?: AfterCall<any>,\n deferCompletionHooks?: boolean,\n): Promise<{\n result: LoginResult;\n usedFallbackTouchId: boolean;\n unlockCredential?: WebAuthnAuthenticationCredential;\n}> {\n const { webAuthnManager } = context;\n\n try {\n // Step 1: Get VRF credentials and authenticators, and validate them\n const [lastUser, latestByAccount, authenticators] = await Promise.all([\n webAuthnManager.getLastUser(),\n IndexedDBManager.clientDB.getLastDBUpdatedUser(nearAccountId),\n webAuthnManager.getAuthenticatorsByUser(nearAccountId),\n ]);\n\n // Prefer the most recently updated record for this account; fall back to lastUser pointer.\n let userData = null as (typeof lastUser) | null;\n if (latestByAccount && latestByAccount.nearAccountId === nearAccountId) {\n userData = latestByAccount;\n } else if (lastUser && lastUser.nearAccountId === nearAccountId) {\n userData = lastUser;\n } else {\n userData = await webAuthnManager.getUserByDevice(nearAccountId, 1);\n }\n\n // Validate user data and authenticators\n if (!userData) {\n throw new Error(`User data not found for ${nearAccountId} in IndexedDB. Please register an account.`);\n }\n if (!userData.clientNearPublicKey) {\n throw new Error(`No NEAR public key found for ${nearAccountId}. Please register an account.`);\n }\n if (\n !userData.encryptedVrfKeypair?.encryptedVrfDataB64u ||\n !userData.encryptedVrfKeypair?.chacha20NonceB64u\n ) {\n throw new Error('No VRF credentials found. Please register an account.');\n }\n if (authenticators.length === 0) {\n throw new Error(`No authenticators found for account ${nearAccountId}. Please register.`);\n }\n\n // Step 2: Try Shamir 3-pass commutative unlock first (no TouchID required), fallback to TouchID\n onEvent?.({\n step: 2,\n phase: LoginPhase.STEP_2_WEBAUTHN_ASSERTION,\n status: LoginStatus.PROGRESS,\n message: 'Unlocking VRF keys...'\n });\n\n let unlockResult: { success: boolean; error?: string } = { success: false };\n let usedFallbackTouchId = false;\n let unlockCredential: WebAuthnAuthenticationCredential | undefined;\n let activeDeviceNumber = userData.deviceNumber;\n // Effective user row whose VRF/NEAR keys are actually used for this login.\n // May be switched when multiple devices exist and the user picks a different passkey.\n let effectiveUserData = userData;\n\n const hasServerEncrypted = !!userData.serverEncryptedVrfKeypair;\n const relayerUrl = context.configs.relayer?.url;\n const useShamir3PassVRFKeyUnlock = hasServerEncrypted && !!relayerUrl && !!userData.serverEncryptedVrfKeypair?.serverKeyId;\n\n if (useShamir3PassVRFKeyUnlock) {\n try {\n const shamir = userData.serverEncryptedVrfKeypair as ServerEncryptedVrfKeypair;\n if (!shamir.ciphertextVrfB64u || !shamir.kek_s_b64u) {\n throw new Error('Missing Shamir3Pass fields (ciphertextVrfB64u/kek_s_b64u)');\n }\n\n unlockResult = await webAuthnManager.shamir3PassDecryptVrfKeypair({\n nearAccountId,\n kek_s_b64u: shamir.kek_s_b64u,\n ciphertextVrfB64u: shamir.ciphertextVrfB64u,\n serverKeyId: shamir.serverKeyId,\n });\n\n if (unlockResult.success) {\n const vrfStatus = await webAuthnManager.checkVrfStatus();\n const active = vrfStatus.active && vrfStatus.nearAccountId === nearAccountId;\n if (!active) {\n unlockResult = { success: false, error: 'VRF session inactive after Shamir3Pass' };\n }\n if (active) {\n // Proactive rotation if serverKeyId changed and we unlocked via Shamir\n await webAuthnManager.maybeProactiveShamirRefresh(nearAccountId);\n }\n } else {\n throw new Error(`Shamir3Pass auto-unlock failed: ${unlockResult.error}`);\n }\n } catch (error: any) {\n unlockResult = { success: false, error: error.message };\n }\n }\n\n // Fallback to TouchID if Shamir3Pass decryption failed\n if (!unlockResult.success) {\n const fallback = await fallbackUnlockVrfKeypairWithTouchId({\n webAuthnManager,\n nearAccountId,\n authenticators,\n userData,\n onEvent,\n });\n unlockResult = fallback.unlockResult;\n usedFallbackTouchId = fallback.usedFallbackTouchId;\n unlockCredential = fallback.unlockCredential;\n effectiveUserData = fallback.effectiveUserData;\n activeDeviceNumber = fallback.activeDeviceNumber;\n }\n\n if (!unlockResult.success) {\n throw new Error(`Failed to unlock VRF keypair: ${unlockResult.error}`);\n }\n\n onEvent?.({\n step: 3,\n phase: LoginPhase.STEP_3_VRF_UNLOCK,\n status: LoginStatus.SUCCESS,\n message: 'VRF keypair unlocked successfully'\n });\n\n // Proactive refresh: if Shamir3Pass failed and we used TouchID, re-encrypt under current server key\n try {\n const relayerUrl = context.configs.relayer?.url;\n if (usedFallbackTouchId && relayerUrl) {\n const refreshed = await webAuthnManager.shamir3PassEncryptCurrentVrfKeypair();\n await webAuthnManager.updateServerEncryptedVrfKeypair(nearAccountId, refreshed);\n }\n } catch (refreshErr: any) {\n console.warn('Non-fatal: Failed to refresh serverEncryptedVrfKeypair:', refreshErr?.message || refreshErr);\n }\n\n // Step 3: Update local data and return success\n // Ensure last-user deviceNumber reflects the passkey actually used for login.\n try {\n if (typeof activeDeviceNumber === 'number' && Number.isFinite(activeDeviceNumber)) {\n await webAuthnManager.setLastUser(nearAccountId, activeDeviceNumber);\n } else if (typeof userData.deviceNumber === 'number') {\n await webAuthnManager.setLastUser(nearAccountId, userData.deviceNumber);\n }\n } catch {\n // Non-fatal; continue even if last-user update fails.\n }\n await webAuthnManager.updateLastLogin(nearAccountId);\n\n const result: LoginResult = {\n success: true,\n loggedInNearAccountId: nearAccountId,\n // Ensure the clientNearPublicKey reflects the device whose VRF credentials\n // are actually active for this login.\n clientNearPublicKey: effectiveUserData?.clientNearPublicKey!, // non-null, validated above\n nearAccountId: nearAccountId\n };\n\n if (!deferCompletionHooks) {\n onEvent?.({\n step: 4,\n phase: LoginPhase.STEP_4_LOGIN_COMPLETE,\n status: LoginStatus.SUCCESS,\n message: 'Login completed successfully',\n nearAccountId: nearAccountId,\n clientNearPublicKey: effectiveUserData?.clientNearPublicKey || ''\n });\n afterCall?.(true, result);\n }\n return { result, usedFallbackTouchId, unlockCredential };\n\n } catch (error: any) {\n // Use centralized error handling\n const errorMessage = getUserFriendlyErrorMessage(error, 'login');\n\n onError?.(error);\n onEvent?.({\n step: 0,\n phase: LoginPhase.LOGIN_ERROR,\n status: LoginStatus.ERROR,\n message: errorMessage,\n error: errorMessage\n });\n\n const result: LoginResult = { success: false, error: errorMessage };\n afterCall?.(false);\n return { result, usedFallbackTouchId: false };\n }\n}\n\n/**\n * TouchID fallback path for VRF unlock.\n *\n * Used when Shamir 3-pass auto-unlock fails/unavailable:\n * - Prompts WebAuthn to obtain a serialized credential with PRF.first + PRF.second.\n * - Aligns the local encrypted VRF keypair blob with the passkey the user actually chose\n * (important when multiple devices/passkeys exist for the same account).\n * - Unlocks the VRF keypair inside the VRF worker and returns updated effective user context.\n */\nasync function fallbackUnlockVrfKeypairWithTouchId(args: {\n webAuthnManager: PasskeyManagerContext['webAuthnManager'];\n nearAccountId: AccountId;\n authenticators: ClientAuthenticatorData[];\n userData: ClientUserData;\n onEvent?: (event: LoginSSEvent) => void;\n}): Promise<{\n unlockResult: { success: boolean; error?: string };\n usedFallbackTouchId: boolean;\n unlockCredential: WebAuthnAuthenticationCredential;\n effectiveUserData: ClientUserData;\n activeDeviceNumber: number;\n}> {\n const { webAuthnManager, nearAccountId, authenticators, userData, onEvent } = args;\n\n onEvent?.({\n step: 2,\n phase: LoginPhase.STEP_2_WEBAUTHN_ASSERTION,\n status: LoginStatus.PROGRESS,\n message: 'Logging in, unlocking VRF credentials...'\n });\n\n const challenge = createRandomVRFChallenge();\n const credential = await webAuthnManager.getAuthenticationCredentialsSerializedDualPrf({\n nearAccountId,\n challenge: challenge as VRFChallenge,\n credentialIds: authenticators.map((a) => a.credentialId),\n });\n\n let effectiveUserData = userData;\n let activeDeviceNumber = userData.deviceNumber;\n\n // If multiple authenticators exist, align VRF credentials with the passkey\n // the user actually chose, based on credentialId → deviceNumber.\n if (authenticators.length > 1) {\n const rawId = credential.rawId;\n const matched = authenticators.find(a => a.credentialId === rawId);\n if (matched) {\n try {\n const byDevice = await IndexedDBManager.clientDB.getUserByDevice(nearAccountId, matched.deviceNumber);\n if (byDevice) {\n effectiveUserData = byDevice;\n activeDeviceNumber = matched.deviceNumber;\n }\n } catch {\n // If lookup by device fails, fall back to the base userData.\n }\n }\n }\n\n const unlockResult = await webAuthnManager.unlockVRFKeypair({\n nearAccountId: nearAccountId,\n encryptedVrfKeypair: {\n encryptedVrfDataB64u: effectiveUserData.encryptedVrfKeypair.encryptedVrfDataB64u,\n chacha20NonceB64u: effectiveUserData.encryptedVrfKeypair.chacha20NonceB64u,\n },\n credential: credential,\n });\n\n return {\n unlockResult,\n usedFallbackTouchId: unlockResult.success,\n unlockCredential: credential,\n effectiveUserData,\n activeDeviceNumber,\n };\n}\n\n/**\n * High-level login snapshot used by React contexts/UI.\n *\n * Returns:\n * - `login`: derived from IndexedDB last-user pointer + VRF worker status\n * - `signingSession`: warm signing session status when available\n *\n * The `nearAccountId` argument is treated as a \"query hint\" and must match the\n * last logged-in account to be considered logged in (prevents accidental cross-account reads).\n */\nexport async function getLoginSession(\n context: PasskeyManagerContext,\n nearAccountId?: AccountId\n): Promise<LoginSession> {\n const login = await getLoginStateInternal(context, nearAccountId);\n if (!login?.isLoggedIn || !login.nearAccountId) return { login, signingSession: null };\n try {\n const signingSession = await context.webAuthnManager.getWarmSigningSessionStatus(login.nearAccountId);\n return { login, signingSession };\n } catch {\n return { login, signingSession: null };\n }\n}\n\n/**\n * Internal helper for computing `LoginState`.\n *\n * Implementation detail:\n * - Trusts the IndexedDB last-user pointer for account selection, then confirms\n * that the VRF worker is actually active for that same account.\n */\nasync function getLoginStateInternal(\n context: PasskeyManagerContext,\n nearAccountId?: AccountId\n): Promise<LoginState> {\n const { webAuthnManager } = context;\n try {\n // Determine target account strictly from the last logged-in device.\n const lastUser = await webAuthnManager.getLastUser();\n const targetAccountId = nearAccountId ?? lastUser?.nearAccountId ?? null;\n\n // If caller requested a specific account, it must match the last logged-in account.\n if (!lastUser || (targetAccountId && lastUser.nearAccountId !== targetAccountId)) {\n return {\n isLoggedIn: false,\n nearAccountId: targetAccountId || null,\n publicKey: null,\n vrfActive: false,\n userData: null\n };\n }\n\n const userData = lastUser;\n const publicKey = userData?.clientNearPublicKey || null;\n\n // Check actual VRF worker status\n const vrfStatus = await webAuthnManager.checkVrfStatus();\n const vrfActive = vrfStatus.active && vrfStatus.nearAccountId === targetAccountId;\n\n // Determine if user is considered \"logged in\"\n // User is logged in if they have user data and VRF is active\n const isLoggedIn = !!(userData && userData.clientNearPublicKey && vrfActive);\n\n return {\n isLoggedIn,\n nearAccountId: targetAccountId,\n publicKey,\n vrfActive,\n userData,\n vrfSessionDuration: vrfStatus.sessionDuration || 0\n };\n\n } catch (error: any) {\n console.warn('Error getting login state:', error);\n return {\n isLoggedIn: false,\n nearAccountId: nearAccountId || null,\n publicKey: null,\n vrfActive: false,\n userData: null\n };\n }\n}\n\n/**\n * List recently used accounts from IndexedDB.\n *\n * Used for account picker UIs and initial app bootstrap state.\n */\nexport async function getRecentLogins(\n context: PasskeyManagerContext\n): Promise<GetRecentLoginsResult> {\n const { webAuthnManager } = context;\n // Get all user accounts from IndexDB\n const allUsersData = await webAuthnManager.getAllUsers();\n const accountIds = allUsersData.map(user => user.nearAccountId);\n // Get last used account for initial state\n const lastUsedAccount = await webAuthnManager.getLastUser();\n return {\n accountIds,\n lastUsedAccount,\n };\n}\n\n/**\n * Clear the active VRF session and any client-side nonce caches.\n *\n * This is the canonical \"logout\" operation for the SDK (does not delete accounts).\n */\nexport async function logoutAndClearSession(context: PasskeyManagerContext): Promise<void> {\n const { webAuthnManager } = context;\n await webAuthnManager.clearVrfSession();\n try { webAuthnManager.getNonceManager().clear(); } catch {}\n}\n"],"mappings":"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"}
@@ -11,6 +11,7 @@ const require_userHandle = require('../WebAuthnManager/userHandle.js');
11
11
  require_sdkSentEvents.init_sdkSentEvents();
12
12
  require_validation.init_validation();
13
13
  require_accountIds.init_accountIds();
14
+ require_vrf_worker.init_vrf_worker();
14
15
  require_index.init_IndexedDBManager();
15
16
  require_rpcCalls.init_rpcCalls();
16
17
  /**