@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.
- package/dist/cjs/core/TatchiPasskey/emailRecovery.js +67 -45
- package/dist/cjs/core/TatchiPasskey/emailRecovery.js.map +1 -1
- package/dist/cjs/core/TatchiPasskey/index.js +2 -1
- package/dist/cjs/core/TatchiPasskey/index.js.map +1 -1
- package/dist/cjs/core/TatchiPasskey/linkDevice.js +2 -1
- package/dist/cjs/core/TatchiPasskey/linkDevice.js.map +1 -1
- package/dist/cjs/core/TatchiPasskey/scanDevice.js +5 -3
- package/dist/cjs/core/TatchiPasskey/scanDevice.js.map +1 -1
- package/dist/cjs/core/WalletIframe/client/router.js +1 -1
- package/dist/cjs/core/WalletIframe/client/router.js.map +1 -1
- package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/validation.js +3 -4
- package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/validation.js.map +1 -1
- package/dist/cjs/core/defaultConfigs.js +3 -7
- package/dist/cjs/core/defaultConfigs.js.map +1 -1
- package/dist/cjs/core/nearCrypto.js +29 -5
- package/dist/cjs/core/nearCrypto.js.map +1 -1
- package/dist/cjs/core/rpcCalls.js +56 -26
- package/dist/cjs/core/rpcCalls.js.map +1 -1
- package/dist/cjs/react/components/AccountMenuButton/{LinkedDevicesModal-BCrFe5p3.css → LinkedDevicesModal-BRtht0XI.css} +1 -1
- package/dist/{esm/react/components/AccountMenuButton/LinkedDevicesModal-BCrFe5p3.css.map → cjs/react/components/AccountMenuButton/LinkedDevicesModal-BRtht0XI.css.map} +1 -1
- package/dist/cjs/react/components/AccountMenuButton/{ProfileDropdown-CRJrtxDb.css → ProfileDropdown-BG_6hcim.css} +1 -1
- package/dist/{esm/react/components/AccountMenuButton/ProfileDropdown-CRJrtxDb.css.map → cjs/react/components/AccountMenuButton/ProfileDropdown-BG_6hcim.css.map} +1 -1
- package/dist/cjs/react/components/AccountMenuButton/{Web3AuthProfileButton-DXFRw8ND.css → Web3AuthProfileButton-k8_FAYFq.css} +1 -1
- package/dist/cjs/react/components/AccountMenuButton/{Web3AuthProfileButton-DXFRw8ND.css.map → Web3AuthProfileButton-k8_FAYFq.css.map} +1 -1
- package/dist/cjs/react/components/AccountMenuButton/icons/{TouchIcon-DNgbAK_i.css → TouchIcon-C-RcGfr5.css} +1 -1
- package/dist/cjs/react/components/AccountMenuButton/icons/{TouchIcon-DNgbAK_i.css.map → TouchIcon-C-RcGfr5.css.map} +1 -1
- package/dist/cjs/react/components/PasskeyAuthMenu/{PasskeyAuthMenu-DRwSoF8q.css → PasskeyAuthMenu-DKMiLeT9.css} +59 -4
- package/dist/cjs/react/components/PasskeyAuthMenu/{PasskeyAuthMenu-DRwSoF8q.css.map → PasskeyAuthMenu-DKMiLeT9.css.map} +1 -1
- package/dist/cjs/react/components/PasskeyAuthMenu/adapters/tatchi.js +1 -0
- package/dist/cjs/react/components/PasskeyAuthMenu/adapters/tatchi.js.map +1 -1
- package/dist/cjs/react/components/PasskeyAuthMenu/client.js +30 -8
- package/dist/cjs/react/components/PasskeyAuthMenu/client.js.map +1 -1
- package/dist/cjs/react/components/PasskeyAuthMenu/controller/useSDKEvents.js +22 -0
- package/dist/cjs/react/components/PasskeyAuthMenu/controller/useSDKEvents.js.map +1 -0
- package/dist/cjs/react/components/PasskeyAuthMenu/ui/ContentSwitcher.js +17 -4
- package/dist/cjs/react/components/PasskeyAuthMenu/ui/ContentSwitcher.js.map +1 -1
- package/dist/cjs/react/components/PasskeyAuthMenu/ui/EmailRecoverySlide.js +254 -140
- package/dist/cjs/react/components/PasskeyAuthMenu/ui/EmailRecoverySlide.js.map +1 -1
- package/dist/cjs/react/components/{ShowQRCode-CL4gsszN.css → ShowQRCode-CB0UCQ_h.css} +1 -1
- package/dist/cjs/react/components/{ShowQRCode-CL4gsszN.css.map → ShowQRCode-CB0UCQ_h.css.map} +1 -1
- package/dist/cjs/react/context/useSDKFlowRuntime.js +183 -0
- package/dist/cjs/react/context/useSDKFlowRuntime.js.map +1 -0
- package/dist/cjs/react/context/useTatchiContextValue.js +24 -15
- package/dist/cjs/react/context/useTatchiContextValue.js.map +1 -1
- package/dist/cjs/react/context/useTatchiWithSdkFlow.js +96 -0
- package/dist/cjs/react/context/useTatchiWithSdkFlow.js.map +1 -0
- package/dist/cjs/react/sdk/src/core/EmailRecovery/index.js +1 -0
- package/dist/cjs/react/sdk/src/core/TatchiPasskey/emailRecovery.js +67 -45
- package/dist/cjs/react/sdk/src/core/TatchiPasskey/emailRecovery.js.map +1 -1
- package/dist/cjs/react/sdk/src/core/TatchiPasskey/index.js +2 -1
- package/dist/cjs/react/sdk/src/core/TatchiPasskey/index.js.map +1 -1
- package/dist/cjs/react/sdk/src/core/TatchiPasskey/linkDevice.js +2 -1
- package/dist/cjs/react/sdk/src/core/TatchiPasskey/linkDevice.js.map +1 -1
- package/dist/cjs/react/sdk/src/core/TatchiPasskey/scanDevice.js +5 -3
- package/dist/cjs/react/sdk/src/core/TatchiPasskey/scanDevice.js.map +1 -1
- package/dist/cjs/react/sdk/src/core/WalletIframe/client/router.js +1 -1
- package/dist/cjs/react/sdk/src/core/WalletIframe/client/router.js.map +1 -1
- package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/validation.js +3 -4
- package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/validation.js.map +1 -1
- package/dist/cjs/react/sdk/src/core/defaultConfigs.js +3 -7
- package/dist/cjs/react/sdk/src/core/defaultConfigs.js.map +1 -1
- package/dist/cjs/react/sdk/src/core/nearCrypto.js +29 -5
- package/dist/cjs/react/sdk/src/core/nearCrypto.js.map +1 -1
- package/dist/cjs/react/sdk/src/core/rpcCalls.js +56 -26
- package/dist/cjs/react/sdk/src/core/rpcCalls.js.map +1 -1
- package/dist/cjs/server/email-recovery/emailParsers.js +2 -1
- package/dist/cjs/server/email-recovery/emailParsers.js.map +1 -1
- package/dist/cjs/server/email-recovery/index.js +6 -6
- package/dist/cjs/server/email-recovery/index.js.map +1 -1
- package/dist/cjs/server/email-recovery/rpcCalls.js +22 -3
- package/dist/cjs/server/email-recovery/rpcCalls.js.map +1 -1
- package/dist/cjs/server/router/cloudflare.js +8 -3
- package/dist/cjs/server/router/cloudflare.js.map +1 -1
- package/dist/cjs/server/router/express.js.map +1 -1
- package/dist/cjs/server/sdk/src/core/defaultConfigs.js +2 -4
- package/dist/cjs/server/sdk/src/core/defaultConfigs.js.map +1 -1
- package/dist/cjs/server/sdk/src/core/nearCrypto.js +26 -7
- package/dist/cjs/server/sdk/src/core/nearCrypto.js.map +1 -1
- package/dist/esm/core/TatchiPasskey/emailRecovery.js +67 -45
- package/dist/esm/core/TatchiPasskey/emailRecovery.js.map +1 -1
- package/dist/esm/core/TatchiPasskey/index.js +2 -1
- package/dist/esm/core/TatchiPasskey/index.js.map +1 -1
- package/dist/esm/core/TatchiPasskey/linkDevice.js +2 -1
- package/dist/esm/core/TatchiPasskey/linkDevice.js.map +1 -1
- package/dist/esm/core/TatchiPasskey/scanDevice.js +5 -3
- package/dist/esm/core/TatchiPasskey/scanDevice.js.map +1 -1
- package/dist/esm/core/WalletIframe/client/router.js +1 -1
- package/dist/esm/core/WalletIframe/client/router.js.map +1 -1
- package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/validation.js +2 -3
- package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/validation.js.map +1 -1
- package/dist/esm/core/defaultConfigs.js +3 -7
- package/dist/esm/core/defaultConfigs.js.map +1 -1
- package/dist/esm/core/nearCrypto.js +24 -6
- package/dist/esm/core/nearCrypto.js.map +1 -1
- package/dist/esm/core/rpcCalls.js +56 -26
- package/dist/esm/core/rpcCalls.js.map +1 -1
- package/dist/esm/react/components/AccountMenuButton/{LinkedDevicesModal-BCrFe5p3.css → LinkedDevicesModal-BRtht0XI.css} +1 -1
- package/dist/{cjs/react/components/AccountMenuButton/LinkedDevicesModal-BCrFe5p3.css.map → esm/react/components/AccountMenuButton/LinkedDevicesModal-BRtht0XI.css.map} +1 -1
- package/dist/esm/react/components/AccountMenuButton/{ProfileDropdown-CRJrtxDb.css → ProfileDropdown-BG_6hcim.css} +1 -1
- package/dist/{cjs/react/components/AccountMenuButton/ProfileDropdown-CRJrtxDb.css.map → esm/react/components/AccountMenuButton/ProfileDropdown-BG_6hcim.css.map} +1 -1
- package/dist/esm/react/components/AccountMenuButton/{Web3AuthProfileButton-DXFRw8ND.css → Web3AuthProfileButton-k8_FAYFq.css} +1 -1
- package/dist/esm/react/components/AccountMenuButton/{Web3AuthProfileButton-DXFRw8ND.css.map → Web3AuthProfileButton-k8_FAYFq.css.map} +1 -1
- package/dist/esm/react/components/AccountMenuButton/icons/{TouchIcon-DNgbAK_i.css → TouchIcon-C-RcGfr5.css} +1 -1
- package/dist/esm/react/components/AccountMenuButton/icons/{TouchIcon-DNgbAK_i.css.map → TouchIcon-C-RcGfr5.css.map} +1 -1
- package/dist/esm/react/components/PasskeyAuthMenu/{PasskeyAuthMenu-DRwSoF8q.css → PasskeyAuthMenu-DKMiLeT9.css} +59 -4
- package/dist/esm/react/components/PasskeyAuthMenu/{PasskeyAuthMenu-DRwSoF8q.css.map → PasskeyAuthMenu-DKMiLeT9.css.map} +1 -1
- package/dist/esm/react/components/PasskeyAuthMenu/adapters/tatchi.js +1 -0
- package/dist/esm/react/components/PasskeyAuthMenu/adapters/tatchi.js.map +1 -1
- package/dist/esm/react/components/PasskeyAuthMenu/client.js +30 -8
- package/dist/esm/react/components/PasskeyAuthMenu/client.js.map +1 -1
- package/dist/esm/react/components/PasskeyAuthMenu/controller/useSDKEvents.js +20 -0
- package/dist/esm/react/components/PasskeyAuthMenu/controller/useSDKEvents.js.map +1 -0
- package/dist/esm/react/components/PasskeyAuthMenu/ui/ContentSwitcher.js +17 -4
- package/dist/esm/react/components/PasskeyAuthMenu/ui/ContentSwitcher.js.map +1 -1
- package/dist/esm/react/components/PasskeyAuthMenu/ui/EmailRecoverySlide.js +254 -140
- package/dist/esm/react/components/PasskeyAuthMenu/ui/EmailRecoverySlide.js.map +1 -1
- package/dist/esm/react/components/{ShowQRCode-CL4gsszN.css → ShowQRCode-CB0UCQ_h.css} +1 -1
- package/dist/esm/react/components/{ShowQRCode-CL4gsszN.css.map → ShowQRCode-CB0UCQ_h.css.map} +1 -1
- package/dist/esm/react/context/useSDKFlowRuntime.js +181 -0
- package/dist/esm/react/context/useSDKFlowRuntime.js.map +1 -0
- package/dist/esm/react/context/useTatchiContextValue.js +25 -16
- package/dist/esm/react/context/useTatchiContextValue.js.map +1 -1
- package/dist/esm/react/context/useTatchiWithSdkFlow.js +94 -0
- package/dist/esm/react/context/useTatchiWithSdkFlow.js.map +1 -0
- package/dist/esm/react/sdk/src/core/EmailRecovery/index.js +1 -1
- package/dist/esm/react/sdk/src/core/TatchiPasskey/emailRecovery.js +67 -45
- package/dist/esm/react/sdk/src/core/TatchiPasskey/emailRecovery.js.map +1 -1
- package/dist/esm/react/sdk/src/core/TatchiPasskey/index.js +2 -1
- package/dist/esm/react/sdk/src/core/TatchiPasskey/index.js.map +1 -1
- package/dist/esm/react/sdk/src/core/TatchiPasskey/linkDevice.js +2 -1
- package/dist/esm/react/sdk/src/core/TatchiPasskey/linkDevice.js.map +1 -1
- package/dist/esm/react/sdk/src/core/TatchiPasskey/scanDevice.js +5 -3
- package/dist/esm/react/sdk/src/core/TatchiPasskey/scanDevice.js.map +1 -1
- package/dist/esm/react/sdk/src/core/WalletIframe/client/router.js +1 -1
- package/dist/esm/react/sdk/src/core/WalletIframe/client/router.js.map +1 -1
- package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/validation.js +2 -3
- package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/validation.js.map +1 -1
- package/dist/esm/react/sdk/src/core/defaultConfigs.js +3 -7
- package/dist/esm/react/sdk/src/core/defaultConfigs.js.map +1 -1
- package/dist/esm/react/sdk/src/core/nearCrypto.js +24 -6
- package/dist/esm/react/sdk/src/core/nearCrypto.js.map +1 -1
- package/dist/esm/react/sdk/src/core/rpcCalls.js +56 -26
- package/dist/esm/react/sdk/src/core/rpcCalls.js.map +1 -1
- package/dist/esm/react/styles/styles.css +58 -3
- package/dist/esm/sdk/{defaultConfigs-DpslkAQd.js → defaultConfigs-CfQDV-ya.js} +3 -7
- package/dist/esm/sdk/{getDeviceNumber-fXizNGQl.js → getDeviceNumber-BpernPnM.js} +4 -8
- package/dist/esm/sdk/getDeviceNumber-BpernPnM.js.map +1 -0
- package/dist/esm/sdk/offline-export-app.js +23 -6
- package/dist/esm/sdk/offline-export-app.js.map +1 -1
- package/dist/esm/sdk/{router-DuGYOd3G.js → router-BWtacLJg.js} +1 -1
- package/dist/esm/sdk/{rpcCalls-BQrJMTdg.js → rpcCalls-CYGJSCgm.js} +3 -3
- package/dist/esm/sdk/{rpcCalls-YVeUVMk2.js → rpcCalls-DZZSa-sk.js} +57 -27
- package/dist/esm/sdk/{transactions-bqaAwL4k.js → transactions-Cn9xTWlK.js} +2 -2
- package/dist/esm/sdk/{transactions-bqaAwL4k.js.map → transactions-Cn9xTWlK.js.map} +1 -1
- package/dist/esm/sdk/{transactions-BalIhtJ9.js → transactions-DfdwDQCn.js} +1 -1
- package/dist/esm/sdk/wallet-iframe-host.js +549 -557
- package/dist/esm/server/email-recovery/emailParsers.js +3 -1
- package/dist/esm/server/email-recovery/emailParsers.js.map +1 -1
- package/dist/esm/server/email-recovery/index.js +6 -6
- package/dist/esm/server/email-recovery/index.js.map +1 -1
- package/dist/esm/server/email-recovery/rpcCalls.js +22 -3
- package/dist/esm/server/email-recovery/rpcCalls.js.map +1 -1
- package/dist/esm/server/router/cloudflare.js +8 -3
- package/dist/esm/server/router/cloudflare.js.map +1 -1
- package/dist/esm/server/router/express.js.map +1 -1
- package/dist/esm/server/sdk/src/core/defaultConfigs.js +2 -4
- package/dist/esm/server/sdk/src/core/defaultConfigs.js.map +1 -1
- package/dist/esm/server/sdk/src/core/nearCrypto.js +26 -8
- package/dist/esm/server/sdk/src/core/nearCrypto.js.map +1 -1
- package/dist/esm/wasm_vrf_worker/pkg/wasm_vrf_worker_bg.wasm +0 -0
- package/dist/types/src/core/TatchiPasskey/emailRecovery.d.ts +5 -4
- package/dist/types/src/core/TatchiPasskey/emailRecovery.d.ts.map +1 -1
- package/dist/types/src/core/TatchiPasskey/index.d.ts +1 -1
- package/dist/types/src/core/TatchiPasskey/index.d.ts.map +1 -1
- package/dist/types/src/core/TatchiPasskey/scanDevice.d.ts.map +1 -1
- package/dist/types/src/core/WalletIframe/TatchiPasskeyIframe.d.ts +1 -1
- package/dist/types/src/core/WalletIframe/TatchiPasskeyIframe.d.ts.map +1 -1
- package/dist/types/src/core/WalletIframe/client/router.d.ts +1 -1
- package/dist/types/src/core/WalletIframe/client/router.d.ts.map +1 -1
- package/dist/types/src/core/WalletIframe/shared/messages.d.ts +1 -1
- package/dist/types/src/core/WalletIframe/shared/messages.d.ts.map +1 -1
- package/dist/types/src/core/WebAuthnManager/SignerWorkerManager/handlers/validation.d.ts +2 -1
- package/dist/types/src/core/WebAuthnManager/SignerWorkerManager/handlers/validation.d.ts.map +1 -1
- package/dist/types/src/core/defaultConfigs.d.ts.map +1 -1
- package/dist/types/src/core/nearCrypto.d.ts +14 -0
- package/dist/types/src/core/nearCrypto.d.ts.map +1 -1
- package/dist/types/src/core/rpcCalls.d.ts +11 -8
- package/dist/types/src/core/rpcCalls.d.ts.map +1 -1
- package/dist/types/src/core/types/tatchi.d.ts +0 -4
- package/dist/types/src/core/types/tatchi.d.ts.map +1 -1
- package/dist/types/src/react/components/PasskeyAuthMenu/adapters/tatchi.d.ts +2 -0
- package/dist/types/src/react/components/PasskeyAuthMenu/adapters/tatchi.d.ts.map +1 -1
- package/dist/types/src/react/components/PasskeyAuthMenu/client.d.ts.map +1 -1
- package/dist/types/src/react/components/PasskeyAuthMenu/controller/useSDKEvents.d.ts +10 -0
- package/dist/types/src/react/components/PasskeyAuthMenu/controller/useSDKEvents.d.ts.map +1 -0
- package/dist/types/src/react/components/PasskeyAuthMenu/types.d.ts +8 -3
- package/dist/types/src/react/components/PasskeyAuthMenu/types.d.ts.map +1 -1
- package/dist/types/src/react/components/PasskeyAuthMenu/ui/ContentSwitcher.d.ts +2 -0
- package/dist/types/src/react/components/PasskeyAuthMenu/ui/ContentSwitcher.d.ts.map +1 -1
- package/dist/types/src/react/components/PasskeyAuthMenu/ui/EmailRecoverySlide.d.ts +1 -1
- package/dist/types/src/react/components/PasskeyAuthMenu/ui/EmailRecoverySlide.d.ts.map +1 -1
- package/dist/types/src/react/context/useSDKFlowRuntime.d.ts +10 -0
- package/dist/types/src/react/context/useSDKFlowRuntime.d.ts.map +1 -0
- package/dist/types/src/react/context/useTatchiContextValue.d.ts.map +1 -1
- package/dist/types/src/react/context/useTatchiWithSdkFlow.d.ts +9 -0
- package/dist/types/src/react/context/useTatchiWithSdkFlow.d.ts.map +1 -0
- package/dist/types/src/react/types.d.ts +31 -0
- package/dist/types/src/react/types.d.ts.map +1 -1
- package/dist/types/src/server/email-recovery/emailParsers.d.ts.map +1 -1
- package/dist/types/src/server/email-recovery/index.d.ts +5 -6
- package/dist/types/src/server/email-recovery/index.d.ts.map +1 -1
- package/dist/types/src/server/email-recovery/rpcCalls.d.ts +1 -0
- package/dist/types/src/server/email-recovery/rpcCalls.d.ts.map +1 -1
- package/dist/types/src/server/router/cloudflare-adaptor.d.ts.map +1 -1
- package/dist/workers/wasm_vrf_worker_bg.wasm +0 -0
- package/package.json +1 -1
- 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
|
|
3
|
-
const require_index = require('../../../sdk/src/core/
|
|
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
|
-
|
|
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
|
|
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
|
|
133
|
-
const raw =
|
|
134
|
-
safeSetErrorText(
|
|
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 (
|
|
234
|
-
const emails = records.map((r) =>
|
|
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 =
|
|
267
|
+
const resolvedEmails = deriveEmailsFromRecoveryRecords(records);
|
|
263
268
|
if (!cancelled) {
|
|
264
269
|
safeSetLocalRecoveryEmails(resolvedEmails);
|
|
265
|
-
|
|
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
|
-
|
|
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
|
-
|
|
308
|
-
|
|
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:
|
|
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
|
|
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
|
|
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-
|
|
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-
|
|
456
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
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.
|
|
572
|
+
}) }),
|
|
573
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
474
574
|
className: "w3a-email-recovery-summary",
|
|
475
575
|
"aria-live": "polite",
|
|
476
|
-
children:
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
className: "w3a-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
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:
|
|
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.
|
|
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
|
]
|