Skip to content

Commit

Permalink
Merge pull request #37 from novasamatech/feat/total-balance
Browse files Browse the repository at this point in the history
Feat: total balance
  • Loading branch information
sokolova-an authored Jan 12, 2024
2 parents 65abfa5 + 92967fd commit 830649d
Show file tree
Hide file tree
Showing 10 changed files with 100 additions and 69 deletions.
68 changes: 12 additions & 56 deletions src/common/utils/balance.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,9 @@
import BigNumber from 'bignumber.js';
import { decodeAddress } from '@polkadot/keyring';
import { BN, BN_TEN } from '@polkadot/util';

import { Address, AssetAccount, ChainAssetAccount, ChainAssetId, ChainId, TrasferAsset } from '../types';
import { AssetAccount, AssetPrice, ChainAssetAccount, ChainAssetId } from '../types';
import { Chain } from '../chainRegistry/types';
import { IAssetBalance } from '../balances/types';
import { EstimateFee, ExtrinsicBuilder, SubmitExtrinsic } from '../extrinsicService/types';
import { Balance } from '@polkadot/types/interfaces';
import { FAKE_ACCOUNT_ID } from './constants';
import { getKeyringPairFromSeed } from '../wallet';

const ZERO_BALANCE = '0';

Expand Down Expand Up @@ -173,55 +168,16 @@ export const formatAmount = (amount: string, precision: number): string => {
return new BN(amount.replace(/\D/g, '')).mul(BN_TEN.pow(bnPrecision)).toString();
};

export async function handleSend(
submitExtrinsic: SubmitExtrinsic,
{ destinationAddress, chainId, amount, transferAll, asset }: TrasferAsset,
giftTransfer?: string,
) {
const decodedAddress = decodeAddress(destinationAddress || giftTransfer);

return await submitExtrinsic(chainId, (builder) => {
const transferFunction = transferAll
? builder.api.tx.balances.transferAll(decodedAddress, false)
: builder.api.tx.balances.transferKeepAlive(decodedAddress, formatAmount(amount as string, asset.precision));

builder.addCall(transferFunction);
}).then((hash) => {
console.log('Success, Hash:', hash?.toString());
});
}
export const getTotalBalance = (assets: AssetAccount[], assetsPrices?: AssetPrice) => {
if (!assets.length || !assetsPrices) return;

export async function handleFee(
estimateFee: EstimateFee,
chainId: ChainId,
precision: number,
isGift?: boolean,
): Promise<number> {
return await estimateFee(chainId, (builder: ExtrinsicBuilder) =>
builder.addCall(builder.api.tx.balances.transferAll(decodeAddress(FAKE_ACCOUNT_ID), false)),
).then((fee: Balance) => {
const finalFee = isGift ? Number(fee) * 2 : fee;
const { formattedValue } = formatBalance(finalFee.toString(), precision);

return Number(formattedValue);
});
}
return assets.reduce((acc, asset) => {
if (!asset.asset.priceId) return acc;

export async function claimGift(
seed: string,
address: Address,
chainId: ChainId,
submitExtrinsic: SubmitExtrinsic,
): Promise<void> {
const keyring = getKeyringPairFromSeed(seed);

return await submitExtrinsic(
chainId,
(builder) => {
builder.addCall(builder.api.tx.balances.transferAll(decodeAddress(address), false));
},
keyring,
).then((hash) => {
console.log('Success, Hash:', hash?.toString());
});
}
const price = assetsPrices[asset.asset.priceId].price || 0;
const formatedBalance = Number(formatBalance(asset.totalBalance, asset.asset.precision).formattedValue);
acc += price * formatedBalance;

return acc;
}, 0);
};
61 changes: 61 additions & 0 deletions src/common/utils/extrinsics.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { decodeAddress } from '@polkadot/util-crypto';

import { EstimateFee, ExtrinsicBuilder, SubmitExtrinsic } from '../extrinsicService/types';
import { Address, ChainId, TrasferAsset } from '../types';
import { FAKE_ACCOUNT_ID } from './constants';
import { Balance } from '@polkadot/types/interfaces';
import { formatAmount, formatBalance } from './balance';
import { getKeyringPairFromSeed } from '../wallet';

export async function handleSend(
submitExtrinsic: SubmitExtrinsic,
{ destinationAddress, chainId, amount, transferAll, asset }: TrasferAsset,
giftTransfer?: string,
) {
const decodedAddress = decodeAddress(destinationAddress || giftTransfer);

return await submitExtrinsic(chainId, (builder) => {
const transferFunction = transferAll
? builder.api.tx.balances.transferAll(decodedAddress, false)
: builder.api.tx.balances.transferKeepAlive(decodedAddress, formatAmount(amount as string, asset.precision));

builder.addCall(transferFunction);
}).then((hash) => {
console.log('Success, Hash:', hash?.toString());
});
}

export async function handleFee(
estimateFee: EstimateFee,
chainId: ChainId,
precision: number,
isGift?: boolean,
): Promise<number> {
return await estimateFee(chainId, (builder: ExtrinsicBuilder) =>
builder.addCall(builder.api.tx.balances.transferAll(decodeAddress(FAKE_ACCOUNT_ID), false)),
).then((fee: Balance) => {
const finalFee = isGift ? Number(fee) * 2 : fee;
const { formattedValue } = formatBalance(finalFee.toString(), precision);

return Number(formattedValue);
});
}

export async function claimGift(
seed: string,
address: Address,
chainId: ChainId,
submitExtrinsic: SubmitExtrinsic,
): Promise<void> {
const keyring = getKeyringPairFromSeed(seed);

return await submitExtrinsic(
chainId,
(builder) => {
builder.addCall(builder.api.tx.balances.transferAll(decodeAddress(address), false));
},
keyring,
).then((hash) => {
console.log('Success, Hash:', hash?.toString());
});
}
5 changes: 2 additions & 3 deletions src/components/Assets/AssetBalance.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { cnTw } from '@/common/utils/twMerge';

import { CaptionText, Icon } from '@/components';
import { CaptionText, Icon, TokenPrice } from '@/components';
import { PriceItem } from '@/common/types';
import { IconNames } from '../Icon/types';
import TokenPrice from '../Price/TokenPrice';
import { Asset } from '@/common/chainRegistry/types';
import Balance from './Balance';

Expand All @@ -24,7 +23,7 @@ const AssetBalance = ({ balance, asset, name, className, showPrice, showArrow }:
<div className={cnTw('grid grid-cols-[50px,1fr,auto] items-center gap-x-2 grid-rows-[1fr,auto]', className)}>
<Icon name={symbol as IconNames} size={40} alt={name} className="row-span-2" />
<CaptionText>{symbol}</CaptionText>
<CaptionText className="flex items-center">
<CaptionText className="flex items-center justify-self-end">
<Balance balance={balance} precision={precision} />
{showArrow && <Icon name="chevronForward" className="w-4 h-4 ml-2" />}
</CaptionText>
Expand Down
4 changes: 3 additions & 1 deletion src/components/Price/Price.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { formatFiatBalance } from '@/common/utils/balance';
import { Shimmering } from '@/components';

type Props = {
amount: string | number;
amount?: string | number;
symbol?: string;
};

const Price = ({ amount, symbol = '$' }: Props) => {
if (amount === undefined) return <Shimmering width={50} height={30} />;
const { formattedValue, suffix } = formatFiatBalance(amount);

return (
Expand Down
2 changes: 1 addition & 1 deletion src/components/Price/TokenPrice.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useGlobalContext } from '@/common/providers/contextProvider';
import { BodyText, Price, Shimmering } from '..';
import { BodyText, Price, Shimmering } from '@/components';
import { formatBalance } from '@/common/utils/balance';

type Props = {
Expand Down
2 changes: 2 additions & 0 deletions src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
} from './Typography';
import { Icon, IconButton } from './Icon';
import Price from './Price/Price';
import TokenPrice from '@/components/Price/TokenPrice';
import AssetBalance from './Assets/AssetBalance';
import AssetsList from './Assets/AssetsList';
import Plate from './Plate/Plate';
Expand Down Expand Up @@ -41,4 +42,5 @@ export {
Identicon,
Layout,
GiftPlate,
TokenPrice,
};
16 changes: 13 additions & 3 deletions src/pages/transfer/amount.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,22 @@ import { Button, CircularProgress, Input } from '@nextui-org/react';
import { useTelegram } from '@common/providers/telegramProvider';
import { useGlobalContext } from '@/common/providers/contextProvider';
import { Paths } from '@/common/routing';
import { HeadlineText, Icon, Identicon, CaptionText, LargeTitleText, TextBase, Layout, BodyText } from '@/components';
import {
HeadlineText,
Icon,
Identicon,
CaptionText,
LargeTitleText,
TextBase,
Layout,
BodyText,
TokenPrice,
} from '@/components';
import { IconNames } from '@/components/Icon/types';
import { useExtrinsicProvider } from '@/common/extrinsicService/ExtrinsicProvider';
import { formatBalance, handleFee } from '@/common/utils/balance';
import { formatBalance } from '@/common/utils/balance';
import { handleFee } from '@/common/utils/extrinsics';
import { ChainId } from '@/common/types';
import TokenPrice from '@/components/Price/TokenPrice';

export default function AmountPage() {
const router = useRouter();
Expand Down
2 changes: 1 addition & 1 deletion src/pages/transfer/confirmation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { Divider } from '@nextui-org/react';
import { useTelegram } from '@common/providers/telegramProvider';
import { useGlobalContext } from '@/common/providers/contextProvider';
import { Paths } from '@/common/routing';
import { handleSend } from '@/common/utils/extrinsics';
import {
HeadlineText,
Icon,
Expand All @@ -21,7 +22,6 @@ import {
} from '@/components';
import { IconNames } from '@/components/Icon/types';
import { useExtrinsicProvider } from '@/common/extrinsicService/ExtrinsicProvider';
import { handleSend } from '@/common/utils/balance';
import { TrasferAsset } from '@/common/types';

export default function ConfirmationPage() {
Expand Down
2 changes: 1 addition & 1 deletion src/pages/transfer/create-gift.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ import { Paths } from '@/common/routing';
import { HeadlineText, Layout } from '@/components';
import GiftDetails from '@/screens/gifts/GiftDetails';
import { useExtrinsicProvider } from '@/common/extrinsicService/ExtrinsicProvider';
import { handleSend } from '@/common/utils/balance';
import { ChainId, TrasferAsset } from '@/common/types';
import { createGiftWallet } from '@/common/wallet';
import { createTgLink } from '@/common/telegram';
import { TgLink } from '@/common/telegram/types';
import { backupGifts } from '@/common/utils/gift';
import { handleSend } from '@/common/utils/extrinsics';

export default function CreateGiftPage() {
const router = useRouter();
Expand Down
7 changes: 4 additions & 3 deletions src/screens/dashboard/main/DashboardMain.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@ import { useTelegram } from '@/common/providers/telegramProvider';
import { useBalances } from '@common/balances/BalanceProvider';
import { useChainRegistry } from '@common/chainRegistry';
import { getMnemonic, resetWallet } from '@common/wallet';
import { claimGift, updateAssetsBalance } from '@/common/utils/balance';
import { getTotalBalance, updateAssetsBalance } from '@/common/utils/balance';
import { ChainAssetAccount } from '@common/types';
import { IAssetBalance } from '@common/balances/types';
import { Paths } from '@/common/routing';
import { getPrice } from '@/common/utils/coingecko';
import { claimGift } from '@/common/utils/extrinsics';
import { BodyText, CaptionText, Icon, AssetsList, Plate, Price, IconButton, LargeTitleText } from '@/components';

export const DashboardMain = () => {
Expand Down Expand Up @@ -73,7 +74,7 @@ export const DashboardMain = () => {
}

subscribeBalance(account, (balance: IAssetBalance) => {
console.info(`${address} ${chain.name} => balance: ${balance.total().toString()}`);
console.info(`${address} ${chain.name} => balance: ${balance.total()}`);
setAssets((prevAssets) => updateAssetsBalance(prevAssets, chain, balance));
});
}
Expand Down Expand Up @@ -103,7 +104,7 @@ export const DashboardMain = () => {
<Plate className="flex flex-col items-center mb-2 rounded-3xl">
<BodyText className="text-text-hint">Total balance</BodyText>
<LargeTitleText>
<Price amount="0" />
<Price amount={getTotalBalance(assets, assetsPrices)} />
</LargeTitleText>
<div className="grid grid-cols-3 w-full justify-items-center mt-4">
<IconButton text="Send" iconName="send" color="primary" onClick={() => router.push(Paths.TRANSFER)} />
Expand Down

0 comments on commit 830649d

Please sign in to comment.