Refactor high-complexity React components in Dify frontend. Use when `pnpm analyze-component...
npx skills add sendaifun/skills --skill "ranger-finance"
Install specific skill from multi-skill repository
# Description
Ranger Finance SDK for building perpetual futures trading applications on Solana. The first Solana Perps Aggregator - aggregates liquidity across multiple perp protocols (Drift, Flash, Adrena, Jupiter). Use when integrating perps trading, smart order routing, position management, or building AI trading agents.
# SKILL.md
name: ranger-finance
description: Ranger Finance SDK for building perpetual futures trading applications on Solana. The first Solana Perps Aggregator - aggregates liquidity across multiple perp protocols (Drift, Flash, Adrena, Jupiter). Use when integrating perps trading, smart order routing, position management, or building AI trading agents.
Ranger Finance SDK Development Guide
A comprehensive guide for building Solana applications with Ranger Finance - the first perpetual futures aggregator on Solana.
Overview
Ranger Finance is a Smart Order Router (SOR) that aggregates perpetual futures trading across multiple Solana protocols:
- Drift Protocol: Leading perps DEX on Solana
- Flash Trade: High-performance perpetuals
- Adrena: Leverage trading protocol
- Jupiter Perps: Jupiter's perpetuals platform
Key Benefits
- Best Execution: Automatically routes orders to venues with best pricing
- Unified API: Single interface for all supported perp protocols
- Position Aggregation: View and manage positions across all venues
- AI Agent Support: Built-in MCP server for AI trading agents
Quick Start
Installation (TypeScript)
# Clone the SDK demo
git clone https://github.com/ranger-finance/sor-ts-demo.git
cd sor-ts-demo
npm install
Environment Setup
Create a .env file:
RANGER_API_KEY=your_api_key_here
SOLANA_RPC_URL=https://api.mainnet-beta.solana.com
WALLET_PRIVATE_KEY=your_base58_private_key # Optional, for signing
Basic Setup
import { SorApi, TradeSide } from 'ranger-sor-sdk';
import dotenv from 'dotenv';
dotenv.config();
// Initialize the SOR API client
const sorApi = new SorApi({
apiKey: process.env.RANGER_API_KEY!,
solanaRpcUrl: process.env.SOLANA_RPC_URL,
});
// Your wallet public key
const walletAddress = 'YOUR_WALLET_PUBLIC_KEY';
Core Concepts
1. Trade Sides
type TradeSide = 'Long' | 'Short';
2. Adjustment Types
type AdjustmentType =
| 'Quote' // Get a quote only
| 'Increase' // Open or increase position
| 'DecreaseFlash' // Decrease via Flash
| 'DecreaseJupiter' // Decrease via Jupiter
| 'DecreaseDrift' // Decrease via Drift
| 'DecreaseAdrena' // Decrease via Adrena
| 'CloseFlash' // Close via Flash
| 'CloseJupiter' // Close via Jupiter
| 'CloseDrift' // Close via Drift
| 'CloseAdrena' // Close via Adrena
| 'CloseAll'; // Close entire position
3. Position Interface
interface Position {
id: string;
symbol: string;
side: TradeSide;
quantity: number;
entry_price: number;
liquidation_price: number;
position_leverage: number;
real_collateral: number;
unrealized_pnl: number;
borrow_fee: number;
funding_fee: number;
open_fee: number;
close_fee: number;
created_at: string;
opened_at: string;
platform: string; // 'DRIFT', 'FLASH', 'ADRENA', 'JUPITER'
}
4. Quote Response
interface Quote {
base: number;
fee: number;
total: number;
fee_breakdown: {
base_fee: number;
spread_fee: number;
volatility_fee: number;
margin_fee: number;
close_fee: number;
other_fees: number;
};
}
interface VenueAllocation {
venue_name: string;
collateral: number;
size: number;
quote: Quote;
order_available_liquidity: number;
venue_available_liquidity: number;
}
interface OrderMetadataResponse {
venues: VenueAllocation[];
total_collateral: number;
total_size: number;
}
Trading Operations
Get a Quote
Before executing a trade, get a quote to see pricing across venues:
import { SorApi, OrderMetadataRequest, TradeSide } from 'ranger-sor-sdk';
const sorApi = new SorApi({ apiKey: process.env.RANGER_API_KEY! });
async function getQuote() {
const request: OrderMetadataRequest = {
fee_payer: walletAddress,
symbol: 'SOL',
side: 'Long' as TradeSide,
size: 1.0, // 1 SOL position size
collateral: 10.0, // 10 USDC collateral (10x leverage)
size_denomination: 'SOL',
collateral_denomination: 'USDC',
adjustment_type: 'Quote',
};
const quote = await sorApi.getOrderMetadata(request);
console.log('Available venues:');
quote.venues.forEach(venue => {
console.log(` ${venue.venue_name}: ${venue.quote.total} USDC`);
});
return quote;
}
Open/Increase a Position
async function openLongPosition() {
const request = {
fee_payer: walletAddress,
symbol: 'SOL',
side: 'Long' as TradeSide,
size: 1.0,
collateral: 10.0,
size_denomination: 'SOL',
collateral_denomination: 'USDC',
adjustment_type: 'Increase' as const,
};
// Get transaction instructions
const response = await sorApi.increasePosition(request);
console.log('Transaction message (base64):', response.message);
if (response.meta) {
console.log('Executed price:', response.meta.executed_price);
console.log('Venues used:', response.meta.venues_used);
}
return response;
}
// Open a short position
async function openShortPosition() {
const request = {
fee_payer: walletAddress,
symbol: 'ETH',
side: 'Short' as TradeSide,
size: 0.5,
collateral: 100.0,
size_denomination: 'ETH',
collateral_denomination: 'USDC',
adjustment_type: 'Increase' as const,
};
return await sorApi.increasePosition(request);
}
Decrease a Position
async function decreasePosition() {
const request = {
fee_payer: walletAddress,
symbol: 'SOL',
side: 'Long' as TradeSide,
size: 0.5, // Decrease by 0.5 SOL
collateral: 5.0, // Withdraw 5 USDC collateral
size_denomination: 'SOL',
collateral_denomination: 'USDC',
adjustment_type: 'DecreaseFlash' as const, // Route through Flash
};
return await sorApi.decreasePosition(request);
}
Close a Position
// Close entire position on a specific venue
async function closePosition() {
const request = {
fee_payer: walletAddress,
symbol: 'SOL',
side: 'Long' as TradeSide,
adjustment_type: 'CloseFlash' as const,
};
return await sorApi.closePosition(request);
}
// Close all positions across all venues
async function closeAllPositions() {
const request = {
fee_payer: walletAddress,
symbol: 'SOL',
side: 'Long' as TradeSide,
adjustment_type: 'CloseAll' as const,
};
return await sorApi.closePosition(request);
}
Sign and Execute Transaction
import { Keypair, VersionedTransaction } from '@solana/web3.js';
import bs58 from 'bs58';
async function executeTradeWithSigning() {
// Get transaction instructions
const txResponse = await sorApi.increasePosition({
fee_payer: walletAddress,
symbol: 'SOL',
side: 'Long',
size: 1.0,
collateral: 10.0,
size_denomination: 'SOL',
collateral_denomination: 'USDC',
adjustment_type: 'Increase',
});
// Create keypair from private key
const privateKeyBytes = bs58.decode(process.env.WALLET_PRIVATE_KEY!);
const keypair = Keypair.fromSecretKey(privateKeyBytes);
// Define signing function
const signTransaction = async (tx: VersionedTransaction) => {
tx.sign([keypair]);
return tx;
};
// Execute the transaction
const result = await sorApi.executeTransaction(txResponse, signTransaction);
console.log('Transaction signature:', result.signature);
return result;
}
Position Management
Fetch All Positions
async function getAllPositions() {
const positions = await sorApi.getPositions(walletAddress);
positions.positions.forEach(pos => {
console.log(`${pos.symbol} ${pos.side}: ${pos.quantity} @ ${pos.entry_price}`);
console.log(` Platform: ${pos.platform}`);
console.log(` PnL: ${pos.unrealized_pnl}`);
console.log(` Liquidation: ${pos.liquidation_price}`);
});
return positions;
}
Filter Positions by Platform
async function getDriftPositions() {
const positions = await sorApi.getPositions(walletAddress, {
platforms: ['DRIFT'],
});
return positions;
}
async function getFlashAndAdrenaPositions() {
const positions = await sorApi.getPositions(walletAddress, {
platforms: ['FLASH', 'ADRENA'],
});
return positions;
}
Filter Positions by Symbol
async function getSolPositions() {
const positions = await sorApi.getPositions(walletAddress, {
symbols: ['SOL-PERP'],
});
return positions;
}
AI Agent Integration
Ranger provides an MCP (Model Context Protocol) server for AI agent integration.
Installation (Python)
pip install mcp-agent numpy
MCP Server Tools
The Ranger MCP server exposes these tools:
SOR Tools:
- sor_get_trade_quote - Get pricing quotes
- sor_increase_position - Open/increase positions
- sor_decrease_position - Reduce positions
- sor_close_position - Close positions
Data API Tools:
- data_get_positions - Fetch current positions
- data_get_trade_history - Trading history
- data_get_liquidations - Liquidation data and signals
- data_get_funding_rates - Funding rate analytics
Example: Mean Reversion Agent
import asyncio
from ranger_mcp_agent.examples.mean_reversion_agent import run_mean_reversion_agent
async def main():
# Run a mean reversion trading strategy
await run_mean_reversion_agent()
if __name__ == "__main__":
asyncio.run(main())
Starting the MCP Server
cd ranger-agent-kit/perps-mcp
cp .env.example .env
# Edit .env with your API credentials
python -m ranger_mcp
API Reference
SorApi Class
class SorApi {
constructor(config: SorSdkConfig);
// Get quote for a trade
getOrderMetadata(request: OrderMetadataRequest): Promise<OrderMetadataResponse>;
// Open or increase a position
increasePosition(request: IncreasePositionRequest): Promise<TransactionResponse>;
// Reduce a position
decreasePosition(request: DecreasePositionRequest): Promise<TransactionResponse>;
// Close a position
closePosition(request: ClosePositionRequest): Promise<TransactionResponse>;
// Get positions for a wallet
getPositions(
publicKey: string,
options?: {
platforms?: string[];
symbols?: string[];
startDate?: string;
endDate?: string;
}
): Promise<PositionsResponse>;
// Execute a signed transaction
executeTransaction(
transactionResponse: TransactionResponse,
signTransaction: (tx: VersionedTransaction) => Promise<VersionedTransaction>
): Promise<{ signature: string }>;
// Get Solana connection
getConnection(): Connection;
}
Configuration
interface SorSdkConfig {
apiKey: string;
sorApiBaseUrl?: string; // Default: Ranger SOR API
dataApiBaseUrl?: string; // Default: Ranger Data API
solanaRpcUrl?: string; // Default: Mainnet RPC
}
Request Types
interface BaseRequest {
fee_payer: string;
symbol: string;
side: TradeSide;
size_denomination?: string;
collateral_denomination?: string;
}
interface IncreasePositionRequest extends BaseRequest {
size: number;
collateral: number;
size_denomination: string;
collateral_denomination: string;
adjustment_type: 'Increase';
}
interface DecreasePositionRequest extends BaseRequest {
size: number;
collateral: number;
size_denomination: string;
collateral_denomination: string;
adjustment_type: 'DecreaseFlash' | 'DecreaseJupiter' | 'DecreaseDrift' | 'DecreaseAdrena';
}
interface ClosePositionRequest extends BaseRequest {
adjustment_type: 'CloseFlash' | 'CloseJupiter' | 'CloseDrift' | 'CloseAdrena' | 'CloseAll';
}
Response Types
interface TransactionResponse {
message: string; // Base64-encoded transaction
meta?: {
executed_price?: number;
executed_size?: number;
executed_collateral?: number;
venues_used?: string[];
};
}
interface PositionsResponse {
positions: Position[];
}
Supported Markets
Ranger aggregates perpetual markets across:
| Protocol | Markets |
|---|---|
| Drift | SOL, BTC, ETH, and 20+ assets |
| Flash | SOL, BTC, ETH |
| Adrena | SOL, BTC, ETH |
| Jupiter | SOL, BTC, ETH |
Error Handling
try {
const response = await sorApi.increasePosition(request);
} catch (error) {
if (error.error_code) {
// API error
console.error('API Error:', error.message);
console.error('Error code:', error.error_code);
} else {
// Network or other error
throw error;
}
}
Best Practices
-
Always Get Quotes First: Before executing trades, use
getOrderMetadatato compare pricing across venues. -
Handle Transaction Signing Securely: Never hardcode private keys. Use environment variables or secure key management.
-
Monitor Positions: Regularly fetch positions to track PnL and liquidation prices.
-
Use Appropriate Venue: When decreasing/closing, choose the venue where your position exists.
-
Set Appropriate Collateral: Consider leverage when setting collateral. Higher collateral = lower liquidation risk.
Resources
Skill Structure
ranger-finance/
βββ SKILL.md # This file
βββ resources/
β βββ api-reference.md # API endpoint reference
β βββ types-reference.md # Complete TypeScript types
βββ examples/
β βββ basic/
β β βββ example.ts # Basic trade operations
β βββ positions/
β β βββ example.ts # Position queries and management
β βββ transactions/
β βββ example.ts # Transaction signing flow
βββ templates/
β βββ setup.ts # Ready-to-use setup template
βββ docs/
βββ troubleshooting.md # Common issues and solutions
βββ ai-agent-integration.md # AI agent setup guide
# Supported AI Coding Agents
This skill is compatible with the SKILL.md standard and works with all major AI coding agents:
Learn more about the SKILL.md standard and how to use these skills with your preferred AI coding agent.