diff --git a/packages/core/src/service/proService.ts b/packages/core/src/service/proService.ts index e960808b..4f5bdef1 100644 --- a/packages/core/src/service/proService.ts +++ b/packages/core/src/service/proService.ts @@ -22,8 +22,7 @@ import { ProServiceDashboardCellNumericFiat, ProServiceDashboardCellString, ProServiceDashboardColumnType, - ProServiceService, - OpenAPI + ProServiceService } from '../tonConsoleApi'; import { delay } from '../utils/common'; import { Flatten } from '../utils/types'; @@ -44,9 +43,12 @@ export const getBackupState = async (storage: IStorage) => { return backup ?? toEmptySubscription(); }; -export const getProState = async (storage: IStorage): Promise => { +export const getProState = async ( + authTokenService: ProAuthTokenService, + storage: IStorage +): Promise => { try { - return await loadProState(storage); + return await loadProState(authTokenService, storage); } catch (e) { console.error(e); return { @@ -81,18 +83,16 @@ export const walletVersionFromProServiceDTO = (value: string) => { } }; -const attachProAuthToken = async (storage: IStorage) => { - const token = await storage.get(AppKey.PRO_AUTH_TOKEN); - OpenAPI.TOKEN = token ?? undefined; +export type ProAuthTokenService = { + attachToken: () => Promise; + onTokenUpdated: (token: string | null) => Promise; }; -const updateProAuthToken = async (storage: IStorage, token: string | null) => { - await storage.set(AppKey.PRO_AUTH_TOKEN, token); - return attachProAuthToken(storage); -}; - -export const loadProState = async (storage: IStorage): Promise => { - await attachProAuthToken(storage); +const loadProState = async ( + authService: ProAuthTokenService, + storage: IStorage +): Promise => { + await authService.attachToken(); const user = await ProServiceService.proServiceGetUserInfo(); let authorizedWallet: ProStateWallet | null = null; @@ -159,7 +159,7 @@ export const loadProState = async (storage: IStorage): Promise => { }; export const authViaTonConnect = async ( - storage: IStorage, + authService: ProAuthTokenService, api: APIConfig, wallet: TonWalletStandard, signProof: (bufferToSing: Buffer) => Promise @@ -191,16 +191,16 @@ export const authViaTonConnect = async ( throw new Error('Unable to authorize'); } - await updateProAuthToken(storage, result.auth_token); + await authService.onTokenUpdated(result.auth_token); }; -export const logoutTonConsole = async (storage: IStorage) => { +export const logoutTonConsole = async (authService: ProAuthTokenService) => { const result = await ProServiceService.proServiceLogout(); if (!result.ok) { throw new Error('Unable to logout'); } - await updateProAuthToken(storage, null); + await authService.onTokenUpdated(null); }; export const getProServiceTiers = async (lang?: Language | undefined, promoCode?: string) => { @@ -244,9 +244,9 @@ export const createRecipient = async ( return [recipient, asset]; }; -export const retryProService = async (storage: IStorage) => { +export const retryProService = async (authService: ProAuthTokenService, storage: IStorage) => { for (let i = 0; i < 10; i++) { - const state = await getProState(storage); + const state = await getProState(authService, storage); if (state.subscription.valid) { return; } @@ -267,14 +267,18 @@ export const waitProServiceInvoice = async (invoice: InvoicesInvoice) => { } while (updated.status === InvoiceStatus.PENDING); }; -export async function startProServiceTrial(storage: IStorage, botId: string, lang?: string) { +export async function startProServiceTrial( + authService: ProAuthTokenService, + botId: string, + lang?: string +) { const tgData = await loginViaTG(botId, lang); if (!tgData) { return false; } const result = await ProServiceService.proServiceTrial(tgData); - await updateProAuthToken(storage, result.auth_token); + await authService.onTokenUpdated(result.auth_token); return result.ok; } diff --git a/packages/uikit/src/state/pro.ts b/packages/uikit/src/state/pro.ts index 89a727db..1b248ca7 100644 --- a/packages/uikit/src/state/pro.ts +++ b/packages/uikit/src/state/pro.ts @@ -11,15 +11,16 @@ import { getProServiceTiers, getProState, logoutTonConsole, + ProAuthTokenService, retryProService, setBackupState, startProServiceTrial, waitProServiceInvoice } from '@tonkeeper/core/dist/service/proService'; -import { InvoicesInvoice } from '@tonkeeper/core/dist/tonConsoleApi'; +import { InvoicesInvoice, OpenAPI } from '@tonkeeper/core/dist/tonConsoleApi'; import { ProServiceTier } from '@tonkeeper/core/src/tonConsoleApi/models/ProServiceTier'; import { useMemo } from 'react'; -import { useAppContext } from '../hooks/appContext'; +import { useAppContext, useAppPlatform } from '../hooks/appContext'; import { useAppSdk } from '../hooks/appSdk'; import { useTranslation } from '../hooks/translation'; import { useAccountsStorage } from '../hooks/useStorage'; @@ -33,6 +34,7 @@ import { isAccountTonWalletStandard } from '@tonkeeper/core/dist/entries/account'; import { useActiveApi } from './wallet'; +import { AppKey } from '@tonkeeper/core/dist/Keys'; export const useProBackupState = () => { const sdk = useAppSdk(); @@ -43,11 +45,42 @@ export const useProBackupState = () => { ); }; +export const useProAuthTokenService = (): ProAuthTokenService => { + const appPlatform = useAppPlatform(); + const storage = useAppSdk().storage; + + return useMemo(() => { + if (appPlatform === 'tablet') { + return { + async attachToken() { + const token = await storage.get(AppKey.PRO_AUTH_TOKEN); + OpenAPI.TOKEN = token ?? undefined; + }, + async onTokenUpdated(token: string | null) { + await storage.set(AppKey.PRO_AUTH_TOKEN, token); + return this.attachToken(); + } + }; + } else { + return { + async attachToken() { + /* */ + }, + async onTokenUpdated() { + /* */ + } + }; + } + }, [appPlatform]); +}; + export const useProState = () => { const sdk = useAppSdk(); const client = useQueryClient(); + const authService = useProAuthTokenService(); + return useQuery([QueryKey.pro], async () => { - const state = await getProState(sdk.storage); + const state = await getProState(authService, sdk.storage); await setBackupState(sdk.storage, state.subscription); await client.invalidateQueries([QueryKey.proBackup]); return state; @@ -61,6 +94,7 @@ export const useSelectWalletForProMutation = () => { const { t } = useTranslation(); const { mutateAsync: checkTouchId } = useCheckTouchId(); const accountsStorage = useAccountsStorage(); + const authService = useProAuthTokenService(); return useMutation(async walletId => { const accounts = (await accountsStorage.getAccounts()).filter(isAccountTonWalletStandard); @@ -81,7 +115,7 @@ export const useSelectWalletForProMutation = () => { } await authViaTonConnect( - sdk.storage, + authService, api, wallet, signTonConnectOver({ sdk, accountId: account.id, wallet, t, checkTouchId }) @@ -93,9 +127,10 @@ export const useSelectWalletForProMutation = () => { export const useProLogout = () => { const client = useQueryClient(); - const sdk = useAppSdk(); + const authService = useProAuthTokenService(); + return useMutation(async () => { - await logoutTonConsole(sdk.storage); + await logoutTonConsole(authService); await client.invalidateQueries([QueryKey.pro]); }); }; @@ -162,9 +197,11 @@ export const useCreateInvoiceMutation = () => { export const useWaitInvoiceMutation = () => { const client = useQueryClient(); const sdk = useAppSdk(); + const authService = useProAuthTokenService(); + return useMutation(async data => { await waitProServiceInvoice(data.invoice); - await retryProService(sdk.storage); + await retryProService(authService, sdk.storage); await client.invalidateQueries([QueryKey.pro]); }); }; @@ -175,11 +212,11 @@ export const useActivateTrialMutation = () => { const { i18n: { language } } = useTranslation(); - const sdk = useAppSdk(); + const authService = useProAuthTokenService(); return useMutation(async () => { const result = await startProServiceTrial( - sdk.storage, + authService, (ctx.env as { tgAuthBotId: string }).tgAuthBotId, language );