Skip to content

Commit

Permalink
Hotfix 4.1.2 (#787)
Browse files Browse the repository at this point in the history
  • Loading branch information
sorokin0andrey authored Apr 8, 2024
1 parent b5e0cf8 commit 14bdc8f
Show file tree
Hide file tree
Showing 16 changed files with 178 additions and 101 deletions.
15 changes: 8 additions & 7 deletions packages/mobile/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import crashlytics from '@react-native-firebase/crashlytics';
import messaging from '@react-native-firebase/messaging';
import { withIAPContext } from 'react-native-iap';
import { startApp } from './src/index';
import { tk } from './src/wallet';

LogBox.ignoreLogs([
'Non-serializable values were found in the navigation state',
Expand All @@ -47,15 +46,17 @@ async function handleDappMessage(remoteMessage) {
) {
return null;
}

await useNotificationsStore.persist.rehydrate();
if (remoteMessage.data?.type === 'better_stake_option_found') {
tk.wallet.staking.toggleRestakeBanner(
true,
remoteMessage.data.stakingAddressToMigrateFrom,
);
useNotificationsStore
.getState()
.actions.toggleRestakeBanner(
remoteMessage.data.account,
true,
remoteMessage.data.stakingAddressToMigrateFrom,
);
}

await useNotificationsStore.persist.rehydrate();
useNotificationsStore.getState().actions.addNotification(
{
...remoteMessage.data,
Expand Down
49 changes: 31 additions & 18 deletions packages/mobile/src/components/RestakeBanner/RestakeBanner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { IconsComposition } from './IconsComposition';
import { useFiatValue } from '$hooks/useFiatValue';
import { CryptoCurrencies } from '$shared/constants';
import { stakingFormatter } from '$utils/formatter';
import { useNotificationsStore } from '$store';

export interface ExtendedPoolInfo extends PoolInfo {
isWithdrawal: boolean;
Expand All @@ -35,6 +36,7 @@ export interface ExtendedPoolInfo extends PoolInfo {
export interface RestakeBannerProps {
poolsList: ExtendedPoolInfo[];
migrateFrom: string;
bypassUnstakeStep?: boolean;
}

export enum RestakeSteps {
Expand All @@ -52,11 +54,14 @@ export const RestakeBanner = memo<RestakeBannerProps>((props) => {
) as ExtendedPoolInfo;
}, [props.poolsList]);
const { handleTopUpPress } = usePoolInfo(tonstakersPool);
const toggleRestakeBanner = useNotificationsStore(
(state) => state.actions.toggleRestakeBanner,
);

const handleCloseRestakeBanner = useCallback(() => {
LayoutAnimation.easeInEaseOut();
tk.wallet.staking.toggleRestakeBanner(false);
}, []);
toggleRestakeBanner(tk.wallet.address.ton.raw, false);
}, [toggleRestakeBanner]);

const poolToWithdrawal = useMemo(
() =>
Expand All @@ -68,8 +73,6 @@ export const RestakeBanner = memo<RestakeBannerProps>((props) => {
[poolToWithdrawal],
);

const bypassStakeStep = useStakingState((s) => s.bypassStakeStep, []);

const readyWithdraw = useFiatValue(
CryptoCurrencies.Ton,
stakingFormatter.fromNano(toWithdrawalStakingInfo?.ready_withdraw ?? '0'),
Expand All @@ -79,13 +82,17 @@ export const RestakeBanner = memo<RestakeBannerProps>((props) => {

const handleWithdrawal = useCallback(
(pool: ExtendedPoolInfo, withdrawAll?: boolean) => () => {
if (pool.implementation === PoolImplementationType.Tf) {
nav.push(AppStackRouteNames.StakingSend, {
poolAddress: pool.address,
transactionType: StakingTransactionType.WITHDRAWAL_CONFIRM,
});
return;
}
nav.push(AppStackRouteNames.StakingSend, {
amount: withdrawAll && pool.balance,
poolAddress: pool.address,
transactionType:
pool.implementation === PoolImplementationType.Tf
? StakingTransactionType.WITHDRAWAL_CONFIRM
: StakingTransactionType.WITHDRAWAL,
transactionType: StakingTransactionType.WITHDRAWAL,
});
},
[nav],
Expand All @@ -107,7 +114,11 @@ export const RestakeBanner = memo<RestakeBannerProps>((props) => {
return RestakeSteps.DONE;
}
// Go to last step if pool to withdrawal is empty now (or if balance so small, or step is bypassed)
if (bypassStakeStep || Number(poolToWithdrawal?.balance) < 0.1) {
if (
props.bypassUnstakeStep ||
!poolToWithdrawal?.balance ||
Number(poolToWithdrawal?.balance) < 0.1
) {
return RestakeSteps.STAKE_INTO_TONSTAKERS;
}
// If user has pending withdrawal, render step with waiting
Expand All @@ -116,7 +127,7 @@ export const RestakeBanner = memo<RestakeBannerProps>((props) => {
}
return RestakeSteps.UNSTAKE;
}, [
bypassStakeStep,
props.bypassUnstakeStep,
isWaitingForWithdrawal,
poolToWithdrawal?.balance,
readyWithdraw.amount,
Expand All @@ -130,8 +141,8 @@ export const RestakeBanner = memo<RestakeBannerProps>((props) => {
}, [currentStepId, handleCloseRestakeBanner]);

const { formattedDuration, isCooldown } = useStakingCycle(
poolToWithdrawal?.cycle_start,
poolToWithdrawal?.cycle_end,
poolToWithdrawal?.cycle_start ?? Date.now(),
poolToWithdrawal?.cycle_end ?? Date.now(),
isWaitingForWithdrawal,
);

Expand Down Expand Up @@ -195,12 +206,14 @@ export const RestakeBanner = memo<RestakeBannerProps>((props) => {
}),
})}
/>,
<Button
color="tertiary"
size="small"
onPress={handleWithdrawal(poolToWithdrawal)}
title={t('restake_banner.unstake_action_manual')}
/>,
poolToWithdrawal.implementation !== PoolImplementationType.Tf && (
<Button
color="tertiary"
size="small"
onPress={handleWithdrawal(poolToWithdrawal)}
title={t('restake_banner.unstake_action_manual')}
/>
),
]
}
stepId={RestakeSteps.UNSTAKE}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export const DeleteAccountDone: React.FC = () => {
}, []);

const handleAnimationEnd = useCallback(() => {
dispatch(walletActions.cleanWallet({ cleanAll: true }));
dispatch(walletActions.cleanWallet({ cleanAll: false }));
}, [dispatch]);

return (
Expand Down
6 changes: 5 additions & 1 deletion packages/mobile/src/core/Notifications/Notification.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
disableNotifications,
useConnectedAppsList,
useDAppsNotifications,
useNotificationsStore,
} from '$store';
import { format, getDomainFromURL } from '$utils';
import { Swipeable, TouchableOpacity } from 'react-native-gesture-handler';
Expand Down Expand Up @@ -54,6 +55,9 @@ export const Notification: React.FC<NotificationProps> = (props) => {
const { showActionSheetWithOptions } = useActionSheet();
const { deleteNotificationByReceivedAt } = useDAppsNotifications();
const listItemRef = useRef(null);
const toggleRestakeBanner = useNotificationsStore(
(state) => state.actions.toggleRestakeBanner,
);

const handleDelete = useCallback(() => {
deleteNotificationByReceivedAt(props.notification.received_at);
Expand Down Expand Up @@ -141,7 +145,7 @@ export const Notification: React.FC<NotificationProps> = (props) => {

const handleOpenInWebView = useCallback(() => {
if (props.notification.type === NotificationType.BETTER_STAKE_OPTION_FOUND) {
tk.wallet.staking.toggleRestakeBanner(true);
toggleRestakeBanner(tk.wallet.address.ton.raw, true);
}

if (!props.notification.link && !props.notification.deeplink) {
Expand Down
30 changes: 17 additions & 13 deletions packages/mobile/src/core/Settings/Settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -211,20 +211,24 @@ export const Settings: FC = () => {
}, []);

const handleDeleteAccount = useCallback(() => {
Alert.alert(t('settings_delete_alert_title'), t('settings_delete_alert_caption'), [
{
text: t('cancel'),
style: 'cancel',
},
{
text: t('settings_delete_alert_button'),
style: 'destructive',
onPress: () => {
trackEvent('delete_wallet');
openDeleteAccountDone();
Alert.alert(
t('settings_delete_alert_title', { space: Platform.OS === 'ios' ? '\n' : ' ' }),
t('settings_delete_alert_caption'),
[
{
text: t('cancel'),
style: 'cancel',
},
},
]);
{
text: t('settings_delete_alert_button'),
style: 'destructive',
onPress: () => {
trackEvent('delete_wallet');
openDeleteAccountDone();
},
},
],
);
}, []);

const handleCustomizePress = useCallback(
Expand Down
32 changes: 19 additions & 13 deletions packages/mobile/src/core/Staking/Staking.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { useStakingRefreshControl } from '$hooks/useStakingRefreshControl';
import { useNavigation } from '@tonkeeper/router';
import { MainStackRouteNames, openDAppBrowser } from '$navigation';
import { StakingListCell } from '$shared/components';
import { FlashCountKeys, useFlashCount } from '$store';
import { FlashCountKeys, useFlashCount, useNotificationsStore } from '$store';
import { Button, Icon, ScrollHandler, Spacer, Text } from '$uikit';
import { List } from '$uikit/List/old/List';
import { getImplementationIcon, getPoolIcon } from '$utils/staking';
Expand All @@ -24,6 +24,8 @@ import { useBalancesState, useJettons, useStakingState } from '@tonkeeper/shared
import { StakingManager, StakingProvider } from '$wallet/managers/StakingManager';
import { config } from '$config';
import { RestakeBanner } from '../../components/RestakeBanner/RestakeBanner';
import { shallow } from 'zustand/shallow';
import { tk } from '$wallet';

interface Props {}

Expand All @@ -36,9 +38,11 @@ export const Staking: FC<Props> = () => {
const pools = useStakingState((s) => s.pools);
const stakingInfo = useStakingState((s) => s.stakingInfo);
const highestApyPool = useStakingState((s) => s.highestApyPool);
const showRestakeBanner = useStakingState((s) => s.showRestakeBanner);
const stakingAddressToMigrateFrom = useStakingState(
(s) => s.stakingAddressToMigrateFrom,

const rawAddress = tk.wallet.address.ton.raw ?? '';
const notificationsStore = useNotificationsStore(
(state) => state.wallets[rawAddress],
shallow,
);

const [flashShownCount] = useFlashCount(FlashCountKeys.Staking);
Expand Down Expand Up @@ -221,15 +225,17 @@ export const Staking: FC<Props> = () => {
showsVerticalScrollIndicator={false}
>
<S.Content bottomInset={bottomInset}>
{showRestakeBanner && stakingAddressToMigrateFrom && (
<>
<RestakeBanner
migrateFrom={stakingAddressToMigrateFrom}
poolsList={poolsList}
/>
<Spacer y={16} />
</>
)}
{notificationsStore?.showRestakeBanner &&
notificationsStore?.stakingAddressToMigrateFrom && (
<>
<RestakeBanner
bypassUnstakeStep={notificationsStore?.bypassUnstakeStep}
migrateFrom={notificationsStore?.stakingAddressToMigrateFrom}
poolsList={poolsList}
/>
<Spacer y={16} />
</>
)}
{!hasActivePools ? (
<S.LargeTitleContainer>
<Text variant="h2">{t('staking.title_large')}</Text>
Expand Down
38 changes: 29 additions & 9 deletions packages/mobile/src/core/StakingSend/StakingSend.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { AppStackRouteNames } from '$navigation';
import { AppStackParamList } from '$navigation/AppStack';
import { StepView, StepViewItem, StepViewRef } from '$shared/components';
import { CryptoCurrencies, Decimals } from '$shared/constants';
import { Toast } from '$store';
import { Toast, useNotificationsStore } from '$store';
import { getStakingPoolByAddress } from '@tonkeeper/shared/utils/staking';
import { walletWalletSelector } from '$store/wallet';
import { NavBar } from '$uikit';
Expand Down Expand Up @@ -38,6 +38,7 @@ import { SignRawMessage } from '$core/ModalContainer/NFTOperations/TXRequest.typ
import { useStakingState, useWallet } from '@tonkeeper/shared/hooks';
import { tk } from '$wallet';
import { Address } from '@tonkeeper/shared/Address';
import { shallow } from 'zustand/shallow';

interface Props {
route: RouteProp<AppStackParamList, AppStackRouteNames.StakingSend>;
Expand Down Expand Up @@ -176,6 +177,15 @@ export const StakingSend: FC<Props> = (props) => {

const messages = useRef<SignRawMessage[]>([]);

const rawAddress = wallet.address.ton.raw ?? '';
const stakingAddressToMigrateFrom = useNotificationsStore(
(state) => state.wallets[rawAddress]?.stakingAddressToMigrateFrom,
shallow,
);
const bypassUnstakeStep = useNotificationsStore(
(state) => state.actions.bypassUnstakeStep,
);

const { isLiquidJetton, price } = useCurrencyToSend(currency, tokenType);

const parsedAmount = useMemo(() => {
Expand Down Expand Up @@ -341,22 +351,32 @@ export const StakingSend: FC<Props> = (props) => {
const privateKey = await vault.getTonPrivateKey();

await actionRef.current.send(privateKey);

const endTimestamp = pool.cycle_end * 1000;
const isCooldown = Date.now() > endTimestamp;

if (
isWithdrawalConfrim &&
tk.wallet.staking.state.data.stakingAddressToMigrateFrom &&
Address.compare(
tk.wallet.staking.state.data.stakingAddressToMigrateFrom,
pool.address,
)
(isWithdrawalConfrim || isCooldown) &&
stakingAddressToMigrateFrom &&
Address.compare(stakingAddressToMigrateFrom, pool.address)
) {
tk.wallet.staking.setBypassStakeStep();
bypassUnstakeStep(rawAddress);
}
} catch (e) {
throw e;
} finally {
setSending(false);
}
}, [isDeposit, isWithdrawalConfrim, pool, totalFee, unlockVault]);
}, [
bypassUnstakeStep,
isDeposit,
isWithdrawalConfrim,
pool,
rawAddress,
stakingAddressToMigrateFrom,
totalFee,
unlockVault,
]);

useEffect(() => {
if (isWithdrawalConfrim || initialAmount) {
Expand Down
9 changes: 9 additions & 0 deletions packages/mobile/src/store/zustand/notifications/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ export interface INotificationsState {
last_seen: number;
last_seen_activity_screen: number;
should_show_red_dot: boolean;
showRestakeBanner?: boolean;
stakingAddressToMigrateFrom?: string;
bypassUnstakeStep?: boolean;
}

export interface INotificationsStore {
Expand All @@ -35,5 +38,11 @@ export interface INotificationsStore {
deleteNotificationByReceivedAt: (receivedAt: number, rawAddress: string) => void;
removeNotificationsByDappUrl: (dapp_url: string, rawAddress: string) => void;
removeRedDot: (rawAddress: string) => void;
toggleRestakeBanner: (
rawAddress: string,
showRestakeBanner: boolean,
stakingAddressToMigrateFrom?: string,
) => void;
bypassUnstakeStep: (rawAddress: string) => void;
};
}
Loading

0 comments on commit 14bdc8f

Please sign in to comment.