> ## Documentation Index
> Fetch the complete documentation index at: https://docs.useveil.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Wallet tools

> Create wallets, inspect balances, configure auto-settle rules, and credit sandbox wallets via MCP.

Nine tools manage Veil wallets. A wallet is a blockchain address that holds crypto on a specific chain. Deposits received there can convert to fiat automatically (auto-settle) or stay as crypto until you run an offramp manually.

***

### veil\_wallets\_list

List your wallets with balances, deposit addresses, and bank account pointers. Auto-provisions default wallets on first access for fully-onboarded users.

**Inputs**

None.

**Outputs**

<ResponseField name="status" type="string" required>
  `ok` on success, `error` on failure.
</ResponseField>

<ResponseField name="wallets" type="array">
  Array of wallet records. Each has: `id`, `name`, `chain`, `chainName`, `depositAddress`, `supportedAssets`, `balance` (map of asset to amount string), `createdAt`, and `bankAccount` (`{ id, suffixLast4, currency }` or null).
</ResponseField>

<ResponseField name="totalBalance" type="object">
  Aggregate balance across all wallets, keyed by asset.
</ResponseField>

<ResponseField name="stage" type="string">
  Present when the user has not completed onboarding. Describes the missing step.
</ResponseField>

<ResponseField name="reason" type="string">
  Error description when `status` is `error`.
</ResponseField>

**Example**

```dialog theme={null}
[calls veil_wallets_list]
→ status: "ok", wallets: [{
    id: "wal_xyz", name: "Base wallet", chain: "base", chainName: "Base",
    depositAddress: "0xabc…123", supportedAssets: ["USDC", "USDT"],
    balance: { USDC: "120.00", USDT: "0.00" },
    bankAccount: { id: "ba_abc", suffixLast4: "1234", currency: "EUR" }
  }], totalBalance: { USDC: "120.00" }
```

***

### veil\_wallet\_create

Create a new wallet on a specific chain. Requires completed KYC and a bank account. Returns an error if a wallet already exists on the requested chain.

**Inputs**

<ParamField body="chain" type="string" required>
  Blockchain to create the wallet on. One of `ethereum`, `base`, `polygon`, or `solana`.
</ParamField>

<ParamField body="name" type="string">
  Optional display name for the wallet.
</ParamField>

**Outputs**

<ResponseField name="status" type="string" required>
  `ok` on success, `error` on failure.
</ResponseField>

<ResponseField name="wallet" type="object">
  The newly created wallet record. Same shape as each item in `veil_wallets_list`.
</ResponseField>

<ResponseField name="reason" type="string">
  Error description when `status` is `error`. Common values include `A wallet already exists on this chain` and `Complete onboarding first`.
</ResponseField>

**Example**

```dialog theme={null}
[calls veil_wallet_create with chain="base"]
→ status: "ok", wallet: { id: "wal_new", chain: "base", depositAddress: "0xdef…456", balance: {} }
```

***

### veil\_wallet\_get

Get details for a specific wallet, including deposit address, balance, and the last 10 transactions. To see auto-settle configuration, call `veil_rules_list`.

**Inputs**

<ParamField body="walletId" type="string" required>
  Wallet ID from `veil_wallets_list`.
</ParamField>

**Outputs**

<ResponseField name="status" type="string" required>
  `ok` on success, `error` on failure.
</ResponseField>

<ResponseField name="wallet" type="object">
  Full wallet record. Same shape as `veil_wallets_list`.
</ResponseField>

<ResponseField name="recentTransactions" type="array">
  Last 10 transactions for this wallet. Each has: `id`, `type`, `status`, `amountIn`, `assetIn`, `amountOut`, `currencyOut`, `fee`, `wireRef`, `createdAt`, `settledAt`.
</ResponseField>

<ResponseField name="reason" type="string">
  Error description when `status` is `error`.
</ResponseField>

**Example**

```dialog theme={null}
[calls veil_wallet_get with walletId="wal_xyz"]
→ status: "ok", wallet: { balance: { USDC: "120.00" }, depositAddress: "0xabc…123" },
  recentTransactions: [{ id: "txn_123", status: "completed", amountOut: "46.23" }]
```

***

### veil\_wallet\_set\_primary\_bank\_execute

Start a payout-bank reassignment for a wallet. Sends a one-time confirmation code to the account email. Call `veil_wallet_set_primary_bank_confirm` with the returned `requestId` and the code to apply the change. Call `veil_bank_accounts_list` first to see available bank accounts.

**Inputs**

<ParamField body="walletId" type="string" required>
  Wallet to update.
</ParamField>

<ParamField body="bankAccountId" type="string" required>
  Bank account to set as primary. From `veil_bank_accounts_list`.
</ParamField>

**Outputs**

<ResponseField name="status" type="string" required>
  `ok` on success, `error` on failure.
</ResponseField>

<ResponseField name="requestId" type="string">
  Opaque identifier to pass to `veil_wallet_set_primary_bank_confirm`.
</ResponseField>

<ResponseField name="maskedEmail" type="string">
  Partially masked email address where the confirmation code was sent.
</ResponseField>

<ResponseField name="expiresIn" type="number">
  Seconds until the confirmation code expires.
</ResponseField>

<ResponseField name="message" type="string">
  Human-readable prompt to display while waiting for the code.
</ResponseField>

<ResponseField name="reason" type="string">
  Error description when `status` is `error`.
</ResponseField>

**Example**

```dialog theme={null}
[calls veil_wallet_set_primary_bank_execute with walletId="wal_xyz", bankAccountId="ba_def"]
→ status: "ok", requestId: "req_abc", maskedEmail: "u***@example.com", expiresIn: 600,
  message: "A confirmation code has been sent to u***@example.com."
```

***

### veil\_wallet\_set\_primary\_bank\_confirm

Confirm a payout-bank reassignment using the code sent by `veil_wallet_set_primary_bank_execute`. Cannot be changed while transactions are in flight.

**Inputs**

<ParamField body="walletId" type="string" required>
  Wallet to update (must match the execute call).
</ParamField>

<ParamField body="bankAccountId" type="string" required>
  Bank account to set as primary (must match the execute call).
</ParamField>

<ParamField body="requestId" type="string" required>
  The `requestId` returned by `veil_wallet_set_primary_bank_execute`.
</ParamField>

<ParamField body="otp" type="string" required>
  The 6-digit confirmation code from the email.
</ParamField>

**Outputs**

<ResponseField name="status" type="string" required>
  `ok` on success, `error` on failure.
</ResponseField>

<ResponseField name="wallet" type="object">
  Updated wallet record with the new `bankAccount` pointer.
</ResponseField>

<ResponseField name="reason" type="string">
  Error description when `status` is `error`. When the code is incorrect, re-call this tool with the same `requestId` — the code remains valid until it expires or too many wrong attempts are made.
</ResponseField>

**Example**

```dialog theme={null}
[calls veil_wallet_set_primary_bank_confirm with walletId="wal_xyz", bankAccountId="ba_def",
  requestId="req_abc", otp="123456"]
→ status: "ok", wallet.bankAccount: { id: "ba_def", suffixLast4: "5678", currency: "USD" }
```

***

### veil\_wallet\_set\_source\_address\_execute

Start an auto-settle rule change that routes deposits from a source address to a specific bank account. Sends a one-time confirmation code to the account email. Call `veil_wallet_set_source_address_confirm` with the `requestId` and the code to apply the change.

**Inputs**

<ParamField body="walletId" type="string" required>
  Wallet to configure.
</ParamField>

<ParamField body="sourceAddress" type="string" required>
  The sending address to watch. Deposits from this address trigger auto-settle.
</ParamField>

<ParamField body="bankAccountId" type="string" required>
  Bank account to route payouts to. From `veil_bank_accounts_list`.
</ParamField>

**Outputs**

<ResponseField name="status" type="string" required>
  `ok` on success, `error` on failure.
</ResponseField>

<ResponseField name="requestId" type="string">
  Opaque identifier to pass to `veil_wallet_set_source_address_confirm`.
</ResponseField>

<ResponseField name="maskedEmail" type="string">
  Partially masked email address where the confirmation code was sent.
</ResponseField>

<ResponseField name="expiresIn" type="number">
  Seconds until the confirmation code expires.
</ResponseField>

<ResponseField name="message" type="string">
  Human-readable prompt to display while waiting for the code.
</ResponseField>

<ResponseField name="reason" type="string">
  Error description when `status` is `error`.
</ResponseField>

**Example**

```dialog theme={null}
[calls veil_wallet_set_source_address_execute with walletId="wal_xyz",
  sourceAddress="0xabc…123", bankAccountId="ba_abc"]
→ status: "ok", requestId: "req_def", maskedEmail: "u***@example.com", expiresIn: 600
```

***

### veil\_wallet\_set\_source\_address\_confirm

Confirm an auto-settle rule change using the code sent by `veil_wallet_set_source_address_execute`. On success, returns the active rule and the minimum deposit threshold (if any).

**Inputs**

<ParamField body="walletId" type="string" required>
  Wallet to configure (must match the execute call).
</ParamField>

<ParamField body="sourceAddress" type="string" required>
  The source address (must match the execute call).
</ParamField>

<ParamField body="bankAccountId" type="string" required>
  The bank account (must match the execute call).
</ParamField>

<ParamField body="requestId" type="string" required>
  The `requestId` returned by `veil_wallet_set_source_address_execute`.
</ParamField>

<ParamField body="otp" type="string" required>
  The 6-digit confirmation code from the email.
</ParamField>

**Outputs**

<ResponseField name="status" type="string" required>
  `ok` on success, `error` on failure.
</ResponseField>

<ResponseField name="rule" type="object">
  The active auto-settle rule. Contains `walletId`, `chain`, `chainName`, `sourceAddress`, `createdAt`, and `bankAccount` (`{ id, suffixLast4, currency }`).
</ResponseField>

<ResponseField name="minimum" type="object">
  The corridor minimum, if one applies. Has `fiat` (number), `fiatCurrency`, `sourceMin` (number), and `sourceCurrency`. Null if no minimum applies.
</ResponseField>

<ResponseField name="reason" type="string">
  Error description when `status` is `error`. When the code is incorrect, re-call this tool with the same `requestId` — the code remains valid until it expires or too many wrong attempts are made. If the payment processor is temporarily unavailable, the code is still valid — retry the confirm call.
</ResponseField>

**Example**

```dialog theme={null}
[calls veil_wallet_set_source_address_confirm with walletId="wal_xyz",
  sourceAddress="0xabc…123", bankAccountId="ba_abc", requestId="req_def", otp="654321"]
→ status: "ok", rule: {
    walletId: "wal_xyz", chain: "base", chainName: "Base",
    sourceAddress: "0xabc…123", createdAt: "2026-05-21T12:00:00Z",
    bankAccount: { id: "ba_abc", suffixLast4: "1234", currency: "EUR" }
  },
  minimum: { fiat: 27.74, fiatCurrency: "EUR", sourceMin: 30, sourceCurrency: "USDC" }
```

***

### veil\_wallet\_disable\_auto\_settle

Disable the auto-settle rule for a wallet. Future deposits land in the wallet as crypto. In-flight transactions complete normally. The deposit address is preserved.

**Inputs**

<ParamField body="walletId" type="string" required>
  Wallet to disable auto-settle on.
</ParamField>

**Outputs**

<ResponseField name="status" type="string" required>
  `ok` on success, `error` on failure.
</ResponseField>

<ResponseField name="rule" type="object">
  Null on successful disable.
</ResponseField>

<ResponseField name="reason" type="string">
  Error description when `status` is `error`.
</ResponseField>

**Example**

```dialog theme={null}
[calls veil_wallet_disable_auto_settle with walletId="wal_xyz"]
→ status: "ok", rule: null
```

***

### veil\_sandbox\_faucet\_credit

Credit 5 USDC\_TEST to a sandbox wallet on Base Sepolia via the Veil faucet. The deposit lands at the wallet's deposit address in about 30 seconds. Sandbox-only — switch with `veil_set_mode` if you're in live mode.

**Inputs**

<ParamField body="walletId" type="string" required>
  Wallet ID from `veil_wallets_list`. Must be a Base Sepolia wallet in sandbox mode.
</ParamField>

**Outputs**

<ResponseField name="status" type="string" required>
  `credited` on success, `error` on failure.
</ResponseField>

<ResponseField name="txHash" type="string">
  On-chain transaction hash of the faucet broadcast. Present when `status` is `credited`.
</ResponseField>

<ResponseField name="broadcastAt" type="string">
  ISO timestamp of when the faucet broadcast the transaction. Present when `status` is `credited`.
</ResponseField>

<ResponseField name="reason" type="string">
  Error description when `status` is `error`. Common values:

  * `The sandbox faucet only runs in sandbox mode. Use veil_set_mode to switch first.` — active mode is live
  * `No wallet with that ID. Use veil_wallets_list to see your wallets.` — wrong ID or not yours
  * `That wallet is not a Base sandbox wallet — the faucet only funds Base sandbox wallets.` — wallet is on a different chain or live mode
  * `Daily faucet limit reached. Try again tomorrow.` — hit the per-day cap (shared with the dashboard and CLI)
  * `Another faucet request is in flight for this account. Retry in a moment.` — a prior request hasn't completed
  * `Sandbox faucet is temporarily disabled.` — faucet is offline for maintenance
  * `Faucet transaction failed to broadcast. Try again in a moment.` — transient broadcast failure
</ResponseField>

**Example**

```dialog theme={null}
[calls veil_sandbox_faucet_credit with walletId="wal_xyz"]
→ status: "credited", txHash: "0xdef…789", broadcastAt: "2026-05-18T14:23:01Z"
```

## See also

* [Wallets](/concepts/wallets) — what wallets are and how balances work
* [Auto-settle](/concepts/auto-settle) — the automatic conversion model
* [Rules tools](/mcp/tools/rules-and-health) — inspect active auto-settle rules
* [Get test tokens](/developers/sandbox/faucet) — dashboard equivalent of `veil_sandbox_faucet_credit`
