@kamino-finance/klend-sdk 7.2.6 → 7.3.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 (223) hide show
  1. package/README.md +1 -0
  2. package/dist/@codegen/klend/accounts/LendingMarket.d.ts +33 -0
  3. package/dist/@codegen/klend/accounts/LendingMarket.d.ts.map +1 -1
  4. package/dist/@codegen/klend/accounts/LendingMarket.js +24 -2
  5. package/dist/@codegen/klend/accounts/LendingMarket.js.map +1 -1
  6. package/dist/@codegen/klend/errors/custom.d.ts +26 -2
  7. package/dist/@codegen/klend/errors/custom.d.ts.map +1 -1
  8. package/dist/@codegen/klend/errors/custom.js +45 -3
  9. package/dist/@codegen/klend/errors/custom.js.map +1 -1
  10. package/dist/@codegen/klend/instructions/index.d.ts +2 -0
  11. package/dist/@codegen/klend/instructions/index.d.ts.map +1 -1
  12. package/dist/@codegen/klend/instructions/index.js +3 -1
  13. package/dist/@codegen/klend/instructions/index.js.map +1 -1
  14. package/dist/@codegen/klend/instructions/initReserve.d.ts +1 -1
  15. package/dist/@codegen/klend/instructions/initReserve.d.ts.map +1 -1
  16. package/dist/@codegen/klend/instructions/initReserve.js +1 -5
  17. package/dist/@codegen/klend/instructions/initReserve.js.map +1 -1
  18. package/dist/@codegen/klend/instructions/liquidateObligationAndRedeemReserveCollateralV2.js +1 -1
  19. package/dist/@codegen/klend/instructions/seedDepositOnInitReserve.d.ts +13 -0
  20. package/dist/@codegen/klend/instructions/seedDepositOnInitReserve.d.ts.map +1 -0
  21. package/dist/@codegen/klend/instructions/seedDepositOnInitReserve.js +24 -0
  22. package/dist/@codegen/klend/instructions/seedDepositOnInitReserve.js.map +1 -0
  23. package/dist/@codegen/klend/instructions/withdrawObligationCollateral.js +1 -1
  24. package/dist/@codegen/klend/instructions/withdrawObligationCollateralV2.js +1 -1
  25. package/dist/@codegen/klend/types/ReserveConfig.d.ts +58 -24
  26. package/dist/@codegen/klend/types/ReserveConfig.d.ts.map +1 -1
  27. package/dist/@codegen/klend/types/ReserveConfig.js +40 -18
  28. package/dist/@codegen/klend/types/ReserveConfig.js.map +1 -1
  29. package/dist/@codegen/klend/types/ReserveFees.d.ts +8 -8
  30. package/dist/@codegen/klend/types/ReserveFees.d.ts.map +1 -1
  31. package/dist/@codegen/klend/types/ReserveFees.js +8 -8
  32. package/dist/@codegen/klend/types/ReserveFees.js.map +1 -1
  33. package/dist/@codegen/klend/types/UpdateConfigMode.d.ts +46 -7
  34. package/dist/@codegen/klend/types/UpdateConfigMode.d.ts.map +1 -1
  35. package/dist/@codegen/klend/types/UpdateConfigMode.js +85 -12
  36. package/dist/@codegen/klend/types/UpdateConfigMode.js.map +1 -1
  37. package/dist/@codegen/klend/types/UpdateLendingMarketMode.d.ts +26 -0
  38. package/dist/@codegen/klend/types/UpdateLendingMarketMode.d.ts.map +1 -1
  39. package/dist/@codegen/klend/types/UpdateLendingMarketMode.js +49 -1
  40. package/dist/@codegen/klend/types/UpdateLendingMarketMode.js.map +1 -1
  41. package/dist/@codegen/klend/types/index.d.ts +4 -4
  42. package/dist/@codegen/klend/types/index.d.ts.map +1 -1
  43. package/dist/@codegen/klend/types/index.js.map +1 -1
  44. package/dist/@codegen/kvault/accounts/GlobalConfig.d.ts +32 -0
  45. package/dist/@codegen/kvault/accounts/GlobalConfig.d.ts.map +1 -0
  46. package/dist/@codegen/kvault/accounts/GlobalConfig.js +125 -0
  47. package/dist/@codegen/kvault/accounts/GlobalConfig.js.map +1 -0
  48. package/dist/@codegen/kvault/accounts/Reserve.js +1 -1
  49. package/dist/@codegen/kvault/accounts/ReserveWhitelistEntry.d.ts +52 -0
  50. package/dist/@codegen/kvault/accounts/ReserveWhitelistEntry.d.ts.map +1 -0
  51. package/dist/@codegen/kvault/accounts/ReserveWhitelistEntry.js +127 -0
  52. package/dist/@codegen/kvault/accounts/ReserveWhitelistEntry.js.map +1 -0
  53. package/dist/@codegen/kvault/accounts/VaultState.d.ts +18 -0
  54. package/dist/@codegen/kvault/accounts/VaultState.d.ts.map +1 -1
  55. package/dist/@codegen/kvault/accounts/VaultState.js +39 -1
  56. package/dist/@codegen/kvault/accounts/VaultState.js.map +1 -1
  57. package/dist/@codegen/kvault/accounts/index.d.ts +4 -0
  58. package/dist/@codegen/kvault/accounts/index.d.ts.map +1 -1
  59. package/dist/@codegen/kvault/accounts/index.js +5 -1
  60. package/dist/@codegen/kvault/accounts/index.js.map +1 -1
  61. package/dist/@codegen/kvault/errors/custom.d.ts +61 -5
  62. package/dist/@codegen/kvault/errors/custom.d.ts.map +1 -1
  63. package/dist/@codegen/kvault/errors/custom.js +108 -9
  64. package/dist/@codegen/kvault/errors/custom.js.map +1 -1
  65. package/dist/@codegen/kvault/instructions/addUpdateWhitelistedReserve.d.ts +16 -0
  66. package/dist/@codegen/kvault/instructions/addUpdateWhitelistedReserve.d.ts.map +1 -0
  67. package/dist/@codegen/kvault/instructions/addUpdateWhitelistedReserve.js +66 -0
  68. package/dist/@codegen/kvault/instructions/addUpdateWhitelistedReserve.js.map +1 -0
  69. package/dist/@codegen/kvault/instructions/buy.d.ts +24 -0
  70. package/dist/@codegen/kvault/instructions/buy.d.ts.map +1 -0
  71. package/dist/@codegen/kvault/instructions/buy.js +67 -0
  72. package/dist/@codegen/kvault/instructions/buy.js.map +1 -0
  73. package/dist/@codegen/kvault/instructions/index.d.ts +12 -0
  74. package/dist/@codegen/kvault/instructions/index.d.ts.map +1 -1
  75. package/dist/@codegen/kvault/instructions/index.js +13 -1
  76. package/dist/@codegen/kvault/instructions/index.js.map +1 -1
  77. package/dist/@codegen/kvault/instructions/initGlobalConfig.d.ts +11 -0
  78. package/dist/@codegen/kvault/instructions/initGlobalConfig.d.ts.map +1 -0
  79. package/dist/@codegen/kvault/instructions/initGlobalConfig.js +20 -0
  80. package/dist/@codegen/kvault/instructions/initGlobalConfig.js.map +1 -0
  81. package/dist/@codegen/kvault/instructions/invest.d.ts +2 -1
  82. package/dist/@codegen/kvault/instructions/invest.d.ts.map +1 -1
  83. package/dist/@codegen/kvault/instructions/invest.js +5 -0
  84. package/dist/@codegen/kvault/instructions/invest.js.map +1 -1
  85. package/dist/@codegen/kvault/instructions/sell.d.ts +40 -0
  86. package/dist/@codegen/kvault/instructions/sell.d.ts.map +1 -0
  87. package/dist/@codegen/kvault/instructions/sell.js +98 -0
  88. package/dist/@codegen/kvault/instructions/sell.js.map +1 -0
  89. package/dist/@codegen/kvault/instructions/updateGlobalConfig.d.ts +13 -0
  90. package/dist/@codegen/kvault/instructions/updateGlobalConfig.d.ts.map +1 -0
  91. package/dist/@codegen/kvault/instructions/updateGlobalConfig.js +63 -0
  92. package/dist/@codegen/kvault/instructions/updateGlobalConfig.js.map +1 -0
  93. package/dist/@codegen/kvault/instructions/updateGlobalConfigAdmin.d.ts +8 -0
  94. package/dist/@codegen/kvault/instructions/updateGlobalConfigAdmin.d.ts.map +1 -0
  95. package/dist/@codegen/kvault/instructions/updateGlobalConfigAdmin.js +21 -0
  96. package/dist/@codegen/kvault/instructions/updateGlobalConfigAdmin.js.map +1 -0
  97. package/dist/@codegen/kvault/instructions/updateReserveAllocation.d.ts +2 -1
  98. package/dist/@codegen/kvault/instructions/updateReserveAllocation.d.ts.map +1 -1
  99. package/dist/@codegen/kvault/instructions/updateReserveAllocation.js +5 -0
  100. package/dist/@codegen/kvault/instructions/updateReserveAllocation.js.map +1 -1
  101. package/dist/@codegen/kvault/instructions/updateVaultConfig.d.ts +2 -1
  102. package/dist/@codegen/kvault/instructions/updateVaultConfig.d.ts.map +1 -1
  103. package/dist/@codegen/kvault/instructions/updateVaultConfig.js +2 -5
  104. package/dist/@codegen/kvault/instructions/updateVaultConfig.js.map +1 -1
  105. package/dist/@codegen/kvault/instructions/withdraw.d.ts +1 -0
  106. package/dist/@codegen/kvault/instructions/withdraw.d.ts.map +1 -1
  107. package/dist/@codegen/kvault/instructions/withdraw.js +1 -0
  108. package/dist/@codegen/kvault/instructions/withdraw.js.map +1 -1
  109. package/dist/@codegen/kvault/instructions/withdrawFromAvailable.d.ts +1 -0
  110. package/dist/@codegen/kvault/instructions/withdrawFromAvailable.d.ts.map +1 -1
  111. package/dist/@codegen/kvault/instructions/withdrawFromAvailable.js +1 -0
  112. package/dist/@codegen/kvault/instructions/withdrawFromAvailable.js.map +1 -1
  113. package/dist/@codegen/kvault/types/ReserveConfig.d.ts +27 -34
  114. package/dist/@codegen/kvault/types/ReserveConfig.d.ts.map +1 -1
  115. package/dist/@codegen/kvault/types/ReserveConfig.js +20 -17
  116. package/dist/@codegen/kvault/types/ReserveConfig.js.map +1 -1
  117. package/dist/@codegen/kvault/types/ReserveFees.d.ts +8 -8
  118. package/dist/@codegen/kvault/types/ReserveFees.d.ts.map +1 -1
  119. package/dist/@codegen/kvault/types/ReserveFees.js +8 -8
  120. package/dist/@codegen/kvault/types/ReserveFees.js.map +1 -1
  121. package/dist/@codegen/kvault/types/UpdateGlobalConfigMode.d.ts +68 -0
  122. package/dist/@codegen/kvault/types/UpdateGlobalConfigMode.d.ts.map +1 -0
  123. package/dist/@codegen/kvault/types/UpdateGlobalConfigMode.js +162 -0
  124. package/dist/@codegen/kvault/types/UpdateGlobalConfigMode.js.map +1 -0
  125. package/dist/@codegen/kvault/types/UpdateReserveWhitelistMode.d.ts +46 -0
  126. package/dist/@codegen/kvault/types/UpdateReserveWhitelistMode.d.ts.map +1 -0
  127. package/dist/@codegen/kvault/types/UpdateReserveWhitelistMode.js +124 -0
  128. package/dist/@codegen/kvault/types/UpdateReserveWhitelistMode.js.map +1 -0
  129. package/dist/@codegen/kvault/types/VaultConfigField.d.ts +65 -0
  130. package/dist/@codegen/kvault/types/VaultConfigField.d.ts.map +1 -1
  131. package/dist/@codegen/kvault/types/VaultConfigField.js +121 -1
  132. package/dist/@codegen/kvault/types/VaultConfigField.js.map +1 -1
  133. package/dist/@codegen/kvault/types/index.d.ts +10 -2
  134. package/dist/@codegen/kvault/types/index.d.ts.map +1 -1
  135. package/dist/@codegen/kvault/types/index.js +5 -1
  136. package/dist/@codegen/kvault/types/index.js.map +1 -1
  137. package/dist/classes/manager.d.ts +19 -1
  138. package/dist/classes/manager.d.ts.map +1 -1
  139. package/dist/classes/manager.js +28 -0
  140. package/dist/classes/manager.js.map +1 -1
  141. package/dist/classes/reserve.d.ts.map +1 -1
  142. package/dist/classes/reserve.js +7 -4
  143. package/dist/classes/reserve.js.map +1 -1
  144. package/dist/classes/vault.d.ts +33 -5
  145. package/dist/classes/vault.d.ts.map +1 -1
  146. package/dist/classes/vault.js +379 -48
  147. package/dist/classes/vault.js.map +1 -1
  148. package/dist/idl/klend.json +129 -59
  149. package/dist/lib.d.ts +1 -0
  150. package/dist/lib.d.ts.map +1 -1
  151. package/dist/lib.js +4 -2
  152. package/dist/lib.js.map +1 -1
  153. package/dist/manager/client_kamino_manager.js +206 -15
  154. package/dist/manager/client_kamino_manager.js.map +1 -1
  155. package/dist/utils/index.d.ts +1 -0
  156. package/dist/utils/index.d.ts.map +1 -1
  157. package/dist/utils/index.js +1 -0
  158. package/dist/utils/index.js.map +1 -1
  159. package/dist/utils/managerTypes.d.ts +1 -1
  160. package/dist/utils/managerTypes.d.ts.map +1 -1
  161. package/dist/utils/managerTypes.js +5 -3
  162. package/dist/utils/managerTypes.js.map +1 -1
  163. package/dist/utils/parse.d.ts +10 -0
  164. package/dist/utils/parse.d.ts.map +1 -0
  165. package/dist/utils/parse.js +24 -0
  166. package/dist/utils/parse.js.map +1 -0
  167. package/dist/utils/seeds.d.ts +5 -5
  168. package/dist/utils/seeds.d.ts.map +1 -1
  169. package/dist/utils/seeds.js +13 -13
  170. package/dist/utils/seeds.js.map +1 -1
  171. package/dist/utils/vault.d.ts.map +1 -1
  172. package/dist/utils/vault.js +6 -0
  173. package/dist/utils/vault.js.map +1 -1
  174. package/package.json +1 -1
  175. package/src/@codegen/klend/accounts/LendingMarket.ts +46 -2
  176. package/src/@codegen/klend/errors/custom.ts +47 -2
  177. package/src/@codegen/klend/instructions/index.ts +2 -0
  178. package/src/@codegen/klend/instructions/initReserve.ts +2 -6
  179. package/src/@codegen/klend/instructions/liquidateObligationAndRedeemReserveCollateralV2.ts +1 -1
  180. package/src/@codegen/klend/instructions/seedDepositOnInitReserve.ts +50 -0
  181. package/src/@codegen/klend/instructions/withdrawObligationCollateral.ts +1 -1
  182. package/src/@codegen/klend/instructions/withdrawObligationCollateralV2.ts +1 -1
  183. package/src/@codegen/klend/types/ReserveConfig.ts +72 -30
  184. package/src/@codegen/klend/types/ReserveFees.ts +12 -12
  185. package/src/@codegen/klend/types/UpdateConfigMode.ts +103 -13
  186. package/src/@codegen/klend/types/UpdateLendingMarketMode.ts +60 -0
  187. package/src/@codegen/klend/types/index.ts +12 -2
  188. package/src/@codegen/kvault/accounts/GlobalConfig.ts +136 -0
  189. package/src/@codegen/kvault/accounts/Reserve.ts +1 -1
  190. package/src/@codegen/kvault/accounts/ReserveWhitelistEntry.ts +157 -0
  191. package/src/@codegen/kvault/accounts/VaultState.ts +57 -1
  192. package/src/@codegen/kvault/accounts/index.ts +7 -0
  193. package/src/@codegen/kvault/errors/custom.ts +109 -8
  194. package/src/@codegen/kvault/instructions/addUpdateWhitelistedReserve.ts +64 -0
  195. package/src/@codegen/kvault/instructions/buy.ts +74 -0
  196. package/src/@codegen/kvault/instructions/index.ts +18 -0
  197. package/src/@codegen/kvault/instructions/initGlobalConfig.ts +44 -0
  198. package/src/@codegen/kvault/instructions/invest.ts +4 -0
  199. package/src/@codegen/kvault/instructions/sell.ts +122 -0
  200. package/src/@codegen/kvault/instructions/updateGlobalConfig.ts +58 -0
  201. package/src/@codegen/kvault/instructions/updateGlobalConfigAdmin.ts +42 -0
  202. package/src/@codegen/kvault/instructions/updateReserveAllocation.ts +4 -0
  203. package/src/@codegen/kvault/instructions/updateVaultConfig.ts +4 -6
  204. package/src/@codegen/kvault/instructions/withdraw.ts +2 -0
  205. package/src/@codegen/kvault/instructions/withdrawFromAvailable.ts +2 -0
  206. package/src/@codegen/kvault/types/ReserveConfig.ts +34 -37
  207. package/src/@codegen/kvault/types/ReserveFees.ts +12 -12
  208. package/src/@codegen/kvault/types/UpdateGlobalConfigMode.ts +160 -0
  209. package/src/@codegen/kvault/types/UpdateReserveWhitelistMode.ts +117 -0
  210. package/src/@codegen/kvault/types/VaultConfigField.ts +150 -0
  211. package/src/@codegen/kvault/types/index.ts +31 -0
  212. package/src/classes/manager.ts +50 -1
  213. package/src/classes/reserve.ts +7 -5
  214. package/src/classes/vault.ts +555 -48
  215. package/src/idl/klend.json +130 -60
  216. package/src/idl/kvault.json +582 -23
  217. package/src/lib.ts +2 -1
  218. package/src/manager/client_kamino_manager.ts +313 -18
  219. package/src/utils/index.ts +2 -1
  220. package/src/utils/managerTypes.ts +6 -4
  221. package/src/utils/parse.ts +18 -0
  222. package/src/utils/seeds.ts +13 -17
  223. package/src/utils/vault.ts +6 -0
@@ -6,6 +6,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.VaultHoldings = exports.ReserveAllocationConfig = exports.KaminoVaultConfig = exports.KaminoVault = exports.KaminoVaultClient = exports.INITIAL_DEPOSIT_LAMPORTS = exports.METADATA_PROGRAM_ID = exports.METADATA_SEED = exports.kaminoVaultStagingId = exports.kaminoVaultId = void 0;
7
7
  exports.getCTokenVaultPda = getCTokenVaultPda;
8
8
  exports.getEventAuthorityPda = getEventAuthorityPda;
9
+ exports.getKvaultGlobalConfigPda = getKvaultGlobalConfigPda;
10
+ exports.getReserveWhitelistEntryPda = getReserveWhitelistEntryPda;
9
11
  const bn_js_1 = __importDefault(require("bn.js"));
10
12
  const kit_1 = require("@solana/kit");
11
13
  const lib_1 = require("../lib");
@@ -42,6 +44,8 @@ const BASE_VAULT_AUTHORITY_SEED = 'authority';
42
44
  const SHARES_SEED = 'shares';
43
45
  const EVENT_AUTHORITY_SEED = '__event_authority';
44
46
  exports.METADATA_SEED = 'metadata';
47
+ const GLOBAL_CONFIG_STATE_SEED = 'global_config';
48
+ const WHITELISTED_RESERVES_SEED = 'whitelisted_reserves';
45
49
  exports.METADATA_PROGRAM_ID = (0, kit_1.address)('metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s');
46
50
  exports.INITIAL_DEPOSIT_LAMPORTS = 1000;
47
51
  const addressEncoder = (0, kit_1.getAddressEncoder)();
@@ -95,6 +99,23 @@ class KaminoVaultClient {
95
99
  holdings.print();
96
100
  console.log('Tokens per share: ', tokensPerShare);
97
101
  }
102
+ /**
103
+ * This method initializes the kvault global config (one off, needs to be signed by program owner)
104
+ * @param admin - the admin of the kvault program
105
+ * @returns - an instruction to initialize the kvault global config
106
+ */
107
+ async initKvaultGlobalConfigIx(admin) {
108
+ const globalConfigAddress = await getKvaultGlobalConfigPda(this.getProgramID());
109
+ const programData = await (0, utils_2.programDataPda)(this.getProgramID());
110
+ const ix = (0, instructions_1.initKVaultGlobalConfig)({
111
+ payer: admin,
112
+ globalConfig: globalConfigAddress,
113
+ programData: programData,
114
+ systemProgram: system_1.SYSTEM_PROGRAM_ADDRESS,
115
+ rent: sysvars_1.SYSVAR_RENT_ADDRESS,
116
+ }, undefined, this.getProgramID());
117
+ return ix;
118
+ }
98
119
  /**
99
120
  * This method will create a vault with a given config. The config can be changed later on, but it is recommended to set it up correctly from the start
100
121
  * @param vaultConfig - the config object used to create a vault
@@ -174,21 +195,21 @@ class KaminoVaultClient {
174
195
  farm_utils_1.FARMS_GLOBAL_CONFIG_MAINNET,
175
196
  ];
176
197
  const insertIntoLUTIxs = await (0, lookupTable_1.insertIntoLookupTableIxs)(this.getConnection(), vaultConfig.admin, lut, accountsToBeInserted, []);
177
- const setLUTIx = this.updateUninitialisedVaultConfigIx(vaultConfig.admin, vaultState.address, new types_1.VaultConfigField.LookupTable(), lut.toString());
198
+ const setLUTIx = await this.updateUninitialisedVaultConfigIx(vaultConfig.admin, vaultState.address, new types_1.VaultConfigField.LookupTable(), lut.toString());
178
199
  const ixs = [createVaultIx, initVaultIx, setLUTIx];
179
200
  if (vaultConfig.getPerformanceFeeBps() > 0) {
180
- const setPerformanceFeeIx = this.updateUninitialisedVaultConfigIx(vaultConfig.admin, vaultState.address, new types_1.VaultConfigField.PerformanceFeeBps(), vaultConfig.getPerformanceFeeBps().toString());
201
+ const setPerformanceFeeIx = await this.updateUninitialisedVaultConfigIx(vaultConfig.admin, vaultState.address, new types_1.VaultConfigField.PerformanceFeeBps(), vaultConfig.getPerformanceFeeBps().toString());
181
202
  ixs.push(setPerformanceFeeIx);
182
203
  }
183
204
  if (vaultConfig.getManagementFeeBps() > 0) {
184
- const setManagementFeeIx = this.updateUninitialisedVaultConfigIx(vaultConfig.admin, vaultState.address, new types_1.VaultConfigField.ManagementFeeBps(), vaultConfig.getManagementFeeBps().toString());
205
+ const setManagementFeeIx = await this.updateUninitialisedVaultConfigIx(vaultConfig.admin, vaultState.address, new types_1.VaultConfigField.ManagementFeeBps(), vaultConfig.getManagementFeeBps().toString());
185
206
  ixs.push(setManagementFeeIx);
186
207
  }
187
208
  if (vaultConfig.name && vaultConfig.name.length > 0) {
188
- const setNameIx = this.updateUninitialisedVaultConfigIx(vaultConfig.admin, vaultState.address, new types_1.VaultConfigField.Name(), vaultConfig.name);
209
+ const setNameIx = await this.updateUninitialisedVaultConfigIx(vaultConfig.admin, vaultState.address, new types_1.VaultConfigField.Name(), vaultConfig.name);
189
210
  ixs.push(setNameIx);
190
211
  }
191
- const setFarmIx = this.updateUninitialisedVaultConfigIx(vaultConfig.admin, vaultState.address, new types_1.VaultConfigField.Farm(), createVaultFarm.farm.address);
212
+ const setFarmIx = await this.updateUninitialisedVaultConfigIx(vaultConfig.admin, vaultState.address, new types_1.VaultConfigField.Farm(), createVaultFarm.farm.address);
192
213
  const metadataIx = await this.getSetSharesMetadataIx(this.getConnection(), vaultConfig.admin, vaultState.address, sharesMint, baseVaultAuthority, vaultConfig.vaultTokenSymbol, vaultConfig.vaultTokenName);
193
214
  return {
194
215
  vault: vaultState,
@@ -254,6 +275,7 @@ class KaminoVaultClient {
254
275
  const vaultState = await vault.getState();
255
276
  const reserveState = reserveAllocationConfig.getReserveState();
256
277
  const cTokenVault = await getCTokenVaultPda(vault.address, reserveAllocationConfig.getReserveAddress(), this._kaminoVaultProgramId);
278
+ const reserveWhitelistEntryOption = await getReserveWhitelistEntryIfExists(reserveAllocationConfig.getReserveAddress(), this.getConnection(), this._kaminoVaultProgramId);
257
279
  const vaultAdmin = parseVaultAdmin(vaultState, vaultAdminAuthority);
258
280
  const updateReserveAllocationAccounts = {
259
281
  signer: vaultAdmin,
@@ -262,6 +284,7 @@ class KaminoVaultClient {
262
284
  reserveCollateralMint: reserveState.collateral.mintPubkey,
263
285
  reserve: reserveAllocationConfig.getReserveAddress(),
264
286
  ctokenVault: cTokenVault,
287
+ reserveWhitelistEntry: reserveWhitelistEntryOption,
265
288
  systemProgram: system_1.SYSTEM_PROGRAM_ADDRESS,
266
289
  rent: sysvars_1.SYSVAR_RENT_ADDRESS,
267
290
  reserveCollateralTokenProgram: token_1.TOKEN_PROGRAM_ADDRESS,
@@ -436,41 +459,26 @@ class KaminoVaultClient {
436
459
  * @param vault the vault to update
437
460
  * @param mode the field to update (based on VaultConfigFieldKind enum)
438
461
  * @param value the value to update the field with
439
- * @param [vaultAdminAuthority] the signer of the transaction. Optional. If not provided the admin of the vault will be used. It should be used when changing the admin of the vault if we want to build or batch multiple ixs in the same tx
462
+ * @param [adminAuthority] the signer of the transaction. Optional. If not provided the admin of the vault will be used. It should be used when changing the admin of the vault if we want to build or batch multiple ixs in the same tx.
463
+ * The global admin should be passed in when wanting to change the AllowAllocationsInWhitelistedReservesOnly or AllowInvestInWhitelistedReservesOnly fields to false
440
464
  * @param [lutIxsSigner] the signer of the transaction to be used for the lookup table instructions. Optional. If not provided the admin of the vault will be used. It should be used when changing the admin of the vault if we want to build or batch multiple ixs in the same tx
441
465
  * @param [skipLutUpdate] if true, the lookup table instructions will not be included in the returned instructions
442
466
  * @returns a struct that contains the instruction to update the field and an optional list of instructions to update the lookup table
443
467
  */
444
- async updateVaultConfigIxs(vault, mode, value, vaultAdminAuthority, lutIxsSigner, skipLutUpdate = false) {
468
+ async updateVaultConfigIxs(vault, mode, value, adminAuthority, lutIxsSigner, skipLutUpdate = false) {
445
469
  const vaultState = await vault.getState();
446
- const admin = parseVaultAdmin(vaultState, vaultAdminAuthority);
470
+ const admin = parseVaultAdmin(vaultState, adminAuthority);
471
+ const globalConfig = await getKvaultGlobalConfigPda(this._kaminoVaultProgramId);
447
472
  const updateVaultConfigAccs = {
448
- vaultAdminAuthority: admin,
473
+ signer: admin,
474
+ globalConfig: globalConfig,
449
475
  vaultState: vault.address,
450
476
  klendProgram: this._kaminoLendProgramId,
451
477
  };
452
- if (vaultAdminAuthority) {
453
- updateVaultConfigAccs.vaultAdminAuthority = vaultAdminAuthority;
454
- }
455
478
  const updateVaultConfigArgs = {
456
479
  entry: mode,
457
- data: Buffer.from([0]),
480
+ data: this.getValueForModeAsBuffer(mode, value),
458
481
  };
459
- if (isNaN(+value) || value === lib_1.DEFAULT_PUBLIC_KEY) {
460
- if (mode.kind === new types_1.VaultConfigField.Name().kind) {
461
- const data = Array.from(this.encodeVaultName(value));
462
- updateVaultConfigArgs.data = Buffer.from(data);
463
- }
464
- else {
465
- const data = (0, kit_1.address)(value);
466
- updateVaultConfigArgs.data = Buffer.from(addressEncoder.encode(data));
467
- }
468
- }
469
- else {
470
- const buffer = Buffer.alloc(8);
471
- buffer.writeBigUInt64LE(BigInt(value.toString()));
472
- updateVaultConfigArgs.data = buffer;
473
- }
474
482
  const vaultReserves = this.getVaultReserves(vaultState);
475
483
  const vaultReservesState = await this.loadVaultReserves(vaultState);
476
484
  let updateVaultConfigIx = (0, instructions_1.updateVaultConfig)(updateVaultConfigArgs, updateVaultConfigAccs, undefined, this._kaminoVaultProgramId);
@@ -503,6 +511,30 @@ class KaminoVaultClient {
503
511
  };
504
512
  return updateVaultConfigIxs;
505
513
  }
514
+ /**
515
+ * Add or update a reserve whitelist entry. This controls whether the reserve is whitelisted for adding/updating
516
+ * allocations or for invest, depending on the mode parameter.
517
+ *
518
+ * @param reserve - Address of the reserve to whitelist
519
+ * @param mode - The whitelist mode: either 'Invest' or 'AddAllocation' with a value (1 = allow, 0 = deny)
520
+ * @param globalAdmin - The global admin that signs the transaction
521
+ * @returns - An instruction to add/update the whitelisted reserve
522
+ */
523
+ async addUpdateWhitelistedReserveIx(reserve, mode, globalAdmin) {
524
+ const globalConfig = await getKvaultGlobalConfigPda(this._kaminoVaultProgramId);
525
+ const reserveWhitelistEntry = await getReserveWhitelistEntryPda(reserve, this._kaminoVaultProgramId);
526
+ const accounts = {
527
+ globalAdmin,
528
+ globalConfig,
529
+ reserve,
530
+ reserveWhitelistEntry,
531
+ systemProgram: system_1.SYSTEM_PROGRAM_ADDRESS,
532
+ };
533
+ const args = {
534
+ update: mode,
535
+ };
536
+ return (0, instructions_1.addUpdateWhitelistedReserve)(args, accounts, undefined, this._kaminoVaultProgramId);
537
+ }
506
538
  /** Sets the farm where the shares can be staked. This is store in vault state and a vault can only have one farm, so the new farm will ovveride the old farm
507
539
  * @param vault - vault to set the farm for
508
540
  * @param farm - the farm where the vault shares can be staked
@@ -520,38 +552,28 @@ class KaminoVaultClient {
520
552
  return this.updateVaultConfigIxs(vault, new types_1.VaultConfigField.Farm(), farm, vaultAdminAuthority, lutIxsSigner, skipLutUpdate);
521
553
  }
522
554
  /**
523
- * This method updates the vault config for a vault that
524
- * @param admin - address of vault to be updated
555
+ * This method updates the vault config during vault initialization, within the same transaction
556
+ * where the vault is created. Use this when the vault state is not yet committed to the chain
557
+ * and cannot be fetched via RPC. For updates to existing vaults, use updateVaultConfigIxs instead.
558
+ *
559
+ * @param admin - the admin that signs the transaction
525
560
  * @param vault - address of vault to be updated
526
561
  * @param mode - the field to be updated
527
562
  * @param value - the new value for the field to be updated (number or pubkey)
528
563
  * @returns - an instruction to update the vault config
529
564
  */
530
- updateUninitialisedVaultConfigIx(admin, vault, mode, value) {
565
+ async updateUninitialisedVaultConfigIx(admin, vault, mode, value) {
566
+ const globalConfig = await getKvaultGlobalConfigPda(this._kaminoVaultProgramId);
531
567
  const updateVaultConfigAccs = {
532
- vaultAdminAuthority: admin,
568
+ signer: admin,
569
+ globalConfig: globalConfig,
533
570
  vaultState: vault,
534
571
  klendProgram: this._kaminoLendProgramId,
535
572
  };
536
573
  const updateVaultConfigArgs = {
537
574
  entry: mode,
538
- data: Buffer.from([0]),
575
+ data: this.getValueForModeAsBuffer(mode, value),
539
576
  };
540
- if (isNaN(+value)) {
541
- if (mode.kind === new types_1.VaultConfigField.Name().kind) {
542
- const data = Array.from(this.encodeVaultName(value));
543
- updateVaultConfigArgs.data = Buffer.from(data);
544
- }
545
- else {
546
- const data = (0, kit_1.address)(value);
547
- updateVaultConfigArgs.data = Buffer.from(addressEncoder.encode(data));
548
- }
549
- }
550
- else {
551
- const buffer = Buffer.alloc(8);
552
- buffer.writeBigUInt64LE(BigInt(value.toString()));
553
- updateVaultConfigArgs.data = buffer;
554
- }
555
577
  const updateVaultConfigIx = (0, instructions_1.updateVaultConfig)(updateVaultConfigArgs, updateVaultConfigAccs, undefined, this._kaminoVaultProgramId);
556
578
  return updateVaultConfigIx;
557
579
  }
@@ -733,6 +755,67 @@ class KaminoVaultClient {
733
755
  depositIxs.stakeInFarmIfNeededIxs = stakeSharesIxs;
734
756
  return depositIxs;
735
757
  }
758
+ // todo (silviu): after all tx indexing works for buy/sell ixs remove this function and use the buyIx in the deposit function above
759
+ async buySharesIxs(user, vault, tokenAmount, vaultReservesMap, farmState) {
760
+ const vaultState = await vault.getState();
761
+ const tokenProgramID = vaultState.tokenProgram;
762
+ const userTokenAta = await (0, lib_1.getAssociatedTokenAddress)(vaultState.tokenMint, user.address, tokenProgramID);
763
+ const createAtasIxs = [];
764
+ const closeAtasIxs = [];
765
+ if (vaultState.tokenMint === lib_1.WRAPPED_SOL_MINT) {
766
+ const [{ ata: wsolAta, createAtaIx: createWsolAtaIxn }] = await (0, utils_2.createAtasIdempotent)(user, [
767
+ {
768
+ mint: lib_1.WRAPPED_SOL_MINT,
769
+ tokenProgram: token_1.TOKEN_PROGRAM_ADDRESS,
770
+ },
771
+ ]);
772
+ createAtasIxs.push(createWsolAtaIxn);
773
+ const transferWsolIxs = (0, lib_1.getTransferWsolIxs)(user, wsolAta, (0, kit_1.lamports)(BigInt((0, utils_1.numberToLamportsDecimal)(tokenAmount, vaultState.tokenMintDecimals.toNumber()).ceil().toString())));
774
+ createAtasIxs.push(...transferWsolIxs);
775
+ }
776
+ const [{ ata: userSharesAta, createAtaIx: createSharesAtaIxs }] = await (0, utils_2.createAtasIdempotent)(user, [
777
+ {
778
+ mint: vaultState.sharesMint,
779
+ tokenProgram: token_1.TOKEN_PROGRAM_ADDRESS,
780
+ },
781
+ ]);
782
+ createAtasIxs.push(createSharesAtaIxs);
783
+ const eventAuthority = await getEventAuthorityPda(this._kaminoVaultProgramId);
784
+ const buyAccounts = {
785
+ user: user,
786
+ vaultState: vault.address,
787
+ tokenVault: vaultState.tokenVault,
788
+ tokenMint: vaultState.tokenMint,
789
+ baseVaultAuthority: vaultState.baseVaultAuthority,
790
+ sharesMint: vaultState.sharesMint,
791
+ userTokenAta: userTokenAta,
792
+ userSharesAta: userSharesAta,
793
+ tokenProgram: tokenProgramID,
794
+ klendProgram: this._kaminoLendProgramId,
795
+ sharesTokenProgram: token_1.TOKEN_PROGRAM_ADDRESS,
796
+ eventAuthority: eventAuthority,
797
+ program: this._kaminoVaultProgramId,
798
+ };
799
+ const buyArgs = {
800
+ maxAmount: new bn_js_1.default((0, utils_1.numberToLamportsDecimal)(tokenAmount, vaultState.tokenMintDecimals.toNumber()).floor().toString()),
801
+ };
802
+ let buyIx = (0, instructions_1.buy)(buyArgs, buyAccounts, undefined, this._kaminoVaultProgramId);
803
+ const vaultReserves = this.getVaultReserves(vaultState);
804
+ const vaultReservesState = vaultReservesMap ? vaultReservesMap : await this.loadVaultReserves(vaultState);
805
+ buyIx = this.appendRemainingAccountsForVaultReserves(buyIx, vaultReserves, vaultReservesState);
806
+ const depositIxs = {
807
+ depositIxs: [...createAtasIxs, buyIx, ...closeAtasIxs],
808
+ stakeInFarmIfNeededIxs: [],
809
+ };
810
+ // if there is no farm, we can return the deposit instructions, otherwise include the stake ix in the response
811
+ if (!(await vault.hasFarm())) {
812
+ return depositIxs;
813
+ }
814
+ // if there is a farm, stake the shares
815
+ const stakeSharesIxs = await this.stakeSharesIxs(user, vault, undefined, farmState);
816
+ depositIxs.stakeInFarmIfNeededIxs = stakeSharesIxs;
817
+ return depositIxs;
818
+ }
736
819
  /**
737
820
  * This function creates instructions to stake the shares in the vault farm if the vault has a farm
738
821
  * @param user - user to stake
@@ -843,6 +926,85 @@ class KaminoVaultClient {
843
926
  }
844
927
  return withdrawIxs;
845
928
  }
929
+ async sellSharesIxs(user, vault, shareAmountToWithdraw, slot, vaultReservesMap, farmState) {
930
+ const vaultState = await vault.getState();
931
+ const hasFarm = await vault.hasFarm();
932
+ const withdrawIxs = {
933
+ unstakeFromFarmIfNeededIxs: [],
934
+ withdrawIxs: [],
935
+ postWithdrawIxs: [],
936
+ };
937
+ // compute the total shares the user has (in ATA + in farm) and check if they want to withdraw everything or just a part
938
+ let userSharesAtaBalance = new decimal_js_1.default(0);
939
+ const userSharesAta = await (0, lib_1.getAssociatedTokenAddress)(vaultState.sharesMint, user.address);
940
+ const userSharesAtaState = await (0, token_2022_1.fetchMaybeToken)(this.getConnection(), userSharesAta);
941
+ if (userSharesAtaState.exists) {
942
+ const userSharesAtaBalanceInLamports = (0, lib_1.getTokenBalanceFromAccountInfoLamports)(userSharesAtaState);
943
+ userSharesAtaBalance = userSharesAtaBalanceInLamports.div(new decimal_js_1.default(10).pow(vaultState.sharesMintDecimals.toString()));
944
+ }
945
+ let userSharesInFarm = new decimal_js_1.default(0);
946
+ if (hasFarm) {
947
+ userSharesInFarm = await (0, farm_utils_1.getUserSharesInTokensStakedInFarm)(this.getConnection(), user.address, vaultState.vaultFarm, vaultState.sharesMintDecimals.toNumber());
948
+ }
949
+ let sharesToWithdraw = shareAmountToWithdraw;
950
+ const totalUserShares = userSharesAtaBalance.add(userSharesInFarm);
951
+ let withdrawAllShares = false;
952
+ if (sharesToWithdraw.gt(totalUserShares)) {
953
+ sharesToWithdraw = new decimal_js_1.default(utils_2.U64_MAX.toString()).div(new decimal_js_1.default(10).pow(vaultState.sharesMintDecimals.toString()));
954
+ withdrawAllShares = true;
955
+ }
956
+ // if not enough shares in ATA unstake from farm
957
+ const sharesInAtaAreEnoughForWithdraw = sharesToWithdraw.lte(userSharesAtaBalance);
958
+ if (hasFarm && !sharesInAtaAreEnoughForWithdraw && userSharesInFarm.gt(0)) {
959
+ // if we need to unstake we need to make sure share ata is created
960
+ const [{ createAtaIx }] = await (0, utils_2.createAtasIdempotent)(user, [
961
+ {
962
+ mint: vaultState.sharesMint,
963
+ tokenProgram: token_1.TOKEN_PROGRAM_ADDRESS,
964
+ },
965
+ ]);
966
+ withdrawIxs.unstakeFromFarmIfNeededIxs.push(createAtaIx);
967
+ let shareLamportsToWithdraw = new decimal_js_1.default(utils_2.U64_MAX.toString());
968
+ if (!withdrawAllShares) {
969
+ const sharesToWithdrawFromFarm = sharesToWithdraw.sub(userSharesAtaBalance);
970
+ shareLamportsToWithdraw = (0, kliquidity_sdk_1.collToLamportsDecimal)(sharesToWithdrawFromFarm, vaultState.sharesMintDecimals.toNumber());
971
+ }
972
+ const unstakeAndWithdrawFromFarmIxs = await (0, farm_utils_1.getFarmUnstakeAndWithdrawIxs)(this.getConnection(), user, shareLamportsToWithdraw, vaultState.vaultFarm, farmState);
973
+ withdrawIxs.unstakeFromFarmIfNeededIxs.push(unstakeAndWithdrawFromFarmIxs.unstakeIx);
974
+ withdrawIxs.unstakeFromFarmIfNeededIxs.push(unstakeAndWithdrawFromFarmIxs.withdrawIx);
975
+ }
976
+ // if the vault has allocations withdraw otherwise wtihdraw from available ix
977
+ const vaultAllocation = vaultState.vaultAllocationStrategy.find((allocation) => allocation.reserve !== lib_1.DEFAULT_PUBLIC_KEY);
978
+ if (vaultAllocation) {
979
+ const withdrawFromVaultIxs = await this.sellSharesWithReserveIxs(user, vault, sharesToWithdraw, totalUserShares, slot, vaultReservesMap);
980
+ withdrawIxs.withdrawIxs = withdrawFromVaultIxs;
981
+ }
982
+ else {
983
+ const withdrawFromVaultIxs = await this.withdrawFromAvailableIxs(user, vault, sharesToWithdraw);
984
+ withdrawIxs.withdrawIxs = withdrawFromVaultIxs;
985
+ }
986
+ // if the vault is for SOL return the ix to unwrap the SOL
987
+ if (vaultState.tokenMint === lib_1.WRAPPED_SOL_MINT) {
988
+ const userWsolAta = await (0, lib_1.getAssociatedTokenAddress)(lib_1.WRAPPED_SOL_MINT, user.address);
989
+ const unwrapIx = (0, token_2022_1.getCloseAccountInstruction)({
990
+ account: userWsolAta,
991
+ owner: user,
992
+ destination: user.address,
993
+ }, { programAddress: token_1.TOKEN_PROGRAM_ADDRESS });
994
+ withdrawIxs.postWithdrawIxs.push(unwrapIx);
995
+ }
996
+ // if we burn all of user's shares close its shares ATA
997
+ const burnAllUserShares = sharesToWithdraw.gt(totalUserShares);
998
+ if (burnAllUserShares) {
999
+ const closeAtaIx = (0, token_2022_1.getCloseAccountInstruction)({
1000
+ account: userSharesAta,
1001
+ owner: user,
1002
+ destination: user.address,
1003
+ }, { programAddress: token_1.TOKEN_PROGRAM_ADDRESS });
1004
+ withdrawIxs.postWithdrawIxs.push(closeAtaIx);
1005
+ }
1006
+ return withdrawIxs;
1007
+ }
846
1008
  async withdrawFromAvailableIxs(user, vault, shareAmount) {
847
1009
  const vaultState = await vault.getState();
848
1010
  const userSharesAta = await (0, lib_1.getAssociatedTokenAddress)(vaultState.sharesMint, user.address);
@@ -856,6 +1018,83 @@ class KaminoVaultClient {
856
1018
  const withdrawFromAvailableIxn = await this.withdrawFromAvailableIx(user, vault, vaultState, userSharesAta, userTokenAta, shareLamportsToWithdraw);
857
1019
  return [createAtaIx, withdrawFromAvailableIxn];
858
1020
  }
1021
+ async sellSharesWithReserveIxs(user, vault, shareAmount, allUserShares, slot, vaultReservesMap) {
1022
+ const vaultState = await vault.getState();
1023
+ const vaultReservesState = vaultReservesMap ? vaultReservesMap : await this.loadVaultReserves(vaultState);
1024
+ const userSharesAta = await (0, lib_1.getAssociatedTokenAddress)(vaultState.sharesMint, user.address);
1025
+ const [{ ata: userTokenAta, createAtaIx }] = await (0, utils_2.createAtasIdempotent)(user, [
1026
+ {
1027
+ mint: vaultState.tokenMint,
1028
+ tokenProgram: vaultState.tokenProgram,
1029
+ },
1030
+ ]);
1031
+ const withdrawAllShares = shareAmount.gte(allUserShares);
1032
+ const actualSharesToWithdraw = shareAmount.lte(allUserShares) ? shareAmount : allUserShares;
1033
+ const shareLamportsToWithdraw = (0, kliquidity_sdk_1.collToLamportsDecimal)(actualSharesToWithdraw, vaultState.sharesMintDecimals.toNumber());
1034
+ const tokensPerShare = await this.getTokensPerShareSingleVault(vault, slot);
1035
+ const sharesPerToken = new decimal_js_1.default(1).div(tokensPerShare);
1036
+ const tokensToWithdraw = shareLamportsToWithdraw.mul(tokensPerShare);
1037
+ let tokenLeftToWithdraw = tokensToWithdraw;
1038
+ const availableTokens = new decimal_js_1.default(vaultState.tokenAvailable.toString());
1039
+ tokenLeftToWithdraw = tokenLeftToWithdraw.sub(availableTokens);
1040
+ const reserveWithSharesAmountToWithdraw = [];
1041
+ let isFirstWithdraw = true;
1042
+ if (tokenLeftToWithdraw.lte(0)) {
1043
+ // Availabe enough to withdraw all - using the first existent reserve
1044
+ const firstReserve = vaultState.vaultAllocationStrategy.find((reserve) => reserve.reserve !== lib_1.DEFAULT_PUBLIC_KEY);
1045
+ if (withdrawAllShares) {
1046
+ reserveWithSharesAmountToWithdraw.push({
1047
+ reserve: firstReserve.reserve,
1048
+ shares: new decimal_js_1.default(utils_2.U64_MAX.toString()),
1049
+ });
1050
+ }
1051
+ else {
1052
+ reserveWithSharesAmountToWithdraw.push({
1053
+ reserve: firstReserve.reserve,
1054
+ shares: shareLamportsToWithdraw,
1055
+ });
1056
+ }
1057
+ }
1058
+ else {
1059
+ // Get decreasing order sorted available liquidity to withdraw from each reserve allocated to
1060
+ const reserveAllocationAvailableLiquidityToWithdraw = await this.getReserveAllocationAvailableLiquidityToWithdraw(vault, slot, vaultReservesState);
1061
+ // sort
1062
+ const reserveAllocationAvailableLiquidityToWithdrawSorted = [
1063
+ ...reserveAllocationAvailableLiquidityToWithdraw.entries(),
1064
+ ].sort((a, b) => b[1].sub(a[1]).toNumber());
1065
+ reserveAllocationAvailableLiquidityToWithdrawSorted.forEach(([key, availableLiquidityToWithdraw], _) => {
1066
+ if (tokenLeftToWithdraw.gt(0)) {
1067
+ let tokensToWithdrawFromReserve = decimal_js_1.default.min(tokenLeftToWithdraw, availableLiquidityToWithdraw);
1068
+ if (isFirstWithdraw) {
1069
+ tokensToWithdrawFromReserve = tokensToWithdrawFromReserve.add(availableTokens);
1070
+ isFirstWithdraw = false;
1071
+ }
1072
+ if (withdrawAllShares) {
1073
+ reserveWithSharesAmountToWithdraw.push({ reserve: key, shares: new decimal_js_1.default(utils_2.U64_MAX.toString()) });
1074
+ }
1075
+ else {
1076
+ // round up to the nearest integer the shares to withdraw
1077
+ const sharesToWithdrawFromReserve = tokensToWithdrawFromReserve.mul(sharesPerToken).floor();
1078
+ reserveWithSharesAmountToWithdraw.push({ reserve: key, shares: sharesToWithdrawFromReserve });
1079
+ }
1080
+ tokenLeftToWithdraw = tokenLeftToWithdraw.sub(tokensToWithdrawFromReserve);
1081
+ }
1082
+ });
1083
+ }
1084
+ const withdrawIxs = [];
1085
+ withdrawIxs.push(createAtaIx);
1086
+ for (let reserveIndex = 0; reserveIndex < reserveWithSharesAmountToWithdraw.length; reserveIndex++) {
1087
+ const reserveWithTokens = reserveWithSharesAmountToWithdraw[reserveIndex];
1088
+ const reserveState = vaultReservesState.get(reserveWithTokens.reserve);
1089
+ if (reserveState === undefined) {
1090
+ throw new Error(`Reserve ${reserveWithTokens.reserve} not found in vault reserves map`);
1091
+ }
1092
+ const marketAddress = reserveState.state.lendingMarket;
1093
+ const withdrawFromReserveIx = await this.sellIx(user, vault, vaultState, marketAddress, { address: reserveWithTokens.reserve, state: reserveState.state }, userSharesAta, userTokenAta, reserveWithTokens.shares, vaultReservesState);
1094
+ withdrawIxs.push(withdrawFromReserveIx);
1095
+ }
1096
+ return withdrawIxs;
1097
+ }
859
1098
  async withdrawWithReserveIxs(user, vault, shareAmount, allUserShares, slot, vaultReservesMap) {
860
1099
  const vaultState = await vault.getState();
861
1100
  const vaultReservesState = vaultReservesMap ? vaultReservesMap : await this.loadVaultReserves(vaultState);
@@ -1036,6 +1275,7 @@ class KaminoVaultClient {
1036
1275
  if (createAtaIfNeeded) {
1037
1276
  ixs.push(createAtaIx);
1038
1277
  }
1278
+ const reserveWhitelistEntryOption = await getReserveWhitelistEntryIfExists(reserve.address, this.getConnection(), this._kaminoVaultProgramId);
1039
1279
  const investAccounts = {
1040
1280
  payer,
1041
1281
  vaultState: vault.address,
@@ -1048,6 +1288,7 @@ class KaminoVaultClient {
1048
1288
  lendingMarketAuthority: lendingMarketAuth,
1049
1289
  reserveLiquiditySupply: reserve.state.liquidity.supplyVault,
1050
1290
  reserveCollateralMint: reserve.state.collateral.mintPubkey,
1291
+ reserveWhitelistEntry: reserveWhitelistEntryOption,
1051
1292
  klendProgram: this._kaminoLendProgramId,
1052
1293
  instructionSysvarAccount: sysvars_1.SYSVAR_INSTRUCTIONS_ADDRESS,
1053
1294
  tokenProgram: tokenProgram,
@@ -1072,13 +1313,82 @@ class KaminoVaultClient {
1072
1313
  decodeVaultName(token) {
1073
1314
  return (0, utils_1.decodeVaultName)(token);
1074
1315
  }
1316
+ /** Helper to serialize value as Buffer for updateVaultConfig instruction */
1317
+ getValueForModeAsBuffer(mode, value) {
1318
+ const isWhitelistOnlyFlag = mode.kind === new types_1.VaultConfigField.AllowInvestInWhitelistedReservesOnly().kind ||
1319
+ mode.kind === new types_1.VaultConfigField.AllowAllocationsInWhitelistedReservesOnly().kind;
1320
+ if (isWhitelistOnlyFlag) {
1321
+ const flag = (0, utils_2.parseBooleanFlag)(value);
1322
+ return Buffer.from([flag]);
1323
+ }
1324
+ else if (isNaN(+value)) {
1325
+ if (mode.kind === new types_1.VaultConfigField.Name().kind) {
1326
+ const data = Array.from(this.encodeVaultName(value));
1327
+ return Buffer.from(data);
1328
+ }
1329
+ else {
1330
+ const data = (0, kit_1.address)(value);
1331
+ return Buffer.from(addressEncoder.encode(data));
1332
+ }
1333
+ }
1334
+ else {
1335
+ const buffer = Buffer.alloc(8);
1336
+ buffer.writeBigUInt64LE(BigInt(value.toString()));
1337
+ return buffer;
1338
+ }
1339
+ }
1340
+ async sellIx(user, vault, vaultState, marketAddress, reserve, userSharesAta, userTokenAta, shareAmountLamports, vaultReservesState) {
1341
+ const [lendingMarketAuth] = await (0, utils_2.lendingMarketAuthPda)(marketAddress, this._kaminoLendProgramId);
1342
+ const globalConfig = await getKvaultGlobalConfigPda(this._kaminoVaultProgramId);
1343
+ const eventAuthority = await getEventAuthorityPda(this._kaminoVaultProgramId);
1344
+ const sellAccounts = {
1345
+ withdrawFromAvailable: {
1346
+ user,
1347
+ vaultState: vault.address,
1348
+ globalConfig: globalConfig,
1349
+ tokenVault: vaultState.tokenVault,
1350
+ baseVaultAuthority: vaultState.baseVaultAuthority,
1351
+ userTokenAta: userTokenAta,
1352
+ tokenMint: vaultState.tokenMint,
1353
+ userSharesAta: userSharesAta,
1354
+ sharesMint: vaultState.sharesMint,
1355
+ tokenProgram: vaultState.tokenProgram,
1356
+ sharesTokenProgram: token_1.TOKEN_PROGRAM_ADDRESS,
1357
+ klendProgram: this._kaminoLendProgramId,
1358
+ eventAuthority: eventAuthority,
1359
+ program: this._kaminoVaultProgramId,
1360
+ },
1361
+ withdrawFromReserveAccounts: {
1362
+ vaultState: vault.address,
1363
+ reserve: reserve.address,
1364
+ ctokenVault: await getCTokenVaultPda(vault.address, reserve.address, this._kaminoVaultProgramId),
1365
+ lendingMarket: marketAddress,
1366
+ lendingMarketAuthority: lendingMarketAuth,
1367
+ reserveLiquiditySupply: reserve.state.liquidity.supplyVault,
1368
+ reserveCollateralMint: reserve.state.collateral.mintPubkey,
1369
+ reserveCollateralTokenProgram: token_1.TOKEN_PROGRAM_ADDRESS,
1370
+ instructionSysvarAccount: sysvars_1.SYSVAR_INSTRUCTIONS_ADDRESS,
1371
+ },
1372
+ eventAuthority: eventAuthority,
1373
+ program: this._kaminoVaultProgramId,
1374
+ };
1375
+ const sellArgs = {
1376
+ sharesAmount: new bn_js_1.default(shareAmountLamports.floor().toString()),
1377
+ };
1378
+ let sellIxn = (0, instructions_1.sell)(sellArgs, sellAccounts, undefined, this._kaminoVaultProgramId);
1379
+ const vaultReserves = this.getVaultReserves(vaultState);
1380
+ sellIxn = this.appendRemainingAccountsForVaultReserves(sellIxn, vaultReserves, vaultReservesState);
1381
+ return sellIxn;
1382
+ }
1075
1383
  async withdrawIx(user, vault, vaultState, marketAddress, reserve, userSharesAta, userTokenAta, shareAmountLamports, vaultReservesState) {
1076
1384
  const [lendingMarketAuth] = await (0, utils_2.lendingMarketAuthPda)(marketAddress, this._kaminoLendProgramId);
1385
+ const globalConfig = await getKvaultGlobalConfigPda(this._kaminoVaultProgramId);
1077
1386
  const eventAuthority = await getEventAuthorityPda(this._kaminoVaultProgramId);
1078
1387
  const withdrawAccounts = {
1079
1388
  withdrawFromAvailable: {
1080
1389
  user,
1081
1390
  vaultState: vault.address,
1391
+ globalConfig: globalConfig,
1082
1392
  tokenVault: vaultState.tokenVault,
1083
1393
  baseVaultAuthority: vaultState.baseVaultAuthority,
1084
1394
  userTokenAta: userTokenAta,
@@ -1114,10 +1424,12 @@ class KaminoVaultClient {
1114
1424
  return withdrawIxn;
1115
1425
  }
1116
1426
  async withdrawFromAvailableIx(user, vault, vaultState, userSharesAta, userTokenAta, shareAmountLamports) {
1427
+ const globalConfig = await getKvaultGlobalConfigPda(this._kaminoVaultProgramId);
1117
1428
  const eventAuthority = await getEventAuthorityPda(this._kaminoVaultProgramId);
1118
1429
  const withdrawFromAvailableAccounts = {
1119
1430
  user,
1120
1431
  vaultState: vault.address,
1432
+ globalConfig: globalConfig,
1121
1433
  tokenVault: vaultState.tokenVault,
1122
1434
  baseVaultAuthority: vaultState.baseVaultAuthority,
1123
1435
  userTokenAta,
@@ -2853,6 +3165,25 @@ async function getEventAuthorityPda(kaminoVaultProgramId) {
2853
3165
  programAddress: kaminoVaultProgramId,
2854
3166
  }))[0];
2855
3167
  }
3168
+ async function getKvaultGlobalConfigPda(kaminoVaultProgramId) {
3169
+ return (await (0, kit_1.getProgramDerivedAddress)({
3170
+ seeds: [Buffer.from(GLOBAL_CONFIG_STATE_SEED)],
3171
+ programAddress: kaminoVaultProgramId,
3172
+ }))[0];
3173
+ }
3174
+ async function getReserveWhitelistEntryPda(reserveAddress, kaminoVaultProgramId) {
3175
+ return (await (0, kit_1.getProgramDerivedAddress)({
3176
+ seeds: [Buffer.from(WHITELISTED_RESERVES_SEED), addressEncoder.encode(reserveAddress)],
3177
+ programAddress: kaminoVaultProgramId,
3178
+ }))[0];
3179
+ }
3180
+ async function getReserveWhitelistEntryIfExists(reserveAddress, rpc, kaminoVaultProgramId) {
3181
+ const reserveWhitelistEntry = await getReserveWhitelistEntryPda(reserveAddress, kaminoVaultProgramId);
3182
+ const reserveWhitelistEntryAccount = await (0, kit_1.fetchEncodedAccount)(rpc, reserveWhitelistEntry, {
3183
+ commitment: 'processed',
3184
+ });
3185
+ return reserveWhitelistEntryAccount.exists ? (0, kit_1.some)(reserveWhitelistEntry) : (0, kit_1.none)();
3186
+ }
2856
3187
  function parseVaultAdmin(vault, signer) {
2857
3188
  return signer ?? (0, signer_1.noopSigner)(vault.vaultAdminAuthority);
2858
3189
  }