@kamino-finance/klend-sdk 5.1.0 → 5.1.2
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.
- package/README_KAMINO_MANAGER.md +24 -3
- package/dist/classes/manager.d.ts +62 -2
- package/dist/classes/manager.d.ts.map +1 -1
- package/dist/classes/manager.js +76 -0
- package/dist/classes/manager.js.map +1 -1
- package/dist/classes/vault.d.ts +74 -5
- package/dist/classes/vault.d.ts.map +1 -1
- package/dist/classes/vault.js +134 -6
- package/dist/classes/vault.js.map +1 -1
- package/dist/client_kamino_manager.d.ts.map +1 -1
- package/dist/client_kamino_manager.js +6 -0
- package/dist/client_kamino_manager.js.map +1 -1
- package/dist/idl_codegen_kamino_vault/accounts/VaultState.d.ts +9 -3
- package/dist/idl_codegen_kamino_vault/accounts/VaultState.d.ts.map +1 -1
- package/dist/idl_codegen_kamino_vault/accounts/VaultState.js +42 -32
- package/dist/idl_codegen_kamino_vault/accounts/VaultState.js.map +1 -1
- package/dist/idl_codegen_kamino_vault/types/VaultConfigField.d.ts +10 -10
- package/dist/idl_codegen_kamino_vault/types/VaultConfigField.d.ts.map +1 -1
- package/dist/idl_codegen_kamino_vault/types/VaultConfigField.js +51 -52
- package/dist/idl_codegen_kamino_vault/types/VaultConfigField.js.map +1 -1
- package/dist/idl_codegen_kamino_vault/types/WithdrawalCaps.d.ts +2 -2
- package/dist/idl_codegen_kamino_vault/types/WithdrawalCaps.d.ts.map +1 -1
- package/dist/idl_codegen_kamino_vault/types/WithdrawalCaps.js +4 -4
- package/dist/idl_codegen_kamino_vault/types/WithdrawalCaps.js.map +1 -1
- package/dist/lib.d.ts +3 -0
- package/dist/lib.d.ts.map +1 -1
- package/dist/lib.js +4 -0
- package/dist/lib.js.map +1 -1
- package/dist/utils/rpc.js +2 -2
- package/dist/utils/rpc.js.map +1 -1
- package/package.json +3 -2
- package/src/classes/manager.ts +110 -1
- package/src/classes/vault.ts +204 -7
- package/src/client_kamino_manager.ts +8 -0
- package/src/idl_codegen_kamino_vault/accounts/VaultState.ts +178 -175
- package/src/idl_codegen_kamino_vault/types/VaultConfigField.ts +117 -116
- package/src/idl_codegen_kamino_vault/types/WithdrawalCaps.ts +30 -30
- package/src/lib.ts +6 -0
- package/src/utils/rpc.ts +2 -2
package/dist/utils/rpc.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rpc.js","sourceRoot":"","sources":["../../src/utils/rpc.ts"],"names":[],"mappings":";;;;;AAyBA,gDA+CC;AAxED,6CAQyB;AACzB,mCAAgC;AAChC,kDAA0B;AAC1B,kDAAsD;AACtD
|
|
1
|
+
{"version":3,"file":"rpc.js","sourceRoot":"","sources":["../../src/utils/rpc.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kamino-finance/klend-sdk",
|
|
3
|
-
"version": "5.1.
|
|
3
|
+
"version": "5.1.2",
|
|
4
4
|
"description": "Typescript SDK for interacting with the Kamino Lending (klend) protocol",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -65,7 +65,8 @@
|
|
|
65
65
|
"buffer": "^6.0.3",
|
|
66
66
|
"commander": "^9.3.0",
|
|
67
67
|
"decimal.js": "^10.4.3",
|
|
68
|
-
"exponential-backoff": "^3.1.1"
|
|
68
|
+
"exponential-backoff": "^3.1.1",
|
|
69
|
+
"uuid": "^10.0.0"
|
|
69
70
|
},
|
|
70
71
|
"devDependencies": {
|
|
71
72
|
"@orca-so/sdk": "^1.2.25",
|
package/src/classes/manager.ts
CHANGED
|
@@ -14,7 +14,10 @@ import {
|
|
|
14
14
|
KaminoVaultConfig,
|
|
15
15
|
kaminoVaultId,
|
|
16
16
|
ReserveAllocationConfig,
|
|
17
|
+
ReserveOverview,
|
|
17
18
|
VaultHolder,
|
|
19
|
+
VaultHoldings,
|
|
20
|
+
VaultHoldingsWithUSDValue,
|
|
18
21
|
} from './vault';
|
|
19
22
|
import {
|
|
20
23
|
AddAssetToMarketParams,
|
|
@@ -26,6 +29,7 @@ import {
|
|
|
26
29
|
initLendingMarket,
|
|
27
30
|
InitLendingMarketAccounts,
|
|
28
31
|
InitLendingMarketArgs,
|
|
32
|
+
KaminoReserve,
|
|
29
33
|
LendingMarket,
|
|
30
34
|
lendingMarketAuthPda,
|
|
31
35
|
MarketWithAddress,
|
|
@@ -318,7 +322,11 @@ export class KaminoManager {
|
|
|
318
322
|
return this._vaultClient.depositIxs(user, vault, tokenAmount);
|
|
319
323
|
}
|
|
320
324
|
|
|
321
|
-
async updateVaultConfigIx(
|
|
325
|
+
async updateVaultConfigIx(
|
|
326
|
+
vault: KaminoVault,
|
|
327
|
+
mode: VaultConfigFieldKind,
|
|
328
|
+
value: string
|
|
329
|
+
): Promise<TransactionInstruction> {
|
|
322
330
|
return this._vaultClient.updateVaultConfigIx(vault, mode, value);
|
|
323
331
|
}
|
|
324
332
|
|
|
@@ -378,6 +386,18 @@ export class KaminoManager {
|
|
|
378
386
|
return this._vaultClient.getTokensPerShareSingleVault(vault, slot);
|
|
379
387
|
}
|
|
380
388
|
|
|
389
|
+
/**
|
|
390
|
+
* This method calculates the price of one vault share(kToken)
|
|
391
|
+
* @param vault - vault to calculate sharePrice for
|
|
392
|
+
* @param slot - current slot, used to estimate the interest earned in the different reserves with allocation from the vault
|
|
393
|
+
* @param tokenPrice - the price of the vault token (e.g. SOL) in USD
|
|
394
|
+
* @returns - share value in USD
|
|
395
|
+
*/
|
|
396
|
+
async getSharePriceInUSD(vault: KaminoVault, slot: number, tokenPrice: Decimal): Promise<Decimal> {
|
|
397
|
+
const tokensPerShare = await this.getTokensPerShareSingleVault(vault, slot);
|
|
398
|
+
return tokensPerShare.mul(tokenPrice);
|
|
399
|
+
}
|
|
400
|
+
|
|
381
401
|
/**
|
|
382
402
|
* This method returns the user shares balance for a given vault
|
|
383
403
|
* @param user - user to calculate the shares balance for
|
|
@@ -507,6 +527,95 @@ export class KaminoManager {
|
|
|
507
527
|
return result;
|
|
508
528
|
};
|
|
509
529
|
|
|
530
|
+
/**
|
|
531
|
+
* This will return an VaultHoldings object which contains the amount available (uninvested) in vault, total amount invested in reseves and a breakdown of the amount invested in each reserve
|
|
532
|
+
* @param vault - the kamino vault to get available liquidity to withdraw for
|
|
533
|
+
* @param slot - current slot
|
|
534
|
+
* @param vaultReserves - optional parameter; a hashmap from each reserve pubkey to the reserve state. If provided the function will be significantly faster as it will not have to fetch the reserves
|
|
535
|
+
* @returns an VaultHoldings object
|
|
536
|
+
*/
|
|
537
|
+
async getVaultHoldings(
|
|
538
|
+
vault: VaultState,
|
|
539
|
+
slot: number,
|
|
540
|
+
vaultReserves?: PubkeyHashMap<PublicKey, KaminoReserve>
|
|
541
|
+
): Promise<VaultHoldings> {
|
|
542
|
+
return this._vaultClient.getVaultHoldings(vault, slot, vaultReserves);
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
/**
|
|
546
|
+
* This will return an VaultHoldingsWithUSDValue object which contains an holdings field representing the amount available (uninvested) in vault, total amount invested in reseves and a breakdown of the amount invested in each reserve and additional fields for the total USD value of the available and invested amounts
|
|
547
|
+
* @param vault - the kamino vault to get available liquidity to withdraw for
|
|
548
|
+
* @param slot - current slot
|
|
549
|
+
* @param vaultReserves - optional parameter; a hashmap from each reserve pubkey to the reserve state. If provided the function will be significantly faster as it will not have to fetch the reserves
|
|
550
|
+
* @param price - the price of the token in the vault (e.g. USDC)
|
|
551
|
+
* @returns an VaultHoldingsWithUSDValue object with details about the tokens available and invested in the vault, denominated in tokens and USD
|
|
552
|
+
*/
|
|
553
|
+
async getVaultHoldingsWithPrice(
|
|
554
|
+
vault: VaultState,
|
|
555
|
+
slot: number,
|
|
556
|
+
price: Decimal,
|
|
557
|
+
vaultReserves?: PubkeyHashMap<PublicKey, KaminoReserve>
|
|
558
|
+
): Promise<VaultHoldingsWithUSDValue> {
|
|
559
|
+
return this._vaultClient.getVaultHoldingsWithPrice(vault, slot, price, vaultReserves);
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
/**
|
|
563
|
+
* This will return an overview of each reserve that is part of the vault allocation
|
|
564
|
+
* @param vault - the kamino vault to get available liquidity to withdraw for
|
|
565
|
+
* @param slot - current slot
|
|
566
|
+
* @param vaultReserves - optional parameter; a hashmap from each reserve pubkey to the reserve state. If provided the function will be significantly faster as it will not have to fetch the reserves
|
|
567
|
+
* @returns a hashmap from vault reserve pubkey to ReserveOverview object
|
|
568
|
+
*/
|
|
569
|
+
async getVaultReservesDetails(
|
|
570
|
+
vault: VaultState,
|
|
571
|
+
slot: number,
|
|
572
|
+
vaultReserves?: PubkeyHashMap<PublicKey, KaminoReserve>
|
|
573
|
+
): Promise<PubkeyHashMap<PublicKey, ReserveOverview>> {
|
|
574
|
+
return this._vaultClient.getVaultReservesDetails(vault, slot, vaultReserves);
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
/**
|
|
578
|
+
* This will return the APY of the vault under the assumption that all the available tokens in the vault are all the time invested in the reserves
|
|
579
|
+
* @param vault - the kamino vault to get APY for
|
|
580
|
+
* @param slot - current slot
|
|
581
|
+
* @param vaultReserves - optional parameter; a hashmap from each reserve pubkey to the reserve state. If provided the function will be significantly faster as it will not have to fetch the reserves
|
|
582
|
+
* @returns APY for the vault
|
|
583
|
+
*/
|
|
584
|
+
async getVaultTheoreticalAPY(
|
|
585
|
+
vault: VaultState,
|
|
586
|
+
slot: number,
|
|
587
|
+
vaultReserves?: PubkeyHashMap<PublicKey, KaminoReserve>
|
|
588
|
+
): Promise<Decimal> {
|
|
589
|
+
return this._vaultClient.getVaultTheoreticalAPY(vault, slot, vaultReserves);
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
/**
|
|
593
|
+
* This will load the onchain state for all the reserves that the vault has allocations for
|
|
594
|
+
* @param vaultState - the vault state to load reserves for
|
|
595
|
+
* @returns a hashmap from each reserve pubkey to the reserve state
|
|
596
|
+
*/
|
|
597
|
+
async loadVaultReserves(vaultState: VaultState): Promise<PubkeyHashMap<PublicKey, KaminoReserve>> {
|
|
598
|
+
return this._vaultClient.loadVaultReserves(vaultState);
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
/**
|
|
602
|
+
* This will get the list of all reserve pubkeys that the vault has allocations for
|
|
603
|
+
* @param vaultState - the vault state to load reserves for
|
|
604
|
+
* @returns a hashmap from each reserve pubkey to the reserve state
|
|
605
|
+
*/
|
|
606
|
+
getAllVaultReserves(vault: VaultState): PublicKey[] {
|
|
607
|
+
return this._vaultClient.getAllVaultReserves(vault);
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
/**
|
|
611
|
+
* This will load the onchain state for all the reserves that the vault has allocations for
|
|
612
|
+
* @param vaultState - the vault state to load reserves for
|
|
613
|
+
* @returns a hashmap from each reserve pubkey to the reserve state
|
|
614
|
+
*/
|
|
615
|
+
getVaultReserves(vault: VaultState): PublicKey[] {
|
|
616
|
+
return this._vaultClient.getVaultReserves(vault);
|
|
617
|
+
}
|
|
618
|
+
|
|
510
619
|
/**
|
|
511
620
|
* This will trigger invest by balancing, based on weights, the reserve allocations of the vault. It can either withdraw or deposit into reserves to balance them. This is a function that should be cranked
|
|
512
621
|
* @param kaminoVault - vault to invest from
|
package/src/classes/vault.ts
CHANGED
|
@@ -61,6 +61,7 @@ import bs58 from 'bs58';
|
|
|
61
61
|
import { getProgramAccounts } from '../utils/rpc';
|
|
62
62
|
|
|
63
63
|
export const kaminoVaultId = new PublicKey('kvauTFR8qm1dhniz6pYuBZkuene3Hfrs1VQhVRgCNrr');
|
|
64
|
+
export const kaminoVaultStagingId = new PublicKey('STkvh7ostar39Fwr4uZKASs1RNNuYMFMTsE77FiRsL2');
|
|
64
65
|
|
|
65
66
|
const TOKEN_VAULT_SEED = 'token_vault';
|
|
66
67
|
const CTOKEN_VAULT_SEED = 'ctoken_vault';
|
|
@@ -389,9 +390,15 @@ export class KaminoVaultClient {
|
|
|
389
390
|
* @param user - user to deposit
|
|
390
391
|
* @param vault - vault to deposit into
|
|
391
392
|
* @param tokenAmount - token amount to be deposited, in decimals (will be converted in lamports)
|
|
393
|
+
* @param vaultReserves - optional parameter; a hashmap from each reserve pubkey to the reserve state. If provided the function will be significantly faster as it will not have to fetch the reserves
|
|
392
394
|
* @returns - an array of instructions to be used to be executed
|
|
393
395
|
*/
|
|
394
|
-
async depositIxs(
|
|
396
|
+
async depositIxs(
|
|
397
|
+
user: PublicKey,
|
|
398
|
+
vault: KaminoVault,
|
|
399
|
+
tokenAmount: Decimal,
|
|
400
|
+
vaultReservesMap?: PubkeyHashMap<PublicKey, KaminoReserve>
|
|
401
|
+
): Promise<TransactionInstruction[]> {
|
|
395
402
|
const vaultState = await vault.getState(this._connection);
|
|
396
403
|
|
|
397
404
|
const userTokenAta = getAssociatedTokenAddress(vaultState.tokenMint, user);
|
|
@@ -450,7 +457,7 @@ export class KaminoVaultClient {
|
|
|
450
457
|
|
|
451
458
|
const vaultReserves = this.getVaultReserves(vaultState);
|
|
452
459
|
|
|
453
|
-
const vaultReservesState = await this.loadVaultReserves(vaultState);
|
|
460
|
+
const vaultReservesState = vaultReservesMap ? vaultReservesMap : await this.loadVaultReserves(vaultState);
|
|
454
461
|
|
|
455
462
|
let vaultReservesAccountMetas: AccountMeta[] = [];
|
|
456
463
|
let vaultReservesLendingMarkets: AccountMeta[] = [];
|
|
@@ -825,16 +832,21 @@ export class KaminoVaultClient {
|
|
|
825
832
|
* This method calculates the token per shar value. This will always change based on interest earned from the vault, but calculating it requires a bunch of rpc requests. Caching this for a short duration would be optimal
|
|
826
833
|
* @param vault - vault to calculate tokensPerShare for
|
|
827
834
|
* @param slot - current slot, used to estimate the interest earned in the different reserves with allocation from the vault
|
|
835
|
+
* @param vaultReserves - optional parameter; a hashmap from each reserve pubkey to the reserve state. If provided the function will be significantly faster as it will not have to fetch the reserves
|
|
828
836
|
* @returns - token per share value
|
|
829
837
|
*/
|
|
830
|
-
async getTokensPerShareSingleVault(
|
|
838
|
+
async getTokensPerShareSingleVault(
|
|
839
|
+
vault: KaminoVault,
|
|
840
|
+
slot: number,
|
|
841
|
+
vaultReservesMap?: PubkeyHashMap<PublicKey, KaminoReserve>
|
|
842
|
+
): Promise<Decimal> {
|
|
831
843
|
const vaultState = await vault.getState(this._connection);
|
|
832
|
-
const
|
|
844
|
+
const vaultReservesState = vaultReservesMap ? vaultReservesMap : await this.loadVaultReserves(vaultState);
|
|
833
845
|
|
|
834
846
|
const totalVaultLiquidityAmount = new Decimal(vaultState.tokenAvailable.toString());
|
|
835
847
|
vaultState.vaultAllocationStrategy.forEach((allocationStrategy) => {
|
|
836
848
|
if (!allocationStrategy.reserve.equals(PublicKey.default)) {
|
|
837
|
-
const reserve =
|
|
849
|
+
const reserve = vaultReservesState.get(allocationStrategy.reserve);
|
|
838
850
|
if (reserve === undefined) {
|
|
839
851
|
throw new Error(`Reserve ${allocationStrategy.reserve.toBase58()} not found`);
|
|
840
852
|
}
|
|
@@ -983,13 +995,32 @@ export class KaminoVaultClient {
|
|
|
983
995
|
return reserveAllocationAvailableLiquidityToWithdraw;
|
|
984
996
|
}
|
|
985
997
|
|
|
986
|
-
|
|
998
|
+
/**
|
|
999
|
+
* This will get the list of all reserve pubkeys that the vault has allocations for
|
|
1000
|
+
* @param vaultState - the vault state to load reserves for
|
|
1001
|
+
* @returns a hashmap from each reserve pubkey to the reserve state
|
|
1002
|
+
*/
|
|
1003
|
+
getAllVaultReserves(vault: VaultState): PublicKey[] {
|
|
1004
|
+
return vault.vaultAllocationStrategy.map((vaultAllocation) => vaultAllocation.reserve);
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
/**
|
|
1008
|
+
* This will get the list of all reserve pubkeys that the vault has allocations for ex
|
|
1009
|
+
* @param vaultState - the vault state to load reserves for
|
|
1010
|
+
* @returns a hashmap from each reserve pubkey to the reserve state
|
|
1011
|
+
*/
|
|
1012
|
+
getVaultReserves(vault: VaultState): PublicKey[] {
|
|
987
1013
|
return vault.vaultAllocationStrategy
|
|
988
1014
|
.filter((vaultAllocation) => !vaultAllocation.reserve.equals(PublicKey.default))
|
|
989
1015
|
.map((vaultAllocation) => vaultAllocation.reserve);
|
|
990
1016
|
}
|
|
991
1017
|
|
|
992
|
-
|
|
1018
|
+
/**
|
|
1019
|
+
* This will load the onchain state for all the reserves that the vault has allocations for
|
|
1020
|
+
* @param vaultState - the vault state to load reserves for
|
|
1021
|
+
* @returns a hashmap from each reserve pubkey to the reserve state
|
|
1022
|
+
*/
|
|
1023
|
+
async loadVaultReserves(vaultState: VaultState): Promise<PubkeyHashMap<PublicKey, KaminoReserve>> {
|
|
993
1024
|
const vaultReservesAddresses = this.getVaultReserves(vaultState);
|
|
994
1025
|
const reserveAccounts = await this._connection.getMultipleAccountsInfo(vaultReservesAddresses, 'processed');
|
|
995
1026
|
|
|
@@ -1026,6 +1057,152 @@ export class KaminoVaultClient {
|
|
|
1026
1057
|
|
|
1027
1058
|
return kaminoReserves;
|
|
1028
1059
|
}
|
|
1060
|
+
|
|
1061
|
+
/**
|
|
1062
|
+
* This will return an VaultHoldings object which contains the amount available (uninvested) in vault, total amount invested in reseves and a breakdown of the amount invested in each reserve
|
|
1063
|
+
* @param vault - the kamino vault to get available liquidity to withdraw for
|
|
1064
|
+
* @param slot - current slot
|
|
1065
|
+
* @param vaultReserves - optional parameter; a hashmap from each reserve pubkey to the reserve state. If provided the function will be significantly faster as it will not have to fetch the reserves
|
|
1066
|
+
* @returns an VaultHoldings object
|
|
1067
|
+
*/
|
|
1068
|
+
async getVaultHoldings(
|
|
1069
|
+
vault: VaultState,
|
|
1070
|
+
slot: number,
|
|
1071
|
+
vaultReserves?: PubkeyHashMap<PublicKey, KaminoReserve>
|
|
1072
|
+
): Promise<VaultHoldings> {
|
|
1073
|
+
const vaultHoldings: VaultHoldings = {
|
|
1074
|
+
available: new Decimal(vault.tokenAvailable.toString()),
|
|
1075
|
+
invested: new Decimal(0),
|
|
1076
|
+
investedInReserves: new PubkeyHashMap<PublicKey, Decimal>(),
|
|
1077
|
+
};
|
|
1078
|
+
|
|
1079
|
+
const vaultReservesState = vaultReserves ? vaultReserves : await this.loadVaultReserves(vault);
|
|
1080
|
+
|
|
1081
|
+
vault.vaultAllocationStrategy.forEach((allocationStrategy) => {
|
|
1082
|
+
if (allocationStrategy.reserve.equals(PublicKey.default)) {
|
|
1083
|
+
return;
|
|
1084
|
+
}
|
|
1085
|
+
|
|
1086
|
+
const reserve = vaultReservesState.get(allocationStrategy.reserve);
|
|
1087
|
+
if (reserve === undefined) {
|
|
1088
|
+
throw new Error(`Reserve ${allocationStrategy.reserve.toBase58()} not found`);
|
|
1089
|
+
}
|
|
1090
|
+
|
|
1091
|
+
const reserveCollExchangeRate = reserve.getEstimatedCollateralExchangeRate(slot, 0);
|
|
1092
|
+
const reserveAllocationLiquidityAmount = new Decimal(allocationStrategy.cTokenAllocation.toString()).mul(
|
|
1093
|
+
reserveCollExchangeRate
|
|
1094
|
+
);
|
|
1095
|
+
|
|
1096
|
+
vaultHoldings.invested = vaultHoldings.invested.add(reserveAllocationLiquidityAmount);
|
|
1097
|
+
vaultHoldings.investedInReserves.set(allocationStrategy.reserve, reserveAllocationLiquidityAmount);
|
|
1098
|
+
});
|
|
1099
|
+
|
|
1100
|
+
return vaultHoldings;
|
|
1101
|
+
}
|
|
1102
|
+
|
|
1103
|
+
/**
|
|
1104
|
+
* This will return an VaultHoldingsWithUSDValue object which contains an holdings field representing the amount available (uninvested) in vault, total amount invested in reseves and a breakdown of the amount invested in each reserve and additional fields for the total USD value of the available and invested amounts
|
|
1105
|
+
* @param vault - the kamino vault to get available liquidity to withdraw for
|
|
1106
|
+
* @param slot - current slot
|
|
1107
|
+
* @param vaultReserves - optional parameter; a hashmap from each reserve pubkey to the reserve state. If provided the function will be significantly faster as it will not have to fetch the reserves
|
|
1108
|
+
* @param price - the price of the token in the vault (e.g. USDC)
|
|
1109
|
+
* @returns an VaultHoldingsWithUSDValue object with details about the tokens available and invested in the vault, denominated in tokens and USD
|
|
1110
|
+
*/
|
|
1111
|
+
async getVaultHoldingsWithPrice(
|
|
1112
|
+
vault: VaultState,
|
|
1113
|
+
slot: number,
|
|
1114
|
+
price: Decimal,
|
|
1115
|
+
vaultReserves?: PubkeyHashMap<PublicKey, KaminoReserve>
|
|
1116
|
+
): Promise<VaultHoldingsWithUSDValue> {
|
|
1117
|
+
const holdings = await this.getVaultHoldings(vault, slot, vaultReserves);
|
|
1118
|
+
|
|
1119
|
+
const investedInReservesUSD = new PubkeyHashMap<PublicKey, Decimal>();
|
|
1120
|
+
holdings.investedInReserves.forEach((amount, reserve) => {
|
|
1121
|
+
investedInReservesUSD.set(reserve, amount.mul(price));
|
|
1122
|
+
});
|
|
1123
|
+
const holdingsWithUSDValue: VaultHoldingsWithUSDValue = {
|
|
1124
|
+
holdings: holdings,
|
|
1125
|
+
availableUSD: holdings.available.mul(price),
|
|
1126
|
+
investedUSD: holdings.invested.mul(price),
|
|
1127
|
+
investedInReservesUSD: investedInReservesUSD,
|
|
1128
|
+
};
|
|
1129
|
+
|
|
1130
|
+
return holdingsWithUSDValue;
|
|
1131
|
+
}
|
|
1132
|
+
|
|
1133
|
+
/**
|
|
1134
|
+
* This will return an overview of each reserve that is part of the vault allocation
|
|
1135
|
+
* @param vault - the kamino vault to get available liquidity to withdraw for
|
|
1136
|
+
* @param slot - current slot
|
|
1137
|
+
* @param vaultReserves - optional parameter; a hashmap from each reserve pubkey to the reserve state. If provided the function will be significantly faster as it will not have to fetch the reserves
|
|
1138
|
+
* @returns a hashmap from vault reserve pubkey to ReserveOverview object
|
|
1139
|
+
*/
|
|
1140
|
+
async getVaultReservesDetails(
|
|
1141
|
+
vault: VaultState,
|
|
1142
|
+
slot: number,
|
|
1143
|
+
vaultReserves?: PubkeyHashMap<PublicKey, KaminoReserve>
|
|
1144
|
+
): Promise<PubkeyHashMap<PublicKey, ReserveOverview>> {
|
|
1145
|
+
const vaultReservesState = vaultReserves ? vaultReserves : await this.loadVaultReserves(vault);
|
|
1146
|
+
const reservesDetails = new PubkeyHashMap<PublicKey, ReserveOverview>();
|
|
1147
|
+
|
|
1148
|
+
vault.vaultAllocationStrategy.forEach((allocationStrategy) => {
|
|
1149
|
+
if (allocationStrategy.reserve.equals(PublicKey.default)) {
|
|
1150
|
+
return;
|
|
1151
|
+
}
|
|
1152
|
+
|
|
1153
|
+
const reserve = vaultReservesState.get(allocationStrategy.reserve);
|
|
1154
|
+
if (reserve === undefined) {
|
|
1155
|
+
throw new Error(`Reserve ${allocationStrategy.reserve.toBase58()} not found`);
|
|
1156
|
+
}
|
|
1157
|
+
|
|
1158
|
+
reserve.getBorrowedAmount();
|
|
1159
|
+
const reserveOverview: ReserveOverview = {
|
|
1160
|
+
supplyAPY: new Decimal(reserve.totalSupplyAPY(slot)),
|
|
1161
|
+
uUtilizationRatio: new Decimal(reserve.getEstimatedUtilizationRatio(slot, 0)),
|
|
1162
|
+
liquidationThresholdPct: new Decimal(reserve.state.config.liquidationThresholdPct),
|
|
1163
|
+
borrowedAmount: reserve.getBorrowedAmount(),
|
|
1164
|
+
};
|
|
1165
|
+
reservesDetails.set(allocationStrategy.reserve, reserveOverview);
|
|
1166
|
+
});
|
|
1167
|
+
|
|
1168
|
+
return reservesDetails;
|
|
1169
|
+
}
|
|
1170
|
+
|
|
1171
|
+
/**
|
|
1172
|
+
* This will return the APY of the vault under the assumption that all the available tokens in the vault are all the time invested in the reserves
|
|
1173
|
+
* @param vault - the kamino vault to get APY for
|
|
1174
|
+
* @param slot - current slot
|
|
1175
|
+
* @param vaultReserves - optional parameter; a hashmap from each reserve pubkey to the reserve state. If provided the function will be significantly faster as it will not have to fetch the reserves
|
|
1176
|
+
* @returns APY for the vault
|
|
1177
|
+
*/
|
|
1178
|
+
async getVaultTheoreticalAPY(
|
|
1179
|
+
vault: VaultState,
|
|
1180
|
+
slot: number,
|
|
1181
|
+
vaultReserves?: PubkeyHashMap<PublicKey, KaminoReserve>
|
|
1182
|
+
): Promise<Decimal> {
|
|
1183
|
+
const vaultReservesState = vaultReserves ? vaultReserves : await this.loadVaultReserves(vault);
|
|
1184
|
+
|
|
1185
|
+
let totalWeights = new Decimal(0);
|
|
1186
|
+
let totalAPY = new Decimal(0);
|
|
1187
|
+
vault.vaultAllocationStrategy.forEach((allocationStrategy) => {
|
|
1188
|
+
if (allocationStrategy.reserve.equals(PublicKey.default)) {
|
|
1189
|
+
return;
|
|
1190
|
+
}
|
|
1191
|
+
|
|
1192
|
+
const reserve = vaultReservesState.get(allocationStrategy.reserve);
|
|
1193
|
+
if (reserve === undefined) {
|
|
1194
|
+
throw new Error(`Reserve ${allocationStrategy.reserve.toBase58()} not found`);
|
|
1195
|
+
}
|
|
1196
|
+
|
|
1197
|
+
const reserveAPY = new Decimal(reserve.totalSupplyAPY(slot));
|
|
1198
|
+
const weight = new Decimal(allocationStrategy.targetAllocationWeight.toString());
|
|
1199
|
+
const weightedAPY = reserveAPY.mul(weight);
|
|
1200
|
+
totalAPY = totalAPY.add(weightedAPY);
|
|
1201
|
+
totalWeights = totalWeights.add(weight);
|
|
1202
|
+
});
|
|
1203
|
+
|
|
1204
|
+
return totalAPY.div(totalWeights);
|
|
1205
|
+
}
|
|
1029
1206
|
} // KaminoVaultClient
|
|
1030
1207
|
|
|
1031
1208
|
export class KaminoVault {
|
|
@@ -1134,3 +1311,23 @@ export type VaultHolder = {
|
|
|
1134
1311
|
holderPubkey: PublicKey;
|
|
1135
1312
|
amount: Decimal;
|
|
1136
1313
|
};
|
|
1314
|
+
|
|
1315
|
+
export type VaultHoldings = {
|
|
1316
|
+
available: Decimal;
|
|
1317
|
+
invested: Decimal;
|
|
1318
|
+
investedInReserves: PubkeyHashMap<PublicKey, Decimal>;
|
|
1319
|
+
};
|
|
1320
|
+
|
|
1321
|
+
export type VaultHoldingsWithUSDValue = {
|
|
1322
|
+
holdings: VaultHoldings;
|
|
1323
|
+
availableUSD: Decimal;
|
|
1324
|
+
investedUSD: Decimal;
|
|
1325
|
+
investedInReservesUSD: PubkeyHashMap<PublicKey, Decimal>;
|
|
1326
|
+
};
|
|
1327
|
+
|
|
1328
|
+
export type ReserveOverview = {
|
|
1329
|
+
supplyAPY: Decimal;
|
|
1330
|
+
uUtilizationRatio: Decimal;
|
|
1331
|
+
liquidationThresholdPct: Decimal;
|
|
1332
|
+
borrowedAmount: Decimal;
|
|
1333
|
+
};
|
|
@@ -496,6 +496,14 @@ async function main() {
|
|
|
496
496
|
console.log('oracleConfigs', JSON.parse(JSON.stringify(oracleConfigs)));
|
|
497
497
|
});
|
|
498
498
|
|
|
499
|
+
commands.command('get-all-vaults').action(async () => {
|
|
500
|
+
const env = initializeClient(false, false);
|
|
501
|
+
const kaminoManager = new KaminoManager(env.connection, env.kLendProgramId, env.kVaultProgramId);
|
|
502
|
+
|
|
503
|
+
const allVaults = await kaminoManager.getAllVaults();
|
|
504
|
+
console.log('all vaults', allVaults);
|
|
505
|
+
});
|
|
506
|
+
|
|
499
507
|
commands
|
|
500
508
|
.command('download-lending-market-config')
|
|
501
509
|
.requiredOption('--lending-market <string>', 'Lending Market Address')
|