From c71f2159fdd13f821bea3b14b35aeaa234239245 Mon Sep 17 00:00:00 2001 From: jakeyvee Date: Wed, 15 Jan 2025 18:15:35 +0800 Subject: [PATCH] fix: changes for Voltr vault program upgrade --- package.json | 2 +- pnpm-lock.yaml | 10 +-- src/agent/index.ts | 6 +- src/langchain/index.ts | 10 +-- src/tools/index.ts | 2 +- src/tools/voltr_deposit_strategy.ts | 88 ++++++++++++++-------- src/tools/voltr_get_asset_amount.ts | 33 -------- src/tools/voltr_get_position_values.ts | 20 +++++ src/tools/voltr_withdraw_strategy.ts | 100 +++++++++++++------------ 9 files changed, 141 insertions(+), 130 deletions(-) delete mode 100644 src/tools/voltr_get_asset_amount.ts create mode 100644 src/tools/voltr_get_position_values.ts diff --git a/package.json b/package.json index f34069a..9366317 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,7 @@ "@tensor-oss/tensorswap-sdk": "^4.5.0", "@solana/web3.js": "^1.98.0", "@tiplink/api": "^0.3.1", - "@voltr/sdk": "^0.1.0", + "@voltr/vault-sdk": "^0.1.1", "bn.js": "^5.2.1", "bs58": "^6.0.0", "chai": "^5.1.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 754d7ac..0851b6d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -80,9 +80,9 @@ dependencies: '@tiplink/api': specifier: ^0.3.1 version: 0.3.1(fastestsmallesttextencoderdecoder@1.0.22)(sodium-native@3.4.1) - '@voltr/sdk': - specifier: ^0.1.0 - version: 0.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.7.2) + '@voltr/vault-sdk': + specifier: ^0.1.1 + version: 0.1.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.7.2) ai: specifier: ^4.0.22 version: 4.0.25(react@19.0.0)(zod@3.24.1) @@ -2303,8 +2303,8 @@ packages: /@ungap/structured-clone@1.2.1: resolution: {integrity: sha512-fEzPV3hSkSMltkw152tJKNARhOupqbH96MZWyRjNaYZOMIzbrTeQDG+MTc6Mr2pgzFQzFxAfmhGDNP5QK++2ZA==} - /@voltr/sdk@0.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.7.2): - resolution: {integrity: sha512-iLb0zc3ClZYJ9DBgMeuONSnZKa8r54MGj2LfN+4ZXXDx/O+ssjuuFPE+tcmWU0tL0yfHOLRgwWEPc4yynWG3Rg==} + /@voltr/vault-sdk@0.1.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.7.2): + resolution: {integrity: sha512-xh8bxPCwNpjVqEN32+Q40Xf08vdORAmQACDE6ru3T+9qrwNgraLcPEzvWeBNTE0FAMAZdNsYOxWbc2FSK0ZQww==} dependencies: '@coral-xyz/anchor': 0.30.1 '@solana/spl-token': 0.4.9(@solana/web3.js@1.98.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.7.2) diff --git a/src/agent/index.ts b/src/agent/index.ts index 3f811bd..f5c44e8 100644 --- a/src/agent/index.ts +++ b/src/agent/index.ts @@ -55,7 +55,7 @@ import { fetchTokenReportSummary, fetchTokenDetailedReport, OrderParams, - voltrGetAssetAmount, + voltrGetPositionValues, voltrDepositStrategy, voltrWithdrawStrategy, } from "../tools"; @@ -517,7 +517,7 @@ export class SolanaAgentKit { return voltrWithdrawStrategy(this, withdrawAmount, vault, strategy); } - async voltrGetAssetAmount(vault: PublicKey): Promise { - return voltrGetAssetAmount(this, vault); + async voltrGetPositionValues(vault: PublicKey): Promise { + return voltrGetPositionValues(this, vault); } } diff --git a/src/langchain/index.ts b/src/langchain/index.ts index 2fbe3cc..78f130e 100644 --- a/src/langchain/index.ts +++ b/src/langchain/index.ts @@ -2083,9 +2083,9 @@ export class SolanaVoltrWithdrawStrategy extends Tool { } } -export class SolanaVoltrGetAssetAmount extends Tool { - name = "solana_voltr_get_asset_amount"; - description = `Get the total asset amount and current amount for each strategy of a given Voltr vault +export class SolanaVoltrGetPositionValues extends Tool { + name = "solana_voltr_get_position_values"; + description = `Get the total asset value and current value for each strategy of a given Voltr vault Inputs: vault: string (required) @@ -2094,7 +2094,7 @@ export class SolanaVoltrGetAssetAmount extends Tool { super(); } async _call(input: string): Promise { - return this.solanaKit.voltrGetAssetAmount(new PublicKey(input)); + return this.solanaKit.voltrGetPositionValues(new PublicKey(input)); } } @@ -2152,6 +2152,6 @@ export function createSolanaTools(solanaKit: SolanaAgentKit) { new SolanaFetchTokenDetailedReportTool(solanaKit), new SolanaVoltrDepositStrategy(solanaKit), new SolanaVoltrWithdrawStrategy(solanaKit), - new SolanaVoltrGetAssetAmount(solanaKit), + new SolanaVoltrGetPositionValues(solanaKit), ]; } diff --git a/src/tools/index.ts b/src/tools/index.ts index 2e6f4db..6c4cea0 100644 --- a/src/tools/index.ts +++ b/src/tools/index.ts @@ -61,4 +61,4 @@ export * from "./rugcheck"; export * from "./voltr_deposit_strategy"; export * from "./voltr_withdraw_strategy"; -export * from "./voltr_get_asset_amount"; \ No newline at end of file +export * from "./voltr_get_position_values"; \ No newline at end of file diff --git a/src/tools/voltr_deposit_strategy.ts b/src/tools/voltr_deposit_strategy.ts index 4d2aa22..bd94824 100644 --- a/src/tools/voltr_deposit_strategy.ts +++ b/src/tools/voltr_deposit_strategy.ts @@ -1,10 +1,11 @@ -import { VoltrClient } from "@voltr/sdk"; +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"; /** @@ -22,13 +23,21 @@ export async function voltrDepositStrategy( strategy: PublicKey, ): Promise { const vc = new VoltrClient(agent.connection, agent.wallet); - const { vaultAssetIdleAuth } = vc.findVaultAddresses(vault); const vaultAccount = await vc.fetchVaultAccount(vault); - const vaultAssetMint = vaultAccount.asset.assetMint; - const strategyAccount = await vc.fetchStrategyAccount(strategy); - const liquidityReserve = strategyAccount.counterpartyAssetTa; - const protocolProgram = strategyAccount.protocolProgram; - const vaultStrategy = vc.findVaultStrategy(vaultAssetIdleAuth, strategy); + 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()}`, @@ -41,37 +50,50 @@ export async function voltrDepositStrategy( ); const data = (await response.json()).data as { - pubkey: string; - isSigner: boolean; - isWritable: boolean; - }[]; + instructionDiscriminator: number[] | null; + additionalArgs: number[] | null; + remainingAccounts: + | { + pubkey: string; + isSigner: boolean; + isWritable: boolean; + }[] + | null; + }; - const remainingAccounts = data.map((account) => ({ - pubkey: new PublicKey(account.pubkey), - isSigner: account.isSigner, - isWritable: account.isWritable, - })); + 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, { - vault, - vaultAssetMint, - strategy: strategy, - vaultStrategy: vaultStrategy, - counterpartyAssetTa: liquidityReserve, - protocolProgram: protocolProgram, - remainingAccounts, - }); + 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], - { - commitment: "confirmed", - }, - ); + const txSig = await sendAndConfirmTransaction(agent.connection, transaction, [ + agent.wallet, + ]); return txSig; } diff --git a/src/tools/voltr_get_asset_amount.ts b/src/tools/voltr_get_asset_amount.ts deleted file mode 100644 index 9d16923..0000000 --- a/src/tools/voltr_get_asset_amount.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { VoltrClient } from "@voltr/sdk"; -import { SolanaAgentKit } from "../agent"; -import { PublicKey } from "@solana/web3.js"; -import BN from "bn.js"; - -/** - * Deposits assets into a Voltr strategy - * @param agent SolanaAgentKit instance - * @param vault Public key of the target vault - * @returns Transaction signature for the deposit - */ -export async function voltrGetAssetAmount( - agent: SolanaAgentKit, - vault: PublicKey, -): Promise { - const vc = new VoltrClient(agent.connection, agent.wallet); - const vaultAccount = await vc.fetchVaultAccount(vault); - const totalAssetAmount: BN = vaultAccount.asset.totalAmount; - const { vaultAssetIdleAuth } = vc.findVaultAddresses(vault); - const vaultStrategyAccounts = - await vc.fetchVaultStrategyAccounts(vaultAssetIdleAuth); - const strategyInfo = vaultStrategyAccounts.map((vaultStrategyAccount) => ({ - strategyId: vaultStrategyAccount.account.strategy.toBase58(), - amount: vaultStrategyAccount.account.currentAmount.toString(), - })); - - const result = { - totalAmount: totalAssetAmount.toString(), - strategies: strategyInfo, - }; - - return JSON.stringify(result); -} diff --git a/src/tools/voltr_get_position_values.ts b/src/tools/voltr_get_position_values.ts new file mode 100644 index 0000000..43ecff3 --- /dev/null +++ b/src/tools/voltr_get_position_values.ts @@ -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 { + const vc = new VoltrClient(agent.connection, agent.wallet); + const positionAndTotalValues = + await vc.getPositionAndTotalValuesForVault(vault); + + return JSON.stringify(positionAndTotalValues); +} diff --git a/src/tools/voltr_withdraw_strategy.ts b/src/tools/voltr_withdraw_strategy.ts index 6e8ed27..ef567b5 100644 --- a/src/tools/voltr_withdraw_strategy.ts +++ b/src/tools/voltr_withdraw_strategy.ts @@ -1,4 +1,3 @@ -import { VoltrClient } from "@voltr/sdk"; import { SolanaAgentKit } from "../agent"; import { PublicKey, @@ -6,12 +5,8 @@ import { Transaction, } from "@solana/web3.js"; import BN from "bn.js"; -import { - Account, - getAccount, - TOKEN_2022_PROGRAM_ID, - TOKEN_PROGRAM_ID, -} from "@solana/spl-token"; +import { TOKEN_2022_PROGRAM_ID, TOKEN_PROGRAM_ID } from "@solana/spl-token"; +import { VoltrClient } from "@voltr/vault-sdk"; /** * Withdraws assets from a Voltr strategy @@ -28,34 +23,24 @@ export async function voltrWithdrawStrategy( strategy: PublicKey, ): Promise { const vc = new VoltrClient(agent.connection, agent.wallet); - const { vaultAssetIdleAuth } = vc.findVaultAddresses(vault); const vaultAccount = await vc.fetchVaultAccount(vault); - const vaultAssetMint = vaultAccount.asset.assetMint; - const strategyAccount = await vc.fetchStrategyAccount(strategy); - const liquidityReserve = strategyAccount.counterpartyAssetTa; - const protocolProgram = strategyAccount.protocolProgram; - const vaultStrategy = vc.findVaultStrategy(vaultAssetIdleAuth, strategy); + const vaultAssetMint = vaultAccount.asset.mint; + const assetTokenProgram = await agent.connection + .getAccountInfo(new PublicKey(vaultAssetMint)) + .then((account) => account?.owner); - let liquidityReserveAccount: Account; - try { - liquidityReserveAccount = await getAccount( - agent.connection, - liquidityReserve, - "confirmed", - TOKEN_PROGRAM_ID, - ); - } catch (error) { - liquidityReserveAccount = await getAccount( - agent.connection, - liquidityReserve, - "confirmed", - TOKEN_2022_PROGRAM_ID, - ); + if ( + !assetTokenProgram || + !( + assetTokenProgram.equals(TOKEN_PROGRAM_ID) || + assetTokenProgram.equals(TOKEN_2022_PROGRAM_ID) + ) + ) { + throw new Error("Invalid asset token program"); } - const liquidityReserveAuth = liquidityReserveAccount.owner; const response = await fetch( - `https://voltr.xyz/api/remaining-accounts/withdraw-strategy?vault=${vault.toBase58()}&strategy=${strategy.toBase58()}`, + `https://voltr.xyz/api/remaining-accounts/deposit-strategy?vault=${vault.toBase58()}&strategy=${strategy.toBase58()}`, { method: "GET", headers: { @@ -65,27 +50,44 @@ export async function voltrWithdrawStrategy( ); const data = (await response.json()).data as { - pubkey: string; - isSigner: boolean; - isWritable: boolean; - }[]; + instructionDiscriminator: number[] | null; + additionalArgs: number[] | null; + remainingAccounts: + | { + pubkey: string; + isSigner: boolean; + isWritable: boolean; + }[] + | null; + }; - const remainingAccounts = data.map((account) => ({ - pubkey: new PublicKey(account.pubkey), - isSigner: account.isSigner, - isWritable: account.isWritable, - })); + 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, { - vault, - vaultAssetMint, - strategy: strategy, - vaultStrategy: vaultStrategy, - counterpartyAssetTa: liquidityReserve, - counterpartyAssetTaAuth: liquidityReserveAuth, - protocolProgram: protocolProgram, - remainingAccounts, - }); + const withdrawIx = await vc.createWithdrawStrategyIx( + { + withdrawAmount, + additionalArgs, + instructionDiscriminator, + }, + { + vault, + vaultAssetMint, + strategy, + assetTokenProgram, + remainingAccounts, + }, + ); const transaction = new Transaction(); transaction.add(withdrawIx);