@kamino-finance/klend-sdk 7.3.2 → 7.3.4
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 +21 -0
- package/dist/classes/manager.d.ts.map +1 -1
- package/dist/classes/manager.js +31 -2
- package/dist/classes/manager.js.map +1 -1
- package/dist/classes/market.d.ts.map +1 -1
- package/dist/classes/market.js +16 -6
- package/dist/classes/market.js.map +1 -1
- package/dist/classes/reserve.d.ts +2 -1
- package/dist/classes/reserve.d.ts.map +1 -1
- package/dist/classes/reserve.js +11 -5
- package/dist/classes/reserve.js.map +1 -1
- package/dist/classes/shared.d.ts +1 -0
- package/dist/classes/shared.d.ts.map +1 -1
- package/dist/classes/shared.js.map +1 -1
- package/dist/classes/vault.d.ts +16 -1
- package/dist/classes/vault.d.ts.map +1 -1
- package/dist/classes/vault.js +154 -44
- package/dist/classes/vault.js.map +1 -1
- package/dist/utils/readCdnData.d.ts +25 -0
- package/dist/utils/readCdnData.d.ts.map +1 -0
- package/dist/utils/readCdnData.js +29 -0
- package/dist/utils/readCdnData.js.map +1 -0
- package/package.json +1 -1
- package/src/classes/manager.ts +47 -2
- package/src/classes/market.ts +24 -6
- package/src/classes/reserve.ts +13 -5
- package/src/classes/shared.ts +1 -0
- package/src/classes/vault.ts +258 -67
- package/src/utils/readCdnData.ts +50 -0
package/src/classes/manager.ts
CHANGED
|
@@ -104,6 +104,7 @@ import type { AccountInfoBase, AccountInfoWithJsonData, AccountInfoWithPubkey }
|
|
|
104
104
|
import { arrayElementConfigItems, ConfigUpdater } from './configItems';
|
|
105
105
|
import { OracleMappings } from '@kamino-finance/scope-sdk/dist/@codegen/scope/accounts';
|
|
106
106
|
import { getReserveFarmRewardsAPY as getReserveFarmRewardsAPYUtils, ReserveIncentives } from '../utils/farmUtils';
|
|
107
|
+
import { fetchKaminoCdnData } from '../utils/readCdnData';
|
|
107
108
|
|
|
108
109
|
const base58Decoder = getBase58Decoder();
|
|
109
110
|
|
|
@@ -585,6 +586,25 @@ export class KaminoManager {
|
|
|
585
586
|
return this._vaultClient.depositIxs(user, vault, tokenAmount, vaultReservesMap, farmState);
|
|
586
587
|
}
|
|
587
588
|
|
|
589
|
+
/**
|
|
590
|
+
* This function creates instructions to buy shares (i.e. deposit) into a vault. It will also create ATA creation instructions for the vault shares that the user receives in return
|
|
591
|
+
* @param user - user to nuy shares
|
|
592
|
+
* @param vault - vault to buy shares from (if the state is not provided, it will be fetched)
|
|
593
|
+
* @param tokenAmount - token amount to be swapped for shares, in decimals (will be converted in lamports)
|
|
594
|
+
* @param [vaultReservesMap] - optional parameter; a hashmap from each reserve pubkey to the reserve state. Optional. If provided the function will be significantly faster as it will not have to fetch the reserves
|
|
595
|
+
* @param [farmState] - the state of the vault farm, if the vault has a farm. Optional. If not provided, it will be fetched
|
|
596
|
+
* @returns - an instance of DepositIxs which contains the instructions to buy shares in vault and the instructions to stake the shares in the farm if the vault has a farm
|
|
597
|
+
*/
|
|
598
|
+
async buyVaultSharesIxs(
|
|
599
|
+
user: TransactionSigner,
|
|
600
|
+
vault: KaminoVault,
|
|
601
|
+
tokenAmount: Decimal,
|
|
602
|
+
vaultReservesMap?: Map<Address, KaminoReserve>,
|
|
603
|
+
farmState?: FarmState
|
|
604
|
+
): Promise<DepositIxs> {
|
|
605
|
+
return this._vaultClient.buySharesIxs(user, vault, tokenAmount, vaultReservesMap, farmState);
|
|
606
|
+
}
|
|
607
|
+
|
|
588
608
|
/**
|
|
589
609
|
* This function creates instructions to stake the shares in the vault farm if the vault has a farm
|
|
590
610
|
* @param user - user to stake
|
|
@@ -718,6 +738,27 @@ export class KaminoManager {
|
|
|
718
738
|
return this._vaultClient.withdrawIxs(user, vault, shareAmount, slot, vaultReservesMap, farmState);
|
|
719
739
|
}
|
|
720
740
|
|
|
741
|
+
/**
|
|
742
|
+
* This function will return the missing ATA creation instructions, as well as one or multiple withdraw instructions, based on how many reserves it's needed to withdraw from. This might have to be split in multiple transactions
|
|
743
|
+
* @param user - user to sell shares for vault tokens
|
|
744
|
+
* @param vault - vault to sell shares from
|
|
745
|
+
* @param shareAmount - share amount to sell (in tokens, not lamports), in order to withdraw everything, any value > user share amount
|
|
746
|
+
* @param slot - current slot, used to estimate the interest earned in the different reserves with allocation from the vault
|
|
747
|
+
* @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
|
|
748
|
+
* @param [farmState] - the state of the vault farm, if the vault has a farm. Optional. If not provided, it will be fetched
|
|
749
|
+
* @returns an array of instructions to create missing ATAs if needed and the withdraw instructions
|
|
750
|
+
*/
|
|
751
|
+
async sellVaultSharesIxs(
|
|
752
|
+
user: TransactionSigner,
|
|
753
|
+
vault: KaminoVault,
|
|
754
|
+
shareAmount: Decimal,
|
|
755
|
+
slot: Slot,
|
|
756
|
+
vaultReservesMap?: Map<Address, KaminoReserve>,
|
|
757
|
+
farmState?: FarmState
|
|
758
|
+
): Promise<WithdrawIxs> {
|
|
759
|
+
return this._vaultClient.sellSharesIxs(user, vault, shareAmount, slot, vaultReservesMap, farmState);
|
|
760
|
+
}
|
|
761
|
+
|
|
721
762
|
/**
|
|
722
763
|
* This method withdraws all the pending fees from the vault to the owner's token ATA
|
|
723
764
|
* @param vault - vault for which the admin withdraws the pending fees
|
|
@@ -880,7 +921,10 @@ export class KaminoManager {
|
|
|
880
921
|
const allReserves = reservePairs.map(([, reserve]) => reserve);
|
|
881
922
|
|
|
882
923
|
// Get all oracle accounts
|
|
883
|
-
const allOracleAccounts = await
|
|
924
|
+
const [allOracleAccounts, cdnResourcesData] = await Promise.all([
|
|
925
|
+
getAllOracleAccounts(this.getRpc(), allReserves),
|
|
926
|
+
fetchKaminoCdnData(),
|
|
927
|
+
]);
|
|
884
928
|
// Group reserves by market
|
|
885
929
|
const marketToReserve = new Map<Address, ReserveWithAddress[]>();
|
|
886
930
|
for (const [reserveAddress, reserveState] of reservePairs) {
|
|
@@ -919,7 +963,8 @@ export class KaminoManager {
|
|
|
919
963
|
state,
|
|
920
964
|
oracle,
|
|
921
965
|
this.getRpc(),
|
|
922
|
-
this.recentSlotDurationMs
|
|
966
|
+
this.recentSlotDurationMs,
|
|
967
|
+
cdnResourcesData
|
|
923
968
|
);
|
|
924
969
|
reservesByAddress.set(kaminoReserve.address, kaminoReserve);
|
|
925
970
|
});
|
package/src/classes/market.ts
CHANGED
|
@@ -56,6 +56,7 @@ import { ObligationZP } from '../@codegen/klend/zero_padding';
|
|
|
56
56
|
import { checkDefined } from '../utils/validations';
|
|
57
57
|
import { Buffer } from 'buffer';
|
|
58
58
|
import { ReserveStatus } from '../@codegen/klend/types';
|
|
59
|
+
import { fetchKaminoCdnData } from '../utils/readCdnData';
|
|
59
60
|
|
|
60
61
|
export type KaminoMarketRpcApi = GetAccountInfoApi &
|
|
61
62
|
GetMultipleAccountsApi &
|
|
@@ -479,7 +480,10 @@ export class KaminoMarket {
|
|
|
479
480
|
state: reserveAccount,
|
|
480
481
|
};
|
|
481
482
|
});
|
|
482
|
-
const reservesAndOracles = await
|
|
483
|
+
const [reservesAndOracles, cdnResourcesData] = await Promise.all([
|
|
484
|
+
getTokenOracleData(this.getRpc(), deserializedReserves, oracleAccounts),
|
|
485
|
+
fetchKaminoCdnData(),
|
|
486
|
+
]);
|
|
483
487
|
const kaminoReserves = new Map<Address, KaminoReserve>();
|
|
484
488
|
reservesAndOracles.forEach(([reserve, oracle], index) => {
|
|
485
489
|
if (!oracle) {
|
|
@@ -494,7 +498,8 @@ export class KaminoMarket {
|
|
|
494
498
|
reserve,
|
|
495
499
|
oracle,
|
|
496
500
|
this.rpc,
|
|
497
|
-
this.recentSlotDurationMs
|
|
501
|
+
this.recentSlotDurationMs,
|
|
502
|
+
cdnResourcesData
|
|
498
503
|
);
|
|
499
504
|
kaminoReserves.set(kaminoReserve.address, kaminoReserve);
|
|
500
505
|
});
|
|
@@ -1712,7 +1717,10 @@ export async function getReservesForMarket(
|
|
|
1712
1717
|
state: reserveAccount,
|
|
1713
1718
|
};
|
|
1714
1719
|
});
|
|
1715
|
-
const reservesAndOracles = await
|
|
1720
|
+
const [reservesAndOracles, cdnResourcesData] = await Promise.all([
|
|
1721
|
+
getTokenOracleData(rpc, deserializedReserves, oracleAccounts),
|
|
1722
|
+
fetchKaminoCdnData(),
|
|
1723
|
+
]);
|
|
1716
1724
|
const reservesByAddress = new Map<Address, KaminoReserve>();
|
|
1717
1725
|
reservesAndOracles.forEach(([reserve, oracle], index) => {
|
|
1718
1726
|
if (reserve.config.status === ReserveStatus.Obsolete.discriminator) {
|
|
@@ -1725,7 +1733,14 @@ export async function getReservesForMarket(
|
|
|
1725
1733
|
}) reserve in market ${reserve.lendingMarket}`
|
|
1726
1734
|
);
|
|
1727
1735
|
}
|
|
1728
|
-
const kaminoReserve = KaminoReserve.initialize(
|
|
1736
|
+
const kaminoReserve = KaminoReserve.initialize(
|
|
1737
|
+
reserves[index].pubkey,
|
|
1738
|
+
reserve,
|
|
1739
|
+
oracle,
|
|
1740
|
+
rpc,
|
|
1741
|
+
recentSlotDurationMs,
|
|
1742
|
+
cdnResourcesData
|
|
1743
|
+
);
|
|
1729
1744
|
reservesByAddress.set(kaminoReserve.address, kaminoReserve);
|
|
1730
1745
|
});
|
|
1731
1746
|
return reservesByAddress;
|
|
@@ -1743,7 +1758,10 @@ export async function getSingleReserve(
|
|
|
1743
1758
|
if (reserve === null) {
|
|
1744
1759
|
throw new Error(`Reserve account ${reservePk} does not exist`);
|
|
1745
1760
|
}
|
|
1746
|
-
const reservesAndOracles = await
|
|
1761
|
+
const [reservesAndOracles, cdnResourcesData] = await Promise.all([
|
|
1762
|
+
getTokenOracleData(rpc, [{ address: reservePk, state: reserve }], oracleAccounts),
|
|
1763
|
+
fetchKaminoCdnData(),
|
|
1764
|
+
]);
|
|
1747
1765
|
const [, oracle] = reservesAndOracles[0];
|
|
1748
1766
|
|
|
1749
1767
|
if (!oracle) {
|
|
@@ -1753,7 +1771,7 @@ export async function getSingleReserve(
|
|
|
1753
1771
|
}`
|
|
1754
1772
|
);
|
|
1755
1773
|
}
|
|
1756
|
-
return KaminoReserve.initialize(reservePk, reserve, oracle, rpc, recentSlotDurationMs);
|
|
1774
|
+
return KaminoReserve.initialize(reservePk, reserve, oracle, rpc, recentSlotDurationMs, cdnResourcesData);
|
|
1757
1775
|
}
|
|
1758
1776
|
|
|
1759
1777
|
export function getReservesActive(reserves: Map<Address, KaminoReserve>): Map<Address, KaminoReserve> {
|
package/src/classes/reserve.ts
CHANGED
|
@@ -57,6 +57,7 @@ import { SYSVAR_RENT_ADDRESS } from '@solana/sysvars';
|
|
|
57
57
|
import { noopSigner } from '../utils/signer';
|
|
58
58
|
import { getRewardPerTimeUnitSecond } from './farm_utils';
|
|
59
59
|
import { Scope, ScopeEntryMetadata } from '@kamino-finance/scope-sdk';
|
|
60
|
+
import { fetchKaminoCdnData, KaminoCdnData } from '../utils/readCdnData';
|
|
60
61
|
|
|
61
62
|
export type KaminoReserveRpcApi = GetProgramAccountsApi & GetAccountInfoApi & GetMultipleAccountsApi;
|
|
62
63
|
|
|
@@ -97,10 +98,11 @@ export class KaminoReserve {
|
|
|
97
98
|
state: Reserve,
|
|
98
99
|
tokenOraclePrice: TokenOracleData,
|
|
99
100
|
rpc: Rpc<KaminoReserveRpcApi>,
|
|
100
|
-
recentSlotDurationMs: number
|
|
101
|
+
recentSlotDurationMs: number,
|
|
102
|
+
cdnResourcesData?: KaminoCdnData
|
|
101
103
|
): KaminoReserve {
|
|
102
104
|
const reserve = new KaminoReserve(state, address, tokenOraclePrice, rpc, recentSlotDurationMs);
|
|
103
|
-
reserve.stats = reserve.formatReserveData(state);
|
|
105
|
+
reserve.stats = reserve.formatReserveData(state, cdnResourcesData?.deprecatedAssets ?? []);
|
|
104
106
|
return reserve;
|
|
105
107
|
}
|
|
106
108
|
|
|
@@ -779,13 +781,16 @@ export class KaminoReserve {
|
|
|
779
781
|
}
|
|
780
782
|
|
|
781
783
|
async load(tokenOraclePrice: TokenOracleData) {
|
|
782
|
-
const parsedData = await
|
|
784
|
+
const [parsedData, cdnResourcesData] = await Promise.all([
|
|
785
|
+
Reserve.fetch(this.rpc, this.address),
|
|
786
|
+
fetchKaminoCdnData(),
|
|
787
|
+
]);
|
|
783
788
|
if (!parsedData) {
|
|
784
789
|
throw Error(`Unable to parse data of reserve ${this.symbol}`);
|
|
785
790
|
}
|
|
786
791
|
this.state = parsedData;
|
|
787
792
|
this.tokenOraclePrice = tokenOraclePrice;
|
|
788
|
-
this.stats = this.formatReserveData(parsedData);
|
|
793
|
+
this.stats = this.formatReserveData(parsedData, cdnResourcesData?.deprecatedAssets ?? []);
|
|
789
794
|
}
|
|
790
795
|
|
|
791
796
|
totalSupplyAPY(currentSlot: Slot) {
|
|
@@ -874,7 +879,7 @@ export class KaminoReserve {
|
|
|
874
879
|
return { apy: aprToApy(apr, 365), apr };
|
|
875
880
|
}
|
|
876
881
|
|
|
877
|
-
private formatReserveData(parsedData: ReserveFields): ReserveDataType {
|
|
882
|
+
private formatReserveData(parsedData: ReserveFields, deprecatedAssets: string[]): ReserveDataType {
|
|
878
883
|
const mintTotalSupply = new Decimal(parsedData.collateral.mintTotalSupply.toString()).div(this.getMintFactor());
|
|
879
884
|
let reserveStatus = ReserveStatus.Active;
|
|
880
885
|
switch (parsedData.config.status) {
|
|
@@ -888,6 +893,8 @@ export class KaminoReserve {
|
|
|
888
893
|
reserveStatus = ReserveStatus.Hidden;
|
|
889
894
|
break;
|
|
890
895
|
}
|
|
896
|
+
const reserveIsUIDeprecated =
|
|
897
|
+
deprecatedAssets.length > 0 ? deprecatedAssets.includes(this.address.toString()) : undefined;
|
|
891
898
|
return {
|
|
892
899
|
// Reserve config
|
|
893
900
|
|
|
@@ -910,6 +917,7 @@ export class KaminoReserve {
|
|
|
910
917
|
depositLimitCrossedTimestamp: parsedData.liquidity.depositLimitCrossedTimestamp.toNumber(),
|
|
911
918
|
borrowLimitCrossedTimestamp: parsedData.liquidity.borrowLimitCrossedTimestamp.toNumber(),
|
|
912
919
|
borrowFactor: parsedData.config.borrowFactorPct.toNumber(),
|
|
920
|
+
isUIDeprecated: reserveIsUIDeprecated,
|
|
913
921
|
};
|
|
914
922
|
}
|
|
915
923
|
|