Skip to content

0x-SquidSol/vaea-flash

Repository files navigation

VAEA

VAEA Flash

The flash loan infrastructure layer for Solana.
One protocol. Three audiences. Sixty tokens.

App Agent Kit npm crates.io License: MIT

Plugins for AI Agents · CTX for Protocols · SDK for Developers · Docs · Discord

Network Mainnet


VAEA Flash gives three different audiences access to flash loans on Solana — each through the interface that fits them:

Audience Product What it does
AI Agents Plugins Native plugins for Solana Agent Kit, GOAT SDK, and ElizaOS. One line to add aggregated flash loans to any AI agent. 5 tools, 65+ tokens, automatic routing.
Protocols CTX No-CPI A 102-byte PDA your Solana program reads to verify a flash loan is active — without consuming a single CPI level. Your program keeps its full 4-level depth.
Bot Developers SDK A TypeScript + Rust SDK that aggregates Marginfi, Kamino, and Jupiter Lend. One function call, automatic routing, zero-downtime failover, ~91µs local build.

All three products connect to the same underlying infrastructure: the VAEA on-chain program and the Smart Router that routes across 3 lending protocols, 60+ tokens, with automatic failover.


🤖 AI Agent Plugins — Flash Loans for Autonomous Agents

Audience: AI agents (ElizaOS, Solana Agent Kit, GOAT SDK, LangChain, Vercel AI SDK) that need capital for on-chain strategies.

Problem: AI agents can reason about arbitrage, liquidations, and DeFi strategies — but they can't access capital. Existing flash loan tools are mono-protocol (Kamino OR Marginfi, never both). No comparison, no routing, no safety net.

Solution: VAEA provides native plugins for the two leading AI agent frameworks. One line of code gives your agent access to aggregated flash loans across 3 protocols and 65+ tokens — with automatic routing, fee guards, and profitability checks.

Solana Agent Kit Plugin (Recommended)

import { SolanaAgentKit } from "solana-agent-kit";
import { VaeaFlashPlugin } from "@vaea/solana-agent-kit-plugin";

const agent = new SolanaAgentKit(wallet, RPC_URL, { OPENAI_API_KEY })
  .use(VaeaFlashPlugin());  // ← 1 line, that's it

Works with: ElizaOS, LangChain, Vercel AI SDK, custom agents.

GOAT SDK Plugin

import { vaeaFlashPlugin } from "@vaea/goat-plugin";

const tools = await getOnChainTools({
  wallet: solana({ connection, keypair }),
  plugins: [vaeaFlashPlugin()],
});

Works with: LangChain, Vercel AI SDK, ElizaOS, any GOAT-compatible framework.

Plugin Tools (5)

Tool Type Description
vaea_check_capacity 👁️ Eyes Available liquidity — all tokens or filtered by symbol
vaea_get_quote 👁️ Eyes Exact fee breakdown for a specific flash loan
vaea_find_best_route 👁️ Eyes Optimal route — compare Kamino vs Marginfi vs JupLend
vaea_check_profitability 👁️ Eyes Is this strategy worth executing? Factors all costs
vaea_build_flash_loan 🔧 Build Build unsigned atomic TX (prefix + suffix instructions)

Why VAEA vs Direct Protocol Plugins

Feature Direct (Kamino/Marginfi plugin) VAEA Plugin
Source comparison ❌ Manual, per-protocol ✅ Automatic across 3
Multi-source routing ✅ Split across protocols
Fee guard ✅ Built-in
Profitability check ✅ Built-in
Tokens supported ~20 per protocol 65+ aggregated
Plugins needed 3 separate plugins 1 plugin

Security

  • Build-only — plugins never touch private keys, only build unsigned transactions
  • Atomic — if repay fails, entire TX reverts, zero risk
  • Fee guardmax_fee_bps auto-rejects expensive routes

Also Available: MCP Server

For AI agents using the Model Context Protocol (Claude Desktop, Cursor, Windsurf), VAEA also provides an MCP server with 8 tools:

{
  "mcpServers": {
    "vaea-flash": {
      "command": "npx",
      "args": ["-y", "@vaea/mcp-server"]
    }
  }
}

AI Agent Packages

Package Framework Install
@vaea/solana-agent-kit-plugin Solana Agent Kit v2 npm i @vaea/solana-agent-kit-plugin
@vaea/goat-plugin GOAT SDK npm i @vaea/goat-plugin
@vaea/mcp-server MCP (Claude, Cursor) npx @vaea/mcp-server

🔐 CTX — Zero-CPI Verification for Protocols

Audience: Solana program developers (Anchor or native) who need to know if their instruction is executing inside a flash loan.

Problem: On Solana, CPI depth is limited to 4 levels. If your protocol calls a flash loan program via CPI to verify the loan is active, that's one level consumed. In a deep call chain — ProtocolA → ProtocolB → Jupiter → AMM → Token — you've already used 4 levels. Adding a CPI for flash loan verification makes it 5. Transaction fails.

Solution: Don't CPI. Read a PDA instead.

How It Works

The VAEA on-chain program creates a FlashState PDA (102 bytes) when begin_flash executes. This PDA exists only for the duration of the transaction (same-slot enforcement via sysvar introspection). Your program reads this account — a standard Solana account read, not a cross-program invocation.

// In your Anchor program — zero CPI to VAEA
use vaea_flash_ctx::{FlashLoan, FlashPolicy};

pub fn my_handler(ctx: Context<MyAccounts>) -> Result<()> {
    let loan = FlashLoan::verify(
        &ctx.accounts.flash_state,   // 102-byte PDA
        &ctx.accounts.sysvar_ix,     // sysvar instructions
    )?;

    // loan.amount     — how much was borrowed
    // loan.token_mint — which token
    // loan.fee_lamports — VAEA fee in native units

    // v2 Security fields (unfakeable):
    // loan.ix_index   — position of begin_flash in the TX
    // loan.gap        — IX between begin_flash and end_flash
    // loan.num_ix     — total instructions in the TX

    // Optional: enforce security policy
    let policy = FlashPolicy {
        max_gap: Some(5), max_ix: Some(10), max_ix_index: Some(2),
    };
    let loan = FlashLoan::verify_with_policy(
        &ctx.accounts.flash_state, &ctx.accounts.sysvar_ix, &policy,
    )?;

    // Your program still has FULL CPI depth (4 levels):
    marginfi::cpi::repay(...)?;           // Level 1→2→3
    jupiter::cpi::route(...)?;            // Level 1→2→3→4 ← works
    Ok(())
}

CPI Depth Comparison

With CPI flash loan verification:         With VAEA CTX (No-CPI):
  Protocol → FlashLoan.verify = 1 CPI       Protocol reads PDA = 0 CPI
  Protocol → Jupiter → AMM → Token = 4      Protocol → Jupiter → AMM → Token = 3
  Proto_A → Proto_B → Jup → AMM = 5 ❌      Proto_A → Proto_B → Jup → AMM = 4 ✅

FlashState PDA Layout (102 bytes)

Offset Size Field Description
0 8 discriminator Anchor account discriminator
8 32 payer Borrower's public key
40 32 token_mint Borrowed token mint
72 8 amount Amount in native units (u64)
80 8 fee_lamports VAEA fee in native units (u64)
88 1 source_tier 0=SDK, 1=UI, 2=Protocol
89 8 slot_created Slot when loan was initiated
97 1 bump PDA bump seed
98 1 version Schema version (currently 2)
99 1 ix_index v2 Position of begin_flash in the TX
100 1 gap v2 IX count between begin_flash and end_flash
101 1 num_ix v2 Total instructions in the transaction

PDA seeds: ["flash", payer, token_mint]. Only the VAEA program (VAEAmcjQ5RB9yonyrCRSkRT8womX6uqm5PS7PXr528b) can create this account.

Why Only VAEA Creates This PDA

A flash loan borrowed directly from Kamino or Marginfi (without VAEA) does not create a FlashState PDA. There is no account to read. A program using vaea-flash-ctx only accepts flash loans that pass through VAEA.

This isn't a vendor lock-in — it's a consequence of how the verification works. The PDA is the proof. No PDA, no verification. VAEA is the only program that creates this proof without consuming CPI depth.

Install

[dependencies]
vaea-flash-ctx = "0.1"

🛠️ SDK — Flash Loan Toolkit for Developers

Audience: Bot developers, liquidators, arbitrageurs — anyone who writes code and needs instant capital on Solana.

Problem: Marginfi, Kamino, and Jupiter Lend each expose their own flash loan interface with different accounts, different fees, different constraints. If one protocol is paused or exploited, your bot breaks.

Solution: One SDK, three protocols, automatic routing with zero-downtime failover.

3-Line Flash Loan

const flash = new VaeaFlash({ connection, wallet });

await flash.executeLocal({
  token: 'SOL',
  amount: 1000,
  onFunds: async () => [myArbIx],
});

The SDK resolves the token, derives all accounts locally, picks the cheapest protocol, builds the transaction in ~91µs, signs, and sends. No HTTP call. No API dependency.

Rust Example

use vaea_flash_sdk::{VaeaFlash, BorrowParams};

let flash = VaeaFlash::with_rpc(
    "https://api.vaea.fi",
    "https://api.mainnet-beta.solana.com",
    &payer,
)?;

let sig = flash.execute(BorrowParams {
    token: "SOL".into(),
    amount: 1000.0,
    instructions: vec![my_arb_ix],
    max_fee_bps: Some(10),
    ..Default::default()
}).await?;

SDK Packages

Package Install Language
@vaea/flash npm i @vaea/flash TypeScript
vaea-flash-sdk cargo add vaea-flash-sdk Rust

Zero Downtime

Scenario Direct Integration Via VAEA
Protocol active ✅ Works ✅ Works
Protocol paused ❌ Bot dead ✅ Auto-reroutes
Protocol exploited ❌ Bot dead ✅ Auto-reroutes
Recovery time Hours — manual code change 0 seconds

Built-In Features

Feature What It Does
Smart Router Compares all 3 protocols, picks the cheapest path
Turbo Mode Local build in ~91µs — zero HTTP
Jito Bundles Private MEV-protected execution
Fee Guard Auto-rejects if fee exceeds threshold
Profitability Check Factors in all costs before sending
Smart Retry Adaptive retry with priority fee escalation
Multi-Token Borrow SOL + USDC atomically in one TX
Warm Cache Background polling for instant capacity reads

How the Three Products Connect

┌─────────────────────────────────────────────────────────────┐
│  AI Agent / Bot / Script / dApp                               │
│  Uses: Plugins (AI agents) or SDK (devs)                     │
│  → Discovers liquidity → Plans route → Builds TX              │
│  → Smart Router picks cheapest across 3 protocols             │
│  → Creates FlashState PDA on-chain                            │
└────────┬────────────────────────────────────────────────────┘
         │ calls your program between borrow and repay
         ▼
┌─────────────────────────────────────────────────────────────┐
│  Your Solana Program                                         │
│  Uses: vaea-flash-ctx (CTX)                                  │
│  → Reads FlashState PDA (102 bytes, 0 CPI)                   │
│  → Verifies: amount, token, fee, slot + security fields      │
│  → Executes own logic with full 4-level CPI depth            │
└─────────────────────────────────────────────────────────────┘

The plugins and SDK borrow capital. The CTX crate verifies the loan inside called programs. Together, they create a complete flash loan pipeline where the borrower gets aggregated liquidity and the called program gets Zero-CPI verification.


Supported Tokens (60+)

The Smart Router discovers tokens dynamically from all three protocols. Core tokens available on multiple protocols:

Token Protocols Total Cost (VAEA fee included)
SOL Marginfi + Kamino + Jupiter Lend 2.1 bps
USDC Marginfi + Kamino + Jupiter Lend 2.1 bps
USDT Marginfi + Kamino + Jupiter Lend 2.1 bps
mSOL Marginfi + Kamino + Jupiter Lend 2.1 bps
JitoSOL Marginfi + Kamino + Jupiter Lend 2.1 bps
JupSOL Marginfi + Jupiter Lend 2 bps
cbBTC Kamino + Jupiter Lend 2.1 bps
JUP Marginfi + Kamino + Jupiter Lend 2.1 bps
JLP Kamino + Jupiter Lend 2.1 bps
bSOL Marginfi + Kamino 2.1 bps

GET /v1/capacity — real-time borrowing capacity per token.
GET /v1/matrix — full token × protocol liquidity matrix.
If a protocol is paused, the router skips it automatically.


Fee Model

Tier Fee Who Pays
SDK 2 bps (0.02%) Flash loan user (bots, scripts, CLI)
UI 2 bps (0.02%) Flash loan user (frontend dApps)
Protocol 2 bps (0.02%) Flash loan user (via protocol integration)

Flat. Same rate everywhere. The fee is always paid by the end user who initiates the flash loan, not by the protocol that integrates vaea-flash-ctx. CTX integration is free for protocol developers.

Protocol fees (Kamino: ~0.1 bps, Marginfi/JupLend: 0) are added on top. Minimum fee: 1 lamport.


API Reference

Base URL: https://api.vaea.fi · Rate limit: 30 req/s per IP

Method Endpoint Description
GET /v1/capacity Real-time borrowing capacity for all tokens (~2s refresh)
GET /v1/capacity/aggregated Per-source breakdown (Marginfi / Kamino / JupLend)
GET /v1/vte?token=SOL&amount=1000 Truth Engine — best route with cost analysis + alternatives
GET /v1/quote?token=SOL&amount=1000&source=sdk Fee quote with full breakdown
POST /v1/build Build flash loan instructions (prefix + suffix)
POST /v1/flash/build Build optimized flash TX with VAEA program wrapping
GET /v1/matrix Liquidity matrix — all tokens × all protocols
GET /v1/sources Protocol list with token counts and fee tiers
GET /v1/discovery Dynamic token discovery summary
GET /v1/health System health + protocol pause status (Marginfi/Kamino/JupLend)
GET /v1/stats API usage statistics (endpoint hit counts, uptime)

/v1/health response includes per-protocol pause detection:

  • protocols.marginfi.pausedtrue if Marginfi PanicStateCache is active
  • protocols.kamino.pausedtrue if Kamino emergency_mode or borrow_disabled
  • protocols.jupiter_lend.paused — always false (no on-chain pause flag)
  • active_protocols / total_protocols — count of usable sources

Architecture

┌─────────────────────────────────────────────────────────┐
│  Consumers                                               │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────────┐ │
│  │ Plugins     │  │ SDK (TS)    │  │ SDK (Rust)      │ │
│  │ AI Agents   │  │ Bot devs    │  │ Bot devs        │ │
│  └──────┬──────┘  └──────┬──────┘  └────────┬────────┘ │
└─────────┼────────────────┼──────────────────┼──────────┘
          └────────────────┼──────────────────┘
                           ▼
        │  VAEA On-Chain Program           │
        │  begin_flash → [user logic]      │
        │    → end_flash                   │
        │  FlashState PDA: 102 B (v2)      │
        │  5 accounts per IX               │
        └──┬─────────┬──────────┬──────────┘
           │         │          │
     ┌─────▼──┐ ┌────▼───┐ ┌───▼──────────┐
     │Marginfi│ │ Kamino │ │ Jupiter Lend │
     │ ~143   │ │ ~51    │ │    ~39       │
     │ banks  │ │reserves│ │  reserves    │
     └────────┘ └────────┘ └──────────────┘

        ┌────────────────────────────────────┐
        │  CTX — vaea-flash-ctx v2           │
        │  Reads FlashState PDA              │
        │  0 CPI · ~2K CU · 102 bytes       │
        │  Security: ix_index, gap, num_ix   │
        │  Used BY protocols only            │
        └────────────────────────────────────┘

VAEA owns no liquidity. The Smart Router compares all three lending protocols, picks the cheapest path, and splits when needed. If a source is unavailable, it reroutes automatically.


Security

Property Detail
Atomicity If repay fails → entire TX reverts. No partial execution
Sysvar introspection begin_flashend_flash pairing enforced via instruction sysvar
Non-custodial Tokens flow: lending protocol → you → lending protocol
Permissionless No KYC, no registration, no approval
PDA isolation Seeds include token_mint — prevents cross-token collisions
Fee floor Minimum 1 lamport per flash loan
Zero data retention No database. Pure on-chain state reads
v2 ix_index Position of begin_flash in the TX — detects exploit setup phases (many IX before borrow = unusual)
v2 gap IX count between begin and end — large gap increases attack surface for price manipulation
v2 num_ix Total instructions — abnormally high count (>15) indicates complex multi-step exploit pattern

What VAEA Does and Doesn't Do

VAEA makes Solana healthier:

  • ✅ Accelerates liquidations → less bad debt for lending protocols
  • ✅ Facilitates arbitrage → tighter price parity across DEXes
  • ✅ Gives protocols visibility into flash loans (CTX) without CPI cost
  • ✅ Protocol-agnostic — doesn't favor any single lending protocol

VAEA is neutral on:

  • ⚖️ Oracle manipulation risk — depends on protocol oracle design, not VAEA
  • ⚖️ Liquidator concentration — liquidators still compete with each other

VAEA does not:

  • ❌ Prevent all flash loan attacks — VAEA is plumbing, not a security layer
  • ❌ Make Solana immune to exploits — protocols must still be well-designed

Error Handling

import { VaeaFlash, VaeaError } from '@vaea/flash';

try {
  await flash.executeLocal(params);
} catch (err) {
  if (err instanceof VaeaError) {
    switch (err.code) {
      case 'FEE_TOO_HIGH':           // Fee > maxFeeBps
      case 'INSUFFICIENT_LIQUIDITY': // Amount > available
      case 'TX_EXPIRED':             // Blockhash stale (auto-retried)
      case 'ROUTE_UNAVAILABLE':      // All sources down
      case 'SIMULATION_FAILED':      // TX simulation failed
      case 'NETWORK_ERROR':          // API unreachable
    }
  }
}

Complete Example — Arbitrage Bot

import { VaeaFlash, VaeaError } from '@vaea/flash';
import { Connection, Keypair } from '@solana/web3.js';
import fs from 'fs';

async function main() {
  const wallet = Keypair.fromSecretKey(
    new Uint8Array(JSON.parse(fs.readFileSync('~/.config/solana/id.json', 'utf-8')))
  );
  const flash = new VaeaFlash({
    connection: new Connection('https://api.mainnet-beta.solana.com'),
    wallet,
    preWarm: true,
  });

  try {
    // Check profitability before sending
    const profit = await flash.isProfitable({
      token: 'SOL', amount: 100,
      expectedRevenue: 0.1, jitoTip: 0.001,
    });

    if (profit.recommendation === 'abort') return;

    // Execute: Turbo build + Jito bundle + adaptive retry
    const sig = await flash.executeLocal({
      token: 'SOL',
      amount: 100,
      onFunds: async () => [myArbIx],
    }, {
      sendVia: 'jito',
      jito: { tip: 'competitive' },
      retry: { maxAttempts: 3, strategy: 'adaptive' },
    });

    console.log('✅', sig);
  } catch (err) {
    if (err instanceof VaeaError) console.error(`[${err.code}]: ${err.message}`);
    else throw err;
  } finally {
    flash.destroy();
  }
}

main();

Devnet

Program ID:  VAEAmcjQ5RB9yonyrCRSkRT8womX6uqm5PS7PXr528b
ALT:         DjncKSi9KqtnFx6hFYa7ARmwJ7B4Y7UH3XpR2XEuXNJr
Mainnet:     April 2026

Repository Structure

vaea-flash/
├── plugins/
│   ├── solana-agent-kit/     # @vaea/solana-agent-kit-plugin — Agent Kit v2
│   └── goat-sdk/             # @vaea/goat-plugin — GOAT SDK
├── mcp/
│   ├── typescript/           # @vaea/mcp-server (npm) — MCP for Claude/Cursor
│   └── rust/                 # vaea-mcp-server (Cargo) — MCP for Claude/Cursor
├── sdk/
│   ├── typescript/           # @vaea/flash (npm) — SDK for bot devs
│   └── rust/                 # vaea-flash-sdk (crates.io) — SDK for bot devs
├── crates/
│   └── vaea-flash-ctx/       # CTX: Zero-CPI verification for protocols
├── programs/
│   └── vaea-flash/           # On-chain Anchor program
├── frontend/
│   └── web/                  # vaea.fi/flash (Next.js)
├── examples/
│   ├── typescript/
│   └── rust/
└── LICENSE                   # MIT

License

Everything in this repository is MIT — use it, fork it, build on it, no restrictions.

What's open vs what's not

Component License Repo
On-chain program MIT This repo
SDK (TypeScript + Rust) MIT This repo
AI Agent Plugins MIT This repo
MCP Server MIT This repo
CTX Crate MIT This repo
Frontend MIT This repo
Smart Router / API Hosted service

The routing engine, the VTE, and the API backend are not in this repository — they run as a hosted service at api.vaea.fi. This is the same model used across the Solana ecosystem: Jupiter's routing engine is a hosted service, Jito's block engine is a hosted service, Helius's indexer is a hosted service. The SDKs, plugins, and interfaces are open — the infrastructure behind the API is operated as a service.

We believe this is the right tradeoff: you get full source access to every piece of code that touches your wallet, your transactions, and your programs. The routing logic that picks the cheapest protocol is an optimization detail — it doesn't affect the security model, and you can always call Kamino, Marginfi, or Jupiter Lend directly if you prefer.

Audit

The first investment from any funding will be a professional security audit of the on-chain program. Until then, the program is deployed on devnet. We recommend against using the CTX crate in production until the audit is complete.

Website · Docs · Twitter · Discord

About

Flash loan infrastructure for Solana — MCP server for AI agents, CTX (Zero-CPI) verification for protocols, SDK for developers. Aggregates Marginfi, Kamino & Jupiter Lend. 60+ tokens, smart routing, 2 bps flat fee.

Resources

License

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors