Dflow
npx machina-cli add skill eugenepyvovarov/mcpbundler-agent-skills-marketplace/dflow --openclawDFlow - Next-Generation Solana Trading Infrastructure
Comprehensive guide for building trading applications on Solana using DFlow's Swap API. Enables token swaps with optimal routing, lower slippage, and access to both spot markets and prediction markets.
Overview
DFlow provides a suite of APIs for next-generation trading on Solana:
- 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
- Prediction Markets - Infrastructure for trading outcome tokens
Base URL
https://quote-api.dflow.net
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)
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:
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:
{
"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 processingopen- Order opened, awaiting fillpendingClose- Filled, closing transaction pendingclosed- Order completed successfullyexpired- Transaction expired before landingfailed- 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:
{
"userPublicKey": "Base58...",
"quoteResponse": { /* from /quote */ },
"dynamicComputeUnitLimit": true,
"prioritizationFeeLamports": 150000,
"wrapAndUnwrapSol": true
}
Response:
{
"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:
{
"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-statusfor completion - Better for complex routes or prediction markets
// 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
- Initialized - Market created
- Active - Trading enabled
- Inactive - Trading paused
- Closed - No more trading
- Determined - Outcome known
- Finalized - Payouts available
Trading Prediction Markets
// 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:
// 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
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:
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:
// 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
Skill Structure
dflow/
├── SKILL.md # This file
├── resources/
│ ├── api-reference.md # Complete API reference
│ ├── 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
├── templates/
│ └── swap-client.ts # Copy-paste starter
└── docs/
├── advanced-patterns.md # Complex integrations
└── troubleshooting.md # Common issues
Guidelines
- Use Trade API for most cases - Unified endpoint handles both sync/async
- Always handle async orders - Check
executionModeand poll status - Set appropriate slippage - "auto" for convenience, custom for control
- Include priority fees - Essential for reliable execution
- Handle errors gracefully - Network issues, slippage, insufficient balance
- Monitor rate limits - Use API key for production
- Test on devnet first - DFlow supports Solana devnet
Resources
Source
git clone https://github.com/eugenepyvovarov/mcpbundler-agent-skills-marketplace/blob/main/dflow/SKILL.mdView on GitHub Overview
DFlow provides APIs for next-generation trading on Solana, including Imperative Swaps for full route control, Declarative Swaps with deferred optimization, a unified Trade API for spot and prediction markets, and dedicated prediction market tooling. It enables token swaps with optimal routing and lower slippage, accessible via a simple API base URL. Authentication is done with an API key sent in the x-api-key header.
How This Skill Works
Developers call the DFlow quote and swap endpoints to obtain quotes and build swap transactions. Imperative Swaps give you signature-time control over routing, while Declarative Swaps offer intent-based swaps with deferred optimization. The Trade API unifies spot and prediction market trading, and responses include signed transactions ready for on-chain submission using a Solana connection.
When to Use It
- You need full, programmatic control over swap routing decisions at signature time (Imperative Swaps).
- You prefer intent-based swaps with deferred route optimization to simplify development (Declarative Swaps).
- You want a single, unified interface for both spot and prediction market trading (Trade API).
- You plan to access and trade in prediction markets and outcome tokens.
- You want to start quickly using the Quick Start flow and API keys for authenticated access.
Quick Start
- Step 1: Get a quote using inputMint, outputMint, amount, and slippageBps against https://quote-api.dflow.net.
- Step 2: Fetch the swap or order transaction, then deserialize the base64-encoded VersionedTransaction, sign with your keypair, and ready it for submission.
- Step 3: Send the signed transaction to Solana, and for async orders, poll /order-status to track completion.
Best Practices
- Choose Imperative Swaps when you need precise control over routing and timing of swaps.
- Use the Trade API for simpler, single-call quotes and transaction handling, especially for synchronous workflows.
- Always include inputMint, outputMint, amount, and slippageBps in quotes/orders to get accurate quotes.
- Leverage dynamicComputeUnitLimit and prioritizationFeeLamports where supported to optimize on-chain compute costs.
- Securely store API keys, send them in the x-api-key header, and monitor order status for async trades.
Example Use Cases
- A Solana wallet integrates DFlow to perform token swaps with optimal routing and low slippage.
- A DeFi trading bot uses Imperative Swaps to implement custom, route-specific trading strategies.
- An app uses the Trade API to trade both spot tokens and prediction market positions in one flow.
- A prediction market dashboard uses DFlow infrastructure to place outcome-token bets.
- A multi-exchange aggregator fetches quotes via /quote and executes via /swap or /order for fast routing.