Complete Solana DeFi Stack: Drift Perps + Jito Staking + Jupiter Swaps
Complete Solana DeFi Stack: Drift Perps + Jito Staking + Jupiter Swaps — One API to Rule Them All
Tired of integrating each DeFi protocol separately? If you're building a Solana DeFi bot that needs to swap on Jupiter, stake with Jito, and trade perps on Drift, you're probably drowning in three different SDKs, three different authentication flows, and three different ways transactions can fail. WAIaaS gives you a single REST API that talks to all of them — plus 12 other protocols across EVM and Solana — without you having to touch any of their native SDKs directly.
Why This Actually Matters
The friction of multi-protocol DeFi development is real and it's expensive. Every protocol you add to your stack is another dependency to maintain, another set of breaking changes to chase, another auth model to understand. And that's before you even think about transaction safety — who's making sure your trading bot doesn't drain your wallet if a position goes sideways or a policy limit gets breached?
WAIaaS is an open-source, self-hosted Wallet-as-a-Service that sits between your code and the blockchain. It handles key management, transaction signing, policy enforcement, and protocol interaction through a single API surface. The daemon exposes 39 REST API route modules and integrates 15 DeFi protocol providers out of the box. On the Solana side, that includes Jupiter Swap, Jito Staking, Drift, Kamino, and the Jupiter-powered cross-chain bridge via Across — plus the full EVM stack (Aave v3, Lido, Hyperliquid, Pendle, Polymarket, and more). Your trading bot really shouldn't need 13 different SDKs.
The Protocol Stack
Before diving into code, here's what you're working with on Solana specifically (from the verified protocol list):
- Jupiter Swap — token swaps on Solana
- Jito Staking — liquid SOL staking
- Drift — perpetual futures and spot trading
- Kamino — lending and yield strategies
- Across — cross-chain bridging
- XRPL DEX — decentralized exchange on XRPL
On the EVM side you get Aave v3, Lido, Hyperliquid, Pendle, Polymarket, 0x Swap, LI.FI, D'CENT, and ERC-8004 agent validation. All 15 providers, one unified API pattern.
Getting the Daemon Running
The fastest path is Docker. Two commands and you're live:
git clone https://github.com/waiaas/WAIaaS.git
cd WAIaaS
docker compose up -d
The daemon binds to 127.0.0.1:3100 by default (DOCKER-02). If you want auto-provisioning so you don't have to set a master password manually 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/waiaas/waiaas:latest
# Retrieve auto-generated master password
docker exec waiaas cat /data/recovery.key
Once it's running, create a wallet scoped to Solana mainnet:
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"}'
Then create a session token that your trading bot will use for all subsequent calls:
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 bot authenticates with from here on. The master password never touches your application code.
Three Auth Layers — Understanding the Separation
WAIaaS uses three distinct auth methods for three distinct roles:
- masterAuth (X-Master-Password) — system admin operations: creating wallets, sessions, and policies. Uses Argon2id hashing.
- sessionAuth (Bearer token) — what your AI agent or trading bot uses for transactions, balance queries, and DeFi actions. JWT HS256.
- ownerAuth (X-Owner-Signature) — the human fund owner, used for approving transactions that breach policy thresholds. SIWS/SIWE signatures.
This separation matters for DeFi bots specifically. Your bot gets a session token with bounded permissions. The owner (you) retains control via wallet signature for anything above your configured thresholds. The bot cannot escalate its own permissions.
Swapping on Jupiter
Here's a real swap call — SOL to USDC via 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"
}'
The action provider pattern is consistent: /v1/actions/<provider>/<action>. You call the same endpoint shape for every protocol. Your bot's routing logic stays clean — swap logic on one provider looks identical structurally to swap logic on another.
Before running any swap in production, simulate it first:
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 lets you validate that a transaction would succeed — including policy checks — before committing to execution. For a trading bot running in production, this is the difference between catching a bad trade and eating a failed transaction fee.
Policy Engine: Guard Rails for Your Bot
This is where WAIaaS gets genuinely useful for DeFi developers. The policy engine has 21 policy types across 4 security tiers (INSTANT, NOTIFY, DELAY, APPROVAL) and follows default-deny enforcement: transactions are blocked unless explicitly allowed.
For a Solana trading bot, a sensible starting policy set looks like this:
SPENDING_LIMIT — your first line of defense:
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 mechanical: amount ≤ instant_max → execute immediately; ≤ notify_max → execute and notify you; ≤ delay_max → queue for 15 minutes (cancellable); above that → requires your explicit wallet signature approval. Your bot can run autonomously within bounds you control, and anything anomalous — a fat-finger trade, a runaway loop, a compromised session — gets caught before it clears.
For DeFi-specific risk management, there are dedicated policy types that matter for a perps/staking strategy:
- PERP_MAX_LEVERAGE — cap leverage on Drift positions
- PERP_MAX_POSITION_USD — maximum position size in USD
- PERP_ALLOWED_MARKETS — whitelist which perp markets the bot can trade
- LENDING_LTV_LIMIT — maximum loan-to-value ratio if using Kamino lending
- LENDING_ASSET_WHITELIST — restrict which assets can be used as collateral
- CONTRACT_WHITELIST — default-deny, only calls whitelisted contract addresses
- ALLOWED_TOKENS — default-deny, only transfers whitelisted tokens
The transaction pipeline itself has 7 stages (validate → auth → policy → wait → execute → confirm) so every transaction passes through policy enforcement before it touches the chain.
Staking SOL with Jito
Liquid staking via Jito follows the same action provider pattern. You get jitoSOL back, which remains liquid while earning staking yield — useful if your strategy needs to maintain positions while the underlying SOL is staked.
The pattern for DeFi actions across all 15 protocols is: authenticate with your session token, POST to /v1/actions/<provider>/<action>, pass the protocol-specific parameters. The daemon handles the RPC calls, transaction construction, signing, and confirmation.
For EVM-side staking, Lido works the same way — Lido (EVM) and Jito (Solana) are both integrated as first-class providers.
TypeScript SDK for Tighter Integration
If you'd rather not hand-roll HTTP calls, the TypeScript SDK wraps the REST API:
import { WAIaaSClient } from '@waiaas/sdk';
const client = new WAIaaSClient({
baseUrl: 'http://127.0.0.1:3100',
sessionToken: process.env.WAIAAS_SESSION_TOKEN,
});
// Check balance before executing strategy
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}`);
The SDK includes getBalance(), getAddress(), getAssets(), sendToken(), getTransaction(), listTransactions(), signTransaction(), and x402Fetch() — zero external dependencies. For async polling (which you'll need for any transaction that goes through DELAY or APPROVAL tiers):
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));
}
Error handling gives you typed error codes:
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 the one you'll care about most as you tune your policy configuration. The error response from the REST API is equally explicit:
{
"error": {
"code": "POLICY_DENIED",
"message": "Transaction denied by SPENDING_LIMIT policy",
"domain": "POLICY",
"retryable": false
}
}
Connecting It to Claude or Another AI Agent via MCP
If your strategy involves an LLM making trading decisions (rather than deterministic code), WAIaaS ships 45 MCP tools covering wallet, transaction, DeFi, NFT, and x402 operations. The MCP package connects directly to Claude Desktop or any MCP-compatible framework.
waiaas mcp setup --all # Auto-register all wallets with Claude Desktop
Or configure manually in claude_desktop_config.json:
{
"mcpServers": {
"waiaas": {
"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"
}
}
}
}
Relevant MCP tools for a DeFi strategy: action-provider, get-defi-positions, get-health-factor, get-balance, get-assets, simulate-transaction, send-token, hyperliquid, polymarket. The agent calls these tools; the policy engine still enforces every transaction the agent tries to execute.
Quick Start: Solana DeFi Stack in 5 Steps
- Start the daemon —
docker compose up -dfrom the cloned repo - Create a Solana mainnet wallet — POST to
/v1/walletswith masterAuth - Create a session token — POST to
/v1/sessions, store the token securely - Set your policies — at minimum, SPENDING_LIMIT + ALLOWED_TOKENS + CONTRACT_WHITELIST
- Start trading — POST to
/v1/actions/jupiter-swap/swap,/v1/actions/jito-staking/stake, or/v1/actions/drift/...using your session token
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 a single step.
What's Next
The OpenAPI 3.0 spec auto-generates at /doc and the interactive Scalar API reference UI lives at /reference — both available immediately once your daemon is running. Start there to explore all 39 route modules and find the action endpoints for the specific protocols in your strategy. The 684+ test files in the repo are also worth skimming if you want to understand expected request/response shapes for edge cases.
The full source, Docker images, and documentation are at:
- GitHub: https://github.com/waiaas/WAIaaS
- Official site: https://waiaas.ai