Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 32 additions & 9 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,26 @@ OMNICLAW_PRIVATE_KEY=0x...
# authority. The policy engine exposes the controlled payment API.
OMNICLAW_AGENT_TOKEN=replace-with-agent-token
OMNICLAW_AGENT_POLICY_PATH=./policy.json
OMNICLAW_AGENT_STATE_PATH=./wallet-state.json
OMNICLAW_OWNER_TOKEN=replace-with-owner-token

# Buyer server rail profile.
# hybrid = Circle direct transfer + x402 paid APIs
# circle = Circle direct transfer only
# x402 = x402 paid APIs only
OMNICLAW_BUYER_MODE=hybrid

# Credential requirements by mode:
# hybrid: CIRCLE_API_KEY + ENTITY_SECRET + OMNICLAW_PRIVATE_KEY + OMNICLAW_RPC_URL
# circle: CIRCLE_API_KEY + ENTITY_SECRET
# x402: OMNICLAW_PRIVATE_KEY + OMNICLAW_RPC_URL
# x402 Gateway nanopayments also require funded Gateway balance. They do not
# require CIRCLE_API_KEY when the seller provides GatewayWalletBatched metadata.

# Optional explicit rail overrides. Leave unset to use OMNICLAW_BUYER_MODE.
# OMNICLAW_ENABLE_CIRCLE_TRANSFER=true
# OMNICLAW_ENABLE_X402=true

# Policy hot reload interval in seconds. Use a larger value or disable reload in
# production if policies are deployed immutably.
OMNICLAW_POLICY_RELOAD_INTERVAL=5
Expand All @@ -49,36 +67,41 @@ OMNICLAW_REDIS_URL=redis://localhost:6379/0
# =============================================================================

# Used by `omniclaw-cli` when acting as an agent execution layer.
OMNICLAW_SERVER_URL=http://127.0.0.1:8080
OMNICLAW_SERVER_URL=http://127.0.0.1:9091
OMNICLAW_TOKEN=replace-with-agent-token

# Optional human-readable CLI output. Default output is agent-friendly JSON.
OMNICLAW_CLI_HUMAN=0

# =============================================================================
# Circle Gateway / Nanopayments
# x402 Nanopayment Funding (Circle Gateway)
# =============================================================================

# Required for Circle Gateway nanopayments, Gateway balance, and Circle-backed
# wallet operations.
CIRCLE_API_KEY=replace-with-circle-api-key
# Required for Circle direct transfers and optional Circle Gateway API helper
# operations. For OMNICLAW_BUYER_MODE=x402, leave this blank unless you have
# a real Circle API key for helper operations.
CIRCLE_API_KEY=

# Entity secret for Circle wallet encryption.
# Entity secret for Circle Developer Wallet encryption. Required only when the
# Circle direct transfer rail is enabled.
# If your Circle account/API key already has an Entity Secret, set it here.
# Circle only allows one active Entity Secret per account/API key, so OmniClaw
# only auto-generates/registers a new one when no existing secret is provided or
# found in the managed local credential store.
ENTITY_SECRET=

OMNICLAW_NANOPAYMENTS_ENABLED=true
OMNICLAW_NANOPAYMENTS_ENV=testnet
# Nanopayment knobs below tune Gateway behavior when x402 uses GatewayWalletBatched.
# Gateway API environment is derived from OMNICLAW_ENV:
# production/prod/mainnet -> mainnet; all other values -> testnet.
OMNICLAW_NANOPAYMENTS_AUTO_TOPUP=false
OMNICLAW_NANOPAYMENTS_TOPUP_THRESHOLD=1.00
OMNICLAW_NANOPAYMENTS_TOPUP_AMOUNT=10.00
OMNICLAW_NANOPAYMENTS_MICRO_THRESHOLD=1.00

# Optional Gateway contract override for GatewayWalletBatched metadata.
# Optional Gateway contract overrides. OmniClaw has defaults for supported EVM
# networks; set these only when a network's Gateway metadata changes.
CIRCLE_GATEWAY_CONTRACT=
CIRCLE_GATEWAY_USDC_ADDRESS=

# =============================================================================
# Production Hardening
Expand Down
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ logs/
tmp/
.runtime/
output/doc/
examples/agent/buyer/policy.json
examples/agent/buyer/*.state.json
examples/agent/buyer/wallet-state.json
examples/agent/buyer/runtime/
examples/agent/runtime/

# Private operating workspace
# Keep the root internal workspace out of git.
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile.agent
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,4 @@ EXPOSE 9090

ENV OMNICLAW_AGENT_PORT=9090

CMD ["uv", "run", "omniclaw", "server", "--host", "0.0.0.0", "--port", "9090"]
CMD ["uv", "run", "uvicorn", "omniclaw.agent.server:app", "--host", "0.0.0.0", "--port", "9090"]
39 changes: 28 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,27 +32,44 @@ pip install omniclaw
Start the policy engine:

```bash
export OMNICLAW_PRIVATE_KEY="0x..."
export OMNICLAW_AGENT_TOKEN="agent-token"
export OMNICLAW_AGENT_POLICY_PATH="./policy.json"
export OMNICLAW_NETWORK="BASE-SEPOLIA"
export OMNICLAW_RPC_URL="https://sepolia.base.org"

docker compose up --build omniclaw-agent
cp .env.example .env
# Hybrid mode (default): leave OMNICLAW_BUYER_MODE=hybrid and fill CIRCLE_API_KEY,
# ENTITY_SECRET, OMNICLAW_PRIVATE_KEY, OMNICLAW_AGENT_TOKEN, OMNICLAW_OWNER_TOKEN,
# OMNICLAW_NETWORK, and OMNICLAW_RPC_URL.
# x402-only Gateway mode: set OMNICLAW_BUYER_MODE=x402, leave CIRCLE_API_KEY and
# ENTITY_SECRET empty unless you need optional Circle Gateway API helpers, and fill
# OMNICLAW_PRIVATE_KEY, OMNICLAW_AGENT_TOKEN, OMNICLAW_OWNER_TOKEN,
# OMNICLAW_NETWORK, and OMNICLAW_RPC_URL.

mkdir -p examples/agent/buyer/runtime
cp examples/agent/buyer/policy.example.json examples/agent/buyer/runtime/policy.json
# Edit examples/agent/buyer/runtime/policy.json so the token matches OMNICLAW_AGENT_TOKEN.

docker compose -f examples/agent/buyer/docker-compose.yml --env-file .env up --build
```

The policy file is stable configuration. Generated wallet state is written separately
to `examples/agent/buyer/runtime/wallet-state.json`.

Buyer-facing policy rails are:

- `circle_transfer` for direct Circle Developer Wallet transfers.
- `x402` for paid API payments. OmniClaw chooses Gateway nanopayment or the standard
x402 payment path internally based on seller accepts, buyer config, and Gateway balance.

Configure the buyer CLI:

```bash
export OMNICLAW_SERVER_URL="http://localhost:8080"
export OMNICLAW_TOKEN="agent-token"
set -a; source .env; set +a
export OMNICLAW_SERVER_URL="http://127.0.0.1:9091"
export OMNICLAW_TOKEN="$OMNICLAW_AGENT_TOKEN"
```

Inspect and pay an x402 endpoint:

```bash
omniclaw-cli inspect-x402 --recipient https://paid.example.com/compute
omniclaw-cli pay --recipient https://paid.example.com/compute --idempotency-key job-123
omniclaw-cli inspect-x402 --recipient "http://127.0.0.1:4023/compute?size=20"
omniclaw-cli pay --recipient "http://127.0.0.1:4023/compute?size=20" --amount 0.10 --idempotency-key job-123
```

## Development
Expand Down
18 changes: 15 additions & 3 deletions docs/API_REFERENCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@ client = OmniClaw()
await client.pay(
wallet_id="wallet-id",
recipient="https://paid.example.com/compute",
amount=None,
amount="0.10",
idempotency_key="job-123",
)
```

Use `amount=None` for x402 URLs where the endpoint publishes the amount in `PAYMENT-REQUIRED`.
For x402 URLs, `amount` is the maximum amount the buyer is willing to pay.

### Gateway Buyer Helpers

Expand All @@ -43,5 +43,17 @@ The local policy engine exposes buyer payment, wallet, ledger, policy, and x402
Start it with:

```bash
docker compose up --build omniclaw-agent
docker compose -f examples/agent/buyer/docker-compose.yml --env-file .env up --build
```

Agent requests use:

```text
Authorization: Bearer <agent-token>
```

Privileged guard-bypass and confirmation endpoints also require:

```text
X-Omniclaw-Owner-Token: <owner-token>
```
34 changes: 25 additions & 9 deletions docs/POLICY_REFERENCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,16 @@ Hot reload:
"wallets": {
"primary": {
"name": "Primary Wallet",
"wallet_id": "wlt_...",
"address": "0x...",
"limits": {
"daily_max": "100.00",
"per_tx_max": "50.00"
},
"recipients": {
"mode": "allow_all"
},
"rails": {
"circle_transfer": true,
"x402": true
}
}
}
Expand All @@ -53,8 +55,6 @@ Hot reload:
"wallets": {
"primary": {
"name": "Primary Wallet",
"wallet_id": "wlt_...",
"address": "0x...",
"limits": {
"daily_max": "1000.00",
"hourly_max": "200.00",
Expand All @@ -70,6 +70,10 @@ Hot reload:
"addresses": ["0xSeller1...", "0xSeller2..."],
"domains": ["api.service-a.com"]
},
"rails": {
"circle_transfer": true,
"x402": true
},
"confirm_threshold": "50.00"
}
}
Expand Down Expand Up @@ -105,11 +109,12 @@ Hot reload:
| Field | Type | Description |
|-------|------|-------------|
| `name` | string | Wallet name |
| `wallet_id` | string | Circle Developer Wallet ID (auto-generated if missing) |
| `address` | string | Circle Developer Wallet address (auto-filled if missing) |
| `wallet_id` | string | Optional existing Circle Developer Wallet ID |
| `address` | string | Optional expected Circle Developer Wallet address |
| `limits` | object | Spending limits |
| `rate_limits` | object | Rate limits |
| `recipients` | object | Recipient rules |
| `rails` | object | Buyer payment rails enabled for this wallet |
| `confirm_threshold` | decimal | Amount requiring owner confirmation |

### limits
Expand All @@ -136,6 +141,15 @@ Hot reload:
| `addresses` | array | List of allowed/blocked addresses |
| `domains` | array | List of allowed/blocked domains (for x402 URLs) |

### rails

| Field | Type | Description |
|-------|------|-------------|
| `circle_transfer` | boolean | Allow direct Circle Developer Wallet transfers |
| `x402` | boolean | Allow paid API payments. OmniClaw chooses Gateway nanopayment or the standard x402 payment path internally based on seller accepts, buyer config, and Gateway balance. |

Generated Circle wallet IDs and EOA addresses are stored in `OMNICLAW_AGENT_STATE_PATH`, not in `policy.json`. Keep policy files stable and reviewable.

---

## Recipient Modes
Expand Down Expand Up @@ -285,9 +299,9 @@ Agent can pay everyone EXCEPT these addresses/domains.

---

## Environment Override
## SDK Environment Guard Defaults

You can also set limits via environment variables instead of policy.json:
When using the SDK directly, you can set default guard limits via environment variables:

```bash
export OMNICLAW_DAILY_BUDGET="100.00"
Expand All @@ -296,7 +310,8 @@ export OMNICLAW_TX_LIMIT="25.00"
export OMNICLAW_RATE_LIMIT_PER_MIN="10"
```

These override policy.json values if set.
The buyer server applies `policy.json` as its source of truth. Put server-side
agent limits in the policy file.

---

Expand All @@ -305,3 +320,4 @@ These override policy.json values if set.
- Simple: `examples/policy-simple.json`
- Advanced: `examples/policy-advanced.json`
- Default: `examples/default-policy.json`
- Buyer server template: `examples/agent/buyer/policy.example.json`
69 changes: 56 additions & 13 deletions docs/agent-getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,77 @@

This guide is for agent buyers.

## Start Core
## Start The Buyer Server

```bash
export OMNICLAW_PRIVATE_KEY="0x..."
export OMNICLAW_AGENT_TOKEN="agent-token"
export OMNICLAW_AGENT_POLICY_PATH="./policy.json"
export OMNICLAW_NETWORK="BASE-SEPOLIA"
export OMNICLAW_RPC_URL="https://sepolia.base.org"
cp .env.example .env
# For hybrid mode, fill CIRCLE_API_KEY, ENTITY_SECRET, OMNICLAW_PRIVATE_KEY,
# OMNICLAW_AGENT_TOKEN, OMNICLAW_OWNER_TOKEN, OMNICLAW_NETWORK, and OMNICLAW_RPC_URL.
# For x402-only Gateway mode instead, set OMNICLAW_BUYER_MODE=x402 and leave
# CIRCLE_API_KEY and ENTITY_SECRET empty unless you need optional Circle Gateway
# API helper operations.

docker compose up --build omniclaw-agent
mkdir -p examples/agent/buyer/runtime
cp examples/agent/buyer/policy.example.json examples/agent/buyer/runtime/policy.json
# Edit examples/agent/buyer/runtime/policy.json so the token matches OMNICLAW_AGENT_TOKEN.

docker compose -f examples/agent/buyer/docker-compose.yml --env-file .env up --build
```

The buyer server runs in hybrid mode by default:

- Circle Developer Wallet for direct USDC transfers.
- EOA signer for x402 paid APIs. When the seller advertises `GatewayWalletBatched`
and the buyer has Gateway balance, OmniClaw can use the Gateway nanopayment path.
- Stable policy in `examples/agent/buyer/runtime/policy.json`.
- Generated wallet state in `examples/agent/buyer/runtime/wallet-state.json`.

Mode requirements:

| Mode | Credentials |
| --- | --- |
| `hybrid` | `CIRCLE_API_KEY`, `ENTITY_SECRET`, `OMNICLAW_PRIVATE_KEY`, `OMNICLAW_RPC_URL` |
| `circle` | `CIRCLE_API_KEY`, `ENTITY_SECRET` |
| `x402` | `OMNICLAW_PRIVATE_KEY`, `OMNICLAW_RPC_URL`, and funded Gateway balance for `GatewayWalletBatched` nanopayments |

`CIRCLE_API_KEY` is not required for x402 Gateway nanopayments. It is only needed
for Circle direct transfers and optional Circle Gateway API helper operations.
Gateway is an x402 execution path, not a separate buyer rail.

## Configure The Buyer CLI

```bash
export OMNICLAW_SERVER_URL="http://localhost:8080"
export OMNICLAW_TOKEN="agent-token"
set -a; source .env; set +a
export OMNICLAW_SERVER_URL="http://127.0.0.1:9091"
export OMNICLAW_TOKEN="$OMNICLAW_AGENT_TOKEN"
```

## Inspect A Paid URL

```bash
omniclaw-cli can-pay --recipient https://paid.example.com/compute
omniclaw-cli inspect-x402 --recipient https://paid.example.com/compute
omniclaw-cli can-pay --recipient "http://127.0.0.1:4023/compute?size=20"
omniclaw-cli inspect-x402 --recipient "http://127.0.0.1:4023/compute?size=20"
```

## Pay A Paid API

```bash
omniclaw-cli pay --recipient "http://127.0.0.1:4023/compute?size=20" --amount 0.10 --idempotency-key job-123
```

## Direct Transfer

```bash
omniclaw-cli pay \
--recipient <recipient-evm-address> \
--amount 1.00 \
--idempotency-key transfer-123
```

## Pay
## x402 Nanopayment Funding

```bash
omniclaw-cli pay --recipient https://paid.example.com/compute --idempotency-key job-123
omniclaw-cli deposit-address
omniclaw-cli balance-detail
omniclaw-cli deposit --amount 10.00 --check-gas
```
2 changes: 1 addition & 1 deletion docs/agent-skills.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ Use these flows when an agent needs to inspect or pay a URL through the policy e
```bash
omniclaw-cli can-pay --recipient https://paid.example.com/compute
omniclaw-cli inspect-x402 --recipient https://paid.example.com/compute
omniclaw-cli pay --recipient https://paid.example.com/compute --idempotency-key job-123
omniclaw-cli pay --recipient https://paid.example.com/compute --amount 0.10 --idempotency-key job-123
```
Loading
Loading