Automated Kamino Lending: Build AI Agents That Optimize Solana Yield
Automated Kamino Lending: Build AI Agents That Optimize Solana Yield
Automated Kamino lending is exactly the kind of DeFi workflow that exposes how fragmented the current toolchain is — you need Kamino's SDK, a Solana wallet library, a monitoring loop, and something to handle policy and approvals before you've written a single line of business logic. If you're building a yield-optimization agent, you probably don't want to spend three weeks wiring protocol SDKs together before your strategy code runs once.
Why Protocol Fragmentation Is the Real Problem
The DeFi space has matured fast. Kamino on Solana, Aave on EVM, Lido and Jito for staking, Jupiter and 0x for swaps, Hyperliquid and Drift for perps — the protocols are good. The problem is the integration layer. Each one has its own SDK, its own auth model, its own error surface. A yield optimization agent that moves capital between Kamino, Jupiter swap, and Jito staking touches three separate integration surfaces, each of which needs maintenance as protocols upgrade.
The deeper problem is that programmatic DeFi access needs more than just protocol calls. A real agent needs guardrails: spending limits, token whitelists, approval workflows for large positions, health factor monitoring so you don't get liquidated. Building all of that yourself, on top of 13 different SDKs, is genuinely a multi-month project.
WAIaaS (Wallet-as-a-Service for AI Agents) treats this as infrastructure. You get a single REST API that covers 15 DeFi protocol providers — including Kamino, Jupiter, Jito, Aave v3, Lido, Drift, Hyperliquid, and cross-chain bridges — with a policy engine, session-based auth, and transaction pipeline already built in. Your agent calls one API. The infrastructure handles the rest.
What's Actually in the Box
WAIaaS is a self-hosted daemon you run locally or in your infrastructure. It's a 15-package monorepo that exposes a REST API with 39 route modules and 45 MCP tools for direct Claude Desktop integration. The DeFi action layer covers 15 protocol providers:
- Solana: jupiter-swap, kamino, jito-staking, xrpl-dex, drift
- EVM: aave-v3, lido-staking, pendle, zerox-swap, hyperliquid
- Cross-chain: lifi, across, dcent-swap
- Prediction markets: polymarket
- Agent reputation: erc8004
Every transaction goes through a 7-stage pipeline: validate → auth → policy → wait → execute → confirm. The policy engine has 21 policy types and 4 security tiers (INSTANT, NOTIFY, DELAY, APPROVAL) with default-deny enforcement. This matters for a lending agent specifically — you want hard limits on LTV ratios, asset whitelists, and spending caps before an agent starts repositioning capital autonomously.
Networks supported: 2 chain types (Solana and EVM) across 18 networks.
Setting Up the Daemon
Start with Docker — it's the fastest path to a running daemon:
git clone https://github.com/minhoyoo-iotrust/WAIaaS.git
cd WAIaaS
docker compose up -d
The default port binding is 127.0.0.1:3100:3100. The image is ghcr.io/minhoyoo-iotrust/waiaas:latest. If you want auto-provisioning (auto-generated master password on first start):
docker run -d \
--name waiaas \
-p 127.0.0.1:3100:3100 \
-v waiaas-data:/data \
-e WAIAAS_AUTO_PROVISION=true \
ghcr.io/minhoyoo-iotrust/waiaas:latest
# Retrieve auto-generated master password
docker exec waiaas cat /data/recovery.key
For production, use the secrets overlay:
mkdir -p secrets
echo "your-secure-password" > secrets/master_password.txt
chmod 600 secrets/master_password.txt
docker compose -f docker-compose.yml -f docker-compose.secrets.yml up -d
Or, if you prefer the CLI path:
npm install -g @waiaas/cli
waiaas init
waiaas start
waiaas quickset --mode mainnet
quickset creates wallets and MCP sessions in one step.
Authentication: Three Roles, Clear Separation
WAIaaS has three auth layers and it's worth understanding which one your agent uses before you write any code.
# 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>"
Your Kamino lending agent will use sessionAuth for all runtime operations. masterAuth is for setup — creating the wallet, creating the session, configuring policies. ownerAuth is for the human in the loop when an APPROVAL-tier transaction needs sign-off.
Create a wallet and session before you deploy your agent:
# Create a Solana mainnet 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": "kamino-yield-agent", "chain": "solana", "environment": "mainnet"}'
# Create a session 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>"}'
The session token (wai_sess_...) is what your agent uses at runtime.
Policies Before Capital
This is the part most yield-bot tutorials skip. Before your agent touches any capital, you want policies in place. The policy engine's default-deny behavior means if you haven't whitelisted a token, the transaction is blocked — which is exactly what you want for an autonomous agent.
For a Kamino lending agent, you'll want at minimum:
Spending limit — 4-tier security based on transaction amount:
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
}
}'
Tier assignment is automatic: amount <= instant_max → INSTANT (execute immediately), <= notify_max → NOTIFY (execute + alert), <= delay_max → DELAY (queue for 900 seconds, cancellable), > delay_max → APPROVAL (requires human sign-off via WalletConnect, Telegram, or push notification).
Token whitelist — only allow the assets your strategy uses:
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": "ALLOWED_TOKENS",
"rules": {
"tokens": [
{"address": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", "symbol": "USDC", "chain": "solana"},
{"address": "So11111111111111111111111111111111111111112", "symbol": "SOL", "chain": "solana"}
]
}
}'
LTV limit — hard cap on loan-to-value for lending positions:
The LENDING_LTV_LIMIT policy type enforces a maximum LTV ratio, blocking any lending action that would push the position above the threshold. Combined with LENDING_ASSET_WHITELIST, you can constrain exactly which assets the agent is allowed to use as collateral.
Contract whitelist — restrict which protocol contracts the agent can call:
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": "CONTRACT_WHITELIST",
"rules": {
"contracts": [
{"address": "JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4", "name": "Jupiter", "chain": "solana"}
]
}
}'
There are 21 policy types in total, covering everything from rate limits to perpetuals max leverage to ERC-8128 HTTP signing domains. For a lending agent, LENDING_LTV_LIMIT, LENDING_ASSET_WHITELIST, SPENDING_LIMIT, ALLOWED_TOKENS, and CONTRACT_WHITELIST are the core five.
The Agent: Swapping, Lending, Monitoring
With policies in place, your agent's runtime logic becomes straightforward API calls. Here's the pattern for a Kamino yield agent that swaps SOL to USDC on Jupiter, then supplies to a Kamino lending market.
Check balance first:
import { WAIaaSClient } from '@waiaas/sdk';
const client = new WAIaaSClient({
baseUrl: process.env['WAIAAS_BASE_URL'] ?? 'http://localhost:3100',
sessionToken: process.env['WAIAAS_SESSION_TOKEN'],
});
const balance = await client.getBalance();
console.log(`Balance: ${balance.balance} ${balance.symbol} (${balance.chain}/${balance.network})`);
Simulate before executing — always dry-run first on a strategy rebalance:
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
}'
The dry-run API simulates the transaction through the full pipeline — including policy checks — without executing. If the simulation returns a POLICY_DENIED error, you catch it before spending gas.
Execute the Jupiter swap:
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"
}'
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));
}
Monitor DeFi positions — the get-defi-positions tool (available via both REST and MCP) returns your lending/staking positions across protocols. For health factor monitoring, the get-health-factor MCP tool surfaces the current health factor directly, so your agent can trigger a deleveraging action before liquidation.
Handle policy errors explicitly:
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
}
}
A POLICY_DENIED with domain POLICY and retryable: false means a hard rule was hit — log it, alert the operator, don't retry. A DELAY tier transaction isn't an error; it's queued and will execute after the configured delay unless the owner cancels it via WalletConnect or Telegram.
MCP Integration: Claude as Your Yield Strategist
If you want to go a step further and have Claude Desktop act as the strategy layer — analyzing positions, deciding when to rebalance, executing the moves — the MCP integration wires directly into the same infrastructure.
{
"mcpServers": {
"waiaas-kamino": {
"command": "npx",
"args": ["-y", "@waiaas/mcp"],
"env": {
"WAIAAS_BASE_URL": "http://127.0.0.1:3100",
"WAIAAS_SESSION_TOKEN": "wai_sess_<your-token>",
"WAIAAS_DATA_DIR": "~/.waiaas"
}
}
}
}
Or use the CLI shortcut:
waiaas mcp setup --all
With 45 MCP tools registered, Claude can call get_defi_positions, get_health_factor, execute_action (for the Kamino supply/borrow actions), and get_balance in a single conversation. The same policy engine applies — Claude's tool calls go through the same pipeline as direct REST calls.
Gas Conditional Execution
One detail worth knowing for yield strategies: WAIaaS has a gas conditional execution feature — transactions only execute when the gas price meets a configured threshold. For a strategy that does frequent rebalancing, this prevents your agent from executing during gas spikes and eating into yield.
Quick Start Summary
docker compose up -d— start the daemon (image:ghcr.io/minhoyoo-iotrust/waiaas:latest, port127.0.0.1:3100:3100)- Create a Solana mainnet wallet via
POST /v1/walletswithmasterAuth - Create a session via
POST /v1/sessions— save thewai_sess_...token - Set policies:
SPENDING_LIMIT,ALLOWED_TOKENS,LENDING_LTV_LIMIT,CONTRACT_WHITELIST - Install the TypeScript SDK (
npm install @waiaas/sdk) and start callingexecuteActionfor Kamino, Jupiter, and Jito
The OpenAPI spec is auto-generated at /doc and the interactive Scalar API reference UI is at /reference — both available immediately after the daemon starts.
What's Next
The same session token and policy setup that works for Kamino lending works identically for Aave v3, Lido staking, Hyperliquid perps, and cross-chain bridging via LI.FI and Across — 15 protocol providers,