FortiBlox LogoFortiBlox Docs
AXIO Block Engine

Searcher Guide

Complete guide for MEV searchers — authentication, bundle submission, strategy optimization, and best practices on the AXIO engine.

Searcher Guide

This guide covers everything you need to build and run MEV strategies on the AXIO block engine.

1. What is a Bundle?

A bundle is an ordered list of 1-5 transactions that execute atomically — all succeed or none are included. Bundles compete in a continuous auction where the engine selects the best non-conflicting set for each slot.

Bundle properties:

  • Atomic execution — no partial fills, no dangling state
  • Priority inclusion — bundles are injected into the banking stage before mempool transactions
  • No mempool exposure — your transactions never enter the public mempool
  • Fair auction — bundles compete on expected value, not just tip size

2. Getting Started

Request an API Key

API keys are required for all bundle submissions.

  1. Contact the AXIO team with your searcher identity (an X1/Solana pubkey you control)
  2. You will receive an API key and authentication credentials
  3. Store them securely — treat them like a private key

Install the SDK

# TypeScript
npm install @axio/searcher-sdk

# Rust
cargo add axio-searcher-sdk

Connect to the Engine

import { AxioClient } from "@axio/searcher-sdk";

const axio = new AxioClient({
  apiKey: process.env.AXIO_API_KEY,
  endpoint: "grpc://engine.axio.fortiblox.com:7440",
});

3. Submitting Bundles

Basic Bundle Submission

import { Transaction, SystemProgram, PublicKey } from "@solana/web3.js";

// Build your transactions
const frontrunTx = new Transaction().add(/* your frontrun instruction */);
const victimTx = /* the victim transaction */;
const backrunTx = new Transaction().add(/* your backrun instruction */);

// Sign transactions
frontrunTx.sign(keypair);
backrunTx.sign(keypair);

// Submit bundle
const result = await axio.submitBundle({
  transactions: [
    frontrunTx.serialize({ requireAllSignatures: false }),
    victimTx.serialize({ requireAllSignatures: false }),
    backrunTx.serialize({ requireAllSignatures: false }),
  ],
  tip: 500_000, // lamports — must be >= current tip floor
  mevType: "sandwich",
});

console.log(`Bundle ${result.bundleId}: ${result.status}`);

Streaming Bundle Submission (gRPC)

For high-frequency strategies, use the streaming API to maintain a persistent gRPC connection:

const stream = axio.createBundleStream();

stream.on("confirmation", (confirmation) => {
  console.log(`Bundle ${confirmation.bundleId}: ${confirmation.status}`);
  if (confirmation.status === "included") {
    console.log(`Landed in slot ${confirmation.slot}`);
  }
});

// Submit bundles on the stream
await stream.submit({
  transactions: [/* serialized txs */],
  tip: 500_000,
  mevType: "arbitrage",
});

Encrypted Bundle Submission

For maximum privacy, bundles can be encrypted with X25519 + ChaCha20-Poly1305:

const result = await axio.submitEncryptedBundle({
  transactions: [/* serialized txs */],
  tip: 500_000,
  mevType: "sandwich",
  // Encryption is handled automatically — the SDK performs key exchange
});

The engine decrypts bundles only during evaluation. Even relay operators cannot read encrypted bundle contents.

4. Bundle Requirements

ConstraintValue
Max transactions per bundle5
Max total bundle size50 KB
Min tipDynamic tip floor (check /api/v1/tip-floor)
Tip transactionMust be last in bundle
Target slotDefaults to next available; max +12 slots ahead
Bundle TTL10 seconds from submission

Tip Program

Tips are paid to one of 8 rotating PDA vaults managed by the forti-tips program:

Program: 7dWho2FmC68LZBirmAf68GsrEJSFjpaVTF5pYPqVDCug

The tip instruction must transfer lamports from the searcher's wallet to the tip vault for the target slot. The SDK handles vault selection automatically.

Dynamic Tip Floor

AXIO uses an EIP-1559-style dynamic tip floor that adjusts with block space demand. When demand is high, the floor rises; when demand drops, the floor falls. Check the current floor:

const floor = await axio.getTipFloor();
console.log(`Current tip floor: ${floor} lamports`);

Always bid above the floor. Bundles below the floor are rejected before evaluation.

5. MEV Strategies

Sandwich Attacks

Sandwich the target transaction with a frontrun (buy) and backrun (sell):

Bundle: [frontrun_buy, victim_swap, backrun_sell]

Tips:

  • Use createAssociatedTokenAccountIdempotentInstruction in the frontrun to ensure the wSOL ATA exists
  • Pre-compute sandwich bundles every 500ms and submit within 150ms of the leader window
  • For multi-victim sandwiches (4-5 tx), the engine supports sequential execution with full state carryover

Arbitrage

Exploit price discrepancies across DEXes:

Bundle: [swap_dex_a, swap_dex_b]  // buy low on A, sell high on B

Tips:

  • The engine includes an internal arb scanner for XDEX and forti-amm pools
  • Triangular arbitrage (A→B→C→A) is supported with up to 5 hop routes
  • Use the mevType: "arbitrage" flag for better auction scoring

Liquidations

Liquidate undercollateralized positions in lending protocols:

Bundle: [liquidate_position, swap_collateral]

JIT Liquidity

Provide just-in-time liquidity to a trade and withdraw after:

Bundle: [add_liquidity, victim_swap, remove_liquidity]

6. Reputation System

AXIO maintains a persistent reputation score for each searcher based on:

FactorWeightDescription
Landing rate40%Percentage of submitted bundles that land on-chain
Simulation success25%Percentage of bundles that pass simulation
Tip accuracy20%How close your tips are to the optimal bid
Volume consistency15%Regular submission volume (not spiky)

Tiers:

TierMin ScoreBenefits
Bronze0Standard rate limits
Silver602x rate limit, priority evaluation
Gold805x rate limit, priority evaluation, reduced tip floor
Platinum9510x rate limit, priority evaluation, lowest tip floor

Reputation is persistent across sessions and stored server-side.

7. Rate Limits

TierBundles/secStreamsBurst
Bronze5010100
Silver10020200
Gold25050500
Platinum5001001,000

Rate limiting uses a token bucket algorithm. When you exceed your limit, the engine applies in-stream backpressure (sleep) rather than disconnecting — your connection stays alive.

8. Best Practices

Do

  • Pre-compute your bundles and submit fast during the leader window
  • Track the leader schedule to know when your validator is about to produce a block
  • Use the streaming API for high-frequency strategies (avoid per-bundle connection overhead)
  • Include accurate mevType for better auction scoring and reputation
  • Monitor your reputation score via the /api/v1/reputation endpoint
  • Handle confirmations — track which bundles land and adjust your strategy

Don't

  • Don't spam — low-quality bundles that fail simulation hurt your reputation
  • Don't submit below the tip floor — these bundles are rejected immediately
  • Don't use stale state — always build bundles against the latest slot
  • Don't ignore the TTL — bundles expire after 10 seconds
  • Don't hardcode the tip vault — use the SDK's automatic vault selection

9. Monitoring

Check Bundle Status

const status = await axio.getBundleStatus(bundleId);
// { bundleId, status: "included" | "dropped" | "expired", slot, signatures }

Check Reputation

const rep = await axio.getReputation();
// { score: 87, tier: "Gold", landingRate: 0.94, simSuccess: 0.98 }

Check Tip Floor

const floor = await axio.getTipFloor();
// Current dynamic tip floor in lamports