| name | web3-fullstack-systematic-build |
| description | Systematic approach to building full-stack Web3 applications layer by layer |
Web3 Full-Stack Systematic Build
This skill provides a structured, layer-by-layer approach to building complex full-stack Web3 applications. Follow this sequence to maintain clarity, reduce coupling, and enable incremental testing even when tool failures occur.
Phase 1: Project Structure
First, establish the complete directory structure before writing any code:
project-name/
├── contracts/
│ ├── interfaces/
│ ├── core/
│ ├── libraries/
│ └── deployment/
├── frontend/
│ ├── src/
│ │ ├── components/
│ │ ├── hooks/
│ │ ├── config/
│ │ └── utils/
│ └── public/
├── scripts/
│ ├── deploy/
│ └── test/
├── zk-circuits/
└── docs/
Action: Create all directories upfront using:
mkdir -p contracts/{interfaces,core,libraries,deployment}
mkdir -p frontend/src/{components,hooks,config,utils}
mkdir -p frontend/public
mkdir -p scripts/{deploy,test}
mkdir -p zk-circuits docs
Phase 2: Interface Contracts First
Define all interface contracts before implementing logic. This establishes clear API boundaries.
Example interface structure:
// contracts/interfaces/IToken.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface IToken {
function transfer(address to, uint256 amount) external returns (bool);
function balanceOf(address account) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
}
Actions:
- List all external protocols you'll integrate (e.g., Aave, Connext, Uniswap)
- Create interface files for each protocol's required functions
- Create interfaces for your own contracts' public APIs
- Validate interface completeness before proceeding
Phase 3: Core Contract Implementation
Implement contracts in dependency order, starting with libraries, then core logic.
Order of implementation:
- Libraries - Utility functions with no state dependencies
- Base contracts - Abstract contracts with shared logic
- Core contracts - Main business logic implementing interfaces
- Integration contracts - Contracts that bridge multiple protocols
Example:
// contracts/core/PrivatePool.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../interfaces/IToken.sol";
import "../libraries/SafeMath.sol";
contract PrivatePool {
using SafeMath for uint256;
IToken public token;
mapping(address => uint256) private balances;
constructor(address _token) {
token = IToken(_token);
}
function deposit(uint256 amount) external {
token.transferFrom(msg.sender, address(this), amount);
balances[msg.sender] = balances[msg.sender].add(amount);
}
}
Actions:
- Implement one contract at a time
- Compile and test each contract before moving to the next
- Keep contracts focused on single responsibilities
- Document all state variables and functions
Phase 4: Frontend Configuration
Set up frontend infrastructure before building components.
Create these config files first:
- Network configuration (
frontend/src/config/networks.js):
export const networks = {
mainnet: {
chainId: 1,
rpcUrl: process.env.REACT_APP_MAINNET_RPC,
explorer: 'https://etherscan.io'
},
testnet: {
chainId: 5,
rpcUrl: process.env.REACT_APP_TESTNET_RPC,
explorer: 'https://goerli.etherscan.io'
}
};
- Contract addresses (
frontend/src/config/contracts.js):
export const contractAddresses = {
PrivatePool: process.env.REACT_APP_PRIVATE_POOL_ADDRESS,
Token: process.env.REACT_APP_TOKEN_ADDRESS
};
- ABI imports (
frontend/src/config/abis/):
import PrivatePoolABI from './PrivatePool.json';
export { PrivatePoolABI };
Actions:
- Create environment variable templates (
.env.example)
- Set up Web3 provider configuration (ethers.js, web3.js, or wagmi)
- Configure wallet connection logic
- Create utility functions for common operations
Phase 5: Component Development
Build frontend components in this order:
- Utility components - Buttons, inputs, modals (no Web3 logic)
- Web3 wrapper components - Wallet connection, network switcher
- Contract interaction components - Forms that call contract functions
- Data display components - Components showing on-chain data
- Page components - Assembling everything into pages
Example component:
import { useState } from 'react';
import { useContractWrite } from 'wagmi';
import { PrivatePoolABI } from '../config/abis';
export function DepositForm({ contractAddress, tokenAddress }) {
const [amount, setAmount] = useState('');
const { write: deposit } = useContractWrite({
address: contractAddress,
abi: PrivatePoolABI,
functionName: 'deposit',
args: [BigInt(amount)]
});
return (
<form onSubmit={(e) => { e.preventDefault(); deposit(); }}>
<input
value={amount}
onChange={(e) => setAmount(e.target.value)}
placeholder="Amount"
/>
<button type="submit">Deposit</button>
</form>
);
}
Actions:
- Create components with clear prop interfaces
- Implement error handling for all Web3 interactions
- Add loading states for pending transactions
- Test each component in isolation
Phase 6: Deployment Scripts
Create deployment scripts last, after all contracts are complete and tested.
Structure:
async function main() {
const Token = await ethers.getContractFactory("Token");
const token = await Token.deploy();
await token.deployed();
console.log("Token deployed to:", token.address);
fs.writeFileSync(
'frontend/.env',
`REACT_APP_TOKEN_ADDRESS=${token.address}\n`,
{ flag: 'a' }
);
}
Actions:
- Create deployment scripts for each contract in dependency order
- Include address saving mechanism for frontend integration
- Create verification scripts for block explorers
- Document deployment parameters and expected outputs
Key Principles
- Interface-first design - Define contracts before implementing
- Layer-by-layer progression - Complete each phase before next
- Incremental testing - Test at each layer, not just at the end
- Configuration before components - Set up infrastructure first
- Documentation at each step - Update docs as you progress
Recovery from Failures
If a tool failure occurs:
- Note which phase completed successfully
- Resume from the last completed phase
- Re-validate interfaces and contracts before continuing
- Use the directory structure as a progress checklist
This systematic approach ensures partial progress is preserved and the overall architecture remains coherent even when interruptions occur.