@kamino-finance/klend-sdk 5.13.1 → 5.13.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/classes/action.d.ts +32 -31
- package/dist/classes/action.d.ts.map +1 -1
- package/dist/classes/action.js +126 -95
- package/dist/classes/action.js.map +1 -1
- package/dist/classes/index.d.ts +3 -2
- package/dist/classes/index.d.ts.map +1 -1
- package/dist/classes/index.js +3 -2
- package/dist/classes/index.js.map +1 -1
- package/dist/classes/manager.d.ts +7 -7
- package/dist/classes/manager.d.ts.map +1 -1
- package/dist/classes/manager.js +46 -46
- package/dist/classes/manager.js.map +1 -1
- package/dist/classes/obligationOrder.d.ts +1 -1
- package/dist/classes/obligationOrder.d.ts.map +1 -1
- package/dist/classes/reserve.d.ts +2 -2
- package/dist/classes/reserve.d.ts.map +1 -1
- package/dist/classes/reserve.js +70 -70
- package/dist/classes/reserve.js.map +1 -1
- package/dist/classes/shared.d.ts +13 -0
- package/dist/classes/shared.d.ts.map +1 -1
- package/dist/classes/utils.d.ts +1 -9
- package/dist/classes/utils.d.ts.map +1 -1
- package/dist/classes/utils.js +4 -51
- package/dist/classes/utils.js.map +1 -1
- package/dist/classes/vault.d.ts +5 -3
- package/dist/classes/vault.d.ts.map +1 -1
- package/dist/classes/vault.js +50 -41
- package/dist/classes/vault.js.map +1 -1
- package/dist/classes/{types.d.ts → vault_types.d.ts} +2 -15
- package/dist/classes/vault_types.d.ts.map +1 -0
- package/dist/classes/{types.js → vault_types.js} +1 -1
- package/dist/classes/vault_types.js.map +1 -0
- package/dist/client_kamino_manager.d.ts.map +1 -1
- package/dist/client_kamino_manager.js +25 -26
- package/dist/client_kamino_manager.js.map +1 -1
- package/dist/lending_operations/repay_with_collateral_operations.js +6 -6
- package/dist/lending_operations/repay_with_collateral_operations.js.map +1 -1
- package/dist/lending_operations/swap_collateral_operations.d.ts +6 -6
- package/dist/lending_operations/swap_collateral_operations.d.ts.map +1 -1
- package/dist/lending_operations/swap_collateral_operations.js +61 -61
- package/dist/lending_operations/swap_collateral_operations.js.map +1 -1
- package/dist/leverage/calcs.d.ts +0 -1
- package/dist/leverage/calcs.d.ts.map +1 -1
- package/dist/leverage/calcs.js +5 -8
- package/dist/leverage/calcs.js.map +1 -1
- package/dist/leverage/operations.d.ts +5 -5
- package/dist/leverage/operations.d.ts.map +1 -1
- package/dist/leverage/operations.js +73 -73
- package/dist/leverage/operations.js.map +1 -1
- package/dist/leverage/types.d.ts +1 -1
- package/dist/leverage/types.d.ts.map +1 -1
- package/dist/leverage/utils.d.ts +2 -2
- package/dist/leverage/utils.d.ts.map +1 -1
- package/dist/leverage/utils.js +5 -5
- package/dist/leverage/utils.js.map +1 -1
- package/dist/referrals/instructions.d.ts +3 -3
- package/dist/referrals/instructions.d.ts.map +1 -1
- package/dist/referrals/instructions.js +10 -10
- package/dist/referrals/instructions.js.map +1 -1
- package/dist/referrals/operations.js +6 -6
- package/dist/referrals/operations.js.map +1 -1
- package/dist/utils/ata.d.ts +3 -3
- package/dist/utils/ata.d.ts.map +1 -1
- package/dist/utils/ata.js +22 -22
- package/dist/utils/ata.js.map +1 -1
- package/dist/utils/instruction.d.ts +2 -2
- package/dist/utils/instruction.d.ts.map +1 -1
- package/dist/utils/instruction.js +12 -12
- package/dist/utils/instruction.js.map +1 -1
- package/dist/utils/lookupTable.js +6 -6
- package/dist/utils/lookupTable.js.map +1 -1
- package/dist/utils/userMetadata.d.ts +1 -1
- package/dist/utils/userMetadata.d.ts.map +1 -1
- package/dist/utils/userMetadata.js +3 -3
- package/dist/utils/userMetadata.js.map +1 -1
- package/package.json +1 -1
- package/src/classes/action.ts +143 -102
- package/src/classes/index.ts +5 -2
- package/src/classes/manager.ts +54 -51
- package/src/classes/obligationOrder.ts +1 -1
- package/src/classes/reserve.ts +126 -132
- package/src/classes/shared.ts +15 -0
- package/src/classes/utils.ts +3 -52
- package/src/classes/vault.ts +53 -42
- package/src/classes/{types.ts → vault_types.ts} +1 -16
- package/src/client.ts +16 -16
- package/src/client_kamino_manager.ts +25 -25
- package/src/lending_operations/repay_with_collateral_operations.ts +13 -13
- package/src/lending_operations/swap_collateral_operations.ts +85 -85
- package/src/leverage/calcs.ts +2 -6
- package/src/leverage/operations.ts +84 -84
- package/src/leverage/types.ts +1 -1
- package/src/leverage/utils.ts +5 -5
- package/src/referrals/instructions.ts +6 -6
- package/src/referrals/operations.ts +9 -9
- package/src/utils/ata.ts +18 -18
- package/src/utils/instruction.ts +10 -10
- package/src/utils/lookupTable.ts +6 -6
- package/src/utils/userMetadata.ts +1 -1
- package/dist/classes/types.d.ts.map +0 -1
- package/dist/classes/types.js.map +0 -1
- package/dist/classes/types_utils.d.ts +0 -14
- package/dist/classes/types_utils.d.ts.map +0 -1
- package/dist/classes/types_utils.js +0 -50
- package/dist/classes/types_utils.js.map +0 -1
- package/src/classes/types_utils.ts +0 -49
|
@@ -7,13 +7,13 @@ import {
|
|
|
7
7
|
SwapIxsProvider,
|
|
8
8
|
SwapQuoteProvider,
|
|
9
9
|
getScopeRefreshIx,
|
|
10
|
-
|
|
10
|
+
LeverageIxsOutput,
|
|
11
11
|
FlashLoanInfo,
|
|
12
12
|
} from '../leverage';
|
|
13
13
|
import {
|
|
14
14
|
createAtasIdempotent,
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
getComputeBudgetAndPriorityFeeIxs,
|
|
16
|
+
removeBudgetAndAtaIxs,
|
|
17
17
|
ScopePriceRefreshConfig,
|
|
18
18
|
U64_MAX,
|
|
19
19
|
uniqueAccountsWithProgramIds,
|
|
@@ -128,7 +128,7 @@ export async function getRepayWithCollSwapInputs<QuoteResponse>({
|
|
|
128
128
|
const inputAmountLamports = Decimal.min(withdrawableCollLamports, maxCollNeededFromOracle);
|
|
129
129
|
|
|
130
130
|
// Build the repay & withdraw collateral tx to get the number of accounts
|
|
131
|
-
const klendIxs:
|
|
131
|
+
const klendIxs: LeverageIxsOutput = await buildRepayWithCollateralIxs(
|
|
132
132
|
kaminoMarket,
|
|
133
133
|
debtReserve,
|
|
134
134
|
collReserve,
|
|
@@ -256,7 +256,7 @@ export async function getRepayWithCollIxs<QuoteResponse>({
|
|
|
256
256
|
);
|
|
257
257
|
|
|
258
258
|
const swapResponse = await swapper(swapInputs, initialInputs.klendAccounts, swapQuote);
|
|
259
|
-
const ixs:
|
|
259
|
+
const ixs: LeverageIxsOutput = await buildRepayWithCollateralIxs(
|
|
260
260
|
kaminoMarket,
|
|
261
261
|
debtReserve,
|
|
262
262
|
collReserve,
|
|
@@ -295,9 +295,9 @@ async function buildRepayWithCollateralIxs(
|
|
|
295
295
|
debtRepayAmountLamports: Decimal,
|
|
296
296
|
collWithdrawLamports: Decimal,
|
|
297
297
|
useV2Ixs: boolean
|
|
298
|
-
): Promise<
|
|
298
|
+
): Promise<LeverageIxsOutput> {
|
|
299
299
|
// 1. Create atas & budget txns
|
|
300
|
-
const
|
|
300
|
+
const budgetIxs = budgetAndPriorityFeeIxs || getComputeBudgetAndPriorityFeeIxs(1_400_000);
|
|
301
301
|
|
|
302
302
|
const atas = [
|
|
303
303
|
{ mint: collReserve.getLiquidityMint(), tokenProgram: collReserve.getLiquidityTokenProgram() },
|
|
@@ -311,7 +311,7 @@ async function buildRepayWithCollateralIxs(
|
|
|
311
311
|
|
|
312
312
|
// 2. Flash borrow & repay the debt to repay amount needed
|
|
313
313
|
const { flashBorrowIxn, flashRepayIxn } = getFlashLoanInstructions({
|
|
314
|
-
borrowIxnIndex:
|
|
314
|
+
borrowIxnIndex: budgetIxs.length + atasAndIxs.length + (scopeRefreshIxn.length > 0 ? 1 : 0),
|
|
315
315
|
walletPublicKey: obligation.state.owner,
|
|
316
316
|
lendingMarketAuthority: market.getLendingMarketAuthority(),
|
|
317
317
|
lendingMarketAddress: market.getAddress(),
|
|
@@ -369,11 +369,11 @@ async function buildRepayWithCollateralIxs(
|
|
|
369
369
|
|
|
370
370
|
// 4. Swap collateral to debt to repay flash loan
|
|
371
371
|
const { preActionIxs, swapIxs } = swapQuoteIxs;
|
|
372
|
-
const swapInstructions =
|
|
372
|
+
const swapInstructions = removeBudgetAndAtaIxs(swapIxs, []);
|
|
373
373
|
|
|
374
|
-
const
|
|
374
|
+
const ixs = [
|
|
375
375
|
...scopeRefreshIxn,
|
|
376
|
-
...
|
|
376
|
+
...budgetIxs,
|
|
377
377
|
...atasAndIxs.map((x) => x.createAtaIx),
|
|
378
378
|
flashBorrowIxn,
|
|
379
379
|
...preActionIxs,
|
|
@@ -382,12 +382,12 @@ async function buildRepayWithCollateralIxs(
|
|
|
382
382
|
flashRepayIxn,
|
|
383
383
|
];
|
|
384
384
|
|
|
385
|
-
const res:
|
|
385
|
+
const res: LeverageIxsOutput = {
|
|
386
386
|
flashLoanInfo: {
|
|
387
387
|
flashBorrowReserve: debtReserve.address,
|
|
388
388
|
flashLoanFee: debtReserve.getFlashLoanFee(),
|
|
389
389
|
},
|
|
390
|
-
instructions:
|
|
390
|
+
instructions: ixs,
|
|
391
391
|
};
|
|
392
392
|
|
|
393
393
|
return res;
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
createAtasIdempotent,
|
|
18
18
|
DEFAULT_MAX_COMPUTE_UNITS,
|
|
19
19
|
getAssociatedTokenAddress,
|
|
20
|
-
|
|
20
|
+
getComputeBudgetAndPriorityFeeIxs,
|
|
21
21
|
PublicKeySet,
|
|
22
22
|
ScopePriceRefreshConfig,
|
|
23
23
|
U64_MAX,
|
|
@@ -28,9 +28,9 @@ import Decimal from 'decimal.js';
|
|
|
28
28
|
import { createCloseAccountInstruction, NATIVE_MINT, TOKEN_PROGRAM_ID } from '@solana/spl-token';
|
|
29
29
|
|
|
30
30
|
/**
|
|
31
|
-
* Inputs to the `
|
|
31
|
+
* Inputs to the `getSwapCollIxs()` operation.
|
|
32
32
|
*/
|
|
33
|
-
export interface
|
|
33
|
+
export interface SwapCollIxsInputs<QuoteResponse> {
|
|
34
34
|
/**
|
|
35
35
|
* The amount of source collateral to be swapped-in for the target collateral.
|
|
36
36
|
* This value will be treated exactly (i.e. slippage is not applied here) and thus must not exceed the collateral's
|
|
@@ -66,7 +66,7 @@ export interface SwapCollIxnsInputs<QuoteResponse> {
|
|
|
66
66
|
obligation: KaminoObligation;
|
|
67
67
|
referrer: PublicKey;
|
|
68
68
|
currentSlot: number;
|
|
69
|
-
|
|
69
|
+
budgetAndPriorityFeeIxs?: TransactionInstruction[];
|
|
70
70
|
scopeRefreshConfig?: ScopePriceRefreshConfig;
|
|
71
71
|
useV2Ixs: boolean;
|
|
72
72
|
quoter: SwapQuoteProvider<QuoteResponse>;
|
|
@@ -75,9 +75,9 @@ export interface SwapCollIxnsInputs<QuoteResponse> {
|
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
/**
|
|
78
|
-
* Outputs from the `
|
|
78
|
+
* Outputs from the `getSwapCollIxs()` operation.
|
|
79
79
|
*/
|
|
80
|
-
export interface
|
|
80
|
+
export interface SwapCollIxsOutputs<QuoteResponse> {
|
|
81
81
|
/**
|
|
82
82
|
* Instructions for on-chain execution.
|
|
83
83
|
*/
|
|
@@ -143,12 +143,12 @@ export interface SwapCollIxnsOutputs<QuoteResponse> {
|
|
|
143
143
|
/**
|
|
144
144
|
* Constructs instructions needed to partially/fully swap the given source collateral for some other collateral type.
|
|
145
145
|
*/
|
|
146
|
-
export async function
|
|
147
|
-
inputs:
|
|
148
|
-
): Promise<
|
|
146
|
+
export async function getSwapCollIxs<QuoteResponse>(
|
|
147
|
+
inputs: SwapCollIxsInputs<QuoteResponse>
|
|
148
|
+
): Promise<SwapCollIxsOutputs<QuoteResponse>> {
|
|
149
149
|
const [args, context] = extractArgsAndContext(inputs);
|
|
150
150
|
|
|
151
|
-
// Conceptually, we need to construct the following
|
|
151
|
+
// Conceptually, we need to construct the following ixs:
|
|
152
152
|
// 0. any set-up, like budgeting and ATAs
|
|
153
153
|
// 1. `flash-borrowed target coll = targetCollReserve.flashBorrow()`
|
|
154
154
|
// 2. `targetCollReserve.deposit(flash-borrowed target coll)`
|
|
@@ -157,38 +157,38 @@ export async function getSwapCollIxns<QuoteResponse>(
|
|
|
157
157
|
// 5. `flashRepay(externally-swapped target coll)`
|
|
158
158
|
// However, there is a cyclic dependency:
|
|
159
159
|
// - To construct 4. (specifically, to query the external swap quote), we need to know all accounts used by Kamino's
|
|
160
|
-
// own
|
|
160
|
+
// own ixs.
|
|
161
161
|
// - To construct 1. (i.e. flash-borrow), we need to know the target collateral swap-out from 4.
|
|
162
162
|
|
|
163
|
-
// Construct the Klend's own
|
|
164
|
-
const
|
|
165
|
-
const klendAccounts = uniqueAccountsWithProgramIds(
|
|
163
|
+
// Construct the Klend's own ixs with a fake swap-out (only to learn the klend accounts used):
|
|
164
|
+
const fakeKlendIxs = await getKlendIxs(args, FAKE_TARGET_COLL_SWAP_OUT_AMOUNT, context);
|
|
165
|
+
const klendAccounts = uniqueAccountsWithProgramIds(listIxs(fakeKlendIxs));
|
|
166
166
|
|
|
167
|
-
// Construct the external swap
|
|
168
|
-
const
|
|
167
|
+
// Construct the external swap ixs (and learn the actual swap-out amount):
|
|
168
|
+
const externalSwapIxs = await getExternalSwapIxs(args, klendAccounts, context);
|
|
169
169
|
|
|
170
170
|
// We now have the full information needed to simulate the end-state, so let's check that the operation is legal:
|
|
171
171
|
context.logger(
|
|
172
|
-
`Expected to swap ${args.sourceCollSwapAmount} ${context.sourceCollReserve.symbol} collateral into ${
|
|
172
|
+
`Expected to swap ${args.sourceCollSwapAmount} ${context.sourceCollReserve.symbol} collateral into ${externalSwapIxs.swapOutAmount} ${context.targetCollReserve.symbol} collateral`
|
|
173
173
|
);
|
|
174
|
-
checkResultingObligationValid(args,
|
|
174
|
+
checkResultingObligationValid(args, externalSwapIxs.swapOutAmount, context);
|
|
175
175
|
|
|
176
|
-
// Construct the Klend's own
|
|
177
|
-
const
|
|
176
|
+
// Construct the Klend's own ixs with an actual swap-out amount:
|
|
177
|
+
const klendIxs = await getKlendIxs(args, externalSwapIxs.swapOutAmount, context);
|
|
178
178
|
|
|
179
179
|
return {
|
|
180
|
-
ixs:
|
|
181
|
-
lookupTables:
|
|
180
|
+
ixs: listIxs(klendIxs, externalSwapIxs.ixs),
|
|
181
|
+
lookupTables: externalSwapIxs.luts,
|
|
182
182
|
useV2Ixs: context.useV2Ixs,
|
|
183
183
|
simulationDetails: {
|
|
184
184
|
flashLoan: {
|
|
185
|
-
targetCollFlashBorrowedAmount:
|
|
186
|
-
targetCollFlashRepaidAmount:
|
|
185
|
+
targetCollFlashBorrowedAmount: klendIxs.simulationDetails.targetCollFlashBorrowedAmount,
|
|
186
|
+
targetCollFlashRepaidAmount: externalSwapIxs.swapOutAmount,
|
|
187
187
|
},
|
|
188
188
|
externalSwap: {
|
|
189
189
|
sourceCollSwapInAmount: args.sourceCollSwapAmount, // repeated `/inputs.sourceCollSwapAmount`, only for clarity
|
|
190
|
-
targetCollSwapOutAmount:
|
|
191
|
-
quoteResponse:
|
|
190
|
+
targetCollSwapOutAmount: externalSwapIxs.swapOutAmount, // repeated `../flashLoan.targetCollFlashRepaidAmount`, only for clarity
|
|
191
|
+
quoteResponse: externalSwapIxs.simulationDetails.quoteResponse,
|
|
192
192
|
},
|
|
193
193
|
},
|
|
194
194
|
};
|
|
@@ -201,7 +201,7 @@ type SwapCollArgs = {
|
|
|
201
201
|
};
|
|
202
202
|
|
|
203
203
|
type SwapCollContext<QuoteResponse> = {
|
|
204
|
-
|
|
204
|
+
budgetAndPriorityFeeIxs: TransactionInstruction[];
|
|
205
205
|
market: KaminoMarket;
|
|
206
206
|
sourceCollReserve: KaminoReserve;
|
|
207
207
|
targetCollReserve: KaminoReserve;
|
|
@@ -216,7 +216,7 @@ type SwapCollContext<QuoteResponse> = {
|
|
|
216
216
|
};
|
|
217
217
|
|
|
218
218
|
function extractArgsAndContext<QuoteResponse>(
|
|
219
|
-
inputs:
|
|
219
|
+
inputs: SwapCollIxsInputs<QuoteResponse>
|
|
220
220
|
): [SwapCollArgs, SwapCollContext<QuoteResponse>] {
|
|
221
221
|
if (inputs.sourceCollTokenMint.equals(inputs.targetCollTokenMint)) {
|
|
222
222
|
throw new Error(`Cannot swap from/to the same collateral`);
|
|
@@ -231,8 +231,8 @@ function extractArgsAndContext<QuoteResponse>(
|
|
|
231
231
|
newElevationGroup: inputs.market.getExistingElevationGroup(inputs.newElevationGroup, 'Newly-requested'),
|
|
232
232
|
},
|
|
233
233
|
{
|
|
234
|
-
|
|
235
|
-
inputs.
|
|
234
|
+
budgetAndPriorityFeeIxs:
|
|
235
|
+
inputs.budgetAndPriorityFeeIxs || getComputeBudgetAndPriorityFeeIxs(DEFAULT_MAX_COMPUTE_UNITS),
|
|
236
236
|
sourceCollReserve: inputs.market.getExistingReserveByMint(inputs.sourceCollTokenMint, 'Current collateral'),
|
|
237
237
|
targetCollReserve: inputs.market.getExistingReserveByMint(inputs.targetCollTokenMint, 'Target collateral'),
|
|
238
238
|
logger: console.log,
|
|
@@ -248,28 +248,28 @@ function extractArgsAndContext<QuoteResponse>(
|
|
|
248
248
|
];
|
|
249
249
|
}
|
|
250
250
|
|
|
251
|
-
const FAKE_TARGET_COLL_SWAP_OUT_AMOUNT = new Decimal(1); // see the lengthy `
|
|
251
|
+
const FAKE_TARGET_COLL_SWAP_OUT_AMOUNT = new Decimal(1); // see the lengthy `getSwapCollIxs()` impl comment
|
|
252
252
|
|
|
253
|
-
type
|
|
254
|
-
|
|
253
|
+
type SwapCollKlendIxs = {
|
|
254
|
+
setupIxs: TransactionInstruction[];
|
|
255
255
|
targetCollFlashBorrowIxn: TransactionInstruction;
|
|
256
|
-
|
|
257
|
-
|
|
256
|
+
depositTargetCollIxs: TransactionInstruction[];
|
|
257
|
+
withdrawSourceCollIxs: TransactionInstruction[];
|
|
258
258
|
targetCollFlashRepayIxn: TransactionInstruction;
|
|
259
|
-
|
|
259
|
+
cleanupIxs: TransactionInstruction[];
|
|
260
260
|
flashLoanInfo: FlashLoanInfo;
|
|
261
261
|
simulationDetails: {
|
|
262
262
|
targetCollFlashBorrowedAmount: Decimal;
|
|
263
263
|
};
|
|
264
264
|
};
|
|
265
265
|
|
|
266
|
-
async function
|
|
266
|
+
async function getKlendIxs(
|
|
267
267
|
args: SwapCollArgs,
|
|
268
268
|
targetCollSwapOutAmount: Decimal,
|
|
269
269
|
context: SwapCollContext<any>
|
|
270
|
-
): Promise<
|
|
271
|
-
const {
|
|
272
|
-
const
|
|
270
|
+
): Promise<SwapCollKlendIxs> {
|
|
271
|
+
const { ataCreationIxs, targetCollAta } = getAtaCreationIxs(context);
|
|
272
|
+
const setupIxs = [...context.budgetAndPriorityFeeIxs, ...ataCreationIxs];
|
|
273
273
|
|
|
274
274
|
const scopeRefreshIxn = await getScopeRefreshIx(
|
|
275
275
|
context.market,
|
|
@@ -280,37 +280,37 @@ async function getKlendIxns(
|
|
|
280
280
|
);
|
|
281
281
|
|
|
282
282
|
if (scopeRefreshIxn) {
|
|
283
|
-
|
|
283
|
+
setupIxs.unshift(...scopeRefreshIxn);
|
|
284
284
|
}
|
|
285
285
|
|
|
286
286
|
const targetCollFlashBorrowedAmount = calculateTargetCollFlashBorrowedAmount(targetCollSwapOutAmount, context);
|
|
287
|
-
const { targetCollFlashBorrowIxn, targetCollFlashRepayIxn } =
|
|
287
|
+
const { targetCollFlashBorrowIxn, targetCollFlashRepayIxn } = getTargetCollFlashLoanIxs(
|
|
288
288
|
targetCollFlashBorrowedAmount,
|
|
289
|
-
|
|
289
|
+
setupIxs.length,
|
|
290
290
|
targetCollAta,
|
|
291
291
|
context
|
|
292
292
|
);
|
|
293
293
|
|
|
294
|
-
const
|
|
295
|
-
const
|
|
294
|
+
const depositTargetCollIxs = await getDepositTargetCollIxs(targetCollFlashBorrowedAmount, context);
|
|
295
|
+
const withdrawSourceCollIxs = await getWithdrawSourceCollIxs(
|
|
296
296
|
args,
|
|
297
|
-
|
|
297
|
+
depositTargetCollIxs.removesElevationGroup,
|
|
298
298
|
context
|
|
299
299
|
);
|
|
300
300
|
|
|
301
|
-
const
|
|
301
|
+
const cleanupIxs = getAtaCloseIxs(context);
|
|
302
302
|
|
|
303
303
|
return {
|
|
304
|
-
|
|
304
|
+
setupIxs,
|
|
305
305
|
flashLoanInfo: {
|
|
306
306
|
flashBorrowReserve: context.targetCollReserve.address,
|
|
307
307
|
flashLoanFee: context.targetCollReserve.getFlashLoanFee(),
|
|
308
308
|
},
|
|
309
309
|
targetCollFlashBorrowIxn,
|
|
310
|
-
|
|
311
|
-
|
|
310
|
+
depositTargetCollIxs: depositTargetCollIxs.ixs,
|
|
311
|
+
withdrawSourceCollIxs,
|
|
312
312
|
targetCollFlashRepayIxn,
|
|
313
|
-
|
|
313
|
+
cleanupIxs,
|
|
314
314
|
simulationDetails: {
|
|
315
315
|
targetCollFlashBorrowedAmount,
|
|
316
316
|
},
|
|
@@ -332,8 +332,8 @@ function calculateTargetCollFlashBorrowedAmount(
|
|
|
332
332
|
return targetCollFlashRepaidAmount.sub(targetCollFlashLoanFee);
|
|
333
333
|
}
|
|
334
334
|
|
|
335
|
-
function
|
|
336
|
-
const
|
|
335
|
+
function getAtaCreationIxs(context: SwapCollContext<any>) {
|
|
336
|
+
const atasAndAtaCreationIxs = createAtasIdempotent(context.obligation.state.owner, [
|
|
337
337
|
{
|
|
338
338
|
mint: context.sourceCollReserve.getLiquidityMint(),
|
|
339
339
|
tokenProgram: context.sourceCollReserve.getLiquidityTokenProgram(),
|
|
@@ -344,25 +344,25 @@ function getAtaCreationIxns(context: SwapCollContext<any>) {
|
|
|
344
344
|
},
|
|
345
345
|
]);
|
|
346
346
|
return {
|
|
347
|
-
|
|
348
|
-
targetCollAta:
|
|
347
|
+
ataCreationIxs: atasAndAtaCreationIxs.map((tuple) => tuple.createAtaIx),
|
|
348
|
+
targetCollAta: atasAndAtaCreationIxs[1].ata,
|
|
349
349
|
};
|
|
350
350
|
}
|
|
351
351
|
|
|
352
|
-
function
|
|
353
|
-
const
|
|
352
|
+
function getAtaCloseIxs(context: SwapCollContext<any>) {
|
|
353
|
+
const ataCloseIxs: TransactionInstruction[] = [];
|
|
354
354
|
if (
|
|
355
355
|
context.sourceCollReserve.getLiquidityMint().equals(NATIVE_MINT) ||
|
|
356
356
|
context.targetCollReserve.getLiquidityMint().equals(NATIVE_MINT)
|
|
357
357
|
) {
|
|
358
358
|
const owner = context.obligation.state.owner;
|
|
359
359
|
const wsolAta = getAssociatedTokenAddress(NATIVE_MINT, owner, false);
|
|
360
|
-
|
|
360
|
+
ataCloseIxs.push(createCloseAccountInstruction(wsolAta, owner, owner, [], TOKEN_PROGRAM_ID));
|
|
361
361
|
}
|
|
362
|
-
return
|
|
362
|
+
return ataCloseIxs;
|
|
363
363
|
}
|
|
364
364
|
|
|
365
|
-
function
|
|
365
|
+
function getTargetCollFlashLoanIxs(
|
|
366
366
|
targetCollAmount: Decimal,
|
|
367
367
|
flashBorrowIxnIndex: number,
|
|
368
368
|
destinationAta: PublicKey,
|
|
@@ -386,15 +386,15 @@ function getTargetCollFlashLoanIxns(
|
|
|
386
386
|
return { targetCollFlashBorrowIxn, targetCollFlashRepayIxn };
|
|
387
387
|
}
|
|
388
388
|
|
|
389
|
-
type
|
|
389
|
+
type DepositTargetCollIxs = {
|
|
390
390
|
removesElevationGroup: boolean;
|
|
391
|
-
|
|
391
|
+
ixs: TransactionInstruction[];
|
|
392
392
|
};
|
|
393
393
|
|
|
394
|
-
async function
|
|
394
|
+
async function getDepositTargetCollIxs(
|
|
395
395
|
targetCollAmount: Decimal,
|
|
396
396
|
context: SwapCollContext<any>
|
|
397
|
-
): Promise<
|
|
397
|
+
): Promise<DepositTargetCollIxs> {
|
|
398
398
|
const removesElevationGroup = mustRemoveElevationGroupBeforeDeposit(context);
|
|
399
399
|
const depositCollAction = await KaminoAction.buildDepositTxns(
|
|
400
400
|
context.market,
|
|
@@ -403,9 +403,9 @@ async function getDepositTargetCollIxns(
|
|
|
403
403
|
context.obligation.state.owner,
|
|
404
404
|
context.obligation,
|
|
405
405
|
context.useV2Ixs,
|
|
406
|
-
undefined, // we create the scope refresh
|
|
406
|
+
undefined, // we create the scope refresh ix outside of KaminoAction
|
|
407
407
|
0, // no extra compute budget
|
|
408
|
-
false, // we do not need ATA
|
|
408
|
+
false, // we do not need ATA ixs here (we construct and close them ourselves)
|
|
409
409
|
removesElevationGroup, // we may need to (temporarily) remove the elevation group; the same or a different one will be set on withdraw, if requested
|
|
410
410
|
{ skipInitialization: true, skipLutCreation: true }, // we are dealing with an existing obligation, no need to create user metadata
|
|
411
411
|
context.referrer,
|
|
@@ -413,7 +413,7 @@ async function getDepositTargetCollIxns(
|
|
|
413
413
|
removesElevationGroup ? 0 : undefined // only applicable when removing the group
|
|
414
414
|
);
|
|
415
415
|
return {
|
|
416
|
-
|
|
416
|
+
ixs: KaminoAction.actionToIxs(depositCollAction),
|
|
417
417
|
removesElevationGroup,
|
|
418
418
|
};
|
|
419
419
|
}
|
|
@@ -436,7 +436,7 @@ function mustRemoveElevationGroupBeforeDeposit(context: SwapCollContext<any>): b
|
|
|
436
436
|
return false; // the obligation has some elevation group and the new collateral can be added to it
|
|
437
437
|
}
|
|
438
438
|
|
|
439
|
-
async function
|
|
439
|
+
async function getWithdrawSourceCollIxs(
|
|
440
440
|
args: SwapCollArgs,
|
|
441
441
|
depositRemovedElevationGroup: boolean,
|
|
442
442
|
context: SwapCollContext<any>
|
|
@@ -452,9 +452,9 @@ async function getWithdrawSourceCollIxns(
|
|
|
452
452
|
context.obligation.state.owner,
|
|
453
453
|
context.obligation,
|
|
454
454
|
context.useV2Ixs,
|
|
455
|
-
undefined, // we create the scope refresh
|
|
455
|
+
undefined, // we create the scope refresh ix outside of KaminoAction
|
|
456
456
|
0, // no extra compute budget
|
|
457
|
-
false, // we do not need ATA
|
|
457
|
+
false, // we do not need ATA ixs here (we construct and close them ourselves)
|
|
458
458
|
requestedElevationGroup !== undefined, // the `elevationGroupIdToRequestAfterWithdraw()` has already decided on this
|
|
459
459
|
{ skipInitialization: true, skipLutCreation: true }, // we are dealing with an existing obligation, no need to create user metadata
|
|
460
460
|
context.referrer,
|
|
@@ -497,20 +497,20 @@ function elevationGroupIdToRequestAfterWithdraw(
|
|
|
497
497
|
}
|
|
498
498
|
}
|
|
499
499
|
|
|
500
|
-
type
|
|
500
|
+
type ExternalSwapIxs<QuoteResponse> = {
|
|
501
501
|
swapOutAmount: Decimal;
|
|
502
|
-
|
|
502
|
+
ixs: TransactionInstruction[];
|
|
503
503
|
luts: AddressLookupTableAccount[];
|
|
504
504
|
simulationDetails: {
|
|
505
505
|
quoteResponse?: QuoteResponse;
|
|
506
506
|
};
|
|
507
507
|
};
|
|
508
508
|
|
|
509
|
-
async function
|
|
509
|
+
async function getExternalSwapIxs<QuoteResponse>(
|
|
510
510
|
args: SwapCollArgs,
|
|
511
511
|
klendAccounts: PublicKey[],
|
|
512
512
|
context: SwapCollContext<QuoteResponse>
|
|
513
|
-
): Promise<
|
|
513
|
+
): Promise<ExternalSwapIxs<QuoteResponse>> {
|
|
514
514
|
const externalSwapInputs = {
|
|
515
515
|
inputAmountLamports: args.sourceCollSwapAmount.mul(context.sourceCollReserve.getMintFactor()),
|
|
516
516
|
inputMint: context.sourceCollReserve.getLiquidityMint(),
|
|
@@ -519,12 +519,12 @@ async function getExternalSwapIxns<QuoteResponse>(
|
|
|
519
519
|
};
|
|
520
520
|
const externalSwapQuote = await context.quoter(externalSwapInputs, klendAccounts);
|
|
521
521
|
const swapOutAmount = externalSwapQuote.priceAInB.mul(args.sourceCollSwapAmount);
|
|
522
|
-
const
|
|
522
|
+
const externalSwapIxsAndLuts = await context.swapper(externalSwapInputs, klendAccounts, externalSwapQuote);
|
|
523
523
|
// Note: we can ignore the returned `preActionIxs` field - we do not request any of them from the swapper.
|
|
524
524
|
return {
|
|
525
525
|
swapOutAmount,
|
|
526
|
-
|
|
527
|
-
luts:
|
|
526
|
+
ixs: externalSwapIxsAndLuts.swapIxs,
|
|
527
|
+
luts: externalSwapIxsAndLuts.lookupTables,
|
|
528
528
|
simulationDetails: {
|
|
529
529
|
quoteResponse: externalSwapQuote.quoteResponse,
|
|
530
530
|
},
|
|
@@ -606,14 +606,14 @@ function checkResultingObligationValid(
|
|
|
606
606
|
}
|
|
607
607
|
}
|
|
608
608
|
|
|
609
|
-
function
|
|
609
|
+
function listIxs(klendIxs: SwapCollKlendIxs, externalSwapIxs?: TransactionInstruction[]): TransactionInstruction[] {
|
|
610
610
|
return [
|
|
611
|
-
...
|
|
612
|
-
|
|
613
|
-
...
|
|
614
|
-
...
|
|
615
|
-
...(
|
|
616
|
-
|
|
617
|
-
...
|
|
611
|
+
...klendIxs.setupIxs,
|
|
612
|
+
klendIxs.targetCollFlashBorrowIxn,
|
|
613
|
+
...klendIxs.depositTargetCollIxs,
|
|
614
|
+
...klendIxs.withdrawSourceCollIxs,
|
|
615
|
+
...(externalSwapIxs || []),
|
|
616
|
+
klendIxs.targetCollFlashRepayIxn,
|
|
617
|
+
...klendIxs.cleanupIxs,
|
|
618
618
|
];
|
|
619
619
|
}
|
package/src/leverage/calcs.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { PublicKey } from '@solana/web3.js';
|
|
2
2
|
import Decimal from 'decimal.js';
|
|
3
3
|
import { collToLamportsDecimal, Kamino, StrategyWithAddress, TokenAmounts } from '@kamino-finance/kliquidity-sdk';
|
|
4
|
-
import { KaminoMarket, KaminoObligation, KaminoReserve } from '../classes';
|
|
4
|
+
import { KaminoMarket, KaminoObligation, KaminoReserve, toJson } from '../classes';
|
|
5
5
|
import { getExpectedTokenBalanceAfterBorrow } from './utils';
|
|
6
6
|
import {
|
|
7
7
|
AdjustLeverageCalcsResult,
|
|
@@ -11,10 +11,6 @@ import {
|
|
|
11
11
|
} from './types';
|
|
12
12
|
import { fuzzyEqual } from '../utils';
|
|
13
13
|
|
|
14
|
-
export const toJson = (object: any): string => {
|
|
15
|
-
return JSON.stringify(object, null, 2);
|
|
16
|
-
};
|
|
17
|
-
|
|
18
14
|
const closingPositionDiffTolerance = 0.0001;
|
|
19
15
|
|
|
20
16
|
export enum FormTabs {
|
|
@@ -683,7 +679,7 @@ export function withdrawLeverageCalcs(
|
|
|
683
679
|
.mul(irSlippageBpsForDebt.add('0.1').div('10_000').add('1'))
|
|
684
680
|
.toDecimalPlaces(debtReserve?.state.liquidity.mintDecimals.toNumber()!, Decimal.ROUND_CEIL);
|
|
685
681
|
|
|
686
|
-
// 6. Get swap
|
|
682
|
+
// 6. Get swap ixs
|
|
687
683
|
// 5. Get swap estimations to understand how much we need to borrow from borrow reserve
|
|
688
684
|
// prevent withdrawing more then deposited if we close position
|
|
689
685
|
const depositTokenWithdrawAmount = !isClosingPosition
|