@tatchi-xyz/sdk 0.19.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/EmailRecovery/index.js +25 -0
- package/dist/cjs/core/EmailRecovery/index.js.map +1 -1
- package/dist/cjs/core/TatchiPasskey/emailRecovery.js +135 -77
- 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/core/types/emailRecovery.js +33 -0
- package/dist/cjs/core/types/emailRecovery.js.map +1 -0
- package/dist/cjs/index.js +4 -0
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/react/components/AccountMenuButton/{LinkedDevicesModal-CSSowiHP.css → LinkedDevicesModal-BRtht0XI.css} +1 -1
- package/dist/{esm/react/components/AccountMenuButton/LinkedDevicesModal-CSSowiHP.css.map → cjs/react/components/AccountMenuButton/LinkedDevicesModal-BRtht0XI.css.map} +1 -1
- package/dist/cjs/react/components/AccountMenuButton/{ProfileDropdown-CEPMZ1gY.css → ProfileDropdown-BG_6hcim.css} +1 -1
- package/dist/{esm/react/components/AccountMenuButton/ProfileDropdown-CEPMZ1gY.css.map → cjs/react/components/AccountMenuButton/ProfileDropdown-BG_6hcim.css.map} +1 -1
- package/dist/cjs/react/components/AccountMenuButton/{Web3AuthProfileButton-DopOg7Xc.css → Web3AuthProfileButton-k8_FAYFq.css} +1 -1
- package/dist/cjs/react/components/AccountMenuButton/{Web3AuthProfileButton-DopOg7Xc.css.map → Web3AuthProfileButton-k8_FAYFq.css.map} +1 -1
- package/dist/cjs/react/components/AccountMenuButton/icons/{TouchIcon-BQWentvJ.css → TouchIcon-C-RcGfr5.css} +1 -1
- package/dist/cjs/react/components/AccountMenuButton/icons/{TouchIcon-BQWentvJ.css.map → TouchIcon-C-RcGfr5.css.map} +1 -1
- package/dist/cjs/react/components/PasskeyAuthMenu/{PasskeyAuthMenu-DwrzWMYx.css → PasskeyAuthMenu-DKMiLeT9.css} +59 -4
- package/dist/cjs/react/components/PasskeyAuthMenu/{PasskeyAuthMenu-DwrzWMYx.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 +354 -154
- package/dist/cjs/react/components/PasskeyAuthMenu/ui/EmailRecoverySlide.js.map +1 -1
- package/dist/cjs/react/components/{ShowQRCode-CCN4h6Uv.css → ShowQRCode-CB0UCQ_h.css} +1 -1
- package/dist/cjs/react/components/{ShowQRCode-CCN4h6Uv.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 +26 -0
- package/dist/cjs/react/sdk/src/core/EmailRecovery/index.js.map +1 -1
- package/dist/cjs/react/sdk/src/core/TatchiPasskey/emailRecovery.js +135 -77
- 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/react/sdk/src/core/types/emailRecovery.js +33 -0
- package/dist/cjs/react/sdk/src/core/types/emailRecovery.js.map +1 -0
- 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/EmailRecovery/index.js +25 -1
- package/dist/esm/core/EmailRecovery/index.js.map +1 -1
- package/dist/esm/core/TatchiPasskey/emailRecovery.js +136 -78
- 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/core/types/emailRecovery.js +26 -0
- package/dist/esm/core/types/emailRecovery.js.map +1 -0
- package/dist/esm/index.js +3 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/react/components/AccountMenuButton/{LinkedDevicesModal-CSSowiHP.css → LinkedDevicesModal-BRtht0XI.css} +1 -1
- package/dist/{cjs/react/components/AccountMenuButton/LinkedDevicesModal-CSSowiHP.css.map → esm/react/components/AccountMenuButton/LinkedDevicesModal-BRtht0XI.css.map} +1 -1
- package/dist/esm/react/components/AccountMenuButton/{ProfileDropdown-CEPMZ1gY.css → ProfileDropdown-BG_6hcim.css} +1 -1
- package/dist/{cjs/react/components/AccountMenuButton/ProfileDropdown-CEPMZ1gY.css.map → esm/react/components/AccountMenuButton/ProfileDropdown-BG_6hcim.css.map} +1 -1
- package/dist/esm/react/components/AccountMenuButton/{Web3AuthProfileButton-DopOg7Xc.css → Web3AuthProfileButton-k8_FAYFq.css} +1 -1
- package/dist/esm/react/components/AccountMenuButton/{Web3AuthProfileButton-DopOg7Xc.css.map → Web3AuthProfileButton-k8_FAYFq.css.map} +1 -1
- package/dist/esm/react/components/AccountMenuButton/icons/{TouchIcon-BQWentvJ.css → TouchIcon-C-RcGfr5.css} +1 -1
- package/dist/esm/react/components/AccountMenuButton/icons/{TouchIcon-BQWentvJ.css.map → TouchIcon-C-RcGfr5.css.map} +1 -1
- package/dist/esm/react/components/PasskeyAuthMenu/{PasskeyAuthMenu-DwrzWMYx.css → PasskeyAuthMenu-DKMiLeT9.css} +59 -4
- package/dist/esm/react/components/PasskeyAuthMenu/{PasskeyAuthMenu-DwrzWMYx.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 +354 -154
- package/dist/esm/react/components/PasskeyAuthMenu/ui/EmailRecoverySlide.js.map +1 -1
- package/dist/esm/react/components/{ShowQRCode-CCN4h6Uv.css → ShowQRCode-CB0UCQ_h.css} +1 -1
- package/dist/esm/react/components/{ShowQRCode-CCN4h6Uv.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 +25 -1
- package/dist/esm/react/sdk/src/core/EmailRecovery/index.js.map +1 -1
- package/dist/esm/react/sdk/src/core/TatchiPasskey/emailRecovery.js +136 -78
- 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/sdk/src/core/types/emailRecovery.js +26 -0
- package/dist/esm/react/sdk/src/core/types/emailRecovery.js.map +1 -0
- 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 +660 -590
- 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/EmailRecovery/index.d.ts +8 -0
- package/dist/types/src/core/EmailRecovery/index.d.ts.map +1 -1
- package/dist/types/src/core/TatchiPasskey/emailRecovery.d.ts +8 -5
- 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/emailRecovery.d.ts +10 -0
- package/dist/types/src/core/types/emailRecovery.d.ts.map +1 -0
- package/dist/types/src/core/types/index.d.ts +1 -0
- package/dist/types/src/core/types/index.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/index.d.ts +1 -0
- package/dist/types/src/index.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,14 +1,68 @@
|
|
|
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
|
+
const require_emailRecovery = require('../../../sdk/src/core/types/emailRecovery.js');
|
|
4
5
|
let react = require("react");
|
|
5
6
|
react = require_rolldown_runtime.__toESM(react);
|
|
6
7
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
7
8
|
react_jsx_runtime = require_rolldown_runtime.__toESM(react_jsx_runtime);
|
|
8
9
|
|
|
9
10
|
//#region src/react/components/PasskeyAuthMenu/ui/EmailRecoverySlide.tsx
|
|
10
|
-
|
|
11
|
-
|
|
11
|
+
require_sdkSentEvents.init_sdkSentEvents();
|
|
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
|
+
}
|
|
25
|
+
function getEmailRecoveryErrorCode(err) {
|
|
26
|
+
const code = err?.code;
|
|
27
|
+
if (typeof code !== "string") return null;
|
|
28
|
+
return Object.values(require_emailRecovery.EmailRecoveryErrorCode).includes(code) ? code : null;
|
|
29
|
+
}
|
|
30
|
+
function getEmailRecoveryUiError(err) {
|
|
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
|
+
};
|
|
37
|
+
const code = getEmailRecoveryErrorCode(err);
|
|
38
|
+
switch (code) {
|
|
39
|
+
case require_emailRecovery.EmailRecoveryErrorCode.VRF_CHALLENGE_EXPIRED: return {
|
|
40
|
+
message: fallback || "Timed out finalizing registration (VRF challenge expired). Please restart email recovery and try again.",
|
|
41
|
+
canRestart: true
|
|
42
|
+
};
|
|
43
|
+
case require_emailRecovery.EmailRecoveryErrorCode.REGISTRATION_NOT_VERIFIED: return {
|
|
44
|
+
message: fallback || "Registration did not verify on-chain. Please restart email recovery and try again.",
|
|
45
|
+
canRestart: true
|
|
46
|
+
};
|
|
47
|
+
default: return {
|
|
48
|
+
message: fallback || "Email recovery failed",
|
|
49
|
+
canRestart: false
|
|
50
|
+
};
|
|
51
|
+
}
|
|
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
|
+
}
|
|
12
66
|
const EmailRecoverySlide = ({ tatchiPasskey, accountId, refreshLoginState, emailRecoveryOptions }) => {
|
|
13
67
|
const mountedRef = react.default.useRef(true);
|
|
14
68
|
const mailtoAttemptTimerRef = react.default.useRef(null);
|
|
@@ -25,19 +79,22 @@ const EmailRecoverySlide = ({ tatchiPasskey, accountId, refreshLoginState, email
|
|
|
25
79
|
}, []);
|
|
26
80
|
const [isBusy, setIsBusy] = react.default.useState(false);
|
|
27
81
|
const [accountIdInput, setAccountIdInput] = react.default.useState("");
|
|
28
|
-
const [recoveryEmailInput, setRecoveryEmailInput] = react.default.useState("");
|
|
29
82
|
const [pendingMailtoUrl, setPendingMailtoUrl] = react.default.useState(null);
|
|
83
|
+
const [pendingNearPublicKey, setPendingNearPublicKey] = react.default.useState(null);
|
|
30
84
|
const [mailtoUiState, setMailtoUiState] = react.default.useState("ready");
|
|
31
85
|
const [statusText, setStatusText] = react.default.useState(null);
|
|
32
86
|
const [pollingElapsedMs, setPollingElapsedMs] = react.default.useState(null);
|
|
33
87
|
const [errorText, setErrorText] = react.default.useState(null);
|
|
88
|
+
const [canRestart, setCanRestart] = react.default.useState(false);
|
|
34
89
|
const [accountInfo, setAccountInfo] = react.default.useState(null);
|
|
35
90
|
const [accountInfoLoading, setAccountInfoLoading] = react.default.useState(false);
|
|
36
91
|
const [accountInfoError, setAccountInfoError] = react.default.useState(null);
|
|
37
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");
|
|
38
96
|
const [explorerToast, setExplorerToast] = react.default.useState(null);
|
|
39
97
|
const lastPrefilledAccountIdRef = react.default.useRef("");
|
|
40
|
-
const lastPrefilledRecoveryEmailRef = react.default.useRef("");
|
|
41
98
|
react.default.useEffect(() => {
|
|
42
99
|
const next = (accountId || "").trim();
|
|
43
100
|
if (!next) return;
|
|
@@ -48,14 +105,19 @@ const EmailRecoverySlide = ({ tatchiPasskey, accountId, refreshLoginState, email
|
|
|
48
105
|
}, [accountId]);
|
|
49
106
|
react.default.useEffect(() => {
|
|
50
107
|
setPendingMailtoUrl(null);
|
|
108
|
+
setPendingNearPublicKey(null);
|
|
51
109
|
setMailtoUiState("ready");
|
|
52
110
|
cancelRequestedRef.current = false;
|
|
53
111
|
setStatusText(null);
|
|
54
112
|
setPollingElapsedMs(null);
|
|
55
113
|
setErrorText(null);
|
|
114
|
+
setCanRestart(false);
|
|
56
115
|
setAccountInfo(null);
|
|
57
116
|
setAccountInfoError(null);
|
|
58
117
|
setLocalRecoveryEmails([]);
|
|
118
|
+
setRecoveryEmailRecords([]);
|
|
119
|
+
setRecoveryEmailInput("");
|
|
120
|
+
setRecoveryEmailMatchStatus("empty");
|
|
59
121
|
setExplorerToast(null);
|
|
60
122
|
if (mailtoAttemptTimerRef.current != null) {
|
|
61
123
|
window.clearTimeout(mailtoAttemptTimerRef.current);
|
|
@@ -69,22 +131,26 @@ const EmailRecoverySlide = ({ tatchiPasskey, accountId, refreshLoginState, email
|
|
|
69
131
|
};
|
|
70
132
|
};
|
|
71
133
|
const safeSetPendingMailtoUrl = react.default.useMemo(() => safeSet(setPendingMailtoUrl), []);
|
|
134
|
+
const safeSetPendingNearPublicKey = react.default.useMemo(() => safeSet(setPendingNearPublicKey), []);
|
|
72
135
|
const safeSetStatusText = react.default.useMemo(() => safeSet(setStatusText), []);
|
|
73
136
|
const safeSetPollingElapsedMs = react.default.useMemo(() => safeSet(setPollingElapsedMs), []);
|
|
74
137
|
const safeSetErrorText = react.default.useMemo(() => safeSet(setErrorText), []);
|
|
75
138
|
const safeSetIsBusy = react.default.useMemo(() => safeSet(setIsBusy), []);
|
|
139
|
+
const safeSetCanRestart = react.default.useMemo(() => safeSet(setCanRestart), []);
|
|
76
140
|
const safeSetAccountInfo = react.default.useMemo(() => safeSet(setAccountInfo), []);
|
|
77
141
|
const safeSetAccountInfoLoading = react.default.useMemo(() => safeSet(setAccountInfoLoading), []);
|
|
78
142
|
const safeSetAccountInfoError = react.default.useMemo(() => safeSet(setAccountInfoError), []);
|
|
79
143
|
const safeSetLocalRecoveryEmails = react.default.useMemo(() => safeSet(setLocalRecoveryEmails), []);
|
|
144
|
+
const safeSetRecoveryEmailRecords = react.default.useMemo(() => safeSet(setRecoveryEmailRecords), []);
|
|
145
|
+
const safeSetRecoveryEmailMatchStatus = react.default.useMemo(() => safeSet(setRecoveryEmailMatchStatus), []);
|
|
80
146
|
const safeSetExplorerToast = react.default.useMemo(() => safeSet(setExplorerToast), []);
|
|
81
147
|
const safeSetMailtoUiState = react.default.useMemo(() => safeSet(setMailtoUiState), []);
|
|
82
148
|
const onEvent = react.default.useCallback((ev) => {
|
|
83
149
|
if (cancelRequestedRef.current) return;
|
|
84
150
|
safeSetStatusText(ev?.message || null);
|
|
85
151
|
emailRecoveryOptions?.onEvent?.(ev);
|
|
86
|
-
const data = ev
|
|
87
|
-
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"];
|
|
88
154
|
const txHash = typeof rawTxHash === "string" ? rawTxHash.trim() : "";
|
|
89
155
|
if (txHash) {
|
|
90
156
|
const base = String(tatchiPasskey.configs?.nearExplorerUrl || "https://testnet.nearblocks.io").replace(/\/$/, "");
|
|
@@ -94,16 +160,18 @@ const EmailRecoverySlide = ({ tatchiPasskey, accountId, refreshLoginState, email
|
|
|
94
160
|
transactionHash: txHash
|
|
95
161
|
});
|
|
96
162
|
}
|
|
97
|
-
const elapsedRaw = data?.elapsedMs ?? data?.elapsed_ms;
|
|
163
|
+
const elapsedRaw = data?.["elapsedMs"] ?? data?.["elapsed_ms"];
|
|
98
164
|
if (elapsedRaw == null) safeSetPollingElapsedMs(null);
|
|
99
165
|
const elapsed = elapsedRaw == null ? NaN : Number(elapsedRaw);
|
|
100
166
|
if (!Number.isNaN(elapsed)) safeSetPollingElapsedMs(elapsed);
|
|
101
|
-
if (ev
|
|
102
|
-
const raw =
|
|
103
|
-
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");
|
|
170
|
+
safeSetCanRestart(false);
|
|
104
171
|
}
|
|
105
172
|
}, [
|
|
106
173
|
emailRecoveryOptions,
|
|
174
|
+
safeSetCanRestart,
|
|
107
175
|
safeSetErrorText,
|
|
108
176
|
safeSetExplorerToast,
|
|
109
177
|
safeSetPollingElapsedMs,
|
|
@@ -120,6 +188,16 @@ const EmailRecoverySlide = ({ tatchiPasskey, accountId, refreshLoginState, email
|
|
|
120
188
|
accountId: normalized
|
|
121
189
|
});
|
|
122
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]);
|
|
123
201
|
const launchMailto = react.default.useCallback((rawMailtoUrl) => {
|
|
124
202
|
const url = String(rawMailtoUrl || "").trim();
|
|
125
203
|
if (!url) return;
|
|
@@ -165,40 +243,9 @@ const EmailRecoverySlide = ({ tatchiPasskey, accountId, refreshLoginState, email
|
|
|
165
243
|
document.removeEventListener("visibilitychange", onVisibilityChange);
|
|
166
244
|
};
|
|
167
245
|
}, [mailtoUiState, safeSetMailtoUiState]);
|
|
168
|
-
const fetchLocalRecoveryEmailsFromIndexedDB = react.default.useCallback(async (rawAccountId) => {
|
|
169
|
-
const normalized = (rawAccountId || "").trim();
|
|
170
|
-
if (!normalized) {
|
|
171
|
-
console.log("[EmailRecoverySlide] fetchLocalRecoveryEmails: empty accountId");
|
|
172
|
-
return [];
|
|
173
|
-
}
|
|
174
|
-
try {
|
|
175
|
-
console.log("[EmailRecoverySlide] fetchLocalRecoveryEmails: loading from IndexedDB", { accountId: normalized });
|
|
176
|
-
const records = await require_index.IndexedDBManager.getRecoveryEmails(require_accountIds.toAccountId(normalized));
|
|
177
|
-
console.log("[EmailRecoverySlide] fetchLocalRecoveryEmails: raw IndexedDB records", {
|
|
178
|
-
accountId: normalized,
|
|
179
|
-
count: Array.isArray(records) ? records.length : 0,
|
|
180
|
-
records
|
|
181
|
-
});
|
|
182
|
-
if (!Array.isArray(records) || records.length === 0) return [];
|
|
183
|
-
const sorted = [...records].sort((a, b) => (b?.addedAt || 0) - (a?.addedAt || 0));
|
|
184
|
-
const emails = sorted.map((r) => String(r?.email || "").trim().toLowerCase()).filter((e) => !!e && e.includes("@"));
|
|
185
|
-
const uniq = Array.from(new Set(emails));
|
|
186
|
-
console.log("[EmailRecoverySlide] fetchLocalRecoveryEmails: parsed emails", {
|
|
187
|
-
accountId: normalized,
|
|
188
|
-
emails: uniq
|
|
189
|
-
});
|
|
190
|
-
return uniq;
|
|
191
|
-
} catch (err) {
|
|
192
|
-
console.log("[EmailRecoverySlide] fetchLocalRecoveryEmails: failed to read IndexedDB", {
|
|
193
|
-
accountId: normalized,
|
|
194
|
-
error: err instanceof Error ? err.message : String(err)
|
|
195
|
-
});
|
|
196
|
-
return [];
|
|
197
|
-
}
|
|
198
|
-
}, []);
|
|
199
246
|
const deriveEmailsFromRecoveryRecords = react.default.useCallback((records) => {
|
|
200
|
-
if (
|
|
201
|
-
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("@"));
|
|
202
249
|
return Array.from(new Set(emails));
|
|
203
250
|
}, []);
|
|
204
251
|
react.default.useEffect(() => {
|
|
@@ -216,27 +263,11 @@ const EmailRecoverySlide = ({ tatchiPasskey, accountId, refreshLoginState, email
|
|
|
216
263
|
const handle = window.setTimeout(() => {
|
|
217
264
|
(async () => {
|
|
218
265
|
try {
|
|
219
|
-
const isWalletIframeMode = !!tatchiPasskey.configs?.iframeWallet?.walletOrigin;
|
|
220
|
-
let localEmails = [];
|
|
221
|
-
if (!isWalletIframeMode) {
|
|
222
|
-
localEmails = await fetchLocalRecoveryEmailsFromIndexedDB(normalized);
|
|
223
|
-
if (!cancelled) console.log("[EmailRecoverySlide] local saved emails (IndexedDB)", {
|
|
224
|
-
accountId: normalized,
|
|
225
|
-
localEmails
|
|
226
|
-
});
|
|
227
|
-
}
|
|
228
266
|
const records = await tatchiPasskey.getRecoveryEmails(normalized);
|
|
229
|
-
const resolvedEmails =
|
|
267
|
+
const resolvedEmails = deriveEmailsFromRecoveryRecords(records);
|
|
230
268
|
if (!cancelled) {
|
|
231
269
|
safeSetLocalRecoveryEmails(resolvedEmails);
|
|
232
|
-
|
|
233
|
-
accountId: normalized,
|
|
234
|
-
emails: resolvedEmails
|
|
235
|
-
});
|
|
236
|
-
if (resolvedEmails.length === 1 && (recoveryEmailInput.trim() === "" || recoveryEmailInput === lastPrefilledRecoveryEmailRef.current)) {
|
|
237
|
-
lastPrefilledRecoveryEmailRef.current = resolvedEmails[0];
|
|
238
|
-
setRecoveryEmailInput(resolvedEmails[0]);
|
|
239
|
-
}
|
|
270
|
+
safeSetRecoveryEmailRecords(records);
|
|
240
271
|
}
|
|
241
272
|
const info = records ? { emailsCount: Array.isArray(records) ? records.length : 0 } : null;
|
|
242
273
|
if (cancelled) return;
|
|
@@ -244,7 +275,10 @@ const EmailRecoverySlide = ({ tatchiPasskey, accountId, refreshLoginState, email
|
|
|
244
275
|
} catch (err) {
|
|
245
276
|
if (cancelled) return;
|
|
246
277
|
safeSetAccountInfo(null);
|
|
247
|
-
|
|
278
|
+
const msg = err instanceof Error ? err.message : "";
|
|
279
|
+
safeSetAccountInfoError(msg || "Failed to load email recovery settings for this account");
|
|
280
|
+
safeSetLocalRecoveryEmails([]);
|
|
281
|
+
safeSetRecoveryEmailRecords([]);
|
|
248
282
|
} finally {
|
|
249
283
|
if (!cancelled) safeSetAccountInfoLoading(false);
|
|
250
284
|
}
|
|
@@ -257,37 +291,114 @@ const EmailRecoverySlide = ({ tatchiPasskey, accountId, refreshLoginState, email
|
|
|
257
291
|
}, [
|
|
258
292
|
accountIdInput,
|
|
259
293
|
deriveEmailsFromRecoveryRecords,
|
|
260
|
-
fetchLocalRecoveryEmailsFromIndexedDB,
|
|
261
|
-
recoveryEmailInput,
|
|
262
294
|
safeSetAccountInfo,
|
|
263
295
|
safeSetAccountInfoError,
|
|
264
296
|
safeSetAccountInfoLoading,
|
|
265
297
|
safeSetLocalRecoveryEmails,
|
|
298
|
+
safeSetRecoveryEmailRecords,
|
|
266
299
|
tatchiPasskey
|
|
267
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
|
+
]);
|
|
268
345
|
const handleStart = react.default.useCallback(async () => {
|
|
269
346
|
const normalizedAccountId = (accountIdInput || "").trim();
|
|
270
347
|
if (!normalizedAccountId) {
|
|
271
348
|
safeSetErrorText("Enter an account ID.");
|
|
272
349
|
return;
|
|
273
350
|
}
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
351
|
+
if (accountInfoLoading) {
|
|
352
|
+
safeSetErrorText("Checking recovery email settings…");
|
|
353
|
+
return;
|
|
354
|
+
}
|
|
355
|
+
if (accountInfoError) {
|
|
356
|
+
safeSetErrorText(accountInfoError);
|
|
357
|
+
return;
|
|
358
|
+
}
|
|
359
|
+
if (!accountInfo) {
|
|
360
|
+
safeSetErrorText("Failed to load email recovery settings for this account.");
|
|
277
361
|
return;
|
|
278
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
|
+
}
|
|
279
388
|
safeSetIsBusy(true);
|
|
280
389
|
cancelRequestedRef.current = false;
|
|
281
390
|
safeSetErrorText(null);
|
|
391
|
+
safeSetCanRestart(false);
|
|
282
392
|
safeSetStatusText(null);
|
|
283
393
|
safeSetPollingElapsedMs(null);
|
|
284
394
|
safeSetPendingMailtoUrl(null);
|
|
395
|
+
safeSetPendingNearPublicKey(null);
|
|
285
396
|
safeSetMailtoUiState("ready");
|
|
286
397
|
let didForwardError = false;
|
|
287
398
|
try {
|
|
288
399
|
const result = await tatchiPasskey.startEmailRecovery({
|
|
289
400
|
accountId: normalizedAccountId,
|
|
290
|
-
recoveryEmail:
|
|
401
|
+
...recoveryEmail ? { recoveryEmail } : {},
|
|
291
402
|
options: {
|
|
292
403
|
onEvent,
|
|
293
404
|
onError: (err) => {
|
|
@@ -295,11 +406,11 @@ const EmailRecoverySlide = ({ tatchiPasskey, accountId, refreshLoginState, email
|
|
|
295
406
|
safeSetErrorText(err?.message || "Failed to start email recovery");
|
|
296
407
|
didForwardError = true;
|
|
297
408
|
emailRecoveryOptions?.onError?.(err);
|
|
298
|
-
}
|
|
299
|
-
afterCall: async () => {}
|
|
409
|
+
}
|
|
300
410
|
}
|
|
301
411
|
});
|
|
302
412
|
safeSetPendingMailtoUrl(result.mailtoUrl);
|
|
413
|
+
safeSetPendingNearPublicKey(result.nearPublicKey);
|
|
303
414
|
safeSetStatusText("Recovery email draft ready. If it didn’t open automatically, click “Open recovery email draft”. Waiting for verification…");
|
|
304
415
|
attemptOpenMailtoAuto(result.mailtoUrl);
|
|
305
416
|
const finalizePromise = tatchiPasskey.finalizeEmailRecovery({
|
|
@@ -309,11 +420,14 @@ const EmailRecoverySlide = ({ tatchiPasskey, accountId, refreshLoginState, email
|
|
|
309
420
|
onEvent,
|
|
310
421
|
onError: (err) => {
|
|
311
422
|
if (cancelRequestedRef.current) return;
|
|
312
|
-
|
|
423
|
+
const uiError = getEmailRecoveryUiError(err);
|
|
424
|
+
safeSetErrorText(uiError.message || "Failed to finalize email recovery");
|
|
425
|
+
safeSetCanRestart(uiError.canRestart);
|
|
426
|
+
const txHash = getEmailRecoveryErrorTxHash(err);
|
|
427
|
+
if (txHash) showExplorerTxToast(txHash);
|
|
313
428
|
didForwardError = true;
|
|
314
429
|
emailRecoveryOptions?.onError?.(err);
|
|
315
|
-
}
|
|
316
|
-
afterCall: async () => {}
|
|
430
|
+
}
|
|
317
431
|
}
|
|
318
432
|
});
|
|
319
433
|
showExplorerToast(normalizedAccountId);
|
|
@@ -336,10 +450,16 @@ const EmailRecoverySlide = ({ tatchiPasskey, accountId, refreshLoginState, email
|
|
|
336
450
|
safeSetStatusText(null);
|
|
337
451
|
safeSetPollingElapsedMs(null);
|
|
338
452
|
safeSetPendingMailtoUrl(null);
|
|
453
|
+
safeSetPendingNearPublicKey(null);
|
|
339
454
|
safeSetMailtoUiState("ready");
|
|
455
|
+
safeSetCanRestart(false);
|
|
340
456
|
return;
|
|
341
457
|
}
|
|
342
|
-
|
|
458
|
+
const uiError = getEmailRecoveryUiError(err);
|
|
459
|
+
safeSetErrorText(uiError.message || "Failed to start email recovery");
|
|
460
|
+
safeSetCanRestart(uiError.canRestart);
|
|
461
|
+
const txHash = getEmailRecoveryErrorTxHash(err);
|
|
462
|
+
if (txHash) showExplorerTxToast(txHash);
|
|
343
463
|
if (!didForwardError && err instanceof Error) emailRecoveryOptions?.onError?.(err);
|
|
344
464
|
} finally {
|
|
345
465
|
safeSetIsBusy(false);
|
|
@@ -347,9 +467,14 @@ const EmailRecoverySlide = ({ tatchiPasskey, accountId, refreshLoginState, email
|
|
|
347
467
|
}, [
|
|
348
468
|
accountIdInput,
|
|
349
469
|
emailRecoveryOptions,
|
|
350
|
-
recoveryEmailInput,
|
|
351
470
|
onEvent,
|
|
352
471
|
refreshLoginState,
|
|
472
|
+
accountInfo,
|
|
473
|
+
accountInfoError,
|
|
474
|
+
accountInfoLoading,
|
|
475
|
+
recoveryEmailConfirmationRequired,
|
|
476
|
+
recoveryEmailInput,
|
|
477
|
+
recoveryEmailRecords,
|
|
353
478
|
showExplorerToast,
|
|
354
479
|
safeSetErrorText,
|
|
355
480
|
safeSetIsBusy,
|
|
@@ -358,10 +483,64 @@ const EmailRecoverySlide = ({ tatchiPasskey, accountId, refreshLoginState, email
|
|
|
358
483
|
safeSetStatusText,
|
|
359
484
|
safeSetMailtoUiState,
|
|
360
485
|
attemptOpenMailtoAuto,
|
|
486
|
+
showExplorerTxToast,
|
|
361
487
|
tatchiPasskey
|
|
362
488
|
]);
|
|
363
|
-
const
|
|
489
|
+
const handleRestart = react.default.useCallback(async () => {
|
|
490
|
+
const normalizedAccountId = (accountIdInput || "").trim();
|
|
491
|
+
if (!normalizedAccountId) return;
|
|
492
|
+
safeSetIsBusy(true);
|
|
493
|
+
try {
|
|
494
|
+
cancelRequestedRef.current = true;
|
|
495
|
+
await tatchiPasskey.cancelEmailRecovery({
|
|
496
|
+
accountId: normalizedAccountId,
|
|
497
|
+
nearPublicKey: pendingNearPublicKey || void 0
|
|
498
|
+
}).catch(() => {});
|
|
499
|
+
safeSetErrorText(null);
|
|
500
|
+
safeSetStatusText(null);
|
|
501
|
+
safeSetPollingElapsedMs(null);
|
|
502
|
+
safeSetPendingMailtoUrl(null);
|
|
503
|
+
safeSetPendingNearPublicKey(null);
|
|
504
|
+
safeSetMailtoUiState("ready");
|
|
505
|
+
safeSetCanRestart(false);
|
|
506
|
+
} finally {
|
|
507
|
+
cancelRequestedRef.current = false;
|
|
508
|
+
safeSetIsBusy(false);
|
|
509
|
+
}
|
|
510
|
+
}, [
|
|
511
|
+
accountIdInput,
|
|
512
|
+
pendingNearPublicKey,
|
|
513
|
+
safeSetCanRestart,
|
|
514
|
+
safeSetErrorText,
|
|
515
|
+
safeSetIsBusy,
|
|
516
|
+
safeSetMailtoUiState,
|
|
517
|
+
safeSetPendingMailtoUrl,
|
|
518
|
+
safeSetPendingNearPublicKey,
|
|
519
|
+
safeSetPollingElapsedMs,
|
|
520
|
+
safeSetStatusText,
|
|
521
|
+
tatchiPasskey
|
|
522
|
+
]);
|
|
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";
|
|
364
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;
|
|
365
544
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
366
545
|
className: "w3a-email-recovery-slide",
|
|
367
546
|
children: [
|
|
@@ -371,92 +550,113 @@ const EmailRecoverySlide = ({ tatchiPasskey, accountId, refreshLoginState, email
|
|
|
371
550
|
}),
|
|
372
551
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
373
552
|
className: "w3a-email-recovery-help",
|
|
374
|
-
children: "Send a special
|
|
553
|
+
children: "Send a special email to recover your account. This email must be sent from the designated email recovery address."
|
|
375
554
|
}),
|
|
376
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
377
|
-
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",
|
|
378
557
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
379
|
-
className: "w3a-input-
|
|
380
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
inputMode: "text",
|
|
392
|
-
disabled: isBusy
|
|
393
|
-
})
|
|
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
|
|
394
570
|
})
|
|
395
571
|
})
|
|
396
|
-
}),
|
|
397
|
-
/* @__PURE__ */ (0, react_jsx_runtime.
|
|
572
|
+
}) }),
|
|
573
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
398
574
|
className: "w3a-email-recovery-summary",
|
|
399
575
|
"aria-live": "polite",
|
|
400
|
-
children:
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
className: "w3a-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
})
|
|
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."
|
|
421
629
|
})
|
|
422
|
-
|
|
423
|
-
}),
|
|
424
|
-
localRecoveryEmails.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
425
|
-
className: "w3a-email-recovery-summary",
|
|
426
|
-
"aria-live": "polite",
|
|
427
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { children: "Saved on this device:" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
428
|
-
className: "w3a-email-recovery-saved-emails",
|
|
429
|
-
children: localRecoveryEmails.map((email) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
430
|
-
type: "button",
|
|
431
|
-
className: "w3a-email-recovery-email-chip",
|
|
432
|
-
onClick: () => setRecoveryEmailInput(email),
|
|
433
|
-
disabled: isBusy,
|
|
434
|
-
children: email
|
|
435
|
-
}, email))
|
|
436
|
-
})]
|
|
437
|
-
}),
|
|
438
|
-
localRecoveryEmails.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("datalist", {
|
|
439
|
-
id: "w3a-email-recovery-saved-emails",
|
|
440
|
-
children: localRecoveryEmails.map((email) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", { value: email }, email))
|
|
630
|
+
]
|
|
441
631
|
}),
|
|
442
632
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
443
633
|
className: "w3a-email-recovery-actions",
|
|
444
|
-
children: [
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
"
|
|
458
|
-
|
|
459
|
-
|
|
634
|
+
children: [
|
|
635
|
+
(!pendingMailtoUrl || !isBusy) && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
636
|
+
onClick: handleStart,
|
|
637
|
+
className: "w3a-link-device-btn w3a-link-device-btn-primary",
|
|
638
|
+
disabled: startDisabled,
|
|
639
|
+
children: accountInfoLoading ? "Checking recovery emails…" : noRecoveryEmailsConfigured ? "No recovery emails configured" : disableStartForRecoveryEmailMismatch ? "Confirm recovery email" : isBusy ? "Working…" : "Start Email Recovery"
|
|
640
|
+
}),
|
|
641
|
+
pendingMailtoUrl && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
642
|
+
type: "button",
|
|
643
|
+
onClick: () => attemptOpenMailtoFromUserGesture(pendingMailtoUrl),
|
|
644
|
+
className: "w3a-link-device-btn w3a-link-device-btn-primary",
|
|
645
|
+
disabled: mailtoUiState === "opening",
|
|
646
|
+
"aria-busy": mailtoUiState === "opening",
|
|
647
|
+
children: [mailtoUiState === "opening" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
648
|
+
className: "w3a-spinner",
|
|
649
|
+
"aria-hidden": "true"
|
|
650
|
+
}), mailtoUiState === "opening" ? "Opening email…" : "Open recovery email draft"]
|
|
651
|
+
}),
|
|
652
|
+
errorText && canRestart && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
653
|
+
type: "button",
|
|
654
|
+
onClick: handleRestart,
|
|
655
|
+
className: "w3a-link-device-btn",
|
|
656
|
+
disabled: isBusy,
|
|
657
|
+
children: "Restart email recovery"
|
|
658
|
+
})
|
|
659
|
+
]
|
|
460
660
|
}),
|
|
461
661
|
(errorText || statusText || explorerToast) && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
462
662
|
className: `w3a-email-recovery-status${errorText ? " is-error" : ""}`,
|