@agentix/plugin-solana-ranger
Version:
1,387 lines (1,364 loc) • 42.4 kB
JavaScript
// 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
};