DEV Community

Cover image for Build Gasless AI Trading Bots with ERC-4337 Account Abstraction
Wallet Guy
Wallet Guy

Posted on

Build Gasless AI Trading Bots with ERC-4337 Account Abstraction

Build Gasless AI Trading Bots with ERC-4337 Account Abstraction

Gasless AI trading bots are finally practical — but only if you're not spending half your development time wiring up 13 different protocol SDKs. Jupiter, Aave, Lido, Drift, Hyperliquid, Across — every DeFi protocol has its own integration story, its own auth model, its own quirks. If you're building a trading bot or automated yield strategy, that integration tax quietly becomes the actual project.

Why This Integration Tax Kills DeFi Bots

Here's the reality of building a multi-protocol DeFi bot in 2026: you pick a strategy — say, borrow on Aave, bridge to Solana via Across, deploy liquidity on Kamino — and suddenly you're maintaining separate SDKs for each leg. When Aave pushes a contract upgrade, you patch one library. When Jupiter changes its routing API, you patch another. Before you know it, 60% of your codebase is protocol glue code, not strategy logic.

The stakes are real. A bot that goes offline during a market move because a dependency broke isn't just annoying — it's a P&L event. Developers building serious automated strategies need one stable interface that handles the protocol-level complexity so they can focus on the logic that actually generates returns.

ERC-4337 Account Abstraction makes gasless transactions possible in theory. What makes them practical in production is having a system that combines AA with policy enforcement, multi-protocol access, and security controls that don't require you to rebuild from scratch.

What WAIaaS Actually Gives You

WAIaaS is an open-source, self-hosted Wallet-as-a-Service for AI agents. The relevant part for DeFi developers: it exposes 15 integrated DeFi protocol providers through a single REST API, with ERC-4337 Account Abstraction, a 7-stage transaction pipeline, and a policy engine with 21 policy types baked in.

The 15 protocols are: aave-v3, across, dcent-swap, drift, erc8004, hyperliquid, jito-staking, jupiter-swap, kamino, lido-staking, lifi, pendle, polymarket, xrpl-dex, and zerox-swap.

That covers the major DeFi categories you actually care about:

  • Swaps: Jupiter (Solana), 0x, LI.FI, D'CENT
  • Lending: Aave v3, Kamino
  • Liquid staking: Lido (EVM), Jito (Solana)
  • Cross-chain bridging: LI.FI, Across
  • Perpetuals and spot: Hyperliquid, Drift
  • Prediction markets: Polymarket
  • Fixed yield: Pendle

Two chain types — EVM and Solana — across 18 networks. One API surface.

On the account abstraction side, WAIaaS provides ERC-4337 support with smart accounts, gasless transactions, and a UserOp build/sign API. That means your bot can execute transactions without holding ETH for gas on every chain it operates on — the sponsor handles it.

The Three-Auth Model You Need to Understand

Before diving into code, the auth model matters for how you architect your bot.

WAIaaS uses three authentication layers:

# masterAuth — system administrator (wallet creation, session management, policies)
-H "X-Master-Password: my-secret-password"

# sessionAuth — AI agent (transactions, balance queries, DeFi actions)
-H "Authorization: Bearer wai_sess_eyJhbGciOiJIUzI1NiJ9..."

# ownerAuth — fund owner (transaction approval, kill switch recovery)
-H "X-Owner-Signature: <ed25519-or-secp256k1-signature>"
-H "X-Owner-Message: <signed-message>"
Enter fullscreen mode Exit fullscreen mode

For a trading bot, the pattern is: your system admin creates wallets and sessions with masterAuth, the bot itself runs with sessionAuth (a JWT scoped to a specific wallet), and you as the fund owner retain ownerAuth for approving large transactions or recovering control. The bot never touches your master password.

Auth methods under the hood: masterAuth uses Argon2id, ownerAuth uses SIWS/SIWE (Sign-In with Solana/Ethereum), and sessionAuth uses JWT HS256. Per-session TTL, maxRenewals, and absoluteLifetime are all configurable.

Setting Up Your Trading Bot Wallet

Start with Docker — it's the fastest path to a running instance:

git clone https://github.com/waiaas/WAIaaS.git
cd WAIaaS
docker compose up -d
Enter fullscreen mode Exit fullscreen mode

The daemon binds to 127.0.0.1:3100 by default. Create a wallet for your bot:

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"}'
Enter fullscreen mode Exit fullscreen mode

Then create a session token for the bot:

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>"}'
Enter fullscreen mode Exit fullscreen mode

That session token (wai_sess_...) is what your bot uses for every subsequent call. Scope it tight — the policy engine is what enforces the actual limits.

Policy Engine: Your Bot's Risk Manager

This is the part that separates production-grade bots from scripts. WAIaaS has a policy engine with 21 policy types and 4 security tiers: INSTANT, NOTIFY, DELAY, and APPROVAL.

The default is deny. Transactions are blocked unless explicitly allowed. This is the right default for autonomous agents moving real funds.

Here's a practical policy setup for a trading bot:

# Spending limit with 4-tier security
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
    }
  }'
Enter fullscreen mode Exit fullscreen mode

Tier assignment logic: amount <= instant_max → execute immediately. <= notify_max → execute and notify you. <= delay_max → queue for 900 seconds (cancellable). > delay_max → requires human approval via WalletConnect, Telegram, or push notification.

For a bot that trades across protocols, you also want contract and token whitelists — these are default-deny independently:

The CONTRACT_WHITELIST policy blocks calls to any contract not explicitly listed. The ALLOWED_TOKENS policy blocks transfers of any token not on the list. The APPROVED_SPENDERS policy controls which addresses can be approved to spend from the wallet. For perpetuals, PERP_MAX_LEVERAGE, PERP_MAX_POSITION_USD, and PERP_ALLOWED_MARKETS let you enforce risk limits at the infrastructure layer rather than in your bot code.

DeFi-specific policies worth knowing: LENDING_LTV_LIMIT caps loan-to-value ratios on Aave/Kamino positions, LENDING_ASSET_WHITELIST restricts which assets can be used as collateral or borrowed, and VENUE_WHITELIST controls which trading venues the bot can route through.

Multi-Protocol Execution: The Actual API Calls

Here's what unified protocol access looks like in practice. All of these use the same session token pattern.

Swap on Jupiter (Solana):

curl -X POST http://127.0.0.1:3100/v1/actions/jupiter-swap/swap \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer wai_sess_<token>" \
  -d '{
    "inputMint": "So11111111111111111111111111111111111111112",
    "outputMint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
    "amount": "1000000000"
  }'
Enter fullscreen mode Exit fullscreen mode

That's SOL → USDC. The routing, slippage handling, and transaction construction happen inside the provider — your bot just sends the intent.

Check balance before acting:

curl http://127.0.0.1:3100/v1/wallet/balance \
  -H "Authorization: Bearer wai_sess_eyJhbGciOiJIUzI1NiJ9..."
Enter fullscreen mode Exit fullscreen mode

Simulate before executing (critical for bots):

curl -X POST http://127.0.0.1:3100/v1/transactions/send \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer wai_sess_<token>" \
  -d '{
    "type": "TRANSFER",
    "to": "recipient-address",
    "amount": "0.1",
    "dryRun": true
  }'
Enter fullscreen mode Exit fullscreen mode

The dryRun flag runs the transaction through the full 7-stage pipeline — validate, auth, policy check, wait, execute, confirm — but stops before broadcast. You get the policy decision, the simulated outcome, and any errors before any funds move. For automated strategies, always dry-run before live execution on new code paths.

Gas conditional execution is another pipeline feature worth knowing: transactions can be configured to execute only when gas price meets a threshold. That's stage4-wait in the pipeline — your bot queues the transaction and the pipeline holds it until conditions are met.

Building the Bot in TypeScript

The TypeScript SDK gives you typed access to the same API surface:

import { WAIaaSClient, WAIaaSError } from '@waiaas/sdk';

const client = new WAIaaSClient({
  baseUrl: process.env['WAIAAS_BASE_URL'] ?? 'http://localhost:3100',
  sessionToken: process.env['WAIAAS_SESSION_TOKEN'],
});

// Check balance before trading
const balance = await client.getBalance();
console.log(`Balance: ${balance.balance} ${balance.symbol} (${balance.chain}/${balance.network})`);

// Execute a transfer — DeFi action calls follow the same pattern
const sendResult = await client.sendToken({
  type: 'TRANSFER',
  to: 'recipient-address',
  amount: '0.001',
});
console.log(`Transaction submitted: ${sendResult.id} (status: ${sendResult.status})`);

// Poll for confirmation
const POLL_TIMEOUT_MS = 60_000;
const startTime = Date.now();
while (Date.now() - startTime < POLL_TIMEOUT_MS) {
  const tx = await client.getTransaction(sendResult.id);
  if (tx.status === 'COMPLETED') {
    console.log(`Confirmed! Hash: ${tx.txHash}`);
    break;
  }
  if (tx.status === 'FAILED') {
    console.error(`Failed: ${tx.error}`);
    break;
  }
  await new Promise(resolve => setTimeout(resolve, 1000));
}
Enter fullscreen mode Exit fullscreen mode

Error handling is worth being explicit about. Policy denials come back as structured errors:

try {
  const tx = await client.sendToken({ to: '...', amount: '1.0' });
} catch (error) {
  if (error instanceof WAIaaSError) {
    console.error(`API Error: [${error.code}] ${error.message}`);
    // error.code examples: INSUFFICIENT_BALANCE, POLICY_DENIED, TOKEN_EXPIRED
  }
}
Enter fullscreen mode Exit fullscreen mode

A POLICY_DENIED error with code detail tells you exactly which policy fired — SPENDING_LIMIT, CONTRACT_WHITELIST, PERP_MAX_LEVERAGE, etc. That's actionable. Your bot can log it, alert you, and back off — rather than silently failing or throwing an opaque RPC error.

MCP Integration for AI-Driven Strategies

If your bot uses an LLM for decision-making (Claude, GPT-4, or any MCP-compatible agent), WAIaaS exposes 45 MCP tools that map directly to wallet, transaction, DeFi, NFT, and x402 operations.

Quick setup:

waiaas mcp setup --all    # Auto-register all wallets with Claude Desktop
Enter fullscreen mode Exit fullscreen mode

The Claude Desktop config:

{
  "mcpServers": {
    "waiaas-trading": {
      "command": "npx",
      "args": ["-y", "@waiaas/mcp"],
      "env": {
        "WAIAAS_BASE_URL": "http://127.0.0.1:3100",
        "WAIAAS_AGENT_ID": "019c47d6-51ef-7f43-a76b-d50e875d95f4",
        "WAIAAS_AGENT_NAME": "trading-agent",
        "WAIAAS_DATA_DIR": "~/.waiaas"
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

You can run multiple wallets as separate MCP servers — one for your Solana trading wallet, one for your EVM yield strategies — with separate policy sets for each. The agent calls get_defi_positions to see current exposure across Aave, Kamino, Lido, and Jito, then acts on the result.

Quick Start: Five Steps to a Running Bot

  1. Deploy WAIaaS: docker compose up -d — daemon runs at 127.0.0.1:3100
  2. Create a wallet: POST /v1/wallets with masterAuth
  3. Create a session: POST /v1/sessions with masterAuth, get wai_sess_... token
  4. Set policies: At minimum, SPENDING_LIMIT + ALLOWED_TOKENS + CONTRACT_WHITELIST
  5. Execute: Use sessionAuth for all bot calls — swap, lend, stake, bridge through the unified API

For auto-provisioning without a manual password setup:

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

docker exec waiaas cat /data/recovery.key
Enter fullscreen mode Exit fullscreen mode

The full OpenAPI 3.0 spec is at http://127.0.0.1:3100/doc with an interactive reference UI at /reference. All 39 REST API route modules are documented there — useful when you're mapping protocol-specific action parameters.

What's Next

The 15 integrated DeFi protocols, 21 policy types, and ERC-4337 support are documented in full detail on the WAIaaS GitHub repository — the codebase is open source and the protocol provider implementations are readable. For production deployments, review the Docker Secrets overlay pattern (docker-compose.secrets.yml) and the 3-layer security architecture before going live with real funds. Visit waiaas.ai for the full documentation and community resources.

Top comments (0)