@tatchi-xyz/sdk 0.20.0 → 0.21.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 (217) hide show
  1. package/dist/cjs/core/TatchiPasskey/emailRecovery.js +67 -45
  2. package/dist/cjs/core/TatchiPasskey/emailRecovery.js.map +1 -1
  3. package/dist/cjs/core/TatchiPasskey/index.js +2 -1
  4. package/dist/cjs/core/TatchiPasskey/index.js.map +1 -1
  5. package/dist/cjs/core/TatchiPasskey/linkDevice.js +2 -1
  6. package/dist/cjs/core/TatchiPasskey/linkDevice.js.map +1 -1
  7. package/dist/cjs/core/TatchiPasskey/scanDevice.js +5 -3
  8. package/dist/cjs/core/TatchiPasskey/scanDevice.js.map +1 -1
  9. package/dist/cjs/core/WalletIframe/client/router.js +1 -1
  10. package/dist/cjs/core/WalletIframe/client/router.js.map +1 -1
  11. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/validation.js +3 -4
  12. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/validation.js.map +1 -1
  13. package/dist/cjs/core/defaultConfigs.js +3 -7
  14. package/dist/cjs/core/defaultConfigs.js.map +1 -1
  15. package/dist/cjs/core/nearCrypto.js +29 -5
  16. package/dist/cjs/core/nearCrypto.js.map +1 -1
  17. package/dist/cjs/core/rpcCalls.js +56 -26
  18. package/dist/cjs/core/rpcCalls.js.map +1 -1
  19. package/dist/cjs/react/components/AccountMenuButton/{LinkedDevicesModal-BCrFe5p3.css → LinkedDevicesModal-BRtht0XI.css} +1 -1
  20. package/dist/{esm/react/components/AccountMenuButton/LinkedDevicesModal-BCrFe5p3.css.map → cjs/react/components/AccountMenuButton/LinkedDevicesModal-BRtht0XI.css.map} +1 -1
  21. package/dist/cjs/react/components/AccountMenuButton/{ProfileDropdown-CRJrtxDb.css → ProfileDropdown-BG_6hcim.css} +1 -1
  22. package/dist/{esm/react/components/AccountMenuButton/ProfileDropdown-CRJrtxDb.css.map → cjs/react/components/AccountMenuButton/ProfileDropdown-BG_6hcim.css.map} +1 -1
  23. package/dist/cjs/react/components/AccountMenuButton/{Web3AuthProfileButton-DXFRw8ND.css → Web3AuthProfileButton-k8_FAYFq.css} +1 -1
  24. package/dist/cjs/react/components/AccountMenuButton/{Web3AuthProfileButton-DXFRw8ND.css.map → Web3AuthProfileButton-k8_FAYFq.css.map} +1 -1
  25. package/dist/cjs/react/components/AccountMenuButton/icons/{TouchIcon-DNgbAK_i.css → TouchIcon-C-RcGfr5.css} +1 -1
  26. package/dist/cjs/react/components/AccountMenuButton/icons/{TouchIcon-DNgbAK_i.css.map → TouchIcon-C-RcGfr5.css.map} +1 -1
  27. package/dist/cjs/react/components/PasskeyAuthMenu/{PasskeyAuthMenu-DRwSoF8q.css → PasskeyAuthMenu-DKMiLeT9.css} +59 -4
  28. package/dist/cjs/react/components/PasskeyAuthMenu/{PasskeyAuthMenu-DRwSoF8q.css.map → PasskeyAuthMenu-DKMiLeT9.css.map} +1 -1
  29. package/dist/cjs/react/components/PasskeyAuthMenu/adapters/tatchi.js +1 -0
  30. package/dist/cjs/react/components/PasskeyAuthMenu/adapters/tatchi.js.map +1 -1
  31. package/dist/cjs/react/components/PasskeyAuthMenu/client.js +30 -8
  32. package/dist/cjs/react/components/PasskeyAuthMenu/client.js.map +1 -1
  33. package/dist/cjs/react/components/PasskeyAuthMenu/controller/useSDKEvents.js +22 -0
  34. package/dist/cjs/react/components/PasskeyAuthMenu/controller/useSDKEvents.js.map +1 -0
  35. package/dist/cjs/react/components/PasskeyAuthMenu/ui/ContentSwitcher.js +17 -4
  36. package/dist/cjs/react/components/PasskeyAuthMenu/ui/ContentSwitcher.js.map +1 -1
  37. package/dist/cjs/react/components/PasskeyAuthMenu/ui/EmailRecoverySlide.js +254 -140
  38. package/dist/cjs/react/components/PasskeyAuthMenu/ui/EmailRecoverySlide.js.map +1 -1
  39. package/dist/cjs/react/components/{ShowQRCode-CL4gsszN.css → ShowQRCode-CB0UCQ_h.css} +1 -1
  40. package/dist/cjs/react/components/{ShowQRCode-CL4gsszN.css.map → ShowQRCode-CB0UCQ_h.css.map} +1 -1
  41. package/dist/cjs/react/context/useSDKFlowRuntime.js +183 -0
  42. package/dist/cjs/react/context/useSDKFlowRuntime.js.map +1 -0
  43. package/dist/cjs/react/context/useTatchiContextValue.js +24 -15
  44. package/dist/cjs/react/context/useTatchiContextValue.js.map +1 -1
  45. package/dist/cjs/react/context/useTatchiWithSdkFlow.js +96 -0
  46. package/dist/cjs/react/context/useTatchiWithSdkFlow.js.map +1 -0
  47. package/dist/cjs/react/sdk/src/core/EmailRecovery/index.js +1 -0
  48. package/dist/cjs/react/sdk/src/core/TatchiPasskey/emailRecovery.js +67 -45
  49. package/dist/cjs/react/sdk/src/core/TatchiPasskey/emailRecovery.js.map +1 -1
  50. package/dist/cjs/react/sdk/src/core/TatchiPasskey/index.js +2 -1
  51. package/dist/cjs/react/sdk/src/core/TatchiPasskey/index.js.map +1 -1
  52. package/dist/cjs/react/sdk/src/core/TatchiPasskey/linkDevice.js +2 -1
  53. package/dist/cjs/react/sdk/src/core/TatchiPasskey/linkDevice.js.map +1 -1
  54. package/dist/cjs/react/sdk/src/core/TatchiPasskey/scanDevice.js +5 -3
  55. package/dist/cjs/react/sdk/src/core/TatchiPasskey/scanDevice.js.map +1 -1
  56. package/dist/cjs/react/sdk/src/core/WalletIframe/client/router.js +1 -1
  57. package/dist/cjs/react/sdk/src/core/WalletIframe/client/router.js.map +1 -1
  58. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/validation.js +3 -4
  59. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/validation.js.map +1 -1
  60. package/dist/cjs/react/sdk/src/core/defaultConfigs.js +3 -7
  61. package/dist/cjs/react/sdk/src/core/defaultConfigs.js.map +1 -1
  62. package/dist/cjs/react/sdk/src/core/nearCrypto.js +29 -5
  63. package/dist/cjs/react/sdk/src/core/nearCrypto.js.map +1 -1
  64. package/dist/cjs/react/sdk/src/core/rpcCalls.js +56 -26
  65. package/dist/cjs/react/sdk/src/core/rpcCalls.js.map +1 -1
  66. package/dist/cjs/server/email-recovery/emailParsers.js +2 -1
  67. package/dist/cjs/server/email-recovery/emailParsers.js.map +1 -1
  68. package/dist/cjs/server/email-recovery/index.js +6 -6
  69. package/dist/cjs/server/email-recovery/index.js.map +1 -1
  70. package/dist/cjs/server/email-recovery/rpcCalls.js +22 -3
  71. package/dist/cjs/server/email-recovery/rpcCalls.js.map +1 -1
  72. package/dist/cjs/server/router/cloudflare.js +8 -3
  73. package/dist/cjs/server/router/cloudflare.js.map +1 -1
  74. package/dist/cjs/server/router/express.js.map +1 -1
  75. package/dist/cjs/server/sdk/src/core/defaultConfigs.js +2 -4
  76. package/dist/cjs/server/sdk/src/core/defaultConfigs.js.map +1 -1
  77. package/dist/cjs/server/sdk/src/core/nearCrypto.js +26 -7
  78. package/dist/cjs/server/sdk/src/core/nearCrypto.js.map +1 -1
  79. package/dist/esm/core/TatchiPasskey/emailRecovery.js +67 -45
  80. package/dist/esm/core/TatchiPasskey/emailRecovery.js.map +1 -1
  81. package/dist/esm/core/TatchiPasskey/index.js +2 -1
  82. package/dist/esm/core/TatchiPasskey/index.js.map +1 -1
  83. package/dist/esm/core/TatchiPasskey/linkDevice.js +2 -1
  84. package/dist/esm/core/TatchiPasskey/linkDevice.js.map +1 -1
  85. package/dist/esm/core/TatchiPasskey/scanDevice.js +5 -3
  86. package/dist/esm/core/TatchiPasskey/scanDevice.js.map +1 -1
  87. package/dist/esm/core/WalletIframe/client/router.js +1 -1
  88. package/dist/esm/core/WalletIframe/client/router.js.map +1 -1
  89. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/validation.js +2 -3
  90. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/validation.js.map +1 -1
  91. package/dist/esm/core/defaultConfigs.js +3 -7
  92. package/dist/esm/core/defaultConfigs.js.map +1 -1
  93. package/dist/esm/core/nearCrypto.js +24 -6
  94. package/dist/esm/core/nearCrypto.js.map +1 -1
  95. package/dist/esm/core/rpcCalls.js +56 -26
  96. package/dist/esm/core/rpcCalls.js.map +1 -1
  97. package/dist/esm/react/components/AccountMenuButton/{LinkedDevicesModal-BCrFe5p3.css → LinkedDevicesModal-BRtht0XI.css} +1 -1
  98. package/dist/{cjs/react/components/AccountMenuButton/LinkedDevicesModal-BCrFe5p3.css.map → esm/react/components/AccountMenuButton/LinkedDevicesModal-BRtht0XI.css.map} +1 -1
  99. package/dist/esm/react/components/AccountMenuButton/{ProfileDropdown-CRJrtxDb.css → ProfileDropdown-BG_6hcim.css} +1 -1
  100. package/dist/{cjs/react/components/AccountMenuButton/ProfileDropdown-CRJrtxDb.css.map → esm/react/components/AccountMenuButton/ProfileDropdown-BG_6hcim.css.map} +1 -1
  101. package/dist/esm/react/components/AccountMenuButton/{Web3AuthProfileButton-DXFRw8ND.css → Web3AuthProfileButton-k8_FAYFq.css} +1 -1
  102. package/dist/esm/react/components/AccountMenuButton/{Web3AuthProfileButton-DXFRw8ND.css.map → Web3AuthProfileButton-k8_FAYFq.css.map} +1 -1
  103. package/dist/esm/react/components/AccountMenuButton/icons/{TouchIcon-DNgbAK_i.css → TouchIcon-C-RcGfr5.css} +1 -1
  104. package/dist/esm/react/components/AccountMenuButton/icons/{TouchIcon-DNgbAK_i.css.map → TouchIcon-C-RcGfr5.css.map} +1 -1
  105. package/dist/esm/react/components/PasskeyAuthMenu/{PasskeyAuthMenu-DRwSoF8q.css → PasskeyAuthMenu-DKMiLeT9.css} +59 -4
  106. package/dist/esm/react/components/PasskeyAuthMenu/{PasskeyAuthMenu-DRwSoF8q.css.map → PasskeyAuthMenu-DKMiLeT9.css.map} +1 -1
  107. package/dist/esm/react/components/PasskeyAuthMenu/adapters/tatchi.js +1 -0
  108. package/dist/esm/react/components/PasskeyAuthMenu/adapters/tatchi.js.map +1 -1
  109. package/dist/esm/react/components/PasskeyAuthMenu/client.js +30 -8
  110. package/dist/esm/react/components/PasskeyAuthMenu/client.js.map +1 -1
  111. package/dist/esm/react/components/PasskeyAuthMenu/controller/useSDKEvents.js +20 -0
  112. package/dist/esm/react/components/PasskeyAuthMenu/controller/useSDKEvents.js.map +1 -0
  113. package/dist/esm/react/components/PasskeyAuthMenu/ui/ContentSwitcher.js +17 -4
  114. package/dist/esm/react/components/PasskeyAuthMenu/ui/ContentSwitcher.js.map +1 -1
  115. package/dist/esm/react/components/PasskeyAuthMenu/ui/EmailRecoverySlide.js +254 -140
  116. package/dist/esm/react/components/PasskeyAuthMenu/ui/EmailRecoverySlide.js.map +1 -1
  117. package/dist/esm/react/components/{ShowQRCode-CL4gsszN.css → ShowQRCode-CB0UCQ_h.css} +1 -1
  118. package/dist/esm/react/components/{ShowQRCode-CL4gsszN.css.map → ShowQRCode-CB0UCQ_h.css.map} +1 -1
  119. package/dist/esm/react/context/useSDKFlowRuntime.js +181 -0
  120. package/dist/esm/react/context/useSDKFlowRuntime.js.map +1 -0
  121. package/dist/esm/react/context/useTatchiContextValue.js +25 -16
  122. package/dist/esm/react/context/useTatchiContextValue.js.map +1 -1
  123. package/dist/esm/react/context/useTatchiWithSdkFlow.js +94 -0
  124. package/dist/esm/react/context/useTatchiWithSdkFlow.js.map +1 -0
  125. package/dist/esm/react/sdk/src/core/EmailRecovery/index.js +1 -1
  126. package/dist/esm/react/sdk/src/core/TatchiPasskey/emailRecovery.js +67 -45
  127. package/dist/esm/react/sdk/src/core/TatchiPasskey/emailRecovery.js.map +1 -1
  128. package/dist/esm/react/sdk/src/core/TatchiPasskey/index.js +2 -1
  129. package/dist/esm/react/sdk/src/core/TatchiPasskey/index.js.map +1 -1
  130. package/dist/esm/react/sdk/src/core/TatchiPasskey/linkDevice.js +2 -1
  131. package/dist/esm/react/sdk/src/core/TatchiPasskey/linkDevice.js.map +1 -1
  132. package/dist/esm/react/sdk/src/core/TatchiPasskey/scanDevice.js +5 -3
  133. package/dist/esm/react/sdk/src/core/TatchiPasskey/scanDevice.js.map +1 -1
  134. package/dist/esm/react/sdk/src/core/WalletIframe/client/router.js +1 -1
  135. package/dist/esm/react/sdk/src/core/WalletIframe/client/router.js.map +1 -1
  136. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/validation.js +2 -3
  137. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/validation.js.map +1 -1
  138. package/dist/esm/react/sdk/src/core/defaultConfigs.js +3 -7
  139. package/dist/esm/react/sdk/src/core/defaultConfigs.js.map +1 -1
  140. package/dist/esm/react/sdk/src/core/nearCrypto.js +24 -6
  141. package/dist/esm/react/sdk/src/core/nearCrypto.js.map +1 -1
  142. package/dist/esm/react/sdk/src/core/rpcCalls.js +56 -26
  143. package/dist/esm/react/sdk/src/core/rpcCalls.js.map +1 -1
  144. package/dist/esm/react/styles/styles.css +58 -3
  145. package/dist/esm/sdk/{defaultConfigs-DpslkAQd.js → defaultConfigs-CfQDV-ya.js} +3 -7
  146. package/dist/esm/sdk/{getDeviceNumber-fXizNGQl.js → getDeviceNumber-BpernPnM.js} +4 -8
  147. package/dist/esm/sdk/getDeviceNumber-BpernPnM.js.map +1 -0
  148. package/dist/esm/sdk/offline-export-app.js +23 -6
  149. package/dist/esm/sdk/offline-export-app.js.map +1 -1
  150. package/dist/esm/sdk/{router-DuGYOd3G.js → router-BWtacLJg.js} +1 -1
  151. package/dist/esm/sdk/{rpcCalls-BQrJMTdg.js → rpcCalls-CYGJSCgm.js} +3 -3
  152. package/dist/esm/sdk/{rpcCalls-YVeUVMk2.js → rpcCalls-DZZSa-sk.js} +57 -27
  153. package/dist/esm/sdk/{transactions-bqaAwL4k.js → transactions-Cn9xTWlK.js} +2 -2
  154. package/dist/esm/sdk/{transactions-bqaAwL4k.js.map → transactions-Cn9xTWlK.js.map} +1 -1
  155. package/dist/esm/sdk/{transactions-BalIhtJ9.js → transactions-DfdwDQCn.js} +1 -1
  156. package/dist/esm/sdk/wallet-iframe-host.js +549 -557
  157. package/dist/esm/server/email-recovery/emailParsers.js +3 -1
  158. package/dist/esm/server/email-recovery/emailParsers.js.map +1 -1
  159. package/dist/esm/server/email-recovery/index.js +6 -6
  160. package/dist/esm/server/email-recovery/index.js.map +1 -1
  161. package/dist/esm/server/email-recovery/rpcCalls.js +22 -3
  162. package/dist/esm/server/email-recovery/rpcCalls.js.map +1 -1
  163. package/dist/esm/server/router/cloudflare.js +8 -3
  164. package/dist/esm/server/router/cloudflare.js.map +1 -1
  165. package/dist/esm/server/router/express.js.map +1 -1
  166. package/dist/esm/server/sdk/src/core/defaultConfigs.js +2 -4
  167. package/dist/esm/server/sdk/src/core/defaultConfigs.js.map +1 -1
  168. package/dist/esm/server/sdk/src/core/nearCrypto.js +26 -8
  169. package/dist/esm/server/sdk/src/core/nearCrypto.js.map +1 -1
  170. package/dist/esm/wasm_vrf_worker/pkg/wasm_vrf_worker_bg.wasm +0 -0
  171. package/dist/types/src/core/TatchiPasskey/emailRecovery.d.ts +5 -4
  172. package/dist/types/src/core/TatchiPasskey/emailRecovery.d.ts.map +1 -1
  173. package/dist/types/src/core/TatchiPasskey/index.d.ts +1 -1
  174. package/dist/types/src/core/TatchiPasskey/index.d.ts.map +1 -1
  175. package/dist/types/src/core/TatchiPasskey/scanDevice.d.ts.map +1 -1
  176. package/dist/types/src/core/WalletIframe/TatchiPasskeyIframe.d.ts +1 -1
  177. package/dist/types/src/core/WalletIframe/TatchiPasskeyIframe.d.ts.map +1 -1
  178. package/dist/types/src/core/WalletIframe/client/router.d.ts +1 -1
  179. package/dist/types/src/core/WalletIframe/client/router.d.ts.map +1 -1
  180. package/dist/types/src/core/WalletIframe/shared/messages.d.ts +1 -1
  181. package/dist/types/src/core/WalletIframe/shared/messages.d.ts.map +1 -1
  182. package/dist/types/src/core/WebAuthnManager/SignerWorkerManager/handlers/validation.d.ts +2 -1
  183. package/dist/types/src/core/WebAuthnManager/SignerWorkerManager/handlers/validation.d.ts.map +1 -1
  184. package/dist/types/src/core/defaultConfigs.d.ts.map +1 -1
  185. package/dist/types/src/core/nearCrypto.d.ts +14 -0
  186. package/dist/types/src/core/nearCrypto.d.ts.map +1 -1
  187. package/dist/types/src/core/rpcCalls.d.ts +11 -8
  188. package/dist/types/src/core/rpcCalls.d.ts.map +1 -1
  189. package/dist/types/src/core/types/tatchi.d.ts +0 -4
  190. package/dist/types/src/core/types/tatchi.d.ts.map +1 -1
  191. package/dist/types/src/react/components/PasskeyAuthMenu/adapters/tatchi.d.ts +2 -0
  192. package/dist/types/src/react/components/PasskeyAuthMenu/adapters/tatchi.d.ts.map +1 -1
  193. package/dist/types/src/react/components/PasskeyAuthMenu/client.d.ts.map +1 -1
  194. package/dist/types/src/react/components/PasskeyAuthMenu/controller/useSDKEvents.d.ts +10 -0
  195. package/dist/types/src/react/components/PasskeyAuthMenu/controller/useSDKEvents.d.ts.map +1 -0
  196. package/dist/types/src/react/components/PasskeyAuthMenu/types.d.ts +8 -3
  197. package/dist/types/src/react/components/PasskeyAuthMenu/types.d.ts.map +1 -1
  198. package/dist/types/src/react/components/PasskeyAuthMenu/ui/ContentSwitcher.d.ts +2 -0
  199. package/dist/types/src/react/components/PasskeyAuthMenu/ui/ContentSwitcher.d.ts.map +1 -1
  200. package/dist/types/src/react/components/PasskeyAuthMenu/ui/EmailRecoverySlide.d.ts +1 -1
  201. package/dist/types/src/react/components/PasskeyAuthMenu/ui/EmailRecoverySlide.d.ts.map +1 -1
  202. package/dist/types/src/react/context/useSDKFlowRuntime.d.ts +10 -0
  203. package/dist/types/src/react/context/useSDKFlowRuntime.d.ts.map +1 -0
  204. package/dist/types/src/react/context/useTatchiContextValue.d.ts.map +1 -1
  205. package/dist/types/src/react/context/useTatchiWithSdkFlow.d.ts +9 -0
  206. package/dist/types/src/react/context/useTatchiWithSdkFlow.d.ts.map +1 -0
  207. package/dist/types/src/react/types.d.ts +31 -0
  208. package/dist/types/src/react/types.d.ts.map +1 -1
  209. package/dist/types/src/server/email-recovery/emailParsers.d.ts.map +1 -1
  210. package/dist/types/src/server/email-recovery/index.d.ts +5 -6
  211. package/dist/types/src/server/email-recovery/index.d.ts.map +1 -1
  212. package/dist/types/src/server/email-recovery/rpcCalls.d.ts +1 -0
  213. package/dist/types/src/server/email-recovery/rpcCalls.d.ts.map +1 -1
  214. package/dist/types/src/server/router/cloudflare-adaptor.d.ts.map +1 -1
  215. package/dist/workers/wasm_vrf_worker_bg.wasm +0 -0
  216. package/package.json +1 -1
  217. package/dist/esm/sdk/getDeviceNumber-fXizNGQl.js.map +0 -1
@@ -1,6 +1,6 @@
1
1
  const require_rolldown_runtime = require('../../../_virtual/rolldown_runtime.js');
2
- const require_accountIds = require('../../../sdk/src/core/types/accountIds.js');
3
- const require_index = require('../../../sdk/src/core/IndexedDBManager/index.js');
2
+ const require_sdkSentEvents = require('../../../sdk/src/core/types/sdkSentEvents.js');
3
+ const require_index = require('../../../sdk/src/core/EmailRecovery/index.js');
4
4
  const require_emailRecovery = require('../../../sdk/src/core/types/emailRecovery.js');
5
5
  let react = require("react");
6
6
  react = require_rolldown_runtime.__toESM(react);
@@ -8,9 +8,20 @@ let react_jsx_runtime = require("react/jsx-runtime");
8
8
  react_jsx_runtime = require_rolldown_runtime.__toESM(react_jsx_runtime);
9
9
 
10
10
  //#region src/react/components/PasskeyAuthMenu/ui/EmailRecoverySlide.tsx
11
- require_index.init_IndexedDBManager();
12
- require_accountIds.init_accountIds();
11
+ require_sdkSentEvents.init_sdkSentEvents();
13
12
  require_emailRecovery.init_emailRecovery();
13
+ require_index.init_EmailRecovery();
14
+ async function hashRecoveryEmailForAccountHex(args) {
15
+ const salt = String(args.accountId || "").trim().toLowerCase();
16
+ if (!salt) return null;
17
+ const canonical = require_index.canonicalizeEmail(String(args.recoveryEmail || ""));
18
+ if (!canonical || !canonical.includes("@")) return null;
19
+ if (typeof crypto === "undefined" || !crypto.subtle) return null;
20
+ const input = `${canonical}|${salt}`;
21
+ const bytes = new TextEncoder().encode(input);
22
+ const digest = await crypto.subtle.digest("SHA-256", bytes);
23
+ return require_index.bytesToHex(new Uint8Array(digest));
24
+ }
14
25
  function getEmailRecoveryErrorCode(err) {
15
26
  const code = err?.code;
16
27
  if (typeof code !== "string") return null;
@@ -18,6 +29,11 @@ function getEmailRecoveryErrorCode(err) {
18
29
  }
19
30
  function getEmailRecoveryUiError(err) {
20
31
  const fallback = err instanceof Error ? err.message : String(err || "");
32
+ const normalizedFallback = fallback.trim().toLowerCase();
33
+ if (normalizedFallback.includes("recovery email is required")) return {
34
+ message: fallback || "Recovery email is required for email-based account recovery. Make sure you send the email from your configured recovery email address.",
35
+ canRestart: true
36
+ };
21
37
  const code = getEmailRecoveryErrorCode(err);
22
38
  switch (code) {
23
39
  case require_emailRecovery.EmailRecoveryErrorCode.VRF_CHALLENGE_EXPIRED: return {
@@ -34,6 +50,19 @@ function getEmailRecoveryUiError(err) {
34
50
  };
35
51
  }
36
52
  }
53
+ function getEmailRecoveryErrorTxHash(err) {
54
+ const carrier = err;
55
+ const ctx = carrier?.context && typeof carrier.context === "object" ? carrier.context : null;
56
+ const details = carrier?.details && typeof carrier.details === "object" ? carrier.details : null;
57
+ const source = ctx ?? details;
58
+ if (!source) return null;
59
+ const txHash = source.transactionHash;
60
+ return typeof txHash === "string" && txHash.trim().length > 0 ? txHash.trim() : null;
61
+ }
62
+ function asRecord(value) {
63
+ if (!value || typeof value !== "object") return null;
64
+ return value;
65
+ }
37
66
  const EmailRecoverySlide = ({ tatchiPasskey, accountId, refreshLoginState, emailRecoveryOptions }) => {
38
67
  const mountedRef = react.default.useRef(true);
39
68
  const mailtoAttemptTimerRef = react.default.useRef(null);
@@ -50,7 +79,6 @@ const EmailRecoverySlide = ({ tatchiPasskey, accountId, refreshLoginState, email
50
79
  }, []);
51
80
  const [isBusy, setIsBusy] = react.default.useState(false);
52
81
  const [accountIdInput, setAccountIdInput] = react.default.useState("");
53
- const [recoveryEmailInput, setRecoveryEmailInput] = react.default.useState("");
54
82
  const [pendingMailtoUrl, setPendingMailtoUrl] = react.default.useState(null);
55
83
  const [pendingNearPublicKey, setPendingNearPublicKey] = react.default.useState(null);
56
84
  const [mailtoUiState, setMailtoUiState] = react.default.useState("ready");
@@ -62,9 +90,11 @@ const EmailRecoverySlide = ({ tatchiPasskey, accountId, refreshLoginState, email
62
90
  const [accountInfoLoading, setAccountInfoLoading] = react.default.useState(false);
63
91
  const [accountInfoError, setAccountInfoError] = react.default.useState(null);
64
92
  const [localRecoveryEmails, setLocalRecoveryEmails] = react.default.useState([]);
93
+ const [recoveryEmailRecords, setRecoveryEmailRecords] = react.default.useState([]);
94
+ const [recoveryEmailInput, setRecoveryEmailInput] = react.default.useState("");
95
+ const [recoveryEmailMatchStatus, setRecoveryEmailMatchStatus] = react.default.useState("empty");
65
96
  const [explorerToast, setExplorerToast] = react.default.useState(null);
66
97
  const lastPrefilledAccountIdRef = react.default.useRef("");
67
- const lastPrefilledRecoveryEmailRef = react.default.useRef("");
68
98
  react.default.useEffect(() => {
69
99
  const next = (accountId || "").trim();
70
100
  if (!next) return;
@@ -85,6 +115,9 @@ const EmailRecoverySlide = ({ tatchiPasskey, accountId, refreshLoginState, email
85
115
  setAccountInfo(null);
86
116
  setAccountInfoError(null);
87
117
  setLocalRecoveryEmails([]);
118
+ setRecoveryEmailRecords([]);
119
+ setRecoveryEmailInput("");
120
+ setRecoveryEmailMatchStatus("empty");
88
121
  setExplorerToast(null);
89
122
  if (mailtoAttemptTimerRef.current != null) {
90
123
  window.clearTimeout(mailtoAttemptTimerRef.current);
@@ -108,14 +141,16 @@ const EmailRecoverySlide = ({ tatchiPasskey, accountId, refreshLoginState, email
108
141
  const safeSetAccountInfoLoading = react.default.useMemo(() => safeSet(setAccountInfoLoading), []);
109
142
  const safeSetAccountInfoError = react.default.useMemo(() => safeSet(setAccountInfoError), []);
110
143
  const safeSetLocalRecoveryEmails = react.default.useMemo(() => safeSet(setLocalRecoveryEmails), []);
144
+ const safeSetRecoveryEmailRecords = react.default.useMemo(() => safeSet(setRecoveryEmailRecords), []);
145
+ const safeSetRecoveryEmailMatchStatus = react.default.useMemo(() => safeSet(setRecoveryEmailMatchStatus), []);
111
146
  const safeSetExplorerToast = react.default.useMemo(() => safeSet(setExplorerToast), []);
112
147
  const safeSetMailtoUiState = react.default.useMemo(() => safeSet(setMailtoUiState), []);
113
148
  const onEvent = react.default.useCallback((ev) => {
114
149
  if (cancelRequestedRef.current) return;
115
150
  safeSetStatusText(ev?.message || null);
116
151
  emailRecoveryOptions?.onEvent?.(ev);
117
- const data = ev?.data || {};
118
- const rawTxHash = data?.transactionHash ?? data?.transaction_hash;
152
+ const data = "data" in ev ? asRecord(ev.data) : null;
153
+ const rawTxHash = data?.["transactionHash"] ?? data?.["transaction_hash"];
119
154
  const txHash = typeof rawTxHash === "string" ? rawTxHash.trim() : "";
120
155
  if (txHash) {
121
156
  const base = String(tatchiPasskey.configs?.nearExplorerUrl || "https://testnet.nearblocks.io").replace(/\/$/, "");
@@ -125,13 +160,13 @@ const EmailRecoverySlide = ({ tatchiPasskey, accountId, refreshLoginState, email
125
160
  transactionHash: txHash
126
161
  });
127
162
  }
128
- const elapsedRaw = data?.elapsedMs ?? data?.elapsed_ms;
163
+ const elapsedRaw = data?.["elapsedMs"] ?? data?.["elapsed_ms"];
129
164
  if (elapsedRaw == null) safeSetPollingElapsedMs(null);
130
165
  const elapsed = elapsedRaw == null ? NaN : Number(elapsedRaw);
131
166
  if (!Number.isNaN(elapsed)) safeSetPollingElapsedMs(elapsed);
132
- if (ev?.phase === "email-recovery-error" || ev?.status === "error") {
133
- const raw = ev?.error || ev?.message || "Email recovery failed";
134
- safeSetErrorText(String(raw));
167
+ if (ev.phase === require_sdkSentEvents.EmailRecoveryPhase.ERROR || ev.status === require_sdkSentEvents.EmailRecoveryStatus.ERROR) {
168
+ const raw = "error" in ev ? ev.error : ev.message;
169
+ safeSetErrorText(raw || "Email recovery failed");
135
170
  safeSetCanRestart(false);
136
171
  }
137
172
  }, [
@@ -153,6 +188,16 @@ const EmailRecoverySlide = ({ tatchiPasskey, accountId, refreshLoginState, email
153
188
  accountId: normalized
154
189
  });
155
190
  }, [safeSetExplorerToast, tatchiPasskey]);
191
+ const showExplorerTxToast = react.default.useCallback((txHash) => {
192
+ const normalized = (txHash || "").trim();
193
+ if (!normalized) return;
194
+ const base = String(tatchiPasskey.configs?.nearExplorerUrl || "https://testnet.nearblocks.io").replace(/\/$/, "");
195
+ const url = base.includes("nearblocks.io") ? `${base}/txns/${normalized}` : `${base}/transactions/${normalized}`;
196
+ safeSetExplorerToast({
197
+ url,
198
+ transactionHash: normalized
199
+ });
200
+ }, [safeSetExplorerToast, tatchiPasskey]);
156
201
  const launchMailto = react.default.useCallback((rawMailtoUrl) => {
157
202
  const url = String(rawMailtoUrl || "").trim();
158
203
  if (!url) return;
@@ -198,40 +243,9 @@ const EmailRecoverySlide = ({ tatchiPasskey, accountId, refreshLoginState, email
198
243
  document.removeEventListener("visibilitychange", onVisibilityChange);
199
244
  };
200
245
  }, [mailtoUiState, safeSetMailtoUiState]);
201
- const fetchLocalRecoveryEmailsFromIndexedDB = react.default.useCallback(async (rawAccountId) => {
202
- const normalized = (rawAccountId || "").trim();
203
- if (!normalized) {
204
- console.log("[EmailRecoverySlide] fetchLocalRecoveryEmails: empty accountId");
205
- return [];
206
- }
207
- try {
208
- console.log("[EmailRecoverySlide] fetchLocalRecoveryEmails: loading from IndexedDB", { accountId: normalized });
209
- const records = await require_index.IndexedDBManager.getRecoveryEmails(require_accountIds.toAccountId(normalized));
210
- console.log("[EmailRecoverySlide] fetchLocalRecoveryEmails: raw IndexedDB records", {
211
- accountId: normalized,
212
- count: Array.isArray(records) ? records.length : 0,
213
- records
214
- });
215
- if (!Array.isArray(records) || records.length === 0) return [];
216
- const sorted = [...records].sort((a, b) => (b?.addedAt || 0) - (a?.addedAt || 0));
217
- const emails = sorted.map((r) => String(r?.email || "").trim().toLowerCase()).filter((e) => !!e && e.includes("@"));
218
- const uniq = Array.from(new Set(emails));
219
- console.log("[EmailRecoverySlide] fetchLocalRecoveryEmails: parsed emails", {
220
- accountId: normalized,
221
- emails: uniq
222
- });
223
- return uniq;
224
- } catch (err) {
225
- console.log("[EmailRecoverySlide] fetchLocalRecoveryEmails: failed to read IndexedDB", {
226
- accountId: normalized,
227
- error: err instanceof Error ? err.message : String(err)
228
- });
229
- return [];
230
- }
231
- }, []);
232
246
  const deriveEmailsFromRecoveryRecords = react.default.useCallback((records) => {
233
- if (!Array.isArray(records) || records.length === 0) return [];
234
- const emails = records.map((r) => String(r?.email || "").trim().toLowerCase()).filter((e) => !!e && e.includes("@"));
247
+ if (records.length === 0) return [];
248
+ const emails = records.map((r) => r.email.trim().toLowerCase()).filter((e) => e.length > 0 && e.includes("@"));
235
249
  return Array.from(new Set(emails));
236
250
  }, []);
237
251
  react.default.useEffect(() => {
@@ -249,27 +263,11 @@ const EmailRecoverySlide = ({ tatchiPasskey, accountId, refreshLoginState, email
249
263
  const handle = window.setTimeout(() => {
250
264
  (async () => {
251
265
  try {
252
- const isWalletIframeMode = !!tatchiPasskey.configs?.iframeWallet?.walletOrigin;
253
- let localEmails = [];
254
- if (!isWalletIframeMode) {
255
- localEmails = await fetchLocalRecoveryEmailsFromIndexedDB(normalized);
256
- if (!cancelled) console.log("[EmailRecoverySlide] local saved emails (IndexedDB)", {
257
- accountId: normalized,
258
- localEmails
259
- });
260
- }
261
266
  const records = await tatchiPasskey.getRecoveryEmails(normalized);
262
- const resolvedEmails = isWalletIframeMode ? deriveEmailsFromRecoveryRecords(records) : localEmails;
267
+ const resolvedEmails = deriveEmailsFromRecoveryRecords(records);
263
268
  if (!cancelled) {
264
269
  safeSetLocalRecoveryEmails(resolvedEmails);
265
- console.log("[EmailRecoverySlide] recovery email suggestions (state)", {
266
- accountId: normalized,
267
- emails: resolvedEmails
268
- });
269
- if (resolvedEmails.length === 1 && (recoveryEmailInput.trim() === "" || recoveryEmailInput === lastPrefilledRecoveryEmailRef.current)) {
270
- lastPrefilledRecoveryEmailRef.current = resolvedEmails[0];
271
- setRecoveryEmailInput(resolvedEmails[0]);
272
- }
270
+ safeSetRecoveryEmailRecords(records);
273
271
  }
274
272
  const info = records ? { emailsCount: Array.isArray(records) ? records.length : 0 } : null;
275
273
  if (cancelled) return;
@@ -277,7 +275,10 @@ const EmailRecoverySlide = ({ tatchiPasskey, accountId, refreshLoginState, email
277
275
  } catch (err) {
278
276
  if (cancelled) return;
279
277
  safeSetAccountInfo(null);
280
- safeSetAccountInfoError(err?.message || "Failed to load email recovery settings for this account");
278
+ const msg = err instanceof Error ? err.message : "";
279
+ safeSetAccountInfoError(msg || "Failed to load email recovery settings for this account");
280
+ safeSetLocalRecoveryEmails([]);
281
+ safeSetRecoveryEmailRecords([]);
281
282
  } finally {
282
283
  if (!cancelled) safeSetAccountInfoLoading(false);
283
284
  }
@@ -290,25 +291,100 @@ const EmailRecoverySlide = ({ tatchiPasskey, accountId, refreshLoginState, email
290
291
  }, [
291
292
  accountIdInput,
292
293
  deriveEmailsFromRecoveryRecords,
293
- fetchLocalRecoveryEmailsFromIndexedDB,
294
- recoveryEmailInput,
295
294
  safeSetAccountInfo,
296
295
  safeSetAccountInfoError,
297
296
  safeSetAccountInfoLoading,
298
297
  safeSetLocalRecoveryEmails,
298
+ safeSetRecoveryEmailRecords,
299
299
  tatchiPasskey
300
300
  ]);
301
+ const recoveryEmailConfirmationRequired = !accountInfoLoading && !accountInfoError && !!accountInfo && accountInfo.emailsCount > 0 && localRecoveryEmails.length === 0;
302
+ react.default.useEffect(() => {
303
+ const normalizedAccountId = (accountIdInput || "").trim();
304
+ const rawEmail = (recoveryEmailInput || "").trim();
305
+ if (!rawEmail || !normalizedAccountId) {
306
+ safeSetRecoveryEmailMatchStatus("empty");
307
+ return;
308
+ }
309
+ if (!Array.isArray(recoveryEmailRecords) || recoveryEmailRecords.length === 0) {
310
+ safeSetRecoveryEmailMatchStatus("checking");
311
+ return;
312
+ }
313
+ let cancelled = false;
314
+ safeSetRecoveryEmailMatchStatus("checking");
315
+ const handle = window.setTimeout(() => {
316
+ (async () => {
317
+ try {
318
+ const hashHex = await hashRecoveryEmailForAccountHex({
319
+ recoveryEmail: rawEmail,
320
+ accountId: normalizedAccountId
321
+ });
322
+ if (cancelled) return;
323
+ if (!hashHex) {
324
+ safeSetRecoveryEmailMatchStatus("invalid");
325
+ return;
326
+ }
327
+ const normalizedHashHex = hashHex.toLowerCase();
328
+ const matches = recoveryEmailRecords.some((rec) => String(rec.hashHex || "").toLowerCase() === normalizedHashHex);
329
+ safeSetRecoveryEmailMatchStatus(matches ? "match" : "mismatch");
330
+ } catch {
331
+ if (!cancelled) safeSetRecoveryEmailMatchStatus("invalid");
332
+ }
333
+ })();
334
+ }, 250);
335
+ return () => {
336
+ cancelled = true;
337
+ window.clearTimeout(handle);
338
+ };
339
+ }, [
340
+ accountIdInput,
341
+ recoveryEmailInput,
342
+ recoveryEmailRecords,
343
+ safeSetRecoveryEmailMatchStatus
344
+ ]);
301
345
  const handleStart = react.default.useCallback(async () => {
302
346
  const normalizedAccountId = (accountIdInput || "").trim();
303
347
  if (!normalizedAccountId) {
304
348
  safeSetErrorText("Enter an account ID.");
305
349
  return;
306
350
  }
307
- const emailCandidate = (recoveryEmailInput || "").trim().toLowerCase();
308
- if (!emailCandidate) {
309
- safeSetErrorText("Enter the recovery email to send from.");
351
+ if (accountInfoLoading) {
352
+ safeSetErrorText("Checking recovery email settings…");
310
353
  return;
311
354
  }
355
+ if (accountInfoError) {
356
+ safeSetErrorText(accountInfoError);
357
+ return;
358
+ }
359
+ if (!accountInfo) {
360
+ safeSetErrorText("Failed to load email recovery settings for this account.");
361
+ return;
362
+ }
363
+ if (accountInfo.emailsCount === 0) {
364
+ safeSetErrorText("No recovery emails are configured for this account.");
365
+ return;
366
+ }
367
+ const recoveryEmail = recoveryEmailInput.trim();
368
+ if (recoveryEmailConfirmationRequired) {
369
+ if (!recoveryEmail) {
370
+ safeSetErrorText("Enter the recovery email address you will send from.");
371
+ return;
372
+ }
373
+ const hashHex = await hashRecoveryEmailForAccountHex({
374
+ recoveryEmail,
375
+ accountId: normalizedAccountId
376
+ }).catch(() => null);
377
+ if (!hashHex) {
378
+ safeSetErrorText("Enter a valid recovery email address.");
379
+ return;
380
+ }
381
+ const normalizedHashHex = hashHex.toLowerCase();
382
+ const matches = recoveryEmailRecords.some((rec) => String(rec.hashHex || "").toLowerCase() === normalizedHashHex);
383
+ if (!matches) {
384
+ safeSetErrorText("That email is not configured for recovery on this account. Please use your configured recovery email address.");
385
+ return;
386
+ }
387
+ }
312
388
  safeSetIsBusy(true);
313
389
  cancelRequestedRef.current = false;
314
390
  safeSetErrorText(null);
@@ -322,7 +398,7 @@ const EmailRecoverySlide = ({ tatchiPasskey, accountId, refreshLoginState, email
322
398
  try {
323
399
  const result = await tatchiPasskey.startEmailRecovery({
324
400
  accountId: normalizedAccountId,
325
- recoveryEmail: emailCandidate,
401
+ ...recoveryEmail ? { recoveryEmail } : {},
326
402
  options: {
327
403
  onEvent,
328
404
  onError: (err) => {
@@ -330,8 +406,7 @@ const EmailRecoverySlide = ({ tatchiPasskey, accountId, refreshLoginState, email
330
406
  safeSetErrorText(err?.message || "Failed to start email recovery");
331
407
  didForwardError = true;
332
408
  emailRecoveryOptions?.onError?.(err);
333
- },
334
- afterCall: async () => {}
409
+ }
335
410
  }
336
411
  });
337
412
  safeSetPendingMailtoUrl(result.mailtoUrl);
@@ -348,10 +423,11 @@ const EmailRecoverySlide = ({ tatchiPasskey, accountId, refreshLoginState, email
348
423
  const uiError = getEmailRecoveryUiError(err);
349
424
  safeSetErrorText(uiError.message || "Failed to finalize email recovery");
350
425
  safeSetCanRestart(uiError.canRestart);
426
+ const txHash = getEmailRecoveryErrorTxHash(err);
427
+ if (txHash) showExplorerTxToast(txHash);
351
428
  didForwardError = true;
352
429
  emailRecoveryOptions?.onError?.(err);
353
- },
354
- afterCall: async () => {}
430
+ }
355
431
  }
356
432
  });
357
433
  showExplorerToast(normalizedAccountId);
@@ -382,6 +458,8 @@ const EmailRecoverySlide = ({ tatchiPasskey, accountId, refreshLoginState, email
382
458
  const uiError = getEmailRecoveryUiError(err);
383
459
  safeSetErrorText(uiError.message || "Failed to start email recovery");
384
460
  safeSetCanRestart(uiError.canRestart);
461
+ const txHash = getEmailRecoveryErrorTxHash(err);
462
+ if (txHash) showExplorerTxToast(txHash);
385
463
  if (!didForwardError && err instanceof Error) emailRecoveryOptions?.onError?.(err);
386
464
  } finally {
387
465
  safeSetIsBusy(false);
@@ -389,9 +467,14 @@ const EmailRecoverySlide = ({ tatchiPasskey, accountId, refreshLoginState, email
389
467
  }, [
390
468
  accountIdInput,
391
469
  emailRecoveryOptions,
392
- recoveryEmailInput,
393
470
  onEvent,
394
471
  refreshLoginState,
472
+ accountInfo,
473
+ accountInfoError,
474
+ accountInfoLoading,
475
+ recoveryEmailConfirmationRequired,
476
+ recoveryEmailInput,
477
+ recoveryEmailRecords,
395
478
  showExplorerToast,
396
479
  safeSetErrorText,
397
480
  safeSetIsBusy,
@@ -400,6 +483,7 @@ const EmailRecoverySlide = ({ tatchiPasskey, accountId, refreshLoginState, email
400
483
  safeSetStatusText,
401
484
  safeSetMailtoUiState,
402
485
  attemptOpenMailtoAuto,
486
+ showExplorerTxToast,
403
487
  tatchiPasskey
404
488
  ]);
405
489
  const handleRestart = react.default.useCallback(async () => {
@@ -436,8 +520,27 @@ const EmailRecoverySlide = ({ tatchiPasskey, accountId, refreshLoginState, email
436
520
  safeSetStatusText,
437
521
  tatchiPasskey
438
522
  ]);
439
- const summaryLine = accountInfoLoading ? "Checking if account has recovery emails configured..." : accountInfo && !accountInfoError ? `Recovery emails configured: ${accountInfo.emailsCount}` : "\xA0";
523
+ const summaryLine = accountInfoLoading ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: ["Checking if account has recovery emails configured", /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
524
+ className: "w3a-ellipsis",
525
+ "aria-hidden": "true",
526
+ children: [
527
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
528
+ className: "w3a-ellipsis-dot",
529
+ children: "."
530
+ }),
531
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
532
+ className: "w3a-ellipsis-dot",
533
+ children: "."
534
+ }),
535
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
536
+ className: "w3a-ellipsis-dot",
537
+ children: "."
538
+ })
539
+ ]
540
+ })] }) : accountInfo && !accountInfoError ? `Recovery emails configured: ${accountInfo.emailsCount}` : "\xA0";
440
541
  const noRecoveryEmailsConfigured = !accountInfoLoading && !accountInfoError && !!accountInfo && accountInfo.emailsCount === 0;
542
+ const disableStartForRecoveryEmailMismatch = recoveryEmailConfirmationRequired && (recoveryEmailMatchStatus === "empty" || recoveryEmailMatchStatus === "checking" || recoveryEmailMatchStatus === "invalid" || recoveryEmailMatchStatus === "mismatch");
543
+ const startDisabled = isBusy || accountInfoLoading || !!accountInfoError || !accountInfo || noRecoveryEmailsConfigured || disableStartForRecoveryEmailMismatch;
441
544
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
442
545
  className: "w3a-email-recovery-slide",
443
546
  children: [
@@ -447,73 +550,84 @@ const EmailRecoverySlide = ({ tatchiPasskey, accountId, refreshLoginState, email
447
550
  }),
448
551
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
449
552
  className: "w3a-email-recovery-help",
450
- children: "Send a recovery email from your registered email address. Your account will be recovered with a new key once the email is verified."
553
+ children: "Send a special email to recover your account. This email must be sent from the designated email recovery address."
451
554
  }),
452
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
453
- className: "w3a-email-recovery-field",
555
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
556
+ className: "w3a-input-pill w3a-email-recovery-input-pill",
454
557
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
455
- className: "w3a-input-pill w3a-email-recovery-input-pill",
456
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
457
- className: "w3a-input-wrap",
458
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
459
- type: "text",
460
- value: accountIdInput,
461
- onChange: (e) => setAccountIdInput(e.target.value),
462
- placeholder: "NEAR account ID (e.g. alice.testnet)",
463
- className: "w3a-input",
464
- autoCapitalize: "none",
465
- autoCorrect: "off",
466
- spellCheck: false,
467
- inputMode: "text",
468
- disabled: isBusy
469
- })
558
+ className: "w3a-input-wrap",
559
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
560
+ type: "text",
561
+ value: accountIdInput,
562
+ onChange: (e) => setAccountIdInput(e.target.value),
563
+ placeholder: "NEAR account ID (e.g. alice.testnet)",
564
+ className: "w3a-input",
565
+ autoCapitalize: "none",
566
+ autoCorrect: "off",
567
+ spellCheck: false,
568
+ inputMode: "text",
569
+ disabled: isBusy
470
570
  })
471
571
  })
472
- }),
473
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
572
+ }) }),
573
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
474
574
  className: "w3a-email-recovery-summary",
475
575
  "aria-live": "polite",
476
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { children: summaryLine })
477
- }),
478
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
479
- className: "w3a-email-recovery-field",
480
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
481
- className: "w3a-input-pill w3a-email-recovery-input-pill",
482
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
483
- className: "w3a-input-wrap",
484
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
485
- type: "email",
486
- value: recoveryEmailInput,
487
- onChange: (e) => setRecoveryEmailInput(e.target.value),
488
- placeholder: "Recovery email to send from",
489
- className: "w3a-input",
490
- list: localRecoveryEmails.length > 0 ? "w3a-email-recovery-saved-emails" : void 0,
491
- autoCapitalize: "none",
492
- autoCorrect: "off",
493
- spellCheck: false,
494
- inputMode: "email",
495
- disabled: isBusy || noRecoveryEmailsConfigured
496
- })
576
+ children: [
577
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { children: summaryLine }),
578
+ !!accountInfoError && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
579
+ className: "w3a-email-recovery-warning",
580
+ children: accountInfoError
581
+ }),
582
+ localRecoveryEmails.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
583
+ className: "w3a-email-recovery-saved-emails",
584
+ role: "list",
585
+ "aria-label": "Recovery emails",
586
+ children: localRecoveryEmails.map((email) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
587
+ className: "w3a-email-recovery-email-chip w3a-email-recovery-email-chip-static",
588
+ role: "listitem",
589
+ children: email
590
+ }, email))
591
+ }),
592
+ recoveryEmailConfirmationRequired && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
593
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
594
+ className: "w3a-email-recovery-warning",
595
+ children: "This device can’t display your configured recovery email address. Enter the email you will send from to confirm it matches what’s configured for this account."
596
+ }),
597
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
598
+ className: "w3a-input-pill w3a-email-recovery-input-pill",
599
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
600
+ className: "w3a-input-wrap",
601
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
602
+ type: "email",
603
+ value: recoveryEmailInput,
604
+ onChange: (e) => setRecoveryEmailInput(e.target.value),
605
+ placeholder: "Recovery email address (sender)",
606
+ className: "w3a-input",
607
+ autoCapitalize: "none",
608
+ autoCorrect: "off",
609
+ spellCheck: false,
610
+ inputMode: "email",
611
+ disabled: isBusy
612
+ })
613
+ })
614
+ }),
615
+ recoveryEmailMatchStatus === "checking" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { children: "Checking recovery email…" }),
616
+ recoveryEmailMatchStatus === "invalid" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
617
+ className: "w3a-email-recovery-warning",
618
+ children: "Enter a valid email address."
619
+ }),
620
+ recoveryEmailMatchStatus === "mismatch" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
621
+ className: "w3a-email-recovery-warning",
622
+ children: "That email is not configured for recovery on this account."
623
+ }),
624
+ recoveryEmailMatchStatus === "match" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { children: "Recovery email verified for this account." })
625
+ ] }),
626
+ !!accountIdInput.trim() && !noRecoveryEmailsConfigured && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
627
+ className: "w3a-email-recovery-from-warning",
628
+ children: recoveryEmailInput.trim() ? `Check that you are sending the recovery email from ${recoveryEmailInput.trim()}.` : "Check that you are sending the recovery email from your designated recovery email."
497
629
  })
498
- })
499
- }),
500
- localRecoveryEmails.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
501
- className: "w3a-email-recovery-summary",
502
- "aria-live": "polite",
503
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { children: "Saved on this device:" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
504
- className: "w3a-email-recovery-saved-emails",
505
- children: localRecoveryEmails.map((email) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
506
- type: "button",
507
- className: "w3a-email-recovery-email-chip",
508
- onClick: () => setRecoveryEmailInput(email),
509
- disabled: isBusy,
510
- children: email
511
- }, email))
512
- })]
513
- }),
514
- localRecoveryEmails.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("datalist", {
515
- id: "w3a-email-recovery-saved-emails",
516
- children: localRecoveryEmails.map((email) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", { value: email }, email))
630
+ ]
517
631
  }),
518
632
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
519
633
  className: "w3a-email-recovery-actions",
@@ -521,8 +635,8 @@ const EmailRecoverySlide = ({ tatchiPasskey, accountId, refreshLoginState, email
521
635
  (!pendingMailtoUrl || !isBusy) && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
522
636
  onClick: handleStart,
523
637
  className: "w3a-link-device-btn w3a-link-device-btn-primary",
524
- disabled: isBusy || noRecoveryEmailsConfigured,
525
- children: noRecoveryEmailsConfigured ? "No recovery emails configured" : isBusy ? "Working…" : "Start Email Recovery"
638
+ disabled: startDisabled,
639
+ children: accountInfoLoading ? "Checking recovery emails…" : noRecoveryEmailsConfigured ? "No recovery emails configured" : disableStartForRecoveryEmailMismatch ? "Confirm recovery email" : isBusy ? "Working…" : "Start Email Recovery"
526
640
  }),
527
641
  pendingMailtoUrl && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
528
642
  type: "button",
@@ -556,13 +670,13 @@ const EmailRecoverySlide = ({ tatchiPasskey, accountId, refreshLoginState, email
556
670
  "s)."
557
671
  ]
558
672
  }),
559
- explorerToast && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
673
+ explorerToast && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("br", {}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
560
674
  className: "w3a-email-recovery-link",
561
675
  href: explorerToast.url,
562
676
  target: "_blank",
563
677
  rel: "noopener noreferrer",
564
678
  children: "View on explorer"
565
- }) })
679
+ })] })
566
680
  ]
567
681
  })
568
682
  ]