Two-Service Docker Architecture: WAIaaS Daemon + Push Relay for Production AI Wallets

Running a self-hosted Docker architecture with multiple services can be complex, especially when building production-ready AI wallet infrastructure. Most developers assume they need heavyweight Kubernetes orchestration or complex service meshes, but WAIaaS takes a different approach with its clean two-service Docker architecture: a core daemon for wallet operations and a specialized push relay for secure transaction approvals.

Why Architecture Matters for AI Wallets

When your AI agents handle real cryptocurrency transactions, architecture isn't just about code organization—it's about security boundaries, failure isolation, and operational simplicity. A monolithic wallet service might seem simpler, but it creates a single point of failure. Split everything into microservices, and you're drowning in complexity.

The stakes are high: your AI agents need reliable access to funds, human operators need secure approval workflows, and your infrastructure needs to survive partial failures without losing transactions or compromising private keys.

WAIaaS Two-Service Architecture

WAIaaS splits wallet infrastructure into exactly two Docker containers, each with a focused responsibility:

Service 1: WAIaaS Daemon (Core Wallet Service)

The daemon handles all wallet operations: transaction signing, balance queries, DeFi protocol integrations, and the REST API that AI agents use. It includes 39 REST API route modules, supports 15 DeFi protocol providers, and manages the complete 7-stage transaction pipeline from validation to confirmation.

Service 2: Push Relay (Approval Notifications)

The push relay handles secure human-in-the-loop approvals via multiple channels: Telegram, push notifications, and WalletConnect integration. When a transaction requires human approval (based on your policy configuration), the push relay ensures the notification reaches you through redundant channels.

Production Docker Deployment

Here's the complete production setup with both services:

services:
  daemon:
    image: ghcr.io/minhoyoo-iotrust/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
      - WAIAAS_DAEMON_LOG_LEVEL=info
    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

  push-relay:
    image: ghcr.io/minhoyoo-iotrust/waiaas-push-relay:latest
    container_name: waiaas-push-relay
    environment:
      - PUSH_RELAY_PORT=3200
      - WAIAAS_DAEMON_URL=http://daemon:3100
    env_file:
      - path: .env
        required: false
    restart: unless-stopped
    depends_on:
      - daemon

volumes:
  waiaas-data:
    driver: local

The key architectural decision here: the daemon exposes port 3100 for AI agent access, while the push relay operates internally on port 3200, communicating with the daemon via Docker's internal network.

Production Secrets with Docker Secrets

For production deployments, sensitive configuration uses Docker Secrets instead of environment variables:

# Create secret files with proper permissions
mkdir -p secrets
echo "your-secure-master-password" > secrets/master_password.txt
echo "your-telegram-bot-token" > secrets/telegram_token.txt
echo "your-push-notification-key" > secrets/push_key.txt
chmod 600 secrets/*

# Deploy with secrets overlay
docker compose -f docker-compose.yml -f docker-compose.secrets.yml up -d

The secrets overlay (docker-compose.secrets.yml) mounts these files into containers as read-only secrets, avoiding environment variable exposure in process lists or container inspect output.

Service Communication and Failure Handling

The two services communicate over Docker's internal network, with the daemon as the authoritative service. Here's how they handle common failure scenarios:

Daemon failure, push relay running: New transactions queue in the daemon's persistent storage when it restarts. The push relay continues handling pending approvals.

Push relay failure, daemon running: Transactions requiring approval enter the DELAY tier instead of blocking entirely. You can manually approve via the Admin Web UI at /admin.

Both services down: All state persists in the named Docker volume. Restart both services and they resume from exactly where they left off.

This design means you're never locked out of your funds, even during partial infrastructure failures.

Auto-Provision for Zero-Touch Deployment

For self-hosters who want completely automated setup, the daemon supports auto-provisioning:

docker run -d \
  --name waiaas \
  -p 127.0.0.1:3100:3100 \
  -v waiaas-data:/data \
  -e WAIAAS_AUTO_PROVISION=true \
  ghcr.io/minhoyoo-iotrust/waiaas:latest

# Retrieve the auto-generated master password
docker exec waiaas cat /data/recovery.key

Auto-provision generates a random master password, creates default wallets for both Solana and Ethereum mainnet, configures basic spending limit policies, and saves the master password to recovery.key for later retrieval.

Multi-Network Configuration

The daemon's network support spans 2 chain types (EVM and Solana) with 18 networks total. Configure custom RPC endpoints for better reliability:

# Environment variables for custom RPC endpoints
WAIAAS_RPC_SOLANA_MAINNET=https://your-solana-rpc.com
WAIAAS_RPC_EVM_ETHEREUM_MAINNET=https://your-ethereum-rpc.com
WAIAAS_RPC_EVM_POLYGON_MAINNET=https://your-polygon-rpc.com

This architecture lets you use private RPC providers, avoiding rate limits from public endpoints when your AI agents are actively trading.

Security Boundaries Between Services

The two-service split creates clear security boundaries:

Daemon security perimeter: Contains private keys, handles all transaction signing, enforces the 21 policy types across 4 security tiers (INSTANT, NOTIFY, DELAY, APPROVAL). Uses 3 auth methods: masterAuth (Argon2id), ownerAuth (SIWS/SIWE), and sessionAuth (JWT HS256).

Push relay security perimeter: Never sees private keys, only handles notification routing and approval workflows. If compromised, attackers can't sign transactions—only potentially interfere with approval notifications.

This isolation means even if the push relay is compromised, your wallet private keys remain secure in the daemon's container.

Operational Benefits

Running both services gives you several operational advantages:

Service independence: Update the push relay without touching wallet operations. Restart notification services without affecting ongoing DeFi positions.

Monitoring separation: Different health check endpoints, separate log streams, isolated resource usage metrics.

Scaling flexibility: Heavy DeFi operations might require more daemon resources, while high-frequency approval workflows might need push relay scaling.

Quick Start: Two-Service Setup

Here's how to get both services running in under 5 minutes:

  1. Clone and configure:
git clone https://github.com/minhoyoo-iotrust/WAIaaS.git
cd WAIaaS
cp .env.example .env
# Edit .env with your Telegram bot token, push notification keys
  1. Start both services:
docker compose up -d
  1. Verify health:
curl http://127.0.0.1:3100/health    # Daemon health
docker logs waiaas-push-relay         # Push relay logs
  1. Create a wallet and session:
docker exec -it waiaas-daemon waiaas init --auto-provision
docker exec -it waiaas-daemon waiaas quickset --mode mainnet
  1. Test the approval flow:
# This transaction will trigger push notifications
curl -X POST http://127.0.0.1:3100/v1/transactions/send \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer wai_sess_<your-token>" \
  -d '{"type": "TRANSFER", "to": "your-address", "amount": "0.001"}'

Both services should now be running with health checks, persistent storage, and secure approval workflows.

Related Posts

Want to dive deeper into WAIaaS architecture? Check out Docker deployment guide for more deployment options, or Policy engine security to understand how the 21 policy types protect your AI agents across both services.

What's Next

This two-service architecture scales from development to production without major changes—the same Docker Compose file works for both. Ready to run your own AI wallet infrastructure? Clone the repository at https://github.com/minhoyoo-iotrust/WAIaaS and visit https://waiaas.ai for complete documentation and examples.