@kamino-finance/klend-sdk 3.2.0 → 3.2.2

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.
@@ -1,4 +1,17 @@
1
- ## Kamino Manager CLI
1
+ # Kamino Manager Guidelines
2
+
3
+ ## 1. Kamino Manager CLI
4
+
5
+ #### Installation Instructions
6
+
7
+ Ensure *yarn* is installed first [here](https://classic.yarnpkg.com/lang/en/docs/install/)
8
+ ```shell
9
+ git clone git@github.com:Kamino-Finance/klend-sdk.git
10
+ cd klend-sdk
11
+ yarn
12
+ ```
13
+
14
+ #### Requirements
2
15
 
3
16
  In order to use the CLI, the followign `.env` configuration is required:
4
17
  ```
@@ -11,59 +24,134 @@ KVAULT_PROGRAM_ID_STAGING="STkvh7ostar39Fwr4uZKASs1RNNuYMFMTsE77FiRsL2"
11
24
  ```
12
25
 
13
26
  #### Create a new market
14
- `npx ts-node src/client_kamino_manager.ts create-market --staging`
27
+ ```
28
+ yarn kamino-manager create-market --staging --mode execute
29
+ ```
15
30
 
16
- - bs58 - is a boolean flag. If set it will print the bs58 txn instead of executing. Should be used for multisig
17
- - staging - is a boolean flag. If set, staging programs will be used
18
- - multisig - address string to be used as admin PublicKey. To be used in conjunction with bs58 flag
31
+ - **mode** - can have these values:
32
+ - *inspect* - will print an url to the explorer txn inspection, where it can be simulated
33
+ - *simulate* - will print the simulation outputs
34
+ - *execute* - will execute the transaction
35
+ - *multisig* - will print the bs58 transaction to be used within a multisig
36
+ It is recommended to **1. inspect/simulate** and then **2. execute/multisig**
37
+ - **staging** - is a boolean flag. If set, staging programs will be used
38
+ - **multisig** - address string to be used as admin PublicKey. To be used in conjunction with multisig mode
19
39
 
20
40
  #### Add a new asset to market / Create new reserve
21
- `npx ts-node src/client_kamino_manager.ts add-asset-to-market --market market_address --mint token_mint --mint-program-id TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA --reserve-config-path ./configs/reserve_config_example.json --staging`
41
+ ```
42
+ yarn kamino-manager add-asset-to-market --market market_address --mint token_mint --mint-program-id TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA --reserve-config-path ./configs/reserve_config_example.json --staging --mode execute
43
+ ```
22
44
 
23
- - market - address to create the reserve for
24
- - mint - the liquidity mint to create the reserve for
25
- - mint-program-id - the program id of the mint - `TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA` - spl token program `TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb` - for token 2022 token program
26
- - bs58 - is a boolean flag. If set it will print the bs58 txn instead of executing. Should be used for multisig
27
- - staging - is a boolean flag. If set, staging programs will be used
28
- - multisig - address string to be used as admin PublicKey. To be used in conjunction with bs58 flag
45
+ - **market** - address to create the reserve for
46
+ - **mint** - the liquidity mint to create the reserve for
47
+ - **mint-program-id** - the program id of the mint - `TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA` - spl token program `TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb` - for token 2022 token program
48
+ - **reserve-config-path** - path to the reserve config to be used. A reserve config example can be found [here](https://github.com/Kamino-Finance/klend-sdk/blob/master/configs/reserve_config_example.json)
49
+ - **mode** - can have these values:
50
+ - *inspect* - will print an url to the explorer txn inspection, where it can be simulated
51
+ - *simulate* - will print the simulation outputs
52
+ - *execute* - will execute the transaction
53
+ - *multisig* - will print the bs58 transaction to be used within a multisig
54
+ It is recommended to **1. inspect/simulate** and then **2. execute/multisig**
55
+ - **staging** - is a boolean flag. If set, staging programs will be used
56
+ - **multisig** - address string to be used as admin PublicKey. To be used in conjunction with multisig mode
29
57
 
30
- #### Update a reserve config
31
- `npx ts-node src/client_kamino_manager.ts update-reserve-config --reserve reserve_address --reserve-config-path ./configs/reserve_config_example.json --staging --update-entire-config`
32
58
 
33
- - reserve - address to update the reserve config for
34
- - reserve-config-path - the path to the config file to be used
35
- - update-entire-config - wether to update the entrie reserve config or just the difference between current on-chain state and given config
36
- - bs58 - is a boolean flag. If set it will print the bs58 txn instead of executing. Should be used for multisig
37
- - staging - is a boolean flag. If set, staging programs will be used
38
59
 
39
60
  #### Download a reserve config
40
61
 
41
62
  In order to update a reserve config, you need the latest reserve configuration, to modify. To get the latest, this command can be used:
42
63
 
43
- `npx ts-node src/client_kamino_manager.ts download-reserve-config --reserve reserve_address --staging`
64
+ ```
65
+ yarn kamino-manager download-reserve-config --reserve reserve_address --staging
66
+ ```
67
+
68
+ - **reserve** - address to update the reserve config for
69
+ - **staging** - is a boolean flag. If set, staging programs will be used
70
+
71
+ #### Update a reserve config
72
+ ```
73
+ yarn kamino-manager update-reserve-config --reserve reserve_address --reserve-config-path ./configs/reserve_config_example.json --staging --update-entire-config --mode execute
74
+ ```
75
+
76
+ - **reserve** - address to update the reserve config for
77
+ - **reserve-config-path** - the path to the config file to be used
78
+ - **update-entire-config** - wether to update the entrie reserve config or just the difference between current on-chain state and given config
79
+ - **mode** - can have these values:
80
+ - *inspect* - will print an url to the explorer txn inspection, where it can be simulated
81
+ - *simulate* - will print the simulation outputs
82
+ - *execute* - will execute the transaction
83
+ - *multisig* - will print the bs58 transaction to be used within a multisig
84
+ It is recommended to **1. inspect/simulate** and then **2. execute/multisig**
85
+ - **staging** - is a boolean flag. If set, staging programs will be used
44
86
 
45
- - reserve - address to update the reserve config for
46
- - staging - is a boolean flag. If set, staging programs will be used
87
+ A reserve config example can be found [here](https://github.com/Kamino-Finance/klend-sdk/blob/master/configs/reserve_config_example.json)
47
88
 
48
89
  #### Create a vault
49
- `npx ts-node src/client_kamino_manager.ts create-vault --mint token_mint --staging`
90
+ ```
91
+ yarn kamino-manager create-vault --mint token_mint --staging --mode execute
92
+ ```
50
93
 
51
- - mint - the liquidity mint to create the reserve for
52
- - bs58 - is a boolean flag. If set it will print the bs58 txn instead of executing. Should be used for multisig
53
- - staging - is a boolean flag. If set, staging programs will be used
54
- - multisig - address string to be used as admin PublicKey. To be used in conjunction with bs58 flag
94
+ - **mint** - the liquidity mint to create the reserve for
95
+ - **mode** - can have these values:
96
+ - *inspect* - will print an url to the explorer txn inspection, where it can be simulated
97
+ - *simulate* - will print the simulation outputs
98
+ - *execute* - will execute the transaction
99
+ - *multisig* - will print the bs58 transaction to be used within a multisig
100
+ It is recommended to **1. inspect/simulate** and then **2. execute/multisig**
101
+ - **staging** - is a boolean flag. If set, staging programs will be used
102
+ - **multisig** - address string to be used as admin PublicKey. To be used in conjunction with multisig mode
55
103
 
56
104
  #### Update vault reserve allocation
57
- `npx ts-node src/client_kamino_manager.ts update-vault-reserve-allocation --vault vault_address --reserve reserve_address --allocation-weight number --allocation-cap number --staging`
105
+ ```
106
+ yarn kamino-manager update-vault-reserve-allocation --vault vault_address --reserve reserve_address --allocation-weight number --allocation-cap number --staging --mode execute
107
+ ```
58
108
 
59
- - vault - the vault address to add/update the reserve allocation for
60
- - reserve - the reserve address to add/update the reserve allocation for
61
- - allocation-weight - the allocation weight for given reserve; only relevant in relation with the other reserve allocation weights
62
- - allocation-cap - the allocation cap in decimal (not lamports) for given reserve
63
- - bs58 - is a boolean flag. If set it will print the bs58 txn instead of executing. Should be used for multisig
64
- - staging - is a boolean flag. If set, staging programs will be used
65
- - multisig - address string to be used as admin PublicKey. To be used in conjunction with bs58 flag
109
+ - **vault** - the vault address to add/update the reserve allocation for
110
+ - **reserve** - the reserve address to add/update the reserve allocation for
111
+ - **allocation-weight** - the allocation weight for given reserve; only relevant in relation with the other reserve allocation weights
112
+ - **allocation-cap** - the allocation cap in decimal (not lamports) for given reserve
113
+ - **mode** - can have these values:
114
+ - *inspect* - will print an url to the explorer txn inspection, where it can be simulated
115
+ - *simulate* - will print the simulation outputs
116
+ - *execute* - will execute the transaction
117
+ - *multisig* - will print the bs58 transaction to be used within a multisig
118
+ It is recommended to **1. inspect/simulate** and then **2. execute/multisig**
119
+ - **staging** - is a boolean flag. If set, staging programs will be used
120
+ - **multisig** - address string to be used as admin PublicKey. To be used in conjunction with multisig mode
66
121
 
67
122
  #### Get oracle mappings
68
123
  This can be used to get scope oracle mappings to be used when configuring the reserve oracle config.
69
- `npx ts-node src/client_kamino_manager.ts get-oracle-mappings`
124
+ ```
125
+ yarn kamino-manager get-oracle-mappings
126
+ ```
127
+
128
+ ## 2. Kamino Manager Class
129
+
130
+ In order to use the kamino manager class, which provides a high-level interface
131
+ for the main actions in regards to managing a market or a vault, you will need to use
132
+ the kamino manager class.
133
+
134
+ #### Installation Instructions
135
+
136
+ Run one of the following commands within the project directory you want to use the manager class within
137
+ ```shell
138
+ # npm
139
+ npm install @kamino-finance/klend-sdk
140
+
141
+ # yarn
142
+ yarn add @kamino-finance/klend-sdk
143
+ ```
144
+
145
+ #### Getting Started
146
+
147
+ ```ts
148
+ const connection = new anchor.web3.Connection("rpc.url");
149
+ const kaminoManager = new KaminoManager(connection, kLendProgramId, kVaultProgramId);
150
+ ```
151
+
152
+ - kLendProgramId and kVaultProgramId can be undefined and default prod programs will be used
153
+ - programIds can be found [here](https://github.com/Kamino-Finance/klend-sdk/blob/master/.env.example)
154
+
155
+ #### Example Usage
156
+
157
+ For usage examples, a good starting place is [this](https://github.com/Kamino-Finance/klend-sdk/blob/master/tests/kamino_manager_tests/kamino_manager.test.ts) test file
@@ -8,6 +8,7 @@ export declare const POSITION_LIMIT = 10;
8
8
  export declare const BORROWS_LIMIT = 5;
9
9
  export declare const DEPOSITS_LIMIT = 8;
10
10
  export type ActionType = 'deposit' | 'borrow' | 'withdraw' | 'repay' | 'mint' | 'redeem' | 'depositCollateral' | 'liquidate' | 'depositAndBorrow' | 'repayAndWithdraw' | 'refreshObligation' | 'requestElevationGroup' | 'withdrawReferrerFees';
11
+ export type AuxiliaryIx = 'setup' | 'inBetween' | 'cleanup';
11
12
  export declare class KaminoAction {
12
13
  kaminoMarket: KaminoMarket;
13
14
  reserve: KaminoReserve;
@@ -131,7 +132,7 @@ export declare class KaminoAction {
131
132
  addLiquidateIx(maxAllowedLtvOverridePercent?: number): Promise<void>;
132
133
  addInBetweenIxs(action: ActionType, includeAtaIxns: boolean, requestElevationGroup: boolean, addInitObligationForFarm: boolean, isClosingPosition?: boolean): Promise<void>;
133
134
  addRefreshObligation(crank: PublicKey): void;
134
- addSupportIxsWithoutInitObligation(action: ActionType, includeAtaIxns: boolean, addToSetupIxs?: boolean, requestElevationGroup?: boolean, addInitObligationForFarm?: boolean, isClosingPosition?: boolean, twoTokenAction?: boolean): Promise<void>;
135
+ addSupportIxsWithoutInitObligation(action: ActionType, includeAtaIxns: boolean, addAsSupportIx?: AuxiliaryIx, requestElevationGroup?: boolean, addInitObligationForFarm?: boolean, isClosingPosition?: boolean, twoTokenAction?: boolean): Promise<void>;
135
136
  addSupportIxs(action: ActionType, includeAtaIxns: boolean, requestElevationGroup: boolean, includeUserMetadata: boolean, addInitObligationForFarm: boolean, twoTokenAction?: boolean): Promise<void>;
136
137
  private static optionalAccount;
137
138
  private addRefreshReserveIxs;
@@ -164,7 +164,7 @@ class KaminoAction {
164
164
  axn.addComputeBudgetIxn(extraComputeBudget);
165
165
  }
166
166
  axn.addRefreshObligation(payer);
167
- axn.addRequestElevationIx(elevationGroup, true);
167
+ axn.addRequestElevationIx(elevationGroup, 'setup');
168
168
  return axn;
169
169
  });
170
170
  }
@@ -863,12 +863,12 @@ class KaminoAction {
863
863
  }
864
864
  addInBetweenIxs(action_1, includeAtaIxns_1, requestElevationGroup_1, addInitObligationForFarm_1) {
865
865
  return __awaiter(this, arguments, void 0, function* (action, includeAtaIxns, requestElevationGroup, addInitObligationForFarm, isClosingPosition = false) {
866
- yield this.addSupportIxsWithoutInitObligation(action, includeAtaIxns, false, requestElevationGroup, addInitObligationForFarm, isClosingPosition);
866
+ yield this.addSupportIxsWithoutInitObligation(action, includeAtaIxns, 'inBetween', requestElevationGroup, addInitObligationForFarm, isClosingPosition);
867
867
  });
868
868
  }
869
869
  addRefreshObligation(crank) {
870
870
  const uniqueReserveAddresses = new utils_1.PublicKeySet(this.depositReserves.concat(this.borrowReserves)).toArray();
871
- const addAllToSetupIxns = true;
871
+ const addAllToSetupIxns = 'setup';
872
872
  // Union of addresses
873
873
  const allReservesExcludingCurrent = [...uniqueReserveAddresses];
874
874
  this.addRefreshReserveIxs(allReservesExcludingCurrent, addAllToSetupIxns);
@@ -877,7 +877,7 @@ class KaminoAction {
877
877
  this.addRefreshObligationIx(addAllToSetupIxns, false);
878
878
  }
879
879
  addSupportIxsWithoutInitObligation(action_1, includeAtaIxns_1) {
880
- return __awaiter(this, arguments, void 0, function* (action, includeAtaIxns, addToSetupIxs = true, requestElevationGroup = false, addInitObligationForFarm = false, isClosingPosition = false, twoTokenAction = false) {
880
+ return __awaiter(this, arguments, void 0, function* (action, includeAtaIxns, addAsSupportIx = 'setup', requestElevationGroup = false, addInitObligationForFarm = false, isClosingPosition = false, twoTokenAction = false) {
881
881
  var _a;
882
882
  // TODO: why are we not doing this first?
883
883
  if (includeAtaIxns) {
@@ -955,63 +955,63 @@ class KaminoAction {
955
955
  const currentReserveAddresses = new utils_1.PublicKeySet(currentReserves.map((reserve) => reserve.address));
956
956
  // Union of addresses
957
957
  const allReservesExcludingCurrent = [...uniqueReserveAddresses.toArray()].filter((address) => !currentReserveAddresses.contains(address));
958
- this.addRefreshReserveIxs(allReservesExcludingCurrent, addToSetupIxs);
958
+ this.addRefreshReserveIxs(allReservesExcludingCurrent, addAsSupportIx);
959
959
  if (addInitObligationForFarm) {
960
960
  if (action === 'liquidate') {
961
- yield this.addInitObligationForFarm(this.reserve, types_1.ReserveFarmKind.Debt, addToSetupIxs);
962
- yield this.addInitObligationForFarm(this.outflowReserve, types_1.ReserveFarmKind.Collateral, addToSetupIxs);
961
+ yield this.addInitObligationForFarm(this.reserve, types_1.ReserveFarmKind.Debt, addAsSupportIx);
962
+ yield this.addInitObligationForFarm(this.outflowReserve, types_1.ReserveFarmKind.Collateral, addAsSupportIx);
963
963
  }
964
964
  else if (action === 'depositAndBorrow' ||
965
965
  action === 'depositCollateral' ||
966
966
  action === 'withdraw' ||
967
967
  action === 'deposit') {
968
- yield this.addInitObligationForFarm(this.reserve, types_1.ReserveFarmKind.Collateral, addToSetupIxs);
968
+ yield this.addInitObligationForFarm(this.reserve, types_1.ReserveFarmKind.Collateral, addAsSupportIx);
969
969
  if (this.outflowReserve) {
970
- yield this.addInitObligationForFarm(this.outflowReserve, types_1.ReserveFarmKind.Debt, addToSetupIxs);
970
+ yield this.addInitObligationForFarm(this.outflowReserve, types_1.ReserveFarmKind.Debt, addAsSupportIx);
971
971
  }
972
972
  }
973
973
  else if (action === 'repayAndWithdraw' || action === 'borrow' || action === 'repay') {
974
974
  // todo - probably don't need to add both debt and collateral for everything here
975
- yield this.addInitObligationForFarm(this.reserve, types_1.ReserveFarmKind.Debt, addToSetupIxs);
975
+ yield this.addInitObligationForFarm(this.reserve, types_1.ReserveFarmKind.Debt, addAsSupportIx);
976
976
  if (this.outflowReserve) {
977
- yield this.addInitObligationForFarm(this.outflowReserve, types_1.ReserveFarmKind.Collateral, addToSetupIxs);
977
+ yield this.addInitObligationForFarm(this.outflowReserve, types_1.ReserveFarmKind.Collateral, addAsSupportIx);
978
978
  }
979
979
  }
980
980
  else {
981
- yield this.addInitObligationForFarm(this.reserve, types_1.ReserveFarmKind.Collateral, addToSetupIxs);
982
- yield this.addInitObligationForFarm(this.reserve, types_1.ReserveFarmKind.Debt, addToSetupIxs);
981
+ yield this.addInitObligationForFarm(this.reserve, types_1.ReserveFarmKind.Collateral, addAsSupportIx);
982
+ yield this.addInitObligationForFarm(this.reserve, types_1.ReserveFarmKind.Debt, addAsSupportIx);
983
983
  if (this.outflowReserve) {
984
- yield this.addInitObligationForFarm(this.outflowReserve, types_1.ReserveFarmKind.Collateral, addToSetupIxs);
985
- yield this.addInitObligationForFarm(this.outflowReserve, types_1.ReserveFarmKind.Debt, addToSetupIxs);
984
+ yield this.addInitObligationForFarm(this.outflowReserve, types_1.ReserveFarmKind.Collateral, addAsSupportIx);
985
+ yield this.addInitObligationForFarm(this.outflowReserve, types_1.ReserveFarmKind.Debt, addAsSupportIx);
986
986
  }
987
987
  }
988
988
  }
989
- this.addRefreshReserveIxs(currentReserveAddresses.toArray(), addToSetupIxs);
990
- if (action === 'repayAndWithdraw' && !addToSetupIxs && isClosingPosition) {
989
+ this.addRefreshReserveIxs(currentReserveAddresses.toArray(), addAsSupportIx);
990
+ if (action === 'repayAndWithdraw' && addAsSupportIx === 'inBetween' && isClosingPosition) {
991
991
  // addToSetupIxs === addInBetween (same thing)
992
992
  // If this is a repay and withdraw, and it's not the first action, and it's closing a position
993
993
  // we don't need to include the repay reserve in the refresh obligation
994
994
  // I am ashamed of this code, we need to rewrite this entire thing
995
- this.addRefreshObligationIx(addToSetupIxs, true);
995
+ this.addRefreshObligationIx(addAsSupportIx, true);
996
996
  }
997
997
  else {
998
- this.addRefreshObligationIx(addToSetupIxs, false);
998
+ this.addRefreshObligationIx(addAsSupportIx, false);
999
999
  }
1000
- if (addToSetupIxs) {
1000
+ if (addAsSupportIx === 'setup') {
1001
1001
  // If this is an setup ixn (therefore not an in-between), it means it's either a one off action
1002
1002
  // or the first of a two-token-action
1003
1003
  if (action === 'liquidate') {
1004
- this.addRefreshFarmsForReserve([this.outflowReserve], addToSetupIxs, types_1.ReserveFarmKind.Collateral);
1005
- this.addRefreshFarmsForReserve([this.reserve], addToSetupIxs, types_1.ReserveFarmKind.Debt);
1004
+ this.addRefreshFarmsForReserve([this.outflowReserve], addAsSupportIx, types_1.ReserveFarmKind.Collateral);
1005
+ this.addRefreshFarmsForReserve([this.reserve], addAsSupportIx, types_1.ReserveFarmKind.Debt);
1006
1006
  }
1007
1007
  else if (action === 'depositAndBorrow' ||
1008
1008
  action === 'depositCollateral' ||
1009
1009
  action === 'withdraw' ||
1010
1010
  action === 'deposit') {
1011
- this.addRefreshFarmsForReserve(currentReserves, addToSetupIxs, types_1.ReserveFarmKind.Collateral, undefined, twoTokenAction);
1011
+ this.addRefreshFarmsForReserve(currentReserves, addAsSupportIx, types_1.ReserveFarmKind.Collateral, undefined, twoTokenAction);
1012
1012
  }
1013
1013
  else if (action === 'repayAndWithdraw' || action === 'borrow' || action === 'repay') {
1014
- this.addRefreshFarmsForReserve(currentReserves, addToSetupIxs, types_1.ReserveFarmKind.Debt, undefined, twoTokenAction);
1014
+ this.addRefreshFarmsForReserve(currentReserves, addAsSupportIx, types_1.ReserveFarmKind.Debt, undefined, twoTokenAction);
1015
1015
  }
1016
1016
  else {
1017
1017
  throw new Error(`Could not decide on refresh farm for action ${action}`);
@@ -1022,15 +1022,28 @@ class KaminoAction {
1022
1022
  // so we skip the refresh farm obligation of the first reserve as that operation already happened
1023
1023
  // add added to 'setup' ixns
1024
1024
  if (action === 'depositAndBorrow') {
1025
- this.addRefreshFarmsForReserve([this.outflowReserve], addToSetupIxs, types_1.ReserveFarmKind.Debt);
1025
+ this.addRefreshFarmsForReserve([this.outflowReserve], addAsSupportIx, types_1.ReserveFarmKind.Debt);
1026
1026
  }
1027
1027
  else if (action === 'repayAndWithdraw') {
1028
- this.addRefreshFarmsForReserve([this.outflowReserve], addToSetupIxs, types_1.ReserveFarmKind.Collateral);
1028
+ this.addRefreshFarmsForReserve([this.outflowReserve], addAsSupportIx, types_1.ReserveFarmKind.Collateral);
1029
1029
  }
1030
1030
  else {
1031
1031
  throw new Error(`Could not decide on refresh farm for action ${action}`);
1032
1032
  }
1033
1033
  }
1034
+ if (action === 'repay' && requestElevationGroup) {
1035
+ const repayObligationLiquidity = this.obligation.borrows.get(this.reserve.address);
1036
+ if (!repayObligationLiquidity) {
1037
+ throw new Error(`Could not find debt reserve ${this.reserve.address} in obligation`);
1038
+ }
1039
+ if (new decimal_js_1.default(repayObligationLiquidity.amount).lte(new decimal_js_1.default(this.amount.toString())) &&
1040
+ this.obligation.borrows.size === 1) {
1041
+ this.addRefreshReserveIxs(allReservesExcludingCurrent, 'cleanup');
1042
+ // Skip the borrow reserve, since we repay in the same tx
1043
+ this.addRefreshObligationIx('cleanup', true);
1044
+ this.addRequestElevationIx(0, 'cleanup', true);
1045
+ }
1046
+ }
1034
1047
  if ((action === 'depositAndBorrow' || action === 'borrow') && requestElevationGroup) {
1035
1048
  let emodeGroupsDebt = this.reserve.state.config.elevationGroups;
1036
1049
  let emodeGroupsColl = this.reserve.state.config.elevationGroups;
@@ -1058,16 +1071,16 @@ class KaminoAction {
1058
1071
  });
1059
1072
  const eModeGroup = groups.find((group) => group.id === eModeGroupWithMaxLtvAndDebtReserve).id;
1060
1073
  console.log('Setting eModeGroup to', eModeGroup);
1061
- let addToSetupIxs = false;
1074
+ let addAsSupportIx = 'inBetween';
1062
1075
  if (eModeGroup !== 0 && eModeGroup !== ((_a = this.obligation) === null || _a === void 0 ? void 0 : _a.state.elevationGroup)) {
1063
1076
  if (action === 'borrow') {
1064
1077
  this.obligation.refreshedStats.potentialElevationGroupUpdate = eModeGroup;
1065
- addToSetupIxs = true;
1078
+ addAsSupportIx = 'setup';
1066
1079
  }
1067
- this.addRequestElevationIx(eModeGroup, addToSetupIxs);
1068
- this.addRefreshReserveIxs(allReservesExcludingCurrent, addToSetupIxs);
1069
- this.addRefreshReserveIxs(currentReserveAddresses.toArray(), addToSetupIxs);
1070
- this.addRefreshObligationIx(addToSetupIxs);
1080
+ this.addRequestElevationIx(eModeGroup, addAsSupportIx);
1081
+ this.addRefreshReserveIxs(allReservesExcludingCurrent, addAsSupportIx);
1082
+ this.addRefreshReserveIxs(currentReserveAddresses.toArray(), addAsSupportIx);
1083
+ this.addRefreshObligationIx(addAsSupportIx);
1071
1084
  }
1072
1085
  }
1073
1086
  }
@@ -1084,7 +1097,7 @@ class KaminoAction {
1084
1097
  yield this.addInitReferrerTokenStateIxs();
1085
1098
  yield this.addInitObligationIxs();
1086
1099
  }
1087
- yield this.addSupportIxsWithoutInitObligation(action, includeAtaIxns, true, requestElevationGroup, addInitObligationForFarm, false, twoTokenAction);
1100
+ yield this.addSupportIxsWithoutInitObligation(action, includeAtaIxns, 'setup', requestElevationGroup, addInitObligationForFarm, false, twoTokenAction);
1088
1101
  });
1089
1102
  }
1090
1103
  static optionalAccount(pubkey, programId = lib_1.PROGRAM_ID) {
@@ -1095,7 +1108,7 @@ class KaminoAction {
1095
1108
  return programId;
1096
1109
  }
1097
1110
  }
1098
- addRefreshReserveIxs(reserves, addToSetupIxs = true) {
1111
+ addRefreshReserveIxs(reserves, addAsSupportIx = 'setup') {
1099
1112
  reserves.forEach((reserveAddress) => {
1100
1113
  const foundReserve = this.kaminoMarket.getReserveByAddress(reserveAddress);
1101
1114
  if (!foundReserve) {
@@ -1110,14 +1123,18 @@ class KaminoAction {
1110
1123
  switchboardTwapOracle: KaminoAction.optionalAccount(state.config.tokenInfo.switchboardConfiguration.twapAggregator, this.kaminoMarket.programId),
1111
1124
  scopePrices: KaminoAction.optionalAccount(state.config.tokenInfo.scopeConfiguration.priceFeed, this.kaminoMarket.programId),
1112
1125
  }, this.kaminoMarket.programId);
1113
- if (addToSetupIxs) {
1126
+ if (addAsSupportIx === 'setup') {
1114
1127
  this.setupIxs.push(refreshReserveIx);
1115
1128
  this.setupIxsLabels.push(`RefreshReserve[${reserveAddress}]`);
1116
1129
  }
1117
- else {
1130
+ else if (addAsSupportIx === 'inBetween') {
1118
1131
  this.inBetweenIxs.push(refreshReserveIx);
1119
1132
  this.inBetweenIxsLabels.push(`RefreshReserve[${reserveAddress}]`);
1120
1133
  }
1134
+ else {
1135
+ this.cleanupIxs.push(refreshReserveIx);
1136
+ this.cleanupIxsLabels.push(`RefreshReserve[${reserveAddress}]`);
1137
+ }
1121
1138
  });
1122
1139
  }
1123
1140
  static getRefreshAllReserves(kaminoMarket, reserves) {
@@ -1137,7 +1154,7 @@ class KaminoAction {
1137
1154
  }, kaminoMarket.programId);
1138
1155
  });
1139
1156
  }
1140
- addRefreshObligationIx(addToSetupIxs = true, skipBorrowObligations = false) {
1157
+ addRefreshObligationIx(addAsSupportIx = 'setup', skipBorrowObligations = false) {
1141
1158
  const marketAddress = this.kaminoMarket.getAddress();
1142
1159
  const obligationPda = this.getObligationPda();
1143
1160
  const refreshObligationIx = (0, instructions_1.refreshObligation)({
@@ -1166,16 +1183,20 @@ class KaminoAction {
1166
1183
  ...depositReserveAccountMetas,
1167
1184
  ...(skipBorrowObligations ? [] : [...borrowReserveAccountMetas, ...borrowReservesReferrerTokenStates]),
1168
1185
  ]);
1169
- if (addToSetupIxs) {
1186
+ if (addAsSupportIx === 'setup') {
1170
1187
  this.setupIxs.push(refreshObligationIx);
1171
1188
  this.setupIxsLabels.push(`RefreshObligation[${obligationPda.toString()}]`);
1172
1189
  }
1173
- else {
1190
+ else if (addAsSupportIx === 'inBetween') {
1174
1191
  this.inBetweenIxs.push(refreshObligationIx);
1175
1192
  this.inBetweenIxsLabels.push(`RefreshObligation[${obligationPda.toString()}]`);
1176
1193
  }
1194
+ else {
1195
+ this.cleanupIxs.push(refreshObligationIx);
1196
+ this.cleanupIxsLabels.push(`RefreshObligation[${obligationPda.toString()}]`);
1197
+ }
1177
1198
  }
1178
- addRequestElevationIx(elevationGroup, addToSetupIxs) {
1199
+ addRequestElevationIx(elevationGroup, addAsSupportIx, skipBorrowObligations = false) {
1179
1200
  const obligationPda = this.getObligationPda();
1180
1201
  const args = {
1181
1202
  elevationGroup,
@@ -1207,19 +1228,22 @@ class KaminoAction {
1207
1228
  .filter((x) => !x.pubkey.equals(this.kaminoMarket.programId));
1208
1229
  requestElevationGroupIx.keys = requestElevationGroupIx.keys.concat([
1209
1230
  ...depositReserveAccountMetas,
1210
- ...borrowReserveAccountMetas,
1211
- ...borrowReservesReferrerTokenStates,
1231
+ ...(skipBorrowObligations ? [] : [...borrowReserveAccountMetas, ...borrowReservesReferrerTokenStates]),
1212
1232
  ]);
1213
- if (addToSetupIxs) {
1233
+ if (addAsSupportIx === 'setup') {
1214
1234
  this.setupIxs.push(requestElevationGroupIx);
1215
1235
  this.setupIxsLabels.push(`RequestElevation[${obligationPda}], elevation_group:${elevationGroup}`);
1216
1236
  }
1217
- else {
1237
+ else if (addAsSupportIx === 'inBetween') {
1218
1238
  this.inBetweenIxs.push(requestElevationGroupIx);
1219
1239
  this.inBetweenIxsLabels.push(`RequestElevation[${obligationPda}], elevation_group:${elevationGroup}`);
1220
1240
  }
1241
+ else {
1242
+ this.cleanupIxs.push(requestElevationGroupIx);
1243
+ this.cleanupIxsLabels.push(`RequestElevation[${obligationPda}], elevation_group:${elevationGroup}`);
1244
+ }
1221
1245
  }
1222
- addRefreshFarmsForReserve(reserves, addToSetupIxs = true, mode, crank = this.payer, twoTokenAction = false) {
1246
+ addRefreshFarmsForReserve(reserves, addAsSupportIx = 'setup', mode, crank = this.payer, twoTokenAction = false) {
1223
1247
  const BASE_SEED_USER_STATE = Buffer.from('user');
1224
1248
  const getPda = (farm) => web3_js_1.PublicKey.findProgramAddressSync([BASE_SEED_USER_STATE, farm.toBytes(), this.getObligationPda().toBytes()], farms_sdk_1.farmsId)[0];
1225
1249
  const farms = [];
@@ -1256,7 +1280,7 @@ class KaminoAction {
1256
1280
  systemProgram: web3_js_1.SystemProgram.programId,
1257
1281
  };
1258
1282
  const refreshFarmForObligationix = (0, instructions_1.refreshObligationFarmsForReserve)(args, accounts, this.kaminoMarket.programId);
1259
- if (addToSetupIxs) {
1283
+ if (addAsSupportIx === 'setup') {
1260
1284
  this.setupIxs.push(refreshFarmForObligationix);
1261
1285
  this.setupIxsLabels.push(`RefreshFarmForObligation[${arg[0].kind}, res=${arg[3].address.toString()}, obl=${this.getObligationPda().toString()}]`);
1262
1286
  if (twoTokenAction) {
@@ -1269,7 +1293,7 @@ class KaminoAction {
1269
1293
  this.refreshFarmsCleanupTxnIxsLabels.push(`RefreshFarmForObligation[${arg[0].kind}, res=${arg[3].address.toString()}, obl=${this.getObligationPda().toString()}]`);
1270
1294
  }
1271
1295
  }
1272
- else {
1296
+ else if (addAsSupportIx === 'inBetween') {
1273
1297
  this.inBetweenIxs.push(refreshFarmForObligationix);
1274
1298
  this.inBetweenIxsLabels.push(`RefreshFarmForObligation[${arg[0].kind}, res=${arg[3].address.toString()}, obl=${this.getObligationPda().toString()}]`);
1275
1299
  this.refreshFarmsCleanupTxnIxs.push(refreshFarmForObligationix);
@@ -1282,7 +1306,7 @@ class KaminoAction {
1282
1306
  this.cleanupIxsLabels.splice(this.cleanupIxsLabels.length - 1, 0, ...this.refreshFarmsCleanupTxnIxsLabels);
1283
1307
  }
1284
1308
  addInitObligationForFarm(reserve_1, mode_1) {
1285
- return __awaiter(this, arguments, void 0, function* (reserve, mode, addToSetupIxs = true) {
1309
+ return __awaiter(this, arguments, void 0, function* (reserve, mode, addAsSupportIx = 'setup') {
1286
1310
  const BASE_SEED_USER_STATE = Buffer.from('user');
1287
1311
  const getPda = (farm) => web3_js_1.PublicKey.findProgramAddressSync([BASE_SEED_USER_STATE, farm.toBytes(), this.getObligationPda().toBytes()], farms_sdk_1.farmsId)[0];
1288
1312
  const farms = [];
@@ -1316,11 +1340,11 @@ class KaminoAction {
1316
1340
  systemProgram: web3_js_1.SystemProgram.programId,
1317
1341
  };
1318
1342
  const initObligationForFarm = (0, instructions_1.initObligationFarmsForReserve)(args, accounts, this.kaminoMarket.programId);
1319
- if (addToSetupIxs) {
1343
+ if (addAsSupportIx === 'setup') {
1320
1344
  this.setupIxs.push(initObligationForFarm);
1321
1345
  this.setupIxsLabels.push(`InitObligationForFarm[${reserve.address.toString()}, ${this.getObligationPda().toString()}]`);
1322
1346
  }
1323
- else {
1347
+ else if (addAsSupportIx === 'inBetween') {
1324
1348
  this.inBetweenIxs.push(initObligationForFarm);
1325
1349
  this.inBetweenIxsLabels.push(`InitObligationForFarm[${reserve.address.toString()}, ${this.getObligationPda().toString()}]`);
1326
1350
  }