@0dotxyz/p0-ts-sdk 2.2.0-alpha.5 → 2.2.0-alpha.7

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/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { PublicKey, SolanaJSONRPCError, ComputeBudgetProgram, SystemProgram, TransactionMessage, VersionedTransaction, Transaction, StakeProgram, Keypair, StakeAuthorizationLayout, AddressLookupTableAccount, SYSVAR_RENT_PUBKEY, TransactionInstruction, LAMPORTS_PER_SOL, SYSVAR_INSTRUCTIONS_PUBKEY, STAKE_CONFIG_ID as STAKE_CONFIG_ID$1 } from '@solana/web3.js';
1
+ import { PublicKey, SolanaJSONRPCError, ComputeBudgetProgram, SystemProgram, TransactionMessage, VersionedTransaction, Transaction, AddressLookupTableAccount, SYSVAR_RENT_PUBKEY, StakeProgram, TransactionInstruction, LAMPORTS_PER_SOL, Keypair, StakeAuthorizationLayout, SYSVAR_INSTRUCTIONS_PUBKEY, STAKE_CONFIG_ID as STAKE_CONFIG_ID$1 } from '@solana/web3.js';
2
2
  import { object, string, enums, array, assert } from 'superstruct';
3
3
  import BigNumber3, { BigNumber } from 'bignumber.js';
4
4
  import BN11, { BN } from 'bn.js';
@@ -91,10 +91,9 @@ function getConfig(environment = "production", overrides) {
91
91
 
92
92
  // src/errors/transaction-building.errors.ts
93
93
  var TransactionBuildingErrorCode = /* @__PURE__ */ ((TransactionBuildingErrorCode2) => {
94
- TransactionBuildingErrorCode2["JUPITER_SWAP_SIZE_EXCEEDED_REPAY"] = "JUPITER_SWAP_SIZE_EXCEEDED_REPAY";
95
- TransactionBuildingErrorCode2["JUPITER_SWAP_SIZE_EXCEEDED_LOOP"] = "JUPITER_SWAP_SIZE_EXCEEDED_LOOP";
96
94
  TransactionBuildingErrorCode2["SWAP_SIZE_EXCEEDED_LOOP"] = "SWAP_SIZE_EXCEEDED_LOOP";
97
95
  TransactionBuildingErrorCode2["SWAP_SIZE_EXCEEDED_REPAY"] = "SWAP_SIZE_EXCEEDED_REPAY";
96
+ TransactionBuildingErrorCode2["SWAP_SIZE_EXCEEDED_POSITION_SWAP"] = "SWAP_SIZE_EXCEEDED_POSITION_SWAP";
98
97
  TransactionBuildingErrorCode2["ORACLE_CRANK_FAILED"] = "ORACLE_CRANK_FAILED";
99
98
  TransactionBuildingErrorCode2["KAMINO_RESERVE_NOT_FOUND"] = "KAMINO_RESERVE_NOT_FOUND";
100
99
  TransactionBuildingErrorCode2["DRIFT_STATE_NOT_FOUND"] = "DRIFT_STATE_NOT_FOUND";
@@ -115,23 +114,6 @@ var TransactionBuildingError = class _TransactionBuildingError extends Error {
115
114
  Error.captureStackTrace(this, _TransactionBuildingError);
116
115
  }
117
116
  }
118
- /**
119
- * Jupiter swap instruction size exceeds available transaction size
120
- */
121
- static jupiterSwapSizeExceededLoop(bytes, accountKeys) {
122
- return new _TransactionBuildingError(
123
- "JUPITER_SWAP_SIZE_EXCEEDED_LOOP" /* JUPITER_SWAP_SIZE_EXCEEDED_LOOP */,
124
- "Jupiter swap instruction size exceeds available transaction size",
125
- { bytes, accountKeys }
126
- );
127
- }
128
- static jupiterSwapSizeExceededRepay(bytes, accountKeys) {
129
- return new _TransactionBuildingError(
130
- "JUPITER_SWAP_SIZE_EXCEEDED_REPAY" /* JUPITER_SWAP_SIZE_EXCEEDED_REPAY */,
131
- "Jupiter swap instruction size exceeds available transaction size",
132
- { bytes, accountKeys }
133
- );
134
- }
135
117
  static swapSizeExceededLoop(bytes, accountKeys, provider) {
136
118
  return new _TransactionBuildingError(
137
119
  "SWAP_SIZE_EXCEEDED_LOOP" /* SWAP_SIZE_EXCEEDED_LOOP */,
@@ -146,6 +128,13 @@ var TransactionBuildingError = class _TransactionBuildingError extends Error {
146
128
  { bytes, accountKeys, provider }
147
129
  );
148
130
  }
131
+ static swapSizeExceededPositionSwap(bytes, accountKeys, provider) {
132
+ return new _TransactionBuildingError(
133
+ "SWAP_SIZE_EXCEEDED_POSITION_SWAP" /* SWAP_SIZE_EXCEEDED_POSITION_SWAP */,
134
+ `${provider ?? "Swap"} instruction size exceeds available transaction size`,
135
+ { bytes, accountKeys, provider }
136
+ );
137
+ }
149
138
  /**
150
139
  * Failed to crank oracles for one or more banks
151
140
  */
@@ -44358,12 +44347,28 @@ var V1Client = class _V1Client {
44358
44347
  return new Promise((resolve, reject) => {
44359
44348
  const ws = new WebSocket(url, [SUBPROTOCOL]);
44360
44349
  ws.binaryType = "arraybuffer";
44361
- ws.on("open", () => {
44350
+ const onOpen = () => {
44351
+ ws.off("error", onError);
44352
+ ws.off("close", onClose);
44362
44353
  resolve(new _V1Client(ws));
44363
- });
44364
- ws.on("error", (err) => {
44354
+ };
44355
+ const onError = (err) => {
44356
+ ws.off("open", onOpen);
44357
+ ws.off("close", onClose);
44365
44358
  reject(err);
44366
- });
44359
+ };
44360
+ const onClose = (code, reason) => {
44361
+ ws.off("open", onOpen);
44362
+ ws.off("error", onError);
44363
+ reject(
44364
+ new Error(
44365
+ `WebSocket closed before open (code=${code}${reason.length ? `, reason=${reason.toString()}` : ""})`
44366
+ )
44367
+ );
44368
+ };
44369
+ ws.once("open", onOpen);
44370
+ ws.once("error", onError);
44371
+ ws.once("close", onClose);
44367
44372
  });
44368
44373
  }
44369
44374
  // --- Constructor ---
@@ -46903,6 +46908,444 @@ async function makeJuplendDepositTx(params) {
46903
46908
  });
46904
46909
  return solanaTx;
46905
46910
  }
46911
+ async function makeBeginFlashLoanIx3(program, marginfiAccountPk, endIndex, authority, isSync) {
46912
+ const ix = isSync && authority ? sync_instructions_default.makeBeginFlashLoanIx(
46913
+ program.programId,
46914
+ {
46915
+ marginfiAccount: marginfiAccountPk,
46916
+ authority
46917
+ },
46918
+ { endIndex: new BN11(endIndex) }
46919
+ ) : await instructions_default.makeBeginFlashLoanIx(
46920
+ program,
46921
+ {
46922
+ marginfiAccount: marginfiAccountPk,
46923
+ authority
46924
+ },
46925
+ { endIndex: new BN11(endIndex) }
46926
+ );
46927
+ return { instructions: [ix], keys: [] };
46928
+ }
46929
+ async function makeEndFlashLoanIx3(program, marginfiAccountPk, projectedActiveBanks, authority, isSync) {
46930
+ const remainingAccounts = computeHealthAccountMetas(projectedActiveBanks);
46931
+ const ix = isSync && authority ? sync_instructions_default.makeEndFlashLoanIx(
46932
+ program.programId,
46933
+ {
46934
+ marginfiAccount: marginfiAccountPk,
46935
+ authority
46936
+ },
46937
+ remainingAccounts.map((account) => ({
46938
+ pubkey: account,
46939
+ isSigner: false,
46940
+ isWritable: false
46941
+ }))
46942
+ ) : await instructions_default.makeEndFlashLoanIx(
46943
+ program,
46944
+ {
46945
+ marginfiAccount: marginfiAccountPk,
46946
+ authority
46947
+ },
46948
+ remainingAccounts.map((account) => ({
46949
+ pubkey: account,
46950
+ isSigner: false,
46951
+ isWritable: false
46952
+ }))
46953
+ );
46954
+ return { instructions: [ix], keys: [] };
46955
+ }
46956
+ async function makeFlashLoanTx({
46957
+ program,
46958
+ marginfiAccount,
46959
+ ixs,
46960
+ bankMap,
46961
+ blockhash,
46962
+ addressLookupTableAccounts,
46963
+ signers,
46964
+ isSync
46965
+ }) {
46966
+ const endIndex = ixs.length + 1;
46967
+ const projectedActiveBanksKeys = computeProjectedActiveBanksNoCpi(
46968
+ marginfiAccount.balances,
46969
+ ixs,
46970
+ program
46971
+ );
46972
+ const projectedActiveBanks = projectedActiveBanksKeys.map((account) => {
46973
+ const b = bankMap.get(account.toBase58());
46974
+ if (!b) throw Error(`Bank ${account.toBase58()} not found, in makeFlashLoanTx function`);
46975
+ return b;
46976
+ });
46977
+ const beginFlashLoanIx = await makeBeginFlashLoanIx3(
46978
+ program,
46979
+ marginfiAccount.address,
46980
+ endIndex,
46981
+ marginfiAccount.authority,
46982
+ isSync
46983
+ );
46984
+ const endFlashLoanIx = await makeEndFlashLoanIx3(
46985
+ program,
46986
+ marginfiAccount.address,
46987
+ projectedActiveBanks,
46988
+ marginfiAccount.authority,
46989
+ isSync
46990
+ );
46991
+ const message = new TransactionMessage({
46992
+ payerKey: marginfiAccount.authority,
46993
+ recentBlockhash: blockhash,
46994
+ instructions: [...beginFlashLoanIx.instructions, ...ixs, ...endFlashLoanIx.instructions]
46995
+ }).compileToV0Message(addressLookupTableAccounts);
46996
+ const tx = addTransactionMetadata(new VersionedTransaction(message), {
46997
+ addressLookupTables: addressLookupTableAccounts,
46998
+ type: "FLASHLOAN" /* FLASHLOAN */,
46999
+ signers
47000
+ });
47001
+ if (signers) {
47002
+ tx.sign(signers);
47003
+ }
47004
+ return tx;
47005
+ }
47006
+
47007
+ // src/services/account/actions/loop.ts
47008
+ async function makeLoopTx(params) {
47009
+ const {
47010
+ program,
47011
+ marginfiAccount,
47012
+ bankMap,
47013
+ depositOpts,
47014
+ borrowOpts,
47015
+ bankMetadataMap,
47016
+ addressLookupTableAccounts,
47017
+ connection,
47018
+ oraclePrices,
47019
+ crossbarUrl,
47020
+ additionalIxs = []
47021
+ } = params;
47022
+ const blockhash = (await connection.getLatestBlockhash("confirmed")).blockhash;
47023
+ const setupIxs = await makeSetupIx({
47024
+ connection,
47025
+ authority: marginfiAccount.authority,
47026
+ tokens: [
47027
+ {
47028
+ mint: borrowOpts.borrowBank.mint,
47029
+ tokenProgram: borrowOpts.tokenProgram
47030
+ },
47031
+ {
47032
+ mint: depositOpts.depositBank.mint,
47033
+ tokenProgram: depositOpts.tokenProgram
47034
+ }
47035
+ ]
47036
+ });
47037
+ const updateJupLendRateIxs = makeUpdateJupLendRateIxs(
47038
+ params.marginfiAccount,
47039
+ params.bankMap,
47040
+ [depositOpts.depositBank.address],
47041
+ params.bankMetadataMap
47042
+ );
47043
+ const updateDriftMarketIxs = makeUpdateDriftMarketIxs(
47044
+ params.marginfiAccount,
47045
+ params.bankMap,
47046
+ [depositOpts.depositBank.address],
47047
+ params.bankMetadataMap
47048
+ );
47049
+ const kaminoRefreshIxs = makeRefreshKaminoBanksIxs(
47050
+ marginfiAccount,
47051
+ bankMap,
47052
+ [borrowOpts.borrowBank.address, depositOpts.depositBank.address],
47053
+ bankMetadataMap
47054
+ );
47055
+ const { flashloanTx, setupInstructions, swapQuote, amountToDeposit, depositIxs, borrowIxs } = await buildLoopFlashloanTx({
47056
+ ...params,
47057
+ blockhash
47058
+ });
47059
+ const jupiterSetupInstructions = setupInstructions.filter((ix) => {
47060
+ if (ix.programId.equals(ComputeBudgetProgram.programId)) {
47061
+ return false;
47062
+ }
47063
+ if (ix.programId.equals(ASSOCIATED_TOKEN_PROGRAM_ID)) {
47064
+ const mintKey = ix.keys[3]?.pubkey;
47065
+ if (mintKey?.equals(depositOpts.depositBank.mint) || mintKey?.equals(borrowOpts.borrowBank.mint)) {
47066
+ return false;
47067
+ }
47068
+ }
47069
+ return true;
47070
+ });
47071
+ setupIxs.push(...jupiterSetupInstructions);
47072
+ const { instructions: updateFeedIxs, luts: feedLuts } = await makeSmartCrankSwbFeedIx({
47073
+ marginfiAccount,
47074
+ bankMap,
47075
+ oraclePrices,
47076
+ assetShareValueMultiplierByBank: params.assetShareValueMultiplierByBank,
47077
+ instructions: [...borrowIxs.instructions, ...depositIxs.instructions],
47078
+ program,
47079
+ connection,
47080
+ crossbarUrl
47081
+ });
47082
+ let additionalTxs = [];
47083
+ if (depositOpts.depositBank.mint.equals(NATIVE_MINT) && depositOpts.inputDepositAmount) {
47084
+ setupIxs.push(
47085
+ ...makeWrapSolIxs(marginfiAccount.authority, new BigNumber(depositOpts.inputDepositAmount))
47086
+ );
47087
+ }
47088
+ if (setupIxs.length > 0 || additionalIxs.length > 0 || kaminoRefreshIxs.instructions.length > 0 || updateDriftMarketIxs.instructions.length > 0 || updateJupLendRateIxs.instructions.length > 0) {
47089
+ const ixs = [
47090
+ ...additionalIxs,
47091
+ ...setupIxs,
47092
+ ...kaminoRefreshIxs.instructions,
47093
+ ...updateDriftMarketIxs.instructions,
47094
+ ...updateJupLendRateIxs.instructions
47095
+ ];
47096
+ const txs = splitInstructionsToFitTransactions([], ixs, {
47097
+ blockhash,
47098
+ payerKey: marginfiAccount.authority,
47099
+ luts: addressLookupTableAccounts ?? []
47100
+ });
47101
+ additionalTxs.push(
47102
+ ...txs.map(
47103
+ (tx) => addTransactionMetadata(tx, {
47104
+ type: "CREATE_ATA" /* CREATE_ATA */,
47105
+ addressLookupTables: addressLookupTableAccounts
47106
+ })
47107
+ )
47108
+ );
47109
+ }
47110
+ if (updateFeedIxs.length > 0) {
47111
+ const message = new TransactionMessage({
47112
+ payerKey: marginfiAccount.authority,
47113
+ recentBlockhash: blockhash,
47114
+ instructions: updateFeedIxs
47115
+ }).compileToV0Message(feedLuts);
47116
+ additionalTxs.push(
47117
+ addTransactionMetadata(new VersionedTransaction(message), {
47118
+ addressLookupTables: feedLuts,
47119
+ type: "CRANK" /* CRANK */
47120
+ })
47121
+ );
47122
+ }
47123
+ const transactions = [...additionalTxs, flashloanTx];
47124
+ return {
47125
+ transactions,
47126
+ actionTxIndex: transactions.length - 1,
47127
+ quoteResponse: swapQuote
47128
+ };
47129
+ }
47130
+ async function buildLoopFlashloanTx({
47131
+ program,
47132
+ marginfiAccount,
47133
+ bankMap,
47134
+ borrowOpts,
47135
+ depositOpts,
47136
+ bankMetadataMap,
47137
+ addressLookupTableAccounts,
47138
+ connection,
47139
+ swapOpts,
47140
+ overrideInferAccounts,
47141
+ blockhash
47142
+ }) {
47143
+ const cuRequestIxs = [
47144
+ ComputeBudgetProgram.setComputeUnitLimit({ units: 12e5 }),
47145
+ ComputeBudgetProgram.setComputeUnitPrice({ microLamports: 1 })
47146
+ ];
47147
+ let amountToDeposit;
47148
+ let swapInstructions = [];
47149
+ let setupInstructions = [];
47150
+ let swapLookupTables = [];
47151
+ let swapQuote;
47152
+ let sizeConstraintUsed = 0;
47153
+ if (depositOpts.depositBank.mint.equals(borrowOpts.borrowBank.mint)) {
47154
+ amountToDeposit = borrowOpts.borrowAmount + (depositOpts.loopMode === "DEPOSIT" ? depositOpts.inputDepositAmount : 0);
47155
+ } else {
47156
+ const destinationTokenAccount = getAssociatedTokenAddressSync(
47157
+ new PublicKey(depositOpts.depositBank.mint),
47158
+ marginfiAccount.authority,
47159
+ true,
47160
+ depositOpts.tokenProgram.equals(TOKEN_2022_PROGRAM_ID) ? TOKEN_2022_PROGRAM_ID : void 0
47161
+ );
47162
+ const swapConstraints = await computeFlashloanSwapConstraints({
47163
+ program,
47164
+ marginfiAccount,
47165
+ bankMap,
47166
+ bankMetadataMap,
47167
+ addressLookupTableAccounts: addressLookupTableAccounts ?? [],
47168
+ primaryIx: {
47169
+ type: "borrow",
47170
+ bank: borrowOpts.borrowBank,
47171
+ tokenProgram: borrowOpts.tokenProgram
47172
+ },
47173
+ secondaryIx: {
47174
+ type: "deposit",
47175
+ bank: depositOpts.depositBank,
47176
+ tokenProgram: depositOpts.tokenProgram
47177
+ },
47178
+ overrideInferAccounts
47179
+ });
47180
+ const swapResponse = await getSwapIxsForFlashloan({
47181
+ inputMint: borrowOpts.borrowBank.mint.toBase58(),
47182
+ outputMint: depositOpts.depositBank.mint.toBase58(),
47183
+ amount: uiToNative(borrowOpts.borrowAmount, borrowOpts.borrowBank.mintDecimals).toNumber(),
47184
+ swapMode: "ExactIn",
47185
+ authority: marginfiAccount.authority,
47186
+ connection,
47187
+ destinationTokenAccount,
47188
+ swapOpts,
47189
+ sizeConstraint: swapConstraints.sizeConstraint,
47190
+ maxSwapTotalAccounts: swapConstraints.maxSwapTotalAccounts
47191
+ });
47192
+ sizeConstraintUsed = swapConstraints.sizeConstraint;
47193
+ const outAmountThreshold = nativeToUi(
47194
+ swapResponse.quoteResponse.otherAmountThreshold,
47195
+ depositOpts.depositBank.mintDecimals
47196
+ );
47197
+ amountToDeposit = outAmountThreshold + (depositOpts.loopMode === "DEPOSIT" ? depositOpts.inputDepositAmount : 0);
47198
+ swapInstructions = swapResponse.swapInstructions;
47199
+ setupInstructions = swapResponse.setupInstructions;
47200
+ swapLookupTables = swapResponse.addressLookupTableAddresses;
47201
+ swapQuote = swapResponse.quoteResponse;
47202
+ }
47203
+ const borrowIxs = await makeBorrowIx3({
47204
+ program,
47205
+ bank: borrowOpts.borrowBank,
47206
+ bankMap,
47207
+ tokenProgram: borrowOpts.tokenProgram,
47208
+ amount: borrowOpts.borrowAmount,
47209
+ marginfiAccount,
47210
+ authority: marginfiAccount.authority,
47211
+ isSync: false,
47212
+ opts: {
47213
+ createAtas: false,
47214
+ wrapAndUnwrapSol: false,
47215
+ overrideInferAccounts
47216
+ }
47217
+ });
47218
+ let depositIxs;
47219
+ switch (depositOpts.depositBank.config.assetTag) {
47220
+ case 3 /* KAMINO */: {
47221
+ const reserve = bankMetadataMap[depositOpts.depositBank.address.toBase58()]?.kaminoStates?.reserveState;
47222
+ if (!reserve) {
47223
+ throw TransactionBuildingError.kaminoReserveNotFound(
47224
+ depositOpts.depositBank.address.toBase58(),
47225
+ depositOpts.depositBank.mint.toBase58(),
47226
+ depositOpts.depositBank.tokenSymbol
47227
+ );
47228
+ }
47229
+ depositIxs = await makeKaminoDepositIx3({
47230
+ program,
47231
+ bank: depositOpts.depositBank,
47232
+ tokenProgram: depositOpts.tokenProgram,
47233
+ amount: amountToDeposit,
47234
+ accountAddress: marginfiAccount.address,
47235
+ authority: marginfiAccount.authority,
47236
+ group: marginfiAccount.group,
47237
+ reserve,
47238
+ opts: {
47239
+ wrapAndUnwrapSol: false,
47240
+ overrideInferAccounts
47241
+ }
47242
+ });
47243
+ break;
47244
+ }
47245
+ case 4 /* DRIFT */: {
47246
+ const driftState = bankMetadataMap[depositOpts.depositBank.address.toBase58()]?.driftStates;
47247
+ if (!driftState) {
47248
+ throw TransactionBuildingError.driftStateNotFound(
47249
+ depositOpts.depositBank.address.toBase58(),
47250
+ depositOpts.depositBank.mint.toBase58(),
47251
+ depositOpts.depositBank.tokenSymbol
47252
+ );
47253
+ }
47254
+ const driftMarketIndex = driftState.spotMarketState.marketIndex;
47255
+ const driftOracle = driftState.spotMarketState.oracle;
47256
+ depositIxs = await makeDriftDepositIx3({
47257
+ program,
47258
+ bank: depositOpts.depositBank,
47259
+ tokenProgram: depositOpts.tokenProgram,
47260
+ amount: amountToDeposit,
47261
+ accountAddress: marginfiAccount.address,
47262
+ authority: marginfiAccount.authority,
47263
+ group: marginfiAccount.group,
47264
+ driftMarketIndex,
47265
+ driftOracle,
47266
+ opts: {
47267
+ wrapAndUnwrapSol: false,
47268
+ overrideInferAccounts
47269
+ }
47270
+ });
47271
+ break;
47272
+ }
47273
+ case 6 /* JUPLEND */: {
47274
+ depositIxs = await makeJuplendDepositIx2({
47275
+ program,
47276
+ bank: depositOpts.depositBank,
47277
+ tokenProgram: depositOpts.tokenProgram,
47278
+ amount: amountToDeposit,
47279
+ accountAddress: marginfiAccount.address,
47280
+ authority: marginfiAccount.authority,
47281
+ group: marginfiAccount.group,
47282
+ opts: {
47283
+ wrapAndUnwrapSol: false,
47284
+ overrideInferAccounts
47285
+ }
47286
+ });
47287
+ break;
47288
+ }
47289
+ default: {
47290
+ depositIxs = await makeDepositIx3({
47291
+ program,
47292
+ bank: depositOpts.depositBank,
47293
+ tokenProgram: depositOpts.tokenProgram,
47294
+ amount: amountToDeposit,
47295
+ accountAddress: marginfiAccount.address,
47296
+ authority: marginfiAccount.authority,
47297
+ group: marginfiAccount.group,
47298
+ opts: {
47299
+ wrapAndUnwrapSol: false,
47300
+ overrideInferAccounts
47301
+ }
47302
+ });
47303
+ break;
47304
+ }
47305
+ }
47306
+ const luts = [...addressLookupTableAccounts ?? [], ...swapLookupTables];
47307
+ const allNonFlIxs = [
47308
+ ...cuRequestIxs,
47309
+ ...borrowIxs.instructions,
47310
+ ...swapInstructions,
47311
+ ...depositIxs.instructions
47312
+ ];
47313
+ if (swapInstructions.length > 0) {
47314
+ compileFlashloanPrecheck({
47315
+ allIxs: allNonFlIxs,
47316
+ payer: marginfiAccount.authority,
47317
+ luts,
47318
+ sizeConstraint: sizeConstraintUsed,
47319
+ swapIxCount: swapInstructions.length,
47320
+ swapLutCount: swapLookupTables.length
47321
+ });
47322
+ }
47323
+ const flashloanTx = await makeFlashLoanTx({
47324
+ program,
47325
+ marginfiAccount,
47326
+ bankMap,
47327
+ addressLookupTableAccounts: luts,
47328
+ blockhash,
47329
+ ixs: allNonFlIxs
47330
+ });
47331
+ const txSize = getTxSize(flashloanTx);
47332
+ const totalKeys = getTotalAccountKeys(flashloanTx);
47333
+ if (txSize > MAX_TX_SIZE || totalKeys > MAX_ACCOUNT_LOCKS) {
47334
+ throw TransactionBuildingError.swapSizeExceededLoop(
47335
+ txSize,
47336
+ totalKeys,
47337
+ swapOpts.swapConfig?.provider
47338
+ );
47339
+ }
47340
+ return {
47341
+ flashloanTx,
47342
+ setupInstructions,
47343
+ swapQuote,
47344
+ borrowIxs,
47345
+ depositIxs,
47346
+ amountToDeposit
47347
+ };
47348
+ }
46906
47349
  async function makeRepayIx3({
46907
47350
  program,
46908
47351
  bank,
@@ -47357,882 +47800,6 @@ async function buildRepayWithCollatFlashloanTx({
47357
47800
  };
47358
47801
  }
47359
47802
 
47360
- // src/services/account/utils/flashloan-size.utils.ts
47361
- var SWAP_MERGE_OVERHEAD = 150;
47362
- var FL_IX_OVERHEAD = 52;
47363
- function compactU16Size(n) {
47364
- return n < 128 ? 1 : n < 16384 ? 2 : 3;
47365
- }
47366
- function computeV0TxSize(ixs, payerKey, luts) {
47367
- const keyMap = /* @__PURE__ */ new Map();
47368
- const payerStr = payerKey.toBase58();
47369
- keyMap.set(payerStr, { isSigner: true, isWritable: true });
47370
- const programIds = /* @__PURE__ */ new Set();
47371
- for (const ix of ixs) {
47372
- const progStr = ix.programId.toBase58();
47373
- programIds.add(progStr);
47374
- if (!keyMap.has(progStr)) {
47375
- keyMap.set(progStr, { isSigner: false, isWritable: false });
47376
- }
47377
- for (const meta of ix.keys) {
47378
- const keyStr = meta.pubkey.toBase58();
47379
- const existing = keyMap.get(keyStr);
47380
- if (existing) {
47381
- existing.isSigner = existing.isSigner || meta.isSigner;
47382
- existing.isWritable = existing.isWritable || meta.isWritable;
47383
- } else {
47384
- keyMap.set(keyStr, { isSigner: meta.isSigner, isWritable: meta.isWritable });
47385
- }
47386
- }
47387
- }
47388
- const lutLookup = /* @__PURE__ */ new Map();
47389
- for (let li = 0; li < luts.length; li++) {
47390
- const addresses = luts[li].state.addresses;
47391
- for (let ai = 0; ai < addresses.length; ai++) {
47392
- const addrStr = addresses[ai].toBase58();
47393
- if (!lutLookup.has(addrStr)) {
47394
- lutLookup.set(addrStr, { lutIdx: li, addrIdx: ai });
47395
- }
47396
- }
47397
- }
47398
- let numStaticKeys = 0;
47399
- let numWritableStaticKeys = 0;
47400
- const lutWritableIdxs = luts.map(() => /* @__PURE__ */ new Set());
47401
- const lutReadonlyIdxs = luts.map(() => /* @__PURE__ */ new Set());
47402
- for (const [keyStr, props] of keyMap) {
47403
- if (props.isSigner || programIds.has(keyStr)) {
47404
- numStaticKeys++;
47405
- if (props.isWritable) numWritableStaticKeys++;
47406
- continue;
47407
- }
47408
- const lutEntry = lutLookup.get(keyStr);
47409
- if (lutEntry) {
47410
- if (props.isWritable) {
47411
- lutWritableIdxs[lutEntry.lutIdx].add(lutEntry.addrIdx);
47412
- } else {
47413
- lutReadonlyIdxs[lutEntry.lutIdx].add(lutEntry.addrIdx);
47414
- }
47415
- } else {
47416
- numStaticKeys++;
47417
- if (props.isWritable) numWritableStaticKeys++;
47418
- }
47419
- }
47420
- const fixedOverhead = 101;
47421
- const staticKeysSection = compactU16Size(numStaticKeys) + numStaticKeys * 32;
47422
- let ixSection = compactU16Size(ixs.length);
47423
- for (const ix of ixs) {
47424
- const numAccounts = ix.keys.length;
47425
- ixSection += 1 + // programId index
47426
- compactU16Size(numAccounts) + numAccounts + // account key indexes
47427
- compactU16Size(ix.data.length) + ix.data.length;
47428
- }
47429
- let numUsedLuts = 0;
47430
- let lutSection = 0;
47431
- for (let li = 0; li < luts.length; li++) {
47432
- const wCount = lutWritableIdxs[li].size;
47433
- const rCount = lutReadonlyIdxs[li].size;
47434
- if (wCount === 0 && rCount === 0) continue;
47435
- numUsedLuts++;
47436
- lutSection += 32 + // LUT address
47437
- compactU16Size(wCount) + wCount + // writable indexes
47438
- compactU16Size(rCount) + rCount;
47439
- }
47440
- lutSection += compactU16Size(numUsedLuts);
47441
- let totalLutKeys = 0;
47442
- for (let li = 0; li < luts.length; li++) {
47443
- totalLutKeys += lutWritableIdxs[li].size + lutReadonlyIdxs[li].size;
47444
- }
47445
- const accountCount = numStaticKeys + totalLutKeys;
47446
- let totalLutWritableKeys = 0;
47447
- for (let li = 0; li < luts.length; li++) {
47448
- totalLutWritableKeys += lutWritableIdxs[li].size;
47449
- }
47450
- const writableAccountCount = numWritableStaticKeys + totalLutWritableKeys;
47451
- const size = fixedOverhead + staticKeysSection + ixSection + lutSection + 1;
47452
- return { size, accountCount, writableAccountCount };
47453
- }
47454
- function computeFlashLoanNonSwapBudget({
47455
- program,
47456
- marginfiAccount,
47457
- ixs,
47458
- bankMap,
47459
- addressLookupTableAccounts
47460
- }) {
47461
- const projectedActiveBanksKeys = computeProjectedActiveBanksNoCpi(
47462
- marginfiAccount.balances,
47463
- ixs,
47464
- program
47465
- );
47466
- const projectedActiveBanks = projectedActiveBanksKeys.map((key) => {
47467
- const b = bankMap.get(key.toBase58());
47468
- if (!b) throw new Error(`Bank ${key.toBase58()} not found in computeFlashLoanNonSwapBudget`);
47469
- return b;
47470
- });
47471
- const endIndex = ixs.length + 1;
47472
- const beginFlIx = sync_instructions_default.makeBeginFlashLoanIx(
47473
- program.programId,
47474
- { marginfiAccount: marginfiAccount.address, authority: marginfiAccount.authority },
47475
- { endIndex: new BN11(endIndex) }
47476
- );
47477
- const endFlRemainingAccounts = computeHealthAccountMetas(projectedActiveBanks);
47478
- const endFlIx = sync_instructions_default.makeEndFlashLoanIx(
47479
- program.programId,
47480
- { marginfiAccount: marginfiAccount.address, authority: marginfiAccount.authority },
47481
- endFlRemainingAccounts.map((pubkey) => ({ pubkey, isSigner: false, isWritable: false }))
47482
- );
47483
- const allNonSwapIxs = [beginFlIx, ...ixs, endFlIx];
47484
- const nonSwapMsg = new TransactionMessage({
47485
- payerKey: marginfiAccount.authority,
47486
- recentBlockhash: PublicKey.default.toBase58(),
47487
- instructions: allNonSwapIxs
47488
- }).compileToV0Message(addressLookupTableAccounts);
47489
- const nonSwapSize = new VersionedTransaction(nonSwapMsg).serialize().length;
47490
- const { header, staticAccountKeys, addressTableLookups } = nonSwapMsg;
47491
- const nonSwapTotal = staticAccountKeys.length + addressTableLookups.reduce(
47492
- (s, l) => s + l.writableIndexes.length + l.readonlyIndexes.length,
47493
- 0
47494
- );
47495
- const sizeConstraint = MAX_TX_SIZE - nonSwapSize - SWAP_MERGE_OVERHEAD;
47496
- const maxSwapTotalAccounts = MAX_ACCOUNT_LOCKS - nonSwapTotal;
47497
- console.log("[flashloan-budget]", {
47498
- method: "compiled",
47499
- nonSwapSize,
47500
- nonSwapTotal,
47501
- sizeConstraint,
47502
- maxSwapTotalAccounts
47503
- });
47504
- return { sizeConstraint, maxSwapTotalAccounts };
47505
- }
47506
- function compileFlashloanPrecheck({
47507
- allIxs,
47508
- payer,
47509
- luts,
47510
- sizeConstraint,
47511
- swapIxCount,
47512
- swapLutCount
47513
- }) {
47514
- const msg = new TransactionMessage({
47515
- payerKey: payer,
47516
- recentBlockhash: PublicKey.default.toBase58(),
47517
- instructions: allIxs
47518
- }).compileToV0Message(luts);
47519
- const rawSize = new VersionedTransaction(msg).serialize().length;
47520
- const fullTxSize = rawSize + FL_IX_OVERHEAD;
47521
- const overshoot = fullTxSize - MAX_TX_SIZE;
47522
- const { header, staticAccountKeys, addressTableLookups } = msg;
47523
- const writableStatic = staticAccountKeys.length - header.numReadonlySignedAccounts - header.numReadonlyUnsignedAccounts;
47524
- const writableLut = addressTableLookups.reduce((s, l) => s + l.writableIndexes.length, 0);
47525
- const writableAccounts = writableStatic + writableLut;
47526
- const totalAccounts = staticAccountKeys.length + addressTableLookups.reduce(
47527
- (s, l) => s + l.writableIndexes.length + l.readonlyIndexes.length,
47528
- 0
47529
- );
47530
- console.log("[flashloan-precheck]", {
47531
- fullTxSize,
47532
- overshoot,
47533
- sizeConstraint,
47534
- writableAccounts,
47535
- totalAccounts,
47536
- staticKeys: staticAccountKeys.length,
47537
- numLuts: addressTableLookups.length,
47538
- swapIxCount,
47539
- swapLutCount
47540
- });
47541
- return { fullTxSize, overshoot, writableAccounts, totalAccounts };
47542
- }
47543
- async function buildBudgetIx(config, program, marginfiAccount, bankMap, bankMetadataMap, overrideInferAccounts) {
47544
- const { bank, tokenProgram } = config;
47545
- switch (config.type) {
47546
- case "borrow":
47547
- return makeBorrowIx3({
47548
- program,
47549
- bank,
47550
- bankMap,
47551
- tokenProgram,
47552
- amount: 1,
47553
- marginfiAccount,
47554
- authority: marginfiAccount.authority,
47555
- isSync: true,
47556
- opts: { createAtas: false, wrapAndUnwrapSol: false, overrideInferAccounts }
47557
- });
47558
- case "repay":
47559
- return makeRepayIx3({
47560
- program,
47561
- bank,
47562
- tokenProgram,
47563
- amount: 1,
47564
- accountAddress: marginfiAccount.address,
47565
- authority: marginfiAccount.authority,
47566
- repayAll: false,
47567
- isSync: true,
47568
- opts: { wrapAndUnwrapSol: false, overrideInferAccounts }
47569
- });
47570
- case "deposit":
47571
- return buildDepositBudgetIx(
47572
- config,
47573
- program,
47574
- marginfiAccount,
47575
- bankMetadataMap,
47576
- overrideInferAccounts
47577
- );
47578
- case "withdraw":
47579
- return buildWithdrawBudgetIx(
47580
- config,
47581
- program,
47582
- marginfiAccount,
47583
- bankMap,
47584
- bankMetadataMap,
47585
- overrideInferAccounts
47586
- );
47587
- }
47588
- }
47589
- async function buildDepositBudgetIx(config, program, marginfiAccount, bankMetadataMap, overrideInferAccounts) {
47590
- const { bank, tokenProgram } = config;
47591
- const opts = { wrapAndUnwrapSol: false, overrideInferAccounts };
47592
- switch (bank.config.assetTag) {
47593
- case 3 /* KAMINO */: {
47594
- const reserve = bankMetadataMap[bank.address.toBase58()]?.kaminoStates?.reserveState;
47595
- if (!reserve) {
47596
- throw TransactionBuildingError.kaminoReserveNotFound(
47597
- bank.address.toBase58(),
47598
- bank.mint.toBase58(),
47599
- bank.tokenSymbol
47600
- );
47601
- }
47602
- return makeKaminoDepositIx3({
47603
- program,
47604
- bank,
47605
- tokenProgram,
47606
- amount: 1,
47607
- accountAddress: marginfiAccount.address,
47608
- authority: marginfiAccount.authority,
47609
- group: marginfiAccount.group,
47610
- reserve,
47611
- isSync: true,
47612
- opts
47613
- });
47614
- }
47615
- case 4 /* DRIFT */: {
47616
- const driftState = bankMetadataMap[bank.address.toBase58()]?.driftStates;
47617
- if (!driftState) {
47618
- throw TransactionBuildingError.driftStateNotFound(
47619
- bank.address.toBase58(),
47620
- bank.mint.toBase58(),
47621
- bank.tokenSymbol
47622
- );
47623
- }
47624
- return makeDriftDepositIx3({
47625
- program,
47626
- bank,
47627
- tokenProgram,
47628
- amount: 1,
47629
- accountAddress: marginfiAccount.address,
47630
- authority: marginfiAccount.authority,
47631
- group: marginfiAccount.group,
47632
- driftMarketIndex: driftState.spotMarketState.marketIndex,
47633
- driftOracle: driftState.spotMarketState.oracle,
47634
- isSync: true,
47635
- opts
47636
- });
47637
- }
47638
- case 6 /* JUPLEND */: {
47639
- return makeJuplendDepositIx2({
47640
- program,
47641
- bank,
47642
- tokenProgram,
47643
- amount: 1,
47644
- accountAddress: marginfiAccount.address,
47645
- authority: marginfiAccount.authority,
47646
- group: marginfiAccount.group,
47647
- isSync: true,
47648
- opts
47649
- });
47650
- }
47651
- default: {
47652
- return makeDepositIx3({
47653
- program,
47654
- bank,
47655
- tokenProgram,
47656
- amount: 1,
47657
- accountAddress: marginfiAccount.address,
47658
- authority: marginfiAccount.authority,
47659
- group: marginfiAccount.group,
47660
- isSync: true,
47661
- opts
47662
- });
47663
- }
47664
- }
47665
- }
47666
- async function buildWithdrawBudgetIx(config, program, marginfiAccount, bankMap, bankMetadataMap, overrideInferAccounts) {
47667
- const { bank, tokenProgram } = config;
47668
- const opts = { createAtas: false, wrapAndUnwrapSol: false, overrideInferAccounts };
47669
- switch (bank.config.assetTag) {
47670
- case 3 /* KAMINO */: {
47671
- const reserve = bankMetadataMap[bank.address.toBase58()]?.kaminoStates?.reserveState;
47672
- if (!reserve) {
47673
- throw TransactionBuildingError.kaminoReserveNotFound(
47674
- bank.address.toBase58(),
47675
- bank.mint.toBase58(),
47676
- bank.tokenSymbol
47677
- );
47678
- }
47679
- return makeKaminoWithdrawIx3({
47680
- program,
47681
- bank,
47682
- bankMap,
47683
- tokenProgram,
47684
- cTokenAmount: 1,
47685
- marginfiAccount,
47686
- authority: marginfiAccount.authority,
47687
- reserve,
47688
- withdrawAll: false,
47689
- isSync: true,
47690
- opts
47691
- });
47692
- }
47693
- case 4 /* DRIFT */: {
47694
- const driftState = bankMetadataMap[bank.address.toBase58()]?.driftStates;
47695
- if (!driftState) {
47696
- throw TransactionBuildingError.driftStateNotFound(
47697
- bank.address.toBase58(),
47698
- bank.mint.toBase58(),
47699
- bank.tokenSymbol
47700
- );
47701
- }
47702
- return makeDriftWithdrawIx3({
47703
- program,
47704
- bank,
47705
- bankMap,
47706
- tokenProgram,
47707
- amount: 1,
47708
- marginfiAccount,
47709
- authority: marginfiAccount.authority,
47710
- driftSpotMarket: driftState.spotMarketState,
47711
- userRewards: driftState.userRewards,
47712
- withdrawAll: false,
47713
- isSync: true,
47714
- opts
47715
- });
47716
- }
47717
- case 6 /* JUPLEND */: {
47718
- const jupLendState = bankMetadataMap[bank.address.toBase58()]?.jupLendStates;
47719
- if (!jupLendState) {
47720
- throw TransactionBuildingError.jupLendStateNotFound(
47721
- bank.address.toBase58(),
47722
- bank.mint.toBase58(),
47723
- bank.tokenSymbol
47724
- );
47725
- }
47726
- return makeJuplendWithdrawIx2({
47727
- program,
47728
- bank,
47729
- bankMap,
47730
- tokenProgram,
47731
- amount: 1,
47732
- marginfiAccount,
47733
- authority: marginfiAccount.authority,
47734
- jupLendingState: jupLendState.jupLendingState,
47735
- withdrawAll: false,
47736
- opts
47737
- });
47738
- }
47739
- default: {
47740
- return makeWithdrawIx3({
47741
- program,
47742
- bank,
47743
- bankMap,
47744
- tokenProgram,
47745
- amount: 1,
47746
- marginfiAccount,
47747
- authority: marginfiAccount.authority,
47748
- withdrawAll: false,
47749
- isSync: true,
47750
- opts
47751
- });
47752
- }
47753
- }
47754
- }
47755
- async function computeFlashloanSwapConstraints({
47756
- program,
47757
- marginfiAccount,
47758
- bankMap,
47759
- addressLookupTableAccounts,
47760
- bankMetadataMap,
47761
- primaryIx,
47762
- secondaryIx,
47763
- overrideInferAccounts
47764
- }) {
47765
- const cuRequestIxs = [
47766
- ComputeBudgetProgram.setComputeUnitLimit({ units: 12e5 }),
47767
- ComputeBudgetProgram.setComputeUnitPrice({ microLamports: 1 })
47768
- ];
47769
- const [primaryResult, secondaryResult] = await Promise.all([
47770
- buildBudgetIx(
47771
- primaryIx,
47772
- program,
47773
- marginfiAccount,
47774
- bankMap,
47775
- bankMetadataMap,
47776
- overrideInferAccounts
47777
- ),
47778
- buildBudgetIx(
47779
- secondaryIx,
47780
- program,
47781
- marginfiAccount,
47782
- bankMap,
47783
- bankMetadataMap,
47784
- overrideInferAccounts
47785
- )
47786
- ]);
47787
- return computeFlashLoanNonSwapBudget({
47788
- program,
47789
- marginfiAccount,
47790
- bankMap,
47791
- addressLookupTableAccounts,
47792
- ixs: [...cuRequestIxs, ...primaryResult.instructions, ...secondaryResult.instructions]
47793
- });
47794
- }
47795
-
47796
- // src/services/account/actions/flash-loan.ts
47797
- async function makeBeginFlashLoanIx3(program, marginfiAccountPk, endIndex, authority, isSync) {
47798
- const ix = isSync && authority ? sync_instructions_default.makeBeginFlashLoanIx(
47799
- program.programId,
47800
- {
47801
- marginfiAccount: marginfiAccountPk,
47802
- authority
47803
- },
47804
- { endIndex: new BN11(endIndex) }
47805
- ) : await instructions_default.makeBeginFlashLoanIx(
47806
- program,
47807
- {
47808
- marginfiAccount: marginfiAccountPk,
47809
- authority
47810
- },
47811
- { endIndex: new BN11(endIndex) }
47812
- );
47813
- return { instructions: [ix], keys: [] };
47814
- }
47815
- async function makeEndFlashLoanIx3(program, marginfiAccountPk, projectedActiveBanks, authority, isSync) {
47816
- const remainingAccounts = computeHealthAccountMetas(projectedActiveBanks);
47817
- const ix = isSync && authority ? sync_instructions_default.makeEndFlashLoanIx(
47818
- program.programId,
47819
- {
47820
- marginfiAccount: marginfiAccountPk,
47821
- authority
47822
- },
47823
- remainingAccounts.map((account) => ({
47824
- pubkey: account,
47825
- isSigner: false,
47826
- isWritable: false
47827
- }))
47828
- ) : await instructions_default.makeEndFlashLoanIx(
47829
- program,
47830
- {
47831
- marginfiAccount: marginfiAccountPk,
47832
- authority
47833
- },
47834
- remainingAccounts.map((account) => ({
47835
- pubkey: account,
47836
- isSigner: false,
47837
- isWritable: false
47838
- }))
47839
- );
47840
- return { instructions: [ix], keys: [] };
47841
- }
47842
- async function makeFlashLoanTx({
47843
- program,
47844
- marginfiAccount,
47845
- ixs,
47846
- bankMap,
47847
- blockhash,
47848
- addressLookupTableAccounts,
47849
- signers,
47850
- isSync
47851
- }) {
47852
- const endIndex = ixs.length + 1;
47853
- const projectedActiveBanksKeys = computeProjectedActiveBanksNoCpi(
47854
- marginfiAccount.balances,
47855
- ixs,
47856
- program
47857
- );
47858
- const projectedActiveBanks = projectedActiveBanksKeys.map((account) => {
47859
- const b = bankMap.get(account.toBase58());
47860
- if (!b) throw Error(`Bank ${account.toBase58()} not found, in makeFlashLoanTx function`);
47861
- return b;
47862
- });
47863
- const beginFlashLoanIx = await makeBeginFlashLoanIx3(
47864
- program,
47865
- marginfiAccount.address,
47866
- endIndex,
47867
- marginfiAccount.authority,
47868
- isSync
47869
- );
47870
- const endFlashLoanIx = await makeEndFlashLoanIx3(
47871
- program,
47872
- marginfiAccount.address,
47873
- projectedActiveBanks,
47874
- marginfiAccount.authority,
47875
- isSync
47876
- );
47877
- const message = new TransactionMessage({
47878
- payerKey: marginfiAccount.authority,
47879
- recentBlockhash: blockhash,
47880
- instructions: [...beginFlashLoanIx.instructions, ...ixs, ...endFlashLoanIx.instructions]
47881
- }).compileToV0Message(addressLookupTableAccounts);
47882
- const tx = addTransactionMetadata(new VersionedTransaction(message), {
47883
- addressLookupTables: addressLookupTableAccounts,
47884
- type: "FLASHLOAN" /* FLASHLOAN */,
47885
- signers
47886
- });
47887
- if (signers) {
47888
- tx.sign(signers);
47889
- }
47890
- return tx;
47891
- }
47892
-
47893
- // src/services/account/actions/loop.ts
47894
- async function makeLoopTx(params) {
47895
- const {
47896
- program,
47897
- marginfiAccount,
47898
- bankMap,
47899
- depositOpts,
47900
- borrowOpts,
47901
- bankMetadataMap,
47902
- addressLookupTableAccounts,
47903
- connection,
47904
- oraclePrices,
47905
- crossbarUrl,
47906
- additionalIxs = []
47907
- } = params;
47908
- const blockhash = (await connection.getLatestBlockhash("confirmed")).blockhash;
47909
- const setupIxs = await makeSetupIx({
47910
- connection,
47911
- authority: marginfiAccount.authority,
47912
- tokens: [
47913
- {
47914
- mint: borrowOpts.borrowBank.mint,
47915
- tokenProgram: borrowOpts.tokenProgram
47916
- },
47917
- {
47918
- mint: depositOpts.depositBank.mint,
47919
- tokenProgram: depositOpts.tokenProgram
47920
- }
47921
- ]
47922
- });
47923
- const updateJupLendRateIxs = makeUpdateJupLendRateIxs(
47924
- params.marginfiAccount,
47925
- params.bankMap,
47926
- [depositOpts.depositBank.address],
47927
- params.bankMetadataMap
47928
- );
47929
- const updateDriftMarketIxs = makeUpdateDriftMarketIxs(
47930
- params.marginfiAccount,
47931
- params.bankMap,
47932
- [depositOpts.depositBank.address],
47933
- params.bankMetadataMap
47934
- );
47935
- const kaminoRefreshIxs = makeRefreshKaminoBanksIxs(
47936
- marginfiAccount,
47937
- bankMap,
47938
- [borrowOpts.borrowBank.address, depositOpts.depositBank.address],
47939
- bankMetadataMap
47940
- );
47941
- const { flashloanTx, setupInstructions, swapQuote, amountToDeposit, depositIxs, borrowIxs } = await buildLoopFlashloanTx({
47942
- ...params,
47943
- blockhash
47944
- });
47945
- const jupiterSetupInstructions = setupInstructions.filter((ix) => {
47946
- if (ix.programId.equals(ComputeBudgetProgram.programId)) {
47947
- return false;
47948
- }
47949
- if (ix.programId.equals(ASSOCIATED_TOKEN_PROGRAM_ID)) {
47950
- const mintKey = ix.keys[3]?.pubkey;
47951
- if (mintKey?.equals(depositOpts.depositBank.mint) || mintKey?.equals(borrowOpts.borrowBank.mint)) {
47952
- return false;
47953
- }
47954
- }
47955
- return true;
47956
- });
47957
- setupIxs.push(...jupiterSetupInstructions);
47958
- const { instructions: updateFeedIxs, luts: feedLuts } = await makeSmartCrankSwbFeedIx({
47959
- marginfiAccount,
47960
- bankMap,
47961
- oraclePrices,
47962
- assetShareValueMultiplierByBank: params.assetShareValueMultiplierByBank,
47963
- instructions: [...borrowIxs.instructions, ...depositIxs.instructions],
47964
- program,
47965
- connection,
47966
- crossbarUrl
47967
- });
47968
- let additionalTxs = [];
47969
- if (depositOpts.depositBank.mint.equals(NATIVE_MINT) && depositOpts.inputDepositAmount) {
47970
- setupIxs.push(
47971
- ...makeWrapSolIxs(marginfiAccount.authority, new BigNumber(depositOpts.inputDepositAmount))
47972
- );
47973
- }
47974
- if (setupIxs.length > 0 || additionalIxs.length > 0 || kaminoRefreshIxs.instructions.length > 0 || updateDriftMarketIxs.instructions.length > 0 || updateJupLendRateIxs.instructions.length > 0) {
47975
- const ixs = [
47976
- ...additionalIxs,
47977
- ...setupIxs,
47978
- ...kaminoRefreshIxs.instructions,
47979
- ...updateDriftMarketIxs.instructions,
47980
- ...updateJupLendRateIxs.instructions
47981
- ];
47982
- const txs = splitInstructionsToFitTransactions([], ixs, {
47983
- blockhash,
47984
- payerKey: marginfiAccount.authority,
47985
- luts: addressLookupTableAccounts ?? []
47986
- });
47987
- additionalTxs.push(
47988
- ...txs.map(
47989
- (tx) => addTransactionMetadata(tx, {
47990
- type: "CREATE_ATA" /* CREATE_ATA */,
47991
- addressLookupTables: addressLookupTableAccounts
47992
- })
47993
- )
47994
- );
47995
- }
47996
- if (updateFeedIxs.length > 0) {
47997
- const message = new TransactionMessage({
47998
- payerKey: marginfiAccount.authority,
47999
- recentBlockhash: blockhash,
48000
- instructions: updateFeedIxs
48001
- }).compileToV0Message(feedLuts);
48002
- additionalTxs.push(
48003
- addTransactionMetadata(new VersionedTransaction(message), {
48004
- addressLookupTables: feedLuts,
48005
- type: "CRANK" /* CRANK */
48006
- })
48007
- );
48008
- }
48009
- const transactions = [...additionalTxs, flashloanTx];
48010
- return {
48011
- transactions,
48012
- actionTxIndex: transactions.length - 1,
48013
- quoteResponse: swapQuote
48014
- };
48015
- }
48016
- async function buildLoopFlashloanTx({
48017
- program,
48018
- marginfiAccount,
48019
- bankMap,
48020
- borrowOpts,
48021
- depositOpts,
48022
- bankMetadataMap,
48023
- addressLookupTableAccounts,
48024
- connection,
48025
- swapOpts,
48026
- overrideInferAccounts,
48027
- blockhash
48028
- }) {
48029
- const cuRequestIxs = [
48030
- ComputeBudgetProgram.setComputeUnitLimit({ units: 12e5 }),
48031
- ComputeBudgetProgram.setComputeUnitPrice({ microLamports: 1 })
48032
- ];
48033
- let amountToDeposit;
48034
- let swapInstructions = [];
48035
- let setupInstructions = [];
48036
- let swapLookupTables = [];
48037
- let swapQuote;
48038
- let sizeConstraintUsed = 0;
48039
- if (depositOpts.depositBank.mint.equals(borrowOpts.borrowBank.mint)) {
48040
- amountToDeposit = borrowOpts.borrowAmount + (depositOpts.loopMode === "DEPOSIT" ? depositOpts.inputDepositAmount : 0);
48041
- } else {
48042
- const destinationTokenAccount = getAssociatedTokenAddressSync(
48043
- new PublicKey(depositOpts.depositBank.mint),
48044
- marginfiAccount.authority,
48045
- true,
48046
- depositOpts.tokenProgram.equals(TOKEN_2022_PROGRAM_ID) ? TOKEN_2022_PROGRAM_ID : void 0
48047
- );
48048
- const swapConstraints = await computeFlashloanSwapConstraints({
48049
- program,
48050
- marginfiAccount,
48051
- bankMap,
48052
- bankMetadataMap,
48053
- addressLookupTableAccounts: addressLookupTableAccounts ?? [],
48054
- primaryIx: {
48055
- type: "borrow",
48056
- bank: borrowOpts.borrowBank,
48057
- tokenProgram: borrowOpts.tokenProgram
48058
- },
48059
- secondaryIx: {
48060
- type: "deposit",
48061
- bank: depositOpts.depositBank,
48062
- tokenProgram: depositOpts.tokenProgram
48063
- },
48064
- overrideInferAccounts
48065
- });
48066
- const swapResponse = await getSwapIxsForFlashloan({
48067
- inputMint: borrowOpts.borrowBank.mint.toBase58(),
48068
- outputMint: depositOpts.depositBank.mint.toBase58(),
48069
- amount: uiToNative(borrowOpts.borrowAmount, borrowOpts.borrowBank.mintDecimals).toNumber(),
48070
- swapMode: "ExactIn",
48071
- authority: marginfiAccount.authority,
48072
- connection,
48073
- destinationTokenAccount,
48074
- swapOpts,
48075
- sizeConstraint: swapConstraints.sizeConstraint,
48076
- maxSwapTotalAccounts: swapConstraints.maxSwapTotalAccounts
48077
- });
48078
- sizeConstraintUsed = swapConstraints.sizeConstraint;
48079
- const outAmountThreshold = nativeToUi(
48080
- swapResponse.quoteResponse.otherAmountThreshold,
48081
- depositOpts.depositBank.mintDecimals
48082
- );
48083
- amountToDeposit = outAmountThreshold + (depositOpts.loopMode === "DEPOSIT" ? depositOpts.inputDepositAmount : 0);
48084
- swapInstructions = swapResponse.swapInstructions;
48085
- setupInstructions = swapResponse.setupInstructions;
48086
- swapLookupTables = swapResponse.addressLookupTableAddresses;
48087
- swapQuote = swapResponse.quoteResponse;
48088
- }
48089
- const borrowIxs = await makeBorrowIx3({
48090
- program,
48091
- bank: borrowOpts.borrowBank,
48092
- bankMap,
48093
- tokenProgram: borrowOpts.tokenProgram,
48094
- amount: borrowOpts.borrowAmount,
48095
- marginfiAccount,
48096
- authority: marginfiAccount.authority,
48097
- isSync: false,
48098
- opts: {
48099
- createAtas: false,
48100
- wrapAndUnwrapSol: false,
48101
- overrideInferAccounts
48102
- }
48103
- });
48104
- let depositIxs;
48105
- switch (depositOpts.depositBank.config.assetTag) {
48106
- case 3 /* KAMINO */: {
48107
- const reserve = bankMetadataMap[depositOpts.depositBank.address.toBase58()]?.kaminoStates?.reserveState;
48108
- if (!reserve) {
48109
- throw TransactionBuildingError.kaminoReserveNotFound(
48110
- depositOpts.depositBank.address.toBase58(),
48111
- depositOpts.depositBank.mint.toBase58(),
48112
- depositOpts.depositBank.tokenSymbol
48113
- );
48114
- }
48115
- depositIxs = await makeKaminoDepositIx3({
48116
- program,
48117
- bank: depositOpts.depositBank,
48118
- tokenProgram: depositOpts.tokenProgram,
48119
- amount: amountToDeposit,
48120
- accountAddress: marginfiAccount.address,
48121
- authority: marginfiAccount.authority,
48122
- group: marginfiAccount.group,
48123
- reserve,
48124
- opts: {
48125
- wrapAndUnwrapSol: false,
48126
- overrideInferAccounts
48127
- }
48128
- });
48129
- break;
48130
- }
48131
- case 4 /* DRIFT */: {
48132
- const driftState = bankMetadataMap[depositOpts.depositBank.address.toBase58()]?.driftStates;
48133
- if (!driftState) {
48134
- throw TransactionBuildingError.driftStateNotFound(
48135
- depositOpts.depositBank.address.toBase58(),
48136
- depositOpts.depositBank.mint.toBase58(),
48137
- depositOpts.depositBank.tokenSymbol
48138
- );
48139
- }
48140
- const driftMarketIndex = driftState.spotMarketState.marketIndex;
48141
- const driftOracle = driftState.spotMarketState.oracle;
48142
- depositIxs = await makeDriftDepositIx3({
48143
- program,
48144
- bank: depositOpts.depositBank,
48145
- tokenProgram: depositOpts.tokenProgram,
48146
- amount: amountToDeposit,
48147
- accountAddress: marginfiAccount.address,
48148
- authority: marginfiAccount.authority,
48149
- group: marginfiAccount.group,
48150
- driftMarketIndex,
48151
- driftOracle,
48152
- opts: {
48153
- wrapAndUnwrapSol: false,
48154
- overrideInferAccounts
48155
- }
48156
- });
48157
- break;
48158
- }
48159
- case 6 /* JUPLEND */: {
48160
- depositIxs = await makeJuplendDepositIx2({
48161
- program,
48162
- bank: depositOpts.depositBank,
48163
- tokenProgram: depositOpts.tokenProgram,
48164
- amount: amountToDeposit,
48165
- accountAddress: marginfiAccount.address,
48166
- authority: marginfiAccount.authority,
48167
- group: marginfiAccount.group,
48168
- opts: {
48169
- wrapAndUnwrapSol: false,
48170
- overrideInferAccounts
48171
- }
48172
- });
48173
- break;
48174
- }
48175
- default: {
48176
- depositIxs = await makeDepositIx3({
48177
- program,
48178
- bank: depositOpts.depositBank,
48179
- tokenProgram: depositOpts.tokenProgram,
48180
- amount: amountToDeposit,
48181
- accountAddress: marginfiAccount.address,
48182
- authority: marginfiAccount.authority,
48183
- group: marginfiAccount.group,
48184
- opts: {
48185
- wrapAndUnwrapSol: false,
48186
- overrideInferAccounts
48187
- }
48188
- });
48189
- break;
48190
- }
48191
- }
48192
- const luts = [...addressLookupTableAccounts ?? [], ...swapLookupTables];
48193
- const allNonFlIxs = [
48194
- ...cuRequestIxs,
48195
- ...borrowIxs.instructions,
48196
- ...swapInstructions,
48197
- ...depositIxs.instructions
48198
- ];
48199
- if (swapInstructions.length > 0) {
48200
- compileFlashloanPrecheck({
48201
- allIxs: allNonFlIxs,
48202
- payer: marginfiAccount.authority,
48203
- luts,
48204
- sizeConstraint: sizeConstraintUsed,
48205
- swapIxCount: swapInstructions.length,
48206
- swapLutCount: swapLookupTables.length
48207
- });
48208
- }
48209
- const flashloanTx = await makeFlashLoanTx({
48210
- program,
48211
- marginfiAccount,
48212
- bankMap,
48213
- addressLookupTableAccounts: luts,
48214
- blockhash,
48215
- ixs: allNonFlIxs
48216
- });
48217
- const txSize = getTxSize(flashloanTx);
48218
- const totalKeys = getTotalAccountKeys(flashloanTx);
48219
- if (txSize > MAX_TX_SIZE || totalKeys > MAX_ACCOUNT_LOCKS) {
48220
- throw TransactionBuildingError.swapSizeExceededLoop(
48221
- txSize,
48222
- totalKeys,
48223
- swapOpts.swapConfig?.provider
48224
- );
48225
- }
48226
- return {
48227
- flashloanTx,
48228
- setupInstructions,
48229
- swapQuote,
48230
- borrowIxs,
48231
- depositIxs,
48232
- amountToDeposit
48233
- };
48234
- }
48235
-
48236
47803
  // src/services/account/actions/emissions.ts
48237
47804
  async function makeClearEmissionsIx(program, marginfiAccount, banks, bankAddress) {
48238
47805
  const bank = banks.get(bankAddress.toBase58());
@@ -48660,7 +48227,7 @@ async function buildSwapCollateralFlashloanTx({
48660
48227
  const txSize = getTxSize(flashloanTx);
48661
48228
  const totalKeys = getTotalAccountKeys(flashloanTx);
48662
48229
  if (txSize > MAX_TX_SIZE || totalKeys > MAX_ACCOUNT_LOCKS) {
48663
- throw TransactionBuildingError.swapSizeExceededLoop(
48230
+ throw TransactionBuildingError.swapSizeExceededPositionSwap(
48664
48231
  txSize,
48665
48232
  totalKeys,
48666
48233
  swapOpts.swapConfig?.provider
@@ -48921,7 +48488,7 @@ async function buildSwapDebtFlashloanTx({
48921
48488
  const txSize = getTxSize(flashloanTx);
48922
48489
  const totalKeys = getTotalAccountKeys(flashloanTx);
48923
48490
  if (txSize > MAX_TX_SIZE || totalKeys > MAX_ACCOUNT_LOCKS) {
48924
- throw TransactionBuildingError.swapSizeExceededLoop(
48491
+ throw TransactionBuildingError.swapSizeExceededPositionSwap(
48925
48492
  txSize,
48926
48493
  totalKeys,
48927
48494
  swapOpts.swapConfig?.provider
@@ -48935,179 +48502,6 @@ async function buildSwapDebtFlashloanTx({
48935
48502
  repayIxs
48936
48503
  };
48937
48504
  }
48938
- var SYSVAR_CLOCK_ID2 = new PublicKey("SysvarC1ock11111111111111111111111111111111");
48939
- async function makeMintStakedLstIx(params) {
48940
- const { amount, authority, stakeAccountPk, validator, connection } = params;
48941
- const pool = findPoolAddress(validator);
48942
- const lstMint = findPoolMintAddress(pool);
48943
- const poolStakeAuth = findPoolStakeAuthorityAddress(pool);
48944
- const lstAta = getAssociatedTokenAddressSync(lstMint, authority);
48945
- const [lstAccInfo, stakeAccInfoParsed, rentExemptReserve] = await Promise.all([
48946
- connection.getAccountInfo(lstAta),
48947
- connection.getParsedAccountInfo(stakeAccountPk),
48948
- connection.getMinimumBalanceForRentExemption(StakeProgram.space)
48949
- ]);
48950
- const stakeAccParsed = stakeAccInfoParsed?.value?.data;
48951
- const amountLamports = Math.round(Number(amount) * LAMPORTS_PER_SOL);
48952
- const stakeAccLamports = Number(stakeAccParsed?.parsed?.info?.stake?.delegation?.stake ?? 0);
48953
- const isFullStake = amountLamports >= stakeAccLamports;
48954
- const instructions2 = [];
48955
- const signers = [];
48956
- if (!lstAccInfo) {
48957
- instructions2.push(
48958
- createAssociatedTokenAccountInstruction(authority, lstAta, authority, lstMint)
48959
- );
48960
- }
48961
- let targetStakePubkey;
48962
- if (!isFullStake) {
48963
- const splitStakeAccount = Keypair.generate();
48964
- signers.push(splitStakeAccount);
48965
- targetStakePubkey = splitStakeAccount.publicKey;
48966
- instructions2.push(
48967
- ...StakeProgram.split(
48968
- {
48969
- stakePubkey: stakeAccountPk,
48970
- authorizedPubkey: authority,
48971
- splitStakePubkey: splitStakeAccount.publicKey,
48972
- lamports: amountLamports
48973
- },
48974
- rentExemptReserve
48975
- ).instructions
48976
- );
48977
- } else {
48978
- targetStakePubkey = stakeAccountPk;
48979
- }
48980
- const [authorizeStakerIx, authorizeWithdrawIx] = await Promise.all([
48981
- StakeProgram.authorize({
48982
- stakePubkey: targetStakePubkey,
48983
- authorizedPubkey: authority,
48984
- newAuthorizedPubkey: poolStakeAuth,
48985
- stakeAuthorizationType: StakeAuthorizationLayout.Staker
48986
- }).instructions,
48987
- StakeProgram.authorize({
48988
- stakePubkey: targetStakePubkey,
48989
- authorizedPubkey: authority,
48990
- newAuthorizedPubkey: poolStakeAuth,
48991
- stakeAuthorizationType: StakeAuthorizationLayout.Withdrawer
48992
- }).instructions
48993
- ]);
48994
- [authorizeStakerIx[0], authorizeWithdrawIx[0]].forEach((ix) => {
48995
- if (ix) {
48996
- ix.keys = ix.keys.map((key) => ({
48997
- ...key,
48998
- isWritable: key.pubkey.equals(SYSVAR_CLOCK_ID2) ? false : key.isWritable
48999
- }));
49000
- }
49001
- });
49002
- instructions2.push(...authorizeStakerIx, ...authorizeWithdrawIx);
49003
- const depositStakeIx = await SinglePoolInstruction.depositStake(
49004
- pool,
49005
- targetStakePubkey,
49006
- lstAta,
49007
- authority
49008
- );
49009
- instructions2.push(depositStakeIx);
49010
- return { instructions: instructions2, keys: signers };
49011
- }
49012
- async function makeMintStakedLstTx(params) {
49013
- const { connection, luts, blockhash: providedBlockhash } = params;
49014
- const { instructions: instructions2, keys } = await makeMintStakedLstIx(params);
49015
- const blockhash = providedBlockhash ?? (await connection.getLatestBlockhash("confirmed")).blockhash;
49016
- const message = new TransactionMessage({
49017
- payerKey: params.authority,
49018
- recentBlockhash: blockhash,
49019
- instructions: instructions2
49020
- }).compileToV0Message(luts);
49021
- const tx = new VersionedTransaction(message);
49022
- return addTransactionMetadata(tx, {
49023
- signers: keys,
49024
- addressLookupTables: luts,
49025
- type: "DEPOSIT_STAKE" /* DEPOSIT_STAKE */
49026
- });
49027
- }
49028
- async function makeRedeemStakedLstIx(params) {
49029
- const { amount, authority, validator, connection } = params;
49030
- const pool = findPoolAddress(validator);
49031
- const lstMint = findPoolMintAddress(pool);
49032
- const mintAuthority = findPoolMintAuthorityAddress(pool);
49033
- const lstAta = getAssociatedTokenAddressSync(lstMint, authority);
49034
- const rentExemption = await connection.getMinimumBalanceForRentExemption(
49035
- StakeProgram.space
49036
- );
49037
- const stakeAmount = new BigNumber3(new BigNumber3(amount).toString());
49038
- const instructions2 = [];
49039
- const signers = [];
49040
- const stakeAccount = Keypair.generate();
49041
- signers.push(stakeAccount);
49042
- instructions2.push(
49043
- SystemProgram.createAccount({
49044
- fromPubkey: authority,
49045
- newAccountPubkey: stakeAccount.publicKey,
49046
- lamports: rentExemption,
49047
- space: StakeProgram.space,
49048
- programId: StakeProgram.programId
49049
- })
49050
- );
49051
- instructions2.push(
49052
- createApproveInstruction(
49053
- lstAta,
49054
- mintAuthority,
49055
- authority,
49056
- BigInt(stakeAmount.multipliedBy(1e9).toFixed(0))
49057
- )
49058
- );
49059
- const withdrawStakeIx = await SinglePoolInstruction.withdrawStake(
49060
- pool,
49061
- stakeAccount.publicKey,
49062
- authority,
49063
- lstAta,
49064
- stakeAmount
49065
- );
49066
- instructions2.push(withdrawStakeIx);
49067
- return { instructions: instructions2, keys: signers };
49068
- }
49069
- async function makeRedeemStakedLstTx(params) {
49070
- const { connection, luts, blockhash: providedBlockhash } = params;
49071
- const { instructions: instructions2, keys } = await makeRedeemStakedLstIx(params);
49072
- const blockhash = providedBlockhash ?? (await connection.getLatestBlockhash("confirmed")).blockhash;
49073
- const message = new TransactionMessage({
49074
- payerKey: params.authority,
49075
- recentBlockhash: blockhash,
49076
- instructions: instructions2
49077
- }).compileToV0Message(luts);
49078
- const tx = new VersionedTransaction(message);
49079
- return addTransactionMetadata(tx, {
49080
- signers: keys,
49081
- addressLookupTables: luts,
49082
- type: "WITHDRAW_STAKE" /* WITHDRAW_STAKE */
49083
- });
49084
- }
49085
- async function makeMergeStakeAccountsTx(params) {
49086
- const {
49087
- authority,
49088
- sourceStakeAccount,
49089
- destinationStakeAccount,
49090
- connection,
49091
- luts,
49092
- blockhash: providedBlockhash
49093
- } = params;
49094
- const mergeIx = StakeProgram.merge({
49095
- stakePubkey: destinationStakeAccount,
49096
- sourceStakePubKey: sourceStakeAccount,
49097
- authorizedPubkey: authority
49098
- }).instructions;
49099
- const blockhash = providedBlockhash ?? (await connection.getLatestBlockhash("confirmed")).blockhash;
49100
- const message = new TransactionMessage({
49101
- payerKey: authority,
49102
- recentBlockhash: blockhash,
49103
- instructions: mergeIx
49104
- }).compileToV0Message(luts);
49105
- const tx = new VersionedTransaction(message);
49106
- return addTransactionMetadata(tx, {
49107
- addressLookupTables: luts,
49108
- type: "MERGE_STAKE_ACCOUNTS" /* MERGE_STAKE_ACCOUNTS */
49109
- });
49110
- }
49111
48505
 
49112
48506
  // src/services/account/services/account-simulation.service.ts
49113
48507
  async function simulateAccountHealthCacheWithFallback(params) {
@@ -49956,7 +49350,7 @@ async function getTitanExactOutViaWebSocket(params) {
49956
49350
  inputMint: new PublicKey(inputMint).toBytes(),
49957
49351
  outputMint: new PublicKey(outputMint).toBytes(),
49958
49352
  amount,
49959
- swapMode: "ExactOut",
49353
+ swapMode: "ExactOut" /* ExactOut */,
49960
49354
  slippageBps
49961
49355
  },
49962
49356
  transaction: {
@@ -50214,140 +49608,575 @@ var getExactOutEstimate = async (params) => {
50214
49608
  );
50215
49609
  }
50216
49610
  }
50217
- const firstProvider = attempts[0]?.provider ?? "Swap";
50218
- throw TransactionBuildingError.swapQuoteFailed(
50219
- firstProvider,
50220
- inputMint,
50221
- outputMint,
50222
- lastError?.message ?? "No swap route available"
50223
- );
50224
- };
50225
- function mapJupiterQuoteToSwapQuoteResult(quote) {
50226
- return {
50227
- inAmount: quote.inAmount,
50228
- outAmount: quote.outAmount,
50229
- otherAmountThreshold: quote.otherAmountThreshold,
50230
- slippageBps: quote.slippageBps,
50231
- platformFee: quote.platformFee ? {
50232
- amount: quote.platformFee.amount ?? "0",
50233
- feeBps: quote.platformFee.feeBps ?? 0
50234
- } : void 0,
50235
- priceImpactPct: quote.priceImpactPct,
50236
- contextSlot: quote.contextSlot,
50237
- timeTaken: quote.timeTaken,
50238
- provider: "JUPITER" /* JUPITER */
50239
- };
50240
- }
50241
-
50242
- // src/services/account/utils/jupiter.utils.ts
50243
- var REFERRAL_PROGRAM_ID = new PublicKey("REFER4ZgmyYx9c6He5XfaTMiGfdLwRnkV4RPp9t9iF3");
50244
- var REFERRAL_ACCOUNT_PUBKEY = new PublicKey("Mm7HcujSK2JzPW4eX7g4oqTXbWYDuFxapNMHXe8yp1B");
50245
- var getFeeAccount = (mint) => {
50246
- const [feeAccount] = PublicKey.findProgramAddressSync(
50247
- [Buffer.from("referral_ata"), REFERRAL_ACCOUNT_PUBKEY.toBuffer(), mint.toBuffer()],
50248
- REFERRAL_PROGRAM_ID
50249
- );
50250
- return feeAccount.toBase58();
50251
- };
50252
- var checkFeeAccount = async (connection, mint) => {
50253
- const feeAccount = getFeeAccount(mint);
50254
- const hasFeeAccount = !!await connection.getAccountInfo(new PublicKey(feeAccount));
50255
- return { feeAccount, hasFeeAccount };
50256
- };
50257
- function deserializeJupiterInstruction(instruction) {
50258
- return new TransactionInstruction({
50259
- programId: new PublicKey(instruction.programId),
50260
- keys: instruction.accounts.map((key) => ({
50261
- pubkey: new PublicKey(key.pubkey),
50262
- isSigner: key.isSigner,
50263
- isWritable: key.isWritable
50264
- })),
50265
- data: Buffer.from(instruction.data, "base64")
50266
- });
50267
- }
50268
- function toJupiterConfig(apiConfig) {
50269
- if (!apiConfig) return void 0;
50270
- return {
50271
- basePath: apiConfig.basePath,
50272
- apiKey: apiConfig.apiKey ? () => apiConfig.apiKey : void 0,
50273
- headers: apiConfig.headers
50274
- };
49611
+ const firstProvider = attempts[0]?.provider ?? "Swap";
49612
+ throw TransactionBuildingError.swapQuoteFailed(
49613
+ firstProvider,
49614
+ inputMint,
49615
+ outputMint,
49616
+ lastError?.message ?? "No swap route available"
49617
+ );
49618
+ };
49619
+ function mapJupiterQuoteToSwapQuoteResult(quote) {
49620
+ return {
49621
+ inAmount: quote.inAmount,
49622
+ outAmount: quote.outAmount,
49623
+ otherAmountThreshold: quote.otherAmountThreshold,
49624
+ slippageBps: quote.slippageBps,
49625
+ platformFee: quote.platformFee ? {
49626
+ amount: quote.platformFee.amount ?? "0",
49627
+ feeBps: quote.platformFee.feeBps ?? 0
49628
+ } : void 0,
49629
+ priceImpactPct: quote.priceImpactPct,
49630
+ contextSlot: quote.contextSlot,
49631
+ timeTaken: quote.timeTaken,
49632
+ provider: "JUPITER" /* JUPITER */
49633
+ };
49634
+ }
49635
+
49636
+ // src/services/account/utils/jupiter.utils.ts
49637
+ var REFERRAL_PROGRAM_ID = new PublicKey("REFER4ZgmyYx9c6He5XfaTMiGfdLwRnkV4RPp9t9iF3");
49638
+ var REFERRAL_ACCOUNT_PUBKEY = new PublicKey("Mm7HcujSK2JzPW4eX7g4oqTXbWYDuFxapNMHXe8yp1B");
49639
+ var getFeeAccount = (mint) => {
49640
+ const [feeAccount] = PublicKey.findProgramAddressSync(
49641
+ [Buffer.from("referral_ata"), REFERRAL_ACCOUNT_PUBKEY.toBuffer(), mint.toBuffer()],
49642
+ REFERRAL_PROGRAM_ID
49643
+ );
49644
+ return feeAccount.toBase58();
49645
+ };
49646
+ var checkFeeAccount = async (connection, mint) => {
49647
+ const feeAccount = getFeeAccount(mint);
49648
+ const hasFeeAccount = !!await connection.getAccountInfo(new PublicKey(feeAccount));
49649
+ return { feeAccount, hasFeeAccount };
49650
+ };
49651
+ function deserializeJupiterInstruction(instruction) {
49652
+ return new TransactionInstruction({
49653
+ programId: new PublicKey(instruction.programId),
49654
+ keys: instruction.accounts.map((key) => ({
49655
+ pubkey: new PublicKey(key.pubkey),
49656
+ isSigner: key.isSigner,
49657
+ isWritable: key.isWritable
49658
+ })),
49659
+ data: Buffer.from(instruction.data, "base64")
49660
+ });
49661
+ }
49662
+ function toJupiterConfig(apiConfig) {
49663
+ if (!apiConfig) return void 0;
49664
+ return {
49665
+ basePath: apiConfig.basePath,
49666
+ apiKey: apiConfig.apiKey ? () => apiConfig.apiKey : void 0,
49667
+ headers: apiConfig.headers
49668
+ };
49669
+ }
49670
+ var getJupiterSwapIxsForFlashloan = async ({
49671
+ quoteParams,
49672
+ authority,
49673
+ connection,
49674
+ destinationTokenAccount,
49675
+ apiConfig,
49676
+ maxSwapAccounts
49677
+ }) => {
49678
+ const configParams = toJupiterConfig(apiConfig);
49679
+ const jupiterApiClient = configParams?.basePath ? new SwapApi(new Configuration(configParams)) : createJupiterApiClient(configParams);
49680
+ const feeMint = quoteParams.swapMode === "ExactIn" ? quoteParams.outputMint : quoteParams.inputMint;
49681
+ const { feeAccount, hasFeeAccount } = await checkFeeAccount(connection, new PublicKey(feeMint));
49682
+ const project0JupiterLut = (await connection.getAddressLookupTable(ADDRESS_LOOKUP_TABLE_FOR_SWAP))?.value;
49683
+ let finalQuoteParams = quoteParams;
49684
+ if (!hasFeeAccount) {
49685
+ console.warn("Warning: feeAccountInfo is undefined");
49686
+ finalQuoteParams = {
49687
+ ...quoteParams,
49688
+ platformFeeBps: void 0
49689
+ };
49690
+ }
49691
+ const JUPITER_MAX_ACCOUNTS_MARGIN = 4;
49692
+ const maxAccounts = maxSwapAccounts !== void 0 ? maxSwapAccounts - JUPITER_MAX_ACCOUNTS_MARGIN : 40;
49693
+ const swapQuote = await jupiterApiClient.quoteGet({
49694
+ ...finalQuoteParams,
49695
+ maxAccounts
49696
+ });
49697
+ const swapInstructionResponse = await jupiterApiClient.swapInstructionsPost({
49698
+ swapRequest: {
49699
+ quoteResponse: swapQuote,
49700
+ userPublicKey: authority.toBase58(),
49701
+ feeAccount: hasFeeAccount ? feeAccount : void 0,
49702
+ wrapAndUnwrapSol: false,
49703
+ destinationTokenAccount: destinationTokenAccount.toBase58()
49704
+ }
49705
+ });
49706
+ const lutAddresses = swapInstructionResponse.addressLookupTableAddresses;
49707
+ const lutAccountsRaw = await connection.getMultipleAccountsInfo(
49708
+ lutAddresses.map((address) => new PublicKey(address))
49709
+ );
49710
+ const addressLookupTableAccounts = lutAccountsRaw.map((accountInfo, index) => {
49711
+ const addressLookupTableAddress = lutAddresses[index];
49712
+ if (!accountInfo || !addressLookupTableAddress) {
49713
+ return null;
49714
+ }
49715
+ return new AddressLookupTableAccount({
49716
+ key: new PublicKey(addressLookupTableAddress),
49717
+ state: AddressLookupTableAccount.deserialize(accountInfo.data)
49718
+ });
49719
+ }).filter((account) => account !== null).concat(project0JupiterLut ? [project0JupiterLut] : []);
49720
+ const instruction = deserializeJupiterInstruction(swapInstructionResponse.swapInstruction);
49721
+ const setupInstructions = swapInstructionResponse.setupInstructions.map(
49722
+ deserializeJupiterInstruction
49723
+ );
49724
+ return {
49725
+ swapInstructions: [instruction],
49726
+ setupInstructions,
49727
+ addressLookupTableAddresses: addressLookupTableAccounts,
49728
+ quoteResponse: mapJupiterQuoteToSwapQuoteResult(swapQuote)
49729
+ };
49730
+ };
49731
+
49732
+ // src/services/account/utils/misc.utils.ts
49733
+ function floor(value, decimals) {
49734
+ return Math.floor(value * 10 ** decimals) / 10 ** decimals;
49735
+ }
49736
+ function ceil(value, decimals) {
49737
+ return Math.ceil(value * 10 ** decimals) / 10 ** decimals;
49738
+ }
49739
+ function computeClosePositionTokenAmount(position, mintDecimals) {
49740
+ const closePositionTokenAmount = position.isLending ? floor(position.amount, mintDecimals) : ceil(position.amount, mintDecimals);
49741
+ return closePositionTokenAmount;
49742
+ }
49743
+ function isWholePosition(position, amount, mintDecimals) {
49744
+ const closePositionTokenAmount = computeClosePositionTokenAmount(position, mintDecimals);
49745
+ return amount >= closePositionTokenAmount;
49746
+ }
49747
+ var SWAP_MERGE_OVERHEAD = 150;
49748
+ var FL_IX_OVERHEAD = 52;
49749
+ function compactU16Size(n) {
49750
+ return n < 128 ? 1 : n < 16384 ? 2 : 3;
49751
+ }
49752
+ function computeV0TxSize(ixs, payerKey, luts) {
49753
+ const keyMap = /* @__PURE__ */ new Map();
49754
+ const payerStr = payerKey.toBase58();
49755
+ keyMap.set(payerStr, { isSigner: true, isWritable: true });
49756
+ const programIds = /* @__PURE__ */ new Set();
49757
+ for (const ix of ixs) {
49758
+ const progStr = ix.programId.toBase58();
49759
+ programIds.add(progStr);
49760
+ if (!keyMap.has(progStr)) {
49761
+ keyMap.set(progStr, { isSigner: false, isWritable: false });
49762
+ }
49763
+ for (const meta of ix.keys) {
49764
+ const keyStr = meta.pubkey.toBase58();
49765
+ const existing = keyMap.get(keyStr);
49766
+ if (existing) {
49767
+ existing.isSigner = existing.isSigner || meta.isSigner;
49768
+ existing.isWritable = existing.isWritable || meta.isWritable;
49769
+ } else {
49770
+ keyMap.set(keyStr, { isSigner: meta.isSigner, isWritable: meta.isWritable });
49771
+ }
49772
+ }
49773
+ }
49774
+ const lutLookup = /* @__PURE__ */ new Map();
49775
+ for (let li = 0; li < luts.length; li++) {
49776
+ const addresses = luts[li].state.addresses;
49777
+ for (let ai = 0; ai < addresses.length; ai++) {
49778
+ const addrStr = addresses[ai].toBase58();
49779
+ if (!lutLookup.has(addrStr)) {
49780
+ lutLookup.set(addrStr, { lutIdx: li, addrIdx: ai });
49781
+ }
49782
+ }
49783
+ }
49784
+ let numStaticKeys = 0;
49785
+ let numWritableStaticKeys = 0;
49786
+ const lutWritableIdxs = luts.map(() => /* @__PURE__ */ new Set());
49787
+ const lutReadonlyIdxs = luts.map(() => /* @__PURE__ */ new Set());
49788
+ for (const [keyStr, props] of keyMap) {
49789
+ if (props.isSigner || programIds.has(keyStr)) {
49790
+ numStaticKeys++;
49791
+ if (props.isWritable) numWritableStaticKeys++;
49792
+ continue;
49793
+ }
49794
+ const lutEntry = lutLookup.get(keyStr);
49795
+ if (lutEntry) {
49796
+ if (props.isWritable) {
49797
+ lutWritableIdxs[lutEntry.lutIdx].add(lutEntry.addrIdx);
49798
+ } else {
49799
+ lutReadonlyIdxs[lutEntry.lutIdx].add(lutEntry.addrIdx);
49800
+ }
49801
+ } else {
49802
+ numStaticKeys++;
49803
+ if (props.isWritable) numWritableStaticKeys++;
49804
+ }
49805
+ }
49806
+ const fixedOverhead = 101;
49807
+ const staticKeysSection = compactU16Size(numStaticKeys) + numStaticKeys * 32;
49808
+ let ixSection = compactU16Size(ixs.length);
49809
+ for (const ix of ixs) {
49810
+ const numAccounts = ix.keys.length;
49811
+ ixSection += 1 + // programId index
49812
+ compactU16Size(numAccounts) + numAccounts + // account key indexes
49813
+ compactU16Size(ix.data.length) + ix.data.length;
49814
+ }
49815
+ let numUsedLuts = 0;
49816
+ let lutSection = 0;
49817
+ for (let li = 0; li < luts.length; li++) {
49818
+ const wCount = lutWritableIdxs[li].size;
49819
+ const rCount = lutReadonlyIdxs[li].size;
49820
+ if (wCount === 0 && rCount === 0) continue;
49821
+ numUsedLuts++;
49822
+ lutSection += 32 + // LUT address
49823
+ compactU16Size(wCount) + wCount + // writable indexes
49824
+ compactU16Size(rCount) + rCount;
49825
+ }
49826
+ lutSection += compactU16Size(numUsedLuts);
49827
+ let totalLutKeys = 0;
49828
+ for (let li = 0; li < luts.length; li++) {
49829
+ totalLutKeys += lutWritableIdxs[li].size + lutReadonlyIdxs[li].size;
49830
+ }
49831
+ const accountCount = numStaticKeys + totalLutKeys;
49832
+ let totalLutWritableKeys = 0;
49833
+ for (let li = 0; li < luts.length; li++) {
49834
+ totalLutWritableKeys += lutWritableIdxs[li].size;
49835
+ }
49836
+ const writableAccountCount = numWritableStaticKeys + totalLutWritableKeys;
49837
+ const size = fixedOverhead + staticKeysSection + ixSection + lutSection + 1;
49838
+ return { size, accountCount, writableAccountCount };
49839
+ }
49840
+ function computeFlashLoanNonSwapBudget({
49841
+ program,
49842
+ marginfiAccount,
49843
+ ixs,
49844
+ bankMap,
49845
+ addressLookupTableAccounts
49846
+ }) {
49847
+ const projectedActiveBanksKeys = computeProjectedActiveBanksNoCpi(
49848
+ marginfiAccount.balances,
49849
+ ixs,
49850
+ program
49851
+ );
49852
+ const projectedActiveBanks = projectedActiveBanksKeys.map((key) => {
49853
+ const b = bankMap.get(key.toBase58());
49854
+ if (!b) throw new Error(`Bank ${key.toBase58()} not found in computeFlashLoanNonSwapBudget`);
49855
+ return b;
49856
+ });
49857
+ const endIndex = ixs.length + 1;
49858
+ const beginFlIx = sync_instructions_default.makeBeginFlashLoanIx(
49859
+ program.programId,
49860
+ { marginfiAccount: marginfiAccount.address, authority: marginfiAccount.authority },
49861
+ { endIndex: new BN11(endIndex) }
49862
+ );
49863
+ const endFlRemainingAccounts = computeHealthAccountMetas(projectedActiveBanks);
49864
+ const endFlIx = sync_instructions_default.makeEndFlashLoanIx(
49865
+ program.programId,
49866
+ { marginfiAccount: marginfiAccount.address, authority: marginfiAccount.authority },
49867
+ endFlRemainingAccounts.map((pubkey) => ({ pubkey, isSigner: false, isWritable: false }))
49868
+ );
49869
+ const allNonSwapIxs = [beginFlIx, ...ixs, endFlIx];
49870
+ const nonSwapMsg = new TransactionMessage({
49871
+ payerKey: marginfiAccount.authority,
49872
+ recentBlockhash: PublicKey.default.toBase58(),
49873
+ instructions: allNonSwapIxs
49874
+ }).compileToV0Message(addressLookupTableAccounts);
49875
+ const nonSwapSize = new VersionedTransaction(nonSwapMsg).serialize().length;
49876
+ const { header, staticAccountKeys, addressTableLookups } = nonSwapMsg;
49877
+ const nonSwapTotal = staticAccountKeys.length + addressTableLookups.reduce(
49878
+ (s, l) => s + l.writableIndexes.length + l.readonlyIndexes.length,
49879
+ 0
49880
+ );
49881
+ const sizeConstraint = MAX_TX_SIZE - nonSwapSize - SWAP_MERGE_OVERHEAD;
49882
+ const maxSwapTotalAccounts = MAX_ACCOUNT_LOCKS - nonSwapTotal;
49883
+ console.log("[flashloan-budget]", {
49884
+ method: "compiled",
49885
+ nonSwapSize,
49886
+ nonSwapTotal,
49887
+ sizeConstraint,
49888
+ maxSwapTotalAccounts
49889
+ });
49890
+ return { sizeConstraint, maxSwapTotalAccounts };
49891
+ }
49892
+ function compileFlashloanPrecheck({
49893
+ allIxs,
49894
+ payer,
49895
+ luts,
49896
+ sizeConstraint,
49897
+ swapIxCount,
49898
+ swapLutCount
49899
+ }) {
49900
+ const msg = new TransactionMessage({
49901
+ payerKey: payer,
49902
+ recentBlockhash: PublicKey.default.toBase58(),
49903
+ instructions: allIxs
49904
+ }).compileToV0Message(luts);
49905
+ const rawSize = new VersionedTransaction(msg).serialize().length;
49906
+ const fullTxSize = rawSize + FL_IX_OVERHEAD;
49907
+ const overshoot = fullTxSize - MAX_TX_SIZE;
49908
+ const { header, staticAccountKeys, addressTableLookups } = msg;
49909
+ const writableStatic = staticAccountKeys.length - header.numReadonlySignedAccounts - header.numReadonlyUnsignedAccounts;
49910
+ const writableLut = addressTableLookups.reduce((s, l) => s + l.writableIndexes.length, 0);
49911
+ const writableAccounts = writableStatic + writableLut;
49912
+ const totalAccounts = staticAccountKeys.length + addressTableLookups.reduce(
49913
+ (s, l) => s + l.writableIndexes.length + l.readonlyIndexes.length,
49914
+ 0
49915
+ );
49916
+ console.log("[flashloan-precheck]", {
49917
+ fullTxSize,
49918
+ overshoot,
49919
+ sizeConstraint,
49920
+ writableAccounts,
49921
+ totalAccounts,
49922
+ staticKeys: staticAccountKeys.length,
49923
+ numLuts: addressTableLookups.length,
49924
+ swapIxCount,
49925
+ swapLutCount
49926
+ });
49927
+ return { fullTxSize, overshoot, writableAccounts, totalAccounts };
49928
+ }
49929
+ async function buildBudgetIx(config, program, marginfiAccount, bankMap, bankMetadataMap, overrideInferAccounts) {
49930
+ const { bank, tokenProgram } = config;
49931
+ switch (config.type) {
49932
+ case "borrow":
49933
+ return makeBorrowIx3({
49934
+ program,
49935
+ bank,
49936
+ bankMap,
49937
+ tokenProgram,
49938
+ amount: 1,
49939
+ marginfiAccount,
49940
+ authority: marginfiAccount.authority,
49941
+ isSync: true,
49942
+ opts: { createAtas: false, wrapAndUnwrapSol: false, overrideInferAccounts }
49943
+ });
49944
+ case "repay":
49945
+ return makeRepayIx3({
49946
+ program,
49947
+ bank,
49948
+ tokenProgram,
49949
+ amount: 1,
49950
+ accountAddress: marginfiAccount.address,
49951
+ authority: marginfiAccount.authority,
49952
+ repayAll: false,
49953
+ isSync: true,
49954
+ opts: { wrapAndUnwrapSol: false, overrideInferAccounts }
49955
+ });
49956
+ case "deposit":
49957
+ return buildDepositBudgetIx(
49958
+ config,
49959
+ program,
49960
+ marginfiAccount,
49961
+ bankMetadataMap,
49962
+ overrideInferAccounts
49963
+ );
49964
+ case "withdraw":
49965
+ return buildWithdrawBudgetIx(
49966
+ config,
49967
+ program,
49968
+ marginfiAccount,
49969
+ bankMap,
49970
+ bankMetadataMap,
49971
+ overrideInferAccounts
49972
+ );
49973
+ }
49974
+ }
49975
+ async function buildDepositBudgetIx(config, program, marginfiAccount, bankMetadataMap, overrideInferAccounts) {
49976
+ const { bank, tokenProgram } = config;
49977
+ const opts = { wrapAndUnwrapSol: false, overrideInferAccounts };
49978
+ switch (bank.config.assetTag) {
49979
+ case 3 /* KAMINO */: {
49980
+ const reserve = bankMetadataMap[bank.address.toBase58()]?.kaminoStates?.reserveState;
49981
+ if (!reserve) {
49982
+ throw TransactionBuildingError.kaminoReserveNotFound(
49983
+ bank.address.toBase58(),
49984
+ bank.mint.toBase58(),
49985
+ bank.tokenSymbol
49986
+ );
49987
+ }
49988
+ return makeKaminoDepositIx3({
49989
+ program,
49990
+ bank,
49991
+ tokenProgram,
49992
+ amount: 1,
49993
+ accountAddress: marginfiAccount.address,
49994
+ authority: marginfiAccount.authority,
49995
+ group: marginfiAccount.group,
49996
+ reserve,
49997
+ isSync: true,
49998
+ opts
49999
+ });
50000
+ }
50001
+ case 4 /* DRIFT */: {
50002
+ const driftState = bankMetadataMap[bank.address.toBase58()]?.driftStates;
50003
+ if (!driftState) {
50004
+ throw TransactionBuildingError.driftStateNotFound(
50005
+ bank.address.toBase58(),
50006
+ bank.mint.toBase58(),
50007
+ bank.tokenSymbol
50008
+ );
50009
+ }
50010
+ return makeDriftDepositIx3({
50011
+ program,
50012
+ bank,
50013
+ tokenProgram,
50014
+ amount: 1,
50015
+ accountAddress: marginfiAccount.address,
50016
+ authority: marginfiAccount.authority,
50017
+ group: marginfiAccount.group,
50018
+ driftMarketIndex: driftState.spotMarketState.marketIndex,
50019
+ driftOracle: driftState.spotMarketState.oracle,
50020
+ isSync: true,
50021
+ opts
50022
+ });
50023
+ }
50024
+ case 6 /* JUPLEND */: {
50025
+ return makeJuplendDepositIx2({
50026
+ program,
50027
+ bank,
50028
+ tokenProgram,
50029
+ amount: 1,
50030
+ accountAddress: marginfiAccount.address,
50031
+ authority: marginfiAccount.authority,
50032
+ group: marginfiAccount.group,
50033
+ isSync: true,
50034
+ opts
50035
+ });
50036
+ }
50037
+ default: {
50038
+ return makeDepositIx3({
50039
+ program,
50040
+ bank,
50041
+ tokenProgram,
50042
+ amount: 1,
50043
+ accountAddress: marginfiAccount.address,
50044
+ authority: marginfiAccount.authority,
50045
+ group: marginfiAccount.group,
50046
+ isSync: true,
50047
+ opts
50048
+ });
50049
+ }
50050
+ }
50275
50051
  }
50276
- var getJupiterSwapIxsForFlashloan = async ({
50277
- quoteParams,
50278
- authority,
50279
- connection,
50280
- destinationTokenAccount,
50281
- apiConfig,
50282
- maxSwapAccounts
50283
- }) => {
50284
- const configParams = toJupiterConfig(apiConfig);
50285
- const jupiterApiClient = configParams?.basePath ? new SwapApi(new Configuration(configParams)) : createJupiterApiClient(configParams);
50286
- const feeMint = quoteParams.swapMode === "ExactIn" ? quoteParams.outputMint : quoteParams.inputMint;
50287
- const { feeAccount, hasFeeAccount } = await checkFeeAccount(connection, new PublicKey(feeMint));
50288
- const project0JupiterLut = (await connection.getAddressLookupTable(ADDRESS_LOOKUP_TABLE_FOR_SWAP))?.value;
50289
- let finalQuoteParams = quoteParams;
50290
- if (!hasFeeAccount) {
50291
- console.warn("Warning: feeAccountInfo is undefined");
50292
- finalQuoteParams = {
50293
- ...quoteParams,
50294
- platformFeeBps: void 0
50295
- };
50296
- }
50297
- const maxAccounts = maxSwapAccounts ?? 40;
50298
- const swapQuote = await jupiterApiClient.quoteGet({
50299
- ...finalQuoteParams,
50300
- maxAccounts
50301
- });
50302
- const swapInstructionResponse = await jupiterApiClient.swapInstructionsPost({
50303
- swapRequest: {
50304
- quoteResponse: swapQuote,
50305
- userPublicKey: authority.toBase58(),
50306
- feeAccount: hasFeeAccount ? feeAccount : void 0,
50307
- wrapAndUnwrapSol: false,
50308
- destinationTokenAccount: destinationTokenAccount.toBase58()
50052
+ async function buildWithdrawBudgetIx(config, program, marginfiAccount, bankMap, bankMetadataMap, overrideInferAccounts) {
50053
+ const { bank, tokenProgram } = config;
50054
+ const opts = { createAtas: false, wrapAndUnwrapSol: false, overrideInferAccounts };
50055
+ switch (bank.config.assetTag) {
50056
+ case 3 /* KAMINO */: {
50057
+ const reserve = bankMetadataMap[bank.address.toBase58()]?.kaminoStates?.reserveState;
50058
+ if (!reserve) {
50059
+ throw TransactionBuildingError.kaminoReserveNotFound(
50060
+ bank.address.toBase58(),
50061
+ bank.mint.toBase58(),
50062
+ bank.tokenSymbol
50063
+ );
50064
+ }
50065
+ return makeKaminoWithdrawIx3({
50066
+ program,
50067
+ bank,
50068
+ bankMap,
50069
+ tokenProgram,
50070
+ cTokenAmount: 1,
50071
+ marginfiAccount,
50072
+ authority: marginfiAccount.authority,
50073
+ reserve,
50074
+ withdrawAll: false,
50075
+ isSync: true,
50076
+ opts
50077
+ });
50309
50078
  }
50310
- });
50311
- const lutAddresses = swapInstructionResponse.addressLookupTableAddresses;
50312
- const lutAccountsRaw = await connection.getMultipleAccountsInfo(
50313
- lutAddresses.map((address) => new PublicKey(address))
50314
- );
50315
- const addressLookupTableAccounts = lutAccountsRaw.map((accountInfo, index) => {
50316
- const addressLookupTableAddress = lutAddresses[index];
50317
- if (!accountInfo || !addressLookupTableAddress) {
50318
- return null;
50079
+ case 4 /* DRIFT */: {
50080
+ const driftState = bankMetadataMap[bank.address.toBase58()]?.driftStates;
50081
+ if (!driftState) {
50082
+ throw TransactionBuildingError.driftStateNotFound(
50083
+ bank.address.toBase58(),
50084
+ bank.mint.toBase58(),
50085
+ bank.tokenSymbol
50086
+ );
50087
+ }
50088
+ return makeDriftWithdrawIx3({
50089
+ program,
50090
+ bank,
50091
+ bankMap,
50092
+ tokenProgram,
50093
+ amount: 1,
50094
+ marginfiAccount,
50095
+ authority: marginfiAccount.authority,
50096
+ driftSpotMarket: driftState.spotMarketState,
50097
+ userRewards: driftState.userRewards,
50098
+ withdrawAll: false,
50099
+ isSync: true,
50100
+ opts
50101
+ });
50319
50102
  }
50320
- return new AddressLookupTableAccount({
50321
- key: new PublicKey(addressLookupTableAddress),
50322
- state: AddressLookupTableAccount.deserialize(accountInfo.data)
50323
- });
50324
- }).filter((account) => account !== null).concat(project0JupiterLut ? [project0JupiterLut] : []);
50325
- const instruction = deserializeJupiterInstruction(swapInstructionResponse.swapInstruction);
50326
- const setupInstructions = swapInstructionResponse.setupInstructions.map(
50327
- deserializeJupiterInstruction
50328
- );
50329
- return {
50330
- swapInstructions: [instruction],
50331
- setupInstructions,
50332
- addressLookupTableAddresses: addressLookupTableAccounts,
50333
- quoteResponse: mapJupiterQuoteToSwapQuoteResult(swapQuote)
50334
- };
50335
- };
50336
-
50337
- // src/services/account/utils/misc.utils.ts
50338
- function floor(value, decimals) {
50339
- return Math.floor(value * 10 ** decimals) / 10 ** decimals;
50340
- }
50341
- function ceil(value, decimals) {
50342
- return Math.ceil(value * 10 ** decimals) / 10 ** decimals;
50343
- }
50344
- function computeClosePositionTokenAmount(position, mintDecimals) {
50345
- const closePositionTokenAmount = position.isLending ? floor(position.amount, mintDecimals) : ceil(position.amount, mintDecimals);
50346
- return closePositionTokenAmount;
50103
+ case 6 /* JUPLEND */: {
50104
+ const jupLendState = bankMetadataMap[bank.address.toBase58()]?.jupLendStates;
50105
+ if (!jupLendState) {
50106
+ throw TransactionBuildingError.jupLendStateNotFound(
50107
+ bank.address.toBase58(),
50108
+ bank.mint.toBase58(),
50109
+ bank.tokenSymbol
50110
+ );
50111
+ }
50112
+ return makeJuplendWithdrawIx2({
50113
+ program,
50114
+ bank,
50115
+ bankMap,
50116
+ tokenProgram,
50117
+ amount: 1,
50118
+ marginfiAccount,
50119
+ authority: marginfiAccount.authority,
50120
+ jupLendingState: jupLendState.jupLendingState,
50121
+ withdrawAll: false,
50122
+ opts
50123
+ });
50124
+ }
50125
+ default: {
50126
+ return makeWithdrawIx3({
50127
+ program,
50128
+ bank,
50129
+ bankMap,
50130
+ tokenProgram,
50131
+ amount: 1,
50132
+ marginfiAccount,
50133
+ authority: marginfiAccount.authority,
50134
+ withdrawAll: false,
50135
+ isSync: true,
50136
+ opts
50137
+ });
50138
+ }
50139
+ }
50347
50140
  }
50348
- function isWholePosition(position, amount, mintDecimals) {
50349
- const closePositionTokenAmount = computeClosePositionTokenAmount(position, mintDecimals);
50350
- return amount >= closePositionTokenAmount;
50141
+ async function computeFlashloanSwapConstraints({
50142
+ program,
50143
+ marginfiAccount,
50144
+ bankMap,
50145
+ addressLookupTableAccounts,
50146
+ bankMetadataMap,
50147
+ primaryIx,
50148
+ secondaryIx,
50149
+ overrideInferAccounts
50150
+ }) {
50151
+ const cuRequestIxs = [
50152
+ ComputeBudgetProgram.setComputeUnitLimit({ units: 12e5 }),
50153
+ ComputeBudgetProgram.setComputeUnitPrice({ microLamports: 1 })
50154
+ ];
50155
+ const [primaryResult, secondaryResult] = await Promise.all([
50156
+ buildBudgetIx(
50157
+ primaryIx,
50158
+ program,
50159
+ marginfiAccount,
50160
+ bankMap,
50161
+ bankMetadataMap,
50162
+ overrideInferAccounts
50163
+ ),
50164
+ buildBudgetIx(
50165
+ secondaryIx,
50166
+ program,
50167
+ marginfiAccount,
50168
+ bankMap,
50169
+ bankMetadataMap,
50170
+ overrideInferAccounts
50171
+ )
50172
+ ]);
50173
+ return computeFlashLoanNonSwapBudget({
50174
+ program,
50175
+ marginfiAccount,
50176
+ bankMap,
50177
+ addressLookupTableAccounts,
50178
+ ixs: [...cuRequestIxs, ...primaryResult.instructions, ...secondaryResult.instructions]
50179
+ });
50351
50180
  }
50352
50181
 
50353
50182
  // src/services/price/utils/smart-crank.utils.ts
@@ -51827,6 +51656,78 @@ function computeRemainingCapacity(bank) {
51827
51656
  };
51828
51657
  }
51829
51658
 
51659
+ // src/services/bank/utils/bank-metrics.utils.ts
51660
+ function computeBankTotalDeposits(bank, assetShareValueMultiplier) {
51661
+ const totalAssets = getTotalAssetQuantity(bank).times(
51662
+ assetShareValueMultiplier ?? 1
51663
+ );
51664
+ return nativeToUi(totalAssets, bank.mintDecimals);
51665
+ }
51666
+ function computeBankTotalBorrows(bank) {
51667
+ return nativeToUi(getTotalLiabilityQuantity(bank), bank.mintDecimals);
51668
+ }
51669
+ function computeBankTotalDepositsUsd(bank, oraclePrice, assetShareValueMultiplier) {
51670
+ return computeUsdValue({
51671
+ bank,
51672
+ oraclePrice,
51673
+ quantity: getTotalAssetQuantity(bank),
51674
+ priceBias: 1 /* None */,
51675
+ isWeightedPrice: false,
51676
+ assetShareValueMultiplier
51677
+ }).toNumber();
51678
+ }
51679
+ function computeBankTotalBorrowsUsd(bank, oraclePrice) {
51680
+ return computeUsdValue({
51681
+ bank,
51682
+ oraclePrice,
51683
+ quantity: getTotalLiabilityQuantity(bank),
51684
+ priceBias: 1 /* None */,
51685
+ isWeightedPrice: false
51686
+ }).toNumber();
51687
+ }
51688
+ function computeBankPoolSize(bank, assetShareValueMultiplier) {
51689
+ const totalDeposits = computeBankTotalDeposits(bank, assetShareValueMultiplier);
51690
+ const totalBorrows = computeBankTotalBorrows(bank);
51691
+ const borrowCap = nativeToUi(bank.config.borrowLimit, bank.mintDecimals);
51692
+ return Math.max(0, Math.min(totalDeposits, borrowCap) - totalBorrows);
51693
+ }
51694
+ function computeBankDepositCapRemaining(bank) {
51695
+ const { depositCapacity } = computeRemainingCapacity(bank);
51696
+ return Math.max(0, nativeToUi(depositCapacity, bank.mintDecimals));
51697
+ }
51698
+ function computeBankBorrowCapRemaining(bank) {
51699
+ const { borrowCapacity } = computeRemainingCapacity(bank);
51700
+ return Math.max(0, nativeToUi(borrowCapacity, bank.mintDecimals));
51701
+ }
51702
+ function computeBankSupplyApy(bank) {
51703
+ return aprToApy(computeInterestRates(bank).lendingRate.toNumber());
51704
+ }
51705
+ function computeBankBorrowApy(bank) {
51706
+ return aprToApy(computeInterestRates(bank).borrowingRate.toNumber());
51707
+ }
51708
+ function computeBankMetrics(params) {
51709
+ const { bank, oraclePrice, assetShareValueMultiplier, symbol = "" } = params;
51710
+ return {
51711
+ symbol,
51712
+ totalDeposits: computeBankTotalDeposits(bank, assetShareValueMultiplier),
51713
+ totalBorrows: computeBankTotalBorrows(bank),
51714
+ totalDepositsUsd: computeBankTotalDepositsUsd(
51715
+ bank,
51716
+ oraclePrice,
51717
+ assetShareValueMultiplier
51718
+ ),
51719
+ totalBorrowsUsd: computeBankTotalBorrowsUsd(bank, oraclePrice),
51720
+ utilizationRate: computeUtilizationRate(bank).toNumber(),
51721
+ poolSize: computeBankPoolSize(bank, assetShareValueMultiplier),
51722
+ depositCap: nativeToUi(bank.config.depositLimit, bank.mintDecimals),
51723
+ borrowCap: nativeToUi(bank.config.borrowLimit, bank.mintDecimals),
51724
+ depositCapRemaining: computeBankDepositCapRemaining(bank),
51725
+ borrowCapRemaining: computeBankBorrowCapRemaining(bank),
51726
+ supplyApy: computeBankSupplyApy(bank),
51727
+ borrowApy: computeBankBorrowApy(bank)
51728
+ };
51729
+ }
51730
+
51830
51731
  // src/services/bank/bank.service.ts
51831
51732
  async function freezeBankConfigIx(program, bankAddress, bankConfigOpt) {
51832
51733
  let bankConfigRaw;
@@ -52611,6 +52512,230 @@ function getValidatorVoteAccountByBank() {
52611
52512
  }
52612
52513
  return _voteAccountByBank;
52613
52514
  }
52515
+ async function computeStakedBankMultipliers(stakedBanks, connection) {
52516
+ const multiplierByBank = /* @__PURE__ */ new Map();
52517
+ if (stakedBanks.length === 0) {
52518
+ return multiplierByBank;
52519
+ }
52520
+ const metadataMap = getStakedBankMetadataMap();
52521
+ const stakedBankAddresses = [];
52522
+ const poolStakeAddresses = [];
52523
+ const lstMintAddresses = [];
52524
+ for (const bank of stakedBanks) {
52525
+ const metadata = metadataMap.get(bank.address.toBase58());
52526
+ if (!metadata) {
52527
+ multiplierByBank.set(bank.address.toBase58(), new BigNumber3(1));
52528
+ continue;
52529
+ }
52530
+ const pool = findPoolAddress(new PublicKey(metadata.validatorVoteAccount));
52531
+ stakedBankAddresses.push(bank.address.toBase58());
52532
+ poolStakeAddresses.push(findPoolStakeAddress(pool));
52533
+ lstMintAddresses.push(findPoolMintAddress(pool));
52534
+ }
52535
+ if (stakedBankAddresses.length === 0) {
52536
+ return multiplierByBank;
52537
+ }
52538
+ const allAddresses = [
52539
+ ...poolStakeAddresses.map((a) => a.toBase58()),
52540
+ ...lstMintAddresses.map((a) => a.toBase58())
52541
+ ];
52542
+ const accountInfos = await chunkedGetRawMultipleAccountInfoOrdered(connection, allAddresses);
52543
+ const poolStakeInfos = accountInfos.slice(0, poolStakeAddresses.length);
52544
+ const lstMintInfos = accountInfos.slice(poolStakeAddresses.length);
52545
+ for (let i = 0; i < stakedBankAddresses.length; i++) {
52546
+ const bankAddr = stakedBankAddresses[i];
52547
+ const poolStakeInfo = poolStakeInfos[i];
52548
+ const lstMintInfo = lstMintInfos[i];
52549
+ if (!poolStakeInfo || !lstMintInfo) {
52550
+ multiplierByBank.set(bankAddr, new BigNumber3(1));
52551
+ continue;
52552
+ }
52553
+ const stakeLamports = poolStakeInfo.lamports;
52554
+ const supplyBuffer = lstMintInfo.data.slice(36, 44);
52555
+ const lstMintSupply = Number(Buffer.from(supplyBuffer).readBigUInt64LE(0));
52556
+ if (lstMintSupply === 0) {
52557
+ multiplierByBank.set(bankAddr, new BigNumber3(1));
52558
+ continue;
52559
+ }
52560
+ const adjustedStake = Math.max(stakeLamports - LAMPORTS_PER_SOL, 0);
52561
+ const multiplier = new BigNumber3(adjustedStake).dividedBy(lstMintSupply);
52562
+ multiplierByBank.set(bankAddr, multiplier);
52563
+ }
52564
+ return multiplierByBank;
52565
+ }
52566
+ var SYSVAR_CLOCK_ID2 = new PublicKey("SysvarC1ock11111111111111111111111111111111");
52567
+ async function makeMintStakedLstIx(params) {
52568
+ const { amount, authority, stakeAccountPk, validator, connection } = params;
52569
+ const pool = findPoolAddress(validator);
52570
+ const lstMint = findPoolMintAddress(pool);
52571
+ const poolStakeAuth = findPoolStakeAuthorityAddress(pool);
52572
+ const lstAta = getAssociatedTokenAddressSync(lstMint, authority);
52573
+ const [lstAccInfo, stakeAccInfoParsed, rentExemptReserve] = await Promise.all([
52574
+ connection.getAccountInfo(lstAta),
52575
+ connection.getParsedAccountInfo(stakeAccountPk),
52576
+ connection.getMinimumBalanceForRentExemption(StakeProgram.space)
52577
+ ]);
52578
+ const stakeAccParsed = stakeAccInfoParsed?.value?.data;
52579
+ const amountLamports = Math.round(Number(amount) * LAMPORTS_PER_SOL);
52580
+ const stakeAccLamports = Number(stakeAccParsed?.parsed?.info?.stake?.delegation?.stake ?? 0);
52581
+ const isFullStake = amountLamports >= stakeAccLamports;
52582
+ const instructions2 = [];
52583
+ const signers = [];
52584
+ if (!lstAccInfo) {
52585
+ instructions2.push(
52586
+ createAssociatedTokenAccountInstruction(authority, lstAta, authority, lstMint)
52587
+ );
52588
+ }
52589
+ let targetStakePubkey;
52590
+ if (!isFullStake) {
52591
+ const splitStakeAccount = Keypair.generate();
52592
+ signers.push(splitStakeAccount);
52593
+ targetStakePubkey = splitStakeAccount.publicKey;
52594
+ instructions2.push(
52595
+ ...StakeProgram.split(
52596
+ {
52597
+ stakePubkey: stakeAccountPk,
52598
+ authorizedPubkey: authority,
52599
+ splitStakePubkey: splitStakeAccount.publicKey,
52600
+ lamports: amountLamports
52601
+ },
52602
+ rentExemptReserve
52603
+ ).instructions
52604
+ );
52605
+ } else {
52606
+ targetStakePubkey = stakeAccountPk;
52607
+ }
52608
+ const [authorizeStakerIx, authorizeWithdrawIx] = await Promise.all([
52609
+ StakeProgram.authorize({
52610
+ stakePubkey: targetStakePubkey,
52611
+ authorizedPubkey: authority,
52612
+ newAuthorizedPubkey: poolStakeAuth,
52613
+ stakeAuthorizationType: StakeAuthorizationLayout.Staker
52614
+ }).instructions,
52615
+ StakeProgram.authorize({
52616
+ stakePubkey: targetStakePubkey,
52617
+ authorizedPubkey: authority,
52618
+ newAuthorizedPubkey: poolStakeAuth,
52619
+ stakeAuthorizationType: StakeAuthorizationLayout.Withdrawer
52620
+ }).instructions
52621
+ ]);
52622
+ [authorizeStakerIx[0], authorizeWithdrawIx[0]].forEach((ix) => {
52623
+ if (ix) {
52624
+ ix.keys = ix.keys.map((key) => ({
52625
+ ...key,
52626
+ isWritable: key.pubkey.equals(SYSVAR_CLOCK_ID2) ? false : key.isWritable
52627
+ }));
52628
+ }
52629
+ });
52630
+ instructions2.push(...authorizeStakerIx, ...authorizeWithdrawIx);
52631
+ const depositStakeIx = await SinglePoolInstruction.depositStake(
52632
+ pool,
52633
+ targetStakePubkey,
52634
+ lstAta,
52635
+ authority
52636
+ );
52637
+ instructions2.push(depositStakeIx);
52638
+ return { instructions: instructions2, keys: signers };
52639
+ }
52640
+ async function makeMintStakedLstTx(params) {
52641
+ const { connection, luts, blockhash: providedBlockhash } = params;
52642
+ const { instructions: instructions2, keys } = await makeMintStakedLstIx(params);
52643
+ const blockhash = providedBlockhash ?? (await connection.getLatestBlockhash("confirmed")).blockhash;
52644
+ const message = new TransactionMessage({
52645
+ payerKey: params.authority,
52646
+ recentBlockhash: blockhash,
52647
+ instructions: instructions2
52648
+ }).compileToV0Message(luts);
52649
+ const tx = new VersionedTransaction(message);
52650
+ return addTransactionMetadata(tx, {
52651
+ signers: keys,
52652
+ addressLookupTables: luts,
52653
+ type: "DEPOSIT_STAKE" /* DEPOSIT_STAKE */
52654
+ });
52655
+ }
52656
+ async function makeRedeemStakedLstIx(params) {
52657
+ const { amount, authority, validator, connection } = params;
52658
+ const pool = findPoolAddress(validator);
52659
+ const lstMint = findPoolMintAddress(pool);
52660
+ const mintAuthority = findPoolMintAuthorityAddress(pool);
52661
+ const lstAta = getAssociatedTokenAddressSync(lstMint, authority);
52662
+ const rentExemption = await connection.getMinimumBalanceForRentExemption(
52663
+ StakeProgram.space
52664
+ );
52665
+ const stakeAmount = new BigNumber3(new BigNumber3(amount).toString());
52666
+ const instructions2 = [];
52667
+ const signers = [];
52668
+ const stakeAccount = Keypair.generate();
52669
+ signers.push(stakeAccount);
52670
+ instructions2.push(
52671
+ SystemProgram.createAccount({
52672
+ fromPubkey: authority,
52673
+ newAccountPubkey: stakeAccount.publicKey,
52674
+ lamports: rentExemption,
52675
+ space: StakeProgram.space,
52676
+ programId: StakeProgram.programId
52677
+ })
52678
+ );
52679
+ instructions2.push(
52680
+ createApproveInstruction(
52681
+ lstAta,
52682
+ mintAuthority,
52683
+ authority,
52684
+ BigInt(stakeAmount.multipliedBy(1e9).toFixed(0))
52685
+ )
52686
+ );
52687
+ const withdrawStakeIx = await SinglePoolInstruction.withdrawStake(
52688
+ pool,
52689
+ stakeAccount.publicKey,
52690
+ authority,
52691
+ lstAta,
52692
+ stakeAmount
52693
+ );
52694
+ instructions2.push(withdrawStakeIx);
52695
+ return { instructions: instructions2, keys: signers };
52696
+ }
52697
+ async function makeRedeemStakedLstTx(params) {
52698
+ const { connection, luts, blockhash: providedBlockhash } = params;
52699
+ const { instructions: instructions2, keys } = await makeRedeemStakedLstIx(params);
52700
+ const blockhash = providedBlockhash ?? (await connection.getLatestBlockhash("confirmed")).blockhash;
52701
+ const message = new TransactionMessage({
52702
+ payerKey: params.authority,
52703
+ recentBlockhash: blockhash,
52704
+ instructions: instructions2
52705
+ }).compileToV0Message(luts);
52706
+ const tx = new VersionedTransaction(message);
52707
+ return addTransactionMetadata(tx, {
52708
+ signers: keys,
52709
+ addressLookupTables: luts,
52710
+ type: "WITHDRAW_STAKE" /* WITHDRAW_STAKE */
52711
+ });
52712
+ }
52713
+ async function makeMergeStakeAccountsTx(params) {
52714
+ const {
52715
+ authority,
52716
+ sourceStakeAccount,
52717
+ destinationStakeAccount,
52718
+ connection,
52719
+ luts,
52720
+ blockhash: providedBlockhash
52721
+ } = params;
52722
+ const mergeIx = StakeProgram.merge({
52723
+ stakePubkey: destinationStakeAccount,
52724
+ sourceStakePubKey: sourceStakeAccount,
52725
+ authorizedPubkey: authority
52726
+ }).instructions;
52727
+ const blockhash = providedBlockhash ?? (await connection.getLatestBlockhash("confirmed")).blockhash;
52728
+ const message = new TransactionMessage({
52729
+ payerKey: authority,
52730
+ recentBlockhash: blockhash,
52731
+ instructions: mergeIx
52732
+ }).compileToV0Message(luts);
52733
+ const tx = new VersionedTransaction(message);
52734
+ return addTransactionMetadata(tx, {
52735
+ addressLookupTables: luts,
52736
+ type: "MERGE_STAKE_ACCOUNTS" /* MERGE_STAKE_ACCOUNTS */
52737
+ });
52738
+ }
52614
52739
  async function getKaminoMetadata(options) {
52615
52740
  const kaminoBanks = options.banks.filter((b) => b.config.assetTag === 3 /* KAMINO */);
52616
52741
  const DEFAULT_PUBKEY = PublicKey.default;
@@ -55047,66 +55172,6 @@ var MarginfiAccountWrapper = class {
55047
55172
  return this.account.getHealthCheckAccounts(this.client.bankMap, mandatoryBanks, excludedBanks);
55048
55173
  }
55049
55174
  // ----------------------------------------------------------------------------
55050
- // Native stake actions
55051
- // Note: These call standalone action functions directly rather than routing
55052
- // through this.account because they interact with the SPL stake pool program,
55053
- // not the marginfi program. No MarginfiAccount state is needed.
55054
- // ----------------------------------------------------------------------------
55055
- /**
55056
- * Creates a transaction to mint LST from a native stake account.
55057
- *
55058
- * Converts a native stake account (or a portion of it) into LST tokens
55059
- * by depositing the stake into the single-validator pool.
55060
- *
55061
- * @param amount - SOL amount to convert (in UI units)
55062
- * @param stakeAccountPk - The stake account to convert
55063
- * @param validator - The validator vote account
55064
- */
55065
- async makeMintStakedLstTx(amount, stakeAccountPk, validator) {
55066
- return makeMintStakedLstTx({
55067
- amount,
55068
- authority: this.authority,
55069
- stakeAccountPk,
55070
- validator,
55071
- connection: this.client.program.provider.connection,
55072
- luts: this.client.addressLookupTables
55073
- });
55074
- }
55075
- /**
55076
- * Creates a transaction to redeem LST tokens back to a native stake account.
55077
- *
55078
- * Burns LST tokens and withdraws the underlying stake into a new stake account.
55079
- *
55080
- * @param amount - LST amount to redeem (in UI units)
55081
- * @param validator - The validator vote account
55082
- */
55083
- async makeRedeemStakedLstTx(amount, validator) {
55084
- return makeRedeemStakedLstTx({
55085
- amount,
55086
- authority: this.authority,
55087
- validator,
55088
- connection: this.client.program.provider.connection,
55089
- luts: this.client.addressLookupTables
55090
- });
55091
- }
55092
- /**
55093
- * Creates a transaction to merge two stake accounts.
55094
- *
55095
- * Both accounts must share the same authorized staker/withdrawer and vote account.
55096
- *
55097
- * @param sourceStakeAccount - The stake account to merge from (will be consumed)
55098
- * @param destinationStakeAccount - The stake account to merge into
55099
- */
55100
- async makeMergeStakeAccountsTx(sourceStakeAccount, destinationStakeAccount) {
55101
- return makeMergeStakeAccountsTx({
55102
- authority: this.authority,
55103
- sourceStakeAccount,
55104
- destinationStakeAccount,
55105
- connection: this.client.program.provider.connection,
55106
- luts: this.client.addressLookupTables
55107
- });
55108
- }
55109
- // ----------------------------------------------------------------------------
55110
55175
  // Helper methods
55111
55176
  // ----------------------------------------------------------------------------
55112
55177
  /**
@@ -55376,56 +55441,11 @@ var Project0Client = class _Project0Client {
55376
55441
  break;
55377
55442
  }
55378
55443
  });
55379
- const stakedBanks = banksArray.filter((b) => b.config.assetTag === 2 /* STAKED */);
55380
- if (stakedBanks.length > 0) {
55381
- const metadataMap = getStakedBankMetadataMap();
55382
- const stakedBankAddresses = [];
55383
- const poolStakeAddresses = [];
55384
- const lstMintAddresses = [];
55385
- for (const bank of stakedBanks) {
55386
- const metadata = metadataMap.get(bank.address.toBase58());
55387
- if (!metadata) {
55388
- assetShareMultiplierByBank.set(bank.address.toBase58(), new BigNumber3(1));
55389
- continue;
55390
- }
55391
- const pool = findPoolAddress(new PublicKey(metadata.validatorVoteAccount));
55392
- stakedBankAddresses.push(bank.address.toBase58());
55393
- poolStakeAddresses.push(findPoolStakeAddress(pool));
55394
- lstMintAddresses.push(findPoolMintAddress(pool));
55395
- }
55396
- if (stakedBankAddresses.length > 0) {
55397
- const allAddresses = [
55398
- ...poolStakeAddresses.map((a) => a.toBase58()),
55399
- ...lstMintAddresses.map((a) => a.toBase58())
55400
- ];
55401
- const accountInfos = await chunkedGetRawMultipleAccountInfoOrdered(
55402
- connection,
55403
- allAddresses
55404
- );
55405
- const poolStakeInfos = accountInfos.slice(0, poolStakeAddresses.length);
55406
- const lstMintInfos = accountInfos.slice(poolStakeAddresses.length);
55407
- for (let i = 0; i < stakedBankAddresses.length; i++) {
55408
- const bankAddr = stakedBankAddresses[i];
55409
- const poolStakeInfo = poolStakeInfos[i];
55410
- const lstMintInfo = lstMintInfos[i];
55411
- if (!poolStakeInfo || !lstMintInfo) {
55412
- assetShareMultiplierByBank.set(bankAddr, new BigNumber3(1));
55413
- continue;
55414
- }
55415
- const stakeLamports = poolStakeInfo.lamports;
55416
- const supplyBuffer = lstMintInfo.data.slice(36, 44);
55417
- const lstMintSupply = Number(Buffer.from(supplyBuffer).readBigUInt64LE(0));
55418
- if (lstMintSupply === 0) {
55419
- assetShareMultiplierByBank.set(bankAddr, new BigNumber3(1));
55420
- continue;
55421
- }
55422
- const LAMPORTS_PER_SOL5 = 1e9;
55423
- const adjustedStake = Math.max(stakeLamports - LAMPORTS_PER_SOL5, 0);
55424
- const multiplier = new BigNumber3(adjustedStake).dividedBy(lstMintSupply);
55425
- assetShareMultiplierByBank.set(bankAddr, multiplier);
55426
- }
55427
- }
55428
- }
55444
+ const stakedMultipliers = await computeStakedBankMultipliers(
55445
+ banksArray.filter((b) => b.config.assetTag === 2 /* STAKED */),
55446
+ connection
55447
+ );
55448
+ stakedMultipliers.forEach((v, k) => assetShareMultiplierByBank.set(k, v));
55429
55449
  const emodePairs = getEmodePairs(banksArray);
55430
55450
  return new _Project0Client(
55431
55451
  program,
@@ -55467,6 +55487,6 @@ var EmodeSettings = class _EmodeSettings {
55467
55487
  }
55468
55488
  };
55469
55489
 
55470
- export { ADDRESS_LOOKUP_TABLE_FOR_GROUP, ADDRESS_LOOKUP_TABLE_FOR_SWAP, AccountFlags, AccountType, AssetTag, BUNDLE_TX_SIZE, Balance, Bank, BankConfig, BankConfigFlag, BankVaultType, DEFAULT_ORACLE_MAX_AGE, DISABLED_FLAG, EMPTY_HEALTH_CACHE, EmodeEntryFlags, EmodeFlags, EmodeImpactStatus, EmodeSettings, EmodeTag, FLASHLOAN_ENABLED_FLAG, HOURS_PER_YEAR, HealthCache, HealthCacheFlags, HealthCacheSimulationError, HealthCacheStatus, JUPITER_V6_PROGRAM, JUP_SWAP_LUT_PROGRAM_AUTHORITY_INDEX, LST_MINT, MARGINFI_IDL, MARGINFI_PROGRAM, MARGINFI_PROGRAM_STAGING, MARGINFI_PROGRAM_STAGING_ALT, MARGINFI_SPONSORED_SHARD_ID, MAX_ACCOUNT_LOCKS, MAX_CONFIDENCE_INTERVAL_RATIO, MAX_TX_SIZE, MAX_U64, MPL_METADATA_PROGRAM_ID, MarginRequirementType, MarginfiAccount, MarginfiAccountWrapper, MarginfiGroup, OperationalState, OracleSetup, PDA_BANK_EMISSIONS_AUTH_SEED, PDA_BANK_EMISSIONS_VAULT_SEED, PDA_BANK_FEE_STATE_SEED, PDA_BANK_FEE_VAULT_AUTH_SEED, PDA_BANK_FEE_VAULT_SEED, PDA_BANK_INSURANCE_VAULT_AUTH_SEED, PDA_BANK_INSURANCE_VAULT_SEED, PDA_BANK_LIQUIDITY_VAULT_AUTH_SEED, PDA_BANK_LIQUIDITY_VAULT_SEED, PDA_MARGINFI_ACCOUNT_SEED, PRIORITY_TX_SIZE, PYTH_PRICE_CONF_INTERVALS, PYTH_PUSH_ORACLE_ID, PYTH_SPONSORED_SHARD_ID, PriceBias, Project0Client, RiskTier, SINGLE_POOL_PROGRAM_ID, STAKE_CONFIG_ID, STAKE_PROGRAM_ID, SWB_PRICE_CONF_INTERVALS, SYSTEM_PROGRAM_ID, SYSVAR_CLOCK_ID, SYSVAR_RENT_ID, SYSVAR_STAKE_HISTORY_ID, SwapProvider, TRANSFER_ACCOUNT_AUTHORITY_FLAG, TransactionArenaKeyMap, TransactionBuildingError, TransactionBuildingErrorCode, TransactionConfigMap, TransactionType, USDC_DECIMALS, USDC_MINT, WSOL_MINT, ZERO_ORACLE_KEY, accountFlagToBN, addOracleToBanksIx, addTransactionMetadata, adjustPriceComponent, aprToApy, apyToApr, balanceToDto, bankConfigRawToDto, bankConfigToBankConfigRaw, bankMetadataMapToDto, bankMetadataToDto, bankRawToDto, bigNumberToWrappedI80F48, bpsToPercentile, calculateApyFromInterest, calculateInterestFromApy, capConfidenceInterval, categorizePythBanks, checkBatchOracleCrankability, checkMultipleOraclesCrankability, chunkedGetRawMultipleAccountInfoOrdered, chunkedGetRawMultipleAccountInfoOrderedWithNulls, chunkedGetRawMultipleAccountInfos, compileFlashloanPrecheck, composeRemainingAccounts, computeAccountValue, computeActiveEmodePairs, computeAssetHealthComponent, computeAssetUsdValue, computeBalanceUsdValue, computeBaseInterestRate, computeClaimedEmissions, computeClosePositionTokenAmount, computeEmodeImpacts, computeFlashLoanNonSwapBudget, computeFlashloanSwapConstraints, computeFreeCollateralFromBalances, computeFreeCollateralFromCache, computeHealthAccountMetas, computeHealthCacheStatus, computeHealthCheckAccounts, computeHealthComponentsFromBalances, computeHealthComponentsFromCache, computeHealthComponentsWithoutBiasFromBalances, computeInterestRates, computeLiabilityHealthComponent, computeLiabilityUsdValue, computeLiquidationPriceForBank, computeLoopingParams, computeLowestEmodeWeights, computeMaxBorrowForBank, computeMaxLeverage, computeMaxWithdrawForBank, computeNetApy, computeProjectedActiveBalancesNoCpi, computeProjectedActiveBanksNoCpi, computeQuantity, computeQuantityUi, computeRemainingCapacity, computeSmartCrank, computeTotalOutstandingEmissions, computeTvl, computeUsdValue, computeUtilizationRate, computeV0TxSize, convertVoteAccCoeffsToBankCoeffs, createActiveEmodePairFromPairs, createEmptyBalance, decodeAccountRaw, decodeBankRaw, decodeInstruction, decompileV0Transaction, deriveBankEmissionsAuth, deriveBankEmissionsVault, deriveBankFeeVault, deriveBankFeeVaultAuthority, deriveBankInsuranceVault, deriveBankInsuranceVaultAuthority, deriveBankLiquidityVault, deriveBankLiquidityVaultAuthority, deriveFeeState, deriveMarginfiAccount, dtoToBalance, dtoToBank, dtoToBankConfig, dtoToBankConfigRaw, dtoToBankMetadata, dtoToBankMetadataMap, dtoToBankRaw, dtoToEmodeSettings, dtoToEmodeSettingsRaw, dtoToGroup, dtoToHealthCache, dtoToInterestRateConfig, dtoToMarginfiAccount, dtoToOraclePrice, dtoToValidatorStakeGroup, emodeSettingsRawToDto, extractPythOracleKeys, fetchBank, fetchBankIntegrationMetadata, fetchMarginfiAccountAddresses, fetchMarginfiAccountData, fetchMultipleBanks, fetchNativeStakeAccounts, fetchOracleData, fetchProgramForMints, fetchPythOracleData, fetchPythOraclePricesFromAPI, fetchPythOraclePricesFromChain, fetchStakeAccount, fetchStakePoolActiveStates, fetchStakePoolMev, fetchSwbOracleAccountsFromAPI, fetchSwbOracleAccountsFromChain, fetchSwbOracleData, fetchSwbOraclePricesFromAPI, fetchSwbOraclePricesFromCrossbar, findRandomAvailableAccountIndex, freezeBankConfigIx, getAccountKeys, getActiveAccountFlags, getActiveBalances, getActiveEmodeEntryFlags, getActiveEmodeFlags, getActiveHealthCacheFlags, getAssetQuantity, getAssetShares, getAssetWeight, getBalance, getBalanceUsdValueWithPriceBias, getBankVaultAuthority, getBankVaultSeeds, getBirdeyeFallbackPricesByFeedId, getBirdeyePricesForMints, getConfig, getDriftCTokenMultiplier, getDriftMetadata, getDriftStatesDto, getEmodePairs, getExactOutEstimate, getHealthCacheStatusDescription, getHealthSimulationTransactions, getJupLendFTokenMultiplier, getJupLendMetadata, getJupLendStatesDto, getJupiterSwapIxsForFlashloan, getKaminoCTokenMultiplier, getKaminoMetadata, getKaminoStatesDto, getLiabilityQuantity, getLiabilityShares, getLiabilityWeight, getOracleSourceFromBank, getOracleSourceFromOracleSetup, getOracleSourceNameFromKey, getPrice, getPriceWithConfidence, getStakedBankMetadataMap, getSwapIxsForFlashloan, getTitanExactOutEstimate, getTitanSwapIxsForFlashloan, getTotalAccountKeys, getTotalAssetQuantity, getTotalLiabilityQuantity, getTxSize, getValidatorVoteAccountByBank, getWritableAccountKeys, groupToDto, hasAccountFlag, hasEmodeEntryFlag, hasEmodeFlag, hasHealthCacheFlag, healthCacheToDto, isFlashloan, isV0Tx, isWeightedPrice, isWholePosition, makeAddPermissionlessStakedBankIx, makeBeginFlashLoanIx3 as makeBeginFlashLoanIx, makeBorrowIx3 as makeBorrowIx, makeBorrowTx, makeBundleTipIx, makeClearEmissionsIx, makeCloseMarginfiAccountIx, makeCloseMarginfiAccountTx, makeCrankSwbFeedIx, makeCreateAccountIxWithProjection, makeCreateAccountTxWithProjection, makeCreateMarginfiAccountIx, makeCreateMarginfiAccountTx, makeDepositIx3 as makeDepositIx, makeDepositTx, makeDriftDepositIx3 as makeDriftDepositIx, makeDriftDepositTx, makeDriftWithdrawIx3 as makeDriftWithdrawIx, makeDriftWithdrawTx, makeEndFlashLoanIx3 as makeEndFlashLoanIx, makeFlashLoanTx, makeJuplendDepositIx2 as makeJuplendDepositIx, makeJuplendDepositTx, makeJuplendWithdrawIx2 as makeJuplendWithdrawIx, makeJuplendWithdrawTx, makeKaminoDepositIx3 as makeKaminoDepositIx, makeKaminoDepositTx, makeKaminoWithdrawIx3 as makeKaminoWithdrawIx, makeKaminoWithdrawTx, makeLoopTx, makeMergeStakeAccountsTx, makeMintStakedLstIx, makeMintStakedLstTx, makePoolAddBankIx3 as makePoolAddBankIx, makePoolConfigureBankIx3 as makePoolConfigureBankIx, makePriorityFeeIx, makePriorityFeeMicroIx, makePulseHealthIx2 as makePulseHealthIx, makeRedeemStakedLstIx, makeRedeemStakedLstTx, makeRefreshKaminoBanksIxs, makeRepayIx3 as makeRepayIx, makeRepayTx, makeRepayWithCollatTx, makeSetupIx, makeSmartCrankSwbFeedIx, makeSwapCollateralTx, makeSwapDebtTx, makeTxPriorityIx, makeUnwrapSolIx, makeUpdateDriftMarketIxs, makeUpdateJupLendRateIxs, makeUpdateSwbFeedIx, makeVersionedTransaction, makeWithdrawIx3 as makeWithdrawIx, makeWithdrawTx, makeWrapSolIxs, mapBrokenFeedsToOraclePrices, mapJupiterQuoteToSwapQuoteResult, mapPythBanksToOraclePrices, mapSwbBanksToOraclePrices, marginfiAccountToDto, nativeToUi, oraclePriceToDto, parseBalanceRaw, parseBankConfigRaw, parseBankRaw, parseEmodeSettingsRaw, parseEmodeTag, parseHealthCacheRaw, parseMarginfiAccountRaw, parseOperationalState, parseOracleSetup, parseOraclePriceData as parsePriceInfo, parseRiskTier, parseRpcPythPriceData, parseSwbOraclePriceData, partitionBanksByCrankability, resolveAmount, serializeBankConfigOpt, serializeInterestRateConfig, serializeOperationalState, serializeOracleSetup, serializeOracleSetupToIndex, serializeRiskTier, shortenAddress, simulateAccountHealthCache, simulateAccountHealthCacheWithFallback, simulateBundle, splitInstructionsToFitTransactions, toBankConfigDto, toBankDto, toBigNumber, toEmodeSettingsDto, toInterestRateConfigDto, toJupiterConfig, toNumber, uiToNative, uiToNativeBigNumber, validatorStakeGroupToDto, wrappedI80F48toBigNumber };
55490
+ export { ADDRESS_LOOKUP_TABLE_FOR_GROUP, ADDRESS_LOOKUP_TABLE_FOR_SWAP, AccountFlags, AccountType, AssetTag, BUNDLE_TX_SIZE, Balance, Bank, BankConfig, BankConfigFlag, BankVaultType, DEFAULT_ORACLE_MAX_AGE, DISABLED_FLAG, EMPTY_HEALTH_CACHE, EmodeEntryFlags, EmodeFlags, EmodeImpactStatus, EmodeSettings, EmodeTag, FLASHLOAN_ENABLED_FLAG, HOURS_PER_YEAR, HealthCache, HealthCacheFlags, HealthCacheSimulationError, HealthCacheStatus, JUPITER_V6_PROGRAM, JUP_SWAP_LUT_PROGRAM_AUTHORITY_INDEX, LST_MINT, MARGINFI_IDL, MARGINFI_PROGRAM, MARGINFI_PROGRAM_STAGING, MARGINFI_PROGRAM_STAGING_ALT, MARGINFI_SPONSORED_SHARD_ID, MAX_ACCOUNT_LOCKS, MAX_CONFIDENCE_INTERVAL_RATIO, MAX_TX_SIZE, MAX_U64, MPL_METADATA_PROGRAM_ID, MarginRequirementType, MarginfiAccount, MarginfiAccountWrapper, MarginfiGroup, OperationalState, OracleSetup, PDA_BANK_EMISSIONS_AUTH_SEED, PDA_BANK_EMISSIONS_VAULT_SEED, PDA_BANK_FEE_STATE_SEED, PDA_BANK_FEE_VAULT_AUTH_SEED, PDA_BANK_FEE_VAULT_SEED, PDA_BANK_INSURANCE_VAULT_AUTH_SEED, PDA_BANK_INSURANCE_VAULT_SEED, PDA_BANK_LIQUIDITY_VAULT_AUTH_SEED, PDA_BANK_LIQUIDITY_VAULT_SEED, PDA_MARGINFI_ACCOUNT_SEED, PRIORITY_TX_SIZE, PYTH_PRICE_CONF_INTERVALS, PYTH_PUSH_ORACLE_ID, PYTH_SPONSORED_SHARD_ID, PriceBias, Project0Client, RiskTier, SINGLE_POOL_PROGRAM_ID, STAKE_CONFIG_ID, STAKE_PROGRAM_ID, SWB_PRICE_CONF_INTERVALS, SYSTEM_PROGRAM_ID, SYSVAR_CLOCK_ID, SYSVAR_RENT_ID, SYSVAR_STAKE_HISTORY_ID, SwapProvider, TRANSFER_ACCOUNT_AUTHORITY_FLAG, TransactionArenaKeyMap, TransactionBuildingError, TransactionBuildingErrorCode, TransactionConfigMap, TransactionType, USDC_DECIMALS, USDC_MINT, WSOL_MINT, ZERO_ORACLE_KEY, accountFlagToBN, addOracleToBanksIx, addTransactionMetadata, adjustPriceComponent, aprToApy, apyToApr, balanceToDto, bankConfigRawToDto, bankConfigToBankConfigRaw, bankMetadataMapToDto, bankMetadataToDto, bankRawToDto, bigNumberToWrappedI80F48, bpsToPercentile, calculateApyFromInterest, calculateInterestFromApy, capConfidenceInterval, categorizePythBanks, checkBatchOracleCrankability, checkMultipleOraclesCrankability, chunkedGetRawMultipleAccountInfoOrdered, chunkedGetRawMultipleAccountInfoOrderedWithNulls, chunkedGetRawMultipleAccountInfos, compileFlashloanPrecheck, composeRemainingAccounts, computeAccountValue, computeActiveEmodePairs, computeAssetHealthComponent, computeAssetUsdValue, computeBalanceUsdValue, computeBankBorrowApy, computeBankBorrowCapRemaining, computeBankDepositCapRemaining, computeBankMetrics, computeBankPoolSize, computeBankSupplyApy, computeBankTotalBorrows, computeBankTotalBorrowsUsd, computeBankTotalDeposits, computeBankTotalDepositsUsd, computeBaseInterestRate, computeClaimedEmissions, computeClosePositionTokenAmount, computeEmodeImpacts, computeFlashLoanNonSwapBudget, computeFlashloanSwapConstraints, computeFreeCollateralFromBalances, computeFreeCollateralFromCache, computeHealthAccountMetas, computeHealthCacheStatus, computeHealthCheckAccounts, computeHealthComponentsFromBalances, computeHealthComponentsFromCache, computeHealthComponentsWithoutBiasFromBalances, computeInterestRates, computeLiabilityHealthComponent, computeLiabilityUsdValue, computeLiquidationPriceForBank, computeLoopingParams, computeLowestEmodeWeights, computeMaxBorrowForBank, computeMaxLeverage, computeMaxWithdrawForBank, computeNetApy, computeProjectedActiveBalancesNoCpi, computeProjectedActiveBanksNoCpi, computeQuantity, computeQuantityUi, computeRemainingCapacity, computeSmartCrank, computeStakedBankMultipliers, computeTotalOutstandingEmissions, computeTvl, computeUsdValue, computeUtilizationRate, computeV0TxSize, convertVoteAccCoeffsToBankCoeffs, createActiveEmodePairFromPairs, createEmptyBalance, decodeAccountRaw, decodeBankRaw, decodeInstruction, decompileV0Transaction, deriveBankEmissionsAuth, deriveBankEmissionsVault, deriveBankFeeVault, deriveBankFeeVaultAuthority, deriveBankInsuranceVault, deriveBankInsuranceVaultAuthority, deriveBankLiquidityVault, deriveBankLiquidityVaultAuthority, deriveFeeState, deriveMarginfiAccount, dtoToBalance, dtoToBank, dtoToBankConfig, dtoToBankConfigRaw, dtoToBankMetadata, dtoToBankMetadataMap, dtoToBankRaw, dtoToEmodeSettings, dtoToEmodeSettingsRaw, dtoToGroup, dtoToHealthCache, dtoToInterestRateConfig, dtoToMarginfiAccount, dtoToOraclePrice, dtoToValidatorStakeGroup, emodeSettingsRawToDto, extractPythOracleKeys, fetchBank, fetchBankIntegrationMetadata, fetchMarginfiAccountAddresses, fetchMarginfiAccountData, fetchMultipleBanks, fetchNativeStakeAccounts, fetchOracleData, fetchProgramForMints, fetchPythOracleData, fetchPythOraclePricesFromAPI, fetchPythOraclePricesFromChain, fetchStakeAccount, fetchStakePoolActiveStates, fetchStakePoolMev, fetchSwbOracleAccountsFromAPI, fetchSwbOracleAccountsFromChain, fetchSwbOracleData, fetchSwbOraclePricesFromAPI, fetchSwbOraclePricesFromCrossbar, findRandomAvailableAccountIndex, freezeBankConfigIx, generateDummyAccount, getAccountKeys, getActiveAccountFlags, getActiveBalances, getActiveEmodeEntryFlags, getActiveEmodeFlags, getActiveHealthCacheFlags, getAssetQuantity, getAssetShares, getAssetWeight, getBalance, getBalanceUsdValueWithPriceBias, getBankVaultAuthority, getBankVaultSeeds, getBirdeyeFallbackPricesByFeedId, getBirdeyePricesForMints, getConfig, getDriftCTokenMultiplier, getDriftMetadata, getDriftStatesDto, getEmodePairs, getExactOutEstimate, getHealthCacheStatusDescription, getHealthSimulationTransactions, getJupLendFTokenMultiplier, getJupLendMetadata, getJupLendStatesDto, getJupiterSwapIxsForFlashloan, getKaminoCTokenMultiplier, getKaminoMetadata, getKaminoStatesDto, getLiabilityQuantity, getLiabilityShares, getLiabilityWeight, getOracleSourceFromBank, getOracleSourceFromOracleSetup, getOracleSourceNameFromKey, getPrice, getPriceWithConfidence, getStakedBankMetadataMap, getSwapIxsForFlashloan, getTitanExactOutEstimate, getTitanSwapIxsForFlashloan, getTotalAccountKeys, getTotalAssetQuantity, getTotalLiabilityQuantity, getTxSize, getValidatorVoteAccountByBank, getWritableAccountKeys, groupToDto, hasAccountFlag, hasEmodeEntryFlag, hasEmodeFlag, hasHealthCacheFlag, healthCacheToDto, isFlashloan, isV0Tx, isWeightedPrice, isWholePosition, makeAddPermissionlessStakedBankIx, makeBeginFlashLoanIx3 as makeBeginFlashLoanIx, makeBorrowIx3 as makeBorrowIx, makeBorrowTx, makeBundleTipIx, makeClearEmissionsIx, makeCloseMarginfiAccountIx, makeCloseMarginfiAccountTx, makeCrankSwbFeedIx, makeCreateAccountIxWithProjection, makeCreateAccountTxWithProjection, makeCreateMarginfiAccountIx, makeCreateMarginfiAccountTx, makeDepositIx3 as makeDepositIx, makeDepositTx, makeDriftDepositIx3 as makeDriftDepositIx, makeDriftDepositTx, makeDriftWithdrawIx3 as makeDriftWithdrawIx, makeDriftWithdrawTx, makeEndFlashLoanIx3 as makeEndFlashLoanIx, makeFlashLoanTx, makeJuplendDepositIx2 as makeJuplendDepositIx, makeJuplendDepositTx, makeJuplendWithdrawIx2 as makeJuplendWithdrawIx, makeJuplendWithdrawTx, makeKaminoDepositIx3 as makeKaminoDepositIx, makeKaminoDepositTx, makeKaminoWithdrawIx3 as makeKaminoWithdrawIx, makeKaminoWithdrawTx, makeLoopTx, makeMergeStakeAccountsTx, makeMintStakedLstIx, makeMintStakedLstTx, makePoolAddBankIx3 as makePoolAddBankIx, makePoolConfigureBankIx3 as makePoolConfigureBankIx, makePriorityFeeIx, makePriorityFeeMicroIx, makePulseHealthIx2 as makePulseHealthIx, makeRedeemStakedLstIx, makeRedeemStakedLstTx, makeRefreshKaminoBanksIxs, makeRepayIx3 as makeRepayIx, makeRepayTx, makeRepayWithCollatTx, makeSetupIx, makeSmartCrankSwbFeedIx, makeSwapCollateralTx, makeSwapDebtTx, makeTxPriorityIx, makeUnwrapSolIx, makeUpdateDriftMarketIxs, makeUpdateJupLendRateIxs, makeUpdateSwbFeedIx, makeVersionedTransaction, makeWithdrawIx3 as makeWithdrawIx, makeWithdrawTx, makeWrapSolIxs, mapBrokenFeedsToOraclePrices, mapJupiterQuoteToSwapQuoteResult, mapPythBanksToOraclePrices, mapSwbBanksToOraclePrices, marginfiAccountToDto, nativeToUi, oraclePriceToDto, parseBalanceRaw, parseBankConfigRaw, parseBankRaw, parseEmodeSettingsRaw, parseEmodeTag, parseHealthCacheRaw, parseMarginfiAccountRaw, parseOperationalState, parseOracleSetup, parseOraclePriceData as parsePriceInfo, parseRiskTier, parseRpcPythPriceData, parseSwbOraclePriceData, partitionBanksByCrankability, resolveAmount, serializeBankConfigOpt, serializeInterestRateConfig, serializeOperationalState, serializeOracleSetup, serializeOracleSetupToIndex, serializeRiskTier, shortenAddress, simulateAccountHealthCache, simulateAccountHealthCacheWithFallback, simulateBundle, splitInstructionsToFitTransactions, toBankConfigDto, toBankDto, toBigNumber, toEmodeSettingsDto, toInterestRateConfigDto, toJupiterConfig, toNumber, uiToNative, uiToNativeBigNumber, validatorStakeGroupToDto, wrappedI80F48toBigNumber };
55471
55491
  //# sourceMappingURL=index.js.map
55472
55492
  //# sourceMappingURL=index.js.map