# Accounts

> pay topup, account, setup, send, and subscriptions — manage wallets, fund them, send stablecoins, and track MPP subscriptions.

Account commands manage the local wallets in `~/.config/pay/accounts.yml`, fund them, send stablecoins, and track active MPP subscription delegations.

| Command                               | One-liner                                                          |
| ------------------------------------- | ------------------------------------------------------------------ |
| [`topup`](#pay-topup)                 | Fund an account from PayPal, Venmo, Apple Pay, or a mobile wallet. |
| [`account`](#pay-account)             | New / import / list / default / remove / export wallets.           |
| [`setup`](#pay-setup)                 | Generate a keypair, store it, and run the funding flow.            |
| [`send`](#pay-send)                   | Send stablecoins to a recipient.                                   |
| [`subscriptions`](#pay-subscriptions) | Manage MPP subscription delegations.                               |

<Callout type="caution">
  `send`, `account remove`, `account export`, and `subscriptions cancel` move funds or destroy local state. Treat them
  as high-intent — don't run them on a user's behalf without explicit confirmation.
</Callout>

## `pay setup`

Generate a keypair, store it in the OS secure store, and install MCP configs for any detected agent (Claude Code, Cursor, Codex). Ends by launching the [`topup`](#pay-topup) flow so you can fund the new account immediately.

```sh
pay setup
pay setup --force                       # replace an existing account
pay setup --backend keychain            # macOS (default)
pay setup --backend gnome-keyring       # Linux (default)
pay setup --backend windows-hello       # Windows (default)
pay setup --update                      # refresh MCP config only — no new account
```

| Flag        | Type   | Default    | Description                                                                                                                          |
| ----------- | ------ | ---------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `--force`   | bool   | `false`    | Replace an existing account on the current network.                                                                                  |
| `--backend` | enum   | OS default | Storage backend: `keychain` (macOS), `gnome-keyring` (Linux), `windows-hello` (Windows).                                             |
| `--update`  | bool   | `false`    | Reinstall MCP configs and the agent skill without creating a new account.                                                            |
| `--account` | string | derived    | Account name. When omitted, `pay` derives it from `$USER` / `$USERNAME` / `whoami`, sanitized, with `default` as the final fallback. |

After funds arrive, `pay setup` prints `Setup complete` with the received amount and a transaction link. Press `Esc` to skip funding; `pay setup` prints `Setup aborted` with the `pay topup` command to run later. Sandbox calls work regardless — they generate ephemeral wallets on first use.

## `pay topup`

Fund an account on mainnet (or localnet with `--sandbox`). Opens an interactive TUI with two paths.

```sh
pay topup
pay topup --account <pubkey>
pay topup --sandbox                     # localnet account instead of mainnet
```

| Flag        | Type   | Description                                                               |
| ----------- | ------ | ------------------------------------------------------------------------- |
| `--account` | string | Account address to receive funds. Defaults to the active mainnet account. |
| `--sandbox` | bool   | Fund the sandbox (localnet) account instead of mainnet.                   |

| Path                | What happens                                                                                                                                                         |
| ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Mobile wallet**   | Renders a Solana Pay QR encoding `solana:<pubkey>?amount=<n>&spl-token=<USDC mint>`. Scan from Phantom, Solflare, Backpack, etc.                                     |
| **Buy stablecoins** | Press `Enter` to open the gateway `/onramp` redirect in your browser. Pick PayPal, Venmo, or Apple Pay; the gateway hands off to MoonPay with a server-side API key. |

The TUI polls the wallet's stablecoin balance every second (after a 5-second startup delay) for up to 5 minutes. When the balance increases, the success animation fires and the command exits. After 5 minutes idle, polling halts and a yellow `▲ idle 5m — press R to refresh` banner appears; press `R` to restart the cycle.

Override the onramp host or pay-api host via [environment variables](/docs/toolchain/global-flags#environment-variables).

## `pay whoami`

See [Pass-through → `pay whoami`](/docs/toolchain/commands/pass-through#pay-whoami). It's grouped under pass-through because it mirrors the Unix `whoami` shape, but it inspects the active `pay` account.

## `pay account`

Manage accounts. With no subcommand, lists accounts and prints the available subcommands. Alias: `accounts`.

```sh
pay account
pay account new work
pay account import work ./keypair.json
pay account list
pay account default work
pay account export work
pay account remove work
```

| Subcommand                                    | Aliases         | Purpose                        |
| --------------------------------------------- | --------------- | ------------------------------ |
| [`new <NAME>`](#pay-account-new)              | —               | Create a new account.          |
| [`import <NAME> <FILE>`](#pay-account-import) | —               | Import from a JSON key file.   |
| [`list`](#pay-account-list)                   | `ls`            | List accounts with balances.   |
| [`default <NAME>`](#pay-account-default)      | —               | Set the default account.       |
| [`remove <NAME>`](#pay-account-remove)        | `rm`, `destroy` | Permanently delete an account. |
| [`export <NAME> [PATH]`](#pay-account-export) | `backup`        | Export to a JSON key file.     |

### `pay account new`

```sh
pay account new work
pay account new work --backend keychain --force
```

| Flag        | Type       | Description                                                             |
| ----------- | ---------- | ----------------------------------------------------------------------- |
| `<NAME>`    | positional | Account name. Required.                                                 |
| `--backend` | enum       | `keychain`, `gnome-keyring`, or `windows-hello`. Defaults to OS native. |
| `--force`   | bool       | Replace an existing account with the same name.                         |

### `pay account import`

```sh
pay account import imported ./keypair.json
```

| Flag        | Type       | Description                                      |
| ----------- | ---------- | ------------------------------------------------ |
| `<NAME>`    | positional | Account name. Required.                          |
| `<FILE>`    | positional | Path to the JSON key file. Required.             |
| `--backend` | enum       | `keychain`, `gnome-keyring`, or `windows-hello`. |

### `pay account list`

```sh
pay account list
pay accounts ls
```

Lists every registered account with its non-zero stablecoin balances. Use `pay --no-dna account list` for machine-readable output.

### `pay account default`

Update the default account.

```sh
pay account default work
```

| Flag     | Type       | Description                                 |
| -------- | ---------- | ------------------------------------------- |
| `<NAME>` | positional | Account name to make the default. Required. |

### `pay account remove`

Permanently delete an account and its secret key. Aliases: `rm`, `destroy`.

```sh
pay account remove work
pay account remove sandbox-abc123 --sandbox --yes
```

| Flag        | Type       | Description                                  |
| ----------- | ---------- | -------------------------------------------- |
| `<NAME>`    | positional | Account name. Required.                      |
| `--sandbox` | bool       | Remove from `localnet` instead of `mainnet`. |
| `--yes`     | bool       | Skip the confirmation prompt.                |

### `pay account export`

Export an account to a JSON key file. Alias: `backup`.

```sh
pay account export work
pay account export work ./work-backup.json
pay account export work -                 # stdout
```

| Flag     | Type       | Description                                                                            |
| -------- | ---------- | -------------------------------------------------------------------------------------- |
| `<NAME>` | positional | Account name. Required.                                                                |
| `[PATH]` | positional | Output file path, or `-` for stdout. Defaults to `./pay-account-<name>-<pubkey>.json`. |

## `pay send`

Send stablecoins to a recipient address or a configured account name. `max` sends the entire selected stablecoin balance. Alias: `push`.

```sh
pay send 1.25 <recipient>
pay send 1 <recipient> --currency USDC
pay send max <recipient> --currency USDT
pay send 1 <recipient> --memo invoice-123
pay send 1 <recipient> --memo-hex 48656c6c6f
pay send 1 <recipient> --fee-within
```

| Flag           | Type       | Description                                                                                         |
| -------------- | ---------- | --------------------------------------------------------------------------------------------------- |
| `<AMOUNT>`     | positional | Decimal amount, or `max`. Required.                                                                 |
| `<RECIPIENT>`  | positional | Base58 pubkey or account name. Required.                                                            |
| `--currency`   | string     | Stablecoin symbol. When omitted, `pay` picks an eligible balance or prompts when multiple can pay.  |
| `--memo`       | string     | Optional memo. Max 566 bytes. Mutually exclusive with `--memo-hex`.                                 |
| `--memo-hex`   | hex        | Hex-encoded UTF-8 memo. Must decode to valid UTF-8.                                                 |
| `--fee-within` | bool       | Take the fee-payer refund out of `AMOUNT` instead of adding on top. Implied when `AMOUNT` is `max`. |

Non-interactive callers should pass `--currency` explicitly — otherwise `pay` prompts when multiple stablecoin balances could fund the transfer.

## `pay subscriptions`

Manage MPP `subscription`-intent delegations. With no subcommand, lists all subscriptions and prints the available verbs. Aliases: `subscription`, `subs`.

```sh
pay subscriptions                       # default = list + help
pay subscriptions list --network mainnet
pay subscriptions status <id>
pay subscriptions new --plan <pda> --mint <mint> --puller <pubkey> --recipient <wallet> --amount 1000000 --period 30d
pay subscriptions cancel <id>
pay subscriptions refresh
```

| Subcommand                              | Purpose                                                   |
| --------------------------------------- | --------------------------------------------------------- |
| [`list`](#pay-subscriptions-list)       | List subscriptions across every account, or filter.       |
| [`status`](#pay-subscriptions-status)   | Show detail for one subscription by base58 ID.            |
| [`new`](#pay-subscriptions-new)         | Activate a new subscription against an on-chain Plan PDA. |
| [`cancel`](#pay-subscriptions-cancel)   | Cancel a subscription.                                    |
| [`refresh`](#pay-subscriptions-refresh) | Backfill missing on-chain data on local entries.          |

### `pay subscriptions list`

```sh
pay subscriptions list
pay subscriptions list --account work
pay subscriptions list --network devnet --json
```

| Flag        | Type   | Description                                               |
| ----------- | ------ | --------------------------------------------------------- |
| `--account` | string | Filter to a single account name.                          |
| `--network` | string | Filter to a single network slug (`mainnet`, `devnet`, …). |
| `--json`    | bool   | Emit JSON instead of a table.                             |

### `pay subscriptions status`

Show detail for a single subscription by its base58 `subscription_id`.

```sh
pay subscriptions status 4xZ…
pay subscriptions status 4xZ… --json
```

| Flag                | Type       | Description                                                                                              |
| ------------------- | ---------- | -------------------------------------------------------------------------------------------------------- |
| `<SUBSCRIPTION_ID>` | positional | Base58 `subscription_id` (the `SubscriptionDelegation` PDA from the `Payment-Receipt` header). Required. |
| `--json`            | bool       | Emit JSON instead of the formatted view.                                                                 |

### `pay subscriptions new`

Activate a new subscription against an explicit on-chain Plan PDA. Every required flag corresponds to a field the on-chain program checks.

```sh
pay subscriptions new \
  --plan PLAN_PDA_BASE58 \
  --mint USDC_MINT_BASE58 \
  --puller SERVER_PULLER_BASE58 \
  --recipient WALLET_BASE58 \
  --amount 1000000 \
  --period 30d
```

| Flag              | Type       | Required | Description                                                                                      |
| ----------------- | ---------- | -------- | ------------------------------------------------------------------------------------------------ |
| `--plan`          | base58     | yes      | On-chain `Plan` PDA — the spec's required `externalId`.                                          |
| `--mint`          | base58     | yes      | SPL Token or Token-2022 mint.                                                                    |
| `--puller`        | base58     | yes      | Server puller pubkey. Must be `plan.owner` or in `plan.pullers`.                                 |
| `--recipient`     | base58     | yes      | Recipient wallet bound to the activation transaction. Must be authorized by `plan.destinations`. |
| `--amount`        | base units | yes      | Per-period charge in mint base units (decimal string).                                           |
| `--period`        | duration   | yes      | Billing period (e.g. `30d`, `2w`). `month` is rejected per the Solana subscription profile.      |
| `--description`   | string     | no       | Optional human-readable label echoed into the local record.                                      |
| `--network`       | string     | no       | Solana network slug (`mainnet`, `devnet`, `localnet`, `sandbox`).                                |
| `--account`       | string     | no       | Specific account name within the resolved network.                                               |
| `--rpc-url`       | URL        | no       | RPC URL override.                                                                                |
| `--fee-payer-key` | base58     | no       | Fee-payer pubkey when the server is sponsoring fees.                                             |

### `pay subscriptions cancel`

Cancel a subscription by base58 ID.

```sh
pay subscriptions cancel 4xZ…
pay subscriptions cancel 4xZ… --local-only
pay subscriptions cancel 4xZ… --via-gateway https://pay-api.gateway-402.com
```

| Flag                  | Type       | Description                                                                                                                                                                                                |
| --------------------- | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `<SUBSCRIPTION_ID>`   | positional | Base58 `subscription_id`. Required.                                                                                                                                                                        |
| `--local-only`        | bool       | Skip the on-chain cancel tx; only flip the local entry to `cancelled`. Use when the on-chain side was already cancelled out of band.                                                                       |
| `--via-gateway`       | URL        | Force routing through the pay-api gateway, even when the subscriber has enough SOL for a direct broadcast. Auto-routed via `$PAY_API_URL` when the subscriber's SOL balance is below the per-tx threshold. |
| `--gateway-fee-payer` | base58     | Gateway operator pubkey that signs as fee-payer. Required when routing via the gateway. Defaults to `$PAY_API_FEE_PAYER`.                                                                                  |
| `--rpc-url`           | URL        | RPC URL override. Defaults to `$PAY_RPC_URL`, else the canonical public RPC for the subscription's network.                                                                                                |

### `pay subscriptions refresh`

Backfill missing on-chain data (e.g. `activation_signature`) on local entries.

```sh
pay subscriptions refresh
pay subscriptions refresh --account work --network mainnet
```

| Flag        | Type   | Description                                                                              |
| ----------- | ------ | ---------------------------------------------------------------------------------------- |
| `--account` | string | Filter to a single account name.                                                         |
| `--network` | string | Filter to a single network slug.                                                         |
| `--rpc-url` | URL    | Override the lookup RPC. Falls back to the canonical RPC for the subscription's network. |
