Skip to main content
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 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();
}

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

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;
}

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

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;
}

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.
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 provides sample code to construct a Bitcoin transaction given the actionResponse transaction object and broadcast it to the network.
import { prepareBtcTx } from "./prepareBtcTx";

export async function sendTransaction() {
  const { tx } = await getAction({ actionRequest });
  const privateKeyWIF = "YOUR_PRIVATE_KEY_IN_WIF_FORMAT";

const keyPair = ECPair.fromWIF(privateKeyWIF, NET);
const payment = bitcoin.payments.p2wpkh({
pubkey: keyPair.publicKey,
network: NET,
});

const utxos = await getUtxosForAddress(payment.address);
const rawTransaction = prepareBtcTx({
tx,
privateKeyWIF,
utxos,
feeRate: 15,
});

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

if (!response.ok) {
const errorText = await response.text();
throw new Error(`Broadcast failed: ${response.status} - ${errorText}`);
}

return await response.text();
}

Broadcast on HyperCore

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

Install recommended package

pnpm i @nktkas/hyperliquid viem
2

Import the recommended libraries

We’ll use the HyperLiquid SDK for interacting with the HyperCore network.
import * as HyperLiquid from "@nktkas/hyperliquid";
import { createWalletClient, custom } from "viem";
3

Broadcast the transaction

import * as HyperLiquid from "@nktkas/hyperliquid";
import { createWalletClient, custom } from "viem";

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

  const [account] = await window.ethereum.request({
    method: "eth_requestAccounts",
  });
  const wallet = createWalletClient({
    account,
    transport: custom(window.ethereum),
  });

  const transport = new HyperLiquid.HttpTransport();
  const exchClient = new HyperLiquid.ExchangeClient({ wallet, transport });

  return await exchClient.usdSend({
    destination: tx.destination,
    amount: tx.amount,
  });
}