@kamino-finance/klend-sdk 7.3.0 → 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/dist/classes/manager.d.ts +2 -0
- package/dist/classes/manager.d.ts.map +1 -1
- package/dist/classes/manager.js +6 -0
- package/dist/classes/manager.js.map +1 -1
- package/dist/classes/vault.d.ts +4 -0
- package/dist/classes/vault.d.ts.map +1 -1
- package/dist/classes/vault.js +260 -0
- package/dist/classes/vault.js.map +1 -1
- package/package.json +1 -1
- package/src/classes/manager.ts +21 -0
- package/src/classes/vault.ts +389 -0
package/dist/classes/vault.js
CHANGED
|
@@ -755,6 +755,67 @@ class KaminoVaultClient {
|
|
|
755
755
|
depositIxs.stakeInFarmIfNeededIxs = stakeSharesIxs;
|
|
756
756
|
return depositIxs;
|
|
757
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
|
+
}
|
|
758
819
|
/**
|
|
759
820
|
* This function creates instructions to stake the shares in the vault farm if the vault has a farm
|
|
760
821
|
* @param user - user to stake
|
|
@@ -865,6 +926,85 @@ class KaminoVaultClient {
|
|
|
865
926
|
}
|
|
866
927
|
return withdrawIxs;
|
|
867
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
|
+
}
|
|
868
1008
|
async withdrawFromAvailableIxs(user, vault, shareAmount) {
|
|
869
1009
|
const vaultState = await vault.getState();
|
|
870
1010
|
const userSharesAta = await (0, lib_1.getAssociatedTokenAddress)(vaultState.sharesMint, user.address);
|
|
@@ -878,6 +1018,83 @@ class KaminoVaultClient {
|
|
|
878
1018
|
const withdrawFromAvailableIxn = await this.withdrawFromAvailableIx(user, vault, vaultState, userSharesAta, userTokenAta, shareLamportsToWithdraw);
|
|
879
1019
|
return [createAtaIx, withdrawFromAvailableIxn];
|
|
880
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
|
+
}
|
|
881
1098
|
async withdrawWithReserveIxs(user, vault, shareAmount, allUserShares, slot, vaultReservesMap) {
|
|
882
1099
|
const vaultState = await vault.getState();
|
|
883
1100
|
const vaultReservesState = vaultReservesMap ? vaultReservesMap : await this.loadVaultReserves(vaultState);
|
|
@@ -1120,6 +1337,49 @@ class KaminoVaultClient {
|
|
|
1120
1337
|
return buffer;
|
|
1121
1338
|
}
|
|
1122
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
|
+
}
|
|
1123
1383
|
async withdrawIx(user, vault, vaultState, marketAddress, reserve, userSharesAta, userTokenAta, shareAmountLamports, vaultReservesState) {
|
|
1124
1384
|
const [lendingMarketAuth] = await (0, utils_2.lendingMarketAuthPda)(marketAddress, this._kaminoLendProgramId);
|
|
1125
1385
|
const globalConfig = await getKvaultGlobalConfigPda(this._kaminoVaultProgramId);
|