@kamino-finance/klend-sdk 6.0.5-beta.5 → 6.0.5-beta.8
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/action.d.ts +1 -1
- package/dist/classes/action.d.ts.map +1 -1
- package/dist/classes/action.js +28 -13
- package/dist/classes/action.js.map +1 -1
- package/dist/classes/manager.d.ts +29 -18
- package/dist/classes/manager.d.ts.map +1 -1
- package/dist/classes/manager.js +65 -47
- package/dist/classes/manager.js.map +1 -1
- package/dist/classes/market.d.ts +2 -3
- package/dist/classes/market.d.ts.map +1 -1
- package/dist/classes/market.js +8 -9
- package/dist/classes/market.js.map +1 -1
- package/dist/client_kamino_manager.d.ts.map +1 -1
- package/dist/client_kamino_manager.js +30 -22
- package/dist/client_kamino_manager.js.map +1 -1
- package/dist/leverage/operations.d.ts +3 -2
- package/dist/leverage/operations.d.ts.map +1 -1
- package/dist/leverage/operations.js +17 -12
- package/dist/leverage/operations.js.map +1 -1
- package/dist/leverage/types.d.ts +1 -0
- package/dist/leverage/types.d.ts.map +1 -1
- package/dist/utils/managerTypes.d.ts +1 -2
- package/dist/utils/managerTypes.d.ts.map +1 -1
- package/dist/utils/managerTypes.js +9 -9
- package/dist/utils/managerTypes.js.map +1 -1
- package/dist/utils/oracle.d.ts +2 -2
- package/dist/utils/oracle.d.ts.map +1 -1
- package/dist/utils/oracle.js.map +1 -1
- package/dist/utils/pubkey.d.ts +1 -0
- package/dist/utils/pubkey.d.ts.map +1 -1
- package/dist/utils/pubkey.js +10 -0
- package/dist/utils/pubkey.js.map +1 -1
- package/package.json +2 -2
- package/src/classes/action.ts +28 -12
- package/src/classes/manager.ts +80 -51
- package/src/classes/market.ts +14 -19
- package/src/client.ts +4 -4
- package/src/client_kamino_manager.ts +40 -35
- package/src/leverage/operations.ts +21 -14
- package/src/leverage/types.ts +1 -0
- package/src/utils/managerTypes.ts +1 -2
- package/src/utils/oracle.ts +2 -2
- package/src/utils/pubkey.ts +9 -0
package/src/classes/action.ts
CHANGED
|
@@ -75,7 +75,7 @@ import { KaminoReserve } from './reserve';
|
|
|
75
75
|
import { ReserveFarmKind } from '../idl_codegen/types';
|
|
76
76
|
import { farmsId } from '@kamino-finance/farms-sdk';
|
|
77
77
|
import { Reserve } from '../idl_codegen/accounts';
|
|
78
|
-
import { VanillaObligation } from '../utils
|
|
78
|
+
import { VanillaObligation } from '../utils';
|
|
79
79
|
import { PROGRAM_ID } from '../lib';
|
|
80
80
|
import { Scope } from '@kamino-finance/scope-sdk';
|
|
81
81
|
import { ObligationOrderAtIndex } from './obligationOrder';
|
|
@@ -430,12 +430,12 @@ export class KaminoAction {
|
|
|
430
430
|
return axn;
|
|
431
431
|
}
|
|
432
432
|
|
|
433
|
-
async addScopeRefreshIxs(scope: Scope, tokens: number[],
|
|
433
|
+
async addScopeRefreshIxs(scope: Scope, tokens: number[], scopeConfig: PublicKey) {
|
|
434
434
|
this.setupIxsLabels.unshift(`refreshScopePrices`);
|
|
435
435
|
this.setupIxs.unshift(
|
|
436
436
|
await scope.refreshPriceListIx(
|
|
437
437
|
{
|
|
438
|
-
|
|
438
|
+
config: scopeConfig,
|
|
439
439
|
},
|
|
440
440
|
tokens
|
|
441
441
|
)
|
|
@@ -732,10 +732,16 @@ export class KaminoAction {
|
|
|
732
732
|
...(axn.outflowReserve ? [axn.outflowReserve.address] : []),
|
|
733
733
|
...(axn.preLoadedDepositReservesSameTx ? axn.preLoadedDepositReservesSameTx : []),
|
|
734
734
|
]).toArray();
|
|
735
|
-
const tokenIds = getTokenIdsForScopeRefresh(axn.kaminoMarket, allReserves);
|
|
736
735
|
|
|
737
|
-
|
|
738
|
-
|
|
736
|
+
const scopeTokensMap = getTokenIdsForScopeRefresh(axn.kaminoMarket, allReserves);
|
|
737
|
+
|
|
738
|
+
if (scopeTokensMap.size > 0 && scopeRefreshConfig) {
|
|
739
|
+
for (const [configPubkey, config] of scopeRefreshConfig.scopeConfigurations) {
|
|
740
|
+
const tokenIds = scopeTokensMap.get(config.oraclePrices);
|
|
741
|
+
if (tokenIds && tokenIds.length > 0) {
|
|
742
|
+
await axn.addScopeRefreshIxs(scopeRefreshConfig.scope, tokenIds, configPubkey);
|
|
743
|
+
}
|
|
744
|
+
}
|
|
739
745
|
}
|
|
740
746
|
return axn;
|
|
741
747
|
}
|
|
@@ -922,10 +928,15 @@ export class KaminoAction {
|
|
|
922
928
|
...(axn.outflowReserve ? [axn.outflowReserve.address] : []),
|
|
923
929
|
...(axn.preLoadedDepositReservesSameTx ? axn.preLoadedDepositReservesSameTx : []),
|
|
924
930
|
]).toArray();
|
|
925
|
-
const
|
|
931
|
+
const scopeTokensMap = getTokenIdsForScopeRefresh(axn.kaminoMarket, allReserves);
|
|
926
932
|
|
|
927
|
-
if (
|
|
928
|
-
|
|
933
|
+
if (scopeTokensMap.size > 0 && scopeRefreshConfig) {
|
|
934
|
+
for (const [configPubkey, config] of scopeRefreshConfig.scopeConfigurations) {
|
|
935
|
+
const tokenIds = scopeTokensMap.get(config.oraclePrices);
|
|
936
|
+
if (tokenIds && tokenIds.length > 0) {
|
|
937
|
+
await axn.addScopeRefreshIxs(scopeRefreshConfig.scope, tokenIds, configPubkey);
|
|
938
|
+
}
|
|
939
|
+
}
|
|
929
940
|
}
|
|
930
941
|
return axn;
|
|
931
942
|
}
|
|
@@ -2748,10 +2759,15 @@ export class KaminoAction {
|
|
|
2748
2759
|
...(this.outflowReserve ? [this.outflowReserve.address] : []),
|
|
2749
2760
|
...(this.preLoadedDepositReservesSameTx ? this.preLoadedDepositReservesSameTx : []),
|
|
2750
2761
|
]).toArray();
|
|
2751
|
-
const
|
|
2762
|
+
const scopeTokensMap = getTokenIdsForScopeRefresh(this.kaminoMarket, allReserves);
|
|
2752
2763
|
|
|
2753
|
-
if (
|
|
2754
|
-
|
|
2764
|
+
if (scopeTokensMap.size > 0 && scopeRefreshConfig) {
|
|
2765
|
+
for (const [configPubkey, config] of scopeRefreshConfig.scopeConfigurations) {
|
|
2766
|
+
const tokenIds = scopeTokensMap.get(config.oraclePrices);
|
|
2767
|
+
if (tokenIds && tokenIds.length > 0) {
|
|
2768
|
+
await this.addScopeRefreshIxs(scopeRefreshConfig.scope, tokenIds, configPubkey);
|
|
2769
|
+
}
|
|
2770
|
+
}
|
|
2755
2771
|
}
|
|
2756
2772
|
}
|
|
2757
2773
|
|
package/src/classes/manager.ts
CHANGED
|
@@ -52,6 +52,7 @@ import {
|
|
|
52
52
|
Reserve,
|
|
53
53
|
ReserveWithAddress,
|
|
54
54
|
ScopeOracleConfig,
|
|
55
|
+
setOrAppend,
|
|
55
56
|
updateEntireReserveConfigIx,
|
|
56
57
|
updateLendingMarket,
|
|
57
58
|
UpdateLendingMarketAccounts,
|
|
@@ -60,7 +61,7 @@ import {
|
|
|
60
61
|
UpdateLendingMarketOwnerAccounts,
|
|
61
62
|
} from '../lib';
|
|
62
63
|
import { PROGRAM_ID } from '../idl_codegen/programId';
|
|
63
|
-
import { Scope, TokenMetadatas, U16_MAX } from '@kamino-finance/scope-sdk';
|
|
64
|
+
import { OracleMappings, Scope, TokenMetadatas, U16_MAX } from '@kamino-finance/scope-sdk';
|
|
64
65
|
import BN from 'bn.js';
|
|
65
66
|
import { ReserveConfig, UpdateLendingMarketMode, UpdateLendingMarketModeKind } from '../idl_codegen/types';
|
|
66
67
|
import Decimal from 'decimal.js';
|
|
@@ -69,7 +70,7 @@ import { VaultState } from '../idl_codegen_kamino_vault/accounts';
|
|
|
69
70
|
import { TOKEN_PROGRAM_ID } from '@solana/spl-token';
|
|
70
71
|
import { Data } from '@kamino-finance/kliquidity-sdk';
|
|
71
72
|
import bs58 from 'bs58';
|
|
72
|
-
import { getProgramAccounts } from '../utils
|
|
73
|
+
import { getProgramAccounts } from '../utils';
|
|
73
74
|
import { VaultConfigField, VaultConfigFieldKind } from '../idl_codegen_kamino_vault/types';
|
|
74
75
|
import {
|
|
75
76
|
AcceptVaultOwnershipIxs,
|
|
@@ -317,6 +318,7 @@ export class KaminoManager {
|
|
|
317
318
|
* This function enables the update of the scope oracle configuration. In order to get a list of scope prices, getScopeOracleConfigs can be used
|
|
318
319
|
* @param market - lending market which owns the reserve
|
|
319
320
|
* @param reserve - reserve which to be updated
|
|
321
|
+
* @param oraclePrices - scope OraclePrices account pubkey
|
|
320
322
|
* @param scopeOracleConfig - new scope oracle config
|
|
321
323
|
* @param scopeTwapConfig - new scope twap config
|
|
322
324
|
* @param maxAgeBufferSeconds - buffer to be added to onchain max_age - if oracle price is older than that, txns interacting with the reserve will fail
|
|
@@ -325,6 +327,7 @@ export class KaminoManager {
|
|
|
325
327
|
async updateReserveScopeOracleConfigurationIxs(
|
|
326
328
|
market: MarketWithAddress,
|
|
327
329
|
reserve: ReserveWithAddress,
|
|
330
|
+
oraclePrices: PublicKey,
|
|
328
331
|
scopeOracleConfig: ScopeOracleConfig,
|
|
329
332
|
scopeTwapConfig?: ScopeOracleConfig,
|
|
330
333
|
maxAgeBufferSeconds: number = 20
|
|
@@ -341,7 +344,7 @@ export class KaminoManager {
|
|
|
341
344
|
}
|
|
342
345
|
|
|
343
346
|
const { scopeConfiguration } = getReserveOracleConfigs({
|
|
344
|
-
scopePriceConfigAddress:
|
|
347
|
+
scopePriceConfigAddress: oraclePrices,
|
|
345
348
|
scopeChain: [scopeOracleConfig.oracleId],
|
|
346
349
|
scopeTwapChain: [scopeTwapId],
|
|
347
350
|
});
|
|
@@ -523,7 +526,6 @@ export class KaminoManager {
|
|
|
523
526
|
* This method withdraws all the pending fees from the vault to the owner's token ATA
|
|
524
527
|
* @param vault - vault for which the admin withdraws the pending fees
|
|
525
528
|
* @param slot - current slot, used to estimate the interest earned in the different reserves with allocation from the vault
|
|
526
|
-
* @param [vaultReservesMap] - 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
|
|
527
529
|
* @returns - list of instructions to withdraw all pending fees, including the ATA creation instructions if needed
|
|
528
530
|
*/
|
|
529
531
|
async withdrawPendingFeesIxs(vault: KaminoVault, slot: number): Promise<TransactionInstruction[]> {
|
|
@@ -533,7 +535,7 @@ export class KaminoManager {
|
|
|
533
535
|
/**
|
|
534
536
|
* This method inserts the missing keys from the provided keys into an existent lookup table
|
|
535
537
|
* @param payer - payer wallet pubkey
|
|
536
|
-
* @param
|
|
538
|
+
* @param lut
|
|
537
539
|
* @param keys - keys to insert into the lookup table
|
|
538
540
|
* @param [accountsInLUT] - the existent accounts in the lookup table. Optional. If provided, the function will not fetch the accounts in the lookup table
|
|
539
541
|
* @returns - an array of instructions to insert the missing keys into the lookup table
|
|
@@ -551,7 +553,6 @@ export class KaminoManager {
|
|
|
551
553
|
* Sync a vault for lookup table; create and set the LUT for the vault if needed and fill it with all the needed accounts
|
|
552
554
|
* @param vault the vault to sync and set the LUT for if needed
|
|
553
555
|
* @param vaultReserves optional; the state of the reserves in the vault allocation
|
|
554
|
-
* @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
|
|
555
556
|
* @returns a struct that contains a list of ix to create the LUT and assign it to the vault if needed + a list of ixs to insert all the accounts in the LUT
|
|
556
557
|
*/
|
|
557
558
|
async syncVaultLUTIxs(
|
|
@@ -632,8 +633,8 @@ export class KaminoManager {
|
|
|
632
633
|
|
|
633
634
|
/**
|
|
634
635
|
* This method returns the vault name
|
|
635
|
-
* @param vault - vault to retrieve the onchain name for
|
|
636
636
|
* @returns - the vault name as string
|
|
637
|
+
* @param vaultState
|
|
637
638
|
*/
|
|
638
639
|
getDecodedVaultName(vaultState: VaultState): string {
|
|
639
640
|
return this._vaultClient.decodeVaultName(vaultState.name);
|
|
@@ -691,7 +692,7 @@ export class KaminoManager {
|
|
|
691
692
|
}
|
|
692
693
|
}
|
|
693
694
|
|
|
694
|
-
|
|
695
|
+
return lendingMarketPairs.map(([pubkey, market]) => {
|
|
695
696
|
const reserves = marketToReserve.get(pubkey);
|
|
696
697
|
const reservesByAddress = new PubkeyHashMap<PublicKey, KaminoReserve>();
|
|
697
698
|
if (!reserves) {
|
|
@@ -720,8 +721,6 @@ export class KaminoManager {
|
|
|
720
721
|
|
|
721
722
|
return KaminoMarket.loadWithReserves(this.getConnection(), market, reservesByAddress, pubkey, slotDuration);
|
|
722
723
|
});
|
|
723
|
-
|
|
724
|
-
return combinedMarkets;
|
|
725
724
|
}
|
|
726
725
|
|
|
727
726
|
/**
|
|
@@ -859,7 +858,7 @@ export class KaminoManager {
|
|
|
859
858
|
* @param vault - the kamino vault to get available liquidity to withdraw for
|
|
860
859
|
* @param price - the price of the token in the vault (e.g. USDC)
|
|
861
860
|
* @param [slot] - the slot for which to calculate the holdings. Optional. If not provided the function will fetch the current slot
|
|
862
|
-
* @param
|
|
861
|
+
* @param vaultReserves
|
|
863
862
|
* @param [currentSlot] - the latest confirmed slot. Optional. If provided the function will be faster as it will not have to fetch the latest slot
|
|
864
863
|
* @returns an VaultHoldingsWithUSDValue object with details about the tokens available and invested in the vault, denominated in tokens and USD
|
|
865
864
|
*/
|
|
@@ -878,7 +877,7 @@ export class KaminoManager {
|
|
|
878
877
|
* @param vault - the kamino vault to get available liquidity to withdraw for
|
|
879
878
|
* @param price - the price of the token in the vault (e.g. USDC)
|
|
880
879
|
* @param [slot] - the slot for which to retrieve the vault overview for. Optional. If not provided the function will fetch the current slot
|
|
881
|
-
* @param
|
|
880
|
+
* @param vaultReserves
|
|
882
881
|
* @param [kaminoMarkets] - a list of all kamino markets. Optional. If provided the function will be significantly faster as it will not have to fetch the markets
|
|
883
882
|
* @param [currentSlot] - the latest confirmed slot. Optional. If provided the function will be faster as it will not have to fetch the latest slot
|
|
884
883
|
* @returns an VaultOverview object with details about the tokens available and invested in the vault, denominated in tokens and USD
|
|
@@ -938,7 +937,7 @@ export class KaminoManager {
|
|
|
938
937
|
* 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 as ratio; for percentage it needs multiplication by 100
|
|
939
938
|
* @param vault - the kamino vault to get APY for
|
|
940
939
|
* @param slot - current slot
|
|
941
|
-
* @param
|
|
940
|
+
* @param vaultReserves
|
|
942
941
|
* @returns a struct containing estimated gross APY and net APY (gross - vault fees) for the vault
|
|
943
942
|
*/
|
|
944
943
|
async getVaultTheoreticalAPY(
|
|
@@ -953,7 +952,7 @@ export class KaminoManager {
|
|
|
953
952
|
* This will return the APY of the vault based on the current invested amounts; for percentage it needs multiplication by 100
|
|
954
953
|
* @param vault - the kamino vault to get APY for
|
|
955
954
|
* @param slot - current slot
|
|
956
|
-
* @param
|
|
955
|
+
* @param vaultReserves
|
|
957
956
|
* @returns a struct containing estimated gross APY and net APY (gross - vault fees) for the vault
|
|
958
957
|
*/
|
|
959
958
|
async getVaultActualAPY(
|
|
@@ -976,8 +975,10 @@ export class KaminoManager {
|
|
|
976
975
|
/**
|
|
977
976
|
* Simulate the current holdings of the vault and the earned interest
|
|
978
977
|
* @param vaultState the kamino vault state to get simulated holdings and earnings for
|
|
979
|
-
* @param
|
|
980
|
-
* @param
|
|
978
|
+
* @param vaultReserves
|
|
979
|
+
* @param vaultReserves
|
|
980
|
+
* @param slot
|
|
981
|
+
* @param slot
|
|
981
982
|
* @param [previousTotalAUM] - the previous AUM of the vault to compute the earned interest relative to this value. Optional. If not provided the function will estimate the total AUM at the slot of the last state update on chain
|
|
982
983
|
* @param [currentSlot] - the latest confirmed slot. Optional. If provided the function will be faster as it will not have to fetch the latest slot
|
|
983
984
|
* @returns a struct of simulated vault holdings and earned interest
|
|
@@ -1056,8 +1057,8 @@ export class KaminoManager {
|
|
|
1056
1057
|
|
|
1057
1058
|
/**
|
|
1058
1059
|
* This will load the onchain state for all the reserves that the vault has allocations for
|
|
1059
|
-
* @param vaultState - the vault state to load reserves for
|
|
1060
1060
|
* @returns a hashmap from each reserve pubkey to the reserve state
|
|
1061
|
+
* @param vault
|
|
1061
1062
|
*/
|
|
1062
1063
|
getVaultReserves(vault: VaultState): PublicKey[] {
|
|
1063
1064
|
return this._vaultClient.getVaultReserves(vault);
|
|
@@ -1067,6 +1068,15 @@ export class KaminoManager {
|
|
|
1067
1068
|
* This will retrieve all the tokens that can be use as collateral by the users who borrow the token in the vault alongside details about the min and max loan to value ratio
|
|
1068
1069
|
* @param vaultState - the vault state to load reserves for
|
|
1069
1070
|
*
|
|
1071
|
+
* @param slot
|
|
1072
|
+
* @param vaultReservesMap
|
|
1073
|
+
* @param kaminoMarkets
|
|
1074
|
+
* @param slot
|
|
1075
|
+
* @param vaultReservesMap
|
|
1076
|
+
* @param kaminoMarkets
|
|
1077
|
+
* @param slot
|
|
1078
|
+
* @param vaultReservesMap
|
|
1079
|
+
* @param kaminoMarkets
|
|
1070
1080
|
* @returns a hashmap from each reserve pubkey to the market overview of the collaterals that can be used and the min and max loan to value ratio in that market
|
|
1071
1081
|
*/
|
|
1072
1082
|
async getVaultCollaterals(
|
|
@@ -1080,6 +1090,7 @@ export class KaminoManager {
|
|
|
1080
1090
|
|
|
1081
1091
|
/**
|
|
1082
1092
|
* 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
|
|
1093
|
+
* @param payer
|
|
1083
1094
|
* @param kaminoVault - vault to invest from
|
|
1084
1095
|
* @returns - an array of invest instructions for each invest action required for the vault reserves
|
|
1085
1096
|
*/
|
|
@@ -1090,8 +1101,8 @@ export class KaminoManager {
|
|
|
1090
1101
|
/**
|
|
1091
1102
|
* This will trigger invest by balancing, based on weights, the reserve allocation of the vault. It can either withdraw or deposit into the given reserve to balance it
|
|
1092
1103
|
* @param payer wallet pubkey
|
|
1093
|
-
* @param
|
|
1094
|
-
* @param
|
|
1104
|
+
* @param kaminoVault
|
|
1105
|
+
* @param reserveWithAddress
|
|
1095
1106
|
* @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
|
|
1096
1107
|
* @returns - an array of invest instructions for each invest action required for the vault reserves
|
|
1097
1108
|
*/
|
|
@@ -1124,7 +1135,7 @@ export class KaminoManager {
|
|
|
1124
1135
|
|
|
1125
1136
|
/**
|
|
1126
1137
|
* This will return the amount of token invested from the vault into the given reserve
|
|
1127
|
-
* @param
|
|
1138
|
+
* @param vaultState
|
|
1128
1139
|
* @param slot - current slot
|
|
1129
1140
|
* @param reserve - the reserve state to get vault invested amount in
|
|
1130
1141
|
* @returns vault amount supplied in reserve in decimal
|
|
@@ -1135,43 +1146,63 @@ export class KaminoManager {
|
|
|
1135
1146
|
|
|
1136
1147
|
/**
|
|
1137
1148
|
* This returns an array of scope oracle configs to be used to set the scope price and twap oracles for a reserve
|
|
1138
|
-
* @param
|
|
1149
|
+
* @param market - kamino market
|
|
1139
1150
|
* @param cluster - cluster to fetch from, this should be left unchanged unless working on devnet or locally
|
|
1140
|
-
* @returns -
|
|
1151
|
+
* @returns - a map with keys as scope OraclePrices pubkeys and values of scope oracle configs
|
|
1141
1152
|
*/
|
|
1142
1153
|
async getScopeOracleConfigs(
|
|
1143
|
-
|
|
1154
|
+
market: KaminoMarket,
|
|
1144
1155
|
cluster: ENV = 'mainnet-beta'
|
|
1145
|
-
): Promise<
|
|
1146
|
-
const scopeOracleConfigs
|
|
1156
|
+
): Promise<PubkeyHashMap<PublicKey, ScopeOracleConfig[]>> {
|
|
1157
|
+
const scopeOracleConfigs = new PubkeyHashMap<PublicKey, ScopeOracleConfig[]>();
|
|
1147
1158
|
|
|
1148
1159
|
const scope = new Scope(cluster, this._connection);
|
|
1149
|
-
const oracleMappings = await scope.getOracleMappings({ feed: feed });
|
|
1150
|
-
const [, feedConfig] = await scope.getFeedConfiguration({ feed: feed });
|
|
1151
|
-
const tokenMetadatas = await TokenMetadatas.fetch(this._connection, feedConfig.tokensMetadata);
|
|
1152
|
-
const decoder = new TextDecoder('utf-8');
|
|
1153
|
-
|
|
1154
|
-
console.log('feedConfig.tokensMetadata', feedConfig.tokensMetadata);
|
|
1155
1160
|
|
|
1156
|
-
|
|
1157
|
-
|
|
1161
|
+
const configs = (await scope.getAllConfigurations()).filter(([_, config]) =>
|
|
1162
|
+
market.scopeFeeds.contains(config.oraclePrices)
|
|
1163
|
+
);
|
|
1164
|
+
if (!configs || configs.length === 0) {
|
|
1165
|
+
return scopeOracleConfigs;
|
|
1158
1166
|
}
|
|
1159
1167
|
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1168
|
+
const configOracleMappings = await OracleMappings.fetchMultiple(
|
|
1169
|
+
this._connection,
|
|
1170
|
+
configs.map(([_, config]) => config.oracleMappings),
|
|
1171
|
+
scope.config.programId
|
|
1172
|
+
);
|
|
1173
|
+
|
|
1174
|
+
const configTokenMetadatas = await TokenMetadatas.fetchMultiple(
|
|
1175
|
+
this._connection,
|
|
1176
|
+
configs.map(([_, config]) => config.tokensMetadata),
|
|
1177
|
+
scope.config.programId
|
|
1178
|
+
);
|
|
1179
|
+
const decoder = new TextDecoder('utf-8');
|
|
1180
|
+
|
|
1181
|
+
for (let i = 0; i < configs.length; i++) {
|
|
1182
|
+
const [configPubkey, config] = configs[i];
|
|
1183
|
+
const oracleMappings = configOracleMappings[i];
|
|
1184
|
+
const tokenMetadatas = configTokenMetadatas[i];
|
|
1185
|
+
if (!oracleMappings) {
|
|
1186
|
+
throw new Error(`OracleMappings account not found for config ${configPubkey}`);
|
|
1187
|
+
}
|
|
1188
|
+
if (!tokenMetadatas) {
|
|
1189
|
+
throw new Error(`TokenMetadatas account not found for config ${configPubkey}`);
|
|
1190
|
+
}
|
|
1191
|
+
|
|
1192
|
+
for (let j = 0; j < oracleMappings.priceInfoAccounts.length; j++) {
|
|
1193
|
+
if (!oracleMappings.priceInfoAccounts[j].equals(PublicKey.default)) {
|
|
1194
|
+
const name = decoder.decode(Uint8Array.from(tokenMetadatas.metadatasArray[j].name)).replace(/\0/g, '');
|
|
1195
|
+
const oracleType = parseOracleType(oracleMappings.priceTypes[j]);
|
|
1196
|
+
setOrAppend(scopeOracleConfigs, config.oraclePrices, {
|
|
1197
|
+
name: name,
|
|
1198
|
+
oracleType: oracleType,
|
|
1199
|
+
oracleId: j,
|
|
1200
|
+
oracleAccount: oracleMappings.priceInfoAccounts[j],
|
|
1201
|
+
twapEnabled: oracleMappings.twapEnabled[j] === 1,
|
|
1202
|
+
twapSourceId: oracleMappings.twapSource[j],
|
|
1203
|
+
max_age: tokenMetadatas.metadatasArray[j].maxAgePriceSlots.toNumber(),
|
|
1204
|
+
});
|
|
1205
|
+
}
|
|
1175
1206
|
}
|
|
1176
1207
|
}
|
|
1177
1208
|
|
|
@@ -1329,7 +1360,5 @@ function updateMarketConfigIx(
|
|
|
1329
1360
|
value: [...value, ...Array(72 - value.length).fill(0)],
|
|
1330
1361
|
};
|
|
1331
1362
|
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
return ix;
|
|
1363
|
+
return updateLendingMarket(args, accounts, programId);
|
|
1335
1364
|
}
|
package/src/classes/market.ts
CHANGED
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
CandidatePrice,
|
|
23
23
|
PublicKeySet,
|
|
24
24
|
DEPOSITS_LIMIT,
|
|
25
|
+
setOrAppend,
|
|
25
26
|
} from '../utils';
|
|
26
27
|
import base58 from 'bs58';
|
|
27
28
|
import { BN } from '@coral-xyz/anchor';
|
|
@@ -62,7 +63,7 @@ export class KaminoMarket {
|
|
|
62
63
|
|
|
63
64
|
private readonly recentSlotDurationMs: number;
|
|
64
65
|
|
|
65
|
-
|
|
66
|
+
readonly scopeFeeds: PublicKeySet<PublicKey>;
|
|
66
67
|
|
|
67
68
|
private constructor(
|
|
68
69
|
connection: Connection,
|
|
@@ -93,7 +94,6 @@ export class KaminoMarket {
|
|
|
93
94
|
* @param recentSlotDurationMs
|
|
94
95
|
* @param programId
|
|
95
96
|
* @param withReserves
|
|
96
|
-
* @param setupLocalTest
|
|
97
97
|
* @param withReserves
|
|
98
98
|
*/
|
|
99
99
|
static async load(
|
|
@@ -1544,16 +1544,7 @@ export async function getSingleReserve(
|
|
|
1544
1544
|
if (!oracle) {
|
|
1545
1545
|
throw Error(`Could not find oracle for ${parseTokenSymbol(reserveState.config.tokenInfo.name)} reserve`);
|
|
1546
1546
|
}
|
|
1547
|
-
|
|
1548
|
-
reserve,
|
|
1549
|
-
reservePk,
|
|
1550
|
-
reserveState,
|
|
1551
|
-
oracle,
|
|
1552
|
-
connection,
|
|
1553
|
-
recentSlotDurationMs
|
|
1554
|
-
);
|
|
1555
|
-
|
|
1556
|
-
return kaminoReserve;
|
|
1547
|
+
return KaminoReserve.initialize(reserve, reservePk, reserveState, oracle, connection, recentSlotDurationMs);
|
|
1557
1548
|
}
|
|
1558
1549
|
|
|
1559
1550
|
export function getReservesActive(reserves: Map<PublicKey, KaminoReserve>): Map<PublicKey, KaminoReserve> {
|
|
@@ -1566,8 +1557,11 @@ export function getReservesActive(reserves: Map<PublicKey, KaminoReserve>): Map<
|
|
|
1566
1557
|
return reservesActive;
|
|
1567
1558
|
}
|
|
1568
1559
|
|
|
1569
|
-
export function getTokenIdsForScopeRefresh(
|
|
1570
|
-
|
|
1560
|
+
export function getTokenIdsForScopeRefresh(
|
|
1561
|
+
kaminoMarket: KaminoMarket,
|
|
1562
|
+
reserves: PublicKey[]
|
|
1563
|
+
): PubkeyHashMap<PublicKey, number[]> {
|
|
1564
|
+
const tokenIds = new PubkeyHashMap<PublicKey, number[]>();
|
|
1571
1565
|
|
|
1572
1566
|
for (const reserveAddress of reserves) {
|
|
1573
1567
|
const reserve = kaminoMarket.getReserveByAddress(reserveAddress);
|
|
@@ -1575,17 +1569,18 @@ export function getTokenIdsForScopeRefresh(kaminoMarket: KaminoMarket, reserves:
|
|
|
1575
1569
|
throw new Error(`Reserve not found for reserve ${reserveAddress.toBase58()}`);
|
|
1576
1570
|
}
|
|
1577
1571
|
|
|
1578
|
-
|
|
1572
|
+
const { scopeConfiguration } = reserve.state.config.tokenInfo;
|
|
1573
|
+
if (!scopeConfiguration.priceFeed.equals(PublicKey.default)) {
|
|
1579
1574
|
let x = 0;
|
|
1580
1575
|
|
|
1581
|
-
while (
|
|
1582
|
-
tokenIds.
|
|
1576
|
+
while (scopeConfiguration.priceChain[x] !== U16_MAX) {
|
|
1577
|
+
setOrAppend(tokenIds, scopeConfiguration.priceFeed, scopeConfiguration.priceChain[x]);
|
|
1583
1578
|
x++;
|
|
1584
1579
|
}
|
|
1585
1580
|
|
|
1586
1581
|
x = 0;
|
|
1587
|
-
while (
|
|
1588
|
-
tokenIds.
|
|
1582
|
+
while (scopeConfiguration.twapChain[x] !== U16_MAX) {
|
|
1583
|
+
setOrAppend(tokenIds, scopeConfiguration.priceFeed, scopeConfiguration.twapChain[x]);
|
|
1589
1584
|
x++;
|
|
1590
1585
|
}
|
|
1591
1586
|
}
|
package/src/client.ts
CHANGED
|
@@ -362,7 +362,7 @@ async function deposit(connection: Connection, wallet: Keypair, token: string, d
|
|
|
362
362
|
wallet.publicKey,
|
|
363
363
|
new VanillaObligation(STAGING_LENDING_MARKET),
|
|
364
364
|
true,
|
|
365
|
-
{ scope: new Scope('mainnet-beta', connection),
|
|
365
|
+
{ scope: new Scope('mainnet-beta', connection), scopeConfigurations: [] }
|
|
366
366
|
);
|
|
367
367
|
console.log('User obligation', kaminoAction.getObligationPda().toString());
|
|
368
368
|
|
|
@@ -384,7 +384,7 @@ async function withdraw(connection: Connection, wallet: Keypair, token: string,
|
|
|
384
384
|
wallet.publicKey,
|
|
385
385
|
new VanillaObligation(new PublicKey(STAGING_LENDING_MARKET)),
|
|
386
386
|
true,
|
|
387
|
-
{ scope: new Scope('mainnet-beta', connection),
|
|
387
|
+
{ scope: new Scope('mainnet-beta', connection), scopeConfigurations: [] }
|
|
388
388
|
);
|
|
389
389
|
console.log('User obligation', kaminoAction.getObligationPda().toString());
|
|
390
390
|
|
|
@@ -406,7 +406,7 @@ async function borrow(connection: Connection, wallet: Keypair, token: string, bo
|
|
|
406
406
|
wallet.publicKey,
|
|
407
407
|
new VanillaObligation(new PublicKey(STAGING_LENDING_MARKET)),
|
|
408
408
|
true,
|
|
409
|
-
{ scope: new Scope('mainnet-beta', connection),
|
|
409
|
+
{ scope: new Scope('mainnet-beta', connection), scopeConfigurations: [] }
|
|
410
410
|
);
|
|
411
411
|
console.log('User obligation', kaminoAction.getObligationPda().toString());
|
|
412
412
|
|
|
@@ -428,7 +428,7 @@ async function repay(connection: Connection, wallet: Keypair, token: string, bor
|
|
|
428
428
|
wallet.publicKey,
|
|
429
429
|
new VanillaObligation(new PublicKey(STAGING_LENDING_MARKET)),
|
|
430
430
|
true,
|
|
431
|
-
{ scope: new Scope('mainnet-beta', connection),
|
|
431
|
+
{ scope: new Scope('mainnet-beta', connection), scopeConfigurations: [] },
|
|
432
432
|
await connection.getSlot()
|
|
433
433
|
);
|
|
434
434
|
console.log('User obligation', kaminoAction.getObligationPda().toString());
|