Skip to content

4: Bebop Multi-Swap Tool #169

@premiumjibles

Description

@premiumjibles

Summary

Implement multi-token swap functionality using Bebop's native multi-swap API. Enables fan-out (1 token → up to 5 tokens) and fan-in (up to 5 tokens → 1 token) operations in a single transaction.

Background

Bebop natively supports multi-token swaps:

  • Fan-out: "Take 1 ETH and split into BTC, SOL, LINK, UNI, AAVE"
  • Fan-in: "Consolidate these 5 tokens into ETH"

This is same-chain only, works with standard EOA wallets (no smart wallet required), and integrates with Permit2 for gasless approvals on tokens already approved to Permit2.

Third-Party API

  • Bebop PMM API: https://api.bebop.xyz
  • Bebop JAM Solver Auction API
  • Supports 12+ chains including all our EVM chains
  • 0% slippage guarantee via PMM quotes

User Flow

Fan-Out Example

User: "Take 1 ETH and divide it equally into LINK, UNI, AAVE, and MATIC"

Agent: "I'll split your ETH into 4 tokens:

📊 Multi-Swap Preview
• Sell: 1 ETH (~$2,500)
• Buy:
  - 0.25 ETH worth of LINK (~$625)
  - 0.25 ETH worth of UNI (~$625)
  - 0.25 ETH worth of AAVE (~$625)
  - 0.25 ETH worth of MATIC (~$625)

This executes as ONE transaction with guaranteed pricing.

[Execute Multi-Swap]"

Fan-In Example

User: "Consolidate my LINK, UNI, and AAVE into ETH"

Agent: "I'll consolidate 3 tokens into ETH:

📊 Multi-Swap Preview
• Selling:
  - 50 LINK (~$750)
  - 100 UNI (~$650)
  - 5 AAVE (~$600)
• Receiving: ~0.8 ETH ($2,000)

This executes as ONE transaction.

[Execute Multi-Swap]"

Tool Schema

const multiSwapSchema = z.object({
  type: z.enum(['fan_out', 'fan_in']),
  // Fan-out: single sell asset, multiple buy assets
  // Fan-in: multiple sell assets, single buy asset
  sellAssets: z.array(z.object({
    symbol: z.string(),
    network: z.string(),
    amount: z.string().optional(), // Required for fan-in
  })).min(1).max(5),
  buyAssets: z.array(z.object({
    symbol: z.string(),
    network: z.string(),
    percentage: z.number().optional(), // For fan-out distribution
  })).min(1).max(5),
  network: z.string().describe('Network for the swap (must be same-chain)'),
})

const getMultiSwapQuoteSchema = z.object({
  ...multiSwapSchema.shape,
})

Tool Output

interface MultiSwapOutput {
  success: boolean
  type: 'fan_out' | 'fan_in'
  summary: {
    sellAssets: Array<{ symbol: string; amount: string; valueUsd: number }>
    buyAssets: Array<{ symbol: string; estimatedAmount: string; valueUsd: number }>
    totalSellValueUsd: number
    totalBuyValueUsd: number
    priceImpact: string
    provider: 'bebop'
  }
  // Single transaction - Bebop handles batching internally
  swapTx: TransactionData
  needsApproval: boolean
  approvalTxs?: TransactionData[] // May need multiple approvals for fan-in
}

UI Card

┌─────────────────────────────────────────────┐
│ 🔀 Multi-Swap                    [Bebop]    │
├─────────────────────────────────────────────┤
│ Splitting 1 ETH into 4 tokens               │
│                                             │
│ You Pay:                                    │
│   1 ETH ($2,500)                            │
│                                             │
│ You Receive:                                │
│   ~45 LINK ($625)                           │
│   ~62 UNI ($625)                            │
│   ~7 AAVE ($625)                            │
│   ~1,250 MATIC ($625)                       │
│                                             │
│ Price: Guaranteed (0% slippage)             │
│ Network: Ethereum                           │
│                                             │
│ [Execute Multi-Swap]                        │
└─────────────────────────────────────────────┘

Implementation

Server Changes

  1. Create apps/agentic-server/src/utils/getBebopMultiRate/
    • getBebopMultiQuote.ts - Fetch multi-swap quote from Bebop API
    • Handle both fan-out and fan-in scenarios
  2. Create apps/agentic-server/src/tools/initiateMultiSwap.ts
    • New tool for multi-swap operations
    • Validate max 5 tokens
    • Ensure same-chain operation
    • Build approval transactions if needed

Client Changes

  1. Create apps/agentic-chat/src/hooks/useMultiSwapExecution.ts
    • Similar to useSwapExecution but handles multiple approvals for fan-in
    • Single swap transaction (Bebop batches internally)
  2. Create apps/agentic-chat/src/components/tools/MultiSwapUI.tsx
    • Display multi-token preview
    • Show all assets being swapped
    • Execute button

API Integration

Bebop multi-swap endpoint (needs verification):

POST https://api.bebop.xyz/router/{network}/v1/quote
{
  "sell_tokens": ["0x...", "0x..."],  // Multiple for fan-in
  "buy_tokens": ["0x...", "0x..."],   // Multiple for fan-out
  "sell_amounts": ["1000000", "2000000"],
  "taker_address": "0x..."
}

Limitations

  • Max 5 tokens per operation (Bebop limit)
  • Same-chain only - all assets must be on the same network
  • Cross-chain not supported - use sequential Relay swaps for cross-chain
  • EVM only - Solana not supported by Bebop

Acceptance Criteria

  • Fan-out: Split one token into up to 5 tokens
  • Fan-in: Consolidate up to 5 tokens into one
  • Single transaction execution (Bebop handles batching)
  • Permit2 integration for gasless approvals where available
  • UI shows all tokens being swapped
  • Agent understands multi-swap requests naturally
  • Graceful fallback to sequential swaps if >5 tokens requested
  • Error handling for unsupported networks/tokens

Dependencies

  • SS-5295: Long-Running Order Infrastructure (for tracking)
  • Existing Bebop integration (getBebopRate)

Future Enhancements

  • Cross-chain multi-swap via sequential Relay calls
  • Percentage-based distribution ("split evenly" vs custom amounts)
  • Rebalancing tool built on top of multi-swap

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status

    Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions