# Agent Wallets

Every agent in RailProtocol has a non-custodial Solana wallet. The wallet is the source of funds for all payments the agent makes. RailProtocol cannot move funds without a valid signed instruction from the agent's keypair.

***

## How wallets work

Agent wallets are **program-derived addresses (PDAs)** on Solana, derived from the agent's unique ID and the RailProtocol on-chain program. The PDA is deterministic — the same agent ID always produces the same wallet address.

USDC is held in a Solana Associated Token Account (ATA) owned by the PDA. When an agent makes a payment, RailProtocol constructs a Solana transaction signed by the agent's keypair, transfers USDC to the payee, and records the payment in the on-chain ledger.

***

## Creating a wallet

```bash
rail wallet create --agent my-agent
```

```
Agent wallet created.

  Agent:    my-agent
  Address:  7xKXtg2xpAGMq8KLwpSodE9LFKq8Z1EscezSShpump
  Balance:  0.00 USDC
  Network:  Solana Mainnet
```

In the SDK:

```typescript
const wallet = await rail.wallet.get();
console.log(wallet.address);  // 7xKXtg2xpAGMq8KLwpSodE9LFKq8Z1EscezSShpump
console.log(wallet.balance);  // { usdc: 0.00 }
```

***

## Funding a wallet

### Via dashboard

Deposit USDC to the wallet address at [app.railprotocol.org](https://app.railprotocol.org). The dashboard also supports card top-ups that convert to USDC on-chain automatically.

### Via direct transfer

Send USDC (SPL Token) to the wallet address from any Solana wallet. Funds arrive within one block confirmation (under 400ms).

### Via CLI

```bash
rail wallet fund my-agent --usdc 100
```

This initiates a transfer from the funding source configured in your account settings.

***

## Checking balance

```bash
rail wallet balance --agent my-agent
```

```
Agent:    my-agent
Address:  7xKXtg2xpAGMq8KLwpSodE9LFKq8Z1EscezSShpump
Balance:  42.50 USDC
Network:  Solana Mainnet
```

In the SDK:

```typescript
const { usdc } = await rail.wallet.balance();
console.log(usdc);  // 42.50
```

***

## Withdrawing funds

Withdraw USDC from an agent wallet to any Solana wallet address:

```bash
rail wallet withdraw my-agent \
  --to 9zXKtg2xpAGMq8KLwpSodE9LFKq8Z1EscezSShpump \
  --usdc 20
```

Withdrawals require authentication and are logged on-chain.

***

## Keypair management

Each agent wallet is controlled by an Ed25519 keypair. RailProtocol generates and stores the keypair in encrypted form in your account. The private key never leaves RailProtocol's key management service.

For Enterprise accounts with bring-your-own-key (BYOK) requirements:

```bash
rail wallet import my-agent --keypair ./my-agent-keypair.json
```

The keypair file must be in Solana CLI JSON format (a 64-byte array). Once imported, RailProtocol stores the keypair under your account's KMS encryption.

***

## Multiple wallets

Each agent has exactly one wallet. If you need multiple spending accounts within a single agent (for example, separating payments by task type), create separate agent IDs:

```bash
rail wallet create --agent my-agent-compute
rail wallet create --agent my-agent-data
```

Each agent ID corresponds to a distinct PDA and a distinct USDC balance.

***

## On-chain visibility

Because agent wallets are Solana PDAs, every transaction is publicly visible on Solana Explorer. Anyone with the wallet address can verify the full payment history independently of RailProtocol.

```bash
rail wallet explorer my-agent
# Opens: https://explorer.solana.com/address/7xKXtg2xpAGMq8KLwpSodE9LFKq8Z1EscezSShpump
```

***

## Non-custodial guarantee

RailProtocol holds the encrypted agent keypair, but cannot unilaterally move funds. Every payment transaction requires:

1. A valid signed instruction from the agent's keypair
2. A spend policy check that passes
3. A valid x402 or MPP payment request from an authorized domain

There is no administrative override. RailProtocol support cannot transfer funds from an agent wallet without the keypair signature.

***

## Further reading

* [Spend policies](/features/spend-policies.md)
* [Security and key management](/platform/security.md)
* [TypeScript SDK: wallet methods](/sdk/typescript.md)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.railprotocol.org/features/agent-wallets.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
