Skip to main content

Documentation Index

Fetch the complete documentation index at: https://pond.dflow.net/llms.txt

Use this file to discover all available pages before exploring further.

During development, you can use the developer endpoints without an API key. For production use, you’ll need an API key to avoid rate limits.
Use Declarative Trades to trade tokens with less slippage, lower latency, and better pricing. To execute a declarative trade, request an intent from /intent, sign the open transaction, submit the intent, then monitor until it settles.
1

Set Up

Imports, constants, and the wallet/connection used across every step.
import "dotenv/config";
import { Connection, Keypair, Transaction } from "@solana/web3.js";
import { monitorOrder, ORDER_STATUS } from "@dflow-protocol/swap-api-utils";
import bs58 from "bs58";

const TRADE_API = process.env.DFLOW_TRADE_API_URL!;
const API_KEY = process.env.DFLOW_API_KEY; // Not needed with dev endpoints
const SOL_MINT = "So11111111111111111111111111111111111111112";
const USDC_MINT = process.env.DFLOW_SETTLEMENT_MINT!;
const AMOUNT = 100_000; // 0.0001 SOL (9 decimals)
const SLIPPAGE_BPS = 50; // 0.5%

const connection = new Connection(process.env.SOLANA_RPC_URL!, "confirmed");
const keypair = Keypair.fromSecretKey(
  bs58.decode(process.env.SOLANA_PRIVATE_KEY!)
);

const headers: HeadersInit = {};
if (API_KEY) headers["x-api-key"] = API_KEY;
2

Request an Intent Quote

The GET /intent response returns an open order transaction that signals the trader’s intent to swap at a guaranteed minimum quote with a slippage tolerance. This intent defines the constraints (pair, amount, slippage, fees), not a fixed route.
const params = new URLSearchParams({
  inputMint: SOL_MINT,
  outputMint: USDC_MINT,
  amount: AMOUNT.toString(),
  slippageBps: SLIPPAGE_BPS.toString(),
  userPublicKey: keypair.publicKey.toBase58(),
});

const intentData = await fetch(`${TRADE_API}/intent?${params}`, {
  headers,
}).then((r) => r.json());
3

Sign the Intent

Sign the open transaction returned with the intent, guaranteeing the minimum output without committing to any specific route.
const openTransaction = Transaction.from(
  Buffer.from(intentData.openTransaction, "base64")
);
openTransaction.sign(keypair);
4

Submit the Intent

Submit the signed intent to POST /submit-intent. The DFlow Aggregator picks the route at execution time based on current network conditions.
const submitResponse = await fetch(`${TRADE_API}/submit-intent`, {
  method: "POST",
  headers: { ...headers, "Content-Type": "application/json" },
  body: JSON.stringify({
    quoteResponse: intentData,
    signedOpenTransaction: Buffer.from(openTransaction.serialize()).toString(
      "base64"
    ),
  }),
}).then((r) => r.json());
5

Monitor the Intent

Use the monitorOrder helper from @dflow-protocol/swap-api-utils to wait for the intent to reach a terminal state. The helper watches the order onchain via Solana RPC, so the connection’s RPC must support JSON-RPC batch requests.
const result = await monitorOrder({
  connection,
  intent: intentData,
  signedOpenTransaction: openTransaction,
  submitIntentResponse: submitResponse,
});

const explorerUrl = (sig: string) => `https://orbmarkets.io/tx/${sig}`;
const openTxUrl = explorerUrl(submitResponse.openTransactionSignature);

switch (result.status) {
  case ORDER_STATUS.CLOSED:
  case ORDER_STATUS.PENDING_CLOSE: {
    if (result.fills.length > 0) {
      const qtyIn = result.fills.reduce((acc, x) => acc + x.qtyIn, 0n);
      const qtyOut = result.fills.reduce((acc, x) => acc + x.qtyOut, 0n);
      console.log(`Success: sent ${qtyIn}, received ${qtyOut}`);
      for (const fill of result.fills) {
        console.log(`  Fill: ${explorerUrl(fill.signature)}`);
      }
    } else {
      console.log(`Failed: order closed without fills`);
      console.log(`  Open tx: ${openTxUrl}`);
    }
    break;
  }
  case ORDER_STATUS.OPEN_EXPIRED:
    console.log(
      `Failed: open transaction expired. Try a higher slippage tolerance.`
    );
    console.log(`  Open tx: ${openTxUrl}`);
    break;
  case ORDER_STATUS.OPEN_FAILED:
    console.log(`Failed: open transaction reverted:`, result.transactionError);
    console.log(`  Open tx: ${openTxUrl}`);
    break;
}

API Routes

Cookbook Repository

This recipe, along with many more, is available in the DFlow Cookbook Repo. You can clone it and start coding immediately.

Need Help?

https://mintlify.s3.us-west-1.amazonaws.com/dflow/images/meteor-icons_discord.svg

Join Our Discord

Connect with other developers, get help, and stay updated on the latest DFlow developments.
https://mintlify.s3.us-west-1.amazonaws.com/dflow/images/meteor-icons_telegram.svg

Dev Notifications

Join the DFlow Dev Notifications Telegram group to stay in the loop on new features and other announcements.