Your AI Agent Can Browse the Web. Can It Swap Tokens?
Your AI agent can write code, search the internet, and draft emails — but the moment it needs to touch money, it hits a wall. WAIaaS is an open-source, self-hosted Wallet-as-a-Service that hands your agent a real crypto wallet, with a TypeScript SDK and a Python async SDK that both carry zero external dependencies. Whether you're building with LangChain, CrewAI, AutoGPT, or Claude via MCP, this is the missing piece: your agent can finally pay for things, swap tokens, and interact with DeFi protocols on its own.
The Problem Is Simpler Than You Think
Most AI agent frameworks are great at reasoning and tool use. They're not built to hold keys, sign transactions, or manage blockchain state. So developers end up bolting on custom signing code, managing RPC connections by hand, and writing their own retry logic for on-chain confirmations. That's not the interesting part of building an AI agent — it's infrastructure plumbing.
What you actually want is a clean SDK call: "send 0.1 SOL to this address," and then get back a transaction ID. Everything else — the pipeline, the policy engine, the signing — should be someone else's problem.
WAIaaS handles exactly that. You self-host a daemon (one Docker container), point your SDK at it, and your agent gets a fully featured wallet API with spending policies, security tiers, and DeFi integrations already wired up.
Two SDKs, One API
WAIaaS ships two official SDKs:
-
@waiaas/sdk— TypeScript/Node.js, for agents built with JS-based frameworks or running in serverless environments -
waiaas— Python, async/await native, for LangChain, CrewAI, AutoGPT, and anything else in the Python AI ecosystem
Both SDKs have zero external dependencies. There's nothing to audit beyond the SDK itself, no transitive supply-chain surprises.
TypeScript SDK
npm install @waiaas/sdk
import { WAIaaSClient } from '@waiaas/sdk';
const client = new WAIaaSClient({
baseUrl: 'http://127.0.0.1:3100',
sessionToken: process.env.WAIAAS_SESSION_TOKEN,
});
// Check balance
const balance = await client.getBalance();
console.log(`${balance.balance} ${balance.symbol}`);
// Send native token
const tx = await client.sendToken({
to: 'recipient-address...',
amount: '0.1',
});
console.log(`Transaction: ${tx.id}`);
That's it. No provider setup, no ABI loading, no gas estimation boilerplate. The daemon handles all of that.
Python SDK
pip install waiaas
from waiaas import WAIaaSClient
async with WAIaaSClient("http://localhost:3100", "wai_sess_xxx") as client:
balance = await client.get_balance()
print(balance.balance, balance.symbol)
The Python SDK is async-native, which means it drops cleanly into any asyncio-based agent framework. The context manager handles session lifecycle for you.
What Your Agent Can Actually Do
The TypeScript SDK exposes these methods directly:
getBalance() — Get wallet native token balance
getAddress() — Get wallet address
getAssets() — Get all token balances
sendToken() — Send native or token transfer
getTransaction() — Get transaction by ID
listTransactions() — List transaction history
signTransaction() — Sign arbitrary transaction
x402Fetch() — HTTP fetch with automatic 402 payment
That last one — x402Fetch() — is worth pausing on. WAIaaS supports the x402 HTTP payment protocol, which means your agent can make HTTP requests that automatically pay for themselves when the server returns a 402. If you're building an agent that consumes paid APIs, it can fund its own tool calls without any human in the loop.
Behind the scenes, the daemon has 39 REST API route modules and supports 7 transaction types: Transfer, TokenTransfer, ContractCall, Approve, Batch, NftTransfer, and ContractDeploy. Your SDK calls map to these routes — you're not losing anything by going through the SDK layer.
Building a Real Agent: End-to-End Example
Here's a complete TypeScript example showing how an agent would check its balance, send tokens, and wait for confirmation:
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'],
});
// Step 1: Check wallet balance
const balance = await client.getBalance();
console.log(`Balance: ${balance.balance} ${balance.symbol} (${balance.chain}/${balance.network})`);
// Step 2: Send tokens
const sendResult = await client.sendToken({
type: 'TRANSFER',
to: 'recipient-address',
amount: '0.001',
});
console.log(`Transaction submitted: ${sendResult.id} (status: ${sendResult.status})`);
// Step 3: 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(`Transaction confirmed! Hash: ${tx.txHash}`);
break;
}
if (tx.status === 'FAILED') {
console.error(`Transaction failed: ${tx.error}`);
break;
}
await new Promise(resolve => setTimeout(resolve, 1000));
}
This is real agent code. The polling loop is exactly what you'd write inside a LangChain tool or a CrewAI task. The agent submits the transaction, waits for chain confirmation, and branches on the result — all without knowing anything about RPC nodes or block finality.
Error Handling That Actually Helps
Agent frameworks need structured errors they can reason about. WAIaaS errors carry machine-readable codes:
import { WAIaaSClient, WAIaaSError } from '@waiaas/sdk';
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
}
}
POLICY_DENIED is particularly useful: it means the spending policy on this wallet blocked the transaction. Your agent can catch this, log the reason, and decide whether to request a smaller amount or escalate to a human. This is how you build safe autonomous agents — the safety layer is at the infrastructure level, not in your agent's prompt.
The Policy Layer: Safety by Default
Before your agent can spend anything, the wallet has a policy engine with 21 policy types and 4 security tiers: INSTANT, NOTIFY, DELAY, and APPROVAL.
You configure policies once, at setup time, using the master password:
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
}
}'
With this policy in place: transactions under $100 go through instantly, transactions between $100–$500 notify you but still execute, transactions between $500–$2,000 are delayed 15 minutes (cancellable), and anything over $2,000 requires your manual approval.
Your agent's session token only has sessionAuth privileges — it can sign and submit transactions, but it cannot create wallets, modify policies, or approve held transactions. That's reserved for masterAuth (you, the operator) and ownerAuth (the wallet owner, via WalletConnect or Telegram). Three authentication layers, cleanly separated.
The policy engine is also default-deny: if you haven't configured ALLOWED_TOKENS or CONTRACT_WHITELIST, those transaction types are blocked. Your agent can't accidentally drain a wallet into an unknown contract.
DeFi Actions: Beyond Simple Transfers
The daemon integrates 15 DeFi protocol providers. Your agent can call them via the REST API directly, or you can wrap the API call as a tool in your agent framework.
Here's a Jupiter swap on 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"
}'
The full list of integrated protocols includes Aave v3, Across, D'CENT Swap, Drift, Hyperliquid, Jito Staking, Jupiter Swap, Kamino, Lido Staking, LI.FI, Pendle, Polymarket, XRPL DEX, and 0x Swap. Liquid staking, cross-chain bridging, perpetual futures, prediction markets — all callable from your agent's session token, subject to whatever policies you've set.
Quick Start: Running the Daemon in 5 Minutes
You don't need to deploy anything complex. The whole thing runs in a single Docker container.
Step 1: Install the CLI and initialize
npm install -g @waiaas/cli
waiaas init
waiaas start
Step 2: Create a wallet and session in one command
waiaas quickset --mode mainnet
This prints a session token and an MCP config JSON you can paste directly into Claude Desktop.
Step 3: Or use Docker directly 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
docker exec waiaas cat /data/recovery.key
Step 4: Install your SDK
npm install @waiaas/sdk
# or
pip install waiaas
Step 5: Set your environment variables and start building
export WAIAAS_BASE_URL=http://127.0.0.1:3100
export WAIAAS_SESSION_TOKEN=wai_sess_<from-quickset>
Your agent is now funded and policy-protected. The interactive API reference is available at http://127.0.0.1:3100/reference if you want to explore all 39 route modules before writing code.
Test Before You Send
One more thing worth knowing before you ship your agent: there's a dry-run mode. You can simulate any transaction before it actually executes:
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
}'
Add "dryRun": true to any transaction request and the daemon will run it through the full 7-stage pipeline — validation, auth, policy check — and return what would happen, without touching the chain. This is useful during development and as a pre-flight check inside your agent's decision loop.
What's Next
The SDKs are the entry point, but WAIaaS has a lot more surface area once your agent needs it: 45 MCP tools for Claude Desktop integration, ERC-4337 account abstraction for gasless transactions, and an admin Web UI at /admin for monitoring what your agents are doing in production. The codebase is open-source and the daemon is self-hosted — your keys never leave your infrastructure.
Explore the full project on GitHub at https://github.com/waiaas/WAIaaS, or visit https://waiaas.ai for documentation and getting-started guides. If you're building an agent that needs to interact with blockchains, this is the infrastructure layer you've been missing.
Top comments (0)