diff --git a/apps/desktop/src/app/App.tsx b/apps/desktop/src/app/App.tsx index 296a25b32..dcb4b4cea 100644 --- a/apps/desktop/src/app/App.tsx +++ b/apps/desktop/src/app/App.tsx @@ -1,8 +1,7 @@ import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { localizationText } from '@tonkeeper/core/dist/entries/language'; -import { Network, getApiConfig } from '@tonkeeper/core/dist/entries/network'; -import { AuthState } from '@tonkeeper/core/dist/entries/password'; -import { WalletState } from '@tonkeeper/core/dist/entries/wallet'; +import { getApiConfig } from '@tonkeeper/core/dist/entries/network'; +import { WalletVersion } from '@tonkeeper/core/dist/entries/wallet'; import { useWindowsScroll } from '@tonkeeper/uikit/dist/components/Body'; import ConnectLedgerNotification from '@tonkeeper/uikit/dist/components/ConnectLedgerNotification'; import { CopyNotification } from '@tonkeeper/uikit/dist/components/CopyNotification'; @@ -33,13 +32,12 @@ import { DesktopCoinPage } from '@tonkeeper/uikit/dist/desktop-pages/coin/Deskto import DashboardPage from '@tonkeeper/uikit/dist/desktop-pages/dashboard'; import { DesktopHistoryPage } from '@tonkeeper/uikit/dist/desktop-pages/history/DesktopHistoryPage'; import { DesktopMultiSendPage } from '@tonkeeper/uikit/dist/desktop-pages/multi-send'; -import { NotcoinPage } from '@tonkeeper/uikit/dist/desktop-pages/notcoin/NotcoinPage'; import { DesktopPreferencesRouting } from '@tonkeeper/uikit/dist/desktop-pages/preferences/DesktopPreferencesRouting'; import { DesktopWalletSettingsRouting } from '@tonkeeper/uikit/dist/desktop-pages/settings/DesktopWalletSettingsRouting'; import { DesktopSwapPage } from '@tonkeeper/uikit/dist/desktop-pages/swap'; import { DesktopTokens } from '@tonkeeper/uikit/dist/desktop-pages/tokens/DesktopTokens'; import { AmplitudeAnalyticsContext, useTrackLocation } from '@tonkeeper/uikit/dist/hooks/amplitude'; -import { AppContext, WalletStateContext } from '@tonkeeper/uikit/dist/hooks/appContext'; +import { AppContext, IAppContext } from '@tonkeeper/uikit/dist/hooks/appContext'; import { AfterImportAction, AppSdkContext, @@ -49,27 +47,30 @@ import { useRecommendations } from '@tonkeeper/uikit/dist/hooks/browser/useRecom import { useLock } from '@tonkeeper/uikit/dist/hooks/lock'; import { StorageContext } from '@tonkeeper/uikit/dist/hooks/storage'; import { I18nContext, TranslationContext } from '@tonkeeper/uikit/dist/hooks/translation'; -import { AppProRoute, AppRoute, any } from '@tonkeeper/uikit/dist/libs/routes'; +import { any, AppProRoute, AppRoute } from '@tonkeeper/uikit/dist/libs/routes'; import { Unlock } from '@tonkeeper/uikit/dist/pages/home/Unlock'; import { UnlockNotification } from '@tonkeeper/uikit/dist/pages/home/UnlockNotification'; import ImportRouter from '@tonkeeper/uikit/dist/pages/import'; import Initialize, { InitializeContainer } from '@tonkeeper/uikit/dist/pages/import/Initialize'; import { UserThemeProvider } from '@tonkeeper/uikit/dist/providers/UserThemeProvider'; -import { useAccountState } from '@tonkeeper/uikit/dist/state/account'; import { useUserFiat } from '@tonkeeper/uikit/dist/state/fiat'; -import { useAuthState, useCanPromptTouchId } from '@tonkeeper/uikit/dist/state/password'; +import { useCanPromptTouchId } from '@tonkeeper/uikit/dist/state/password'; import { useProBackupState } from '@tonkeeper/uikit/dist/state/pro'; import { useTonendpoint, useTonenpointConfig } from '@tonkeeper/uikit/dist/state/tonendpoint'; -import { useActiveWallet } from '@tonkeeper/uikit/dist/state/wallet'; +import { + useActiveAccountQuery, + useAccountsStateQuery, + useActiveTonNetwork +} from '@tonkeeper/uikit/dist/state/wallet'; import { Container, GlobalStyleCss } from '@tonkeeper/uikit/dist/styles/globalStyle'; import { FC, Suspense, useEffect, useMemo } from 'react'; import { useTranslation } from 'react-i18next'; import { + createMemoryRouter, Outlet, Route, RouterProvider, Routes, - createMemoryRouter, useLocation, useNavigate } from 'react-router-dom'; @@ -80,6 +81,11 @@ import { DeepLinkSubscription } from './components/DeepLink'; import { TonConnectSubscription } from './components/TonConnectSubscription'; import { DesktopDns } from '@tonkeeper/uikit/dist/desktop-pages/nft/DesktopDns'; import { DesktopCollectables } from '@tonkeeper/uikit/dist/desktop-pages/nft/DesktopCollectables'; +import { useUserLanguage } from '@tonkeeper/uikit/dist/state/language'; +import { useDebuggingTools } from '@tonkeeper/uikit/dist/hooks/useDebuggingTools'; +import { useDevSettings } from '@tonkeeper/uikit/dist/state/dev'; +import { ModalsRoot } from '@tonkeeper/uikit/dist/components/ModalsRoot'; +import { Account } from '@tonkeeper/core/dist/entries/account'; const queryClient = new QueryClient({ defaultOptions: { @@ -121,7 +127,6 @@ const sdk = new DesktopAppSdk(); const TARGET_ENV = 'desktop'; const langs = 'en,zh_CN,ru,it,tr'; -const listOfAuth: AuthState['kind'][] = ['keychain']; declare const REACT_APP_TONCONSOLE_API: string; declare const REACT_APP_TG_BOT_ID: string; @@ -254,19 +259,21 @@ const FullSizeWrapperBounded = styled(FullSizeWrapper)` `; export const Loader: FC = () => { - const { data: activeWallet } = useActiveWallet(); + const network = useActiveTonNetwork(); + const { data: activeAccount, isLoading: activeWalletLoading } = useActiveAccountQuery(); + const { data: accounts, isLoading: isWalletsLoading } = useAccountsStateQuery(); + const { data: lang, isLoading: isLangLoading } = useUserLanguage(); + const { data: devSettings } = useDevSettings(); const lock = useLock(sdk); const { i18n } = useTranslation(); - const { data: account } = useAccountState(); - const { data: auth } = useAuthState(); const { data: fiat } = useUserFiat(); const tonendpoint = useTonendpoint({ targetEnv: TARGET_ENV, build: sdk.version, - network: activeWallet?.network, - lang: activeWallet?.lang, + network, + lang, platform: 'desktop' }); const { data: config } = useTonenpointConfig(tonendpoint); @@ -274,40 +281,35 @@ export const Loader: FC = () => { const navigate = useNavigate(); useAppHeight(); - const { data: tracker } = useAnalytics(sdk.version, account, activeWallet); + const { data: tracker } = useAnalytics(sdk.version, activeAccount, accounts); useEffect(() => { - if ( - activeWallet && - activeWallet.lang && - i18n.language !== localizationText(activeWallet.lang) - ) { - i18n.reloadResources([localizationText(activeWallet.lang)]).then(() => - i18n.changeLanguage(localizationText(activeWallet.lang)) + if (lang && i18n.language !== localizationText(lang)) { + i18n.reloadResources([localizationText(lang)]).then(() => + i18n.changeLanguage(localizationText(lang)) ); } - }, [activeWallet, i18n]); + }, [lang, i18n]); useEffect(() => { window.backgroundApi.onRefresh(() => queryClient.invalidateQueries()); }, []); if ( - auth === undefined || - account === undefined || + activeWalletLoading || + isLangLoading || + isWalletsLoading || config === undefined || lock === undefined || - fiat === undefined + fiat === undefined || + !devSettings ) { return ; } - const network = activeWallet?.network ?? Network.MAINNET; - const context = { + const context: IAppContext = { api: getApiConfig(config, network, REACT_APP_TONCONSOLE_API), - auth, fiat, - account, config, tonendpoint, standalone: true, @@ -318,7 +320,8 @@ export const Loader: FC = () => { env: { tgAuthBotId: REACT_APP_TG_BOT_ID, stonfiReferralAddress: REACT_APP_STONFI_REFERRAL_ADDRESS - } + }, + defaultWalletVersion: WalletVersion.V5R1 }; return ( @@ -328,9 +331,10 @@ export const Loader: FC = () => { value={() => navigate(AppRoute.home, { replace: true })} > - + + @@ -344,14 +348,15 @@ const usePrefetch = () => { }; export const Content: FC<{ - activeWallet?: WalletState | null; + activeAccount?: Account | null; lock: boolean; -}> = ({ activeWallet, lock }) => { +}> = ({ activeAccount, lock }) => { const location = useLocation(); useWindowsScroll(); useAppWidth(); useTrackLocation(); usePrefetch(); + useDebuggingTools(); if (lock) { return ( @@ -361,15 +366,12 @@ export const Content: FC<{ ); } - if (!activeWallet || location.pathname.startsWith(AppRoute.import)) { + if (!activeAccount || location.pathname.startsWith(AppRoute.import)) { return ( - } - /> + } /> } /> @@ -378,24 +380,19 @@ export const Content: FC<{ } return ( - - - - - - } /> - } /> - } /> - } - /> - } /> - - - - - + + + + + } /> + } /> + } /> + } /> + } /> + + + + ); }; @@ -423,7 +420,6 @@ const WalletContent = () => { element={} /> } /> - } /> } /> diff --git a/apps/desktop/src/electron/sseEvetns.ts b/apps/desktop/src/electron/sseEvetns.ts index 83b2525d6..82abdab1c 100644 --- a/apps/desktop/src/electron/sseEvetns.ts +++ b/apps/desktop/src/electron/sseEvetns.ts @@ -1,5 +1,4 @@ import { TonConnectAppRequest } from '@tonkeeper/core/dist/entries/tonConnect'; -import { accountSelectWallet, getAccountState } from '@tonkeeper/core/dist/service/accountService'; import { replyBadRequestResponse, replyDisconnectResponse @@ -7,26 +6,28 @@ import { import { AccountConnection, disconnectAppConnection, - getAccountConnection + getTonWalletConnections } from '@tonkeeper/core/dist/service/tonConnect/connectionService'; import { getLastEventId, subscribeTonConnect } from '@tonkeeper/core/dist/service/tonConnect/httpBridge'; -import { getWalletState } from '@tonkeeper/core/dist/service/wallet/storeService'; import { delay } from '@tonkeeper/core/dist/utils/common'; import { Buffer as BufferPolyfill } from 'buffer'; import log from 'electron-log/main'; import EventSourcePolyfill from 'eventsource'; import { MainWindow } from './mainWindow'; import { mainStorage } from './storageService'; +import { isStandardTonWallet, WalletId } from '@tonkeeper/core/dist/entries/wallet'; +import { accountsStorage } from '@tonkeeper/core/dist/service/accountsStorage'; +import { getWalletById } from '@tonkeeper/core/dist/entries/account'; globalThis.Buffer = BufferPolyfill; export class TonConnectSSE { private lastEventId: string; private connections: AccountConnection[]; - private dist: Record; + private dist: Record; private closeConnection: () => void | null = null; private static instance: TonConnectSSE = null; @@ -48,18 +49,19 @@ export class TonConnectSSE { public async init() { this.lastEventId = await getLastEventId(mainStorage); - const account = await getAccountState(mainStorage); + const walletsState = (await accountsStorage(mainStorage).getAccounts()).flatMap( + a => a.allTonWallets + ); this.connections = []; this.dist = {}; - for (const key of account.publicKeys) { - const wallet = await getWalletState(mainStorage, key); - const walletConnections = await getAccountConnection(mainStorage, wallet); + for (const wallet of walletsState) { + const walletConnections = await getTonWalletConnections(mainStorage, wallet); this.connections = this.connections.concat(walletConnections); walletConnections.forEach(item => { - this.dist[item.clientSessionId] = key; + this.dist[item.clientSessionId] = wallet.id; }); } } @@ -78,7 +80,13 @@ export class TonConnectSSE { }; private onDisconnect = async ({ connection, request }: TonConnectAppRequest) => { - const wallet = await getWalletState(mainStorage, this.dist[connection.clientSessionId]); + const accounts = await accountsStorage(mainStorage).getAccounts(); + const wallet = getWalletById(accounts, this.dist[connection.clientSessionId]); + + if (!wallet || !isStandardTonWallet(wallet)) { + return; + } + await disconnectAppConnection({ storage: mainStorage, wallet, @@ -101,14 +109,21 @@ export class TonConnectSSE { payload: JSON.parse(params.request.params[0]) }; - const walletPublicKey = this.dist[params.connection.clientSessionId]; + const walletId = this.dist[params.connection.clientSessionId]; - const account = await getAccountState(mainStorage); + const activeAccount = await accountsStorage(mainStorage).getActiveAccount(); + const activeWallet = activeAccount.activeTonWallet; const window = await MainWindow.bringToFront(); - if (account.activePublicKey !== walletPublicKey) { - await accountSelectWallet(mainStorage, walletPublicKey); + if (activeWallet.id !== walletId) { + const accountToActivate = ( + await accountsStorage(mainStorage).getAccounts() + ).find(a => a.getTonWallet(walletId) !== undefined); + + accountToActivate.setActiveTonWallet(walletId); + await accountsStorage(mainStorage).updateAccountInState(accountToActivate); + await accountsStorage(mainStorage).setActiveAccountId(accountToActivate.id); window.webContents.send('refresh'); await delay(500); } diff --git a/apps/desktop/src/libs/aptabaseElectron.ts b/apps/desktop/src/libs/aptabaseElectron.ts index 0b146c281..e21fbe44b 100644 --- a/apps/desktop/src/libs/aptabaseElectron.ts +++ b/apps/desktop/src/libs/aptabaseElectron.ts @@ -1,25 +1,27 @@ import { trackEvent } from '@aptabase/electron/renderer'; import { Network } from '@tonkeeper/core/dist/entries/network'; import { Analytics } from '@tonkeeper/uikit/dist/hooks/analytics'; +import { Account } from '@tonkeeper/core/dist/entries/account'; export class AptabaseElectron implements Analytics { private user_properties: Record = {}; - init = ( - application: string, - walletType: string, - account?: any, - wallet?: any, - version?: string | undefined, - platform?: string | undefined - ) => { - this.user_properties['application'] = application; - this.user_properties['walletType'] = walletType; + init = (params: { + application: string; + walletType: string; + activeAccount: Account; + accounts: Account[]; + network?: Network; + version?: string; + platform?: string; + }) => { + this.user_properties['application'] = params.application; + this.user_properties['walletType'] = params.walletType; this.user_properties['network'] = - wallet?.network === Network.TESTNET ? 'testnet' : 'mainnet'; - this.user_properties['accounts'] = account!.publicKeys.length; - this.user_properties['version'] = version; - this.user_properties['platform'] = platform; + params.network === Network.TESTNET ? 'testnet' : 'mainnet'; + this.user_properties['accounts'] = params.accounts?.length ?? 0; + this.user_properties['version'] = params.version; + this.user_properties['platform'] = params.platform; }; pageView = (location: string) => { diff --git a/apps/desktop/src/libs/hooks.ts b/apps/desktop/src/libs/hooks.ts index 4a3f13b4b..6f92d3cd1 100644 --- a/apps/desktop/src/libs/hooks.ts +++ b/apps/desktop/src/libs/hooks.ts @@ -1,7 +1,6 @@ import { useQuery } from '@tanstack/react-query'; import { AppKey } from '@tonkeeper/core/dist/Keys'; -import { AccountState } from '@tonkeeper/core/dist/entries/account'; -import { WalletState } from '@tonkeeper/core/dist/entries/wallet'; +import { Account } from '@tonkeeper/core/dist/entries/account'; import { throttle } from '@tonkeeper/core/dist/utils/common'; import { Analytics, AnalyticsGroup, toWalletType } from '@tonkeeper/uikit/dist/hooks/analytics'; import { Amplitude } from '@tonkeeper/uikit/dist/hooks/analytics/amplitude'; @@ -10,6 +9,7 @@ import { QueryKey } from '@tonkeeper/uikit/dist/libs/queryKey'; import { useEffect } from 'react'; import { v4 as uuidv4 } from 'uuid'; import { AptabaseElectron } from './aptabaseElectron'; +import { useActiveTonNetwork } from '@tonkeeper/uikit/dist/state/wallet'; export const useAppHeight = () => { useEffect(() => { @@ -48,12 +48,9 @@ export const useAppWidth = () => { declare const REACT_APP_AMPLITUDE: string; -export const useAnalytics = ( - version: string, - account?: AccountState, - wallet?: WalletState | null -) => { +export const useAnalytics = (version: string, activeAccount?: Account, accounts?: Account[]) => { const sdk = useAppSdk(); + const network = useActiveTonNetwork(); return useQuery( [QueryKey.analytics], @@ -75,17 +72,18 @@ export const useAnalytics = ( new Amplitude(REACT_APP_AMPLITUDE, userId) ); - tracker.init( - 'Desktop', - toWalletType(wallet), - account, - wallet, + tracker.init({ + application: 'Desktop', + walletType: toWalletType(activeAccount.activeTonWallet), + activeAccount, + accounts, + network, version, - `${window.backgroundApi.platform()}-${window.backgroundApi.arch()}` - ); + platform: `${window.backgroundApi.platform()}-${window.backgroundApi.arch()}` + }); return tracker; }, - { enabled: account != null } + { enabled: accounts != null && activeAccount !== undefined } ); }; diff --git a/apps/desktop/src/libs/scroll.ts b/apps/desktop/src/libs/scroll.ts index 4a5e3463a..d8d76b46d 100644 --- a/apps/desktop/src/libs/scroll.ts +++ b/apps/desktop/src/libs/scroll.ts @@ -1,30 +1,30 @@ export const disableScroll = () => { - document.documentElement.classList.add('is-locked'); - window.document.body.style.paddingRight = `${getScrollbarWidth()}px`; + document.documentElement.classList.add('is-locked'); + window.document.body.style.paddingRight = `${getScrollbarWidth()}px`; }; export const enableScroll = () => { - document.documentElement.classList.remove('is-locked'); - window.document.body.style.paddingRight = '0px'; + document.documentElement.classList.remove('is-locked'); + window.document.body.style.paddingRight = '0px'; }; export const getScrollbarWidth = () => { - // Creating invisible container - const outer = document.createElement('div'); - outer.style.visibility = 'hidden'; - outer.style.overflow = 'scroll'; // forcing scrollbar to appear - (outer.style as any).msOverflowStyle = 'scrollbar'; // needed for WinJS apps - document.body.appendChild(outer); + // Creating invisible container + const outer = document.createElement('div'); + outer.style.visibility = 'hidden'; + outer.style.overflow = 'scroll'; // forcing scrollbar to appear + (outer.style as any).msOverflowStyle = 'scrollbar'; // needed for WinJS apps + document.body.appendChild(outer); - // Creating inner element and placing it in the container - const inner = document.createElement('div'); - outer.appendChild(inner); + // Creating inner element and placing it in the container + const inner = document.createElement('div'); + outer.appendChild(inner); - // Calculating difference between container's full width and the child width - const scrollbarWidth = outer.offsetWidth - inner.offsetWidth; + // Calculating difference between container's full width and the child width + const scrollbarWidth = outer.offsetWidth - inner.offsetWidth; - // Removing temporary elements from the DOM - outer.parentNode!.removeChild(outer); + // Removing temporary elements from the DOM + outer.parentNode!.removeChild(outer); - return scrollbarWidth; + return scrollbarWidth; }; diff --git a/apps/desktop/src/libs/storage.ts b/apps/desktop/src/libs/storage.ts index 8c71fd507..721b04415 100644 --- a/apps/desktop/src/libs/storage.ts +++ b/apps/desktop/src/libs/storage.ts @@ -2,23 +2,23 @@ import { IStorage } from '@tonkeeper/core/dist/Storage'; import { sendBackground } from './backgroudService'; export class DesktopStorage implements IStorage { - get = async (key: string) => { - return sendBackground({ king: 'storage-get', key }); - }; + get = async (key: string) => { + return sendBackground({ king: 'storage-get', key }); + }; - set = async (key: string, value: R) => { - return sendBackground({ king: 'storage-set', key, value }); - }; + set = async (key: string, value: R) => { + return sendBackground({ king: 'storage-set', key, value }); + }; - setBatch = async >(value: V) => { - return sendBackground({ king: 'storage-set-batch', value }); - }; + setBatch = async >(value: V) => { + return sendBackground({ king: 'storage-set-batch', value }); + }; - delete = async (key: string) => { - return sendBackground({ king: 'storage-delete', key }); - }; + delete = async (key: string) => { + return sendBackground({ king: 'storage-delete', key }); + }; - clear = async () => { - await sendBackground({ king: 'storage-clear' }); - }; + clear = async () => { + await sendBackground({ king: 'storage-clear' }); + }; } diff --git a/apps/extension/src/App.tsx b/apps/extension/src/App.tsx index 6348fd4ad..07e1ff675 100644 --- a/apps/extension/src/App.tsx +++ b/apps/extension/src/App.tsx @@ -1,7 +1,7 @@ import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { localizationFrom } from '@tonkeeper/core/dist/entries/language'; -import { Network, getApiConfig } from '@tonkeeper/core/dist/entries/network'; -import { WalletState } from '@tonkeeper/core/dist/entries/wallet'; +import { getApiConfig } from '@tonkeeper/core/dist/entries/network'; +import { WalletVersion } from "@tonkeeper/core/dist/entries/wallet"; import { InnerBody, useWindowsScroll } from '@tonkeeper/uikit/dist/components/Body'; import { CopyNotification } from '@tonkeeper/uikit/dist/components/CopyNotification'; import { Footer, FooterGlobalStyle } from '@tonkeeper/uikit/dist/components/Footer'; @@ -25,7 +25,6 @@ import { AmplitudeAnalyticsContext, useTrackLocation } from '@tonkeeper/uikit/di import { AppContext, IAppContext, - WalletStateContext } from '@tonkeeper/uikit/dist/hooks/appContext'; import { AfterImportAction, @@ -40,11 +39,9 @@ import { Unlock } from '@tonkeeper/uikit/dist/pages/home/Unlock'; import { UnlockNotification } from '@tonkeeper/uikit/dist/pages/home/UnlockNotification'; import Initialize, { InitializeContainer } from '@tonkeeper/uikit/dist/pages/import/Initialize'; import { UserThemeProvider } from '@tonkeeper/uikit/dist/providers/UserThemeProvider'; -import { useAccountState } from '@tonkeeper/uikit/dist/state/account'; import { useUserFiat } from '@tonkeeper/uikit/dist/state/fiat'; -import { useAuthState } from '@tonkeeper/uikit/dist/state/password'; -import { useTonendpoint, useTonenpointConfig } from '@tonkeeper/uikit/dist/state/tonendpoint'; -import { useActiveWallet } from '@tonkeeper/uikit/dist/state/wallet'; +import { useTonendpoint, useTonenpointConfig } from "@tonkeeper/uikit/dist/state/tonendpoint"; +import { useActiveAccountQuery, useAccountsStateQuery, useActiveTonNetwork } from "@tonkeeper/uikit/dist/state/wallet"; import { Container, GlobalStyle } from '@tonkeeper/uikit/dist/styles/globalStyle'; import React, { FC, PropsWithChildren, Suspense, useEffect, useMemo } from 'react'; import { MemoryRouter, Route, Routes, useLocation, useNavigate } from 'react-router-dom'; @@ -55,6 +52,11 @@ import { TonConnectSubscription } from './components/TonConnectSubscription'; import { connectToBackground } from './event'; import { ExtensionAppSdk } from './libs/appSdk'; import { useAnalytics, useAppWidth } from './libs/hooks'; +import { useMutateUserLanguage } from "@tonkeeper/uikit/dist/state/language"; +import { useDevSettings } from "@tonkeeper/uikit/dist/state/dev"; +import { ModalsRoot } from "@tonkeeper/uikit/dist/components/ModalsRoot"; +import { Account } from "@tonkeeper/core/dist/entries/account"; +import { useDebuggingTools } from "@tonkeeper/uikit/dist/hooks/useDebuggingTools"; const ImportRouter = React.lazy(() => import('@tonkeeper/uikit/dist/pages/import')); const Settings = React.lazy(() => import('@tonkeeper/uikit/dist/pages/settings')); @@ -175,23 +177,29 @@ const Wrapper = styled(FullSizeWrapper)<{ `; export const Loader: FC = React.memo(() => { - const { data: activeWallet } = useActiveWallet(); + const { data: activeAccount, isLoading: activeWalletLoading } = useActiveAccountQuery(); + const { data: accounts, isLoading: isWalletsLoading } = useAccountsStateQuery(); const { data: fiat } = useUserFiat(); + const { mutate: setLang } = useMutateUserLanguage(); + const { data: devSettings } = useDevSettings(); + const network = useActiveTonNetwork(); + + useEffect(() => { + setLang(localizationFrom(browser.i18n.getUILanguage())) + }, [setLang]); const lock = useLock(sdk); - const { data: account } = useAccountState(); - const { data: auth } = useAuthState(); const tonendpoint = useTonendpoint({ targetEnv: TARGET_ENV, build: sdk.version, - network: activeWallet?.network, + network, lang: localizationFrom(browser.i18n.getUILanguage()) }); const { data: config } = useTonenpointConfig(tonendpoint); - const { data: tracker } = useAnalytics(sdk.storage, account, activeWallet, sdk.version); + const { data: tracker } = useAnalytics(sdk.storage, activeAccount || undefined, accounts, sdk.version); - if (!account || !auth || !config || lock === undefined || fiat === undefined) { + if (activeWalletLoading || isWalletsLoading || !config || lock === undefined || fiat === undefined || !devSettings) { return ( @@ -199,12 +207,8 @@ export const Loader: FC = React.memo(() => { ); } - const network = activeWallet?.network ?? Network.MAINNET; - const context: IAppContext = { api: getApiConfig(config, network), - account, - auth, fiat, config, tonendpoint, @@ -213,7 +217,8 @@ export const Loader: FC = React.memo(() => { extension: true, proFeatures: false, hideQrScanner: true, - hideSigner: true + hideSigner: true, + defaultWalletVersion: WalletVersion.V5R1 }; return ( @@ -221,11 +226,12 @@ export const Loader: FC = React.memo(() => { - + }> + @@ -246,16 +252,17 @@ const InitialRedirect: FC = ({ children }) => { }; export const Content: FC<{ - activeWallet?: WalletState | null; + activeAccount?: Account | null; lock: boolean; -}> = ({ activeWallet, lock }) => { +}> = ({ activeAccount, lock }) => { const location = useLocation(); - const pageView = !activeWallet || location.pathname.startsWith(AppRoute.import); + const pageView = !activeAccount || location.pathname.startsWith(AppRoute.import); useWindowsScroll(!pageView); useAppWidth(); useTrackLocation(); + useDebuggingTools(); if (lock) { return ( @@ -274,7 +281,7 @@ export const Content: FC<{ path={any(AppRoute.import)} element={ - + } /> @@ -294,67 +301,65 @@ export const Content: FC<{ return ( - - - }> - - - } - /> - }> - - - } - /> - }> - - - } - /> - - }> - - - } - /> - + + }> + + + } + /> + }> + + + } + /> + }> + + + } + /> + - + }> + } /> - } /> - -