@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.
- package/README_KAMINO_MANAGER.md +124 -36
- package/dist/classes/action.d.ts +2 -1
- package/dist/classes/action.js +74 -50
- package/dist/classes/action.js.map +1 -1
- package/dist/classes/reserve.js +1 -1
- package/dist/classes/reserve.js.map +1 -1
- package/dist/client_kamino_manager.js +78 -65
- package/dist/client_kamino_manager.js.map +1 -1
- package/package.json +3 -2
package/README_KAMINO_MANAGER.md
CHANGED
|
@@ -1,4 +1,17 @@
|
|
|
1
|
-
|
|
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
|
-
|
|
27
|
+
```
|
|
28
|
+
yarn kamino-manager create-market --staging --mode execute
|
|
29
|
+
```
|
|
15
30
|
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
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
|
-
|
|
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
|
-
-
|
|
27
|
-
-
|
|
28
|
-
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
-
|
|
53
|
-
-
|
|
54
|
-
-
|
|
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
|
-
|
|
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
|
-
-
|
|
64
|
-
-
|
|
65
|
-
-
|
|
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
|
-
|
|
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
|
package/dist/classes/action.d.ts
CHANGED
|
@@ -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,
|
|
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;
|
package/dist/classes/action.js
CHANGED
|
@@ -164,7 +164,7 @@ class KaminoAction {
|
|
|
164
164
|
axn.addComputeBudgetIxn(extraComputeBudget);
|
|
165
165
|
}
|
|
166
166
|
axn.addRefreshObligation(payer);
|
|
167
|
-
axn.addRequestElevationIx(elevationGroup,
|
|
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,
|
|
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 =
|
|
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,
|
|
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,
|
|
958
|
+
this.addRefreshReserveIxs(allReservesExcludingCurrent, addAsSupportIx);
|
|
959
959
|
if (addInitObligationForFarm) {
|
|
960
960
|
if (action === 'liquidate') {
|
|
961
|
-
yield this.addInitObligationForFarm(this.reserve, types_1.ReserveFarmKind.Debt,
|
|
962
|
-
yield this.addInitObligationForFarm(this.outflowReserve, types_1.ReserveFarmKind.Collateral,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
982
|
-
yield this.addInitObligationForFarm(this.reserve, types_1.ReserveFarmKind.Debt,
|
|
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,
|
|
985
|
-
yield this.addInitObligationForFarm(this.outflowReserve, types_1.ReserveFarmKind.Debt,
|
|
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(),
|
|
990
|
-
if (action === 'repayAndWithdraw' &&
|
|
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(
|
|
995
|
+
this.addRefreshObligationIx(addAsSupportIx, true);
|
|
996
996
|
}
|
|
997
997
|
else {
|
|
998
|
-
this.addRefreshObligationIx(
|
|
998
|
+
this.addRefreshObligationIx(addAsSupportIx, false);
|
|
999
999
|
}
|
|
1000
|
-
if (
|
|
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],
|
|
1005
|
-
this.addRefreshFarmsForReserve([this.reserve],
|
|
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,
|
|
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,
|
|
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],
|
|
1025
|
+
this.addRefreshFarmsForReserve([this.outflowReserve], addAsSupportIx, types_1.ReserveFarmKind.Debt);
|
|
1026
1026
|
}
|
|
1027
1027
|
else if (action === 'repayAndWithdraw') {
|
|
1028
|
-
this.addRefreshFarmsForReserve([this.outflowReserve],
|
|
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
|
|
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
|
-
|
|
1078
|
+
addAsSupportIx = 'setup';
|
|
1066
1079
|
}
|
|
1067
|
-
this.addRequestElevationIx(eModeGroup,
|
|
1068
|
-
this.addRefreshReserveIxs(allReservesExcludingCurrent,
|
|
1069
|
-
this.addRefreshReserveIxs(currentReserveAddresses.toArray(),
|
|
1070
|
-
this.addRefreshObligationIx(
|
|
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,
|
|
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,
|
|
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 (
|
|
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(
|
|
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 (
|
|
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,
|
|
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 (
|
|
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,
|
|
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 (
|
|
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,
|
|
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 (
|
|
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
|
}
|