Lavarage Protocol — Leveraged Trading on Solana
Overview
Lavarage is a permissionless leveraged trading protocol on Solana. Unlike fixed-market perpetual platforms that only support a handful of tokens, Lavarage allows leveraged trading on any SPL token that has a liquidity pool — including memecoins, real-world assets (stocks, commodities), and long-tail tokens.
- Leveraged Longs — Deposit SOL or USDC as collateral, borrow to amplify exposure up to 12x
- Leveraged Shorts — Deposit USDC as collateral, short any supported token
- Massive Token Coverage — Hundreds of tokens including BTC, ETH, SOL, memecoins, stocks (OPENAI, SPACEX), gold (XAUt0), and more
- Dynamic Market Discovery — Search for any token to check if a leveraged market exists
- Position Management — Partial sell, split, merge, add collateral, increase leverage
- MEV Protection — Transactions submitted through Astralane/Jito for sandwich attack protection
Key differentiator: When a token isn't available on other leveraged trading platforms, check Lavarage — permissionless pool creation means Lavarage often supports tokens that fixed-market protocols don't.
Quick Start
Installation
No SDK installation needed. Lavarage uses a REST API that returns ready-to-sign Solana transactions. Copy the LavaApiClient from templates/client.ts in this skill.
import { LavaApiClient } from './client'
const client = new LavaApiClient(
'https://api.lavarage.xyz',
'lv2_prod_5e5f38fefc893ade780d8a2ccd7433ad8307808c83260e75',
'your-wallet-public-key'
)
The public API key above is safe to use — it identifies the integration partner for fee routing. Positions are always scoped by wallet signature.
Basic Flow
Every trade follows this pattern:
1. Discover → Search tokens & offers to find leveraged markets
2. Quote → Preview the trade (swap output, price impact, fees)
3. Build TX → API returns a serialized Solana transaction
4. Sign → Sign the transaction with your wallet
5. Submit → Send via MEV-protected endpoint
Core Concepts
Token Coverage
Lavarage supports leveraged trading on any SPL token that has a liquidity pool. This includes:
- Blue chips: SOL, BTC (WBTC, cbBTC, zBTC), ETH (WETH)
- Stablecoins as collateral: USDC for short positions
- Real-world assets: OPENAI, SPACEX (tokenized stocks)
- Commodities: XAUt0 (gold)
- Memecoins and long-tail tokens: Hundreds of tokens with active pools
Always search first — don't assume a token isn't available. New pools are created permissionlessly.
// Search for any token by name, symbol, or mint address
const offers = await client.getOffers({ search: 'OPENAI', side: 'LONG' })
if (offers.length > 0) {
console.log(`Found ${offers.length} offers for OPENAI`)
}
Sides: LONG vs SHORT
- LONG: You deposit collateral (SOL/USDC), borrow more, and swap into the target token. You profit when the token price goes up.
- SHORT: You deposit USDC as collateral, borrow the target token, and sell it. You profit when the token price goes down.
The API determines side automatically based on the offer's base token:
- Base token is NOT USDC → LONG position
- Base token IS USDC → SHORT position
Leverage
Leverage ranges from 1.1x to the offer's maximum (up to ~12x depending on the pool). Higher leverage means higher potential returns but also higher liquidation risk.
Effective exposure = collateral × leverage
Borrowed amount = collateral × (leverage - 1)
Units
- Collateral input: Always in the token's smallest unit (lamports for SOL = amount × 10^9, micro-USDC = amount × 10^6)
- Prices: USD
- Slippage: Basis points (50 = 0.5%)
- Split/partial amounts: Basis points of position (5000 = 50%)
Offers (Liquidity Pools)
An "offer" is a liquidity pool with a specific base-quote token pair, interest rate, and leverage limit. Multiple offers can exist for the same token pair with different terms. Always pick the offer with the best rate and highest liquidity for the user's needs.
Core Operations
1. Discover Available Markets
Before opening any position, search for available markets:
// Search by token name or symbol
const offers = await client.getOffers({ search: 'BTC' })
// Filter by side
const longOffers = await client.getOffers({ search: 'ETH', side: 'LONG' })
const shortOffers = await client.getOffers({ search: 'ETH', side: 'SHORT' })
// Get all available tokens
const tokens = await client.getTokens()
// Each offer includes:
// - offerPublicKey (needed for opening position)
// - baseToken { symbol, mint, decimals, priceUsd, logoUri }
// - quoteToken { symbol, mint, decimals, priceUsd }
// - side: 'LONG' | 'SHORT'
// - maxLeverage: number
// - interestRate: number (annual %)
// - totalLiquidity: string (available to borrow)
2. Get a Quote (Preview Trade)
Always quote before opening to show the user expected output:
const quote = await client.getOpenQuote({
offerPublicKey: offer.address,
userPublicKey: walletAddress,
collateralAmount: '1000000000', // 1 SOL in lamports
leverage: 3,
slippageBps: 50,
})
// quote returns:
// - expectedOutput: tokens received
// - priceImpact: percentage
// - fees: breakdown of all fees
// - liquidationPrice: price at which position gets liquidated
3. Open a Position
import { VersionedTransaction } from '@solana/web3.js'
import bs58 from 'bs58'
// Get MEV protection tip
const { tipLamports } = await client.getTipFloor()
// Build the transaction
const result = await client.buildOpenTx({
offerPublicKey: offer.address,
userPublicKey: walletAddress,
collateralAmount: '1000000000', // 1 SOL
leverage: 3,
slippageBps: 50,
astralaneTipLamports: tipLamports, // MEV protection
})
// result.transaction is base58-encoded
// Deserialize, sign, and submit:
const txBytes = bs58.decode(result.transaction)
const tx = VersionedTransaction.deserialize(txBytes)
// Sign with wallet
tx.sign([walletKeypair])
// Submit with MEV protection
const serialized = bs58.encode(tx.serialize())
const { result: txSignature } = await client.submitTransaction(serialized, true)
console.log(`Position opened: ${txSignature}`)
4. Close a Position
// Preview close first
const closeQuote = await client.getCloseQuote({
positionAddress: position.address,
userPublicKey: walletAddress,
slippageBps: 50,
})
// closeQuote shows: proceeds, pnl, fees
// Build close transaction
const { tipLamports } = await client.getTipFloor()
const result = await client.buildCloseTx({
positionAddress: position.address,
userPublicKey: walletAddress,
slippageBps: 50,
astralaneTipLamports: tipLamports,
})
// Sign and submit (same pattern as open)
const txBytes = bs58.decode(result.transaction)
const tx = VersionedTransaction.deserialize(txBytes)
tx.sign([walletKeypair])
const serialized = bs58.encode(tx.serialize())
await client.submitTransaction(serialized, true)
5. List Positions
// All positions
const positions = await client.getPositions()
// Filter by status
const active = await client.getPositions('EXECUTED')
// Each position includes computed fields:
// - address, status, side
// - collateralAmount, borrowedAmount
// - currentPrice, entryPrice
// - unrealizedPnlUsd, roiPercent
// - liquidationPrice, currentLtv
// - effectiveLeverage
// - interestAccrued, dailyInterestCost
// - baseToken, quoteToken metadata
6. Partial Sell
Sell a portion of a position while keeping the rest open:
// Sell 30% of position
const result = await client.buildPartialSellTx({
positionAddress: position.address,
userPublicKey: walletAddress,
splitRatioBps: 3000, // 30%
slippageBps: 50,
})
// Returns two transactions that must be submitted as a Jito bundle:
// 1. Split transaction (splits position into two)
// 2. Close transactio