17.05.2026 funny
This commit is contained in:
76
src/widgets/token-table/model/useChainTokenRows.ts
Normal file
76
src/widgets/token-table/model/useChainTokenRows.ts
Normal file
@@ -0,0 +1,76 @@
|
||||
import { useWalletBalance } from '@features/wallet'
|
||||
import type { Chain } from '@features/wallet'
|
||||
import { TOKENS, type Token } from './tokens'
|
||||
|
||||
const NATIVE_TICKER: Record<Chain, string> = {
|
||||
BTC: 'BTC',
|
||||
ETH: 'ETH',
|
||||
SOL: 'SOL',
|
||||
TRX: 'TRX',
|
||||
BSC: 'BNB',
|
||||
}
|
||||
|
||||
const NATIVE_NAME: Record<Chain, string> = {
|
||||
BTC: 'Bitcoin',
|
||||
ETH: 'Ethereum',
|
||||
SOL: 'Solana',
|
||||
TRX: 'Tron',
|
||||
BSC: 'BNB',
|
||||
}
|
||||
|
||||
const DEFAULT_TOKEN_COLOR = '#2A2D3A'
|
||||
|
||||
function formatUsd(value: number | null | undefined): string {
|
||||
if (value == null) return '$—'
|
||||
return `$${value.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`
|
||||
}
|
||||
|
||||
function formatPrice(value: number | null | undefined): string {
|
||||
if (value == null) return '$—'
|
||||
if (value >= 1) {
|
||||
return `$${value.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`
|
||||
}
|
||||
return `$${value.toLocaleString('en-US', { minimumFractionDigits: 4, maximumFractionDigits: 6 })}`
|
||||
}
|
||||
|
||||
function lookupStatic(ticker: string): Token | undefined {
|
||||
return TOKENS.find((t) => t.ticker === ticker)
|
||||
}
|
||||
|
||||
export function useChainTokenRows(chain: Chain) {
|
||||
const { data, isLoading } = useWalletBalance(chain)
|
||||
|
||||
if (!data) return { rows: [] as Token[], isLoading }
|
||||
|
||||
const nativeTicker = NATIVE_TICKER[chain]
|
||||
const nativeStatic = lookupStatic(nativeTicker)
|
||||
|
||||
const nativeRow: Token = {
|
||||
ticker: nativeTicker,
|
||||
name: NATIVE_NAME[chain],
|
||||
logo: nativeStatic?.logo,
|
||||
color: nativeStatic?.color ?? DEFAULT_TOKEN_COLOR,
|
||||
price: formatPrice(data.native.usdPrice),
|
||||
change: 0,
|
||||
bal: data.native.formatted,
|
||||
usd: formatUsd(data.native.usdValue),
|
||||
fav: false,
|
||||
}
|
||||
|
||||
const tokenRows: Token[] = Object.entries(data.tokens).map(([symbol, amount]) => {
|
||||
const staticToken = lookupStatic(symbol)
|
||||
return {
|
||||
ticker: symbol,
|
||||
name: staticToken?.name ?? symbol,
|
||||
logo: staticToken?.logo,
|
||||
color: staticToken?.color ?? DEFAULT_TOKEN_COLOR,
|
||||
price: formatPrice(amount.usdPrice),
|
||||
change: 0,
|
||||
bal: amount.formatted,
|
||||
usd: formatUsd(amount.usdValue),
|
||||
fav: false,
|
||||
}
|
||||
})
|
||||
|
||||
return { rows: [nativeRow, ...tokenRows], isLoading }
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
import { useAllWalletBalances, usePrices } from '@features/wallet'
|
||||
import { CHAINS } from '@features/wallet'
|
||||
import { TOKENS } from './tokens'
|
||||
import type { WalletBalanceData } from '@features/wallet'
|
||||
|
||||
const PRICE_SYMBOLS = ['BTC', 'ETH', 'SOL', 'TRX', 'BSC']
|
||||
|
||||
type ChainSource =
|
||||
| { chain: 'BTC' | 'ETH' | 'SOL' | 'TRX' | 'BSC'; type: 'native' }
|
||||
| { chain: 'ETH'; type: 'token'; symbol: string }
|
||||
|
||||
const CHAIN_MAP: Record<string, ChainSource> = {
|
||||
BTC: { chain: 'BTC', type: 'native' },
|
||||
ETH: { chain: 'ETH', type: 'native' },
|
||||
SOL: { chain: 'SOL', type: 'native' },
|
||||
TRX: { chain: 'TRX', type: 'native' },
|
||||
BSC: { chain: 'BSC', type: 'native' },
|
||||
}
|
||||
|
||||
function formatUsd(value: number | null | undefined): string {
|
||||
if (value == null) return '$—'
|
||||
return `$${value.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`
|
||||
}
|
||||
|
||||
function formatPrice(value: number | null | undefined): string {
|
||||
if (value == null) return '$—'
|
||||
if (value >= 1) {
|
||||
return `$${value.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`
|
||||
}
|
||||
return `$${value.toLocaleString('en-US', { minimumFractionDigits: 4, maximumFractionDigits: 6 })}`
|
||||
}
|
||||
|
||||
export function useTokenRows() {
|
||||
const balanceResults = useAllWalletBalances()
|
||||
const pricesQuery = usePrices(PRICE_SYMBOLS)
|
||||
|
||||
const isLoading = balanceResults.some(r => r.isLoading) || pricesQuery.isLoading
|
||||
|
||||
const balanceByChain: Record<string, WalletBalanceData> = {}
|
||||
CHAINS.forEach((chain, i) => {
|
||||
const data = balanceResults[i].data
|
||||
if (data) balanceByChain[chain] = data
|
||||
})
|
||||
|
||||
const rows = TOKENS.map(t => {
|
||||
const src = CHAIN_MAP[t.ticker]
|
||||
const chainData = src ? balanceByChain[src.chain] : undefined
|
||||
|
||||
let bal = t.bal
|
||||
let usd = t.usd
|
||||
|
||||
if (chainData) {
|
||||
const amount =
|
||||
src.type === 'native'
|
||||
? chainData.native
|
||||
: chainData.tokens[src.type === 'token' ? src.symbol : t.ticker]
|
||||
|
||||
if (amount) {
|
||||
bal = amount.formatted ?? t.bal
|
||||
usd = formatUsd(amount.usdValue)
|
||||
}
|
||||
}
|
||||
|
||||
const priceEntry = pricesQuery.data?.[t.ticker]
|
||||
const price = priceEntry ? formatPrice(priceEntry.usd) : t.price
|
||||
|
||||
return { ...t, price, bal, usd }
|
||||
})
|
||||
|
||||
return { rows, isLoading }
|
||||
}
|
||||
Reference in New Issue
Block a user