Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature(mobile): Support locked tokens #782

Merged
merged 1 commit into from
Apr 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
182 changes: 127 additions & 55 deletions packages/@core-js/src/TonAPI/TonAPIGenerated.ts

Large diffs are not rendered by default.

34 changes: 31 additions & 3 deletions packages/mobile/src/core/Jetton/Jetton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import { useWallet, useWalletCurrency } from '@tonkeeper/shared/hooks';
import { tk } from '$wallet';
import { Chart } from '$shared/components/Chart/new/Chart';
import { ChartPeriod } from '$store/zustand/chart';
import { formatDate } from '@tonkeeper/shared/utils/date';

const unverifiedTokenHitSlop = { top: 4, left: 4, bottom: 4, right: 4 };

Expand All @@ -37,6 +38,10 @@ export const Jetton: React.FC<JettonProps> = ({ route }) => {
const jetton = useJetton(route.params.jettonAddress);
const jettonActivityList = useJettonActivityList(jetton.jettonAddress);
const jettonPrice = useTokenPrice(jetton.jettonAddress, jetton.balance);
const lockedJettonPrice = useTokenPrice(
jetton.jettonAddress,
jetton.lock?.amount.toString() ?? '0',
);
const wallet = useWallet();

const isWatchOnly = wallet && wallet.isWatchOnly;
Expand Down Expand Up @@ -95,10 +100,33 @@ export const Jetton: React.FC<JettonProps> = ({ route }) => {
>
{jettonPrice.formatted.totalFiat}
</HideableAmount>
{jetton.lock ? (
<>
<Spacer y={12} />
<Text variant="body2" color="textSecondary">
{formatter.format(jetton.lock.amount, {
decimals: jetton.metadata.decimals,
currency: jetton.metadata.symbol,
currencySeparator: 'wide',
})}
 ·
{' '}
{lockedJettonPrice.formatted.totalFiat}
</Text>
<Text variant="body2" color="textTertiary">
{t('jetton_locked_till', {
date: formatDate(jetton.lock.till * 1000, 'd MMM yyyy'),
})}
</Text>
</>
) : null}
{jettonPrice.formatted.fiat ? (
<Text style={{ marginTop: 12 }} variant="body2" color="foregroundSecondary">
{t('jetton_price')} {jettonPrice.formatted.fiat}
</Text>
<>
<Spacer y={12} />
<Text variant="body2" color="foregroundSecondary">
{t('jetton_price')} {jettonPrice.formatted.fiat}
</Text>
</>
) : null}
</S.JettonAmountWrapper>
{jetton.metadata.image ? (
Expand Down
1 change: 1 addition & 0 deletions packages/mobile/src/store/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,7 @@ export interface JettonBalanceModel {
currency: CryptoCurrency;
metadata: JettonMetadata;
balance: string;
lock?: { amount: string; till: number };
jettonAddress: string;
walletAddress: string;
verification: JettonVerification;
Expand Down
37 changes: 29 additions & 8 deletions packages/mobile/src/tabs/Wallet/components/WalletContentList.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { memo, useMemo } from 'react';
import React, { memo, ReactNode, useMemo } from 'react';
import { t } from '@tonkeeper/shared/i18n';
import {
Screen,
Expand Down Expand Up @@ -55,7 +55,7 @@ type TokenItem = {
onPress?: () => void;
title: string;
subtitle?: string;
value?: string;
value?: string | ReactNode;
subvalue?: string;
rate?: Rate;
picture?: string;
Expand Down Expand Up @@ -142,11 +142,15 @@ const RenderItem = ({ item }: { item: Content }) => {
}
picture={item.picture}
value={
<HideableAmount
style={styles.valueText.static}
variant="label1"
stars=" * * *"
>{` ${item.value}`}</HideableAmount>
typeof item.value === 'string' ? (
<HideableAmount
style={styles.valueText.static}
variant="label1"
stars=" * * *"
>{` ${item.value}`}</HideableAmount>
) : (
item.value
)
}
subvalue={
item.subvalue && (
Expand Down Expand Up @@ -303,7 +307,24 @@ export const WalletContentList = memo<BalancesListProps>(
onPress: () => openJetton(item.address.rawAddress),
picture: item.iconUrl,
title: item.symbol,
value: item.quantity.formatted,
value: item.lock ? (
<HideableAmount
style={styles.valueText.static}
variant="label1"
stars=" * * *"
>
{item.quantity.formatted}
<Text type="label1" color="textTertiary">
{' '}
·{' '}
</Text>
<Text type="label1" color="textSecondary">
{item.lock.formatted}
</Text>
</HideableAmount>
) : (
item.quantity.formatted
),
subvalue: item.rate.total,
rate: item.rate.price
? {
Expand Down
6 changes: 6 additions & 0 deletions packages/mobile/src/tabs/Wallet/hooks/useTokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ type TokenInfo = {
value: string;
formatted: string;
};
lock?: {
formatted: string;
};
price: TokenPrice;
rate: {
price: string | null;
Expand Down Expand Up @@ -65,6 +68,9 @@ export const useTonkens = (): {
value: item.balance,
formatted: formatter.format(item.balance),
},
lock: item.lock && {
formatted: formatter.format(item.lock.amount),
},
price: rate,
rate: {
price: rate.formatted.fiat,
Expand Down
2 changes: 0 additions & 2 deletions packages/mobile/src/wallet/managers/JettonsManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ import { JettonBalanceModel } from '../models/JettonBalanceModel';
import { Address } from '@tonkeeper/core/src/formatters/Address';
import { TokenApprovalManager } from './TokenApprovalManager';
import { TonPriceManager } from './TonPriceManager';
import BigNumber from 'bignumber.js';
import { AmountFormatter } from '@tonkeeper/core';
import { sortByPrice } from '@tonkeeper/core/src/utils/jettons';

export type JettonsState = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,22 @@ export class JettonBalanceModel {
jettonAddress: string;
walletAddress: string;
verification: JettonVerification;
lock?: { amount: string; till: number };

constructor(jettonBalance: JettonBalance) {
this.metadata = jettonBalance.jetton;
this.balance = AmountFormatter.fromNanoStatic(
jettonBalance.balance,
jettonBalance.jetton.decimals,
);
// @ts-ignore will be implemented in API later
this.lock = jettonBalance.lock && {
amount: AmountFormatter.fromNanoStatic(
jettonBalance.lock.amount,
jettonBalance.jetton.decimals,
),
till: jettonBalance.lock.till,
};
this.jettonAddress = new Address(jettonBalance.jetton.address).toFriendly();
this.walletAddress = new Address(jettonBalance.wallet_address.address).toFriendly();
this.verification = jettonBalance.jetton
Expand Down
1 change: 1 addition & 0 deletions packages/shared/i18n/locales/tonkeeper/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,7 @@
"jetton_name": "%{name} Token",
"jetton_open_explorer": "View details",
"jetton_price": "Price:",
"jetton_locked_till": "Locked until %{date}",
"jettons_list_title": "Tokens",
"jettons_manage_tokens": "Manage tokens",
"jettons_show_jettons": "Show tokens in wallet",
Expand Down
1 change: 1 addition & 0 deletions packages/shared/i18n/locales/tonkeeper/ru-RU.json
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,7 @@
"jetton_name" : "%{name} Токен",
"jetton_open_explorer" : "Подробнее",
"jetton_price" : "Цена:",
"jetton_locked_till": "Заблокированы до %{date}",
"jettons_list_title" : "Токены",
"jettons_manage_tokens" : "Настроить токены",
"jetton_token" : "Токен",
Expand Down