Skip to main content

Documentation Index

Fetch the complete documentation index at: https://v2-docs.exponent.finance/llms.txt

Use this file to discover all available pages before exploring further.

This page walks through the full orderbook trading lifecycle — loading state, getting quotes, posting and filling orders, collecting interest, and withdrawing funds.

Installation

yarn add @exponent-labs/exponent-sdk

Setup

import { Orderbook, LOCAL_ENV } from "@exponent-labs/exponent-sdk";
import {
  Connection,
  PublicKey,
  Transaction,
  sendAndConfirmTransaction,
  Keypair,
} from "@solana/web3.js";
const connection = new Connection("https://api.mainnet-beta.solana.com");
const wallet = Keypair.fromSecretKey(/* your keypair */);
const orderbookAddress = new PublicKey("...");
const syMintAddress = new PublicKey("...");

const orderbook = await Orderbook.load(LOCAL_ENV, connection, orderbookAddress);
1

Get a Quote

getQuote simulates a trade and returns the expected output before you send a transaction.
import { QuoteDirection } from "@exponent-labs/exponent-sdk";

const clock = await connection.getClock();
const unixNow = Number(clock.unixTimestamp);

const quote = orderbook.getQuote({
  inAmount: 1_000_000_000,
  direction: QuoteDirection.SY_TO_YT,
  unixNow,
  syExchangeRate: 1.000009210084,
});

console.log("Expected output:", quote.outAmount);
console.log("Maker fees:", quote.makerFees);
console.log("Taker fees:", quote.takerFees);
Always use connection.getClock() for the unixNow parameter — Date.now() may drift from the onchain clock and produce inaccurate quotes.
2

Post a Limit Order

ixWrapperPostOffer places a limit order on the orderbook. The wrapper handles token account creation for you.
import { OfferType, offerOptions } from "@exponent-labs/exponent-sdk";

const { ix, setupIxs } = await orderbook.ixWrapperPostOffer({
  trader: wallet.publicKey,
  price: 5.0,
  amount: 1_000_000_000n,
  offerType: OfferType.SellYt,
  offerOption: offerOptions("FillOrKill", [false]),
  virtualOffer: false,
  expirySeconds: 3600,
  mintSy: syMintAddress,
});

const tx = new Transaction().add(...setupIxs, ix);
await sendAndConfirmTransaction(connection, tx, [wallet]);
The setupIxs array creates PT, YT, and SY token accounts if they do not exist. Always include them before ix in your transaction.
3

Execute a Market Order

ixWrapperMarketOffer fills against existing orders immediately.
import { OfferType } from "@exponent-labs/exponent-sdk";

const { ix, setupIxs } = await orderbook.ixWrapperMarketOffer({
  trader: wallet.publicKey,
  maxPriceApy: 5.5,
  amount: 1_000_000_000n,
  offerType: OfferType.BuyYt,
  minAmountOut: 990_000_000n,
  virtualOffer: false,
  mintSy: syMintAddress,
});

const tx = new Transaction().add(...setupIxs, ix);
await sendAndConfirmTransaction(connection, tx, [wallet]);
Set minAmountOut for slippage protection. The transaction reverts if the output falls below this threshold.
4

Check Open Orders

Query your active orders to see what is currently on the book.
const openOrders = orderbook.getUserOpenOrders(wallet.publicKey);

for (const order of openOrders) {
  console.log("Index:", order.offerIndex);
  console.log("Type:", order.type);
  console.log("Price APY:", order.priceApy);
  console.log("Amount:", order.amount);
}
5

Remove an Order

Cancel an open order using its offerIdx from getUserOpenOrders.
const ix = await orderbook.ixWrapperRemoveOffer({
  trader: wallet.publicKey,
  offerIdx: openOrders[0].offerIndex,
  mintSy: syMintAddress,
});

const tx = new Transaction().add(ix);
await sendAndConfirmTransaction(connection, tx, [wallet]);
Use getUserOpenOrders to find the offerIdx of the order you want to remove. Removing an order returns PT/YT back to your escrow balance.
6

Collect Interest

Collect yield that has accrued on YT held in your open or filled orders.
const ix = await orderbook.ixWrapperCollectInterest({
  trader: wallet.publicKey,
  mintSy: syMintAddress,
});

const tx = new Transaction().add(ix);
await sendAndConfirmTransaction(connection, tx, [wallet]);
Interest accrues on YT held in open sell orders and from filled buy orders. You can collect it at any time without affecting your active orders.
7

Withdraw Funds

Withdraw PT, YT, and SY from your orderbook escrow back to your wallet.
import { amount } from "@exponent-labs/exponent-sdk";

const ix = await orderbook.ixWrapperWithdrawFunds({
  trader: wallet.publicKey,
  mintSy: syMintAddress,
  ptAmount: amount("All"),
  ytAmount: amount("All"),
  syAmount: amount("All"),
});

const tx = new Transaction().add(ix);
await sendAndConfirmTransaction(connection, tx, [wallet]);
Use amount("All") to withdraw all available funds, or amount("Some", [500_000_000n]) for a specific amount. The amount helper is imported from @exponent-labs/exponent-sdk.

Reading State

Read orderbook and user state without transactions:
import { QuoteDirection } from "@exponent-labs/exponent-sdk";

// Check your escrow balances
const balances = orderbook.getUserBalances(wallet.publicKey);
console.log("PT:", balances.pt);
console.log("YT:", balances.yt);
console.log("SY:", balances.sy);
console.log("Staked YT:", balances.stakedYt);
console.log("Staged interest:", balances.staged);

// Get a quote for a potential trade
const clock = await connection.getClock();
const quote = orderbook.getQuote({
  inAmount: 1_000_000_000,
  direction: QuoteDirection.SY_TO_YT,
  unixNow: Number(clock.unixTimestamp),
  syExchangeRate: 1.0001,
});

// View open orders
const orders = orderbook.getUserOpenOrders(wallet.publicKey);

Next Steps

Core Concepts

Understand escrows, fee decay, interest accrual, expiry behavior, and the account model behind the orderbook.

Virtual Offers

Learn how PT trades route through shared YT liquidity using strip and merge flows under the hood.

TypeScript Instructions

Explore the full set of instruction builders for posting offers, taking liquidity, removing orders, collecting interest, and withdrawing funds.

Read Functions

Query quotes, balances, open orders, and other orderbook state without sending transactions.