A clean starter template for building Monad Testnet apps with wallet UX and smart-contract interactions.
This template includes:
- Privy authentication with embedded EVM wallet
- Monad Testnet network configuration (Wagmi + Viem)
- Deposit and withdraw wallet modals
- On-chain counter integration (
getMyCount,totalCount,increaseCounter) - Next.js App Router + TypeScript + Tailwind setup
- Wallet authentication
- Embedded wallet support via Privy
- One-click network switch/add for Monad Testnet
- Counter contract hook (
useCounterContract) - Transaction confirmation flow with receipt waiting
- Responsive counter UI for desktop/mobile
- API route stubs ready for extension
- Next.js 16 (App Router)
- React 19 + TypeScript
- Tailwind CSS
- Wagmi + Viem
- Privy (
@privy-io/react-auth,@privy-io/wagmi)
src/app/page.tsx: main counter app pagesrc/app/profile/page.tsx: secondary counter utilities pagesrc/hooks/useMyContract.ts: counter contract reads/writessrc/config/chains.ts: Monad chain + contract address configsrc/components/wallet/WalletActions.tsx: balance, deposit, withdraw controlssrc/components/wallet/AddFundsModal.tsx: deposit/receive UIsrc/components/wallet/WithdrawModal.tsx: withdraw UIsrc/lib/contract/abi.json: counter contract ABI
- Node.js 20+
- npm
- Privy App ID
- Monad Testnet wallet/funds for testing
- Install dependencies
npm install- Create local env file
touch .env.local- Add required environment variables
NEXT_PUBLIC_PRIVY_APP_ID=your_privy_app_id
NEXT_PUBLIC_COUNTER_ADDRESS=0x65138ffa2eC30375776627bFF6318D3e792Bd0B9
NEXT_PUBLIC_SITE_URL=http://localhost:3000Notes:
NEXT_PUBLIC_COUNTER_ADDRESSis optional if you want to keep the default contract already set insrc/config/chains.ts.NEXT_PUBLIC_SITE_URLis used for app metadata URLs.
- Run locally
npm run devOpen http://localhost:3000.
The template is wired to the following contract by default:
- Address:
0x65138ffa2eC30375776627bFF6318D3e792Bd0B9 - Network: Monad Testnet (
chainId 10143)
ABI location:
src/lib/contract/abi.json
Hook usage:
useCounterContract()exposes:myCounttotalCountincreaseCounter()isPending,isLoading,actionError
Configured in src/config/chains.ts:
- RPC:
https://testnet-rpc.monad.xyz - Explorer:
https://testnet.monadvision.com - Symbol:
MON
If a wallet is on another chain, the app attempts:
wallet_switchEthereumChain- fallback to
wallet_addEthereumChain
npm run dev
npm run build
npm run start
npm run lintnpm run build passes in this template. You may still see non-blocking warnings from transitive wallet dependencies (MetaMask SDK optional modules).
Common next steps for developers:
- Add event indexing for
CounterIncreased - Add a history table for user increments
- Add test coverage for hooks and UI actions
- Replace stub API routes with project-specific endpoints
Use this template as a starter for hackathon and production prototypes.