# Configuration

> Files pay reads on every invocation — pay.toml, accounts.yml, and the PAY_* environment variables.

`pay` reads three sources, in this order of precedence:

1. Explicit flags (`--sandbox`, `--account`, …)
2. `PAY_*` environment variables
3. `pay.toml` (looked up via `$PAY_CONFIG`, then `./pay.toml`, then `~/.config/pay/pay.toml`)
4. Built-in defaults

Accounts live separately in `~/.config/pay/accounts.yml`. That file is mandatory once you have a non-ephemeral wallet.

## `~/.config/pay/accounts.yml`

The on-disk registry of wallets, grouped by network. Schema version `2`:

```yaml
version: 2
accounts:
  mainnet:
    default:
      keystore: apple-keychain # apple-keychain | gnome-keyring | windows-hello | file | ephemeral
      active: true # used when multiple accounts share a network
      auth_required: true # mainnet defaults to true; sandbox defaults to false
      pubkey: 96WoyH3JmANSMsQLGC3MKyiGiXCymZyM9SLaWjcRrKuD
  localnet:
    sandbox-abc123:
      keystore: ephemeral
      pubkey: 5jSk… # base58
      secret_key_b58: 4xZ… # only for keystore: ephemeral
      created_at: 2026-05-02T17:21:03Z
```

| Field            | Required         | Description                                                                                                                                 |
| ---------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| `keystore`       | yes              | Where the secret key lives. `apple-keychain`, `gnome-keyring`, `windows-hello`, `file`, or `ephemeral`.                                     |
| `active`         | no               | Which account to use when multiple accounts share a network. If no account is marked `active`, pay falls back to the first alphabetically.  |
| `auth_required`  | no               | Require an OS prompt before signing. `true` by default on mainnet, `false` on sandbox/localnet.                                             |
| `pubkey`         | yes              | Cached base58 public key.                                                                                                                   |
| `path`           | only `file`      | Path to the JSON key file on disk.                                                                                                          |
| `secret_key_b58` | only `ephemeral` | Inline base58 secret. Used for sandbox-generated wallets.                                                                                   |
| `created_at`     | only `ephemeral` | RFC 3339 timestamp.                                                                                                                         |
| `subscriptions`  | no               | Map of subscription IDs to local subscription state, written by [`pay subscriptions`](/docs/toolchain/commands/accounts#pay-subscriptions). |

### Keystore backends

| Backend          | Platform     | Notes                                                                        |
| ---------------- | ------------ | ---------------------------------------------------------------------------- |
| `apple-keychain` | macOS        | Default on macOS. Stored in the user's login keychain.                       |
| `gnome-keyring`  | Linux        | Default on Linux when the Secret Service is available.                       |
| `windows-hello`  | Windows      | Default on Windows.                                                          |
| `file`           | any          | Plain JSON key file at `path`. Use only when secure storage isn't available. |
| `ephemeral`      | sandbox only | Auto-generated by `--sandbox` calls and persisted under `localnet:`.         |

## `~/.config/pay/pay.toml`

Optional defaults applied to every invocation. All keys are optional.

```toml
auto_pay   = false                                  # auto-satisfy 402 challenges
keypair    = "~/.config/solana/id.json"             # legacy keypair for non-payment commands
rpc_url    = "https://api.mainnet-beta.solana.com"  # RPC override
log_format = "text"                                 # text | json
```

| Key          | Type   | Default  | Description                                                                                  |
| ------------ | ------ | -------- | -------------------------------------------------------------------------------------------- |
| `auto_pay`   | bool   | `false`  | Automatically satisfy HTTP 402 challenges without prompting.                                 |
| `keypair`    | string | —        | Path to a Solana keypair file, for commands that read pay.toml directly.                     |
| `rpc_url`    | string | —        | Mainnet RPC override. Subordinate to `--sandbox`/`--local`/`--mainnet` and to `PAY_RPC_URL`. |
| `log_format` | string | `"text"` | `"text"` or `"json"`.                                                                        |

Discovery order: `$PAY_CONFIG`, then `./pay.toml`, then `~/.config/pay/pay.toml`. Any `PAY_*` environment variable wins over the file.

## Environment variables

See [Global flags → Environment variables](/docs/toolchain/global-flags#environment-variables) for the full table. The two you reach for most:

| Variable             | What it does                                                             |
| -------------------- | ------------------------------------------------------------------------ |
| `PAY_ACTIVE_ACCOUNT` | Force a named account, overriding `active: true` in `accounts.yml`.      |
| `NO_DNA`             | Mark the caller as an AI agent: enables auto-pay and JSON-shaped output. |
