UNPKG

@agentix/plugin-solana-sanctum

Version:
682 lines (663 loc) 20.1 kB
// src/index.ts import { PluginBase, SolanaWalletBase as SolanaWalletBase4 } from "agentix"; // src/actions/sanctumGetLSTPrice.ts import { z } from "zod"; // src/tools/sanctum_get_lst_price.ts import axios from "redaxios"; // src/constants/index.ts var SANCTUM_STAT_API_URI = "https://extra-api.sanctum.so"; var SANCTUM_TRADE_API_URI = "https://sanctum-s-api.fly.dev"; // src/tools/sanctum_get_lst_price.ts async function sanctumGetLSTPrice(inputs) { try { const client = axios.create({ baseURL: SANCTUM_STAT_API_URI }); const response = await client.get("/v1/sol-value/current", { params: { lst: inputs }, paramsSerializer: (params) => { return params.lst.map((value) => `lst=${value}`).join("&"); } }); const result = response.data.solValues; return result; } catch (error) { throw new Error(`Failed to get price: ${error.message}`); } } // src/tools/sanctum_get_lst_apy.ts import axios2 from "redaxios"; async function sanctumGetLSTAPY(inputs) { try { const client = axios2.create({ baseURL: SANCTUM_STAT_API_URI }); const response = await client.get("/v1/apy/latest", { params: { lst: inputs }, paramsSerializer: (params) => { return params.lst.map((value) => `lst=${value}`).join("&"); } }); const result = response.data.apys; return result; } catch (error) { throw new Error(`Failed to get apy: ${error.message}`); } } // src/tools/sanctum_get_lst_tvl.ts import axios3 from "redaxios"; async function sanctumGetLSTTVL(inputs) { try { const client = axios3.create({ baseURL: SANCTUM_TRADE_API_URI }); const response = await client.get("/v1/tvl/current", { params: { lst: inputs }, paramsSerializer: (params) => { return params.lst.map((value) => `lst=${value}`).join("&"); } }); const result = response.data.tvls; return result; } catch (error) { throw new Error(`Failed to get tvl: ${error.message}`); } } // src/tools/sanctum_add_liquidity.ts import { PublicKey, TransactionInstruction, TransactionMessage, VersionedTransaction } from "@solana/web3.js"; import axios4 from "redaxios"; import { signOrSendTX } from "agentix"; async function sanctumAddLiquidity(agent, lstMint, amount, quotedAmount, priorityFee) { try { const client = axios4.create({ baseURL: SANCTUM_TRADE_API_URI }); const response = await client.post("/v1/liquidity/add", { amount, dstLstAcc: null, lstMint, priorityFee: { Auto: { max_unit_price_micro_lamports: priorityFee, unit_limit: 3e5 } }, quotedAmount, signer: agent.wallet.getAddress(), srcLstAcc: null }); const txBuffer = Buffer.from(response.data.tx, "base64"); const { blockhash } = await agent.wallet.getConnection().getLatestBlockhash(); const tx = VersionedTransaction.deserialize(txBuffer); const messages = tx.message; const instructions = messages.compiledInstructions.map((ix) => { return new TransactionInstruction({ programId: messages.staticAccountKeys[ix.programIdIndex], keys: ix.accountKeyIndexes.map((i) => ({ pubkey: messages.staticAccountKeys[i], isSigner: messages.isAccountSigner(i), isWritable: messages.isAccountWritable(i) })), data: Buffer.from(ix.data, "base64") }); }); const newMessage = new TransactionMessage({ payerKey: new PublicKey(agent.wallet.getAddress()), recentBlockhash: blockhash, instructions }).compileToV0Message(); const newTx = new VersionedTransaction(newMessage); return await signOrSendTX(agent, newTx); } catch (error) { throw new Error(`Failed to add liquidity: ${error.message}`); } } // src/tools/sanctum_remove_liquidity.ts import { PublicKey as PublicKey2, TransactionInstruction as TransactionInstruction2, TransactionMessage as TransactionMessage2, VersionedTransaction as VersionedTransaction2 } from "@solana/web3.js"; import axios5 from "redaxios"; import { signOrSendTX as signOrSendTX2 } from "agentix"; async function sanctumRemoveLiquidity(agent, lstMint, amount, quotedAmount, priorityFee) { try { const client = axios5.create({ baseURL: SANCTUM_TRADE_API_URI }); const response = await client.post("/v1/liquidity/remove", { amount, dstLstAcc: null, lstMint, priorityFee: { Auto: { max_unit_price_micro_lamports: priorityFee, unit_limit: 3e5 } }, quotedAmount, signer: agent.wallet.getAddress(), srcLstAcc: null }); const txBuffer = Buffer.from(response.data.tx, "base64"); const { blockhash } = await agent.wallet.getConnection().getLatestBlockhash(); const tx = VersionedTransaction2.deserialize(txBuffer); const messages = tx.message; const instructions = messages.compiledInstructions.map((ix) => { return new TransactionInstruction2({ programId: messages.staticAccountKeys[ix.programIdIndex], keys: ix.accountKeyIndexes.map((i) => ({ pubkey: messages.staticAccountKeys[i], isSigner: messages.isAccountSigner(i), isWritable: messages.isAccountWritable(i) })), data: Buffer.from(ix.data, "base64") }); }); const newMessage = new TransactionMessage2({ payerKey: new PublicKey2(agent.wallet.getAddress()), recentBlockhash: blockhash, instructions }).compileToV0Message(); const newTx = new VersionedTransaction2(newMessage); return await signOrSendTX2(agent, newTx); } catch (error) { throw new Error(`Remove Liquidity failed: ${error.message}`); } } // src/tools/sanctum_get_owned_lst.ts import { TOKEN_PROGRAM_ID } from "@solana/spl-token"; import axios6 from "redaxios"; import { PublicKey as PublicKey3 } from "@solana/web3.js"; async function sanctumGetOwnedLST(agent) { try { const [tokenAccountData] = await Promise.all([ agent.wallet.getConnection().getParsedTokenAccountsByOwner(new PublicKey3(agent.wallet.getAddress()), { programId: TOKEN_PROGRAM_ID }) ]); const removedZeroBalance = tokenAccountData.value.filter( (v) => v.account.data.parsed.info.tokenAmount.uiAmount !== 0 ); const tokens = await Promise.all( removedZeroBalance.map(async (v) => { return { mint: v.account.data.parsed.info.mint, amount: v.account.data.parsed.info.tokenAmount.uiAmount, decimals: v.account.data.parsed.info.tokenAmount.decimals }; }) ); const lsts = tokens.filter((token) => { return token.decimals === 9; }); const addresses = lsts.map((token) => token.mint); const client = axios6.create({ baseURL: SANCTUM_STAT_API_URI }); const response = await client.get("/v1/sol-value/current", { params: { lst: addresses }, paramsSerializer: (params) => { return params.lst.map((value) => `lst=${value}`).join("&"); } }); const result = Object.keys(response.data.solValues); const lstsWithValue = await Promise.all( lsts.map((lst) => { if (result.includes(lst.mint)) { return { mint: lst.mint, amount: lst.amount }; } return null; }).filter((lst) => lst !== null) ); return lstsWithValue; } catch (error) { throw new Error(`Failed to get owned lst: ${error.message}`); } } // src/tools/sanctum_swap_lst.ts import { PublicKey as PublicKey4, VersionedTransaction as VersionedTransaction3 } from "@solana/web3.js"; import { TransactionInstruction as TransactionInstruction3 } from "@solana/web3.js"; import { TransactionMessage as TransactionMessage3 } from "@solana/web3.js"; import axios7 from "redaxios"; import { signOrSendTX as signOrSendTX3 } from "agentix"; async function sanctumSwapLST(agent, inputLstMint, amount, quotedAmount, priorityFee, outputLstMint) { try { const client = axios7.create({ baseURL: SANCTUM_TRADE_API_URI }); const response = await client.post("/v1/swap", { amount, dstLstAcc: null, input: inputLstMint, mode: "ExactIn", priorityFee: { Auto: { max_unit_price_micro_lamports: priorityFee, unit_limit: 3e5 } }, outputLstMint, quotedAmount, signer: agent.wallet.getAddress(), srcLstAcc: null }); const txBuffer = Buffer.from(response.data.tx, "base64"); const { blockhash } = await agent.wallet.getConnection().getLatestBlockhash(); const tx = VersionedTransaction3.deserialize(txBuffer); const messages = tx.message; const instructions = messages.compiledInstructions.map((ix) => { return new TransactionInstruction3({ programId: messages.staticAccountKeys[ix.programIdIndex], keys: ix.accountKeyIndexes.map((i) => ({ pubkey: messages.staticAccountKeys[i], isSigner: messages.isAccountSigner(i), isWritable: messages.isAccountWritable(i) })), data: Buffer.from(ix.data, "base64") }); }); const newMessage = new TransactionMessage3({ payerKey: new PublicKey4(agent.wallet.getAddress()), recentBlockhash: blockhash, instructions }).compileToV0Message(); const newTx = new VersionedTransaction3(newMessage); return await signOrSendTX3(agent, newTx); } catch (error) { throw new Error(`Failed to swap lst: ${error.message}`); } } // src/actions/sanctumGetLSTPrice.ts var sanctumGetLSTPriceAction = { name: "GET_SANCTUM_PRICE", similes: ["get sanctum LST price", "fetch sanctum LST price"], description: "Fetch the Price of a LST(Liquid Staking Token) on Sanctum with specified mint addresses or symbols", examples: [ [ { input: { inputs: [ "INF", "pwrsol", "mSoLzYCxHdYgdzU16g5QSh3i5K3z3KZK7ytfqcJm7So", "laineSOL" ] }, output: { INF: "1303329251", laineSOL: "1221330946", mSoLzYCxHdYgdzU16g5QSh3i5K3z3KZK7ytfqcJm7So: "1279055247", pwrsol: "1105899448" }, explanation: "Fetch the prices of LSTs on Sanctum" } ] ], schema: z.object({ mints: z.array(z.string()) }), handler: async (_agent, input) => { try { const prices = await sanctumGetLSTPrice(input.mints); return { status: "success", message: "Price fetched successfully", prices }; } catch (error) { return { status: "error", message: `Fetching Sanctum LST price failed: ${error.message}` }; } } }; // src/actions/sanctumGetLSTTVL.ts import { z as z2 } from "zod"; var sanctumGetLSTTVLAction = { name: "GET_SANCTUM_TVL", similes: ["get sanctum LST TVL", "fetch sanctum LST TVL"], description: "Fetch the TVL of a LST(Liquid Staking Token) on Sanctum with specified mint addresses or symbols", examples: [ [ { input: { inputs: [ "INF", "pwrsol", "mSoLzYCxHdYgdzU16g5QSh3i5K3z3KZK7ytfqcJm7So", "laineSOL" ] }, output: { pwrsol: "3100602224977", INF: "620838653321879", mSoLzYCxHdYgdzU16g5QSh3i5K3z3KZK7ytfqcJm7So: "4892112998338119", laineSOL: "55512833109331" }, explanation: "Fetch the TVL of LSTs on Sanctum" } ] ], schema: z2.object({ inputs: z2.array(z2.string()) }), handler: async (_agent, input) => { try { const tvls = await sanctumGetLSTTVL(input.inputs); return { status: "success", message: "TVL fetched successfully", tvls }; } catch (error) { return { status: "error", message: `Fetching Sanctum LST TVL failed: ${error.message}` }; } } }; // src/actions/sanctumGetLSTAPY.ts import { z as z3 } from "zod"; var sanctumGetLSTAPYAction = { name: "GET_SANCTUM_APY", similes: ["get sanctum LST APY", "fetch sanctum LST APY"], description: "Fetch the APY of a LST(Liquid Staking Token) on Sanctum with specified mint addresses or symbols", examples: [ [ { input: { inputs: [ "INF", "pwrsol", "mSoLzYCxHdYgdzU16g5QSh3i5K3z3KZK7ytfqcJm7So", "laineSOL" ] }, output: { pwrsol: 0.08321988140942367, laineSOL: 0.0831767225669587, INF: 0.06542961909093714, mSoLzYCxHdYgdzU16g5QSh3i5K3z3KZK7ytfqcJm7So: 0.08143705823579084 }, explanation: "Fetch the APY of LSTs on Sanctum" } ] ], schema: z3.object({ inputs: z3.array(z3.string()) }), handler: async (_agent, input) => { try { const apys = await sanctumGetLSTAPY(input.inputs); return { status: "success", message: "APY fetched successfully", apys }; } catch (error) { return { status: "error", message: `Fetching Sanctum LST APY failed: ${error.message}` }; } } }; // src/actions/sanctumAddLiquidity.ts import { z as z4 } from "zod"; var sanctumAddLiquidityAction = { name: "SANCTUM_ADD_LIQUIDITY", similes: ["add liquidity to sanctum pool", "deposit to sanctum pool"], description: "Add liquidity to a Sanctum pool with specified parameters", examples: [ [ { input: { lstMint: "So11111111111111111111111111111111111111112", amount: "1000000000", quotedAmount: "900000000", priorityFee: 5e3 }, output: { status: "success", message: "Liquidity added successfully", txId: "2jg87stmvPygRXJrqfpydZQSzGJK9rKvawekzy5mzuEmSjRf8bCmiGpFH8iLa2YrQxtreWcK99319DVTpCJHYZfx" }, explanation: "Add liquidity to a Sanctum pool" } ] ], schema: z4.object({ lstMint: z4.string(), amount: z4.string(), quotedAmount: z4.string(), priorityFee: z4.number() }), handler: async (agent, input) => { try { const result = await sanctumAddLiquidity( agent, input.lstMint, input.amount, input.quotedAmount, input.priorityFee ); return { status: "success", message: typeof result === "string" ? "Liquidity added successfully" : "Liquidity addition transaction generated successfully. Please send the transaction to the network.", transaction: result }; } catch (error) { return { status: "error", message: `Adding liquidity to Sanctum pool failed: ${error.message}` }; } } }; // src/actions/sanctumRemoveLiquidity.ts import { z as z5 } from "zod"; var sanctumRemoveLiquidityAction = { name: "SANCTUM_REMOVE_LIQUIDITY", similes: ["remove liquidity from sanctum pool", "withdraw from sanctum pool"], description: "Remove liquidity from a Sanctum pool with specified parameters", examples: [ [ { input: { lstMint: "So11111111111111111111111111111111111111112", amount: "1000000000", quotedAmount: "900000000", priorityFee: 5e3 }, output: { status: "success", message: "Liquidity removed successfully", txId: "2FqduazbmVrYAs6VMj7whKvFhEJnCyCvm7GiX4xCj1FSVr4CquPqFoCPDokUuJJ3T24EpXLPxrJWmGq6EnpsrJWf" }, explanation: "Remove liquidity from a Sanctum pool" } ] ], schema: z5.object({ lstMint: z5.string(), amount: z5.string(), quotedAmount: z5.string(), priorityFee: z5.number() }), handler: async (agent, input) => { try { const result = await sanctumRemoveLiquidity( agent, input.lstMint, input.amount, input.quotedAmount, input.priorityFee ); return { status: "success", message: typeof result === "string" ? "Liquidity removed successfully" : "Liquidity removal transaction generated and signed succesfully. Please send it to the network.", transaction: result }; } catch (error) { return { status: "error", message: `Removing liquidity from Sanctum pool failed: ${error.message}` }; } } }; // src/actions/sanctumGetOwnedLST.ts import { z as z6 } from "zod"; var sanctumGetOwnedLSTAction = { name: "SANCTUM_GET_OWNED_LST", similes: [ "get owned lst", "get owned lst tokens", "get owned lst assets", "get owned lst assets list" ], description: "Fetch the owned LST(Liquid Staking Token) on Sanctum with specified account", examples: [ [ { input: {}, output: { lsts: [ { mint: "mSoLzYCxHdYgdzU16g5QSh3i5K3z3KZK7ytfqcJm7So", balance: 35e-4 } ] }, explanation: "Owned LSTs fetched successfully" } ] ], schema: z6.object({}), handler: async (agent) => { try { const result = await sanctumGetOwnedLST(agent); return { status: "success", message: "Owned LSTs fetched successfully", lsts: result }; } catch (error) { return { status: "error", message: `Fetching owned LSTs failed: ${error.message}` }; } } }; // src/actions/sanctumSwapLST.ts import { z as z7 } from "zod"; var sanctumSwapLSTAction = { name: "SANCTUM_SWAP_LST", similes: ["swap lst in sanctum", "swap lst", "trade lst in sanctum"], description: `Swap LST(Liquid Staking Token) on Sanctum with specified parameters`, examples: [ [ { input: { inputLstMint: "So11111111111111111111111111111111111111112", amount: "1000000000", quotedAmount: "900000000", priorityFee: 5e3, outputLstMint: "bSo13r4TkiE4KumL71LsHTPpL2euBYLFx6h9HP3piy1" }, output: { status: "success", message: "LST swapped successfully", txId: "2FqduazbmVrYAs6VMj7whKvFhEJnCyCvm7GiX4xCj1FSVr4CquPqFoCPDokUuJJ3T24EpXLPxrJWmGq6EnpsrJWf" }, explanation: "Swap lst successfully on Sanctum" } ] ], schema: z7.object({ inputLstMint: z7.string(), amount: z7.string(), quotedAmount: z7.string(), priorityFee: z7.number(), outputLstMint: z7.string() }), handler: async (agent, input) => { try { const result = await sanctumSwapLST( agent, input.inputLstMint, input.amount, input.quotedAmount, input.priorityFee, input.outputLstMint ); return { status: "success", message: typeof result === "string" ? "LST swapped successfully" : "LST swap transaction signed successfully. Please send the transaction to the network.", transaction: result }; } catch (error) { return { status: "error", message: `Swapping LST on Sanctum failed: ${error.message}` }; } } }; // src/index.ts var SanctumPlugin = class extends PluginBase { constructor() { const methods = { sanctumAddLiquidity, sanctumGetLSTAPY, sanctumGetLSTPrice, sanctumGetLSTTVL, sanctumGetOwnedLST, sanctumRemoveLiquidity, sanctumSwapLST }; const actions = [ sanctumAddLiquidityAction, sanctumGetLSTAPYAction, sanctumGetLSTPriceAction, sanctumGetLSTTVLAction, sanctumGetOwnedLSTAction, sanctumRemoveLiquidityAction, sanctumSwapLSTAction ]; const supportedChains = [ { type: "solana" } ]; super("sanctum", methods, actions, supportedChains); } supportsWallet(wallet) { return wallet instanceof SolanaWalletBase4; } }; var index_default = SanctumPlugin; export { index_default as default };