Skip to content

Commit bc2788e

Browse files
authored
Initial Claude setup (#4122)
# Description Add instructions for Claude to work more efficiently. Expect .env.claude with secrets filled in. Contact me. None of this was written by hand. To put together the order debugging document I took transcripts of both Felix's talks on the topic and our internal docs and threw it at Claude. Then I tried it for an order and made some edits. # Changes - [x] Sets up MCP servers for main DB and analytics DB - [x] Sets up MPC for fetch - [x] Add CLAUDE.md instructing Claude about the project and coding practices (formatting, style, etc.) - [x] Adds a document telling Claude how to debug orders so it knows what to do next time you ask him "y order {uid} not filled" - [x] Added a comman so you can run `/debug-order 0xd997dc715a7610c75e5f97548685befacb7ea5ad878cb4bac1816903514ed84d1dffc418c0d83bd8b98ab3d2e07b83bf5439f4236981a392` within Claude Code ## How to test Ask Claude Coe to do stuff for you. <!-- ## Related Issues Fixes # -->
1 parent fde29a4 commit bc2788e

5 files changed

Lines changed: 862 additions & 0 deletions

File tree

.claude/commands/debug-order.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
---
2+
description: Debug why a CoW Protocol order failed to match
3+
---
4+
5+
Debug order: $ARGUMENTS
6+
7+
Read and follow the instructions in ./docs/COW_ORDER_DEBUG_SKILL.md to investigate this order.
8+
9+
Key steps:
10+
1. Parse the order UID and network from arguments (default: mainnet)
11+
2. Fetch order data from API to get status and details
12+
3. Check order_events in DB for lifecycle events
13+
4. Search Victoria Logs for the order UID
14+
- For finding discarded solutions where the order UID appears in calldata, use regex: `.*ORDER_UID_WITHOUT_0X.*` plus `discarded`
15+
5. Identify root cause and report findings with evidence
16+
6. If you haven't found anything go wild and try all SQL / log searches / codebase searches you can think of
17+
18+
Always show your evidence (log lines, DB results, API responses) when presenting findings.

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@
55
/.idea
66
**/testing.*.toml
77
/playground/.env
8+
.env.claude

.mcp.json

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"mcpServers": {
3+
"postgres-protocol": {
4+
"command": "/bin/bash",
5+
"args": [
6+
"-c",
7+
"set -a && source .env.claude && set +a && npx -y @modelcontextprotocol/server-postgres \"${COW_DB_URL}\""
8+
]
9+
},
10+
"postgres-analytics": {
11+
"command": "/bin/bash",
12+
"args": [
13+
"-c",
14+
"set -a && source .env.claude && set +a && npx -y @modelcontextprotocol/server-postgres \"${COW_ANALYTICS_DB_URL}\""
15+
]
16+
},
17+
"fetch": {
18+
"command": "/bin/bash",
19+
"args": [
20+
"-c",
21+
"set -a && source .env.claude && set +a && /opt/homebrew/bin/uvx mcp-server-fetch"
22+
]
23+
}
24+
}
25+
}

CLAUDE.md

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
# Cow Protocol Services
2+
3+
Backend services for Cow Protocol, a decentralized trading protocol with batch auctions on EVM networks.
4+
5+
## Project Structure
6+
7+
This is a Rust workspace containing multiple services and libraries:
8+
9+
### Main Services (Binaries)
10+
- **orderbook** - HTTP API for order submission and queries
11+
- **autopilot** - Protocol driver that manages auctions
12+
- **driver** - Handles liquidity collection and solution selection
13+
- **solvers** - Internal solver engine (baseline)
14+
- **refunder** - Handles refunds
15+
16+
### Key Libraries
17+
- **shared** - Common functionality (pricing, liquidity, gas estimation)
18+
- **database** - PostgreSQL abstraction and migrations
19+
- **model** - Serialization models for API
20+
- **contracts** - Smart contract bindings
21+
22+
## Architecture Overview
23+
24+
```
25+
User signs order → Orderbook validates → Autopilot includes in auction
26+
27+
┌─────────────────────────┴─────────────────────────┐
28+
↓ ↓
29+
Colocated External Solvers Our Drivers + Non-Colocated Solvers
30+
(run their own driver+solver) ↓ ↓
31+
│ Our solvers External solver APIs
32+
│ (baseline, (non-colocated partners
33+
│ balancer, ...) like 1inch, 0x, etc)
34+
└─────────────────────────┬─────────────────────────┘
35+
36+
Autopilot ranks solutions, picks winner(s)
37+
38+
Winning driver submits to chain (2-3 block window)
39+
40+
Settlement contract executes:
41+
1. Pre-interactions (incl user pre-hooks)
42+
2. Transfer sell tokens in
43+
3. Main interactions (swaps/routing)
44+
4. Pay out buy tokens
45+
5. Post-interactions (incl user post-hooks)
46+
47+
Circuit breaker monitors compliance
48+
```
49+
50+
**Solver types:**
51+
- **Colocated**: External partners run their own driver + solver. Full control, full responsibility.
52+
- **Non-colocated**: We run the driver, configured with their solver API endpoint. We handle simulation/submission.
53+
54+
**Key components:**
55+
- **Orderbook**: Validates + stores orders, handles quoting
56+
- **Autopilot**: Central auctioneer, runs every ~12-15s (eventually every block), filters orders, adds fee policies, sends auction to solvers, ranks solutions
57+
- **Driver**: Fetches liquidity, encodes solutions to calldata, simulates, submits to chain. Handles everything except route-finding.
58+
- **Solver Engine**: Pure math — finds best routes/matches. Can be internal (baseline, balancer) or external API calls.
59+
- **Circuit Breaker**: Monitors on-chain settlements match off-chain auction outcomes. Jails misbehaving solvers.
60+
61+
## Technology Stack
62+
63+
- **Language**: Rust 2021+ Edition
64+
- **Runtime**: Tokio async
65+
- **Database**: PostgreSQL with sqlx
66+
- **Web3**: Alloy
67+
- **HTTP**: Axum
68+
69+
## Documentation
70+
71+
- **Protocol Documentation**: https://docs.cow.fi/
72+
- Technical Reference: API specs and SDK docs
73+
- Concepts: Protocol fundamentals and architecture
74+
75+
## Testing
76+
77+
- Use `just` commands for running tests (see Justfile)
78+
- E2E tests available in `crates/e2e`
79+
- Local development environment in `playground/`
80+
81+
## Directory Structure
82+
83+
```
84+
crates/ # 25+ Rust crates (binaries + libraries)
85+
database/ # PostgreSQL migrations and schemas
86+
playground/ # Local dev environment
87+
configs/ # Configuration files
88+
```
89+
90+
# General Coding Instructions
91+
92+
If there is a test you can run then run it or `cargo check` or `cargo build`; run it after you have made changes.
93+
Use rust-analyzer MCP when appropriate such as finding usages or renaming. After a change run "cargo +nightly fmt".
94+
95+
## Code Style
96+
97+
Instead of using full paths like `volume_fee_bucket_overrides: Vec<shared::arguments::TokenBucketFeeOverride>`, import the type at the beginning so you don't have to use the full path later.
98+
99+
Don't add a lot of comments. Add comments only if the code is a bit weird or the concept is not clear.
100+
101+
## CoW Protocol Database Access
102+
103+
**Always show the SQL query before executing it** against postgres MCP tools (`mcp__postgres-protocol__query`, `mcp__postgres-analytics__query`).
104+
105+
**Query timeout**: MCP servers are configured with a 120 second timeout. For potentially long-running queries, prefix with `SET statement_timeout = '30s';` (or appropriate duration) to fail fast:
106+
```sql
107+
SET statement_timeout = '30s';
108+
SELECT ... FROM large_table ...;
109+
```
110+
If a query times out, try a different approach (add more filters, use a smaller time range, simplify aggregations, or break into smaller queries).
111+
112+
Read-only replica available via MCP. If that fails for some reason, then you can use psql with:
113+
```bash
114+
source .env.claude && PGPASSWORD="$COW_DB_PASSWORD" psql \
115+
-h "$COW_DB_HOST" -p "$COW_DB_PORT" -U "$COW_DB_USER" -d <database> -c "<query>"
116+
```
117+
but use MCP where possible.
118+
119+
Databases: `mainnet`, `arbitrum-one`, `base`, `linea`, `polygon`, `xdai`, `sepolia`, `plasma`, `ink`, `bnb` etc.
120+
121+
## RPC Node
122+
123+
Use `$ETH_MAINNET_RPC` from `.env.claude` for mainnet. Use `cast` or whatever tools you want freely.
124+
125+
## Grafana Logs Access
126+
127+
Query logs via the Grafana API (credentials in `.env.claude`):
128+
129+
```bash
130+
source .env.claude && curl -s -H "Authorization: Bearer $GRAFANA_API_TOKEN" \
131+
"$GRAFANA_URL/api/ds/query" \
132+
-X POST -H "Content-Type: application/json" \
133+
-d '{
134+
"queries": [{
135+
"refId": "A",
136+
"datasource": {"type": "victoriametrics-logs-datasource", "uid": "'"$VICTORIA_LOGS_DATASOURCE_UID"'"},
137+
"expr": "<search_term>",
138+
"queryType": "instant"
139+
}],
140+
"from": "now-1h",
141+
"to": "now"
142+
}'
143+
```
144+
Adjust expr for search terms (e.g., plasma, ink, error)
145+
Adjust from/to for time range (e.g., now-15m, now-24h)
146+
Parse log lines with: | jq -r '.results.A.frames[0].data.values[1][]'
147+
148+
## Etherscan API (V2)
149+
150+
Use MCP `mcp__fetch__fetch` tool. API Key in `.env.claude` as `$ETHERSCAN_API_KEY`.
151+
152+
**Important**: V1 API is deprecated. Use V2 with the `chainid` parameter:
153+
- Mainnet: `chainid=1`
154+
- Arbitrum: `chainid=42161`
155+
- Base: `chainid=8453`
156+
157+
Example URL format:
158+
```
159+
https://api.etherscan.io/v2/api?chainid=1&module=account&action=balance&address=<addr>&tag=latest&apikey=<key>
160+
```
161+
162+
Read the API key from `.env.claude` and use it directly in the URL (MCP fetch doesn't do shell variable substitution).
163+
164+
## Investigating orders
165+
166+
When asked to look into what happened to an order read file ./docs/COW_ORDER_DEBUG_SKILL.md and follow the instructions there.
167+
Make heavy use of logs and DB to find all info you need and present finding to the user with evidence.

0 commit comments

Comments
 (0)