From 23d6c499553c4a23de64a5ffb6150030b096d92c Mon Sep 17 00:00:00 2001 From: Arihant Bansal <17180950+arihantbansal@users.noreply.github.com> Date: Sat, 18 Jan 2025 12:58:32 +0530 Subject: [PATCH] meteora lp --- src/agent/index.ts | 34 ++++++++++++ src/langchain/meteora/meteora_dlmm_lp.ts | 49 +++++++++++++++++ .../create_meteora_dlmm_lp_position.ts | 53 +++++++++++++++++++ src/tools/meteora/index.ts | 1 + 4 files changed, 137 insertions(+) create mode 100644 src/langchain/meteora/meteora_dlmm_lp.ts create mode 100644 src/tools/meteora/create_meteora_dlmm_lp_position.ts diff --git a/src/agent/index.ts b/src/agent/index.ts index 6f6f9c96..47491b90 100644 --- a/src/agent/index.ts +++ b/src/agent/index.ts @@ -114,6 +114,7 @@ import { voltrGetPositionValues, voltrDepositStrategy, voltrWithdrawStrategy, + createMeteoraDlmmLpPosition, } from "../tools"; import { Config, @@ -450,6 +451,13 @@ export class SolanaAgentKit { ); } + async createMeteoraDlmmLpPosition( + pool: PublicKey, + totalXAmount: BN, + ): Promise { + return createMeteoraDlmmLpPosition(this, pool, totalXAmount); + } + async orcaClosePosition(positionMintAddress: PublicKey) { return orcaClosePosition(this, positionMintAddress); } @@ -654,6 +662,7 @@ export class SolanaAgentKit { ) { return rock_paper_scissor(this, amount, choice); } + async createTiplink(amount: number, splmintAddress?: PublicKey) { return create_TipLink(this, amount, splmintAddress); } @@ -698,9 +707,11 @@ export class SolanaAgentKit { async flashCloseTrade(params: FlashCloseTradeParams): Promise { return flashCloseTrade(this, params); } + async heliusParseTransactions(transactionId: string): Promise { return parseTransaction(this, transactionId); } + async getAllAssetsbyOwner(owner: PublicKey, limit: number): Promise { return getAssetsByOwner(this, owner, limit); } @@ -746,6 +757,7 @@ export class SolanaAgentKit { ); return `Transaction: ${tx}`; } + async sendTranctionWithPriority( priorityLevel: string, amount: number, @@ -805,15 +817,18 @@ export class SolanaAgentKit { ): Promise { return multisig_execute_proposal(this, transactionIndex); } + async CreateWebhook( accountAddresses: string[], webhookURL: string, ): Promise { return create_HeliusWebhook(this, accountAddresses, webhookURL); } + async getWebhook(id: string): Promise { return getHeliusWebhook(this, id); } + async deleteWebhook(webhookID: string): Promise { return deleteHeliusWebhook(this, webhookID); } @@ -839,6 +854,7 @@ export class SolanaAgentKit { async depositIntoDriftVault(amount: number, vault: string) { return await depositIntoVault(this, amount, vault); } + async depositToDriftUserAccount( amount: number, symbol: string, @@ -846,18 +862,23 @@ export class SolanaAgentKit { ) { return await depositToDriftUserAccount(this, amount, symbol, isRepayment); } + async deriveDriftVaultAddress(name: string) { return await getVaultAddress(this, name); } + async doesUserHaveDriftAccount() { return await doesUserHaveDriftAccount(this); } + async driftUserAccountInfo() { return await driftUserAccountInfo(this); } + async requestWithdrawalFromDriftVault(amount: number, vault: string) { return await requestWithdrawalFromVault(this, amount, vault); } + async tradeUsingDelegatedDriftVault( vault: string, amount: number, @@ -876,6 +897,7 @@ export class SolanaAgentKit { price, ); } + async tradeUsingDriftPerpAccount( amount: number, symbol: string, @@ -885,6 +907,7 @@ export class SolanaAgentKit { ) { return await driftPerpTrade(this, { action, amount, symbol, type, price }); } + async updateDriftVault( vaultAddress: string, params: { @@ -901,9 +924,11 @@ export class SolanaAgentKit { ) { return await updateVault(this, vaultAddress, params); } + async getDriftVaultInfo(vaultName: string) { return await getVaultInfo(this, vaultName); } + async withdrawFromDriftAccount( amount: number, symbol: string, @@ -911,9 +936,11 @@ export class SolanaAgentKit { ) { return await withdrawFromDriftUserAccount(this, amount, symbol, isBorrow); } + async withdrawFromDriftVault(vault: string) { return await withdrawFromDriftVault(this, vault); } + async updateDriftVaultDelegate(vaultAddress: string, delegate: string) { return await updateVaultDelegate(this, vaultAddress, delegate); } @@ -931,15 +958,19 @@ export class SolanaAgentKit { }; } } + async stakeToDriftInsuranceFund(amount: number, symbol: string) { return await stakeToDriftInsuranceFund(this, amount, symbol); } + async requestUnstakeFromDriftInsuranceFund(amount: number, symbol: string) { return await requestUnstakeFromDriftInsuranceFund(this, amount, symbol); } + async unstakeFromDriftInsuranceFund(symbol: string) { return await unstakeFromDriftInsuranceFund(this, symbol); } + async driftSpotTokenSwap( params: { fromSymbol: string; @@ -962,12 +993,14 @@ export class SolanaAgentKit { slippage: params.slippage, }); } + async getPerpMarketFundingRate( symbol: `${string}-PERP`, period: "year" | "hour" = "year", ) { return calculatePerpMarketFundingRate(this, symbol, period); } + async getEntryQuoteOfPerpTrade( amount: number, symbol: `${string}-PERP`, @@ -975,6 +1008,7 @@ export class SolanaAgentKit { ) { return getEntryQuoteOfPerpTrade(symbol, amount, action); } + async getLendAndBorrowAPY(symbol: string) { return getLendingAndBorrowAPY(this, symbol); } diff --git a/src/langchain/meteora/meteora_dlmm_lp.ts b/src/langchain/meteora/meteora_dlmm_lp.ts new file mode 100644 index 00000000..5d364a67 --- /dev/null +++ b/src/langchain/meteora/meteora_dlmm_lp.ts @@ -0,0 +1,49 @@ +import { PublicKey } from "@solana/web3.js"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; +import { BN } from "bn.js"; + +export class SolanaMeteoraCreateDlmmLpPosition extends Tool { + name = "meteora_create_dlmm_lp_position"; + description = `Create a Meteora DLMM LP position. + + Inputs (JSON string): + - pool: string, pool address (required). + - totalXAmount: number, total X amount to deposit, e.g., 100 (required). + `; + + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + + async _call(input: string): Promise { + try { + interface CreateMeteoraDlmmLpPositionInput { + pool: string; + totalXAmount: number; + } + + const inputFormat: CreateMeteoraDlmmLpPositionInput = JSON.parse(input); + + const pool = new PublicKey(inputFormat.pool); + const totalXAmount = new BN(inputFormat.totalXAmount); + + const txId = await this.solanaKit.createMeteoraDlmmLpPosition( + pool, + totalXAmount, + ); + + return JSON.stringify({ + status: "success", + message: "Meteora DLMM LP position created successfully.", + transaction: txId, + }); + } catch (error: any) { + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); + } + } +} diff --git a/src/tools/meteora/create_meteora_dlmm_lp_position.ts b/src/tools/meteora/create_meteora_dlmm_lp_position.ts new file mode 100644 index 00000000..6ebab31a --- /dev/null +++ b/src/tools/meteora/create_meteora_dlmm_lp_position.ts @@ -0,0 +1,53 @@ +import { Keypair, PublicKey } from "@solana/web3.js"; +import DLMM, { StrategyType } from "@meteora-ag/dlmm"; +import BN from "bn.js"; +import { SolanaAgentKit } from "../../agent"; +import { sendTx } from "../../utils/send_tx"; + +export async function createMeteoraDlmmLpPosition( + agent: SolanaAgentKit, + pool: PublicKey, + totalXAmount: BN, +): Promise { + const dlmmPool = await DLMM.create(agent.connection, pool); + + const activeBin = await dlmmPool.getActiveBin(); + const activeBinPriceLamport = activeBin.price; + const activeBinPricePerToken = dlmmPool.fromPricePerLamport( + Number(activeBin.price), + ); + + const newBalancePosition = Keypair.generate(); + + const TOTAL_RANGE_INTERVAL = 10; // 10 bins on each side of the active bin + const minBinId = activeBin.binId - TOTAL_RANGE_INTERVAL; + const maxBinId = activeBin.binId + TOTAL_RANGE_INTERVAL; + + const totalYAmount = totalXAmount.mul(new BN(Number(activeBinPricePerToken))); + + const createPositionTx = + await dlmmPool.initializePositionAndAddLiquidityByStrategy({ + positionPubKey: newBalancePosition.publicKey, + user: agent.wallet.publicKey, + totalXAmount, + totalYAmount, + strategy: { + maxBinId, + minBinId, + strategyType: StrategyType.SpotBalanced, + }, + }); + + try { + const createBalancePositionTxHash = await sendTx( + agent, + createPositionTx.instructions, + [agent.wallet, newBalancePosition], + ); + + return createBalancePositionTxHash; + } catch (error) { + console.log("🚀 ~ error:", JSON.parse(JSON.stringify(error))); + throw new Error("Failed to create balance position"); + } +} diff --git a/src/tools/meteora/index.ts b/src/tools/meteora/index.ts index 2ba0ce92..530f6e5a 100644 --- a/src/tools/meteora/index.ts +++ b/src/tools/meteora/index.ts @@ -1,2 +1,3 @@ export * from "./create_meteora_dlmm_pool"; export * from "./create_meteora_dynamic_amm_pool"; +export * from "./create_meteora_dlmm_lp_position";