# Cipher Gate

A proxy RPC that routes signing requests to a browser wallet.

Cipher Gate sits between an EVM dev tool (Foundry, Hardhat, ethers/viem scripts) and an
upstream RPC. Read calls pass straight through. **Write/sign calls** —
`eth_sendTransaction`, `personal_sign`, `eth_signTypedData*`, etc. — are intercepted and
pushed to a local browser UI, where you approve and sign with a real wallet
(MetaMask, Ledger, any WalletConnect/Reown wallet). The signed result flows back to the
caller. Your dev tool talks to a plain RPC endpoint and never sees a private key.

```
 forge / hardhat ──HTTP──▶ cipher-gate ──read──▶ upstream RPC
                              │
                              └─write/sign──▶ browser UI ──▶ your wallet
```

## Install

```bash
cargo install cipher-gate
```

The published crate ships a prebuilt UI, so this needs only a Rust toolchain — no Node.js.

## Usage

```bash
cipher-gate --rpc-url https://eth.llamarpc.com
```

Then:

1. Point your tool's RPC at `http://localhost:8545`.
2. Open `http://localhost:8545` in a browser and connect a wallet.
3. Run your tool. Signing requests appear as cards to approve or reject — each shows a
   transaction simulation result and decoded calldata (with warnings for risky
   operations like unlimited approvals).

It works out of the box with a built-in Reown (WalletConnect) project ID. To use your own
quota instead, pass `--reown-project-id` (or set `REOWN_PROJECT_ID`) — get a free ID at
<https://cloud.reown.com>.

### Options

| Flag | Default | Description |
|------|---------|-------------|
| `--rpc-url <URL>` | _required_ | Upstream RPC to forward read calls to |
| `--reown-project-id <ID>` | built-in | Override the bundled Reown project ID (or `REOWN_PROJECT_ID`) |
| `--port <PORT>` | `8545` | Port for the JSON-RPC proxy + UI |
| `--ui-port <PORT>` | — | Serve the UI on a separate port from the proxy |
| `--host <ADDR>` | `127.0.0.1` | Bind address |
| `--allowed-origin <ORIGIN>` | — | Extra browser Origin allowed to open the WS (repeatable) |

## Security

- **Localhost-only by default.** Cipher Gate binds `127.0.0.1`, so it is not reachable
  from other machines. Set `--host 0.0.0.0` to expose it on your network — only do this on
  a trusted network, since anyone who can reach it can drive your wallet. You must then
  also pass `--allowed-origin http://<your-address>:<port>`.
- **Per-run token.** Each run generates a secret token embedded in the UI's WebSocket URL;
  connections without it are rejected.
- **Origin-checked WebSocket.** The signing socket only accepts browser Origins it was
  told about (loopback by default), blocking other local web pages from connecting.

## Development

Requires Rust and Node.js.

```bash
# Full build (build.rs builds the frontend if frontend/out is absent)
cargo build --release

# Frontend dev server with hot reload (expects the proxy running on :8545)
cd frontend && npm run dev

# Force-rebuild the embedded UI on the next cargo build
rm -rf frontend/out   # or: CIPHER_GATE_REBUILD_FRONTEND=1 cargo build
```

See [CLAUDE.md](CLAUDE.md) for architecture details.

## License

MIT
