@liquid-af/sdk
v0.7.2
Published
TypeScript SDK for the Liquid DeFi protocol on Solana
Downloads
2,388
Readme
@liquid-af/sdk
TypeScript SDK for the Liquid DeFi protocol on Solana — bonding curve token launches and AMM trading.
Protocol Overview
Liquid is a five-program system on Solana:
┌──────────────────────┐ ┌───────────────────────┐
│ liquid │ │ liquid-swap │
│ Bonding curve: │ │ CPMM AMM: │
│ create, buy, sell, │ │ pools, swaps, │
│ migrate │ │ deposits, withdraws │
└────┬─────┬───────────┘ └────┬─────┬────────────┘
│ │ │ │
│ │ ┌───────────────┐ │ │
│ ├─►│ liquid-fees │◄──┤ │
│ │ │ Fee config │ │ │
│ │ └───────┬───────┘ │ │
│ │ │ │ │
│ │ ┌───────────────┐ │ │
│ └─►│ liquid-state │◄──┘ │
│ │ User state │ │
│ └───────┬───────┘ │
│ │ │
│ ┌──────────▼──────────┐ │
└────►│ liquid-events │◄─────┘
│ CPI event emission │
└─────────────────────┘Tokens launch on a bonding curve. Once the curve fills, liquidity migrates to an AMM pool for open trading.
Installation
npm install @liquid-af/sdkPeer dependencies:
npm install @coral-xyz/anchor @solana/web3.js @solana/spl-token bn.jsQuick Start
import { Connection, Keypair, PublicKey } from "@solana/web3.js";
import BN from "bn.js";
import { LiquidClient } from "@liquid-af/sdk";
const connection = new Connection("https://api.mainnet-beta.solana.com");
const client = new LiquidClient({ connection });
// Preview a buy on a bonding curve (SOL)
const mint = new PublicKey("Token111...");
const preview = await client.previewBuyOnCurve(
mint,
new BN(100_000_000), // 0.1 SOL
{ solPriceUsd: new BN(150_000_000) } // SOL = $150
);
console.log("Tokens out:", preview.tokensOut.toString());
console.log("Price impact:", preview.priceImpactBps, "bps");
console.log("Total fees:", preview.fees.totalFees.toString());
// Build the buy instruction
const pythPriceFeed = new PublicKey("7UVimffxr9ow1uXYxsr4LHAcV58mLzhmwaeKvJ1pjLiE"); // SOL/USD
const ix = await client.buildBuyNativeAutoResolve({
user: wallet.publicKey,
mint,
pythPriceFeed,
amountIn: new BN(100_000_000),
minAmountOut: preview.tokensOut.muln(95).divn(100), // 5% slippage
feeRecipient: protocolFeeRecipient,
});
// Build a transaction with priority fee
const tx = await client.buildTransaction([ix], {
feePayer: wallet.publicKey,
computeUnits: 300_000,
priorityFee: 50_000, // micro-lamports per CU
});
// Sign and send (wallet-dependent)
tx.sign(wallet);
const sig = await connection.sendRawTransaction(tx.serialize());Configuration
Pre-built Configs
import { LiquidClient, MAINNET_CONFIG, DEVNET_CONFIG, LOCALNET_CONFIG } from "@liquid-af/sdk";
const client = new LiquidClient({ connection }); // defaults to mainnet
const testClient = new LiquidClient({ connection, config: DEVNET_CONFIG });Constants
| Constant | Value | Description |
|----------|-------|-------------|
| BPS_DENOMINATOR | 10,000 | 100% in basis points |
| WSOL_MINT | So11111111...112 | Wrapped SOL mint |
| MIN_TRANSACTION_AMOUNT | 100,000 | Minimum trade in lamports |
| MAX_FEE_RECIPIENTS_FEES | 10 | Max per-token fee recipients |
| LIMITS.NAME | 1–32 chars | Token name length |
| LIMITS.SYMBOL | 1–16 chars | Token symbol length |
| LIMITS.URI | 10–100 chars | Token URI length |
Bonding Curve (SOL)
Create a Token
const mint = Keypair.generate();
const ix = await client.buildCreateNativeCurve({
creator: wallet.publicKey,
mint: mint.publicKey,
pythPriceFeed,
name: "My Token",
symbol: "MTK",
uri: "https://example.com/metadata.json",
});Buy Tokens
// Standard — you provide the creator address
const ix = await client.buildBuyNative({
user: wallet.publicKey,
mint,
creator: creatorPubkey,
pythPriceFeed,
amountIn: new BN(500_000_000),
minAmountOut: new BN(1_000_000),
feeRecipient: protocolFeeRecipient,
});
// Auto-resolve — fetches creator from on-chain state
const ix = await client.buildBuyNativeAutoResolve({
user: wallet.publicKey,
mint,
pythPriceFeed,
amountIn: new BN(500_000_000),
minAmountOut: new BN(1_000_000),
feeRecipient: protocolFeeRecipient,
});With referral vaults:
const ix = await client.buildBuyNativeAutoResolve({
user: wallet.publicKey,
mint,
pythPriceFeed,
amountIn: new BN(500_000_000),
minAmountOut: new BN(1_000_000),
feeRecipient: protocolFeeRecipient,
creatorReferralVault: creatorRefVault, // creator's referrer earns rewards
traderReferralVault: traderRefVault, // buyer's referrer earns rewards
});Sell Tokens
const ix = await client.buildSellNativeAutoResolve({
user: wallet.publicKey,
mint,
pythPriceFeed,
amountIn: new BN(5_000_000), // tokens to sell
minAmountOut: new BN(100_000_000), // minimum SOL back
feeRecipient: protocolFeeRecipient,
});Bonding Curve (Stable / Token)
Stable curves use a Quote Token (e.g., USDC) instead of SOL and do not use an oracle.
Create a Token
const ix = await client.buildCreateStableCurve({
creator: wallet.publicKey,
mint: mint.publicKey,
quoteMint: usdcMint,
name: "Stable Token",
symbol: "STBL",
uri: "https://example.com/stable.json",
});Buy Tokens
const ix = await client.buildBuyStableAutoResolve({
user: wallet.publicKey,
mint,
quoteMint: usdcMint,
amountIn: new BN(100_000_000), // 100 USDC
minAmountOut: new BN(1_000),
feeRecipient: protocolFeeRecipient,
});Sell Tokens
const ix = await client.buildSellStableAutoResolve({
user: wallet.publicKey,
mint,
quoteMint: usdcMint,
amountIn: new BN(500_000),
minAmountOut: new BN(10_000_000), // USDC back
feeRecipient: protocolFeeRecipient,
});Migrate to AMM
When a bonding curve completes (all real tokens sold), anyone can trigger migration:
const ix = await client.buildMigrateNative({
migrator: wallet.publicKey,
mint,
});Withdraw Referral Rewards
const ix = await client.buildWithdrawReferralRewards({ user: wallet.publicKey });Buyback (Permissionless)
When a token's fee config is revoked, accumulated fees are used for buyback-and-burn:
const ix = await client.buildExecuteBuybackNative({
payer: wallet.publicKey,
mint,
pythPriceFeed,
});AMM (Liquidity Pools)
All AMM methods auto-resolve token programs (SPL Token vs Token-2022) and default quoteMint to WSOL.
Swap — Sell (Fixed Input)
Sell a fixed amount of base tokens for quote tokens:
const ix = await client.buildSwapSell({
payer: wallet.publicKey,
creator: creatorPubkey,
baseMint: tokenMint,
amountIn: new BN(10_000_000), // base tokens to sell
minimumAmountOut: new BN(50_000_000), // min SOL received
feeRecipient: protocolFeeRecipient,
});Swap — Buy (Fixed Output)
Buy a fixed amount of base tokens, paying up to a maximum in quote tokens:
const ix = await client.buildSwapBuy({
payer: wallet.publicKey,
creator: creatorPubkey,
baseMint: tokenMint,
maxAmountIn: new BN(500_000_000), // max SOL to spend
amountOut: new BN(10_000_000), // exact base tokens to receive
feeRecipient: protocolFeeRecipient,
});Deposit Liquidity
const ix = await client.buildDeposit({
owner: wallet.publicKey,
baseMint: tokenMint,
lpTokenAmount: new BN(1_000_000),
maximumBaseAmount: new BN(10_000_000),
maximumQuoteAmount: new BN(500_000_000),
});Withdraw Liquidity
const ix = await client.buildWithdraw({
owner: wallet.publicKey,
baseMint: tokenMint,
lpTokenAmount: new BN(1_000_000),
minimumBaseAmount: new BN(9_000_000),
minimumQuoteAmount: new BN(450_000_000),
});Create Pool
const ix = await client.buildCreatePool({
signer: wallet.publicKey,
baseMint: tokenMint,
initAmountBase: new BN(100_000_000),
initAmountQuote: new BN(5_000_000_000),
creator: creatorPubkey,
});AMM Buyback
const ix = await client.buildSwapExecuteBuyback({
payer: wallet.publicKey,
baseMint: tokenMint,
});Trade Previews
Async Previews (Auto-Fetch)
These fetch on-chain state automatically:
// Bonding curve (SOL) — buy preview
const buyPreview = await client.previewBuyOnCurve(
mint,
new BN(100_000_000),
{ solPriceUsd: new BN(150_000_000) } // Required for SOL curves
);
console.log(buyPreview.tokensOut.toString()); // tokens you'd receive
console.log(buyPreview.willComplete); // would this buy complete the curve?
// Bonding curve (stable) — sell preview
const sellPreview = await client.previewSellOnCurve(
mint,
new BN(5_000_000),
{ quoteMint: usdcMint } // Required for stable curves
);
console.log(sellPreview.quoteOutNet.toString()); // tokens after fees
Pure Math Previews (No network calls)
Use these when you already have the on-chain state (avoids redundant RPC calls):
import { calculateBuyCurvePreview, calculateSwapSellPreview } from "@liquid-af/sdk";
// Bonding curve — you supply the state
const preview = calculateBuyCurvePreview(new BN(100_000_000), {
globalConfig: {
protocolFeeBasisPoints: 100,
creatorFeeBasisPoints: 50,
creatorReferralRewardBasisPoints: 500,
traderReferralRewardBasisPoints: 500,
},
bondingCurve: {
virtualQuoteReserves: new BN(30_000_000_000), // SOL or quote token
virtualTokenReserves: new BN(1_000_000_000_000),
realTokenReserves: new BN(800_000_000_000),
},
});
// AMM — you supply vault balances
const ammPreview = calculateSwapSellPreview(new BN(10_000_000), {
ammConfig: { lpFeeRate: 20, creatorFeeRate: 95, protocolFeeRate: 5 },
baseVaultBalance: new BN(500_000_000),
quoteVaultBalance: new BN(2_000_000_000),
});Prefetching Pattern
Batch your RPC calls and pass prefetched state to avoid extra requests:
// Fetch once, preview multiple amounts
const [globalConfig, bondingCurve] = await Promise.all([
client.fetchLiquidGlobalConfig(),
client.fetchNativeBondingCurve(mint),
]);
// Must pass solPriceUsd for native curves if not pre-provided in globalConfig
const previewOptions = {
prefetched: { globalConfig, bondingCurve },
solPriceUsd: new BN(150_000_000)
};
const preview1 = await client.previewBuyOnCurve(mint, new BN(100_000_000), previewOptions);
const preview2 = await client.previewBuyOnCurve(mint, new BN(500_000_000), previewOptions);Fee Configuration
Tokens can have one of three fee modes:
| Mode | Behavior |
|------|----------|
| Recipients | Fees split among up to 10 recipients by BPS allocation |
| Revoked | Fee config is permanently locked; fees route to buyback |
Update
const ix = await client.buildUpdateFeeConfig({
authority: wallet.publicKey,
tokenMint: mint,
recipients: [{ pubkey: newRecipient, basisPoints: 10_000 }],
newUpdateAuthority: null, // keep existing
});Revoke (Permanent)
const ix = await client.buildRevokeFeeConfig({
authority: wallet.publicKey,
tokenMint: mint,
quoteMint: WSOL_MINT,
});Distribute Fees (Permissionless)
const ix = await client.buildDistributeFees({
payer: wallet.publicKey,
tokenMint: mint,
recipientVaults: [vault1, vault2],
});Fee Helpers
import {
createRecipients,
createEqualRecipients,
createSingleRecipient,
validateRecipientsSum,
calculateDistribution,
} from "@liquid-af/sdk";
// Custom split
const recipients = createRecipients([pk1, pk2, pk3], [5000, 3000, 2000]);
// Equal split across 4 recipients
const equal = createEqualRecipients(4, [pk1, pk2, pk3, pk4]);
// Single recipient (100%)
const solo = createSingleRecipient(pk1);
// Validate sum equals 10,000 BPS
validateRecipientsSum(recipients); // true
// Calculate expected distribution from a vault balance
const amounts = calculateDistribution(10_000_000, recipients);
// [{ pubkey: pk1, amount: 4554560 }, { pubkey: pk2, amount: 2733336 }, ...]User State & Referrals
Initialize User
const ix = await client.buildInitializeUser({ user: wallet.publicKey });Set Referrer (One-Time)
const ix = await client.buildSetReferrer({
user: wallet.publicKey,
referrer: referrerPubkey,
});Activate Cashback Spending
const ix = await client.buildSetCashbackMode({ user: wallet.publicKey });Fetch User Data
const props = await client.fetchUserProperties(wallet.publicKey);
console.log("Total SOL volume:", props.totalSolVolume.toString());
console.log("Cashback credits:", props.cashbackCredits.toString());
console.log("Referrer:", props.referrer?.toString() ?? "none");
console.log("Spending active:", props.isSpending);
const volume = await client.fetchTokenVolume(mint);
console.log("Token SOL volume:", volume.totalSolVolume.toString());Account Fetching
All fetchers return deserialized, typed account data.
| Method | Returns | Description |
|--------|---------|-------------|
| fetchLiquidGlobalConfig() | GlobalConfiguration | Bonding curve protocol config |
| fetchNativeBondingCurve(mint) | BondingCurveState | Curve state for a token |
| fetchNativeBondingCurveByAddress(addr) | BondingCurveState | Curve state by PDA address |
| fetchAmmConfig() | AmmConfig | AMM protocol config |
| fetchPoolState(baseMint, quoteMint?) | PoolState | Pool state by mints |
| fetchPoolStateByAddress(addr) | PoolState | Pool state by PDA address |
| fetchObservationState(poolAddr) | ObservationState | Oracle observation data |
| fetchFeeConfig(tokenMint) | UnifiedFeeConfiguration | Fee config for a token |
| fetchFeeConfigByAddress(addr) | UnifiedFeeConfiguration | Fee config by PDA address |
| fetchUserProperties(user) | UserProperties | User volumes and referral data |
| fetchTokenVolume(mint) | TokenVolumeAccumulator | Per-token volume stats |
| fetchGlobalCurveVolume() | GlobalCurveVolume | Total bonding curve volumes |
| fetchGlobalAmmVolume() | GlobalAmmVolume | Total AMM volumes |
| fetchCashbackConfig() | CashbackConfiguration | Cashback tier config |
const curve = await client.fetchNativeBondingCurve(mint);
console.log("Creator:", curve.creator.toString());
console.log("Real SOL reserves:", curve.realSolReserves.toString());
console.log("Complete:", curve.complete);
console.log("Migrated:", curve.migrated);PDA Derivation
Individual PDAs
Each returns [PublicKey, number] (address + bump):
const [bondingCurve, bump] = client.getBondingCurvePDA(mint);
const [solVault] = client.getBondingCurveSolVaultPDA(bondingCurve);
const [referralVault] = client.getReferralVaultPDA(referrer);
const [buybackVault] = client.getBuybackVaultPDA(bondingCurve);
const [pool] = client.getPoolPDA(baseMint, quoteMint);
const [lpMint] = client.getPoolLpMintPDA(pool);
const [vault] = client.getPoolVaultPDA(pool, mint);
const [observation] = client.getObservationPDA(pool);
const [feeConfig] = client.getFeeConfigPDA(tokenMint);
const [feeVault] = client.getFeeVaultPDA(feeConfig);
const [userProps] = client.getUserPropertiesPDA(user);
const [tokenVolume] = client.getTokenVolumePDA(mint);Batch PDAs
// All PDAs for a bonding curve token
const curvePdas = client.getAllBondingCurvePDAs(mint, creator);
// { bondingCurve, bondingCurveSolVault, referralVault,
// buybackVault, feeConfig, feeVault, userProperties, tokenVolume }
// All PDAs for an AMM pool
const poolPdas = client.getAllPoolPDAs(baseMint);
// { poolState, lpMint, baseVault, quoteVault, observation,
// ammConfig, ammAuthority, feeConfig, tokenVolume }
// All PDAs needed for native migration
const migrationPdas = client.getNativeMigrationPDAs(tokenMint);
// { bondingCurve, ammPoolState, ammLpMint, ammBaseVault,
// ammQuoteVault, ammObservation, ammConfig, ammAuthority }
// All PDAs needed for stable migration
const stableMigrationPdas = client.getStableMigrationPDAs(tokenMint, quoteMint);
// { bondingCurve, ammPoolState, ammLpMint, ammBaseVault,
// ammQuoteVault, ammObservation, ammConfig, ammAuthority }Math Utilities
Pure functions with no side effects or network calls.
Bonding Curve Math
import { calculateBuyExpectation, calculateSellExpectation } from "@liquid-af/sdk";
const buyResult = calculateBuyExpectation(
new BN(100_000_000), // SOL in
{ virtualQuoteReserves, virtualTokenReserves, realTokenReserves },
{ protocolFeeBps: 100, creatorFeeBps: 50, creatorReferralBps: 500, traderReferralBps: 500 },
false, // hasCreatorRef
false, // hasTraderRef
);
// { tokensOut, protocolFee, creatorFee, ..., newVirtualQuote, newVirtualToken }AMM Math
import { calculateAmmSellOutput, calculateAmmBuyInput, calculateLpToTokens } from "@liquid-af/sdk";
const sell = calculateAmmSellOutput(
new BN(10_000_000), // base tokens in
baseVaultBalance,
quoteVaultBalance,
{ lpFeeRate: 20, creatorFeeRate: 95, protocolFeeRate: 5 },
);
// { quoteOut, quoteOutNet, lpFee, creatorFee, protocolFee, totalFees }
const buy = calculateAmmBuyInput(
new BN(10_000_000), // base tokens desired
baseVaultBalance,
quoteVaultBalance,
{ lpFeeRate: 20, creatorFeeRate: 10, protocolFeeRate: 15 },
);
// { quoteIn, quoteInGross, lpFee, creatorFee, protocolFee, totalFees }
const { baseAmount, quoteAmount } = calculateLpToTokens(
lpTokens, totalLpSupply, baseVaultBalance, quoteVaultBalance,
);Fee Math
import { calculateFees, calcBps } from "@liquid-af/sdk";
const fees = calculateFees(
new BN(1_000_000_000),
{ protocolFeeBps: 100, creatorFeeBps: 50, creatorReferralBps: 500, traderReferralBps: 500 },
true, // hasCreatorRef
false, // hasTraderRef
);
// { protocolFee, creatorFee, creatorReferralFee, traderReferralFee, totalFees }
const amount = calcBps(new BN(1_000_000), 250); // 2.5% of 1MEvents
Parse Transaction Logs
import { parseTransactionEvents, getLiquidEventsProgram } from "@liquid-af/sdk";
const program = getLiquidEventsProgram(connection);
const txDetails = await connection.getTransaction(signature, { commitment: "confirmed" });
const events = parseTransactionEvents(txDetails.meta.logMessages, program);
for (const event of events) {
if (event.name === "tradeEvent") {
const data = event.data as TradeEvent;
console.log("Trade on", data.mint.toString());
}
}Listen for Events
import { addEventListener, getLiquidEventsProgram } from "@liquid-af/sdk";
const program = getLiquidEventsProgram(connection);
const listenerId = addEventListener<SwapEvent>(program, "swapEvent", (event) => {
console.log("Swap:", event.inputAmount.toString(), "→", event.outputAmount.toString());
});
// Later: cleanup
await program.removeEventListener(listenerId);Wait for a Specific Event
import { waitForEvent } from "@liquid-af/sdk";
const { result: signature, event } = await waitForEvent<TradeEvent>(
program,
"tradeEvent",
() => sendAndConfirm(connection, () => program.methods.buyNative(...).rpc()),
5000, // timeout ms
);Event Types
| Event | Origin | When |
|-------|--------|------|
| TokenCreatedEvent | liquid → liquid-events | Token + bonding curve created |
| TradeEvent | liquid → liquid-events | Buy or sell on bonding curve |
| MigrationCompletedEvent | liquid → liquid-events | Curve migrated to AMM |
| SwapEvent | liquid-swap → liquid-events | AMM swap executed |
| LpChangeEvent | liquid-swap → liquid-events | Deposit or withdrawal |
All events are emitted through liquid-events via CPI. Use getLiquidEventsProgram(connection) for parsing.
Transaction Building
Build Unsigned Transaction
const ix1 = await client.buildBuyNativeAutoResolve({ ... });
const ix2 = await client.buildSetCashbackMode({ user: wallet.publicKey });
const tx = await client.buildTransaction([ix1, ix2], {
feePayer: wallet.publicKey,
computeUnits: 400_000,
priorityFee: 100_000, // micro-lamports per CU
});
// tx is unsigned — sign with your wallet before sendingCompute Budget Helper
import { withComputeBudget } from "@liquid-af/sdk";
const instructions = [ix1, ix2];
const withBudget = withComputeBudget(instructions, {
computeUnits: 400_000,
priorityFee: 100_000,
});
// Returns [SetComputeUnitLimit, SetComputeUnitPrice, ix1, ix2]Send & Confirm
import { sendAndConfirm, confirmTx } from "@liquid-af/sdk";
// Handles timeout recovery automatically
const sig = await sendAndConfirm(connection, () => program.methods.buyNative(...).rpc());
// Or confirm a known signature
await confirmTx(connection, signature, blockhash, lastValidBlockHeight);Resolve Token Program
// Detects whether a mint uses SPL Token or Token-2022
const tokenProgram = await client.resolveTokenProgram(mint);Error Handling
import { LiquidError, LiquidErrorCode } from "@liquid-af/sdk";
try {
const curve = await client.fetchNativeBondingCurve(mint);
} catch (err) {
const liquidErr = LiquidError.fromAnchorError(err);
switch (liquidErr.code) {
case LiquidErrorCode.AccountNotFound:
console.log("Bonding curve doesn't exist for this mint");
break;
case LiquidErrorCode.TransactionTimeout:
console.log("Transaction timed out — may still land");
break;
case LiquidErrorCode.SimulationFailed:
console.log("Simulation failed:", liquidErr.message);
break;
default:
throw liquidErr;
}
}Error codes: WalletNotConnected, InvalidConfig, AccountNotFound, AccountDeserializationFailed, TransactionBuildFailed, TransactionTimeout, SimulationFailed.
Subpath Imports
For tree-shaking or minimal bundles, import only what you need:
import { LiquidClient } from "@liquid-af/sdk/client";
import { getBondingCurvePDA, getPoolPDA } from "@liquid-af/sdk/pda";
import { calculateBuyExpectation } from "@liquid-af/sdk/math";
import { fetchNativeBondingCurve } from "@liquid-af/sdk/accounts";
import { buildBuyNative } from "@liquid-af/sdk/instructions";
import { previewBuyOnCurve } from "@liquid-af/sdk/helpers";
import { parseTransactionEvents } from "@liquid-af/sdk/events";
import { buildTransaction } from "@liquid-af/sdk/transaction";
import { createReadonlyProvider } from "@liquid-af/sdk/provider";
import { LiquidError } from "@liquid-af/sdk/errors";| Subpath | Contents |
|---------|----------|
| @liquid-af/sdk | Everything (default) |
| @liquid-af/sdk/client | LiquidClient class |
| @liquid-af/sdk/pda | PDA derivation functions |
| @liquid-af/sdk/math | Pure calculation functions |
| @liquid-af/sdk/accounts | Account fetchers |
| @liquid-af/sdk/instructions | Instruction builders |
| @liquid-af/sdk/helpers | Preview functions and user helpers |
| @liquid-af/sdk/events | Event parsing and listeners |
| @liquid-af/sdk/transaction | Transaction building and sending |
| @liquid-af/sdk/provider | Anchor provider utilities |
| @liquid-af/sdk/errors | Error types |
Standalone Functions
Every method on LiquidClient delegates to a standalone function exported from its respective subpath. The client adds convenience (stores connection and config), but you can use the functions directly:
import { buildBuyNative } from "@liquid-af/sdk/instructions";
import { fetchNativeBondingCurve } from "@liquid-af/sdk/accounts";
import { getBondingCurvePDA } from "@liquid-af/sdk/pda";
import { MAINNET_CONFIG } from "@liquid-af/sdk";
// Standalone usage — pass config and connection explicitly
const curve = await fetchNativeBondingCurve(connection, mint, MAINNET_CONFIG);
const [pda] = getBondingCurvePDA(mint, MAINNET_CONFIG.liquidProgramId);
const ix = await buildBuyNative({ ..., config: MAINNET_CONFIG });IDL & Program Instances
For advanced use cases that need direct Anchor program access:
import {
getLiquidProgram,
getLiquidSwapProgram,
getLiquidFeesProgram,
getLiquidStateProgram,
getLiquidEventsProgram,
liquidIdl,
liquidEventsIdl,
} from "@liquid-af/sdk";
const program = getLiquidProgram(connection); // Program<Liquid>
const swapProgram = getLiquidSwapProgram(connection); // Program<LiquidSwap>
const eventsProgram = getLiquidEventsProgram(connection); // Program<LiquidEvents>