f
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { COIN_ICONS } from '@shared/assets/coins'
|
||||
import type { Chain } from '@features/wallet'
|
||||
|
||||
export interface Token {
|
||||
ticker: string
|
||||
@@ -10,6 +11,10 @@ export interface Token {
|
||||
bal: string
|
||||
usd: string
|
||||
fav: boolean
|
||||
/** Stable unique key — tickers can repeat across chains (e.g. USDT on ETH/TRX/BSC). */
|
||||
id?: string
|
||||
/** Network this row belongs to — used to target send/receive modals. */
|
||||
chain?: Chain
|
||||
}
|
||||
|
||||
export const TOKENS: readonly Token[] = [
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useWalletBalance } from '@features/wallet'
|
||||
import { useWalletBalance, usePortfolio, CHAINS } from '@features/wallet'
|
||||
import type { Chain } from '@features/wallet'
|
||||
import { getCoinIcon } from '@shared/assets/coins'
|
||||
import { truncateDecimals } from '@shared/lib/utils/truncateDecimals'
|
||||
@@ -76,3 +76,65 @@ export function useChainTokenRows(chain: Chain) {
|
||||
|
||||
return { rows: [nativeRow, ...tokenRows], isLoading }
|
||||
}
|
||||
|
||||
function hasBalance(amountFormatted: string): boolean {
|
||||
return parseFloat(amountFormatted) > 0
|
||||
}
|
||||
|
||||
function unitPrice(usd: number, amountFormatted: string): number | null {
|
||||
const amount = parseFloat(amountFormatted)
|
||||
return amount > 0 && usd > 0 ? usd / amount : null
|
||||
}
|
||||
|
||||
export function useAllWalletTokenRows() {
|
||||
const { data, isLoading } = usePortfolio()
|
||||
|
||||
if (!data) return { rows: [] as Token[], isLoading }
|
||||
|
||||
const rows: Token[] = []
|
||||
|
||||
for (const chain of CHAINS) {
|
||||
const chainData = data.chains?.[chain]
|
||||
if (!chainData) continue
|
||||
|
||||
const nativeTicker = NATIVE_TICKER[chain]
|
||||
if (chainData.native && hasBalance(chainData.native.amountFormatted)) {
|
||||
const nativeStatic = lookupStatic(nativeTicker)
|
||||
rows.push({
|
||||
id: `${chain}-${nativeTicker}`,
|
||||
chain,
|
||||
ticker: nativeTicker,
|
||||
name: NATIVE_NAME[chain],
|
||||
logo: getCoinIcon(nativeTicker) ?? nativeStatic?.logo,
|
||||
color: nativeStatic?.color ?? DEFAULT_TOKEN_COLOR,
|
||||
price: formatPrice(unitPrice(chainData.native.usd, chainData.native.amountFormatted)),
|
||||
change: 0,
|
||||
bal: truncateDecimals(chainData.native.amountFormatted),
|
||||
usd: formatUsd(chainData.native.usd),
|
||||
fav: false,
|
||||
})
|
||||
}
|
||||
|
||||
for (const token of chainData.tokens ?? []) {
|
||||
if (!hasBalance(token.amountFormatted)) continue
|
||||
const staticToken = lookupStatic(token.symbol)
|
||||
rows.push({
|
||||
id: `${chain}-${token.symbol}`,
|
||||
chain,
|
||||
ticker: token.symbol,
|
||||
name: staticToken?.name ?? token.symbol,
|
||||
logo: getCoinIcon(token.symbol) ?? staticToken?.logo,
|
||||
color: staticToken?.color ?? DEFAULT_TOKEN_COLOR,
|
||||
price: formatPrice(unitPrice(token.usd, token.amountFormatted)),
|
||||
change: 0,
|
||||
bal: truncateDecimals(token.amountFormatted),
|
||||
usd: formatUsd(token.usd),
|
||||
fav: false,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
rows.sort((a, b) => (parseFloat(b.usd.replace(/[$,—]/g, '')) || 0) - (parseFloat(a.usd.replace(/[$,—]/g, '')) || 0))
|
||||
|
||||
return { rows, isLoading }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user