# radius-cli

*Local wallet and execution CLI for Radius*

`radius-cli` is the canonical terminal surface for local Radius wallets and agent workflows. Use it to create or select a wallet, sign messages, check balances, send transactions, read contracts, inspect transactions, and pay for x402- and MPP-protected endpoints.

Use viem for application code and [`radius-sdk`](/reference/radius-sdk.md) to accept or make x402 payments from TypeScript. Use Foundry for smart contract builds, tests, and deployment scripts. Use `radius-cli` when an agent or terminal needs to operate a local Radius wallet.

## Install and verify

Requires Node.js 22 or later.

Run one command with `npx`:

```bash
npx radius-cli --help
```

Or install the binary globally:

```bash
npm install -g radius-cli
command -v radius-cli
radius-cli --help
```

Use `radius-cli` version `0.4.0` or later. From `0.3.0`, `wallet balance` reports RUSD and SBC separately, and `wallet send` transfers any ERC-20. From `0.4.0`, `wallet pay` (formerly `wallet x402`, with `--threshold` and `--approve-permit2` formerly `--x402-threshold` and `--x402-approve-permit2`) also pays MPP challenges and USDC on Base. From `0.5.0`, `sell check` checks a seller's `402` before you deploy it. Verify that your installed binary exposes the payment command:

```bash
radius-cli --version
radius-cli wallet pay --help
```

## Networks

| Network   | Chain ID | Default RPC                          |
| --------- | -------- | ------------------------------------ |
| `mainnet` | 723487   | `https://rpc.radiustech.xyz`         |
| `testnet` | 72344    | `https://rpc.testnet.radiustech.xyz` |

`radius-cli` defaults to mainnet. Set the network explicitly in scripts and agent workflows.

```bash
RADIUS_NETWORK=testnet radius-cli wallet address
```

Override the RPC endpoint with `--rpc-url` or `RADIUS_RPC_URL`:

```bash
RADIUS_NETWORK=testnet RADIUS_RPC_URL={TESTNET_RPC_URL} radius-cli wallet balance
```

## Project-scoped agent wallet

Use `RADIUS_HOME` to isolate wallet state per project, repo, or agent run:

```bash
export RADIUS_HOME=.radius
export RADIUS_NETWORK=testnet

radius-cli wallet address
radius-cli wallet balance --json
```

On first use, account-needing commands such as `wallet address`, `wallet balance`, `wallet sign`, and `wallet send` create a keystore in the configured Radius home. By default that is `~/.radius`; with `RADIUS_HOME=.radius`, it is local to the current project.

> **Warning:** Do not commit `.radius/`, `.env`, exported private keys, or command output that contains secret material. Prefer `radius-cli wallet address` for logging wallet identity.

To opt into a password before creating a wallet, set `RADIUS_PASSWORD`:

```bash
RADIUS_HOME=.radius RADIUS_NETWORK=testnet RADIUS_PASSWORD='use-a-secret-manager' radius-cli wallet new
```

## Configuration precedence

`radius-cli` resolves configuration in this order:

1. CLI flags: `--network`, `--rpc-url`, `--sbc`, `--rusd`, `--json`, `--private-key`
2. Environment: `RADIUS_NETWORK`, `RADIUS_RPC_URL`, `RADIUS_SBC_ADDRESS`, `RADIUS_RUSD_ADDRESS`, `RADIUS_PAY_NETWORKS`, `RADIUS_BASE_RPC_URL`, `RADIUS_BASE_SEPOLIA_RPC_URL`, `RADIUS_PASSWORD`, `RADIUS_KEYSTORE_PATH`, `RADIUS_HOME`
3. Radius config file in the active Radius home
4. Built-in defaults

SBC defaults to `0x33ad9e4BD16B69B5BFdED37D8B5D9fF9aba014Fb`, its address on both mainnet and testnet. Set `RADIUS_SBC_ADDRESS` or pass `--sbc` only to use another deployment of the same token.

## Wallet commands

Create or import a wallet:

```bash
radius-cli wallet new
radius-cli wallet import 0xPRIVATE_KEY
radius-cli wallet address
```

Check balances:

```bash
RADIUS_HOME=.radius RADIUS_NETWORK=testnet \
  radius-cli wallet balance --json

radius-cli wallet balance 0x0000000000000000000000000000000000000000 --json
```

The JSON reports `sbc` and `rusd` separately (with `sbcWei` and `rusdWei`), their sum as `totalUsd`, and `aggregateWei`, the value `eth_getBalance` returns. On Radius `eth_getBalance` already includes SBC; see [The Turnstile and balances](/reference/ethereum-compatibility.md#the-turnstile-and-balances).

Sign and verify messages:

```bash
radius-cli wallet sign "hello"
echo -n "hello" | radius-cli wallet sign -
radius-cli wallet verify "hello" 0xSIGNATURE --address 0xSignerAddress
```

Send native RUSD:

```bash
RADIUS_HOME=.radius RADIUS_NETWORK=testnet \
  radius-cli wallet send 0xRecipientAddress 0.10 RUSD
```

Send SBC:

```bash
RADIUS_HOME=.radius RADIUS_NETWORK=testnet \
  radius-cli wallet send 0xRecipientAddress 0.10 SBC
```

Send any other ERC-20 by its address; decimals are read from the token:

```bash
RADIUS_HOME=.radius RADIUS_NETWORK=testnet \
  radius-cli wallet send 0xRecipientAddress 0.10 0xTokenAddress
```

Call an arbitrary state-changing contract function:

```bash
radius-cli wallet send 0xTokenAddress "transfer(address,uint256)" 0xRecipientAddress 100000
```

Use `--json` for machine-readable output and `--no-wait` when you only need the submitted transaction hash.

## Read commands

Read a contract:

```bash
radius-cli call 0xTokenAddress "balanceOf(address)(uint256)" 0xWalletAddress
```

Inspect chain data:

```bash
radius-cli tx 0xTransactionHash --json
radius-cli receipt 0xTransactionHash --json
radius-cli storage 0xContractAddress 0
radius-cli code 0xContractAddress
radius-cli nonce 0xWalletAddress
```

Function signatures use cast-style syntax: `name(args)` for writes and `name(args)(returns)` for decoded reads.

## Paid endpoints

Use `radius-cli wallet pay <verb> <url>` to request an endpoint that charges over x402 or MPP. If the endpoint responds with `402 Payment Required`, the CLI checks the offer, signs and pays from the local wallet, then retries the request. The protocol side is [`radius-sdk`](/reference/radius-sdk.md), the same client applications use.

Agent-friendly GET request:

```bash
RADIUS_HOME=.radius RADIUS_NETWORK=testnet \
  radius-cli wallet pay get https://example.com/protected \
  --threshold 0.001 \
  --json \
  -y
```

POST with headers and JSON body:

```bash
RADIUS_HOME=.radius RADIUS_NETWORK=testnet \
  radius-cli wallet pay post https://api.example.com/query \
  -H "Content-Type: application/json" \
  -d '{"query":"radius"}' \
  --threshold 0.01 \
  --json \
  -y
```

Supported verbs are `get`, `post`, `put`, `patch`, `delete`, `head`, and `options`. `-d` accepts a literal string, `@path` to read a file, or `-` to read stdin.

### Spending limits

`--threshold` is in display units for the payment asset, not raw integer units. For SBC, `0.01` means 0.01 SBC.

| Flags                  | Offer at or below threshold       | Offer above threshold             |
| ---------------------- | --------------------------------- | --------------------------------- |
| `--threshold`          | Pays without prompting            | Prompts on a TTY; refuses without |
| `--threshold` and `-y` | Pays without prompting            | Refuses (exit code 2)             |
| `-y`, no threshold     | Pays any amount                   | Pays any amount                   |
| Neither                | Prompts on a TTY; refuses without | Prompts on a TTY; refuses without |

Use `--threshold` with `-y` for agent runs: the threshold stays a hard cap, and `-y` only removes the prompt. The threshold limits one request; it does not enforce a total budget across requests.

### Networks and protocols

By default the CLI pays SBC on Radius. `--networks radius,base` also pays USDC on Base, and `--network testnet` pairs Radius testnet with Base Sepolia. The same wallet signs on every network:

```bash
RADIUS_HOME=.radius RADIUS_NETWORK=testnet \
  radius-cli wallet pay get https://example.com/protected \
  --networks radius,base \
  --threshold 0.001 \
  --json \
  -y
```

The list is a preference order among the networks your wallet can pay on: when a server accepts more than one, the CLI reads the wallet's balance on each and pays on the first that covers the price. A wallet that holds only USDC on Base pays on Base with `--networks radius,base`. Set the list for every run with `RADIUS_PAY_NETWORKS` or `payNetworks` in the config file. Base RPC endpoints come from `RADIUS_BASE_RPC_URL` and `RADIUS_BASE_SEPOLIA_RPC_URL`, or `rpcUrls` in the config file.

The CLI pays [x402](/build/x402.md) and [MPP](/reference/radius-sdk.md#mpp) (`WWW-Authenticate: Payment` challenges for `evm` charges). With `--protocol auto`, the default, a server that offers both is paid over x402; `--protocol x402` or `--protocol mpp` restricts it to one.

### What the CLI pays

* **Network and asset:** SBC on Radius, and USDC on Base when `--networks` includes it. Offers on other networks or in other assets are refused before anything is signed, and the keystore is unlocked only after an offer is accepted.
* **Offer choice:** x402 before MPP, then networks in `--networks` order, then offers in the server's order, skipping networks where the wallet's balance does not cover the price.
* **Protocol versions:** x402 v1 and v2, selected from the server's `x402Version`; MPP `evm` charges, paid with an EIP-3009 authorization and needing no approval or gas.
* **Schemes:** `exact` with EIP-3009 (v1 and v2) or Permit2 (v2), and `upto` with Permit2 (v2), where the facilitator settles actual usage up to the signed maximum.
* **Redirects:** followed by `fetch` (up to 20). A request whose `402` comes after a redirect is paid at the final URL, repeating the verb and body, with the price cap and `--threshold` applied to that offer. A redirect after payment is followed without the payment header, and the receipt is read from it.

### Permit2 approval

Permit2 payments need a SBC allowance for the Permit2 contract. When the server declares `eip2612GasSponsoring`, as the Radius facilitator does, the CLI signs a permit for the payment amount with each payment and sends no approval transaction, so a wallet that holds only SBC can pay.

A facilitator that sponsors a raw unlimited approve (`erc20ApprovalGasSponsoring`) instead of a permit is treated like an unsponsored approval: the CLI prompts, or refuses without a TTY unless you pass `--approve-permit2` (or `-y`).

Without sponsorship, pass `--approve-permit2` (or `-y`) to send a one-time unlimited approval automatically, paying gas in SBC on Radius or ETH on Base; otherwise the CLI prompts, or refuses without a TTY. `--approve-permit2` also sends the approval when the payment is sponsored, which resolves a facilitator `412` response. Each payment is still authorized by a Permit2 signature capped to its amount.

### Output

The response body goes to stdout. Payment confirmation and, with `--include`, status and headers go to stderr. With `--json`, stdout is one object: `{status, headers, body, bodyEncoding, payment}`. `payment.network` is the CAIP-2 network paid on and `payment.protocol` is `x402` or `mpp`.

## Check a paid endpoint

Use `radius-cli sell check <url>` on your own paid route, locally or deployed, to see what buyers will be asked for. It requests the URL without paying (`-X` sets the method, `-H` and `-d` work as for `wallet pay`), decodes the x402 `PAYMENT-REQUIRED` challenge (or, as the SDK buyer does, an x402 challenge in the JSON body) and any MPP `WWW-Authenticate: Payment` challenge with [`radius-sdk`](/reference/radius-sdk.md), and checks:

* the unpaid response is a `402` marked `no-store`
* each offer's network is known, its asset and EIP-712 domain are the network's payment asset, its amount parses (and equals `--price` at the asset's decimals), `payTo` is an address, and `maxTimeoutSeconds` is sensible
* the challenge's `resource.url` is the requested URL
* the facilitator's `/supported` lists each offer's scheme, network and transfer method: the network's default facilitator, or the ones given with `--facilitator <url>` (`RADIUS_FACILITATOR_API_KEY` is sent as `x-api-key`)
* a `radius-sdk` buyer would select the offer, and each MPP challenge mirrors an x402 offer

```bash
radius-cli sell check http://localhost:8787/api/lookup --price '$0.001'
radius-cli sell check https://api.example.com/query -X post -d '{"q":1}' --facilitator https://facilitator.example
radius-cli --json sell check http://localhost:8787/api/lookup --probe-head
```

`--probe-head` also sends an unpaid `HEAD` and warns when it is served, because routers answer `HEAD` with the `GET` handler. `--pay --threshold <amount>` then makes one paid request from the local wallet and checks that a receipt comes back. It pays on testnet unless `--network mainnet` is given, whatever `RADIUS_NETWORK` says. The paid request gets a longer timeout than `--timeout`, and if it still fails after the payment was sent, the report says the payment may have settled.

The command prints one line per check (`ok`, `warn`, `FAIL`, `skip`, `info`); with `--json`, stdout is one object with `ok`, `offers`, `mpp`, `facilitators`, `checks` and `summary`. It exits `0` when no check failed, `1` when one did, and `2` on invalid flags (a malformed `-H`, an unreadable `-d @file`, an unknown `--network`, a bad `--price` or `--threshold`).

## When to use other tools

| Task                                       | Preferred tool                           |
| ------------------------------------------ | ---------------------------------------- |
| Application reads and writes               | viem                                     |
| React wallet UX                            | wagmi + viem                             |
| Contract tests and deployment scripts      | Foundry                                  |
| Local agent wallet operations              | `radius-cli`                             |
| One-off contract reads from a terminal     | `radius-cli call` or Foundry `cast call` |
| Paid endpoints from an agent shell         | `radius-cli wallet pay`                  |
| Check your own paid endpoint               | `radius-cli sell check`                  |
| Accept or make x402 payments in TypeScript | [`radius-sdk`](/reference/radius-sdk.md)    |

## Related pages

* [Build with LLMs](/build/coding-assistants.md)
* [Create and Fund a Wallet](/build/wallet.md)
* [Tooling configuration](/build/tooling.md)
* [Network and RPC](/reference/network.md)
* [radius-sdk](/reference/radius-sdk.md)
* [x402 payments](/build/x402.md)
* [Agent payments](/build/examples/agent-payments.md)
* [Example projects](/build/examples/workshop-playground.md)
