create-awarizon-app 1.0.9 → 1.0.11

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.
Files changed (33) hide show
  1. package/dist/index.js +0 -0
  2. package/package.json +8 -8
  3. package/templates/expo/app/(tabs)/_layout.tsx +4 -3
  4. package/templates/expo/app/(tabs)/index.tsx +40 -64
  5. package/templates/expo/app/(tabs)/nft.tsx +142 -0
  6. package/templates/expo/app/(tabs)/wallet.tsx +127 -0
  7. package/templates/expo/babel.config.js +6 -0
  8. package/templates/expo/package.json +22 -23
  9. package/templates/expo-js/app/(tabs)/_layout.jsx +4 -3
  10. package/templates/expo-js/app/(tabs)/index.jsx +40 -66
  11. package/templates/expo-js/app/(tabs)/nft.jsx +141 -0
  12. package/templates/expo-js/app/(tabs)/wallet.jsx +128 -0
  13. package/templates/expo-js/package.json +19 -20
  14. package/templates/nextjs/app/layout.tsx +5 -1
  15. package/templates/nextjs/app/nft/page.tsx +140 -0
  16. package/templates/nextjs/app/page.tsx +37 -155
  17. package/templates/nextjs/app/wallet/page.tsx +116 -0
  18. package/templates/nextjs/components/Header.tsx +56 -0
  19. package/templates/nextjs/package.json +15 -16
  20. package/templates/nextjs-js/app/layout.jsx +5 -1
  21. package/templates/nextjs-js/app/nft/page.jsx +139 -0
  22. package/templates/nextjs-js/app/page.jsx +37 -128
  23. package/templates/nextjs-js/app/wallet/page.jsx +116 -0
  24. package/templates/nextjs-js/components/Header.jsx +56 -0
  25. package/templates/nextjs-js/package.json +11 -12
  26. package/templates/react/package.json +14 -15
  27. package/templates/react/src/App.tsx +88 -145
  28. package/templates/react/src/pages/NftPage.tsx +138 -0
  29. package/templates/react/src/pages/WalletPage.tsx +114 -0
  30. package/templates/react-js/package.json +11 -12
  31. package/templates/react-js/src/App.jsx +86 -118
  32. package/templates/react-js/src/pages/NftPage.jsx +137 -0
  33. package/templates/react-js/src/pages/WalletPage.jsx +114 -0
@@ -1,141 +1,50 @@
1
1
  'use client'
2
2
 
3
- import { useReadContract, ConnectButton } from '@awarizon/react'
4
- import { ERC20_ABI } from '@awarizon/web3'
5
- import { Badge } from '@/components/ui/Badge'
6
- import { Button } from '@/components/ui/Button'
7
- import { Card } from '@/components/ui/Card'
3
+ import { usePrices } from '@awarizon/react'
8
4
  import { Skeleton } from '@/components/ui/Skeleton'
9
- import { StatCard } from '@/components/ui/StatCard'
10
5
 
11
- const USDC_BASE = '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'
12
-
13
- function DataRow({ label, value, loading }) {
14
- return (
15
- <div className="flex items-center justify-between py-3 border-b border-zinc-800/50 last:border-0">
16
- <code className="text-[11px] text-yellow-400/70 font-mono">{label}</code>
17
- {loading
18
- ? <Skeleton className="h-3.5 w-28" />
19
- : <span className="font-mono text-xs text-zinc-300">{value ?? '—'}</span>}
20
- </div>
21
- )
22
- }
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' },
12
+ ]
23
13
 
24
14
  export default function Home() {
25
- const { data: name, isLoading: l1 } = useReadContract({ address: USDC_BASE, abi: ERC20_ABI, method: 'name' })
26
- const { data: symbol, isLoading: l2 } = useReadContract({ address: USDC_BASE, abi: ERC20_ABI, method: 'symbol' })
27
- const { data: decimals, isLoading: l3 } = useReadContract({ address: USDC_BASE, abi: ERC20_ABI, method: 'decimals' })
28
- const { data: totalSupply, isLoading: l4 } = useReadContract({ address: USDC_BASE, abi: ERC20_ABI, method: 'totalSupply' })
29
-
30
- const formatted =
31
- totalSupply !== undefined && decimals !== undefined
32
- ? (Number(totalSupply) / 10 ** Number(decimals))
33
- .toLocaleString(undefined, { maximumFractionDigits: 2 })
34
- : undefined
35
-
36
- const synced = !l1 && !l2 && !l3 && !l4
15
+ const { prices, isLoading } = usePrices(TOKENS.map(t => t.symbol))
37
16
 
38
17
  return (
39
- <div className="min-h-screen bg-zinc-950 text-zinc-100">
40
-
41
- {/* ── Header ─────────────────────────────────────── */}
42
- <header className="sticky top-0 z-10 border-b border-zinc-800/60 bg-zinc-950/80 backdrop-blur-sm px-6 py-4">
43
- <div className="max-w-4xl mx-auto flex items-center justify-between">
44
- <div className="flex items-center gap-2.5">
45
- <div className="w-5 h-5 rounded-[4px] bg-yellow-400" />
46
- <span className="font-mono text-[11px] tracking-[0.2em] text-zinc-400 uppercase">
47
- {{project-name}}
48
- </span>
49
- </div>
50
- <div className="flex items-center gap-3">
51
- <Badge variant="outline">Base</Badge>
52
- <Badge variant={synced ? 'success' : 'loading'}>
53
- {synced ? '● Live' : '○ Loading'}
54
- </Badge>
55
- {process.env.NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID && <ConnectButton />}
56
- </div>
57
- </div>
58
- </header>
59
-
60
- <main className="max-w-4xl mx-auto px-6 py-12">
61
-
62
- {/* ── Hero ───────────────────────────────────────── */}
63
- <div className="mb-10">
64
- <Badge variant="outline" className="mb-5">Awarizon Web3 SDK · Next.js</Badge>
65
- <h1 className="text-4xl font-bold tracking-tight text-white mb-3">{{ProjectName}}</h1>
66
- <p className="text-zinc-400 text-base max-w-lg leading-relaxed">
67
- Live on-chain reads from Base — no backend required. Built with{' '}
68
- <code className="font-mono text-[11px] text-yellow-400/80">@awarizon/react</code>.
69
- </p>
70
- </div>
71
-
72
- {/* ── Data grid ──────────────────────────────────── */}
73
- <div className="grid md:grid-cols-3 gap-4 mb-4">
74
-
75
- <Card className="md:col-span-2">
76
- <div className="flex items-start justify-between mb-4">
77
- <div>
78
- <p className="font-mono text-[9px] tracking-widest text-zinc-600 uppercase mb-1.5">
79
- Contract · Live Read
80
- </p>
81
- <code className="font-mono text-xs text-zinc-500">0x8335…2913 · Base</code>
82
- </div>
83
- <Badge variant={synced ? 'success' : 'loading'}>
84
- {synced ? 'Synced' : 'Fetching…'}
85
- </Badge>
86
- </div>
87
- <DataRow label="name()" value={name} loading={l1} />
88
- <DataRow label="symbol()" value={symbol} loading={l2} />
89
- <DataRow label="decimals()" value={String(decimals ?? '')} loading={l3} />
90
- <DataRow label="totalSupply()" value={formatted} loading={l4} />
91
- </Card>
92
-
93
- <div className="flex flex-col gap-4">
94
- <StatCard label="Total Supply" value={formatted} loading={l4} sub="USDC · formatted" className="flex-1" />
95
- <StatCard label="Token" value={symbol} loading={l2} sub="Base mainnet" className="flex-1" />
96
- </div>
97
- </div>
98
-
99
- {/* ── Network info ─────────────────────────────────── */}
100
- <div className="grid sm:grid-cols-3 gap-4 mb-4">
101
- {[
102
- { label: 'Network', value: 'Base Mainnet' },
103
- { label: 'Chain ID', value: '8453' },
104
- { label: 'SDK', value: '@awarizon/react' },
105
- ].map(({ label, value }) => (
18
+ <main className="max-w-5xl mx-auto px-6 py-10">
19
+ <div className="grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-5 gap-4">
20
+ {TOKENS.map(({ symbol, name, color }) => {
21
+ const price = prices[symbol]?.price
22
+ return (
106
23
  <div
107
- key={label}
108
- className="bg-zinc-900/50 border border-zinc-800/40 rounded-xl px-5 py-4 flex items-center justify-between"
24
+ key={symbol}
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"
109
26
  >
110
- <span className="font-mono text-[10px] text-zinc-600 uppercase tracking-widest">{label}</span>
111
- <code className="font-mono text-xs text-zinc-400">{value}</code>
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)}
33
+ </div>
34
+ <p className="text-[11px] text-zinc-500 font-medium mb-0.5">{symbol}</p>
35
+ <p className="text-xs text-zinc-600">{name}</p>
36
+ </div>
37
+ <div className="text-lg font-semibold text-white tracking-tight">
38
+ {isLoading
39
+ ? <Skeleton className="h-5 w-20" />
40
+ : price != null
41
+ ? `$${price.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`
42
+ : '—'}
43
+ </div>
112
44
  </div>
113
- ))}
114
- </div>
115
-
116
- {/* ── Next steps ──────────────────────────────────── */}
117
- <Card>
118
- <p className="font-mono text-[9px] tracking-widest text-zinc-600 uppercase mb-4">Next Steps</p>
119
- <ul className="space-y-3 mb-6">
120
- {[
121
- ['01', 'Replace USDC_BASE with your contract address'],
122
- ['02', 'Swap ERC20_ABI for your contract ABI'],
123
- ['03', 'Change chain="base" in app/layout.jsx to your target network'],
124
- ['04', 'Use useWriteContract() for transactions'],
125
- ['05', 'Add walletConnectProjectId to AwarizonProvider for mobile wallet support'],
126
- ].map(([n, s]) => (
127
- <li key={n} className="flex items-start gap-3">
128
- <span className="font-mono text-[10px] text-yellow-400/50 mt-0.5 shrink-0 select-none">{n}</span>
129
- <span className="text-sm text-zinc-400 leading-relaxed">{s}</span>
130
- </li>
131
- ))}
132
- </ul>
133
- <div className="flex flex-wrap gap-2">
134
- <Button href="https://awarizon.com/docs" target="_blank" rel="noreferrer">Read the docs →</Button>
135
- <Button href="https://awarizon.com/dashboard" target="_blank" rel="noreferrer" variant="secondary">Dashboard</Button>
136
- </div>
137
- </Card>
138
- </main>
139
- </div>
45
+ )
46
+ })}
47
+ </div>
48
+ </main>
140
49
  )
141
50
  }
@@ -0,0 +1,116 @@
1
+ 'use client'
2
+
3
+ import { useWallet, useNativeBalance, usePrices, ConnectButton } from '@awarizon/react'
4
+ import { Badge } from '@/components/ui/Badge'
5
+ import { Card } from '@/components/ui/Card'
6
+ import { Skeleton } from '@/components/ui/Skeleton'
7
+ import { StatCard } from '@/components/ui/StatCard'
8
+
9
+ const SYMBOLS = ['ETH', 'BTC', 'USDC']
10
+
11
+ function DataRow({ label, value, loading }) {
12
+ return (
13
+ <div className="flex items-center justify-between py-3 border-b border-zinc-800/50 last:border-0">
14
+ <span className="font-mono text-[10px] text-zinc-600 uppercase tracking-widest">{label}</span>
15
+ {loading
16
+ ? <Skeleton className="h-3.5 w-32" />
17
+ : <span className="font-mono text-xs text-zinc-300">{value ?? '—'}</span>}
18
+ </div>
19
+ )
20
+ }
21
+
22
+ export default function WalletPage() {
23
+ const { address, isConnected, isChainMismatch, chainId, connectorInfo } = useWallet()
24
+ const { formatted: nativeBalance, isLoading: balanceLoading } = useNativeBalance(
25
+ address ?? undefined,
26
+ 12_000,
27
+ )
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
+
35
+ const ethFiatValue =
36
+ nativeBalance != null && prices['ETH']?.price != null
37
+ ? `$${(parseFloat(nativeBalance) * prices['ETH'].price).toLocaleString(undefined, { maximumFractionDigits: 2 })}`
38
+ : undefined
39
+
40
+ return (
41
+ <main className="max-w-4xl mx-auto px-6 py-12">
42
+
43
+ {/* ── Hero ───────────────────────────────────────── */}
44
+ <div className="mb-10">
45
+ <Badge variant="outline" className="mb-5">Portfolio</Badge>
46
+ <h1 className="text-4xl font-bold tracking-tight text-white mb-3">Wallet</h1>
47
+ <p className="text-zinc-400 text-base max-w-lg leading-relaxed">
48
+ Live balance and portfolio data via{' '}
49
+ <code className="font-mono text-[11px] text-yellow-400/80">useWallet</code>,{' '}
50
+ <code className="font-mono text-[11px] text-yellow-400/80">useNativeBalance</code>, and{' '}
51
+ <code className="font-mono text-[11px] text-yellow-400/80">usePrices</code>.
52
+ </p>
53
+ </div>
54
+
55
+ {!isConnected ? (
56
+ <Card className="py-12 flex flex-col items-center text-center">
57
+ <p className="font-mono text-[10px] tracking-widest text-zinc-600 uppercase mb-3">
58
+ No Wallet Connected
59
+ </p>
60
+ <p className="text-zinc-400 text-sm mb-6 max-w-sm leading-relaxed">
61
+ Connect a wallet to view your address, native balance, and real-time portfolio value.
62
+ </p>
63
+ <ConnectButton />
64
+ </Card>
65
+ ) : (
66
+ <>
67
+ {isChainMismatch && (
68
+ <div className="mb-4 px-4 py-3 bg-amber-500/10 border border-amber-500/20 rounded-xl">
69
+ <span className="font-mono text-xs text-amber-400">
70
+ Wrong network — switch to the chain configured in components/Providers.jsx
71
+ </span>
72
+ </div>
73
+ )}
74
+
75
+ {/* ── Account ──────────────────────────────────── */}
76
+ <Card className="mb-4">
77
+ <p className="font-mono text-[9px] tracking-widest text-zinc-600 uppercase mb-4">Account</p>
78
+ <DataRow label="Address" value={address ?? undefined} loading={false} />
79
+ <DataRow label="Chain ID" value={chainId != null ? String(chainId) : undefined} loading={false} />
80
+ <DataRow label="Connector" value={connectorInfo?.name ?? connectorInfo?.type} loading={false} />
81
+ </Card>
82
+
83
+ {/* ── 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>
99
+
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
+ </>
113
+ )}
114
+ </main>
115
+ )
116
+ }
@@ -0,0 +1,56 @@
1
+ 'use client'
2
+
3
+ import Link from 'next/link'
4
+ import { usePathname } from 'next/navigation'
5
+ import { ConnectButton } from '@awarizon/react'
6
+
7
+ const NAV = [
8
+ { href: '/', label: 'Markets' },
9
+ { href: '/nft', label: 'NFT' },
10
+ { href: '/wallet', label: 'Wallet' },
11
+ ]
12
+
13
+ export function Header() {
14
+ const pathname = usePathname()
15
+ return (
16
+ <header className="sticky top-0 z-50 border-b border-white/[0.06] bg-zinc-950/70 backdrop-blur-2xl">
17
+ <div className="max-w-5xl mx-auto px-6 h-16 flex items-center justify-between gap-8">
18
+
19
+ <div className="flex items-center gap-2.5 shrink-0">
20
+ <div className="w-7 h-7 rounded-lg bg-yellow-400" />
21
+ <span className="text-sm font-semibold text-white">{'{{project-name}}'}</span>
22
+ </div>
23
+
24
+ <nav className="flex items-center">
25
+ {NAV.map(({ href, label }) => {
26
+ const active = pathname === href
27
+ return (
28
+ <Link
29
+ key={href}
30
+ href={href}
31
+ className={[
32
+ 'relative px-4 py-2 text-sm font-medium transition-colors',
33
+ active ? 'text-white' : 'text-zinc-500 hover:text-zinc-300',
34
+ ].join(' ')}
35
+ >
36
+ {label}
37
+ {active && (
38
+ <span className="absolute bottom-0 left-4 right-4 h-px bg-yellow-400" />
39
+ )}
40
+ </Link>
41
+ )
42
+ })}
43
+ </nav>
44
+
45
+ <div className="flex items-center gap-3 shrink-0">
46
+ <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
49
+ </div>
50
+ {process.env.NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID && <ConnectButton />}
51
+ </div>
52
+
53
+ </div>
54
+ </header>
55
+ )
56
+ }
@@ -3,24 +3,23 @@
3
3
  "version": "0.1.0",
4
4
  "private": true,
5
5
  "scripts": {
6
- "dev": "next dev",
6
+ "dev": "next dev",
7
7
  "build": "next build",
8
8
  "start": "next start",
9
- "lint": "next lint"
9
+ "lint": "next lint"
10
10
  },
11
11
  "dependencies": {
12
- "@awarizon/react": "^1.6.1",
13
- "@awarizon/web3": "^1.3.4",
14
- "next": "14.2.5",
15
- "react": "^18",
16
- "react-dom": "^18"
12
+ "@awarizon/react": "^1.6.2",
13
+ "@awarizon/web3": "^1.3.5",
14
+ "next": "14.2.5",
15
+ "react": "^18",
16
+ "react-dom": "^18"
17
17
  },
18
18
  "devDependencies": {
19
- "eslint": "^8",
19
+ "eslint": "^8",
20
20
  "eslint-config-next": "14.2.5",
21
- "autoprefixer": "^10.4.19",
22
- "postcss": "^8.4.38",
23
- "tailwindcss": "^3.4.4"
21
+ "autoprefixer": "^10.4.19",
22
+ "postcss": "^8.4.38",
23
+ "tailwindcss": "^3.4.4"
24
24
  }
25
25
  }
26
-
@@ -4,26 +4,25 @@
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "scripts": {
7
- "dev": "vite",
8
- "build": "tsc -b && vite build",
7
+ "dev": "vite",
8
+ "build": "tsc -b && vite build",
9
9
  "preview": "vite preview",
10
- "lint": "eslint ."
10
+ "lint": "eslint ."
11
11
  },
12
12
  "dependencies": {
13
- "@awarizon/react": "^1.6.1",
14
- "@awarizon/web3": "^1.3.4",
15
- "react": "^18.3.1",
16
- "react-dom": "^18.3.1"
13
+ "@awarizon/react": "^1.6.2",
14
+ "@awarizon/web3": "^1.3.5",
15
+ "react": "^18.3.1",
16
+ "react-dom": "^18.3.1"
17
17
  },
18
18
  "devDependencies": {
19
- "@types/react": "^18.3.1",
20
- "@types/react-dom": "^18.3.1",
19
+ "@types/react": "^18.3.1",
20
+ "@types/react-dom": "^18.3.1",
21
21
  "@vitejs/plugin-react": "^4.3.1",
22
- "typescript": "^5.5.3",
23
- "vite": "^5.4.1",
24
- "autoprefixer": "^10.4.19",
25
- "postcss": "^8.4.38",
26
- "tailwindcss": "^3.4.4"
22
+ "typescript": "^5.5.3",
23
+ "vite": "^5.4.1",
24
+ "autoprefixer": "^10.4.19",
25
+ "postcss": "^8.4.38",
26
+ "tailwindcss": "^3.4.4"
27
27
  }
28
28
  }
29
-