# Changelog All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] ## [0.5.0] — 2026-05-15 ### Added (Phase 3/4 roadmap — merged 2026-05-13) - **GMX V2 Synthetics adapter** — `gmx.service.ts` with market data, execution fee calculation, and market resolution for Arbitrum. `buildGmxCreateOrder()` in the transaction builder encodes ExchangeRouter multicall for MarketIncrease/Decrease and LimitIncrease/Decrease orders. Two new routes (`POST /v1/transactions/gmx-open`, `POST /v1/transactions/gmx-close`) and three MCP tools (`list_gmx_markets`, `open_gmx_position`, `close_gmx_position`). Schema: `GMX_OPEN`, `GMX_CLOSE` added to `TxType` enum (migration 0011). GMX contract addresses configured for Arbitrum (42161). - **EscrowModule.sol** — on-chain custody contract for A2A job payments. Supports ETH and ERC-20 lock/release/refund with operator-only settlement (mirrors AgentPolicyModule trust model). 22 Foundry tests pass including 3 fuzz tests (256 runs each). Deploy.s.sol updated to deploy EscrowModule alongside existing contracts. - **On-chain escrow backend integration** — `escrow-onchain.service.ts` wraps EscrowModule for the backend (builds lock/release/refund calldata via viem). `escrow.service.ts` conditionally queues on-chain lock at job creation when EscrowModule is deployed; `payment-finalizer.service.ts` queues on-chain release (CONFIRMED) or refund (FAILED). Falls back to DB-only escrow when contract is absent — zero behavior change for chains without it. Schema: `ESCROW_LOCK`, `ESCROW_RELEASE`, `ESCROW_REFUND` added to `TxType` (migration 0012). Config: `ESCROW_MODULE_ADDRESS_` env vars for all chains. - **Revenue sharing — Operator model** — new `Operator` table (name, walletAddress, revShareBps default 20%, contactEmail). `Agent.operatorId` optional FK links agents to their managing operator. `OperatorRevenue` records per-fee-event split between operator and protocol. `OperatorSettlement` tracks payout lifecycle (PENDING → PROCESSING → SETTLED/FAILED). Migration 0013. - **Revenue sharing — fee splitting** — `FeeService.recordFeeEvent()` now auto-accrues the operator's share via `OperatorService.accrueRevenue()` when the agent has an active operator. Fire-and-forget; failure is non-fatal. - **Revenue sharing — admin endpoints** — `POST/GET /admin/operators` (create/list), `GET /admin/operators/:id` (stats: agent count, pending/accrued/settled revenue), `POST/DELETE /admin/agents/:id/operator` (assign/remove), `POST/GET /admin/settlements` (create/list), `PATCH /admin/settlements/:id/complete|fail`. - **Contract deployment runbook expanded** — `docs/operations/contract-deployment.md` rewritten from Base-only to multi-chain: prerequisites, per-chain deployment checklist, fee configuration table, post-deployment verification (manual + automated via `scripts/verify-deployment.sh`), address registry, Safe module installation, disaster recovery (wrong params, mid-tx failure, emergency pause, fee BPS change). - **Deployment verification script** — `scripts/verify-deployment.sh` uses `cast` to verify operator, feeWallet, feeBps, policyModule, and (optionally) EscrowModule operator on any chain. ### Changed (breaking — mcp-server 0.2.0 → 0.3.0) - **MCP tool rename: `request_policy_update` → `update_policy`.** Closes step 6 of [#49](https://github.com/felippeyann/agentfi/issues/49). The old name + description implied an operator-approval workflow; the tool actually wrote the policy immediately. Renamed honestly and rewrote the description: _"applies IMMEDIATELY — there is no operator approval step. The operator can audit and revert via the admin panel."_ `reason` field is still required and logged for audit but does not gate the write. `@agent_fi/mcp-server` bumped to **0.3.0** (SemVer breaking); no deprecated alias — pre-1.0 project, clean rename. ### Added - **MCP agent self-inspection tools** — source package `@agent_fi/mcp-server@0.4.0` adds `get_my_agent_profile` and `get_my_pnl`, and the backend `/mcp/sse` proxy exposes matching tools. This lets agent clients inspect identity/policy/billing and P&L directly through MCP instead of dropping to REST. - **Claude Desktop MCP demo helper** — `npm run demo:claude-mcp` registers a local provider/requester pair, publishes a demo manifest, prints a two-server Claude Desktop config, and emits prompts for discovery, A2A job flow, trust, and P&L. Documented at [`docs/demos/claude-desktop-mcp.md`](docs/demos/claude-desktop-mcp.md). - **Graphify code graph** — committed `graphify-out/GRAPH_REPORT.md`, `graph.json`, and `graph.html` plus `AGENTS.md` guidance so agents can navigate the codebase through a queryable graph before broad grep/file reads. - **Dev smoke test** — `npm run smoke:dev` runs a zero-dependency first-run validation against the local dev stack: health, agent registration, manifest publish, agent search, no-reward A2A job completion, trust report, and P&L response shape. - **A2A handshake — `sign_handshake` / `verify_handshake` implemented.** Closes steps 3–5 of [#49](https://github.com/felippeyann/agentfi/issues/49); previously both returned 501. - `POST /v1/agents/me/sign-handshake` now signs an arbitrary message with the agent's wallet via EIP-191 `personal_sign`. `LocalWalletService` uses viem's `signMessage`; `TurnkeyService` uses `signRawPayload` with `HASH_FUNCTION_NO_OP` after pre-hashing with viem's `hashMessage`, then assembles a standard 65-byte r‖s‖v signature. - `POST /v1/agents/verify-handshake` (public) accepts `{ message, signature, address }` or `{ message, signature, agentId }`. Tries ECDSA recovery first (works for EOA); falls back to EIP-1271 via the chain's public client for contract wallets (Safe). Returns `{ valid, address, verifiedVia: 'ecdsa' | 'eip1271' }`. - 4 unit tests cover local sign → viem recover round-trip, tampered-message rejection, multi-wallet isolation. - **`POST /v1/public/agents`** — open self-registration endpoint for autonomous agents. Resolves the first half of [#49](https://github.com/felippeyann/agentfi/issues/49) (VISION.md's "agents that can provision and fund their own wallets"). No operator `API_SECRET` required. Tier forced to `FREE` regardless of body. Per-IP rate limit via `PUBLIC_REGISTRATION_RATE_LIMIT_PER_HOUR` (default 5/hour, operator-configurable, `0` disables). Shared `provisionAgent()` helper refactored out; OpenAPI spec + types regenerated. - **`examples/delegation-chain/`** — three-agent cascade showing agents hiring agents through the job queue (Alice → Bob → Charlie, return path assembled back up). Demonstrates the coordination substrate behind VISION.md's agent-economy claim. Runs on the zero-credential dev stack (no rewards → no chain tx); adds a one-line `reward` field to graduate to atomic on-chain payment at every hop. Documented at [`examples/delegation-chain/README.md`](examples/delegation-chain/README.md). - **`examples/swap-planner/`** — DeFi planning pipeline example: registers an agent on Base with a strict policy (max-per-tx, allowed contracts, token allowlist), inspects the policy state, then simulates a 10 USDC → WETH swap via Uniswap V3. Runs on the zero-credential dev stack (USDC Base decimals come from the local token registry → no RPC; Tenderly gracefully degrades to mocked success). Graduates to real execution by swapping `/v1/transactions/simulate` → `/v1/transactions/swap`. Documented at [`examples/swap-planner/README.md`](examples/swap-planner/README.md). - **`examples/a2a-collab/`** — end-to-end two-agent example that registers Alice (provider) + Bob (requester), publishes a service manifest, searches, creates + accepts + completes a job, and inspects reputation + P&L. ~150 lines of Node 22 native-fetch, zero dependencies, works against the zero-credential dev stack (no on-chain payment). Documented at [`examples/a2a-collab/README.md`](examples/a2a-collab/README.md). - **Zero-credential dev quickstart** — new `LocalWalletService` (in-memory viem keys), pluggable via `WALLET_PROVIDER=local` env, paired with `docker-compose.dev.yml` and [`docs/dev-quickstart.md`](docs/dev-quickstart.md). `git clone` → `docker compose up` → running in ~3 minutes, no external accounts required. Production boot with `WALLET_PROVIDER=local` is refused at env validation (keys would be lost on restart). - **`WalletService` factory** at `packages/backend/src/services/wallet/index.ts` selects Turnkey or Local based on `WALLET_PROVIDER`; all three call sites (agent registration, health check, tx submitter) now go through the factory. - **9 unit tests** for `LocalWalletService` — wallet creation, distinct addresses, signing with signature recovery, lookup errors, list, health. - **README badges** — npm version, npm monthly downloads. - **`STATE.md`** at the repo root — comprehensive, point-in-time project state (purpose, stack, capabilities, phase progress). Sits between VISION.md (the _why_) and HANDOFF.md (live tasks) as required reading. - **README.md** refreshed to reflect shipped work: ENS identity, OpenAPI spec, mcp-server v0.2.0 on npm, P&L v2 with gas costs. Getting-Started-for-Operators section now points at the provider-agnostic deployment guide. - **HANDOFF.md** "Files to Read First" ordering updated to include STATE.md. ### Fixed - **A2A reward accounting decimals** — escrow reservations, payment revenue snapshots, and P&L live fallbacks now share a local token registry for non-native reward tokens instead of assuming every ERC-20 reward has 6 decimals. Known USDC/WETH-style rewards are priced with chain-local decimals; unknown ERC-20 rewards resolve explicitly as unresolved instead of silently guessing. - **Zero-credential Docker first-run path** — fresh `docker compose -f docker-compose.dev.yml up --build` now boots all five services healthy and passes `npm run smoke:dev` plus the three example scripts. - API dev compose runs `prisma migrate deploy` before Fastify starts, so a clean Postgres volume has the required tables. - Docker healthchecks use `127.0.0.1` to avoid Alpine resolving `localhost` to IPv6 `::1` when services listen on IPv4. - Admin Docker image sets `HOSTNAME=0.0.0.0` so Next standalone is reachable inside the container and through host port mapping. - MCP Docker image copies workspace-local `packages/mcp-server/node_modules`, fixing TypeScript 6 builds that could not resolve `dotenv/config`. - Standalone MCP dev compose gets a placeholder `AGENTFI_API_KEY` so the SSE service can boot before a real agent key exists. - **Public discovery auth** — global agent-key middleware now skips the public routes already documented as unauthenticated: `/v1/agents/search`, `/v1/agents/:id/manifest`, `/v1/agents/:id/trust-report`, and `/v1/agents/verify-handshake`. ### Changed - **Operator setup checklist clarified** — `docs/operations/setup-checklist.md` now separates dev quickstart, real-chain local testing, and production. It documents `WALLET_PROVIDER=local` as dev-only, removes stale deploy/preflight-scenario commands, and makes Turnkey/Alchemy/Postgres/Redis requirements explicit for production operators. - **Self-hosted deployment posture**: AgentFi has no canonical hosted production instance — every operator runs their own. Docs rewritten to reflect this: `docs/operations/production-deploy.md` is now provider-agnostic (Railway as reference example, Fly.io/Render/Docker documented as alternatives); `release-runbook.md` updated accordingly. ### Removed - `.github/workflows/deploy-production.yml` — custom Railway-CLI deploy workflow. Provider-native GitHub integrations (Railway/Fly/Render) auto-deploy on merge to `main` or on tag; the custom workflow added coupling without value. - `scripts/check-production-deploy-env.mjs` and `scripts/run-deploy-preflight-scenarios.mjs` — preflight tied to the deleted workflow. - `Deploy Preflight Check` CI job (ci.yml) — validated the removed preflight script; not a required status check. - Preflight invocation in `scripts/release-v1.mjs`. ### Added - **OpenAPI 3.0.3 spec** at [`docs/api/openapi.yaml`](docs/api/openapi.yaml) — machine-readable description of all 47 endpoints, with auth schemes, request/response schemas, and reusable error responses. Enables SDK generation, Postman/Insomnia import, and `openapi-typescript` type generation. Validates clean under `@redocly/cli lint`. - **Generated TypeScript types** at `packages/mcp-server/src/api.generated.ts`, produced from the OpenAPI spec by `openapi-typescript`. MCP tools (and any future SDK) can now import `components['schemas']['PnLBreakdown']`, `['Agent']`, etc. instead of re-declaring them. - **New npm scripts at repo root**: `spec:lint` (Redocly lint), `spec:types` (regenerate types), `spec:check` (CI drift check — fails if the generated file is stale relative to the spec). - **New CI job** `OpenAPI Spec` runs the lint + drift check on every PR, so the spec and generated types can't drift apart unnoticed. - **Agent Persistent Identity via ENS (Phase 4)**: when `ENS_PARENT_DOMAIN` + `ENS_CONTROLLER_PRIVATE_KEY` are configured, every new agent gets a subdomain of the form `-.` (e.g., `alice-abc123.agentfi.eth`) that resolves to its Safe address — other dApps, explorers, and peer agents can reference agents by name instead of hex address - New `EnsService` in `packages/backend/src/services/identity/ens.service.ts` — wraps ENS Registry `setSubnodeRecord` + public resolver `setAddr` via viem - `ensName` field on Agent model (migration `0007_agent_ens`) — unique, nullable - `ensName` exposed in `POST /v1/agents`, `GET /v1/agents/me`, `GET /v1/agents/:id`, and `GET /v1/agents/:id/manifest` responses - Registration is best-effort: on-chain failures are logged and leave `ensName: null`, so agent creation still succeeds - **Agent P&L v2 — Gas cost tracking (Phase 4)**: `PnLService` now counts real gas burn as a cost category - Migration 0006: adds `effectiveGasPriceWei` TEXT to `Transaction` - `MonitorService` persists `receipt.effectiveGasPrice` at confirmation time (same for E2E test poller) - New cost category `costs.gas` in the P&L breakdown — `usd = gasUsed * effectiveGasPriceWei * ETH/USD`, summed across CONFIRMED + REVERTED txs in the period (REVERTED txs still burn gas on-chain) - Pre-migration rows with missing `gasUsed`/`effectiveGasPriceWei` are skipped and reported in `notes` - `PnLService` constructor now accepts an optional `PrismaClient` (defaults to the shared client) so it is unit-testable without a live DB - New unit test `pnl.service.test.ts` — 8 cases covering gas math, REVERTED handling, missing-row skipping, profitability thresholds - **Fastify upgraded to v5** — resolves the last HIGH npm vulnerability (DoS via sendWebStream, content-type tab bypass, X-Forwarded-Proto spoofing). All plugins were already v5-compatible from prior Dependabot updates — zero code changes needed. - `packages/mcp-server/RELEASE.md` — complete publish guide for bumping the mcp-server npm package (versioning, keywords, npm publish, git tags, MCP directory submissions) - **Curve Finance StableSwap adapter**: `POST /v1/transactions/swap-curve` — token-to-token swaps on any Curve classic pool (3pool, tri-pool, etc.) - `TransactionBuilder.buildCurveSwap()` method with `CURVE_STABLESWAP_ABI` - MCP tool `swap_curve` in standalone mcp-server package and backend MCP proxy (16 total tools) - mcp-server version bumped to `0.2.0` (adds Compound, ERC-4626, and Curve tools since `0.1.0`) - **Agent P&L Dashboard (Phase 4)**: per-agent profit & loss computed from real DB data - New `PnLService` in `packages/backend/src/services/billing/pnl.service.ts` - `GET /v1/agents/me/pnl` — agent-facing P&L with earnings, costs, breakeven status - `GET /admin/agents/:id/pnl` — admin version for any agent - Both accept optional `?since=` query param - Earnings: A2A job rewards received as provider (COMPLETED jobs) - Costs: protocol fees paid + A2A rewards paid as requester - Directly serves VISION.md thesis: "the moment an agent's earnings exceed its costs..." - **A2A Escrow v2**: reward funds are reserved at job creation time and released on terminal state - New `EscrowService`: `reserveJobEscrow()`, `releaseJobEscrow()`, `markEscrowReleased()` - Migration 0005: adds `reservedAmount`, `reservedToken`, `reservedChainId`, `reservedAt`, `reservationStatus` to Job - `POST /v1/jobs` with reward now atomically commits USD volume and rejects if daily limit would be exceeded - `PATCH /v1/jobs/:id` releases escrow on CANCELLED/FAILED (returns daily volume credit) or marks RELEASED on COMPLETED - **ERC-4626 vault adapter**: generic tokenized vault support — any compliant vault (Yearn, Morpho, Beefy, Gearbox, etc.) works without pre-registration - `POST /v1/transactions/deposit-erc4626` and `POST /v1/transactions/withdraw-erc4626` - `TransactionBuilder.buildErc4626Deposit()` and `buildErc4626Withdraw()` methods - `ERC4626_VAULT_ABI` constant (deposit, withdraw, redeem, asset) - MCP tools `deposit_erc4626` and `withdraw_erc4626` in mcp-server + backend proxy (15 total tools) - **Reputation Scoring v2.1 (time-decay)**: recent 30-day transactions and job outcomes now carry 2x weight vs historical events - **Daily Reputation Cron**: BullMQ repeatable job recomputes all active agents' scores daily at 02:00 UTC (override via `REPUTATION_CRON_PATTERN`) - `packages/backend/src/queues/reputation.queue.ts` — new queue, worker, and `scheduleReputationUpdate()` - **Compound V3 integration**: `POST /v1/transactions/supply-compound` and `POST /v1/transactions/withdraw-compound` - `TransactionBuilder.buildCompoundSupply()` and `buildCompoundWithdraw()` methods - `COMPOUND_COMET_ABI` constant for Comet market contracts - Compound V3 USDC market addresses added to `contracts.ts` (Mainnet, Base, Arbitrum, Polygon) - **MCP tools `supply_compound` and `withdraw_compound`** exposed in both the standalone mcp-server package and the backend MCP endpoint (13 total tools) - **Reputation Scoring v2**: computed from real behavior metrics (tx success rate 40%, job completion rate 30%, volume score 20%, consistency 10%) instead of simple counter - `ReputationService.computeReputationScore()`, `refreshReputation()`, `updateAllReputationScores()` - Admin endpoints: `POST /admin/reputation/recompute` (all or single agent), `GET /admin/reputation/:agentId` (shows persisted vs computed drift) - **A2A Payment Execution**: `executeA2APayment()` function in transactions.ts - Jobs PATCH handler now auto-triggers atomic payment when status transitions to COMPLETED (if `reward` is specified) - Payment runs async with full policy + simulation + fee calculation, same as public transfer endpoint - Migration 0004: ON DELETE CASCADE for Job to Agent foreign keys - SECURITY.md vulnerability disclosure policy - CHANGELOG.md release history - CODE_OF_CONDUCT.md (Contributor Covenant v2.1) - GitHub issue templates (bug report, feature request) - GitHub pull request template - Dependabot configuration for automated dependency updates - `prisma migrate deploy` step in CI Backend Tests job - E2E polling helpers: `waitForFeeEvent()` and `waitForDailyVolume()` - API reference documentation (`docs/api-reference.md`) - Package READMEs for backend, admin, and contracts - GitHub CI and license badges in main README - `.github/CODEOWNERS` for code review routing - Apache 2.0 license and repository fields in all package.json files - VISION.md referenced as required reading in README, CONTRIBUTING, docs hub, and claude-instructions - Roadmap updated with Phase 2.5 (hardening), Phase 3 (A2A primitives), Phase 4 (self-sustaining) - Published `@agent_fi/mcp-server@0.1.0` to npm - Branch protection ruleset on `main` (require PR + status checks) - npm scope changed from `@agentfi` to `@agent_fi` ### Changed - Branch consolidation: all development unified on `main` (default), `master` deleted - CI workflow triggers updated from `master` to `main` - Next.js upgraded from v14 to v16 (admin dashboard) - Dockerfiles now run as non-root user (`appuser:1001`) ### Fixed - FK constraint violation in test cleanup (Job records blocking Agent deletion) - Test cleanup order in agent.search.test.ts and transaction.e2e.ts - NODE_ENV validation: added 'test' to accepted enum values - CI Backend Tests: database migrations now applied before running unit tests - E2E flaky test: FeeEvent assertion now uses polling instead of 2s setTimeout - E2E FeeEvent test: set `routedViaExecutor: true` (was `false`, preventing FeeEvent creation) - npm dependency vulnerabilities (path-to-regexp, picomatch, Next.js HIGH severity) ### Security - Admin secret comparison now uses `timingSafeEqual` (prevents timing attacks) - Daily volume limit check is now atomic (prevents TOCTOU race condition) - Agent search endpoint no longer exposes `safeAddress` in public responses - Admin batch endpoint validates Ethereum address format - Auth middleware: early return on failed operator secret prevents fall-through ### Removed - `desktop.ini` from repository (added to .gitignore) - Placeholder A2A signature generation (security risk) - Placeholder A2A verification returning `valid: true` unconditionally ## [0.1.0] - 2026-03-25 ### Added - Initial release - Agent registration with Turnkey MPC wallets - Safe smart wallet deployment per agent - Transaction pipeline: API, Policy, Fee, Queue, Submit, Monitor - AgentPolicyModule and AgentExecutor smart contracts (Solidity 0.8.24) - Protocol fee engine (FREE: 30bps, PRO: 15bps, ENTERPRISE: 5bps) - Human-in-the-Loop (HITL) approval system for high-value transactions - A2A (Agent-to-Agent) job queue with reputation tracking - X402 payment protocol with nonce replay protection - Admin dashboard (Next.js 14) - MCP server with 10+ DeFi tools - Multi-chain support (Ethereum, Base, Arbitrum, Polygon) - E2E test suite with local Anvil node - Foundry contract tests with coverage - CI/CD pipeline (GitHub Actions + Railway) - Documentation hub with operator guides and agent quickstart [Unreleased]: https://github.com/felippeyann/agentfi/compare/v0.1.0...HEAD [0.1.0]: https://github.com/felippeyann/agentfi/releases/tag/v0.1.0