# Searcher Integration

Submit MEV bundles to Block Chef and compete in Toby's open auction. This guide covers data access, bundle submission, and optimization.

## Prerequisites

* Solana development experience (Rust or TypeScript via `@solana/web3.js`)
* Familiarity with MEV concepts: arbitrage, liquidations, backrunning
* RPC access to a Solana node (or a provider like Helius, Triton, etc.)
* A funded Solana wallet for bundle tips

## Architecture

The searcher data flow looks like this:

**Laser Stream** (real-time data) → **Your Strategy** (analysis + bundle construction) → **Block Chef** (auction + verification) → **Validator** (block inclusion)

You consume data from Laser Stream, identify opportunities, build transaction bundles, and submit them to Block Chef. Block Chef runs a fair auction. The highest-tipping valid bundles win inclusion in the next block.

## Connecting to Laser Stream

Laser Stream is Toby's optimized data feed, part of the OtterFlow infrastructure. It refines raw blockchain data into signals built for MEV detection, with 30-50% lower hardware requirements compared to running your own firehose.

### Supported Data

* **Transaction data:** Real-time transaction stream with decoded instruction data
* **Account state changes:** Monitor specific accounts for balance or state updates
* **DEX events:** Swap events across Raydium, Orca, Meteora, and other major Solana DEXs
* **Liquidation triggers:** Lending protocol health factor alerts (Solend, Marginfi, Kamino)

### Connection Methods

**WebSocket** for real-time streaming and low-latency strategy execution:

```
wss://laser.toby.so/v1/stream
```

**REST API** for historical queries and batch data access:

```
https://laser.toby.so/v1/query
```

Authentication requires an API key passed via the `X-Toby-Key` header:

```typescript
import WebSocket from "ws";

const ws = new WebSocket("wss://laser.toby.so/v1/stream", {
  headers: { "X-Toby-Key": process.env.TOBY_API_KEY }
});

ws.on("message", (data) => {
  const event = JSON.parse(data.toString());

  if (event.type === "dex_swap") {
    // Raydium/Orca/Meteora swap detected
    const { pool, amountIn, amountOut, mint } = event.data;
    evaluateArbitrageOpportunity(pool, amountIn, amountOut, mint);
  }

  if (event.type === "liquidation_trigger") {
    // Lending protocol health factor alert
    const { protocol, account, healthFactor } = event.data;
    if (healthFactor < 1.05) buildLiquidationBundle(protocol, account);
  }
});
```

> **⚠️ Devnet Only:** The endpoints and API shown above are for the **devnet environment**. Mainnet URLs and SDK packages will be published at launch. Request devnet API keys via [Discord](https://discord.gg/toby).

## Submitting Bundles to Block Chef

### Bundle Requirements

Every bundle submitted to Block Chef must meet these criteria:

* **Valid Solana transactions.** All transactions must be properly signed and simulate successfully.
* **Competitive tip.** Each bundle includes a tip that determines its auction priority. Higher tips = higher inclusion probability.
* **No harmful patterns.** Sandwiches and other user-extractive strategies are automatically detected and rejected. Block Chef enforces the OpenMEV Council's filtering rules.

### Submission Flow

1. **Build your transaction bundle.** Construct one or more Solana transactions that capture the MEV opportunity you've identified.
2. **Attach a competitive tip.** Add a tip transaction to your bundle. The tip is paid to the block-producing validator and Toby network (5% protocol fee).
3. **Submit to Block Chef.** Send your bundle to the Block Chef API:

   ```
   POST https://blockchef.toby.so/v1/bundles
   ```
4. **Receive confirmation.** Block Chef returns a bundle ID and status (`accepted`, `rejected`, `filtered`). Rejected bundles include a reason code.
5. **Monitor inclusion.** Track whether your bundle was included in the target block via the status endpoint or WebSocket subscription.

### Example: Full Bundle Submission

```typescript
import { Connection, Keypair, Transaction } from "@solana/web3.js";

const BLOCK_CHEF_URL = "https://blockchef.toby.so/v1/bundles";

async function submitBundle(
  signedTxs: Transaction[],
  tipTx: Transaction,
  apiKey: string
) {
  const bundle = {
    transactions: signedTxs.map(tx =>
      tx.serialize().toString("base64")
    ),
    tip: tipTx.serialize().toString("base64"),
    metadata: {
      strategy: "arbitrage",
      targetSlot: await getCurrentSlot() + 1,
    },
  };

  const response = await fetch(BLOCK_CHEF_URL, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "X-Toby-Key": apiKey,
    },
    body: JSON.stringify(bundle),
  });

  const result = await response.json();
  // result.status: "accepted" | "rejected" | "filtered"
  // result.bundleId: "bc_7f3a..."
  // result.reason: null | "sandwich_detected" | "invalid_signature" | ...
  return result;
}
```

### Response Format

```json
{
  "bundleId": "bc_7f3a8b2c1d4e5f6a",
  "status": "accepted",
  "reason": null,
  "auction": {
    "tipRank": 3,
    "totalCompeting": 47,
    "estimatedInclusion": 0.89
  },
  "targetSlot": 284719403
}
```

> **⚠️ Devnet Only:** The endpoints and code above are for the **devnet environment**. Mainnet URLs will be published at launch. Request devnet access via [Discord](https://discord.gg/toby).

## Best Practices

* **Tip competitively.** Block Chef runs a fair auction. The best tips win. Monitor the current tip floor via the `/v1/tipfloor` endpoint to calibrate.
* **Avoid filtered strategies.** Sandwiches and front-running patterns are automatically rejected. Focus on arbitrage, liquidations, and backrunning.
* **Monitor inclusion rates.** Track your bundle acceptance and inclusion rates. Low inclusion with high acceptance means your tips need adjustment.
* **Use Laser Stream.** It gives you the lowest-latency data access. Running your own node works, but Laser Stream delivers pre-processed signals that reduce compute overhead.
* **Test on devnet first.** Validate your strategy against devnet before deploying to mainnet. Block Chef runs identical logic on both networks.
* **Bundle atomically.** Structure your transactions so the full bundle succeeds or fails together. Partial execution can leave you exposed.

***

**Related:**

* [Block Chef](https://learn.toby.foundation/products-and-infrastructure/block-chef): How the auction and verification system works
* [OtterFlow](https://learn.toby.foundation/products-and-infrastructure/otterflow): Full data infrastructure documentation
* [Getting Started](https://learn.toby.foundation/builders/getting-started): Architecture overview and integration paths
