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

feat(wallet,wallet-dashboard): show fiat balance #4747

Merged
merged 26 commits into from
Jan 22, 2025
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
134db37
feat: add fiat balance
VmMad Jan 10, 2025
c4d3a64
feat: add fiat balance
VmMad Jan 10, 2025
fd0ab04
Merge branch 'develop' into tooling-dashboard/hook-fiat-price
VmMad Jan 13, 2025
65b6f6c
feat: improve useTotalFiatBalance hook
VmMad Jan 13, 2025
31d97cb
fix: import error
VmMad Jan 13, 2025
7e8290e
fix: import
VmMad Jan 13, 2025
a2028d4
fix: transform coinType to FiatTokenName
VmMad Jan 13, 2025
46b21d3
fix: use format function for usd balance
VmMad Jan 13, 2025
3359825
fix: show token price only for mainnet
VmMad Jan 13, 2025
f3a43f2
feat: add burnt and minted tokens
evavirseda Jan 14, 2025
88c768f
Merge branch 'develop' into tooling-explorer/add-burned-minted-token-…
evavirseda Jan 14, 2025
4e56cbf
fix
evavirseda Jan 14, 2025
07c2ed1
fix workflow
evavirseda Jan 14, 2025
d153df7
feat: add hook
evavirseda Jan 14, 2025
5d178a5
Merge branch 'develop' into tooling-explorer/add-burned-minted-token-…
evavirseda Jan 14, 2025
ba0ffa9
Merge branch 'develop' into tooling-explorer/add-burned-minted-token-…
evavirseda Jan 15, 2025
d2d2772
Merge branch 'tooling-explorer/add-burned-minted-token-amounts-to-end…
VmMad Jan 15, 2025
7cdcf89
feat: add FiatTokenBalance feature
VmMad Jan 15, 2025
5dad3ee
Merge branch 'develop' into tooling-dashboard/hook-fiat-price
VmMad Jan 15, 2025
eac39d0
fix: remove querying the network in the fiat price
VmMad Jan 20, 2025
108ae33
chore: rename fiat converion
VmMad Jan 20, 2025
52bfafa
Merge branch 'develop' into tooling-dashboard/hook-fiat-price
VmMad Jan 20, 2025
cc7d778
Merge branch 'develop' into tooling-dashboard/hook-fiat-price
VmMad Jan 20, 2025
7538fee
fix: missing network params
VmMad Jan 20, 2025
f7fd0e2
fix: imports
VmMad Jan 20, 2025
506281c
feat: improve hooks
VmMad Jan 21, 2025
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
4 changes: 3 additions & 1 deletion apps/apps-backend/src/constants.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Copyright (c) 2024 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

import { FiatTokenName } from '@iota/core/enums/fiatTokenName.enums';

export const tokenPriceKey = (coinName: string) => `tokenPrice${coinName}`;
export const TOKEN_PRICE_CURRENCY = 'usd';
export const TOKEN_PRICE_COINS = ['iota'];
export const TOKEN_PRICE_COINS = [FiatTokenName.Iota];
5 changes: 2 additions & 3 deletions apps/apps-backend/src/prices/prices.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Controller, Get, Inject, Param } from '@nestjs/common';
import { Cache, CACHE_MANAGER } from '@nestjs/cache-manager';
import { CoinGeckoService } from '../coingecko/coingecko.service';
import { TOKEN_PRICE_COINS, tokenPriceKey } from '../constants';
import { FiatTokenName } from '@iota/core/enums/fiatTokenName.enums';

const ONE_HOUR_IN_MS = 1000 * 60 * 60;

Expand All @@ -16,9 +17,7 @@ export class PricesController {
) {}

@Get('cetus/:coin')
async getTokenPrice(@Param('coin') coin: string) {
coin = coin.toLowerCase();

async getTokenPrice(@Param('coin') coin: FiatTokenName) {
if (!TOKEN_PRICE_COINS.includes(coin)) {
throw new Error('Invalid coin');
}
Expand Down
6 changes: 6 additions & 0 deletions apps/core/src/enums/fiatTokenName.enums.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// Copyright (c) 2024 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

export enum FiatTokenName {
Iota = 'iota',
}
1 change: 1 addition & 0 deletions apps/core/src/enums/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@
export * from './theme.enums';
export * from './explorerLinkType.enums';
export * from './features.enums';
export * from './fiatTokenName.enums';
1 change: 1 addition & 0 deletions apps/core/src/hooks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export * from './useTransactionData';
export * from './useGetStakingValidatorDetails';
export * from './useCursorPagination';
export * from './useTheme';
export * from './useTotalFiatBalance';
export * from './useNFTBasicData';
export * from './useOwnedNFT';
export * from './useNftDetails';
Expand Down
9 changes: 5 additions & 4 deletions apps/core/src/hooks/useTokenPrice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,23 @@ import BigNumber from 'bignumber.js';

import { useAppsBackend } from './useAppsBackend';
import { useCoinMetadata } from './useFormatCoin';
import { FiatTokenName } from '../enums';

type TokenPriceResponse = { price: string | null };

export function useTokenPrice(coinType: string) {
export function useTokenPrice(tokenName: FiatTokenName) {
const { request } = useAppsBackend();
return useQuery({
queryKey: ['apps-backend', 'token-price', coinType],
queryFn: () => request<TokenPriceResponse>(`cetus/${coinType}`),
queryKey: ['apps-backend', 'token-price', tokenName],
queryFn: () => request<TokenPriceResponse>(`cetus/${tokenName}`),

// These values are set to one minute to prevent displaying stale data, as token prices can change frequently.
staleTime: 60 * 1000,
gcTime: 60 * 1000,
});
}

export function useBalanceInUSD(coinType: string, balance: bigint | string | number) {
export function useBalanceInUSD(coinType: FiatTokenName, balance: bigint | string | number) {
const { data: coinMetadata } = useCoinMetadata(coinType);
const { data: tokenPrice } = useTokenPrice(coinType);
if (!tokenPrice || !coinMetadata || !tokenPrice.price) return null;
Expand Down
33 changes: 33 additions & 0 deletions apps/core/src/hooks/useTotalFiatBalance.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright (c) 2024 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

import { useCurrentAccount } from '@iota/dapp-kit';
import { useBalance } from './useBalance';
import { useTokenPrice } from './useTokenPrice';
import { CoinFormat, formatBalance, useCoinMetadata } from './useFormatCoin';
import { IOTA_TYPE_ARG } from '@iota/iota-sdk/utils';
import { FiatTokenName } from '../enums';

export function useTotalFiatBalance(): string {
const { data: { price } = {} } = useTokenPrice(FiatTokenName.Iota);
const address = useCurrentAccount()?.address;

if (!address) {
return '';
}

const { data: coinBalance } = useBalance(address);
const totalBalance = Number(coinBalance?.totalBalance || 0);
const queryResult = useCoinMetadata(IOTA_TYPE_ARG);
const iotaToFiat = totalBalance && price ? totalBalance * Number(price || 0) : 0;
const formatted = formatBalance(iotaToFiat, queryResult.data?.decimals || 0, CoinFormat.FULL);
return price ? `${coinToFiat(formatted, price)}` : '';
}

function coinToFiat(coinBalance: string, coinPrice: string): string {
const totalBalanceInUsd = Number(coinBalance) * Number(coinPrice);
return Number(totalBalanceInUsd).toLocaleString('en', {
style: 'currency',
currency: 'USD',
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import { useCurrentAccount, useIotaClientContext } from '@iota/dapp-kit';
import { formatAddress, IOTA_TYPE_ARG } from '@iota/iota-sdk/utils';
import { useBalance, useFormatCoin } from '@iota/core';
import { useBalance, useFormatCoin, useTotalFiatBalance } from '@iota/core';
import { Address, Button, ButtonSize, ButtonType, Panel } from '@iota/apps-ui-kit';
import { getNetwork } from '@iota/iota-sdk/client';
import { ReceiveFundsDialog, SendTokenDialog } from '../dialogs';
Expand All @@ -14,6 +14,7 @@ export function AccountBalance() {
const account = useCurrentAccount();
const address = account?.address;
const [isReceiveDialogOpen, setIsReceiveDialogOpen] = useState(false);
const fiatBalance = useTotalFiatBalance();
const { network } = useIotaClientContext();
const { explorer } = getNetwork(network);
const { data: coinBalance, isPending } = useBalance(address!);
Expand Down Expand Up @@ -41,19 +42,28 @@ export function AccountBalance() {
<p>Loading...</p>
) : (
<div className="flex h-full flex-col items-center justify-center gap-y-lg p-lg">
{address && (
<Address
text={formattedAddress}
isCopyable
copyText={address}
isExternal
externalLink={explorerLink}
onCopySuccess={handleOnCopySuccess}
/>
)}
<span className="text-headline-lg text-neutral-10 dark:text-neutral-92">
{formatted} {symbol}
</span>
<div className="flex flex-col items-center gap-y-xs">
{address && (
<div className="-mr-lg">
<Address
text={formattedAddress}
isCopyable
copyText={address}
isExternal
externalLink={explorerLink}
onCopySuccess={handleOnCopySuccess}
/>
</div>
)}
<span className="text-headline-lg text-neutral-10 dark:text-neutral-92">
{formatted} {symbol}
</span>
{fiatBalance && (
<span className="text-body-md text-neutral-10 dark:text-neutral-92">
{fiatBalance}
</span>
)}
</div>
<div className="flex w-full max-w-56 gap-xs">
<Button
onClick={openSendTokenDialog}
Expand Down
Loading