惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

罗磊的独立博客
美团技术团队
Apple Machine Learning Research
Apple Machine Learning Research
Hugging Face - Blog
Hugging Face - Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
月光博客
月光博客
WordPress大学
WordPress大学
The Cloudflare Blog
阮一峰的网络日志
阮一峰的网络日志
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
博客园_首页
博客园 - Franky
博客园 - 司徒正美
酷 壳 – CoolShell
酷 壳 – CoolShell
爱范儿
爱范儿
Jina AI
Jina AI
Last Week in AI
Last Week in AI
雷峰网
雷峰网
IT之家
IT之家
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - 聂微东
小众软件
小众软件
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
V
V2EX

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant
A .NET Dinosaur in Web3. Day 7 — First connect
Alena · 2026-05-17 · via DEV Community

Intro

This day is a bit different from the previous ones. Initially, the idea was simple — one contract per day. But Web3 is not just about contracts and blockchain. There are other layers — UI, integration, the way everything connects together. At some point it became obvious: it makes more sense to start structuring the project early, instead of treating each part in isolation. As a developer who is getting close to an architect level — and someone who enjoys microservice architecture — I got curious: how are these projects actually structured?

A contract is just one piece. A dApp is a system. I assume the same principles apply here — some form of clean architecture, separation of concerns, clear boundaries. And for something like WishList Chain, it felt important to start thinking about the structure from the beginning.

At that point, I started thinking not just about the contract itself, but about the structure of the whole project. Because Web3 is clearly not only about writing smart contracts. There is always a frontend, some kind of interaction layer, maybe scripts or bots, and potentially even a backend later on. All of these parts are connected, whether you plan for it or not.

So the question became less about "what to build next" and more about "how to structure it properly from the beginning."

That's where the idea of using a monorepo came in.

Why Monorepo?

I decided to approach this a bit differently. Usually, I create separate repositories by responsibility (the "S" in SOLID), but not this time.

Here the picture is clearer. The contract and the frontend are tightly connected. Any change in the contract — new fields, updated logic, even a different address — will require changes in multiple places. That means more manual work, more context switching, and more chances to break something.

Better to keep things as simple as possible.

So instead of splitting things too early, I decided to keep everything in one place. A single repository, but clearly separated layers inside it:

wish-list-chain/
├── apps/
│   └── web/       ← Next.js 15
├── contracts/     ← Hardhat
├── package.json
└── .env

Enter fullscreen mode Exit fullscreen mode

From a structural point of view, it already feels closer to a real system rather than a set of experiments.

I know this goes a bit against how I usually structure things. Normally, I prefer to separate repositories by responsibility — the "S" in SOLID. It keeps boundaries clear and makes scaling easier later. But in this case, it felt like the separation would introduce more friction than value. The responsibilities are still separated — just not at the repository level.

Project Stack

Before the code — a quick map of what we're working with and why.

Tool Role .NET analogy
Next.js 15 (App Router) Frontend framework ASP.NET Core MVC
wagmi 2 React hooks for blockchain SDK wrapper for Web3 calls
viem 2 Low-level Ethereum client HttpClient for the blockchain
RainbowKit Wallet connection UI OAuth login button
@tanstack/react-query Async state management No direct equivalent
WalletConnect / Reown Multi-wallet protocol OAuth provider

Theory — A Little Bit

wagmi sits on top of viem. viem handles the low-level blockchain calls. wagmi provides React hooks like useAccount, useReadContract, useWriteContract. You can drop down to viem when you need more control, but most of the time wagmi is enough.

RainbowKit is just a UI layer on top of wagmi — the modal, the button, the wallet list. It doesn't do any blockchain work itself.

What Clicked

Next.js 15 App Router makes everything a Server Component by default. wagmi hooks rely on React state and browser APIs — they can't run on the server. Any component that calls useAccount, useReadContract, or renders <ConnectButton /> needs 'use client' at the top. Otherwise, the code looks correct — but simply doesn't work.

ConnectKit doesn't support React 19 yet.

I actually started with ConnectKit — clean UI, good docs, everything looked straightforward. It failed immediately. Peer dependency error: it requires React 17 or 18, while Next.js 15 already ships with React 19. So that path just… stopped there.

This is the current state of the Web3 frontend ecosystem: some libraries are ahead, some are behind. Check React version compatibility before installing anything.

Downgrading React didn't feel right. So I kept React 19 and aligned the rest of the stack around it — wagmi 2.x ended up being the stable choice.

RainbowKit requires wagmi 2. wagmi 3 is out but RainbowKit hasn't released a compatible version yet. Pinning wagmi to version 2 for now. This will resolve eventually — until then, mixing versions breaks the dependency tree.

The Result

<ConnectButton /> renders. Click it — RainbowKit modal opens with MetaMask, WalletConnect, and others. Connect MetaMask — wallet address and balance appear.

That's a Next.js 15 app reading live data from the Sepolia blockchain through a connected wallet. No backend. No API. The blockchain is the data source.

Next: read totalDreamPower directly from the WishlistV3 contract using useReadContract.

Repo: github.com/alena-dev-soft/wish-list-chain

Stage: Dinosaur 🦕 — frontend connected. Blockchain is the backend.