@agentix/plugin-solana-sanctum
Version:
682 lines (663 loc) • 20.1 kB
JavaScript
// 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
};