@kamino-finance/klend-sdk 7.3.10-beta.0 → 7.3.10-beta.1

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 (131) hide show
  1. package/dist/classes/action.d.ts +21 -91
  2. package/dist/classes/action.d.ts.map +1 -1
  3. package/dist/classes/action.js +152 -139
  4. package/dist/classes/action.js.map +1 -1
  5. package/dist/classes/actionTypes.d.ts +310 -0
  6. package/dist/classes/actionTypes.d.ts.map +1 -0
  7. package/dist/classes/actionTypes.js +3 -0
  8. package/dist/classes/actionTypes.js.map +1 -0
  9. package/dist/classes/configItems.d.ts +1 -6
  10. package/dist/classes/configItems.d.ts.map +1 -1
  11. package/dist/classes/configItems.js +1 -93
  12. package/dist/classes/configItems.js.map +1 -1
  13. package/dist/classes/farm_utils.d.ts +1 -1
  14. package/dist/classes/farm_utils.d.ts.map +1 -1
  15. package/dist/classes/farm_utils.js +3 -1
  16. package/dist/classes/farm_utils.js.map +1 -1
  17. package/dist/classes/market.d.ts +15 -10
  18. package/dist/classes/market.d.ts.map +1 -1
  19. package/dist/classes/market.js +49 -26
  20. package/dist/classes/market.js.map +1 -1
  21. package/dist/classes/obligation.d.ts +9 -9
  22. package/dist/classes/obligation.d.ts.map +1 -1
  23. package/dist/classes/obligation.js +48 -50
  24. package/dist/classes/obligation.js.map +1 -1
  25. package/dist/classes/obligationOrder.d.ts.map +1 -1
  26. package/dist/classes/obligationOrder.js +6 -3
  27. package/dist/classes/obligationOrder.js.map +1 -1
  28. package/dist/classes/reserve.d.ts +7 -3
  29. package/dist/classes/reserve.d.ts.map +1 -1
  30. package/dist/classes/reserve.js +31 -43
  31. package/dist/classes/reserve.js.map +1 -1
  32. package/dist/classes/shared.d.ts +3 -2
  33. package/dist/classes/shared.d.ts.map +1 -1
  34. package/dist/classes/vault.d.ts +28 -1
  35. package/dist/classes/vault.d.ts.map +1 -1
  36. package/dist/classes/vault.js +103 -6
  37. package/dist/classes/vault.js.map +1 -1
  38. package/dist/classes/vault_types.d.ts +2 -1
  39. package/dist/classes/vault_types.d.ts.map +1 -1
  40. package/dist/client/commands/borrow.d.ts +1 -1
  41. package/dist/client/commands/borrow.d.ts.map +1 -1
  42. package/dist/client/commands/borrow.js +11 -2
  43. package/dist/client/commands/borrow.js.map +1 -1
  44. package/dist/client/commands/deposit.d.ts +1 -1
  45. package/dist/client/commands/deposit.d.ts.map +1 -1
  46. package/dist/client/commands/deposit.js +11 -2
  47. package/dist/client/commands/deposit.js.map +1 -1
  48. package/dist/client/commands/printReserve.d.ts +1 -1
  49. package/dist/client/commands/printReserve.d.ts.map +1 -1
  50. package/dist/client/commands/printReserve.js +2 -4
  51. package/dist/client/commands/printReserve.js.map +1 -1
  52. package/dist/client/commands/repay.d.ts +1 -1
  53. package/dist/client/commands/repay.d.ts.map +1 -1
  54. package/dist/client/commands/repay.js +12 -2
  55. package/dist/client/commands/repay.js.map +1 -1
  56. package/dist/client/commands/withdraw.d.ts +1 -1
  57. package/dist/client/commands/withdraw.d.ts.map +1 -1
  58. package/dist/client/commands/withdraw.js +11 -2
  59. package/dist/client/commands/withdraw.js.map +1 -1
  60. package/dist/lending_operations/repay_with_collateral_calcs.d.ts +1 -1
  61. package/dist/lending_operations/repay_with_collateral_calcs.d.ts.map +1 -1
  62. package/dist/lending_operations/repay_with_collateral_calcs.js +2 -2
  63. package/dist/lending_operations/repay_with_collateral_calcs.js.map +1 -1
  64. package/dist/lending_operations/repay_with_collateral_operations.d.ts +4 -4
  65. package/dist/lending_operations/repay_with_collateral_operations.d.ts.map +1 -1
  66. package/dist/lending_operations/repay_with_collateral_operations.js +43 -10
  67. package/dist/lending_operations/repay_with_collateral_operations.js.map +1 -1
  68. package/dist/lending_operations/swap_collateral_operations.d.ts +4 -4
  69. package/dist/lending_operations/swap_collateral_operations.d.ts.map +1 -1
  70. package/dist/lending_operations/swap_collateral_operations.js +40 -21
  71. package/dist/lending_operations/swap_collateral_operations.js.map +1 -1
  72. package/dist/leverage/operations.d.ts +6 -6
  73. package/dist/leverage/operations.d.ts.map +1 -1
  74. package/dist/leverage/operations.js +167 -52
  75. package/dist/leverage/operations.js.map +1 -1
  76. package/dist/leverage/types.d.ts +2 -2
  77. package/dist/leverage/types.d.ts.map +1 -1
  78. package/dist/manager/client_kamino_manager.js +0 -2
  79. package/dist/manager/client_kamino_manager.js.map +1 -1
  80. package/dist/obligation_orders/price_based.js +5 -3
  81. package/dist/obligation_orders/price_based.js.map +1 -1
  82. package/dist/utils/Logger.d.ts +14 -0
  83. package/dist/utils/Logger.d.ts.map +1 -0
  84. package/dist/utils/Logger.js +12 -0
  85. package/dist/utils/Logger.js.map +1 -0
  86. package/dist/utils/ObligationType.d.ts +33 -1
  87. package/dist/utils/ObligationType.d.ts.map +1 -1
  88. package/dist/utils/ObligationType.js +81 -2
  89. package/dist/utils/ObligationType.js.map +1 -1
  90. package/dist/utils/api.d.ts +13 -4
  91. package/dist/utils/api.d.ts.map +1 -1
  92. package/dist/utils/api.js +33 -31
  93. package/dist/utils/api.js.map +1 -1
  94. package/dist/utils/userMetadata.d.ts +2 -2
  95. package/dist/utils/userMetadata.d.ts.map +1 -1
  96. package/dist/utils/userMetadata.js +49 -25
  97. package/dist/utils/userMetadata.js.map +1 -1
  98. package/dist/utils/validations.d.ts +1 -0
  99. package/dist/utils/validations.d.ts.map +1 -1
  100. package/dist/utils/validations.js +5 -0
  101. package/dist/utils/validations.js.map +1 -1
  102. package/package.json +1 -1
  103. package/src/classes/action.ts +346 -372
  104. package/src/classes/actionTypes.ts +295 -0
  105. package/src/classes/configItems.ts +1 -99
  106. package/src/classes/farm_utils.ts +5 -1
  107. package/src/classes/market.ts +74 -31
  108. package/src/classes/obligation.ts +54 -53
  109. package/src/classes/obligationOrder.ts +6 -3
  110. package/src/classes/reserve.ts +118 -122
  111. package/src/classes/shared.ts +4 -2
  112. package/src/classes/vault.ts +160 -7
  113. package/src/classes/vault_types.ts +2 -1
  114. package/src/client/client.ts +17 -18
  115. package/src/client/commands/borrow.ts +10 -9
  116. package/src/client/commands/deposit.ts +10 -9
  117. package/src/client/commands/printReserve.ts +2 -4
  118. package/src/client/commands/repay.ts +11 -10
  119. package/src/client/commands/withdraw.ts +15 -9
  120. package/src/lending_operations/repay_with_collateral_calcs.ts +3 -4
  121. package/src/lending_operations/repay_with_collateral_operations.ts +40 -38
  122. package/src/lending_operations/swap_collateral_operations.ts +47 -41
  123. package/src/leverage/operations.ts +168 -129
  124. package/src/leverage/types.ts +2 -2
  125. package/src/manager/client_kamino_manager.ts +0 -2
  126. package/src/obligation_orders/price_based.ts +7 -5
  127. package/src/utils/Logger.ts +14 -0
  128. package/src/utils/ObligationType.ts +92 -1
  129. package/src/utils/api.ts +56 -33
  130. package/src/utils/userMetadata.ts +64 -30
  131. package/src/utils/validations.ts +5 -0
@@ -0,0 +1,295 @@
1
+ import { Address, Option, Slot, TransactionSigner } from '@solana/kit';
2
+ import BN from 'bn.js';
3
+ import { ObligationType, ScopePriceRefreshConfig } from '../utils';
4
+ import { KaminoObligation } from './obligation';
5
+ import { KaminoMarket } from './market';
6
+ import { ActionType } from './action';
7
+
8
+ /**
9
+ * Props for KaminoAction.initialize
10
+ */
11
+ export interface InitializeActionProps {
12
+ kaminoMarket: KaminoMarket;
13
+ action: ActionType;
14
+ amount: string | BN;
15
+ reserveAddress: Address;
16
+ owner: TransactionSigner;
17
+ obligation: KaminoObligation | ObligationType;
18
+ referrer?: Option<Address>;
19
+ currentSlot?: Slot;
20
+ payer?: TransactionSigner;
21
+ }
22
+
23
+ /**
24
+ * Props for KaminoAction.buildDepositTxns
25
+ */
26
+ export interface BuildDepositTxnsProps {
27
+ kaminoMarket: KaminoMarket;
28
+ amount: string | BN;
29
+ reserveAddress: Address;
30
+ owner: TransactionSigner;
31
+ obligation: KaminoObligation | ObligationType;
32
+ useV2Ixs: boolean;
33
+ scopeRefreshConfig: ScopePriceRefreshConfig | undefined;
34
+ extraComputeBudget?: number;
35
+ includeAtaIxs?: boolean;
36
+ requestElevationGroup?: boolean;
37
+ initUserMetadata?: { skipInitialization: boolean; skipLutCreation: boolean };
38
+ referrer?: Option<Address>;
39
+ currentSlot?: Slot;
40
+ overrideElevationGroupRequest?: number;
41
+ }
42
+
43
+ /**
44
+ * Props for KaminoAction.buildBorrowTxns
45
+ */
46
+ export interface BuildBorrowTxnsProps {
47
+ kaminoMarket: KaminoMarket;
48
+ amount: string | BN;
49
+ reserveAddress: Address;
50
+ owner: TransactionSigner;
51
+ obligation: KaminoObligation | ObligationType;
52
+ useV2Ixs: boolean;
53
+ scopeRefreshConfig: ScopePriceRefreshConfig | undefined;
54
+ extraComputeBudget?: number;
55
+ includeAtaIxs?: boolean;
56
+ requestElevationGroup?: boolean;
57
+ initUserMetadata?: { skipInitialization: boolean; skipLutCreation: boolean };
58
+ referrer?: Option<Address>;
59
+ currentSlot?: Slot;
60
+ overrideElevationGroupRequest?: number;
61
+ }
62
+
63
+ /**
64
+ * Props for KaminoAction.buildDepositReserveLiquidityTxns
65
+ */
66
+ export interface BuildDepositReserveLiquidityTxnsProps {
67
+ kaminoMarket: KaminoMarket;
68
+ amount: string | BN;
69
+ reserveAddress: Address;
70
+ owner: TransactionSigner;
71
+ obligation: KaminoObligation | ObligationType;
72
+ scopeRefreshConfig: ScopePriceRefreshConfig | undefined;
73
+ extraComputeBudget?: number;
74
+ includeAtaIxs?: boolean;
75
+ requestElevationGroup?: boolean;
76
+ referrer?: Option<Address>;
77
+ currentSlot?: Slot;
78
+ }
79
+
80
+ /**
81
+ * Props for KaminoAction.buildRedeemReserveCollateralTxns
82
+ */
83
+ export interface BuildRedeemReserveCollateralTxnsProps {
84
+ kaminoMarket: KaminoMarket;
85
+ amount: string | BN;
86
+ reserveAddress: Address;
87
+ owner: TransactionSigner;
88
+ obligation: KaminoObligation | ObligationType;
89
+ scopeRefreshConfig: ScopePriceRefreshConfig | undefined;
90
+ extraComputeBudget?: number;
91
+ includeAtaIxs?: boolean;
92
+ requestElevationGroup?: boolean;
93
+ referrer?: Option<Address>;
94
+ currentSlot?: Slot;
95
+ }
96
+
97
+ /**
98
+ * Props for KaminoAction.buildWithdrawTxns
99
+ */
100
+ export interface BuildWithdrawTxnsProps {
101
+ kaminoMarket: KaminoMarket;
102
+ amount: string | BN;
103
+ reserveAddress: Address;
104
+ owner: TransactionSigner;
105
+ obligation: KaminoObligation | ObligationType;
106
+ useV2Ixs: boolean;
107
+ scopeRefreshConfig: ScopePriceRefreshConfig | undefined;
108
+ extraComputeBudget?: number;
109
+ includeAtaIxs?: boolean;
110
+ requestElevationGroup?: boolean;
111
+ initUserMetadata?: { skipInitialization: boolean; skipLutCreation: boolean };
112
+ referrer?: Option<Address>;
113
+ currentSlot?: Slot;
114
+ overrideElevationGroupRequest?: number;
115
+ obligationCustomizations?: {
116
+ addedDepositReserves?: Address[];
117
+ };
118
+ }
119
+
120
+ /**
121
+ * Props for KaminoAction.buildRepayTxns
122
+ */
123
+ export interface BuildRepayTxnsProps {
124
+ kaminoMarket: KaminoMarket;
125
+ amount: string | BN;
126
+ reserveAddress: Address;
127
+ owner: TransactionSigner;
128
+ obligation: KaminoObligation | ObligationType;
129
+ useV2Ixs: boolean;
130
+ scopeRefreshConfig: ScopePriceRefreshConfig | undefined;
131
+ currentSlot: Slot;
132
+ extraComputeBudget?: number;
133
+ includeAtaIxs?: boolean;
134
+ requestElevationGroup?: boolean;
135
+ payer?: TransactionSigner;
136
+ initUserMetadata?: { skipInitialization: boolean; skipLutCreation: boolean };
137
+ referrer?: Option<Address>;
138
+ }
139
+
140
+ /**
141
+ * Props for KaminoAction.buildDepositAndBorrowTxns
142
+ */
143
+ export interface BuildDepositAndBorrowTxnsProps {
144
+ kaminoMarket: KaminoMarket;
145
+ depositAmount: string | BN;
146
+ depositReserveAddress: Address;
147
+ borrowAmount: string | BN;
148
+ borrowReserveAddress: Address;
149
+ owner: TransactionSigner;
150
+ obligation: KaminoObligation | ObligationType;
151
+ useV2Ixs: boolean;
152
+ scopeRefreshConfig: ScopePriceRefreshConfig | undefined;
153
+ extraComputeBudget?: number;
154
+ includeAtaIxs?: boolean;
155
+ requestElevationGroup?: boolean;
156
+ initUserMetadata?: { skipInitialization: boolean; skipLutCreation: boolean };
157
+ referrer?: Option<Address>;
158
+ currentSlot?: Slot;
159
+ }
160
+
161
+ /**
162
+ * Props for KaminoAction.buildRefreshObligationTxns
163
+ */
164
+ export interface BuildRefreshObligationTxnsProps {
165
+ kaminoMarket: KaminoMarket;
166
+ payer: TransactionSigner;
167
+ obligation: KaminoObligation;
168
+ extraComputeBudget?: number;
169
+ currentSlot?: Slot;
170
+ }
171
+
172
+ /**
173
+ * Props for KaminoAction.buildRequestElevationGroupTxns
174
+ */
175
+ export interface BuildRequestElevationGroupTxnsProps {
176
+ kaminoMarket: KaminoMarket;
177
+ owner: TransactionSigner;
178
+ obligation: KaminoObligation;
179
+ elevationGroup: number;
180
+ extraComputeBudget?: number;
181
+ currentSlot?: Slot;
182
+ }
183
+
184
+ /**
185
+ * Props for KaminoAction.buildDepositAndWithdrawV2Txns
186
+ */
187
+ export interface BuildDepositAndWithdrawV2TxnsProps {
188
+ kaminoMarket: KaminoMarket;
189
+ depositAmount: string | BN;
190
+ depositReserveAddress: Address;
191
+ withdrawAmount: string | BN;
192
+ withdrawReserveAddress: Address;
193
+ owner: TransactionSigner;
194
+ currentSlot: Slot;
195
+ obligation: KaminoObligation | ObligationType;
196
+ scopeRefreshConfig: ScopePriceRefreshConfig | undefined;
197
+ extraComputeBudget?: number;
198
+ includeAtaIxs?: boolean;
199
+ requestElevationGroup?: boolean;
200
+ initUserMetadata?: { skipInitialization: boolean; skipLutCreation: boolean };
201
+ referrer?: Option<Address>;
202
+ }
203
+
204
+ /**
205
+ * Props for KaminoAction.buildRepayAndWithdrawTxns
206
+ */
207
+ export interface BuildRepayAndWithdrawTxnsProps {
208
+ kaminoMarket: KaminoMarket;
209
+ repayAmount: string | BN;
210
+ repayReserveAddress: Address;
211
+ withdrawAmount: string | BN;
212
+ withdrawReserveAddress: Address;
213
+ payer: TransactionSigner;
214
+ currentSlot: Slot;
215
+ obligation: KaminoObligation | ObligationType;
216
+ useV2Ixs: boolean;
217
+ scopeRefreshConfig: ScopePriceRefreshConfig | undefined;
218
+ extraComputeBudget?: number;
219
+ includeAtaIxs?: boolean;
220
+ requestElevationGroup?: boolean;
221
+ initUserMetadata?: { skipInitialization: boolean; skipLutCreation: boolean };
222
+ referrer?: Option<Address>;
223
+ }
224
+
225
+ /**
226
+ * Props for KaminoAction.buildRepayAndWithdrawV2Txns
227
+ */
228
+ export interface BuildRepayAndWithdrawV2TxnsProps {
229
+ kaminoMarket: KaminoMarket;
230
+ repayAmount: string | BN;
231
+ repayReserveAddress: Address;
232
+ withdrawAmount: string | BN;
233
+ withdrawReserveAddress: Address;
234
+ payer: TransactionSigner;
235
+ currentSlot: Slot;
236
+ obligation: KaminoObligation | ObligationType;
237
+ scopeRefreshConfig: ScopePriceRefreshConfig | undefined;
238
+ extraComputeBudget?: number;
239
+ includeAtaIxs?: boolean;
240
+ requestElevationGroup?: boolean;
241
+ initUserMetadata?: { skipInitialization: boolean; skipLutCreation: boolean };
242
+ referrer?: Option<Address>;
243
+ }
244
+
245
+ /**
246
+ * Props for KaminoAction.buildLiquidateTxns
247
+ */
248
+ export interface BuildLiquidateTxnsProps {
249
+ kaminoMarket: KaminoMarket;
250
+ amount: string | BN;
251
+ minCollateralReceiveAmount: string | BN;
252
+ repayReserveAddress: Address;
253
+ withdrawReserveAddress: Address;
254
+ liquidator: TransactionSigner;
255
+ obligationOwner: Address;
256
+ obligation: KaminoObligation | ObligationType;
257
+ useV2Ixs: boolean;
258
+ scopeRefreshConfig?: ScopePriceRefreshConfig;
259
+ extraComputeBudget?: number;
260
+ includeAtaIxs?: boolean;
261
+ requestElevationGroup?: boolean;
262
+ initUserMetadata?: { skipInitialization: boolean; skipLutCreation: boolean };
263
+ referrer?: Option<Address>;
264
+ maxAllowedLtvOverridePercent?: number;
265
+ currentSlot?: Slot;
266
+ }
267
+
268
+ /**
269
+ * Props for KaminoAction.buildWithdrawReferrerFeeTxns
270
+ */
271
+ export interface BuildWithdrawReferrerFeeTxnsProps {
272
+ owner: TransactionSigner;
273
+ reserveAddress: Address;
274
+ kaminoMarket: KaminoMarket;
275
+ currentSlot?: Slot;
276
+ }
277
+
278
+ /**
279
+ * Props for KaminoAction.buildDepositObligationCollateralTxns
280
+ */
281
+ export interface BuildDepositObligationCollateralTxnsProps {
282
+ kaminoMarket: KaminoMarket;
283
+ amount: string | BN;
284
+ reserveAddress: Address;
285
+ owner: TransactionSigner;
286
+ obligation: KaminoObligation | ObligationType;
287
+ useV2Ixs: boolean;
288
+ scopeRefreshConfig: ScopePriceRefreshConfig | undefined;
289
+ extraComputeBudget?: number;
290
+ includeAtaIxs?: boolean;
291
+ requestElevationGroup?: boolean;
292
+ initUserMetadata?: { skipInitialization: boolean; skipLutCreation: boolean };
293
+ referrer?: Option<Address>;
294
+ currentSlot?: Slot;
295
+ }
@@ -1,8 +1,6 @@
1
1
  import { struct, Layout } from '@coral-xyz/borsh';
2
2
  import { blobEquals, orThrow, toJson } from './utils';
3
3
  import { Buffer } from 'buffer';
4
- import { ReserveConfig } from '../lib';
5
- import { UpdateConfigModeKind, UpdateConfigMode } from '../@codegen/klend/types';
6
4
 
7
5
  /**
8
6
  * An object literal specifying *all* "update mode" enum values (of type {@code M}) and their corresponding config items
@@ -153,7 +151,7 @@ export class ConfigItemUpdater<C, A> {
153
151
  * A resolver of config item changes.
154
152
  */
155
153
  export class ConfigUpdater<M extends BorshEnum, C> {
156
- protected readonly itemUpdaters: Map<M['kind'], [M, ConfigItemUpdater<C, any>[]]>;
154
+ private readonly itemUpdaters: Map<M['kind'], [M, ConfigItemUpdater<C, any>[]]>;
157
155
 
158
156
  /**
159
157
  * A resolving constructor.
@@ -237,61 +235,6 @@ export class ConfigUpdater<M extends BorshEnum, C> {
237
235
  }
238
236
  }
239
237
 
240
- export class EntireReserveConfigUpdater extends ConfigUpdater<UpdateConfigModeKind, ReserveConfig> {
241
- encodeAllUpdates(
242
- currentConfig: ReserveConfig | undefined,
243
- newConfig: ReserveConfig
244
- ): EncodedConfigUpdate<UpdateConfigModeKind>[] {
245
- const updates: EncodedConfigUpdate<UpdateConfigModeKind>[] = [];
246
- let ltvUpdate: EncodedConfigUpdate<UpdateConfigModeKind> | undefined;
247
- let liquidationThresholdUpdate: EncodedConfigUpdate<UpdateConfigModeKind> | undefined;
248
-
249
- for (const [mode, itemUpdaters] of this.itemUpdaters.values()) {
250
- for (const itemUpdater of itemUpdaters) {
251
- const value = itemUpdater.encodeUpdatedItemFrom(currentConfig, newConfig);
252
- if (value === undefined) {
253
- continue;
254
- }
255
-
256
- const update = { mode, value };
257
-
258
- if (mode.discriminator === UpdateConfigMode.UpdateLoanToValuePct.discriminator) {
259
- ltvUpdate = update;
260
- } else if (mode.discriminator === UpdateConfigMode.UpdateLiquidationThresholdPct.discriminator) {
261
- liquidationThresholdUpdate = update;
262
- // If reserve is already initialized, skip fields that require global admin signature on update
263
- } else {
264
- updates.push(update);
265
- }
266
- }
267
- }
268
-
269
- // Handle ordering of LTV and LiquidationThreshold updates
270
- // ensure LiquidationThreshold >= LTV at all times
271
- if (ltvUpdate && liquidationThresholdUpdate) {
272
- const currentLiquidationThreshold = currentConfig ? currentConfig.liquidationThresholdPct : 0;
273
- const newLiquidationThreshold = newConfig.liquidationThresholdPct;
274
-
275
- if (newLiquidationThreshold > currentLiquidationThreshold) {
276
- // Liquidation threshold is increasing, so it must be updated first
277
- updates.push(liquidationThresholdUpdate);
278
- updates.push(ltvUpdate);
279
- } else {
280
- // All other cases, it's safer to update the LTV first
281
- updates.push(ltvUpdate);
282
- updates.push(liquidationThresholdUpdate);
283
- }
284
- } else if (ltvUpdate) {
285
- updates.push(ltvUpdate);
286
- } else if (liquidationThresholdUpdate) {
287
- updates.push(liquidationThresholdUpdate);
288
- }
289
-
290
- updates.sort((left, right) => priorityOf(left.mode) - priorityOf(right.mode));
291
- return updates;
292
- }
293
- }
294
-
295
238
  /**
296
239
  * The update mode discriminator and the serialized value needed to construct an update ix.
297
240
  */
@@ -350,44 +293,3 @@ type Getter<C, A> = (config: C) => A;
350
293
  function toArray<T>(singleOrArray: SingleOrArray<T>): T[] {
351
294
  return Array.isArray(singleOrArray) ? singleOrArray : [singleOrArray];
352
295
  }
353
-
354
- // Lowest priority gets updated first
355
- function priorityOf(mode: UpdateConfigModeKind): number {
356
- switch (mode.discriminator) {
357
- case UpdateConfigMode.UpdateScopePriceFeed.discriminator:
358
- return 0;
359
- case UpdateConfigMode.UpdateTokenInfoScopeTwap.discriminator:
360
- return 0;
361
- case UpdateConfigMode.UpdateTokenInfoScopeChain.discriminator:
362
- return 0;
363
- case UpdateConfigMode.UpdateTokenInfoLowerHeuristic.discriminator:
364
- return 0;
365
- case UpdateConfigMode.UpdateTokenInfoUpperHeuristic.discriminator:
366
- return 0;
367
- case UpdateConfigMode.UpdateTokenInfoExpHeuristic.discriminator:
368
- return 0;
369
- case UpdateConfigMode.UpdateTokenInfoTwapDivergence.discriminator:
370
- return 0;
371
- case UpdateConfigMode.UpdateTokenInfoName.discriminator:
372
- return 0;
373
- case UpdateConfigMode.UpdateTokenInfoPriceMaxAge.discriminator:
374
- return 0;
375
- case UpdateConfigMode.UpdateTokenInfoTwapMaxAge.discriminator:
376
- return 0;
377
- case UpdateConfigMode.UpdateDeleveragingBonusIncreaseBpsPerDay.discriminator:
378
- return priorityOf(new UpdateConfigMode.UpdateAutodeleverageEnabled()) - 1;
379
- case UpdateConfigMode.UpdateDeleveragingMarginCallPeriod.discriminator:
380
- return priorityOf(new UpdateConfigMode.UpdateAutodeleverageEnabled()) - 1;
381
- case UpdateConfigMode.UpdateDeleveragingThresholdDecreaseBpsPerDay.discriminator:
382
- return priorityOf(new UpdateConfigMode.UpdateAutodeleverageEnabled()) - 1;
383
- case UpdateConfigMode.UpdateAutodeleverageEnabled.discriminator:
384
- return 4;
385
- // Always update last bc we cannot skip validation
386
- case UpdateConfigMode.UpdateDepositLimit.discriminator:
387
- return 63;
388
- case UpdateConfigMode.UpdateBorrowLimit.discriminator:
389
- return 63;
390
- default:
391
- return 10;
392
- }
393
- }
@@ -8,6 +8,7 @@ import {
8
8
  scaleDownWads,
9
9
  WAD,
10
10
  RewardInfo,
11
+ RewardType,
11
12
  } from '@kamino-finance/farms-sdk';
12
13
  import {
13
14
  address,
@@ -174,7 +175,7 @@ export type UnstakeAndWithdrawFromFarmIxs = {
174
175
  withdrawIx: Instruction;
175
176
  };
176
177
 
177
- export function getRewardPerTimeUnitSecond(reward: RewardInfo) {
178
+ export function getRewardPerTimeUnitSecond(reward: RewardInfo, farmTotalStakeLamports: Decimal) {
178
179
  const now = new Decimal(new Date().getTime()).div(1000);
179
180
  let rewardPerTimeUnitSecond = new Decimal(0);
180
181
  for (let i = 0; i < reward.rewardScheduleCurve.points.length - 1; i++) {
@@ -196,8 +197,11 @@ export function getRewardPerTimeUnitSecond(reward: RewardInfo) {
196
197
  const rewardTokenDecimals = reward.token.decimals.toNumber();
197
198
  const rewardAmountPerUnitDecimals = new Decimal(10).pow(reward.rewardsPerSecondDecimals.toString());
198
199
  const rewardAmountPerUnitLamports = new Decimal(10).pow(rewardTokenDecimals.toString());
200
+ const constantRewardStakeAdjustment =
201
+ reward.rewardType === RewardType.Constant.discriminator ? farmTotalStakeLamports : new Decimal(1);
199
202
 
200
203
  const rpsAdjusted = new Decimal(rewardPerTimeUnitSecond.toString())
204
+ .mul(constantRewardStakeAdjustment)
201
205
  .div(rewardAmountPerUnitDecimals)
202
206
  .div(rewardAmountPerUnitLamports);
203
207
 
@@ -34,8 +34,11 @@ import {
34
34
  isNotNullPubkey,
35
35
  lendingMarketAuthPda,
36
36
  LendingObligation,
37
+ LendingObligationFixedRate,
37
38
  LeverageObligation,
39
+ LeverageObligationFixedRate,
38
40
  MultiplyObligation,
41
+ MultiplyObligationFixedRate,
39
42
  ObligationType,
40
43
  PythPrices,
41
44
  referrerTokenStatePda,
@@ -53,7 +56,7 @@ import { Fraction } from './fraction';
53
56
  import { batchFetch, chunks, KaminoPrices, MintToPriceMap } from '@kamino-finance/kliquidity-sdk';
54
57
  import { parseTokenSymbol, parseZeroPaddedUtf8 } from './utils';
55
58
  import { ObligationZP } from '../@codegen/klend/zero_padding';
56
- import { checkDefined } from '../utils/validations';
59
+ import { checkArrayNotEmpty, checkDefined } from '../utils/validations';
57
60
  import { Buffer } from 'buffer';
58
61
  import { ReserveStatus } from '../@codegen/klend/types';
59
62
  import { fetchKaminoCdnData } from '../utils/readCdnData';
@@ -121,6 +124,22 @@ export class KaminoMarket {
121
124
  );
122
125
  }
123
126
 
127
+ /**
128
+ * TESTING ONLY!
129
+ *
130
+ * Used to create mock markets for testing
131
+ */
132
+ static createMarket(
133
+ rpc: Rpc<KaminoMarketRpcApi>,
134
+ state: LendingMarket,
135
+ marketAddress: Address,
136
+ reserves: Map<Address, KaminoReserve>,
137
+ recentSlotDurationMs: number,
138
+ programId: Address = PROGRAM_ID
139
+ ) {
140
+ return new KaminoMarket(rpc, state, marketAddress, reserves, recentSlotDurationMs, programId);
141
+ }
142
+
124
143
  /**
125
144
  * Load a new market with all of its associated reserves
126
145
  * @param rpc
@@ -291,14 +310,22 @@ export class KaminoMarket {
291
310
  return parseZeroPaddedUtf8(this.state.name);
292
311
  }
293
312
 
294
- async getObligationDepositByWallet(owner: Address, mint: Address, obligationType: ObligationType): Promise<Decimal> {
313
+ async getObligationDepositByWallet(
314
+ owner: Address,
315
+ depositReserveAddress: Address,
316
+ obligationType: ObligationType
317
+ ): Promise<Decimal> {
295
318
  const obligation = await this.getObligationByWallet(owner, obligationType);
296
- return obligation?.getDepositByMint(mint)?.amount ?? new Decimal(0);
319
+ return obligation?.getDepositByReserve(depositReserveAddress)?.amount ?? new Decimal(0);
297
320
  }
298
321
 
299
- async getObligationBorrowByWallet(owner: Address, mint: Address, obligationType: ObligationType): Promise<Decimal> {
322
+ async getObligationBorrowByWallet(
323
+ owner: Address,
324
+ borrowReserveAddress: Address,
325
+ obligationType: ObligationType
326
+ ): Promise<Decimal> {
300
327
  const obligation = await this.getObligationByWallet(owner, obligationType);
301
- return obligation?.getBorrowByMint(mint)?.amount ?? new Decimal(0);
328
+ return obligation?.getBorrowByReserve(borrowReserveAddress)?.amount ?? new Decimal(0);
302
329
  }
303
330
 
304
331
  getTotalDepositTVL(): Decimal {
@@ -317,10 +344,10 @@ export class KaminoMarket {
317
344
  return tvl;
318
345
  }
319
346
 
320
- getMaxLeverageForPair(collTokenMint: Address, debtTokenMint: Address): number {
347
+ getMaxLeverageForPair(collReserveAddress: Address, debtReserveAddress: Address): number {
321
348
  const { maxLtv: maxCollateralLtv, borrowFactor } = this.getMaxAndLiquidationLtvAndBorrowFactorForPair(
322
- collTokenMint,
323
- debtTokenMint
349
+ collReserveAddress,
350
+ debtReserveAddress
324
351
  );
325
352
 
326
353
  const maxLeverage =
@@ -345,12 +372,11 @@ export class KaminoMarket {
345
372
  }
346
373
 
347
374
  getMaxAndLiquidationLtvAndBorrowFactorForPair(
348
- collTokenMint: Address,
349
- debtTokenMint: Address
375
+ collReserveAddress: Address,
376
+ debtReserveAddress: Address
350
377
  ): { maxLtv: number; liquidationLtv: number; borrowFactor: number } {
351
- const collReserve: KaminoReserve | undefined = this.getReserveByMint(collTokenMint);
352
- const debtReserve: KaminoReserve | undefined = this.getReserveByMint(debtTokenMint);
353
-
378
+ const collReserve: KaminoReserve | undefined = this.getReserveByAddress(collReserveAddress);
379
+ const debtReserve: KaminoReserve | undefined = this.getReserveByAddress(debtReserveAddress);
354
380
  if (!collReserve || !debtReserve) {
355
381
  throw Error('Could not find one of the reserves.');
356
382
  }
@@ -405,6 +431,22 @@ export class KaminoMarket {
405
431
  );
406
432
  break;
407
433
  }
434
+ case LendingObligationFixedRate.tag: {
435
+ const reserveAddress = productType.toArgs().seed1;
436
+ obligations = obligations.filter((obligation) => obligation.getDepositByReserve(reserveAddress) !== undefined);
437
+ break;
438
+ }
439
+ case LeverageObligationFixedRate.tag:
440
+ case MultiplyObligationFixedRate.tag: {
441
+ const collReserveAddress = productType.toArgs().seed1;
442
+ const debtReserveAddress = productType.toArgs().seed2;
443
+ obligations = obligations.filter((obligation) => {
444
+ const collDeposit = obligation.getDepositByReserve(collReserveAddress);
445
+ const debtBorrow = obligation.getBorrowByReserve(debtReserveAddress);
446
+ return collDeposit !== undefined && debtBorrow !== undefined;
447
+ });
448
+ break;
449
+ }
408
450
  default:
409
451
  throw new Error('Invalid obligation type');
410
452
  }
@@ -457,7 +499,7 @@ export class KaminoMarket {
457
499
  obligation?: KaminoObligation
458
500
  ): Decimal {
459
501
  return obligation
460
- ? obligation.getMaxBorrowAmount(this, debtReserve.getLiquidityMint(), slot, requestElevationGroup)
502
+ ? obligation.getMaxBorrowAmount(this, debtReserve.address, slot, requestElevationGroup)
461
503
  : debtReserve.getMaxBorrowAmountWithCollReserve(this, collReserve, slot);
462
504
  }
463
505
 
@@ -529,46 +571,47 @@ export class KaminoMarket {
529
571
  return checkDefined(this.getReserveByAddress(address), `${description} reserve ${address} not found`);
530
572
  }
531
573
 
532
- getReserveByMint(address: Address): KaminoReserve | undefined {
574
+ getReservesByMint(address: Address): KaminoReserve[] {
575
+ const reserves: KaminoReserve[] = [];
533
576
  for (const reserve of this.reserves.values()) {
534
577
  if (reserve.getLiquidityMint() === address) {
535
- return reserve;
578
+ reserves.push(reserve);
536
579
  }
537
580
  }
538
- return undefined;
581
+ return reserves;
539
582
  }
540
583
 
541
584
  /**
542
585
  * Returns this market's reserve of the given mint address, or throws an error (including the given description) if
543
586
  * such reserve does not exist.
544
587
  */
545
- getExistingReserveByMint(address: Address, description: string = 'Requested'): KaminoReserve {
546
- return checkDefined(this.getReserveByMint(address), `${description} reserve with mint ${address} not found`);
588
+ getExistingReservesByMint(address: Address, description: string = 'Requested'): KaminoReserve[] {
589
+ return checkArrayNotEmpty(this.getReservesByMint(address), `${description} reserve with mint ${address} not found`);
547
590
  }
548
591
 
549
- getReserveBySymbol(symbol: string) {
592
+ getReservesBySymbol(symbol: string): KaminoReserve[] {
593
+ const reserves: KaminoReserve[] = [];
550
594
  for (const reserve of this.reserves.values()) {
551
595
  if (reserve.symbol === symbol) {
552
- return reserve;
596
+ reserves.push(reserve);
553
597
  }
554
598
  }
555
- return undefined;
599
+ return reserves;
556
600
  }
557
601
 
558
602
  /**
559
603
  * Returns this market's reserve of the given symbol, or throws an error (including the given description) if
560
604
  * such reserve does not exist.
561
605
  */
562
- getExistingReserveBySymbol(symbol: string, description: string = 'Requested'): KaminoReserve {
563
- return checkDefined(this.getReserveBySymbol(symbol), `${description} reserve with symbol ${symbol} not found`);
564
- }
565
-
566
- getReserveMintBySymbol(symbol: string) {
567
- return this.getReserveBySymbol(symbol)?.getLiquidityMint();
606
+ getExistingReservesBySymbol(symbol: string, description: string = 'Requested'): KaminoReserve[] {
607
+ return checkArrayNotEmpty(
608
+ this.getReservesBySymbol(symbol),
609
+ `${description} reserve with symbol ${symbol} not found`
610
+ );
568
611
  }
569
612
 
570
613
  async getReserveFarmInfo(
571
- mint: Address,
614
+ reserveAddress: Address,
572
615
  getRewardPrice: (mint: Address) => Promise<number>
573
616
  ): Promise<{ borrowingRewards: ReserveRewardInfo; depositingRewards: ReserveRewardInfo }> {
574
617
  const { address } = this;
@@ -580,10 +623,10 @@ export class KaminoMarket {
580
623
  }
581
624
 
582
625
  // Find the reserve
583
- const kaminoReserve = this.getReserveByMint(mint);
626
+ const kaminoReserve = this.getReserveByAddress(reserveAddress);
584
627
 
585
628
  if (!kaminoReserve) {
586
- throw Error(`Could not find reserve. ${mint}`);
629
+ throw Error(`Could not find reserve ${reserveAddress}`);
587
630
  }
588
631
 
589
632
  const totalDepositAmount = lamportsToNumberDecimal(