40+ TypeScript Methods: Complete SDK Reference for AI Agent Wallet Control

Your AI agent can browse the web, write code, and manage files — but can it swap tokens? If you're building AI agents with LangChain, CrewAI, AutoGPT, or Claude MCP, you've probably hit the wall where your agent needs to actually move money and there's no clean way to do it. The WAIaaS TypeScript SDK (@waiaas/sdk) gives your agent a wallet it can control programmatically, with 40+ methods covering everything from balance checks to DeFi positions.

Why This Gap Matters

AI agents are getting good at reasoning and planning. The bottleneck is now execution — specifically, financial execution. An agent that can decide to swap tokens is useless if it can't do the swap. Bolting together raw RPC calls, key management, and policy enforcement yourself is weeks of work, and you'll still have security holes. What you actually want is a thin SDK layer your agent calls the same way it calls any other tool, with the custody and security handled underneath.

That's what the WAIaaS SDK is: a TypeScript (and Python) client that sits in front of a self-hosted daemon which manages keys, enforces policies, and signs transactions. Your agent code stays clean. The security infrastructure runs separately.

Installation and Setup

npm install @waiaas/sdk 

Before your agent can call any method, you need a running WAIaaS daemon and a session token. The daemon is self-hosted — you control the keys. Spin it up with Docker:

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

Then create a wallet and a session token for your agent:

# Create a wallet 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"}' # Create a session token for the agent 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>"}' 

That session token (wai_sess_...) is what your agent uses. It has scoped permissions — the master password never touches your agent code.

Initializing the Client

Every agent interaction starts here:

import { WAIaaSClient } from '@waiaas/sdk'; const client = new WAIaaSClient({ baseUrl: process.env['WAIAAS_BASE_URL'] ?? 'http://127.0.0.1:3100', sessionToken: process.env['WAIAAS_SESSION_TOKEN'], }); 

Keep the session token in an environment variable. Don't hardcode it. Your agent reads it at runtime and uses this client instance to call every method below.

The Core Methods Your Agent Will Use Daily

Checking Balances

Before any agent takes a financial action, it should know what it has. These two methods cover the basics:

// Native token balance (SOL, ETH, etc.) const balance = await client.getBalance(); console.log(`${balance.balance} ${balance.symbol}`); // All token balances in the wallet const assets = await client.getAssets(); 

getBalance() returns the native token. getAssets() returns everything — native plus any tokens the wallet holds. Use getAssets() when your agent needs to reason about which token to use for a swap or a payment.

Sending Tokens

This is the fundamental action. Your agent pays someone, moves funds, or executes a transfer:

const tx = await client.sendToken({ type: 'TRANSFER', to: 'recipient-address', amount: '0.1', }); console.log(`Transaction submitted: ${tx.id} (status: ${tx.status})`); 

Notice type: 'TRANSFER' — the SDK supports 7 transaction types: Transfer, TokenTransfer, ContractCall, Approve, Batch, NftTransfer, and ContractDeploy. Your agent picks the right type based on what it's doing.

Polling for Confirmation

Submitting a transaction and checking that it confirmed are two different things. Here's the pattern your agent should use:

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)); } 

getTransaction(id) fetches the current state. Poll every second until you get COMPLETED or FAILED. If your agent is making decisions based on transaction results (e.g., "confirm the swap completed before placing the next order"), this loop is what keeps it from acting on stale data.

Transaction History

Agents that need to reason about what they've done before can query history:

const history = await client.listTransactions(); 

This is useful for agents that need to avoid duplicate actions, verify past payments, or build a running log of financial activity.

Signing

Sometimes your agent needs to sign a message or a raw transaction without broadcasting it immediately:

const signed = await client.signTransaction(/* transaction data */); 

Use this when interacting with protocols that require a signed payload before submission, or when your agent is part of a multi-step flow where signing happens separately from execution.

DeFi: Beyond Simple Transfers

The SDK's executeAction method is the gateway to 15 integrated DeFi protocols. Your agent calls it with a provider name and action-specific parameters.

Swapping Tokens 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" }' 

The 15 integrated protocols your agent can reach through this pattern include: aave-v3, across, dcent-swap, drift, erc8004, hyperliquid, jito-staking, jupiter-swap, kamino, lido-staking, lifi, pendle, polymarket, xrpl-dex, and zerox-swap. Each has its own set of actions — swaps, deposits, staking, borrowing, trading.

An agent that can reason about yield opportunities across Aave, Kamino, and Lido — and then actually execute the move — is doing something that wasn't practical to build from scratch six months ago.

Getting DeFi Positions

Before your agent rebalances a portfolio, it needs to know what's currently deployed:

const positions = await client.getDeFiPositions(); 

This returns lending positions, staking balances, and other protocol-specific state across supported integrations. Your agent can use this to reason about health factors, unrealized yields, and rebalancing opportunities before taking action.

Paying for API Calls with x402

Here's a capability that's genuinely new: your agent can pay for its own API access automatically. The x402 HTTP payment protocol lets an agent hit an API endpoint, receive a 402 Payment Required response, and pay the required amount — all in one call.

const response = await client.x402Fetch('https://api.example.com/data'); 

Under the hood, x402Fetch handles the payment negotiation. Your agent doesn't need to know anything about the payment flow — it just gets the data. This is how you build agents that can access paid APIs without hardcoded API keys or manual billing setup.

The WAIaaS policy engine lets you configure X402_ALLOWED_DOMAINS to control which domains your agent is allowed to pay automatically. Your agent can autonomously spend on api.example.com but not everywhere on the internet.

Simulating Before Executing

Before your agent commits real funds, use dry-run mode to validate the transaction:

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 payload. The daemon runs the full pipeline — validation, policy check, gas estimation — but doesn't broadcast. Your agent gets back the same response structure it would get from a real transaction. This is useful for agents that want to validate a plan before execution, or for testing decision logic without spending funds.

Error Handling Your Agent Actually Needs

Agents need to handle errors gracefully, especially around policies and balances. The SDK throws typed errors:

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 means the transaction was blocked by a spending limit, whitelist, or other policy rule. INSUFFICIENT_BALANCE means exactly what it says. TOKEN_EXPIRED means the session token needs to be renewed. Your agent can catch these specifically and respond differently — retry with a smaller amount, alert a human, or gracefully degrade.

The error response from the API always follows a consistent structure:

{ "error": { "code": "POLICY_DENIED", "message": "Transaction denied by SPENDING_LIMIT policy", "domain": "POLICY", "retryable": false } } 

Check retryable before your agent loops — some errors are permanent and retrying wastes time.

Setting Up Spending Policies

Your agent operates within guardrails you define. The policy engine has 21 policy types and 4 security tiers: INSTANT, NOTIFY, DELAY, and APPROVAL. You set these once via the API (or the Admin UI), and the daemon enforces them on every transaction.

A practical starting policy for a trading agent:

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 } }' 

Under $100: executes immediately. $100–$500: executes with a notification sent to you. $500–$2000: waits 15 minutes (you can cancel). Over $2000: requires your explicit approval via WalletConnect or Telegram. Your agent never touches these thresholds — it just submits transactions and gets back the result.

The policy system follows default-deny: if you don't add a token to ALLOWED_TOKENS, the agent can't transfer it. If you don't whitelist a contract in CONTRACT_WHITELIST, the agent can't call it. This means a compromised agent session has a very limited blast radius.

Python SDK Option

If your agent is built in Python (common for LangChain and CrewAI setups), there's a native async client:

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 mirrors the TypeScript API with snake_case method names. Same daemon, same session tokens, same policy enforcement — just a different client language.

Quick Start: From Zero to Agent Wallet in 5 Steps

  1. Start the daemon — docker compose up -d in the cloned repo
  2. Create a wallet — POST to /v1/wallets with your master password
  3. Create a session token — POST to /v1/sessions with the wallet ID
  4. Install the SDK — npm install @waiaas/sdk
  5. Set policies — POST a SPENDING_LIMIT and ALLOWED_TOKENS policy before your agent goes live

Or use the CLI quickstart to do steps 1–3 in one command:

npm install -g @waiaas/cli waiaas init waiaas start waiaas quickset --mode mainnet 

What's Next

The full OpenAPI reference is available interactively at http://127.0.0.1:3100/reference once your daemon is running — every endpoint, every parameter, with a live try-it interface. If you're building with Claude Desktop specifically, check out the MCP integration which exposes 45 tools directly to Claude without any SDK code on your side. The codebase, issue tracker, and contribution guide are all at https://github.com/waiaas/WAIaaS, and the official site with documentation is at https://waiaas.ai.

Your agent can already reason. Now give it a wallet.