Expert guidance for developing features in Curve Finance's Vite-powered React DApp with TanStack Router/Query, Wagmi blockchain integration, and monorepo architecture
Expert guidance for developing features in Curve Finance's frontend DApp - a Vite-powered React application for interacting with Curve's DeFi smart contracts.
This is a Yarn workspaces monorepo containing:
Tech stack: React 19, TypeScript, TanStack Router/Query, Wagmi v2 + Viem, MUI, Vest validation
1. **Setup & Common Commands**
- Install dependencies with Node.js LTS and Yarn 4
- `yarn dev` - Start development server on localhost:3000
- `yarn build` - Build for production
- `yarn typecheck` - Run TypeScript checks
- `yarn lint:fix` - Fix linting issues
- `yarn format` - Format with Prettier
2. **Feature Development by Domain**
- Navigate to domain: `/apps/main/src/[domain]/` (dex, crvusd, loan, lend, llamalend, dao)
- Follow Feature-Sliced Design structure:
- `entities/` - Core models with TanStack Query
- `features/` - User-facing functionality
- `components/` - Domain UI components
- `hooks/` - Custom hooks
- `utils/` - Domain utilities
- `types/` - TypeScript definitions
3. **Data Fetching with queryFactory Pattern**
- Create queries using queryFactory for consistency and validation:
```typescript
export const { useQuery: usePoolData, invalidate: invalidatePool } = queryFactory({
queryKey: (params: PoolParams) => ['pool', params] as const,
queryFn: async ({ chainId, poolId }) => {
const curve = await getCurve(chainId)
return curve.getPool(poolId)
},
staleTime: '5m',
validationSuite: poolValidationSuite,
})
```
- Use in components: `const { data, isLoading } = usePoolData({ chainId, poolId })`
4. **Mutations with TanStack Query**
```typescript
export const useAddRewardToken = ({ chainId, poolId }: GaugeParams) => {
return useMutation({
mutationKey: ['addRewardToken', { chainId, poolId }],
mutationFn: async (params) => {
const curve = await getCurve(chainId)
return curve.gauge.addRewardToken(params)
},
onSuccess: () => {
notify('Success', 'success')
queryClient.invalidateQueries({ queryKey: ['distributors', { chainId, poolId }] })
},
onError: () => notify('Failed', 'error'),
})
}
```
5. **Validation with Vest**
```typescript
import { group, test } from 'vest'
import { enforce } from 'vest/enforce'
export const poolValidationGroup = ({ chainId, poolId }: PoolParams) =>
group('pool', () => {
test('chainId', () => {
enforce(chainId).message('Chain ID required').isNotEmpty()
enforce(chainId).message('Invalid chain ID').isNumber()
})
test('poolId', () => {
enforce(poolId).message('Pool ID required').isNotEmpty()
})
})
```
6. **Routing with TanStack Router**
- Create routes in `/apps/main/src/routes/` with hierarchical structure
- Pattern: rootRoute → domainLayoutRoute → featureRoute
- Network-specific URLs: `/[domain]/[network]/[feature]`
7. **Blockchain Integration**
- Use Wagmi v2 + Viem for new code (migration from ethers.js in progress)
- Access wallet via ConnectionContext: `const { wallet, provider, chainId, switchChain } = useConnection()`
- Curve protocol APIs: `@curvefi/api` (main), `@curvefi/llamalend-api` (lending/minting)
8. **UI Component Development**
- Prefer curve-ui-kit (MUI-based) for new components
- Create Storybook stories for all new UI components
- Run `yarn storybook` on port 6006 to develop in isolation
- Use MUI's sx prop or styled() instead of styled-components
9. **Testing**
- E2E tests: `cd tests && yarn cy:open:e2e` (requires `yarn dev` running)
- Component tests: `cd tests && yarn cy:open:component`
- Write tests in `/tests/cypress/e2e/` or `/tests/cypress/component/`
10. **Migration Guidelines**
- **Zustand → TanStack Query**: Replace store slices with queryFactory queries
- **Ethers → Viem/Wagmi**: Use Viem utilities (`isAddress`, `isAddressEqual`, `zeroAddress`)
- **Styled Components → curve-ui-kit**: Use MUI components with sx prop
- **React Hook Form → Controlled components**: Use local state + Vest validation
**Complete Feature Flow:**
1. Create query in `entities/`: `queryFactory` with validation
2. Create mutation in `features/`: `useMutation` with invalidation
3. Build component in `components/`: Use curve-ui-kit + domain query/mutation
4. Define route in `routes/`: TanStack Router with params
5. Write tests in `tests/`: Cypress E2E + component tests
6. Add Storybook story if new UI component
Leave a review
No reviews yet. Be the first to review this skill!
# Download SKILL.md from killerskills.ai/api/skills/curve-frontend-dapp-development/raw