API Reference: Get Action Submitting transactions differs by source chain VM. Reference available transaction types here. Examples below demonstrate the swap process for each VM. VmId: evm, solana, alt-vm (any non-named VM - e.g., Bitcoin, Ripple).

Create a swap transaction

1

Configure the transaction request

The Swap action type covers same chain swaps, bridge, and cross-chain swap transactions. Swaps are all just swaps!
The recipient should only be different from the sender if you are:
  1. Swapping across VMs that use incompatible key formats or cryptographic curves (e.g., EVM <> Solana)
  2. Sending funds to another address
This example prepares a swap from USDC on Base to USDT on Arbitrum. To transact across non-EVM networks, simply update the chainId and token fields to your desired pairs, no further customizations required.
import { sendTransaction } from "@wagmi/core";
import { useAccount } from "wagmi";

const actionRequest = {
  actionType: "swap-action",
  sender: "0xd8da6bf26964af9d7eed9e03e53415d37aa96045", // generally the user's connected wallet address
  srcToken: "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913", // USDC on Base
  dstToken: "0xfd086bc7cd5c481dcc9c85ebe478a1c0b69fcbb9", // USDT on Arbitrum
  srcChainId: 8453, // Base Chain ID
  dstChainId: 42161, // Arbitrum Chain ID
  slippage: 100, // bps
  swapDirection: "exact-amount-in",
  amount: 10000000n, // denominated in srcToken decimals
  recipient: "0xd8da6bf26964af9d7eed9e03e53415d37aa96045",
};
2

Generate the transaction

Please visit the Get Action API reference for type definitions, including the ActionRequest and ActionResponse. This API endpoint will return a transaction object we will use to actually execute this transaction.
import { sendTransaction } from "@wagmi/core";
import { useAccount } from "wagmi";

const actionRequest: ActionRequest = {
  actionType: "swap-action",
  sender: "0xd8da6bf26964af9d7eed9e03e53415d37aa96045", // generally the user's connected wallet address
  srcToken: "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913", // USDC on Base
  dstToken: "0xfd086bc7cd5c481dcc9c85ebe478a1c0b69fcbb9", // USDT on Arbitrum
  srcChainId: 8453, // Base Chain ID
  dstChainId: 42161, // Arbitrum Chain ID
  slippage: 100, // bps
  swapDirection: "exact-amount-in",
  amount: 10000000n, // denominated in srcToken decimals
  recipient: "0xd8da6bf26964af9d7eed9e03e53415d37aa96045",
};

async function getAction({ actionRequest }): Promise<ActionResponse> {
  const url = new URL("https://api-v2.swaps.xyz/api/getAction");

  Object.entries(actionRequest).forEach(([key, value]) => {
    url.searchParams.set(key, String(value));
  });

  const requestOptions = {
    method: "GET",
    headers: { "x-api-key": SWAPS_API_KEY },
  };

  const response = await fetch(url.toString(), requestOptions);

  return await response.json();
}
That’s it! You now have a transaction you can broadcast on your source chain.

Broadcast on EVM

In this step, we will broadcast the transaction we generated above on Base. This method will work for any EVM chain. View the EVM transaction type here.
1

Import the recommended libraries

This example uses Wagmi; however, you can use your preferred provider. The transaction we’ll generate is compatible with any library.
import { useAccount } from "wagmi";
import { sendTransaction, estimateGas } from "@wagmi/core";
import { wagmiConfig } from "../your_wagmi_config_path";
2

Broadcast the transaction

If your source token is an ERC20, you will have to first submit a token approval. We recommend only approving the amount required for the transaction.

Please follow the guide here.
import { sendTransaction, estimateGas } from "@wagmi/core";
import { arbitrum, base } from "viem/chains";
import { wagmiConfig } from "../your_wagmi_config_path";

export async function broadcastOnEvm({ actionRequest }): Promise<Hash> {
  const account = useAccount({ config: wagmiConfig });
  const { tx } = await getAction({ actionRequest });
  const gas = await estimateGas(wagmiConfig, { account, ...tx });

  const txHash = await sendTransaction(wagmiConfig, {
    ...tx,
    gas,
  });

  return txHash;
}
Transaction broadcasted! Use Basescan to verify your transaction.

Broadcast on Solana

Let’s assume we set Solana as the source chain in the actionRequest used to generate our transaction. Let’s see how we can broadcast it on Solana. View the Solana transaction type here.
1

Import the recommended libraries

We’ll use @solana/web3.js, which is the standard SDK for interacting with the Solana blockchain.
import {
  Connection,
  PublicKey,
  sendAndConfirmTransaction,
  Transaction,
} from "@solana/web3.js";
2

Broadcast the transaction

Ensure that the sender wallet has enough SOL to cover transaction fees. If the swap involves a token account that doesn’t exist yet, your transaction must include an instruction to create it.
import {
  Connection,
  PublicKey,
  sendAndConfirmTransaction,
  Transaction,
} from "@solana/web3.js";

export async function broadcastOnSolana({ actionRequest }): Promise<string> {
  const { tx } = await getAction({ actionRequest });

  const connection = new Connection("https://api.mainnet-beta.solana.com");
  const senderKeypair = ... // Your wallet's keypair (use secure storage)

  const transaction = Transaction.from(Buffer.from(tx.rawTransaction, "base64"));

  const signature = await sendAndConfirmTransaction(connection, transaction, [senderKeypair]);

  return signature;
}
Transaction broadcasted! Use a Solana explorer like Solscan to verify your transaction.

Broadcast on alt VMs

Let’s assume we set Bitcoin as the source chain in the actionRequest used to generate our transaction. Let’s see how we can broadcast it on Bitcoin. View the alt VM transaction type here.
Alt VM transactions are all deposits: the transaction will transfer funds from the sender to the to field specified in the AltVmTransaction response. This transfer triggers the swap transaction and funds will ultimately be delivered to the recipient.
Alt VM transactions require an extra step to track the status of transactions. See the required step here.
1

Install recommended package

pnpm i bitcoinjs-lib
2

Import the recommended libraries

We’ll use bitcoinjs-lib to sign the Bitcoin transaction.
import * as bitcoin from "bitcoinjs-lib";
3

Broadcast the transaction

This example assumes your wallet supports PSBT signing. You’ll finalize and extract the raw transaction, then send it to the Bitcoin network via a public relay (e.g., Blockstream or mempool.space), or your own full node.
import * as bitcoin from "bitcoinjs-lib";

export async function broadcastOnBitcoin({
  actionRequest,
  network = "mainnet",
}): Promise<string> {
  const { tx } = await getAction({ actionRequest });

  const bitcoinNetwork =
    network === "mainnet" ? bitcoin.networks.bitcoin : bitcoin.networks.testnet;

  const psbt = bitcoin.Psbt.fromHex(tx.psbt, { network: bitcoinNetwork });

  const keyPair = bitcoin.ECPair.fromWIF(YOUR_WIF, bitcoinNetwork);
  psbt.signAllInputs(keyPair);
  psbt.finalizeAllInputs();

  const rawTx = psbt.extractTransaction().toHex();

  const res = await fetch("https://blockstream.info/api/tx", {
    method: "POST",
    headers: {
      "Content-Type": "text/plain",
    },
    body: rawTx,
  });

  if (!res.ok) {
    const errorText = await res.text();
    throw new Error(
      `Failed to broadcast transaction: ${res.status} - ${errorText}`
    );
  }

  const txId = await res.text(); // Blockstream returns plain txid in response body
  return txId;
}
Transaction broadcasted! Use a Bitcoin explorer like Blockstream to verify your transaction.