Refactor high-complexity React components in Dify frontend. Use when `pnpm analyze-component...
npx skills add eugenepyvovarov/mcpbundler-agent-skills-marketplace --skill "dflow"
Install specific skill from multi-skill repository
# Description
Comprehensive guide for building Solana trading apps using DFlow's Swap API. Use when integrating quotes, routing, imperative/declarative swaps, or prediction markets.
# SKILL.md
name: dflow
description: Comprehensive guide for building Solana trading apps using DFlow's Swap API. Use when integrating quotes, routing, imperative/declarative swaps, or prediction markets.
DFlow - 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 [email protected] 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 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:
{
"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
# Supported AI Coding Agents
This skill is compatible with the SKILL.md standard and works with all major AI coding agents:
Learn more about the SKILL.md standard and how to use these skills with your preferred AI coding agent.