UNPKG

@agentix/plugin-solana-ranger

Version:
1,387 lines (1,364 loc) 42.4 kB
// src/index.ts import { PluginBase, SolanaWalletBase } from "agentix"; // src/actions/getQuote.ts import { z } from "zod"; var getQuoteSchema = z.object({ fee_payer: z.string().describe("The public key of the fee payer account."), symbol: z.string().describe("Trading symbol (e.g., 'SOL', 'BTC', 'ETH')."), side: z.enum(["Long", "Short"]).describe("Trading side."), size: z.number().positive().describe("The size of the position in base asset."), collateral: z.number().positive().describe("The amount of collateral to use (in USDC)."), size_denomination: z.string().describe("Denomination of the size (must match symbol)."), collateral_denomination: z.literal("USDC").describe("Denomination of the collateral (must be 'USDC')."), adjustment_type: z.enum([ "Increase", "DecreaseFlash", "DecreaseJupiter", "DecreaseDrift", "DecreaseAdrena", "CloseFlash", "CloseJupiter", "CloseDrift", "CloseAdrena", "CloseAll" ]).describe("Type of position adjustment or quote context."), target_venues: z.array(z.enum(["Jupiter", "Flash", "Drift"]).describe("Venue")).optional(), slippage_bps: z.number().int().optional(), priority_fee_micro_lamports: z.number().int().optional() }); var getQuoteAction = { name: "GET_QUOTE", similes: ["get quote", "fetch quote", "quote perp"], description: "Get a trade quote for a perp position using the Ranger SOR API.", examples: [ [ { input: { fee_payer: "YOUR_PUBLIC_KEY", symbol: "SOL", side: "Long", size: 1, collateral: 10, size_denomination: "SOL", collateral_denomination: "USDC", adjustment_type: "Increase" }, output: { venues: [], total_collateral: 10, total_size: 1, average_price: 20.625 }, explanation: "Get a quote for opening a long SOL position." } ] ], schema: getQuoteSchema, handler: async (agent, input, { apiKey }) => { const response = await fetch(`${RANGER_SOR_API_BASE}/v1/order_metadata`, { method: "POST", headers: { "Content-Type": "application/json", "x-api-key": apiKey }, body: JSON.stringify(input) }); if (!response.ok) { const error = await response.json(); throw new Error(`Quote request failed: ${error.message}`); } return response.json(); } }; // src/actions/getPositions.ts import { z as z2 } from "zod"; var getPositionsSchema = z2.object({ public_key: z2.string().describe("User's Solana wallet address."), platforms: z2.array(z2.enum(["DRIFT", "FLASH", "JUPITER", "ADRENA"])).optional().describe("Optional list of platforms to filter by."), symbols: z2.array(z2.string()).optional().describe( "Optional list of symbols to filter by (e.g., ['SOL-PERP', 'BTC-PERP'])." ), from: z2.string().datetime().optional().describe( "Optional earliest position date (ISO 8601 format) to fetch (defaults to 2 days ago in API)." ) }); var getPositionsAction = { name: "GET_POSITIONS", similes: ["get positions", "fetch positions", "positions list"], description: "Fetch open positions for a user from the Ranger API.", examples: [ [ { input: { public_key: "YOUR_PUBLIC_KEY" }, output: { positions: [] }, explanation: "Get all open positions for a user." } ] ], schema: getPositionsSchema, handler: async (agent, input, { apiKey, baseUrl = "https://data-api-staging-437363704888.asia-northeast1.run.app" }) => { const params = new URLSearchParams(); params.set("public_key", input.public_key); if (input.platforms) input.platforms.forEach( (p) => params.append("platforms", p) ); if (input.symbols) input.symbols.forEach((s) => params.append("symbols", s)); if (input.from) params.set("from", input.from); const response = await fetch( `${baseUrl}/v1/positions?${params.toString()}`, { method: "GET", headers: { "Content-Type": "application/json", "x-api-key": apiKey } } ); if (!response.ok) { const error = await response.json(); throw new Error(`Get positions request failed: ${error.message}`); } return response.json(); } }; // src/actions/increasePosition.ts import { z as z3 } from "zod"; import { VersionedTransaction } from "@solana/web3.js"; import base64js from "base64-js"; var increasePositionSchema = z3.object({ fee_payer: z3.string(), symbol: z3.string(), side: z3.enum(["Long", "Short"]), size: z3.number().positive(), collateral: z3.number().positive(), size_denomination: z3.string(), collateral_denomination: z3.literal("USDC"), adjustment_type: z3.literal("Increase"), target_venues: z3.array(z3.enum(["Jupiter", "Flash", "Drift"])).optional(), slippage_bps: z3.number().int().optional(), priority_fee_micro_lamports: z3.number().int().optional(), expected_price: z3.number().optional() }); var increasePositionAction = { name: "INCREASE_POSITION", similes: ["open position", "increase position", "long perp", "short perp"], description: "Open or increase a perp position using the Ranger SOR API.", examples: [ [ { input: { fee_payer: "YOUR_PUBLIC_KEY", symbol: "SOL", side: "Long", size: 1, collateral: 10, size_denomination: "SOL", collateral_denomination: "USDC", adjustment_type: "Increase" }, output: { message: "...", meta: { venues: [] } }, explanation: "Open a long SOL position." } ] ], schema: increasePositionSchema, handler: async (agent, input, { apiKey }) => { const response = await fetch( `${RANGER_SOR_API_BASE}/v1/increase_position`, { method: "POST", headers: { "Content-Type": "application/json", "x-api-key": apiKey }, body: JSON.stringify(input) } ); if (!response.ok) { const error = await response.json(); throw new Error(`Increase position request failed: ${error.message}`); } const data = await response.json(); const messageBase64 = data.message; const messageBytes = base64js.toByteArray(messageBase64); const transaction = VersionedTransaction.deserialize(messageBytes); const { blockhash } = await agent.wallet.getConnection().getLatestBlockhash(); transaction.message.recentBlockhash = blockhash; const signature = await agent.wallet.signAndSendTransaction( transaction ); return { signature, meta: data.meta }; } }; // src/actions/decreasePosition.ts import { z as z4 } from "zod"; import { VersionedTransaction as VersionedTransaction2 } from "@solana/web3.js"; import base64js2 from "base64-js"; var decreasePositionSchema = z4.object({ fee_payer: z4.string(), symbol: z4.string(), side: z4.enum(["Long", "Short"]), size: z4.number().positive(), collateral: z4.number().positive(), size_denomination: z4.string(), collateral_denomination: z4.literal("USDC"), adjustment_type: z4.enum([ "DecreaseFlash", "DecreaseJupiter", "DecreaseDrift", "DecreaseAdrena" ]), target_venues: z4.array(z4.enum(["Jupiter", "Flash", "Drift"])).optional(), slippage_bps: z4.number().int().optional(), priority_fee_micro_lamports: z4.number().int().optional(), expected_price: z4.number().optional() }); var decreasePositionAction = { name: "DECREASE_POSITION", similes: ["reduce position", "decrease position", "partial close perp"], description: "Decrease a perp position using the Ranger SOR API.", examples: [ [ { input: { fee_payer: "YOUR_PUBLIC_KEY", symbol: "SOL", side: "Long", size: 0.5, collateral: 5, size_denomination: "SOL", collateral_denomination: "USDC", adjustment_type: "DecreaseFlash" }, output: { signature: "...", meta: { venues: [] } }, explanation: "Decrease a long SOL position via Flash venue." } ] ], schema: decreasePositionSchema, handler: async (agent, input, { apiKey }) => { const response = await fetch( `${RANGER_SOR_API_BASE}/v1/decrease_position`, { method: "POST", headers: { "Content-Type": "application/json", "x-api-key": apiKey }, body: JSON.stringify(input) } ); if (!response.ok) { const error = await response.json(); throw new Error(`Decrease position request failed: ${error.message}`); } const data = await response.json(); const messageBase64 = data.message; const messageBytes = base64js2.toByteArray(messageBase64); const transaction = VersionedTransaction2.deserialize(messageBytes); const { blockhash } = await agent.wallet.getConnection().getLatestBlockhash(); transaction.message.recentBlockhash = blockhash; const signature = await agent.wallet.signAndSendTransaction( transaction ); return { signature, meta: data.meta }; } }; // src/actions/closePosition.ts import { z as z5 } from "zod"; import { VersionedTransaction as VersionedTransaction3 } from "@solana/web3.js"; import base64js3 from "base64-js"; var closePositionSchema = z5.object({ fee_payer: z5.string(), symbol: z5.string(), side: z5.enum(["Long", "Short"]), adjustment_type: z5.enum([ "CloseFlash", "CloseJupiter", "CloseDrift", "CloseAdrena", "CloseAll" ]), slippage_bps: z5.number().int().optional(), priority_fee_micro_lamports: z5.number().int().optional(), expected_price: z5.number().optional() }); var closePositionAction = { name: "CLOSE_POSITION", similes: ["close position", "exit trade", "close perp"], description: "Close an existing perp position using the Ranger SOR API.", examples: [ [ { input: { fee_payer: "YOUR_PUBLIC_KEY", symbol: "SOL", side: "Long", adjustment_type: "CloseFlash" }, output: { signature: "...", meta: { venues: [] } }, explanation: "Close a long SOL position via Flash venue." } ] ], schema: closePositionSchema, handler: async (agent, input, { apiKey }) => { const response = await fetch(`${RANGER_SOR_API_BASE}/v1/close_position`, { method: "POST", headers: { "Content-Type": "application/json", "x-api-key": apiKey }, body: JSON.stringify(input) }); if (!response.ok) { const error = await response.json(); throw new Error(`Close position request failed: ${error.message}`); } const data = await response.json(); const messageBase64 = data.message; const messageBytes = base64js3.toByteArray(messageBase64); const transaction = VersionedTransaction3.deserialize(messageBytes); const { blockhash } = await agent.wallet.getConnection().getLatestBlockhash(); transaction.message.recentBlockhash = blockhash; const signature = await agent.wallet.signAndSendTransaction( transaction ); return { signature, meta: data.meta }; } }; // src/actions/withdrawBalance.ts import { z as z6 } from "zod"; import { VersionedTransaction as VersionedTransaction4 } from "@solana/web3.js"; import base64js4 from "base64-js"; var withdrawBalanceSchema = z6.object({ fee_payer: z6.string(), symbol: z6.string(), amount: z6.number().positive(), sub_account_id: z6.number().int().optional(), adjustment_type: z6.literal("WithdrawBalanceDrift") }); var withdrawBalanceAction = { name: "WITHDRAW_BALANCE", similes: ["withdraw balance", "withdraw funds", "withdraw drift"], description: "Withdraw available balance from a Drift account using the Ranger SOR API.", examples: [ [ { input: { fee_payer: "YOUR_PUBLIC_KEY", symbol: "USDC", amount: 100, sub_account_id: 0, adjustment_type: "WithdrawBalanceDrift" }, output: { signature: "...", meta: { venue: "Drift", amount: 100, symbol: "USDC" } }, explanation: "Withdraw 100 USDC from Drift." } ] ], schema: withdrawBalanceSchema, handler: async (agent, input, { apiKey }) => { const response = await fetch(`${RANGER_SOR_API_BASE}/v1/withdraw_balance`, { method: "POST", headers: { "Content-Type": "application/json", "x-api-key": apiKey }, body: JSON.stringify(input) }); if (!response.ok) { const error = await response.json(); throw new Error(`Withdraw balance request failed: ${error.message}`); } const data = await response.json(); const messageBase64 = data.message; const messageBytes = base64js4.toByteArray(messageBase64); const transaction = VersionedTransaction4.deserialize(messageBytes); const { blockhash } = await agent.wallet.getConnection().getLatestBlockhash(); transaction.message.recentBlockhash = blockhash; const signature = await agent.wallet.signAndSendTransaction( transaction ); return { signature, meta: data.meta }; } }; // src/actions/depositCollateral.ts import { z as z7 } from "zod"; import { VersionedTransaction as VersionedTransaction5 } from "@solana/web3.js"; import base64js5 from "base64-js"; var depositCollateralSchema = z7.object({ fee_payer: z7.string(), symbol: z7.string(), side: z7.enum(["Long", "Short"]), collateral: z7.number().positive(), collateral_denomination: z7.literal("USDC"), adjustment_type: z7.enum([ "DepositCollateralFlash", "DepositCollateralJupiter", "DepositCollateralDrift" ]) }); var depositCollateralAction = { name: "DEPOSIT_COLLATERAL", similes: ["deposit collateral", "add margin", "add funds"], description: "Deposit collateral to a perp position using the Ranger SOR API.", examples: [ [ { input: { fee_payer: "YOUR_PUBLIC_KEY", symbol: "SOL", side: "Long", collateral: 100, collateral_denomination: "USDC", adjustment_type: "DepositCollateralFlash" }, output: { signature: "...", meta: { venues: [] } }, explanation: "Deposit 100 USDC collateral to a long SOL position via Flash." } ] ], schema: depositCollateralSchema, handler: async (agent, input, { apiKey }) => { const response = await fetch( `${RANGER_SOR_API_BASE}/v1/deposit_collateral`, { method: "POST", headers: { "Content-Type": "application/json", "x-api-key": apiKey }, body: JSON.stringify(input) } ); if (!response.ok) { const error = await response.json(); throw new Error(`Deposit collateral request failed: ${error.message}`); } const data = await response.json(); const messageBase64 = data.message; const messageBytes = base64js5.toByteArray(messageBase64); const transaction = VersionedTransaction5.deserialize(messageBytes); const { blockhash } = await agent.wallet.getConnection().getLatestBlockhash(); transaction.message.recentBlockhash = blockhash; const signature = await agent.wallet.signAndSendTransaction( transaction ); return { signature, meta: data.meta }; } }; // src/actions/withdrawCollateral.ts import { z as z8 } from "zod"; import { VersionedTransaction as VersionedTransaction6 } from "@solana/web3.js"; import base64js6 from "base64-js"; var withdrawCollateralSchema = z8.object({ fee_payer: z8.string(), symbol: z8.string(), side: z8.enum(["Long", "Short"]), collateral: z8.number().positive(), collateral_denomination: z8.literal("USDC"), adjustment_type: z8.enum([ "WithdrawCollateralFlash", "WithdrawCollateralJupiter", "WithdrawCollateralDrift" ]) }); var withdrawCollateralAction = { name: "WITHDRAW_COLLATERAL", similes: ["withdraw collateral", "remove margin", "remove funds"], description: "Withdraw collateral from a perp position using the Ranger SOR API.", examples: [ [ { input: { fee_payer: "YOUR_PUBLIC_KEY", symbol: "SOL", side: "Long", collateral: 50, collateral_denomination: "USDC", adjustment_type: "WithdrawCollateralFlash" }, output: { signature: "...", meta: { venues: [] } }, explanation: "Withdraw 50 USDC collateral from a long SOL position via Flash." } ] ], schema: withdrawCollateralSchema, handler: async (agent, input, { apiKey }) => { const response = await fetch( `${RANGER_SOR_API_BASE}/v1/withdraw_collateral`, { method: "POST", headers: { "Content-Type": "application/json", "x-api-key": apiKey }, body: JSON.stringify(input) } ); if (!response.ok) { const error = await response.json(); throw new Error(`Withdraw collateral request failed: ${error.message}`); } const data = await response.json(); const messageBase64 = data.message; const messageBytes = base64js6.toByteArray(messageBase64); const transaction = VersionedTransaction6.deserialize(messageBytes); const { blockhash } = await agent.wallet.getConnection().getLatestBlockhash(); transaction.message.recentBlockhash = blockhash; const signature = await agent.wallet.signAndSendTransaction( transaction ); return { signature, meta: data.meta }; } }; // src/actions/getTradeHistory.ts import { z as z9 } from "zod"; var getTradeHistorySchema = z9.object({ public_key: z9.string(), platforms: z9.array(z9.string()).optional(), symbols: z9.array(z9.string()).optional(), start_time: z9.string().optional(), end_time: z9.string().optional() }); var getTradeHistoryAction = { name: "GET_TRADE_HISTORY", similes: ["get trade history", "fetch trades", "trade history"], description: "Fetch trade history for a user from the Ranger API.", examples: [ [ { input: { public_key: "YOUR_PUBLIC_KEY" }, output: { trades: [] }, explanation: "Get all trade history for a user." } ] ], schema: getTradeHistorySchema, handler: async (agent, input, { apiKey }) => { const params = new URLSearchParams(); params.set("public_key", input.public_key); if (input.platforms) input.platforms.forEach((p) => params.append("platforms", p)); if (input.symbols) input.symbols.forEach((s) => params.append("symbols", s)); if (input.start_time) params.set("start_time", input.start_time); if (input.end_time) params.set("end_time", input.end_time); const response = await fetch(`${RANGER_DATA_API_BASE}/v1/trade_history?${params.toString()}`, { method: "GET", headers: { "Content-Type": "application/json", "x-api-key": apiKey } }); if (!response.ok) { const error = await response.json(); throw new Error(`Get trade history request failed: ${error.message}`); } return response.json(); } }; // src/actions/getLiquidationsLatest.ts import { z as z10 } from "zod"; var getLiquidationsLatestSchema = z10.object({}); var getLiquidationsLatestAction = { name: "GET_LIQUIDATIONS_LATEST", similes: [ "get latest liquidations", "fetch liquidations", "liquidations latest" ], description: "Fetch the latest liquidations from the Ranger API.", examples: [ [ { input: {}, output: { liquidations: [] }, explanation: "Get the latest liquidations." } ] ], schema: getLiquidationsLatestSchema, handler: async (agent, _input, { apiKey }) => { const response = await fetch( `${RANGER_DATA_API_BASE}/v1/liquidations/latest`, { method: "GET", headers: { "Content-Type": "application/json", "x-api-key": apiKey } } ); if (!response.ok) { const error = await response.json(); throw new Error( `Get liquidations latest request failed: ${error.message}` ); } return response.json(); } }; // src/actions/getLiquidationsTotals.ts import { z as z11 } from "zod"; var getLiquidationsTotalsSchema = z11.object({}); var getLiquidationsTotalsAction = { name: "GET_LIQUIDATIONS_TOTALS", similes: [ "get liquidations totals", "fetch liquidation totals", "liquidations summary" ], description: "Fetch the total liquidations from the Ranger API.", examples: [ [ { input: {}, output: { totals: [] }, explanation: "Get the total liquidations." } ] ], schema: getLiquidationsTotalsSchema, handler: async (agent, _input, { apiKey }) => { const response = await fetch( `${RANGER_DATA_API_BASE}/v1/liquidations/totals`, { method: "GET", headers: { "Content-Type": "application/json", "x-api-key": apiKey } } ); if (!response.ok) { const error = await response.json(); throw new Error( `Get liquidations totals request failed: ${error.message}` ); } return response.json(); } }; // src/actions/getLiquidationsCapitulation.ts import { z as z12 } from "zod"; var getLiquidationsCapitulationSchema = z12.object({ granularity: z12.string().optional(), threshold: z12.number().optional() }); var getLiquidationsCapitulationAction = { name: "GET_LIQUIDATIONS_CAPITULATION", similes: [ "get liquidations capitulation", "fetch liquidation capitulation", "liquidations threshold" ], description: "Fetch liquidations capitulation data from the Ranger API.", examples: [ [ { input: { granularity: "1h", threshold: 1e4 }, output: { data: [] }, explanation: "Get liquidations capitulation with 1h granularity and threshold 10000." } ] ], schema: getLiquidationsCapitulationSchema, handler: async (agent, input, { apiKey }) => { const params = new URLSearchParams(); if (input.granularity) params.set("granularity", input.granularity); if (input.threshold !== void 0) params.set("threshold", input.threshold.toString()); const response = await fetch( `${RANGER_DATA_API_BASE}/v1/liquidations/capitulation?${params.toString()}`, { method: "GET", headers: { "Content-Type": "application/json", "x-api-key": apiKey } } ); if (!response.ok) { const error = await response.json(); throw new Error( `Get liquidations capitulation request failed: ${error.message}` ); } return response.json(); } }; // src/actions/getLiquidationsHeatmap.ts import { z as z13 } from "zod"; var getLiquidationsHeatmapSchema = z13.object({ granularity: z13.string().optional() }); var getLiquidationsHeatmapAction = { name: "GET_LIQUIDATIONS_HEATMAP", similes: [ "get liquidations heatmap", "fetch liquidation heatmap", "liquidations by time" ], description: "Fetch liquidations heatmap data from the Ranger API.", examples: [ [ { input: { granularity: "1h" }, output: { heatmap: [] }, explanation: "Get liquidations heatmap with 1h granularity." } ] ], schema: getLiquidationsHeatmapSchema, handler: async (agent, input, { apiKey }) => { const params = new URLSearchParams(); if (input.granularity) params.set("granularity", input.granularity); const response = await fetch( `${RANGER_DATA_API_BASE}/v1/liquidations/heatmap?${params.toString()}`, { method: "GET", headers: { "Content-Type": "application/json", "x-api-key": apiKey } } ); if (!response.ok) { const error = await response.json(); throw new Error( `Get liquidations heatmap request failed: ${error.message}` ); } return response.json(); } }; // src/actions/getLiquidationsLargest.ts import { z as z14 } from "zod"; var getLiquidationsLargestSchema = z14.object({ granularity: z14.string().optional(), limit: z14.number().int().optional() }); var getLiquidationsLargestAction = { name: "GET_LIQUIDATIONS_LARGEST", similes: [ "get largest liquidations", "fetch largest liquidations", "liquidations biggest" ], description: "Fetch the largest liquidations from the Ranger API.", examples: [ [ { input: { granularity: "1h", limit: 10 }, output: { liquidations: [] }, explanation: "Get the 10 largest liquidations with 1h granularity." } ] ], schema: getLiquidationsLargestSchema, handler: async (agent, input, { apiKey }) => { const params = new URLSearchParams(); if (input.granularity) params.set("granularity", input.granularity); if (input.limit !== void 0) params.set("limit", input.limit.toString()); const response = await fetch( `${RANGER_DATA_API_BASE}/v1/liquidations/largest?${params.toString()}`, { method: "GET", headers: { "Content-Type": "application/json", "x-api-key": apiKey } } ); if (!response.ok) { const error = await response.json(); throw new Error( `Get liquidations largest request failed: ${error.message}` ); } return response.json(); } }; // src/actions/getFundingRateArbs.ts import { z as z15 } from "zod"; var getFundingRateArbsSchema = z15.object({ min_diff: z15.number().optional() }); var getFundingRateArbsAction = { name: "GET_FUNDING_RATE_ARBS", similes: [ "get funding rate arbs", "fetch funding arbitrage", "funding rate opportunities" ], description: "Fetch funding rate arbitrage opportunities from the Ranger API.", examples: [ [ { input: { min_diff: 0.01 }, output: { arbs: [] }, explanation: "Get funding rate arbitrage opportunities with minimum difference 0.01." } ] ], schema: getFundingRateArbsSchema, handler: async (agent, input, { apiKey }) => { const params = new URLSearchParams(); if (input.min_diff !== void 0) params.set("min_diff", input.min_diff.toString()); const response = await fetch( `${RANGER_DATA_API_BASE}/v1/funding_rates/arbs?${params.toString()}`, { method: "GET", headers: { "Content-Type": "application/json", "x-api-key": apiKey } } ); if (!response.ok) { const error = await response.json(); throw new Error(`Get funding rate arbs request failed: ${error.message}`); } return response.json(); } }; // src/actions/getFundingRatesAccumulated.ts import { z as z16 } from "zod"; var getFundingRatesAccumulatedSchema = z16.object({ symbol: z16.string().optional(), granularity: z16.string().optional(), platform: z16.string().optional() }); var getFundingRatesAccumulatedAction = { name: "GET_FUNDING_RATES_ACCUMULATED", similes: [ "get funding rates accumulated", "fetch accumulated funding", "funding rates sum" ], description: "Fetch accumulated funding rates from the Ranger API.", examples: [ [ { input: { symbol: "BTC-PERP", granularity: "1h", platform: "Drift" }, output: { rates: [] }, explanation: "Get accumulated funding rates for BTC-PERP on Drift with 1h granularity." } ] ], schema: getFundingRatesAccumulatedSchema, handler: async (agent, input, { apiKey }) => { const params = new URLSearchParams(); if (input.symbol) params.set("symbol", input.symbol); if (input.granularity) params.set("granularity", input.granularity); if (input.platform) params.set("platform", input.platform); const response = await fetch( `${RANGER_DATA_API_BASE}/v1/funding_rates/accumulated?${params.toString()}`, { method: "GET", headers: { "Content-Type": "application/json", "x-api-key": apiKey } } ); if (!response.ok) { const error = await response.json(); throw new Error( `Get funding rates accumulated request failed: ${error.message}` ); } return response.json(); } }; // src/actions/getBorrowRatesAccumulated.ts import { z as z17 } from "zod"; var getBorrowRatesAccumulatedSchema = z17.object({ symbol: z17.string().optional(), granularity: z17.string().optional(), platform: z17.string().optional() }); var getBorrowRatesAccumulatedAction = { name: "GET_BORROW_RATES_ACCUMULATED", similes: [ "get borrow rates accumulated", "fetch accumulated borrow rates", "borrow rates sum" ], description: "Fetch accumulated borrow rates from the Ranger API.", examples: [ [ { input: { symbol: "BTC-PERP", granularity: "1h", platform: "Drift" }, output: { rates: [] }, explanation: "Get accumulated borrow rates for BTC-PERP on Drift with 1h granularity." } ] ], schema: getBorrowRatesAccumulatedSchema, handler: async (_agent, input, { apiKey }) => { const params = new URLSearchParams(); if (input.symbol) params.set("symbol", input.symbol); if (input.granularity) params.set("granularity", input.granularity); if (input.platform) params.set("platform", input.platform); const response = await fetch( `${RANGER_DATA_API_BASE}/v1/borrow_rates/accumulated?${params.toString()}`, { method: "GET", headers: { "Content-Type": "application/json", "x-api-key": apiKey } } ); if (!response.ok) { const error = await response.json(); throw new Error( `Get borrow rates accumulated request failed: ${error.message}` ); } return response.json(); } }; // src/actions/getFundingRatesExtreme.ts import { z as z18 } from "zod"; var getFundingRatesExtremeSchema = z18.object({ granularity: z18.string().optional(), limit: z18.number().int().optional() }); var getFundingRatesExtremeAction = { name: "GET_FUNDING_RATES_EXTREME", similes: [ "get funding rates extreme", "fetch extreme funding", "funding rates outliers" ], description: "Fetch extreme funding rates from the Ranger API.", examples: [ [ { input: { granularity: "1h", limit: 5 }, output: { rates: [] }, explanation: "Get 5 most extreme funding rates with 1h granularity." } ] ], schema: getFundingRatesExtremeSchema, handler: async (agent, input, { apiKey }) => { const params = new URLSearchParams(); if (input.granularity) params.set("granularity", input.granularity); if (input.limit !== void 0) params.set("limit", input.limit.toString()); const response = await fetch( `${RANGER_DATA_API_BASE}/v1/funding_rates/extreme?${params.toString()}`, { method: "GET", headers: { "Content-Type": "application/json", "x-api-key": apiKey } } ); if (!response.ok) { const error = await response.json(); throw new Error( `Get funding rates extreme request failed: ${error.message}` ); } return response.json(); } }; // src/actions/getFundingRatesOiWeighted.ts import { z as z19 } from "zod"; var getFundingRatesOiWeightedSchema = z19.object({}); var getFundingRatesOiWeightedAction = { name: "GET_FUNDING_RATES_OI_WEIGHTED", similes: [ "get oi weighted funding rates", "fetch open interest weighted funding", "oi weighted funding rates" ], description: "Fetch open interest weighted funding rates from the Ranger API.", examples: [ [ { input: {}, output: { rates: [] }, explanation: "Get open interest weighted funding rates." } ] ], schema: getFundingRatesOiWeightedSchema, handler: async (agent, _input, { apiKey }) => { const response = await fetch( `${RANGER_DATA_API_BASE}/v1/funding_rates/oi_weighted`, { method: "GET", headers: { "Content-Type": "application/json", "x-api-key": apiKey } } ); if (!response.ok) { const error = await response.json(); throw new Error( `Get funding rates oi weighted request failed: ${error.message}` ); } return response.json(); } }; // src/actions/getFundingRatesTrend.ts import { z as z20 } from "zod"; var getFundingRatesTrendSchema = z20.object({ symbol: z20.string(), platform: z20.string().optional() }); var getFundingRatesTrendAction = { name: "GET_FUNDING_RATES_TREND", similes: [ "get funding rates trend", "fetch funding trend", "funding rates history" ], description: "Fetch funding rates trend from the Ranger API.", examples: [ [ { input: { symbol: "BTC-PERP", platform: "Drift" }, output: { trend: [] }, explanation: "Get funding rates trend for BTC-PERP on Drift." } ] ], schema: getFundingRatesTrendSchema, handler: async (agent, input, { apiKey }) => { const params = new URLSearchParams(); params.set("symbol", input.symbol); if (input.platform) params.set("platform", input.platform); const response = await fetch( `${RANGER_DATA_API_BASE}/v1/funding_rates/trend?${params.toString()}`, { method: "GET", headers: { "Content-Type": "application/json", "x-api-key": apiKey } } ); if (!response.ok) { const error = await response.json(); throw new Error( `Get funding rates trend request failed: ${error.message}` ); } return response.json(); } }; // src/tools/ranger_perp_trading.ts import { signOrSendTX } from "agentix"; import { VersionedTransaction as VersionedTransaction7 } from "@solana/web3.js"; import base64js7 from "base64-js"; async function openPerpTradeRanger({ agent, symbol, side, size, collateral, apiKey, ...rest }) { const body = { fee_payer: agent.wallet.getAddress(), symbol, side, size, collateral, size_denomination: symbol, collateral_denomination: "USDC", adjustment_type: "Increase", // TODO: Confirm if this should be "Increase" or another type for open ...rest }; const response = await fetch(`${RANGER_SOR_API_BASE}/v1/increase_position`, { method: "POST", headers: { "Content-Type": "application/json", "x-api-key": apiKey }, body: JSON.stringify(body) }); if (!response.ok) { const error = await response.json(); throw new Error(`Open position request failed: ${error.message}`); } const data = await response.json(); const messageBase64 = data.message; const messageBytes = base64js7.toByteArray(messageBase64); const transaction = VersionedTransaction7.deserialize(messageBytes); const { blockhash } = await agent.wallet.getConnection().getLatestBlockhash(); transaction.message.recentBlockhash = blockhash; return signOrSendTX(agent, transaction); } async function closePerpTradeRanger({ agent, symbol, side, apiKey, ...rest }) { const body = { fee_payer: agent.wallet.getAddress(), symbol, side, adjustment_type: "CloseFlash", // TODO: Confirm adjustment_type for close ...rest }; const response = await fetch(`${RANGER_SOR_API_BASE}/v1/close_position`, { method: "POST", headers: { "Content-Type": "application/json", "x-api-key": apiKey }, body: JSON.stringify(body) }); if (!response.ok) { const error = await response.json(); throw new Error(`Close position request failed: ${error.message}`); } const data = await response.json(); const messageBase64 = data.message; const messageBytes = base64js7.toByteArray(messageBase64); const transaction = VersionedTransaction7.deserialize(messageBytes); const { blockhash } = await agent.wallet.getConnection().getLatestBlockhash(); transaction.message.recentBlockhash = blockhash; return signOrSendTX(agent, transaction); } async function increasePerpPositionRanger({ agent, symbol, side, size, collateral, apiKey, ...rest }) { const body = { fee_payer: agent.wallet.getAddress(), symbol, side, size, collateral, size_denomination: symbol, collateral_denomination: "USDC", adjustment_type: "Increase", ...rest }; const response = await fetch(`${RANGER_SOR_API_BASE}/v1/increase_position`, { method: "POST", headers: { "Content-Type": "application/json", "x-api-key": apiKey }, body: JSON.stringify(body) }); if (!response.ok) { const error = await response.json(); throw new Error(`Increase position request failed: ${error.message}`); } const data = await response.json(); const messageBase64 = data.message; const messageBytes = base64js7.toByteArray(messageBase64); const transaction = VersionedTransaction7.deserialize(messageBytes); const { blockhash } = await agent.wallet.getConnection().getLatestBlockhash(); transaction.message.recentBlockhash = blockhash; return signOrSendTX(agent, transaction); } async function decreasePerpPositionRanger({ agent, symbol, side, size, apiKey, ...rest }) { const body = { fee_payer: agent.wallet.getAddress(), symbol, side, size, adjustment_type: "DecreaseFlash", // TODO: Confirm adjustment_type for decrease ...rest }; const response = await fetch(`${RANGER_SOR_API_BASE}/v1/decrease_position`, { method: "POST", headers: { "Content-Type": "application/json", "x-api-key": apiKey }, body: JSON.stringify(body) }); if (!response.ok) { const error = await response.json(); throw new Error(`Decrease position request failed: ${error.message}`); } const data = await response.json(); const messageBase64 = data.message; const messageBytes = base64js7.toByteArray(messageBase64); const transaction = VersionedTransaction7.deserialize(messageBytes); const { blockhash } = await agent.wallet.getConnection().getLatestBlockhash(); transaction.message.recentBlockhash = blockhash; return signOrSendTX(agent, transaction); } async function withdrawBalanceRanger({ agent, symbol, amount, apiKey, ...rest }) { const body = { fee_payer: agent.wallet.getAddress(), symbol, amount, adjustment_type: "WithdrawBalanceDrift", // TODO: Confirm adjustment_type for withdraw ...rest }; const response = await fetch(`${RANGER_SOR_API_BASE}/v1/withdraw_balance`, { method: "POST", headers: { "Content-Type": "application/json", "x-api-key": apiKey }, body: JSON.stringify(body) }); if (!response.ok) { const error = await response.json(); throw new Error(`Withdraw balance request failed: ${error.message}`); } const data = await response.json(); const messageBase64 = data.message; const messageBytes = base64js7.toByteArray(messageBase64); const transaction = VersionedTransaction7.deserialize(messageBytes); const { blockhash } = await agent.wallet.getConnection().getLatestBlockhash(); transaction.message.recentBlockhash = blockhash; return signOrSendTX(agent, transaction); } async function withdrawCollateralRanger({ agent, symbol, side, collateral, apiKey, ...rest }) { const body = { fee_payer: agent.wallet.getAddress(), symbol, side, collateral, collateral_denomination: "USDC", adjustment_type: "WithdrawCollateralFlash", // TODO: Confirm adjustment_type for withdraw collateral ...rest }; const response = await fetch( `${RANGER_SOR_API_BASE}/v1/withdraw_collateral`, { method: "POST", headers: { "Content-Type": "application/json", "x-api-key": apiKey }, body: JSON.stringify(body) } ); if (!response.ok) { const error = await response.json(); throw new Error(`Withdraw collateral request failed: ${error.message}`); } const data = await response.json(); const messageBase64 = data.message; const messageBytes = base64js7.toByteArray(messageBase64); const transaction = VersionedTransaction7.deserialize(messageBytes); const { blockhash } = await agent.wallet.getConnection().getLatestBlockhash(); transaction.message.recentBlockhash = blockhash; return signOrSendTX(agent, transaction); } // src/index.ts var RangerPlugin = class extends PluginBase { constructor() { const methods = { openPerpTradeRanger, closePerpTradeRanger, increasePerpPositionRanger, decreasePerpPositionRanger, withdrawBalanceRanger, withdrawCollateralRanger }; const actions = [ closePositionAction, decreasePositionAction, depositCollateralAction, getBorrowRatesAccumulatedAction, getFundingRateArbsAction, getFundingRatesAccumulatedAction, getFundingRatesExtremeAction, getFundingRatesOiWeightedAction, getFundingRatesTrendAction, getLiquidationsCapitulationAction, getLiquidationsHeatmapAction, getLiquidationsLargestAction, getLiquidationsLatestAction, getLiquidationsTotalsAction, getPositionsAction, increasePositionAction, getQuoteAction, withdrawBalanceAction, withdrawCollateralAction, getTradeHistoryAction ]; const supportedChains = [ { type: "solana" } ]; super("ranger", methods, actions, supportedChains); } supportsWallet(wallet) { return wallet instanceof SolanaWalletBase; } }; var index_default = RangerPlugin; function getEnvOrDefault(envKey, fallback) { const proc = typeof globalThis !== "undefined" && globalThis.process ? globalThis.process : void 0; if (proc && proc.env && proc.env[envKey]) { return proc.env[envKey]; } return fallback; } var RANGER_SOR_API_BASE = getEnvOrDefault( "RANGER_SOR_API_BASE", "https://staging-sor-api-437363704888.asia-northeast1.run.app" ); var RANGER_DATA_API_BASE = getEnvOrDefault( "RANGER_DATA_API_BASE", "https://data-api-staging-437363704888.asia-northeast1.run.app" ); export { RANGER_DATA_API_BASE, RANGER_SOR_API_BASE, index_default as default };