Integration Overview
The Multiliquid Protocol on Solana can be integrated via the official TypeScript SDK, which provides a complete interface for quoting, building, and executing swaps against the on-chain program, along with liquidity-provider administration flows.SDK Installation
Install and configure the TypeScript SDK
Pair Discovery
Find available trading pairs
Quoting
Get swap quotes using client-side math or simulation
Executing Swaps
Build and submit swap transactions
LP Admin
Create, update, and close pairs and manage liquidity
Ladder Pricing Model
Implement a rolling 24-hour laddered pricing model as an LP
Installation
0.3.2. The package declares runtime dependencies on:
@solana/web3.js ^1.98.4@coral-xyz/anchor ^0.32.1@solana/spl-token ^0.4.14
@solana/web3.js and @coral-xyz/anchor directly in your application when importing them in integration code:
Client Initialization
The SDK provides aMultiliquidClient class that wraps all functionality:
cluster parameter determines which built-in pair registry is used. Both devnet and mainnet use the same program ID: HaWDr94LKJQT2fXuHJGsSGeQf6M7S68FXpEQLcE5RYs6.
Pair Discovery
Built-In Registry (No RPC)
The SDK ships with a hardcoded registry of known pairs for instant lookup:On-Chain Discovery (RPC)
For dynamically discovering pairs not in the registry:Checking Pair Status
Before executing a swap, verify the pair is active:Quoting
The SDK offers two quoting methods: client-side math replication and on-chain simulation.Client-Side Quote
Replicates the on-chain Rust math exactly using BigInt. Fetches current NAV prices from oracles and computes the swap result:SwapQuote includes:
Simulation Quote
Runs the swap instruction against the validator viasimulateTransaction and parses the emitted event:
computeUnitsConsumed, which is useful for setting compute budget instructions.
Executing Swaps
The SDK is instruction-first: the primary API returnsTransactionInstruction objects for maximum composability. A convenience method for building full transactions is also available.
Building a Swap Transaction
Building Individual Instructions
For more control, build the swap instruction separately and compose it with other instructions (e.g., compute budget):The SDK does not include
ComputeBudgetProgram instructions automatically. Set compute unit limits and priority fees based on your requirements. Use getQuoteViaSimulation() to measure actual compute units consumed.Swap Examples
Buy RWA with USDC (ExactIn) Swap exactly 1000 USDC for USTB, accepting at minimum 990 USTB:Swap Parameters Reference
LP Admin and Liquidity
Liquidity providers create, configure, and close their own pairs, and manage vault balances, using the same instruction-first API. The SDK derives PDAs, vault authorities, token program IDs, and Token-2022 transfer-hook accounts automatically. The LP signs every builder below; the global-configadmin is referenced as a non-signing account (the SDK fetches it from GlobalConfig when not supplied via admin).
Permissioned Token Whitelisting
For every permissioned mint used by an LP, the token issuer must separately whitelist (allowlist) both of these addresses:- LP admin address — the
liquidityProviderwallet that owns and authorizes the LP’s source and recipient token accounts. - Vault authority PDA — the LP-specific PDA derived from
["vault_authority", liquidityProvider]that owns the program’s vault ATAs.
init_pair can create the vault ATA, but the Multiliquid program and SDK cannot grant issuer approval or bypass a frozen-account restriction. add_liquidity, remove_liquidity, and swaps involving that vault will fail until the required accounts are authorized and thawed.
Derive the address that must be submitted to the issuer before funding the pair:
Create a Pair
init_pair is LP-signed: the liquidity provider pays for the Pair PDA, LP-stable config, vault ATAs, and UserVaultInfo accounts. The builder pre-validates that the stable mint’s asset config has type Stable and the asset mint’s asset config has type Rwa.
Update Pair Configuration
Add and Remove Liquidity
lpTokenAccount when the liquidity provider uses a non-ATA token account. Set autoCreateAta: false if token accounts are managed externally, and use remainingAccounts only for extra accounts beyond those derived by the SDK.
Close a Pair
close_pair is LP-signed and reclaims rent for the Pair PDA, and — when the pair was the last consumer of a shared vault — the vault ATA and UserVaultInfo PDA. Any remaining vault balances are returned to the LP’s recipient token accounts. The SDK reads UserVaultInfo.used for both vaults and only resolves Token-2022 transfer-hook accounts when the shared-vault counter shows the close will transfer.
Event Parsing
ParseSwapExecuted events from transaction logs:
Error Handling
The SDK provides structured error parsing for on-chain program errors:Amount Formatting
Convert between native token amounts (with decimals) and human-readable strings:Reading On-Chain State
Fetch All Swap State (Single RPC Call)
Fetch Individual Accounts
PDA Derivation
All program accounts are deterministic PDAs. The SDK provides derivation helpers:(mint, vaultAuthority), where vaultAuthority is the LP-specific PDA derived from ["vault_authority", lp]. Fee vault token accounts are ATAs for (stableMint, programAuthority), where programAuthority is the global PDA derived from ["program_authority"].
When deriving vault or fee-vault addresses manually for Token-2022 mints, pass the Token-2022 program ID as the optional tokenProgram argument. Swap and liquidity builders detect the mint owner and derive the correct ATAs automatically.
Integration Best Practices
Security
- Use Hardware Wallets: Never store private keys in code or environment variables for production
- Simulate First: Always call
getQuote()orgetQuoteViaSimulation()before executing - Set Slippage: Always provide
minAmountOutormaxAmountInfor production swaps - Check Pause State: Call
checkPauseStatus()before building transactions
Performance
- Use Client-Side Quotes:
getQuote()is faster thangetQuoteViaSimulation()for most use cases - Set Compute Budget: Use
computeUnitsConsumedfrom simulation to set appropriate compute limits - Reuse Client: Create one
MultiliquidClientinstance and reuse across operations - Use Built-In Registry:
getPairs()returns instantly without RPC calls
Operational
- Priority Fees: Set appropriate priority fees via
ComputeBudgetProgram.setComputeUnitPrice()for time-sensitive operations - Confirmation: Wait for
confirmedorfinalizedcommitment before treating a swap as complete - Event Monitoring: Use
parseSwapEventsFromTransaction()to verify swap results after execution - Error Recovery: Use
parseSwapError()to categorize failures and implement appropriate retry logic
Testing
Devnet
Configure the client for devnet testing:Mainnet
Support and Resources
- Protocol Website: https://www.multiliquid.xyz/
- Program IDL: See Program IDL page
- Deployment Addresses: See Deployments page