Turbo Mode

Turbo Mode

Build flash loan instructions 100% locally in ~91µs — no API call, no HTTP, no network. 2,000× faster than a round-trip.

Latency Comparison

SDKNetwork CallsBuild TimeTotal Latency
VAEA Turbo0 HTTP + 2 RPC~91µs~100ms
VAEA Standard1 HTTP + 2 RPC~5ms~180ms
Jupiter Perps2-3 RPC~15ms~200-400ms
Marginfi Flash3-4 RPC~20ms~300-500ms
Solend Flash4+ RPC~30ms~400-600ms

Code Examples

// Turbo mode — zero API calls, ~91µs build
const sig = await flash.executeLocal({
  token: 'SOL',
  amount: 1000,
  onFunds: async (ixs) => {
    ixs.push(buyInstruction);
    ixs.push(sellInstruction);
    return ixs;
  },
});

How It Works

The SDK contains a hardcoded token registry and replicates the backend's instruction builder locally:

  1. PDA derivation — computes flash vault, user state, config accounts
  2. Account resolution — derives token accounts, ATAs, lookup table addresses
  3. Instruction assembly — builds the borrow → your IXs → repay sandwich

localBuild() API

For full control, use localBuild() to get raw instructions without executing:

typescript
import { localBuild, VAEA_LOOKUP_TABLE } from '@vaea/flash';
import { TransactionMessage, VersionedTransaction } from '@solana/web3.js';

// ~0.09ms — builds begin_flash + end_flash instructions
const { beginFlash, endFlash, expectedFeeNative } = localBuild({
  payer: wallet.publicKey,
  token: 'SOL',
  amount: 1000,
});

// Build your own VersionedTransaction
const { blockhash } = await connection.getLatestBlockhash();
const message = new TransactionMessage({
  payerKey: wallet.publicKey,
  recentBlockhash: blockhash,
  instructions: [beginFlash, myArbIx, endFlash],
}).compileToV0Message([VAEA_LOOKUP_TABLE]);

const tx = new VersionedTransaction(message);
tx.sign([wallet]);
const sig = await connection.sendTransaction(tx, { skipPreflight: true });

When to Use

CriteriaTurbo (executeLocal)Standard (execute)
Speed~100ms~180ms
API dependencyNoneVAEA API required
Offline capable✅ Yes❌ No
Route updates❌ Uses cached registry✅ Always fresh
Best forBots, HFT, productionGeneral use, prototyping
💡 Tip
Pre-warm with flash.warmCache() at boot for even faster first execution. Combine with sendVia: 'jito' for private MEV-protected execution.

borrowLocal() vs executeLocal()

Two levels of control — choose based on how much you want the SDK to handle:

MethodReturnsSends TX?Use Case
borrowLocal(params)TransactionInstruction[]❌ NoGet instructions — you build, sign, send
executeLocal(params, opts)string (tx signature)✅ YesOne-liner: build + sign + send + confirm
typescript
// borrowLocal() — full control over the transaction
const ixs = await flash.borrowLocal({
  token: 'SOL', amount: 1000,
  onFunds: async () => [myArbIx],
});
// ixs = [beginFlash, myArbIx, endFlash]
// → Build your own VersionedTransaction, add compute budget, sign, send

// executeLocal() — one-liner, SDK handles everything
const sig = await flash.executeLocal({
  token: 'SOL', amount: 1000,
  onFunds: async () => [myArbIx],
}, { priorityMicroLamports: 5000 });