# paralock-cli
`paralock`, the command-line tool of [Paralock](https://paralock.xyz): swap shielded ZEC for stablecoins on EVM
chains (Tempo, Base, Ethereum, Arbitrum, Robinhood Chain, HyperEVM), pay exact dollar amounts, recover saved swaps,
and run a market maker, all from one binary with no Node process. It is built on the
[`paralock`](https://crates.io/crates/paralock) Rust SDK and speaks the protocol of the TypeScript SDK and the npm
CLI, so it trades with TypeScript makers and serves TypeScript takers, in htlc and private (adaptor) mode.
> **Status:** experimental and **not audited**. The Zcash leg is transparent on chain in both modes (shield before
> and after), and the devnet is not mainnet. Don't put more money through it than you can afford to lose.
## Install
```sh
`--no-refund`); the swap is saved either way, so `paralock refund <id>` also works after a restart. On mainnet
they ask for confirmation unless `--yes`.
### For scripts
`--json` prints exactly one JSON document on stdout: `{ "ok": true, … }` (the quote, the swap, the checks) or
`{ "ok": false, "error": { "code", "message", "hint", "exitCode" }, "swap"? }`. `paralock maker --json` prints
newline-delimited records instead: `listening`, then one `swap` record per status change, then `stopped`. Warnings
and logs (`-v`, `-vv`, `RUST_LOG`) go to stderr.
| 0 | Success (a swap completed, a refund landed, every required doctor check passed) |
| 1 | Failure; nothing irreversible happened (an unreachable node, a refused quote…) |
| 2 | Usage or configuration error |
| 3 | A swap failed after locking ZEC: refunded, or refundable with `paralock refund <id>` |
## Configuration
`paralock.toml` is read from `--config <file>`, `$PARALOCK_CONFIG`, `./paralock.toml` or
`<state>/paralock.toml`. A complete, commented example is [`paralock.example.toml`](paralock.example.toml):
```toml
network = "mainnet"
maker_url = "https://maker.example"
[zcash]
rpc = "http://127.0.0.1:8232" # or lightwalletd = "https://…"
key_env = "PARALOCK_ZCASH_KEY" # or key_file = "~/.paralock/zcash.key"
[evm.base]
rpc = "https://mainnet.base.org"
chain_id = 8453
htlc = "0x…"
adaptor_escrow = "0x…"
key_env = "PARALOCK_EVM_KEY"
token = { address = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", symbol = "USDC", decimals = 6 } # maker
```
- **Keys** come from environment variables (`key_env`) or files (`key_file`); a key file readable by others gets a
warning. A key written in the file by value is refused unless `allow_inline_keys = true`.
- On a testnet chain id Paralock has deployed to, `htlc`, `adaptor_escrow`, `from_block` and the token default to
that deployment, so `rpc` and `chain_id` are enough.
- `[price]` is CoinGecko by default; a fixed price or a fallback is refused on mainnet.
- `[taker]` sets slippage, the claim window and the longest acceptable Zcash lock; `[maker]` the listen address,
payout address, spread, policy, limits and the HTTP server limits (CORS, rate limit, a client-address header behind
a proxy, timeouts, connection caps).
- Swap stores live in `store_dir` (default `<state>/rust-<network>`), `taker/` and `maker/`. They hold secrets and
per-swap keys: back them up and keep them private. The format differs from the TypeScript SDK's stores.
## The local devnet
`--devnet` uses the devnet that the npm CLI runs (`npx paralock dev`): it reads `devnet.json` from
`<checkout>/.paralock` inside a Paralock checkout, else `$PARALOCK_HOME`, else `~/.paralock`. Starting and stopping
the devnet (ths for Zcash regtest, anvil, the contracts) stays in the npm CLI.
```sh
npx paralock dev # Zcash regtest + anvils + contracts + the TypeScript maker
paralock --devnet doctor
paralock --devnet swap --zec 0.1 # htlc on Tempo, against the TypeScript maker on :7420
paralock --devnet swap --zec 0.1 --chain base --private
paralock --devnet --evm-account 5 maker --port 7424 # a Rust maker on anvil account 5 (fund it first)
paralock --devnet --maker-url http://127.0.0.1:7424 swap --zec 0.1
paralock --devnet swap --zec 0.1 --private --refund-demo # lock, let the maker vanish, refund
```
On the devnet the taker uses its own key (`<state>/rust-cli/taker-zcash.key`), funded from the ths faucet as
needed, and the devnet's taker and relayer accounts on the EVM chains; `--evm-account N` picks anvil dev account N
instead. `--lightwalletd` reaches Zcash through lightwalletd. The maker mines a regtest block only when the chain
has stalled for 6 s (when no TypeScript maker is mining), and `--no-mine` turns that off. The devnet price falls
back to a fixed value when CoinGecko is unreachable; anvil's dev keys are public.
## License
MIT