@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.
- package/README.md +1 -0
- package/dist/@codegen/klend/accounts/LendingMarket.d.ts +33 -0
- package/dist/@codegen/klend/accounts/LendingMarket.d.ts.map +1 -1
- package/dist/@codegen/klend/accounts/LendingMarket.js +24 -2
- package/dist/@codegen/klend/accounts/LendingMarket.js.map +1 -1
- package/dist/@codegen/klend/errors/custom.d.ts +26 -2
- package/dist/@codegen/klend/errors/custom.d.ts.map +1 -1
- package/dist/@codegen/klend/errors/custom.js +45 -3
- package/dist/@codegen/klend/errors/custom.js.map +1 -1
- package/dist/@codegen/klend/instructions/index.d.ts +2 -0
- package/dist/@codegen/klend/instructions/index.d.ts.map +1 -1
- package/dist/@codegen/klend/instructions/index.js +3 -1
- package/dist/@codegen/klend/instructions/index.js.map +1 -1
- package/dist/@codegen/klend/instructions/initReserve.d.ts +1 -1
- package/dist/@codegen/klend/instructions/initReserve.d.ts.map +1 -1
- package/dist/@codegen/klend/instructions/initReserve.js +1 -5
- package/dist/@codegen/klend/instructions/initReserve.js.map +1 -1
- package/dist/@codegen/klend/instructions/liquidateObligationAndRedeemReserveCollateralV2.js +1 -1
- package/dist/@codegen/klend/instructions/seedDepositOnInitReserve.d.ts +13 -0
- package/dist/@codegen/klend/instructions/seedDepositOnInitReserve.d.ts.map +1 -0
- package/dist/@codegen/klend/instructions/seedDepositOnInitReserve.js +24 -0
- package/dist/@codegen/klend/instructions/seedDepositOnInitReserve.js.map +1 -0
- package/dist/@codegen/klend/instructions/withdrawObligationCollateral.js +1 -1
- package/dist/@codegen/klend/instructions/withdrawObligationCollateralV2.js +1 -1
- package/dist/@codegen/klend/types/ReserveConfig.d.ts +58 -24
- package/dist/@codegen/klend/types/ReserveConfig.d.ts.map +1 -1
- package/dist/@codegen/klend/types/ReserveConfig.js +40 -18
- package/dist/@codegen/klend/types/ReserveConfig.js.map +1 -1
- package/dist/@codegen/klend/types/ReserveFees.d.ts +8 -8
- package/dist/@codegen/klend/types/ReserveFees.d.ts.map +1 -1
- package/dist/@codegen/klend/types/ReserveFees.js +8 -8
- package/dist/@codegen/klend/types/ReserveFees.js.map +1 -1
- package/dist/@codegen/klend/types/UpdateConfigMode.d.ts +46 -7
- package/dist/@codegen/klend/types/UpdateConfigMode.d.ts.map +1 -1
- package/dist/@codegen/klend/types/UpdateConfigMode.js +85 -12
- package/dist/@codegen/klend/types/UpdateConfigMode.js.map +1 -1
- package/dist/@codegen/klend/types/UpdateLendingMarketMode.d.ts +26 -0
- package/dist/@codegen/klend/types/UpdateLendingMarketMode.d.ts.map +1 -1
- package/dist/@codegen/klend/types/UpdateLendingMarketMode.js +49 -1
- package/dist/@codegen/klend/types/UpdateLendingMarketMode.js.map +1 -1
- package/dist/@codegen/klend/types/index.d.ts +4 -4
- package/dist/@codegen/klend/types/index.d.ts.map +1 -1
- package/dist/@codegen/klend/types/index.js.map +1 -1
- package/dist/@codegen/kvault/accounts/GlobalConfig.d.ts +32 -0
- package/dist/@codegen/kvault/accounts/GlobalConfig.d.ts.map +1 -0
- package/dist/@codegen/kvault/accounts/GlobalConfig.js +125 -0
- package/dist/@codegen/kvault/accounts/GlobalConfig.js.map +1 -0
- package/dist/@codegen/kvault/accounts/Reserve.js +1 -1
- package/dist/@codegen/kvault/accounts/ReserveWhitelistEntry.d.ts +52 -0
- package/dist/@codegen/kvault/accounts/ReserveWhitelistEntry.d.ts.map +1 -0
- package/dist/@codegen/kvault/accounts/ReserveWhitelistEntry.js +127 -0
- package/dist/@codegen/kvault/accounts/ReserveWhitelistEntry.js.map +1 -0
- package/dist/@codegen/kvault/accounts/VaultState.d.ts +18 -0
- package/dist/@codegen/kvault/accounts/VaultState.d.ts.map +1 -1
- package/dist/@codegen/kvault/accounts/VaultState.js +39 -1
- package/dist/@codegen/kvault/accounts/VaultState.js.map +1 -1
- package/dist/@codegen/kvault/accounts/index.d.ts +4 -0
- package/dist/@codegen/kvault/accounts/index.d.ts.map +1 -1
- package/dist/@codegen/kvault/accounts/index.js +5 -1
- package/dist/@codegen/kvault/accounts/index.js.map +1 -1
- package/dist/@codegen/kvault/errors/custom.d.ts +61 -5
- package/dist/@codegen/kvault/errors/custom.d.ts.map +1 -1
- package/dist/@codegen/kvault/errors/custom.js +108 -9
- package/dist/@codegen/kvault/errors/custom.js.map +1 -1
- package/dist/@codegen/kvault/instructions/addUpdateWhitelistedReserve.d.ts +16 -0
- package/dist/@codegen/kvault/instructions/addUpdateWhitelistedReserve.d.ts.map +1 -0
- package/dist/@codegen/kvault/instructions/addUpdateWhitelistedReserve.js +66 -0
- package/dist/@codegen/kvault/instructions/addUpdateWhitelistedReserve.js.map +1 -0
- package/dist/@codegen/kvault/instructions/buy.d.ts +24 -0
- package/dist/@codegen/kvault/instructions/buy.d.ts.map +1 -0
- package/dist/@codegen/kvault/instructions/buy.js +67 -0
- package/dist/@codegen/kvault/instructions/buy.js.map +1 -0
- package/dist/@codegen/kvault/instructions/index.d.ts +12 -0
- package/dist/@codegen/kvault/instructions/index.d.ts.map +1 -1
- package/dist/@codegen/kvault/instructions/index.js +13 -1
- package/dist/@codegen/kvault/instructions/index.js.map +1 -1
- package/dist/@codegen/kvault/instructions/initGlobalConfig.d.ts +11 -0
- package/dist/@codegen/kvault/instructions/initGlobalConfig.d.ts.map +1 -0
- package/dist/@codegen/kvault/instructions/initGlobalConfig.js +20 -0
- package/dist/@codegen/kvault/instructions/initGlobalConfig.js.map +1 -0
- package/dist/@codegen/kvault/instructions/invest.d.ts +2 -1
- package/dist/@codegen/kvault/instructions/invest.d.ts.map +1 -1
- package/dist/@codegen/kvault/instructions/invest.js +5 -0
- package/dist/@codegen/kvault/instructions/invest.js.map +1 -1
- package/dist/@codegen/kvault/instructions/sell.d.ts +40 -0
- package/dist/@codegen/kvault/instructions/sell.d.ts.map +1 -0
- package/dist/@codegen/kvault/instructions/sell.js +98 -0
- package/dist/@codegen/kvault/instructions/sell.js.map +1 -0
- package/dist/@codegen/kvault/instructions/updateGlobalConfig.d.ts +13 -0
- package/dist/@codegen/kvault/instructions/updateGlobalConfig.d.ts.map +1 -0
- package/dist/@codegen/kvault/instructions/updateGlobalConfig.js +63 -0
- package/dist/@codegen/kvault/instructions/updateGlobalConfig.js.map +1 -0
- package/dist/@codegen/kvault/instructions/updateGlobalConfigAdmin.d.ts +8 -0
- package/dist/@codegen/kvault/instructions/updateGlobalConfigAdmin.d.ts.map +1 -0
- package/dist/@codegen/kvault/instructions/updateGlobalConfigAdmin.js +21 -0
- package/dist/@codegen/kvault/instructions/updateGlobalConfigAdmin.js.map +1 -0
- package/dist/@codegen/kvault/instructions/updateReserveAllocation.d.ts +2 -1
- package/dist/@codegen/kvault/instructions/updateReserveAllocation.d.ts.map +1 -1
- package/dist/@codegen/kvault/instructions/updateReserveAllocation.js +5 -0
- package/dist/@codegen/kvault/instructions/updateReserveAllocation.js.map +1 -1
- package/dist/@codegen/kvault/instructions/updateVaultConfig.d.ts +2 -1
- package/dist/@codegen/kvault/instructions/updateVaultConfig.d.ts.map +1 -1
- package/dist/@codegen/kvault/instructions/updateVaultConfig.js +2 -5
- package/dist/@codegen/kvault/instructions/updateVaultConfig.js.map +1 -1
- package/dist/@codegen/kvault/instructions/withdraw.d.ts +1 -0
- package/dist/@codegen/kvault/instructions/withdraw.d.ts.map +1 -1
- package/dist/@codegen/kvault/instructions/withdraw.js +1 -0
- package/dist/@codegen/kvault/instructions/withdraw.js.map +1 -1
- package/dist/@codegen/kvault/instructions/withdrawFromAvailable.d.ts +1 -0
- package/dist/@codegen/kvault/instructions/withdrawFromAvailable.d.ts.map +1 -1
- package/dist/@codegen/kvault/instructions/withdrawFromAvailable.js +1 -0
- package/dist/@codegen/kvault/instructions/withdrawFromAvailable.js.map +1 -1
- package/dist/@codegen/kvault/types/ReserveConfig.d.ts +27 -34
- package/dist/@codegen/kvault/types/ReserveConfig.d.ts.map +1 -1
- package/dist/@codegen/kvault/types/ReserveConfig.js +20 -17
- package/dist/@codegen/kvault/types/ReserveConfig.js.map +1 -1
- package/dist/@codegen/kvault/types/ReserveFees.d.ts +8 -8
- package/dist/@codegen/kvault/types/ReserveFees.d.ts.map +1 -1
- package/dist/@codegen/kvault/types/ReserveFees.js +8 -8
- package/dist/@codegen/kvault/types/ReserveFees.js.map +1 -1
- package/dist/@codegen/kvault/types/UpdateGlobalConfigMode.d.ts +68 -0
- package/dist/@codegen/kvault/types/UpdateGlobalConfigMode.d.ts.map +1 -0
- package/dist/@codegen/kvault/types/UpdateGlobalConfigMode.js +162 -0
- package/dist/@codegen/kvault/types/UpdateGlobalConfigMode.js.map +1 -0
- package/dist/@codegen/kvault/types/UpdateReserveWhitelistMode.d.ts +46 -0
- package/dist/@codegen/kvault/types/UpdateReserveWhitelistMode.d.ts.map +1 -0
- package/dist/@codegen/kvault/types/UpdateReserveWhitelistMode.js +124 -0
- package/dist/@codegen/kvault/types/UpdateReserveWhitelistMode.js.map +1 -0
- package/dist/@codegen/kvault/types/VaultConfigField.d.ts +65 -0
- package/dist/@codegen/kvault/types/VaultConfigField.d.ts.map +1 -1
- package/dist/@codegen/kvault/types/VaultConfigField.js +121 -1
- package/dist/@codegen/kvault/types/VaultConfigField.js.map +1 -1
- package/dist/@codegen/kvault/types/index.d.ts +10 -2
- package/dist/@codegen/kvault/types/index.d.ts.map +1 -1
- package/dist/@codegen/kvault/types/index.js +5 -1
- package/dist/@codegen/kvault/types/index.js.map +1 -1
- package/dist/classes/manager.d.ts +19 -1
- package/dist/classes/manager.d.ts.map +1 -1
- package/dist/classes/manager.js +28 -0
- package/dist/classes/manager.js.map +1 -1
- package/dist/classes/reserve.d.ts.map +1 -1
- package/dist/classes/reserve.js +7 -4
- package/dist/classes/reserve.js.map +1 -1
- package/dist/classes/vault.d.ts +33 -5
- package/dist/classes/vault.d.ts.map +1 -1
- package/dist/classes/vault.js +379 -48
- package/dist/classes/vault.js.map +1 -1
- package/dist/idl/klend.json +129 -59
- package/dist/lib.d.ts +1 -0
- package/dist/lib.d.ts.map +1 -1
- package/dist/lib.js +4 -2
- package/dist/lib.js.map +1 -1
- package/dist/manager/client_kamino_manager.js +206 -15
- package/dist/manager/client_kamino_manager.js.map +1 -1
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +1 -0
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/managerTypes.d.ts +1 -1
- package/dist/utils/managerTypes.d.ts.map +1 -1
- package/dist/utils/managerTypes.js +5 -3
- package/dist/utils/managerTypes.js.map +1 -1
- package/dist/utils/parse.d.ts +10 -0
- package/dist/utils/parse.d.ts.map +1 -0
- package/dist/utils/parse.js +24 -0
- package/dist/utils/parse.js.map +1 -0
- package/dist/utils/seeds.d.ts +5 -5
- package/dist/utils/seeds.d.ts.map +1 -1
- package/dist/utils/seeds.js +13 -13
- package/dist/utils/seeds.js.map +1 -1
- package/dist/utils/vault.d.ts.map +1 -1
- package/dist/utils/vault.js +6 -0
- package/dist/utils/vault.js.map +1 -1
- package/package.json +1 -1
- package/src/@codegen/klend/accounts/LendingMarket.ts +46 -2
- package/src/@codegen/klend/errors/custom.ts +47 -2
- package/src/@codegen/klend/instructions/index.ts +2 -0
- package/src/@codegen/klend/instructions/initReserve.ts +2 -6
- package/src/@codegen/klend/instructions/liquidateObligationAndRedeemReserveCollateralV2.ts +1 -1
- package/src/@codegen/klend/instructions/seedDepositOnInitReserve.ts +50 -0
- package/src/@codegen/klend/instructions/withdrawObligationCollateral.ts +1 -1
- package/src/@codegen/klend/instructions/withdrawObligationCollateralV2.ts +1 -1
- package/src/@codegen/klend/types/ReserveConfig.ts +72 -30
- package/src/@codegen/klend/types/ReserveFees.ts +12 -12
- package/src/@codegen/klend/types/UpdateConfigMode.ts +103 -13
- package/src/@codegen/klend/types/UpdateLendingMarketMode.ts +60 -0
- package/src/@codegen/klend/types/index.ts +12 -2
- package/src/@codegen/kvault/accounts/GlobalConfig.ts +136 -0
- package/src/@codegen/kvault/accounts/Reserve.ts +1 -1
- package/src/@codegen/kvault/accounts/ReserveWhitelistEntry.ts +157 -0
- package/src/@codegen/kvault/accounts/VaultState.ts +57 -1
- package/src/@codegen/kvault/accounts/index.ts +7 -0
- package/src/@codegen/kvault/errors/custom.ts +109 -8
- package/src/@codegen/kvault/instructions/addUpdateWhitelistedReserve.ts +64 -0
- package/src/@codegen/kvault/instructions/buy.ts +74 -0
- package/src/@codegen/kvault/instructions/index.ts +18 -0
- package/src/@codegen/kvault/instructions/initGlobalConfig.ts +44 -0
- package/src/@codegen/kvault/instructions/invest.ts +4 -0
- package/src/@codegen/kvault/instructions/sell.ts +122 -0
- package/src/@codegen/kvault/instructions/updateGlobalConfig.ts +58 -0
- package/src/@codegen/kvault/instructions/updateGlobalConfigAdmin.ts +42 -0
- package/src/@codegen/kvault/instructions/updateReserveAllocation.ts +4 -0
- package/src/@codegen/kvault/instructions/updateVaultConfig.ts +4 -6
- package/src/@codegen/kvault/instructions/withdraw.ts +2 -0
- package/src/@codegen/kvault/instructions/withdrawFromAvailable.ts +2 -0
- package/src/@codegen/kvault/types/ReserveConfig.ts +34 -37
- package/src/@codegen/kvault/types/ReserveFees.ts +12 -12
- package/src/@codegen/kvault/types/UpdateGlobalConfigMode.ts +160 -0
- package/src/@codegen/kvault/types/UpdateReserveWhitelistMode.ts +117 -0
- package/src/@codegen/kvault/types/VaultConfigField.ts +150 -0
- package/src/@codegen/kvault/types/index.ts +31 -0
- package/src/classes/manager.ts +50 -1
- package/src/classes/reserve.ts +7 -5
- package/src/classes/vault.ts +555 -48
- package/src/idl/klend.json +130 -60
- package/src/idl/kvault.json +582 -23
- package/src/lib.ts +2 -1
- package/src/manager/client_kamino_manager.ts +313 -18
- package/src/utils/index.ts +2 -1
- package/src/utils/managerTypes.ts +6 -4
- package/src/utils/parse.ts +18 -0
- package/src/utils/seeds.ts +13 -17
- package/src/utils/vault.ts +6 -0
package/dist/classes/vault.js
CHANGED
|
@@ -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 [
|
|
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,
|
|
468
|
+
async updateVaultConfigIxs(vault, mode, value, adminAuthority, lutIxsSigner, skipLutUpdate = false) {
|
|
445
469
|
const vaultState = await vault.getState();
|
|
446
|
-
const admin = parseVaultAdmin(vaultState,
|
|
470
|
+
const admin = parseVaultAdmin(vaultState, adminAuthority);
|
|
471
|
+
const globalConfig = await getKvaultGlobalConfigPda(this._kaminoVaultProgramId);
|
|
447
472
|
const updateVaultConfigAccs = {
|
|
448
|
-
|
|
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:
|
|
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
|
|
524
|
-
*
|
|
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
|
-
|
|
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:
|
|
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
|
}
|