Skip to main content
Declarative Swaps allow Solana users to trade tokens with less slippage, lower latency, and better pricing. Using Declarative Swaps through DFlow Swap API is simple. DFlow Swap API aggregates liquidity from all the major Solana DEXs and offers an API for trading any SPL token.
This quickstart assumes familiarity with Solana’s transaction and network connection logic. If unfamiliar, please refer to the Solana Cookbook.
For production use, you’ll need an API key to avoid rate limits. See the API Keys guide for details on obtaining and using an API key.
1

Request a Quote

DFlow Swap API returns a quote specific to the token pair, amount, slippage tolerance, platform fee and other parameters.A route is calculated for the swap at this step, but not hardened into the transaction. Instead, the quote is committed, and the route plan will be recalculated at the time the intent is submitted.
const SOL = "So11111111111111111111111111111111111111112";
const USDC = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v";

/// Amount of SOL to swap to USDC
const amount = 1_000_000_000;

/// Slippage tolerance in bps
const slippageBps = 1;

/// Base URL for the DFlow Swap API
const AGGREGATOR_API_BASE_URL = "https://quote-api.dflow.net";
const API_KEY = process.env.DFLOW_API_KEY; // Optional

const queryParams = new URLSearchParams();
queryParams.append("inputMint", SOL);
queryParams.append("outputMint", USDC);
queryParams.append("amount", amount.toString());

queryParams.append("userPublicKey", keypair.publicKey.toBase58());
queryParams.append("slippageBps", slippageBps.toString());

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

const intentResponse = await fetch(
  `${AGGREGATOR_API_BASE_URL}/intent?${queryParams.toString()}`,
  { headers }
);
const intentData = await intentResponse.json();
2

Sign the Intent

Signing the intent guarantees the minimum amount of output tokens, but does not commit to any given route plan to achieve the minimum amount of output tokens.
const transaction = intentData.openTransaction;
const transactionBytes = Buffer.from(transaction, "base64");
const openTransaction = Transaction.from(transactionBytes);

openTransaction.sign(keypair);
3

Submit the Intent

Intents are submitted to the DFlow Aggregator, which optimizes the execution of the swap based on network conditions.
const headers: HeadersInit = {
  "Content-Type": "application/json",
};
if (API_KEY) {
  headers["x-api-key"] = API_KEY;
}

const response = await fetch(`${AGGREGATOR_API_BASE_URL}/submit-intent`, {
  method: "POST",
  headers,
  body: JSON.stringify({
    quoteResponse: intentData,
    signedOpenTransaction: Buffer.from(openTransaction.serialize()).toString(
      "base64"
    ),
  }),
});
const submitIntentData = await response.json();
4

Monitor the Intent

After submitting the Intent, you can monitor its status using the monitorOrder helper function from the @dflow-protocol/swap-api-utils package.
const result = await monitorOrder({
  connection,
  intent: intentData,
  signedOpenTransaction: openTransaction,
  submitIntentResponse: submitIntentData,
});

switch (result.status) {
  case ORDER_STATUS.CLOSED: {
    if (result.fills.length > 0) {
      // Order was filled and closed
      const qtyIn = result.fills.reduce((acc, x) => acc + x.qtyIn, 0n);
      const qtyOut = result.fills.reduce((acc, x) => acc + x.qtyOut, 0n);
      console.log(`Order succeeded: sent ${qtyIn}, received ${qtyOut}`);
    } else {
      // Order was closed without any fills
      console.log("Order failed");
    }
    break;
  }
  case ORDER_STATUS.PENDING_CLOSE: {
    if (result.fills.length > 0) {
      // Order was filled and is now closable
      const qtyIn = result.fills.reduce((acc, x) => acc + x.qtyIn, 0n);
      const qtyOut = result.fills.reduce((acc, x) => acc + x.qtyOut, 0n);
      console.log(`Order succeeded: sent ${qtyIn}, received ${qtyOut}`);
    } else {
      // Order was not filled and is now closable
      console.log("Order failed");
    }
    break;
  }
  case ORDER_STATUS.OPEN_EXPIRED: {
    // Transaction to open the order expired
    console.log(
      "Transaction expired. Try again with a higher slippage tolerance."
    );
    break;
  }
  case ORDER_STATUS.OPEN_FAILED: {
    // Transaction to open the order was executed and failed
    console.log("Order failed", result.transactionError);
    break;
  }
}
Declarative Swaps Declarative Swaps