diff --git a/src/app/common/asset-utils.ts b/src/app/common/asset-utils.ts index 12a2534e89d..0ef0152f635 100644 --- a/src/app/common/asset-utils.ts +++ b/src/app/common/asset-utils.ts @@ -1,5 +1,5 @@ import type { MarketData } from '@shared/models/market.model'; -import type { Money } from '@shared/models/money.model'; +import { type Money } from '@shared/models/money.model'; import { baseCurrencyAmountInQuote } from './money/calculate-money'; import { i18nFormatCurrency } from './money/format-money'; diff --git a/src/app/components/crypto-assets/bitcoin/brc20-token-asset-list/brc20-token-asset-item.layout.tsx b/src/app/components/crypto-assets/bitcoin/brc20-token-asset-list/brc20-token-asset-item.layout.tsx index 471631f9757..e83635a03c3 100644 --- a/src/app/components/crypto-assets/bitcoin/brc20-token-asset-list/brc20-token-asset-item.layout.tsx +++ b/src/app/components/crypto-assets/bitcoin/brc20-token-asset-list/brc20-token-asset-item.layout.tsx @@ -23,7 +23,7 @@ export function Brc20TokenAssetItemLayout({ onClick, token }: Brc20TokenAssetIte } - titleLeft={token.ticker} + titleLeft={token.tokenData.ticker} captionLeft="BRC-20" titleRight={ - + {formattedBalance.value} diff --git a/src/app/components/crypto-assets/bitcoin/brc20-token-asset-list/brc20-token-asset-list.tsx b/src/app/components/crypto-assets/bitcoin/brc20-token-asset-list/brc20-token-asset-list.tsx index 62046fc2291..e63cfd9a422 100644 --- a/src/app/components/crypto-assets/bitcoin/brc20-token-asset-list/brc20-token-asset-list.tsx +++ b/src/app/components/crypto-assets/bitcoin/brc20-token-asset-list/brc20-token-asset-list.tsx @@ -12,10 +12,10 @@ import { useCurrentAccountNativeSegwitAddressIndexZero } from '@app/store/accoun import { Brc20TokenAssetItemLayout } from './brc20-token-asset-item.layout'; interface Brc20TokenAssetListProps { - brc20Tokens: Brc20Token[]; + tokens: Brc20Token[]; variant?: string; } -export function Brc20TokenAssetList({ brc20Tokens, variant }: Brc20TokenAssetListProps) { +export function Brc20TokenAssetList({ tokens, variant }: Brc20TokenAssetListProps) { const navigate = useNavigate(); const currentAccountBtcAddress = useCurrentAccountNativeSegwitAddressIndexZero(); const { btcBalance: btcCryptoCurrencyAssetBalance } = @@ -25,17 +25,17 @@ export function Brc20TokenAssetList({ brc20Tokens, variant }: Brc20TokenAssetLis variant === 'send' && btcCryptoCurrencyAssetBalance.balance.amount.isGreaterThan(0); function navigateToBrc20SendForm(token: Brc20Token) { - const { ticker, balance, holderAddress, marketData } = token; - navigate(RouteUrls.SendBrc20SendForm.replace(':ticker', ticker), { - state: { balance, ticker, holderAddress, marketData }, + const { balance, holderAddress, marketData, tokenData } = token; + navigate(RouteUrls.SendBrc20SendForm.replace(':ticker', tokenData.ticker), { + state: { balance, ticker: tokenData.ticker, holderAddress, marketData }, }); } return ( - {brc20Tokens.map(token => ( + {tokens.map(token => ( navigateToBrc20SendForm(token) : undefined} /> diff --git a/src/app/components/crypto-assets/bitcoin/runes-asset-list/runes-asset-item.layout.tsx b/src/app/components/crypto-assets/bitcoin/runes-asset-list/runes-asset-item.layout.tsx index 967c7c91529..09780d9adf4 100644 --- a/src/app/components/crypto-assets/bitcoin/runes-asset-list/runes-asset-item.layout.tsx +++ b/src/app/components/crypto-assets/bitcoin/runes-asset-list/runes-asset-item.layout.tsx @@ -12,14 +12,15 @@ interface RunesAssetItemLayoutProps { rune: RuneToken; } export function RunesAssetItemLayout({ rune }: RunesAssetItemLayoutProps) { - const balanceAsString = convertAmountToBaseUnit(rune.balance).toString(); + const { balance, tokenData } = rune; + const balanceAsString = convertAmountToBaseUnit(balance).toString(); const formattedBalance = formatBalance(balanceAsString); return ( } - titleLeft={rune.spaced_rune_name ?? rune.rune_name} + titleLeft={tokenData.spaced_rune_name ?? tokenData.rune_name} captionLeft="Runes" titleRight={ - - {formattedBalance.value} {rune.symbol} + + {formattedBalance.value} {tokenData.symbol} } diff --git a/src/app/components/crypto-assets/bitcoin/runes-asset-list/runes-asset-list.tsx b/src/app/components/crypto-assets/bitcoin/runes-asset-list/runes-asset-list.tsx index deaebbcbe66..d89fb52692d 100644 --- a/src/app/components/crypto-assets/bitcoin/runes-asset-list/runes-asset-list.tsx +++ b/src/app/components/crypto-assets/bitcoin/runes-asset-list/runes-asset-list.tsx @@ -6,5 +6,7 @@ interface RunesAssetListProps { runes: RuneToken[]; } export function RunesAssetList({ runes }: RunesAssetListProps) { - return runes.map((rune, i) => ); + return runes.map((rune, i) => ( + + )); } diff --git a/src/app/components/crypto-assets/choose-crypto-asset/crypto-asset-list.tsx b/src/app/components/crypto-assets/choose-crypto-asset/crypto-asset-list.tsx index e1778a5d097..a6bdb402f4e 100644 --- a/src/app/components/crypto-assets/choose-crypto-asset/crypto-asset-list.tsx +++ b/src/app/components/crypto-assets/choose-crypto-asset/crypto-asset-list.tsx @@ -58,7 +58,7 @@ export function CryptoAssetList({ {() => ( - {brc20Tokens => } + {brc20Tokens => } )} diff --git a/src/app/features/asset-list/components/bitcoin-fungible-tokens-asset-list.tsx b/src/app/features/asset-list/components/bitcoin-fungible-tokens-asset-list.tsx index 4acf6b79c35..ceacfafe001 100644 --- a/src/app/features/asset-list/components/bitcoin-fungible-tokens-asset-list.tsx +++ b/src/app/features/asset-list/components/bitcoin-fungible-tokens-asset-list.tsx @@ -16,7 +16,7 @@ export function BitcoinFungibleTokenAssetList({ return ( <> - {brc20Tokens => } + {brc20Tokens => } {src20Tokens => } diff --git a/src/app/query/bitcoin/bitcoin-client.ts b/src/app/query/bitcoin/bitcoin-client.ts index fa5ea9c7019..5882888ac1c 100644 --- a/src/app/query/bitcoin/bitcoin-client.ts +++ b/src/app/query/bitcoin/bitcoin-client.ts @@ -98,10 +98,11 @@ interface Brc20WalletBalancesResponse { data: Brc20Balance[]; } -export interface Brc20Token extends Brc20Balance, Brc20TickerInfo { +export interface Brc20Token { balance: Money | null; holderAddress: string; marketData: MarketData | null; + tokenData: Brc20Balance & Brc20TickerInfo; } /* RUNES */ @@ -149,8 +150,9 @@ interface RunesTickerInfoResponse { data: RuneTickerInfo; } -export interface RuneToken extends RuneBalance, RuneTickerInfo { +export interface RuneToken { balance: Money; + tokenData: RuneBalance & RuneTickerInfo; } export interface RunesOutputsByAddress { diff --git a/src/app/query/bitcoin/ordinals/brc20/brc20-tokens.hooks.ts b/src/app/query/bitcoin/ordinals/brc20/brc20-tokens.hooks.ts index c2db9af9c99..cb3e43ddab9 100644 --- a/src/app/query/bitcoin/ordinals/brc20/brc20-tokens.hooks.ts +++ b/src/app/query/bitcoin/ordinals/brc20/brc20-tokens.hooks.ts @@ -1,10 +1,11 @@ import BigNumber from 'bignumber.js'; import { createMarketData, createMarketPair } from '@shared/models/market.model'; -import { createMoney } from '@shared/models/money.model'; +import { type Money, createMoney } from '@shared/models/money.model'; import { unitToFractionalUnit } from '@app/common/money/unit-conversion'; import { useGetBrc20TokensQuery } from '@app/query/bitcoin/ordinals/brc20/brc20-tokens.query'; +import { useCalculateBitcoinFiatValue } from '@app/query/common/market-data/market-data.hooks'; import { useConfigOrdinalsbot } from '@app/query/common/remote-config/remote-config.query'; import { useAppDispatch } from '@app/store'; import { useCurrentAccountIndex } from '@app/store/accounts/account'; @@ -81,29 +82,40 @@ export function useBrc20Transfers(holderAddress: string) { }; } -function makeBrc20Token(token: Brc20Token) { +function makeBrc20Token(priceAsFiat: Money, token: Brc20Token) { return { ...token, balance: createMoney( - unitToFractionalUnit(token.decimals)(new BigNumber(token.overall_balance)), - token.ticker, - token.decimals + unitToFractionalUnit(token.tokenData.decimals)( + new BigNumber(token.tokenData.overall_balance) + ), + token.tokenData.ticker, + token.tokenData.decimals ), - marketData: token.min_listed_unit_price + marketData: token.tokenData.min_listed_unit_price ? createMarketData( - createMarketPair(token.ticker, 'USD'), - createMoney(new BigNumber(token.min_listed_unit_price), 'USD') + createMarketPair(token.tokenData.ticker, 'USD'), + createMoney(priceAsFiat.amount, 'USD') ) : null, }; } export function useBrc20Tokens() { + const calculateBitcoinFiatValue = useCalculateBitcoinFiatValue(); const { data: allBrc20TokensResponse } = useGetBrc20TokensQuery(); - const brc20Tokens = allBrc20TokensResponse?.pages + + const tokens = allBrc20TokensResponse?.pages .flatMap(page => page.brc20Tokens) .filter(token => token.length > 0) .flatMap(token => token); - return brc20Tokens?.map(token => makeBrc20Token(token)) ?? []; + return ( + tokens?.map(token => { + const priceAsFiat = calculateBitcoinFiatValue( + createMoney(new BigNumber(token.tokenData.min_listed_unit_price ?? 0), 'BTC') + ); + return makeBrc20Token(priceAsFiat, token); + }) ?? [] + ); } diff --git a/src/app/query/bitcoin/ordinals/brc20/brc20-tokens.query.ts b/src/app/query/bitcoin/ordinals/brc20/brc20-tokens.query.ts index a4a7ff2feb0..c5a294cc309 100644 --- a/src/app/query/bitcoin/ordinals/brc20/brc20-tokens.query.ts +++ b/src/app/query/bitcoin/ordinals/brc20/brc20-tokens.query.ts @@ -59,14 +59,13 @@ export function useGetBrc20TokensQuery() { }) ); - // Initialize token with ticker data + // Initialize token with token data return brc20Tokens.data.map((token, index) => { return { - ...token, - ...tickerPromises[index].data, balance: null, holderAddress: address, marketData: null, + tokenData: { ...token, ...tickerPromises[index].data }, }; }); }); diff --git a/src/app/query/bitcoin/runes/runes-outputs-by-address.query.ts b/src/app/query/bitcoin/runes/runes-outputs-by-address.query.ts index cdfd3323544..5d92ffb56df 100644 --- a/src/app/query/bitcoin/runes/runes-outputs-by-address.query.ts +++ b/src/app/query/bitcoin/runes/runes-outputs-by-address.query.ts @@ -7,7 +7,7 @@ import { useCurrentNetwork } from '@app/store/networks/networks.selectors'; import type { RunesOutputsByAddress } from '../bitcoin-client'; import { useRunesEnabled } from './runes.hooks'; -const queryOptions = { staleTime: 1 * 60 * 1000 }; +const queryOptions = { staleTime: 5 * 60 * 1000 }; export function useGetRunesOutputsByAddressQuery( address: string, diff --git a/src/app/query/bitcoin/runes/runes-ticker-info.query.ts b/src/app/query/bitcoin/runes/runes-ticker-info.query.ts index 1f8a314ed34..36223438ced 100644 --- a/src/app/query/bitcoin/runes/runes-ticker-info.query.ts +++ b/src/app/query/bitcoin/runes/runes-ticker-info.query.ts @@ -6,7 +6,7 @@ import { useCurrentNetwork } from '@app/store/networks/networks.selectors'; import type { RuneTickerInfo } from '../bitcoin-client'; -const queryOptions = { staleTime: 1 * 60 * 1000 }; +const queryOptions = { staleTime: 5 * 60 * 1000 }; export function useGetRunesTickerInfoQuery(runeNames: string[]): UseQueryResult[] { const client = useBitcoinClient(); diff --git a/src/app/query/bitcoin/runes/runes-wallet-balances.query.ts b/src/app/query/bitcoin/runes/runes-wallet-balances.query.ts index dd8ce8525bb..16e8177c169 100644 --- a/src/app/query/bitcoin/runes/runes-wallet-balances.query.ts +++ b/src/app/query/bitcoin/runes/runes-wallet-balances.query.ts @@ -7,7 +7,7 @@ import { useCurrentNetwork } from '@app/store/networks/networks.selectors'; import type { RuneBalance } from '../bitcoin-client'; -const queryOptions = { staleTime: 1 * 60 * 1000 }; +const queryOptions = { staleTime: 5 * 60 * 1000 }; export function useGetRunesWalletBalancesByAddressesQuery( addresses: string[], diff --git a/src/app/query/bitcoin/runes/runes.hooks.ts b/src/app/query/bitcoin/runes/runes.hooks.ts index 7e1cff6e0d8..68ae4966d9e 100644 --- a/src/app/query/bitcoin/runes/runes.hooks.ts +++ b/src/app/query/bitcoin/runes/runes.hooks.ts @@ -13,14 +13,16 @@ const defaultRunesSymbol = 'ยค'; function makeRuneToken(runeBalance: RuneBalance, tickerInfo: RuneTickerInfo): RuneToken { return { - ...runeBalance, - ...tickerInfo, - symbol: tickerInfo.symbol ?? defaultRunesSymbol, balance: createMoney( Number(runeBalance.total_balance), tickerInfo.rune_name, tickerInfo.decimals ), + tokenData: { + ...runeBalance, + ...tickerInfo, + symbol: tickerInfo.symbol ?? defaultRunesSymbol, + }, }; }