Skip to main content
The Titan instructions module enables vault managers and allocators to swap tokens through Titan, a Solana DEX aggregator. The integration works in two steps: fetch a swap quote from Titan’s API, then wrap the resulting instruction in a Squads sync transaction.
Titan swap quotes are fetched over a WebSocket connection that requires authentication credentials (wsUrl and authToken).

Transaction Structure

Every Titan interaction goes through createVaultSyncTransaction, which returns three parts:
const { preInstructions, instruction, postInstructions } =
  await createVaultSyncTransaction({
    instructions,   // Array of VaultInstruction descriptors
    owner,          // Vault PDA (the Squads smart account)
    connection,
    policyPda,      // Policy authorizing this execution
    vaultPda,       // Squads vault PDA
    signer,         // The allocator or manager wallet
    vaultAddress,   // ExponentStrategyVault PDA (auto-resolves hook accounts)
  });

// Send all three parts in order
const tx = new Transaction().add(...preInstructions, instruction, ...postInstructions);
await sendAndConfirmTransaction(connection, tx, [wallet]);
PartWhat it containsWhy it’s separate
preInstructionsAny permissionless setup instructionsMust be top-level instructions
instructionSquads sync transaction wrapping all vault-signed instructionsExecutes with the vault’s smart account as signer
postInstructionsAny post-operation instructionsMust be top-level instructions

Fetching a Quote

getTitanQuote connects to Titan’s WebSocket API, requests a swap route, and returns a TransactionInstruction along with any Address Lookup Table addresses needed for transaction compilation.
import { getTitanQuote } from "@exponent-labs/exponent-sdk";
import { Connection, PublicKey } from "@solana/web3.js";

const connection = new Connection("https://api.mainnet-beta.solana.com");

const quoteResult = await getTitanQuote(connection, {
  wsUrl: "wss://...",         // Titan WebSocket URL
  authToken: "...",           // Titan API auth token
}, {
  inputMint: new PublicKey("..."),    // Token to sell
  outputMint: new PublicKey("..."),   // Token to buy
  amount: 1_000_000_000n,           // Amount of input token in native units
  slippageBps: 50,                   // Slippage tolerance in basis points
  userPublicKey: vaultPda,           // The vault's smart account (trader)
});

Parameters

ParameterTypeDescription
connectionConnectionSolana RPC connection
auth.wsUrlstringTitan WebSocket endpoint URL
auth.authTokenstringTitan API authentication token
params.inputMintPublicKeyMint address of the token to sell
params.outputMintPublicKeyMint address of the token to buy
params.amountbigintAmount of input token in native units
params.slippageBpsnumberOptional. Slippage tolerance in basis points
params.userPublicKeyPublicKeyThe trader’s public key — use the vault’s Squads PDA

Return Value

FieldTypeDescription
instructionTransactionInstructionThe Titan SwapRouteV2 instruction to execute
addressLookupTableAddressesPublicKey[]Address Lookup Table addresses from the Titan route
The quote has a timeout of 15 seconds. Fetch the quote and submit the transaction promptly to avoid stale routes.

Executing a Swap

titanAction.swap wraps the instruction from getTitanQuote into a vault instruction descriptor for createVaultSyncTransaction.
import {
  titanAction,
  createVaultSyncTransaction,
} from "@exponent-labs/exponent-sdk";

const { preInstructions, instruction, postInstructions } =
  await createVaultSyncTransaction({
    instructions: [
      titanAction.swap({
        instruction: quoteResult.instruction,
      }),
    ],
    owner: vaultPda,
    connection,
    policyPda,
    vaultPda,
    signer: wallet.publicKey,
    vaultAddress,
  });

const tx = new Transaction().add(...preInstructions, instruction, ...postInstructions);
await sendAndConfirmTransaction(connection, tx, [wallet]);

Parameters

ParameterTypeDescription
instructionTransactionInstructionThe Titan SwapRouteV2 instruction returned by getTitanQuote
The addressLookupTableAddresses returned by getTitanQuote may be needed when compiling a V0 (versioned) transaction message. Fetch the lookup table accounts on-chain and include them in the TransactionMessage if using versioned transactions.
A matching policy must exist before executing. See Policy Builders.

Full Flow Example

This example demonstrates fetching a Titan swap quote and executing it through the vault.

Step 1: Fetch Swap Quote

import {
  getTitanQuote,
  titanAction,
  createVaultSyncTransaction,
} from "@exponent-labs/exponent-sdk";
import { Connection, PublicKey, Transaction, sendAndConfirmTransaction } from "@solana/web3.js";

const connection = new Connection("https://api.mainnet-beta.solana.com");

const INPUT_MINT = new PublicKey("...");   // e.g., USDC
const OUTPUT_MINT = new PublicKey("...");  // e.g., SOL

const quoteResult = await getTitanQuote(connection, {
  wsUrl: "wss://...",
  authToken: "...",
}, {
  inputMint: INPUT_MINT,
  outputMint: OUTPUT_MINT,
  amount: 1_000_000_000n,
  slippageBps: 50,
  userPublicKey: vaultPda,
});

Step 2: Execute Swap Through Vault

const { preInstructions, instruction, postInstructions } =
  await createVaultSyncTransaction({
    instructions: [
      titanAction.swap({
        instruction: quoteResult.instruction,
      }),
    ],
    owner: vaultPda,
    connection,
    policyPda,
    vaultPda,
    signer: wallet.publicKey,
    vaultAddress,
  });

const tx = new Transaction().add(...preInstructions, instruction, ...postInstructions);
await sendAndConfirmTransaction(connection, tx, [wallet]);