create-awarizon-app 1.0.11 → 1.0.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,12 +1,17 @@
1
1
  'use client'
2
2
 
3
- import { useWallet, useNativeBalance, usePrices, ConnectButton } from '@awarizon/react'
3
+ import { useWallet, useNativeBalance, usePrices, ConnectButton, TokenIcon, ChainIcon, getChainNativeSymbol, getChainName } from '@awarizon/react'
4
4
  import { Badge } from '@/components/ui/Badge'
5
5
  import { Card } from '@/components/ui/Card'
6
6
  import { Skeleton } from '@/components/ui/Skeleton'
7
- import { StatCard } from '@/components/ui/StatCard'
8
7
 
9
- const SYMBOLS = ['ETH', 'BTC', 'USDC']
8
+ const ASSETS = [
9
+ { symbol: 'ETH', name: 'Ethereum' },
10
+ { symbol: 'BTC', name: 'Bitcoin' },
11
+ { symbol: 'USDC', name: 'USD Coin' },
12
+ { symbol: 'BNB', name: 'BNB' },
13
+ { symbol: 'HYPE', name: 'Hyperliquid' },
14
+ ]
10
15
 
11
16
  function DataRow({ label, value, loading }: { label: string; value?: string; loading: boolean }) {
12
17
  return (
@@ -21,16 +26,12 @@ function DataRow({ label, value, loading }: { label: string; value?: string; loa
21
26
 
22
27
  export default function WalletPage() {
23
28
  const { address, isConnected, isChainMismatch, chainId, connectorInfo } = useWallet()
29
+ const nativeSymbol = chainId != null ? getChainNativeSymbol(chainId) : 'ETH'
24
30
  const { formatted: nativeBalance, isLoading: balanceLoading } = useNativeBalance(
25
31
  address ?? undefined,
26
32
  12_000,
27
33
  )
28
- const { prices, isLoading: pricesLoading } = usePrices(SYMBOLS)
29
-
30
- const fmtPrice = (sym: string) =>
31
- prices[sym]?.price != null
32
- ? `$${prices[sym].price.toLocaleString(undefined, { maximumFractionDigits: 2 })}`
33
- : undefined
34
+ const { prices, isLoading: pricesLoading } = usePrices(ASSETS.map(a => a.symbol))
34
35
 
35
36
  const ethFiatValue =
36
37
  nativeBalance != null && prices['ETH']?.price != null
@@ -76,39 +77,67 @@ export default function WalletPage() {
76
77
  <Card className="mb-4">
77
78
  <p className="font-mono text-[9px] tracking-widest text-zinc-600 uppercase mb-4">Account</p>
78
79
  <DataRow label="Address" value={address ?? undefined} loading={false} />
79
- <DataRow label="Chain ID" value={chainId != null ? String(chainId) : undefined} loading={false} />
80
+ <DataRow label="Chain" value={chainId != null ? getChainName(chainId) : undefined} loading={false} />
80
81
  <DataRow label="Connector" value={connectorInfo?.name ?? connectorInfo?.type} loading={false} />
81
82
  </Card>
82
83
 
83
84
  {/* ── Balance ──────────────────────────────────── */}
84
- <div className="grid sm:grid-cols-3 gap-4 mb-4">
85
- <StatCard
86
- label="Native Balance"
87
- value={nativeBalance != null ? `${parseFloat(nativeBalance).toFixed(6)} ETH` : undefined}
88
- loading={balanceLoading}
89
- sub="useNativeBalance · 12 s poll"
90
- className="sm:col-span-2"
91
- />
92
- <StatCard
93
- label="Est. Value"
94
- value={ethFiatValue}
95
- loading={balanceLoading || pricesLoading}
96
- sub="ETH × market price"
97
- />
98
- </div>
85
+ <Card className="mb-4">
86
+ <p className="font-mono text-[9px] tracking-widest text-zinc-600 uppercase mb-3">Balance</p>
87
+ <div className="flex items-center gap-3 py-2">
88
+ {chainId != null
89
+ ? <ChainIcon chainId={chainId} size={36} radiusFraction={0.5} />
90
+ : <TokenIcon symbol={nativeSymbol} size={36} radiusFraction={0.5} />
91
+ }
92
+ <div className="flex-1 min-w-0">
93
+ <p className="text-sm font-medium text-white">{nativeSymbol}</p>
94
+ <p className="text-xs text-zinc-500">{chainId != null ? getChainName(chainId) : 'Native'}</p>
95
+ </div>
96
+ <div className="text-right">
97
+ {balanceLoading
98
+ ? <Skeleton className="h-4 w-28" />
99
+ : <>
100
+ <p className="text-sm font-medium text-white">
101
+ {nativeBalance != null ? `${parseFloat(nativeBalance).toFixed(6)} ${nativeSymbol}` : '—'}
102
+ </p>
103
+ {ethFiatValue && (
104
+ <p className="text-xs text-zinc-500">{ethFiatValue}</p>
105
+ )}
106
+ </>
107
+ }
108
+ </div>
109
+ </div>
110
+ </Card>
99
111
 
100
- {/* ── Prices ───────────────────────────────────── */}
101
- <div className="grid sm:grid-cols-3 gap-4">
102
- {SYMBOLS.map(sym => (
103
- <StatCard
104
- key={sym}
105
- label={sym}
106
- value={fmtPrice(sym)}
107
- loading={pricesLoading}
108
- sub="USD · usePrices"
109
- />
110
- ))}
111
- </div>
112
+ {/* ── Assets ───────────────────────────────────── */}
113
+ <Card>
114
+ <p className="font-mono text-[9px] tracking-widest text-zinc-600 uppercase mb-3">Assets</p>
115
+ <div className="divide-y divide-zinc-800/50">
116
+ {ASSETS.map(({ symbol, name }) => {
117
+ const price = prices[symbol]?.price
118
+ return (
119
+ <div key={symbol} className="flex items-center gap-3 py-3 first:pt-0 last:pb-0">
120
+ <TokenIcon symbol={symbol} size={36} radiusFraction={0.28} />
121
+ <div className="flex-1 min-w-0">
122
+ <p className="text-sm font-medium text-white">{symbol}</p>
123
+ <p className="text-xs text-zinc-500">{name}</p>
124
+ </div>
125
+ <div className="text-right">
126
+ {pricesLoading
127
+ ? <Skeleton className="h-4 w-20" />
128
+ : <p className="text-sm font-medium text-white">
129
+ {price != null
130
+ ? `$${price.toLocaleString(undefined, { maximumFractionDigits: 2 })}`
131
+ : '—'}
132
+ </p>
133
+ }
134
+ <p className="text-xs text-zinc-600">USD · usePrices</p>
135
+ </div>
136
+ </div>
137
+ )
138
+ })}
139
+ </div>
140
+ </Card>
112
141
  </>
113
142
  )}
114
143
  </main>
@@ -2,7 +2,7 @@
2
2
 
3
3
  import Link from 'next/link'
4
4
  import { usePathname } from 'next/navigation'
5
- import { ConnectButton } from '@awarizon/react'
5
+ import { ConnectButton, ChainIcon, useWallet, getChainName } from '@awarizon/react'
6
6
 
7
7
  const NAV = [
8
8
  { href: '/', label: 'Markets' },
@@ -12,6 +12,10 @@ const NAV = [
12
12
 
13
13
  export function Header() {
14
14
  const pathname = usePathname()
15
+ const { chainId } = useWallet()
16
+ const displayChainId = chainId ?? 8453
17
+ const chainName = getChainName(displayChainId)
18
+
15
19
  return (
16
20
  <header className="sticky top-0 z-50 border-b border-white/[0.06] bg-zinc-950/70 backdrop-blur-2xl">
17
21
  <div className="max-w-5xl mx-auto px-6 h-16 flex items-center justify-between gap-8">
@@ -44,8 +48,8 @@ export function Header() {
44
48
 
45
49
  <div className="flex items-center gap-3 shrink-0">
46
50
  <div className="hidden sm:flex items-center gap-1.5 px-3 py-1.5 rounded-full border border-zinc-800 bg-zinc-900/60 text-xs text-zinc-400 font-medium">
47
- <span className="w-1.5 h-1.5 rounded-full bg-green-400 inline-block" />
48
- Base
51
+ <ChainIcon chainId={displayChainId} size={16} radiusFraction={0.5} />
52
+ {chainName}
49
53
  </div>
50
54
  {process.env.NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID && <ConnectButton />}
51
55
  </div>
@@ -9,8 +9,8 @@
9
9
  "lint": "next lint"
10
10
  },
11
11
  "dependencies": {
12
- "@awarizon/react": "^1.6.2",
13
- "@awarizon/web3": "^1.3.5",
12
+ "@awarizon/react": "^1.6.4",
13
+ "@awarizon/web3": "^1.3.7",
14
14
  "next": "14.2.5",
15
15
  "react": "^18",
16
16
  "react-dom": "^18"
@@ -1,14 +1,14 @@
1
1
  'use client'
2
2
 
3
- import { usePrices } from '@awarizon/react'
3
+ import { usePrices, TokenIcon } from '@awarizon/react'
4
4
  import { Skeleton } from '@/components/ui/Skeleton'
5
5
 
6
6
  const TOKENS = [
7
- { symbol: 'ETH', name: 'Ethereum', color: '#627EEA' },
8
- { symbol: 'BTC', name: 'Bitcoin', color: '#F7931A' },
9
- { symbol: 'USDC', name: 'USD Coin', color: '#2775CA' },
10
- { symbol: 'BNB', name: 'BNB', color: '#F3BA2F' },
11
- { symbol: 'SOL', name: 'Solana', color: '#9945FF' },
7
+ { symbol: 'ETH', name: 'Ethereum' },
8
+ { symbol: 'BTC', name: 'Bitcoin' },
9
+ { symbol: 'USDC', name: 'USD Coin' },
10
+ { symbol: 'BNB', name: 'BNB' },
11
+ { symbol: 'HYPE', name: 'Hyperliquid' },
12
12
  ]
13
13
 
14
14
  export default function Home() {
@@ -17,7 +17,7 @@ export default function Home() {
17
17
  return (
18
18
  <main className="max-w-5xl mx-auto px-6 py-10">
19
19
  <div className="grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-5 gap-4">
20
- {TOKENS.map(({ symbol, name, color }) => {
20
+ {TOKENS.map(({ symbol, name }) => {
21
21
  const price = prices[symbol]?.price
22
22
  return (
23
23
  <div
@@ -25,11 +25,8 @@ export default function Home() {
25
25
  className="bg-zinc-900/40 border border-zinc-800/40 rounded-2xl p-5 hover:bg-zinc-900/60 hover:border-zinc-700/50 transition-all cursor-default"
26
26
  >
27
27
  <div className="mb-4">
28
- <div
29
- className="w-10 h-10 rounded-full flex items-center justify-center text-[10px] font-bold tracking-wider mb-3"
30
- style={{ backgroundColor: `${color}18`, border: `1px solid ${color}25`, color }}
31
- >
32
- {symbol.slice(0, 3)}
28
+ <div className="mb-3">
29
+ <TokenIcon symbol={symbol} size={40} radiusFraction={0.28} />
33
30
  </div>
34
31
  <p className="text-[11px] text-zinc-500 font-medium mb-0.5">{symbol}</p>
35
32
  <p className="text-xs text-zinc-600">{name}</p>
@@ -1,12 +1,17 @@
1
1
  'use client'
2
2
 
3
- import { useWallet, useNativeBalance, usePrices, ConnectButton } from '@awarizon/react'
3
+ import { useWallet, useNativeBalance, usePrices, ConnectButton, TokenIcon, ChainIcon, getChainNativeSymbol, getChainName } from '@awarizon/react'
4
4
  import { Badge } from '@/components/ui/Badge'
5
5
  import { Card } from '@/components/ui/Card'
6
6
  import { Skeleton } from '@/components/ui/Skeleton'
7
- import { StatCard } from '@/components/ui/StatCard'
8
7
 
9
- const SYMBOLS = ['ETH', 'BTC', 'USDC']
8
+ const ASSETS = [
9
+ { symbol: 'ETH', name: 'Ethereum' },
10
+ { symbol: 'BTC', name: 'Bitcoin' },
11
+ { symbol: 'USDC', name: 'USD Coin' },
12
+ { symbol: 'BNB', name: 'BNB' },
13
+ { symbol: 'HYPE', name: 'Hyperliquid' },
14
+ ]
10
15
 
11
16
  function DataRow({ label, value, loading }) {
12
17
  return (
@@ -21,16 +26,12 @@ function DataRow({ label, value, loading }) {
21
26
 
22
27
  export default function WalletPage() {
23
28
  const { address, isConnected, isChainMismatch, chainId, connectorInfo } = useWallet()
29
+ const nativeSymbol = chainId != null ? getChainNativeSymbol(chainId) : 'ETH'
24
30
  const { formatted: nativeBalance, isLoading: balanceLoading } = useNativeBalance(
25
31
  address ?? undefined,
26
32
  12_000,
27
33
  )
28
- const { prices, isLoading: pricesLoading } = usePrices(SYMBOLS)
29
-
30
- const fmtPrice = (sym) =>
31
- prices[sym]?.price != null
32
- ? `$${prices[sym].price.toLocaleString(undefined, { maximumFractionDigits: 2 })}`
33
- : undefined
34
+ const { prices, isLoading: pricesLoading } = usePrices(ASSETS.map(a => a.symbol))
34
35
 
35
36
  const ethFiatValue =
36
37
  nativeBalance != null && prices['ETH']?.price != null
@@ -76,39 +77,67 @@ export default function WalletPage() {
76
77
  <Card className="mb-4">
77
78
  <p className="font-mono text-[9px] tracking-widest text-zinc-600 uppercase mb-4">Account</p>
78
79
  <DataRow label="Address" value={address ?? undefined} loading={false} />
79
- <DataRow label="Chain ID" value={chainId != null ? String(chainId) : undefined} loading={false} />
80
+ <DataRow label="Chain" value={chainId != null ? getChainName(chainId) : undefined} loading={false} />
80
81
  <DataRow label="Connector" value={connectorInfo?.name ?? connectorInfo?.type} loading={false} />
81
82
  </Card>
82
83
 
83
84
  {/* ── Balance ──────────────────────────────────── */}
84
- <div className="grid sm:grid-cols-3 gap-4 mb-4">
85
- <StatCard
86
- label="Native Balance"
87
- value={nativeBalance != null ? `${parseFloat(nativeBalance).toFixed(6)} ETH` : undefined}
88
- loading={balanceLoading}
89
- sub="useNativeBalance · 12 s poll"
90
- className="sm:col-span-2"
91
- />
92
- <StatCard
93
- label="Est. Value"
94
- value={ethFiatValue}
95
- loading={balanceLoading || pricesLoading}
96
- sub="ETH × market price"
97
- />
98
- </div>
85
+ <Card className="mb-4">
86
+ <p className="font-mono text-[9px] tracking-widest text-zinc-600 uppercase mb-3">Balance</p>
87
+ <div className="flex items-center gap-3 py-2">
88
+ {chainId != null
89
+ ? <ChainIcon chainId={chainId} size={36} radiusFraction={0.5} />
90
+ : <TokenIcon symbol={nativeSymbol} size={36} radiusFraction={0.5} />
91
+ }
92
+ <div className="flex-1 min-w-0">
93
+ <p className="text-sm font-medium text-white">{nativeSymbol}</p>
94
+ <p className="text-xs text-zinc-500">{chainId != null ? getChainName(chainId) : 'Native'}</p>
95
+ </div>
96
+ <div className="text-right">
97
+ {balanceLoading
98
+ ? <Skeleton className="h-4 w-28" />
99
+ : <>
100
+ <p className="text-sm font-medium text-white">
101
+ {nativeBalance != null ? `${parseFloat(nativeBalance).toFixed(6)} ${nativeSymbol}` : '—'}
102
+ </p>
103
+ {ethFiatValue && (
104
+ <p className="text-xs text-zinc-500">{ethFiatValue}</p>
105
+ )}
106
+ </>
107
+ }
108
+ </div>
109
+ </div>
110
+ </Card>
99
111
 
100
- {/* ── Prices ───────────────────────────────────── */}
101
- <div className="grid sm:grid-cols-3 gap-4">
102
- {SYMBOLS.map(sym => (
103
- <StatCard
104
- key={sym}
105
- label={sym}
106
- value={fmtPrice(sym)}
107
- loading={pricesLoading}
108
- sub="USD · usePrices"
109
- />
110
- ))}
111
- </div>
112
+ {/* ── Assets ───────────────────────────────────── */}
113
+ <Card>
114
+ <p className="font-mono text-[9px] tracking-widest text-zinc-600 uppercase mb-3">Assets</p>
115
+ <div className="divide-y divide-zinc-800/50">
116
+ {ASSETS.map(({ symbol, name }) => {
117
+ const price = prices[symbol]?.price
118
+ return (
119
+ <div key={symbol} className="flex items-center gap-3 py-3 first:pt-0 last:pb-0">
120
+ <TokenIcon symbol={symbol} size={36} radiusFraction={0.28} />
121
+ <div className="flex-1 min-w-0">
122
+ <p className="text-sm font-medium text-white">{symbol}</p>
123
+ <p className="text-xs text-zinc-500">{name}</p>
124
+ </div>
125
+ <div className="text-right">
126
+ {pricesLoading
127
+ ? <Skeleton className="h-4 w-20" />
128
+ : <p className="text-sm font-medium text-white">
129
+ {price != null
130
+ ? `$${price.toLocaleString(undefined, { maximumFractionDigits: 2 })}`
131
+ : '—'}
132
+ </p>
133
+ }
134
+ <p className="text-xs text-zinc-600">USD · usePrices</p>
135
+ </div>
136
+ </div>
137
+ )
138
+ })}
139
+ </div>
140
+ </Card>
112
141
  </>
113
142
  )}
114
143
  </main>
@@ -2,7 +2,7 @@
2
2
 
3
3
  import Link from 'next/link'
4
4
  import { usePathname } from 'next/navigation'
5
- import { ConnectButton } from '@awarizon/react'
5
+ import { ConnectButton, ChainIcon, useWallet, getChainName } from '@awarizon/react'
6
6
 
7
7
  const NAV = [
8
8
  { href: '/', label: 'Markets' },
@@ -12,6 +12,10 @@ const NAV = [
12
12
 
13
13
  export function Header() {
14
14
  const pathname = usePathname()
15
+ const { chainId } = useWallet()
16
+ const displayChainId = chainId ?? 8453
17
+ const chainName = getChainName(displayChainId)
18
+
15
19
  return (
16
20
  <header className="sticky top-0 z-50 border-b border-white/[0.06] bg-zinc-950/70 backdrop-blur-2xl">
17
21
  <div className="max-w-5xl mx-auto px-6 h-16 flex items-center justify-between gap-8">
@@ -44,8 +48,8 @@ export function Header() {
44
48
 
45
49
  <div className="flex items-center gap-3 shrink-0">
46
50
  <div className="hidden sm:flex items-center gap-1.5 px-3 py-1.5 rounded-full border border-zinc-800 bg-zinc-900/60 text-xs text-zinc-400 font-medium">
47
- <span className="w-1.5 h-1.5 rounded-full bg-green-400 inline-block" />
48
- Base
51
+ <ChainIcon chainId={displayChainId} size={16} radiusFraction={0.5} />
52
+ {chainName}
49
53
  </div>
50
54
  {process.env.NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID && <ConnectButton />}
51
55
  </div>
@@ -9,8 +9,8 @@
9
9
  "lint": "next lint"
10
10
  },
11
11
  "dependencies": {
12
- "@awarizon/react": "^1.6.2",
13
- "@awarizon/web3": "^1.3.5",
12
+ "@awarizon/react": "^1.6.4",
13
+ "@awarizon/web3": "^1.3.7",
14
14
  "next": "14.2.5",
15
15
  "react": "^18",
16
16
  "react-dom": "^18"
@@ -10,8 +10,8 @@
10
10
  "lint": "eslint ."
11
11
  },
12
12
  "dependencies": {
13
- "@awarizon/react": "^1.6.2",
14
- "@awarizon/web3": "^1.3.5",
13
+ "@awarizon/react": "^1.6.4",
14
+ "@awarizon/web3": "^1.3.7",
15
15
  "react": "^18.3.1",
16
16
  "react-dom": "^18.3.1"
17
17
  },
@@ -1,5 +1,5 @@
1
1
  import { useState } from 'react'
2
- import { usePrices, ConnectButton } from '@awarizon/react'
2
+ import { usePrices, ConnectButton, TokenIcon, ChainIcon, useWallet, getChainName } from '@awarizon/react'
3
3
  import { Skeleton } from './components/ui/Skeleton'
4
4
  import { NftPage } from './pages/NftPage'
5
5
  import { WalletPage } from './pages/WalletPage'
@@ -13,11 +13,11 @@ const NAV: { id: Page; label: string }[] = [
13
13
  ]
14
14
 
15
15
  const TOKENS = [
16
- { symbol: 'ETH', name: 'Ethereum', color: '#627EEA' },
17
- { symbol: 'BTC', name: 'Bitcoin', color: '#F7931A' },
18
- { symbol: 'USDC', name: 'USD Coin', color: '#2775CA' },
19
- { symbol: 'BNB', name: 'BNB', color: '#F3BA2F' },
20
- { symbol: 'SOL', name: 'Solana', color: '#9945FF' },
16
+ { symbol: 'ETH', name: 'Ethereum' },
17
+ { symbol: 'BTC', name: 'Bitcoin' },
18
+ { symbol: 'USDC', name: 'USD Coin' },
19
+ { symbol: 'BNB', name: 'BNB' },
20
+ { symbol: 'HYPE', name: 'Hyperliquid' },
21
21
  ]
22
22
 
23
23
  function HomePage() {
@@ -26,7 +26,7 @@ function HomePage() {
26
26
  return (
27
27
  <main className="max-w-5xl mx-auto px-6 py-10">
28
28
  <div className="grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-5 gap-4">
29
- {TOKENS.map(({ symbol, name, color }) => {
29
+ {TOKENS.map(({ symbol, name }) => {
30
30
  const price = prices[symbol]?.price
31
31
  return (
32
32
  <div
@@ -34,11 +34,8 @@ function HomePage() {
34
34
  className="bg-zinc-900/40 border border-zinc-800/40 rounded-2xl p-5 hover:bg-zinc-900/60 hover:border-zinc-700/50 transition-all cursor-default"
35
35
  >
36
36
  <div className="mb-4">
37
- <div
38
- className="w-10 h-10 rounded-full flex items-center justify-center text-[10px] font-bold tracking-wider mb-3"
39
- style={{ backgroundColor: `${color}18`, border: `1px solid ${color}25`, color }}
40
- >
41
- {symbol.slice(0, 3)}
37
+ <div className="mb-3">
38
+ <TokenIcon symbol={symbol} size={40} radiusFraction={0.28} />
42
39
  </div>
43
40
  <p className="text-[11px] text-zinc-500 font-medium mb-0.5">{symbol}</p>
44
41
  <p className="text-xs text-zinc-600">{name}</p>
@@ -60,6 +57,9 @@ function HomePage() {
60
57
 
61
58
  export default function App() {
62
59
  const [page, setPage] = useState<Page>('home')
60
+ const { chainId } = useWallet()
61
+ const displayChainId = chainId ?? 8453
62
+ const chainName = getChainName(displayChainId)
63
63
 
64
64
  return (
65
65
  <div className="min-h-screen">
@@ -92,8 +92,8 @@ export default function App() {
92
92
 
93
93
  <div className="flex items-center gap-3 shrink-0">
94
94
  <div className="hidden sm:flex items-center gap-1.5 px-3 py-1.5 rounded-full border border-zinc-800 bg-zinc-900/60 text-xs text-zinc-400 font-medium">
95
- <span className="w-1.5 h-1.5 rounded-full bg-green-400 inline-block" />
96
- Base
95
+ <ChainIcon chainId={displayChainId} size={16} radiusFraction={0.5} />
96
+ {chainName}
97
97
  </div>
98
98
  {import.meta.env.VITE_WALLETCONNECT_PROJECT_ID && <ConnectButton />}
99
99
  </div>
@@ -1,10 +1,15 @@
1
- import { useWallet, useNativeBalance, usePrices, ConnectButton } from '@awarizon/react'
1
+ import { useWallet, useNativeBalance, usePrices, ConnectButton, TokenIcon, ChainIcon, getChainNativeSymbol, getChainName } from '@awarizon/react'
2
2
  import { Badge } from '../components/ui/Badge'
3
3
  import { Card } from '../components/ui/Card'
4
4
  import { Skeleton } from '../components/ui/Skeleton'
5
- import { StatCard } from '../components/ui/StatCard'
6
5
 
7
- const SYMBOLS = ['ETH', 'BTC', 'USDC']
6
+ const ASSETS = [
7
+ { symbol: 'ETH', name: 'Ethereum' },
8
+ { symbol: 'BTC', name: 'Bitcoin' },
9
+ { symbol: 'USDC', name: 'USD Coin' },
10
+ { symbol: 'BNB', name: 'BNB' },
11
+ { symbol: 'HYPE', name: 'Hyperliquid' },
12
+ ]
8
13
 
9
14
  function DataRow({ label, value, loading }: { label: string; value?: string; loading: boolean }) {
10
15
  return (
@@ -19,16 +24,12 @@ function DataRow({ label, value, loading }: { label: string; value?: string; loa
19
24
 
20
25
  export function WalletPage() {
21
26
  const { address, isConnected, isChainMismatch, chainId, connectorInfo } = useWallet()
27
+ const nativeSymbol = chainId != null ? getChainNativeSymbol(chainId) : 'ETH'
22
28
  const { formatted: nativeBalance, isLoading: balanceLoading } = useNativeBalance(
23
29
  address ?? undefined,
24
30
  12_000,
25
31
  )
26
- const { prices, isLoading: pricesLoading } = usePrices(SYMBOLS)
27
-
28
- const fmtPrice = (sym: string) =>
29
- prices[sym]?.price != null
30
- ? `$${prices[sym].price.toLocaleString(undefined, { maximumFractionDigits: 2 })}`
31
- : undefined
32
+ const { prices, isLoading: pricesLoading } = usePrices(ASSETS.map(a => a.symbol))
32
33
 
33
34
  const ethFiatValue =
34
35
  nativeBalance != null && prices['ETH']?.price != null
@@ -74,39 +75,67 @@ export function WalletPage() {
74
75
  <Card className="mb-4">
75
76
  <p className="font-mono text-[9px] tracking-widest text-zinc-600 uppercase mb-4">Account</p>
76
77
  <DataRow label="Address" value={address ?? undefined} loading={false} />
77
- <DataRow label="Chain ID" value={chainId != null ? String(chainId) : undefined} loading={false} />
78
+ <DataRow label="Chain" value={chainId != null ? getChainName(chainId) : undefined} loading={false} />
78
79
  <DataRow label="Connector" value={connectorInfo?.name ?? connectorInfo?.type} loading={false} />
79
80
  </Card>
80
81
 
81
82
  {/* ── Balance ──────────────────────────────────── */}
82
- <div className="grid sm:grid-cols-3 gap-4 mb-4">
83
- <StatCard
84
- label="Native Balance"
85
- value={nativeBalance != null ? `${parseFloat(nativeBalance).toFixed(6)} ETH` : undefined}
86
- loading={balanceLoading}
87
- sub="useNativeBalance · 12 s poll"
88
- className="sm:col-span-2"
89
- />
90
- <StatCard
91
- label="Est. Value"
92
- value={ethFiatValue}
93
- loading={balanceLoading || pricesLoading}
94
- sub="ETH × market price"
95
- />
96
- </div>
83
+ <Card className="mb-4">
84
+ <p className="font-mono text-[9px] tracking-widest text-zinc-600 uppercase mb-3">Balance</p>
85
+ <div className="flex items-center gap-3 py-2">
86
+ {chainId != null
87
+ ? <ChainIcon chainId={chainId} size={36} radiusFraction={0.5} />
88
+ : <TokenIcon symbol={nativeSymbol} size={36} radiusFraction={0.5} />
89
+ }
90
+ <div className="flex-1 min-w-0">
91
+ <p className="text-sm font-medium text-white">{nativeSymbol}</p>
92
+ <p className="text-xs text-zinc-500">{chainId != null ? getChainName(chainId) : 'Native'}</p>
93
+ </div>
94
+ <div className="text-right">
95
+ {balanceLoading
96
+ ? <Skeleton className="h-4 w-28" />
97
+ : <>
98
+ <p className="text-sm font-medium text-white">
99
+ {nativeBalance != null ? `${parseFloat(nativeBalance).toFixed(6)} ${nativeSymbol}` : '—'}
100
+ </p>
101
+ {ethFiatValue && (
102
+ <p className="text-xs text-zinc-500">{ethFiatValue}</p>
103
+ )}
104
+ </>
105
+ }
106
+ </div>
107
+ </div>
108
+ </Card>
97
109
 
98
- {/* ── Prices ───────────────────────────────────── */}
99
- <div className="grid sm:grid-cols-3 gap-4">
100
- {SYMBOLS.map(sym => (
101
- <StatCard
102
- key={sym}
103
- label={sym}
104
- value={fmtPrice(sym)}
105
- loading={pricesLoading}
106
- sub="USD · usePrices"
107
- />
108
- ))}
109
- </div>
110
+ {/* ── Assets ───────────────────────────────────── */}
111
+ <Card>
112
+ <p className="font-mono text-[9px] tracking-widest text-zinc-600 uppercase mb-3">Assets</p>
113
+ <div className="divide-y divide-zinc-800/50">
114
+ {ASSETS.map(({ symbol, name }) => {
115
+ const price = prices[symbol]?.price
116
+ return (
117
+ <div key={symbol} className="flex items-center gap-3 py-3 first:pt-0 last:pb-0">
118
+ <TokenIcon symbol={symbol} size={36} radiusFraction={0.28} />
119
+ <div className="flex-1 min-w-0">
120
+ <p className="text-sm font-medium text-white">{symbol}</p>
121
+ <p className="text-xs text-zinc-500">{name}</p>
122
+ </div>
123
+ <div className="text-right">
124
+ {pricesLoading
125
+ ? <Skeleton className="h-4 w-20" />
126
+ : <p className="text-sm font-medium text-white">
127
+ {price != null
128
+ ? `$${price.toLocaleString(undefined, { maximumFractionDigits: 2 })}`
129
+ : '—'}
130
+ </p>
131
+ }
132
+ <p className="text-xs text-zinc-600">USD · usePrices</p>
133
+ </div>
134
+ </div>
135
+ )
136
+ })}
137
+ </div>
138
+ </Card>
110
139
  </>
111
140
  )}
112
141
  </main>
@@ -10,8 +10,8 @@
10
10
  "lint": "eslint ."
11
11
  },
12
12
  "dependencies": {
13
- "@awarizon/react": "^1.6.2",
14
- "@awarizon/web3": "^1.3.5",
13
+ "@awarizon/react": "^1.6.4",
14
+ "@awarizon/web3": "^1.3.7",
15
15
  "react": "^18.3.1",
16
16
  "react-dom": "^18.3.1"
17
17
  },