A production-ready Next.js template for using smart wallets with Privy Auth on Monad Testnet. This template demonstrates how to integrate Privy's smart wallet functionality, enabling seamless user onboarding and transaction execution without requiring users to manage private keys.
- π Smart Wallet Integration - Automatic smart wallet creation for all users via Privy
- πΌ Embedded Wallets - No need for users to install browser extensions
- π Batch Transactions - Execute multiple transactions in a single batch
- π Transaction Examples - Complete examples for minting NFTs, approvals, and batch operations
- π Monad Testnet Support - Pre-configured for Monad Testnet (Chain ID: 10143)
- π Server-Side Auth - Secure authentication with server-side token verification
- π± Responsive Design - Modern UI built with Tailwind CSS
- β‘ TypeScript - Fully typed for better developer experience
- π¨ Beautiful UI - Custom graphics and styling
- Framework: Next.js (Pages Router)
- Language: TypeScript
- Styling: Tailwind CSS
- Authentication: Privy Auth
- Smart Wallets: Privy Smart Wallets
- Blockchain: Monad Testnet (Chain ID: 10143)
- Blockchain Library: Viem
- UI Components: Headless UI, Heroicons
Smart-Wallet-Privy-Template/
βββ pages/
β βββ _app.tsx # Root app component with PrivyProvider and SmartWalletsProvider
β βββ index.tsx # Login page with server-side auth check
β βββ dashboard.tsx # Dashboard with smart wallet transaction examples
β βββ api/
β βββ verify.ts # API route for token verification
βββ components/
β βββ graphics/
β β βββ login.tsx # Login page graphics
β β βββ portal.tsx # Portal graphics component
β βββ lib/
β β βββ abis/
β β βββ mint.ts # NFT mint ABI
β βββ formatted-date.tsx # Date formatting component
β βββ layout.tsx # Layout component
β βββ logo.tsx # Logo component
β βββ navbar.tsx # Navigation bar
βββ styles/
β βββ globals.css # Global styles
βββ public/
β βββ fonts/ # Custom fonts
β βββ images/ # Static images
β βββ logos/ # Logo assets
βββ .env.local # Environment variables (create this)
βββ package.json
βββ tsconfig.json
βββ README.md
Before you begin, ensure you have:
- Node.js 18+ installed
- npm 9+ (or yarn/pnpm)
- A Privy account with an app created
- Smart wallets configured in your Privy dashboard
- Monad Testnet configured in your wallet (Chain ID: 10143)
- Testnet tokens from the Monad Faucet
# If cloning from a repository
git clone <repository-url>
cd Smart-Wallet-Privy-Template
# Or use this as a template for your projectnpm install
# or
yarn install
# or
pnpm installCreate a .env.local file in the root directory:
# Privy App ID (public, safe to expose)
NEXT_PUBLIC_PRIVY_APP_ID=your_privy_app_id_here
# Privy App Secret (server-side only, keep private!)
PRIVY_APP_SECRET=your_privy_app_secret_here- Sign up/Login to Privy Dashboard
- Create a new app or select an existing one
- Get your App ID:
- Go to Settings β API Keys
- Copy your App ID (this is public and safe to expose)
- Get your App Secret:
- In the same section, copy your App Secret (keep this private!)
- Only use this server-side, never expose it to the client
- In your Privy dashboard, navigate to Wallets β Smart Wallets
- Enable smart wallets for your app
- Configure your smart wallet settings:
- Choose your smart wallet provider (e.g., Privy's default)
- Set up gas sponsorship if desired
- Configure wallet creation settings
The template includes example transactions with an NFT contract. Update the contract address in pages/dashboard.tsx:
const NFT_CONTRACT_ADDRESS = "0xYourContractAddressOnMonadTestnet" as const;Note: You'll need to deploy your own contract on Monad Testnet or use an existing contract address.
npm run dev
# or
yarn dev
# or
pnpm devOpen http://localhost:3000 in your browser.
βββββββββββββββ ββββββββββββββββ βββββββββββββββ
β Client ββββββββββΆβ Next.js ββββββββββΆβ Privy β
β (Browser) β β Server β β Service β
βββββββββββββββ ββββββββββββββββ βββββββββββββββ
β β β
β 1. Login Request β β
βββββββββββββββββββββββββββΆβ β
β β 2. Authenticate β
β ββββββββββββββββββββββββββΆβ
β β β
β β 3. Auth Token β
β βββββββββββββββββββββββββββ€
β β β
β 4. Auth Cookie β β
ββββββββββββββββββββββββββββ€ β
β β β
β 5. Smart Wallet Created β β
β β β
β 6. Execute Transaction β β
βββββββββββββββββββββββββββΆβ β
β β 7. Send to Monad β
β ββββββββββββββββββββββββββΆβ
β β β
β 8. Transaction Receipt β β
ββββββββββββββββββββββββββββ€ β
- User Login: User clicks "Log in" button on the home page
- Privy Modal: Privy authentication modal opens
- Authentication: User authenticates via email, social login, or wallet
- Smart Wallet Creation: Privy automatically creates a smart wallet for the user
- Server Verification: Server verifies the auth token and sets a cookie
- Dashboard Access: User is redirected to the dashboard
The template demonstrates three types of transactions:
-
Single Transaction (Mint NFT):
smartWalletClient.sendTransaction({ to: NFT_CONTRACT_ADDRESS, data: encodeFunctionData({ abi: mintAbi, functionName: "mint", args: [...] }), });
-
Single Transaction (Approve):
smartWalletClient.sendTransaction({ to: NFT_CONTRACT_ADDRESS, data: encodeFunctionData({ abi: erc721Abi, functionName: "setApprovalForAll", args: [...] }), });
-
Batch Transaction:
smartWalletClient.sendTransaction({ account: smartWalletClient.account, calls: [ { to: NFT_CONTRACT_ADDRESS, data: mintData }, { to: NFT_CONTRACT_ADDRESS, data: approveData }, ], });
- PrivyProvider: Wraps the app with Privy authentication
- SmartWalletsProvider: Enables smart wallet functionality
- Monad Testnet Configuration: Defines the Monad testnet chain
- Server-Side Auth Check: Verifies existing auth tokens
- Login Flow: Handles user authentication
- Redirect Logic: Redirects authenticated users to dashboard
- Smart Wallet Client: Uses
useSmartWalletshook to get the smart wallet client - Transaction Examples: Demonstrates minting, approvals, and batch transactions
- User Info Display: Shows the authenticated user object
The template is configured for Monad Testnet. To change networks, update pages/_app.tsx:
// Define your chain
const yourChain = defineChain({
id: YOUR_CHAIN_ID,
name: "Your Chain Name",
// ... chain configuration
});
// Update PrivyProvider config
<PrivyProvider
config={{
defaultChain: yourChain,
supportedChains: [yourChain],
// ...
}}
>Add new transaction functions in pages/dashboard.tsx:
const onCustomTransaction = () => {
if (!smartWalletClient) return;
smartWalletClient.sendTransaction({
to: YOUR_CONTRACT_ADDRESS,
data: encodeFunctionData({
abi: yourAbi,
functionName: "yourFunction",
args: [/* your args */],
}),
});
};The template uses Tailwind CSS for styling. Modify components to customize the appearance:
- Colors: Update Tailwind classes in components
- Layout: Modify component structure in
pages/andcomponents/ - Graphics: Replace graphics in
components/graphics/
Create new pages in the pages/ directory:
// pages/your-page.tsx
import { usePrivy } from "@privy-io/react-auth";
import { useSmartWallets } from "@privy-io/react-auth/smart-wallets";
export default function YourPage() {
const { authenticated } = usePrivy();
const { client } = useSmartWallets();
// Your page content
}- β
Check
.env.localexists in root directory - β
Verify variable name is exactly
NEXT_PUBLIC_PRIVY_APP_ID - β Restart dev server after adding env vars
- β
Ensure variable name is exactly
PRIVY_APP_SECRET - β
Check
.env.localfile (not.env) - β Restart dev server
- β Verify smart wallets are enabled in Privy dashboard
- β Check smart wallet configuration in dashboard
- β Ensure you're using the correct App ID
- β Check browser console for errors
- β Verify contract address is correct for Monad Testnet
- β Ensure contract exists on Monad Testnet
- β Check smart wallet has sufficient balance
- β Verify ABI matches your contract
- β Check browser console for detailed error messages
- β Verify Privy App ID is correct
- β Check Privy dashboard for app status
- β Ensure cookies are enabled in browser
- β Check server logs for authentication errors
- β Verify Monad Testnet is correctly configured
- β
Check RPC endpoint is accessible:
https://testnet-rpc.monad.xyz - β Ensure wallet is connected to Monad Testnet
- β Verify Chain ID is 10143
-
Push to GitHub
git add . git commit -m "Initial commit" git push origin main
-
Import to Vercel
- Go to Vercel
- Click "New Project"
- Import your repository
-
Add Environment Variables
NEXT_PUBLIC_PRIVY_APP_ID: Your Privy App IDPRIVY_APP_SECRET: Your Privy App Secret
-
Deploy
- Click "Deploy"
- Wait for build to complete
This is a standard Next.js app and can be deployed to any platform supporting Next.js:
- Netlify: Set build command to
npm run buildand publish directory to.next - Railway/Render: Set build command to
npm run buildand start command tonpm start - AWS Amplify: Follow Next.js deployment guide
- Self-hosted: Run
npm run buildandnpm start
Required for Production:
NEXT_PUBLIC_PRIVY_APP_ID: Public App ID (exposed to browser)PRIVY_APP_SECRET: Private App Secret (server-side only)
Security Notes:
- β
Never commit
.env.localto git - β Use platform-specific env var management
- β
PRIVY_APP_SECRETshould never be exposed client-side - β
NEXT_PUBLIC_*variables are exposed to browser
- Privy Documentation - Complete Privy Auth and Smart Wallets guide
- Privy Smart Wallets Docs - Smart wallet implementation guide
- Monad Documentation - Official Monad blockchain docs
- Monad Testnet Documentation - Testnet information
- Monad Explorer - Explore Monad Testnet transactions
- Monad Faucet - Get testnet tokens
- Monad Discord - Community support
- Viem Documentation - Blockchain interaction library
- Next.js Documentation - Next.js framework guide
This is a template repository. Feel free to fork and customize for your needs!
If you have improvements or find issues:
- Fork the repository
- Create a feature branch
- Make your changes
- Submit a pull request
This template is provided as-is for educational and development purposes.
- Testnet Only: This template is configured for Monad Testnet - use testnet tokens only
- Contract Address: The NFT contract address in
dashboard.tsxis a placeholder - update it with your own contract - Smart Wallet Configuration: Ensure smart wallets are properly configured in your Privy dashboard
- API Keys: Keep your
PRIVY_APP_SECRETsecure and never commit it to version control - Gas Sponsorship: Configure gas sponsorship in Privy dashboard if you want to sponsor user transactions
- Rate Limits: Be aware of Privy API rate limits for production use
This template is pre-configured for Monad Testnet:
- Chain ID: 10143
- RPC URL: https://testnet-rpc.monad.xyz
- Block Explorers:
- Faucet: Get testnet tokens
- Native Currency: MON (18 decimals)
Built for the Monad Ecosystem π
Happy Building! π