DEV Community

Cover image for Dual-Language AI Agent SDK: TypeScript + Python Async APIs with Zero Dependencies
Wallet Guy
Wallet Guy

Posted on

Dual-Language AI Agent SDK: TypeScript + Python Async APIs with Zero Dependencies

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
Enter fullscreen mode Exit fullscreen mode
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}`);
Enter fullscreen mode Exit fullscreen mode

That's it. No provider setup, no ABI loading, no gas estimation boilerplate. The daemon handles all of that.

Python SDK

pip install waiaas
Enter fullscreen mode Exit fullscreen mode
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)
Enter fullscreen mode Exit fullscreen mode

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

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));
}
Enter fullscreen mode Exit fullscreen mode

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

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

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

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

Step 2: Create a wallet and session in one command

waiaas quickset --mode mainnet
Enter fullscreen mode Exit fullscreen mode

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

Step 4: Install your SDK

npm install @waiaas/sdk
# or
pip install waiaas
Enter fullscreen mode Exit fullscreen mode

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

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

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)