Files
hermes-agent/website/docs/user-guide/features/wallet.md
Shannon Sands b2bb11ab4a fix(keystore): reorder unlock priority — interactive prompt before env var
The env var HERMES_KEYSTORE_PASSPHRASE is now correctly positioned as a
last-resort fallback for headless/Docker/systemd deployments, not as the
second-choice unlock method.

New unlock priority:
1. OS credential store (hermes keystore remember)
2. Interactive passphrase prompt (when TTY available)
3. HERMES_KEYSTORE_PASSPHRASE env var (headless fallback only)

Updated docs and code comments to clearly communicate this is a conscious
security tradeoff for unattended operation, not the recommended path.
2026-03-29 08:38:29 +10:00

9.0 KiB

sidebar_position
sidebar_position
18

Crypto Wallet

Give your agent its own crypto wallet. Hermes can hold funds, check balances, and send native tokens on Solana and EVM chains — with encrypted key storage and policy-controlled spending limits.

The agent never has access to private keys. Keys are encrypted at rest in a local keystore, and every transaction goes through a policy engine that enforces spending limits, rate limits, and owner approval thresholds.

Installation

The wallet is an optional extra — install what you need:

# EVM chains (Ethereum, Base, Polygon, Arbitrum, Optimism)
pip install 'hermes-agent[wallet]'

# + Solana support
pip install 'hermes-agent[wallet-solana]'

Setup

1. Initialize the encrypted keystore

The keystore holds all your secrets (API keys, wallet private keys) encrypted with a master passphrase.

hermes keystore init

You'll be prompted to create a passphrase. This is needed each time Hermes starts. To avoid typing it every time:

# Save to your OS credential store (macOS Keychain, Windows Credential Locker,
# GNOME/KDE Secret Service, or Linux keyctl when available)
hermes keystore remember

For headless/Docker/systemd deployments where no credential store or TTY is available, you can set HERMES_KEYSTORE_PASSPHRASE as an environment variable. This is a conscious security tradeoff — the passphrase is visible in the process environment — and should only be used for unattended deployments:

# Headless/Docker/systemd only — not recommended for interactive use
export HERMES_KEYSTORE_PASSPHRASE="your-passphrase"

Hermes intentionally does not fall back to a machine-derived encrypted file for remembered passphrases. In the current same-user execution model, that would be derivable by the local agent process and would weaken the keystore boundary.


### 2. Create a wallet

```bash
# Create a user wallet (all sends require your approval)
hermes wallet create --chain solana

# Or create an agent wallet (auto-approves within policy limits)
hermes wallet create-agent --chain solana --label "Trading Bot"

:::tip Fresh wallets recommended We recommend creating fresh wallets for your agent rather than importing personal wallets. Send the agent some tokens to get started — keep your personal funds separate. :::

3. Fund the wallet

hermes wallet fund

This displays the deposit address. Send tokens to it from your personal wallet or an exchange.

4. Enable the wallet toolset

Add wallet to your toolsets in ~/.hermes/config.yaml:

toolsets:
- hermes-cli
- wallet

Or pass it at runtime:

hermes chat -t hermes-cli,wallet

Agent Tools

Once the wallet toolset is enabled, the agent gets these tools:

Tool Description
wallet_list List all wallets with addresses and balances
wallet_balance Check balance of a specific wallet
wallet_address Get a wallet's deposit address (for sharing / receiving)
wallet_send Send native tokens — goes through the policy engine
wallet_estimate_gas Estimate transaction fees
wallet_history View recent transaction history
wallet_networks List supported blockchain networks

The agent can check its own balances, share its address to receive funds, estimate fees, and initiate transfers. It cannot read private keys, bypass spending policies, or disable the kill switch.

CLI Commands

hermes wallet create         Create a new wallet (fresh keypair)
hermes wallet create-agent   Create an agent wallet (auto-approve within limits)
hermes wallet import         Import wallet from exported private key (migration)
hermes wallet export         Export private key for migration to another machine
hermes wallet list           List all wallets with balances
hermes wallet balance        Check a wallet's balance
hermes wallet send <to> <amount>   Send tokens (interactive confirmation)
hermes wallet fund           Show deposit address for receiving tokens
hermes wallet history        View transaction history
hermes wallet freeze         Kill switch — block ALL transactions
hermes wallet unfreeze       Resume after freeze
hermes wallet status         Overview of wallet state

Keystore Commands

The keystore manages all encrypted secrets (API keys, wallet keys):

hermes keystore init              Create a new encrypted keystore
hermes keystore list              List stored secrets (names only, no values)
hermes keystore set <name>        Add or update a secret
hermes keystore show <name>       Decrypt and display a secret
hermes keystore delete <name>     Remove a secret
hermes keystore set-category      Change a secret's access category
hermes keystore migrate           Import secrets from .env file
hermes keystore remember          Cache passphrase in OS credential store
hermes keystore forget            Remove cached passphrase
hermes keystore change-passphrase Re-encrypt with a new passphrase
hermes keystore audit             Show access log
hermes keystore status            Show keystore status

Security Model

Encryption

  • Master key derived from your passphrase via Argon2id (memory-hard KDF, 64MB)
  • Each secret encrypted with XSalsa20-Poly1305 via libsodium SecretBox (AEAD, random nonce per write)
  • Master key held in memory only — never written to disk
  • Keystore DB file permissions: 0600, directory: 0700

Secret Categories

Category Who can access Examples
injectable Agent (via os.environ) API keys — OPENROUTER_API_KEY
gated Agent on request (logged) GITHUB_TOKEN
sealed Never the agent Wallet private keys
user_only CLI only SUDO_PASSWORD

Policy Engine

Every transaction is evaluated against a configurable set of policies:

Policy Description Default (agent wallet)
spending_limit Max per transaction 1.0 native token
daily_limit Aggregate daily cap 5.0 native token
rate_limit Max transactions per window 5 per hour
cooldown Minimum time between txns 30 seconds
require_approval Owner approval above threshold 0.5 native token
allowed_recipients Address whitelist
blocked_recipients Address blacklist

User wallets require owner approval for all transactions by default.

Agent wallets auto-approve within limits — transactions above the threshold trigger an owner approval prompt.

Kill Switch

hermes wallet freeze

Instantly blocks all transactions across all wallets. No policy exceptions. Resume with hermes wallet unfreeze.

Transaction Approval

When a transaction requires approval:

CLI mode: An interactive prompt appears with the transaction details and approve/deny choices — identical to the dangerous command approval prompt.

Gateway mode (Telegram/Discord/etc.): The transaction summary is shown with instructions to reply /approve or /deny.

Supported Networks

Mainnets

  • Ethereum (ETH)
  • Base (ETH)
  • Polygon (POL)
  • Arbitrum One (ETH)
  • Optimism (ETH)
  • Solana (SOL)

Testnets

  • Ethereum Sepolia
  • Base Sepolia
  • Solana Devnet

Custom RPC Endpoints

Override default RPC endpoints in config.yaml:

wallet:
  rpc_endpoints:
    solana: "https://my-custom-rpc.example.com"
    ethereum: "https://eth-mainnet.alchemyapi.io/v2/YOUR_KEY"

Migration Between Machines

To move a wallet to a new machine:

On the source machine:

hermes wallet export --chain solana
# Re-enter your keystore passphrase
# Private key is displayed — copy it securely

On the destination machine:

hermes keystore init                     # Set up keystore (if not already done)
hermes wallet import --chain solana --type agent
# Paste the private key when prompted

:::warning The exported private key gives full control of the wallet. Never share it, transmit it over unencrypted channels, or store it in plaintext. :::

Configuration

Full wallet configuration in ~/.hermes/config.yaml:

wallet:
  enabled: true
  default_chain: solana

  # Override default RPC endpoints
  rpc_endpoints:
    solana: "https://api.mainnet-beta.solana.com"
    ethereum: "https://eth.llamarpc.com"

  # Minimal policy overrides currently supported at runtime
  # (global/shared state, not per-wallet yet)
  agent_wallet:
    enabled: true
    auto_approve_below_native: "0.5"   # maps to require_approval.above_native
    daily_limit_native: "5.0"          # maps to daily_limit.max_native
    max_per_tx_native: "1.0"           # maps to spending_limit.max_native

:::note Per-wallet policy management and richer policy configuration are not fully surfaced yet. Today Hermes supports:

  • runtime RPC endpoint overrides via wallet.rpc_endpoints
  • a minimal set of global agent-wallet policy overrides via wallet.agent_wallet
  • durable freeze/rate-limit/daily-limit state across CLI invocations

More granular per-wallet policy editing is planned follow-up work. :::