mirror of
https://github.com/d0zingcat/solana-agent-kit.git
synced 2026-05-28 15:11:17 +00:00
Add Voltr check balance, deposit and withdraw strategy (#128)
# Pull Request Description ## Related Issue Fixes # (issue number) ## Changes Made This PR adds the following changes: <!-- List the key changes made in this PR --> - Query Voltr vault and strategies balances - Withdraw from Voltr strategies - Deposit into Voltr strategies ## Implementation Details <!-- Provide technical details about the implementation --> - utilises Voltr's SDK `@voltr/sdk` to instantiate a `VoltrClient` - find and fetch relevant accounts to create instructions using `VoltrClient` ## Transaction executed by agent <!-- If applicable, provide example usage, transactions, or screenshots --> Example transaction: https://solana.fm/tx/GnUd38TMhtBYNv29nNAyESEWLwjHhUW6hraNrPE3RTF6LtdqNtnoBBqEKptT5JaWqv6TiFp6MeooUa9Rt7vMAu9?cluster=mainnet-alpha Demo: https://x.com/voltrxyz/status/1875204418465059189 ## Prompt Used <!-- If relevant, include the prompt or configuration used --> Tested on autonomous mode. ``` async function runAutonomousMode(agent: any, config: any, interval = 10) { console.log("Starting autonomous mode..."); let iterations = 0; while (true) { try { const evenThought = "1. Get the total amount and amount for each strategy of a Voltr vault: 3ab3KVY9GbDbUUbRnYNSBDQqABTDup7HmdgADHGpB8Bq. " + "2. Take note of the strategies id with the their respective amount. " + "3. Calculate the sum of all strategy amounts. " + "4. Subtract that sum from the vault total to get the excess amount. " + "5. Indicate the excess amount and the strategy id with the lowest amount."; const oddThought = "Using the latest excess amount, if it is 0 then do nothing. " + "Else if it is more than 0, deposit the excess amount into the lowest strategy and vault: 3ab3KVY9GbDbUUbRnYNSBDQqABTDup7HmdgADHGpB8Bq."; const thought = iterations % 2 === 0 ? evenThought : oddThought; const stream = await agent.stream( { messages: [new HumanMessage(thought)] }, config, ); for await (const chunk of stream) { if ("agent" in chunk) { for (const message of chunk.agent.messages) { console.log(message.content); } } else if ("tools" in chunk) { for (const message of chunk.tools.messages) { console.log(message.content); } } console.log("-------------------"); } iterations++; await new Promise((resolve) => setTimeout(resolve, interval * 1000)); } catch (error) { if (error instanceof Error) { console.error("Error:", error.message); } process.exit(1); } } } ``` ## Additional Notes <!-- Any additional information that reviewers should know --> ## Checklist - [x] I have tested these changes locally - [x] I have updated the documentation - [x] I have added a transaction link - [x] I have added the prompt used to test it
This commit is contained in:
@@ -25,3 +25,4 @@ export * from "./tiplink";
|
||||
export * from "./lightprotocol";
|
||||
export * from "./squads";
|
||||
export * from "./helius";
|
||||
export * from "./voltr";
|
||||
|
||||
3
src/tools/voltr/index.ts
Normal file
3
src/tools/voltr/index.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export * from "./voltr_deposit_strategy";
|
||||
export * from "./voltr_withdraw_strategy";
|
||||
export * from "./voltr_get_position_values";
|
||||
99
src/tools/voltr/voltr_deposit_strategy.ts
Normal file
99
src/tools/voltr/voltr_deposit_strategy.ts
Normal file
@@ -0,0 +1,99 @@
|
||||
import { TOKEN_PROGRAM_ID, TOKEN_2022_PROGRAM_ID } from "@solana/spl-token";
|
||||
import { SolanaAgentKit } from "../../agent";
|
||||
import {
|
||||
PublicKey,
|
||||
sendAndConfirmTransaction,
|
||||
Transaction,
|
||||
} from "@solana/web3.js";
|
||||
import { VoltrClient } from "@voltr/vault-sdk";
|
||||
import BN from "bn.js";
|
||||
|
||||
/**
|
||||
* Deposits assets into a Voltr strategy
|
||||
* @param agent SolanaAgentKit instance
|
||||
* @param depositAmount Amount to deposit in base units (BN)
|
||||
* @param vault Public key of the target vault
|
||||
* @param strategy Public key of the target strategy
|
||||
* @returns Transaction signature for the deposit
|
||||
*/
|
||||
export async function voltrDepositStrategy(
|
||||
agent: SolanaAgentKit,
|
||||
depositAmount: BN,
|
||||
vault: PublicKey,
|
||||
strategy: PublicKey,
|
||||
): Promise<string> {
|
||||
const vc = new VoltrClient(agent.connection, agent.wallet);
|
||||
const vaultAccount = await vc.fetchVaultAccount(vault);
|
||||
const vaultAssetMint = vaultAccount.asset.mint;
|
||||
const assetTokenProgram = await agent.connection
|
||||
.getAccountInfo(new PublicKey(vaultAssetMint))
|
||||
.then((account) => account?.owner);
|
||||
|
||||
if (
|
||||
!assetTokenProgram ||
|
||||
!(
|
||||
assetTokenProgram.equals(TOKEN_PROGRAM_ID) ||
|
||||
assetTokenProgram.equals(TOKEN_2022_PROGRAM_ID)
|
||||
)
|
||||
) {
|
||||
throw new Error("Invalid asset token program");
|
||||
}
|
||||
|
||||
const response = await fetch(
|
||||
`https://voltr.xyz/api/remaining-accounts/deposit-strategy?vault=${vault.toBase58()}&strategy=${strategy.toBase58()}`,
|
||||
{
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
const data = (await response.json()).data as {
|
||||
instructionDiscriminator: number[] | null;
|
||||
additionalArgs: number[] | null;
|
||||
remainingAccounts:
|
||||
| {
|
||||
pubkey: string;
|
||||
isSigner: boolean;
|
||||
isWritable: boolean;
|
||||
}[]
|
||||
| null;
|
||||
};
|
||||
|
||||
const additionalArgs = data.additionalArgs
|
||||
? Buffer.from(data.additionalArgs)
|
||||
: null;
|
||||
const instructionDiscriminator = data.instructionDiscriminator
|
||||
? Buffer.from(data.instructionDiscriminator)
|
||||
: null;
|
||||
const remainingAccounts =
|
||||
data.remainingAccounts?.map((account) => ({
|
||||
pubkey: new PublicKey(account.pubkey),
|
||||
isSigner: account.isSigner,
|
||||
isWritable: account.isWritable,
|
||||
})) ?? [];
|
||||
|
||||
const depositIx = await vc.createDepositStrategyIx(
|
||||
{
|
||||
depositAmount,
|
||||
additionalArgs,
|
||||
instructionDiscriminator,
|
||||
},
|
||||
{
|
||||
vault,
|
||||
vaultAssetMint,
|
||||
strategy: strategy,
|
||||
assetTokenProgram,
|
||||
remainingAccounts,
|
||||
},
|
||||
);
|
||||
|
||||
const transaction = new Transaction();
|
||||
transaction.add(depositIx);
|
||||
|
||||
const txSig = await sendAndConfirmTransaction(agent.connection, transaction, [
|
||||
agent.wallet,
|
||||
]);
|
||||
return txSig;
|
||||
}
|
||||
20
src/tools/voltr/voltr_get_position_values.ts
Normal file
20
src/tools/voltr/voltr_get_position_values.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import { SolanaAgentKit } from "../../agent";
|
||||
import { PublicKey } from "@solana/web3.js";
|
||||
import { VoltrClient } from "@voltr/vault-sdk";
|
||||
|
||||
/**
|
||||
* Gets the value of assets in a Voltr vault
|
||||
* @param agent SolanaAgentKit instance
|
||||
* @param vault Public key of the target vault
|
||||
* @returns Position and total values for the vault
|
||||
*/
|
||||
export async function voltrGetPositionValues(
|
||||
agent: SolanaAgentKit,
|
||||
vault: PublicKey,
|
||||
): Promise<string> {
|
||||
const vc = new VoltrClient(agent.connection, agent.wallet);
|
||||
const positionAndTotalValues =
|
||||
await vc.getPositionAndTotalValuesForVault(vault);
|
||||
|
||||
return JSON.stringify(positionAndTotalValues);
|
||||
}
|
||||
99
src/tools/voltr/voltr_withdraw_strategy.ts
Normal file
99
src/tools/voltr/voltr_withdraw_strategy.ts
Normal file
@@ -0,0 +1,99 @@
|
||||
import { SolanaAgentKit } from "../../agent";
|
||||
import {
|
||||
PublicKey,
|
||||
sendAndConfirmTransaction,
|
||||
Transaction,
|
||||
} from "@solana/web3.js";
|
||||
import BN from "bn.js";
|
||||
import { TOKEN_2022_PROGRAM_ID, TOKEN_PROGRAM_ID } from "@solana/spl-token";
|
||||
import { VoltrClient } from "@voltr/vault-sdk";
|
||||
|
||||
/**
|
||||
* Withdraws assets from a Voltr strategy
|
||||
* @param agent SolanaAgentKit instance
|
||||
* @param withdrawAmount Amount to withdraw in base units (BN)
|
||||
* @param vault Public key of the target vault
|
||||
* @param strategy Public key of the target strategy
|
||||
* @returns Transaction signature for the deposit
|
||||
*/
|
||||
export async function voltrWithdrawStrategy(
|
||||
agent: SolanaAgentKit,
|
||||
withdrawAmount: BN,
|
||||
vault: PublicKey,
|
||||
strategy: PublicKey,
|
||||
): Promise<string> {
|
||||
const vc = new VoltrClient(agent.connection, agent.wallet);
|
||||
const vaultAccount = await vc.fetchVaultAccount(vault);
|
||||
const vaultAssetMint = vaultAccount.asset.mint;
|
||||
const assetTokenProgram = await agent.connection
|
||||
.getAccountInfo(new PublicKey(vaultAssetMint))
|
||||
.then((account) => account?.owner);
|
||||
|
||||
if (
|
||||
!assetTokenProgram ||
|
||||
!(
|
||||
assetTokenProgram.equals(TOKEN_PROGRAM_ID) ||
|
||||
assetTokenProgram.equals(TOKEN_2022_PROGRAM_ID)
|
||||
)
|
||||
) {
|
||||
throw new Error("Invalid asset token program");
|
||||
}
|
||||
|
||||
const response = await fetch(
|
||||
`https://voltr.xyz/api/remaining-accounts/deposit-strategy?vault=${vault.toBase58()}&strategy=${strategy.toBase58()}`,
|
||||
{
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
const data = (await response.json()).data as {
|
||||
instructionDiscriminator: number[] | null;
|
||||
additionalArgs: number[] | null;
|
||||
remainingAccounts:
|
||||
| {
|
||||
pubkey: string;
|
||||
isSigner: boolean;
|
||||
isWritable: boolean;
|
||||
}[]
|
||||
| null;
|
||||
};
|
||||
|
||||
const additionalArgs = data.additionalArgs
|
||||
? Buffer.from(data.additionalArgs)
|
||||
: null;
|
||||
const instructionDiscriminator = data.instructionDiscriminator
|
||||
? Buffer.from(data.instructionDiscriminator)
|
||||
: null;
|
||||
const remainingAccounts =
|
||||
data.remainingAccounts?.map((account) => ({
|
||||
pubkey: new PublicKey(account.pubkey),
|
||||
isSigner: account.isSigner,
|
||||
isWritable: account.isWritable,
|
||||
})) ?? [];
|
||||
|
||||
const withdrawIx = await vc.createWithdrawStrategyIx(
|
||||
{
|
||||
withdrawAmount,
|
||||
additionalArgs,
|
||||
instructionDiscriminator,
|
||||
},
|
||||
{
|
||||
vault,
|
||||
vaultAssetMint,
|
||||
strategy,
|
||||
assetTokenProgram,
|
||||
remainingAccounts,
|
||||
},
|
||||
);
|
||||
|
||||
const transaction = new Transaction();
|
||||
transaction.add(withdrawIx);
|
||||
|
||||
const txSig = await sendAndConfirmTransaction(agent.connection, transaction, [
|
||||
agent.wallet,
|
||||
]);
|
||||
return txSig;
|
||||
}
|
||||
Reference in New Issue
Block a user