A full-stack EVM-based web application demonstrating wallet integration, token balances tracking, and a global leaderboard feature.
This is a TypeScript monorepo containing:
apps/client
: Next.js static generated frontend application with Tailwind CSSapps/server
: Express.js backend with SQLite database
- 🔑 Secure wallet connection and authentication
- 💰 Token balance display
- 🏆 Global leaderboard with registered users
- 🔒 Signature-based authentication
- 🎨 Responsive UI
- 🌙 Automatic dark mode based on system preferences
- Next.js 14
- TypeScript
- Tailwind CSS
- connectkit + wagmi for wallet integration
- Express.js with TypeScript
- SQLite with Drizzle ORM
- viem for Ethereum interactions
- zod for request validation
- Node.js 20+
- yarn
- An Ethereum wallet (e.g., MetaMask)
- Clone the repository:
git clone <repository-url>
cd web3-demo-dapp
- Install dependencies:
yarn install
- Setup environment variables:
To fetch wallet balances, you’ll need a Dune Echo API key, which you can create for free at dune.com/settings/api.
Then, create a .env
file inside the apps/server
directory and add the required environment variables.
cp apps/server/.env.example apps/server/.env
# Fill in required variables
- Setup database:
yarn server:db:migrate
To run server tests, use the following command:
yarn server:test
- Start the backend server:
yarn server:dev
- Start the frontend application:
yarn client:dev
The application will be available at:
- Frontend: http://localhost:3000
- Backend API: http://localhost:3001
-
Live API Usage in Tests: Server tests for the
/balances
endpoint currently run against real third-party API without mocking. While acceptable for a small number of tests, this approach should be used sparingly. For broader or more complex test coverage, mocks should be implemented. -
Database Initialization in Tests: Database setup in tests should rely on the ORM schema to ensure consistency.
-
Shared Types: Request and response types used in backend endpoints should be reused between the client and server via a shared package. This promotes type safety, reduces duplication, and minimizes potential inconsistencies.
-
UI Styling Approach: Since the project specification did not mandate a specific component library, I opted to use Tailwind CSS utility classes for styling. For projects with more advanced UI requirements, adopting a component library such as MUI, Chakra UI, or
shadcn/ui
(for a more customizable, Tailwind-friendly approach) would be beneficial. -
Dependency Versions: Some dependencies may not be the latest available. Updating them should be considered as a follow-up to ensure access to the newest features, improvements, and security patches.
-
AI Assistance: The project was built with the help of an AI coding assistant to accelerate development and explore different implementation options. However, all code, features, and design decisions were thoroughly reviewed, refined, and validated by the author to ensure quality and correctness.
MIT © Kris Urbas