@kamino-finance/klend-sdk 6.0.0 → 6.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -9,6 +9,7 @@ import {
9
9
  generateKeyPairSigner,
10
10
  GetAccountInfoApi,
11
11
  getAddressEncoder,
12
+ getBase58Decoder,
12
13
  GetProgramAccountsDatasizeFilter,
13
14
  GetProgramAccountsMemcmpFilter,
14
15
  getProgramDerivedAddress,
@@ -81,7 +82,6 @@ import {
81
82
  U64_MAX,
82
83
  VAULT_INITIAL_DEPOSIT,
83
84
  } from '../utils';
84
- import bs58 from 'bs58';
85
85
  import { getAccountOwner, getProgramAccounts } from '../utils/rpc';
86
86
  import {
87
87
  AcceptVaultOwnershipIxs,
@@ -98,7 +98,7 @@ import {
98
98
  } from './vault_types';
99
99
  import { batchFetch, collToLamportsDecimal, ZERO } from '@kamino-finance/kliquidity-sdk';
100
100
  import { FullBPSDecimal } from '@kamino-finance/kliquidity-sdk/dist/utils/CreationParameters';
101
- import { FarmState } from '@kamino-finance/farms-sdk/dist';
101
+ import { FarmIncentives, FarmState } from '@kamino-finance/farms-sdk/dist';
102
102
  import { getAccountsInLut, initLookupTableIx } from '../utils/lookupTable';
103
103
  import {
104
104
  getFarmStakeIxs,
@@ -120,6 +120,7 @@ import { SYSVAR_INSTRUCTIONS_ADDRESS, SYSVAR_RENT_ADDRESS } from '@solana/sysvar
120
120
  import { noopSigner } from '../utils/signer';
121
121
  import { getExtendLookupTableInstruction } from '@solana-program/address-lookup-table';
122
122
  import { Farms } from '@kamino-finance/farms-sdk';
123
+ import { getFarmIncentives } from '@kamino-finance/farms-sdk/dist/utils/apy';
123
124
 
124
125
  export const kaminoVaultId = address('KvauGMspG5k6rtzrqqn7WNn3oZdyKqLKwK2XWQ8FLjd');
125
126
  export const kaminoVaultStagingId = address('stKvQfwRsQiKnLtMNVLHKS3exFJmZFsgfzBPWHECUYK');
@@ -136,6 +137,7 @@ export const METADATA_PROGRAM_ID: Address = address('metaqbxxUerdq28cj1RbAWkYQm3
136
137
  export const INITIAL_DEPOSIT_LAMPORTS = 1000;
137
138
 
138
139
  const addressEncoder = getAddressEncoder();
140
+ const base58Decoder = getBase58Decoder();
139
141
 
140
142
  /**
141
143
  * KaminoVaultClient is a class that provides a high-level interface to interact with the Kamino Vault program.
@@ -2043,7 +2045,7 @@ export class KaminoVaultClient {
2043
2045
  {
2044
2046
  memcmp: {
2045
2047
  offset: 0n,
2046
- bytes: bs58.encode(VaultState.discriminator) as Base58EncodedBytes,
2048
+ bytes: base58Decoder.decode(VaultState.discriminator) as Base58EncodedBytes,
2047
2049
  encoding: 'base58',
2048
2050
  },
2049
2051
  },
@@ -2065,7 +2067,7 @@ export class KaminoVaultClient {
2065
2067
  {
2066
2068
  memcmp: {
2067
2069
  offset: 0n,
2068
- bytes: bs58.encode(VaultState.discriminator) as Base58EncodedBytes,
2070
+ bytes: base58Decoder.decode(VaultState.discriminator) as Base58EncodedBytes,
2069
2071
  encoding: 'base58',
2070
2072
  },
2071
2073
  },
@@ -2917,6 +2919,9 @@ export class KaminoVaultClient {
2917
2919
  };
2918
2920
  }
2919
2921
 
2922
+ /**
2923
+ * This will compute the PDA that is used as delegatee in Farms program to compute the user state PDA for vault depositor investing in vault with reserve having a supply farm
2924
+ */
2920
2925
  computeUserFarmStateDelegateePDAForUserInVault(
2921
2926
  farmsProgramId: Address,
2922
2927
  vault: Address,
@@ -2929,6 +2934,30 @@ export class KaminoVaultClient {
2929
2934
  });
2930
2935
  }
2931
2936
 
2937
+ /**
2938
+ * Read the APY of the farm built on top of the vault (farm in vaultState.vaultFarm)
2939
+ * @param vault - the vault to read the farm APY for
2940
+ * @param vaultTokenPrice - the price of the vault token in USD (e.g. 1.0 for USDC)
2941
+ * @param [slot] - the slot to read the farm APY for. Optional. If not provided, the function will read the current slot
2942
+ * @returns the APY of the farm built on top of the vault
2943
+ */
2944
+ async getVaultRewardsAPY(vault: KaminoVault, vaultTokenPrice: Decimal, slot?: Slot): Promise<FarmIncentives> {
2945
+ const vaultState = await vault.getState(this.getConnection());
2946
+ if (vaultState.vaultFarm === DEFAULT_PUBLIC_KEY) {
2947
+ return {
2948
+ incentivesStats: [],
2949
+ totalIncentivesApy: 0,
2950
+ };
2951
+ }
2952
+
2953
+ const tokensPerShare = await this.getTokensPerShareSingleVault(vault, slot);
2954
+ const sharePrice = tokensPerShare.mul(vaultTokenPrice);
2955
+ const stakedTokenMintDecimals = vaultState.sharesMintDecimals.toNumber();
2956
+
2957
+ const farmsClient = new Farms(this.getConnection());
2958
+ return getFarmIncentives(farmsClient, vaultState.vaultFarm, sharePrice, stakedTokenMintDecimals);
2959
+ }
2960
+
2932
2961
  private appendRemainingAccountsForVaultReserves(
2933
2962
  ix: IInstruction,
2934
2963
  vaultReserves: Address[],
@@ -4,6 +4,7 @@ import {
4
4
  appendTransactionMessageInstructions,
5
5
  compileTransactionMessage,
6
6
  createTransactionMessage,
7
+ getBase58Decoder,
7
8
  getCompiledTransactionMessageEncoder,
8
9
  IInstruction,
9
10
  pipe,
@@ -13,9 +14,10 @@ import {
13
14
  } from '@solana/kit';
14
15
  import { INVALID_BUT_SUFFICIENT_FOR_COMPILATION_BLOCKHASH } from './simulate';
15
16
  import { AddressLookupTable } from '@solana-program/address-lookup-table';
16
- import bs58 from 'bs58';
17
17
  import { removeComputeBudgetProgramInstructions } from './priorityFee';
18
18
 
19
+ const base58Decoder = getBase58Decoder();
20
+
19
21
  export async function printMultisigTx(
20
22
  payer: TransactionSigner,
21
23
  ixs: IInstruction[],
@@ -40,6 +42,6 @@ export async function printMultisigTx(
40
42
  const compiled = compileTransactionMessage(transactionMessage);
41
43
  const encodedMessageBytes = getCompiledTransactionMessageEncoder().encode(compiled);
42
44
 
43
- const base58EncodedMessage = bs58.encode(Uint8Array.from(encodedMessageBytes));
45
+ const base58EncodedMessage = base58Decoder.decode(encodedMessageBytes);
44
46
  console.log('Base58 encoded tx:', base58EncodedMessage);
45
47
  }
@@ -1310,6 +1310,22 @@ async function main() {
1310
1310
  console.log('vaultOverview', vaultOverview);
1311
1311
  });
1312
1312
 
1313
+ commands
1314
+ .command('get-vault-farm-apy')
1315
+ .requiredOption('--vault <string>', 'Vault address')
1316
+ .requiredOption('--token-price <number>', 'Vault token price in USD')
1317
+ .option(`--staging`, 'If true, will use the staging programs')
1318
+ .action(async ({ vault, tokenPrice, staging }) => {
1319
+ const env = await initEnv(staging);
1320
+ const slotDuration = await getMedianSlotDurationInMsFromLastEpochs();
1321
+
1322
+ const kaminoManager = new KaminoManager(env.c.rpc, slotDuration, env.klendProgramId, env.kvaultProgramId);
1323
+
1324
+ const kaminoVault = new KaminoVault(address(vault));
1325
+ const farmAPY = await kaminoManager.getVaultFarmRewardsAPY(kaminoVault, new Decimal(tokenPrice));
1326
+ console.log('farmAPY', farmAPY);
1327
+ });
1328
+
1313
1329
  commands
1314
1330
  .command('get-vault-allocation-distribution')
1315
1331
  .requiredOption('--vault <string>', 'Vault address')
@@ -4,6 +4,7 @@ import {
4
4
  appendTransactionMessageInstructions,
5
5
  compileTransactionMessage,
6
6
  createTransactionMessage,
7
+ getBase58Decoder,
7
8
  getCompiledTransactionMessageEncoder,
8
9
  IInstruction,
9
10
  pipe,
@@ -13,9 +14,10 @@ import {
13
14
  } from '@solana/kit';
14
15
  import { INVALID_BUT_SUFFICIENT_FOR_COMPILATION_BLOCKHASH } from './simulate';
15
16
  import { AddressLookupTable } from '@solana-program/address-lookup-table';
16
- import bs58 from 'bs58';
17
17
  import { removeComputeBudgetProgramInstructions } from './priorityFee';
18
18
 
19
+ const base58Decoder = getBase58Decoder();
20
+
19
21
  export async function printMultisigTx(
20
22
  payer: TransactionSigner,
21
23
  ixs: IInstruction[],
@@ -40,6 +42,6 @@ export async function printMultisigTx(
40
42
  const compiled = compileTransactionMessage(transactionMessage);
41
43
  const encodedMessageBytes = getCompiledTransactionMessageEncoder().encode(compiled);
42
44
 
43
- const base58EncodedMessage = bs58.encode(Uint8Array.from(encodedMessageBytes));
45
+ const base58EncodedMessage = base58Decoder.decode(encodedMessageBytes);
44
46
  console.log('Base58 encoded tx:', base58EncodedMessage);
45
47
  }
@@ -1,7 +1,8 @@
1
- import { Address, Base58EncodedBytes, GetProgramAccountsApi, Rpc } from '@solana/kit';
1
+ import { Address, Base58EncodedBytes, getBase58Decoder, GetProgramAccountsApi, Rpc } from '@solana/kit';
2
2
  import { LendingMarket, Obligation, Reserve } from '../@codegen/klend/accounts';
3
3
  import { PROGRAM_ID } from '../@codegen/klend/programId';
4
- import bs58 from 'bs58';
4
+
5
+ const base58Decoder = getBase58Decoder();
5
6
 
6
7
  export async function* getAllObligationAccounts(
7
8
  connection: Rpc<GetProgramAccountsApi>
@@ -17,14 +18,14 @@ export async function* getAllObligationAccounts(
17
18
  {
18
19
  memcmp: {
19
20
  offset: 0n,
20
- bytes: bs58.encode(Obligation.discriminator) as Base58EncodedBytes,
21
+ bytes: base58Decoder.decode(Obligation.discriminator) as Base58EncodedBytes,
21
22
  encoding: 'base58',
22
23
  },
23
24
  },
24
25
  {
25
26
  memcmp: {
26
27
  offset: 64n,
27
- bytes: bs58.encode([i]) as Base58EncodedBytes, // ...via sharding by userId's first byte (just as a source of randomness)
28
+ bytes: base58Decoder.decode(Buffer.from([i])) as Base58EncodedBytes, // ...via sharding by userId's first byte (just as a source of randomness)
28
29
  encoding: 'base58',
29
30
  },
30
31
  },
@@ -51,7 +52,7 @@ export async function* getAllReserveAccounts(
51
52
  {
52
53
  memcmp: {
53
54
  offset: 0n,
54
- bytes: bs58.encode(Reserve.discriminator) as Base58EncodedBytes,
55
+ bytes: base58Decoder.decode(Reserve.discriminator) as Base58EncodedBytes,
55
56
  encoding: 'base58',
56
57
  },
57
58
  },
@@ -78,7 +79,7 @@ export async function* getAllLendingMarketAccounts(
78
79
  {
79
80
  memcmp: {
80
81
  offset: 0n,
81
- bytes: bs58.encode(LendingMarket.discriminator) as Base58EncodedBytes,
82
+ bytes: base58Decoder.decode(LendingMarket.discriminator) as Base58EncodedBytes,
82
83
  encoding: 'base58',
83
84
  },
84
85
  },