@0dotxyz/p0-ts-sdk 2.2.0-beta.2 → 2.2.0

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,7 +1,7 @@
1
- import { PublicKey, SolanaJSONRPCError, ComputeBudgetProgram, SystemProgram, TransactionMessage, VersionedTransaction, Transaction, AddressLookupTableAccount, SYSVAR_RENT_PUBKEY, StakeProgram, TransactionInstruction, LAMPORTS_PER_SOL, SYSVAR_INSTRUCTIONS_PUBKEY } 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
- import BN11 from 'bn.js';
4
+ import BN11, { BN } from 'bn.js';
5
5
  import Decimal3, { Decimal } from 'decimal.js';
6
6
  import { BorshCoder, BorshAccountsCoder, BorshInstructionCoder, AnchorProvider, Program } from '@coral-xyz/anchor';
7
7
  import { struct, u32, u8 } from '@solana/buffer-layout';
@@ -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
  */
@@ -359,7 +348,6 @@ var MAX_U64 = BigInt("18446744073709551615").toString();
359
348
 
360
349
  // src/constants/transaction.consts.ts
361
350
  var MAX_TX_SIZE = 1232;
362
- var MAX_WRITABLE_ACCOUNTS = 64;
363
351
  var MAX_ACCOUNT_LOCKS = 64;
364
352
  var BUNDLE_TX_SIZE = 81;
365
353
  var PRIORITY_TX_SIZE = 44;
@@ -15137,9 +15125,48 @@ var MintLayout = struct([
15137
15125
  publicKey("freezeAuthority")
15138
15126
  ]);
15139
15127
  MintLayout.span;
15128
+ var approveInstructionData = struct([
15129
+ u8("instruction"),
15130
+ u64("amount")
15131
+ ]);
15132
+ function createApproveInstruction(account, delegate, owner, amount, multiSigners = [], programId = TOKEN_PROGRAM_ID) {
15133
+ const keys = addSigners(
15134
+ [
15135
+ { pubkey: account, isSigner: false, isWritable: true },
15136
+ { pubkey: delegate, isSigner: false, isWritable: false }
15137
+ ],
15138
+ owner,
15139
+ multiSigners
15140
+ );
15141
+ const data = Buffer$1.alloc(approveInstructionData.span);
15142
+ approveInstructionData.encode(
15143
+ {
15144
+ instruction: 4 /* Approve */,
15145
+ amount: BigInt(amount)
15146
+ },
15147
+ data
15148
+ );
15149
+ return new TransactionInstruction({ keys, programId, data });
15150
+ }
15140
15151
  struct([
15141
15152
  u8("instruction")
15142
15153
  ]);
15154
+ function createAssociatedTokenAccountInstruction(payer, associatedToken, owner, mint, programId = TOKEN_PROGRAM_ID, associatedTokenProgramId = ASSOCIATED_TOKEN_PROGRAM_ID) {
15155
+ const keys = [
15156
+ { pubkey: payer, isSigner: true, isWritable: true },
15157
+ { pubkey: associatedToken, isSigner: false, isWritable: true },
15158
+ { pubkey: owner, isSigner: false, isWritable: false },
15159
+ { pubkey: mint, isSigner: false, isWritable: false },
15160
+ { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
15161
+ { pubkey: programId, isSigner: false, isWritable: false },
15162
+ { pubkey: SYSVAR_RENT_PUBKEY, isSigner: false, isWritable: false }
15163
+ ];
15164
+ return new TransactionInstruction({
15165
+ keys,
15166
+ programId: associatedTokenProgramId,
15167
+ data: Buffer$1.alloc(0)
15168
+ });
15169
+ }
15143
15170
  function createAssociatedTokenAccountIdempotentInstruction(payer, associatedToken, owner, mint, programId = TOKEN_PROGRAM_ID, associatedTokenProgramId = ASSOCIATED_TOKEN_PROGRAM_ID) {
15144
15171
  return buildAssociatedTokenAccountInstruction(
15145
15172
  payer,
@@ -43352,6 +43379,173 @@ new Fraction(new BN11(0));
43352
43379
  function roundNearest(decimal) {
43353
43380
  return decimal.toDecimalPlaces(0, Decimal3.ROUND_HALF_CEIL);
43354
43381
  }
43382
+ var SinglePoolInstruction = {
43383
+ initializePool: (voteAccount) => {
43384
+ const pool = findPoolAddress(voteAccount);
43385
+ const stake = findPoolStakeAddress(pool);
43386
+ const mint = findPoolMintAddress(pool);
43387
+ const stakeAuthority = findPoolStakeAuthorityAddress(pool);
43388
+ const mintAuthority = findPoolMintAuthorityAddress(pool);
43389
+ return createTransactionInstruction(
43390
+ SINGLE_POOL_PROGRAM_ID,
43391
+ [
43392
+ { pubkey: voteAccount, isSigner: false, isWritable: false },
43393
+ { pubkey: pool, isSigner: false, isWritable: true },
43394
+ { pubkey: stake, isSigner: false, isWritable: true },
43395
+ { pubkey: mint, isSigner: false, isWritable: true },
43396
+ { pubkey: stakeAuthority, isSigner: false, isWritable: false },
43397
+ { pubkey: mintAuthority, isSigner: false, isWritable: false },
43398
+ { pubkey: SYSVAR_RENT_ID, isSigner: false, isWritable: false },
43399
+ { pubkey: SYSVAR_CLOCK_ID, isSigner: false, isWritable: false },
43400
+ { pubkey: SYSVAR_STAKE_HISTORY_ID, isSigner: false, isWritable: false },
43401
+ { pubkey: STAKE_CONFIG_ID$1, isSigner: false, isWritable: false },
43402
+ { pubkey: SYSTEM_PROGRAM_ID, isSigner: false, isWritable: false },
43403
+ { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
43404
+ { pubkey: STAKE_PROGRAM_ID, isSigner: false, isWritable: false }
43405
+ ],
43406
+ Buffer.from([0 /* InitializePool */])
43407
+ );
43408
+ },
43409
+ initializeOnRamp: (pool) => {
43410
+ const onRamp = findPoolOnRampAddress(pool);
43411
+ const stakeAuthority = findPoolStakeAuthorityAddress(pool);
43412
+ return createTransactionInstruction(
43413
+ SINGLE_POOL_PROGRAM_ID,
43414
+ [
43415
+ { pubkey: pool, isSigner: false, isWritable: false },
43416
+ { pubkey: onRamp, isSigner: false, isWritable: true },
43417
+ { pubkey: stakeAuthority, isSigner: false, isWritable: false },
43418
+ { pubkey: SYSVAR_RENT_ID, isSigner: false, isWritable: false },
43419
+ { pubkey: SYSTEM_PROGRAM_ID, isSigner: false, isWritable: false },
43420
+ { pubkey: STAKE_PROGRAM_ID, isSigner: false, isWritable: false }
43421
+ ],
43422
+ Buffer.from([6 /* InitializeOnRamp */])
43423
+ );
43424
+ },
43425
+ depositStake: async (pool, userStakeAccount, userTokenAccount, userLamportAccount) => {
43426
+ const stake = findPoolStakeAddress(pool);
43427
+ const onRamp = findPoolOnRampAddress(pool);
43428
+ const mint = findPoolMintAddress(pool);
43429
+ const stakeAuthority = findPoolStakeAuthorityAddress(pool);
43430
+ const mintAuthority = findPoolMintAuthorityAddress(pool);
43431
+ return createTransactionInstruction(
43432
+ SINGLE_POOL_PROGRAM_ID,
43433
+ [
43434
+ { pubkey: pool, isSigner: false, isWritable: false },
43435
+ { pubkey: stake, isSigner: false, isWritable: true },
43436
+ { pubkey: onRamp, isSigner: false, isWritable: false },
43437
+ { pubkey: mint, isSigner: false, isWritable: true },
43438
+ { pubkey: stakeAuthority, isSigner: false, isWritable: false },
43439
+ { pubkey: mintAuthority, isSigner: false, isWritable: false },
43440
+ { pubkey: userStakeAccount, isSigner: false, isWritable: true },
43441
+ { pubkey: userTokenAccount, isSigner: false, isWritable: true },
43442
+ { pubkey: userLamportAccount, isSigner: false, isWritable: true },
43443
+ { pubkey: SYSVAR_CLOCK_ID, isSigner: false, isWritable: false },
43444
+ { pubkey: SYSVAR_STAKE_HISTORY_ID, isSigner: false, isWritable: false },
43445
+ { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
43446
+ { pubkey: STAKE_PROGRAM_ID, isSigner: false, isWritable: false }
43447
+ ],
43448
+ Buffer.from([2 /* DepositStake */])
43449
+ );
43450
+ },
43451
+ withdrawStake: async (pool, userStakeAccount, userStakeAuthority, userTokenAccount, tokenAmount) => {
43452
+ const stake = findPoolStakeAddress(pool);
43453
+ const onRamp = findPoolOnRampAddress(pool);
43454
+ const mint = findPoolMintAddress(pool);
43455
+ const stakeAuthority = findPoolStakeAuthorityAddress(pool);
43456
+ const mintAuthority = findPoolMintAuthorityAddress(pool);
43457
+ const rawAmount = BigInt(tokenAmount.multipliedBy(1e9).toString());
43458
+ const data = Buffer.concat([
43459
+ Buffer.from([3 /* WithdrawStake */]),
43460
+ userStakeAuthority.toBuffer(),
43461
+ Buffer.from(new BN(rawAmount.toString()).toArray("le", 8))
43462
+ ]);
43463
+ return createTransactionInstruction(
43464
+ SINGLE_POOL_PROGRAM_ID,
43465
+ [
43466
+ { pubkey: pool, isSigner: false, isWritable: false },
43467
+ { pubkey: stake, isSigner: false, isWritable: true },
43468
+ { pubkey: onRamp, isSigner: false, isWritable: false },
43469
+ { pubkey: mint, isSigner: false, isWritable: true },
43470
+ { pubkey: stakeAuthority, isSigner: false, isWritable: false },
43471
+ { pubkey: mintAuthority, isSigner: false, isWritable: false },
43472
+ { pubkey: userStakeAccount, isSigner: false, isWritable: true },
43473
+ { pubkey: userTokenAccount, isSigner: false, isWritable: true },
43474
+ { pubkey: SYSVAR_CLOCK_ID, isSigner: false, isWritable: false },
43475
+ { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
43476
+ { pubkey: STAKE_PROGRAM_ID, isSigner: false, isWritable: false }
43477
+ ],
43478
+ data
43479
+ );
43480
+ },
43481
+ createTokenMetadata: async (pool, payer) => {
43482
+ const mint = findPoolMintAddress(pool);
43483
+ const [mintAuthority, mplAuthority, mplMetadata] = await Promise.all([
43484
+ findPoolMintAuthorityAddress(pool),
43485
+ findPoolMplAuthorityAddress(pool),
43486
+ findMplMetadataAddress(mint)
43487
+ ]);
43488
+ return createTransactionInstruction(
43489
+ SINGLE_POOL_PROGRAM_ID,
43490
+ [
43491
+ { pubkey: pool, isSigner: false, isWritable: false },
43492
+ { pubkey: mint, isSigner: false, isWritable: false },
43493
+ { pubkey: mintAuthority, isSigner: false, isWritable: false },
43494
+ { pubkey: mplAuthority, isSigner: false, isWritable: false },
43495
+ { pubkey: payer, isSigner: true, isWritable: true },
43496
+ { pubkey: mplMetadata, isSigner: false, isWritable: true },
43497
+ { pubkey: MPL_METADATA_PROGRAM_ID, isSigner: false, isWritable: false },
43498
+ { pubkey: SYSTEM_PROGRAM_ID, isSigner: false, isWritable: false }
43499
+ ],
43500
+ Buffer.from([4 /* CreateTokenMetadata */])
43501
+ );
43502
+ },
43503
+ updateTokenMetadata: async (voteAccount, authorizedWithdrawer, tokenName, tokenSymbol, tokenUri = "") => {
43504
+ if (tokenName.length > 32) {
43505
+ throw new Error("maximum token name length is 32 characters");
43506
+ }
43507
+ if (tokenSymbol.length > 10) {
43508
+ throw new Error("maximum token symbol length is 10 characters");
43509
+ }
43510
+ if (tokenUri.length > 200) {
43511
+ throw new Error("maximum token uri length is 200 characters");
43512
+ }
43513
+ const pool = findPoolAddress(voteAccount);
43514
+ const [mint, mplAuthority] = await Promise.all([
43515
+ findPoolMintAddress(pool),
43516
+ findPoolMplAuthorityAddress(pool)
43517
+ ]);
43518
+ const mplMetadata = await findMplMetadataAddress(mint);
43519
+ const data = Buffer.concat([
43520
+ Buffer.from([5 /* UpdateTokenMetadata */]),
43521
+ Buffer.from(new Uint32Array([tokenName.length]).buffer),
43522
+ Buffer.from(tokenName),
43523
+ Buffer.from(new Uint32Array([tokenSymbol.length]).buffer),
43524
+ Buffer.from(tokenSymbol),
43525
+ Buffer.from(new Uint32Array([tokenUri.length]).buffer),
43526
+ Buffer.from(tokenUri)
43527
+ ]);
43528
+ return createTransactionInstruction(
43529
+ SINGLE_POOL_PROGRAM_ID,
43530
+ [
43531
+ { pubkey: voteAccount, isSigner: false, isWritable: false },
43532
+ { pubkey: pool, isSigner: false, isWritable: false },
43533
+ { pubkey: mplAuthority, isSigner: false, isWritable: false },
43534
+ { pubkey: authorizedWithdrawer, isSigner: true, isWritable: false },
43535
+ { pubkey: mplMetadata, isSigner: false, isWritable: true },
43536
+ { pubkey: MPL_METADATA_PROGRAM_ID, isSigner: false, isWritable: false }
43537
+ ],
43538
+ data
43539
+ );
43540
+ }
43541
+ };
43542
+ var createTransactionInstruction = (programId, keys, data) => {
43543
+ return {
43544
+ programId,
43545
+ keys,
43546
+ data
43547
+ };
43548
+ };
43355
43549
  var findPda = (baseAddress, prefix, programId = SINGLE_POOL_PROGRAM_ID) => {
43356
43550
  const [pda] = PublicKey.findProgramAddressSync(
43357
43551
  [Buffer.from(prefix), baseAddress.toBuffer()],
@@ -43362,7 +43556,17 @@ var findPda = (baseAddress, prefix, programId = SINGLE_POOL_PROGRAM_ID) => {
43362
43556
  var findPoolAddress = (voteAccountAddress) => findPda(voteAccountAddress, "pool");
43363
43557
  var findPoolMintAddress = (poolAddress) => findPda(poolAddress, "mint");
43364
43558
  var findPoolStakeAddress = (poolAddress) => findPda(poolAddress, "stake");
43559
+ var findPoolStakeAuthorityAddress = (poolAddress) => findPda(poolAddress, "stake_authority");
43560
+ var findPoolMintAuthorityAddress = (poolAddress) => findPda(poolAddress, "mint_authority");
43561
+ var findPoolMplAuthorityAddress = (poolAddress) => findPda(poolAddress, "mpl_authority");
43365
43562
  var findPoolOnRampAddress = (poolAddress) => findPda(poolAddress, "onramp");
43563
+ var findMplMetadataAddress = async (poolMintAddress) => {
43564
+ const [pda] = PublicKey.findProgramAddressSync(
43565
+ [Buffer.from("metadata"), MPL_METADATA_PROGRAM_ID.toBuffer(), poolMintAddress.toBuffer()],
43566
+ MPL_METADATA_PROGRAM_ID
43567
+ );
43568
+ return pda;
43569
+ };
43366
43570
  BigInt(33);
43367
43571
  BigInt(200);
43368
43572
  BigInt(82);
@@ -44143,12 +44347,28 @@ var V1Client = class _V1Client {
44143
44347
  return new Promise((resolve, reject) => {
44144
44348
  const ws = new WebSocket(url, [SUBPROTOCOL]);
44145
44349
  ws.binaryType = "arraybuffer";
44146
- ws.on("open", () => {
44350
+ const onOpen = () => {
44351
+ ws.off("error", onError);
44352
+ ws.off("close", onClose);
44147
44353
  resolve(new _V1Client(ws));
44148
- });
44149
- ws.on("error", (err) => {
44354
+ };
44355
+ const onError = (err) => {
44356
+ ws.off("open", onOpen);
44357
+ ws.off("close", onClose);
44150
44358
  reject(err);
44151
- });
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);
44152
44372
  });
44153
44373
  }
44154
44374
  // --- Constructor ---
@@ -46149,10 +46369,11 @@ async function makeBorrowIx3({
46149
46369
  );
46150
46370
  borrowIxs.push(createAtaIdempotentIx);
46151
46371
  }
46372
+ const mandatoryBanks = [bank.address, ...opts.additionalHealthCheckBanks ?? []];
46152
46373
  const healthAccounts = computeHealthCheckAccounts(
46153
46374
  marginfiAccount.balances,
46154
46375
  bankMap,
46155
- [bank.address],
46376
+ mandatoryBanks,
46156
46377
  []
46157
46378
  );
46158
46379
  const remainingAccounts = [];
@@ -46687,81 +46908,116 @@ async function makeJuplendDepositTx(params) {
46687
46908
  });
46688
46909
  return solanaTx;
46689
46910
  }
46690
- async function makeRepayIx3({
46691
- program,
46692
- bank,
46693
- tokenProgram,
46694
- amount,
46695
- authority,
46696
- accountAddress,
46697
- repayAll = false,
46698
- isSync = false,
46699
- opts = {}
46700
- }) {
46701
- const wrapAndUnwrapSol = opts.wrapAndUnwrapSol ?? true;
46702
- const wSolBalanceUi = opts.wSolBalanceUi ?? 0;
46703
- const repayIxs = [];
46704
- const userAta = getAssociatedTokenAddressSync(bank.mint, authority, true, tokenProgram);
46705
- const remainingAccounts = tokenProgram.equals(TOKEN_2022_PROGRAM_ID) ? [{ pubkey: bank.mint, isSigner: false, isWritable: false }] : [];
46706
- if (bank.mint.equals(NATIVE_MINT) && wrapAndUnwrapSol) {
46707
- repayIxs.push(...makeWrapSolIxs(authority, new BigNumber(amount).minus(wSolBalanceUi)));
46708
- }
46709
- const repayIx = !isSync || !opts.overrideInferAccounts?.group ? await instructions_default.makeRepayIx(
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(
46710
46920
  program,
46711
46921
  {
46712
- marginfiAccount: accountAddress,
46713
- signerTokenAccount: userAta,
46714
- bank: bank.address,
46715
- tokenProgram,
46716
- authority: opts.overrideInferAccounts?.authority ?? authority,
46717
- group: opts.overrideInferAccounts?.group,
46718
- liquidityVault: opts.overrideInferAccounts?.liquidityVault
46922
+ marginfiAccount: marginfiAccountPk,
46923
+ authority
46719
46924
  },
46720
- { amount: uiToNative(amount, bank.mintDecimals), repayAll },
46721
- remainingAccounts
46722
- ) : sync_instructions_default.makeRepayIx(
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(
46723
46932
  program.programId,
46724
46933
  {
46725
- marginfiAccount: accountAddress,
46726
- signerTokenAccount: userAta,
46727
- bank: bank.address,
46728
- tokenProgram,
46729
- authority: opts.overrideInferAccounts?.authority ?? authority,
46730
- group: opts.overrideInferAccounts?.group
46934
+ marginfiAccount: marginfiAccountPk,
46935
+ authority
46731
46936
  },
46732
- { amount: uiToNative(amount, bank.mintDecimals), repayAll },
46733
- remainingAccounts
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
+ }))
46734
46953
  );
46735
- repayIxs.push(repayIx);
46736
- return {
46737
- instructions: repayIxs,
46738
- keys: []
46739
- };
46954
+ return { instructions: [ix], keys: [] };
46740
46955
  }
46741
- async function makeRepayTx(params) {
46742
- const { luts, ...depositIxParams } = params;
46743
- const ixs = await makeRepayIx3(depositIxParams);
46744
- const tx = new Transaction().add(...ixs.instructions);
46745
- tx.feePayer = params.authority;
46746
- const solanaTx = addTransactionMetadata(tx, {
46747
- type: "REPAY" /* REPAY */,
46748
- signers: ixs.keys,
46749
- addressLookupTables: luts
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;
46750
46976
  });
46751
- return solanaTx;
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;
46752
47005
  }
46753
- async function makeRepayWithCollatTx(params) {
47006
+
47007
+ // src/services/account/actions/loop.ts
47008
+ async function makeLoopTx(params) {
46754
47009
  const {
46755
47010
  program,
46756
47011
  marginfiAccount,
46757
47012
  bankMap,
46758
- withdrawOpts,
46759
- repayOpts,
47013
+ depositOpts,
47014
+ borrowOpts,
46760
47015
  bankMetadataMap,
46761
47016
  addressLookupTableAccounts,
46762
47017
  connection,
46763
47018
  oraclePrices,
46764
- crossbarUrl
47019
+ crossbarUrl,
47020
+ additionalIxs = []
46765
47021
  } = params;
46766
47022
  const blockhash = (await connection.getLatestBlockhash("confirmed")).blockhash;
46767
47023
  const setupIxs = await makeSetupIx({
@@ -46769,34 +47025,34 @@ async function makeRepayWithCollatTx(params) {
46769
47025
  authority: marginfiAccount.authority,
46770
47026
  tokens: [
46771
47027
  {
46772
- mint: repayOpts.repayBank.mint,
46773
- tokenProgram: repayOpts.tokenProgram
47028
+ mint: borrowOpts.borrowBank.mint,
47029
+ tokenProgram: borrowOpts.tokenProgram
46774
47030
  },
46775
47031
  {
46776
- mint: withdrawOpts.withdrawBank.mint,
46777
- tokenProgram: withdrawOpts.tokenProgram
47032
+ mint: depositOpts.depositBank.mint,
47033
+ tokenProgram: depositOpts.tokenProgram
46778
47034
  }
46779
47035
  ]
46780
47036
  });
46781
- const updateJuplendMarketIxs = makeUpdateJupLendRateIxs(
46782
- marginfiAccount,
46783
- bankMap,
46784
- [withdrawOpts.withdrawBank.address],
46785
- bankMetadataMap
47037
+ const updateJupLendRateIxs = makeUpdateJupLendRateIxs(
47038
+ params.marginfiAccount,
47039
+ params.bankMap,
47040
+ [depositOpts.depositBank.address],
47041
+ params.bankMetadataMap
46786
47042
  );
46787
47043
  const updateDriftMarketIxs = makeUpdateDriftMarketIxs(
46788
- marginfiAccount,
46789
- bankMap,
46790
- [withdrawOpts.withdrawBank.address],
46791
- bankMetadataMap
47044
+ params.marginfiAccount,
47045
+ params.bankMap,
47046
+ [depositOpts.depositBank.address],
47047
+ params.bankMetadataMap
46792
47048
  );
46793
47049
  const kaminoRefreshIxs = makeRefreshKaminoBanksIxs(
46794
47050
  marginfiAccount,
46795
47051
  bankMap,
46796
- [withdrawOpts.withdrawBank.address, repayOpts.repayBank.address],
47052
+ [borrowOpts.borrowBank.address, depositOpts.depositBank.address],
46797
47053
  bankMetadataMap
46798
47054
  );
46799
- const { flashloanTx, setupInstructions, swapQuote, amountToRepay, withdrawIxs, repayIxs } = await buildRepayWithCollatFlashloanTx({
47055
+ const { flashloanTx, setupInstructions, swapQuote, amountToDeposit, depositIxs, borrowIxs } = await buildLoopFlashloanTx({
46800
47056
  ...params,
46801
47057
  blockhash
46802
47058
  });
@@ -46806,7 +47062,7 @@ async function makeRepayWithCollatTx(params) {
46806
47062
  }
46807
47063
  if (ix.programId.equals(ASSOCIATED_TOKEN_PROGRAM_ID)) {
46808
47064
  const mintKey = ix.keys[3]?.pubkey;
46809
- if (mintKey?.equals(withdrawOpts.withdrawBank.mint) || mintKey?.equals(repayOpts.repayBank.mint)) {
47065
+ if (mintKey?.equals(depositOpts.depositBank.mint) || mintKey?.equals(borrowOpts.borrowBank.mint)) {
46810
47066
  return false;
46811
47067
  }
46812
47068
  }
@@ -46818,18 +47074,24 @@ async function makeRepayWithCollatTx(params) {
46818
47074
  bankMap,
46819
47075
  oraclePrices,
46820
47076
  assetShareValueMultiplierByBank: params.assetShareValueMultiplierByBank,
46821
- instructions: [...withdrawIxs.instructions, ...repayIxs.instructions],
47077
+ instructions: [...borrowIxs.instructions, ...depositIxs.instructions],
46822
47078
  program,
46823
47079
  connection,
46824
47080
  crossbarUrl
46825
47081
  });
46826
47082
  let additionalTxs = [];
46827
- if (setupIxs.length > 0 || kaminoRefreshIxs.instructions.length > 0 || updateDriftMarketIxs.instructions.length > 0 || updateJuplendMarketIxs.instructions.length > 0) {
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) {
46828
47089
  const ixs = [
47090
+ ...additionalIxs,
46829
47091
  ...setupIxs,
46830
47092
  ...kaminoRefreshIxs.instructions,
46831
47093
  ...updateDriftMarketIxs.instructions,
46832
- ...updateJuplendMarketIxs.instructions
47094
+ ...updateJupLendRateIxs.instructions
46833
47095
  ];
46834
47096
  const txs = splitInstructionsToFitTransactions([], ixs, {
46835
47097
  blockhash,
@@ -46859,16 +47121,19 @@ async function makeRepayWithCollatTx(params) {
46859
47121
  );
46860
47122
  }
46861
47123
  const transactions = [...additionalTxs, flashloanTx];
46862
- return { transactions, swapQuote, amountToRepay };
47124
+ return {
47125
+ transactions,
47126
+ actionTxIndex: transactions.length - 1,
47127
+ quoteResponse: swapQuote
47128
+ };
46863
47129
  }
46864
- async function buildRepayWithCollatFlashloanTx({
47130
+ async function buildLoopFlashloanTx({
46865
47131
  program,
46866
47132
  marginfiAccount,
46867
47133
  bankMap,
46868
- withdrawOpts,
46869
- repayOpts,
47134
+ borrowOpts,
47135
+ depositOpts,
46870
47136
  bankMetadataMap,
46871
- assetShareValueMultiplierByBank,
46872
47137
  addressLookupTableAccounts,
46873
47138
  connection,
46874
47139
  swapOpts,
@@ -46879,20 +47144,20 @@ async function buildRepayWithCollatFlashloanTx({
46879
47144
  ComputeBudgetProgram.setComputeUnitLimit({ units: 12e5 }),
46880
47145
  ComputeBudgetProgram.setComputeUnitPrice({ microLamports: 1 })
46881
47146
  ];
46882
- let amountToRepay;
47147
+ let amountToDeposit;
46883
47148
  let swapInstructions = [];
46884
47149
  let setupInstructions = [];
46885
47150
  let swapLookupTables = [];
46886
47151
  let swapQuote;
46887
47152
  let sizeConstraintUsed = 0;
46888
- if (repayOpts.repayBank.mint.equals(withdrawOpts.withdrawBank.mint)) {
46889
- amountToRepay = withdrawOpts.withdrawAmount;
47153
+ if (depositOpts.depositBank.mint.equals(borrowOpts.borrowBank.mint)) {
47154
+ amountToDeposit = borrowOpts.borrowAmount + (depositOpts.loopMode === "DEPOSIT" ? depositOpts.inputDepositAmount : 0);
46890
47155
  } else {
46891
47156
  const destinationTokenAccount = getAssociatedTokenAddressSync(
46892
- new PublicKey(repayOpts.repayBank.mint),
47157
+ new PublicKey(depositOpts.depositBank.mint),
46893
47158
  marginfiAccount.authority,
46894
47159
  true,
46895
- repayOpts.tokenProgram.equals(TOKEN_2022_PROGRAM_ID) ? TOKEN_2022_PROGRAM_ID : void 0
47160
+ depositOpts.tokenProgram.equals(TOKEN_2022_PROGRAM_ID) ? TOKEN_2022_PROGRAM_ID : void 0
46896
47161
  );
46897
47162
  const swapConstraints = await computeFlashloanSwapConstraints({
46898
47163
  program,
@@ -46901,78 +47166,76 @@ async function buildRepayWithCollatFlashloanTx({
46901
47166
  bankMetadataMap,
46902
47167
  addressLookupTableAccounts: addressLookupTableAccounts ?? [],
46903
47168
  primaryIx: {
46904
- type: "withdraw",
46905
- bank: withdrawOpts.withdrawBank,
46906
- tokenProgram: withdrawOpts.tokenProgram
47169
+ type: "borrow",
47170
+ bank: borrowOpts.borrowBank,
47171
+ tokenProgram: borrowOpts.tokenProgram
46907
47172
  },
46908
47173
  secondaryIx: {
46909
- type: "repay",
46910
- bank: repayOpts.repayBank,
46911
- tokenProgram: repayOpts.tokenProgram
47174
+ type: "deposit",
47175
+ bank: depositOpts.depositBank,
47176
+ tokenProgram: depositOpts.tokenProgram
46912
47177
  },
46913
47178
  overrideInferAccounts
46914
47179
  });
46915
47180
  const swapResponse = await getSwapIxsForFlashloan({
46916
- inputMint: withdrawOpts.withdrawBank.mint.toBase58(),
46917
- outputMint: repayOpts.repayBank.mint.toBase58(),
46918
- amount: uiToNative(
46919
- withdrawOpts.withdrawAmount,
46920
- withdrawOpts.withdrawBank.mintDecimals
46921
- ).toNumber(),
47181
+ inputMint: borrowOpts.borrowBank.mint.toBase58(),
47182
+ outputMint: depositOpts.depositBank.mint.toBase58(),
47183
+ amount: uiToNative(borrowOpts.borrowAmount, borrowOpts.borrowBank.mintDecimals).toNumber(),
46922
47184
  swapMode: "ExactIn",
46923
47185
  authority: marginfiAccount.authority,
46924
47186
  connection,
46925
47187
  destinationTokenAccount,
46926
47188
  swapOpts,
46927
47189
  sizeConstraint: swapConstraints.sizeConstraint,
46928
- maxSwapAccounts: swapConstraints.maxSwapWritableAccounts,
46929
47190
  maxSwapTotalAccounts: swapConstraints.maxSwapTotalAccounts
46930
47191
  });
46931
47192
  sizeConstraintUsed = swapConstraints.sizeConstraint;
46932
- const { quoteResponse } = swapResponse;
46933
- const outAmount = nativeToUi(quoteResponse.outAmount, repayOpts.repayBank.mintDecimals);
46934
47193
  const outAmountThreshold = nativeToUi(
46935
- quoteResponse.otherAmountThreshold,
46936
- repayOpts.repayBank.mintDecimals
47194
+ swapResponse.quoteResponse.otherAmountThreshold,
47195
+ depositOpts.depositBank.mintDecimals
46937
47196
  );
46938
- amountToRepay = outAmount > repayOpts.totalPositionAmount ? repayOpts.totalPositionAmount : outAmountThreshold;
47197
+ amountToDeposit = outAmountThreshold + (depositOpts.loopMode === "DEPOSIT" ? depositOpts.inputDepositAmount : 0);
46939
47198
  swapInstructions = swapResponse.swapInstructions;
47199
+ setupInstructions = swapResponse.setupInstructions;
46940
47200
  swapLookupTables = swapResponse.addressLookupTableAddresses;
46941
- swapQuote = quoteResponse;
47201
+ swapQuote = swapResponse.quoteResponse;
46942
47202
  }
46943
- let withdrawIxs;
46944
- switch (withdrawOpts.withdrawBank.config.assetTag) {
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) {
46945
47220
  case 3 /* KAMINO */: {
46946
- const reserve = bankMetadataMap[withdrawOpts.withdrawBank.address.toBase58()]?.kaminoStates?.reserveState;
47221
+ const reserve = bankMetadataMap[depositOpts.depositBank.address.toBase58()]?.kaminoStates?.reserveState;
46947
47222
  if (!reserve) {
46948
47223
  throw TransactionBuildingError.kaminoReserveNotFound(
46949
- withdrawOpts.withdrawBank.address.toBase58(),
46950
- withdrawOpts.withdrawBank.mint.toBase58(),
46951
- withdrawOpts.withdrawBank.tokenSymbol
47224
+ depositOpts.depositBank.address.toBase58(),
47225
+ depositOpts.depositBank.mint.toBase58(),
47226
+ depositOpts.depositBank.tokenSymbol
46952
47227
  );
46953
47228
  }
46954
- const multiplier = assetShareValueMultiplierByBank.get(withdrawOpts.withdrawBank.address.toBase58()) ?? new BigNumber(1);
46955
- const adjustedAmount = new BigNumber(withdrawOpts.withdrawAmount).div(multiplier).times(1.0001).toNumber();
46956
- withdrawIxs = await makeKaminoWithdrawIx3({
47229
+ depositIxs = await makeKaminoDepositIx3({
46957
47230
  program,
46958
- bank: withdrawOpts.withdrawBank,
46959
- bankMap,
46960
- tokenProgram: withdrawOpts.tokenProgram,
46961
- cTokenAmount: adjustedAmount,
46962
- marginfiAccount,
47231
+ bank: depositOpts.depositBank,
47232
+ tokenProgram: depositOpts.tokenProgram,
47233
+ amount: amountToDeposit,
47234
+ accountAddress: marginfiAccount.address,
46963
47235
  authority: marginfiAccount.authority,
47236
+ group: marginfiAccount.group,
46964
47237
  reserve,
46965
- withdrawAll: isWholePosition(
46966
- {
46967
- amount: withdrawOpts.totalPositionAmount,
46968
- isLending: true
46969
- },
46970
- withdrawOpts.withdrawAmount,
46971
- withdrawOpts.withdrawBank.mintDecimals
46972
- ),
46973
- isSync: false,
46974
47238
  opts: {
46975
- createAtas: false,
46976
47239
  wrapAndUnwrapSol: false,
46977
47240
  overrideInferAccounts
46978
47241
  }
@@ -46980,35 +47243,27 @@ async function buildRepayWithCollatFlashloanTx({
46980
47243
  break;
46981
47244
  }
46982
47245
  case 4 /* DRIFT */: {
46983
- const driftState = bankMetadataMap[withdrawOpts.withdrawBank.address.toBase58()]?.driftStates;
47246
+ const driftState = bankMetadataMap[depositOpts.depositBank.address.toBase58()]?.driftStates;
46984
47247
  if (!driftState) {
46985
47248
  throw TransactionBuildingError.driftStateNotFound(
46986
- withdrawOpts.withdrawBank.address.toBase58(),
46987
- withdrawOpts.withdrawBank.mint.toBase58(),
46988
- withdrawOpts.withdrawBank.tokenSymbol
47249
+ depositOpts.depositBank.address.toBase58(),
47250
+ depositOpts.depositBank.mint.toBase58(),
47251
+ depositOpts.depositBank.tokenSymbol
46989
47252
  );
46990
47253
  }
46991
- withdrawIxs = await makeDriftWithdrawIx3({
47254
+ const driftMarketIndex = driftState.spotMarketState.marketIndex;
47255
+ const driftOracle = driftState.spotMarketState.oracle;
47256
+ depositIxs = await makeDriftDepositIx3({
46992
47257
  program,
46993
- bank: withdrawOpts.withdrawBank,
46994
- bankMap,
46995
- tokenProgram: withdrawOpts.tokenProgram,
46996
- amount: withdrawOpts.withdrawAmount,
46997
- marginfiAccount,
47258
+ bank: depositOpts.depositBank,
47259
+ tokenProgram: depositOpts.tokenProgram,
47260
+ amount: amountToDeposit,
47261
+ accountAddress: marginfiAccount.address,
46998
47262
  authority: marginfiAccount.authority,
46999
- driftSpotMarket: driftState.spotMarketState,
47000
- userRewards: driftState.userRewards,
47001
- withdrawAll: isWholePosition(
47002
- {
47003
- amount: withdrawOpts.totalPositionAmount,
47004
- isLending: true
47005
- },
47006
- withdrawOpts.withdrawAmount,
47007
- withdrawOpts.withdrawBank.mintDecimals
47008
- ),
47009
- isSync: false,
47263
+ group: marginfiAccount.group,
47264
+ driftMarketIndex,
47265
+ driftOracle,
47010
47266
  opts: {
47011
- createAtas: false,
47012
47267
  wrapAndUnwrapSol: false,
47013
47268
  overrideInferAccounts
47014
47269
  }
@@ -47016,686 +47271,156 @@ async function buildRepayWithCollatFlashloanTx({
47016
47271
  break;
47017
47272
  }
47018
47273
  case 6 /* JUPLEND */: {
47019
- const jupLendState = bankMetadataMap[withdrawOpts.withdrawBank.address.toBase58()]?.jupLendStates;
47020
- if (!jupLendState) {
47021
- throw TransactionBuildingError.jupLendStateNotFound(
47022
- withdrawOpts.withdrawBank.address.toBase58(),
47023
- withdrawOpts.withdrawBank.mint.toBase58(),
47024
- withdrawOpts.withdrawBank.tokenSymbol
47025
- );
47026
- }
47027
- withdrawIxs = await makeJuplendWithdrawIx2({
47028
- program,
47029
- bank: withdrawOpts.withdrawBank,
47030
- bankMap,
47031
- tokenProgram: withdrawOpts.tokenProgram,
47032
- amount: withdrawOpts.withdrawAmount,
47033
- marginfiAccount,
47034
- authority: marginfiAccount.authority,
47035
- jupLendingState: jupLendState.jupLendingState,
47036
- withdrawAll: isWholePosition(
47037
- {
47038
- amount: withdrawOpts.totalPositionAmount,
47039
- isLending: true
47040
- },
47041
- withdrawOpts.withdrawAmount,
47042
- withdrawOpts.withdrawBank.mintDecimals
47043
- ),
47044
- opts: {
47045
- createAtas: false,
47046
- wrapAndUnwrapSol: false,
47047
- overrideInferAccounts
47048
- }
47049
- });
47050
- break;
47051
- }
47052
- default: {
47053
- withdrawIxs = await makeWithdrawIx3({
47274
+ depositIxs = await makeJuplendDepositIx2({
47054
47275
  program,
47055
- bank: withdrawOpts.withdrawBank,
47056
- bankMap,
47057
- tokenProgram: withdrawOpts.tokenProgram,
47058
- amount: withdrawOpts.withdrawAmount,
47059
- marginfiAccount,
47276
+ bank: depositOpts.depositBank,
47277
+ tokenProgram: depositOpts.tokenProgram,
47278
+ amount: amountToDeposit,
47279
+ accountAddress: marginfiAccount.address,
47060
47280
  authority: marginfiAccount.authority,
47061
- withdrawAll: isWholePosition(
47062
- {
47063
- amount: withdrawOpts.totalPositionAmount,
47064
- isLending: true
47065
- },
47066
- withdrawOpts.withdrawAmount,
47067
- withdrawOpts.withdrawBank.mintDecimals
47068
- ),
47069
- isSync: false,
47281
+ group: marginfiAccount.group,
47070
47282
  opts: {
47071
- createAtas: false,
47072
47283
  wrapAndUnwrapSol: false,
47073
47284
  overrideInferAccounts
47074
47285
  }
47075
47286
  });
47076
47287
  break;
47077
47288
  }
47078
- }
47079
- const repayIxs = await makeRepayIx3({
47080
- program,
47081
- bank: repayOpts.repayBank,
47082
- tokenProgram: repayOpts.tokenProgram,
47083
- amount: amountToRepay,
47084
- accountAddress: marginfiAccount.address,
47085
- authority: marginfiAccount.authority,
47086
- repayAll: isWholePosition(
47087
- {
47088
- amount: repayOpts.totalPositionAmount,
47089
- isLending: true
47090
- },
47091
- amountToRepay,
47092
- repayOpts.repayBank.mintDecimals
47093
- ),
47094
- isSync: false,
47095
- opts: {
47096
- wrapAndUnwrapSol: false,
47097
- overrideInferAccounts
47098
- }
47099
- });
47100
- const luts = [...addressLookupTableAccounts ?? [], ...swapLookupTables];
47101
- const allNonFlIxs = [
47102
- ...cuRequestIxs,
47103
- ...withdrawIxs.instructions,
47104
- ...swapInstructions,
47105
- ...repayIxs.instructions
47106
- ];
47107
- if (swapInstructions.length > 0) {
47108
- compileFlashloanPrecheck({
47109
- allIxs: allNonFlIxs,
47110
- payer: marginfiAccount.authority,
47111
- luts,
47112
- sizeConstraint: sizeConstraintUsed,
47113
- swapIxCount: swapInstructions.length,
47114
- swapLutCount: swapLookupTables.length
47115
- });
47116
- }
47117
- const flashloanTx = await makeFlashLoanTx({
47118
- program,
47119
- marginfiAccount,
47120
- bankMap,
47121
- addressLookupTableAccounts: luts,
47122
- blockhash,
47123
- ixs: allNonFlIxs,
47124
- isSync: true
47125
- });
47126
- const txSize = getTxSize(flashloanTx);
47127
- const writableKeys = getWritableAccountKeys(flashloanTx);
47128
- const totalKeys = getTotalAccountKeys(flashloanTx);
47129
- if (txSize > MAX_TX_SIZE || writableKeys > MAX_WRITABLE_ACCOUNTS || totalKeys > MAX_ACCOUNT_LOCKS) {
47130
- throw TransactionBuildingError.swapSizeExceededRepay(
47131
- txSize,
47132
- writableKeys,
47133
- swapOpts.swapConfig?.provider
47134
- );
47135
- }
47136
- return {
47137
- flashloanTx,
47138
- setupInstructions,
47139
- swapQuote,
47140
- withdrawIxs,
47141
- repayIxs,
47142
- amountToRepay
47143
- };
47144
- }
47145
-
47146
- // src/services/account/utils/flashloan-size.utils.ts
47147
- var SWAP_MERGE_OVERHEAD = 150;
47148
- var FL_IX_OVERHEAD = 52;
47149
- function compactU16Size(n) {
47150
- return n < 128 ? 1 : n < 16384 ? 2 : 3;
47151
- }
47152
- function computeV0TxSize(ixs, payerKey, luts) {
47153
- const keyMap = /* @__PURE__ */ new Map();
47154
- const payerStr = payerKey.toBase58();
47155
- keyMap.set(payerStr, { isSigner: true, isWritable: true });
47156
- const programIds = /* @__PURE__ */ new Set();
47157
- for (const ix of ixs) {
47158
- const progStr = ix.programId.toBase58();
47159
- programIds.add(progStr);
47160
- if (!keyMap.has(progStr)) {
47161
- keyMap.set(progStr, { isSigner: false, isWritable: false });
47162
- }
47163
- for (const meta of ix.keys) {
47164
- const keyStr = meta.pubkey.toBase58();
47165
- const existing = keyMap.get(keyStr);
47166
- if (existing) {
47167
- existing.isSigner = existing.isSigner || meta.isSigner;
47168
- existing.isWritable = existing.isWritable || meta.isWritable;
47169
- } else {
47170
- keyMap.set(keyStr, { isSigner: meta.isSigner, isWritable: meta.isWritable });
47171
- }
47172
- }
47173
- }
47174
- const lutLookup = /* @__PURE__ */ new Map();
47175
- for (let li = 0; li < luts.length; li++) {
47176
- const addresses = luts[li].state.addresses;
47177
- for (let ai = 0; ai < addresses.length; ai++) {
47178
- const addrStr = addresses[ai].toBase58();
47179
- if (!lutLookup.has(addrStr)) {
47180
- lutLookup.set(addrStr, { lutIdx: li, addrIdx: ai });
47181
- }
47182
- }
47183
- }
47184
- let numStaticKeys = 0;
47185
- let numWritableStaticKeys = 0;
47186
- const lutWritableIdxs = luts.map(() => /* @__PURE__ */ new Set());
47187
- const lutReadonlyIdxs = luts.map(() => /* @__PURE__ */ new Set());
47188
- for (const [keyStr, props] of keyMap) {
47189
- if (props.isSigner || programIds.has(keyStr)) {
47190
- numStaticKeys++;
47191
- if (props.isWritable) numWritableStaticKeys++;
47192
- continue;
47193
- }
47194
- const lutEntry = lutLookup.get(keyStr);
47195
- if (lutEntry) {
47196
- if (props.isWritable) {
47197
- lutWritableIdxs[lutEntry.lutIdx].add(lutEntry.addrIdx);
47198
- } else {
47199
- lutReadonlyIdxs[lutEntry.lutIdx].add(lutEntry.addrIdx);
47200
- }
47201
- } else {
47202
- numStaticKeys++;
47203
- if (props.isWritable) numWritableStaticKeys++;
47204
- }
47205
- }
47206
- const fixedOverhead = 101;
47207
- const staticKeysSection = compactU16Size(numStaticKeys) + numStaticKeys * 32;
47208
- let ixSection = compactU16Size(ixs.length);
47209
- for (const ix of ixs) {
47210
- const numAccounts = ix.keys.length;
47211
- ixSection += 1 + // programId index
47212
- compactU16Size(numAccounts) + numAccounts + // account key indexes
47213
- compactU16Size(ix.data.length) + ix.data.length;
47214
- }
47215
- let numUsedLuts = 0;
47216
- let lutSection = 0;
47217
- for (let li = 0; li < luts.length; li++) {
47218
- const wCount = lutWritableIdxs[li].size;
47219
- const rCount = lutReadonlyIdxs[li].size;
47220
- if (wCount === 0 && rCount === 0) continue;
47221
- numUsedLuts++;
47222
- lutSection += 32 + // LUT address
47223
- compactU16Size(wCount) + wCount + // writable indexes
47224
- compactU16Size(rCount) + rCount;
47225
- }
47226
- lutSection += compactU16Size(numUsedLuts);
47227
- let totalLutKeys = 0;
47228
- for (let li = 0; li < luts.length; li++) {
47229
- totalLutKeys += lutWritableIdxs[li].size + lutReadonlyIdxs[li].size;
47230
- }
47231
- const accountCount = numStaticKeys + totalLutKeys;
47232
- let totalLutWritableKeys = 0;
47233
- for (let li = 0; li < luts.length; li++) {
47234
- totalLutWritableKeys += lutWritableIdxs[li].size;
47235
- }
47236
- const writableAccountCount = numWritableStaticKeys + totalLutWritableKeys;
47237
- const size = fixedOverhead + staticKeysSection + ixSection + lutSection + 1;
47238
- return { size, accountCount, writableAccountCount };
47239
- }
47240
- function computeFlashLoanNonSwapBudget({
47241
- program,
47242
- marginfiAccount,
47243
- ixs,
47244
- bankMap,
47245
- addressLookupTableAccounts
47246
- }) {
47247
- const projectedActiveBanksKeys = computeProjectedActiveBanksNoCpi(
47248
- marginfiAccount.balances,
47249
- ixs,
47250
- program
47251
- );
47252
- const projectedActiveBanks = projectedActiveBanksKeys.map((key) => {
47253
- const b = bankMap.get(key.toBase58());
47254
- if (!b) throw new Error(`Bank ${key.toBase58()} not found in computeFlashLoanNonSwapBudget`);
47255
- return b;
47256
- });
47257
- const endIndex = ixs.length + 1;
47258
- const beginFlIx = sync_instructions_default.makeBeginFlashLoanIx(
47259
- program.programId,
47260
- { marginfiAccount: marginfiAccount.address, authority: marginfiAccount.authority },
47261
- { endIndex: new BN11(endIndex) }
47262
- );
47263
- const endFlRemainingAccounts = computeHealthAccountMetas(projectedActiveBanks);
47264
- const endFlIx = sync_instructions_default.makeEndFlashLoanIx(
47265
- program.programId,
47266
- { marginfiAccount: marginfiAccount.address, authority: marginfiAccount.authority },
47267
- endFlRemainingAccounts.map((pubkey) => ({ pubkey, isSigner: false, isWritable: false }))
47268
- );
47269
- const allNonSwapIxs = [beginFlIx, ...ixs, endFlIx];
47270
- const nonSwapMsg = new TransactionMessage({
47271
- payerKey: marginfiAccount.authority,
47272
- recentBlockhash: PublicKey.default.toBase58(),
47273
- instructions: allNonSwapIxs
47274
- }).compileToV0Message(addressLookupTableAccounts);
47275
- const nonSwapSize = new VersionedTransaction(nonSwapMsg).serialize().length;
47276
- const { header, staticAccountKeys, addressTableLookups } = nonSwapMsg;
47277
- const writableStatic = staticAccountKeys.length - header.numReadonlySignedAccounts - header.numReadonlyUnsignedAccounts;
47278
- const writableLut = addressTableLookups.reduce((s, l) => s + l.writableIndexes.length, 0);
47279
- const nonSwapWritable = writableStatic + writableLut;
47280
- const nonSwapTotal = staticAccountKeys.length + addressTableLookups.reduce(
47281
- (s, l) => s + l.writableIndexes.length + l.readonlyIndexes.length,
47282
- 0
47283
- );
47284
- const sizeConstraint = MAX_TX_SIZE - nonSwapSize - SWAP_MERGE_OVERHEAD;
47285
- const maxSwapWritableAccounts = MAX_WRITABLE_ACCOUNTS - nonSwapWritable;
47286
- const maxSwapTotalAccounts = MAX_ACCOUNT_LOCKS - nonSwapTotal;
47287
- console.log("[flashloan-budget]", {
47288
- method: "compiled",
47289
- nonSwapSize,
47290
- nonSwapWritable,
47291
- nonSwapTotal,
47292
- sizeConstraint,
47293
- maxSwapWritableAccounts,
47294
- maxSwapTotalAccounts
47295
- });
47296
- return { sizeConstraint, maxSwapWritableAccounts, maxSwapTotalAccounts };
47297
- }
47298
- function compileFlashloanPrecheck({
47299
- allIxs,
47300
- payer,
47301
- luts,
47302
- sizeConstraint,
47303
- swapIxCount,
47304
- swapLutCount
47305
- }) {
47306
- const msg = new TransactionMessage({
47307
- payerKey: payer,
47308
- recentBlockhash: PublicKey.default.toBase58(),
47309
- instructions: allIxs
47310
- }).compileToV0Message(luts);
47311
- const rawSize = new VersionedTransaction(msg).serialize().length;
47312
- const fullTxSize = rawSize + FL_IX_OVERHEAD;
47313
- const overshoot = fullTxSize - MAX_TX_SIZE;
47314
- const { header, staticAccountKeys, addressTableLookups } = msg;
47315
- const writableStatic = staticAccountKeys.length - header.numReadonlySignedAccounts - header.numReadonlyUnsignedAccounts;
47316
- const writableLut = addressTableLookups.reduce((s, l) => s + l.writableIndexes.length, 0);
47317
- const writableAccounts = writableStatic + writableLut;
47318
- const totalAccounts = staticAccountKeys.length + addressTableLookups.reduce(
47319
- (s, l) => s + l.writableIndexes.length + l.readonlyIndexes.length,
47320
- 0
47321
- );
47322
- console.log("[flashloan-precheck]", {
47323
- fullTxSize,
47324
- overshoot,
47325
- sizeConstraint,
47326
- writableAccounts,
47327
- totalAccounts,
47328
- staticKeys: staticAccountKeys.length,
47329
- numLuts: addressTableLookups.length,
47330
- swapIxCount,
47331
- swapLutCount
47332
- });
47333
- return { fullTxSize, overshoot, writableAccounts, totalAccounts };
47334
- }
47335
- async function buildBudgetIx(config, program, marginfiAccount, bankMap, bankMetadataMap, overrideInferAccounts) {
47336
- const { bank, tokenProgram } = config;
47337
- switch (config.type) {
47338
- case "borrow":
47339
- return makeBorrowIx3({
47340
- program,
47341
- bank,
47342
- bankMap,
47343
- tokenProgram,
47344
- amount: 1,
47345
- marginfiAccount,
47346
- authority: marginfiAccount.authority,
47347
- isSync: true,
47348
- opts: { createAtas: false, wrapAndUnwrapSol: false, overrideInferAccounts }
47349
- });
47350
- case "repay":
47351
- return makeRepayIx3({
47352
- program,
47353
- bank,
47354
- tokenProgram,
47355
- amount: 1,
47356
- accountAddress: marginfiAccount.address,
47357
- authority: marginfiAccount.authority,
47358
- repayAll: false,
47359
- isSync: true,
47360
- opts: { wrapAndUnwrapSol: false, overrideInferAccounts }
47361
- });
47362
- case "deposit":
47363
- return buildDepositBudgetIx(
47364
- config,
47365
- program,
47366
- marginfiAccount,
47367
- bankMetadataMap,
47368
- overrideInferAccounts
47369
- );
47370
- case "withdraw":
47371
- return buildWithdrawBudgetIx(
47372
- config,
47373
- program,
47374
- marginfiAccount,
47375
- bankMap,
47376
- bankMetadataMap,
47377
- overrideInferAccounts
47378
- );
47379
- }
47380
- }
47381
- async function buildDepositBudgetIx(config, program, marginfiAccount, bankMetadataMap, overrideInferAccounts) {
47382
- const { bank, tokenProgram } = config;
47383
- const opts = { wrapAndUnwrapSol: false, overrideInferAccounts };
47384
- switch (bank.config.assetTag) {
47385
- case 3 /* KAMINO */: {
47386
- const reserve = bankMetadataMap[bank.address.toBase58()]?.kaminoStates?.reserveState;
47387
- if (!reserve) {
47388
- throw TransactionBuildingError.kaminoReserveNotFound(
47389
- bank.address.toBase58(),
47390
- bank.mint.toBase58(),
47391
- bank.tokenSymbol
47392
- );
47393
- }
47394
- return makeKaminoDepositIx3({
47395
- program,
47396
- bank,
47397
- tokenProgram,
47398
- amount: 1,
47399
- accountAddress: marginfiAccount.address,
47400
- authority: marginfiAccount.authority,
47401
- group: marginfiAccount.group,
47402
- reserve,
47403
- isSync: true,
47404
- opts
47405
- });
47406
- }
47407
- case 4 /* DRIFT */: {
47408
- const driftState = bankMetadataMap[bank.address.toBase58()]?.driftStates;
47409
- if (!driftState) {
47410
- throw TransactionBuildingError.driftStateNotFound(
47411
- bank.address.toBase58(),
47412
- bank.mint.toBase58(),
47413
- bank.tokenSymbol
47414
- );
47415
- }
47416
- return makeDriftDepositIx3({
47417
- program,
47418
- bank,
47419
- tokenProgram,
47420
- amount: 1,
47421
- accountAddress: marginfiAccount.address,
47422
- authority: marginfiAccount.authority,
47423
- group: marginfiAccount.group,
47424
- driftMarketIndex: driftState.spotMarketState.marketIndex,
47425
- driftOracle: driftState.spotMarketState.oracle,
47426
- isSync: true,
47427
- opts
47428
- });
47429
- }
47430
- case 6 /* JUPLEND */: {
47431
- return makeJuplendDepositIx2({
47432
- program,
47433
- bank,
47434
- tokenProgram,
47435
- amount: 1,
47436
- accountAddress: marginfiAccount.address,
47437
- authority: marginfiAccount.authority,
47438
- group: marginfiAccount.group,
47439
- isSync: true,
47440
- opts
47441
- });
47442
- }
47443
- default: {
47444
- return makeDepositIx3({
47445
- program,
47446
- bank,
47447
- tokenProgram,
47448
- amount: 1,
47449
- accountAddress: marginfiAccount.address,
47450
- authority: marginfiAccount.authority,
47451
- group: marginfiAccount.group,
47452
- isSync: true,
47453
- opts
47454
- });
47455
- }
47456
- }
47457
- }
47458
- async function buildWithdrawBudgetIx(config, program, marginfiAccount, bankMap, bankMetadataMap, overrideInferAccounts) {
47459
- const { bank, tokenProgram } = config;
47460
- const opts = { createAtas: false, wrapAndUnwrapSol: false, overrideInferAccounts };
47461
- switch (bank.config.assetTag) {
47462
- case 3 /* KAMINO */: {
47463
- const reserve = bankMetadataMap[bank.address.toBase58()]?.kaminoStates?.reserveState;
47464
- if (!reserve) {
47465
- throw TransactionBuildingError.kaminoReserveNotFound(
47466
- bank.address.toBase58(),
47467
- bank.mint.toBase58(),
47468
- bank.tokenSymbol
47469
- );
47470
- }
47471
- return makeKaminoWithdrawIx3({
47472
- program,
47473
- bank,
47474
- bankMap,
47475
- tokenProgram,
47476
- cTokenAmount: 1,
47477
- marginfiAccount,
47478
- authority: marginfiAccount.authority,
47479
- reserve,
47480
- withdrawAll: false,
47481
- isSync: true,
47482
- opts
47483
- });
47484
- }
47485
- case 4 /* DRIFT */: {
47486
- const driftState = bankMetadataMap[bank.address.toBase58()]?.driftStates;
47487
- if (!driftState) {
47488
- throw TransactionBuildingError.driftStateNotFound(
47489
- bank.address.toBase58(),
47490
- bank.mint.toBase58(),
47491
- bank.tokenSymbol
47492
- );
47493
- }
47494
- return makeDriftWithdrawIx3({
47495
- program,
47496
- bank,
47497
- bankMap,
47498
- tokenProgram,
47499
- amount: 1,
47500
- marginfiAccount,
47501
- authority: marginfiAccount.authority,
47502
- driftSpotMarket: driftState.spotMarketState,
47503
- userRewards: driftState.userRewards,
47504
- withdrawAll: false,
47505
- isSync: true,
47506
- opts
47507
- });
47508
- }
47509
- case 6 /* JUPLEND */: {
47510
- const jupLendState = bankMetadataMap[bank.address.toBase58()]?.jupLendStates;
47511
- if (!jupLendState) {
47512
- throw TransactionBuildingError.jupLendStateNotFound(
47513
- bank.address.toBase58(),
47514
- bank.mint.toBase58(),
47515
- bank.tokenSymbol
47516
- );
47517
- }
47518
- return makeJuplendWithdrawIx2({
47519
- program,
47520
- bank,
47521
- bankMap,
47522
- tokenProgram,
47523
- amount: 1,
47524
- marginfiAccount,
47525
- authority: marginfiAccount.authority,
47526
- jupLendingState: jupLendState.jupLendingState,
47527
- withdrawAll: false,
47528
- opts
47529
- });
47530
- }
47531
- default: {
47532
- return makeWithdrawIx3({
47533
- program,
47534
- bank,
47535
- bankMap,
47536
- tokenProgram,
47537
- amount: 1,
47538
- marginfiAccount,
47289
+ default: {
47290
+ depositIxs = await makeDepositIx3({
47291
+ program,
47292
+ bank: depositOpts.depositBank,
47293
+ tokenProgram: depositOpts.tokenProgram,
47294
+ amount: amountToDeposit,
47295
+ accountAddress: marginfiAccount.address,
47539
47296
  authority: marginfiAccount.authority,
47540
- withdrawAll: false,
47541
- isSync: true,
47542
- opts
47297
+ group: marginfiAccount.group,
47298
+ opts: {
47299
+ wrapAndUnwrapSol: false,
47300
+ overrideInferAccounts
47301
+ }
47543
47302
  });
47303
+ break;
47544
47304
  }
47545
47305
  }
47546
- }
47547
- async function computeFlashloanSwapConstraints({
47548
- program,
47549
- marginfiAccount,
47550
- bankMap,
47551
- addressLookupTableAccounts,
47552
- bankMetadataMap,
47553
- primaryIx,
47554
- secondaryIx,
47555
- overrideInferAccounts
47556
- }) {
47557
- const cuRequestIxs = [
47558
- ComputeBudgetProgram.setComputeUnitLimit({ units: 12e5 }),
47559
- ComputeBudgetProgram.setComputeUnitPrice({ microLamports: 1 })
47306
+ const luts = [...addressLookupTableAccounts ?? [], ...swapLookupTables];
47307
+ const allNonFlIxs = [
47308
+ ...cuRequestIxs,
47309
+ ...borrowIxs.instructions,
47310
+ ...swapInstructions,
47311
+ ...depositIxs.instructions
47560
47312
  ];
47561
- const [primaryResult, secondaryResult] = await Promise.all([
47562
- buildBudgetIx(
47563
- primaryIx,
47564
- program,
47565
- marginfiAccount,
47566
- bankMap,
47567
- bankMetadataMap,
47568
- overrideInferAccounts
47569
- ),
47570
- buildBudgetIx(
47571
- secondaryIx,
47572
- program,
47573
- marginfiAccount,
47574
- bankMap,
47575
- bankMetadataMap,
47576
- overrideInferAccounts
47577
- )
47578
- ]);
47579
- return computeFlashLoanNonSwapBudget({
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({
47580
47324
  program,
47581
47325
  marginfiAccount,
47582
47326
  bankMap,
47583
- addressLookupTableAccounts,
47584
- ixs: [...cuRequestIxs, ...primaryResult.instructions, ...secondaryResult.instructions]
47327
+ addressLookupTableAccounts: luts,
47328
+ blockhash,
47329
+ ixs: allNonFlIxs
47585
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
+ };
47586
47348
  }
47587
-
47588
- // src/services/account/actions/flash-loan.ts
47589
- async function makeBeginFlashLoanIx3(program, marginfiAccountPk, endIndex, authority, isSync) {
47590
- const ix = isSync && authority ? sync_instructions_default.makeBeginFlashLoanIx(
47591
- program.programId,
47592
- {
47593
- marginfiAccount: marginfiAccountPk,
47594
- authority
47595
- },
47596
- { endIndex: new BN11(endIndex) }
47597
- ) : await instructions_default.makeBeginFlashLoanIx(
47349
+ async function makeRepayIx3({
47350
+ program,
47351
+ bank,
47352
+ tokenProgram,
47353
+ amount,
47354
+ authority,
47355
+ accountAddress,
47356
+ repayAll = false,
47357
+ isSync = false,
47358
+ opts = {}
47359
+ }) {
47360
+ const wrapAndUnwrapSol = opts.wrapAndUnwrapSol ?? true;
47361
+ const wSolBalanceUi = opts.wSolBalanceUi ?? 0;
47362
+ const repayIxs = [];
47363
+ const userAta = getAssociatedTokenAddressSync(bank.mint, authority, true, tokenProgram);
47364
+ const remainingAccounts = tokenProgram.equals(TOKEN_2022_PROGRAM_ID) ? [{ pubkey: bank.mint, isSigner: false, isWritable: false }] : [];
47365
+ if (bank.mint.equals(NATIVE_MINT) && wrapAndUnwrapSol) {
47366
+ repayIxs.push(...makeWrapSolIxs(authority, new BigNumber(amount).minus(wSolBalanceUi)));
47367
+ }
47368
+ const repayIx = !isSync || !opts.overrideInferAccounts?.group ? await instructions_default.makeRepayIx(
47598
47369
  program,
47599
47370
  {
47600
- marginfiAccount: marginfiAccountPk,
47601
- authority
47371
+ marginfiAccount: accountAddress,
47372
+ signerTokenAccount: userAta,
47373
+ bank: bank.address,
47374
+ tokenProgram,
47375
+ authority: opts.overrideInferAccounts?.authority ?? authority,
47376
+ group: opts.overrideInferAccounts?.group,
47377
+ liquidityVault: opts.overrideInferAccounts?.liquidityVault
47602
47378
  },
47603
- { endIndex: new BN11(endIndex) }
47604
- );
47605
- return { instructions: [ix], keys: [] };
47606
- }
47607
- async function makeEndFlashLoanIx3(program, marginfiAccountPk, projectedActiveBanks, authority, isSync) {
47608
- const remainingAccounts = computeHealthAccountMetas(projectedActiveBanks);
47609
- const ix = isSync && authority ? sync_instructions_default.makeEndFlashLoanIx(
47379
+ { amount: uiToNative(amount, bank.mintDecimals), repayAll },
47380
+ remainingAccounts
47381
+ ) : sync_instructions_default.makeRepayIx(
47610
47382
  program.programId,
47611
47383
  {
47612
- marginfiAccount: marginfiAccountPk,
47613
- authority
47614
- },
47615
- remainingAccounts.map((account) => ({
47616
- pubkey: account,
47617
- isSigner: false,
47618
- isWritable: false
47619
- }))
47620
- ) : await instructions_default.makeEndFlashLoanIx(
47621
- program,
47622
- {
47623
- marginfiAccount: marginfiAccountPk,
47624
- authority
47384
+ marginfiAccount: accountAddress,
47385
+ signerTokenAccount: userAta,
47386
+ bank: bank.address,
47387
+ tokenProgram,
47388
+ authority: opts.overrideInferAccounts?.authority ?? authority,
47389
+ group: opts.overrideInferAccounts?.group
47625
47390
  },
47626
- remainingAccounts.map((account) => ({
47627
- pubkey: account,
47628
- isSigner: false,
47629
- isWritable: false
47630
- }))
47391
+ { amount: uiToNative(amount, bank.mintDecimals), repayAll },
47392
+ remainingAccounts
47631
47393
  );
47632
- return { instructions: [ix], keys: [] };
47394
+ repayIxs.push(repayIx);
47395
+ return {
47396
+ instructions: repayIxs,
47397
+ keys: []
47398
+ };
47633
47399
  }
47634
- async function makeFlashLoanTx({
47635
- program,
47636
- marginfiAccount,
47637
- ixs,
47638
- bankMap,
47639
- blockhash,
47640
- addressLookupTableAccounts,
47641
- signers,
47642
- isSync
47643
- }) {
47644
- const endIndex = ixs.length + 1;
47645
- const projectedActiveBanksKeys = computeProjectedActiveBanksNoCpi(
47646
- marginfiAccount.balances,
47647
- ixs,
47648
- program
47649
- );
47650
- const projectedActiveBanks = projectedActiveBanksKeys.map((account) => {
47651
- const b = bankMap.get(account.toBase58());
47652
- if (!b) throw Error(`Bank ${account.toBase58()} not found, in makeFlashLoanTx function`);
47653
- return b;
47654
- });
47655
- const beginFlashLoanIx = await makeBeginFlashLoanIx3(
47656
- program,
47657
- marginfiAccount.address,
47658
- endIndex,
47659
- marginfiAccount.authority,
47660
- isSync
47661
- );
47662
- const endFlashLoanIx = await makeEndFlashLoanIx3(
47663
- program,
47664
- marginfiAccount.address,
47665
- projectedActiveBanks,
47666
- marginfiAccount.authority,
47667
- isSync
47668
- );
47669
- const message = new TransactionMessage({
47670
- payerKey: marginfiAccount.authority,
47671
- recentBlockhash: blockhash,
47672
- instructions: [...beginFlashLoanIx.instructions, ...ixs, ...endFlashLoanIx.instructions]
47673
- }).compileToV0Message(addressLookupTableAccounts);
47674
- const tx = addTransactionMetadata(new VersionedTransaction(message), {
47675
- addressLookupTables: addressLookupTableAccounts,
47676
- type: "FLASHLOAN" /* FLASHLOAN */,
47677
- signers
47400
+ async function makeRepayTx(params) {
47401
+ const { luts, ...depositIxParams } = params;
47402
+ const ixs = await makeRepayIx3(depositIxParams);
47403
+ const tx = new Transaction().add(...ixs.instructions);
47404
+ tx.feePayer = params.authority;
47405
+ const solanaTx = addTransactionMetadata(tx, {
47406
+ type: "REPAY" /* REPAY */,
47407
+ signers: ixs.keys,
47408
+ addressLookupTables: luts
47678
47409
  });
47679
- if (signers) {
47680
- tx.sign(signers);
47681
- }
47682
- return tx;
47410
+ return solanaTx;
47683
47411
  }
47684
-
47685
- // src/services/account/actions/loop.ts
47686
- async function makeLoopTx(params) {
47412
+ async function makeRepayWithCollatTx(params) {
47687
47413
  const {
47688
47414
  program,
47689
47415
  marginfiAccount,
47690
47416
  bankMap,
47691
- depositOpts,
47692
- borrowOpts,
47417
+ withdrawOpts,
47418
+ repayOpts,
47693
47419
  bankMetadataMap,
47694
47420
  addressLookupTableAccounts,
47695
47421
  connection,
47696
47422
  oraclePrices,
47697
- crossbarUrl,
47698
- additionalIxs = []
47423
+ crossbarUrl
47699
47424
  } = params;
47700
47425
  const blockhash = (await connection.getLatestBlockhash("confirmed")).blockhash;
47701
47426
  const setupIxs = await makeSetupIx({
@@ -47703,34 +47428,34 @@ async function makeLoopTx(params) {
47703
47428
  authority: marginfiAccount.authority,
47704
47429
  tokens: [
47705
47430
  {
47706
- mint: borrowOpts.borrowBank.mint,
47707
- tokenProgram: borrowOpts.tokenProgram
47431
+ mint: repayOpts.repayBank.mint,
47432
+ tokenProgram: repayOpts.tokenProgram
47708
47433
  },
47709
47434
  {
47710
- mint: depositOpts.depositBank.mint,
47711
- tokenProgram: depositOpts.tokenProgram
47435
+ mint: withdrawOpts.withdrawBank.mint,
47436
+ tokenProgram: withdrawOpts.tokenProgram
47712
47437
  }
47713
47438
  ]
47714
47439
  });
47715
- const updateJupLendRateIxs = makeUpdateJupLendRateIxs(
47716
- params.marginfiAccount,
47717
- params.bankMap,
47718
- [depositOpts.depositBank.address],
47719
- params.bankMetadataMap
47440
+ const updateJuplendMarketIxs = makeUpdateJupLendRateIxs(
47441
+ marginfiAccount,
47442
+ bankMap,
47443
+ [withdrawOpts.withdrawBank.address],
47444
+ bankMetadataMap
47720
47445
  );
47721
47446
  const updateDriftMarketIxs = makeUpdateDriftMarketIxs(
47722
- params.marginfiAccount,
47723
- params.bankMap,
47724
- [depositOpts.depositBank.address],
47725
- params.bankMetadataMap
47447
+ marginfiAccount,
47448
+ bankMap,
47449
+ [withdrawOpts.withdrawBank.address],
47450
+ bankMetadataMap
47726
47451
  );
47727
47452
  const kaminoRefreshIxs = makeRefreshKaminoBanksIxs(
47728
47453
  marginfiAccount,
47729
47454
  bankMap,
47730
- [borrowOpts.borrowBank.address, depositOpts.depositBank.address],
47455
+ [withdrawOpts.withdrawBank.address, repayOpts.repayBank.address],
47731
47456
  bankMetadataMap
47732
47457
  );
47733
- const { flashloanTx, setupInstructions, swapQuote, amountToDeposit, depositIxs, borrowIxs } = await buildLoopFlashloanTx({
47458
+ const { flashloanTx, setupInstructions, swapQuote, amountToRepay, withdrawIxs, repayIxs } = await buildRepayWithCollatFlashloanTx({
47734
47459
  ...params,
47735
47460
  blockhash
47736
47461
  });
@@ -47740,7 +47465,7 @@ async function makeLoopTx(params) {
47740
47465
  }
47741
47466
  if (ix.programId.equals(ASSOCIATED_TOKEN_PROGRAM_ID)) {
47742
47467
  const mintKey = ix.keys[3]?.pubkey;
47743
- if (mintKey?.equals(depositOpts.depositBank.mint) || mintKey?.equals(borrowOpts.borrowBank.mint)) {
47468
+ if (mintKey?.equals(withdrawOpts.withdrawBank.mint) || mintKey?.equals(repayOpts.repayBank.mint)) {
47744
47469
  return false;
47745
47470
  }
47746
47471
  }
@@ -47752,24 +47477,18 @@ async function makeLoopTx(params) {
47752
47477
  bankMap,
47753
47478
  oraclePrices,
47754
47479
  assetShareValueMultiplierByBank: params.assetShareValueMultiplierByBank,
47755
- instructions: [...borrowIxs.instructions, ...depositIxs.instructions],
47480
+ instructions: [...withdrawIxs.instructions, ...repayIxs.instructions],
47756
47481
  program,
47757
47482
  connection,
47758
47483
  crossbarUrl
47759
47484
  });
47760
47485
  let additionalTxs = [];
47761
- if (depositOpts.depositBank.mint.equals(NATIVE_MINT) && depositOpts.inputDepositAmount) {
47762
- setupIxs.push(
47763
- ...makeWrapSolIxs(marginfiAccount.authority, new BigNumber(depositOpts.inputDepositAmount))
47764
- );
47765
- }
47766
- if (setupIxs.length > 0 || additionalIxs.length > 0 || kaminoRefreshIxs.instructions.length > 0 || updateDriftMarketIxs.instructions.length > 0 || updateJupLendRateIxs.instructions.length > 0) {
47486
+ if (setupIxs.length > 0 || kaminoRefreshIxs.instructions.length > 0 || updateDriftMarketIxs.instructions.length > 0 || updateJuplendMarketIxs.instructions.length > 0) {
47767
47487
  const ixs = [
47768
- ...additionalIxs,
47769
47488
  ...setupIxs,
47770
47489
  ...kaminoRefreshIxs.instructions,
47771
47490
  ...updateDriftMarketIxs.instructions,
47772
- ...updateJupLendRateIxs.instructions
47491
+ ...updateJuplendMarketIxs.instructions
47773
47492
  ];
47774
47493
  const txs = splitInstructionsToFitTransactions([], ixs, {
47775
47494
  blockhash,
@@ -47799,19 +47518,16 @@ async function makeLoopTx(params) {
47799
47518
  );
47800
47519
  }
47801
47520
  const transactions = [...additionalTxs, flashloanTx];
47802
- return {
47803
- transactions,
47804
- actionTxIndex: transactions.length - 1,
47805
- quoteResponse: swapQuote
47806
- };
47521
+ return { transactions, swapQuote, amountToRepay };
47807
47522
  }
47808
- async function buildLoopFlashloanTx({
47523
+ async function buildRepayWithCollatFlashloanTx({
47809
47524
  program,
47810
47525
  marginfiAccount,
47811
47526
  bankMap,
47812
- borrowOpts,
47813
- depositOpts,
47527
+ withdrawOpts,
47528
+ repayOpts,
47814
47529
  bankMetadataMap,
47530
+ assetShareValueMultiplierByBank,
47815
47531
  addressLookupTableAccounts,
47816
47532
  connection,
47817
47533
  swapOpts,
@@ -47822,20 +47538,20 @@ async function buildLoopFlashloanTx({
47822
47538
  ComputeBudgetProgram.setComputeUnitLimit({ units: 12e5 }),
47823
47539
  ComputeBudgetProgram.setComputeUnitPrice({ microLamports: 1 })
47824
47540
  ];
47825
- let amountToDeposit;
47541
+ let amountToRepay;
47826
47542
  let swapInstructions = [];
47827
47543
  let setupInstructions = [];
47828
47544
  let swapLookupTables = [];
47829
47545
  let swapQuote;
47830
47546
  let sizeConstraintUsed = 0;
47831
- if (depositOpts.depositBank.mint.equals(borrowOpts.borrowBank.mint)) {
47832
- amountToDeposit = borrowOpts.borrowAmount + (depositOpts.loopMode === "DEPOSIT" ? depositOpts.inputDepositAmount : 0);
47547
+ if (repayOpts.repayBank.mint.equals(withdrawOpts.withdrawBank.mint)) {
47548
+ amountToRepay = withdrawOpts.withdrawAmount;
47833
47549
  } else {
47834
47550
  const destinationTokenAccount = getAssociatedTokenAddressSync(
47835
- new PublicKey(depositOpts.depositBank.mint),
47551
+ new PublicKey(repayOpts.repayBank.mint),
47836
47552
  marginfiAccount.authority,
47837
47553
  true,
47838
- depositOpts.tokenProgram.equals(TOKEN_2022_PROGRAM_ID) ? TOKEN_2022_PROGRAM_ID : void 0
47554
+ repayOpts.tokenProgram.equals(TOKEN_2022_PROGRAM_ID) ? TOKEN_2022_PROGRAM_ID : void 0
47839
47555
  );
47840
47556
  const swapConstraints = await computeFlashloanSwapConstraints({
47841
47557
  program,
@@ -47844,77 +47560,77 @@ async function buildLoopFlashloanTx({
47844
47560
  bankMetadataMap,
47845
47561
  addressLookupTableAccounts: addressLookupTableAccounts ?? [],
47846
47562
  primaryIx: {
47847
- type: "borrow",
47848
- bank: borrowOpts.borrowBank,
47849
- tokenProgram: borrowOpts.tokenProgram
47563
+ type: "withdraw",
47564
+ bank: withdrawOpts.withdrawBank,
47565
+ tokenProgram: withdrawOpts.tokenProgram
47850
47566
  },
47851
47567
  secondaryIx: {
47852
- type: "deposit",
47853
- bank: depositOpts.depositBank,
47854
- tokenProgram: depositOpts.tokenProgram
47568
+ type: "repay",
47569
+ bank: repayOpts.repayBank,
47570
+ tokenProgram: repayOpts.tokenProgram
47855
47571
  },
47856
47572
  overrideInferAccounts
47857
47573
  });
47858
47574
  const swapResponse = await getSwapIxsForFlashloan({
47859
- inputMint: borrowOpts.borrowBank.mint.toBase58(),
47860
- outputMint: depositOpts.depositBank.mint.toBase58(),
47861
- amount: uiToNative(borrowOpts.borrowAmount, borrowOpts.borrowBank.mintDecimals).toNumber(),
47575
+ inputMint: withdrawOpts.withdrawBank.mint.toBase58(),
47576
+ outputMint: repayOpts.repayBank.mint.toBase58(),
47577
+ amount: uiToNative(
47578
+ withdrawOpts.withdrawAmount,
47579
+ withdrawOpts.withdrawBank.mintDecimals
47580
+ ).toNumber(),
47862
47581
  swapMode: "ExactIn",
47863
47582
  authority: marginfiAccount.authority,
47864
47583
  connection,
47865
47584
  destinationTokenAccount,
47866
47585
  swapOpts,
47867
47586
  sizeConstraint: swapConstraints.sizeConstraint,
47868
- maxSwapAccounts: swapConstraints.maxSwapWritableAccounts,
47869
47587
  maxSwapTotalAccounts: swapConstraints.maxSwapTotalAccounts
47870
47588
  });
47871
47589
  sizeConstraintUsed = swapConstraints.sizeConstraint;
47590
+ const { quoteResponse } = swapResponse;
47591
+ const outAmount = nativeToUi(quoteResponse.outAmount, repayOpts.repayBank.mintDecimals);
47872
47592
  const outAmountThreshold = nativeToUi(
47873
- swapResponse.quoteResponse.otherAmountThreshold,
47874
- depositOpts.depositBank.mintDecimals
47593
+ quoteResponse.otherAmountThreshold,
47594
+ repayOpts.repayBank.mintDecimals
47875
47595
  );
47876
- amountToDeposit = outAmountThreshold + (depositOpts.loopMode === "DEPOSIT" ? depositOpts.inputDepositAmount : 0);
47596
+ amountToRepay = outAmount > repayOpts.totalPositionAmount ? repayOpts.totalPositionAmount : outAmountThreshold;
47877
47597
  swapInstructions = swapResponse.swapInstructions;
47878
- setupInstructions = swapResponse.setupInstructions;
47879
47598
  swapLookupTables = swapResponse.addressLookupTableAddresses;
47880
- swapQuote = swapResponse.quoteResponse;
47599
+ swapQuote = quoteResponse;
47881
47600
  }
47882
- const borrowIxs = await makeBorrowIx3({
47883
- program,
47884
- bank: borrowOpts.borrowBank,
47885
- bankMap,
47886
- tokenProgram: borrowOpts.tokenProgram,
47887
- amount: borrowOpts.borrowAmount,
47888
- marginfiAccount,
47889
- authority: marginfiAccount.authority,
47890
- isSync: false,
47891
- opts: {
47892
- createAtas: false,
47893
- wrapAndUnwrapSol: false,
47894
- overrideInferAccounts
47895
- }
47896
- });
47897
- let depositIxs;
47898
- switch (depositOpts.depositBank.config.assetTag) {
47601
+ let withdrawIxs;
47602
+ switch (withdrawOpts.withdrawBank.config.assetTag) {
47899
47603
  case 3 /* KAMINO */: {
47900
- const reserve = bankMetadataMap[depositOpts.depositBank.address.toBase58()]?.kaminoStates?.reserveState;
47604
+ const reserve = bankMetadataMap[withdrawOpts.withdrawBank.address.toBase58()]?.kaminoStates?.reserveState;
47901
47605
  if (!reserve) {
47902
47606
  throw TransactionBuildingError.kaminoReserveNotFound(
47903
- depositOpts.depositBank.address.toBase58(),
47904
- depositOpts.depositBank.mint.toBase58(),
47905
- depositOpts.depositBank.tokenSymbol
47607
+ withdrawOpts.withdrawBank.address.toBase58(),
47608
+ withdrawOpts.withdrawBank.mint.toBase58(),
47609
+ withdrawOpts.withdrawBank.tokenSymbol
47906
47610
  );
47907
47611
  }
47908
- depositIxs = await makeKaminoDepositIx3({
47612
+ const multiplier = assetShareValueMultiplierByBank.get(withdrawOpts.withdrawBank.address.toBase58()) ?? new BigNumber(1);
47613
+ const adjustedAmount = new BigNumber(withdrawOpts.withdrawAmount).div(multiplier).times(1.0001).toNumber();
47614
+ withdrawIxs = await makeKaminoWithdrawIx3({
47909
47615
  program,
47910
- bank: depositOpts.depositBank,
47911
- tokenProgram: depositOpts.tokenProgram,
47912
- amount: amountToDeposit,
47913
- accountAddress: marginfiAccount.address,
47616
+ bank: withdrawOpts.withdrawBank,
47617
+ bankMap,
47618
+ tokenProgram: withdrawOpts.tokenProgram,
47619
+ cTokenAmount: adjustedAmount,
47620
+ marginfiAccount,
47914
47621
  authority: marginfiAccount.authority,
47915
- group: marginfiAccount.group,
47916
47622
  reserve,
47623
+ withdrawAll: isWholePosition(
47624
+ {
47625
+ amount: withdrawOpts.totalPositionAmount,
47626
+ isLending: true
47627
+ },
47628
+ withdrawOpts.withdrawAmount,
47629
+ withdrawOpts.withdrawBank.mintDecimals
47630
+ ),
47631
+ isSync: false,
47917
47632
  opts: {
47633
+ createAtas: false,
47918
47634
  wrapAndUnwrapSol: false,
47919
47635
  overrideInferAccounts
47920
47636
  }
@@ -47922,27 +47638,35 @@ async function buildLoopFlashloanTx({
47922
47638
  break;
47923
47639
  }
47924
47640
  case 4 /* DRIFT */: {
47925
- const driftState = bankMetadataMap[depositOpts.depositBank.address.toBase58()]?.driftStates;
47641
+ const driftState = bankMetadataMap[withdrawOpts.withdrawBank.address.toBase58()]?.driftStates;
47926
47642
  if (!driftState) {
47927
47643
  throw TransactionBuildingError.driftStateNotFound(
47928
- depositOpts.depositBank.address.toBase58(),
47929
- depositOpts.depositBank.mint.toBase58(),
47930
- depositOpts.depositBank.tokenSymbol
47644
+ withdrawOpts.withdrawBank.address.toBase58(),
47645
+ withdrawOpts.withdrawBank.mint.toBase58(),
47646
+ withdrawOpts.withdrawBank.tokenSymbol
47931
47647
  );
47932
47648
  }
47933
- const driftMarketIndex = driftState.spotMarketState.marketIndex;
47934
- const driftOracle = driftState.spotMarketState.oracle;
47935
- depositIxs = await makeDriftDepositIx3({
47649
+ withdrawIxs = await makeDriftWithdrawIx3({
47936
47650
  program,
47937
- bank: depositOpts.depositBank,
47938
- tokenProgram: depositOpts.tokenProgram,
47939
- amount: amountToDeposit,
47940
- accountAddress: marginfiAccount.address,
47651
+ bank: withdrawOpts.withdrawBank,
47652
+ bankMap,
47653
+ tokenProgram: withdrawOpts.tokenProgram,
47654
+ amount: withdrawOpts.withdrawAmount,
47655
+ marginfiAccount,
47941
47656
  authority: marginfiAccount.authority,
47942
- group: marginfiAccount.group,
47943
- driftMarketIndex,
47944
- driftOracle,
47657
+ driftSpotMarket: driftState.spotMarketState,
47658
+ userRewards: driftState.userRewards,
47659
+ withdrawAll: isWholePosition(
47660
+ {
47661
+ amount: withdrawOpts.totalPositionAmount,
47662
+ isLending: true
47663
+ },
47664
+ withdrawOpts.withdrawAmount,
47665
+ withdrawOpts.withdrawBank.mintDecimals
47666
+ ),
47667
+ isSync: false,
47945
47668
  opts: {
47669
+ createAtas: false,
47946
47670
  wrapAndUnwrapSol: false,
47947
47671
  overrideInferAccounts
47948
47672
  }
@@ -47950,15 +47674,33 @@ async function buildLoopFlashloanTx({
47950
47674
  break;
47951
47675
  }
47952
47676
  case 6 /* JUPLEND */: {
47953
- depositIxs = await makeJuplendDepositIx2({
47677
+ const jupLendState = bankMetadataMap[withdrawOpts.withdrawBank.address.toBase58()]?.jupLendStates;
47678
+ if (!jupLendState) {
47679
+ throw TransactionBuildingError.jupLendStateNotFound(
47680
+ withdrawOpts.withdrawBank.address.toBase58(),
47681
+ withdrawOpts.withdrawBank.mint.toBase58(),
47682
+ withdrawOpts.withdrawBank.tokenSymbol
47683
+ );
47684
+ }
47685
+ withdrawIxs = await makeJuplendWithdrawIx2({
47954
47686
  program,
47955
- bank: depositOpts.depositBank,
47956
- tokenProgram: depositOpts.tokenProgram,
47957
- amount: amountToDeposit,
47958
- accountAddress: marginfiAccount.address,
47687
+ bank: withdrawOpts.withdrawBank,
47688
+ bankMap,
47689
+ tokenProgram: withdrawOpts.tokenProgram,
47690
+ amount: withdrawOpts.withdrawAmount,
47691
+ marginfiAccount,
47959
47692
  authority: marginfiAccount.authority,
47960
- group: marginfiAccount.group,
47693
+ jupLendingState: jupLendState.jupLendingState,
47694
+ withdrawAll: isWholePosition(
47695
+ {
47696
+ amount: withdrawOpts.totalPositionAmount,
47697
+ isLending: true
47698
+ },
47699
+ withdrawOpts.withdrawAmount,
47700
+ withdrawOpts.withdrawBank.mintDecimals
47701
+ ),
47961
47702
  opts: {
47703
+ createAtas: false,
47962
47704
  wrapAndUnwrapSol: false,
47963
47705
  overrideInferAccounts
47964
47706
  }
@@ -47966,15 +47708,25 @@ async function buildLoopFlashloanTx({
47966
47708
  break;
47967
47709
  }
47968
47710
  default: {
47969
- depositIxs = await makeDepositIx3({
47711
+ withdrawIxs = await makeWithdrawIx3({
47970
47712
  program,
47971
- bank: depositOpts.depositBank,
47972
- tokenProgram: depositOpts.tokenProgram,
47973
- amount: amountToDeposit,
47974
- accountAddress: marginfiAccount.address,
47713
+ bank: withdrawOpts.withdrawBank,
47714
+ bankMap,
47715
+ tokenProgram: withdrawOpts.tokenProgram,
47716
+ amount: withdrawOpts.withdrawAmount,
47717
+ marginfiAccount,
47975
47718
  authority: marginfiAccount.authority,
47976
- group: marginfiAccount.group,
47719
+ withdrawAll: isWholePosition(
47720
+ {
47721
+ amount: withdrawOpts.totalPositionAmount,
47722
+ isLending: true
47723
+ },
47724
+ withdrawOpts.withdrawAmount,
47725
+ withdrawOpts.withdrawBank.mintDecimals
47726
+ ),
47727
+ isSync: false,
47977
47728
  opts: {
47729
+ createAtas: false,
47978
47730
  wrapAndUnwrapSol: false,
47979
47731
  overrideInferAccounts
47980
47732
  }
@@ -47982,12 +47734,33 @@ async function buildLoopFlashloanTx({
47982
47734
  break;
47983
47735
  }
47984
47736
  }
47737
+ const repayIxs = await makeRepayIx3({
47738
+ program,
47739
+ bank: repayOpts.repayBank,
47740
+ tokenProgram: repayOpts.tokenProgram,
47741
+ amount: amountToRepay,
47742
+ accountAddress: marginfiAccount.address,
47743
+ authority: marginfiAccount.authority,
47744
+ repayAll: isWholePosition(
47745
+ {
47746
+ amount: repayOpts.totalPositionAmount,
47747
+ isLending: true
47748
+ },
47749
+ amountToRepay,
47750
+ repayOpts.repayBank.mintDecimals
47751
+ ),
47752
+ isSync: false,
47753
+ opts: {
47754
+ wrapAndUnwrapSol: false,
47755
+ overrideInferAccounts
47756
+ }
47757
+ });
47985
47758
  const luts = [...addressLookupTableAccounts ?? [], ...swapLookupTables];
47986
47759
  const allNonFlIxs = [
47987
47760
  ...cuRequestIxs,
47988
- ...borrowIxs.instructions,
47761
+ ...withdrawIxs.instructions,
47989
47762
  ...swapInstructions,
47990
- ...depositIxs.instructions
47763
+ ...repayIxs.instructions
47991
47764
  ];
47992
47765
  if (swapInstructions.length > 0) {
47993
47766
  compileFlashloanPrecheck({
@@ -48005,15 +47778,15 @@ async function buildLoopFlashloanTx({
48005
47778
  bankMap,
48006
47779
  addressLookupTableAccounts: luts,
48007
47780
  blockhash,
48008
- ixs: allNonFlIxs
47781
+ ixs: allNonFlIxs,
47782
+ isSync: true
48009
47783
  });
48010
47784
  const txSize = getTxSize(flashloanTx);
48011
- const writableKeys = getWritableAccountKeys(flashloanTx);
48012
47785
  const totalKeys = getTotalAccountKeys(flashloanTx);
48013
- if (txSize > MAX_TX_SIZE || writableKeys > MAX_WRITABLE_ACCOUNTS || totalKeys > MAX_ACCOUNT_LOCKS) {
48014
- throw TransactionBuildingError.swapSizeExceededLoop(
47786
+ if (txSize > MAX_TX_SIZE || totalKeys > MAX_ACCOUNT_LOCKS) {
47787
+ throw TransactionBuildingError.swapSizeExceededRepay(
48015
47788
  txSize,
48016
- writableKeys,
47789
+ totalKeys,
48017
47790
  swapOpts.swapConfig?.provider
48018
47791
  );
48019
47792
  }
@@ -48021,9 +47794,9 @@ async function buildLoopFlashloanTx({
48021
47794
  flashloanTx,
48022
47795
  setupInstructions,
48023
47796
  swapQuote,
48024
- borrowIxs,
48025
- depositIxs,
48026
- amountToDeposit
47797
+ withdrawIxs,
47798
+ repayIxs,
47799
+ amountToRepay
48027
47800
  };
48028
47801
  }
48029
47802
 
@@ -48325,7 +48098,6 @@ async function buildSwapCollateralFlashloanTx({
48325
48098
  destinationTokenAccount,
48326
48099
  swapOpts,
48327
48100
  sizeConstraint: swapConstraints.sizeConstraint,
48328
- maxSwapAccounts: swapConstraints.maxSwapWritableAccounts,
48329
48101
  maxSwapTotalAccounts: swapConstraints.maxSwapTotalAccounts
48330
48102
  });
48331
48103
  sizeConstraintUsed = swapConstraints.sizeConstraint;
@@ -48453,12 +48225,11 @@ async function buildSwapCollateralFlashloanTx({
48453
48225
  isSync: true
48454
48226
  });
48455
48227
  const txSize = getTxSize(flashloanTx);
48456
- const writableKeys = getWritableAccountKeys(flashloanTx);
48457
48228
  const totalKeys = getTotalAccountKeys(flashloanTx);
48458
- if (txSize > MAX_TX_SIZE || writableKeys > MAX_WRITABLE_ACCOUNTS || totalKeys > MAX_ACCOUNT_LOCKS) {
48459
- throw TransactionBuildingError.swapSizeExceededLoop(
48229
+ if (txSize > MAX_TX_SIZE || totalKeys > MAX_ACCOUNT_LOCKS) {
48230
+ throw TransactionBuildingError.swapSizeExceededPositionSwap(
48460
48231
  txSize,
48461
- writableKeys,
48232
+ totalKeys,
48462
48233
  swapOpts.swapConfig?.provider
48463
48234
  );
48464
48235
  }
@@ -48644,7 +48415,6 @@ async function buildSwapDebtFlashloanTx({
48644
48415
  destinationTokenAccount,
48645
48416
  swapOpts,
48646
48417
  sizeConstraint: swapConstraints.sizeConstraint,
48647
- maxSwapAccounts: swapConstraints.maxSwapWritableAccounts,
48648
48418
  maxSwapTotalAccounts: swapConstraints.maxSwapTotalAccounts
48649
48419
  });
48650
48420
  const { quoteResponse } = swapResponses;
@@ -48716,12 +48486,11 @@ async function buildSwapDebtFlashloanTx({
48716
48486
  isSync: true
48717
48487
  });
48718
48488
  const txSize = getTxSize(flashloanTx);
48719
- const writableKeys = getWritableAccountKeys(flashloanTx);
48720
48489
  const totalKeys = getTotalAccountKeys(flashloanTx);
48721
- if (txSize > MAX_TX_SIZE || writableKeys > MAX_WRITABLE_ACCOUNTS || totalKeys > MAX_ACCOUNT_LOCKS) {
48722
- throw TransactionBuildingError.swapSizeExceededLoop(
48490
+ if (txSize > MAX_TX_SIZE || totalKeys > MAX_ACCOUNT_LOCKS) {
48491
+ throw TransactionBuildingError.swapSizeExceededPositionSwap(
48723
48492
  txSize,
48724
- writableKeys,
48493
+ totalKeys,
48725
48494
  swapOpts.swapConfig?.provider
48726
48495
  );
48727
48496
  }
@@ -49389,23 +49158,27 @@ var getTitanSwapIxsForFlashloan = async ({
49389
49158
  quoteParams.swapMode === "ExactIn" ? quoteParams.outputMint : quoteParams.inputMint
49390
49159
  );
49391
49160
  const { feeAccount, hasFeeAccount } = await checkTitanFeeAccount(connection, feeMint);
49161
+ const useFeeAccount = hasFeeAccount && !!quoteParams.platformFeeBps;
49392
49162
  let finalQuoteParams = quoteParams;
49393
- if (!hasFeeAccount) {
49394
- console.warn("Warning: Titan fee account ATA does not exist, disabling platform fee");
49163
+ if (!useFeeAccount) {
49164
+ if (!hasFeeAccount) {
49165
+ console.warn("Warning: Titan fee account ATA does not exist, disabling platform fee");
49166
+ }
49395
49167
  finalQuoteParams = {
49396
49168
  ...quoteParams,
49397
49169
  platformFeeBps: void 0
49398
49170
  };
49399
49171
  }
49172
+ const effectiveFeeAccount = useFeeAccount ? feeAccount : void 0;
49400
49173
  if (basePath.startsWith("wss://") || basePath.startsWith("ws://")) {
49401
49174
  return getTitanSwapIxsViaWebSocket(
49402
49175
  { quoteParams: finalQuoteParams, authority, connection, destinationTokenAccount, apiConfig },
49403
- hasFeeAccount ? feeAccount : void 0
49176
+ effectiveFeeAccount
49404
49177
  );
49405
49178
  } else {
49406
49179
  return getTitanSwapIxsViaHttpProxy(
49407
49180
  { quoteParams: finalQuoteParams, authority, connection, destinationTokenAccount, apiConfig },
49408
- hasFeeAccount ? feeAccount : void 0
49181
+ effectiveFeeAccount
49409
49182
  );
49410
49183
  }
49411
49184
  };
@@ -49581,7 +49354,7 @@ async function getTitanExactOutViaWebSocket(params) {
49581
49354
  inputMint: new PublicKey(inputMint).toBytes(),
49582
49355
  outputMint: new PublicKey(outputMint).toBytes(),
49583
49356
  amount,
49584
- swapMode: "ExactOut",
49357
+ swapMode: "ExactOut" /* ExactOut */,
49585
49358
  slippageBps
49586
49359
  },
49587
49360
  transaction: {
@@ -49668,8 +49441,7 @@ function getSwapProviderFn({
49668
49441
  connection,
49669
49442
  destinationTokenAccount,
49670
49443
  swapOpts,
49671
- sizeConstraint,
49672
- maxSwapAccounts
49444
+ sizeConstraint
49673
49445
  }) {
49674
49446
  switch (attemptProvider) {
49675
49447
  case "TITAN" /* TITAN */:
@@ -49683,7 +49455,6 @@ function getSwapProviderFn({
49683
49455
  platformFeeBps: swapOpts.swapConfig?.platformFeeBps,
49684
49456
  directRoutesOnly: swapOpts.swapConfig?.directRoutesOnly,
49685
49457
  sizeConstraint,
49686
- maxSwapAccounts,
49687
49458
  maxSwapTotalAccounts
49688
49459
  },
49689
49460
  authority,
@@ -49707,7 +49478,7 @@ function getSwapProviderFn({
49707
49478
  connection,
49708
49479
  destinationTokenAccount,
49709
49480
  apiConfig,
49710
- maxSwapAccounts
49481
+ maxSwapAccounts: maxSwapTotalAccounts
49711
49482
  });
49712
49483
  default:
49713
49484
  return void 0;
@@ -49760,7 +49531,7 @@ var getSwapIxsForFlashloan = async (params) => {
49760
49531
  destinationTokenAccount,
49761
49532
  swapOpts,
49762
49533
  sizeConstraint,
49763
- maxSwapAccounts
49534
+ maxSwapTotalAccounts
49764
49535
  } = params;
49765
49536
  if (swapOpts.swapIxs) {
49766
49537
  return {
@@ -49793,8 +49564,7 @@ var getSwapIxsForFlashloan = async (params) => {
49793
49564
  connection,
49794
49565
  destinationTokenAccount,
49795
49566
  swapOpts,
49796
- sizeConstraint,
49797
- maxSwapAccounts
49567
+ sizeConstraint
49798
49568
  });
49799
49569
  if (!fn) continue;
49800
49570
  try {
@@ -49804,178 +49574,616 @@ var getSwapIxsForFlashloan = async (params) => {
49804
49574
  lastError = err;
49805
49575
  console.warn(`[swap] ${attemptProvider} failed:`, err instanceof Error ? err.message : err);
49806
49576
  }
49807
- }
49808
- const firstProvider = attempts[0]?.provider ?? "Swap";
49809
- throw TransactionBuildingError.swapQuoteFailed(
49810
- firstProvider,
49811
- inputMint,
49812
- outputMint,
49813
- lastError?.message ?? "No swap route available"
49814
- );
49815
- };
49816
- var getExactOutEstimate = async (params) => {
49817
- const { inputMint, outputMint, amount, swapOpts, connection } = params;
49818
- const provider = swapOpts.swapConfig?.provider ?? "JUPITER" /* JUPITER */;
49819
- const attempts = [
49820
- { provider, apiConfig: swapOpts.swapConfig?.apiConfig },
49821
- ...swapOpts.swapConfig?.fallbackProviders ?? []
49822
- ];
49823
- let lastError;
49824
- for (const { provider: attemptProvider, apiConfig } of attempts) {
49825
- const fn = getExactOutProviderFn({
49826
- attemptProvider,
49827
- inputMint,
49828
- outputMint,
49829
- amount,
49830
- swapOpts,
49831
- apiConfig
49832
- });
49833
- if (!fn) continue;
49834
- try {
49835
- return await fn(apiConfig);
49836
- } catch (err) {
49837
- if (err instanceof TransactionBuildingError) throw err;
49838
- lastError = err;
49839
- console.warn(
49840
- `[exactout] ${attemptProvider} failed:`,
49841
- err instanceof Error ? err.message : err
49842
- );
49577
+ }
49578
+ const firstProvider = attempts[0]?.provider ?? "Swap";
49579
+ throw TransactionBuildingError.swapQuoteFailed(
49580
+ firstProvider,
49581
+ inputMint,
49582
+ outputMint,
49583
+ lastError?.message ?? "No swap route available"
49584
+ );
49585
+ };
49586
+ var getExactOutEstimate = async (params) => {
49587
+ const { inputMint, outputMint, amount, swapOpts, connection } = params;
49588
+ const provider = swapOpts.swapConfig?.provider ?? "JUPITER" /* JUPITER */;
49589
+ const attempts = [
49590
+ { provider, apiConfig: swapOpts.swapConfig?.apiConfig },
49591
+ ...swapOpts.swapConfig?.fallbackProviders ?? []
49592
+ ];
49593
+ let lastError;
49594
+ for (const { provider: attemptProvider, apiConfig } of attempts) {
49595
+ const fn = getExactOutProviderFn({
49596
+ attemptProvider,
49597
+ inputMint,
49598
+ outputMint,
49599
+ amount,
49600
+ swapOpts,
49601
+ apiConfig
49602
+ });
49603
+ if (!fn) continue;
49604
+ try {
49605
+ return await fn(apiConfig);
49606
+ } catch (err) {
49607
+ if (err instanceof TransactionBuildingError) throw err;
49608
+ lastError = err;
49609
+ console.warn(
49610
+ `[exactout] ${attemptProvider} failed:`,
49611
+ err instanceof Error ? err.message : err
49612
+ );
49613
+ }
49614
+ }
49615
+ const firstProvider = attempts[0]?.provider ?? "Swap";
49616
+ throw TransactionBuildingError.swapQuoteFailed(
49617
+ firstProvider,
49618
+ inputMint,
49619
+ outputMint,
49620
+ lastError?.message ?? "No swap route available"
49621
+ );
49622
+ };
49623
+ function mapJupiterQuoteToSwapQuoteResult(quote) {
49624
+ return {
49625
+ inAmount: quote.inAmount,
49626
+ outAmount: quote.outAmount,
49627
+ otherAmountThreshold: quote.otherAmountThreshold,
49628
+ slippageBps: quote.slippageBps,
49629
+ platformFee: quote.platformFee ? {
49630
+ amount: quote.platformFee.amount ?? "0",
49631
+ feeBps: quote.platformFee.feeBps ?? 0
49632
+ } : void 0,
49633
+ priceImpactPct: quote.priceImpactPct,
49634
+ contextSlot: quote.contextSlot,
49635
+ timeTaken: quote.timeTaken,
49636
+ provider: "JUPITER" /* JUPITER */
49637
+ };
49638
+ }
49639
+
49640
+ // src/services/account/utils/jupiter.utils.ts
49641
+ var REFERRAL_PROGRAM_ID = new PublicKey("REFER4ZgmyYx9c6He5XfaTMiGfdLwRnkV4RPp9t9iF3");
49642
+ var REFERRAL_ACCOUNT_PUBKEY = new PublicKey("Mm7HcujSK2JzPW4eX7g4oqTXbWYDuFxapNMHXe8yp1B");
49643
+ var getFeeAccount = (mint) => {
49644
+ const [feeAccount] = PublicKey.findProgramAddressSync(
49645
+ [Buffer.from("referral_ata"), REFERRAL_ACCOUNT_PUBKEY.toBuffer(), mint.toBuffer()],
49646
+ REFERRAL_PROGRAM_ID
49647
+ );
49648
+ return feeAccount.toBase58();
49649
+ };
49650
+ var checkFeeAccount = async (connection, mint) => {
49651
+ const feeAccount = getFeeAccount(mint);
49652
+ const hasFeeAccount = !!await connection.getAccountInfo(new PublicKey(feeAccount));
49653
+ return { feeAccount, hasFeeAccount };
49654
+ };
49655
+ function deserializeJupiterInstruction(instruction) {
49656
+ return new TransactionInstruction({
49657
+ programId: new PublicKey(instruction.programId),
49658
+ keys: instruction.accounts.map((key) => ({
49659
+ pubkey: new PublicKey(key.pubkey),
49660
+ isSigner: key.isSigner,
49661
+ isWritable: key.isWritable
49662
+ })),
49663
+ data: Buffer.from(instruction.data, "base64")
49664
+ });
49665
+ }
49666
+ function toJupiterConfig(apiConfig) {
49667
+ if (!apiConfig) return void 0;
49668
+ return {
49669
+ basePath: apiConfig.basePath,
49670
+ apiKey: apiConfig.apiKey ? () => apiConfig.apiKey : void 0,
49671
+ headers: apiConfig.headers
49672
+ };
49673
+ }
49674
+ var getJupiterSwapIxsForFlashloan = async ({
49675
+ quoteParams,
49676
+ authority,
49677
+ connection,
49678
+ destinationTokenAccount,
49679
+ apiConfig,
49680
+ maxSwapAccounts
49681
+ }) => {
49682
+ const configParams = toJupiterConfig(apiConfig);
49683
+ const jupiterApiClient = configParams?.basePath ? new SwapApi(new Configuration(configParams)) : createJupiterApiClient(configParams);
49684
+ const feeMint = quoteParams.swapMode === "ExactIn" ? quoteParams.outputMint : quoteParams.inputMint;
49685
+ const { feeAccount, hasFeeAccount } = await checkFeeAccount(connection, new PublicKey(feeMint));
49686
+ const project0JupiterLut = (await connection.getAddressLookupTable(ADDRESS_LOOKUP_TABLE_FOR_SWAP))?.value;
49687
+ const useFeeAccount = hasFeeAccount && !!quoteParams.platformFeeBps;
49688
+ let finalQuoteParams = quoteParams;
49689
+ if (!useFeeAccount) {
49690
+ if (!hasFeeAccount) {
49691
+ console.warn("Warning: feeAccountInfo is undefined");
49692
+ }
49693
+ finalQuoteParams = {
49694
+ ...quoteParams,
49695
+ platformFeeBps: void 0
49696
+ };
49697
+ }
49698
+ const JUPITER_MAX_ACCOUNTS_MARGIN = 4;
49699
+ const maxAccounts = maxSwapAccounts !== void 0 ? maxSwapAccounts - JUPITER_MAX_ACCOUNTS_MARGIN : 40;
49700
+ const swapQuote = await jupiterApiClient.quoteGet({
49701
+ ...finalQuoteParams,
49702
+ maxAccounts
49703
+ });
49704
+ const swapInstructionResponse = await jupiterApiClient.swapInstructionsPost({
49705
+ swapRequest: {
49706
+ quoteResponse: swapQuote,
49707
+ userPublicKey: authority.toBase58(),
49708
+ feeAccount: useFeeAccount ? feeAccount : void 0,
49709
+ wrapAndUnwrapSol: false,
49710
+ destinationTokenAccount: destinationTokenAccount.toBase58()
49711
+ }
49712
+ });
49713
+ const lutAddresses = swapInstructionResponse.addressLookupTableAddresses;
49714
+ const lutAccountsRaw = await connection.getMultipleAccountsInfo(
49715
+ lutAddresses.map((address) => new PublicKey(address))
49716
+ );
49717
+ const addressLookupTableAccounts = lutAccountsRaw.map((accountInfo, index) => {
49718
+ const addressLookupTableAddress = lutAddresses[index];
49719
+ if (!accountInfo || !addressLookupTableAddress) {
49720
+ return null;
49721
+ }
49722
+ return new AddressLookupTableAccount({
49723
+ key: new PublicKey(addressLookupTableAddress),
49724
+ state: AddressLookupTableAccount.deserialize(accountInfo.data)
49725
+ });
49726
+ }).filter((account) => account !== null).concat(project0JupiterLut ? [project0JupiterLut] : []);
49727
+ const instruction = deserializeJupiterInstruction(swapInstructionResponse.swapInstruction);
49728
+ const setupInstructions = swapInstructionResponse.setupInstructions.map(
49729
+ deserializeJupiterInstruction
49730
+ );
49731
+ return {
49732
+ swapInstructions: [instruction],
49733
+ setupInstructions,
49734
+ addressLookupTableAddresses: addressLookupTableAccounts,
49735
+ quoteResponse: mapJupiterQuoteToSwapQuoteResult(swapQuote)
49736
+ };
49737
+ };
49738
+
49739
+ // src/services/account/utils/misc.utils.ts
49740
+ function floor(value, decimals) {
49741
+ return Math.floor(value * 10 ** decimals) / 10 ** decimals;
49742
+ }
49743
+ function ceil(value, decimals) {
49744
+ return Math.ceil(value * 10 ** decimals) / 10 ** decimals;
49745
+ }
49746
+ function computeClosePositionTokenAmount(position, mintDecimals) {
49747
+ const closePositionTokenAmount = position.isLending ? floor(position.amount, mintDecimals) : ceil(position.amount, mintDecimals);
49748
+ return closePositionTokenAmount;
49749
+ }
49750
+ function isWholePosition(position, amount, mintDecimals) {
49751
+ const closePositionTokenAmount = computeClosePositionTokenAmount(position, mintDecimals);
49752
+ return amount >= closePositionTokenAmount;
49753
+ }
49754
+ var SWAP_MERGE_OVERHEAD = 150;
49755
+ var FL_IX_OVERHEAD = 52;
49756
+ function compactU16Size(n) {
49757
+ return n < 128 ? 1 : n < 16384 ? 2 : 3;
49758
+ }
49759
+ function computeV0TxSize(ixs, payerKey, luts) {
49760
+ const keyMap = /* @__PURE__ */ new Map();
49761
+ const payerStr = payerKey.toBase58();
49762
+ keyMap.set(payerStr, { isSigner: true, isWritable: true });
49763
+ const programIds = /* @__PURE__ */ new Set();
49764
+ for (const ix of ixs) {
49765
+ const progStr = ix.programId.toBase58();
49766
+ programIds.add(progStr);
49767
+ if (!keyMap.has(progStr)) {
49768
+ keyMap.set(progStr, { isSigner: false, isWritable: false });
49769
+ }
49770
+ for (const meta of ix.keys) {
49771
+ const keyStr = meta.pubkey.toBase58();
49772
+ const existing = keyMap.get(keyStr);
49773
+ if (existing) {
49774
+ existing.isSigner = existing.isSigner || meta.isSigner;
49775
+ existing.isWritable = existing.isWritable || meta.isWritable;
49776
+ } else {
49777
+ keyMap.set(keyStr, { isSigner: meta.isSigner, isWritable: meta.isWritable });
49778
+ }
49779
+ }
49780
+ }
49781
+ const lutLookup = /* @__PURE__ */ new Map();
49782
+ for (let li = 0; li < luts.length; li++) {
49783
+ const addresses = luts[li].state.addresses;
49784
+ for (let ai = 0; ai < addresses.length; ai++) {
49785
+ const addrStr = addresses[ai].toBase58();
49786
+ if (!lutLookup.has(addrStr)) {
49787
+ lutLookup.set(addrStr, { lutIdx: li, addrIdx: ai });
49788
+ }
49789
+ }
49790
+ }
49791
+ let numStaticKeys = 0;
49792
+ let numWritableStaticKeys = 0;
49793
+ const lutWritableIdxs = luts.map(() => /* @__PURE__ */ new Set());
49794
+ const lutReadonlyIdxs = luts.map(() => /* @__PURE__ */ new Set());
49795
+ for (const [keyStr, props] of keyMap) {
49796
+ if (props.isSigner || programIds.has(keyStr)) {
49797
+ numStaticKeys++;
49798
+ if (props.isWritable) numWritableStaticKeys++;
49799
+ continue;
49800
+ }
49801
+ const lutEntry = lutLookup.get(keyStr);
49802
+ if (lutEntry) {
49803
+ if (props.isWritable) {
49804
+ lutWritableIdxs[lutEntry.lutIdx].add(lutEntry.addrIdx);
49805
+ } else {
49806
+ lutReadonlyIdxs[lutEntry.lutIdx].add(lutEntry.addrIdx);
49807
+ }
49808
+ } else {
49809
+ numStaticKeys++;
49810
+ if (props.isWritable) numWritableStaticKeys++;
49811
+ }
49812
+ }
49813
+ const fixedOverhead = 101;
49814
+ const staticKeysSection = compactU16Size(numStaticKeys) + numStaticKeys * 32;
49815
+ let ixSection = compactU16Size(ixs.length);
49816
+ for (const ix of ixs) {
49817
+ const numAccounts = ix.keys.length;
49818
+ ixSection += 1 + // programId index
49819
+ compactU16Size(numAccounts) + numAccounts + // account key indexes
49820
+ compactU16Size(ix.data.length) + ix.data.length;
49821
+ }
49822
+ let numUsedLuts = 0;
49823
+ let lutSection = 0;
49824
+ for (let li = 0; li < luts.length; li++) {
49825
+ const wCount = lutWritableIdxs[li].size;
49826
+ const rCount = lutReadonlyIdxs[li].size;
49827
+ if (wCount === 0 && rCount === 0) continue;
49828
+ numUsedLuts++;
49829
+ lutSection += 32 + // LUT address
49830
+ compactU16Size(wCount) + wCount + // writable indexes
49831
+ compactU16Size(rCount) + rCount;
49832
+ }
49833
+ lutSection += compactU16Size(numUsedLuts);
49834
+ let totalLutKeys = 0;
49835
+ for (let li = 0; li < luts.length; li++) {
49836
+ totalLutKeys += lutWritableIdxs[li].size + lutReadonlyIdxs[li].size;
49837
+ }
49838
+ const accountCount = numStaticKeys + totalLutKeys;
49839
+ let totalLutWritableKeys = 0;
49840
+ for (let li = 0; li < luts.length; li++) {
49841
+ totalLutWritableKeys += lutWritableIdxs[li].size;
49842
+ }
49843
+ const writableAccountCount = numWritableStaticKeys + totalLutWritableKeys;
49844
+ const size = fixedOverhead + staticKeysSection + ixSection + lutSection + 1;
49845
+ return { size, accountCount, writableAccountCount };
49846
+ }
49847
+ function computeFlashLoanNonSwapBudget({
49848
+ program,
49849
+ marginfiAccount,
49850
+ ixs,
49851
+ bankMap,
49852
+ addressLookupTableAccounts
49853
+ }) {
49854
+ const projectedActiveBanksKeys = computeProjectedActiveBanksNoCpi(
49855
+ marginfiAccount.balances,
49856
+ ixs,
49857
+ program
49858
+ );
49859
+ const projectedActiveBanks = projectedActiveBanksKeys.map((key) => {
49860
+ const b = bankMap.get(key.toBase58());
49861
+ if (!b) throw new Error(`Bank ${key.toBase58()} not found in computeFlashLoanNonSwapBudget`);
49862
+ return b;
49863
+ });
49864
+ const endIndex = ixs.length + 1;
49865
+ const beginFlIx = sync_instructions_default.makeBeginFlashLoanIx(
49866
+ program.programId,
49867
+ { marginfiAccount: marginfiAccount.address, authority: marginfiAccount.authority },
49868
+ { endIndex: new BN11(endIndex) }
49869
+ );
49870
+ const endFlRemainingAccounts = computeHealthAccountMetas(projectedActiveBanks);
49871
+ const endFlIx = sync_instructions_default.makeEndFlashLoanIx(
49872
+ program.programId,
49873
+ { marginfiAccount: marginfiAccount.address, authority: marginfiAccount.authority },
49874
+ endFlRemainingAccounts.map((pubkey) => ({ pubkey, isSigner: false, isWritable: false }))
49875
+ );
49876
+ const allNonSwapIxs = [beginFlIx, ...ixs, endFlIx];
49877
+ const nonSwapMsg = new TransactionMessage({
49878
+ payerKey: marginfiAccount.authority,
49879
+ recentBlockhash: PublicKey.default.toBase58(),
49880
+ instructions: allNonSwapIxs
49881
+ }).compileToV0Message(addressLookupTableAccounts);
49882
+ const nonSwapSize = new VersionedTransaction(nonSwapMsg).serialize().length;
49883
+ const { header, staticAccountKeys, addressTableLookups } = nonSwapMsg;
49884
+ const nonSwapTotal = staticAccountKeys.length + addressTableLookups.reduce(
49885
+ (s, l) => s + l.writableIndexes.length + l.readonlyIndexes.length,
49886
+ 0
49887
+ );
49888
+ const sizeConstraint = MAX_TX_SIZE - nonSwapSize - SWAP_MERGE_OVERHEAD;
49889
+ const maxSwapTotalAccounts = MAX_ACCOUNT_LOCKS - nonSwapTotal;
49890
+ console.log("[flashloan-budget]", {
49891
+ method: "compiled",
49892
+ nonSwapSize,
49893
+ nonSwapTotal,
49894
+ sizeConstraint,
49895
+ maxSwapTotalAccounts
49896
+ });
49897
+ return { sizeConstraint, maxSwapTotalAccounts };
49898
+ }
49899
+ function compileFlashloanPrecheck({
49900
+ allIxs,
49901
+ payer,
49902
+ luts,
49903
+ sizeConstraint,
49904
+ swapIxCount,
49905
+ swapLutCount
49906
+ }) {
49907
+ const msg = new TransactionMessage({
49908
+ payerKey: payer,
49909
+ recentBlockhash: PublicKey.default.toBase58(),
49910
+ instructions: allIxs
49911
+ }).compileToV0Message(luts);
49912
+ const rawSize = new VersionedTransaction(msg).serialize().length;
49913
+ const fullTxSize = rawSize + FL_IX_OVERHEAD;
49914
+ const overshoot = fullTxSize - MAX_TX_SIZE;
49915
+ const { header, staticAccountKeys, addressTableLookups } = msg;
49916
+ const writableStatic = staticAccountKeys.length - header.numReadonlySignedAccounts - header.numReadonlyUnsignedAccounts;
49917
+ const writableLut = addressTableLookups.reduce((s, l) => s + l.writableIndexes.length, 0);
49918
+ const writableAccounts = writableStatic + writableLut;
49919
+ const totalAccounts = staticAccountKeys.length + addressTableLookups.reduce(
49920
+ (s, l) => s + l.writableIndexes.length + l.readonlyIndexes.length,
49921
+ 0
49922
+ );
49923
+ console.log("[flashloan-precheck]", {
49924
+ fullTxSize,
49925
+ overshoot,
49926
+ sizeConstraint,
49927
+ writableAccounts,
49928
+ totalAccounts,
49929
+ staticKeys: staticAccountKeys.length,
49930
+ numLuts: addressTableLookups.length,
49931
+ swapIxCount,
49932
+ swapLutCount
49933
+ });
49934
+ return { fullTxSize, overshoot, writableAccounts, totalAccounts };
49935
+ }
49936
+ async function buildBudgetIx(config, program, marginfiAccount, bankMap, bankMetadataMap, overrideInferAccounts) {
49937
+ const { bank, tokenProgram } = config;
49938
+ switch (config.type) {
49939
+ case "borrow":
49940
+ return makeBorrowIx3({
49941
+ program,
49942
+ bank,
49943
+ bankMap,
49944
+ tokenProgram,
49945
+ amount: 1,
49946
+ marginfiAccount,
49947
+ authority: marginfiAccount.authority,
49948
+ isSync: true,
49949
+ opts: { createAtas: false, wrapAndUnwrapSol: false, overrideInferAccounts }
49950
+ });
49951
+ case "repay":
49952
+ return makeRepayIx3({
49953
+ program,
49954
+ bank,
49955
+ tokenProgram,
49956
+ amount: 1,
49957
+ accountAddress: marginfiAccount.address,
49958
+ authority: marginfiAccount.authority,
49959
+ repayAll: false,
49960
+ isSync: true,
49961
+ opts: { wrapAndUnwrapSol: false, overrideInferAccounts }
49962
+ });
49963
+ case "deposit":
49964
+ return buildDepositBudgetIx(
49965
+ config,
49966
+ program,
49967
+ marginfiAccount,
49968
+ bankMetadataMap,
49969
+ overrideInferAccounts
49970
+ );
49971
+ case "withdraw":
49972
+ return buildWithdrawBudgetIx(
49973
+ config,
49974
+ program,
49975
+ marginfiAccount,
49976
+ bankMap,
49977
+ bankMetadataMap,
49978
+ overrideInferAccounts
49979
+ );
49980
+ }
49981
+ }
49982
+ async function buildDepositBudgetIx(config, program, marginfiAccount, bankMetadataMap, overrideInferAccounts) {
49983
+ const { bank, tokenProgram } = config;
49984
+ const opts = { wrapAndUnwrapSol: false, overrideInferAccounts };
49985
+ switch (bank.config.assetTag) {
49986
+ case 3 /* KAMINO */: {
49987
+ const reserve = bankMetadataMap[bank.address.toBase58()]?.kaminoStates?.reserveState;
49988
+ if (!reserve) {
49989
+ throw TransactionBuildingError.kaminoReserveNotFound(
49990
+ bank.address.toBase58(),
49991
+ bank.mint.toBase58(),
49992
+ bank.tokenSymbol
49993
+ );
49994
+ }
49995
+ return makeKaminoDepositIx3({
49996
+ program,
49997
+ bank,
49998
+ tokenProgram,
49999
+ amount: 1,
50000
+ accountAddress: marginfiAccount.address,
50001
+ authority: marginfiAccount.authority,
50002
+ group: marginfiAccount.group,
50003
+ reserve,
50004
+ isSync: true,
50005
+ opts
50006
+ });
50007
+ }
50008
+ case 4 /* DRIFT */: {
50009
+ const driftState = bankMetadataMap[bank.address.toBase58()]?.driftStates;
50010
+ if (!driftState) {
50011
+ throw TransactionBuildingError.driftStateNotFound(
50012
+ bank.address.toBase58(),
50013
+ bank.mint.toBase58(),
50014
+ bank.tokenSymbol
50015
+ );
50016
+ }
50017
+ return makeDriftDepositIx3({
50018
+ program,
50019
+ bank,
50020
+ tokenProgram,
50021
+ amount: 1,
50022
+ accountAddress: marginfiAccount.address,
50023
+ authority: marginfiAccount.authority,
50024
+ group: marginfiAccount.group,
50025
+ driftMarketIndex: driftState.spotMarketState.marketIndex,
50026
+ driftOracle: driftState.spotMarketState.oracle,
50027
+ isSync: true,
50028
+ opts
50029
+ });
50030
+ }
50031
+ case 6 /* JUPLEND */: {
50032
+ return makeJuplendDepositIx2({
50033
+ program,
50034
+ bank,
50035
+ tokenProgram,
50036
+ amount: 1,
50037
+ accountAddress: marginfiAccount.address,
50038
+ authority: marginfiAccount.authority,
50039
+ group: marginfiAccount.group,
50040
+ isSync: true,
50041
+ opts
50042
+ });
50043
+ }
50044
+ default: {
50045
+ return makeDepositIx3({
50046
+ program,
50047
+ bank,
50048
+ tokenProgram,
50049
+ amount: 1,
50050
+ accountAddress: marginfiAccount.address,
50051
+ authority: marginfiAccount.authority,
50052
+ group: marginfiAccount.group,
50053
+ isSync: true,
50054
+ opts
50055
+ });
49843
50056
  }
49844
50057
  }
49845
- const firstProvider = attempts[0]?.provider ?? "Swap";
49846
- throw TransactionBuildingError.swapQuoteFailed(
49847
- firstProvider,
49848
- inputMint,
49849
- outputMint,
49850
- lastError?.message ?? "No swap route available"
49851
- );
49852
- };
49853
- function mapJupiterQuoteToSwapQuoteResult(quote) {
49854
- return {
49855
- inAmount: quote.inAmount,
49856
- outAmount: quote.outAmount,
49857
- otherAmountThreshold: quote.otherAmountThreshold,
49858
- slippageBps: quote.slippageBps,
49859
- platformFee: quote.platformFee ? {
49860
- amount: quote.platformFee.amount ?? "0",
49861
- feeBps: quote.platformFee.feeBps ?? 0
49862
- } : void 0,
49863
- priceImpactPct: quote.priceImpactPct,
49864
- contextSlot: quote.contextSlot,
49865
- timeTaken: quote.timeTaken,
49866
- provider: "JUPITER" /* JUPITER */
49867
- };
49868
- }
49869
-
49870
- // src/services/account/utils/jupiter.utils.ts
49871
- var REFERRAL_PROGRAM_ID = new PublicKey("REFER4ZgmyYx9c6He5XfaTMiGfdLwRnkV4RPp9t9iF3");
49872
- var REFERRAL_ACCOUNT_PUBKEY = new PublicKey("Mm7HcujSK2JzPW4eX7g4oqTXbWYDuFxapNMHXe8yp1B");
49873
- var getFeeAccount = (mint) => {
49874
- const [feeAccount] = PublicKey.findProgramAddressSync(
49875
- [Buffer.from("referral_ata"), REFERRAL_ACCOUNT_PUBKEY.toBuffer(), mint.toBuffer()],
49876
- REFERRAL_PROGRAM_ID
49877
- );
49878
- return feeAccount.toBase58();
49879
- };
49880
- var checkFeeAccount = async (connection, mint) => {
49881
- const feeAccount = getFeeAccount(mint);
49882
- const hasFeeAccount = !!await connection.getAccountInfo(new PublicKey(feeAccount));
49883
- return { feeAccount, hasFeeAccount };
49884
- };
49885
- function deserializeJupiterInstruction(instruction) {
49886
- return new TransactionInstruction({
49887
- programId: new PublicKey(instruction.programId),
49888
- keys: instruction.accounts.map((key) => ({
49889
- pubkey: new PublicKey(key.pubkey),
49890
- isSigner: key.isSigner,
49891
- isWritable: key.isWritable
49892
- })),
49893
- data: Buffer.from(instruction.data, "base64")
49894
- });
49895
- }
49896
- function toJupiterConfig(apiConfig) {
49897
- if (!apiConfig) return void 0;
49898
- return {
49899
- basePath: apiConfig.basePath,
49900
- apiKey: apiConfig.apiKey ? () => apiConfig.apiKey : void 0,
49901
- headers: apiConfig.headers
49902
- };
49903
50058
  }
49904
- var getJupiterSwapIxsForFlashloan = async ({
49905
- quoteParams,
49906
- authority,
49907
- connection,
49908
- destinationTokenAccount,
49909
- apiConfig,
49910
- maxSwapAccounts
49911
- }) => {
49912
- const configParams = toJupiterConfig(apiConfig);
49913
- const jupiterApiClient = configParams?.basePath ? new SwapApi(new Configuration(configParams)) : createJupiterApiClient(configParams);
49914
- const feeMint = quoteParams.swapMode === "ExactIn" ? quoteParams.outputMint : quoteParams.inputMint;
49915
- const { feeAccount, hasFeeAccount } = await checkFeeAccount(connection, new PublicKey(feeMint));
49916
- const project0JupiterLut = (await connection.getAddressLookupTable(ADDRESS_LOOKUP_TABLE_FOR_SWAP))?.value;
49917
- let finalQuoteParams = quoteParams;
49918
- if (!hasFeeAccount) {
49919
- console.warn("Warning: feeAccountInfo is undefined");
49920
- finalQuoteParams = {
49921
- ...quoteParams,
49922
- platformFeeBps: void 0
49923
- };
49924
- }
49925
- const maxAccounts = maxSwapAccounts ?? 40;
49926
- const swapQuote = await jupiterApiClient.quoteGet({
49927
- ...finalQuoteParams,
49928
- maxAccounts
49929
- });
49930
- const swapInstructionResponse = await jupiterApiClient.swapInstructionsPost({
49931
- swapRequest: {
49932
- quoteResponse: swapQuote,
49933
- userPublicKey: authority.toBase58(),
49934
- feeAccount: hasFeeAccount ? feeAccount : void 0,
49935
- wrapAndUnwrapSol: false,
49936
- destinationTokenAccount: destinationTokenAccount.toBase58()
50059
+ async function buildWithdrawBudgetIx(config, program, marginfiAccount, bankMap, bankMetadataMap, overrideInferAccounts) {
50060
+ const { bank, tokenProgram } = config;
50061
+ const opts = { createAtas: false, wrapAndUnwrapSol: false, overrideInferAccounts };
50062
+ switch (bank.config.assetTag) {
50063
+ case 3 /* KAMINO */: {
50064
+ const reserve = bankMetadataMap[bank.address.toBase58()]?.kaminoStates?.reserveState;
50065
+ if (!reserve) {
50066
+ throw TransactionBuildingError.kaminoReserveNotFound(
50067
+ bank.address.toBase58(),
50068
+ bank.mint.toBase58(),
50069
+ bank.tokenSymbol
50070
+ );
50071
+ }
50072
+ return makeKaminoWithdrawIx3({
50073
+ program,
50074
+ bank,
50075
+ bankMap,
50076
+ tokenProgram,
50077
+ cTokenAmount: 1,
50078
+ marginfiAccount,
50079
+ authority: marginfiAccount.authority,
50080
+ reserve,
50081
+ withdrawAll: false,
50082
+ isSync: true,
50083
+ opts
50084
+ });
49937
50085
  }
49938
- });
49939
- const lutAddresses = swapInstructionResponse.addressLookupTableAddresses;
49940
- const lutAccountsRaw = await connection.getMultipleAccountsInfo(
49941
- lutAddresses.map((address) => new PublicKey(address))
49942
- );
49943
- const addressLookupTableAccounts = lutAccountsRaw.map((accountInfo, index) => {
49944
- const addressLookupTableAddress = lutAddresses[index];
49945
- if (!accountInfo || !addressLookupTableAddress) {
49946
- return null;
50086
+ case 4 /* DRIFT */: {
50087
+ const driftState = bankMetadataMap[bank.address.toBase58()]?.driftStates;
50088
+ if (!driftState) {
50089
+ throw TransactionBuildingError.driftStateNotFound(
50090
+ bank.address.toBase58(),
50091
+ bank.mint.toBase58(),
50092
+ bank.tokenSymbol
50093
+ );
50094
+ }
50095
+ return makeDriftWithdrawIx3({
50096
+ program,
50097
+ bank,
50098
+ bankMap,
50099
+ tokenProgram,
50100
+ amount: 1,
50101
+ marginfiAccount,
50102
+ authority: marginfiAccount.authority,
50103
+ driftSpotMarket: driftState.spotMarketState,
50104
+ userRewards: driftState.userRewards,
50105
+ withdrawAll: false,
50106
+ isSync: true,
50107
+ opts
50108
+ });
49947
50109
  }
49948
- return new AddressLookupTableAccount({
49949
- key: new PublicKey(addressLookupTableAddress),
49950
- state: AddressLookupTableAccount.deserialize(accountInfo.data)
49951
- });
49952
- }).filter((account) => account !== null).concat(project0JupiterLut ? [project0JupiterLut] : []);
49953
- const instruction = deserializeJupiterInstruction(swapInstructionResponse.swapInstruction);
49954
- const setupInstructions = swapInstructionResponse.setupInstructions.map(
49955
- deserializeJupiterInstruction
49956
- );
49957
- return {
49958
- swapInstructions: [instruction],
49959
- setupInstructions,
49960
- addressLookupTableAddresses: addressLookupTableAccounts,
49961
- quoteResponse: mapJupiterQuoteToSwapQuoteResult(swapQuote)
49962
- };
49963
- };
49964
-
49965
- // src/services/account/utils/misc.utils.ts
49966
- function floor(value, decimals) {
49967
- return Math.floor(value * 10 ** decimals) / 10 ** decimals;
49968
- }
49969
- function ceil(value, decimals) {
49970
- return Math.ceil(value * 10 ** decimals) / 10 ** decimals;
49971
- }
49972
- function computeClosePositionTokenAmount(position, mintDecimals) {
49973
- const closePositionTokenAmount = position.isLending ? floor(position.amount, mintDecimals) : ceil(position.amount, mintDecimals);
49974
- return closePositionTokenAmount;
50110
+ case 6 /* JUPLEND */: {
50111
+ const jupLendState = bankMetadataMap[bank.address.toBase58()]?.jupLendStates;
50112
+ if (!jupLendState) {
50113
+ throw TransactionBuildingError.jupLendStateNotFound(
50114
+ bank.address.toBase58(),
50115
+ bank.mint.toBase58(),
50116
+ bank.tokenSymbol
50117
+ );
50118
+ }
50119
+ return makeJuplendWithdrawIx2({
50120
+ program,
50121
+ bank,
50122
+ bankMap,
50123
+ tokenProgram,
50124
+ amount: 1,
50125
+ marginfiAccount,
50126
+ authority: marginfiAccount.authority,
50127
+ jupLendingState: jupLendState.jupLendingState,
50128
+ withdrawAll: false,
50129
+ opts
50130
+ });
50131
+ }
50132
+ default: {
50133
+ return makeWithdrawIx3({
50134
+ program,
50135
+ bank,
50136
+ bankMap,
50137
+ tokenProgram,
50138
+ amount: 1,
50139
+ marginfiAccount,
50140
+ authority: marginfiAccount.authority,
50141
+ withdrawAll: false,
50142
+ isSync: true,
50143
+ opts
50144
+ });
50145
+ }
50146
+ }
49975
50147
  }
49976
- function isWholePosition(position, amount, mintDecimals) {
49977
- const closePositionTokenAmount = computeClosePositionTokenAmount(position, mintDecimals);
49978
- return amount >= closePositionTokenAmount;
50148
+ async function computeFlashloanSwapConstraints({
50149
+ program,
50150
+ marginfiAccount,
50151
+ bankMap,
50152
+ addressLookupTableAccounts,
50153
+ bankMetadataMap,
50154
+ primaryIx,
50155
+ secondaryIx,
50156
+ overrideInferAccounts
50157
+ }) {
50158
+ const cuRequestIxs = [
50159
+ ComputeBudgetProgram.setComputeUnitLimit({ units: 12e5 }),
50160
+ ComputeBudgetProgram.setComputeUnitPrice({ microLamports: 1 })
50161
+ ];
50162
+ const [primaryResult, secondaryResult] = await Promise.all([
50163
+ buildBudgetIx(
50164
+ primaryIx,
50165
+ program,
50166
+ marginfiAccount,
50167
+ bankMap,
50168
+ bankMetadataMap,
50169
+ overrideInferAccounts
50170
+ ),
50171
+ buildBudgetIx(
50172
+ secondaryIx,
50173
+ program,
50174
+ marginfiAccount,
50175
+ bankMap,
50176
+ bankMetadataMap,
50177
+ overrideInferAccounts
50178
+ )
50179
+ ]);
50180
+ return computeFlashLoanNonSwapBudget({
50181
+ program,
50182
+ marginfiAccount,
50183
+ bankMap,
50184
+ addressLookupTableAccounts,
50185
+ ixs: [...cuRequestIxs, ...primaryResult.instructions, ...secondaryResult.instructions]
50186
+ });
49979
50187
  }
49980
50188
 
49981
50189
  // src/services/price/utils/smart-crank.utils.ts
@@ -50643,18 +50851,15 @@ var fetchPythOracleData = async (banks, opts) => {
50643
50851
  bankOraclePriceMap: /* @__PURE__ */ new Map()
50644
50852
  };
50645
50853
  }
50646
- pythStakedCollateralBanks.map((bank) => [
50647
- opts.validatorVoteAccountByBank?.[bank.address.toBase58()] ?? "",
50648
- bank.mint.toBase58()
50649
- ]);
50650
- const priceCoeffByBank = {};
50651
50854
  const combinedPythBanks = [
50652
50855
  ...pythPushBanks,
50856
+ ...pythStakedCollateralBanks,
50653
50857
  ...pythPushKaminosBanks,
50654
50858
  ...driftPythPullBanks,
50655
50859
  ...solendPythPullBanks,
50656
50860
  ...juplendPythPullBanks
50657
50861
  ];
50862
+ const priceCoeffByBank = {};
50658
50863
  const pythOracleKeys = extractPythOracleKeys(combinedPythBanks);
50659
50864
  const uniquePythOracleKeys = Array.from(new Set(pythOracleKeys));
50660
50865
  let oraclePrices;
@@ -51458,6 +51663,78 @@ function computeRemainingCapacity(bank) {
51458
51663
  };
51459
51664
  }
51460
51665
 
51666
+ // src/services/bank/utils/bank-metrics.utils.ts
51667
+ function computeBankTotalDeposits(bank, assetShareValueMultiplier) {
51668
+ const totalAssets = getTotalAssetQuantity(bank).times(
51669
+ assetShareValueMultiplier ?? 1
51670
+ );
51671
+ return nativeToUi(totalAssets, bank.mintDecimals);
51672
+ }
51673
+ function computeBankTotalBorrows(bank) {
51674
+ return nativeToUi(getTotalLiabilityQuantity(bank), bank.mintDecimals);
51675
+ }
51676
+ function computeBankTotalDepositsUsd(bank, oraclePrice, assetShareValueMultiplier) {
51677
+ return computeUsdValue({
51678
+ bank,
51679
+ oraclePrice,
51680
+ quantity: getTotalAssetQuantity(bank),
51681
+ priceBias: 1 /* None */,
51682
+ isWeightedPrice: false,
51683
+ assetShareValueMultiplier
51684
+ }).toNumber();
51685
+ }
51686
+ function computeBankTotalBorrowsUsd(bank, oraclePrice) {
51687
+ return computeUsdValue({
51688
+ bank,
51689
+ oraclePrice,
51690
+ quantity: getTotalLiabilityQuantity(bank),
51691
+ priceBias: 1 /* None */,
51692
+ isWeightedPrice: false
51693
+ }).toNumber();
51694
+ }
51695
+ function computeBankPoolSize(bank, assetShareValueMultiplier) {
51696
+ const totalDeposits = computeBankTotalDeposits(bank, assetShareValueMultiplier);
51697
+ const totalBorrows = computeBankTotalBorrows(bank);
51698
+ const borrowCap = nativeToUi(bank.config.borrowLimit, bank.mintDecimals);
51699
+ return Math.max(0, Math.min(totalDeposits, borrowCap) - totalBorrows);
51700
+ }
51701
+ function computeBankDepositCapRemaining(bank) {
51702
+ const { depositCapacity } = computeRemainingCapacity(bank);
51703
+ return Math.max(0, nativeToUi(depositCapacity, bank.mintDecimals));
51704
+ }
51705
+ function computeBankBorrowCapRemaining(bank) {
51706
+ const { borrowCapacity } = computeRemainingCapacity(bank);
51707
+ return Math.max(0, nativeToUi(borrowCapacity, bank.mintDecimals));
51708
+ }
51709
+ function computeBankSupplyApy(bank) {
51710
+ return aprToApy(computeInterestRates(bank).lendingRate.toNumber());
51711
+ }
51712
+ function computeBankBorrowApy(bank) {
51713
+ return aprToApy(computeInterestRates(bank).borrowingRate.toNumber());
51714
+ }
51715
+ function computeBankMetrics(params) {
51716
+ const { bank, oraclePrice, assetShareValueMultiplier, symbol = "" } = params;
51717
+ return {
51718
+ symbol,
51719
+ totalDeposits: computeBankTotalDeposits(bank, assetShareValueMultiplier),
51720
+ totalBorrows: computeBankTotalBorrows(bank),
51721
+ totalDepositsUsd: computeBankTotalDepositsUsd(
51722
+ bank,
51723
+ oraclePrice,
51724
+ assetShareValueMultiplier
51725
+ ),
51726
+ totalBorrowsUsd: computeBankTotalBorrowsUsd(bank, oraclePrice),
51727
+ utilizationRate: computeUtilizationRate(bank).toNumber(),
51728
+ poolSize: computeBankPoolSize(bank, assetShareValueMultiplier),
51729
+ depositCap: nativeToUi(bank.config.depositLimit, bank.mintDecimals),
51730
+ borrowCap: nativeToUi(bank.config.borrowLimit, bank.mintDecimals),
51731
+ depositCapRemaining: computeBankDepositCapRemaining(bank),
51732
+ borrowCapRemaining: computeBankBorrowCapRemaining(bank),
51733
+ supplyApy: computeBankSupplyApy(bank),
51734
+ borrowApy: computeBankBorrowApy(bank)
51735
+ };
51736
+ }
51737
+
51461
51738
  // src/services/bank/bank.service.ts
51462
51739
  async function freezeBankConfigIx(program, bankAddress, bankConfigOpt) {
51463
51740
  let bankConfigRaw;
@@ -51859,6 +52136,613 @@ function dtoToValidatorStakeGroup(validatorStakeGroupDto) {
51859
52136
  }))
51860
52137
  };
51861
52138
  }
52139
+
52140
+ // src/services/native-stake/utils/metadata.data.ts
52141
+ var STAKED_BANK_METADATA_JSON = [
52142
+ {
52143
+ bankAddress: "8g5qG6PVygcVSXV1cJnjXaD1yhrDwcWAMQCY2wR9VuAf",
52144
+ validatorVoteAccount: "CooLbbZy5Xmdt7DiHPQ3ss2uRXawnTXXVgpMS8E8jDzr",
52145
+ tokenAddress: "BADo3D6nMtGnsAaTv3iEes8mMcq92TuFoBWebFe8kzeA",
52146
+ tokenName: "Cavey Cool",
52147
+ tokenSymbol: "COOL"
52148
+ },
52149
+ {
52150
+ bankAddress: "BuCckNm1djpp3vZVhvh1CrrniirY6sr2hwUmeP5kTcGz",
52151
+ validatorVoteAccount: "mrgn4t2JabSgvGnrCaHXMvz8ocr4F52scsxJnkQMQsQ",
52152
+ tokenAddress: "FUyAyVbYrMfiaN1QEQYFZTuBNzW5EJf3jWzjjymGqKLv",
52153
+ tokenName: "Project 0 Meridian",
52154
+ tokenSymbol: "MERIDIAN"
52155
+ },
52156
+ {
52157
+ bankAddress: "Hco1P3dGRXz3ZGFvMkbDgghZQy47Tp7vp7koSYRvP6nm",
52158
+ validatorVoteAccount: "mrgn6ETrBDM8mjjYN8rbVwFqVwF8z6rtmvGLbdGuVUU",
52159
+ tokenAddress: "A4B5MGQvcZCUqeiUEAB4ckZ2tvH2UmEg31vF7TiERDkH",
52160
+ tokenName: "MRGN 3",
52161
+ tokenSymbol: "MRGN3"
52162
+ },
52163
+ {
52164
+ bankAddress: "EPh2abWP8DusPH8myWnECAAeQUZgAz927aMbmwXt3eRY",
52165
+ validatorVoteAccount: "mrgn2vsZ5EJ8YEfAMNPXmRux7th9cNfBasQ1JJvVwPn",
52166
+ tokenAddress: "6Mt7tBWLUJfDxqCFTsjoRXF9wD55g4Lhs5nAyYp244pX",
52167
+ tokenName: "Project 0 Horizon",
52168
+ tokenSymbol: "HORIZON"
52169
+ },
52170
+ {
52171
+ bankAddress: "6wjAwhnxTMEzHk8NNHVXgkx1jSrb6TX1bC17j3S56FfB",
52172
+ validatorVoteAccount: "3N7s9zXMZ4QqvHQR15t5GNHyqc89KduzMP7423eWiD5g",
52173
+ tokenAddress: "DKPvRV4dxUejjGpr2XwFmzZbbbTD7vx9Jmt1kk43n4d5",
52174
+ tokenName: "Binance",
52175
+ tokenSymbol: "BINANCE"
52176
+ },
52177
+ {
52178
+ bankAddress: "J9tksvZEDSwtNtZ6yxYjWDDkzhPbwDMnihU61NkFG9FE",
52179
+ validatorVoteAccount: "he1iusunGwqrNtafDtLdhsUQDFvo13z9sUa36PauBtk",
52180
+ tokenAddress: "2k79y8CApbU9jAvWhLS2j6uRbaVjpLJTUzstBTho9vGq",
52181
+ tokenName: "Helius",
52182
+ tokenSymbol: "HELIUS"
52183
+ },
52184
+ {
52185
+ bankAddress: "Dfr6Sf44ftecaJaoJMzFQABdkt3CEHfBwut1WyacRzaE",
52186
+ validatorVoteAccount: "SLaYv7tCwetrFGbPCRnqpHswG5qqKino78EYpbGF7xY",
52187
+ tokenAddress: "Vsw4JT33S7bLbhjySMMyrP3JKvTAcNi9WG5Doekrmgg",
52188
+ tokenName: "Solayer",
52189
+ tokenSymbol: "SOLAYER"
52190
+ },
52191
+ {
52192
+ bankAddress: "BZAm4qGscR8gg5bmWrEq6BTofgaZPbg7Fwfa7rFghEXL",
52193
+ validatorVoteAccount: "J1to3PQfXidUUhprQWgdKkQAMWPJAEqSJ7amkBDE9qhF",
52194
+ tokenAddress: "6B8hZSupE5mcACmjzozP6C1DR2uaCCtmrGqcYWC6SBCc",
52195
+ tokenName: "Bonk",
52196
+ tokenSymbol: "BONK"
52197
+ },
52198
+ {
52199
+ bankAddress: "3UrMZ26NRKu2y6c2dPE7gZVHwEmhpwKLcWACg3tjCVEt",
52200
+ validatorVoteAccount: "J2nUHEAgZFRyuJbFjdqPrAa9gyWDuc7hErtDQHPhsYRp",
52201
+ tokenAddress: "9M7oMo4oL6RDPG7WbAX3Zz4dPzbMgpiCzwrQPMwG4Wgq",
52202
+ tokenName: "Phantom",
52203
+ tokenSymbol: "PHANTOM"
52204
+ },
52205
+ {
52206
+ bankAddress: "8c269gkonvATm93nviuYiriCQ829f7ypx3aScYDR1YoQ",
52207
+ validatorVoteAccount: "D3QPJm7BDzzPeRG51YZSEz3LfV7GvFNu9NkcibzURxuj",
52208
+ tokenAddress: "8hXCCQmYFcDhU5Mkuvyixp2Q11sbyQComkceSSh3GY4a",
52209
+ tokenName: "Starke Finance",
52210
+ tokenSymbol: "STARKE"
52211
+ },
52212
+ {
52213
+ bankAddress: "37tiA2NTF6YCt85XzCidPo9ZVpuqkkmfVJCYQ5Yx5Uhs",
52214
+ validatorVoteAccount: "SBLZib4npE7svxFA7AsD3ytdQAfYNb39c8zsU82AA2E",
52215
+ tokenAddress: "96rXgCFy1Er49169XoKHkeLiKC2k4bTy1641q1TVrMm2",
52216
+ tokenName: "SolBlaze Validator",
52217
+ tokenSymbol: "SOLBLAZE"
52218
+ },
52219
+ {
52220
+ bankAddress: "J9trpcrVdFjVNg6VFrdF1XPGgjftQKZhbbWsxertdv9V",
52221
+ validatorVoteAccount: "FACqsS19VScz8oo2YhdMg35EsAy6xsCZ9Y58eJXGv8QJ",
52222
+ tokenAddress: "AH6fxpHS2gtMtJgBy8y8pEAPkqyop2pSugF6REs9NaTp",
52223
+ tokenName: "Lantern",
52224
+ tokenSymbol: "LNTRN"
52225
+ },
52226
+ {
52227
+ bankAddress: "EGTfrYiuWpPPZ4yfY9tCxnK6QMkY7pzVie9DxK772iGe",
52228
+ validatorVoteAccount: "EfnywDKqArxK6N6FS9ctsuzNdxfx3pzfXEQE5EevQ1SV",
52229
+ tokenAddress: "FcXEwHku68ZquqtSj1eSWS1SVWkhAZSyb4usfpiuEJAL",
52230
+ tokenName: "PROJECT SUPER",
52231
+ tokenSymbol: "SUPER"
52232
+ },
52233
+ {
52234
+ bankAddress: "A5e7UTE3g11ZfKgftqRCvxAgcDuFGyeDjMka96zJWSWe",
52235
+ validatorVoteAccount: "3ZUQekqiZoybB57y49eqtvSaoonqDwuNbeqEGwN88JkQ",
52236
+ tokenAddress: "F1XPjtpsEy23Q7po4JkWjp1jkDZcvFYSrqD8TR1YL3EF",
52237
+ tokenName: "Paws",
52238
+ tokenSymbol: "PAWS"
52239
+ },
52240
+ {
52241
+ bankAddress: "91jkdp4cF8vCDhjwude3SGSGrmVWFk5vTAtR6fsGVAfy",
52242
+ validatorVoteAccount: "gangtRyGPTvYWb8K3xS2feJQaCks4iJ7rytFUPtVqSY",
52243
+ tokenAddress: "6ZS7ZVDw91BVAC8gsz3SZBSeVeF2GtXtL2BHK31Kvyjm",
52244
+ tokenName: "Lotus Validator",
52245
+ tokenSymbol: "LOTUS"
52246
+ },
52247
+ {
52248
+ bankAddress: "72BS34HkCgq8RWQR7kuVVmiJMtKqSxG4CHX6ZXpSCwg7",
52249
+ validatorVoteAccount: "oRAnGeU5h8h2UkvbfnE5cjXnnAa4rBoaxmS4kbFymSe",
52250
+ tokenAddress: "9yF8pXctzicum2P73uuk4Dhqf2MVz6tzRAe8THGXCJcp",
52251
+ tokenName: "Orangefin Ventures",
52252
+ tokenSymbol: "ORANGEFIN"
52253
+ },
52254
+ {
52255
+ bankAddress: "8F4DsU3NMFunUxBZkWrpYR8zwhAfoAt7QuiEPMtyhWvX",
52256
+ validatorVoteAccount: "3xjfK9C9YNcta8MvK1US4sQ3bc6DEjoJoR3qLExGf9xE",
52257
+ tokenAddress: "Akib1NYJzzh9HkiDH41S2LUefUmR1bKsk65xgqUcW5C5",
52258
+ tokenName: "pico\u{1F644}.sol",
52259
+ tokenSymbol: "PICO"
52260
+ },
52261
+ {
52262
+ bankAddress: "GdtggomQth6cxuYPdiVhBbcX7VC9rnDDwLMfxipxE2Po",
52263
+ validatorVoteAccount: "oPaLTmyvoUhW26QCMwLA5JNUeBYy72PDpFoXQF8SeX4",
52264
+ tokenAddress: "C71A3W7g5XALUNwTDWTwHX3qhfypaYZ41aNZjBpcaC9D",
52265
+ tokenName: "Temporal Opal",
52266
+ tokenSymbol: "OPAL"
52267
+ },
52268
+ {
52269
+ bankAddress: "5sJCKePwAhyD3mzrzLRDM2PkFMc85nnvvarxHLsvWvpg",
52270
+ validatorVoteAccount: "9jYFwBfbjYmvasFbJyES9apLJDTkwtbgSDRWanHEvcRw",
52271
+ tokenAddress: "Hj69K1WbnfZFipLbrzdxgGhDqCR47q48bN5nUHt6xQZo",
52272
+ tokenName: "WATCHTOWER",
52273
+ tokenSymbol: "WATCHTOWER"
52274
+ },
52275
+ {
52276
+ bankAddress: "3F3QXT3BtkegaBfFjn2odKLurFYLHJHJ99xKV2TRTvrk",
52277
+ validatorVoteAccount: "6JfBwvcz5QUKQJ37BMKTLrf968DDJBtwoZLw19aHwFtQ",
52278
+ tokenAddress: "8FqX86cQofBHReetZgxrxxvzN4iqMVsj2hbiv7pj2h73",
52279
+ tokenName: "Spectrum Staking",
52280
+ tokenSymbol: "SPECTRUM"
52281
+ },
52282
+ {
52283
+ bankAddress: "CFmvdtEPQJPVqS1QRkeRcdQm2itAPk6k8hSJbmt88Sjc",
52284
+ validatorVoteAccount: "Haz7b47sZBpxh9SwggGndN3fAyNQ1S949BPdxWXS3ab6",
52285
+ tokenAddress: "38ZUTefZnKSUJU3wxpUe3xpiw2j5WQPnmzSTNbS1JqLA",
52286
+ tokenName: "Temporal Emerald",
52287
+ tokenSymbol: "EMERALD"
52288
+ },
52289
+ {
52290
+ bankAddress: "CmBDHSVuodmUnanbBVFvY9cauLeosbdFQn9bJANMVYUG",
52291
+ validatorVoteAccount: "mintrNtxN3PhAB45Pt41XqyKghTTpqcoBkQTZqh96iR",
52292
+ tokenAddress: "GxGmv7s7s2co3pLZukns946fr5zmR8c5buWRD9prGd6v",
52293
+ tokenName: "Hanabi Staking",
52294
+ tokenSymbol: "haSOLmrgn"
52295
+ },
52296
+ {
52297
+ bankAddress: "7bLfrb4fWVYkVpZ9rg7dBUwKRAqLyiivCW4ahMMGcKyS",
52298
+ validatorVoteAccount: "76DafWkJ6pGK2hoD41HjrM4xTBhfKqrDYDazv13n5ir1",
52299
+ tokenAddress: "GT7n9uZbYzHv52YqDBowtZ5ZVW91umaBQTNPFQNeLUpR",
52300
+ tokenName: "Solana Japan Validator",
52301
+ tokenSymbol: "SolJAPAn"
52302
+ },
52303
+ {
52304
+ bankAddress: "6q5DB86DhCBQt5bqzZwgopV8EA96aCnngu5ebR1ooDFq",
52305
+ validatorVoteAccount: "Cue647T8jgwpRSDUb8ttTYx7NiEfJCRZNiiw1qmchXsG",
52306
+ tokenAddress: "EAR6LenhNstHxR9289rWakm82WgLJYvHD7NawfXtuyUx",
52307
+ tokenName: "KIWAMI",
52308
+ tokenSymbol: "KIWAMI"
52309
+ },
52310
+ {
52311
+ bankAddress: "GLSCJ39N82Xo21621jMheinvjQLrBrkG7gzo2C5L1y6y",
52312
+ validatorVoteAccount: "7emL18Bnve7wbYE9Az7vYJjikxN6YPU81igf6rVU5FN8",
52313
+ tokenAddress: "EQuMUgLZArKwWUk6uGPmTGYUgNbfgJrbBaNR7CQyZ5uf",
52314
+ tokenName: "Temporal Topaz",
52315
+ tokenSymbol: "TOPAZ"
52316
+ },
52317
+ {
52318
+ bankAddress: "4irzCCsU53ffh9XB7NxGzbbHjvSR7FTfPbn6KoXkt7kX",
52319
+ validatorVoteAccount: "2iWXwF2Q5W6o7yntV2mkbxncB4rYHnX61y3NU8a8EFMJ",
52320
+ tokenAddress: "14Pets6QpE9iXKkXg8Ri4GcDazRMfWR3guM6LZXnFChc",
52321
+ tokenName: "Bull Moose SOL",
52322
+ tokenSymbol: "bmsSOL"
52323
+ },
52324
+ {
52325
+ bankAddress: "C96do7nkEaaFjHq8jHzPpyPTdJSea5xEGwxDzDSepCzf",
52326
+ validatorVoteAccount: "voteRnv6PBzmiGP8NicWtQiqEJTwKKq2SxtqtdLUJjd",
52327
+ tokenAddress: "3YEDiJ4r4xRGNhq6nudRnkwrdKHG7PAtDim24CjTMtBH",
52328
+ tokenName: "diman",
52329
+ tokenSymbol: "DIMAN"
52330
+ },
52331
+ {
52332
+ bankAddress: "9dZiyG51FBR4BWpAs69XbDpr7GfVAEB1ZB89v38maV36",
52333
+ validatorVoteAccount: "Simpj3KyRQmpRkXuBvCQFS7DBBG6vqw93SkZb9UD1hp",
52334
+ tokenAddress: "77YLpVLQXr2KU66GM2JykbT9g5du7LarWgehbWD3CJaB",
52335
+ tokenName: "SIMPDIGIT",
52336
+ tokenSymbol: "SIMPDIGIT"
52337
+ },
52338
+ {
52339
+ bankAddress: "2foqT8wWzWRduyV37uRdj81DijkNMKzYD3D6JPfir7La",
52340
+ validatorVoteAccount: "48oxpSHQkM4sdXUY9NQ8KnEtebzZbyk8uUT7JRdVQNuf",
52341
+ tokenAddress: "42m7Ygk5VxREdKfcFrsH1HnuoqCke8BcVcxNeywMCfp2",
52342
+ tokenName: "Infinite Lux",
52343
+ tokenSymbol: "LUX"
52344
+ },
52345
+ {
52346
+ bankAddress: "FsdWEJzHXkUXejWnb7c1p9UJtF69hVWQNNoakjoXyRCJ",
52347
+ validatorVoteAccount: "4AUED4uj6nSTuANzaAUnGBPJQRmhpDYDwoWJNkoUUBBW",
52348
+ tokenAddress: "CiyQTfHJ9PbTwC7TGf4pXZk8szcWGJ8TeFhhCuUwybqi",
52349
+ tokenName: "Anagram",
52350
+ tokenSymbol: "ANAGRAM"
52351
+ },
52352
+ {
52353
+ bankAddress: "2hs1pHAzDWGqnn1d8VQkc8bZRfQ45grYvzfau8dnWFUk",
52354
+ validatorVoteAccount: "2NxEEbhqqj1Qptq5LXLbDTP5tLa9f7PqkU8zNgxbGU9P",
52355
+ tokenAddress: "9yQLxEzusZ7QiZNafDNdzbEaTCPuJToGjMhLRJtZbgsd",
52356
+ tokenName: "NANSEN",
52357
+ tokenSymbol: "NANSEN"
52358
+ },
52359
+ {
52360
+ bankAddress: "FCi8unSVCwJd3QkrhTtv6LTTjw1c4zV65D5cG5N1rAG6",
52361
+ validatorVoteAccount: "Va1idkzkB6LEmVFmxWbWU8Ao9qehC62Tjmf68L3uYKj",
52362
+ tokenAddress: "AExKb8oJ6mGPYJUyfiX49DMMi226h2AnWeG1G6neQBEz",
52363
+ tokenName: "VALIDATOR",
52364
+ tokenSymbol: "VALID"
52365
+ },
52366
+ {
52367
+ bankAddress: "HzS8RqaQ5syk6EHbVi7h9rFYN48PpxykUXEs6w9wNfNP",
52368
+ validatorVoteAccount: "sTach38ebT8jnGH8i2D1g8NDAS6An19whVMnSSWPXt4",
52369
+ tokenAddress: "AFDVYBqxADagPfN9DdbrNrf9zZqugub7CV4kUJEUrK6J",
52370
+ tokenName: "Stache Node",
52371
+ tokenSymbol: "STACHE"
52372
+ },
52373
+ {
52374
+ bankAddress: "9Hs4E6ACNw6Hmwjvm1duXzbaWmvXxSxN11agw4updEn1",
52375
+ validatorVoteAccount: "EtMSc3MvcDXUr6ChK5GxyFVwTxYA3zqP5XzjE9jwKvSV",
52376
+ tokenAddress: "ENKFyZQZHzNNSxcKYoaVsNLi2xoGPoStZH4A9xxezjbC",
52377
+ tokenName: "Mad Lads CN",
52378
+ tokenSymbol: "MadLadsCN"
52379
+ },
52380
+ {
52381
+ bankAddress: "4watsWcjTBAwsrZpArwQbnNX4bQ1yeHBxgdbrGT4eMu9",
52382
+ validatorVoteAccount: "EARNynHRWg6GfyJCmrrizcZxARB3HVzcaasvNa8kBS72",
52383
+ tokenAddress: "8fhkWcm2n28JuadzY7mRR8FFDZZfnaPfWgw7pLNVZCbE",
52384
+ tokenName: "Solana Compass Stake",
52385
+ tokenSymbol: "compaStake"
52386
+ },
52387
+ {
52388
+ bankAddress: "9d7MTvcz1VMB1rK6H73quMxkR26dLPz5HDaac2eGRjQx",
52389
+ validatorVoteAccount: "nymsndUdAZyUPpWYz5VEg8Ghj9cFvwTRgciLogpmYaQ",
52390
+ tokenAddress: "FWFeaqpkgDr3ejVSY3HjiUmUg3u9fcr5d66HvimnDLWE",
52391
+ tokenName: "Hypo Nyms",
52392
+ tokenSymbol: "NYMS"
52393
+ },
52394
+ {
52395
+ bankAddress: "6V4vCK3n3JVncfpS16mW8ceLoNPatvu61pKxFmWx8adi",
52396
+ validatorVoteAccount: "BT8LZUvQVwFHRGw2Dwv7UeqDUq7btfjegLpuz5bwgziD",
52397
+ tokenAddress: "9YRS7Stf9dVibTT1M4uVEAuRMcoS4MH1QxqXy9Lssrab",
52398
+ tokenName: "private",
52399
+ tokenSymbol: "private"
52400
+ },
52401
+ {
52402
+ bankAddress: "CK8qRAcmvkDXaqX2S5GkgTCZT5pCz34me1neQhpJYe1Z",
52403
+ validatorVoteAccount: "Ac1beBKixfNdrTAac7GRaTsJTxLyvgGvJjvy4qQfvyfc",
52404
+ tokenAddress: "DLTAbTL5NXhbqX6LX3ie3tf52pdtGpxe2DrZUr1RhgY6",
52405
+ tokenName: "Stronghold",
52406
+ tokenSymbol: "Stronghold"
52407
+ },
52408
+ {
52409
+ bankAddress: "H6CT1aiCgSNw9S6aq38npEhdoN2UPhSKe8Lj9fQqqjuu",
52410
+ validatorVoteAccount: "FREEL1BCzmPpNneC7FHCtBqzeWYrHRbtisFvi4N8XUP9",
52411
+ tokenAddress: "AKFuMoM5rjSpQSL4p6TBoc7D4dmEem9QrHhuSDCBYyZ8",
52412
+ tokenName: "Ross",
52413
+ tokenSymbol: "Ross"
52414
+ },
52415
+ {
52416
+ bankAddress: "G46aHuakgStymbE2WsLbja61mH5UXBPdSdpwf6Ci3saG",
52417
+ validatorVoteAccount: "mnvkHm47ZmRKoSWuQZAfXLRiDPiKCq8PWkMWrp1Wwqe",
52418
+ tokenAddress: "Cq9S5UB9BviPn5yoGkEDk3m7neQag4KJnhPWGyuev9W8",
52419
+ tokenName: "gripto staked sol",
52420
+ tokenSymbol: "GRIPTO"
52421
+ },
52422
+ {
52423
+ bankAddress: "75UmeEMdqVnGn3JHx8yVZEn7viybJ73XYSjhYCYfyhp2",
52424
+ validatorVoteAccount: "4m1PbxzwLdUnEwog3T9UKxgjktgriHgE1CfAhMqDw7Xx",
52425
+ tokenAddress: "432SogPNunjZMneDV6goZ8ZcCQz282GxoSJ4rwqx95pT",
52426
+ tokenName: "kumasol",
52427
+ tokenSymbol: "kumasol"
52428
+ },
52429
+ {
52430
+ bankAddress: "3zk6EmXANYQK12bwy9dySRAM4cT2vT5cDcAB79j8G33B",
52431
+ validatorVoteAccount: "HvsD9L5t62MGv3QBD2K7xjkipGYr9UZN7BtsW8NuSPpg",
52432
+ tokenAddress: "5vmwd6JHDCmX9W2XT1n2QpvYGA2kk4Xf7qWSayDU6caT",
52433
+ tokenName: "ArgenTerraSOL",
52434
+ tokenSymbol: "atSOL"
52435
+ },
52436
+ {
52437
+ bankAddress: "4C2vPweGNpiE6kTEbYvcbUBHNWxrn4ErQYaqWm5zDexx",
52438
+ validatorVoteAccount: "FnAPJkzf19s87sm24Qhv6bHZMZvZ43gjNUBRgjwXpD4v",
52439
+ tokenAddress: "6q4kVnwUpkE3i7W32dqaX6V12pbsrCnMqZ7TWz9yp1m5",
52440
+ tokenName: "BLOCKPORT",
52441
+ tokenSymbol: "BPT"
52442
+ },
52443
+ {
52444
+ bankAddress: "E5hZu5QQ1pRmGvyS4JHGXVQwzdUPaYM4yEiNKr64YzyG",
52445
+ validatorVoteAccount: "nfGcSJkP35SkPa5475iBChmq1UNcj7JE1uQHrrasymm",
52446
+ tokenAddress: "AQpQoJ3tJKGH9Yn8GSzoUsVcHPJjj3xYfQFp9XVr74F6",
52447
+ tokenName: "Test01",
52448
+ tokenSymbol: "TEST01"
52449
+ },
52450
+ {
52451
+ bankAddress: "3VCkXWAmE5DSwYRpqGFnkUz7vvD2RKbhFvrhzLuE8msu",
52452
+ validatorVoteAccount: "abc1zP7ihWsgQW8z5YmfQNqMckJE5Dfx8fwUNMNVNkY",
52453
+ tokenAddress: "BNisp3omkr6Rg5nHESWafjUbeCpGPy6MYq1iRJRgSAsh",
52454
+ tokenName: "ALGO STAKE",
52455
+ tokenSymbol: "ALGO"
52456
+ },
52457
+ {
52458
+ bankAddress: "7BHHMWw3P1AyebLhX9A8wnDeeGy8jgFXqqHuEZt7BVmW",
52459
+ validatorVoteAccount: "8Pep3GmYiijRALqrMKpez92cxvF4YPTzoZg83uXh14pW",
52460
+ tokenAddress: "zBH13AzXYCqHZKS8NGa4KR8zQhWiyvFdDY15nmfrHgS",
52461
+ tokenName: "8Pep",
52462
+ tokenSymbol: "8Pep"
52463
+ },
52464
+ {
52465
+ bankAddress: "9QWUatjtJtc98yts4ufWnmNeaWQRmaaLjFwbK3iMdS47",
52466
+ validatorVoteAccount: "CatzoSMUkTRidT5DwBxAC2pEtnwMBTpkCepHkFgZDiqb",
52467
+ tokenAddress: "98B1NMLYaNJQNxiQGr53vbjNFMNTYFmDqoCgj7qD9Vhm",
52468
+ tokenName: "JUPITER ",
52469
+ tokenSymbol: "JUPITER"
52470
+ },
52471
+ {
52472
+ bankAddress: "5q1wJkGqqRh6mSBtjG8sfjBsgJSGdA2QoXTWv4UQbHGk",
52473
+ validatorVoteAccount: "shft7Fry1js37Hm9wq4dfwcZSp2DyKszeWMvEpjYCQ1",
52474
+ tokenAddress: "C1KwBJZNwUaodUcP5kXqD52NCuZzThNAG2cw3vt5H6iE",
52475
+ tokenName: "BLUESHIFT",
52476
+ tokenSymbol: "SHIFT"
52477
+ },
52478
+ {
52479
+ bankAddress: "FZaHyfg9hmNMKpfUJ474wNKPaPdXMpnJouasKnndECiZ",
52480
+ validatorVoteAccount: "DdCNGDpP7qMgoAy6paFzhhak2EeyCZcgjH7ak5u5v28m",
52481
+ tokenAddress: "PhxXAYTkFZS23ZWvFcz6H6Uq4VnVBMa6hniiAyudjaW",
52482
+ tokenName: "KILN1",
52483
+ tokenSymbol: "KILN1"
52484
+ },
52485
+ {
52486
+ bankAddress: "5CBocarwfJeWGNozGemWktRYSz6kPikRPdfH8ZHSFrsg",
52487
+ validatorVoteAccount: "8zuMRTXThoPTTPLLvaiKiJshLLCqGMt9BdRjjCL19xBc",
52488
+ tokenAddress: "BDsEuxFWznAP5cUCannnfjyjDtTwqN57CkGfDbjx2nNZ",
52489
+ tokenName: "DawnLabs",
52490
+ tokenSymbol: "DawnLabs"
52491
+ },
52492
+ {
52493
+ bankAddress: "9ivswG37QpCUmkPkLMpRZT7PMyP64V9dDpZdteM254ec",
52494
+ validatorVoteAccount: "gaToR246dheK1DGAMEqxMdBJZwU4qFyt7DzhSwAHFWF",
52495
+ tokenAddress: "TjA2rtxoUFzyPVAw35VQGEQnNXiwcmNjKSk29nmkq1P",
52496
+ tokenName: "Valigator Open",
52497
+ tokenSymbol: "Valigator"
52498
+ }
52499
+ ];
52500
+
52501
+ // src/services/native-stake/utils/metadata.utils.ts
52502
+ var _metadataMap = null;
52503
+ var _voteAccountByBank = null;
52504
+ function getStakedBankMetadataMap() {
52505
+ if (!_metadataMap) {
52506
+ _metadataMap = /* @__PURE__ */ new Map();
52507
+ for (const entry of STAKED_BANK_METADATA_JSON) {
52508
+ _metadataMap.set(entry.bankAddress, entry);
52509
+ }
52510
+ }
52511
+ return _metadataMap;
52512
+ }
52513
+ function getValidatorVoteAccountByBank() {
52514
+ if (!_voteAccountByBank) {
52515
+ _voteAccountByBank = {};
52516
+ for (const entry of STAKED_BANK_METADATA_JSON) {
52517
+ _voteAccountByBank[entry.bankAddress] = entry.validatorVoteAccount;
52518
+ }
52519
+ }
52520
+ return _voteAccountByBank;
52521
+ }
52522
+ async function computeStakedBankMultipliers(stakedBanks, connection) {
52523
+ const multiplierByBank = /* @__PURE__ */ new Map();
52524
+ if (stakedBanks.length === 0) {
52525
+ return multiplierByBank;
52526
+ }
52527
+ const metadataMap = getStakedBankMetadataMap();
52528
+ const stakedBankAddresses = [];
52529
+ const poolStakeAddresses = [];
52530
+ const lstMintAddresses = [];
52531
+ for (const bank of stakedBanks) {
52532
+ const metadata = metadataMap.get(bank.address.toBase58());
52533
+ if (!metadata) {
52534
+ multiplierByBank.set(bank.address.toBase58(), new BigNumber3(1));
52535
+ continue;
52536
+ }
52537
+ const pool = findPoolAddress(new PublicKey(metadata.validatorVoteAccount));
52538
+ stakedBankAddresses.push(bank.address.toBase58());
52539
+ poolStakeAddresses.push(findPoolStakeAddress(pool));
52540
+ lstMintAddresses.push(findPoolMintAddress(pool));
52541
+ }
52542
+ if (stakedBankAddresses.length === 0) {
52543
+ return multiplierByBank;
52544
+ }
52545
+ const allAddresses = [
52546
+ ...poolStakeAddresses.map((a) => a.toBase58()),
52547
+ ...lstMintAddresses.map((a) => a.toBase58())
52548
+ ];
52549
+ const accountInfos = await chunkedGetRawMultipleAccountInfoOrdered(connection, allAddresses);
52550
+ const poolStakeInfos = accountInfos.slice(0, poolStakeAddresses.length);
52551
+ const lstMintInfos = accountInfos.slice(poolStakeAddresses.length);
52552
+ for (let i = 0; i < stakedBankAddresses.length; i++) {
52553
+ const bankAddr = stakedBankAddresses[i];
52554
+ const poolStakeInfo = poolStakeInfos[i];
52555
+ const lstMintInfo = lstMintInfos[i];
52556
+ if (!poolStakeInfo || !lstMintInfo) {
52557
+ multiplierByBank.set(bankAddr, new BigNumber3(1));
52558
+ continue;
52559
+ }
52560
+ const stakeLamports = poolStakeInfo.lamports;
52561
+ const supplyBuffer = lstMintInfo.data.slice(36, 44);
52562
+ const lstMintSupply = Number(Buffer.from(supplyBuffer).readBigUInt64LE(0));
52563
+ if (lstMintSupply === 0) {
52564
+ multiplierByBank.set(bankAddr, new BigNumber3(1));
52565
+ continue;
52566
+ }
52567
+ const adjustedStake = Math.max(stakeLamports - LAMPORTS_PER_SOL, 0);
52568
+ const multiplier = new BigNumber3(adjustedStake).dividedBy(lstMintSupply);
52569
+ multiplierByBank.set(bankAddr, multiplier);
52570
+ }
52571
+ return multiplierByBank;
52572
+ }
52573
+ var SYSVAR_CLOCK_ID2 = new PublicKey("SysvarC1ock11111111111111111111111111111111");
52574
+ async function makeMintStakedLstIx(params) {
52575
+ const { amount, authority, stakeAccountPk, validator, connection } = params;
52576
+ const pool = findPoolAddress(validator);
52577
+ const lstMint = findPoolMintAddress(pool);
52578
+ const poolStakeAuth = findPoolStakeAuthorityAddress(pool);
52579
+ const lstAta = getAssociatedTokenAddressSync(lstMint, authority);
52580
+ const [lstAccInfo, stakeAccInfoParsed, rentExemptReserve] = await Promise.all([
52581
+ connection.getAccountInfo(lstAta),
52582
+ connection.getParsedAccountInfo(stakeAccountPk),
52583
+ connection.getMinimumBalanceForRentExemption(StakeProgram.space)
52584
+ ]);
52585
+ const stakeAccParsed = stakeAccInfoParsed?.value?.data;
52586
+ const amountLamports = Math.round(Number(amount) * LAMPORTS_PER_SOL);
52587
+ const stakeAccLamports = Number(stakeAccParsed?.parsed?.info?.stake?.delegation?.stake ?? 0);
52588
+ const isFullStake = amountLamports >= stakeAccLamports;
52589
+ const instructions2 = [];
52590
+ const signers = [];
52591
+ if (!lstAccInfo) {
52592
+ instructions2.push(
52593
+ createAssociatedTokenAccountInstruction(authority, lstAta, authority, lstMint)
52594
+ );
52595
+ }
52596
+ let targetStakePubkey;
52597
+ if (!isFullStake) {
52598
+ const splitStakeAccount = Keypair.generate();
52599
+ signers.push(splitStakeAccount);
52600
+ targetStakePubkey = splitStakeAccount.publicKey;
52601
+ instructions2.push(
52602
+ ...StakeProgram.split(
52603
+ {
52604
+ stakePubkey: stakeAccountPk,
52605
+ authorizedPubkey: authority,
52606
+ splitStakePubkey: splitStakeAccount.publicKey,
52607
+ lamports: amountLamports
52608
+ },
52609
+ rentExemptReserve
52610
+ ).instructions
52611
+ );
52612
+ } else {
52613
+ targetStakePubkey = stakeAccountPk;
52614
+ }
52615
+ const [authorizeStakerIx, authorizeWithdrawIx] = await Promise.all([
52616
+ StakeProgram.authorize({
52617
+ stakePubkey: targetStakePubkey,
52618
+ authorizedPubkey: authority,
52619
+ newAuthorizedPubkey: poolStakeAuth,
52620
+ stakeAuthorizationType: StakeAuthorizationLayout.Staker
52621
+ }).instructions,
52622
+ StakeProgram.authorize({
52623
+ stakePubkey: targetStakePubkey,
52624
+ authorizedPubkey: authority,
52625
+ newAuthorizedPubkey: poolStakeAuth,
52626
+ stakeAuthorizationType: StakeAuthorizationLayout.Withdrawer
52627
+ }).instructions
52628
+ ]);
52629
+ [authorizeStakerIx[0], authorizeWithdrawIx[0]].forEach((ix) => {
52630
+ if (ix) {
52631
+ ix.keys = ix.keys.map((key) => ({
52632
+ ...key,
52633
+ isWritable: key.pubkey.equals(SYSVAR_CLOCK_ID2) ? false : key.isWritable
52634
+ }));
52635
+ }
52636
+ });
52637
+ instructions2.push(...authorizeStakerIx, ...authorizeWithdrawIx);
52638
+ const depositStakeIx = await SinglePoolInstruction.depositStake(
52639
+ pool,
52640
+ targetStakePubkey,
52641
+ lstAta,
52642
+ authority
52643
+ );
52644
+ instructions2.push(depositStakeIx);
52645
+ return { instructions: instructions2, keys: signers };
52646
+ }
52647
+ async function makeMintStakedLstTx(params) {
52648
+ const { connection, luts, blockhash: providedBlockhash } = params;
52649
+ const { instructions: instructions2, keys } = await makeMintStakedLstIx(params);
52650
+ const blockhash = providedBlockhash ?? (await connection.getLatestBlockhash("confirmed")).blockhash;
52651
+ const message = new TransactionMessage({
52652
+ payerKey: params.authority,
52653
+ recentBlockhash: blockhash,
52654
+ instructions: instructions2
52655
+ }).compileToV0Message(luts);
52656
+ const tx = new VersionedTransaction(message);
52657
+ return addTransactionMetadata(tx, {
52658
+ signers: keys,
52659
+ addressLookupTables: luts,
52660
+ type: "DEPOSIT_STAKE" /* DEPOSIT_STAKE */
52661
+ });
52662
+ }
52663
+ async function makeRedeemStakedLstIx(params) {
52664
+ const { amount, authority, validator, connection } = params;
52665
+ const pool = findPoolAddress(validator);
52666
+ const lstMint = findPoolMintAddress(pool);
52667
+ const mintAuthority = findPoolMintAuthorityAddress(pool);
52668
+ const lstAta = getAssociatedTokenAddressSync(lstMint, authority);
52669
+ const rentExemption = await connection.getMinimumBalanceForRentExemption(
52670
+ StakeProgram.space
52671
+ );
52672
+ const stakeAmount = new BigNumber3(new BigNumber3(amount).toString());
52673
+ const instructions2 = [];
52674
+ const signers = [];
52675
+ const stakeAccount = Keypair.generate();
52676
+ signers.push(stakeAccount);
52677
+ instructions2.push(
52678
+ SystemProgram.createAccount({
52679
+ fromPubkey: authority,
52680
+ newAccountPubkey: stakeAccount.publicKey,
52681
+ lamports: rentExemption,
52682
+ space: StakeProgram.space,
52683
+ programId: StakeProgram.programId
52684
+ })
52685
+ );
52686
+ instructions2.push(
52687
+ createApproveInstruction(
52688
+ lstAta,
52689
+ mintAuthority,
52690
+ authority,
52691
+ BigInt(stakeAmount.multipliedBy(1e9).toFixed(0))
52692
+ )
52693
+ );
52694
+ const withdrawStakeIx = await SinglePoolInstruction.withdrawStake(
52695
+ pool,
52696
+ stakeAccount.publicKey,
52697
+ authority,
52698
+ lstAta,
52699
+ stakeAmount
52700
+ );
52701
+ instructions2.push(withdrawStakeIx);
52702
+ return { instructions: instructions2, keys: signers };
52703
+ }
52704
+ async function makeRedeemStakedLstTx(params) {
52705
+ const { connection, luts, blockhash: providedBlockhash } = params;
52706
+ const { instructions: instructions2, keys } = await makeRedeemStakedLstIx(params);
52707
+ const blockhash = providedBlockhash ?? (await connection.getLatestBlockhash("confirmed")).blockhash;
52708
+ const message = new TransactionMessage({
52709
+ payerKey: params.authority,
52710
+ recentBlockhash: blockhash,
52711
+ instructions: instructions2
52712
+ }).compileToV0Message(luts);
52713
+ const tx = new VersionedTransaction(message);
52714
+ return addTransactionMetadata(tx, {
52715
+ signers: keys,
52716
+ addressLookupTables: luts,
52717
+ type: "WITHDRAW_STAKE" /* WITHDRAW_STAKE */
52718
+ });
52719
+ }
52720
+ async function makeMergeStakeAccountsTx(params) {
52721
+ const {
52722
+ authority,
52723
+ sourceStakeAccount,
52724
+ destinationStakeAccount,
52725
+ connection,
52726
+ luts,
52727
+ blockhash: providedBlockhash
52728
+ } = params;
52729
+ const mergeIx = StakeProgram.merge({
52730
+ stakePubkey: destinationStakeAccount,
52731
+ sourceStakePubKey: sourceStakeAccount,
52732
+ authorizedPubkey: authority
52733
+ }).instructions;
52734
+ const blockhash = providedBlockhash ?? (await connection.getLatestBlockhash("confirmed")).blockhash;
52735
+ const message = new TransactionMessage({
52736
+ payerKey: authority,
52737
+ recentBlockhash: blockhash,
52738
+ instructions: mergeIx
52739
+ }).compileToV0Message(luts);
52740
+ const tx = new VersionedTransaction(message);
52741
+ return addTransactionMetadata(tx, {
52742
+ addressLookupTables: luts,
52743
+ type: "MERGE_STAKE_ACCOUNTS" /* MERGE_STAKE_ACCOUNTS */
52744
+ });
52745
+ }
51862
52746
  async function getKaminoMetadata(options) {
51863
52747
  const kaminoBanks = options.banks.filter((b) => b.config.assetTag === 3 /* KAMINO */);
51864
52748
  const DEFAULT_PUBKEY = PublicKey.default;
@@ -54556,7 +55440,6 @@ var Project0Client = class _Project0Client {
54556
55440
  assetShareMultiplierByBank.set(bank.address.toBase58(), new BigNumber3(1));
54557
55441
  break;
54558
55442
  case 2 /* STAKED */:
54559
- assetShareMultiplierByBank.set(bank.address.toBase58(), new BigNumber3(1));
54560
55443
  break;
54561
55444
  case 0 /* DEFAULT */:
54562
55445
  case 1 /* SOL */:
@@ -54565,6 +55448,11 @@ var Project0Client = class _Project0Client {
54565
55448
  break;
54566
55449
  }
54567
55450
  });
55451
+ const stakedMultipliers = await computeStakedBankMultipliers(
55452
+ banksArray.filter((b) => b.config.assetTag === 2 /* STAKED */),
55453
+ connection
55454
+ );
55455
+ stakedMultipliers.forEach((v, k) => assetShareMultiplierByBank.set(k, v));
54568
55456
  const emodePairs = getEmodePairs(banksArray);
54569
55457
  return new _Project0Client(
54570
55458
  program,
@@ -54606,6 +55494,6 @@ var EmodeSettings = class _EmodeSettings {
54606
55494
  }
54607
55495
  };
54608
55496
 
54609
- 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, MAX_WRITABLE_ACCOUNTS, 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, getSwapIxsForFlashloan, getTitanExactOutEstimate, getTitanSwapIxsForFlashloan, getTotalAccountKeys, getTotalAssetQuantity, getTotalLiabilityQuantity, getTxSize, 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, makePoolAddBankIx3 as makePoolAddBankIx, makePoolConfigureBankIx3 as makePoolConfigureBankIx, makePriorityFeeIx, makePriorityFeeMicroIx, makePulseHealthIx2 as makePulseHealthIx, 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 };
55497
+ 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 };
54610
55498
  //# sourceMappingURL=index.js.map
54611
55499
  //# sourceMappingURL=index.js.map