Skip to main content

Executing Swaps

This guide walks through the full swap lifecycle using the Vulcx API on Fogo.

Flow

  1. Get a quote. Find the best route and estimated output.
  2. Build a transaction. Get an unsigned transaction from the API.
  3. Sign. Sign the transaction with the user’s wallet.
  4. Submit. Send the signed transaction to the network.
  5. Confirm. Wait for on-chain confirmation.

Step 1: Get a quote

curl "https://api.vulcx.xyz/api/v1/quote?\
inputMint=So11111111111111111111111111111111111111112&\
outputMint=uSd2czE61Evaf76RNbq4KPpXnkiL3irdzgLFUMe3NoG&\
amount=1000000000&\
swapMode=ExactIn&\
slippageBps=50" \
  -H "Authorization: Bearer $VULCX_KEY"
const quoteResponse = await fetch(
  "https://api.vulcx.xyz/api/v1/quote?" +
    new URLSearchParams({
      inputMint: "So11111111111111111111111111111111111111112",
      outputMint: "uSd2czE61Evaf76RNbq4KPpXnkiL3irdzgLFUMe3NoG",
      amount: "1000000000",
      swapMode: "ExactIn",
      slippageBps: "50",
    }),
  { headers: { Authorization: `Bearer ${process.env.VULCX_KEY}` } }
);
const quote = await quoteResponse.json();
console.log(`Best route: ${quote.data.hopCount} hop(s), output: ${quote.data.amountOut}`);
import os, requests

quote_resp = requests.get(
    "https://api.vulcx.xyz/api/v1/quote",
    params={
        "inputMint": "So11111111111111111111111111111111111111112",
        "outputMint": "uSd2czE61Evaf76RNbq4KPpXnkiL3irdzgLFUMe3NoG",
        "amount": "1000000000",
        "swapMode": "ExactIn",
        "slippageBps": "50",
    },
    headers={"Authorization": f"Bearer {os.environ['VULCX_KEY']}"},
)
quote = quote_resp.json()
print(f"Best route: {quote['data']['hopCount']} hop(s), output: {quote['data']['amountOut']}")

Step 2: Build the swap transaction

curl -X POST "https://api.vulcx.xyz/api/v1/swap" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $VULCX_KEY" \
  -d '{
    "userWallet": "YOUR_WALLET_ADDRESS",
    "inputMint": "So11111111111111111111111111111111111111112",
    "outputMint": "uSd2czE61Evaf76RNbq4KPpXnkiL3irdzgLFUMe3NoG",
    "amount": "1000000000",
    "swapMode": "ExactIn",
    "slippageBps": 50
  }'
const swapResponse = await fetch("https://api.vulcx.xyz/api/v1/swap", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    Authorization: `Bearer ${process.env.VULCX_KEY}`,
  },
  body: JSON.stringify({
    userWallet: wallet.publicKey.toBase58(),
    inputMint: "So11111111111111111111111111111111111111112",
    outputMint: "uSd2czE61Evaf76RNbq4KPpXnkiL3irdzgLFUMe3NoG",
    amount: "1000000000",
    swapMode: "ExactIn",
    slippageBps: 50,
  }),
});
const swap = await swapResponse.json();
swap_resp = requests.post(
    "https://api.vulcx.xyz/api/v1/swap",
    json={
        "userWallet": "YOUR_WALLET_ADDRESS",
        "inputMint": "So11111111111111111111111111111111111111112",
        "outputMint": "uSd2czE61Evaf76RNbq4KPpXnkiL3irdzgLFUMe3NoG",
        "amount": "1000000000",
        "swapMode": "ExactIn",
        "slippageBps": 50,
    },
    headers={"Authorization": f"Bearer {os.environ['VULCX_KEY']}"},
)
swap = swap_resp.json()

Step 3: Sign and submit

TypeScript
import { Connection, VersionedTransaction } from "@solana/web3.js";

const connection = new Connection("https://mainnet.fogo.io");

const txBuffer = Buffer.from(swap.data.transaction, "base64");
const transaction = VersionedTransaction.deserialize(txBuffer);

transaction.sign([wallet]);

const signature = await connection.sendRawTransaction(transaction.serialize(), {
  skipPreflight: false,
  maxRetries: 3,
});

const confirmation = await connection.confirmTransaction({
  signature,
  blockhash: transaction.message.recentBlockhash,
  lastValidBlockHeight: swap.data.lastValidBlockHeight,
});

if (confirmation.value.err) {
  throw new Error(`Transaction failed: ${JSON.stringify(confirmation.value.err)}`);
}

console.log(`Swap confirmed: https://solscan.io/tx/${signature}`);

Using raw instructions instead

If you need to compose swap instructions with other instructions (e.g., creating token accounts, adding memos), use POST /instructions instead of POST /swap. See the Get Instructions endpoint.
Last modified on July 5, 2026