@kamino-finance/klend-sdk 5.4.1 → 5.4.3
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/action.js +2 -2
- package/dist/classes/action.js.map +1 -1
- package/dist/classes/vault.d.ts.map +1 -1
- package/dist/classes/vault.js +52 -22
- package/dist/classes/vault.js.map +1 -1
- package/dist/client_kamino_manager.d.ts.map +1 -1
- package/dist/client_kamino_manager.js +10 -4
- package/dist/client_kamino_manager.js.map +1 -1
- package/dist/idl_codegen_kamino_vault/accounts/VaultState.js +1 -1
- package/dist/idl_codegen_kamino_vault/accounts/VaultState.js.map +1 -1
- package/package.json +1 -1
- package/src/classes/action.ts +2 -2
- package/src/classes/vault.ts +56 -28
- package/src/client_kamino_manager.ts +15 -4
- package/src/idl_codegen_kamino_vault/accounts/VaultState.ts +1 -1
package/package.json
CHANGED
package/src/classes/action.ts
CHANGED
|
@@ -2023,7 +2023,7 @@ export class KaminoAction {
|
|
|
2023
2023
|
const borrowReservesReferrerTokenStates = borrowReservesList
|
|
2024
2024
|
.map((reserve) => {
|
|
2025
2025
|
if (this.referrer.equals(PublicKey.default)) {
|
|
2026
|
-
return { pubkey: this.kaminoMarket.programId, isSigner: false, isWritable:
|
|
2026
|
+
return { pubkey: this.kaminoMarket.programId, isSigner: false, isWritable: false };
|
|
2027
2027
|
}
|
|
2028
2028
|
const referrerTokenStateAddress = referrerTokenStatePda(this.referrer, reserve, this.kaminoMarket.programId)[0];
|
|
2029
2029
|
return { pubkey: referrerTokenStateAddress, isSigner: false, isWritable: true };
|
|
@@ -2081,7 +2081,7 @@ export class KaminoAction {
|
|
|
2081
2081
|
const borrowReservesReferrerTokenStates = borrowReservesList
|
|
2082
2082
|
.map((reserve) => {
|
|
2083
2083
|
if (this.referrer.equals(PublicKey.default)) {
|
|
2084
|
-
return { pubkey: this.kaminoMarket.programId, isSigner: false, isWritable:
|
|
2084
|
+
return { pubkey: this.kaminoMarket.programId, isSigner: false, isWritable: false };
|
|
2085
2085
|
}
|
|
2086
2086
|
const reserveState = this.kaminoMarket.getReserveByAddress(reserve)!;
|
|
2087
2087
|
const referrerTokenStateAddress = referrerTokenStatePda(
|
package/src/classes/vault.ts
CHANGED
|
@@ -676,8 +676,8 @@ export class KaminoVaultClient {
|
|
|
676
676
|
const kaminoVault = new KaminoVault(vault.address, vaultState, vault.programId);
|
|
677
677
|
|
|
678
678
|
// if the vault has allocations withdraw otherwise wtihdraw from available ix
|
|
679
|
-
const vaultAllocation = vaultState.vaultAllocationStrategy.find(
|
|
680
|
-
|
|
679
|
+
const vaultAllocation = vaultState.vaultAllocationStrategy.find((allocation) =>
|
|
680
|
+
allocation.reserve.equals(PublicKey.default)
|
|
681
681
|
);
|
|
682
682
|
|
|
683
683
|
if (vaultAllocation) {
|
|
@@ -735,18 +735,25 @@ export class KaminoVaultClient {
|
|
|
735
735
|
},
|
|
736
736
|
]);
|
|
737
737
|
|
|
738
|
-
const
|
|
738
|
+
const shareLamportsToWithdraw = collToLamportsDecimal(shareAmount, vaultState.sharesMintDecimals.toNumber());
|
|
739
|
+
const tokensPerShare = await this.getTokensPerShareSingleVault(vault, slot);
|
|
740
|
+
const sharesPerToken = new Decimal(1).div(tokensPerShare);
|
|
741
|
+
const tokensToWithdraw = shareLamportsToWithdraw.mul(tokensPerShare);
|
|
739
742
|
let tokenLeftToWithdraw = tokensToWithdraw;
|
|
743
|
+
const availableTokens = new Decimal(vaultState.tokenAvailable.toString());
|
|
744
|
+
tokenLeftToWithdraw = tokenLeftToWithdraw.sub(availableTokens);
|
|
740
745
|
|
|
741
|
-
|
|
746
|
+
type ReserveWithTokensToWithdraw = { reserve: PublicKey; shares: Decimal };
|
|
742
747
|
|
|
743
|
-
const
|
|
744
|
-
|
|
745
|
-
amountToWithdraw.push(new Decimal(vaultState.tokenAvailable.toString()));
|
|
748
|
+
const reserveWithSharesAmountToWithdraw: ReserveWithTokensToWithdraw[] = [];
|
|
749
|
+
let isFirstWithdraw = true;
|
|
746
750
|
|
|
747
751
|
if (tokenLeftToWithdraw.lte(0)) {
|
|
748
752
|
// Availabe enough to withdraw all - using first reserve as it does not matter
|
|
749
|
-
|
|
753
|
+
reserveWithSharesAmountToWithdraw.push({
|
|
754
|
+
reserve: vaultState.vaultAllocationStrategy[0].reserve,
|
|
755
|
+
shares: shareLamportsToWithdraw,
|
|
756
|
+
});
|
|
750
757
|
} else {
|
|
751
758
|
// Get decreasing order sorted available liquidity to withdraw from each reserve allocated to
|
|
752
759
|
const reserveAllocationAvailableLiquidityToWithdraw = await this.getReserveAllocationAvailableLiquidityToWithdraw(
|
|
@@ -755,15 +762,22 @@ export class KaminoVaultClient {
|
|
|
755
762
|
vaultReservesState
|
|
756
763
|
);
|
|
757
764
|
// sort
|
|
758
|
-
const reserveAllocationAvailableLiquidityToWithdrawSorted =
|
|
759
|
-
|
|
760
|
-
);
|
|
765
|
+
const reserveAllocationAvailableLiquidityToWithdrawSorted = [
|
|
766
|
+
...reserveAllocationAvailableLiquidityToWithdraw.entries(),
|
|
767
|
+
].sort((a, b) => b[1].sub(a[1]).toNumber());
|
|
761
768
|
|
|
762
|
-
reserveAllocationAvailableLiquidityToWithdrawSorted.forEach((availableLiquidityToWithdraw,
|
|
769
|
+
reserveAllocationAvailableLiquidityToWithdrawSorted.forEach(([key, availableLiquidityToWithdraw], _) => {
|
|
763
770
|
if (tokenLeftToWithdraw.gt(0)) {
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
771
|
+
let tokensToWithdrawFromReserve = Decimal.min(tokenLeftToWithdraw, availableLiquidityToWithdraw);
|
|
772
|
+
if (isFirstWithdraw) {
|
|
773
|
+
tokensToWithdrawFromReserve = tokensToWithdrawFromReserve.add(availableTokens);
|
|
774
|
+
isFirstWithdraw = false;
|
|
775
|
+
}
|
|
776
|
+
// round up to the nearest integer the shares to withdraw
|
|
777
|
+
const sharesToWithdrawFromReserve = tokensToWithdrawFromReserve.mul(sharesPerToken).ceil();
|
|
778
|
+
reserveWithSharesAmountToWithdraw.push({ reserve: key, shares: sharesToWithdrawFromReserve });
|
|
779
|
+
|
|
780
|
+
tokenLeftToWithdraw = tokenLeftToWithdraw.sub(tokensToWithdrawFromReserve);
|
|
767
781
|
}
|
|
768
782
|
});
|
|
769
783
|
}
|
|
@@ -771,26 +785,35 @@ export class KaminoVaultClient {
|
|
|
771
785
|
const withdrawIxns: TransactionInstruction[] = [];
|
|
772
786
|
withdrawIxns.push(createAtaIx);
|
|
773
787
|
|
|
774
|
-
|
|
775
|
-
|
|
788
|
+
// let sharesLeftToWithdraw = shareAmount;
|
|
789
|
+
for (let reserveIndex = 0; reserveIndex < reserveWithSharesAmountToWithdraw.length; reserveIndex++) {
|
|
790
|
+
const reserveWithTokens = reserveWithSharesAmountToWithdraw[reserveIndex];
|
|
791
|
+
const reserveState = vaultReservesState.get(reserveWithTokens.reserve);
|
|
776
792
|
if (reserveState === undefined) {
|
|
777
|
-
throw new Error(`Reserve ${reserve.toBase58()} not found in vault reserves map`);
|
|
793
|
+
throw new Error(`Reserve ${reserveWithTokens.reserve.toBase58()} not found in vault reserves map`);
|
|
778
794
|
}
|
|
779
|
-
|
|
780
795
|
const marketAddress = reserveState.state.lendingMarket;
|
|
796
|
+
|
|
797
|
+
const isLastWithdraw = reserveIndex === reserveWithSharesAmountToWithdraw.length - 1;
|
|
798
|
+
// if it is not last withdraw it means that we can pass all shares as we are withdrawing everything from that reserve
|
|
799
|
+
let sharesToWithdraw = shareAmount;
|
|
800
|
+
if (isLastWithdraw) {
|
|
801
|
+
sharesToWithdraw = reserveWithTokens.shares;
|
|
802
|
+
}
|
|
803
|
+
|
|
781
804
|
const withdrawFromReserveIx = this.withdrawIxn(
|
|
782
805
|
user,
|
|
783
806
|
vault,
|
|
784
807
|
vaultState,
|
|
785
808
|
marketAddress,
|
|
786
|
-
{ address: reserve, state: reserveState.state },
|
|
809
|
+
{ address: reserveWithTokens.reserve, state: reserveState.state },
|
|
787
810
|
userSharesAta,
|
|
788
811
|
userTokenAta,
|
|
789
|
-
|
|
812
|
+
sharesToWithdraw,
|
|
790
813
|
vaultReservesState
|
|
791
814
|
);
|
|
792
815
|
withdrawIxns.push(withdrawFromReserveIx);
|
|
793
|
-
}
|
|
816
|
+
}
|
|
794
817
|
|
|
795
818
|
return withdrawIxns;
|
|
796
819
|
}
|
|
@@ -1484,18 +1507,23 @@ export class KaminoVaultClient {
|
|
|
1484
1507
|
|
|
1485
1508
|
const reserveAllocationAvailableLiquidityToWithdraw = new PubkeyHashMap<PublicKey, Decimal>();
|
|
1486
1509
|
vaultState.vaultAllocationStrategy.forEach((allocationStrategy) => {
|
|
1510
|
+
if (allocationStrategy.reserve.equals(PublicKey.default)) {
|
|
1511
|
+
return;
|
|
1512
|
+
}
|
|
1487
1513
|
const reserve = reserves.get(allocationStrategy.reserve);
|
|
1488
1514
|
if (reserve === undefined) {
|
|
1489
1515
|
throw new Error(`Reserve ${allocationStrategy.reserve.toBase58()} not found`);
|
|
1490
1516
|
}
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1517
|
+
let referralFeeBps = 0;
|
|
1518
|
+
const denominator = reserve.state.config.protocolTakeRatePct / 100;
|
|
1519
|
+
if (denominator > 0) {
|
|
1520
|
+
referralFeeBps = new Fraction(reserve.state.liquidity.absoluteReferralRateSf)
|
|
1494
1521
|
.toDecimal()
|
|
1495
|
-
.div(
|
|
1522
|
+
.div(denominator)
|
|
1496
1523
|
.floor()
|
|
1497
|
-
.toNumber()
|
|
1498
|
-
|
|
1524
|
+
.toNumber();
|
|
1525
|
+
}
|
|
1526
|
+
const reserveCollExchangeRate = reserve.getEstimatedCollateralExchangeRate(slot, referralFeeBps);
|
|
1499
1527
|
const reserveAllocationLiquidityAmount = new Decimal(allocationStrategy.ctokenAllocation.toString()).div(
|
|
1500
1528
|
reserveCollExchangeRate
|
|
1501
1529
|
);
|
|
@@ -649,7 +649,7 @@ async function main() {
|
|
|
649
649
|
const kaminoVault = new KaminoVault(vaultAddress, undefined, env.kVaultProgramId);
|
|
650
650
|
const instructions = await kaminoManager.depositToVaultIxs(env.payer.publicKey, kaminoVault, amount);
|
|
651
651
|
|
|
652
|
-
const depositSig = await processTxn(env.client, env.payer, instructions, mode, 2500, []);
|
|
652
|
+
const depositSig = await processTxn(env.client, env.payer, instructions, mode, 2500, [], 800_000);
|
|
653
653
|
|
|
654
654
|
mode === 'execute' && console.log('User deposit:', depositSig);
|
|
655
655
|
});
|
|
@@ -675,14 +675,14 @@ async function main() {
|
|
|
675
675
|
const kaminoManager = new KaminoManager(env.connection, env.kLendProgramId, env.kVaultProgramId);
|
|
676
676
|
|
|
677
677
|
const kaminoVault = new KaminoVault(vaultAddress, undefined, env.kVaultProgramId);
|
|
678
|
-
const
|
|
678
|
+
const withdrawIxs = await kaminoManager.withdrawFromVaultIxs(
|
|
679
679
|
env.payer.publicKey,
|
|
680
680
|
kaminoVault,
|
|
681
681
|
new Decimal(amount),
|
|
682
682
|
await env.connection.getSlot('confirmed')
|
|
683
683
|
);
|
|
684
684
|
|
|
685
|
-
const depositSig = await processTxn(env.client, env.payer,
|
|
685
|
+
const depositSig = await processTxn(env.client, env.payer, withdrawIxs, mode, 2500, [], 800_000);
|
|
686
686
|
|
|
687
687
|
mode === 'execute' && console.log('User withdraw:', depositSig);
|
|
688
688
|
});
|
|
@@ -754,7 +754,7 @@ async function main() {
|
|
|
754
754
|
kaminoVault,
|
|
755
755
|
reserveWithAddress
|
|
756
756
|
);
|
|
757
|
-
const investReserveSig = await processTxn(env.client, env.payer, instructions, mode, 2500, [],
|
|
757
|
+
const investReserveSig = await processTxn(env.client, env.payer, instructions, mode, 2500, [], 400_000);
|
|
758
758
|
|
|
759
759
|
mode === 'execute' && console.log('Reserve invested:', investReserveSig);
|
|
760
760
|
});
|
|
@@ -926,6 +926,17 @@ async function main() {
|
|
|
926
926
|
console.log('all vaults', allVaults);
|
|
927
927
|
});
|
|
928
928
|
|
|
929
|
+
commands.command('get-all-vaults-pks').action(async () => {
|
|
930
|
+
const env = initializeClient(false, false);
|
|
931
|
+
const kaminoManager = new KaminoManager(env.connection, env.kLendProgramId, env.kVaultProgramId);
|
|
932
|
+
|
|
933
|
+
const allVaults = await kaminoManager.getAllVaults();
|
|
934
|
+
console.log(
|
|
935
|
+
'all vaults',
|
|
936
|
+
allVaults.map((vault) => vault.address.toBase58())
|
|
937
|
+
);
|
|
938
|
+
});
|
|
939
|
+
|
|
929
940
|
commands
|
|
930
941
|
.command('get-simulated-interest-and-fees')
|
|
931
942
|
.requiredOption('--vault <string>', 'Vault address')
|
|
@@ -231,7 +231,7 @@ export class VaultState {
|
|
|
231
231
|
}
|
|
232
232
|
|
|
233
233
|
static decode(data: Buffer): VaultState {
|
|
234
|
-
if (!data.slice(0, 8)
|
|
234
|
+
if (!VaultState.discriminator.equals(data.slice(0, 8))) {
|
|
235
235
|
throw new Error("invalid account discriminator")
|
|
236
236
|
}
|
|
237
237
|
|