DEV Community

Cover image for 15 DeFi Protocols Integration Guide: Building Multi-Protocol Arbitrage Bots
Wallet Guy
Wallet Guy

Posted on

15 DeFi Protocols Integration Guide: Building Multi-Protocol Arbitrage Bots

15 DeFi Protocols Integration Guide: Building Multi-Protocol Arbitrage Bots

Your arbitrage bot spotted the opportunity — a 0.8% spread between Jupiter and a Drift perp, a cross-chain delta between Ethereum and Solana, a Pendle yield arb that closes in two blocks. The question isn't whether you can see the trade. It's whether your wallet infrastructure can execute it before the window closes, without blowing your edge on gas, without getting rekt by an unsigned transaction, and without writing a different signing library for every protocol you touch.

Why Wallet Infrastructure Is the Bottleneck

Most trading bot tutorials get you to the point of computing the arb. They don't talk about what happens next: signing, broadcasting, handling nonce conflicts, managing approvals, enforcing position limits so a runaway strategy doesn't liquidate your entire treasury, or bridging collateral between chains mid-strategy. These aren't afterthoughts. For a bot running thousands of transactions a day, they are the strategy.

WAIaaS is an open-source, self-hosted Wallet-as-a-Service designed for exactly this — giving AI agents and automated systems a programmable, policy-governed wallet backend that handles signing, sequencing, gas management, and multi-protocol execution through a single REST API. It runs entirely on your own infrastructure. No custody risk. No third-party key management.

The numbers are concrete: 15 DeFi protocol providers integrated, covering the major execution venues across EVM and Solana. Let's look at what that means for a multi-protocol trading system.

What's in the Protocol Stack

WAIaaS integrates these 15 DeFi providers out of the box:

aave-v3         — EVM lending/borrowing
across          — Cross-chain bridging
dcent-swap      — Token swaps
drift           — Solana perpetuals + spot
erc8004         — Onchain agent reputation
hyperliquid     — Perpetual futures + spot, sub-accounts
jito-staking    — Solana liquid staking
jupiter-swap    — Solana DEX aggregation
kamino          — Solana lending
lido-staking    — EVM liquid staking
lifi            — Cross-chain bridging + swap routing
pendle          — Yield tokenization
polymarket      — Prediction markets
xrpl-dex        — XRPL native DEX
zerox-swap      — EVM DEX aggregation (0x)
Enter fullscreen mode Exit fullscreen mode

For a multi-chain arb system, the useful combinations are obvious: route spot through Jupiter or 0x depending on chain, hedge or lever up on Drift or Hyperliquid, move collateral cross-chain via LI.FI or Across, manage borrow capacity on Aave or Kamino. All of this goes through the same session token, the same REST endpoint, the same error format.

The Architecture: One API, One Wallet

Every action your bot takes flows through a 7-stage transaction pipeline: validate → auth → policy → wait → execute → confirm. That pipeline enforces your risk controls at the infrastructure level, not in application code that might crash or have a bug path.

The auth model has three layers:

  • masterAuth (Argon2id): admin operations — create wallets, set policies, issue sessions
  • sessionAuth (JWT HS256): your bot's runtime credential — send transactions, call DeFi actions
  • ownerAuth (SIWS/SIWE): human approval for high-value transactions

Your bot uses sessionAuth for everything during normal operation. Human override exists via ownerAuth when a transaction exceeds the approval threshold you configured.

Executing a Multi-Leg Trade

Here's what a Solana arb leg looks like — swap SOL for USDC on Jupiter:

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 one leg. The same pattern, with different provider paths, handles the other legs of a multi-protocol strategy. The endpoint structure is consistent: /v1/actions/{provider}/{action}. Your bot doesn't need to know the ABI of the Jupiter aggregator, manage versioned instruction formats, or handle Solana transaction serialization — that's all inside the provider layer.

For EVM swaps, you'd hit zerox-swap the same way. For a perp hedge on Hyperliquid after the spot leg fills, you'd call the Hyperliquid provider. The session token carries across all of them.

Gas Conditional Execution

Gas costs eat arb edge. A 0.3% spread disappears if you're paying 0.25% in gas on a congested Ethereum block. WAIaaS has a gas conditional execution feature built into the pipeline: transactions only execute when the gas price meets a threshold you configure.

This means your bot can submit a transaction and let the infrastructure hold it until execution conditions are met — rather than building your own gas polling loop, handling re-submission, managing nonce state across retries, and dealing with stuck transactions. The stage4-wait pipeline stage handles this.

For Solana strategies where priority fees matter, the same conditional logic applies. Your bot stays simple; the infrastructure absorbs the complexity.

Dry-Run Before You Commit

Before any live execution, you can simulate:

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

Set dryRun: true and you get the full pipeline simulation — policy checks, balance validation, gas estimation — without broadcasting. For a bot running novel strategy paths, this is how you validate execution before committing capital. Run the dry-run, check the response, then fire the live transaction.

Risk Controls at the Infrastructure Level

Here's the policy configuration a trading bot actually needs. Start with a spending limit that gates transaction size into 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
    }
  }'
Enter fullscreen mode Exit fullscreen mode

Transactions up to $100 execute instantly. $100–$500 executes immediately but you get notified. $500–$2000 gets queued for 15 minutes — cancellable if you catch an error in your strategy logic. Anything above $2000 requires explicit owner approval via WalletConnect or Telegram. This is your circuit breaker. A runaway bot or a compromised session token doesn't drain your whole wallet.

Beyond spending limits, you have 21 policy types available for trading-specific controls:

PERP_MAX_LEVERAGE       — Cap leverage on perpetual positions
PERP_MAX_POSITION_USD   — Cap total position size in USD
PERP_ALLOWED_MARKETS    — Restrict to specific perp markets
CONTRACT_WHITELIST      — Only call known, audited contracts
ALLOWED_TOKENS          — Whitelist tokens the bot can touch
VENUE_WHITELIST         — Restrict to specific trading venues
ACTION_CATEGORY_LIMIT   — Limit DeFi action categories
RATE_LIMIT              — Max transactions per period
LENDING_LTV_LIMIT       — Cap loan-to-value on lending positions
Enter fullscreen mode Exit fullscreen mode

The default-deny principle applies to ALLOWED_TOKENS and CONTRACT_WHITELIST: if you don't explicitly whitelist a token or contract, transactions involving it are blocked. For a trading bot where a compromised strategy might try to sweep funds to an unknown address, this is exactly what you want — explicit allowlists, not blocklists.

Cross-Chain Execution: LI.FI and Across

Two bridging providers give you options depending on latency and fee requirements. Cross-chain arb between Ethereum and Solana, or collateral movement to fund a position on a different chain, goes through the same action provider pattern. LI.FI handles multi-hop routing and swap+bridge in single transactions. Across is optimized for fast bridging with competitive fees.

For a strategy that requires Ethereum collateral to fund a Hyperliquid position, the execution sequence is: check balance on Ethereum, bridge via Across or LI.FI, confirm receipt, open position on Hyperliquid. Each step is a REST call to the WAIaaS daemon with your session token.

TypeScript SDK for Bot Development

If you're building in TypeScript, the SDK removes the HTTP boilerplate and gives you typed responses with proper error handling:

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 executing
const balance = await client.getBalance();
console.log(`Balance: ${balance.balance} ${balance.symbol} (${balance.chain}/${balance.network})`);

// Submit transaction and poll for confirmation
const sendResult = await client.sendToken({
  type: 'TRANSFER',
  to: 'recipient-address',
  amount: '0.001',
});

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: ${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 typed and structured:

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

POLICY_DENIED tells you exactly which policy blocked the transaction. INSUFFICIENT_BALANCE tells you to check your bridge status. TOKEN_EXPIRED tells you to refresh the session. Structured error codes let your bot handle each case programmatically instead of parsing error strings.

Quick Start: Get Trading Infrastructure Running

Step 1: Start the daemon

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

Step 2: Initialize and create a wallet

npm install -g @waiaas/cli
waiaas quickset --mode mainnet
Enter fullscreen mode Exit fullscreen mode

Or manually:

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

Step 3: Create a session token for your 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

Step 4: Set your risk policies

Use the policy API to configure spending limits, token allowlists, and perp position caps before your bot touches mainnet capital.

Step 5: Install the SDK and start building

npm install @waiaas/sdk
Enter fullscreen mode Exit fullscreen mode

Point WAIAAS_BASE_URL and WAIAAS_SESSION_TOKEN at your daemon, and your bot has access to all 15 protocol providers through the typed client.

The Operational Reality

Running a trading bot means running it continuously. The Docker setup handles this: restart: unless-stopped, a healthcheck hitting /health every 30 seconds, and named volume persistence so your wallet data survives container restarts. For production key management, Docker Secrets overlay via docker-compose.secrets.yml keeps your master password out of environment variables.

The daemon exposes OpenAPI 3.0 spec at /doc and an interactive Scalar UI at /reference — useful when you're debugging why a specific action call is returning an unexpected response structure. 39 REST API routes, all documented, all consistent.

For multi-wallet setups — separate bots for different strategies, different risk profiles — you create separate wallets with separate sessions and separate policy sets. A high-frequency low-value bot gets a tight spending limit and a whitelist of three contracts. A longer-duration position bot gets higher limits and perp-specific policies. Infrastructure enforces the separation; your application code doesn't have to.

What's Next

The full protocol list, API reference, and deployment documentation are at https://waiaas.ai. The source — including all 15 provider implementations, the policy engine, and the 7-stage pipeline — is at https://github.com/waiaas/WAIaaS. If you're building a serious trading system and want wallet infrastructure that doesn't become a liability, that's where to start.

Top comments (0)