@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 +2036 -1130
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +218 -19
- package/dist/index.d.ts +218 -19
- package/dist/index.js +2020 -1132
- package/dist/index.js.map +1 -1
- package/dist/vendor.cjs +50 -4
- package/dist/vendor.cjs.map +1 -1
- package/dist/vendor.d.cts +21 -1
- package/dist/vendor.d.ts +21 -1
- package/dist/vendor.js +49 -5
- package/dist/vendor.js.map +1 -1
- package/package.json +4 -1
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
|
-
|
|
44377
|
+
const onOpen = () => {
|
|
44378
|
+
ws.off("error", onError);
|
|
44379
|
+
ws.off("close", onClose);
|
|
44174
44380
|
resolve(new _V1Client(ws));
|
|
44175
|
-
}
|
|
44176
|
-
|
|
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
|
-
|
|
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
|
|
46718
|
-
|
|
46719
|
-
|
|
46720
|
-
|
|
46721
|
-
|
|
46722
|
-
|
|
46723
|
-
|
|
46724
|
-
|
|
46725
|
-
|
|
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:
|
|
46740
|
-
|
|
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
|
-
{
|
|
46748
|
-
|
|
46749
|
-
|
|
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:
|
|
46753
|
-
|
|
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
|
-
|
|
46760
|
-
|
|
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
|
-
|
|
46763
|
-
return {
|
|
46764
|
-
instructions: repayIxs,
|
|
46765
|
-
keys: []
|
|
46766
|
-
};
|
|
46981
|
+
return { instructions: [ix], keys: [] };
|
|
46767
46982
|
}
|
|
46768
|
-
async function
|
|
46769
|
-
|
|
46770
|
-
|
|
46771
|
-
|
|
46772
|
-
|
|
46773
|
-
|
|
46774
|
-
|
|
46775
|
-
|
|
46776
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
46786
|
-
|
|
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:
|
|
46800
|
-
tokenProgram:
|
|
47055
|
+
mint: borrowOpts.borrowBank.mint,
|
|
47056
|
+
tokenProgram: borrowOpts.tokenProgram
|
|
46801
47057
|
},
|
|
46802
47058
|
{
|
|
46803
|
-
mint:
|
|
46804
|
-
tokenProgram:
|
|
47059
|
+
mint: depositOpts.depositBank.mint,
|
|
47060
|
+
tokenProgram: depositOpts.tokenProgram
|
|
46805
47061
|
}
|
|
46806
47062
|
]
|
|
46807
47063
|
});
|
|
46808
|
-
const
|
|
46809
|
-
marginfiAccount,
|
|
46810
|
-
bankMap,
|
|
46811
|
-
[
|
|
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
|
-
[
|
|
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
|
-
[
|
|
47079
|
+
[borrowOpts.borrowBank.address, depositOpts.depositBank.address],
|
|
46824
47080
|
bankMetadataMap
|
|
46825
47081
|
);
|
|
46826
|
-
const { flashloanTx, setupInstructions, swapQuote,
|
|
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(
|
|
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: [...
|
|
47104
|
+
instructions: [...borrowIxs.instructions, ...depositIxs.instructions],
|
|
46849
47105
|
program,
|
|
46850
47106
|
connection,
|
|
46851
47107
|
crossbarUrl
|
|
46852
47108
|
});
|
|
46853
47109
|
let additionalTxs = [];
|
|
46854
|
-
if (
|
|
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
|
-
...
|
|
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 {
|
|
47151
|
+
return {
|
|
47152
|
+
transactions,
|
|
47153
|
+
actionTxIndex: transactions.length - 1,
|
|
47154
|
+
quoteResponse: swapQuote
|
|
47155
|
+
};
|
|
46890
47156
|
}
|
|
46891
|
-
async function
|
|
47157
|
+
async function buildLoopFlashloanTx({
|
|
46892
47158
|
program,
|
|
46893
47159
|
marginfiAccount,
|
|
46894
47160
|
bankMap,
|
|
46895
|
-
|
|
46896
|
-
|
|
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
|
|
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 (
|
|
46916
|
-
|
|
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(
|
|
47184
|
+
new web3_js.PublicKey(depositOpts.depositBank.mint),
|
|
46920
47185
|
marginfiAccount.authority,
|
|
46921
47186
|
true,
|
|
46922
|
-
|
|
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: "
|
|
46932
|
-
bank:
|
|
46933
|
-
tokenProgram:
|
|
47196
|
+
type: "borrow",
|
|
47197
|
+
bank: borrowOpts.borrowBank,
|
|
47198
|
+
tokenProgram: borrowOpts.tokenProgram
|
|
46934
47199
|
},
|
|
46935
47200
|
secondaryIx: {
|
|
46936
|
-
type: "
|
|
46937
|
-
bank:
|
|
46938
|
-
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:
|
|
46944
|
-
outputMint:
|
|
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
|
-
|
|
47221
|
+
swapResponse.quoteResponse.otherAmountThreshold,
|
|
47222
|
+
depositOpts.depositBank.mintDecimals
|
|
46964
47223
|
);
|
|
46965
|
-
|
|
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
|
-
|
|
46971
|
-
|
|
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[
|
|
47248
|
+
const reserve = bankMetadataMap[depositOpts.depositBank.address.toBase58()]?.kaminoStates?.reserveState;
|
|
46974
47249
|
if (!reserve) {
|
|
46975
47250
|
throw TransactionBuildingError.kaminoReserveNotFound(
|
|
46976
|
-
|
|
46977
|
-
|
|
46978
|
-
|
|
47251
|
+
depositOpts.depositBank.address.toBase58(),
|
|
47252
|
+
depositOpts.depositBank.mint.toBase58(),
|
|
47253
|
+
depositOpts.depositBank.tokenSymbol
|
|
46979
47254
|
);
|
|
46980
47255
|
}
|
|
46981
|
-
|
|
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:
|
|
46986
|
-
|
|
46987
|
-
|
|
46988
|
-
|
|
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[
|
|
47273
|
+
const driftState = bankMetadataMap[depositOpts.depositBank.address.toBase58()]?.driftStates;
|
|
47011
47274
|
if (!driftState) {
|
|
47012
47275
|
throw TransactionBuildingError.driftStateNotFound(
|
|
47013
|
-
|
|
47014
|
-
|
|
47015
|
-
|
|
47276
|
+
depositOpts.depositBank.address.toBase58(),
|
|
47277
|
+
depositOpts.depositBank.mint.toBase58(),
|
|
47278
|
+
depositOpts.depositBank.tokenSymbol
|
|
47016
47279
|
);
|
|
47017
47280
|
}
|
|
47018
|
-
|
|
47281
|
+
const driftMarketIndex = driftState.spotMarketState.marketIndex;
|
|
47282
|
+
const driftOracle = driftState.spotMarketState.oracle;
|
|
47283
|
+
depositIxs = await makeDriftDepositIx3({
|
|
47019
47284
|
program,
|
|
47020
|
-
bank:
|
|
47021
|
-
|
|
47022
|
-
|
|
47023
|
-
|
|
47024
|
-
marginfiAccount,
|
|
47285
|
+
bank: depositOpts.depositBank,
|
|
47286
|
+
tokenProgram: depositOpts.tokenProgram,
|
|
47287
|
+
amount: amountToDeposit,
|
|
47288
|
+
accountAddress: marginfiAccount.address,
|
|
47025
47289
|
authority: marginfiAccount.authority,
|
|
47026
|
-
|
|
47027
|
-
|
|
47028
|
-
|
|
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
|
-
|
|
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:
|
|
47083
|
-
|
|
47084
|
-
|
|
47085
|
-
|
|
47086
|
-
marginfiAccount,
|
|
47303
|
+
bank: depositOpts.depositBank,
|
|
47304
|
+
tokenProgram: depositOpts.tokenProgram,
|
|
47305
|
+
amount: amountToDeposit,
|
|
47306
|
+
accountAddress: marginfiAccount.address,
|
|
47087
47307
|
authority: marginfiAccount.authority,
|
|
47088
|
-
|
|
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
|
-
|
|
47107
|
-
|
|
47108
|
-
|
|
47109
|
-
|
|
47110
|
-
|
|
47111
|
-
|
|
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
|
-
|
|
47568
|
-
|
|
47569
|
-
|
|
47324
|
+
group: marginfiAccount.group,
|
|
47325
|
+
opts: {
|
|
47326
|
+
wrapAndUnwrapSol: false,
|
|
47327
|
+
overrideInferAccounts
|
|
47328
|
+
}
|
|
47570
47329
|
});
|
|
47330
|
+
break;
|
|
47571
47331
|
}
|
|
47572
47332
|
}
|
|
47573
|
-
|
|
47574
|
-
|
|
47575
|
-
|
|
47576
|
-
|
|
47577
|
-
|
|
47578
|
-
|
|
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
|
-
|
|
47589
|
-
|
|
47590
|
-
|
|
47591
|
-
|
|
47592
|
-
|
|
47593
|
-
|
|
47594
|
-
|
|
47595
|
-
|
|
47596
|
-
)
|
|
47597
|
-
|
|
47598
|
-
|
|
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
|
-
|
|
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
|
-
|
|
47616
|
-
|
|
47617
|
-
|
|
47618
|
-
|
|
47619
|
-
|
|
47620
|
-
|
|
47621
|
-
|
|
47622
|
-
|
|
47623
|
-
|
|
47624
|
-
|
|
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:
|
|
47628
|
-
|
|
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
|
-
{
|
|
47631
|
-
|
|
47632
|
-
|
|
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:
|
|
47640
|
-
|
|
47641
|
-
|
|
47642
|
-
|
|
47643
|
-
|
|
47644
|
-
|
|
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
|
-
|
|
47654
|
-
|
|
47655
|
-
isSigner: false,
|
|
47656
|
-
isWritable: false
|
|
47657
|
-
}))
|
|
47418
|
+
{ amount: uiToNative(amount, bank.mintDecimals), repayAll },
|
|
47419
|
+
remainingAccounts
|
|
47658
47420
|
);
|
|
47659
|
-
|
|
47421
|
+
repayIxs.push(repayIx);
|
|
47422
|
+
return {
|
|
47423
|
+
instructions: repayIxs,
|
|
47424
|
+
keys: []
|
|
47425
|
+
};
|
|
47660
47426
|
}
|
|
47661
|
-
async function
|
|
47662
|
-
|
|
47663
|
-
|
|
47664
|
-
ixs
|
|
47665
|
-
|
|
47666
|
-
|
|
47667
|
-
|
|
47668
|
-
|
|
47669
|
-
|
|
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
|
-
|
|
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
|
-
|
|
47719
|
-
|
|
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:
|
|
47734
|
-
tokenProgram:
|
|
47458
|
+
mint: repayOpts.repayBank.mint,
|
|
47459
|
+
tokenProgram: repayOpts.tokenProgram
|
|
47735
47460
|
},
|
|
47736
47461
|
{
|
|
47737
|
-
mint:
|
|
47738
|
-
tokenProgram:
|
|
47462
|
+
mint: withdrawOpts.withdrawBank.mint,
|
|
47463
|
+
tokenProgram: withdrawOpts.tokenProgram
|
|
47739
47464
|
}
|
|
47740
47465
|
]
|
|
47741
47466
|
});
|
|
47742
|
-
const
|
|
47743
|
-
|
|
47744
|
-
|
|
47745
|
-
[
|
|
47746
|
-
|
|
47467
|
+
const updateJuplendMarketIxs = makeUpdateJupLendRateIxs(
|
|
47468
|
+
marginfiAccount,
|
|
47469
|
+
bankMap,
|
|
47470
|
+
[withdrawOpts.withdrawBank.address],
|
|
47471
|
+
bankMetadataMap
|
|
47747
47472
|
);
|
|
47748
47473
|
const updateDriftMarketIxs = makeUpdateDriftMarketIxs(
|
|
47749
|
-
|
|
47750
|
-
|
|
47751
|
-
[
|
|
47752
|
-
|
|
47474
|
+
marginfiAccount,
|
|
47475
|
+
bankMap,
|
|
47476
|
+
[withdrawOpts.withdrawBank.address],
|
|
47477
|
+
bankMetadataMap
|
|
47753
47478
|
);
|
|
47754
47479
|
const kaminoRefreshIxs = makeRefreshKaminoBanksIxs(
|
|
47755
47480
|
marginfiAccount,
|
|
47756
47481
|
bankMap,
|
|
47757
|
-
[
|
|
47482
|
+
[withdrawOpts.withdrawBank.address, repayOpts.repayBank.address],
|
|
47758
47483
|
bankMetadataMap
|
|
47759
47484
|
);
|
|
47760
|
-
const { flashloanTx, setupInstructions, swapQuote,
|
|
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(
|
|
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: [...
|
|
47507
|
+
instructions: [...withdrawIxs.instructions, ...repayIxs.instructions],
|
|
47783
47508
|
program,
|
|
47784
47509
|
connection,
|
|
47785
47510
|
crossbarUrl
|
|
47786
47511
|
});
|
|
47787
47512
|
let additionalTxs = [];
|
|
47788
|
-
if (
|
|
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
|
-
...
|
|
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
|
|
47550
|
+
async function buildRepayWithCollatFlashloanTx({
|
|
47836
47551
|
program,
|
|
47837
47552
|
marginfiAccount,
|
|
47838
47553
|
bankMap,
|
|
47839
|
-
|
|
47840
|
-
|
|
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
|
|
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 (
|
|
47859
|
-
|
|
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(
|
|
47578
|
+
new web3_js.PublicKey(repayOpts.repayBank.mint),
|
|
47863
47579
|
marginfiAccount.authority,
|
|
47864
47580
|
true,
|
|
47865
|
-
|
|
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: "
|
|
47875
|
-
bank:
|
|
47876
|
-
tokenProgram:
|
|
47590
|
+
type: "withdraw",
|
|
47591
|
+
bank: withdrawOpts.withdrawBank,
|
|
47592
|
+
tokenProgram: withdrawOpts.tokenProgram
|
|
47877
47593
|
},
|
|
47878
47594
|
secondaryIx: {
|
|
47879
|
-
type: "
|
|
47880
|
-
bank:
|
|
47881
|
-
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:
|
|
47887
|
-
outputMint:
|
|
47888
|
-
amount: uiToNative(
|
|
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
|
-
|
|
47901
|
-
|
|
47620
|
+
quoteResponse.otherAmountThreshold,
|
|
47621
|
+
repayOpts.repayBank.mintDecimals
|
|
47902
47622
|
);
|
|
47903
|
-
|
|
47623
|
+
amountToRepay = outAmount > repayOpts.totalPositionAmount ? repayOpts.totalPositionAmount : outAmountThreshold;
|
|
47904
47624
|
swapInstructions = swapResponse.swapInstructions;
|
|
47905
|
-
setupInstructions = swapResponse.setupInstructions;
|
|
47906
47625
|
swapLookupTables = swapResponse.addressLookupTableAddresses;
|
|
47907
|
-
swapQuote =
|
|
47626
|
+
swapQuote = quoteResponse;
|
|
47908
47627
|
}
|
|
47909
|
-
|
|
47910
|
-
|
|
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[
|
|
47631
|
+
const reserve = bankMetadataMap[withdrawOpts.withdrawBank.address.toBase58()]?.kaminoStates?.reserveState;
|
|
47928
47632
|
if (!reserve) {
|
|
47929
47633
|
throw TransactionBuildingError.kaminoReserveNotFound(
|
|
47930
|
-
|
|
47931
|
-
|
|
47932
|
-
|
|
47634
|
+
withdrawOpts.withdrawBank.address.toBase58(),
|
|
47635
|
+
withdrawOpts.withdrawBank.mint.toBase58(),
|
|
47636
|
+
withdrawOpts.withdrawBank.tokenSymbol
|
|
47933
47637
|
);
|
|
47934
47638
|
}
|
|
47935
|
-
|
|
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:
|
|
47938
|
-
|
|
47939
|
-
|
|
47940
|
-
|
|
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[
|
|
47668
|
+
const driftState = bankMetadataMap[withdrawOpts.withdrawBank.address.toBase58()]?.driftStates;
|
|
47953
47669
|
if (!driftState) {
|
|
47954
47670
|
throw TransactionBuildingError.driftStateNotFound(
|
|
47955
|
-
|
|
47956
|
-
|
|
47957
|
-
|
|
47671
|
+
withdrawOpts.withdrawBank.address.toBase58(),
|
|
47672
|
+
withdrawOpts.withdrawBank.mint.toBase58(),
|
|
47673
|
+
withdrawOpts.withdrawBank.tokenSymbol
|
|
47958
47674
|
);
|
|
47959
47675
|
}
|
|
47960
|
-
|
|
47961
|
-
const driftOracle = driftState.spotMarketState.oracle;
|
|
47962
|
-
depositIxs = await makeDriftDepositIx3({
|
|
47676
|
+
withdrawIxs = await makeDriftWithdrawIx3({
|
|
47963
47677
|
program,
|
|
47964
|
-
bank:
|
|
47965
|
-
|
|
47966
|
-
|
|
47967
|
-
|
|
47678
|
+
bank: withdrawOpts.withdrawBank,
|
|
47679
|
+
bankMap,
|
|
47680
|
+
tokenProgram: withdrawOpts.tokenProgram,
|
|
47681
|
+
amount: withdrawOpts.withdrawAmount,
|
|
47682
|
+
marginfiAccount,
|
|
47968
47683
|
authority: marginfiAccount.authority,
|
|
47969
|
-
|
|
47970
|
-
|
|
47971
|
-
|
|
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
|
-
|
|
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:
|
|
47983
|
-
|
|
47984
|
-
|
|
47985
|
-
|
|
47714
|
+
bank: withdrawOpts.withdrawBank,
|
|
47715
|
+
bankMap,
|
|
47716
|
+
tokenProgram: withdrawOpts.tokenProgram,
|
|
47717
|
+
amount: withdrawOpts.withdrawAmount,
|
|
47718
|
+
marginfiAccount,
|
|
47986
47719
|
authority: marginfiAccount.authority,
|
|
47987
|
-
|
|
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
|
-
|
|
47738
|
+
withdrawIxs = await makeWithdrawIx3({
|
|
47997
47739
|
program,
|
|
47998
|
-
bank:
|
|
47999
|
-
|
|
48000
|
-
|
|
48001
|
-
|
|
47740
|
+
bank: withdrawOpts.withdrawBank,
|
|
47741
|
+
bankMap,
|
|
47742
|
+
tokenProgram: withdrawOpts.tokenProgram,
|
|
47743
|
+
amount: withdrawOpts.withdrawAmount,
|
|
47744
|
+
marginfiAccount,
|
|
48002
47745
|
authority: marginfiAccount.authority,
|
|
48003
|
-
|
|
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
|
-
...
|
|
47788
|
+
...withdrawIxs.instructions,
|
|
48016
47789
|
...swapInstructions,
|
|
48017
|
-
...
|
|
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 ||
|
|
48041
|
-
throw TransactionBuildingError.
|
|
47813
|
+
if (txSize > MAX_TX_SIZE || totalKeys > MAX_ACCOUNT_LOCKS) {
|
|
47814
|
+
throw TransactionBuildingError.swapSizeExceededRepay(
|
|
48042
47815
|
txSize,
|
|
48043
|
-
|
|
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
|
-
|
|
48052
|
-
|
|
48053
|
-
|
|
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 ||
|
|
48486
|
-
throw TransactionBuildingError.
|
|
48256
|
+
if (txSize > MAX_TX_SIZE || totalKeys > MAX_ACCOUNT_LOCKS) {
|
|
48257
|
+
throw TransactionBuildingError.swapSizeExceededPositionSwap(
|
|
48487
48258
|
txSize,
|
|
48488
|
-
|
|
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 ||
|
|
48749
|
-
throw TransactionBuildingError.
|
|
48517
|
+
if (txSize > MAX_TX_SIZE || totalKeys > MAX_ACCOUNT_LOCKS) {
|
|
48518
|
+
throw TransactionBuildingError.swapSizeExceededPositionSwap(
|
|
48750
48519
|
txSize,
|
|
48751
|
-
|
|
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 (!
|
|
49421
|
-
|
|
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
|
-
|
|
49203
|
+
effectiveFeeAccount
|
|
49431
49204
|
);
|
|
49432
49205
|
} else {
|
|
49433
49206
|
return getTitanSwapIxsViaHttpProxy(
|
|
49434
49207
|
{ quoteParams: finalQuoteParams, authority, connection, destinationTokenAccount, apiConfig },
|
|
49435
|
-
|
|
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
|
-
|
|
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
|
-
|
|
49932
|
-
|
|
49933
|
-
|
|
49934
|
-
|
|
49935
|
-
|
|
49936
|
-
|
|
49937
|
-
|
|
49938
|
-
|
|
49939
|
-
|
|
49940
|
-
|
|
49941
|
-
|
|
49942
|
-
|
|
49943
|
-
|
|
49944
|
-
|
|
49945
|
-
|
|
49946
|
-
|
|
49947
|
-
|
|
49948
|
-
|
|
49949
|
-
|
|
49950
|
-
|
|
49951
|
-
|
|
49952
|
-
|
|
49953
|
-
|
|
49954
|
-
|
|
49955
|
-
|
|
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
|
-
|
|
49967
|
-
|
|
49968
|
-
|
|
49969
|
-
|
|
49970
|
-
|
|
49971
|
-
|
|
49972
|
-
|
|
49973
|
-
|
|
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
|
-
|
|
49976
|
-
|
|
49977
|
-
|
|
49978
|
-
|
|
49979
|
-
|
|
49980
|
-
|
|
49981
|
-
|
|
49982
|
-
|
|
49983
|
-
|
|
49984
|
-
|
|
49985
|
-
|
|
49986
|
-
|
|
49987
|
-
|
|
49988
|
-
|
|
49989
|
-
|
|
49990
|
-
|
|
49991
|
-
|
|
49992
|
-
|
|
49993
|
-
|
|
49994
|
-
|
|
49995
|
-
}
|
|
49996
|
-
|
|
49997
|
-
|
|
49998
|
-
|
|
49999
|
-
|
|
50000
|
-
|
|
50001
|
-
|
|
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
|
|
50004
|
-
|
|
50005
|
-
|
|
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;
|