145 lines
4.8 KiB
TypeScript
145 lines
4.8 KiB
TypeScript
import { useState } from 'react'
|
|
import { COIN_ICONS } from '@shared/assets/coins'
|
|
|
|
const btc = COIN_ICONS.BTC
|
|
const eth = COIN_ICONS.ETH
|
|
const sol = COIN_ICONS.SOL
|
|
const trx = COIN_ICONS.TRX
|
|
const arb = COIN_ICONS.ARB
|
|
import type { WalletBalanceData } from '@features/wallet'
|
|
|
|
export interface Token {
|
|
symbol: string
|
|
letter: string
|
|
color: string
|
|
logo?: string
|
|
network: string
|
|
balance: number
|
|
usdRate: number
|
|
decimals: number
|
|
}
|
|
|
|
const TOKENS: Record<string, Token> = {
|
|
BTC: { symbol: 'BTC', letter: '₿', logo: btc, color: '#F7931A', network: 'BITCOIN', balance: 0, usdRate: 67412, decimals: 8 },
|
|
ETH: { symbol: 'ETH', letter: 'E', logo: eth, color: '#627EEA', network: 'ETHEREUM', balance: 0, usdRate: 3521, decimals: 18 },
|
|
SOL: { symbol: 'SOL', letter: 'S', logo: sol, color: '#9945FF', network: 'SOLANA', balance: 0.994, usdRate: 163.84, decimals: 9 },
|
|
TRX: { symbol: 'TRX', letter: 'T', logo: trx, color: '#FF060A', network: 'TRON', balance: 0, usdRate: 0.12, decimals: 6 },
|
|
ARB: { symbol: 'ARB', letter: 'A', logo: arb, color: '#4A6DFF', network: 'ARBITRUM', balance: 0, usdRate: 0.92, decimals: 18 },
|
|
USDC: { symbol: 'USDC', letter: '$', color: '#2775CA', network: 'SOLANA', balance: 0, usdRate: 1, decimals: 6 },
|
|
USDT: { symbol: 'USDT', letter: '$', color: '#26A17B', network: 'ETHEREUM', balance: 0, usdRate: 1, decimals: 6 },
|
|
}
|
|
|
|
export const TOKENS_LIST: Token[] = Object.values(TOKENS)
|
|
|
|
export const TOKEN_META: Record<string, { letter: string; color: string; logo?: string }> = {
|
|
// Native / major
|
|
BTC: { letter: '₿', logo: btc, color: '#F7931A' },
|
|
ETH: { letter: 'E', logo: eth, color: '#627EEA' },
|
|
BSC: { letter: 'B', color: '#F3BA2F' },
|
|
SOL: { letter: 'S', logo: sol, color: '#9945FF' },
|
|
TRX: { letter: 'T', logo: trx, color: '#FF060A' },
|
|
ARB: { letter: 'A', logo: arb, color: '#4A6DFF' },
|
|
// Stablecoins
|
|
USDC: { letter: '$', color: '#2775CA' },
|
|
USDT: { letter: '$', color: '#26A17B' },
|
|
DAI: { letter: 'D', color: '#F5AC37' },
|
|
BUSD: { letter: 'B', color: '#F0B90B' },
|
|
// ETH tokens
|
|
WBTC: { letter: 'W', color: '#F7931A' },
|
|
LINK: { letter: 'L', color: '#2A5ADA' },
|
|
UNI: { letter: 'U', color: '#FF007A' },
|
|
// BSC tokens
|
|
WBNB: { letter: 'W', color: '#F3BA2F' },
|
|
DOGE: { letter: 'D', color: '#C2A633' },
|
|
// SOL tokens
|
|
JUP: { letter: 'J', color: '#C7A52D' },
|
|
WIF: { letter: 'W', color: '#9333EA' },
|
|
BONK: { letter: 'B', color: '#FF8C00' },
|
|
RAY: { letter: 'R', color: '#5AC4BE' },
|
|
ORCA: { letter: 'O', color: '#1B8EF2' },
|
|
PYTH: { letter: 'P', color: '#8B5CF6' },
|
|
JTO: { letter: 'J', color: '#06B6D4' },
|
|
W: { letter: 'W', color: '#6B7280' },
|
|
PUMP: { letter: 'P', color: '#00D4AA' },
|
|
POPCAT: { letter: 'P', color: '#FF6B6B' },
|
|
TRUMP: { letter: 'T', color: '#E63946' },
|
|
PENGU: { letter: 'P', color: '#60A5FA' },
|
|
}
|
|
|
|
const CHAIN_NATIVE: Record<string, string> = {
|
|
ETH: 'ETH', BSC: 'BSC', BTC: 'BTC', TRX: 'TRX', SOL: 'SOL',
|
|
}
|
|
|
|
export function buildTokensFromBalance(data: WalletBalanceData): Token[] {
|
|
const result: Token[] = []
|
|
|
|
const nativeSym = CHAIN_NATIVE[data.chain] ?? data.chain
|
|
const nativeMeta = TOKEN_META[nativeSym]
|
|
result.push({
|
|
symbol: nativeSym,
|
|
letter: nativeMeta?.letter ?? nativeSym[0],
|
|
color: nativeMeta?.color ?? '#888',
|
|
logo: nativeMeta?.logo,
|
|
network: data.chain,
|
|
balance: parseFloat(data.native.formatted),
|
|
usdRate: data.native.usdPrice,
|
|
decimals: data.native.decimals,
|
|
})
|
|
|
|
for (const [sym, info] of Object.entries(data.tokens)) {
|
|
const meta = TOKEN_META[sym]
|
|
result.push({
|
|
symbol: sym,
|
|
letter: meta?.letter ?? sym[0],
|
|
color: meta?.color ?? '#888',
|
|
logo: meta?.logo,
|
|
network: data.chain,
|
|
balance: parseFloat(info.formatted),
|
|
usdRate: info.usdPrice,
|
|
decimals: info.decimals,
|
|
})
|
|
}
|
|
|
|
return result
|
|
}
|
|
|
|
const RATE = 82.2578
|
|
|
|
export function useSwapForm() {
|
|
const [fromAmount, setFromAmountRaw] = useState('0.25')
|
|
const [fromToken, setFromToken] = useState<Token>(TOKENS.SOL)
|
|
const [toToken, setToToken] = useState<Token>(TOKENS.USDC)
|
|
const [isRefreshing, setIsRefreshing] = useState(false)
|
|
|
|
const fromValue = parseFloat(fromAmount) || 0
|
|
const toAmount = (fromValue * RATE).toFixed(4)
|
|
const fromUsd = (fromValue * fromToken.usdRate).toFixed(2)
|
|
const toUsd = (fromValue * RATE * toToken.usdRate).toFixed(2)
|
|
|
|
function setFromAmount(v: string) {
|
|
setFromAmountRaw(v)
|
|
}
|
|
|
|
function setPercent(p: number) {
|
|
setFromAmountRaw((fromToken.balance * p / 100).toFixed(4))
|
|
}
|
|
|
|
function swapTokens() {
|
|
setFromToken(toToken)
|
|
setToToken(fromToken)
|
|
}
|
|
|
|
function refreshRate() {
|
|
setIsRefreshing(true)
|
|
setTimeout(() => setIsRefreshing(false), 400)
|
|
}
|
|
|
|
return {
|
|
fromAmount, toAmount, fromUsd, toUsd,
|
|
fromToken, toToken,
|
|
isRefreshing,
|
|
setFromAmount, setPercent, swapTokens, refreshRate,
|
|
setFromToken, setToToken,
|
|
}
|
|
}
|