APM

>Agent Skill

@sendaifun/dflow

skilldevelopment

Complete DFlow trading protocol SDK - the single source of truth for integrating DFlow on Solana. Covers spot trading, prediction markets, Swap API, Metadata API, WebSocket streaming, and all DFlow tools.

apm::install
$apm install @sendaifun/dflow
apm::skill.md
---
name: dflow
description: Complete DFlow trading protocol SDK - the single source of truth for integrating DFlow on Solana. Covers spot trading, prediction markets, Swap API, Metadata API, WebSocket streaming, and all DFlow tools.
---

# DFlow - Complete Integration Guide

The definitive guide for integrating DFlow - a trading protocol that enables traders to exchange value across spot and prediction markets natively on Solana.

## What is DFlow?

DFlow is a comprehensive trading infrastructure that provides:

- **Trading Applications & Wallets** - Token swaps with intelligent routing and 99.9% token coverage
- **Exchanges & Aggregators** - Access to billions in monthly routed volume across DEXes and Prop AMMs
- **Financial Institutions & Market Makers** - Programmable execution layers with CLPs and async trades
- **Prediction Market Platforms** - Discovery, pricing, routing, and settlement infrastructure

### Key Capabilities

| Feature | Description |
|---------|-------------|
| Token Coverage | 99.9% with millisecond detection |
| Infrastructure | Globally distributed, high-throughput optimization |
| Execution | Advanced algorithms with JIT routing for best-price execution |
| Markets | Support for both spot and prediction market trading |
| MEV Protection | Enhanced sandwich protection with Jito bundles |

## API Overview

DFlow provides two main API categories:

### 1. Swap API (Trading)
**Base URL:** `https://quote-api.dflow.net`

For executing trades:
- **Imperative Swaps** - Full control over route selection at signature time
- **Declarative Swaps** - Intent-based swaps with deferred route optimization
- **Trade API** - Unified interface for spot and prediction market trading
- **Order API** - Quote and transaction generation

### 2. Prediction Market Metadata API
**Base URL:** `https://api.prod.dflow.net`

For querying prediction market data:
- **Events API** - Query prediction events and forecasts
- **Markets API** - Get market details, orderbooks, outcome mints
- **Trades API** - Historical trade data
- **Live Data API** - Real-time milestones and updates
- **WebSocket** - Streaming price and orderbook updates

### Authentication
Most endpoints require an API key via the `x-api-key` header. Contact `hello@dflow.net` to obtain credentials.

## Quick Start

### Imperative Swap (3 Steps)

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

const API_BASE = "https://quote-api.dflow.net";
const API_KEY = process.env.DFLOW_API_KEY; // Optional but recommended

// Token addresses
const SOL = "So11111111111111111111111111111111111111112";
const USDC = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v";

async function imperativeSwap(keypair: Keypair, connection: Connection) {
  // Step 1: Get Quote
  const quoteParams = new URLSearchParams({
    inputMint: SOL,
    outputMint: USDC,
    amount: "1000000000", // 1 SOL
    slippageBps: "50",    // 0.5%
  });

  const quote = await fetch(`${API_BASE}/quote?${quoteParams}`, {
    headers: API_KEY ? { "x-api-key": API_KEY } : {},
  }).then(r => r.json());

  // Step 2: Get Swap Transaction
  const swapResponse = await fetch(`${API_BASE}/swap`, {
    method: "POST",
    headers: {
      "content-type": "application/json",
      ...(API_KEY && { "x-api-key": API_KEY }),
    },
    body: JSON.stringify({
      userPublicKey: keypair.publicKey.toBase58(),
      quoteResponse: quote,
      dynamicComputeUnitLimit: true,
      prioritizationFeeLamports: 150000,
    }),
  }).then(r => r.json());

  // Step 3: Sign and Send
  const tx = VersionedTransaction.deserialize(
    Buffer.from(swapResponse.swapTransaction, "base64")
  );
  tx.sign([keypair]);

  const signature = await connection.sendTransaction(tx);
  await connection.confirmTransaction(signature);

  return signature;
}
```

### Trade API (Unified - Recommended)

The Trade API provides a single endpoint that handles both sync and async execution:

```typescript
async function tradeTokens(keypair: Keypair, connection: Connection) {
  // Step 1: Get Order (quote + transaction in one call)
  const orderParams = new URLSearchParams({
    inputMint: SOL,
    outputMint: USDC,
    amount: "1000000000",
    slippageBps: "50",
    userPublicKey: keypair.publicKey.toBase58(),
  });

  const order = await fetch(`${API_BASE}/order?${orderParams}`, {
    headers: API_KEY ? { "x-api-key": API_KEY } : {},
  }).then(r => r.json());

  // Step 2: Sign and Send
  const tx = VersionedTransaction.deserialize(
    Buffer.from(order.transaction, "base64")
  );
  tx.sign([keypair]);
  const signature = await connection.sendTransaction(tx);

  // Step 3: Monitor (based on execution mode)
  if (order.executionMode === "async") {
    // Poll order status for async trades
    let status = "pending";
    while (status !== "closed" && status !== "failed") {
      await new Promise(r => setTimeout(r, 2000));
      const statusRes = await fetch(
        `${API_BASE}/order-status?signature=${signature}`,
        { headers: API_KEY ? { "x-api-key": API_KEY } : {} }
      ).then(r => r.json());
      status = statusRes.status;
    }
  } else {
    // Sync trades complete atomically
    await connection.confirmTransaction(signature);
  }

  return signature;
}
```

## API Reference

### Order API Endpoints

#### GET /order
Returns a quote and optionally a transaction for spot or prediction market trades.

| Parameter | Required | Description |
|-----------|----------|-------------|
| `inputMint` | Yes | Base58 input token mint |
| `outputMint` | Yes | Base58 output token mint |
| `amount` | Yes | Amount as scaled integer (1 SOL = 1000000000) |
| `userPublicKey` | No | Include to receive signable transaction |
| `slippageBps` | No | Max slippage in basis points or "auto" |
| `platformFeeBps` | No | Platform fee in basis points |
| `prioritizationFeeLamports` | No | "auto", "medium", "high", "veryHigh", or lamport amount |

**Response:**
```json
{
  "outAmount": "150000000",
  "minOutAmount": "149250000",
  "priceImpactPct": "0.05",
  "executionMode": "sync",
  "transaction": "base64...",
  "computeUnitLimit": 200000,
  "lastValidBlockHeight": 123456789,
  "routePlan": [...]
}
```

#### GET /order-status
Check status of async orders.

| Parameter | Required | Description |
|-----------|----------|-------------|
| `signature` | Yes | Base58 transaction signature |
| `lastValidBlockHeight` | No | Block height for expiry check |

**Status Values:**
- `pending` - Order submitted, awaiting processing
- `open` - Order opened, awaiting fill
- `pendingClose` - Filled, closing transaction pending
- `closed` - Order completed successfully
- `expired` - Transaction expired before landing
- `failed` - Order execution failed

### Imperative Swap Endpoints

#### GET /quote
Get a quote for an imperative swap.

| Parameter | Required | Description |
|-----------|----------|-------------|
| `inputMint` | Yes | Base58 input mint |
| `outputMint` | Yes | Base58 output mint |
| `amount` | Yes | Input amount (scaled integer) |
| `slippageBps` | No | Slippage tolerance or "auto" |
| `dexes` | No | Comma-separated DEXes to include |
| `excludeDexes` | No | Comma-separated DEXes to exclude |
| `onlyDirectRoutes` | No | Single-leg routes only |
| `maxRouteLength` | No | Max number of route legs |
| `forJitoBundle` | No | Jito bundle compatible routes |
| `platformFeeBps` | No | Platform fee in basis points |

#### POST /swap
Generate swap transaction from quote.

**Request Body:**
```json
{
  "userPublicKey": "Base58...",
  "quoteResponse": { /* from /quote */ },
  "dynamicComputeUnitLimit": true,
  "prioritizationFeeLamports": 150000,
  "wrapAndUnwrapSol": true
}
```

**Response:**
```json
{
  "swapTransaction": "base64...",
  "computeUnitLimit": 200000,
  "lastValidBlockHeight": 123456789,
  "prioritizationFeeLamports": 150000
}
```

#### POST /swap-instructions
Returns individual instructions instead of a full transaction (for custom transaction building).

### Declarative Swap Endpoints

Declarative swaps use intent-based execution with deferred route optimization.

#### GET /intent
Get an intent quote for a declarative swap.

| Parameter | Required | Description |
|-----------|----------|-------------|
| `inputMint` | Yes | Base58 input mint |
| `outputMint` | Yes | Base58 output mint |
| `amount` | Yes | Input amount (scaled integer) |
| `slippageBps` | No | Slippage tolerance |
| `userPublicKey` | Yes | User's wallet address |

#### POST /submit-intent
Submit a signed intent transaction for execution.

**Request Body:**
```json
{
  "signedTransaction": "base64...",
  "intentResponse": { /* from /intent */ }
}
```

### Token API Endpoints

#### GET /tokens
Returns list of supported token mints.

#### GET /tokens-with-decimals
Returns tokens with decimal information for proper amount scaling.

### Venue API Endpoints

#### GET /venues
Returns list of supported DEX venues (Raydium, Orca, Phoenix, Lifinity, etc.).

## Swap Modes Comparison

| Feature | Imperative | Declarative |
|---------|------------|-------------|
| Route Control | Full control at sign time | Optimized at execution |
| Latency | Higher (two API calls) | Lower (deferred calc) |
| Slippage | Fixed at quote time | Minimized at execution |
| Sandwich Protection | Standard | Enhanced |
| Use Case | Precise route requirements | Best execution priority |

### When to Use Imperative
- Need to review exact route before signing
- Building order books or specific DEX routing
- Complex multi-step transactions
- Need deterministic execution paths

### When to Use Declarative
- Prioritize best execution
- Lower slippage requirements
- Simple token swaps
- MEV protection is important

## Execution Modes

### Synchronous (Atomic)
- Single transaction execution
- All-or-nothing settlement
- Standard confirmation flow
- Use `connection.confirmTransaction()`

### Asynchronous (Multi-Transaction)
- Uses Jito bundles
- Open → Fill → Close transaction flow
- Poll `/order-status` for completion
- Better for complex routes or prediction markets

```typescript
// Async order monitoring
async function monitorAsyncOrder(signature: string) {
  const statuses = ["pending", "open", "pendingClose"];
  let currentStatus = "pending";

  while (statuses.includes(currentStatus)) {
    await new Promise(r => setTimeout(r, 2000));

    const res = await fetch(
      `${API_BASE}/order-status?signature=${signature}`,
      { headers: { "x-api-key": API_KEY } }
    ).then(r => r.json());

    currentStatus = res.status;

    if (currentStatus === "closed") {
      return { success: true, fills: res.fills };
    }
    if (currentStatus === "failed" || currentStatus === "expired") {
      return { success: false, status: currentStatus };
    }
  }
}
```

## Prediction Markets

DFlow provides infrastructure for trading prediction market outcome tokens.

### Market Structure
```
Series (Collection)
  └── Event (Occurrence)
        └── Market (Outcome Trade)
```

### Market Lifecycle
1. **Initialized** - Market created
2. **Active** - Trading enabled
3. **Inactive** - Trading paused
4. **Closed** - No more trading
5. **Determined** - Outcome known
6. **Finalized** - Payouts available

### Trading Prediction Markets
```typescript
// Use the Trade API with prediction market token mints
const order = await fetch(`${API_BASE}/order?${new URLSearchParams({
  inputMint: USDC,
  outputMint: OUTCOME_TOKEN_MINT, // Prediction market token
  amount: "10000000", // 10 USDC
  slippageBps: "100",
  userPublicKey: keypair.publicKey.toBase58(),
  predictionMarketSlippageBps: "200", // Separate slippage for PM
})}`, { headers: { "x-api-key": API_KEY } }).then(r => r.json());
```

## Common Token Mints

| Token | Mint Address |
|-------|--------------|
| SOL (Wrapped) | `So11111111111111111111111111111111111111112` |
| USDC | `EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v` |
| USDT | `Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB` |
| BONK | `DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263` |
| JUP | `JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN` |
| WIF | `EKpQGSJtjMFqKZ9KQanSqYXRcF8fBopzLHYxdM65zcjm` |

## Priority Fees

Configure transaction priority:

```typescript
// Option 1: Auto (recommended)
prioritizationFeeLamports: "auto"

// Option 2: Priority level
prioritizationFeeLamports: {
  priorityLevel: "high" // "medium", "high", "veryHigh"
}

// Option 3: Exact amount
prioritizationFeeLamports: 150000

// Option 4: Max with auto-adjust
prioritizationFeeLamports: {
  autoMultiplier: 2,
  maxLamports: 500000
}
```

## Error Handling

```typescript
async function safeSwap(params: SwapParams) {
  try {
    const quote = await getQuote(params);

    if (!quote.routePlan?.length) {
      throw new Error("No route found");
    }

    const swap = await getSwapTransaction(quote, params.userPublicKey);
    const tx = deserializeTransaction(swap.swapTransaction);
    tx.sign([params.keypair]);

    const signature = await connection.sendTransaction(tx, {
      skipPreflight: false,
      maxRetries: 3,
    });

    return { success: true, signature };
  } catch (error) {
    if (error.message.includes("insufficient")) {
      return { success: false, error: "Insufficient balance" };
    }
    if (error.message.includes("slippage")) {
      return { success: false, error: "Slippage exceeded" };
    }
    return { success: false, error: error.message };
  }
}
```

## Platform Fees

Collect platform fees on swaps:

```typescript
const quote = await fetch(`${API_BASE}/quote?${new URLSearchParams({
  inputMint: SOL,
  outputMint: USDC,
  amount: "1000000000",
  platformFeeBps: "50", // 0.5% fee
  platformFeeMode: "outputMint", // Collect in output token
})}`, { headers: { "x-api-key": API_KEY } }).then(r => r.json());

// In swap request, specify fee account
const swap = await fetch(`${API_BASE}/swap`, {
  method: "POST",
  headers: { "content-type": "application/json", "x-api-key": API_KEY },
  body: JSON.stringify({
    userPublicKey: user.toBase58(),
    quoteResponse: quote,
    feeAccount: platformFeeAccount.toBase58(), // Your fee recipient
  }),
}).then(r => r.json());
```

## Jito Integration

For MEV protection and bundle submission:

```typescript
// Request Jito-compatible routes
const quote = await fetch(`${API_BASE}/quote?${new URLSearchParams({
  inputMint: SOL,
  outputMint: USDC,
  amount: "1000000000",
  forJitoBundle: "true",
})}`, { headers: { "x-api-key": API_KEY } }).then(r => r.json());

// Include Jito sandwich mitigation
const swap = await fetch(`${API_BASE}/swap`, {
  method: "POST",
  body: JSON.stringify({
    userPublicKey: user.toBase58(),
    quoteResponse: quote,
    includeJitoSandwichMitigationAccount: true,
  }),
}).then(r => r.json());
```

## DFlow Swap Orchestrator

The DFlow Swap Orchestrator contract manages declarative swap execution:
```
Program ID: DF1ow3DqMj3HvTj8i8J9yM2hE9hCrLLXpdbaKZu4ZPnz
```

---

## Prediction Market Metadata API

The Prediction Market Metadata API provides comprehensive access to prediction market information.

**Base URL:** `https://api.prod.dflow.net`

### Market Structure

```
Series (Collection)
  └── Event (Occurrence)
        └── Market (Outcome Trade)
              ├── Yes Token (outcome mint)
              └── No Token (outcome mint)
```

### Events API

#### GET /api/v1/event/{ticker}
Returns a single event by its ticker with optional nested markets.

```typescript
const METADATA_API = "https://api.prod.dflow.net";

// Get event details
const event = await fetch(`${METADATA_API}/api/v1/event/TRUMP-2024`, {
  headers: { "x-api-key": API_KEY }
}).then(r => r.json());

// Response includes: ticker, title, status, markets, close_time, etc.
```

#### GET /api/v1/events
Returns a paginated list of all events.

```typescript
const events = await fetch(`${METADATA_API}/api/v1/events?limit=50&offset=0`, {
  headers: { "x-api-key": API_KEY }
}).then(r => r.json());
```

#### GET /api/v1/event/{ticker}/forecast
Returns historical forecast percentile data.

#### GET /api/v1/event/{ticker}/candlesticks
Returns candlestick data from Kalshi.

### Markets API

#### GET /api/v1/market/{ticker}
Returns a single market by ticker.

```typescript
const market = await fetch(`${METADATA_API}/api/v1/market/TRUMP-2024-WIN`, {
  headers: { "x-api-key": API_KEY }
}).then(r => r.json());

// Response: ticker, yes_mint, no_mint, status, last_price, volume, etc.
```

#### GET /api/v1/market/by-mint/{mint_address}
Lookup market by any mint (ledger or outcome mints).

```typescript
const market = await fetch(
  `${METADATA_API}/api/v1/market/by-mint/${outcomeMint}`,
  { headers: { "x-api-key": API_KEY } }
).then(r => r.json());
```

#### POST /api/v1/markets/batch
Batch retrieve multiple markets (max 100).

```typescript
const markets = await fetch(`${METADATA_API}/api/v1/markets/batch`, {
  method: "POST",
  headers: { "content-type": "application/json", "x-api-key": API_KEY },
  body: JSON.stringify({
    tickers: ["MARKET-1", "MARKET-2"],
    mints: ["mint1...", "mint2..."]
  })
}).then(r => r.json());
```

#### GET /api/v1/outcome_mints
Returns all yes_mint and no_mint pubkeys from all supported markets.

```typescript
// Get all outcome mints, optionally filter by close time
const mints = await fetch(
  `${METADATA_API}/api/v1/outcome_mints?min_close_timestamp=${Date.now()}`,
  { headers: { "x-api-key": API_KEY } }
).then(r => r.json());
```

#### POST /api/v1/filter_outcome_mints
Check if addresses are outcome mints (max 200).

```typescript
const filtered = await fetch(`${METADATA_API}/api/v1/filter_outcome_mints`, {
  method: "POST",
  headers: { "content-type": "application/json", "x-api-key": API_KEY },
  body: JSON.stringify({ addresses: ["mint1...", "mint2..."] })
}).then(r => r.json());
```

### Orderbook API

#### GET /api/v1/orderbook/{ticker}
Get orderbook by market ticker.

```typescript
const orderbook = await fetch(
  `${METADATA_API}/api/v1/orderbook/TRUMP-2024-WIN`,
  { headers: { "x-api-key": API_KEY } }
).then(r => r.json());

// Response: bids: [{price, quantity}], asks: [{price, quantity}]
```

#### GET /api/v1/orderbook/by-mint/{mint_address}
Get orderbook using mint address lookup.

### Trades API

#### GET /api/v1/trades
Returns paginated trade history with filtering.

```typescript
const trades = await fetch(
  `${METADATA_API}/api/v1/trades?ticker=TRUMP-2024-WIN&limit=100`,
  { headers: { "x-api-key": API_KEY } }
).then(r => r.json());
```

#### GET /api/v1/trades/by-mint/{mint_address}
Get trades using mint address lookup.

### Live Data API

#### GET /api/v1/milestones/{ticker}
Real-time milestone data from Kalshi.

```typescript
const milestones = await fetch(
  `${METADATA_API}/api/v1/milestones/TRUMP-2024`,
  { headers: { "x-api-key": API_KEY } }
).then(r => r.json());
```

### Series & Categories

#### GET /api/v1/series
Returns series templates for recurring events.

#### GET /api/v1/categories
Returns category tags for filtering.

### WebSocket Streaming

Connect for real-time updates:

```typescript
const ws = new WebSocket("wss://api.prod.dflow.net/ws");

ws.onopen = () => {
  // Subscribe to market updates
  ws.send(JSON.stringify({
    action: "subscribe",
    channel: "market",
    ticker: "TRUMP-2024-WIN"
  }));
};

ws.onmessage = (event) => {
  const data = JSON.parse(event.data);
  // Handle: price_update, orderbook_update, trade, etc.
  console.log("Update:", data);
};
```

### Market Lifecycle

| Status | Description |
|--------|-------------|
| `initialized` | Market created |
| `active` | Trading enabled |
| `inactive` | Trading paused |
| `closed` | No more trading |
| `determined` | Outcome known |
| `finalized` | Payouts available |

---

## GitHub Tools & SDKs

DFlow provides several open-source tools on GitHub:

### solana-agent-kit
**Repository:** [DFlowProtocol/solana-agent-kit](https://github.com/DFlowProtocol/solana-agent-kit)

Toolkit enabling AI agents to connect to Solana protocols:

```typescript
// Use with AI agents for automated trading
import { SolanaAgentKit } from "@dflow/solana-agent-kit";

const agent = new SolanaAgentKit({
  rpcUrl: process.env.RPC_URL,
  privateKey: process.env.PRIVATE_KEY,
});

// Agent can execute DFlow swaps, query markets, etc.
```

### clearpools
**Repository:** [DFlowProtocol/clearpools](https://github.com/DFlowProtocol/clearpools)

Orca Whirlpools with support for flow segmentation:

```typescript
// Extends Orca protocol with DFlow routing
import { ClearPools } from "@dflow/clearpools";

const pools = new ClearPools(connection);
await pools.initializePool(/* params */);
```

### dflow-amm-interface
**Repository:** [DFlowProtocol/dflow-amm-interface](https://github.com/DFlowProtocol/dflow-amm-interface)

Rust trait definitions for DFlow's AMM implementation. Use when building custom AMMs that integrate with DFlow routing.

### Infrastructure Tools
- **solana-accountsdb-plugin-bigtable** - Geyser plugin for Bigtable
- **solana-bigtable-connection** - Bigtable connection library
- **solana-bigtable-geyser-models** - Object models for Geyser data

---

## Skill Structure

```
dflow/
├── SKILL.md                           # This file - complete integration guide
├── resources/
│   ├── api-reference.md               # Swap API reference
│   ├── prediction-market-api.md       # Prediction Market Metadata API reference
│   ├── github-sdks.md                 # GitHub tools & SDKs documentation
│   ├── token-mints.md                 # Common token addresses
│   └── error-codes.md                 # Error handling guide
├── examples/
│   ├── imperative-swaps/              # Imperative swap examples
│   ├── declarative-swaps/             # Declarative swap examples
│   ├── trade-api/                     # Unified Trade API examples
│   └── prediction-markets/            # Prediction market examples
│       ├── query-markets.ts           # Query events, markets, orderbook
│       ├── trade-outcomes.ts          # Trade outcome tokens
│       └── websocket-client.ts        # Real-time data streaming
├── templates/
│   ├── swap-client.ts                 # Swap client starter
│   └── prediction-market-client.ts    # Prediction market client starter
└── docs/
    ├── advanced-patterns.md           # Complex integrations
    └── troubleshooting.md             # Common issues
```

## Guidelines

1. **Use Trade API for most cases** - Unified endpoint handles both sync/async
2. **Always handle async orders** - Check `executionMode` and poll status
3. **Set appropriate slippage** - "auto" for convenience, custom for control
4. **Include priority fees** - Essential for reliable execution
5. **Handle errors gracefully** - Network issues, slippage, insufficient balance
6. **Monitor rate limits** - Use API key for production
7. **Test on devnet first** - DFlow supports Solana devnet

## Resources

- [DFlow Documentation](https://pond.dflow.net)
- [API Keys](mailto:hello@dflow.net)
- [Discord Community](https://discord.gg/dflow)
- [GitHub](https://github.com/dflow-protocol)