{
  "markdown": "# CompraBTC\n\n**Non-custodial Bitcoin DCA agent on Celo.** Define your plan once — *$X every hour/day in BTC* — and an on-chain agent buys Bitcoin for you, straight into your own wallet. Funds never leave your wallet between purchases.\n\n- **Live app:** https://comprabtc.vercel.app (works in MiniPay and any injected wallet)\n- **Agent API:** https://comprabtc-api.vercel.app (`GET /` service descriptor · `GET /api/stats` public metrics)\n- **Built for the** [Celo Agentic Payments & DeFAI Hackathon](https://celobuilders.xyz) — [leaderboard](https://dune.com/celo/agentic-payments-defai-hackathon)\n\n## Deployed contracts (Celo mainnet, chain 42220)\n\n| Contract | Address |\n|---|---|\n| **DCAExecutor** (verified) | [`0xd03ffeBBCaaA8aA21053eEB0EeAde39EFC504189`](https://celoscan.io/address/0xd03ffeBBCaaA8aA21053eEB0EeAde39EFC504189) |\n| USDT (token in) | [`0x48065fbBE25f71C9282ddf5e1cD6D6A887483D5e`](https://celoscan.io/address/0x48065fbBE25f71C9282ddf5e1cD6D6A887483D5e) |\n| WBTC — native bridge (token out) | [`0x8aC2901Dd8A1F17a1A4768A6bA4C3751e3995B2D`](https://celoscan.io/address/0x8aC2901Dd8A1F17a1A4768A6bA4C3751e3995B2D) |\n| Uniswap V3 SwapRouter02 | [`0x5615CDAb10dc425a742d643d949a7F474C01abc4`](https://celoscan.io/address/0x5615CDAb10dc425a742d643d949a7F474C01abc4) |\n\nSwaps route through the USDT/WBTC 0.3% Uniswap V3 pool. Protocol fee: **1% + $0.005 flat** per execution, with on-chain hard caps (≤1%, ≤$0.05 flat) and a revert if the fee would ever eat the installment.\n\nAgent identity: **ERC-8004 #9665** on Celo mainnet ([8004scan](https://www.8004scan.io/agents/celo/9665)). Every transaction carries ERC-8021 attribution tags.\n\n## How it works\n\n```mermaid\nflowchart TB\n    USER[\"👤 User wallet<br/>(MiniPay / MetaMask / Valora)\"]\n    FE[\"Frontend — Next.js PWA<br/>(Vercel)\"]\n\n    subgraph onchain[\"⛓️ Celo mainnet\"]\n        USDT[\"USDT (ERC-20)\"]\n        EXEC[\"DCAExecutor<br/>0xd03f…4189<br/>non-custodial, on-chain limits\"]\n        ROUTER[\"Uniswap V3 SwapRouter02<br/>USDT/WBTC 0.3% pool\"]\n        TREASURY[\"Treasury\"]\n    end\n\n    subgraph backend[\"🤖 Agent backend — Vercel\"]\n        KEEPER[\"Keeper (Vercel Cron, 5 min)<br/>scans PlanCreated events,<br/>checks due plans\"]\n        API[\"Express API<br/>POST /api/execute<br/>(x402-gated, permissionless)\"]\n        DB[(\"Supabase<br/>plans · executions\")]\n        TG[\"Telegram bot<br/>purchase alerts + ops\"]\n    end\n\n    FACIL[\"x402 facilitator<br/>api.x402.celo.org\"]\n\n    USER -- \"① approve(budget) — once\" --> USDT\n    USER -- \"② createPlan(amount, interval) — once\" --> EXEC\n    FE -.-> USER\n    KEEPER -- \"discovers plans<br/>(PlanCreated events)\" --> EXEC\n    KEEPER -- \"③ pays 0.02 USDT via x402<br/>(EIP-3009 signature)\" --> API\n    API -- \"verify + settle\" --> FACIL\n    API -- \"④ execute(user, minOut)<br/>+ ERC-8021 attribution tags\" --> EXEC\n    EXEC -- \"⑤ transferFrom<br/>(one installment)\" --> USDT\n    EXEC -- \"fee 1% + $0.005\" --> TREASURY\n    EXEC -- \"⑥ swap USDT→WBTC\" --> ROUTER\n    ROUTER -- \"⑦ WBTC straight<br/>to the user's wallet\" --> USER\n    API -- \"records execution\" --> DB\n    API -- \"🔔 purchase alert\" --> TG\n```\n\n1. The user approves USDT to `DCAExecutor` (cap = total plan budget) and creates a plan with on-chain limits (amount per run, minimum interval). Cancelling = one click (`cancelPlan` or `approve(0)`).\n2. The keeper discovers plans from `PlanCreated` events, and each cycle pays the execution API with an **x402** micropayment before calling `execute()` — so every purchase is also an agent-to-agent payment.\n3. On-chain limits mean even a compromised keeper can't overcharge: it can never pull more than `amountPerRun` or execute before `minInterval` elapses.\n4. Users get Telegram alerts on every purchase (link from Settings in the app).\n\n## Repository layout\n\n| Directory | What it is |\n|---|---|\n| [`contracts/`](contracts/) | `DCAExecutor.sol` (Foundry) — 21 tests incl. mainnet fork tests, deploy script |\n| [`backend/`](backend/) | Express API + keeper loop (viem) + x402 middleware + Supabase + Telegram bot |\n| [`frontend/`](frontend/) | Next.js PWA (wagmi/viem) — MiniPay auto-connect, plan creation, BTC portfolio |\n| [`docs/`](docs/) | Unit economics, copy review |\n| [`PLAN.md`](PLAN.md) | Full architecture plan and piece-by-piece feasibility verification |\n\n## Running locally\n\n**Frontend** (needs `NEXT_PUBLIC_EXECUTOR_ADDRESS`, `NEXT_PUBLIC_API_URL`, `NEXT_PUBLIC_ATTRIBUTION_CODE`, `NEXT_PUBLIC_TELEGRAM_BOT` in `frontend/.env.local`):\n\n```bash\ncd frontend && pnpm install && pnpm dev   # http://localhost:3000\n```\n\n**Backend + keeper** (Node 22; see `backend/src/config.ts` for required env vars — executor address, keeper key, Supabase credentials, x402 API key; DB schema in `backend/supabase/schema.sql` + migrations in the same folder):\n\n```bash\ncd backend && pnpm install && pnpm dev    # API on :8080, keeper ticks every 60s\n```\n\nLocally the keeper runs as an in-process loop (`setInterval`). Deployed on Vercel the whole Express app is a single function and the keeper is driven by Vercel Cron hitting `GET /api/cron/keeper` (guarded by `CRON_SECRET`, schedule in `backend/vercel.json`) — serverless instances are frozen and reused, so an interval there would fire duplicated, off-schedule ticks. Anything the keeper needs to remember between ticks (alert cooldowns, digest cadence, last scanned block) lives in `agent_keeper_state`, not in memory.\n\n**Contracts:**\n\n```bash\ncd contracts && forge test                # unit + Celo mainnet fork tests\nforge script script/Deploy.s.sol --rpc-url celo --broadcast --verify --interactives 1\n```\n\n## For AI agents\n\nAn agent with its own funded wallet can set up a Bitcoin savings plan in two transactions — and so can an agent assisting a human (the web app handles the signing):\n\n- **MCP server** (treasury DCA): `claude mcp add comprabtc -- npx -y comprabtc-mcp` — tools to check status, create/renew/cancel the plan and track the portfolio, signing with the treasury's own wallet. See [`mcp/README.md`](mcp/README.md).\n- **Agent skill**: `npx skills add csacanam/comprabtc` — covers plan creation (viem), monitoring, budget math, cancelling, and the permissionless x402 execution trigger.\n- **Service descriptor** (machine-readable how-to): [`GET https://comprabtc-api.vercel.app/`](https://comprabtc-api.vercel.app/) · LLM index: [comprabtc.vercel.app/llms.txt](https://comprabtc.vercel.app/llms.txt)\n- **Agent identity**: ERC-8004 #9665 on Celo — [metadata](https://comprabtc.vercel.app/metadata.json) · [8004scan](https://www.8004scan.io/agents/celo/9665)\n\n## Transparency\n\n**Operator wallets (declared):**\n\n| Role | Address |\n|---|---|\n| Keeper (executes plans) | [`0x2F6a8283546d28506B312013F77aA38e60AF99B0`](https://celoscan.io/address/0x2F6a8283546d28506B312013F77aA38e60AF99B0) |\n| Treasury / payTo (receives fees) | [`0x6Bd5c303b2ed7E264C1Ce9D3592457292a1F1c43`](https://celoscan.io/address/0x6Bd5c303b2ed7E264C1Ce9D3592457292a1F1c43) |\n\n**On-chain volume is real user capital.** Each plan starts with a user's own `approve`; the keeper pulls one installment per run via `transferFrom` and the purchased WBTC goes straight to the user's wallet, where it stays. No custody, no round-trips — the volume is actual BTC purchases with real economic intent.\n\n**x402 is internal metering with an open door.** The keeper pays x402 on every run, so **each x402 payment maps to one real executed purchase** — not standalone dust. `/api/execute` is permissionless and auto-registers plans from on-chain events, so any external agent or human can invoke it and settle their own x402; it is not a closed loop.\n\n## Hackathon tracks\n\n- **Track 1 — on-chain revenue:** protocol fee charged inside `execute()`, every tx tagged with ERC-8021 attribution.\n- **Track 2 — x402 payments:** the keeper pays `/api/execute` per run via the Celo x402 facilitator. The endpoint is permissionless — any agent can pay to trigger an execution.\n- **Track 4 — Aigora:** agent registered on the Aigora marketplace (#395) + feedback PRs at [trionlabs/aigora-skills](https://github.com/trionlabs/aigora-skills).\n\n## License\n\nMIT\n",
  "bytes": 8095,
  "sha": "7855f7771b59131f0df206dbce4f74146f617422e0841bec372d2889e5a8a360",
  "repo_slug": "csacanam/comprabtc",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_csacanam_comprabtc_6ede83af/readme"
}