Frontend
Deep dive into the Next.js frontend structure and libraries
Tech Stack
Package | Description |
---|---|
🥟 Bun | Performant package & workspace manager |
⚙️ TypeScript | Type-safe programming language |
🛠️ Biome | Modern Linter & Formatter |
⚛️ Next.js | Production-grade React framework |
🎨 shadcn/ui with Tailwind CSS v4 | Unopinionated UI components with utility-first styling |
⛓️ Papi | Type-safe Polkadot API |
⛓️ ReactiveDOT | Reactive state management using Papi |
File Structure
components.json
next.config.ts
package.json
tsconfig.json
Available Commands
Run these commands from the frontend directory or root with -F frontend
:
# Development
bun run dev # Start dev server
# Production Builds
bun run build # Build for production
bun run start # Start production server
bun run build:standalone # Build for production (self-hosting)
# Code Quality
bun run lint # Run linter & formatter checks
bun run lint:fix # Auto-fix issues
bun run typecheck # TypeScript type checking
# Maintenance
bun run clean # Remove build artifacts
Web3 Base Components
// Account selection dropdown with disconnect option
import { AccountSelect } from '@/components/web3/account-select'
function MyComponent() {
const [account, setAccount] = useState<WalletAccount>()
return <AccountSelect account={account} setAccount={setAccount} />
}
Displays connected accounts in a dropdown. Falls back to ConnectButton
when no account is selected.
// Display account balance with faucet link
import { AccountBalance } from '@/components/web3/account-balance'
<AccountBalance />
Shows the spendable balance of the connected account. Includes a faucet button for testnet chains.
// Network switching component
import { ChainSelect } from '@/components/web3/chain-select'
function MyComponent() {
const [chainId, setChainId] = useState<ChainId>('dev')
return <ChainSelect chainId={chainId} setChainId={setChainId} />
}
Dropdown for switching between configured blockchain networks.
Configuration
Chains
The chain configuration is centralized in /src/lib/reactive-dot/config.ts
.
export const config = {
chains: {
dev: {
descriptor: dev,
provider: getWsProvider('ws://127.0.0.1:9944'),
},
pop: {
descriptor: pop,
provider: getWsProvider('wss://rpc1.paseo.popnetwork.xyz'),
},
// Add more chains here
},
wallets: [walletconnect()],
}
Contracts
Contract deployments are managed in /src/lib/inkathon/deployments.ts
. They are cross-imported from the deployments/
folder in the contracts workspace.
// Imports from the contracts workspace
import { contracts } from '@polkadot-api/descriptors'
import * as flipperPassethub from 'contracts/deployments/flipper/passethub'
import * as flipperPop from 'contracts/deployments/flipper/pop'
export const flipper = {
contract: contracts.flipper,
evmAddresses: {
pop: flipperPop.evmAddress,
passethub: flipperPassethub.evmAddress,
// Add more deployments here
},
ss58Addresses: {
pop: flipperPop.ss58Address,
passethub: flipperPassethub.ss58Address,
// Add more deployments here
},
}
export const deployments = {
flipper,
// Add more contracts here
}