Self-Hosted AI Wallet Infrastructure: Deploy WAIaaS with Docker and 20 CLI Commands
Self-hosting your AI agent's wallet infrastructure means no third party ever touches your private keys — and with Docker and the WAIaaS CLI, you can have the whole stack running in under five minutes. If you've ever asked yourself whether you'd trust a hosted service with the signing keys for an autonomous agent that can move real money, this guide is for you. We'll walk through every step: from a single docker compose up to a production-hardened deployment with secrets management, policy enforcement, and full CLI control.
Why Self-Custody Matters for AI Agents
Running a traditional wallet through a hosted API is a calculated bet. You're betting that the provider stays online, doesn't change pricing, doesn't get breached, and never decides your use case violates their terms of service. For a human checking a balance once a day, that's probably fine. For an autonomous AI agent executing DeFi strategies, paying for API calls via x402, or managing funds across 18 networks — a single point of failure in someone else's data center is a serious risk.
Self-hosting flips that equation. Your keys live on your hardware, in your network, behind your firewall. There are no rate limits imposed by a third-party API tier. There's no usage data flowing to an external provider. The WAIaaS daemon runs entirely on your infrastructure: a Docker container, a named volume, and a handful of environment variables.
This is the crypto equivalent of running your own mail server — except WAIaaS is actually practical to set up in an afternoon.
What You're Deploying
WAIaaS is a 15-package monorepo that ships as two Docker images: the main waiaas/daemon and a push-relay for notifications. The daemon exposes a REST API with 39 route modules, an interactive OpenAPI reference at /reference, and an admin web UI at /admin. It comes with 45 MCP tools for Claude and other AI frameworks, a TypeScript and Python SDK, and a CLI with 20 commands.
The architecture enforces a 3-layer security model: session authentication gates every agent action, a policy engine with 21 policy types governs what agents are allowed to do, and the owner (you) retains a kill switch via WalletConnect or push notifications. Transactions go through a 7-stage pipeline — validate, auth, policy check, wait, execute, confirm — before anything hits the chain.
Step 1: Install the CLI
Everything starts with the @waiaas/cli package. Install it globally:
npm install -g @waiaas/cli
That gives you 20 commands:
backup create backup inspect backup list
init mcp setup notification setup
owner connect owner disconnect owner status
quickset quickstart restore
session prompt set-master start
status stop update
wallet create wallet info
Each command handles a specific lifecycle concern. init bootstraps your local config. start and stop manage the daemon process. wallet create and wallet info manage wallets. backup create, backup inspect, and backup list handle encrypted backups. mcp setup registers your wallets with Claude Desktop automatically.
Step 2: Initialize and Start (CLI Path)
If you prefer the CLI over raw Docker commands, initialization takes three lines:
waiaas init # Create data directory + config.toml
waiaas start # Start daemon (sets master password on first run)
waiaas quickset --mode mainnet # Create wallets + MCP sessions in one step
quickset is the power move here. It creates wallets, generates sessions for your AI agents, and prints the MCP config JSON you need to paste into Claude Desktop — all in one command. If you want to skip the interactive password prompt entirely:
waiaas init --auto-provision # Generates random master password → recovery.key
waiaas start # No password prompt
waiaas quickset # Creates wallets + sessions automatically
waiaas set-master # (Later) Harden password, then delete recovery.key
Auto-provision is useful for scripted deployments or CI environments where you need a fully unattended setup. The generated master password is written to recovery.key — store it somewhere safe, then replace it with a proper password using set-master when you're ready to harden the installation.
Step 3: Deploy with Docker
For a persistent, production-style deployment, Docker Compose is the recommended path. The default docker-compose.yml binds only to 127.0.0.1:3100 — it doesn't expose the daemon to the network by default, which is exactly right for a self-hosted setup where you control access via a reverse proxy or VPN.
git clone https://github.com/waiaas/WAIaaS.git
cd WAIaaS
docker compose up -d
That's the entire quick start. The image pulls from ghcr.io/waiaas/waiaas:latest, mounts a named volume for data persistence, and runs a healthcheck against /health every 30 seconds.
For a single-container deployment with auto-provision:
docker run -d \
--name waiaas \
-p 127.0.0.1:3100:3100 \
-v waiaas-data:/data \
-e WAIAAS_AUTO_PROVISION=true \
ghcr.io/waiaas/waiaas:latest
# Retrieve auto-generated master password
docker exec waiaas cat /data/recovery.key
The full Docker Compose configuration shows what the production setup looks like:
services:
daemon:
image: ghcr.io/waiaas/waiaas:latest
container_name: waiaas-daemon
ports:
- "127.0.0.1:3100:3100"
volumes:
- waiaas-data:/data
environment:
- WAIAAS_DATA_DIR=/data
- WAIAAS_DAEMON_HOSTNAME=0.0.0.0
env_file:
- path: .env
required: false
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3100/health"]
interval: 30s
timeout: 5s
start_period: 10s
retries: 3
volumes:
waiaas-data:
driver: local
Notice the daemon runs as a non-root user (UID 1001) inside the container. The entrypoint supports auto-provision and Docker Secrets out of the box.
Step 4: Harden with Docker Secrets
Passing your master password through an environment variable is convenient for development, but for production you want Docker Secrets. WAIaaS ships with docker-compose.secrets.yml specifically for this:
# Create secret files
mkdir -p secrets
echo "your-secure-password" > secrets/master_password.txt
chmod 600 secrets/master_password.txt
# Deploy with secrets overlay
docker compose -f docker-compose.yml -f docker-compose.secrets.yml up -d
The secrets overlay file handles mounting the secret into the container and telling the entrypoint where to find it. Your password never appears in environment variables, process lists, or Docker inspect output.
Step 5: Create Your First Wallet and Session
With the daemon running, you interact with it via the REST API or the CLI. Here's the API path — useful for understanding what's happening under the hood:
# Create a wallet
curl -X POST http://127.0.0.1:3100/v1/wallets \
-H "Content-Type: application/json" \
-H "X-Master-Password: my-secret-password" \
-d '{"name": "trading-wallet", "chain": "solana", "environment": "mainnet"}'
# Create a session token for your AI agent
curl -X POST http://127.0.0.1:3100/v1/sessions \
-H "Content-Type: application/json" \
-H "X-Master-Password: my-secret-password" \
-d '{"walletId": "<wallet-uuid>"}'
The session token (wai_sess_...) is what your AI agent uses for everything after that: checking balances, sending transactions, executing DeFi actions. The master password stays on the admin side and never goes to the agent.
Step 6: Set Policies Before You Let Agents Loose
This is the step most tutorials skip. Before handing a session token to an autonomous agent, set spending limits. The policy engine uses default-deny enforcement: if you haven't configured ALLOWED_TOKENS, the agent can't transfer tokens. If you haven't configured CONTRACT_WHITELIST, contract calls are blocked.
Start with a spending limit that maps to the 4 security tiers:
curl -X POST http://127.0.0.1:3100/v1/policies \
-H "Content-Type: application/json" \
-H "X-Master-Password: my-secret-password" \
-d '{
"walletId": "<wallet-uuid>",
"type": "SPENDING_LIMIT",
"rules": {
"instant_max_usd": 100,
"notify_max_usd": 500,
"delay_max_usd": 2000,
"delay_seconds": 900,
"daily_limit_usd": 5000
}
}'
This single policy creates a tiered response to transaction size:
- INSTANT — under $100, executes immediately
- NOTIFY — $100–$500, executes immediately but you get a push notification
- DELAY — $500–$2,000, queues for 15 minutes (cancellable)
- APPROVAL — over $2,000, requires your explicit sign-off via WalletConnect, Telegram, or push notification
The full list of 21 policy types covers everything from DeFi-specific controls (PERP_MAX_LEVERAGE, LENDING_LTV_LIMIT) to x402 payment domain whitelists (X402_ALLOWED_DOMAINS) to onchain agent reputation thresholds (REPUTATION_THRESHOLD).
Step 7: Connect Claude via MCP
With the daemon running and policies set, wire up Claude Desktop in one command:
waiaas mcp setup --all # Auto-register all wallets with Claude Desktop
Or configure it manually in claude_desktop_config.json:
{
"mcpServers": {
"waiaas": {
"command": "npx",
"args": ["-y", "@waiaas/mcp"],
"env": {
"WAIAAS_BASE_URL": "http://127.0.0.1:3100",
"WAIAAS_SESSION_TOKEN": "wai_sess_<your-token>",
"WAIAAS_DATA_DIR": "~/.waiaas"
}
}
}
}
The MCP server exposes 45 tools to Claude: wallet operations, token transfers, DeFi actions across 15 integrated protocols, NFT management, transaction simulation, and x402 HTTP payments. Claude can now check your balance, swap tokens on Jupiter, check your Aave health factor, or pay for API calls automatically — all within the policy boundaries you set.
Useful Docker Commands for Day-to-Day Operations
Once deployed, these are the commands you'll reach for most often:
docker compose up -d # Start daemon
docker compose logs -f # Follow logs
docker compose down # Stop (data preserved in named volume)
docker compose down -v # Stop + delete data volume
For monitoring, the daemon exposes its OpenAPI spec and interactive documentation:
# Download OpenAPI 3.0 spec
curl http://127.0.0.1:3100/doc -o openapi.json
# View interactive API reference in browser
open http://127.0.0.1:3100/reference
The admin UI at /admin gives you a web interface for wallet management, session control, the policy editor, DeFi positions dashboard, and notification configuration — useful if you want to poke around without writing curl commands.
Key Environment Variables
WAIAAS_AUTO_PROVISION=true # Auto-generate master password on first start
WAIAAS_DAEMON_PORT=3100 # Listening port
WAIAAS_DAEMON_HOSTNAME=0.0.0.0 # Bind address
WAIAAS_DAEMON_LOG_LEVEL=info # Log level (trace/debug/info/warn/error)
WAIAAS_DATA_DIR=/data # Data directory
WAIAAS_RPC_SOLANA_MAINNET=<url> # Solana mainnet RPC endpoint
WAIAAS_RPC_EVM_ETHEREUM_MAINNET=<url> # Ethereum mainnet RPC endpoint
One thing worth noting for the privacy-conscious: you can point WAIaaS at your own RPC nodes. If you're running a Solana validator or an Ethereum archive node, set WAIAAS_RPC_SOLANA_MAINNET and WAIAAS_RPC_EVM_ETHEREUM_MAINNET to your own endpoints. At that point, zero blockchain data is flowing through a third-party RPC provider.
The Philosophy Behind Self-Hosting This
There's a practical reason and a principled reason to self-host AI wallet infrastructure.
The practical reason: hosted wallet APIs impose rate limits, charge per-call fees, and can change their terms or pricing at any time. An autonomous agent running arbitrage strategies or responding to market conditions needs predictable, low-latency access to signing operations. Self-hosted infrastructure gives you that.
The principled reason: private keys are the root of custody. If a third party holds them, or even has access to the signing environment, you don't fully control the funds. WAIaaS's architecture — session tokens for agents, owner authentication for approvals, master password for administration — keeps the key material on hardware you control, with human-in-the-loop approval for anything above your defined thresholds.
The 3-layer security model (session auth → policy engine with time delays and approval requirements → monitoring and kill switch) means that even if an agent's session token is compromised, an attacker is still bounded by your spending limits and can't move large amounts without triggering the delay or approval tier — giving you time to respond.
What's Next
The GitHub repository at https://github.com/waiaas/WAIaaS has the full documentation, including guides for connecting WalletConnect for mobile approvals, configuring Telegram notifications for the NOTIFY and APPROVAL tiers, and setting up Watchtower for automatic container updates. The official site at https://waiaas.ai has quickstart guides and SDK documentation for both TypeScript and Python.
If you're building something where an AI agent needs to handle real funds — trading bots, payment automation, DeFi position management — start with the smallest possible spending limit in SPENDING_LIMIT, add tokens to ALLOWED_TOKENS one at a time, and expand permissions only as you build confidence in the agent's behavior. Your keys, your server, your rules — but also your responsibility to set those rules carefully before handing an LLM a session token.
Top comments (0)