---
title: Bots & automation
description: How to automate crypto swaps safely with OpenSwap: policy files that set hard limits, a live price feed, and simulation before any real trade.
order: 4
version: 0.1.0
---

# Bots & automation

OpenSwap is built for unattended trading — but with one hard rule at its
core: **a script or an AI may suggest a trade, but only your written policy
can approve one.** A policy is a small JSON file of limits you set once:
which assets, which destination, how much per trade, how much per day. If a
proposed trade breaks any rule, it's rejected cleanly (exit code `4`) and
your loop just moves on.

## Setting up your policy

```bash
openswap bot init
```

That walks you through the choices interactively and can test the result
against live routes on the spot. A finished policy looks like this:

```jsonc
{
  "version": 1,
  "name": "my-strategy",
  "mode": "enforce",                    // "monitor" logs violations without blocking
  "assets":       { "allow_from": ["ARB.USDC-0x…"], "allow_to": ["BTC.BTC"] },
  "protocols":    { "allow": ["chainflip", "near"] },
  "destinations": { "allow": ["bc1q…"] },
  "limits": {
    "max_trade_usd": 250,
    "max_daily_volume_usd": 1000,
    "max_total_fee_usd": 5,
    "max_quote_age_seconds": 20,
    "cooldown_seconds": 60
  },
  "kill_switch_file": "./STOP"          // create this file and everything halts
}
```

One important behavior: **unknown values fail closed.** If a route's USD
value or fees can't be priced, and one of your limits depends on it, the
trade is rejected. The policy never guesses in your favor's opposite.

## The loop

A working bot is five commands:

```bash
openswap watch -a 100 -f arb:USDC -t btc:BTC --jsonl    # 1. live price feed
openswap bot check --policy p.json … --json             # 2. would this trade pass? (no side effects)
openswap bot run   --policy p.json … --json             # 3. execute — simulates by default
openswap bot run   --policy p.json … --json --live      # 4. execute for real
openswap status <receipt> --json                        # 5. watch it finish
```

`bot run` binds quotes to your signer's address, filters to your allowed
protocols, checks the policy, simulates every transaction — and only
broadcasts when you say `--live`. Retries are safe: an idempotency key
(automatic, or set your own with `--idempotency-key`) means a retried run
replays the stored result instead of trading twice.

**In this release (0.1.x), `--live` ships disabled** while the signing lane
is hardened. Everything else — `check`, simulated `run`, the price feed, and
deposit-address bots below — is fully available.

## The signer

Live bot trades on EVM chains sign with a key you configure explicitly:

| Environment variable | Meaning |
| --- | --- |
| `OPENSWAP_EVM_PRIVATE_KEY` | A hot key (you'll be warned on `--live`) |
| `OPENSWAP_EVM_KEYSTORE` + `OPENSWAP_EVM_KEYSTORE_PASSWORD` | An encrypted keystore — the right choice for real funds |
| `OPENSWAP_EVM_RPC_URL` | Your own RPC endpoint (serious bots should set this) |

Before anything signs, guards check the target address, the chain id, and
that the amount being moved never exceeds what was approved.

## Bots without a signer

If your automation pays from external wallet infrastructure instead, use the
normal swap flow with a policy attached:

```bash
openswap swap --policy p.json --json --yes …
```

Same policy protection, but you get a deposit address to pay rather than an
on-chain signature — this works for every chain, not just EVM.
