# Swap CLI

`fynd-swap-cli` is a CLI binary for quoting, simulating, and executing swaps. It's useful for quick testing from the terminal without writing any code.

## Setup

{% tabs %}
{% tab title="Docker Compose" %}
**Prerequisites:**

* **Docker**: [install Docker](https://docs.docker.com/engine/install/)
* **Tycho API key**: [get one here](https://t.me/fynd_portal_bot)

Get the [docker-compose.swap.yml](https://github.com/propeller-heads/fynd/blob/main/docker-compose.swap.yml) file:

```bash
curl -o docker-compose.swap.yml https://raw.githubusercontent.com/propeller-heads/fynd/main/docker-compose.swap.yml
```

Start the server and drop into a shell with `fynd-swap-cli` pre-installed:

```bash
export TYCHO_API_KEY=your_tycho_api_key

docker compose -f docker-compose.swap.yml run --rm fynd-shell
```

This also starts `fynd-serve` automatically. Run swaps with:

```bash
# Inside the fynd-shell container:
fynd-swap-cli
```

{% hint style="info" %}
For on-chain execution, pass `PRIVATE_KEY` at startup: `docker compose -f docker-compose.swap.yml run --rm -e PRIVATE_KEY=your_key fynd-shell`
{% endhint %}

When done, stop and remove the server container:

```bash
docker compose -f docker-compose.swap.yml down
```

{% endtab %}

{% tab title="Build from source" %}
**Prerequisites:** A running Fynd server — start `fynd serve` first. See the [Quickstart](/get-started/quickstart.md) if you haven't.

```bash
cargo install --path tools/fynd-swap-cli
```

{% endtab %}
{% endtabs %}

***

## Dry-run a swap (ERC-20)

By default, `fynd-swap-cli` runs a **dry-run**: it uses a well-funded sender address and injects ERC-20 storage overrides so the simulation succeeds without any real funds or wallet approvals.

```bash
fynd-swap-cli
```

This sells 1 WETH for USDC using the defaults. Pass explicit tokens and amounts to customise:

```bash
fynd-swap-cli \
  --sell-token  0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 \
  --buy-token   0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 \
  --sell-amount 2000000000000000000
```

The output prints the quote (amount\_in, amount\_out, gas estimate, route) followed by the simulation result.

{% hint style="info" %}
`--sell-amount` is in raw atomic units. 1 000 000 000 = 1000 USDC (6 decimals). 1 000 000 000 000 000 000 = 1 WETH (18 decimals).
{% endhint %}

## Dry-run a swap (Permit2)

Add `--transfer-type transfer-from-permit2`. The dry-run uses nonce 0 and maximum deadlines, so no chain reads are needed.

```bash
fynd-swap-cli --transfer-type transfer-from-permit2
```

## Execute on-chain (ERC-20)

Add `--execute` and set `PRIVATE_KEY`. The CLI checks the router allowance automatically and submits an approval transaction first if one is needed.

{% hint style="warning" %}
This sends real transactions. Ensure your wallet has the sell token before running with `--execute`.
{% endhint %}

```bash
export RPC_URL=https://your-rpc-provider.com/v1/your_key
export PRIVATE_KEY=your_private_key_hex   # no 0x prefix

fynd-swap-cli --execute
```

## Execute on-chain (Permit2)

Add `--execute --transfer-type transfer-from-permit2`. The CLI checks whether the ERC-20 allowance to the Permit2 contract is sufficient for the swap. If not, it approves the maximum amount so subsequent swaps do not require re-approval. It then reads the current nonce, builds the EIP-712 permit, signs it, and submits the swap.

```bash
export RPC_URL=https://your-rpc-provider.com/v1/your_key
export PRIVATE_KEY=your_private_key_hex   # no 0x prefix

fynd-swap-cli --transfer-type transfer-from-permit2 --execute
```

## Swap using vault funds

If tokens are already deposited in the Tycho Router vault, use `--transfer-type use-vaults-funds`. No ERC-20 approval or Permit2 signature is needed.

```bash
fynd-swap-cli --transfer-type use-vaults-funds
```

***

## CLI Reference

| Flag              | Env var    | Default                                      | Description                                                     |
| ----------------- | ---------- | -------------------------------------------- | --------------------------------------------------------------- |
| `--sell-token`    | —          | WETH (mainnet)                               | Token address to sell                                           |
| `--buy-token`     | —          | USDC (mainnet)                               | Token address to buy                                            |
| `--sell-amount`   | —          | `1000000000000000000` (1 WETH)               | Amount to sell in raw atomic units                              |
| `--slippage-bps`  | —          | `50` (0.5%)                                  | Slippage tolerance in basis points                              |
| `--fynd-url`      | `FYND_URL` | `http://localhost:3000`                      | Fynd server URL                                                 |
| `--transfer-type` | —          | `transfer-from`                              | `transfer-from`, `transfer-from-permit2`, or `use-vaults-funds` |
| `--execute`       | —          | false (dry-run)                              | Submit the swap on-chain. Requires `PRIVATE_KEY`.               |
| `--permit2`       | —          | `0x000000000022D473030F116dDEE9F6B43aC78BA3` | Permit2 contract address                                        |
| `--rpc-url`       | `RPC_URL`  | `https://reth-ethereum.ithaca.xyz/rpc`       | Ethereum RPC endpoint (must support `eth_call` state overrides) |

## Security Notes

1. **Never expose your private key.** Use the `PRIVATE_KEY` environment variable, never a CLI argument. Run `unset HISTFILE` before setting it to prevent it from being saved to your shell history.
2. **Dry-run first.** The default mode (no `--execute`) simulates the full swap with storage overrides — no funds needed. Confirm the output looks correct before adding `--execute`.
3. **Slippage protection.** The default 0.5% slippage may not be sufficient for large trades or volatile markets. Adjust `--slippage-bps` accordingly.
4. **Mainnet warning.** `--execute` may send multiple transactions (approval + swap). Start with small amounts. All routes execute through the [Tycho Router](https://docs.propellerheads.xyz/tycho/for-solvers/execution/contract-addresses) contract.
5. **Verify routes.** The CLI prints the full route before executing. Multi-hop routes through low-liquidity pools can result in worse execution.
6. **Prices are indicative.** Quotes reflect the best route at query time but are not guaranteed on-chain. Pool states change every block, and the longer you wait to execute, the more the price may drift.

## Troubleshooting

**"Solver is not healthy"**: Wait for the solver to finish loading market data. Check the `fynd serve` terminal for progress, or poll `curl http://localhost:3000/v1/health`.

**"Sell/buy token not found"**: Ensure the token address is correct and [the token exists on Tycho's indexer](https://docs.propellerheads.xyz/tycho/for-solvers/indexer/tycho-rpc#post-v1-tokens).

**"No route found"**: Fynd couldn't find a path between your tokens. Check that both tokens have enough on-chain liquidity.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.fynd.xyz/guides/swap-cli.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
