@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.cjs CHANGED
@@ -118,10 +118,9 @@ function getConfig(environment = "production", overrides) {
118
118
 
119
119
  // src/errors/transaction-building.errors.ts
120
120
  var TransactionBuildingErrorCode = /* @__PURE__ */ ((TransactionBuildingErrorCode2) => {
121
- TransactionBuildingErrorCode2["JUPITER_SWAP_SIZE_EXCEEDED_REPAY"] = "JUPITER_SWAP_SIZE_EXCEEDED_REPAY";
122
- TransactionBuildingErrorCode2["JUPITER_SWAP_SIZE_EXCEEDED_LOOP"] = "JUPITER_SWAP_SIZE_EXCEEDED_LOOP";
123
121
  TransactionBuildingErrorCode2["SWAP_SIZE_EXCEEDED_LOOP"] = "SWAP_SIZE_EXCEEDED_LOOP";
124
122
  TransactionBuildingErrorCode2["SWAP_SIZE_EXCEEDED_REPAY"] = "SWAP_SIZE_EXCEEDED_REPAY";
123
+ TransactionBuildingErrorCode2["SWAP_SIZE_EXCEEDED_POSITION_SWAP"] = "SWAP_SIZE_EXCEEDED_POSITION_SWAP";
125
124
  TransactionBuildingErrorCode2["ORACLE_CRANK_FAILED"] = "ORACLE_CRANK_FAILED";
126
125
  TransactionBuildingErrorCode2["KAMINO_RESERVE_NOT_FOUND"] = "KAMINO_RESERVE_NOT_FOUND";
127
126
  TransactionBuildingErrorCode2["DRIFT_STATE_NOT_FOUND"] = "DRIFT_STATE_NOT_FOUND";
@@ -142,23 +141,6 @@ var TransactionBuildingError = class _TransactionBuildingError extends Error {
142
141
  Error.captureStackTrace(this, _TransactionBuildingError);
143
142
  }
144
143
  }
145
- /**
146
- * Jupiter swap instruction size exceeds available transaction size
147
- */
148
- static jupiterSwapSizeExceededLoop(bytes, accountKeys) {
149
- return new _TransactionBuildingError(
150
- "JUPITER_SWAP_SIZE_EXCEEDED_LOOP" /* JUPITER_SWAP_SIZE_EXCEEDED_LOOP */,
151
- "Jupiter swap instruction size exceeds available transaction size",
152
- { bytes, accountKeys }
153
- );
154
- }
155
- static jupiterSwapSizeExceededRepay(bytes, accountKeys) {
156
- return new _TransactionBuildingError(
157
- "JUPITER_SWAP_SIZE_EXCEEDED_REPAY" /* JUPITER_SWAP_SIZE_EXCEEDED_REPAY */,
158
- "Jupiter swap instruction size exceeds available transaction size",
159
- { bytes, accountKeys }
160
- );
161
- }
162
144
  static swapSizeExceededLoop(bytes, accountKeys, provider) {
163
145
  return new _TransactionBuildingError(
164
146
  "SWAP_SIZE_EXCEEDED_LOOP" /* SWAP_SIZE_EXCEEDED_LOOP */,
@@ -173,6 +155,13 @@ var TransactionBuildingError = class _TransactionBuildingError extends Error {
173
155
  { bytes, accountKeys, provider }
174
156
  );
175
157
  }
158
+ static swapSizeExceededPositionSwap(bytes, accountKeys, provider) {
159
+ return new _TransactionBuildingError(
160
+ "SWAP_SIZE_EXCEEDED_POSITION_SWAP" /* SWAP_SIZE_EXCEEDED_POSITION_SWAP */,
161
+ `${provider ?? "Swap"} instruction size exceeds available transaction size`,
162
+ { bytes, accountKeys, provider }
163
+ );
164
+ }
176
165
  /**
177
166
  * Failed to crank oracles for one or more banks
178
167
  */
@@ -386,7 +375,6 @@ var MAX_U64 = BigInt("18446744073709551615").toString();
386
375
 
387
376
  // src/constants/transaction.consts.ts
388
377
  var MAX_TX_SIZE = 1232;
389
- var MAX_WRITABLE_ACCOUNTS = 64;
390
378
  var MAX_ACCOUNT_LOCKS = 64;
391
379
  var BUNDLE_TX_SIZE = 81;
392
380
  var PRIORITY_TX_SIZE = 44;
@@ -15164,9 +15152,48 @@ var MintLayout = bufferLayout.struct([
15164
15152
  bufferLayoutUtils.publicKey("freezeAuthority")
15165
15153
  ]);
15166
15154
  MintLayout.span;
15155
+ var approveInstructionData = bufferLayout.struct([
15156
+ bufferLayout.u8("instruction"),
15157
+ bufferLayoutUtils.u64("amount")
15158
+ ]);
15159
+ function createApproveInstruction(account, delegate, owner, amount, multiSigners = [], programId = TOKEN_PROGRAM_ID) {
15160
+ const keys = addSigners(
15161
+ [
15162
+ { pubkey: account, isSigner: false, isWritable: true },
15163
+ { pubkey: delegate, isSigner: false, isWritable: false }
15164
+ ],
15165
+ owner,
15166
+ multiSigners
15167
+ );
15168
+ const data = buffer.Buffer.alloc(approveInstructionData.span);
15169
+ approveInstructionData.encode(
15170
+ {
15171
+ instruction: 4 /* Approve */,
15172
+ amount: BigInt(amount)
15173
+ },
15174
+ data
15175
+ );
15176
+ return new web3_js.TransactionInstruction({ keys, programId, data });
15177
+ }
15167
15178
  bufferLayout.struct([
15168
15179
  bufferLayout.u8("instruction")
15169
15180
  ]);
15181
+ function createAssociatedTokenAccountInstruction(payer, associatedToken, owner, mint, programId = TOKEN_PROGRAM_ID, associatedTokenProgramId = ASSOCIATED_TOKEN_PROGRAM_ID) {
15182
+ const keys = [
15183
+ { pubkey: payer, isSigner: true, isWritable: true },
15184
+ { pubkey: associatedToken, isSigner: false, isWritable: true },
15185
+ { pubkey: owner, isSigner: false, isWritable: false },
15186
+ { pubkey: mint, isSigner: false, isWritable: false },
15187
+ { pubkey: web3_js.SystemProgram.programId, isSigner: false, isWritable: false },
15188
+ { pubkey: programId, isSigner: false, isWritable: false },
15189
+ { pubkey: web3_js.SYSVAR_RENT_PUBKEY, isSigner: false, isWritable: false }
15190
+ ];
15191
+ return new web3_js.TransactionInstruction({
15192
+ keys,
15193
+ programId: associatedTokenProgramId,
15194
+ data: buffer.Buffer.alloc(0)
15195
+ });
15196
+ }
15170
15197
  function createAssociatedTokenAccountIdempotentInstruction(payer, associatedToken, owner, mint, programId = TOKEN_PROGRAM_ID, associatedTokenProgramId = ASSOCIATED_TOKEN_PROGRAM_ID) {
15171
15198
  return buildAssociatedTokenAccountInstruction(
15172
15199
  payer,
@@ -43379,6 +43406,173 @@ new Fraction(new BN11__default.default(0));
43379
43406
  function roundNearest(decimal) {
43380
43407
  return decimal.toDecimalPlaces(0, Decimal3__default.default.ROUND_HALF_CEIL);
43381
43408
  }
43409
+ var SinglePoolInstruction = {
43410
+ initializePool: (voteAccount) => {
43411
+ const pool = findPoolAddress(voteAccount);
43412
+ const stake = findPoolStakeAddress(pool);
43413
+ const mint = findPoolMintAddress(pool);
43414
+ const stakeAuthority = findPoolStakeAuthorityAddress(pool);
43415
+ const mintAuthority = findPoolMintAuthorityAddress(pool);
43416
+ return createTransactionInstruction(
43417
+ SINGLE_POOL_PROGRAM_ID,
43418
+ [
43419
+ { pubkey: voteAccount, isSigner: false, isWritable: false },
43420
+ { pubkey: pool, isSigner: false, isWritable: true },
43421
+ { pubkey: stake, isSigner: false, isWritable: true },
43422
+ { pubkey: mint, isSigner: false, isWritable: true },
43423
+ { pubkey: stakeAuthority, isSigner: false, isWritable: false },
43424
+ { pubkey: mintAuthority, isSigner: false, isWritable: false },
43425
+ { pubkey: SYSVAR_RENT_ID, isSigner: false, isWritable: false },
43426
+ { pubkey: SYSVAR_CLOCK_ID, isSigner: false, isWritable: false },
43427
+ { pubkey: SYSVAR_STAKE_HISTORY_ID, isSigner: false, isWritable: false },
43428
+ { pubkey: web3_js.STAKE_CONFIG_ID, isSigner: false, isWritable: false },
43429
+ { pubkey: SYSTEM_PROGRAM_ID, isSigner: false, isWritable: false },
43430
+ { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
43431
+ { pubkey: STAKE_PROGRAM_ID, isSigner: false, isWritable: false }
43432
+ ],
43433
+ Buffer.from([0 /* InitializePool */])
43434
+ );
43435
+ },
43436
+ initializeOnRamp: (pool) => {
43437
+ const onRamp = findPoolOnRampAddress(pool);
43438
+ const stakeAuthority = findPoolStakeAuthorityAddress(pool);
43439
+ return createTransactionInstruction(
43440
+ SINGLE_POOL_PROGRAM_ID,
43441
+ [
43442
+ { pubkey: pool, isSigner: false, isWritable: false },
43443
+ { pubkey: onRamp, isSigner: false, isWritable: true },
43444
+ { pubkey: stakeAuthority, isSigner: false, isWritable: false },
43445
+ { pubkey: SYSVAR_RENT_ID, isSigner: false, isWritable: false },
43446
+ { pubkey: SYSTEM_PROGRAM_ID, isSigner: false, isWritable: false },
43447
+ { pubkey: STAKE_PROGRAM_ID, isSigner: false, isWritable: false }
43448
+ ],
43449
+ Buffer.from([6 /* InitializeOnRamp */])
43450
+ );
43451
+ },
43452
+ depositStake: async (pool, userStakeAccount, userTokenAccount, userLamportAccount) => {
43453
+ const stake = findPoolStakeAddress(pool);
43454
+ const onRamp = findPoolOnRampAddress(pool);
43455
+ const mint = findPoolMintAddress(pool);
43456
+ const stakeAuthority = findPoolStakeAuthorityAddress(pool);
43457
+ const mintAuthority = findPoolMintAuthorityAddress(pool);
43458
+ return createTransactionInstruction(
43459
+ SINGLE_POOL_PROGRAM_ID,
43460
+ [
43461
+ { pubkey: pool, isSigner: false, isWritable: false },
43462
+ { pubkey: stake, isSigner: false, isWritable: true },
43463
+ { pubkey: onRamp, isSigner: false, isWritable: false },
43464
+ { pubkey: mint, isSigner: false, isWritable: true },
43465
+ { pubkey: stakeAuthority, isSigner: false, isWritable: false },
43466
+ { pubkey: mintAuthority, isSigner: false, isWritable: false },
43467
+ { pubkey: userStakeAccount, isSigner: false, isWritable: true },
43468
+ { pubkey: userTokenAccount, isSigner: false, isWritable: true },
43469
+ { pubkey: userLamportAccount, isSigner: false, isWritable: true },
43470
+ { pubkey: SYSVAR_CLOCK_ID, isSigner: false, isWritable: false },
43471
+ { pubkey: SYSVAR_STAKE_HISTORY_ID, isSigner: false, isWritable: false },
43472
+ { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
43473
+ { pubkey: STAKE_PROGRAM_ID, isSigner: false, isWritable: false }
43474
+ ],
43475
+ Buffer.from([2 /* DepositStake */])
43476
+ );
43477
+ },
43478
+ withdrawStake: async (pool, userStakeAccount, userStakeAuthority, userTokenAccount, tokenAmount) => {
43479
+ const stake = findPoolStakeAddress(pool);
43480
+ const onRamp = findPoolOnRampAddress(pool);
43481
+ const mint = findPoolMintAddress(pool);
43482
+ const stakeAuthority = findPoolStakeAuthorityAddress(pool);
43483
+ const mintAuthority = findPoolMintAuthorityAddress(pool);
43484
+ const rawAmount = BigInt(tokenAmount.multipliedBy(1e9).toString());
43485
+ const data = Buffer.concat([
43486
+ Buffer.from([3 /* WithdrawStake */]),
43487
+ userStakeAuthority.toBuffer(),
43488
+ Buffer.from(new BN11.BN(rawAmount.toString()).toArray("le", 8))
43489
+ ]);
43490
+ return createTransactionInstruction(
43491
+ SINGLE_POOL_PROGRAM_ID,
43492
+ [
43493
+ { pubkey: pool, isSigner: false, isWritable: false },
43494
+ { pubkey: stake, isSigner: false, isWritable: true },
43495
+ { pubkey: onRamp, isSigner: false, isWritable: false },
43496
+ { pubkey: mint, isSigner: false, isWritable: true },
43497
+ { pubkey: stakeAuthority, isSigner: false, isWritable: false },
43498
+ { pubkey: mintAuthority, isSigner: false, isWritable: false },
43499
+ { pubkey: userStakeAccount, isSigner: false, isWritable: true },
43500
+ { pubkey: userTokenAccount, isSigner: false, isWritable: true },
43501
+ { pubkey: SYSVAR_CLOCK_ID, isSigner: false, isWritable: false },
43502
+ { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
43503
+ { pubkey: STAKE_PROGRAM_ID, isSigner: false, isWritable: false }
43504
+ ],
43505
+ data
43506
+ );
43507
+ },
43508
+ createTokenMetadata: async (pool, payer) => {
43509
+ const mint = findPoolMintAddress(pool);
43510
+ const [mintAuthority, mplAuthority, mplMetadata] = await Promise.all([
43511
+ findPoolMintAuthorityAddress(pool),
43512
+ findPoolMplAuthorityAddress(pool),
43513
+ findMplMetadataAddress(mint)
43514
+ ]);
43515
+ return createTransactionInstruction(
43516
+ SINGLE_POOL_PROGRAM_ID,
43517
+ [
43518
+ { pubkey: pool, isSigner: false, isWritable: false },
43519
+ { pubkey: mint, isSigner: false, isWritable: false },
43520
+ { pubkey: mintAuthority, isSigner: false, isWritable: false },
43521
+ { pubkey: mplAuthority, isSigner: false, isWritable: false },
43522
+ { pubkey: payer, isSigner: true, isWritable: true },
43523
+ { pubkey: mplMetadata, isSigner: false, isWritable: true },
43524
+ { pubkey: MPL_METADATA_PROGRAM_ID, isSigner: false, isWritable: false },
43525
+ { pubkey: SYSTEM_PROGRAM_ID, isSigner: false, isWritable: false }
43526
+ ],
43527
+ Buffer.from([4 /* CreateTokenMetadata */])
43528
+ );
43529
+ },
43530
+ updateTokenMetadata: async (voteAccount, authorizedWithdrawer, tokenName, tokenSymbol, tokenUri = "") => {
43531
+ if (tokenName.length > 32) {
43532
+ throw new Error("maximum token name length is 32 characters");
43533
+ }
43534
+ if (tokenSymbol.length > 10) {
43535
+ throw new Error("maximum token symbol length is 10 characters");
43536
+ }
43537
+ if (tokenUri.length > 200) {
43538
+ throw new Error("maximum token uri length is 200 characters");
43539
+ }
43540
+ const pool = findPoolAddress(voteAccount);
43541
+ const [mint, mplAuthority] = await Promise.all([
43542
+ findPoolMintAddress(pool),
43543
+ findPoolMplAuthorityAddress(pool)
43544
+ ]);
43545
+ const mplMetadata = await findMplMetadataAddress(mint);
43546
+ const data = Buffer.concat([
43547
+ Buffer.from([5 /* UpdateTokenMetadata */]),
43548
+ Buffer.from(new Uint32Array([tokenName.length]).buffer),
43549
+ Buffer.from(tokenName),
43550
+ Buffer.from(new Uint32Array([tokenSymbol.length]).buffer),
43551
+ Buffer.from(tokenSymbol),
43552
+ Buffer.from(new Uint32Array([tokenUri.length]).buffer),
43553
+ Buffer.from(tokenUri)
43554
+ ]);
43555
+ return createTransactionInstruction(
43556
+ SINGLE_POOL_PROGRAM_ID,
43557
+ [
43558
+ { pubkey: voteAccount, isSigner: false, isWritable: false },
43559
+ { pubkey: pool, isSigner: false, isWritable: false },
43560
+ { pubkey: mplAuthority, isSigner: false, isWritable: false },
43561
+ { pubkey: authorizedWithdrawer, isSigner: true, isWritable: false },
43562
+ { pubkey: mplMetadata, isSigner: false, isWritable: true },
43563
+ { pubkey: MPL_METADATA_PROGRAM_ID, isSigner: false, isWritable: false }
43564
+ ],
43565
+ data
43566
+ );
43567
+ }
43568
+ };
43569
+ var createTransactionInstruction = (programId, keys, data) => {
43570
+ return {
43571
+ programId,
43572
+ keys,
43573
+ data
43574
+ };
43575
+ };
43382
43576
  var findPda = (baseAddress, prefix, programId = SINGLE_POOL_PROGRAM_ID) => {
43383
43577
  const [pda] = web3_js.PublicKey.findProgramAddressSync(
43384
43578
  [Buffer.from(prefix), baseAddress.toBuffer()],
@@ -43389,7 +43583,17 @@ var findPda = (baseAddress, prefix, programId = SINGLE_POOL_PROGRAM_ID) => {
43389
43583
  var findPoolAddress = (voteAccountAddress) => findPda(voteAccountAddress, "pool");
43390
43584
  var findPoolMintAddress = (poolAddress) => findPda(poolAddress, "mint");
43391
43585
  var findPoolStakeAddress = (poolAddress) => findPda(poolAddress, "stake");
43586
+ var findPoolStakeAuthorityAddress = (poolAddress) => findPda(poolAddress, "stake_authority");
43587
+ var findPoolMintAuthorityAddress = (poolAddress) => findPda(poolAddress, "mint_authority");
43588
+ var findPoolMplAuthorityAddress = (poolAddress) => findPda(poolAddress, "mpl_authority");
43392
43589
  var findPoolOnRampAddress = (poolAddress) => findPda(poolAddress, "onramp");
43590
+ var findMplMetadataAddress = async (poolMintAddress) => {
43591
+ const [pda] = web3_js.PublicKey.findProgramAddressSync(
43592
+ [Buffer.from("metadata"), MPL_METADATA_PROGRAM_ID.toBuffer(), poolMintAddress.toBuffer()],
43593
+ MPL_METADATA_PROGRAM_ID
43594
+ );
43595
+ return pda;
43596
+ };
43393
43597
  BigInt(33);
43394
43598
  BigInt(200);
43395
43599
  BigInt(82);
@@ -44170,12 +44374,28 @@ var V1Client = class _V1Client {
44170
44374
  return new Promise((resolve, reject) => {
44171
44375
  const ws = new WebSocket__default.default(url, [SUBPROTOCOL]);
44172
44376
  ws.binaryType = "arraybuffer";
44173
- ws.on("open", () => {
44377
+ const onOpen = () => {
44378
+ ws.off("error", onError);
44379
+ ws.off("close", onClose);
44174
44380
  resolve(new _V1Client(ws));
44175
- });
44176
- ws.on("error", (err) => {
44381
+ };
44382
+ const onError = (err) => {
44383
+ ws.off("open", onOpen);
44384
+ ws.off("close", onClose);
44177
44385
  reject(err);
44178
- });
44386
+ };
44387
+ const onClose = (code, reason) => {
44388
+ ws.off("open", onOpen);
44389
+ ws.off("error", onError);
44390
+ reject(
44391
+ new Error(
44392
+ `WebSocket closed before open (code=${code}${reason.length ? `, reason=${reason.toString()}` : ""})`
44393
+ )
44394
+ );
44395
+ };
44396
+ ws.once("open", onOpen);
44397
+ ws.once("error", onError);
44398
+ ws.once("close", onClose);
44179
44399
  });
44180
44400
  }
44181
44401
  // --- Constructor ---
@@ -46176,10 +46396,11 @@ async function makeBorrowIx3({
46176
46396
  );
46177
46397
  borrowIxs.push(createAtaIdempotentIx);
46178
46398
  }
46399
+ const mandatoryBanks = [bank.address, ...opts.additionalHealthCheckBanks ?? []];
46179
46400
  const healthAccounts = computeHealthCheckAccounts(
46180
46401
  marginfiAccount.balances,
46181
46402
  bankMap,
46182
- [bank.address],
46403
+ mandatoryBanks,
46183
46404
  []
46184
46405
  );
46185
46406
  const remainingAccounts = [];
@@ -46714,81 +46935,116 @@ async function makeJuplendDepositTx(params) {
46714
46935
  });
46715
46936
  return solanaTx;
46716
46937
  }
46717
- async function makeRepayIx3({
46718
- program,
46719
- bank,
46720
- tokenProgram,
46721
- amount,
46722
- authority,
46723
- accountAddress,
46724
- repayAll = false,
46725
- isSync = false,
46726
- opts = {}
46727
- }) {
46728
- const wrapAndUnwrapSol = opts.wrapAndUnwrapSol ?? true;
46729
- const wSolBalanceUi = opts.wSolBalanceUi ?? 0;
46730
- const repayIxs = [];
46731
- const userAta = getAssociatedTokenAddressSync(bank.mint, authority, true, tokenProgram);
46732
- const remainingAccounts = tokenProgram.equals(TOKEN_2022_PROGRAM_ID) ? [{ pubkey: bank.mint, isSigner: false, isWritable: false }] : [];
46733
- if (bank.mint.equals(NATIVE_MINT) && wrapAndUnwrapSol) {
46734
- repayIxs.push(...makeWrapSolIxs(authority, new BigNumber3.BigNumber(amount).minus(wSolBalanceUi)));
46735
- }
46736
- const repayIx = !isSync || !opts.overrideInferAccounts?.group ? await instructions_default.makeRepayIx(
46938
+ async function makeBeginFlashLoanIx3(program, marginfiAccountPk, endIndex, authority, isSync) {
46939
+ const ix = isSync && authority ? sync_instructions_default.makeBeginFlashLoanIx(
46940
+ program.programId,
46941
+ {
46942
+ marginfiAccount: marginfiAccountPk,
46943
+ authority
46944
+ },
46945
+ { endIndex: new BN11__default.default(endIndex) }
46946
+ ) : await instructions_default.makeBeginFlashLoanIx(
46737
46947
  program,
46738
46948
  {
46739
- marginfiAccount: accountAddress,
46740
- signerTokenAccount: userAta,
46741
- bank: bank.address,
46742
- tokenProgram,
46743
- authority: opts.overrideInferAccounts?.authority ?? authority,
46744
- group: opts.overrideInferAccounts?.group,
46745
- liquidityVault: opts.overrideInferAccounts?.liquidityVault
46949
+ marginfiAccount: marginfiAccountPk,
46950
+ authority
46746
46951
  },
46747
- { amount: uiToNative(amount, bank.mintDecimals), repayAll },
46748
- remainingAccounts
46749
- ) : sync_instructions_default.makeRepayIx(
46952
+ { endIndex: new BN11__default.default(endIndex) }
46953
+ );
46954
+ return { instructions: [ix], keys: [] };
46955
+ }
46956
+ async function makeEndFlashLoanIx3(program, marginfiAccountPk, projectedActiveBanks, authority, isSync) {
46957
+ const remainingAccounts = computeHealthAccountMetas(projectedActiveBanks);
46958
+ const ix = isSync && authority ? sync_instructions_default.makeEndFlashLoanIx(
46750
46959
  program.programId,
46751
46960
  {
46752
- marginfiAccount: accountAddress,
46753
- signerTokenAccount: userAta,
46754
- bank: bank.address,
46755
- tokenProgram,
46756
- authority: opts.overrideInferAccounts?.authority ?? authority,
46757
- group: opts.overrideInferAccounts?.group
46961
+ marginfiAccount: marginfiAccountPk,
46962
+ authority
46758
46963
  },
46759
- { amount: uiToNative(amount, bank.mintDecimals), repayAll },
46760
- remainingAccounts
46964
+ remainingAccounts.map((account) => ({
46965
+ pubkey: account,
46966
+ isSigner: false,
46967
+ isWritable: false
46968
+ }))
46969
+ ) : await instructions_default.makeEndFlashLoanIx(
46970
+ program,
46971
+ {
46972
+ marginfiAccount: marginfiAccountPk,
46973
+ authority
46974
+ },
46975
+ remainingAccounts.map((account) => ({
46976
+ pubkey: account,
46977
+ isSigner: false,
46978
+ isWritable: false
46979
+ }))
46761
46980
  );
46762
- repayIxs.push(repayIx);
46763
- return {
46764
- instructions: repayIxs,
46765
- keys: []
46766
- };
46981
+ return { instructions: [ix], keys: [] };
46767
46982
  }
46768
- async function makeRepayTx(params) {
46769
- const { luts, ...depositIxParams } = params;
46770
- const ixs = await makeRepayIx3(depositIxParams);
46771
- const tx = new web3_js.Transaction().add(...ixs.instructions);
46772
- tx.feePayer = params.authority;
46773
- const solanaTx = addTransactionMetadata(tx, {
46774
- type: "REPAY" /* REPAY */,
46775
- signers: ixs.keys,
46776
- addressLookupTables: luts
46983
+ async function makeFlashLoanTx({
46984
+ program,
46985
+ marginfiAccount,
46986
+ ixs,
46987
+ bankMap,
46988
+ blockhash,
46989
+ addressLookupTableAccounts,
46990
+ signers,
46991
+ isSync
46992
+ }) {
46993
+ const endIndex = ixs.length + 1;
46994
+ const projectedActiveBanksKeys = computeProjectedActiveBanksNoCpi(
46995
+ marginfiAccount.balances,
46996
+ ixs,
46997
+ program
46998
+ );
46999
+ const projectedActiveBanks = projectedActiveBanksKeys.map((account) => {
47000
+ const b = bankMap.get(account.toBase58());
47001
+ if (!b) throw Error(`Bank ${account.toBase58()} not found, in makeFlashLoanTx function`);
47002
+ return b;
46777
47003
  });
46778
- return solanaTx;
47004
+ const beginFlashLoanIx = await makeBeginFlashLoanIx3(
47005
+ program,
47006
+ marginfiAccount.address,
47007
+ endIndex,
47008
+ marginfiAccount.authority,
47009
+ isSync
47010
+ );
47011
+ const endFlashLoanIx = await makeEndFlashLoanIx3(
47012
+ program,
47013
+ marginfiAccount.address,
47014
+ projectedActiveBanks,
47015
+ marginfiAccount.authority,
47016
+ isSync
47017
+ );
47018
+ const message = new web3_js.TransactionMessage({
47019
+ payerKey: marginfiAccount.authority,
47020
+ recentBlockhash: blockhash,
47021
+ instructions: [...beginFlashLoanIx.instructions, ...ixs, ...endFlashLoanIx.instructions]
47022
+ }).compileToV0Message(addressLookupTableAccounts);
47023
+ const tx = addTransactionMetadata(new web3_js.VersionedTransaction(message), {
47024
+ addressLookupTables: addressLookupTableAccounts,
47025
+ type: "FLASHLOAN" /* FLASHLOAN */,
47026
+ signers
47027
+ });
47028
+ if (signers) {
47029
+ tx.sign(signers);
47030
+ }
47031
+ return tx;
46779
47032
  }
46780
- async function makeRepayWithCollatTx(params) {
47033
+
47034
+ // src/services/account/actions/loop.ts
47035
+ async function makeLoopTx(params) {
46781
47036
  const {
46782
47037
  program,
46783
47038
  marginfiAccount,
46784
47039
  bankMap,
46785
- withdrawOpts,
46786
- repayOpts,
47040
+ depositOpts,
47041
+ borrowOpts,
46787
47042
  bankMetadataMap,
46788
47043
  addressLookupTableAccounts,
46789
47044
  connection,
46790
47045
  oraclePrices,
46791
- crossbarUrl
47046
+ crossbarUrl,
47047
+ additionalIxs = []
46792
47048
  } = params;
46793
47049
  const blockhash = (await connection.getLatestBlockhash("confirmed")).blockhash;
46794
47050
  const setupIxs = await makeSetupIx({
@@ -46796,34 +47052,34 @@ async function makeRepayWithCollatTx(params) {
46796
47052
  authority: marginfiAccount.authority,
46797
47053
  tokens: [
46798
47054
  {
46799
- mint: repayOpts.repayBank.mint,
46800
- tokenProgram: repayOpts.tokenProgram
47055
+ mint: borrowOpts.borrowBank.mint,
47056
+ tokenProgram: borrowOpts.tokenProgram
46801
47057
  },
46802
47058
  {
46803
- mint: withdrawOpts.withdrawBank.mint,
46804
- tokenProgram: withdrawOpts.tokenProgram
47059
+ mint: depositOpts.depositBank.mint,
47060
+ tokenProgram: depositOpts.tokenProgram
46805
47061
  }
46806
47062
  ]
46807
47063
  });
46808
- const updateJuplendMarketIxs = makeUpdateJupLendRateIxs(
46809
- marginfiAccount,
46810
- bankMap,
46811
- [withdrawOpts.withdrawBank.address],
46812
- bankMetadataMap
47064
+ const updateJupLendRateIxs = makeUpdateJupLendRateIxs(
47065
+ params.marginfiAccount,
47066
+ params.bankMap,
47067
+ [depositOpts.depositBank.address],
47068
+ params.bankMetadataMap
46813
47069
  );
46814
47070
  const updateDriftMarketIxs = makeUpdateDriftMarketIxs(
46815
- marginfiAccount,
46816
- bankMap,
46817
- [withdrawOpts.withdrawBank.address],
46818
- bankMetadataMap
47071
+ params.marginfiAccount,
47072
+ params.bankMap,
47073
+ [depositOpts.depositBank.address],
47074
+ params.bankMetadataMap
46819
47075
  );
46820
47076
  const kaminoRefreshIxs = makeRefreshKaminoBanksIxs(
46821
47077
  marginfiAccount,
46822
47078
  bankMap,
46823
- [withdrawOpts.withdrawBank.address, repayOpts.repayBank.address],
47079
+ [borrowOpts.borrowBank.address, depositOpts.depositBank.address],
46824
47080
  bankMetadataMap
46825
47081
  );
46826
- const { flashloanTx, setupInstructions, swapQuote, amountToRepay, withdrawIxs, repayIxs } = await buildRepayWithCollatFlashloanTx({
47082
+ const { flashloanTx, setupInstructions, swapQuote, amountToDeposit, depositIxs, borrowIxs } = await buildLoopFlashloanTx({
46827
47083
  ...params,
46828
47084
  blockhash
46829
47085
  });
@@ -46833,7 +47089,7 @@ async function makeRepayWithCollatTx(params) {
46833
47089
  }
46834
47090
  if (ix.programId.equals(ASSOCIATED_TOKEN_PROGRAM_ID)) {
46835
47091
  const mintKey = ix.keys[3]?.pubkey;
46836
- if (mintKey?.equals(withdrawOpts.withdrawBank.mint) || mintKey?.equals(repayOpts.repayBank.mint)) {
47092
+ if (mintKey?.equals(depositOpts.depositBank.mint) || mintKey?.equals(borrowOpts.borrowBank.mint)) {
46837
47093
  return false;
46838
47094
  }
46839
47095
  }
@@ -46845,18 +47101,24 @@ async function makeRepayWithCollatTx(params) {
46845
47101
  bankMap,
46846
47102
  oraclePrices,
46847
47103
  assetShareValueMultiplierByBank: params.assetShareValueMultiplierByBank,
46848
- instructions: [...withdrawIxs.instructions, ...repayIxs.instructions],
47104
+ instructions: [...borrowIxs.instructions, ...depositIxs.instructions],
46849
47105
  program,
46850
47106
  connection,
46851
47107
  crossbarUrl
46852
47108
  });
46853
47109
  let additionalTxs = [];
46854
- if (setupIxs.length > 0 || kaminoRefreshIxs.instructions.length > 0 || updateDriftMarketIxs.instructions.length > 0 || updateJuplendMarketIxs.instructions.length > 0) {
47110
+ if (depositOpts.depositBank.mint.equals(NATIVE_MINT) && depositOpts.inputDepositAmount) {
47111
+ setupIxs.push(
47112
+ ...makeWrapSolIxs(marginfiAccount.authority, new BigNumber3.BigNumber(depositOpts.inputDepositAmount))
47113
+ );
47114
+ }
47115
+ if (setupIxs.length > 0 || additionalIxs.length > 0 || kaminoRefreshIxs.instructions.length > 0 || updateDriftMarketIxs.instructions.length > 0 || updateJupLendRateIxs.instructions.length > 0) {
46855
47116
  const ixs = [
47117
+ ...additionalIxs,
46856
47118
  ...setupIxs,
46857
47119
  ...kaminoRefreshIxs.instructions,
46858
47120
  ...updateDriftMarketIxs.instructions,
46859
- ...updateJuplendMarketIxs.instructions
47121
+ ...updateJupLendRateIxs.instructions
46860
47122
  ];
46861
47123
  const txs = splitInstructionsToFitTransactions([], ixs, {
46862
47124
  blockhash,
@@ -46886,16 +47148,19 @@ async function makeRepayWithCollatTx(params) {
46886
47148
  );
46887
47149
  }
46888
47150
  const transactions = [...additionalTxs, flashloanTx];
46889
- return { transactions, swapQuote, amountToRepay };
47151
+ return {
47152
+ transactions,
47153
+ actionTxIndex: transactions.length - 1,
47154
+ quoteResponse: swapQuote
47155
+ };
46890
47156
  }
46891
- async function buildRepayWithCollatFlashloanTx({
47157
+ async function buildLoopFlashloanTx({
46892
47158
  program,
46893
47159
  marginfiAccount,
46894
47160
  bankMap,
46895
- withdrawOpts,
46896
- repayOpts,
47161
+ borrowOpts,
47162
+ depositOpts,
46897
47163
  bankMetadataMap,
46898
- assetShareValueMultiplierByBank,
46899
47164
  addressLookupTableAccounts,
46900
47165
  connection,
46901
47166
  swapOpts,
@@ -46906,20 +47171,20 @@ async function buildRepayWithCollatFlashloanTx({
46906
47171
  web3_js.ComputeBudgetProgram.setComputeUnitLimit({ units: 12e5 }),
46907
47172
  web3_js.ComputeBudgetProgram.setComputeUnitPrice({ microLamports: 1 })
46908
47173
  ];
46909
- let amountToRepay;
47174
+ let amountToDeposit;
46910
47175
  let swapInstructions = [];
46911
47176
  let setupInstructions = [];
46912
47177
  let swapLookupTables = [];
46913
47178
  let swapQuote;
46914
47179
  let sizeConstraintUsed = 0;
46915
- if (repayOpts.repayBank.mint.equals(withdrawOpts.withdrawBank.mint)) {
46916
- amountToRepay = withdrawOpts.withdrawAmount;
47180
+ if (depositOpts.depositBank.mint.equals(borrowOpts.borrowBank.mint)) {
47181
+ amountToDeposit = borrowOpts.borrowAmount + (depositOpts.loopMode === "DEPOSIT" ? depositOpts.inputDepositAmount : 0);
46917
47182
  } else {
46918
47183
  const destinationTokenAccount = getAssociatedTokenAddressSync(
46919
- new web3_js.PublicKey(repayOpts.repayBank.mint),
47184
+ new web3_js.PublicKey(depositOpts.depositBank.mint),
46920
47185
  marginfiAccount.authority,
46921
47186
  true,
46922
- repayOpts.tokenProgram.equals(TOKEN_2022_PROGRAM_ID) ? TOKEN_2022_PROGRAM_ID : void 0
47187
+ depositOpts.tokenProgram.equals(TOKEN_2022_PROGRAM_ID) ? TOKEN_2022_PROGRAM_ID : void 0
46923
47188
  );
46924
47189
  const swapConstraints = await computeFlashloanSwapConstraints({
46925
47190
  program,
@@ -46928,78 +47193,76 @@ async function buildRepayWithCollatFlashloanTx({
46928
47193
  bankMetadataMap,
46929
47194
  addressLookupTableAccounts: addressLookupTableAccounts ?? [],
46930
47195
  primaryIx: {
46931
- type: "withdraw",
46932
- bank: withdrawOpts.withdrawBank,
46933
- tokenProgram: withdrawOpts.tokenProgram
47196
+ type: "borrow",
47197
+ bank: borrowOpts.borrowBank,
47198
+ tokenProgram: borrowOpts.tokenProgram
46934
47199
  },
46935
47200
  secondaryIx: {
46936
- type: "repay",
46937
- bank: repayOpts.repayBank,
46938
- tokenProgram: repayOpts.tokenProgram
47201
+ type: "deposit",
47202
+ bank: depositOpts.depositBank,
47203
+ tokenProgram: depositOpts.tokenProgram
46939
47204
  },
46940
47205
  overrideInferAccounts
46941
47206
  });
46942
47207
  const swapResponse = await getSwapIxsForFlashloan({
46943
- inputMint: withdrawOpts.withdrawBank.mint.toBase58(),
46944
- outputMint: repayOpts.repayBank.mint.toBase58(),
46945
- amount: uiToNative(
46946
- withdrawOpts.withdrawAmount,
46947
- withdrawOpts.withdrawBank.mintDecimals
46948
- ).toNumber(),
47208
+ inputMint: borrowOpts.borrowBank.mint.toBase58(),
47209
+ outputMint: depositOpts.depositBank.mint.toBase58(),
47210
+ amount: uiToNative(borrowOpts.borrowAmount, borrowOpts.borrowBank.mintDecimals).toNumber(),
46949
47211
  swapMode: "ExactIn",
46950
47212
  authority: marginfiAccount.authority,
46951
47213
  connection,
46952
47214
  destinationTokenAccount,
46953
47215
  swapOpts,
46954
47216
  sizeConstraint: swapConstraints.sizeConstraint,
46955
- maxSwapAccounts: swapConstraints.maxSwapWritableAccounts,
46956
47217
  maxSwapTotalAccounts: swapConstraints.maxSwapTotalAccounts
46957
47218
  });
46958
47219
  sizeConstraintUsed = swapConstraints.sizeConstraint;
46959
- const { quoteResponse } = swapResponse;
46960
- const outAmount = nativeToUi(quoteResponse.outAmount, repayOpts.repayBank.mintDecimals);
46961
47220
  const outAmountThreshold = nativeToUi(
46962
- quoteResponse.otherAmountThreshold,
46963
- repayOpts.repayBank.mintDecimals
47221
+ swapResponse.quoteResponse.otherAmountThreshold,
47222
+ depositOpts.depositBank.mintDecimals
46964
47223
  );
46965
- amountToRepay = outAmount > repayOpts.totalPositionAmount ? repayOpts.totalPositionAmount : outAmountThreshold;
47224
+ amountToDeposit = outAmountThreshold + (depositOpts.loopMode === "DEPOSIT" ? depositOpts.inputDepositAmount : 0);
46966
47225
  swapInstructions = swapResponse.swapInstructions;
47226
+ setupInstructions = swapResponse.setupInstructions;
46967
47227
  swapLookupTables = swapResponse.addressLookupTableAddresses;
46968
- swapQuote = quoteResponse;
47228
+ swapQuote = swapResponse.quoteResponse;
46969
47229
  }
46970
- let withdrawIxs;
46971
- switch (withdrawOpts.withdrawBank.config.assetTag) {
47230
+ const borrowIxs = await makeBorrowIx3({
47231
+ program,
47232
+ bank: borrowOpts.borrowBank,
47233
+ bankMap,
47234
+ tokenProgram: borrowOpts.tokenProgram,
47235
+ amount: borrowOpts.borrowAmount,
47236
+ marginfiAccount,
47237
+ authority: marginfiAccount.authority,
47238
+ isSync: false,
47239
+ opts: {
47240
+ createAtas: false,
47241
+ wrapAndUnwrapSol: false,
47242
+ overrideInferAccounts
47243
+ }
47244
+ });
47245
+ let depositIxs;
47246
+ switch (depositOpts.depositBank.config.assetTag) {
46972
47247
  case 3 /* KAMINO */: {
46973
- const reserve = bankMetadataMap[withdrawOpts.withdrawBank.address.toBase58()]?.kaminoStates?.reserveState;
47248
+ const reserve = bankMetadataMap[depositOpts.depositBank.address.toBase58()]?.kaminoStates?.reserveState;
46974
47249
  if (!reserve) {
46975
47250
  throw TransactionBuildingError.kaminoReserveNotFound(
46976
- withdrawOpts.withdrawBank.address.toBase58(),
46977
- withdrawOpts.withdrawBank.mint.toBase58(),
46978
- withdrawOpts.withdrawBank.tokenSymbol
47251
+ depositOpts.depositBank.address.toBase58(),
47252
+ depositOpts.depositBank.mint.toBase58(),
47253
+ depositOpts.depositBank.tokenSymbol
46979
47254
  );
46980
47255
  }
46981
- const multiplier = assetShareValueMultiplierByBank.get(withdrawOpts.withdrawBank.address.toBase58()) ?? new BigNumber3.BigNumber(1);
46982
- const adjustedAmount = new BigNumber3.BigNumber(withdrawOpts.withdrawAmount).div(multiplier).times(1.0001).toNumber();
46983
- withdrawIxs = await makeKaminoWithdrawIx3({
47256
+ depositIxs = await makeKaminoDepositIx3({
46984
47257
  program,
46985
- bank: withdrawOpts.withdrawBank,
46986
- bankMap,
46987
- tokenProgram: withdrawOpts.tokenProgram,
46988
- cTokenAmount: adjustedAmount,
46989
- marginfiAccount,
47258
+ bank: depositOpts.depositBank,
47259
+ tokenProgram: depositOpts.tokenProgram,
47260
+ amount: amountToDeposit,
47261
+ accountAddress: marginfiAccount.address,
46990
47262
  authority: marginfiAccount.authority,
47263
+ group: marginfiAccount.group,
46991
47264
  reserve,
46992
- withdrawAll: isWholePosition(
46993
- {
46994
- amount: withdrawOpts.totalPositionAmount,
46995
- isLending: true
46996
- },
46997
- withdrawOpts.withdrawAmount,
46998
- withdrawOpts.withdrawBank.mintDecimals
46999
- ),
47000
- isSync: false,
47001
47265
  opts: {
47002
- createAtas: false,
47003
47266
  wrapAndUnwrapSol: false,
47004
47267
  overrideInferAccounts
47005
47268
  }
@@ -47007,35 +47270,27 @@ async function buildRepayWithCollatFlashloanTx({
47007
47270
  break;
47008
47271
  }
47009
47272
  case 4 /* DRIFT */: {
47010
- const driftState = bankMetadataMap[withdrawOpts.withdrawBank.address.toBase58()]?.driftStates;
47273
+ const driftState = bankMetadataMap[depositOpts.depositBank.address.toBase58()]?.driftStates;
47011
47274
  if (!driftState) {
47012
47275
  throw TransactionBuildingError.driftStateNotFound(
47013
- withdrawOpts.withdrawBank.address.toBase58(),
47014
- withdrawOpts.withdrawBank.mint.toBase58(),
47015
- withdrawOpts.withdrawBank.tokenSymbol
47276
+ depositOpts.depositBank.address.toBase58(),
47277
+ depositOpts.depositBank.mint.toBase58(),
47278
+ depositOpts.depositBank.tokenSymbol
47016
47279
  );
47017
47280
  }
47018
- withdrawIxs = await makeDriftWithdrawIx3({
47281
+ const driftMarketIndex = driftState.spotMarketState.marketIndex;
47282
+ const driftOracle = driftState.spotMarketState.oracle;
47283
+ depositIxs = await makeDriftDepositIx3({
47019
47284
  program,
47020
- bank: withdrawOpts.withdrawBank,
47021
- bankMap,
47022
- tokenProgram: withdrawOpts.tokenProgram,
47023
- amount: withdrawOpts.withdrawAmount,
47024
- marginfiAccount,
47285
+ bank: depositOpts.depositBank,
47286
+ tokenProgram: depositOpts.tokenProgram,
47287
+ amount: amountToDeposit,
47288
+ accountAddress: marginfiAccount.address,
47025
47289
  authority: marginfiAccount.authority,
47026
- driftSpotMarket: driftState.spotMarketState,
47027
- userRewards: driftState.userRewards,
47028
- withdrawAll: isWholePosition(
47029
- {
47030
- amount: withdrawOpts.totalPositionAmount,
47031
- isLending: true
47032
- },
47033
- withdrawOpts.withdrawAmount,
47034
- withdrawOpts.withdrawBank.mintDecimals
47035
- ),
47036
- isSync: false,
47290
+ group: marginfiAccount.group,
47291
+ driftMarketIndex,
47292
+ driftOracle,
47037
47293
  opts: {
47038
- createAtas: false,
47039
47294
  wrapAndUnwrapSol: false,
47040
47295
  overrideInferAccounts
47041
47296
  }
@@ -47043,686 +47298,156 @@ async function buildRepayWithCollatFlashloanTx({
47043
47298
  break;
47044
47299
  }
47045
47300
  case 6 /* JUPLEND */: {
47046
- const jupLendState = bankMetadataMap[withdrawOpts.withdrawBank.address.toBase58()]?.jupLendStates;
47047
- if (!jupLendState) {
47048
- throw TransactionBuildingError.jupLendStateNotFound(
47049
- withdrawOpts.withdrawBank.address.toBase58(),
47050
- withdrawOpts.withdrawBank.mint.toBase58(),
47051
- withdrawOpts.withdrawBank.tokenSymbol
47052
- );
47053
- }
47054
- withdrawIxs = await makeJuplendWithdrawIx2({
47055
- program,
47056
- bank: withdrawOpts.withdrawBank,
47057
- bankMap,
47058
- tokenProgram: withdrawOpts.tokenProgram,
47059
- amount: withdrawOpts.withdrawAmount,
47060
- marginfiAccount,
47061
- authority: marginfiAccount.authority,
47062
- jupLendingState: jupLendState.jupLendingState,
47063
- withdrawAll: isWholePosition(
47064
- {
47065
- amount: withdrawOpts.totalPositionAmount,
47066
- isLending: true
47067
- },
47068
- withdrawOpts.withdrawAmount,
47069
- withdrawOpts.withdrawBank.mintDecimals
47070
- ),
47071
- opts: {
47072
- createAtas: false,
47073
- wrapAndUnwrapSol: false,
47074
- overrideInferAccounts
47075
- }
47076
- });
47077
- break;
47078
- }
47079
- default: {
47080
- withdrawIxs = await makeWithdrawIx3({
47301
+ depositIxs = await makeJuplendDepositIx2({
47081
47302
  program,
47082
- bank: withdrawOpts.withdrawBank,
47083
- bankMap,
47084
- tokenProgram: withdrawOpts.tokenProgram,
47085
- amount: withdrawOpts.withdrawAmount,
47086
- marginfiAccount,
47303
+ bank: depositOpts.depositBank,
47304
+ tokenProgram: depositOpts.tokenProgram,
47305
+ amount: amountToDeposit,
47306
+ accountAddress: marginfiAccount.address,
47087
47307
  authority: marginfiAccount.authority,
47088
- withdrawAll: isWholePosition(
47089
- {
47090
- amount: withdrawOpts.totalPositionAmount,
47091
- isLending: true
47092
- },
47093
- withdrawOpts.withdrawAmount,
47094
- withdrawOpts.withdrawBank.mintDecimals
47095
- ),
47096
- isSync: false,
47308
+ group: marginfiAccount.group,
47097
47309
  opts: {
47098
- createAtas: false,
47099
47310
  wrapAndUnwrapSol: false,
47100
47311
  overrideInferAccounts
47101
47312
  }
47102
47313
  });
47103
47314
  break;
47104
47315
  }
47105
- }
47106
- const repayIxs = await makeRepayIx3({
47107
- program,
47108
- bank: repayOpts.repayBank,
47109
- tokenProgram: repayOpts.tokenProgram,
47110
- amount: amountToRepay,
47111
- accountAddress: marginfiAccount.address,
47112
- authority: marginfiAccount.authority,
47113
- repayAll: isWholePosition(
47114
- {
47115
- amount: repayOpts.totalPositionAmount,
47116
- isLending: true
47117
- },
47118
- amountToRepay,
47119
- repayOpts.repayBank.mintDecimals
47120
- ),
47121
- isSync: false,
47122
- opts: {
47123
- wrapAndUnwrapSol: false,
47124
- overrideInferAccounts
47125
- }
47126
- });
47127
- const luts = [...addressLookupTableAccounts ?? [], ...swapLookupTables];
47128
- const allNonFlIxs = [
47129
- ...cuRequestIxs,
47130
- ...withdrawIxs.instructions,
47131
- ...swapInstructions,
47132
- ...repayIxs.instructions
47133
- ];
47134
- if (swapInstructions.length > 0) {
47135
- compileFlashloanPrecheck({
47136
- allIxs: allNonFlIxs,
47137
- payer: marginfiAccount.authority,
47138
- luts,
47139
- sizeConstraint: sizeConstraintUsed,
47140
- swapIxCount: swapInstructions.length,
47141
- swapLutCount: swapLookupTables.length
47142
- });
47143
- }
47144
- const flashloanTx = await makeFlashLoanTx({
47145
- program,
47146
- marginfiAccount,
47147
- bankMap,
47148
- addressLookupTableAccounts: luts,
47149
- blockhash,
47150
- ixs: allNonFlIxs,
47151
- isSync: true
47152
- });
47153
- const txSize = getTxSize(flashloanTx);
47154
- const writableKeys = getWritableAccountKeys(flashloanTx);
47155
- const totalKeys = getTotalAccountKeys(flashloanTx);
47156
- if (txSize > MAX_TX_SIZE || writableKeys > MAX_WRITABLE_ACCOUNTS || totalKeys > MAX_ACCOUNT_LOCKS) {
47157
- throw TransactionBuildingError.swapSizeExceededRepay(
47158
- txSize,
47159
- writableKeys,
47160
- swapOpts.swapConfig?.provider
47161
- );
47162
- }
47163
- return {
47164
- flashloanTx,
47165
- setupInstructions,
47166
- swapQuote,
47167
- withdrawIxs,
47168
- repayIxs,
47169
- amountToRepay
47170
- };
47171
- }
47172
-
47173
- // src/services/account/utils/flashloan-size.utils.ts
47174
- var SWAP_MERGE_OVERHEAD = 150;
47175
- var FL_IX_OVERHEAD = 52;
47176
- function compactU16Size(n) {
47177
- return n < 128 ? 1 : n < 16384 ? 2 : 3;
47178
- }
47179
- function computeV0TxSize(ixs, payerKey, luts) {
47180
- const keyMap = /* @__PURE__ */ new Map();
47181
- const payerStr = payerKey.toBase58();
47182
- keyMap.set(payerStr, { isSigner: true, isWritable: true });
47183
- const programIds = /* @__PURE__ */ new Set();
47184
- for (const ix of ixs) {
47185
- const progStr = ix.programId.toBase58();
47186
- programIds.add(progStr);
47187
- if (!keyMap.has(progStr)) {
47188
- keyMap.set(progStr, { isSigner: false, isWritable: false });
47189
- }
47190
- for (const meta of ix.keys) {
47191
- const keyStr = meta.pubkey.toBase58();
47192
- const existing = keyMap.get(keyStr);
47193
- if (existing) {
47194
- existing.isSigner = existing.isSigner || meta.isSigner;
47195
- existing.isWritable = existing.isWritable || meta.isWritable;
47196
- } else {
47197
- keyMap.set(keyStr, { isSigner: meta.isSigner, isWritable: meta.isWritable });
47198
- }
47199
- }
47200
- }
47201
- const lutLookup = /* @__PURE__ */ new Map();
47202
- for (let li = 0; li < luts.length; li++) {
47203
- const addresses = luts[li].state.addresses;
47204
- for (let ai = 0; ai < addresses.length; ai++) {
47205
- const addrStr = addresses[ai].toBase58();
47206
- if (!lutLookup.has(addrStr)) {
47207
- lutLookup.set(addrStr, { lutIdx: li, addrIdx: ai });
47208
- }
47209
- }
47210
- }
47211
- let numStaticKeys = 0;
47212
- let numWritableStaticKeys = 0;
47213
- const lutWritableIdxs = luts.map(() => /* @__PURE__ */ new Set());
47214
- const lutReadonlyIdxs = luts.map(() => /* @__PURE__ */ new Set());
47215
- for (const [keyStr, props] of keyMap) {
47216
- if (props.isSigner || programIds.has(keyStr)) {
47217
- numStaticKeys++;
47218
- if (props.isWritable) numWritableStaticKeys++;
47219
- continue;
47220
- }
47221
- const lutEntry = lutLookup.get(keyStr);
47222
- if (lutEntry) {
47223
- if (props.isWritable) {
47224
- lutWritableIdxs[lutEntry.lutIdx].add(lutEntry.addrIdx);
47225
- } else {
47226
- lutReadonlyIdxs[lutEntry.lutIdx].add(lutEntry.addrIdx);
47227
- }
47228
- } else {
47229
- numStaticKeys++;
47230
- if (props.isWritable) numWritableStaticKeys++;
47231
- }
47232
- }
47233
- const fixedOverhead = 101;
47234
- const staticKeysSection = compactU16Size(numStaticKeys) + numStaticKeys * 32;
47235
- let ixSection = compactU16Size(ixs.length);
47236
- for (const ix of ixs) {
47237
- const numAccounts = ix.keys.length;
47238
- ixSection += 1 + // programId index
47239
- compactU16Size(numAccounts) + numAccounts + // account key indexes
47240
- compactU16Size(ix.data.length) + ix.data.length;
47241
- }
47242
- let numUsedLuts = 0;
47243
- let lutSection = 0;
47244
- for (let li = 0; li < luts.length; li++) {
47245
- const wCount = lutWritableIdxs[li].size;
47246
- const rCount = lutReadonlyIdxs[li].size;
47247
- if (wCount === 0 && rCount === 0) continue;
47248
- numUsedLuts++;
47249
- lutSection += 32 + // LUT address
47250
- compactU16Size(wCount) + wCount + // writable indexes
47251
- compactU16Size(rCount) + rCount;
47252
- }
47253
- lutSection += compactU16Size(numUsedLuts);
47254
- let totalLutKeys = 0;
47255
- for (let li = 0; li < luts.length; li++) {
47256
- totalLutKeys += lutWritableIdxs[li].size + lutReadonlyIdxs[li].size;
47257
- }
47258
- const accountCount = numStaticKeys + totalLutKeys;
47259
- let totalLutWritableKeys = 0;
47260
- for (let li = 0; li < luts.length; li++) {
47261
- totalLutWritableKeys += lutWritableIdxs[li].size;
47262
- }
47263
- const writableAccountCount = numWritableStaticKeys + totalLutWritableKeys;
47264
- const size = fixedOverhead + staticKeysSection + ixSection + lutSection + 1;
47265
- return { size, accountCount, writableAccountCount };
47266
- }
47267
- function computeFlashLoanNonSwapBudget({
47268
- program,
47269
- marginfiAccount,
47270
- ixs,
47271
- bankMap,
47272
- addressLookupTableAccounts
47273
- }) {
47274
- const projectedActiveBanksKeys = computeProjectedActiveBanksNoCpi(
47275
- marginfiAccount.balances,
47276
- ixs,
47277
- program
47278
- );
47279
- const projectedActiveBanks = projectedActiveBanksKeys.map((key) => {
47280
- const b = bankMap.get(key.toBase58());
47281
- if (!b) throw new Error(`Bank ${key.toBase58()} not found in computeFlashLoanNonSwapBudget`);
47282
- return b;
47283
- });
47284
- const endIndex = ixs.length + 1;
47285
- const beginFlIx = sync_instructions_default.makeBeginFlashLoanIx(
47286
- program.programId,
47287
- { marginfiAccount: marginfiAccount.address, authority: marginfiAccount.authority },
47288
- { endIndex: new BN11__default.default(endIndex) }
47289
- );
47290
- const endFlRemainingAccounts = computeHealthAccountMetas(projectedActiveBanks);
47291
- const endFlIx = sync_instructions_default.makeEndFlashLoanIx(
47292
- program.programId,
47293
- { marginfiAccount: marginfiAccount.address, authority: marginfiAccount.authority },
47294
- endFlRemainingAccounts.map((pubkey) => ({ pubkey, isSigner: false, isWritable: false }))
47295
- );
47296
- const allNonSwapIxs = [beginFlIx, ...ixs, endFlIx];
47297
- const nonSwapMsg = new web3_js.TransactionMessage({
47298
- payerKey: marginfiAccount.authority,
47299
- recentBlockhash: web3_js.PublicKey.default.toBase58(),
47300
- instructions: allNonSwapIxs
47301
- }).compileToV0Message(addressLookupTableAccounts);
47302
- const nonSwapSize = new web3_js.VersionedTransaction(nonSwapMsg).serialize().length;
47303
- const { header, staticAccountKeys, addressTableLookups } = nonSwapMsg;
47304
- const writableStatic = staticAccountKeys.length - header.numReadonlySignedAccounts - header.numReadonlyUnsignedAccounts;
47305
- const writableLut = addressTableLookups.reduce((s, l) => s + l.writableIndexes.length, 0);
47306
- const nonSwapWritable = writableStatic + writableLut;
47307
- const nonSwapTotal = staticAccountKeys.length + addressTableLookups.reduce(
47308
- (s, l) => s + l.writableIndexes.length + l.readonlyIndexes.length,
47309
- 0
47310
- );
47311
- const sizeConstraint = MAX_TX_SIZE - nonSwapSize - SWAP_MERGE_OVERHEAD;
47312
- const maxSwapWritableAccounts = MAX_WRITABLE_ACCOUNTS - nonSwapWritable;
47313
- const maxSwapTotalAccounts = MAX_ACCOUNT_LOCKS - nonSwapTotal;
47314
- console.log("[flashloan-budget]", {
47315
- method: "compiled",
47316
- nonSwapSize,
47317
- nonSwapWritable,
47318
- nonSwapTotal,
47319
- sizeConstraint,
47320
- maxSwapWritableAccounts,
47321
- maxSwapTotalAccounts
47322
- });
47323
- return { sizeConstraint, maxSwapWritableAccounts, maxSwapTotalAccounts };
47324
- }
47325
- function compileFlashloanPrecheck({
47326
- allIxs,
47327
- payer,
47328
- luts,
47329
- sizeConstraint,
47330
- swapIxCount,
47331
- swapLutCount
47332
- }) {
47333
- const msg = new web3_js.TransactionMessage({
47334
- payerKey: payer,
47335
- recentBlockhash: web3_js.PublicKey.default.toBase58(),
47336
- instructions: allIxs
47337
- }).compileToV0Message(luts);
47338
- const rawSize = new web3_js.VersionedTransaction(msg).serialize().length;
47339
- const fullTxSize = rawSize + FL_IX_OVERHEAD;
47340
- const overshoot = fullTxSize - MAX_TX_SIZE;
47341
- const { header, staticAccountKeys, addressTableLookups } = msg;
47342
- const writableStatic = staticAccountKeys.length - header.numReadonlySignedAccounts - header.numReadonlyUnsignedAccounts;
47343
- const writableLut = addressTableLookups.reduce((s, l) => s + l.writableIndexes.length, 0);
47344
- const writableAccounts = writableStatic + writableLut;
47345
- const totalAccounts = staticAccountKeys.length + addressTableLookups.reduce(
47346
- (s, l) => s + l.writableIndexes.length + l.readonlyIndexes.length,
47347
- 0
47348
- );
47349
- console.log("[flashloan-precheck]", {
47350
- fullTxSize,
47351
- overshoot,
47352
- sizeConstraint,
47353
- writableAccounts,
47354
- totalAccounts,
47355
- staticKeys: staticAccountKeys.length,
47356
- numLuts: addressTableLookups.length,
47357
- swapIxCount,
47358
- swapLutCount
47359
- });
47360
- return { fullTxSize, overshoot, writableAccounts, totalAccounts };
47361
- }
47362
- async function buildBudgetIx(config, program, marginfiAccount, bankMap, bankMetadataMap, overrideInferAccounts) {
47363
- const { bank, tokenProgram } = config;
47364
- switch (config.type) {
47365
- case "borrow":
47366
- return makeBorrowIx3({
47367
- program,
47368
- bank,
47369
- bankMap,
47370
- tokenProgram,
47371
- amount: 1,
47372
- marginfiAccount,
47373
- authority: marginfiAccount.authority,
47374
- isSync: true,
47375
- opts: { createAtas: false, wrapAndUnwrapSol: false, overrideInferAccounts }
47376
- });
47377
- case "repay":
47378
- return makeRepayIx3({
47379
- program,
47380
- bank,
47381
- tokenProgram,
47382
- amount: 1,
47383
- accountAddress: marginfiAccount.address,
47384
- authority: marginfiAccount.authority,
47385
- repayAll: false,
47386
- isSync: true,
47387
- opts: { wrapAndUnwrapSol: false, overrideInferAccounts }
47388
- });
47389
- case "deposit":
47390
- return buildDepositBudgetIx(
47391
- config,
47392
- program,
47393
- marginfiAccount,
47394
- bankMetadataMap,
47395
- overrideInferAccounts
47396
- );
47397
- case "withdraw":
47398
- return buildWithdrawBudgetIx(
47399
- config,
47400
- program,
47401
- marginfiAccount,
47402
- bankMap,
47403
- bankMetadataMap,
47404
- overrideInferAccounts
47405
- );
47406
- }
47407
- }
47408
- async function buildDepositBudgetIx(config, program, marginfiAccount, bankMetadataMap, overrideInferAccounts) {
47409
- const { bank, tokenProgram } = config;
47410
- const opts = { wrapAndUnwrapSol: false, overrideInferAccounts };
47411
- switch (bank.config.assetTag) {
47412
- case 3 /* KAMINO */: {
47413
- const reserve = bankMetadataMap[bank.address.toBase58()]?.kaminoStates?.reserveState;
47414
- if (!reserve) {
47415
- throw TransactionBuildingError.kaminoReserveNotFound(
47416
- bank.address.toBase58(),
47417
- bank.mint.toBase58(),
47418
- bank.tokenSymbol
47419
- );
47420
- }
47421
- return makeKaminoDepositIx3({
47422
- program,
47423
- bank,
47424
- tokenProgram,
47425
- amount: 1,
47426
- accountAddress: marginfiAccount.address,
47427
- authority: marginfiAccount.authority,
47428
- group: marginfiAccount.group,
47429
- reserve,
47430
- isSync: true,
47431
- opts
47432
- });
47433
- }
47434
- case 4 /* DRIFT */: {
47435
- const driftState = bankMetadataMap[bank.address.toBase58()]?.driftStates;
47436
- if (!driftState) {
47437
- throw TransactionBuildingError.driftStateNotFound(
47438
- bank.address.toBase58(),
47439
- bank.mint.toBase58(),
47440
- bank.tokenSymbol
47441
- );
47442
- }
47443
- return makeDriftDepositIx3({
47444
- program,
47445
- bank,
47446
- tokenProgram,
47447
- amount: 1,
47448
- accountAddress: marginfiAccount.address,
47449
- authority: marginfiAccount.authority,
47450
- group: marginfiAccount.group,
47451
- driftMarketIndex: driftState.spotMarketState.marketIndex,
47452
- driftOracle: driftState.spotMarketState.oracle,
47453
- isSync: true,
47454
- opts
47455
- });
47456
- }
47457
- case 6 /* JUPLEND */: {
47458
- return makeJuplendDepositIx2({
47459
- program,
47460
- bank,
47461
- tokenProgram,
47462
- amount: 1,
47463
- accountAddress: marginfiAccount.address,
47464
- authority: marginfiAccount.authority,
47465
- group: marginfiAccount.group,
47466
- isSync: true,
47467
- opts
47468
- });
47469
- }
47470
- default: {
47471
- return makeDepositIx3({
47472
- program,
47473
- bank,
47474
- tokenProgram,
47475
- amount: 1,
47476
- accountAddress: marginfiAccount.address,
47477
- authority: marginfiAccount.authority,
47478
- group: marginfiAccount.group,
47479
- isSync: true,
47480
- opts
47481
- });
47482
- }
47483
- }
47484
- }
47485
- async function buildWithdrawBudgetIx(config, program, marginfiAccount, bankMap, bankMetadataMap, overrideInferAccounts) {
47486
- const { bank, tokenProgram } = config;
47487
- const opts = { createAtas: false, wrapAndUnwrapSol: false, overrideInferAccounts };
47488
- switch (bank.config.assetTag) {
47489
- case 3 /* KAMINO */: {
47490
- const reserve = bankMetadataMap[bank.address.toBase58()]?.kaminoStates?.reserveState;
47491
- if (!reserve) {
47492
- throw TransactionBuildingError.kaminoReserveNotFound(
47493
- bank.address.toBase58(),
47494
- bank.mint.toBase58(),
47495
- bank.tokenSymbol
47496
- );
47497
- }
47498
- return makeKaminoWithdrawIx3({
47499
- program,
47500
- bank,
47501
- bankMap,
47502
- tokenProgram,
47503
- cTokenAmount: 1,
47504
- marginfiAccount,
47505
- authority: marginfiAccount.authority,
47506
- reserve,
47507
- withdrawAll: false,
47508
- isSync: true,
47509
- opts
47510
- });
47511
- }
47512
- case 4 /* DRIFT */: {
47513
- const driftState = bankMetadataMap[bank.address.toBase58()]?.driftStates;
47514
- if (!driftState) {
47515
- throw TransactionBuildingError.driftStateNotFound(
47516
- bank.address.toBase58(),
47517
- bank.mint.toBase58(),
47518
- bank.tokenSymbol
47519
- );
47520
- }
47521
- return makeDriftWithdrawIx3({
47522
- program,
47523
- bank,
47524
- bankMap,
47525
- tokenProgram,
47526
- amount: 1,
47527
- marginfiAccount,
47528
- authority: marginfiAccount.authority,
47529
- driftSpotMarket: driftState.spotMarketState,
47530
- userRewards: driftState.userRewards,
47531
- withdrawAll: false,
47532
- isSync: true,
47533
- opts
47534
- });
47535
- }
47536
- case 6 /* JUPLEND */: {
47537
- const jupLendState = bankMetadataMap[bank.address.toBase58()]?.jupLendStates;
47538
- if (!jupLendState) {
47539
- throw TransactionBuildingError.jupLendStateNotFound(
47540
- bank.address.toBase58(),
47541
- bank.mint.toBase58(),
47542
- bank.tokenSymbol
47543
- );
47544
- }
47545
- return makeJuplendWithdrawIx2({
47546
- program,
47547
- bank,
47548
- bankMap,
47549
- tokenProgram,
47550
- amount: 1,
47551
- marginfiAccount,
47552
- authority: marginfiAccount.authority,
47553
- jupLendingState: jupLendState.jupLendingState,
47554
- withdrawAll: false,
47555
- opts
47556
- });
47557
- }
47558
- default: {
47559
- return makeWithdrawIx3({
47560
- program,
47561
- bank,
47562
- bankMap,
47563
- tokenProgram,
47564
- amount: 1,
47565
- marginfiAccount,
47316
+ default: {
47317
+ depositIxs = await makeDepositIx3({
47318
+ program,
47319
+ bank: depositOpts.depositBank,
47320
+ tokenProgram: depositOpts.tokenProgram,
47321
+ amount: amountToDeposit,
47322
+ accountAddress: marginfiAccount.address,
47566
47323
  authority: marginfiAccount.authority,
47567
- withdrawAll: false,
47568
- isSync: true,
47569
- opts
47324
+ group: marginfiAccount.group,
47325
+ opts: {
47326
+ wrapAndUnwrapSol: false,
47327
+ overrideInferAccounts
47328
+ }
47570
47329
  });
47330
+ break;
47571
47331
  }
47572
47332
  }
47573
- }
47574
- async function computeFlashloanSwapConstraints({
47575
- program,
47576
- marginfiAccount,
47577
- bankMap,
47578
- addressLookupTableAccounts,
47579
- bankMetadataMap,
47580
- primaryIx,
47581
- secondaryIx,
47582
- overrideInferAccounts
47583
- }) {
47584
- const cuRequestIxs = [
47585
- web3_js.ComputeBudgetProgram.setComputeUnitLimit({ units: 12e5 }),
47586
- web3_js.ComputeBudgetProgram.setComputeUnitPrice({ microLamports: 1 })
47333
+ const luts = [...addressLookupTableAccounts ?? [], ...swapLookupTables];
47334
+ const allNonFlIxs = [
47335
+ ...cuRequestIxs,
47336
+ ...borrowIxs.instructions,
47337
+ ...swapInstructions,
47338
+ ...depositIxs.instructions
47587
47339
  ];
47588
- const [primaryResult, secondaryResult] = await Promise.all([
47589
- buildBudgetIx(
47590
- primaryIx,
47591
- program,
47592
- marginfiAccount,
47593
- bankMap,
47594
- bankMetadataMap,
47595
- overrideInferAccounts
47596
- ),
47597
- buildBudgetIx(
47598
- secondaryIx,
47599
- program,
47600
- marginfiAccount,
47601
- bankMap,
47602
- bankMetadataMap,
47603
- overrideInferAccounts
47604
- )
47605
- ]);
47606
- return computeFlashLoanNonSwapBudget({
47340
+ if (swapInstructions.length > 0) {
47341
+ compileFlashloanPrecheck({
47342
+ allIxs: allNonFlIxs,
47343
+ payer: marginfiAccount.authority,
47344
+ luts,
47345
+ sizeConstraint: sizeConstraintUsed,
47346
+ swapIxCount: swapInstructions.length,
47347
+ swapLutCount: swapLookupTables.length
47348
+ });
47349
+ }
47350
+ const flashloanTx = await makeFlashLoanTx({
47607
47351
  program,
47608
47352
  marginfiAccount,
47609
47353
  bankMap,
47610
- addressLookupTableAccounts,
47611
- ixs: [...cuRequestIxs, ...primaryResult.instructions, ...secondaryResult.instructions]
47354
+ addressLookupTableAccounts: luts,
47355
+ blockhash,
47356
+ ixs: allNonFlIxs
47612
47357
  });
47358
+ const txSize = getTxSize(flashloanTx);
47359
+ const totalKeys = getTotalAccountKeys(flashloanTx);
47360
+ if (txSize > MAX_TX_SIZE || totalKeys > MAX_ACCOUNT_LOCKS) {
47361
+ throw TransactionBuildingError.swapSizeExceededLoop(
47362
+ txSize,
47363
+ totalKeys,
47364
+ swapOpts.swapConfig?.provider
47365
+ );
47366
+ }
47367
+ return {
47368
+ flashloanTx,
47369
+ setupInstructions,
47370
+ swapQuote,
47371
+ borrowIxs,
47372
+ depositIxs,
47373
+ amountToDeposit
47374
+ };
47613
47375
  }
47614
-
47615
- // src/services/account/actions/flash-loan.ts
47616
- async function makeBeginFlashLoanIx3(program, marginfiAccountPk, endIndex, authority, isSync) {
47617
- const ix = isSync && authority ? sync_instructions_default.makeBeginFlashLoanIx(
47618
- program.programId,
47619
- {
47620
- marginfiAccount: marginfiAccountPk,
47621
- authority
47622
- },
47623
- { endIndex: new BN11__default.default(endIndex) }
47624
- ) : await instructions_default.makeBeginFlashLoanIx(
47376
+ async function makeRepayIx3({
47377
+ program,
47378
+ bank,
47379
+ tokenProgram,
47380
+ amount,
47381
+ authority,
47382
+ accountAddress,
47383
+ repayAll = false,
47384
+ isSync = false,
47385
+ opts = {}
47386
+ }) {
47387
+ const wrapAndUnwrapSol = opts.wrapAndUnwrapSol ?? true;
47388
+ const wSolBalanceUi = opts.wSolBalanceUi ?? 0;
47389
+ const repayIxs = [];
47390
+ const userAta = getAssociatedTokenAddressSync(bank.mint, authority, true, tokenProgram);
47391
+ const remainingAccounts = tokenProgram.equals(TOKEN_2022_PROGRAM_ID) ? [{ pubkey: bank.mint, isSigner: false, isWritable: false }] : [];
47392
+ if (bank.mint.equals(NATIVE_MINT) && wrapAndUnwrapSol) {
47393
+ repayIxs.push(...makeWrapSolIxs(authority, new BigNumber3.BigNumber(amount).minus(wSolBalanceUi)));
47394
+ }
47395
+ const repayIx = !isSync || !opts.overrideInferAccounts?.group ? await instructions_default.makeRepayIx(
47625
47396
  program,
47626
47397
  {
47627
- marginfiAccount: marginfiAccountPk,
47628
- authority
47398
+ marginfiAccount: accountAddress,
47399
+ signerTokenAccount: userAta,
47400
+ bank: bank.address,
47401
+ tokenProgram,
47402
+ authority: opts.overrideInferAccounts?.authority ?? authority,
47403
+ group: opts.overrideInferAccounts?.group,
47404
+ liquidityVault: opts.overrideInferAccounts?.liquidityVault
47629
47405
  },
47630
- { endIndex: new BN11__default.default(endIndex) }
47631
- );
47632
- return { instructions: [ix], keys: [] };
47633
- }
47634
- async function makeEndFlashLoanIx3(program, marginfiAccountPk, projectedActiveBanks, authority, isSync) {
47635
- const remainingAccounts = computeHealthAccountMetas(projectedActiveBanks);
47636
- const ix = isSync && authority ? sync_instructions_default.makeEndFlashLoanIx(
47406
+ { amount: uiToNative(amount, bank.mintDecimals), repayAll },
47407
+ remainingAccounts
47408
+ ) : sync_instructions_default.makeRepayIx(
47637
47409
  program.programId,
47638
47410
  {
47639
- marginfiAccount: marginfiAccountPk,
47640
- authority
47641
- },
47642
- remainingAccounts.map((account) => ({
47643
- pubkey: account,
47644
- isSigner: false,
47645
- isWritable: false
47646
- }))
47647
- ) : await instructions_default.makeEndFlashLoanIx(
47648
- program,
47649
- {
47650
- marginfiAccount: marginfiAccountPk,
47651
- authority
47411
+ marginfiAccount: accountAddress,
47412
+ signerTokenAccount: userAta,
47413
+ bank: bank.address,
47414
+ tokenProgram,
47415
+ authority: opts.overrideInferAccounts?.authority ?? authority,
47416
+ group: opts.overrideInferAccounts?.group
47652
47417
  },
47653
- remainingAccounts.map((account) => ({
47654
- pubkey: account,
47655
- isSigner: false,
47656
- isWritable: false
47657
- }))
47418
+ { amount: uiToNative(amount, bank.mintDecimals), repayAll },
47419
+ remainingAccounts
47658
47420
  );
47659
- return { instructions: [ix], keys: [] };
47421
+ repayIxs.push(repayIx);
47422
+ return {
47423
+ instructions: repayIxs,
47424
+ keys: []
47425
+ };
47660
47426
  }
47661
- async function makeFlashLoanTx({
47662
- program,
47663
- marginfiAccount,
47664
- ixs,
47665
- bankMap,
47666
- blockhash,
47667
- addressLookupTableAccounts,
47668
- signers,
47669
- isSync
47670
- }) {
47671
- const endIndex = ixs.length + 1;
47672
- const projectedActiveBanksKeys = computeProjectedActiveBanksNoCpi(
47673
- marginfiAccount.balances,
47674
- ixs,
47675
- program
47676
- );
47677
- const projectedActiveBanks = projectedActiveBanksKeys.map((account) => {
47678
- const b = bankMap.get(account.toBase58());
47679
- if (!b) throw Error(`Bank ${account.toBase58()} not found, in makeFlashLoanTx function`);
47680
- return b;
47681
- });
47682
- const beginFlashLoanIx = await makeBeginFlashLoanIx3(
47683
- program,
47684
- marginfiAccount.address,
47685
- endIndex,
47686
- marginfiAccount.authority,
47687
- isSync
47688
- );
47689
- const endFlashLoanIx = await makeEndFlashLoanIx3(
47690
- program,
47691
- marginfiAccount.address,
47692
- projectedActiveBanks,
47693
- marginfiAccount.authority,
47694
- isSync
47695
- );
47696
- const message = new web3_js.TransactionMessage({
47697
- payerKey: marginfiAccount.authority,
47698
- recentBlockhash: blockhash,
47699
- instructions: [...beginFlashLoanIx.instructions, ...ixs, ...endFlashLoanIx.instructions]
47700
- }).compileToV0Message(addressLookupTableAccounts);
47701
- const tx = addTransactionMetadata(new web3_js.VersionedTransaction(message), {
47702
- addressLookupTables: addressLookupTableAccounts,
47703
- type: "FLASHLOAN" /* FLASHLOAN */,
47704
- signers
47427
+ async function makeRepayTx(params) {
47428
+ const { luts, ...depositIxParams } = params;
47429
+ const ixs = await makeRepayIx3(depositIxParams);
47430
+ const tx = new web3_js.Transaction().add(...ixs.instructions);
47431
+ tx.feePayer = params.authority;
47432
+ const solanaTx = addTransactionMetadata(tx, {
47433
+ type: "REPAY" /* REPAY */,
47434
+ signers: ixs.keys,
47435
+ addressLookupTables: luts
47705
47436
  });
47706
- if (signers) {
47707
- tx.sign(signers);
47708
- }
47709
- return tx;
47437
+ return solanaTx;
47710
47438
  }
47711
-
47712
- // src/services/account/actions/loop.ts
47713
- async function makeLoopTx(params) {
47439
+ async function makeRepayWithCollatTx(params) {
47714
47440
  const {
47715
47441
  program,
47716
47442
  marginfiAccount,
47717
47443
  bankMap,
47718
- depositOpts,
47719
- borrowOpts,
47444
+ withdrawOpts,
47445
+ repayOpts,
47720
47446
  bankMetadataMap,
47721
47447
  addressLookupTableAccounts,
47722
47448
  connection,
47723
47449
  oraclePrices,
47724
- crossbarUrl,
47725
- additionalIxs = []
47450
+ crossbarUrl
47726
47451
  } = params;
47727
47452
  const blockhash = (await connection.getLatestBlockhash("confirmed")).blockhash;
47728
47453
  const setupIxs = await makeSetupIx({
@@ -47730,34 +47455,34 @@ async function makeLoopTx(params) {
47730
47455
  authority: marginfiAccount.authority,
47731
47456
  tokens: [
47732
47457
  {
47733
- mint: borrowOpts.borrowBank.mint,
47734
- tokenProgram: borrowOpts.tokenProgram
47458
+ mint: repayOpts.repayBank.mint,
47459
+ tokenProgram: repayOpts.tokenProgram
47735
47460
  },
47736
47461
  {
47737
- mint: depositOpts.depositBank.mint,
47738
- tokenProgram: depositOpts.tokenProgram
47462
+ mint: withdrawOpts.withdrawBank.mint,
47463
+ tokenProgram: withdrawOpts.tokenProgram
47739
47464
  }
47740
47465
  ]
47741
47466
  });
47742
- const updateJupLendRateIxs = makeUpdateJupLendRateIxs(
47743
- params.marginfiAccount,
47744
- params.bankMap,
47745
- [depositOpts.depositBank.address],
47746
- params.bankMetadataMap
47467
+ const updateJuplendMarketIxs = makeUpdateJupLendRateIxs(
47468
+ marginfiAccount,
47469
+ bankMap,
47470
+ [withdrawOpts.withdrawBank.address],
47471
+ bankMetadataMap
47747
47472
  );
47748
47473
  const updateDriftMarketIxs = makeUpdateDriftMarketIxs(
47749
- params.marginfiAccount,
47750
- params.bankMap,
47751
- [depositOpts.depositBank.address],
47752
- params.bankMetadataMap
47474
+ marginfiAccount,
47475
+ bankMap,
47476
+ [withdrawOpts.withdrawBank.address],
47477
+ bankMetadataMap
47753
47478
  );
47754
47479
  const kaminoRefreshIxs = makeRefreshKaminoBanksIxs(
47755
47480
  marginfiAccount,
47756
47481
  bankMap,
47757
- [borrowOpts.borrowBank.address, depositOpts.depositBank.address],
47482
+ [withdrawOpts.withdrawBank.address, repayOpts.repayBank.address],
47758
47483
  bankMetadataMap
47759
47484
  );
47760
- const { flashloanTx, setupInstructions, swapQuote, amountToDeposit, depositIxs, borrowIxs } = await buildLoopFlashloanTx({
47485
+ const { flashloanTx, setupInstructions, swapQuote, amountToRepay, withdrawIxs, repayIxs } = await buildRepayWithCollatFlashloanTx({
47761
47486
  ...params,
47762
47487
  blockhash
47763
47488
  });
@@ -47767,7 +47492,7 @@ async function makeLoopTx(params) {
47767
47492
  }
47768
47493
  if (ix.programId.equals(ASSOCIATED_TOKEN_PROGRAM_ID)) {
47769
47494
  const mintKey = ix.keys[3]?.pubkey;
47770
- if (mintKey?.equals(depositOpts.depositBank.mint) || mintKey?.equals(borrowOpts.borrowBank.mint)) {
47495
+ if (mintKey?.equals(withdrawOpts.withdrawBank.mint) || mintKey?.equals(repayOpts.repayBank.mint)) {
47771
47496
  return false;
47772
47497
  }
47773
47498
  }
@@ -47779,24 +47504,18 @@ async function makeLoopTx(params) {
47779
47504
  bankMap,
47780
47505
  oraclePrices,
47781
47506
  assetShareValueMultiplierByBank: params.assetShareValueMultiplierByBank,
47782
- instructions: [...borrowIxs.instructions, ...depositIxs.instructions],
47507
+ instructions: [...withdrawIxs.instructions, ...repayIxs.instructions],
47783
47508
  program,
47784
47509
  connection,
47785
47510
  crossbarUrl
47786
47511
  });
47787
47512
  let additionalTxs = [];
47788
- if (depositOpts.depositBank.mint.equals(NATIVE_MINT) && depositOpts.inputDepositAmount) {
47789
- setupIxs.push(
47790
- ...makeWrapSolIxs(marginfiAccount.authority, new BigNumber3.BigNumber(depositOpts.inputDepositAmount))
47791
- );
47792
- }
47793
- if (setupIxs.length > 0 || additionalIxs.length > 0 || kaminoRefreshIxs.instructions.length > 0 || updateDriftMarketIxs.instructions.length > 0 || updateJupLendRateIxs.instructions.length > 0) {
47513
+ if (setupIxs.length > 0 || kaminoRefreshIxs.instructions.length > 0 || updateDriftMarketIxs.instructions.length > 0 || updateJuplendMarketIxs.instructions.length > 0) {
47794
47514
  const ixs = [
47795
- ...additionalIxs,
47796
47515
  ...setupIxs,
47797
47516
  ...kaminoRefreshIxs.instructions,
47798
47517
  ...updateDriftMarketIxs.instructions,
47799
- ...updateJupLendRateIxs.instructions
47518
+ ...updateJuplendMarketIxs.instructions
47800
47519
  ];
47801
47520
  const txs = splitInstructionsToFitTransactions([], ixs, {
47802
47521
  blockhash,
@@ -47826,19 +47545,16 @@ async function makeLoopTx(params) {
47826
47545
  );
47827
47546
  }
47828
47547
  const transactions = [...additionalTxs, flashloanTx];
47829
- return {
47830
- transactions,
47831
- actionTxIndex: transactions.length - 1,
47832
- quoteResponse: swapQuote
47833
- };
47548
+ return { transactions, swapQuote, amountToRepay };
47834
47549
  }
47835
- async function buildLoopFlashloanTx({
47550
+ async function buildRepayWithCollatFlashloanTx({
47836
47551
  program,
47837
47552
  marginfiAccount,
47838
47553
  bankMap,
47839
- borrowOpts,
47840
- depositOpts,
47554
+ withdrawOpts,
47555
+ repayOpts,
47841
47556
  bankMetadataMap,
47557
+ assetShareValueMultiplierByBank,
47842
47558
  addressLookupTableAccounts,
47843
47559
  connection,
47844
47560
  swapOpts,
@@ -47849,20 +47565,20 @@ async function buildLoopFlashloanTx({
47849
47565
  web3_js.ComputeBudgetProgram.setComputeUnitLimit({ units: 12e5 }),
47850
47566
  web3_js.ComputeBudgetProgram.setComputeUnitPrice({ microLamports: 1 })
47851
47567
  ];
47852
- let amountToDeposit;
47568
+ let amountToRepay;
47853
47569
  let swapInstructions = [];
47854
47570
  let setupInstructions = [];
47855
47571
  let swapLookupTables = [];
47856
47572
  let swapQuote;
47857
47573
  let sizeConstraintUsed = 0;
47858
- if (depositOpts.depositBank.mint.equals(borrowOpts.borrowBank.mint)) {
47859
- amountToDeposit = borrowOpts.borrowAmount + (depositOpts.loopMode === "DEPOSIT" ? depositOpts.inputDepositAmount : 0);
47574
+ if (repayOpts.repayBank.mint.equals(withdrawOpts.withdrawBank.mint)) {
47575
+ amountToRepay = withdrawOpts.withdrawAmount;
47860
47576
  } else {
47861
47577
  const destinationTokenAccount = getAssociatedTokenAddressSync(
47862
- new web3_js.PublicKey(depositOpts.depositBank.mint),
47578
+ new web3_js.PublicKey(repayOpts.repayBank.mint),
47863
47579
  marginfiAccount.authority,
47864
47580
  true,
47865
- depositOpts.tokenProgram.equals(TOKEN_2022_PROGRAM_ID) ? TOKEN_2022_PROGRAM_ID : void 0
47581
+ repayOpts.tokenProgram.equals(TOKEN_2022_PROGRAM_ID) ? TOKEN_2022_PROGRAM_ID : void 0
47866
47582
  );
47867
47583
  const swapConstraints = await computeFlashloanSwapConstraints({
47868
47584
  program,
@@ -47871,77 +47587,77 @@ async function buildLoopFlashloanTx({
47871
47587
  bankMetadataMap,
47872
47588
  addressLookupTableAccounts: addressLookupTableAccounts ?? [],
47873
47589
  primaryIx: {
47874
- type: "borrow",
47875
- bank: borrowOpts.borrowBank,
47876
- tokenProgram: borrowOpts.tokenProgram
47590
+ type: "withdraw",
47591
+ bank: withdrawOpts.withdrawBank,
47592
+ tokenProgram: withdrawOpts.tokenProgram
47877
47593
  },
47878
47594
  secondaryIx: {
47879
- type: "deposit",
47880
- bank: depositOpts.depositBank,
47881
- tokenProgram: depositOpts.tokenProgram
47595
+ type: "repay",
47596
+ bank: repayOpts.repayBank,
47597
+ tokenProgram: repayOpts.tokenProgram
47882
47598
  },
47883
47599
  overrideInferAccounts
47884
47600
  });
47885
47601
  const swapResponse = await getSwapIxsForFlashloan({
47886
- inputMint: borrowOpts.borrowBank.mint.toBase58(),
47887
- outputMint: depositOpts.depositBank.mint.toBase58(),
47888
- amount: uiToNative(borrowOpts.borrowAmount, borrowOpts.borrowBank.mintDecimals).toNumber(),
47602
+ inputMint: withdrawOpts.withdrawBank.mint.toBase58(),
47603
+ outputMint: repayOpts.repayBank.mint.toBase58(),
47604
+ amount: uiToNative(
47605
+ withdrawOpts.withdrawAmount,
47606
+ withdrawOpts.withdrawBank.mintDecimals
47607
+ ).toNumber(),
47889
47608
  swapMode: "ExactIn",
47890
47609
  authority: marginfiAccount.authority,
47891
47610
  connection,
47892
47611
  destinationTokenAccount,
47893
47612
  swapOpts,
47894
47613
  sizeConstraint: swapConstraints.sizeConstraint,
47895
- maxSwapAccounts: swapConstraints.maxSwapWritableAccounts,
47896
47614
  maxSwapTotalAccounts: swapConstraints.maxSwapTotalAccounts
47897
47615
  });
47898
47616
  sizeConstraintUsed = swapConstraints.sizeConstraint;
47617
+ const { quoteResponse } = swapResponse;
47618
+ const outAmount = nativeToUi(quoteResponse.outAmount, repayOpts.repayBank.mintDecimals);
47899
47619
  const outAmountThreshold = nativeToUi(
47900
- swapResponse.quoteResponse.otherAmountThreshold,
47901
- depositOpts.depositBank.mintDecimals
47620
+ quoteResponse.otherAmountThreshold,
47621
+ repayOpts.repayBank.mintDecimals
47902
47622
  );
47903
- amountToDeposit = outAmountThreshold + (depositOpts.loopMode === "DEPOSIT" ? depositOpts.inputDepositAmount : 0);
47623
+ amountToRepay = outAmount > repayOpts.totalPositionAmount ? repayOpts.totalPositionAmount : outAmountThreshold;
47904
47624
  swapInstructions = swapResponse.swapInstructions;
47905
- setupInstructions = swapResponse.setupInstructions;
47906
47625
  swapLookupTables = swapResponse.addressLookupTableAddresses;
47907
- swapQuote = swapResponse.quoteResponse;
47626
+ swapQuote = quoteResponse;
47908
47627
  }
47909
- const borrowIxs = await makeBorrowIx3({
47910
- program,
47911
- bank: borrowOpts.borrowBank,
47912
- bankMap,
47913
- tokenProgram: borrowOpts.tokenProgram,
47914
- amount: borrowOpts.borrowAmount,
47915
- marginfiAccount,
47916
- authority: marginfiAccount.authority,
47917
- isSync: false,
47918
- opts: {
47919
- createAtas: false,
47920
- wrapAndUnwrapSol: false,
47921
- overrideInferAccounts
47922
- }
47923
- });
47924
- let depositIxs;
47925
- switch (depositOpts.depositBank.config.assetTag) {
47628
+ let withdrawIxs;
47629
+ switch (withdrawOpts.withdrawBank.config.assetTag) {
47926
47630
  case 3 /* KAMINO */: {
47927
- const reserve = bankMetadataMap[depositOpts.depositBank.address.toBase58()]?.kaminoStates?.reserveState;
47631
+ const reserve = bankMetadataMap[withdrawOpts.withdrawBank.address.toBase58()]?.kaminoStates?.reserveState;
47928
47632
  if (!reserve) {
47929
47633
  throw TransactionBuildingError.kaminoReserveNotFound(
47930
- depositOpts.depositBank.address.toBase58(),
47931
- depositOpts.depositBank.mint.toBase58(),
47932
- depositOpts.depositBank.tokenSymbol
47634
+ withdrawOpts.withdrawBank.address.toBase58(),
47635
+ withdrawOpts.withdrawBank.mint.toBase58(),
47636
+ withdrawOpts.withdrawBank.tokenSymbol
47933
47637
  );
47934
47638
  }
47935
- depositIxs = await makeKaminoDepositIx3({
47639
+ const multiplier = assetShareValueMultiplierByBank.get(withdrawOpts.withdrawBank.address.toBase58()) ?? new BigNumber3.BigNumber(1);
47640
+ const adjustedAmount = new BigNumber3.BigNumber(withdrawOpts.withdrawAmount).div(multiplier).times(1.0001).toNumber();
47641
+ withdrawIxs = await makeKaminoWithdrawIx3({
47936
47642
  program,
47937
- bank: depositOpts.depositBank,
47938
- tokenProgram: depositOpts.tokenProgram,
47939
- amount: amountToDeposit,
47940
- accountAddress: marginfiAccount.address,
47643
+ bank: withdrawOpts.withdrawBank,
47644
+ bankMap,
47645
+ tokenProgram: withdrawOpts.tokenProgram,
47646
+ cTokenAmount: adjustedAmount,
47647
+ marginfiAccount,
47941
47648
  authority: marginfiAccount.authority,
47942
- group: marginfiAccount.group,
47943
47649
  reserve,
47650
+ withdrawAll: isWholePosition(
47651
+ {
47652
+ amount: withdrawOpts.totalPositionAmount,
47653
+ isLending: true
47654
+ },
47655
+ withdrawOpts.withdrawAmount,
47656
+ withdrawOpts.withdrawBank.mintDecimals
47657
+ ),
47658
+ isSync: false,
47944
47659
  opts: {
47660
+ createAtas: false,
47945
47661
  wrapAndUnwrapSol: false,
47946
47662
  overrideInferAccounts
47947
47663
  }
@@ -47949,27 +47665,35 @@ async function buildLoopFlashloanTx({
47949
47665
  break;
47950
47666
  }
47951
47667
  case 4 /* DRIFT */: {
47952
- const driftState = bankMetadataMap[depositOpts.depositBank.address.toBase58()]?.driftStates;
47668
+ const driftState = bankMetadataMap[withdrawOpts.withdrawBank.address.toBase58()]?.driftStates;
47953
47669
  if (!driftState) {
47954
47670
  throw TransactionBuildingError.driftStateNotFound(
47955
- depositOpts.depositBank.address.toBase58(),
47956
- depositOpts.depositBank.mint.toBase58(),
47957
- depositOpts.depositBank.tokenSymbol
47671
+ withdrawOpts.withdrawBank.address.toBase58(),
47672
+ withdrawOpts.withdrawBank.mint.toBase58(),
47673
+ withdrawOpts.withdrawBank.tokenSymbol
47958
47674
  );
47959
47675
  }
47960
- const driftMarketIndex = driftState.spotMarketState.marketIndex;
47961
- const driftOracle = driftState.spotMarketState.oracle;
47962
- depositIxs = await makeDriftDepositIx3({
47676
+ withdrawIxs = await makeDriftWithdrawIx3({
47963
47677
  program,
47964
- bank: depositOpts.depositBank,
47965
- tokenProgram: depositOpts.tokenProgram,
47966
- amount: amountToDeposit,
47967
- accountAddress: marginfiAccount.address,
47678
+ bank: withdrawOpts.withdrawBank,
47679
+ bankMap,
47680
+ tokenProgram: withdrawOpts.tokenProgram,
47681
+ amount: withdrawOpts.withdrawAmount,
47682
+ marginfiAccount,
47968
47683
  authority: marginfiAccount.authority,
47969
- group: marginfiAccount.group,
47970
- driftMarketIndex,
47971
- driftOracle,
47684
+ driftSpotMarket: driftState.spotMarketState,
47685
+ userRewards: driftState.userRewards,
47686
+ withdrawAll: isWholePosition(
47687
+ {
47688
+ amount: withdrawOpts.totalPositionAmount,
47689
+ isLending: true
47690
+ },
47691
+ withdrawOpts.withdrawAmount,
47692
+ withdrawOpts.withdrawBank.mintDecimals
47693
+ ),
47694
+ isSync: false,
47972
47695
  opts: {
47696
+ createAtas: false,
47973
47697
  wrapAndUnwrapSol: false,
47974
47698
  overrideInferAccounts
47975
47699
  }
@@ -47977,15 +47701,33 @@ async function buildLoopFlashloanTx({
47977
47701
  break;
47978
47702
  }
47979
47703
  case 6 /* JUPLEND */: {
47980
- depositIxs = await makeJuplendDepositIx2({
47704
+ const jupLendState = bankMetadataMap[withdrawOpts.withdrawBank.address.toBase58()]?.jupLendStates;
47705
+ if (!jupLendState) {
47706
+ throw TransactionBuildingError.jupLendStateNotFound(
47707
+ withdrawOpts.withdrawBank.address.toBase58(),
47708
+ withdrawOpts.withdrawBank.mint.toBase58(),
47709
+ withdrawOpts.withdrawBank.tokenSymbol
47710
+ );
47711
+ }
47712
+ withdrawIxs = await makeJuplendWithdrawIx2({
47981
47713
  program,
47982
- bank: depositOpts.depositBank,
47983
- tokenProgram: depositOpts.tokenProgram,
47984
- amount: amountToDeposit,
47985
- accountAddress: marginfiAccount.address,
47714
+ bank: withdrawOpts.withdrawBank,
47715
+ bankMap,
47716
+ tokenProgram: withdrawOpts.tokenProgram,
47717
+ amount: withdrawOpts.withdrawAmount,
47718
+ marginfiAccount,
47986
47719
  authority: marginfiAccount.authority,
47987
- group: marginfiAccount.group,
47720
+ jupLendingState: jupLendState.jupLendingState,
47721
+ withdrawAll: isWholePosition(
47722
+ {
47723
+ amount: withdrawOpts.totalPositionAmount,
47724
+ isLending: true
47725
+ },
47726
+ withdrawOpts.withdrawAmount,
47727
+ withdrawOpts.withdrawBank.mintDecimals
47728
+ ),
47988
47729
  opts: {
47730
+ createAtas: false,
47989
47731
  wrapAndUnwrapSol: false,
47990
47732
  overrideInferAccounts
47991
47733
  }
@@ -47993,15 +47735,25 @@ async function buildLoopFlashloanTx({
47993
47735
  break;
47994
47736
  }
47995
47737
  default: {
47996
- depositIxs = await makeDepositIx3({
47738
+ withdrawIxs = await makeWithdrawIx3({
47997
47739
  program,
47998
- bank: depositOpts.depositBank,
47999
- tokenProgram: depositOpts.tokenProgram,
48000
- amount: amountToDeposit,
48001
- accountAddress: marginfiAccount.address,
47740
+ bank: withdrawOpts.withdrawBank,
47741
+ bankMap,
47742
+ tokenProgram: withdrawOpts.tokenProgram,
47743
+ amount: withdrawOpts.withdrawAmount,
47744
+ marginfiAccount,
48002
47745
  authority: marginfiAccount.authority,
48003
- group: marginfiAccount.group,
47746
+ withdrawAll: isWholePosition(
47747
+ {
47748
+ amount: withdrawOpts.totalPositionAmount,
47749
+ isLending: true
47750
+ },
47751
+ withdrawOpts.withdrawAmount,
47752
+ withdrawOpts.withdrawBank.mintDecimals
47753
+ ),
47754
+ isSync: false,
48004
47755
  opts: {
47756
+ createAtas: false,
48005
47757
  wrapAndUnwrapSol: false,
48006
47758
  overrideInferAccounts
48007
47759
  }
@@ -48009,12 +47761,33 @@ async function buildLoopFlashloanTx({
48009
47761
  break;
48010
47762
  }
48011
47763
  }
47764
+ const repayIxs = await makeRepayIx3({
47765
+ program,
47766
+ bank: repayOpts.repayBank,
47767
+ tokenProgram: repayOpts.tokenProgram,
47768
+ amount: amountToRepay,
47769
+ accountAddress: marginfiAccount.address,
47770
+ authority: marginfiAccount.authority,
47771
+ repayAll: isWholePosition(
47772
+ {
47773
+ amount: repayOpts.totalPositionAmount,
47774
+ isLending: true
47775
+ },
47776
+ amountToRepay,
47777
+ repayOpts.repayBank.mintDecimals
47778
+ ),
47779
+ isSync: false,
47780
+ opts: {
47781
+ wrapAndUnwrapSol: false,
47782
+ overrideInferAccounts
47783
+ }
47784
+ });
48012
47785
  const luts = [...addressLookupTableAccounts ?? [], ...swapLookupTables];
48013
47786
  const allNonFlIxs = [
48014
47787
  ...cuRequestIxs,
48015
- ...borrowIxs.instructions,
47788
+ ...withdrawIxs.instructions,
48016
47789
  ...swapInstructions,
48017
- ...depositIxs.instructions
47790
+ ...repayIxs.instructions
48018
47791
  ];
48019
47792
  if (swapInstructions.length > 0) {
48020
47793
  compileFlashloanPrecheck({
@@ -48032,15 +47805,15 @@ async function buildLoopFlashloanTx({
48032
47805
  bankMap,
48033
47806
  addressLookupTableAccounts: luts,
48034
47807
  blockhash,
48035
- ixs: allNonFlIxs
47808
+ ixs: allNonFlIxs,
47809
+ isSync: true
48036
47810
  });
48037
47811
  const txSize = getTxSize(flashloanTx);
48038
- const writableKeys = getWritableAccountKeys(flashloanTx);
48039
47812
  const totalKeys = getTotalAccountKeys(flashloanTx);
48040
- if (txSize > MAX_TX_SIZE || writableKeys > MAX_WRITABLE_ACCOUNTS || totalKeys > MAX_ACCOUNT_LOCKS) {
48041
- throw TransactionBuildingError.swapSizeExceededLoop(
47813
+ if (txSize > MAX_TX_SIZE || totalKeys > MAX_ACCOUNT_LOCKS) {
47814
+ throw TransactionBuildingError.swapSizeExceededRepay(
48042
47815
  txSize,
48043
- writableKeys,
47816
+ totalKeys,
48044
47817
  swapOpts.swapConfig?.provider
48045
47818
  );
48046
47819
  }
@@ -48048,9 +47821,9 @@ async function buildLoopFlashloanTx({
48048
47821
  flashloanTx,
48049
47822
  setupInstructions,
48050
47823
  swapQuote,
48051
- borrowIxs,
48052
- depositIxs,
48053
- amountToDeposit
47824
+ withdrawIxs,
47825
+ repayIxs,
47826
+ amountToRepay
48054
47827
  };
48055
47828
  }
48056
47829
 
@@ -48352,7 +48125,6 @@ async function buildSwapCollateralFlashloanTx({
48352
48125
  destinationTokenAccount,
48353
48126
  swapOpts,
48354
48127
  sizeConstraint: swapConstraints.sizeConstraint,
48355
- maxSwapAccounts: swapConstraints.maxSwapWritableAccounts,
48356
48128
  maxSwapTotalAccounts: swapConstraints.maxSwapTotalAccounts
48357
48129
  });
48358
48130
  sizeConstraintUsed = swapConstraints.sizeConstraint;
@@ -48480,12 +48252,11 @@ async function buildSwapCollateralFlashloanTx({
48480
48252
  isSync: true
48481
48253
  });
48482
48254
  const txSize = getTxSize(flashloanTx);
48483
- const writableKeys = getWritableAccountKeys(flashloanTx);
48484
48255
  const totalKeys = getTotalAccountKeys(flashloanTx);
48485
- if (txSize > MAX_TX_SIZE || writableKeys > MAX_WRITABLE_ACCOUNTS || totalKeys > MAX_ACCOUNT_LOCKS) {
48486
- throw TransactionBuildingError.swapSizeExceededLoop(
48256
+ if (txSize > MAX_TX_SIZE || totalKeys > MAX_ACCOUNT_LOCKS) {
48257
+ throw TransactionBuildingError.swapSizeExceededPositionSwap(
48487
48258
  txSize,
48488
- writableKeys,
48259
+ totalKeys,
48489
48260
  swapOpts.swapConfig?.provider
48490
48261
  );
48491
48262
  }
@@ -48671,7 +48442,6 @@ async function buildSwapDebtFlashloanTx({
48671
48442
  destinationTokenAccount,
48672
48443
  swapOpts,
48673
48444
  sizeConstraint: swapConstraints.sizeConstraint,
48674
- maxSwapAccounts: swapConstraints.maxSwapWritableAccounts,
48675
48445
  maxSwapTotalAccounts: swapConstraints.maxSwapTotalAccounts
48676
48446
  });
48677
48447
  const { quoteResponse } = swapResponses;
@@ -48743,12 +48513,11 @@ async function buildSwapDebtFlashloanTx({
48743
48513
  isSync: true
48744
48514
  });
48745
48515
  const txSize = getTxSize(flashloanTx);
48746
- const writableKeys = getWritableAccountKeys(flashloanTx);
48747
48516
  const totalKeys = getTotalAccountKeys(flashloanTx);
48748
- if (txSize > MAX_TX_SIZE || writableKeys > MAX_WRITABLE_ACCOUNTS || totalKeys > MAX_ACCOUNT_LOCKS) {
48749
- throw TransactionBuildingError.swapSizeExceededLoop(
48517
+ if (txSize > MAX_TX_SIZE || totalKeys > MAX_ACCOUNT_LOCKS) {
48518
+ throw TransactionBuildingError.swapSizeExceededPositionSwap(
48750
48519
  txSize,
48751
- writableKeys,
48520
+ totalKeys,
48752
48521
  swapOpts.swapConfig?.provider
48753
48522
  );
48754
48523
  }
@@ -49416,23 +49185,27 @@ var getTitanSwapIxsForFlashloan = async ({
49416
49185
  quoteParams.swapMode === "ExactIn" ? quoteParams.outputMint : quoteParams.inputMint
49417
49186
  );
49418
49187
  const { feeAccount, hasFeeAccount } = await checkTitanFeeAccount(connection, feeMint);
49188
+ const useFeeAccount = hasFeeAccount && !!quoteParams.platformFeeBps;
49419
49189
  let finalQuoteParams = quoteParams;
49420
- if (!hasFeeAccount) {
49421
- console.warn("Warning: Titan fee account ATA does not exist, disabling platform fee");
49190
+ if (!useFeeAccount) {
49191
+ if (!hasFeeAccount) {
49192
+ console.warn("Warning: Titan fee account ATA does not exist, disabling platform fee");
49193
+ }
49422
49194
  finalQuoteParams = {
49423
49195
  ...quoteParams,
49424
49196
  platformFeeBps: void 0
49425
49197
  };
49426
49198
  }
49199
+ const effectiveFeeAccount = useFeeAccount ? feeAccount : void 0;
49427
49200
  if (basePath.startsWith("wss://") || basePath.startsWith("ws://")) {
49428
49201
  return getTitanSwapIxsViaWebSocket(
49429
49202
  { quoteParams: finalQuoteParams, authority, connection, destinationTokenAccount, apiConfig },
49430
- hasFeeAccount ? feeAccount : void 0
49203
+ effectiveFeeAccount
49431
49204
  );
49432
49205
  } else {
49433
49206
  return getTitanSwapIxsViaHttpProxy(
49434
49207
  { quoteParams: finalQuoteParams, authority, connection, destinationTokenAccount, apiConfig },
49435
- hasFeeAccount ? feeAccount : void 0
49208
+ effectiveFeeAccount
49436
49209
  );
49437
49210
  }
49438
49211
  };
@@ -49608,7 +49381,7 @@ async function getTitanExactOutViaWebSocket(params) {
49608
49381
  inputMint: new web3_js.PublicKey(inputMint).toBytes(),
49609
49382
  outputMint: new web3_js.PublicKey(outputMint).toBytes(),
49610
49383
  amount,
49611
- swapMode: "ExactOut",
49384
+ swapMode: "ExactOut" /* ExactOut */,
49612
49385
  slippageBps
49613
49386
  },
49614
49387
  transaction: {
@@ -49695,8 +49468,7 @@ function getSwapProviderFn({
49695
49468
  connection,
49696
49469
  destinationTokenAccount,
49697
49470
  swapOpts,
49698
- sizeConstraint,
49699
- maxSwapAccounts
49471
+ sizeConstraint
49700
49472
  }) {
49701
49473
  switch (attemptProvider) {
49702
49474
  case "TITAN" /* TITAN */:
@@ -49710,7 +49482,6 @@ function getSwapProviderFn({
49710
49482
  platformFeeBps: swapOpts.swapConfig?.platformFeeBps,
49711
49483
  directRoutesOnly: swapOpts.swapConfig?.directRoutesOnly,
49712
49484
  sizeConstraint,
49713
- maxSwapAccounts,
49714
49485
  maxSwapTotalAccounts
49715
49486
  },
49716
49487
  authority,
@@ -49734,7 +49505,7 @@ function getSwapProviderFn({
49734
49505
  connection,
49735
49506
  destinationTokenAccount,
49736
49507
  apiConfig,
49737
- maxSwapAccounts
49508
+ maxSwapAccounts: maxSwapTotalAccounts
49738
49509
  });
49739
49510
  default:
49740
49511
  return void 0;
@@ -49787,7 +49558,7 @@ var getSwapIxsForFlashloan = async (params) => {
49787
49558
  destinationTokenAccount,
49788
49559
  swapOpts,
49789
49560
  sizeConstraint,
49790
- maxSwapAccounts
49561
+ maxSwapTotalAccounts
49791
49562
  } = params;
49792
49563
  if (swapOpts.swapIxs) {
49793
49564
  return {
@@ -49820,8 +49591,7 @@ var getSwapIxsForFlashloan = async (params) => {
49820
49591
  connection,
49821
49592
  destinationTokenAccount,
49822
49593
  swapOpts,
49823
- sizeConstraint,
49824
- maxSwapAccounts
49594
+ sizeConstraint
49825
49595
  });
49826
49596
  if (!fn) continue;
49827
49597
  try {
@@ -49831,178 +49601,616 @@ var getSwapIxsForFlashloan = async (params) => {
49831
49601
  lastError = err;
49832
49602
  console.warn(`[swap] ${attemptProvider} failed:`, err instanceof Error ? err.message : err);
49833
49603
  }
49834
- }
49835
- const firstProvider = attempts[0]?.provider ?? "Swap";
49836
- throw TransactionBuildingError.swapQuoteFailed(
49837
- firstProvider,
49838
- inputMint,
49839
- outputMint,
49840
- lastError?.message ?? "No swap route available"
49841
- );
49842
- };
49843
- var getExactOutEstimate = async (params) => {
49844
- const { inputMint, outputMint, amount, swapOpts, connection } = params;
49845
- const provider = swapOpts.swapConfig?.provider ?? "JUPITER" /* JUPITER */;
49846
- const attempts = [
49847
- { provider, apiConfig: swapOpts.swapConfig?.apiConfig },
49848
- ...swapOpts.swapConfig?.fallbackProviders ?? []
49849
- ];
49850
- let lastError;
49851
- for (const { provider: attemptProvider, apiConfig } of attempts) {
49852
- const fn = getExactOutProviderFn({
49853
- attemptProvider,
49854
- inputMint,
49855
- outputMint,
49856
- amount,
49857
- swapOpts,
49858
- apiConfig
49859
- });
49860
- if (!fn) continue;
49861
- try {
49862
- return await fn(apiConfig);
49863
- } catch (err) {
49864
- if (err instanceof TransactionBuildingError) throw err;
49865
- lastError = err;
49866
- console.warn(
49867
- `[exactout] ${attemptProvider} failed:`,
49868
- err instanceof Error ? err.message : err
49869
- );
49604
+ }
49605
+ const firstProvider = attempts[0]?.provider ?? "Swap";
49606
+ throw TransactionBuildingError.swapQuoteFailed(
49607
+ firstProvider,
49608
+ inputMint,
49609
+ outputMint,
49610
+ lastError?.message ?? "No swap route available"
49611
+ );
49612
+ };
49613
+ var getExactOutEstimate = async (params) => {
49614
+ const { inputMint, outputMint, amount, swapOpts, connection } = params;
49615
+ const provider = swapOpts.swapConfig?.provider ?? "JUPITER" /* JUPITER */;
49616
+ const attempts = [
49617
+ { provider, apiConfig: swapOpts.swapConfig?.apiConfig },
49618
+ ...swapOpts.swapConfig?.fallbackProviders ?? []
49619
+ ];
49620
+ let lastError;
49621
+ for (const { provider: attemptProvider, apiConfig } of attempts) {
49622
+ const fn = getExactOutProviderFn({
49623
+ attemptProvider,
49624
+ inputMint,
49625
+ outputMint,
49626
+ amount,
49627
+ swapOpts,
49628
+ apiConfig
49629
+ });
49630
+ if (!fn) continue;
49631
+ try {
49632
+ return await fn(apiConfig);
49633
+ } catch (err) {
49634
+ if (err instanceof TransactionBuildingError) throw err;
49635
+ lastError = err;
49636
+ console.warn(
49637
+ `[exactout] ${attemptProvider} failed:`,
49638
+ err instanceof Error ? err.message : err
49639
+ );
49640
+ }
49641
+ }
49642
+ const firstProvider = attempts[0]?.provider ?? "Swap";
49643
+ throw TransactionBuildingError.swapQuoteFailed(
49644
+ firstProvider,
49645
+ inputMint,
49646
+ outputMint,
49647
+ lastError?.message ?? "No swap route available"
49648
+ );
49649
+ };
49650
+ function mapJupiterQuoteToSwapQuoteResult(quote) {
49651
+ return {
49652
+ inAmount: quote.inAmount,
49653
+ outAmount: quote.outAmount,
49654
+ otherAmountThreshold: quote.otherAmountThreshold,
49655
+ slippageBps: quote.slippageBps,
49656
+ platformFee: quote.platformFee ? {
49657
+ amount: quote.platformFee.amount ?? "0",
49658
+ feeBps: quote.platformFee.feeBps ?? 0
49659
+ } : void 0,
49660
+ priceImpactPct: quote.priceImpactPct,
49661
+ contextSlot: quote.contextSlot,
49662
+ timeTaken: quote.timeTaken,
49663
+ provider: "JUPITER" /* JUPITER */
49664
+ };
49665
+ }
49666
+
49667
+ // src/services/account/utils/jupiter.utils.ts
49668
+ var REFERRAL_PROGRAM_ID = new web3_js.PublicKey("REFER4ZgmyYx9c6He5XfaTMiGfdLwRnkV4RPp9t9iF3");
49669
+ var REFERRAL_ACCOUNT_PUBKEY = new web3_js.PublicKey("Mm7HcujSK2JzPW4eX7g4oqTXbWYDuFxapNMHXe8yp1B");
49670
+ var getFeeAccount = (mint) => {
49671
+ const [feeAccount] = web3_js.PublicKey.findProgramAddressSync(
49672
+ [Buffer.from("referral_ata"), REFERRAL_ACCOUNT_PUBKEY.toBuffer(), mint.toBuffer()],
49673
+ REFERRAL_PROGRAM_ID
49674
+ );
49675
+ return feeAccount.toBase58();
49676
+ };
49677
+ var checkFeeAccount = async (connection, mint) => {
49678
+ const feeAccount = getFeeAccount(mint);
49679
+ const hasFeeAccount = !!await connection.getAccountInfo(new web3_js.PublicKey(feeAccount));
49680
+ return { feeAccount, hasFeeAccount };
49681
+ };
49682
+ function deserializeJupiterInstruction(instruction) {
49683
+ return new web3_js.TransactionInstruction({
49684
+ programId: new web3_js.PublicKey(instruction.programId),
49685
+ keys: instruction.accounts.map((key) => ({
49686
+ pubkey: new web3_js.PublicKey(key.pubkey),
49687
+ isSigner: key.isSigner,
49688
+ isWritable: key.isWritable
49689
+ })),
49690
+ data: Buffer.from(instruction.data, "base64")
49691
+ });
49692
+ }
49693
+ function toJupiterConfig(apiConfig) {
49694
+ if (!apiConfig) return void 0;
49695
+ return {
49696
+ basePath: apiConfig.basePath,
49697
+ apiKey: apiConfig.apiKey ? () => apiConfig.apiKey : void 0,
49698
+ headers: apiConfig.headers
49699
+ };
49700
+ }
49701
+ var getJupiterSwapIxsForFlashloan = async ({
49702
+ quoteParams,
49703
+ authority,
49704
+ connection,
49705
+ destinationTokenAccount,
49706
+ apiConfig,
49707
+ maxSwapAccounts
49708
+ }) => {
49709
+ const configParams = toJupiterConfig(apiConfig);
49710
+ const jupiterApiClient = configParams?.basePath ? new api.SwapApi(new api.Configuration(configParams)) : api.createJupiterApiClient(configParams);
49711
+ const feeMint = quoteParams.swapMode === "ExactIn" ? quoteParams.outputMint : quoteParams.inputMint;
49712
+ const { feeAccount, hasFeeAccount } = await checkFeeAccount(connection, new web3_js.PublicKey(feeMint));
49713
+ const project0JupiterLut = (await connection.getAddressLookupTable(ADDRESS_LOOKUP_TABLE_FOR_SWAP))?.value;
49714
+ const useFeeAccount = hasFeeAccount && !!quoteParams.platformFeeBps;
49715
+ let finalQuoteParams = quoteParams;
49716
+ if (!useFeeAccount) {
49717
+ if (!hasFeeAccount) {
49718
+ console.warn("Warning: feeAccountInfo is undefined");
49719
+ }
49720
+ finalQuoteParams = {
49721
+ ...quoteParams,
49722
+ platformFeeBps: void 0
49723
+ };
49724
+ }
49725
+ const JUPITER_MAX_ACCOUNTS_MARGIN = 4;
49726
+ const maxAccounts = maxSwapAccounts !== void 0 ? maxSwapAccounts - JUPITER_MAX_ACCOUNTS_MARGIN : 40;
49727
+ const swapQuote = await jupiterApiClient.quoteGet({
49728
+ ...finalQuoteParams,
49729
+ maxAccounts
49730
+ });
49731
+ const swapInstructionResponse = await jupiterApiClient.swapInstructionsPost({
49732
+ swapRequest: {
49733
+ quoteResponse: swapQuote,
49734
+ userPublicKey: authority.toBase58(),
49735
+ feeAccount: useFeeAccount ? feeAccount : void 0,
49736
+ wrapAndUnwrapSol: false,
49737
+ destinationTokenAccount: destinationTokenAccount.toBase58()
49738
+ }
49739
+ });
49740
+ const lutAddresses = swapInstructionResponse.addressLookupTableAddresses;
49741
+ const lutAccountsRaw = await connection.getMultipleAccountsInfo(
49742
+ lutAddresses.map((address) => new web3_js.PublicKey(address))
49743
+ );
49744
+ const addressLookupTableAccounts = lutAccountsRaw.map((accountInfo, index) => {
49745
+ const addressLookupTableAddress = lutAddresses[index];
49746
+ if (!accountInfo || !addressLookupTableAddress) {
49747
+ return null;
49748
+ }
49749
+ return new web3_js.AddressLookupTableAccount({
49750
+ key: new web3_js.PublicKey(addressLookupTableAddress),
49751
+ state: web3_js.AddressLookupTableAccount.deserialize(accountInfo.data)
49752
+ });
49753
+ }).filter((account) => account !== null).concat(project0JupiterLut ? [project0JupiterLut] : []);
49754
+ const instruction = deserializeJupiterInstruction(swapInstructionResponse.swapInstruction);
49755
+ const setupInstructions = swapInstructionResponse.setupInstructions.map(
49756
+ deserializeJupiterInstruction
49757
+ );
49758
+ return {
49759
+ swapInstructions: [instruction],
49760
+ setupInstructions,
49761
+ addressLookupTableAddresses: addressLookupTableAccounts,
49762
+ quoteResponse: mapJupiterQuoteToSwapQuoteResult(swapQuote)
49763
+ };
49764
+ };
49765
+
49766
+ // src/services/account/utils/misc.utils.ts
49767
+ function floor(value, decimals) {
49768
+ return Math.floor(value * 10 ** decimals) / 10 ** decimals;
49769
+ }
49770
+ function ceil(value, decimals) {
49771
+ return Math.ceil(value * 10 ** decimals) / 10 ** decimals;
49772
+ }
49773
+ function computeClosePositionTokenAmount(position, mintDecimals) {
49774
+ const closePositionTokenAmount = position.isLending ? floor(position.amount, mintDecimals) : ceil(position.amount, mintDecimals);
49775
+ return closePositionTokenAmount;
49776
+ }
49777
+ function isWholePosition(position, amount, mintDecimals) {
49778
+ const closePositionTokenAmount = computeClosePositionTokenAmount(position, mintDecimals);
49779
+ return amount >= closePositionTokenAmount;
49780
+ }
49781
+ var SWAP_MERGE_OVERHEAD = 150;
49782
+ var FL_IX_OVERHEAD = 52;
49783
+ function compactU16Size(n) {
49784
+ return n < 128 ? 1 : n < 16384 ? 2 : 3;
49785
+ }
49786
+ function computeV0TxSize(ixs, payerKey, luts) {
49787
+ const keyMap = /* @__PURE__ */ new Map();
49788
+ const payerStr = payerKey.toBase58();
49789
+ keyMap.set(payerStr, { isSigner: true, isWritable: true });
49790
+ const programIds = /* @__PURE__ */ new Set();
49791
+ for (const ix of ixs) {
49792
+ const progStr = ix.programId.toBase58();
49793
+ programIds.add(progStr);
49794
+ if (!keyMap.has(progStr)) {
49795
+ keyMap.set(progStr, { isSigner: false, isWritable: false });
49796
+ }
49797
+ for (const meta of ix.keys) {
49798
+ const keyStr = meta.pubkey.toBase58();
49799
+ const existing = keyMap.get(keyStr);
49800
+ if (existing) {
49801
+ existing.isSigner = existing.isSigner || meta.isSigner;
49802
+ existing.isWritable = existing.isWritable || meta.isWritable;
49803
+ } else {
49804
+ keyMap.set(keyStr, { isSigner: meta.isSigner, isWritable: meta.isWritable });
49805
+ }
49806
+ }
49807
+ }
49808
+ const lutLookup = /* @__PURE__ */ new Map();
49809
+ for (let li = 0; li < luts.length; li++) {
49810
+ const addresses = luts[li].state.addresses;
49811
+ for (let ai = 0; ai < addresses.length; ai++) {
49812
+ const addrStr = addresses[ai].toBase58();
49813
+ if (!lutLookup.has(addrStr)) {
49814
+ lutLookup.set(addrStr, { lutIdx: li, addrIdx: ai });
49815
+ }
49816
+ }
49817
+ }
49818
+ let numStaticKeys = 0;
49819
+ let numWritableStaticKeys = 0;
49820
+ const lutWritableIdxs = luts.map(() => /* @__PURE__ */ new Set());
49821
+ const lutReadonlyIdxs = luts.map(() => /* @__PURE__ */ new Set());
49822
+ for (const [keyStr, props] of keyMap) {
49823
+ if (props.isSigner || programIds.has(keyStr)) {
49824
+ numStaticKeys++;
49825
+ if (props.isWritable) numWritableStaticKeys++;
49826
+ continue;
49827
+ }
49828
+ const lutEntry = lutLookup.get(keyStr);
49829
+ if (lutEntry) {
49830
+ if (props.isWritable) {
49831
+ lutWritableIdxs[lutEntry.lutIdx].add(lutEntry.addrIdx);
49832
+ } else {
49833
+ lutReadonlyIdxs[lutEntry.lutIdx].add(lutEntry.addrIdx);
49834
+ }
49835
+ } else {
49836
+ numStaticKeys++;
49837
+ if (props.isWritable) numWritableStaticKeys++;
49838
+ }
49839
+ }
49840
+ const fixedOverhead = 101;
49841
+ const staticKeysSection = compactU16Size(numStaticKeys) + numStaticKeys * 32;
49842
+ let ixSection = compactU16Size(ixs.length);
49843
+ for (const ix of ixs) {
49844
+ const numAccounts = ix.keys.length;
49845
+ ixSection += 1 + // programId index
49846
+ compactU16Size(numAccounts) + numAccounts + // account key indexes
49847
+ compactU16Size(ix.data.length) + ix.data.length;
49848
+ }
49849
+ let numUsedLuts = 0;
49850
+ let lutSection = 0;
49851
+ for (let li = 0; li < luts.length; li++) {
49852
+ const wCount = lutWritableIdxs[li].size;
49853
+ const rCount = lutReadonlyIdxs[li].size;
49854
+ if (wCount === 0 && rCount === 0) continue;
49855
+ numUsedLuts++;
49856
+ lutSection += 32 + // LUT address
49857
+ compactU16Size(wCount) + wCount + // writable indexes
49858
+ compactU16Size(rCount) + rCount;
49859
+ }
49860
+ lutSection += compactU16Size(numUsedLuts);
49861
+ let totalLutKeys = 0;
49862
+ for (let li = 0; li < luts.length; li++) {
49863
+ totalLutKeys += lutWritableIdxs[li].size + lutReadonlyIdxs[li].size;
49864
+ }
49865
+ const accountCount = numStaticKeys + totalLutKeys;
49866
+ let totalLutWritableKeys = 0;
49867
+ for (let li = 0; li < luts.length; li++) {
49868
+ totalLutWritableKeys += lutWritableIdxs[li].size;
49869
+ }
49870
+ const writableAccountCount = numWritableStaticKeys + totalLutWritableKeys;
49871
+ const size = fixedOverhead + staticKeysSection + ixSection + lutSection + 1;
49872
+ return { size, accountCount, writableAccountCount };
49873
+ }
49874
+ function computeFlashLoanNonSwapBudget({
49875
+ program,
49876
+ marginfiAccount,
49877
+ ixs,
49878
+ bankMap,
49879
+ addressLookupTableAccounts
49880
+ }) {
49881
+ const projectedActiveBanksKeys = computeProjectedActiveBanksNoCpi(
49882
+ marginfiAccount.balances,
49883
+ ixs,
49884
+ program
49885
+ );
49886
+ const projectedActiveBanks = projectedActiveBanksKeys.map((key) => {
49887
+ const b = bankMap.get(key.toBase58());
49888
+ if (!b) throw new Error(`Bank ${key.toBase58()} not found in computeFlashLoanNonSwapBudget`);
49889
+ return b;
49890
+ });
49891
+ const endIndex = ixs.length + 1;
49892
+ const beginFlIx = sync_instructions_default.makeBeginFlashLoanIx(
49893
+ program.programId,
49894
+ { marginfiAccount: marginfiAccount.address, authority: marginfiAccount.authority },
49895
+ { endIndex: new BN11__default.default(endIndex) }
49896
+ );
49897
+ const endFlRemainingAccounts = computeHealthAccountMetas(projectedActiveBanks);
49898
+ const endFlIx = sync_instructions_default.makeEndFlashLoanIx(
49899
+ program.programId,
49900
+ { marginfiAccount: marginfiAccount.address, authority: marginfiAccount.authority },
49901
+ endFlRemainingAccounts.map((pubkey) => ({ pubkey, isSigner: false, isWritable: false }))
49902
+ );
49903
+ const allNonSwapIxs = [beginFlIx, ...ixs, endFlIx];
49904
+ const nonSwapMsg = new web3_js.TransactionMessage({
49905
+ payerKey: marginfiAccount.authority,
49906
+ recentBlockhash: web3_js.PublicKey.default.toBase58(),
49907
+ instructions: allNonSwapIxs
49908
+ }).compileToV0Message(addressLookupTableAccounts);
49909
+ const nonSwapSize = new web3_js.VersionedTransaction(nonSwapMsg).serialize().length;
49910
+ const { header, staticAccountKeys, addressTableLookups } = nonSwapMsg;
49911
+ const nonSwapTotal = staticAccountKeys.length + addressTableLookups.reduce(
49912
+ (s, l) => s + l.writableIndexes.length + l.readonlyIndexes.length,
49913
+ 0
49914
+ );
49915
+ const sizeConstraint = MAX_TX_SIZE - nonSwapSize - SWAP_MERGE_OVERHEAD;
49916
+ const maxSwapTotalAccounts = MAX_ACCOUNT_LOCKS - nonSwapTotal;
49917
+ console.log("[flashloan-budget]", {
49918
+ method: "compiled",
49919
+ nonSwapSize,
49920
+ nonSwapTotal,
49921
+ sizeConstraint,
49922
+ maxSwapTotalAccounts
49923
+ });
49924
+ return { sizeConstraint, maxSwapTotalAccounts };
49925
+ }
49926
+ function compileFlashloanPrecheck({
49927
+ allIxs,
49928
+ payer,
49929
+ luts,
49930
+ sizeConstraint,
49931
+ swapIxCount,
49932
+ swapLutCount
49933
+ }) {
49934
+ const msg = new web3_js.TransactionMessage({
49935
+ payerKey: payer,
49936
+ recentBlockhash: web3_js.PublicKey.default.toBase58(),
49937
+ instructions: allIxs
49938
+ }).compileToV0Message(luts);
49939
+ const rawSize = new web3_js.VersionedTransaction(msg).serialize().length;
49940
+ const fullTxSize = rawSize + FL_IX_OVERHEAD;
49941
+ const overshoot = fullTxSize - MAX_TX_SIZE;
49942
+ const { header, staticAccountKeys, addressTableLookups } = msg;
49943
+ const writableStatic = staticAccountKeys.length - header.numReadonlySignedAccounts - header.numReadonlyUnsignedAccounts;
49944
+ const writableLut = addressTableLookups.reduce((s, l) => s + l.writableIndexes.length, 0);
49945
+ const writableAccounts = writableStatic + writableLut;
49946
+ const totalAccounts = staticAccountKeys.length + addressTableLookups.reduce(
49947
+ (s, l) => s + l.writableIndexes.length + l.readonlyIndexes.length,
49948
+ 0
49949
+ );
49950
+ console.log("[flashloan-precheck]", {
49951
+ fullTxSize,
49952
+ overshoot,
49953
+ sizeConstraint,
49954
+ writableAccounts,
49955
+ totalAccounts,
49956
+ staticKeys: staticAccountKeys.length,
49957
+ numLuts: addressTableLookups.length,
49958
+ swapIxCount,
49959
+ swapLutCount
49960
+ });
49961
+ return { fullTxSize, overshoot, writableAccounts, totalAccounts };
49962
+ }
49963
+ async function buildBudgetIx(config, program, marginfiAccount, bankMap, bankMetadataMap, overrideInferAccounts) {
49964
+ const { bank, tokenProgram } = config;
49965
+ switch (config.type) {
49966
+ case "borrow":
49967
+ return makeBorrowIx3({
49968
+ program,
49969
+ bank,
49970
+ bankMap,
49971
+ tokenProgram,
49972
+ amount: 1,
49973
+ marginfiAccount,
49974
+ authority: marginfiAccount.authority,
49975
+ isSync: true,
49976
+ opts: { createAtas: false, wrapAndUnwrapSol: false, overrideInferAccounts }
49977
+ });
49978
+ case "repay":
49979
+ return makeRepayIx3({
49980
+ program,
49981
+ bank,
49982
+ tokenProgram,
49983
+ amount: 1,
49984
+ accountAddress: marginfiAccount.address,
49985
+ authority: marginfiAccount.authority,
49986
+ repayAll: false,
49987
+ isSync: true,
49988
+ opts: { wrapAndUnwrapSol: false, overrideInferAccounts }
49989
+ });
49990
+ case "deposit":
49991
+ return buildDepositBudgetIx(
49992
+ config,
49993
+ program,
49994
+ marginfiAccount,
49995
+ bankMetadataMap,
49996
+ overrideInferAccounts
49997
+ );
49998
+ case "withdraw":
49999
+ return buildWithdrawBudgetIx(
50000
+ config,
50001
+ program,
50002
+ marginfiAccount,
50003
+ bankMap,
50004
+ bankMetadataMap,
50005
+ overrideInferAccounts
50006
+ );
50007
+ }
50008
+ }
50009
+ async function buildDepositBudgetIx(config, program, marginfiAccount, bankMetadataMap, overrideInferAccounts) {
50010
+ const { bank, tokenProgram } = config;
50011
+ const opts = { wrapAndUnwrapSol: false, overrideInferAccounts };
50012
+ switch (bank.config.assetTag) {
50013
+ case 3 /* KAMINO */: {
50014
+ const reserve = bankMetadataMap[bank.address.toBase58()]?.kaminoStates?.reserveState;
50015
+ if (!reserve) {
50016
+ throw TransactionBuildingError.kaminoReserveNotFound(
50017
+ bank.address.toBase58(),
50018
+ bank.mint.toBase58(),
50019
+ bank.tokenSymbol
50020
+ );
50021
+ }
50022
+ return makeKaminoDepositIx3({
50023
+ program,
50024
+ bank,
50025
+ tokenProgram,
50026
+ amount: 1,
50027
+ accountAddress: marginfiAccount.address,
50028
+ authority: marginfiAccount.authority,
50029
+ group: marginfiAccount.group,
50030
+ reserve,
50031
+ isSync: true,
50032
+ opts
50033
+ });
50034
+ }
50035
+ case 4 /* DRIFT */: {
50036
+ const driftState = bankMetadataMap[bank.address.toBase58()]?.driftStates;
50037
+ if (!driftState) {
50038
+ throw TransactionBuildingError.driftStateNotFound(
50039
+ bank.address.toBase58(),
50040
+ bank.mint.toBase58(),
50041
+ bank.tokenSymbol
50042
+ );
50043
+ }
50044
+ return makeDriftDepositIx3({
50045
+ program,
50046
+ bank,
50047
+ tokenProgram,
50048
+ amount: 1,
50049
+ accountAddress: marginfiAccount.address,
50050
+ authority: marginfiAccount.authority,
50051
+ group: marginfiAccount.group,
50052
+ driftMarketIndex: driftState.spotMarketState.marketIndex,
50053
+ driftOracle: driftState.spotMarketState.oracle,
50054
+ isSync: true,
50055
+ opts
50056
+ });
50057
+ }
50058
+ case 6 /* JUPLEND */: {
50059
+ return makeJuplendDepositIx2({
50060
+ program,
50061
+ bank,
50062
+ tokenProgram,
50063
+ amount: 1,
50064
+ accountAddress: marginfiAccount.address,
50065
+ authority: marginfiAccount.authority,
50066
+ group: marginfiAccount.group,
50067
+ isSync: true,
50068
+ opts
50069
+ });
50070
+ }
50071
+ default: {
50072
+ return makeDepositIx3({
50073
+ program,
50074
+ bank,
50075
+ tokenProgram,
50076
+ amount: 1,
50077
+ accountAddress: marginfiAccount.address,
50078
+ authority: marginfiAccount.authority,
50079
+ group: marginfiAccount.group,
50080
+ isSync: true,
50081
+ opts
50082
+ });
49870
50083
  }
49871
50084
  }
49872
- const firstProvider = attempts[0]?.provider ?? "Swap";
49873
- throw TransactionBuildingError.swapQuoteFailed(
49874
- firstProvider,
49875
- inputMint,
49876
- outputMint,
49877
- lastError?.message ?? "No swap route available"
49878
- );
49879
- };
49880
- function mapJupiterQuoteToSwapQuoteResult(quote) {
49881
- return {
49882
- inAmount: quote.inAmount,
49883
- outAmount: quote.outAmount,
49884
- otherAmountThreshold: quote.otherAmountThreshold,
49885
- slippageBps: quote.slippageBps,
49886
- platformFee: quote.platformFee ? {
49887
- amount: quote.platformFee.amount ?? "0",
49888
- feeBps: quote.platformFee.feeBps ?? 0
49889
- } : void 0,
49890
- priceImpactPct: quote.priceImpactPct,
49891
- contextSlot: quote.contextSlot,
49892
- timeTaken: quote.timeTaken,
49893
- provider: "JUPITER" /* JUPITER */
49894
- };
49895
- }
49896
-
49897
- // src/services/account/utils/jupiter.utils.ts
49898
- var REFERRAL_PROGRAM_ID = new web3_js.PublicKey("REFER4ZgmyYx9c6He5XfaTMiGfdLwRnkV4RPp9t9iF3");
49899
- var REFERRAL_ACCOUNT_PUBKEY = new web3_js.PublicKey("Mm7HcujSK2JzPW4eX7g4oqTXbWYDuFxapNMHXe8yp1B");
49900
- var getFeeAccount = (mint) => {
49901
- const [feeAccount] = web3_js.PublicKey.findProgramAddressSync(
49902
- [Buffer.from("referral_ata"), REFERRAL_ACCOUNT_PUBKEY.toBuffer(), mint.toBuffer()],
49903
- REFERRAL_PROGRAM_ID
49904
- );
49905
- return feeAccount.toBase58();
49906
- };
49907
- var checkFeeAccount = async (connection, mint) => {
49908
- const feeAccount = getFeeAccount(mint);
49909
- const hasFeeAccount = !!await connection.getAccountInfo(new web3_js.PublicKey(feeAccount));
49910
- return { feeAccount, hasFeeAccount };
49911
- };
49912
- function deserializeJupiterInstruction(instruction) {
49913
- return new web3_js.TransactionInstruction({
49914
- programId: new web3_js.PublicKey(instruction.programId),
49915
- keys: instruction.accounts.map((key) => ({
49916
- pubkey: new web3_js.PublicKey(key.pubkey),
49917
- isSigner: key.isSigner,
49918
- isWritable: key.isWritable
49919
- })),
49920
- data: Buffer.from(instruction.data, "base64")
49921
- });
49922
- }
49923
- function toJupiterConfig(apiConfig) {
49924
- if (!apiConfig) return void 0;
49925
- return {
49926
- basePath: apiConfig.basePath,
49927
- apiKey: apiConfig.apiKey ? () => apiConfig.apiKey : void 0,
49928
- headers: apiConfig.headers
49929
- };
49930
50085
  }
49931
- var getJupiterSwapIxsForFlashloan = async ({
49932
- quoteParams,
49933
- authority,
49934
- connection,
49935
- destinationTokenAccount,
49936
- apiConfig,
49937
- maxSwapAccounts
49938
- }) => {
49939
- const configParams = toJupiterConfig(apiConfig);
49940
- const jupiterApiClient = configParams?.basePath ? new api.SwapApi(new api.Configuration(configParams)) : api.createJupiterApiClient(configParams);
49941
- const feeMint = quoteParams.swapMode === "ExactIn" ? quoteParams.outputMint : quoteParams.inputMint;
49942
- const { feeAccount, hasFeeAccount } = await checkFeeAccount(connection, new web3_js.PublicKey(feeMint));
49943
- const project0JupiterLut = (await connection.getAddressLookupTable(ADDRESS_LOOKUP_TABLE_FOR_SWAP))?.value;
49944
- let finalQuoteParams = quoteParams;
49945
- if (!hasFeeAccount) {
49946
- console.warn("Warning: feeAccountInfo is undefined");
49947
- finalQuoteParams = {
49948
- ...quoteParams,
49949
- platformFeeBps: void 0
49950
- };
49951
- }
49952
- const maxAccounts = maxSwapAccounts ?? 40;
49953
- const swapQuote = await jupiterApiClient.quoteGet({
49954
- ...finalQuoteParams,
49955
- maxAccounts
49956
- });
49957
- const swapInstructionResponse = await jupiterApiClient.swapInstructionsPost({
49958
- swapRequest: {
49959
- quoteResponse: swapQuote,
49960
- userPublicKey: authority.toBase58(),
49961
- feeAccount: hasFeeAccount ? feeAccount : void 0,
49962
- wrapAndUnwrapSol: false,
49963
- destinationTokenAccount: destinationTokenAccount.toBase58()
50086
+ async function buildWithdrawBudgetIx(config, program, marginfiAccount, bankMap, bankMetadataMap, overrideInferAccounts) {
50087
+ const { bank, tokenProgram } = config;
50088
+ const opts = { createAtas: false, wrapAndUnwrapSol: false, overrideInferAccounts };
50089
+ switch (bank.config.assetTag) {
50090
+ case 3 /* KAMINO */: {
50091
+ const reserve = bankMetadataMap[bank.address.toBase58()]?.kaminoStates?.reserveState;
50092
+ if (!reserve) {
50093
+ throw TransactionBuildingError.kaminoReserveNotFound(
50094
+ bank.address.toBase58(),
50095
+ bank.mint.toBase58(),
50096
+ bank.tokenSymbol
50097
+ );
50098
+ }
50099
+ return makeKaminoWithdrawIx3({
50100
+ program,
50101
+ bank,
50102
+ bankMap,
50103
+ tokenProgram,
50104
+ cTokenAmount: 1,
50105
+ marginfiAccount,
50106
+ authority: marginfiAccount.authority,
50107
+ reserve,
50108
+ withdrawAll: false,
50109
+ isSync: true,
50110
+ opts
50111
+ });
49964
50112
  }
49965
- });
49966
- const lutAddresses = swapInstructionResponse.addressLookupTableAddresses;
49967
- const lutAccountsRaw = await connection.getMultipleAccountsInfo(
49968
- lutAddresses.map((address) => new web3_js.PublicKey(address))
49969
- );
49970
- const addressLookupTableAccounts = lutAccountsRaw.map((accountInfo, index) => {
49971
- const addressLookupTableAddress = lutAddresses[index];
49972
- if (!accountInfo || !addressLookupTableAddress) {
49973
- return null;
50113
+ case 4 /* DRIFT */: {
50114
+ const driftState = bankMetadataMap[bank.address.toBase58()]?.driftStates;
50115
+ if (!driftState) {
50116
+ throw TransactionBuildingError.driftStateNotFound(
50117
+ bank.address.toBase58(),
50118
+ bank.mint.toBase58(),
50119
+ bank.tokenSymbol
50120
+ );
50121
+ }
50122
+ return makeDriftWithdrawIx3({
50123
+ program,
50124
+ bank,
50125
+ bankMap,
50126
+ tokenProgram,
50127
+ amount: 1,
50128
+ marginfiAccount,
50129
+ authority: marginfiAccount.authority,
50130
+ driftSpotMarket: driftState.spotMarketState,
50131
+ userRewards: driftState.userRewards,
50132
+ withdrawAll: false,
50133
+ isSync: true,
50134
+ opts
50135
+ });
49974
50136
  }
49975
- return new web3_js.AddressLookupTableAccount({
49976
- key: new web3_js.PublicKey(addressLookupTableAddress),
49977
- state: web3_js.AddressLookupTableAccount.deserialize(accountInfo.data)
49978
- });
49979
- }).filter((account) => account !== null).concat(project0JupiterLut ? [project0JupiterLut] : []);
49980
- const instruction = deserializeJupiterInstruction(swapInstructionResponse.swapInstruction);
49981
- const setupInstructions = swapInstructionResponse.setupInstructions.map(
49982
- deserializeJupiterInstruction
49983
- );
49984
- return {
49985
- swapInstructions: [instruction],
49986
- setupInstructions,
49987
- addressLookupTableAddresses: addressLookupTableAccounts,
49988
- quoteResponse: mapJupiterQuoteToSwapQuoteResult(swapQuote)
49989
- };
49990
- };
49991
-
49992
- // src/services/account/utils/misc.utils.ts
49993
- function floor(value, decimals) {
49994
- return Math.floor(value * 10 ** decimals) / 10 ** decimals;
49995
- }
49996
- function ceil(value, decimals) {
49997
- return Math.ceil(value * 10 ** decimals) / 10 ** decimals;
49998
- }
49999
- function computeClosePositionTokenAmount(position, mintDecimals) {
50000
- const closePositionTokenAmount = position.isLending ? floor(position.amount, mintDecimals) : ceil(position.amount, mintDecimals);
50001
- return closePositionTokenAmount;
50137
+ case 6 /* JUPLEND */: {
50138
+ const jupLendState = bankMetadataMap[bank.address.toBase58()]?.jupLendStates;
50139
+ if (!jupLendState) {
50140
+ throw TransactionBuildingError.jupLendStateNotFound(
50141
+ bank.address.toBase58(),
50142
+ bank.mint.toBase58(),
50143
+ bank.tokenSymbol
50144
+ );
50145
+ }
50146
+ return makeJuplendWithdrawIx2({
50147
+ program,
50148
+ bank,
50149
+ bankMap,
50150
+ tokenProgram,
50151
+ amount: 1,
50152
+ marginfiAccount,
50153
+ authority: marginfiAccount.authority,
50154
+ jupLendingState: jupLendState.jupLendingState,
50155
+ withdrawAll: false,
50156
+ opts
50157
+ });
50158
+ }
50159
+ default: {
50160
+ return makeWithdrawIx3({
50161
+ program,
50162
+ bank,
50163
+ bankMap,
50164
+ tokenProgram,
50165
+ amount: 1,
50166
+ marginfiAccount,
50167
+ authority: marginfiAccount.authority,
50168
+ withdrawAll: false,
50169
+ isSync: true,
50170
+ opts
50171
+ });
50172
+ }
50173
+ }
50002
50174
  }
50003
- function isWholePosition(position, amount, mintDecimals) {
50004
- const closePositionTokenAmount = computeClosePositionTokenAmount(position, mintDecimals);
50005
- return amount >= closePositionTokenAmount;
50175
+ async function computeFlashloanSwapConstraints({
50176
+ program,
50177
+ marginfiAccount,
50178
+ bankMap,
50179
+ addressLookupTableAccounts,
50180
+ bankMetadataMap,
50181
+ primaryIx,
50182
+ secondaryIx,
50183
+ overrideInferAccounts
50184
+ }) {
50185
+ const cuRequestIxs = [
50186
+ web3_js.ComputeBudgetProgram.setComputeUnitLimit({ units: 12e5 }),
50187
+ web3_js.ComputeBudgetProgram.setComputeUnitPrice({ microLamports: 1 })
50188
+ ];
50189
+ const [primaryResult, secondaryResult] = await Promise.all([
50190
+ buildBudgetIx(
50191
+ primaryIx,
50192
+ program,
50193
+ marginfiAccount,
50194
+ bankMap,
50195
+ bankMetadataMap,
50196
+ overrideInferAccounts
50197
+ ),
50198
+ buildBudgetIx(
50199
+ secondaryIx,
50200
+ program,
50201
+ marginfiAccount,
50202
+ bankMap,
50203
+ bankMetadataMap,
50204
+ overrideInferAccounts
50205
+ )
50206
+ ]);
50207
+ return computeFlashLoanNonSwapBudget({
50208
+ program,
50209
+ marginfiAccount,
50210
+ bankMap,
50211
+ addressLookupTableAccounts,
50212
+ ixs: [...cuRequestIxs, ...primaryResult.instructions, ...secondaryResult.instructions]
50213
+ });
50006
50214
  }
50007
50215
 
50008
50216
  // src/services/price/utils/smart-crank.utils.ts
@@ -50670,18 +50878,15 @@ var fetchPythOracleData = async (banks, opts) => {
50670
50878
  bankOraclePriceMap: /* @__PURE__ */ new Map()
50671
50879
  };
50672
50880
  }
50673
- pythStakedCollateralBanks.map((bank) => [
50674
- opts.validatorVoteAccountByBank?.[bank.address.toBase58()] ?? "",
50675
- bank.mint.toBase58()
50676
- ]);
50677
- const priceCoeffByBank = {};
50678
50881
  const combinedPythBanks = [
50679
50882
  ...pythPushBanks,
50883
+ ...pythStakedCollateralBanks,
50680
50884
  ...pythPushKaminosBanks,
50681
50885
  ...driftPythPullBanks,
50682
50886
  ...solendPythPullBanks,
50683
50887
  ...juplendPythPullBanks
50684
50888
  ];
50889
+ const priceCoeffByBank = {};
50685
50890
  const pythOracleKeys = extractPythOracleKeys(combinedPythBanks);
50686
50891
  const uniquePythOracleKeys = Array.from(new Set(pythOracleKeys));
50687
50892
  let oraclePrices;
@@ -51485,6 +51690,78 @@ function computeRemainingCapacity(bank) {
51485
51690
  };
51486
51691
  }
51487
51692
 
51693
+ // src/services/bank/utils/bank-metrics.utils.ts
51694
+ function computeBankTotalDeposits(bank, assetShareValueMultiplier) {
51695
+ const totalAssets = getTotalAssetQuantity(bank).times(
51696
+ assetShareValueMultiplier ?? 1
51697
+ );
51698
+ return nativeToUi(totalAssets, bank.mintDecimals);
51699
+ }
51700
+ function computeBankTotalBorrows(bank) {
51701
+ return nativeToUi(getTotalLiabilityQuantity(bank), bank.mintDecimals);
51702
+ }
51703
+ function computeBankTotalDepositsUsd(bank, oraclePrice, assetShareValueMultiplier) {
51704
+ return computeUsdValue({
51705
+ bank,
51706
+ oraclePrice,
51707
+ quantity: getTotalAssetQuantity(bank),
51708
+ priceBias: 1 /* None */,
51709
+ isWeightedPrice: false,
51710
+ assetShareValueMultiplier
51711
+ }).toNumber();
51712
+ }
51713
+ function computeBankTotalBorrowsUsd(bank, oraclePrice) {
51714
+ return computeUsdValue({
51715
+ bank,
51716
+ oraclePrice,
51717
+ quantity: getTotalLiabilityQuantity(bank),
51718
+ priceBias: 1 /* None */,
51719
+ isWeightedPrice: false
51720
+ }).toNumber();
51721
+ }
51722
+ function computeBankPoolSize(bank, assetShareValueMultiplier) {
51723
+ const totalDeposits = computeBankTotalDeposits(bank, assetShareValueMultiplier);
51724
+ const totalBorrows = computeBankTotalBorrows(bank);
51725
+ const borrowCap = nativeToUi(bank.config.borrowLimit, bank.mintDecimals);
51726
+ return Math.max(0, Math.min(totalDeposits, borrowCap) - totalBorrows);
51727
+ }
51728
+ function computeBankDepositCapRemaining(bank) {
51729
+ const { depositCapacity } = computeRemainingCapacity(bank);
51730
+ return Math.max(0, nativeToUi(depositCapacity, bank.mintDecimals));
51731
+ }
51732
+ function computeBankBorrowCapRemaining(bank) {
51733
+ const { borrowCapacity } = computeRemainingCapacity(bank);
51734
+ return Math.max(0, nativeToUi(borrowCapacity, bank.mintDecimals));
51735
+ }
51736
+ function computeBankSupplyApy(bank) {
51737
+ return aprToApy(computeInterestRates(bank).lendingRate.toNumber());
51738
+ }
51739
+ function computeBankBorrowApy(bank) {
51740
+ return aprToApy(computeInterestRates(bank).borrowingRate.toNumber());
51741
+ }
51742
+ function computeBankMetrics(params) {
51743
+ const { bank, oraclePrice, assetShareValueMultiplier, symbol = "" } = params;
51744
+ return {
51745
+ symbol,
51746
+ totalDeposits: computeBankTotalDeposits(bank, assetShareValueMultiplier),
51747
+ totalBorrows: computeBankTotalBorrows(bank),
51748
+ totalDepositsUsd: computeBankTotalDepositsUsd(
51749
+ bank,
51750
+ oraclePrice,
51751
+ assetShareValueMultiplier
51752
+ ),
51753
+ totalBorrowsUsd: computeBankTotalBorrowsUsd(bank, oraclePrice),
51754
+ utilizationRate: computeUtilizationRate(bank).toNumber(),
51755
+ poolSize: computeBankPoolSize(bank, assetShareValueMultiplier),
51756
+ depositCap: nativeToUi(bank.config.depositLimit, bank.mintDecimals),
51757
+ borrowCap: nativeToUi(bank.config.borrowLimit, bank.mintDecimals),
51758
+ depositCapRemaining: computeBankDepositCapRemaining(bank),
51759
+ borrowCapRemaining: computeBankBorrowCapRemaining(bank),
51760
+ supplyApy: computeBankSupplyApy(bank),
51761
+ borrowApy: computeBankBorrowApy(bank)
51762
+ };
51763
+ }
51764
+
51488
51765
  // src/services/bank/bank.service.ts
51489
51766
  async function freezeBankConfigIx(program, bankAddress, bankConfigOpt) {
51490
51767
  let bankConfigRaw;
@@ -51886,6 +52163,613 @@ function dtoToValidatorStakeGroup(validatorStakeGroupDto) {
51886
52163
  }))
51887
52164
  };
51888
52165
  }
52166
+
52167
+ // src/services/native-stake/utils/metadata.data.ts
52168
+ var STAKED_BANK_METADATA_JSON = [
52169
+ {
52170
+ bankAddress: "8g5qG6PVygcVSXV1cJnjXaD1yhrDwcWAMQCY2wR9VuAf",
52171
+ validatorVoteAccount: "CooLbbZy5Xmdt7DiHPQ3ss2uRXawnTXXVgpMS8E8jDzr",
52172
+ tokenAddress: "BADo3D6nMtGnsAaTv3iEes8mMcq92TuFoBWebFe8kzeA",
52173
+ tokenName: "Cavey Cool",
52174
+ tokenSymbol: "COOL"
52175
+ },
52176
+ {
52177
+ bankAddress: "BuCckNm1djpp3vZVhvh1CrrniirY6sr2hwUmeP5kTcGz",
52178
+ validatorVoteAccount: "mrgn4t2JabSgvGnrCaHXMvz8ocr4F52scsxJnkQMQsQ",
52179
+ tokenAddress: "FUyAyVbYrMfiaN1QEQYFZTuBNzW5EJf3jWzjjymGqKLv",
52180
+ tokenName: "Project 0 Meridian",
52181
+ tokenSymbol: "MERIDIAN"
52182
+ },
52183
+ {
52184
+ bankAddress: "Hco1P3dGRXz3ZGFvMkbDgghZQy47Tp7vp7koSYRvP6nm",
52185
+ validatorVoteAccount: "mrgn6ETrBDM8mjjYN8rbVwFqVwF8z6rtmvGLbdGuVUU",
52186
+ tokenAddress: "A4B5MGQvcZCUqeiUEAB4ckZ2tvH2UmEg31vF7TiERDkH",
52187
+ tokenName: "MRGN 3",
52188
+ tokenSymbol: "MRGN3"
52189
+ },
52190
+ {
52191
+ bankAddress: "EPh2abWP8DusPH8myWnECAAeQUZgAz927aMbmwXt3eRY",
52192
+ validatorVoteAccount: "mrgn2vsZ5EJ8YEfAMNPXmRux7th9cNfBasQ1JJvVwPn",
52193
+ tokenAddress: "6Mt7tBWLUJfDxqCFTsjoRXF9wD55g4Lhs5nAyYp244pX",
52194
+ tokenName: "Project 0 Horizon",
52195
+ tokenSymbol: "HORIZON"
52196
+ },
52197
+ {
52198
+ bankAddress: "6wjAwhnxTMEzHk8NNHVXgkx1jSrb6TX1bC17j3S56FfB",
52199
+ validatorVoteAccount: "3N7s9zXMZ4QqvHQR15t5GNHyqc89KduzMP7423eWiD5g",
52200
+ tokenAddress: "DKPvRV4dxUejjGpr2XwFmzZbbbTD7vx9Jmt1kk43n4d5",
52201
+ tokenName: "Binance",
52202
+ tokenSymbol: "BINANCE"
52203
+ },
52204
+ {
52205
+ bankAddress: "J9tksvZEDSwtNtZ6yxYjWDDkzhPbwDMnihU61NkFG9FE",
52206
+ validatorVoteAccount: "he1iusunGwqrNtafDtLdhsUQDFvo13z9sUa36PauBtk",
52207
+ tokenAddress: "2k79y8CApbU9jAvWhLS2j6uRbaVjpLJTUzstBTho9vGq",
52208
+ tokenName: "Helius",
52209
+ tokenSymbol: "HELIUS"
52210
+ },
52211
+ {
52212
+ bankAddress: "Dfr6Sf44ftecaJaoJMzFQABdkt3CEHfBwut1WyacRzaE",
52213
+ validatorVoteAccount: "SLaYv7tCwetrFGbPCRnqpHswG5qqKino78EYpbGF7xY",
52214
+ tokenAddress: "Vsw4JT33S7bLbhjySMMyrP3JKvTAcNi9WG5Doekrmgg",
52215
+ tokenName: "Solayer",
52216
+ tokenSymbol: "SOLAYER"
52217
+ },
52218
+ {
52219
+ bankAddress: "BZAm4qGscR8gg5bmWrEq6BTofgaZPbg7Fwfa7rFghEXL",
52220
+ validatorVoteAccount: "J1to3PQfXidUUhprQWgdKkQAMWPJAEqSJ7amkBDE9qhF",
52221
+ tokenAddress: "6B8hZSupE5mcACmjzozP6C1DR2uaCCtmrGqcYWC6SBCc",
52222
+ tokenName: "Bonk",
52223
+ tokenSymbol: "BONK"
52224
+ },
52225
+ {
52226
+ bankAddress: "3UrMZ26NRKu2y6c2dPE7gZVHwEmhpwKLcWACg3tjCVEt",
52227
+ validatorVoteAccount: "J2nUHEAgZFRyuJbFjdqPrAa9gyWDuc7hErtDQHPhsYRp",
52228
+ tokenAddress: "9M7oMo4oL6RDPG7WbAX3Zz4dPzbMgpiCzwrQPMwG4Wgq",
52229
+ tokenName: "Phantom",
52230
+ tokenSymbol: "PHANTOM"
52231
+ },
52232
+ {
52233
+ bankAddress: "8c269gkonvATm93nviuYiriCQ829f7ypx3aScYDR1YoQ",
52234
+ validatorVoteAccount: "D3QPJm7BDzzPeRG51YZSEz3LfV7GvFNu9NkcibzURxuj",
52235
+ tokenAddress: "8hXCCQmYFcDhU5Mkuvyixp2Q11sbyQComkceSSh3GY4a",
52236
+ tokenName: "Starke Finance",
52237
+ tokenSymbol: "STARKE"
52238
+ },
52239
+ {
52240
+ bankAddress: "37tiA2NTF6YCt85XzCidPo9ZVpuqkkmfVJCYQ5Yx5Uhs",
52241
+ validatorVoteAccount: "SBLZib4npE7svxFA7AsD3ytdQAfYNb39c8zsU82AA2E",
52242
+ tokenAddress: "96rXgCFy1Er49169XoKHkeLiKC2k4bTy1641q1TVrMm2",
52243
+ tokenName: "SolBlaze Validator",
52244
+ tokenSymbol: "SOLBLAZE"
52245
+ },
52246
+ {
52247
+ bankAddress: "J9trpcrVdFjVNg6VFrdF1XPGgjftQKZhbbWsxertdv9V",
52248
+ validatorVoteAccount: "FACqsS19VScz8oo2YhdMg35EsAy6xsCZ9Y58eJXGv8QJ",
52249
+ tokenAddress: "AH6fxpHS2gtMtJgBy8y8pEAPkqyop2pSugF6REs9NaTp",
52250
+ tokenName: "Lantern",
52251
+ tokenSymbol: "LNTRN"
52252
+ },
52253
+ {
52254
+ bankAddress: "EGTfrYiuWpPPZ4yfY9tCxnK6QMkY7pzVie9DxK772iGe",
52255
+ validatorVoteAccount: "EfnywDKqArxK6N6FS9ctsuzNdxfx3pzfXEQE5EevQ1SV",
52256
+ tokenAddress: "FcXEwHku68ZquqtSj1eSWS1SVWkhAZSyb4usfpiuEJAL",
52257
+ tokenName: "PROJECT SUPER",
52258
+ tokenSymbol: "SUPER"
52259
+ },
52260
+ {
52261
+ bankAddress: "A5e7UTE3g11ZfKgftqRCvxAgcDuFGyeDjMka96zJWSWe",
52262
+ validatorVoteAccount: "3ZUQekqiZoybB57y49eqtvSaoonqDwuNbeqEGwN88JkQ",
52263
+ tokenAddress: "F1XPjtpsEy23Q7po4JkWjp1jkDZcvFYSrqD8TR1YL3EF",
52264
+ tokenName: "Paws",
52265
+ tokenSymbol: "PAWS"
52266
+ },
52267
+ {
52268
+ bankAddress: "91jkdp4cF8vCDhjwude3SGSGrmVWFk5vTAtR6fsGVAfy",
52269
+ validatorVoteAccount: "gangtRyGPTvYWb8K3xS2feJQaCks4iJ7rytFUPtVqSY",
52270
+ tokenAddress: "6ZS7ZVDw91BVAC8gsz3SZBSeVeF2GtXtL2BHK31Kvyjm",
52271
+ tokenName: "Lotus Validator",
52272
+ tokenSymbol: "LOTUS"
52273
+ },
52274
+ {
52275
+ bankAddress: "72BS34HkCgq8RWQR7kuVVmiJMtKqSxG4CHX6ZXpSCwg7",
52276
+ validatorVoteAccount: "oRAnGeU5h8h2UkvbfnE5cjXnnAa4rBoaxmS4kbFymSe",
52277
+ tokenAddress: "9yF8pXctzicum2P73uuk4Dhqf2MVz6tzRAe8THGXCJcp",
52278
+ tokenName: "Orangefin Ventures",
52279
+ tokenSymbol: "ORANGEFIN"
52280
+ },
52281
+ {
52282
+ bankAddress: "8F4DsU3NMFunUxBZkWrpYR8zwhAfoAt7QuiEPMtyhWvX",
52283
+ validatorVoteAccount: "3xjfK9C9YNcta8MvK1US4sQ3bc6DEjoJoR3qLExGf9xE",
52284
+ tokenAddress: "Akib1NYJzzh9HkiDH41S2LUefUmR1bKsk65xgqUcW5C5",
52285
+ tokenName: "pico\u{1F644}.sol",
52286
+ tokenSymbol: "PICO"
52287
+ },
52288
+ {
52289
+ bankAddress: "GdtggomQth6cxuYPdiVhBbcX7VC9rnDDwLMfxipxE2Po",
52290
+ validatorVoteAccount: "oPaLTmyvoUhW26QCMwLA5JNUeBYy72PDpFoXQF8SeX4",
52291
+ tokenAddress: "C71A3W7g5XALUNwTDWTwHX3qhfypaYZ41aNZjBpcaC9D",
52292
+ tokenName: "Temporal Opal",
52293
+ tokenSymbol: "OPAL"
52294
+ },
52295
+ {
52296
+ bankAddress: "5sJCKePwAhyD3mzrzLRDM2PkFMc85nnvvarxHLsvWvpg",
52297
+ validatorVoteAccount: "9jYFwBfbjYmvasFbJyES9apLJDTkwtbgSDRWanHEvcRw",
52298
+ tokenAddress: "Hj69K1WbnfZFipLbrzdxgGhDqCR47q48bN5nUHt6xQZo",
52299
+ tokenName: "WATCHTOWER",
52300
+ tokenSymbol: "WATCHTOWER"
52301
+ },
52302
+ {
52303
+ bankAddress: "3F3QXT3BtkegaBfFjn2odKLurFYLHJHJ99xKV2TRTvrk",
52304
+ validatorVoteAccount: "6JfBwvcz5QUKQJ37BMKTLrf968DDJBtwoZLw19aHwFtQ",
52305
+ tokenAddress: "8FqX86cQofBHReetZgxrxxvzN4iqMVsj2hbiv7pj2h73",
52306
+ tokenName: "Spectrum Staking",
52307
+ tokenSymbol: "SPECTRUM"
52308
+ },
52309
+ {
52310
+ bankAddress: "CFmvdtEPQJPVqS1QRkeRcdQm2itAPk6k8hSJbmt88Sjc",
52311
+ validatorVoteAccount: "Haz7b47sZBpxh9SwggGndN3fAyNQ1S949BPdxWXS3ab6",
52312
+ tokenAddress: "38ZUTefZnKSUJU3wxpUe3xpiw2j5WQPnmzSTNbS1JqLA",
52313
+ tokenName: "Temporal Emerald",
52314
+ tokenSymbol: "EMERALD"
52315
+ },
52316
+ {
52317
+ bankAddress: "CmBDHSVuodmUnanbBVFvY9cauLeosbdFQn9bJANMVYUG",
52318
+ validatorVoteAccount: "mintrNtxN3PhAB45Pt41XqyKghTTpqcoBkQTZqh96iR",
52319
+ tokenAddress: "GxGmv7s7s2co3pLZukns946fr5zmR8c5buWRD9prGd6v",
52320
+ tokenName: "Hanabi Staking",
52321
+ tokenSymbol: "haSOLmrgn"
52322
+ },
52323
+ {
52324
+ bankAddress: "7bLfrb4fWVYkVpZ9rg7dBUwKRAqLyiivCW4ahMMGcKyS",
52325
+ validatorVoteAccount: "76DafWkJ6pGK2hoD41HjrM4xTBhfKqrDYDazv13n5ir1",
52326
+ tokenAddress: "GT7n9uZbYzHv52YqDBowtZ5ZVW91umaBQTNPFQNeLUpR",
52327
+ tokenName: "Solana Japan Validator",
52328
+ tokenSymbol: "SolJAPAn"
52329
+ },
52330
+ {
52331
+ bankAddress: "6q5DB86DhCBQt5bqzZwgopV8EA96aCnngu5ebR1ooDFq",
52332
+ validatorVoteAccount: "Cue647T8jgwpRSDUb8ttTYx7NiEfJCRZNiiw1qmchXsG",
52333
+ tokenAddress: "EAR6LenhNstHxR9289rWakm82WgLJYvHD7NawfXtuyUx",
52334
+ tokenName: "KIWAMI",
52335
+ tokenSymbol: "KIWAMI"
52336
+ },
52337
+ {
52338
+ bankAddress: "GLSCJ39N82Xo21621jMheinvjQLrBrkG7gzo2C5L1y6y",
52339
+ validatorVoteAccount: "7emL18Bnve7wbYE9Az7vYJjikxN6YPU81igf6rVU5FN8",
52340
+ tokenAddress: "EQuMUgLZArKwWUk6uGPmTGYUgNbfgJrbBaNR7CQyZ5uf",
52341
+ tokenName: "Temporal Topaz",
52342
+ tokenSymbol: "TOPAZ"
52343
+ },
52344
+ {
52345
+ bankAddress: "4irzCCsU53ffh9XB7NxGzbbHjvSR7FTfPbn6KoXkt7kX",
52346
+ validatorVoteAccount: "2iWXwF2Q5W6o7yntV2mkbxncB4rYHnX61y3NU8a8EFMJ",
52347
+ tokenAddress: "14Pets6QpE9iXKkXg8Ri4GcDazRMfWR3guM6LZXnFChc",
52348
+ tokenName: "Bull Moose SOL",
52349
+ tokenSymbol: "bmsSOL"
52350
+ },
52351
+ {
52352
+ bankAddress: "C96do7nkEaaFjHq8jHzPpyPTdJSea5xEGwxDzDSepCzf",
52353
+ validatorVoteAccount: "voteRnv6PBzmiGP8NicWtQiqEJTwKKq2SxtqtdLUJjd",
52354
+ tokenAddress: "3YEDiJ4r4xRGNhq6nudRnkwrdKHG7PAtDim24CjTMtBH",
52355
+ tokenName: "diman",
52356
+ tokenSymbol: "DIMAN"
52357
+ },
52358
+ {
52359
+ bankAddress: "9dZiyG51FBR4BWpAs69XbDpr7GfVAEB1ZB89v38maV36",
52360
+ validatorVoteAccount: "Simpj3KyRQmpRkXuBvCQFS7DBBG6vqw93SkZb9UD1hp",
52361
+ tokenAddress: "77YLpVLQXr2KU66GM2JykbT9g5du7LarWgehbWD3CJaB",
52362
+ tokenName: "SIMPDIGIT",
52363
+ tokenSymbol: "SIMPDIGIT"
52364
+ },
52365
+ {
52366
+ bankAddress: "2foqT8wWzWRduyV37uRdj81DijkNMKzYD3D6JPfir7La",
52367
+ validatorVoteAccount: "48oxpSHQkM4sdXUY9NQ8KnEtebzZbyk8uUT7JRdVQNuf",
52368
+ tokenAddress: "42m7Ygk5VxREdKfcFrsH1HnuoqCke8BcVcxNeywMCfp2",
52369
+ tokenName: "Infinite Lux",
52370
+ tokenSymbol: "LUX"
52371
+ },
52372
+ {
52373
+ bankAddress: "FsdWEJzHXkUXejWnb7c1p9UJtF69hVWQNNoakjoXyRCJ",
52374
+ validatorVoteAccount: "4AUED4uj6nSTuANzaAUnGBPJQRmhpDYDwoWJNkoUUBBW",
52375
+ tokenAddress: "CiyQTfHJ9PbTwC7TGf4pXZk8szcWGJ8TeFhhCuUwybqi",
52376
+ tokenName: "Anagram",
52377
+ tokenSymbol: "ANAGRAM"
52378
+ },
52379
+ {
52380
+ bankAddress: "2hs1pHAzDWGqnn1d8VQkc8bZRfQ45grYvzfau8dnWFUk",
52381
+ validatorVoteAccount: "2NxEEbhqqj1Qptq5LXLbDTP5tLa9f7PqkU8zNgxbGU9P",
52382
+ tokenAddress: "9yQLxEzusZ7QiZNafDNdzbEaTCPuJToGjMhLRJtZbgsd",
52383
+ tokenName: "NANSEN",
52384
+ tokenSymbol: "NANSEN"
52385
+ },
52386
+ {
52387
+ bankAddress: "FCi8unSVCwJd3QkrhTtv6LTTjw1c4zV65D5cG5N1rAG6",
52388
+ validatorVoteAccount: "Va1idkzkB6LEmVFmxWbWU8Ao9qehC62Tjmf68L3uYKj",
52389
+ tokenAddress: "AExKb8oJ6mGPYJUyfiX49DMMi226h2AnWeG1G6neQBEz",
52390
+ tokenName: "VALIDATOR",
52391
+ tokenSymbol: "VALID"
52392
+ },
52393
+ {
52394
+ bankAddress: "HzS8RqaQ5syk6EHbVi7h9rFYN48PpxykUXEs6w9wNfNP",
52395
+ validatorVoteAccount: "sTach38ebT8jnGH8i2D1g8NDAS6An19whVMnSSWPXt4",
52396
+ tokenAddress: "AFDVYBqxADagPfN9DdbrNrf9zZqugub7CV4kUJEUrK6J",
52397
+ tokenName: "Stache Node",
52398
+ tokenSymbol: "STACHE"
52399
+ },
52400
+ {
52401
+ bankAddress: "9Hs4E6ACNw6Hmwjvm1duXzbaWmvXxSxN11agw4updEn1",
52402
+ validatorVoteAccount: "EtMSc3MvcDXUr6ChK5GxyFVwTxYA3zqP5XzjE9jwKvSV",
52403
+ tokenAddress: "ENKFyZQZHzNNSxcKYoaVsNLi2xoGPoStZH4A9xxezjbC",
52404
+ tokenName: "Mad Lads CN",
52405
+ tokenSymbol: "MadLadsCN"
52406
+ },
52407
+ {
52408
+ bankAddress: "4watsWcjTBAwsrZpArwQbnNX4bQ1yeHBxgdbrGT4eMu9",
52409
+ validatorVoteAccount: "EARNynHRWg6GfyJCmrrizcZxARB3HVzcaasvNa8kBS72",
52410
+ tokenAddress: "8fhkWcm2n28JuadzY7mRR8FFDZZfnaPfWgw7pLNVZCbE",
52411
+ tokenName: "Solana Compass Stake",
52412
+ tokenSymbol: "compaStake"
52413
+ },
52414
+ {
52415
+ bankAddress: "9d7MTvcz1VMB1rK6H73quMxkR26dLPz5HDaac2eGRjQx",
52416
+ validatorVoteAccount: "nymsndUdAZyUPpWYz5VEg8Ghj9cFvwTRgciLogpmYaQ",
52417
+ tokenAddress: "FWFeaqpkgDr3ejVSY3HjiUmUg3u9fcr5d66HvimnDLWE",
52418
+ tokenName: "Hypo Nyms",
52419
+ tokenSymbol: "NYMS"
52420
+ },
52421
+ {
52422
+ bankAddress: "6V4vCK3n3JVncfpS16mW8ceLoNPatvu61pKxFmWx8adi",
52423
+ validatorVoteAccount: "BT8LZUvQVwFHRGw2Dwv7UeqDUq7btfjegLpuz5bwgziD",
52424
+ tokenAddress: "9YRS7Stf9dVibTT1M4uVEAuRMcoS4MH1QxqXy9Lssrab",
52425
+ tokenName: "private",
52426
+ tokenSymbol: "private"
52427
+ },
52428
+ {
52429
+ bankAddress: "CK8qRAcmvkDXaqX2S5GkgTCZT5pCz34me1neQhpJYe1Z",
52430
+ validatorVoteAccount: "Ac1beBKixfNdrTAac7GRaTsJTxLyvgGvJjvy4qQfvyfc",
52431
+ tokenAddress: "DLTAbTL5NXhbqX6LX3ie3tf52pdtGpxe2DrZUr1RhgY6",
52432
+ tokenName: "Stronghold",
52433
+ tokenSymbol: "Stronghold"
52434
+ },
52435
+ {
52436
+ bankAddress: "H6CT1aiCgSNw9S6aq38npEhdoN2UPhSKe8Lj9fQqqjuu",
52437
+ validatorVoteAccount: "FREEL1BCzmPpNneC7FHCtBqzeWYrHRbtisFvi4N8XUP9",
52438
+ tokenAddress: "AKFuMoM5rjSpQSL4p6TBoc7D4dmEem9QrHhuSDCBYyZ8",
52439
+ tokenName: "Ross",
52440
+ tokenSymbol: "Ross"
52441
+ },
52442
+ {
52443
+ bankAddress: "G46aHuakgStymbE2WsLbja61mH5UXBPdSdpwf6Ci3saG",
52444
+ validatorVoteAccount: "mnvkHm47ZmRKoSWuQZAfXLRiDPiKCq8PWkMWrp1Wwqe",
52445
+ tokenAddress: "Cq9S5UB9BviPn5yoGkEDk3m7neQag4KJnhPWGyuev9W8",
52446
+ tokenName: "gripto staked sol",
52447
+ tokenSymbol: "GRIPTO"
52448
+ },
52449
+ {
52450
+ bankAddress: "75UmeEMdqVnGn3JHx8yVZEn7viybJ73XYSjhYCYfyhp2",
52451
+ validatorVoteAccount: "4m1PbxzwLdUnEwog3T9UKxgjktgriHgE1CfAhMqDw7Xx",
52452
+ tokenAddress: "432SogPNunjZMneDV6goZ8ZcCQz282GxoSJ4rwqx95pT",
52453
+ tokenName: "kumasol",
52454
+ tokenSymbol: "kumasol"
52455
+ },
52456
+ {
52457
+ bankAddress: "3zk6EmXANYQK12bwy9dySRAM4cT2vT5cDcAB79j8G33B",
52458
+ validatorVoteAccount: "HvsD9L5t62MGv3QBD2K7xjkipGYr9UZN7BtsW8NuSPpg",
52459
+ tokenAddress: "5vmwd6JHDCmX9W2XT1n2QpvYGA2kk4Xf7qWSayDU6caT",
52460
+ tokenName: "ArgenTerraSOL",
52461
+ tokenSymbol: "atSOL"
52462
+ },
52463
+ {
52464
+ bankAddress: "4C2vPweGNpiE6kTEbYvcbUBHNWxrn4ErQYaqWm5zDexx",
52465
+ validatorVoteAccount: "FnAPJkzf19s87sm24Qhv6bHZMZvZ43gjNUBRgjwXpD4v",
52466
+ tokenAddress: "6q4kVnwUpkE3i7W32dqaX6V12pbsrCnMqZ7TWz9yp1m5",
52467
+ tokenName: "BLOCKPORT",
52468
+ tokenSymbol: "BPT"
52469
+ },
52470
+ {
52471
+ bankAddress: "E5hZu5QQ1pRmGvyS4JHGXVQwzdUPaYM4yEiNKr64YzyG",
52472
+ validatorVoteAccount: "nfGcSJkP35SkPa5475iBChmq1UNcj7JE1uQHrrasymm",
52473
+ tokenAddress: "AQpQoJ3tJKGH9Yn8GSzoUsVcHPJjj3xYfQFp9XVr74F6",
52474
+ tokenName: "Test01",
52475
+ tokenSymbol: "TEST01"
52476
+ },
52477
+ {
52478
+ bankAddress: "3VCkXWAmE5DSwYRpqGFnkUz7vvD2RKbhFvrhzLuE8msu",
52479
+ validatorVoteAccount: "abc1zP7ihWsgQW8z5YmfQNqMckJE5Dfx8fwUNMNVNkY",
52480
+ tokenAddress: "BNisp3omkr6Rg5nHESWafjUbeCpGPy6MYq1iRJRgSAsh",
52481
+ tokenName: "ALGO STAKE",
52482
+ tokenSymbol: "ALGO"
52483
+ },
52484
+ {
52485
+ bankAddress: "7BHHMWw3P1AyebLhX9A8wnDeeGy8jgFXqqHuEZt7BVmW",
52486
+ validatorVoteAccount: "8Pep3GmYiijRALqrMKpez92cxvF4YPTzoZg83uXh14pW",
52487
+ tokenAddress: "zBH13AzXYCqHZKS8NGa4KR8zQhWiyvFdDY15nmfrHgS",
52488
+ tokenName: "8Pep",
52489
+ tokenSymbol: "8Pep"
52490
+ },
52491
+ {
52492
+ bankAddress: "9QWUatjtJtc98yts4ufWnmNeaWQRmaaLjFwbK3iMdS47",
52493
+ validatorVoteAccount: "CatzoSMUkTRidT5DwBxAC2pEtnwMBTpkCepHkFgZDiqb",
52494
+ tokenAddress: "98B1NMLYaNJQNxiQGr53vbjNFMNTYFmDqoCgj7qD9Vhm",
52495
+ tokenName: "JUPITER ",
52496
+ tokenSymbol: "JUPITER"
52497
+ },
52498
+ {
52499
+ bankAddress: "5q1wJkGqqRh6mSBtjG8sfjBsgJSGdA2QoXTWv4UQbHGk",
52500
+ validatorVoteAccount: "shft7Fry1js37Hm9wq4dfwcZSp2DyKszeWMvEpjYCQ1",
52501
+ tokenAddress: "C1KwBJZNwUaodUcP5kXqD52NCuZzThNAG2cw3vt5H6iE",
52502
+ tokenName: "BLUESHIFT",
52503
+ tokenSymbol: "SHIFT"
52504
+ },
52505
+ {
52506
+ bankAddress: "FZaHyfg9hmNMKpfUJ474wNKPaPdXMpnJouasKnndECiZ",
52507
+ validatorVoteAccount: "DdCNGDpP7qMgoAy6paFzhhak2EeyCZcgjH7ak5u5v28m",
52508
+ tokenAddress: "PhxXAYTkFZS23ZWvFcz6H6Uq4VnVBMa6hniiAyudjaW",
52509
+ tokenName: "KILN1",
52510
+ tokenSymbol: "KILN1"
52511
+ },
52512
+ {
52513
+ bankAddress: "5CBocarwfJeWGNozGemWktRYSz6kPikRPdfH8ZHSFrsg",
52514
+ validatorVoteAccount: "8zuMRTXThoPTTPLLvaiKiJshLLCqGMt9BdRjjCL19xBc",
52515
+ tokenAddress: "BDsEuxFWznAP5cUCannnfjyjDtTwqN57CkGfDbjx2nNZ",
52516
+ tokenName: "DawnLabs",
52517
+ tokenSymbol: "DawnLabs"
52518
+ },
52519
+ {
52520
+ bankAddress: "9ivswG37QpCUmkPkLMpRZT7PMyP64V9dDpZdteM254ec",
52521
+ validatorVoteAccount: "gaToR246dheK1DGAMEqxMdBJZwU4qFyt7DzhSwAHFWF",
52522
+ tokenAddress: "TjA2rtxoUFzyPVAw35VQGEQnNXiwcmNjKSk29nmkq1P",
52523
+ tokenName: "Valigator Open",
52524
+ tokenSymbol: "Valigator"
52525
+ }
52526
+ ];
52527
+
52528
+ // src/services/native-stake/utils/metadata.utils.ts
52529
+ var _metadataMap = null;
52530
+ var _voteAccountByBank = null;
52531
+ function getStakedBankMetadataMap() {
52532
+ if (!_metadataMap) {
52533
+ _metadataMap = /* @__PURE__ */ new Map();
52534
+ for (const entry of STAKED_BANK_METADATA_JSON) {
52535
+ _metadataMap.set(entry.bankAddress, entry);
52536
+ }
52537
+ }
52538
+ return _metadataMap;
52539
+ }
52540
+ function getValidatorVoteAccountByBank() {
52541
+ if (!_voteAccountByBank) {
52542
+ _voteAccountByBank = {};
52543
+ for (const entry of STAKED_BANK_METADATA_JSON) {
52544
+ _voteAccountByBank[entry.bankAddress] = entry.validatorVoteAccount;
52545
+ }
52546
+ }
52547
+ return _voteAccountByBank;
52548
+ }
52549
+ async function computeStakedBankMultipliers(stakedBanks, connection) {
52550
+ const multiplierByBank = /* @__PURE__ */ new Map();
52551
+ if (stakedBanks.length === 0) {
52552
+ return multiplierByBank;
52553
+ }
52554
+ const metadataMap = getStakedBankMetadataMap();
52555
+ const stakedBankAddresses = [];
52556
+ const poolStakeAddresses = [];
52557
+ const lstMintAddresses = [];
52558
+ for (const bank of stakedBanks) {
52559
+ const metadata = metadataMap.get(bank.address.toBase58());
52560
+ if (!metadata) {
52561
+ multiplierByBank.set(bank.address.toBase58(), new BigNumber3__default.default(1));
52562
+ continue;
52563
+ }
52564
+ const pool = findPoolAddress(new web3_js.PublicKey(metadata.validatorVoteAccount));
52565
+ stakedBankAddresses.push(bank.address.toBase58());
52566
+ poolStakeAddresses.push(findPoolStakeAddress(pool));
52567
+ lstMintAddresses.push(findPoolMintAddress(pool));
52568
+ }
52569
+ if (stakedBankAddresses.length === 0) {
52570
+ return multiplierByBank;
52571
+ }
52572
+ const allAddresses = [
52573
+ ...poolStakeAddresses.map((a) => a.toBase58()),
52574
+ ...lstMintAddresses.map((a) => a.toBase58())
52575
+ ];
52576
+ const accountInfos = await chunkedGetRawMultipleAccountInfoOrdered(connection, allAddresses);
52577
+ const poolStakeInfos = accountInfos.slice(0, poolStakeAddresses.length);
52578
+ const lstMintInfos = accountInfos.slice(poolStakeAddresses.length);
52579
+ for (let i = 0; i < stakedBankAddresses.length; i++) {
52580
+ const bankAddr = stakedBankAddresses[i];
52581
+ const poolStakeInfo = poolStakeInfos[i];
52582
+ const lstMintInfo = lstMintInfos[i];
52583
+ if (!poolStakeInfo || !lstMintInfo) {
52584
+ multiplierByBank.set(bankAddr, new BigNumber3__default.default(1));
52585
+ continue;
52586
+ }
52587
+ const stakeLamports = poolStakeInfo.lamports;
52588
+ const supplyBuffer = lstMintInfo.data.slice(36, 44);
52589
+ const lstMintSupply = Number(Buffer.from(supplyBuffer).readBigUInt64LE(0));
52590
+ if (lstMintSupply === 0) {
52591
+ multiplierByBank.set(bankAddr, new BigNumber3__default.default(1));
52592
+ continue;
52593
+ }
52594
+ const adjustedStake = Math.max(stakeLamports - web3_js.LAMPORTS_PER_SOL, 0);
52595
+ const multiplier = new BigNumber3__default.default(adjustedStake).dividedBy(lstMintSupply);
52596
+ multiplierByBank.set(bankAddr, multiplier);
52597
+ }
52598
+ return multiplierByBank;
52599
+ }
52600
+ var SYSVAR_CLOCK_ID2 = new web3_js.PublicKey("SysvarC1ock11111111111111111111111111111111");
52601
+ async function makeMintStakedLstIx(params) {
52602
+ const { amount, authority, stakeAccountPk, validator, connection } = params;
52603
+ const pool = findPoolAddress(validator);
52604
+ const lstMint = findPoolMintAddress(pool);
52605
+ const poolStakeAuth = findPoolStakeAuthorityAddress(pool);
52606
+ const lstAta = getAssociatedTokenAddressSync(lstMint, authority);
52607
+ const [lstAccInfo, stakeAccInfoParsed, rentExemptReserve] = await Promise.all([
52608
+ connection.getAccountInfo(lstAta),
52609
+ connection.getParsedAccountInfo(stakeAccountPk),
52610
+ connection.getMinimumBalanceForRentExemption(web3_js.StakeProgram.space)
52611
+ ]);
52612
+ const stakeAccParsed = stakeAccInfoParsed?.value?.data;
52613
+ const amountLamports = Math.round(Number(amount) * web3_js.LAMPORTS_PER_SOL);
52614
+ const stakeAccLamports = Number(stakeAccParsed?.parsed?.info?.stake?.delegation?.stake ?? 0);
52615
+ const isFullStake = amountLamports >= stakeAccLamports;
52616
+ const instructions2 = [];
52617
+ const signers = [];
52618
+ if (!lstAccInfo) {
52619
+ instructions2.push(
52620
+ createAssociatedTokenAccountInstruction(authority, lstAta, authority, lstMint)
52621
+ );
52622
+ }
52623
+ let targetStakePubkey;
52624
+ if (!isFullStake) {
52625
+ const splitStakeAccount = web3_js.Keypair.generate();
52626
+ signers.push(splitStakeAccount);
52627
+ targetStakePubkey = splitStakeAccount.publicKey;
52628
+ instructions2.push(
52629
+ ...web3_js.StakeProgram.split(
52630
+ {
52631
+ stakePubkey: stakeAccountPk,
52632
+ authorizedPubkey: authority,
52633
+ splitStakePubkey: splitStakeAccount.publicKey,
52634
+ lamports: amountLamports
52635
+ },
52636
+ rentExemptReserve
52637
+ ).instructions
52638
+ );
52639
+ } else {
52640
+ targetStakePubkey = stakeAccountPk;
52641
+ }
52642
+ const [authorizeStakerIx, authorizeWithdrawIx] = await Promise.all([
52643
+ web3_js.StakeProgram.authorize({
52644
+ stakePubkey: targetStakePubkey,
52645
+ authorizedPubkey: authority,
52646
+ newAuthorizedPubkey: poolStakeAuth,
52647
+ stakeAuthorizationType: web3_js.StakeAuthorizationLayout.Staker
52648
+ }).instructions,
52649
+ web3_js.StakeProgram.authorize({
52650
+ stakePubkey: targetStakePubkey,
52651
+ authorizedPubkey: authority,
52652
+ newAuthorizedPubkey: poolStakeAuth,
52653
+ stakeAuthorizationType: web3_js.StakeAuthorizationLayout.Withdrawer
52654
+ }).instructions
52655
+ ]);
52656
+ [authorizeStakerIx[0], authorizeWithdrawIx[0]].forEach((ix) => {
52657
+ if (ix) {
52658
+ ix.keys = ix.keys.map((key) => ({
52659
+ ...key,
52660
+ isWritable: key.pubkey.equals(SYSVAR_CLOCK_ID2) ? false : key.isWritable
52661
+ }));
52662
+ }
52663
+ });
52664
+ instructions2.push(...authorizeStakerIx, ...authorizeWithdrawIx);
52665
+ const depositStakeIx = await SinglePoolInstruction.depositStake(
52666
+ pool,
52667
+ targetStakePubkey,
52668
+ lstAta,
52669
+ authority
52670
+ );
52671
+ instructions2.push(depositStakeIx);
52672
+ return { instructions: instructions2, keys: signers };
52673
+ }
52674
+ async function makeMintStakedLstTx(params) {
52675
+ const { connection, luts, blockhash: providedBlockhash } = params;
52676
+ const { instructions: instructions2, keys } = await makeMintStakedLstIx(params);
52677
+ const blockhash = providedBlockhash ?? (await connection.getLatestBlockhash("confirmed")).blockhash;
52678
+ const message = new web3_js.TransactionMessage({
52679
+ payerKey: params.authority,
52680
+ recentBlockhash: blockhash,
52681
+ instructions: instructions2
52682
+ }).compileToV0Message(luts);
52683
+ const tx = new web3_js.VersionedTransaction(message);
52684
+ return addTransactionMetadata(tx, {
52685
+ signers: keys,
52686
+ addressLookupTables: luts,
52687
+ type: "DEPOSIT_STAKE" /* DEPOSIT_STAKE */
52688
+ });
52689
+ }
52690
+ async function makeRedeemStakedLstIx(params) {
52691
+ const { amount, authority, validator, connection } = params;
52692
+ const pool = findPoolAddress(validator);
52693
+ const lstMint = findPoolMintAddress(pool);
52694
+ const mintAuthority = findPoolMintAuthorityAddress(pool);
52695
+ const lstAta = getAssociatedTokenAddressSync(lstMint, authority);
52696
+ const rentExemption = await connection.getMinimumBalanceForRentExemption(
52697
+ web3_js.StakeProgram.space
52698
+ );
52699
+ const stakeAmount = new BigNumber3__default.default(new BigNumber3__default.default(amount).toString());
52700
+ const instructions2 = [];
52701
+ const signers = [];
52702
+ const stakeAccount = web3_js.Keypair.generate();
52703
+ signers.push(stakeAccount);
52704
+ instructions2.push(
52705
+ web3_js.SystemProgram.createAccount({
52706
+ fromPubkey: authority,
52707
+ newAccountPubkey: stakeAccount.publicKey,
52708
+ lamports: rentExemption,
52709
+ space: web3_js.StakeProgram.space,
52710
+ programId: web3_js.StakeProgram.programId
52711
+ })
52712
+ );
52713
+ instructions2.push(
52714
+ createApproveInstruction(
52715
+ lstAta,
52716
+ mintAuthority,
52717
+ authority,
52718
+ BigInt(stakeAmount.multipliedBy(1e9).toFixed(0))
52719
+ )
52720
+ );
52721
+ const withdrawStakeIx = await SinglePoolInstruction.withdrawStake(
52722
+ pool,
52723
+ stakeAccount.publicKey,
52724
+ authority,
52725
+ lstAta,
52726
+ stakeAmount
52727
+ );
52728
+ instructions2.push(withdrawStakeIx);
52729
+ return { instructions: instructions2, keys: signers };
52730
+ }
52731
+ async function makeRedeemStakedLstTx(params) {
52732
+ const { connection, luts, blockhash: providedBlockhash } = params;
52733
+ const { instructions: instructions2, keys } = await makeRedeemStakedLstIx(params);
52734
+ const blockhash = providedBlockhash ?? (await connection.getLatestBlockhash("confirmed")).blockhash;
52735
+ const message = new web3_js.TransactionMessage({
52736
+ payerKey: params.authority,
52737
+ recentBlockhash: blockhash,
52738
+ instructions: instructions2
52739
+ }).compileToV0Message(luts);
52740
+ const tx = new web3_js.VersionedTransaction(message);
52741
+ return addTransactionMetadata(tx, {
52742
+ signers: keys,
52743
+ addressLookupTables: luts,
52744
+ type: "WITHDRAW_STAKE" /* WITHDRAW_STAKE */
52745
+ });
52746
+ }
52747
+ async function makeMergeStakeAccountsTx(params) {
52748
+ const {
52749
+ authority,
52750
+ sourceStakeAccount,
52751
+ destinationStakeAccount,
52752
+ connection,
52753
+ luts,
52754
+ blockhash: providedBlockhash
52755
+ } = params;
52756
+ const mergeIx = web3_js.StakeProgram.merge({
52757
+ stakePubkey: destinationStakeAccount,
52758
+ sourceStakePubKey: sourceStakeAccount,
52759
+ authorizedPubkey: authority
52760
+ }).instructions;
52761
+ const blockhash = providedBlockhash ?? (await connection.getLatestBlockhash("confirmed")).blockhash;
52762
+ const message = new web3_js.TransactionMessage({
52763
+ payerKey: authority,
52764
+ recentBlockhash: blockhash,
52765
+ instructions: mergeIx
52766
+ }).compileToV0Message(luts);
52767
+ const tx = new web3_js.VersionedTransaction(message);
52768
+ return addTransactionMetadata(tx, {
52769
+ addressLookupTables: luts,
52770
+ type: "MERGE_STAKE_ACCOUNTS" /* MERGE_STAKE_ACCOUNTS */
52771
+ });
52772
+ }
51889
52773
  async function getKaminoMetadata(options) {
51890
52774
  const kaminoBanks = options.banks.filter((b) => b.config.assetTag === 3 /* KAMINO */);
51891
52775
  const DEFAULT_PUBKEY = web3_js.PublicKey.default;
@@ -54583,7 +55467,6 @@ var Project0Client = class _Project0Client {
54583
55467
  assetShareMultiplierByBank.set(bank.address.toBase58(), new BigNumber3__default.default(1));
54584
55468
  break;
54585
55469
  case 2 /* STAKED */:
54586
- assetShareMultiplierByBank.set(bank.address.toBase58(), new BigNumber3__default.default(1));
54587
55470
  break;
54588
55471
  case 0 /* DEFAULT */:
54589
55472
  case 1 /* SOL */:
@@ -54592,6 +55475,11 @@ var Project0Client = class _Project0Client {
54592
55475
  break;
54593
55476
  }
54594
55477
  });
55478
+ const stakedMultipliers = await computeStakedBankMultipliers(
55479
+ banksArray.filter((b) => b.config.assetTag === 2 /* STAKED */),
55480
+ connection
55481
+ );
55482
+ stakedMultipliers.forEach((v, k) => assetShareMultiplierByBank.set(k, v));
54595
55483
  const emodePairs = getEmodePairs(banksArray);
54596
55484
  return new _Project0Client(
54597
55485
  program,
@@ -54670,7 +55558,6 @@ exports.MAX_ACCOUNT_LOCKS = MAX_ACCOUNT_LOCKS;
54670
55558
  exports.MAX_CONFIDENCE_INTERVAL_RATIO = MAX_CONFIDENCE_INTERVAL_RATIO;
54671
55559
  exports.MAX_TX_SIZE = MAX_TX_SIZE;
54672
55560
  exports.MAX_U64 = MAX_U64;
54673
- exports.MAX_WRITABLE_ACCOUNTS = MAX_WRITABLE_ACCOUNTS;
54674
55561
  exports.MPL_METADATA_PROGRAM_ID = MPL_METADATA_PROGRAM_ID;
54675
55562
  exports.MarginRequirementType = MarginRequirementType;
54676
55563
  exports.MarginfiAccount = MarginfiAccount;
@@ -54744,6 +55631,16 @@ exports.computeActiveEmodePairs = computeActiveEmodePairs;
54744
55631
  exports.computeAssetHealthComponent = computeAssetHealthComponent;
54745
55632
  exports.computeAssetUsdValue = computeAssetUsdValue;
54746
55633
  exports.computeBalanceUsdValue = computeBalanceUsdValue;
55634
+ exports.computeBankBorrowApy = computeBankBorrowApy;
55635
+ exports.computeBankBorrowCapRemaining = computeBankBorrowCapRemaining;
55636
+ exports.computeBankDepositCapRemaining = computeBankDepositCapRemaining;
55637
+ exports.computeBankMetrics = computeBankMetrics;
55638
+ exports.computeBankPoolSize = computeBankPoolSize;
55639
+ exports.computeBankSupplyApy = computeBankSupplyApy;
55640
+ exports.computeBankTotalBorrows = computeBankTotalBorrows;
55641
+ exports.computeBankTotalBorrowsUsd = computeBankTotalBorrowsUsd;
55642
+ exports.computeBankTotalDeposits = computeBankTotalDeposits;
55643
+ exports.computeBankTotalDepositsUsd = computeBankTotalDepositsUsd;
54747
55644
  exports.computeBaseInterestRate = computeBaseInterestRate;
54748
55645
  exports.computeClaimedEmissions = computeClaimedEmissions;
54749
55646
  exports.computeClosePositionTokenAmount = computeClosePositionTokenAmount;
@@ -54774,6 +55671,7 @@ exports.computeQuantity = computeQuantity;
54774
55671
  exports.computeQuantityUi = computeQuantityUi;
54775
55672
  exports.computeRemainingCapacity = computeRemainingCapacity;
54776
55673
  exports.computeSmartCrank = computeSmartCrank;
55674
+ exports.computeStakedBankMultipliers = computeStakedBankMultipliers;
54777
55675
  exports.computeTotalOutstandingEmissions = computeTotalOutstandingEmissions;
54778
55676
  exports.computeTvl = computeTvl;
54779
55677
  exports.computeUsdValue = computeUsdValue;
@@ -54834,6 +55732,7 @@ exports.fetchSwbOraclePricesFromAPI = fetchSwbOraclePricesFromAPI;
54834
55732
  exports.fetchSwbOraclePricesFromCrossbar = fetchSwbOraclePricesFromCrossbar;
54835
55733
  exports.findRandomAvailableAccountIndex = findRandomAvailableAccountIndex;
54836
55734
  exports.freezeBankConfigIx = freezeBankConfigIx;
55735
+ exports.generateDummyAccount = generateDummyAccount;
54837
55736
  exports.getAccountKeys = getAccountKeys;
54838
55737
  exports.getActiveAccountFlags = getActiveAccountFlags;
54839
55738
  exports.getActiveBalances = getActiveBalances;
@@ -54872,6 +55771,7 @@ exports.getOracleSourceFromOracleSetup = getOracleSourceFromOracleSetup;
54872
55771
  exports.getOracleSourceNameFromKey = getOracleSourceNameFromKey;
54873
55772
  exports.getPrice = getPrice;
54874
55773
  exports.getPriceWithConfidence = getPriceWithConfidence;
55774
+ exports.getStakedBankMetadataMap = getStakedBankMetadataMap;
54875
55775
  exports.getSwapIxsForFlashloan = getSwapIxsForFlashloan;
54876
55776
  exports.getTitanExactOutEstimate = getTitanExactOutEstimate;
54877
55777
  exports.getTitanSwapIxsForFlashloan = getTitanSwapIxsForFlashloan;
@@ -54879,6 +55779,7 @@ exports.getTotalAccountKeys = getTotalAccountKeys;
54879
55779
  exports.getTotalAssetQuantity = getTotalAssetQuantity;
54880
55780
  exports.getTotalLiabilityQuantity = getTotalLiabilityQuantity;
54881
55781
  exports.getTxSize = getTxSize;
55782
+ exports.getValidatorVoteAccountByBank = getValidatorVoteAccountByBank;
54882
55783
  exports.getWritableAccountKeys = getWritableAccountKeys;
54883
55784
  exports.groupToDto = groupToDto;
54884
55785
  exports.hasAccountFlag = hasAccountFlag;
@@ -54920,11 +55821,16 @@ exports.makeKaminoDepositTx = makeKaminoDepositTx;
54920
55821
  exports.makeKaminoWithdrawIx = makeKaminoWithdrawIx3;
54921
55822
  exports.makeKaminoWithdrawTx = makeKaminoWithdrawTx;
54922
55823
  exports.makeLoopTx = makeLoopTx;
55824
+ exports.makeMergeStakeAccountsTx = makeMergeStakeAccountsTx;
55825
+ exports.makeMintStakedLstIx = makeMintStakedLstIx;
55826
+ exports.makeMintStakedLstTx = makeMintStakedLstTx;
54923
55827
  exports.makePoolAddBankIx = makePoolAddBankIx3;
54924
55828
  exports.makePoolConfigureBankIx = makePoolConfigureBankIx3;
54925
55829
  exports.makePriorityFeeIx = makePriorityFeeIx;
54926
55830
  exports.makePriorityFeeMicroIx = makePriorityFeeMicroIx;
54927
55831
  exports.makePulseHealthIx = makePulseHealthIx2;
55832
+ exports.makeRedeemStakedLstIx = makeRedeemStakedLstIx;
55833
+ exports.makeRedeemStakedLstTx = makeRedeemStakedLstTx;
54928
55834
  exports.makeRefreshKaminoBanksIxs = makeRefreshKaminoBanksIxs;
54929
55835
  exports.makeRepayIx = makeRepayIx3;
54930
55836
  exports.makeRepayTx = makeRepayTx;