Files
timmy-config/docs/finance-integration.md
Rockachopa e99c6d4660
Some checks failed
Architecture Lint / Linter Tests (pull_request) Successful in 28s
Smoke Test / smoke (pull_request) Failing after 32s
Validate Config / YAML Lint (pull_request) Failing after 23s
Validate Config / JSON Validate (pull_request) Successful in 20s
Validate Config / Python Syntax & Import Check (pull_request) Failing after 1m5s
Validate Config / Python Test Suite (pull_request) Has been skipped
Validate Config / Shell Script Lint (pull_request) Failing after 1m4s
Validate Config / Cron Syntax Check (pull_request) Successful in 15s
Validate Config / Deploy Script Dry Run (pull_request) Successful in 13s
PR Checklist / pr-checklist (pull_request) Failing after 4m54s
Validate Config / Playbook Schema Validation (pull_request) Successful in 32s
Architecture Lint / Lint Repository (pull_request) Failing after 24s
feat: integrate USDC/x402 secure payment plugin (#965)
Add hermes-finance-plugin MCP server with approval workflows.

Changes:
- mcp/servers.json: register hermes-finance-plugin MCP server
- config.yaml: extend approvals with finance policy (threshold $10, daily cap $100)
- docs/finance-integration.md: full integration guide
- mcp/setup.sh: add Node.js + plugin installation
- bin/test-finance-payment.py: dry-run demo and smoke test script

Supported networks: Sepolia, Base Sepolia, Base, Ethereum.
Approval: payments >$10 require second signature; $100 daily cap per agent.
Security: private key via env, append-only audit logs, revocation path.

Closes #965
2026-04-29 20:25:08 -04:00

265 lines
7.6 KiB
Markdown

# USDC/x402 Payment Integration — Finance Plugin
**Ticket:** #965
**Plugin:** [hermes-finance-plugin](https://github.com/Clawnch_Bot/hermes-finance-plugin)
**Type:** MCP Server (stdio transport)
**Status:** Integrated
---
## Overview
The `hermes-finance-plugin` is an MCP server that exposes USDC/x402 payment tools to Timmy. It enables agents to:
- Send USDC on Ethereum L1 and L2s (Ethereum, Base, Base Sepolia, Sepolia)
- Enforce per-transaction and daily approval limits
- Log all payment attempts for audit
- Support multi-step approval workflows for high-value transfers
This integration configures the plugin as a sidecar MCP server in `timmy-config`, wires approval policies into `config.yaml`, and provides sandbox testing instructions.
---
## Supported Networks & Wallet Requirements
### Networks
| Network | Chain ID | x402 Enabled | Faucet |
|---------|----------|--------------|--------|
| Sepolia (testnet) | 11155111 | ✅ | https://sepoliafaucet.com |
| Base Sepolia | 84532 | ✅ | https://faucet.base.org |
| Base Mainnet | 8453 | ✅ | N/A (real funds) |
| Ethereum Mainnet | 1 | ✅ | N/A (real funds) |
### Wallet Requirements
- **Private key** stored in `FINANCE_PRIVATE_KEY` env var (no 0x prefix)
- **RPC endpoint** in `FINANCE_RPC_URL` (Infura, Alchemy, or public RPC)
- **USDC balance** — ensure sufficient funds + gas on chosen network
- **x402 marketplace support** — recipient must support x402 payment requests
---
## Approval Workflow Steps
### 1. Agent Requests Payment
Agent calls `payment_send` MCP tool with:
```json
{
"to": "0x...",
"amount_usd": 25.50,
"network": "sepolia",
"reason": "API service fee"
}
```
### 2. Threshold Evaluation
Plugin compares `amount_usd` against `FINANCE_APPROVAL_THRESHOLD_USD` (default: $10):
- **≤ $10** → auto-approved, transaction proceeds
- **> $10** → requires second signature (manual approval step)
### 3. Approval Routing
For amounts > $10, the plugin:
1. Logs approval request to `~/.hermes/logs/finance_approvals.jsonl`
2. Sends approval request via configured notifier (see `config.yaml``notifications`)
3. Waits for explicit `payment_approve` or `payment_reject` signal
4. Proceeds only after approval or times out after 24h
### 4. Daily Cap Enforcement
The plugin maintains a rolling 24h spend ledger per agent in `~/.hermes/logs/finance_spend.jsonl`. If an agent's total since yesterday exceeds `FINANCE_DAILY_CAP_USD` (default: $100), all payment requests are rejected until the window slides.
---
## Rate Limiting & Daily Caps
**Rate limiting:** Built into the x402 protocol itself — each payment request is EIP-712 signed and non-replayable.
**Daily caps:** Per-agent accounting enforced client-side by the plugin. Ledger location:
```
~/.hermes/logs/finance_spend.jsonl
```
Sample ledger entry:
```json
{
"timestamp": "2026-04-29T12:34:56Z",
"agent_id": "allegro",
"tx_hash": "0xabc123...",
"amount_usd": 25.00,
"network": "sepolia",
"to": "0xrecipient...",
"status": "completed"
}
```
---
## Configuring Approval Policies
Add the following to `config.yaml` under `approvals:`:
```yaml
approvals:
mode: manual
finance:
threshold_usd: 10 # Payments > $10 require second signature
daily_cap_usd: 100 # Daily limit per agent
require_second_signature: true
enabled_networks:
- sepolia
- base-sepolia
- base
- ethereum
```
Configurable via environment variables (take precedence):
- `FINANCE_THRESHOLD_USD`
- `FINANCE_DAILY_CAP_USD`
- `FINANCE_REQUIRE_SECOND_SIGNATURE` (true/false)
---
## Setup & Installation
### Prerequisites
- Node.js ≥ 18 (for npx)
- npm or yarn
- Access to a funded testnet wallet (Sepolia or Base Sepolia)
### One-line Install
```bash
cd ~/.timmy/timmy-config/mcp
bash setup.sh
```
The `setup.sh` script:
1. Verifies Node.js installation
2. Installs `hermes-finance-plugin` via npm
3. Validates environment variables
4. Runs a smoke test with `--dry-run`
### Environment Variables
Set these in `~/.zshrc` or `~/.bashrc`:
```bash
# Network selection (sepolia | base-sepolia | base | ethereum)
export FINANCE_NETWORK=sepolia
# Private key (no 0x prefix, keep secret!)
export FINANCE_PRIVATE_KEY=abc123...
# RPC endpoint (Infura/Alchemy/public)
export FINANCE_RPC_URL=https://sepolia.infura.io/v3/YOUR_KEY
# Approval policy (optional — overrides config.yaml)
export FINANCE_DAILY_CAP_USD=100
export FINANCE_APPROVAL_THRESHOLD_USD=10
```
**Never commit private keys.** Use `.env` files or system keychain.
---
## Testing the Plugin
### Dry-Run (no funds)
```bash
~/.hermes/bin/test-finance-payment.py --dry-run --amount 25 --to 0xRecipient
```
Expected output:
```
[DRY-RUN] Would send $25.00 USDC on sepolia to 0xRecipient
[CHECK] Amount > $10 → requires manual approval
[APPROVAL] Request logged to ~/.hermes/logs/finance_approvals.jsonl
```
### Live Test (Sepolia testnet)
```bash
# 1. Get Sepolia ETH & USDC from faucets
# - https://sepoliafaucet.com (ETH)
# - USDC: https://www.usdcfaucet.com (sepolia)
# 2. Run real transaction
~/.hermes/bin/test-finance-payment.py \
--amount 5.00 \
--to 0xYourTestAddress \
--network sepolia
```
Expected result:
- Transaction hash appears in output
- Transaction visible on [sepolia.etherscan.io](https://sepolia.etherscan.io)
- Approval log entry appears if amount > $10
---
## Verification Deliverables
After sandbox testing, produce:
1. **Testnet transaction hash**
Example: `0x4f3a...c2d1` from Sepolia Etherscan
2. **Config snippet showing policy**
Save output of:
```bash
grep -A5 'approvals:' ~/.timmy/timmy-config/config.yaml
```
3. **Screenshot of approval log entry**
```bash
tail -1 ~/.hermes/logs/finance_approvals.jsonl | jq .
```
4. **Risks and mitigations note** (see below)
---
## Security Considerations
### Key Storage
- **Risk:** Private key compromise → total fund loss
- **Mitigation:**
- Store keys in macOS Keychain or `pass` (Unix password manager)
- Use dedicated burner wallet for each agent
- Never check keys into git; enforce via `pre-commit` hooks
- Rotate keys monthly
### Revocation
- **Risk:** Compromised key cannot be revoked on-chain (EVM)
- **Mitigation:**
- Use smart-contract wallets (Safe, Argent) with owner rotation
- Emergency `finance_revoke` MCP tool immediately disables plugin
- Maintain hot/cold wallet split — daily cap limits exposure
### Audit Trail
- **Risk:** Tampered logs hide malicious activity
- **Mitigation:**
- Append-only `finance_spend.jsonl` and `finance_approvals.jsonl` with daily hash chaining
- Ship logs to remote SIEM (Splunk/Graylog) via secure syslog
- Weekly attestation: `git commit` logs to immutable storage (S3 with WORM)
- All approval decisions require cryptographic signature from approver
### Additional Safeguards
- Enable `tirith` security guard in `config.yaml`
- Enforce `security.redact_secrets: true` to avoid private-key logging
- Run plugin in isolated network namespace (optional)
---
## Troubleshooting
| Symptom | Likely Cause | Fix |
|---------|--------------|-----|
| `npx: command not found` | Node.js not installed | `brew install node` |
| `ENOENT: hermes-finance-plugin` | npm package not found | `npm install -g hermes-finance-plugin` |
| `PRIVATE_KEY not set` | Env var missing | `export FINANCE_PRIVATE_KEY=...` |
| `insufficient funds` | Testnet wallet empty | Visit faucets above |
| `approval timeout` | No manual approver | Set `FINANCE_REQUIRE_SECOND_SIGNATURE=false` for test |
---
## References
- x402 spec: https://github.com/coinbase/x402
- USDC on Sepolia: https://docs.circle.com/usdc-misc/testnet
- EIP-712 signatures: https://eips.ethereum.org/EIPS/eip-712