@kamino-finance/klend-sdk 6.0.5-beta.4 → 6.0.5-beta.7

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.
Files changed (48) hide show
  1. package/dist/classes/action.d.ts +1 -1
  2. package/dist/classes/action.d.ts.map +1 -1
  3. package/dist/classes/action.js +28 -13
  4. package/dist/classes/action.js.map +1 -1
  5. package/dist/classes/manager.d.ts +29 -18
  6. package/dist/classes/manager.d.ts.map +1 -1
  7. package/dist/classes/manager.js +65 -47
  8. package/dist/classes/manager.js.map +1 -1
  9. package/dist/classes/market.d.ts +2 -3
  10. package/dist/classes/market.d.ts.map +1 -1
  11. package/dist/classes/market.js +8 -9
  12. package/dist/classes/market.js.map +1 -1
  13. package/dist/client_kamino_manager.d.ts.map +1 -1
  14. package/dist/client_kamino_manager.js +30 -22
  15. package/dist/client_kamino_manager.js.map +1 -1
  16. package/dist/lending_operations/repay_with_collateral_operations.d.ts.map +1 -1
  17. package/dist/lending_operations/repay_with_collateral_operations.js +36 -32
  18. package/dist/lending_operations/repay_with_collateral_operations.js.map +1 -1
  19. package/dist/lending_operations/swap_collateral_operations.d.ts.map +1 -1
  20. package/dist/lending_operations/swap_collateral_operations.js +4 -4
  21. package/dist/lending_operations/swap_collateral_operations.js.map +1 -1
  22. package/dist/leverage/operations.d.ts +1 -1
  23. package/dist/leverage/operations.d.ts.map +1 -1
  24. package/dist/leverage/operations.js +177 -150
  25. package/dist/leverage/operations.js.map +1 -1
  26. package/dist/utils/managerTypes.d.ts +1 -2
  27. package/dist/utils/managerTypes.d.ts.map +1 -1
  28. package/dist/utils/managerTypes.js +9 -9
  29. package/dist/utils/managerTypes.js.map +1 -1
  30. package/dist/utils/oracle.d.ts +2 -2
  31. package/dist/utils/oracle.d.ts.map +1 -1
  32. package/dist/utils/oracle.js.map +1 -1
  33. package/dist/utils/pubkey.d.ts +1 -0
  34. package/dist/utils/pubkey.d.ts.map +1 -1
  35. package/dist/utils/pubkey.js +10 -0
  36. package/dist/utils/pubkey.js.map +1 -1
  37. package/package.json +2 -2
  38. package/src/classes/action.ts +28 -12
  39. package/src/classes/manager.ts +80 -51
  40. package/src/classes/market.ts +14 -19
  41. package/src/client.ts +4 -4
  42. package/src/client_kamino_manager.ts +40 -35
  43. package/src/lending_operations/repay_with_collateral_operations.ts +76 -72
  44. package/src/lending_operations/swap_collateral_operations.ts +13 -11
  45. package/src/leverage/operations.ts +349 -326
  46. package/src/utils/managerTypes.ts +1 -2
  47. package/src/utils/oracle.ts +2 -2
  48. package/src/utils/pubkey.ts +9 -0
@@ -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/rpc';
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: scopeOracleConfig.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 lookupTable - lookup table to insert the keys into
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
- const combinedMarkets = lendingMarketPairs.map(([pubkey, market]) => {
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 [vaultReservesMap] - 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
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 [vaultReservesMap] - 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
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 [vaultReservesMap] - 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
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 [vaultReservesMap] - 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
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 [vaultReservesMap] - 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
980
- * @param [currentSlot] - the current slot. Optional. If not provided it will fetch the current slot
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 vault - vault to invest from
1094
- * @param reserve - reserve to invest into or disinvest from
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 vault - the kamino vault to get invested amount in reserve for
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 feed - scope feed to fetch prices from
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 - an array of scope oracle configs
1151
+ * @returns - a map with keys as scope OraclePrices pubkeys and values of scope oracle configs
1141
1152
  */
1142
1153
  async getScopeOracleConfigs(
1143
- feed: string = 'hubble',
1154
+ market: KaminoMarket,
1144
1155
  cluster: ENV = 'mainnet-beta'
1145
- ): Promise<Array<ScopeOracleConfig>> {
1146
- const scopeOracleConfigs: Array<ScopeOracleConfig> = [];
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
- if (tokenMetadatas === null) {
1157
- throw new Error('TokenMetadatas not found');
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
- for (let index = 0; index < oracleMappings.priceInfoAccounts.length; index++) {
1161
- if (!oracleMappings.priceInfoAccounts[index].equals(PublicKey.default)) {
1162
- const name = decoder.decode(Uint8Array.from(tokenMetadatas.metadatasArray[index].name)).replace(/\0/g, '');
1163
- const oracleType = parseOracleType(oracleMappings.priceTypes[index]);
1164
-
1165
- scopeOracleConfigs.push({
1166
- scopePriceConfigAddress: feedConfig.oraclePrices,
1167
- name: name,
1168
- oracleType: oracleType,
1169
- oracleId: index,
1170
- oracleAccount: oracleMappings.priceInfoAccounts[index],
1171
- twapEnabled: oracleMappings.twapEnabled[index] === 1,
1172
- twapSourceId: oracleMappings.twapSource[index],
1173
- max_age: tokenMetadatas.metadatasArray[index].maxAgePriceSlots.toNumber(),
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
- const ix = updateLendingMarket(args, accounts, programId);
1333
-
1334
- return ix;
1363
+ return updateLendingMarket(args, accounts, programId);
1335
1364
  }
@@ -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
- private readonly scopeFeeds: PublicKeySet<PublicKey>;
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
- const kaminoReserve = KaminoReserve.initialize(
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(kaminoMarket: KaminoMarket, reserves: PublicKey[]): number[] {
1570
- const tokenIds: number[] = [];
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
- if (!reserve.state.config.tokenInfo.scopeConfiguration.priceFeed.equals(PublicKey.default)) {
1572
+ const { scopeConfiguration } = reserve.state.config.tokenInfo;
1573
+ if (!scopeConfiguration.priceFeed.equals(PublicKey.default)) {
1579
1574
  let x = 0;
1580
1575
 
1581
- while (reserve.state.config.tokenInfo.scopeConfiguration.priceChain[x] !== U16_MAX) {
1582
- tokenIds.push(reserve.state.config.tokenInfo.scopeConfiguration.priceChain[x]);
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 (reserve.state.config.tokenInfo.scopeConfiguration.twapChain[x] !== U16_MAX) {
1588
- tokenIds.push(reserve.state.config.tokenInfo.scopeConfiguration.twapChain[x]);
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), scopeFeed: 'hubble' }
365
+ { scope: new Scope('mainnet-beta', connection) }
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), scopeFeed: 'hubble' }
387
+ { scope: new Scope('mainnet-beta', connection) }
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), scopeFeed: 'hubble' }
409
+ { scope: new Scope('mainnet-beta', connection) }
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), scopeFeed: 'hubble' },
431
+ { scope: new Scope('mainnet-beta', connection) },
432
432
  await connection.getSlot()
433
433
  );
434
434
  console.log('User obligation', kaminoAction.getObligationPda().toString());
@@ -52,18 +52,18 @@ import {
52
52
  TokenInfo,
53
53
  WithdrawalCaps,
54
54
  } from './idl_codegen/types';
55
- import { Fraction } from './classes/fraction';
55
+ import { Fraction } from './classes';
56
56
  import Decimal from 'decimal.js';
57
57
  import { BN } from '@coral-xyz/anchor';
58
58
  import { PythConfiguration, SwitchboardConfiguration } from './idl_codegen_kamino_vault/types';
59
59
  import * as fs from 'fs';
60
- import { MarketWithAddress } from './utils/managerTypes';
60
+ import { MarketWithAddress } from './utils';
61
61
  import {
62
62
  ManagementFeeBps,
63
63
  PendingVaultAdmin,
64
64
  PerformanceFeeBps,
65
65
  } from './idl_codegen_kamino_vault/types/VaultConfigField';
66
- import { getAccountOwner } from './utils/rpc';
66
+ import { getAccountOwner } from './utils';
67
67
  import { getAssociatedTokenAddressSync } from '@solana/spl-token';
68
68
 
69
69
  dotenv.config({
@@ -157,12 +157,12 @@ async function main() {
157
157
 
158
158
  console.log('reserve: ', reserve.publicKey);
159
159
 
160
- const _createReserveSig = await processTxn(env.client, env.payer, txnIxs[0], mode, 2500, [reserve]);
160
+ await processTxn(env.client, env.payer, txnIxs[0], mode, 2500, [reserve]);
161
161
 
162
162
  const [lut, createLutIxs] = await createUpdateReserveConfigLutIxs(env, marketAddress, reserve.publicKey);
163
163
  await processTxn(env.client, env.payer, createLutIxs, mode, 2500, []);
164
164
 
165
- const _updateSig = await processTxn(env.client, env.payer, txnIxs[1], mode, 2500, [], 400_000, 1000, [lut]);
165
+ await processTxn(env.client, env.payer, txnIxs[1], mode, 2500, [], 400_000, 1000, [lut]);
166
166
 
167
167
  mode === 'execute' &&
168
168
  console.log(
@@ -224,7 +224,7 @@ async function main() {
224
224
  updateEntireConfig
225
225
  );
226
226
 
227
- const _updateReserveSig = await processTxn(env.client, env.payer, ixs, mode, 2500, [], 400_000);
227
+ await processTxn(env.client, env.payer, ixs, mode, 2500, [], 400_000);
228
228
 
229
229
  mode === 'execute' && console.log('Reserve Updated with config -> ', JSON.parse(JSON.stringify(reserveConfig)));
230
230
  });
@@ -296,7 +296,7 @@ async function main() {
296
296
 
297
297
  const { vault: vaultKp, initVaultIxs: instructions } = await kaminoManager.createVaultIxs(kaminoVaultConfig);
298
298
 
299
- const _createVaultSig = await processTxn(
299
+ await processTxn(
300
300
  env.client,
301
301
  env.payer,
302
302
  [...instructions.createAtaIfNeededIxs, ...instructions.initVaultIxs, instructions.createLUTIx],
@@ -305,7 +305,7 @@ async function main() {
305
305
  [vaultKp]
306
306
  );
307
307
  await sleep(2000);
308
- const _populateLUTSig = await processTxn(
308
+ await processTxn(
309
309
  env.client,
310
310
  env.payer,
311
311
  [...instructions.populateLUTIxs, ...instructions.cleanupIxs],
@@ -314,14 +314,7 @@ async function main() {
314
314
  []
315
315
  );
316
316
 
317
- const _setSharesMetadataSig = await processTxn(
318
- env.client,
319
- env.payer,
320
- [instructions.initSharesMetadataIx],
321
- mode,
322
- 2500,
323
- []
324
- );
317
+ await processTxn(env.client, env.payer, [instructions.initSharesMetadataIx], mode, 2500, []);
325
318
  mode === 'execute' && console.log('Vault created:', vaultKp.publicKey.toBase58());
326
319
  });
327
320
 
@@ -1173,19 +1166,33 @@ async function main() {
1173
1166
  }
1174
1167
  });
1175
1168
 
1176
- commands.command('get-oracle-mappings').action(async () => {
1177
- const env = initializeClient(false, false);
1178
- const kaminoManager = new KaminoManager(
1179
- env.connection,
1180
- DEFAULT_RECENT_SLOT_DURATION_MS,
1181
- env.kLendProgramId,
1182
- env.kVaultProgramId
1183
- );
1169
+ commands
1170
+ .command('get-oracle-mappings')
1171
+ .requiredOption('--lending-market <string>', 'Lending Market Address')
1172
+ .action(async ({ lendingMarket }) => {
1173
+ const env = initializeClient(false, false);
1174
+ const kaminoManager = new KaminoManager(
1175
+ env.connection,
1176
+ DEFAULT_RECENT_SLOT_DURATION_MS,
1177
+ env.kLendProgramId,
1178
+ env.kVaultProgramId
1179
+ );
1180
+ const market = await KaminoMarket.load(
1181
+ env.connection,
1182
+ new PublicKey(lendingMarket),
1183
+ DEFAULT_RECENT_SLOT_DURATION_MS,
1184
+ env.kLendProgramId
1185
+ );
1186
+ if (!market) {
1187
+ throw Error(`Lending market ${lendingMarket} not found`);
1188
+ }
1184
1189
 
1185
- console.log('Getting oracle mappings');
1186
- const oracleConfigs = await kaminoManager.getScopeOracleConfigs();
1187
- console.log('oracleConfigs', JSON.parse(JSON.stringify(oracleConfigs)));
1188
- });
1190
+ console.log('Getting oracle mappings');
1191
+ const oracleConfigs = await kaminoManager.getScopeOracleConfigs(market);
1192
+ for (const [oraclePrices, configs] of oracleConfigs.entries()) {
1193
+ console.log(`OraclePrices pubkey: ${oraclePrices.toString()}`, 'Configs:', JSON.parse(JSON.stringify(configs)));
1194
+ }
1195
+ });
1189
1196
 
1190
1197
  commands.command('get-all-vaults').action(async () => {
1191
1198
  const env = initializeClient(false, false);
@@ -1370,7 +1377,7 @@ async function main() {
1370
1377
  // executing 6 ixs in a txn to make sure they fit
1371
1378
  for (let ixnIndex = 0; ixnIndex < ixs.length; ixnIndex += 6) {
1372
1379
  const ixnToExecute = ixs.slice(ixnIndex, ixnIndex + 6);
1373
- const _updateLendingMarketSig = await processTxn(env.client, env.payer, ixnToExecute, mode, 2500, [], 400_000);
1380
+ await processTxn(env.client, env.payer, ixnToExecute, mode, 2500, [], 400_000);
1374
1381
  }
1375
1382
 
1376
1383
  mode === 'execute' &&
@@ -1410,7 +1417,7 @@ async function main() {
1410
1417
 
1411
1418
  const ix = kaminoManager.updateLendingMarketOwnerIxs(marketWithAddress);
1412
1419
 
1413
- const _updateLendingMarketSig = await processTxn(env.client, env.payer, [ix], mode, 2500, [], 400_000);
1420
+ await processTxn(env.client, env.payer, [ix], mode, 2500, [], 400_000);
1414
1421
 
1415
1422
  mode === 'execute' &&
1416
1423
  console.log(
@@ -1465,7 +1472,7 @@ async function main() {
1465
1472
 
1466
1473
  const ixs = kaminoManager.updateLendingMarketIxs(marketWithAddress, newLendingMarket);
1467
1474
 
1468
- const _updateLendingMarketSig = await processTxn(env.client, env.payer, ixs, mode, 2500, [], 400_000);
1475
+ await processTxn(env.client, env.payer, ixs, mode, 2500, [], 400_000);
1469
1476
 
1470
1477
  mode === 'execute' &&
1471
1478
  console.log(
@@ -1520,7 +1527,7 @@ async function main() {
1520
1527
 
1521
1528
  const ixs = await kaminoManager.updateReserveIxs(marketWithAddress, reserveAddress, newReserveConfig);
1522
1529
 
1523
- const _updateLendingMarketSig = await processTxn(env.client, env.payer, ixs, mode, 2500, [], 400_000);
1530
+ await processTxn(env.client, env.payer, ixs, mode, 2500, [], 400_000);
1524
1531
 
1525
1532
  mode === 'execute' &&
1526
1533
  console.log(
@@ -1811,9 +1818,7 @@ function parseBorrowRateCurve(reserveConfigFromFile: any): BorrowRateCurve {
1811
1818
 
1812
1819
  curvePoints.forEach((curvePoint, index) => (finalCurvePoints[index] = curvePoint));
1813
1820
 
1814
- const borrowRateCurve = new BorrowRateCurve({ points: finalCurvePoints });
1815
-
1816
- return borrowRateCurve;
1821
+ return new BorrowRateCurve({ points: finalCurvePoints });
1817
1822
  }
1818
1823
 
1819
1824
  function parseReserveBorrowLimitAgainstCollInEmode(reserveConfigFromFile: any): BN[] {