@kamino-finance/klend-sdk 5.10.12 → 5.10.13
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/dist/classes/manager.d.ts +14 -12
- package/dist/classes/manager.d.ts.map +1 -1
- package/dist/classes/manager.js +20 -18
- package/dist/classes/manager.js.map +1 -1
- package/dist/classes/obligation.d.ts +1 -0
- package/dist/classes/obligation.d.ts.map +1 -1
- package/dist/classes/obligation.js +22 -0
- package/dist/classes/obligation.js.map +1 -1
- package/dist/classes/reserve.js +1 -1
- package/dist/classes/reserve.js.map +1 -1
- package/dist/classes/types_utils.d.ts +3 -1
- package/dist/classes/types_utils.d.ts.map +1 -1
- package/dist/classes/types_utils.js +26 -0
- package/dist/classes/types_utils.js.map +1 -1
- package/dist/classes/utils.d.ts +8 -0
- package/dist/classes/utils.d.ts.map +1 -1
- package/dist/classes/utils.js +48 -0
- package/dist/classes/utils.js.map +1 -1
- package/dist/classes/vault.d.ts +6 -8
- package/dist/classes/vault.d.ts.map +1 -1
- package/dist/classes/vault.js +19 -22
- package/dist/classes/vault.js.map +1 -1
- package/dist/client_kamino_manager.js +2 -2
- package/dist/client_kamino_manager.js.map +1 -1
- package/dist/lending_operations/swap_collateral_operations.js.map +1 -1
- package/dist/pyth/accounts/index.d.ts +1 -1
- package/dist/pyth/accounts/index.d.ts.map +1 -1
- package/dist/utils/ObligationType.d.ts +10 -4
- package/dist/utils/ObligationType.d.ts.map +1 -1
- package/dist/utils/ObligationType.js +36 -11
- package/dist/utils/ObligationType.js.map +1 -1
- package/dist/utils/constants.d.ts +1 -0
- package/dist/utils/constants.d.ts.map +1 -1
- package/dist/utils/constants.js +2 -1
- package/dist/utils/constants.js.map +1 -1
- package/package.json +1 -1
- package/src/classes/manager.ts +25 -19
- package/src/classes/obligation.ts +42 -2
- package/src/classes/reserve.ts +1 -1
- package/src/classes/types_utils.ts +28 -1
- package/src/classes/utils.ts +50 -1
- package/src/classes/vault.ts +25 -27
- package/src/client_kamino_manager.ts +2 -2
- package/src/lending_operations/swap_collateral_operations.ts +1 -1
- package/src/pyth/accounts/index.ts +1 -1
- package/src/utils/ObligationType.ts +49 -12
- package/src/utils/constants.ts +2 -0
package/src/classes/manager.ts
CHANGED
|
@@ -339,9 +339,10 @@ export class KaminoManager {
|
|
|
339
339
|
user: PublicKey,
|
|
340
340
|
vault: KaminoVault,
|
|
341
341
|
tokenAmount: Decimal,
|
|
342
|
-
vaultReservesMap?: PubkeyHashMap<PublicKey, KaminoReserve
|
|
342
|
+
vaultReservesMap?: PubkeyHashMap<PublicKey, KaminoReserve>,
|
|
343
|
+
farmState?: FarmState
|
|
343
344
|
): Promise<DepositIxs> {
|
|
344
|
-
return this._vaultClient.depositIxs(user, vault, tokenAmount, vaultReservesMap);
|
|
345
|
+
return this._vaultClient.depositIxs(user, vault, tokenAmount, vaultReservesMap, farmState);
|
|
345
346
|
}
|
|
346
347
|
|
|
347
348
|
/**
|
|
@@ -366,19 +367,21 @@ export class KaminoManager {
|
|
|
366
367
|
* @param vault the vault to update
|
|
367
368
|
* @param mode the field to update (based on VaultConfigFieldKind enum)
|
|
368
369
|
* @param value the value to update the field with
|
|
370
|
+
* @param [signer] the signer of the transaction. Optional. If not provided the admin of the vault will be used. It should be used when changing the admin of the vault if we want to build or batch multiple ixs in the same tx
|
|
369
371
|
* @returns a struct that contains the instruction to update the field and an optional list of instructions to update the lookup table
|
|
370
372
|
*/
|
|
371
373
|
async updateVaultConfigIxs(
|
|
372
374
|
vault: KaminoVault,
|
|
373
375
|
mode: VaultConfigFieldKind | string,
|
|
374
|
-
value: string
|
|
376
|
+
value: string,
|
|
377
|
+
signer?: PublicKey
|
|
375
378
|
): Promise<UpdateVaultConfigIxs> {
|
|
376
379
|
if (typeof mode === 'string') {
|
|
377
380
|
const field = VaultConfigField.fromDecoded({ [mode]: '' });
|
|
378
|
-
return this._vaultClient.updateVaultConfigIxs(vault, field, value);
|
|
381
|
+
return this._vaultClient.updateVaultConfigIxs(vault, field, value, signer);
|
|
379
382
|
}
|
|
380
383
|
|
|
381
|
-
return this._vaultClient.updateVaultConfigIxs(vault, mode, value);
|
|
384
|
+
return this._vaultClient.updateVaultConfigIxs(vault, mode, value, signer);
|
|
382
385
|
}
|
|
383
386
|
|
|
384
387
|
/** Sets the farm where the shares can be staked. This is store in vault state and a vault can only have one farm, so the new farm will ovveride the old farm
|
|
@@ -420,15 +423,18 @@ export class KaminoManager {
|
|
|
420
423
|
* @param shareAmount - share amount to withdraw (in tokens, not lamports), in order to withdraw everything, any value > user share amount
|
|
421
424
|
* @param slot - current slot, used to estimate the interest earned in the different reserves with allocation from the vault
|
|
422
425
|
* @param [vaultReservesMap] - 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
|
|
426
|
+
* @param [farmState] - the state of the vault farm, if the vault has a farm. Optional. If not provided, it will be fetched
|
|
423
427
|
* @returns an array of instructions to create missing ATAs if needed and the withdraw instructions
|
|
424
428
|
*/
|
|
425
429
|
async withdrawFromVaultIxs(
|
|
426
430
|
user: PublicKey,
|
|
427
431
|
vault: KaminoVault,
|
|
428
432
|
shareAmount: Decimal,
|
|
429
|
-
slot: number
|
|
433
|
+
slot: number,
|
|
434
|
+
vaultReservesMap?: PubkeyHashMap<PublicKey, KaminoReserve>,
|
|
435
|
+
farmState?: FarmState
|
|
430
436
|
): Promise<WithdrawIxs> {
|
|
431
|
-
return this._vaultClient.withdrawIxs(user, vault, shareAmount, slot);
|
|
437
|
+
return this._vaultClient.withdrawIxs(user, vault, shareAmount, slot, vaultReservesMap, farmState);
|
|
432
438
|
}
|
|
433
439
|
|
|
434
440
|
/**
|
|
@@ -447,7 +453,6 @@ export class KaminoManager {
|
|
|
447
453
|
* @param payer - payer wallet pubkey
|
|
448
454
|
* @param lookupTable - lookup table to insert the keys into
|
|
449
455
|
* @param keys - keys to insert into the lookup table
|
|
450
|
-
* @param [accountsInLUT] - the existent accounts in the lookup table. Optional. If provided, the function will not fetch the accounts in the lookup table
|
|
451
456
|
* @returns - an array of instructions to insert the missing keys into the lookup table
|
|
452
457
|
*/
|
|
453
458
|
async insertIntoLUTIxs(payer: PublicKey, lut: PublicKey, keys: PublicKey[]): Promise<TransactionInstruction[]> {
|
|
@@ -697,6 +702,16 @@ export class KaminoManager {
|
|
|
697
702
|
return this._vaultClient.getVaultOverview(vault, price, slot, vaultReserves, kaminoMarkets);
|
|
698
703
|
}
|
|
699
704
|
|
|
705
|
+
/**
|
|
706
|
+
* Prints a vault in a human readable form
|
|
707
|
+
* @param vaultPubkey - the address of the vault
|
|
708
|
+
* @param [vaultState] - optional parameter to pass the vault state directly; this will save a network call
|
|
709
|
+
* @returns - void; prints the vault to the console
|
|
710
|
+
*/
|
|
711
|
+
async printVault(vaultPubkey: PublicKey, vaultState?: VaultState) {
|
|
712
|
+
return this._vaultClient.printVault(vaultPubkey, vaultState);
|
|
713
|
+
}
|
|
714
|
+
|
|
700
715
|
/**
|
|
701
716
|
* This will return an aggregation of the current state of the vault with all the invested amounts and the utilization ratio of the vault
|
|
702
717
|
* @param vault - the kamino vault to get available liquidity to withdraw for
|
|
@@ -797,15 +812,6 @@ export class KaminoManager {
|
|
|
797
812
|
return this._vaultClient.loadVaultReserves(vaultState);
|
|
798
813
|
}
|
|
799
814
|
|
|
800
|
-
/**
|
|
801
|
-
* This will get the list of all reserve pubkeys that the vault has allocations for
|
|
802
|
-
* @param vaultState - the vault state to load reserves for
|
|
803
|
-
* @returns a hashmap from each reserve pubkey to the reserve state
|
|
804
|
-
*/
|
|
805
|
-
getAllVaultReserves(vault: VaultState): PublicKey[] {
|
|
806
|
-
return this._vaultClient.getAllVaultReserves(vault);
|
|
807
|
-
}
|
|
808
|
-
|
|
809
815
|
/**
|
|
810
816
|
* This will load the onchain state for all the reserves that the vault has allocations for
|
|
811
817
|
* @param vaultState - the vault state to load reserves for
|
|
@@ -830,7 +836,7 @@ export class KaminoManager {
|
|
|
830
836
|
* @param kaminoVault - vault to invest from
|
|
831
837
|
* @returns - an array of invest instructions for each invest action required for the vault reserves
|
|
832
838
|
*/
|
|
833
|
-
async
|
|
839
|
+
async investAllReservesIxs(payer: PublicKey, kaminoVault: KaminoVault): Promise<TransactionInstruction[]> {
|
|
834
840
|
return this._vaultClient.investAllReservesIxs(payer, kaminoVault);
|
|
835
841
|
}
|
|
836
842
|
|
|
@@ -842,7 +848,7 @@ export class KaminoManager {
|
|
|
842
848
|
* @param [vaultReservesMap] - 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
|
|
843
849
|
* @returns - an array of invest instructions for each invest action required for the vault reserves
|
|
844
850
|
*/
|
|
845
|
-
async
|
|
851
|
+
async investSingleReserveIxs(
|
|
846
852
|
payer: PublicKey,
|
|
847
853
|
kaminoVault: KaminoVault,
|
|
848
854
|
reserveWithAddress: ReserveWithAddress,
|
|
@@ -13,7 +13,14 @@ import {
|
|
|
13
13
|
ObligationLiquidityFields,
|
|
14
14
|
} from '../idl_codegen/types';
|
|
15
15
|
import { positiveOrZero, valueOrZero } from './utils';
|
|
16
|
-
import {
|
|
16
|
+
import {
|
|
17
|
+
getObligationPdaWithArgs,
|
|
18
|
+
getObligationType,
|
|
19
|
+
isNotNullPubkey,
|
|
20
|
+
PubkeyHashMap,
|
|
21
|
+
TOTAL_NUMBER_OF_IDS_TO_CHECK,
|
|
22
|
+
U64_MAX,
|
|
23
|
+
} from '../utils';
|
|
17
24
|
import { ActionType } from './action';
|
|
18
25
|
|
|
19
26
|
export type Position = {
|
|
@@ -112,6 +119,39 @@ export class KaminoObligation {
|
|
|
112
119
|
this.obligationTag = obligation.tag.toNumber();
|
|
113
120
|
}
|
|
114
121
|
|
|
122
|
+
getObligationId(
|
|
123
|
+
market: KaminoMarket,
|
|
124
|
+
mintAddress1: PublicKey = PublicKey.default,
|
|
125
|
+
mintAddress2: PublicKey = PublicKey.default
|
|
126
|
+
) {
|
|
127
|
+
if (!this.state.lendingMarket.equals(new PublicKey(market.address))) {
|
|
128
|
+
throw new Error('Obligation does not belong to this market');
|
|
129
|
+
}
|
|
130
|
+
let obligationId: number | undefined;
|
|
131
|
+
const type = getObligationType(market, this.obligationTag, mintAddress1, mintAddress2);
|
|
132
|
+
const baseArgs = type.toArgs();
|
|
133
|
+
|
|
134
|
+
for (let i = 0; i < TOTAL_NUMBER_OF_IDS_TO_CHECK; i++) {
|
|
135
|
+
const pda = getObligationPdaWithArgs(
|
|
136
|
+
new PublicKey(market.address),
|
|
137
|
+
this.state.owner,
|
|
138
|
+
{
|
|
139
|
+
...baseArgs,
|
|
140
|
+
id: i,
|
|
141
|
+
},
|
|
142
|
+
market.programId
|
|
143
|
+
);
|
|
144
|
+
if (pda.equals(this.obligationAddress)) {
|
|
145
|
+
obligationId = i;
|
|
146
|
+
break;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
if (obligationId === undefined) {
|
|
150
|
+
throw new Error(`obligation id not found for obligation ${this.obligationAddress.toString()}`);
|
|
151
|
+
}
|
|
152
|
+
return obligationId;
|
|
153
|
+
}
|
|
154
|
+
|
|
115
155
|
static async load(kaminoMarket: KaminoMarket, obligationAddress: PublicKey): Promise<KaminoObligation | null> {
|
|
116
156
|
const res = await kaminoMarket.getConnection().getAccountInfoAndContext(obligationAddress);
|
|
117
157
|
if (res.value === null) {
|
|
@@ -484,7 +524,7 @@ export class KaminoObligation {
|
|
|
484
524
|
const collateralReservePk = mintCollateral ? market.getReserveByMint(mintCollateral)!.address : undefined;
|
|
485
525
|
const debtReservePk = mintDebt ? market.getReserveByMint(mintDebt)!.address : undefined;
|
|
486
526
|
|
|
487
|
-
const additionalReserves = [];
|
|
527
|
+
const additionalReserves: PublicKey[] = [];
|
|
488
528
|
if (collateralReservePk !== undefined) {
|
|
489
529
|
additionalReserves.push(collateralReservePk);
|
|
490
530
|
}
|
package/src/classes/reserve.ts
CHANGED
|
@@ -1215,7 +1215,7 @@ export function updateEntireReserveConfigIx(
|
|
|
1215
1215
|
const args: UpdateReserveConfigArgs = {
|
|
1216
1216
|
mode: new anchor.BN(25),
|
|
1217
1217
|
value: value,
|
|
1218
|
-
skipValidation:
|
|
1218
|
+
skipValidation: false,
|
|
1219
1219
|
};
|
|
1220
1220
|
|
|
1221
1221
|
const accounts: UpdateReserveConfigAccounts = {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { pubkeyHashMapToJson } from './utils';
|
|
2
|
-
import { VaultHoldings } from './vault';
|
|
2
|
+
import { VaultHoldings, VaultHoldingsWithUSDValue, VaultOverview } from './vault';
|
|
3
3
|
|
|
4
4
|
export function holdingsToJson(holdings: VaultHoldings) {
|
|
5
5
|
return {
|
|
@@ -17,3 +17,30 @@ export function printHoldings(holdings: VaultHoldings) {
|
|
|
17
17
|
console.log(' Total:', holdings.total.toString());
|
|
18
18
|
console.log(' Invested in reserves:', pubkeyHashMapToJson(holdings.investedInReserves));
|
|
19
19
|
}
|
|
20
|
+
|
|
21
|
+
export function printHoldingsWithUSDValue(holdings: VaultHoldingsWithUSDValue) {
|
|
22
|
+
console.log('Holdings with USD value:');
|
|
23
|
+
console.log(' Available:', holdings.availableUSD.toString());
|
|
24
|
+
console.log(' Invested:', holdings.investedUSD.toString());
|
|
25
|
+
console.log(' Total:', holdings.totalUSD.toString());
|
|
26
|
+
console.log(' Invested in reserves:', pubkeyHashMapToJson(holdings.investedInReservesUSD));
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function printVaultOverview(vaultOverview: VaultOverview) {
|
|
30
|
+
console.log('Vault overview:');
|
|
31
|
+
printHoldingsWithUSDValue(vaultOverview.holdingsUSD);
|
|
32
|
+
console.log(' Theoretical Supply APY:', vaultOverview.theoreticalSupplyAPY.toString());
|
|
33
|
+
console.log(' Utilization ratio:', vaultOverview.utilizationRatio.toString());
|
|
34
|
+
console.log(' Total supplied:', vaultOverview.totalSupplied.toString());
|
|
35
|
+
console.log(' Borrowed amount:', vaultOverview.totalBorrowed.toString());
|
|
36
|
+
|
|
37
|
+
vaultOverview.reservesOverview.forEach((reserveOverview, pubkey) => {
|
|
38
|
+
console.log(' Reserve:', pubkey.toString());
|
|
39
|
+
console.log(' Total borrowed from reserve:', reserveOverview.totalBorrowedAmount.toString());
|
|
40
|
+
console.log(' Supplied:', reserveOverview.suppliedAmount.toString());
|
|
41
|
+
console.log(' Utilization ratio:', reserveOverview.utilizationRatio.toString());
|
|
42
|
+
console.log(' Liquidation Threshold Pct:', reserveOverview.liquidationThresholdPct.toString());
|
|
43
|
+
console.log(' Supply APY:', reserveOverview.supplyAPY.toString());
|
|
44
|
+
console.log(' Lending market:', reserveOverview.market.toString());
|
|
45
|
+
});
|
|
46
|
+
}
|
package/src/classes/utils.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { PubkeyHashMap, SLOTS_PER_SECOND, SLOTS_PER_YEAR } from '../utils';
|
|
2
2
|
import Decimal from 'decimal.js';
|
|
3
3
|
import { AccountInfo, PublicKey } from '@solana/web3.js';
|
|
4
|
-
import { SOL_MINTS } from '../lib';
|
|
4
|
+
import { MarketOverview, ReserveOverview, SOL_MINTS } from '../lib';
|
|
5
5
|
import { AccountLayout } from '@solana/spl-token';
|
|
6
|
+
import { ReserveAllocationOverview } from './types';
|
|
6
7
|
|
|
7
8
|
type ObligationFarmScoreType = {
|
|
8
9
|
obligationId: string;
|
|
@@ -271,3 +272,51 @@ export function pubkeyHashMapToJson(map: PubkeyHashMap<PublicKey, any>): { [key:
|
|
|
271
272
|
export function printPubkeyHashMap<V>(map: PubkeyHashMap<PublicKey, V>) {
|
|
272
273
|
console.log(pubkeyHashMapToJson(map));
|
|
273
274
|
}
|
|
275
|
+
|
|
276
|
+
export function printReservesOverviewMap(map: PubkeyHashMap<PublicKey, ReserveOverview>) {
|
|
277
|
+
map.forEach((value, key) => {
|
|
278
|
+
console.log('Reserve:', key.toString());
|
|
279
|
+
printReserveOverview(value);
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
export function printReserveOverview(reserveOverview: ReserveOverview) {
|
|
284
|
+
console.log('Total borrowed from reserve:', reserveOverview.totalBorrowedAmount.toString());
|
|
285
|
+
console.log('Borrowed from the supplied amount:', reserveOverview.amountBorrowedFromSupplied.toString());
|
|
286
|
+
console.log('Supplied:', reserveOverview.suppliedAmount.toString());
|
|
287
|
+
console.log('Utilization ratio:', reserveOverview.utilizationRatio.toString());
|
|
288
|
+
console.log('Liquidation Threshold Pct:', reserveOverview.liquidationThresholdPct.toString());
|
|
289
|
+
console.log('Supply APY:', reserveOverview.supplyAPY.toString());
|
|
290
|
+
console.log('Lending market:', reserveOverview.market.toString());
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
export function printMarketsOverviewMap(map: PubkeyHashMap<PublicKey, MarketOverview>) {
|
|
294
|
+
map.forEach((value, key) => {
|
|
295
|
+
console.log('Reserve:', key.toString());
|
|
296
|
+
printMarketOverview(value);
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
export function printMarketOverview(marketOverview: MarketOverview) {
|
|
301
|
+
console.log('Market overview:');
|
|
302
|
+
console.log(' Address:', marketOverview.address.toString());
|
|
303
|
+
console.log(' Min LTV percentage:', marketOverview.minLTVPct.toString());
|
|
304
|
+
console.log(' Max LTV percentage:', marketOverview.maxLTVPct.toString());
|
|
305
|
+
marketOverview.reservesAsCollateral.forEach((reserve, _) => {
|
|
306
|
+
console.log(' Liquidation LTV percentage:', reserve.liquidationLTVPct.toString());
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
export function printReservesAllocationOverviewMap(map: PubkeyHashMap<PublicKey, ReserveAllocationOverview>) {
|
|
311
|
+
map.forEach((value, key) => {
|
|
312
|
+
console.log('Reserve:', key.toString());
|
|
313
|
+
printReserveAllocationOverview(value);
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
export function printReserveAllocationOverview(reserveAllocationOverview: ReserveAllocationOverview) {
|
|
318
|
+
console.log('Reserve allocation overview:');
|
|
319
|
+
console.log(' Target weight:', reserveAllocationOverview.targetWeight.toString());
|
|
320
|
+
console.log(' Token allocation cap:', reserveAllocationOverview.tokenAllocationCap.toString());
|
|
321
|
+
console.log(' Ctoken allocation:', reserveAllocationOverview.ctokenAllocation.toString());
|
|
322
|
+
}
|
package/src/classes/vault.ts
CHANGED
|
@@ -338,7 +338,7 @@ export class KaminoVaultClient {
|
|
|
338
338
|
* @param vault the vault to update
|
|
339
339
|
* @param mode the field to update (based on VaultConfigFieldKind enum)
|
|
340
340
|
* @param value the value to update the field with
|
|
341
|
-
* @param [signer] the signer of the transaction. Optional. If not provided the admin of the vault will be used. It should be used when changing the admin of the vault if we want to batch multiple ixs in the same tx
|
|
341
|
+
* @param [signer] the signer of the transaction. Optional. If not provided the admin of the vault will be used. It should be used when changing the admin of the vault if we want to build or batch multiple ixs in the same tx
|
|
342
342
|
* @returns a struct that contains the instruction to update the field and an optional list of instructions to update the lookup table
|
|
343
343
|
*/
|
|
344
344
|
async updateVaultConfigIxs(
|
|
@@ -404,7 +404,7 @@ export class KaminoVaultClient {
|
|
|
404
404
|
updateVaultConfigIx.keys = updateVaultConfigIx.keys.concat(vaultReservesAccountMetas);
|
|
405
405
|
updateVaultConfigIx.keys = updateVaultConfigIx.keys.concat(vaultReservesLendingMarkets);
|
|
406
406
|
|
|
407
|
-
const updateLUTIxs = [];
|
|
407
|
+
const updateLUTIxs: TransactionInstruction[] = [];
|
|
408
408
|
|
|
409
409
|
if (mode.kind === new VaultConfigField.PendingVaultAdmin().kind) {
|
|
410
410
|
const newPubkey = new PublicKey(value);
|
|
@@ -529,7 +529,7 @@ export class KaminoVaultClient {
|
|
|
529
529
|
(account) => !account.equals(vaultState.adminAuthority)
|
|
530
530
|
);
|
|
531
531
|
|
|
532
|
-
const LUTIxs = [];
|
|
532
|
+
const LUTIxs: TransactionInstruction[] = [];
|
|
533
533
|
const [initNewLUTIx, newLUT] = initLookupTableIx(vaultState.pendingAdmin, await this.getConnection().getSlot());
|
|
534
534
|
|
|
535
535
|
const insertIntoLUTIxs = await this.insertIntoLookupTableIxs(
|
|
@@ -1005,7 +1005,7 @@ export class KaminoVaultClient {
|
|
|
1005
1005
|
*/
|
|
1006
1006
|
async investAllReservesIxs(payer: PublicKey, vault: KaminoVault): Promise<TransactionInstruction[]> {
|
|
1007
1007
|
const vaultState = await vault.getState(this.getConnection());
|
|
1008
|
-
const allReserves = this.
|
|
1008
|
+
const allReserves = this.getVaultReserves(vaultState);
|
|
1009
1009
|
if (allReserves.length === 0) {
|
|
1010
1010
|
throw new Error('No reserves found for the vault, please select at least one reserve for the vault');
|
|
1011
1011
|
}
|
|
@@ -1488,7 +1488,7 @@ export class KaminoVaultClient {
|
|
|
1488
1488
|
const holdings = await this.getVaultHoldings(vaultState);
|
|
1489
1489
|
const initialVaultAllocations = this.getVaultAllocations(vaultState);
|
|
1490
1490
|
|
|
1491
|
-
const allReserves = this.
|
|
1491
|
+
const allReserves = this.getVaultReserves(vaultState);
|
|
1492
1492
|
|
|
1493
1493
|
let totalAllocation = new Decimal(0);
|
|
1494
1494
|
initialVaultAllocations.forEach((allocation) => {
|
|
@@ -1746,14 +1746,16 @@ export class KaminoVaultClient {
|
|
|
1746
1746
|
* @returns vault amount supplied in reserve in decimal
|
|
1747
1747
|
*/
|
|
1748
1748
|
getSuppliedInReserve(vaultState: VaultState, slot: number, reserve: KaminoReserve): Decimal {
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1749
|
+
let referralFeeBps = 0;
|
|
1750
|
+
const denominator = reserve.state.config.protocolTakeRatePct / 100;
|
|
1751
|
+
if (denominator > 0) {
|
|
1752
|
+
referralFeeBps = new Fraction(reserve.state.liquidity.absoluteReferralRateSf)
|
|
1752
1753
|
.toDecimal()
|
|
1753
|
-
.div(
|
|
1754
|
+
.div(denominator)
|
|
1754
1755
|
.floor()
|
|
1755
|
-
.toNumber()
|
|
1756
|
-
|
|
1756
|
+
.toNumber();
|
|
1757
|
+
}
|
|
1758
|
+
const reserveCollExchangeRate = reserve.getEstimatedCollateralExchangeRate(slot, referralFeeBps);
|
|
1757
1759
|
|
|
1758
1760
|
const reserveAllocation = vaultState.vaultAllocationStrategy.find((allocation) =>
|
|
1759
1761
|
allocation.reserve.equals(reserve.address)
|
|
@@ -1868,19 +1870,6 @@ export class KaminoVaultClient {
|
|
|
1868
1870
|
return reserveAllocationAvailableLiquidityToWithdraw;
|
|
1869
1871
|
}
|
|
1870
1872
|
|
|
1871
|
-
/**
|
|
1872
|
-
* This will get the list of all reserve pubkeys that the vault has allocations for
|
|
1873
|
-
* @param vault - the vault state to load reserves for
|
|
1874
|
-
* @returns a hashmap from each reserve pubkey to the reserve state
|
|
1875
|
-
*/
|
|
1876
|
-
getAllVaultReserves(vault: VaultState): PublicKey[] {
|
|
1877
|
-
return vault.vaultAllocationStrategy
|
|
1878
|
-
.map((vaultAllocation) => vaultAllocation.reserve)
|
|
1879
|
-
.filter((reserve) => {
|
|
1880
|
-
return !reserve.equals(PublicKey.default);
|
|
1881
|
-
});
|
|
1882
|
-
}
|
|
1883
|
-
|
|
1884
1873
|
/**
|
|
1885
1874
|
* This will get the list of all reserve pubkeys that the vault has allocations for ex
|
|
1886
1875
|
* @param vault - the vault state to load reserves for
|
|
@@ -2212,6 +2201,9 @@ export class KaminoVaultClient {
|
|
|
2212
2201
|
if (!totalInvested.isZero()) {
|
|
2213
2202
|
utilizationRatio = totalBorrowed.div(totalInvested.add(totalAvailable));
|
|
2214
2203
|
}
|
|
2204
|
+
|
|
2205
|
+
console.log('totalInvested', totalInvested.toString());
|
|
2206
|
+
console.log('totalBorrowed', totalBorrowed.toString());
|
|
2215
2207
|
return {
|
|
2216
2208
|
totalInvested: totalInvested,
|
|
2217
2209
|
totalBorrowed: totalBorrowed,
|
|
@@ -2245,11 +2237,13 @@ export class KaminoVaultClient {
|
|
|
2245
2237
|
}
|
|
2246
2238
|
|
|
2247
2239
|
const suppliedInReserve = this.getSuppliedInReserve(vault, slot, reserve);
|
|
2240
|
+
const utilizationRatio = new Decimal(reserve.getEstimatedUtilizationRatio(slot, 0));
|
|
2248
2241
|
const reserveOverview: ReserveOverview = {
|
|
2249
2242
|
supplyAPY: new Decimal(reserve.totalSupplyAPY(slot)),
|
|
2250
|
-
utilizationRatio:
|
|
2243
|
+
utilizationRatio: utilizationRatio,
|
|
2251
2244
|
liquidationThresholdPct: new Decimal(reserve.state.config.liquidationThresholdPct),
|
|
2252
|
-
|
|
2245
|
+
totalBorrowedAmount: reserve.getBorrowedAmount(),
|
|
2246
|
+
amountBorrowedFromSupplied: suppliedInReserve.mul(utilizationRatio),
|
|
2253
2247
|
market: reserve.state.lendingMarket,
|
|
2254
2248
|
suppliedAmount: suppliedInReserve,
|
|
2255
2249
|
};
|
|
@@ -2508,6 +2502,9 @@ export type VaultHoldings = {
|
|
|
2508
2502
|
total: Decimal;
|
|
2509
2503
|
};
|
|
2510
2504
|
|
|
2505
|
+
/**
|
|
2506
|
+
* earnedInterest represents the interest earned from now until the slot provided in the future
|
|
2507
|
+
*/
|
|
2511
2508
|
export type SimulatedVaultHoldingsWithEarnedInterest = {
|
|
2512
2509
|
holdings: VaultHoldings;
|
|
2513
2510
|
earnedInterest: Decimal;
|
|
@@ -2525,7 +2522,8 @@ export type ReserveOverview = {
|
|
|
2525
2522
|
supplyAPY: Decimal;
|
|
2526
2523
|
utilizationRatio: Decimal;
|
|
2527
2524
|
liquidationThresholdPct: Decimal;
|
|
2528
|
-
|
|
2525
|
+
totalBorrowedAmount: Decimal;
|
|
2526
|
+
amountBorrowedFromSupplied: Decimal;
|
|
2529
2527
|
suppliedAmount: Decimal;
|
|
2530
2528
|
market: PublicKey;
|
|
2531
2529
|
};
|
|
@@ -737,7 +737,7 @@ async function main() {
|
|
|
737
737
|
const kaminoManager = new KaminoManager(env.connection, env.kLendProgramId, env.kVaultProgramId);
|
|
738
738
|
|
|
739
739
|
const kaminoVault = new KaminoVault(vaultAddress, undefined, env.kVaultProgramId);
|
|
740
|
-
const instructions = await kaminoManager.
|
|
740
|
+
const instructions = await kaminoManager.investAllReservesIxs(env.payer.publicKey, kaminoVault);
|
|
741
741
|
|
|
742
742
|
for (let i = 0; i < instructions.length; i++) {
|
|
743
743
|
const txInstructions: TransactionInstruction[] = [];
|
|
@@ -779,7 +779,7 @@ async function main() {
|
|
|
779
779
|
state: reserveState,
|
|
780
780
|
};
|
|
781
781
|
|
|
782
|
-
const instructions = await kaminoManager.
|
|
782
|
+
const instructions = await kaminoManager.investSingleReserveIxs(
|
|
783
783
|
env.payer.publicKey,
|
|
784
784
|
kaminoVault,
|
|
785
785
|
reserveWithAddress
|
|
@@ -319,7 +319,7 @@ function getAtaCreationIxns(context: SwapCollContext<any>) {
|
|
|
319
319
|
}
|
|
320
320
|
|
|
321
321
|
function getAtaCloseIxns(context: SwapCollContext<any>) {
|
|
322
|
-
const ataCloseIxns = [];
|
|
322
|
+
const ataCloseIxns: TransactionInstruction[] = [];
|
|
323
323
|
if (
|
|
324
324
|
context.sourceCollReserve.getLiquidityMint().equals(WRAPPED_SOL_MINT) ||
|
|
325
325
|
context.targetCollReserve.getLiquidityMint().equals(WRAPPED_SOL_MINT)
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { PriceUpdateV2 } from './PriceUpdateV2';
|
|
2
|
-
export { PriceUpdateV2Fields, PriceUpdateV2JSON } from './PriceUpdateV2';
|
|
2
|
+
export type { PriceUpdateV2Fields, PriceUpdateV2JSON } from './PriceUpdateV2';
|
|
@@ -19,16 +19,18 @@ export type InitObligationArgsModel = {
|
|
|
19
19
|
|
|
20
20
|
export class VanillaObligation {
|
|
21
21
|
readonly programId: PublicKey;
|
|
22
|
+
readonly id: number;
|
|
22
23
|
static tag = 0;
|
|
23
24
|
|
|
24
|
-
constructor(programId: PublicKey) {
|
|
25
|
+
constructor(programId: PublicKey, id?: number) {
|
|
25
26
|
this.programId = programId;
|
|
27
|
+
this.id = id ?? 0;
|
|
26
28
|
}
|
|
27
29
|
|
|
28
30
|
toArgs() {
|
|
29
31
|
const initObligationArgs: InitObligationArgsModel = {
|
|
30
32
|
tag: VanillaObligation.tag,
|
|
31
|
-
id:
|
|
33
|
+
id: this.id,
|
|
32
34
|
seed1: PublicKey.default,
|
|
33
35
|
seed2: PublicKey.default,
|
|
34
36
|
};
|
|
@@ -45,18 +47,20 @@ export class MultiplyObligation {
|
|
|
45
47
|
readonly collToken: PublicKey;
|
|
46
48
|
readonly debtToken: PublicKey;
|
|
47
49
|
readonly programId: PublicKey;
|
|
50
|
+
readonly id: number;
|
|
48
51
|
static tag = 1;
|
|
49
52
|
|
|
50
|
-
constructor(collToken: PublicKey, debtToken: PublicKey, programId: PublicKey) {
|
|
53
|
+
constructor(collToken: PublicKey, debtToken: PublicKey, programId: PublicKey, id?: number) {
|
|
51
54
|
this.collToken = collToken;
|
|
52
55
|
this.debtToken = debtToken;
|
|
53
56
|
this.programId = programId;
|
|
57
|
+
this.id = id ?? 0;
|
|
54
58
|
}
|
|
55
59
|
|
|
56
60
|
toArgs() {
|
|
57
61
|
const initObligationArgs: InitObligationArgsModel = {
|
|
58
62
|
tag: MultiplyObligation.tag,
|
|
59
|
-
id:
|
|
63
|
+
id: this.id,
|
|
60
64
|
seed1: this.collToken,
|
|
61
65
|
seed2: this.debtToken,
|
|
62
66
|
};
|
|
@@ -73,18 +77,20 @@ export class LeverageObligation {
|
|
|
73
77
|
readonly collToken: PublicKey;
|
|
74
78
|
readonly debtToken: PublicKey;
|
|
75
79
|
readonly programId: PublicKey;
|
|
80
|
+
readonly id: number;
|
|
76
81
|
static tag = 3;
|
|
77
82
|
|
|
78
|
-
constructor(collToken: PublicKey, debtToken: PublicKey, programId: PublicKey) {
|
|
83
|
+
constructor(collToken: PublicKey, debtToken: PublicKey, programId: PublicKey, id?: number) {
|
|
79
84
|
this.collToken = collToken;
|
|
80
85
|
this.debtToken = debtToken;
|
|
81
86
|
this.programId = programId;
|
|
87
|
+
this.id = id ?? 0;
|
|
82
88
|
}
|
|
83
89
|
|
|
84
90
|
toArgs() {
|
|
85
91
|
const initObligationArgs: InitObligationArgsModel = {
|
|
86
92
|
tag: LeverageObligation.tag,
|
|
87
|
-
id:
|
|
93
|
+
id: this.id,
|
|
88
94
|
seed1: this.collToken,
|
|
89
95
|
seed2: this.debtToken,
|
|
90
96
|
};
|
|
@@ -100,11 +106,13 @@ export class LeverageObligation {
|
|
|
100
106
|
export class LendingObligation {
|
|
101
107
|
readonly token: PublicKey;
|
|
102
108
|
readonly programId: PublicKey;
|
|
109
|
+
readonly id: number;
|
|
103
110
|
static tag = 2;
|
|
104
111
|
|
|
105
|
-
constructor(token: PublicKey, programId: PublicKey) {
|
|
112
|
+
constructor(token: PublicKey, programId: PublicKey, id?: number) {
|
|
106
113
|
this.token = token;
|
|
107
114
|
this.programId = programId;
|
|
115
|
+
this.id = id ?? 0;
|
|
108
116
|
}
|
|
109
117
|
|
|
110
118
|
toArgs() {
|
|
@@ -123,7 +131,7 @@ export class LendingObligation {
|
|
|
123
131
|
}
|
|
124
132
|
}
|
|
125
133
|
|
|
126
|
-
function getObligationPdaWithArgs(
|
|
134
|
+
export function getObligationPdaWithArgs(
|
|
127
135
|
market: PublicKey,
|
|
128
136
|
user: PublicKey,
|
|
129
137
|
args: InitObligationArgsModel,
|
|
@@ -141,6 +149,39 @@ function getObligationPdaWithArgs(
|
|
|
141
149
|
return obligationAddress;
|
|
142
150
|
}
|
|
143
151
|
|
|
152
|
+
export function getObligationType(
|
|
153
|
+
kaminoMarket: KaminoMarket,
|
|
154
|
+
obligationTag: ObligationTypeTag,
|
|
155
|
+
mintAddress1: PublicKey = PublicKey.default,
|
|
156
|
+
mintAddress2: PublicKey = PublicKey.default
|
|
157
|
+
): ObligationType {
|
|
158
|
+
switch (obligationTag) {
|
|
159
|
+
case VanillaObligation.tag: {
|
|
160
|
+
return new VanillaObligation(kaminoMarket.programId);
|
|
161
|
+
}
|
|
162
|
+
case MultiplyObligation.tag: {
|
|
163
|
+
return new MultiplyObligation(
|
|
164
|
+
mintAddress1,
|
|
165
|
+
mintAddress2,
|
|
166
|
+
kaminoMarket.programId
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
case LeverageObligation.tag: {
|
|
170
|
+
return new LeverageObligation(
|
|
171
|
+
mintAddress1,
|
|
172
|
+
mintAddress2,
|
|
173
|
+
kaminoMarket.programId
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
case LendingObligation.tag: {
|
|
177
|
+
return new LendingObligation(mintAddress1, kaminoMarket.programId);
|
|
178
|
+
}
|
|
179
|
+
default: {
|
|
180
|
+
throw new Error('Invalid obligation type');
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
144
185
|
export function getObligationTypeFromObligation(
|
|
145
186
|
kaminoMarket: KaminoMarket,
|
|
146
187
|
obligation: KaminoObligation
|
|
@@ -148,7 +189,6 @@ export function getObligationTypeFromObligation(
|
|
|
148
189
|
switch (obligation.obligationTag) {
|
|
149
190
|
case VanillaObligation.tag: {
|
|
150
191
|
return new VanillaObligation(kaminoMarket.programId);
|
|
151
|
-
break;
|
|
152
192
|
}
|
|
153
193
|
case MultiplyObligation.tag: {
|
|
154
194
|
return new MultiplyObligation(
|
|
@@ -156,7 +196,6 @@ export function getObligationTypeFromObligation(
|
|
|
156
196
|
obligation.getBorrows()[0].mintAddress,
|
|
157
197
|
kaminoMarket.programId
|
|
158
198
|
);
|
|
159
|
-
break;
|
|
160
199
|
}
|
|
161
200
|
case LeverageObligation.tag: {
|
|
162
201
|
return new LeverageObligation(
|
|
@@ -164,11 +203,9 @@ export function getObligationTypeFromObligation(
|
|
|
164
203
|
obligation.getBorrows()[0].mintAddress,
|
|
165
204
|
kaminoMarket.programId
|
|
166
205
|
);
|
|
167
|
-
break;
|
|
168
206
|
}
|
|
169
207
|
case LendingObligation.tag: {
|
|
170
208
|
return new LendingObligation(obligation.getDeposits()[0].mintAddress, kaminoMarket.programId);
|
|
171
|
-
break;
|
|
172
209
|
}
|
|
173
210
|
default: {
|
|
174
211
|
throw new Error('Invalid obligation type');
|
package/src/utils/constants.ts
CHANGED
|
@@ -10,6 +10,8 @@ export const INITIAL_COLLATERAL_RATE = new Decimal(INITIAL_COLLATERAL_RATIO);
|
|
|
10
10
|
|
|
11
11
|
export const SECONDS_PER_YEAR = 365.242_199 * 24.0 * 60.0 * 60.0;
|
|
12
12
|
|
|
13
|
+
export const TOTAL_NUMBER_OF_IDS_TO_CHECK = 25;
|
|
14
|
+
|
|
13
15
|
export type ENV = 'mainnet-beta' | 'devnet' | 'localnet';
|
|
14
16
|
|
|
15
17
|
export function isENV(value: any): value is ENV {
|