@0dotxyz/p0-ts-sdk 2.2.0-beta.3 → 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 +2025 -1100
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +218 -15
- package/dist/index.d.ts +218 -15
- package/dist/index.js +2009 -1103
- 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
|
*/
|
|
@@ -15163,9 +15152,48 @@ var MintLayout = bufferLayout.struct([
|
|
|
15163
15152
|
bufferLayoutUtils.publicKey("freezeAuthority")
|
|
15164
15153
|
]);
|
|
15165
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
|
+
}
|
|
15166
15178
|
bufferLayout.struct([
|
|
15167
15179
|
bufferLayout.u8("instruction")
|
|
15168
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
|
+
}
|
|
15169
15197
|
function createAssociatedTokenAccountIdempotentInstruction(payer, associatedToken, owner, mint, programId = TOKEN_PROGRAM_ID, associatedTokenProgramId = ASSOCIATED_TOKEN_PROGRAM_ID) {
|
|
15170
15198
|
return buildAssociatedTokenAccountInstruction(
|
|
15171
15199
|
payer,
|
|
@@ -43378,6 +43406,173 @@ new Fraction(new BN11__default.default(0));
|
|
|
43378
43406
|
function roundNearest(decimal) {
|
|
43379
43407
|
return decimal.toDecimalPlaces(0, Decimal3__default.default.ROUND_HALF_CEIL);
|
|
43380
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
|
+
};
|
|
43381
43576
|
var findPda = (baseAddress, prefix, programId = SINGLE_POOL_PROGRAM_ID) => {
|
|
43382
43577
|
const [pda] = web3_js.PublicKey.findProgramAddressSync(
|
|
43383
43578
|
[Buffer.from(prefix), baseAddress.toBuffer()],
|
|
@@ -43388,7 +43583,17 @@ var findPda = (baseAddress, prefix, programId = SINGLE_POOL_PROGRAM_ID) => {
|
|
|
43388
43583
|
var findPoolAddress = (voteAccountAddress) => findPda(voteAccountAddress, "pool");
|
|
43389
43584
|
var findPoolMintAddress = (poolAddress) => findPda(poolAddress, "mint");
|
|
43390
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");
|
|
43391
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
|
+
};
|
|
43392
43597
|
BigInt(33);
|
|
43393
43598
|
BigInt(200);
|
|
43394
43599
|
BigInt(82);
|
|
@@ -44169,12 +44374,28 @@ var V1Client = class _V1Client {
|
|
|
44169
44374
|
return new Promise((resolve, reject) => {
|
|
44170
44375
|
const ws = new WebSocket__default.default(url, [SUBPROTOCOL]);
|
|
44171
44376
|
ws.binaryType = "arraybuffer";
|
|
44172
|
-
|
|
44377
|
+
const onOpen = () => {
|
|
44378
|
+
ws.off("error", onError);
|
|
44379
|
+
ws.off("close", onClose);
|
|
44173
44380
|
resolve(new _V1Client(ws));
|
|
44174
|
-
}
|
|
44175
|
-
|
|
44381
|
+
};
|
|
44382
|
+
const onError = (err) => {
|
|
44383
|
+
ws.off("open", onOpen);
|
|
44384
|
+
ws.off("close", onClose);
|
|
44176
44385
|
reject(err);
|
|
44177
|
-
}
|
|
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);
|
|
44178
44399
|
});
|
|
44179
44400
|
}
|
|
44180
44401
|
// --- Constructor ---
|
|
@@ -46175,10 +46396,11 @@ async function makeBorrowIx3({
|
|
|
46175
46396
|
);
|
|
46176
46397
|
borrowIxs.push(createAtaIdempotentIx);
|
|
46177
46398
|
}
|
|
46399
|
+
const mandatoryBanks = [bank.address, ...opts.additionalHealthCheckBanks ?? []];
|
|
46178
46400
|
const healthAccounts = computeHealthCheckAccounts(
|
|
46179
46401
|
marginfiAccount.balances,
|
|
46180
46402
|
bankMap,
|
|
46181
|
-
|
|
46403
|
+
mandatoryBanks,
|
|
46182
46404
|
[]
|
|
46183
46405
|
);
|
|
46184
46406
|
const remainingAccounts = [];
|
|
@@ -46713,81 +46935,116 @@ async function makeJuplendDepositTx(params) {
|
|
|
46713
46935
|
});
|
|
46714
46936
|
return solanaTx;
|
|
46715
46937
|
}
|
|
46716
|
-
async function
|
|
46717
|
-
|
|
46718
|
-
|
|
46719
|
-
|
|
46720
|
-
|
|
46721
|
-
|
|
46722
|
-
|
|
46723
|
-
|
|
46724
|
-
|
|
46725
|
-
opts = {}
|
|
46726
|
-
}) {
|
|
46727
|
-
const wrapAndUnwrapSol = opts.wrapAndUnwrapSol ?? true;
|
|
46728
|
-
const wSolBalanceUi = opts.wSolBalanceUi ?? 0;
|
|
46729
|
-
const repayIxs = [];
|
|
46730
|
-
const userAta = getAssociatedTokenAddressSync(bank.mint, authority, true, tokenProgram);
|
|
46731
|
-
const remainingAccounts = tokenProgram.equals(TOKEN_2022_PROGRAM_ID) ? [{ pubkey: bank.mint, isSigner: false, isWritable: false }] : [];
|
|
46732
|
-
if (bank.mint.equals(NATIVE_MINT) && wrapAndUnwrapSol) {
|
|
46733
|
-
repayIxs.push(...makeWrapSolIxs(authority, new BigNumber3.BigNumber(amount).minus(wSolBalanceUi)));
|
|
46734
|
-
}
|
|
46735
|
-
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(
|
|
46736
46947
|
program,
|
|
46737
46948
|
{
|
|
46738
|
-
marginfiAccount:
|
|
46739
|
-
|
|
46740
|
-
bank: bank.address,
|
|
46741
|
-
tokenProgram,
|
|
46742
|
-
authority: opts.overrideInferAccounts?.authority ?? authority,
|
|
46743
|
-
group: opts.overrideInferAccounts?.group,
|
|
46744
|
-
liquidityVault: opts.overrideInferAccounts?.liquidityVault
|
|
46949
|
+
marginfiAccount: marginfiAccountPk,
|
|
46950
|
+
authority
|
|
46745
46951
|
},
|
|
46746
|
-
{
|
|
46747
|
-
|
|
46748
|
-
|
|
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(
|
|
46749
46959
|
program.programId,
|
|
46750
46960
|
{
|
|
46751
|
-
marginfiAccount:
|
|
46752
|
-
|
|
46753
|
-
bank: bank.address,
|
|
46754
|
-
tokenProgram,
|
|
46755
|
-
authority: opts.overrideInferAccounts?.authority ?? authority,
|
|
46756
|
-
group: opts.overrideInferAccounts?.group
|
|
46961
|
+
marginfiAccount: marginfiAccountPk,
|
|
46962
|
+
authority
|
|
46757
46963
|
},
|
|
46758
|
-
|
|
46759
|
-
|
|
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
|
+
}))
|
|
46760
46980
|
);
|
|
46761
|
-
|
|
46762
|
-
return {
|
|
46763
|
-
instructions: repayIxs,
|
|
46764
|
-
keys: []
|
|
46765
|
-
};
|
|
46981
|
+
return { instructions: [ix], keys: [] };
|
|
46766
46982
|
}
|
|
46767
|
-
async function
|
|
46768
|
-
|
|
46769
|
-
|
|
46770
|
-
|
|
46771
|
-
|
|
46772
|
-
|
|
46773
|
-
|
|
46774
|
-
|
|
46775
|
-
|
|
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;
|
|
46776
47003
|
});
|
|
46777
|
-
|
|
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;
|
|
46778
47032
|
}
|
|
46779
|
-
|
|
47033
|
+
|
|
47034
|
+
// src/services/account/actions/loop.ts
|
|
47035
|
+
async function makeLoopTx(params) {
|
|
46780
47036
|
const {
|
|
46781
47037
|
program,
|
|
46782
47038
|
marginfiAccount,
|
|
46783
47039
|
bankMap,
|
|
46784
|
-
|
|
46785
|
-
|
|
47040
|
+
depositOpts,
|
|
47041
|
+
borrowOpts,
|
|
46786
47042
|
bankMetadataMap,
|
|
46787
47043
|
addressLookupTableAccounts,
|
|
46788
47044
|
connection,
|
|
46789
47045
|
oraclePrices,
|
|
46790
|
-
crossbarUrl
|
|
47046
|
+
crossbarUrl,
|
|
47047
|
+
additionalIxs = []
|
|
46791
47048
|
} = params;
|
|
46792
47049
|
const blockhash = (await connection.getLatestBlockhash("confirmed")).blockhash;
|
|
46793
47050
|
const setupIxs = await makeSetupIx({
|
|
@@ -46795,34 +47052,34 @@ async function makeRepayWithCollatTx(params) {
|
|
|
46795
47052
|
authority: marginfiAccount.authority,
|
|
46796
47053
|
tokens: [
|
|
46797
47054
|
{
|
|
46798
|
-
mint:
|
|
46799
|
-
tokenProgram:
|
|
47055
|
+
mint: borrowOpts.borrowBank.mint,
|
|
47056
|
+
tokenProgram: borrowOpts.tokenProgram
|
|
46800
47057
|
},
|
|
46801
47058
|
{
|
|
46802
|
-
mint:
|
|
46803
|
-
tokenProgram:
|
|
47059
|
+
mint: depositOpts.depositBank.mint,
|
|
47060
|
+
tokenProgram: depositOpts.tokenProgram
|
|
46804
47061
|
}
|
|
46805
47062
|
]
|
|
46806
47063
|
});
|
|
46807
|
-
const
|
|
46808
|
-
marginfiAccount,
|
|
46809
|
-
bankMap,
|
|
46810
|
-
[
|
|
46811
|
-
bankMetadataMap
|
|
47064
|
+
const updateJupLendRateIxs = makeUpdateJupLendRateIxs(
|
|
47065
|
+
params.marginfiAccount,
|
|
47066
|
+
params.bankMap,
|
|
47067
|
+
[depositOpts.depositBank.address],
|
|
47068
|
+
params.bankMetadataMap
|
|
46812
47069
|
);
|
|
46813
47070
|
const updateDriftMarketIxs = makeUpdateDriftMarketIxs(
|
|
46814
|
-
marginfiAccount,
|
|
46815
|
-
bankMap,
|
|
46816
|
-
[
|
|
46817
|
-
bankMetadataMap
|
|
47071
|
+
params.marginfiAccount,
|
|
47072
|
+
params.bankMap,
|
|
47073
|
+
[depositOpts.depositBank.address],
|
|
47074
|
+
params.bankMetadataMap
|
|
46818
47075
|
);
|
|
46819
47076
|
const kaminoRefreshIxs = makeRefreshKaminoBanksIxs(
|
|
46820
47077
|
marginfiAccount,
|
|
46821
47078
|
bankMap,
|
|
46822
|
-
[
|
|
47079
|
+
[borrowOpts.borrowBank.address, depositOpts.depositBank.address],
|
|
46823
47080
|
bankMetadataMap
|
|
46824
47081
|
);
|
|
46825
|
-
const { flashloanTx, setupInstructions, swapQuote,
|
|
47082
|
+
const { flashloanTx, setupInstructions, swapQuote, amountToDeposit, depositIxs, borrowIxs } = await buildLoopFlashloanTx({
|
|
46826
47083
|
...params,
|
|
46827
47084
|
blockhash
|
|
46828
47085
|
});
|
|
@@ -46832,7 +47089,7 @@ async function makeRepayWithCollatTx(params) {
|
|
|
46832
47089
|
}
|
|
46833
47090
|
if (ix.programId.equals(ASSOCIATED_TOKEN_PROGRAM_ID)) {
|
|
46834
47091
|
const mintKey = ix.keys[3]?.pubkey;
|
|
46835
|
-
if (mintKey?.equals(
|
|
47092
|
+
if (mintKey?.equals(depositOpts.depositBank.mint) || mintKey?.equals(borrowOpts.borrowBank.mint)) {
|
|
46836
47093
|
return false;
|
|
46837
47094
|
}
|
|
46838
47095
|
}
|
|
@@ -46844,18 +47101,24 @@ async function makeRepayWithCollatTx(params) {
|
|
|
46844
47101
|
bankMap,
|
|
46845
47102
|
oraclePrices,
|
|
46846
47103
|
assetShareValueMultiplierByBank: params.assetShareValueMultiplierByBank,
|
|
46847
|
-
instructions: [...
|
|
47104
|
+
instructions: [...borrowIxs.instructions, ...depositIxs.instructions],
|
|
46848
47105
|
program,
|
|
46849
47106
|
connection,
|
|
46850
47107
|
crossbarUrl
|
|
46851
47108
|
});
|
|
46852
47109
|
let additionalTxs = [];
|
|
46853
|
-
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) {
|
|
46854
47116
|
const ixs = [
|
|
47117
|
+
...additionalIxs,
|
|
46855
47118
|
...setupIxs,
|
|
46856
47119
|
...kaminoRefreshIxs.instructions,
|
|
46857
47120
|
...updateDriftMarketIxs.instructions,
|
|
46858
|
-
...
|
|
47121
|
+
...updateJupLendRateIxs.instructions
|
|
46859
47122
|
];
|
|
46860
47123
|
const txs = splitInstructionsToFitTransactions([], ixs, {
|
|
46861
47124
|
blockhash,
|
|
@@ -46885,16 +47148,19 @@ async function makeRepayWithCollatTx(params) {
|
|
|
46885
47148
|
);
|
|
46886
47149
|
}
|
|
46887
47150
|
const transactions = [...additionalTxs, flashloanTx];
|
|
46888
|
-
return {
|
|
47151
|
+
return {
|
|
47152
|
+
transactions,
|
|
47153
|
+
actionTxIndex: transactions.length - 1,
|
|
47154
|
+
quoteResponse: swapQuote
|
|
47155
|
+
};
|
|
46889
47156
|
}
|
|
46890
|
-
async function
|
|
47157
|
+
async function buildLoopFlashloanTx({
|
|
46891
47158
|
program,
|
|
46892
47159
|
marginfiAccount,
|
|
46893
47160
|
bankMap,
|
|
46894
|
-
|
|
46895
|
-
|
|
47161
|
+
borrowOpts,
|
|
47162
|
+
depositOpts,
|
|
46896
47163
|
bankMetadataMap,
|
|
46897
|
-
assetShareValueMultiplierByBank,
|
|
46898
47164
|
addressLookupTableAccounts,
|
|
46899
47165
|
connection,
|
|
46900
47166
|
swapOpts,
|
|
@@ -46905,20 +47171,20 @@ async function buildRepayWithCollatFlashloanTx({
|
|
|
46905
47171
|
web3_js.ComputeBudgetProgram.setComputeUnitLimit({ units: 12e5 }),
|
|
46906
47172
|
web3_js.ComputeBudgetProgram.setComputeUnitPrice({ microLamports: 1 })
|
|
46907
47173
|
];
|
|
46908
|
-
let
|
|
47174
|
+
let amountToDeposit;
|
|
46909
47175
|
let swapInstructions = [];
|
|
46910
47176
|
let setupInstructions = [];
|
|
46911
47177
|
let swapLookupTables = [];
|
|
46912
47178
|
let swapQuote;
|
|
46913
47179
|
let sizeConstraintUsed = 0;
|
|
46914
|
-
if (
|
|
46915
|
-
|
|
47180
|
+
if (depositOpts.depositBank.mint.equals(borrowOpts.borrowBank.mint)) {
|
|
47181
|
+
amountToDeposit = borrowOpts.borrowAmount + (depositOpts.loopMode === "DEPOSIT" ? depositOpts.inputDepositAmount : 0);
|
|
46916
47182
|
} else {
|
|
46917
47183
|
const destinationTokenAccount = getAssociatedTokenAddressSync(
|
|
46918
|
-
new web3_js.PublicKey(
|
|
47184
|
+
new web3_js.PublicKey(depositOpts.depositBank.mint),
|
|
46919
47185
|
marginfiAccount.authority,
|
|
46920
47186
|
true,
|
|
46921
|
-
|
|
47187
|
+
depositOpts.tokenProgram.equals(TOKEN_2022_PROGRAM_ID) ? TOKEN_2022_PROGRAM_ID : void 0
|
|
46922
47188
|
);
|
|
46923
47189
|
const swapConstraints = await computeFlashloanSwapConstraints({
|
|
46924
47190
|
program,
|
|
@@ -46927,24 +47193,21 @@ async function buildRepayWithCollatFlashloanTx({
|
|
|
46927
47193
|
bankMetadataMap,
|
|
46928
47194
|
addressLookupTableAccounts: addressLookupTableAccounts ?? [],
|
|
46929
47195
|
primaryIx: {
|
|
46930
|
-
type: "
|
|
46931
|
-
bank:
|
|
46932
|
-
tokenProgram:
|
|
47196
|
+
type: "borrow",
|
|
47197
|
+
bank: borrowOpts.borrowBank,
|
|
47198
|
+
tokenProgram: borrowOpts.tokenProgram
|
|
46933
47199
|
},
|
|
46934
47200
|
secondaryIx: {
|
|
46935
|
-
type: "
|
|
46936
|
-
bank:
|
|
46937
|
-
tokenProgram:
|
|
47201
|
+
type: "deposit",
|
|
47202
|
+
bank: depositOpts.depositBank,
|
|
47203
|
+
tokenProgram: depositOpts.tokenProgram
|
|
46938
47204
|
},
|
|
46939
47205
|
overrideInferAccounts
|
|
46940
47206
|
});
|
|
46941
47207
|
const swapResponse = await getSwapIxsForFlashloan({
|
|
46942
|
-
inputMint:
|
|
46943
|
-
outputMint:
|
|
46944
|
-
amount: uiToNative(
|
|
46945
|
-
withdrawOpts.withdrawAmount,
|
|
46946
|
-
withdrawOpts.withdrawBank.mintDecimals
|
|
46947
|
-
).toNumber(),
|
|
47208
|
+
inputMint: borrowOpts.borrowBank.mint.toBase58(),
|
|
47209
|
+
outputMint: depositOpts.depositBank.mint.toBase58(),
|
|
47210
|
+
amount: uiToNative(borrowOpts.borrowAmount, borrowOpts.borrowBank.mintDecimals).toNumber(),
|
|
46948
47211
|
swapMode: "ExactIn",
|
|
46949
47212
|
authority: marginfiAccount.authority,
|
|
46950
47213
|
connection,
|
|
@@ -46954,50 +47217,52 @@ async function buildRepayWithCollatFlashloanTx({
|
|
|
46954
47217
|
maxSwapTotalAccounts: swapConstraints.maxSwapTotalAccounts
|
|
46955
47218
|
});
|
|
46956
47219
|
sizeConstraintUsed = swapConstraints.sizeConstraint;
|
|
46957
|
-
const { quoteResponse } = swapResponse;
|
|
46958
|
-
const outAmount = nativeToUi(quoteResponse.outAmount, repayOpts.repayBank.mintDecimals);
|
|
46959
47220
|
const outAmountThreshold = nativeToUi(
|
|
46960
|
-
quoteResponse.otherAmountThreshold,
|
|
46961
|
-
|
|
47221
|
+
swapResponse.quoteResponse.otherAmountThreshold,
|
|
47222
|
+
depositOpts.depositBank.mintDecimals
|
|
46962
47223
|
);
|
|
46963
|
-
|
|
47224
|
+
amountToDeposit = outAmountThreshold + (depositOpts.loopMode === "DEPOSIT" ? depositOpts.inputDepositAmount : 0);
|
|
46964
47225
|
swapInstructions = swapResponse.swapInstructions;
|
|
47226
|
+
setupInstructions = swapResponse.setupInstructions;
|
|
46965
47227
|
swapLookupTables = swapResponse.addressLookupTableAddresses;
|
|
46966
|
-
swapQuote = quoteResponse;
|
|
47228
|
+
swapQuote = swapResponse.quoteResponse;
|
|
46967
47229
|
}
|
|
46968
|
-
|
|
46969
|
-
|
|
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) {
|
|
46970
47247
|
case 3 /* KAMINO */: {
|
|
46971
|
-
const reserve = bankMetadataMap[
|
|
47248
|
+
const reserve = bankMetadataMap[depositOpts.depositBank.address.toBase58()]?.kaminoStates?.reserveState;
|
|
46972
47249
|
if (!reserve) {
|
|
46973
47250
|
throw TransactionBuildingError.kaminoReserveNotFound(
|
|
46974
|
-
|
|
46975
|
-
|
|
46976
|
-
|
|
47251
|
+
depositOpts.depositBank.address.toBase58(),
|
|
47252
|
+
depositOpts.depositBank.mint.toBase58(),
|
|
47253
|
+
depositOpts.depositBank.tokenSymbol
|
|
46977
47254
|
);
|
|
46978
47255
|
}
|
|
46979
|
-
|
|
46980
|
-
const adjustedAmount = new BigNumber3.BigNumber(withdrawOpts.withdrawAmount).div(multiplier).times(1.0001).toNumber();
|
|
46981
|
-
withdrawIxs = await makeKaminoWithdrawIx3({
|
|
47256
|
+
depositIxs = await makeKaminoDepositIx3({
|
|
46982
47257
|
program,
|
|
46983
|
-
bank:
|
|
46984
|
-
|
|
46985
|
-
|
|
46986
|
-
|
|
46987
|
-
marginfiAccount,
|
|
47258
|
+
bank: depositOpts.depositBank,
|
|
47259
|
+
tokenProgram: depositOpts.tokenProgram,
|
|
47260
|
+
amount: amountToDeposit,
|
|
47261
|
+
accountAddress: marginfiAccount.address,
|
|
46988
47262
|
authority: marginfiAccount.authority,
|
|
47263
|
+
group: marginfiAccount.group,
|
|
46989
47264
|
reserve,
|
|
46990
|
-
withdrawAll: isWholePosition(
|
|
46991
|
-
{
|
|
46992
|
-
amount: withdrawOpts.totalPositionAmount,
|
|
46993
|
-
isLending: true
|
|
46994
|
-
},
|
|
46995
|
-
withdrawOpts.withdrawAmount,
|
|
46996
|
-
withdrawOpts.withdrawBank.mintDecimals
|
|
46997
|
-
),
|
|
46998
|
-
isSync: false,
|
|
46999
47265
|
opts: {
|
|
47000
|
-
createAtas: false,
|
|
47001
47266
|
wrapAndUnwrapSol: false,
|
|
47002
47267
|
overrideInferAccounts
|
|
47003
47268
|
}
|
|
@@ -47005,35 +47270,27 @@ async function buildRepayWithCollatFlashloanTx({
|
|
|
47005
47270
|
break;
|
|
47006
47271
|
}
|
|
47007
47272
|
case 4 /* DRIFT */: {
|
|
47008
|
-
const driftState = bankMetadataMap[
|
|
47273
|
+
const driftState = bankMetadataMap[depositOpts.depositBank.address.toBase58()]?.driftStates;
|
|
47009
47274
|
if (!driftState) {
|
|
47010
47275
|
throw TransactionBuildingError.driftStateNotFound(
|
|
47011
|
-
|
|
47012
|
-
|
|
47013
|
-
|
|
47276
|
+
depositOpts.depositBank.address.toBase58(),
|
|
47277
|
+
depositOpts.depositBank.mint.toBase58(),
|
|
47278
|
+
depositOpts.depositBank.tokenSymbol
|
|
47014
47279
|
);
|
|
47015
47280
|
}
|
|
47016
|
-
|
|
47281
|
+
const driftMarketIndex = driftState.spotMarketState.marketIndex;
|
|
47282
|
+
const driftOracle = driftState.spotMarketState.oracle;
|
|
47283
|
+
depositIxs = await makeDriftDepositIx3({
|
|
47017
47284
|
program,
|
|
47018
|
-
bank:
|
|
47019
|
-
|
|
47020
|
-
|
|
47021
|
-
|
|
47022
|
-
marginfiAccount,
|
|
47285
|
+
bank: depositOpts.depositBank,
|
|
47286
|
+
tokenProgram: depositOpts.tokenProgram,
|
|
47287
|
+
amount: amountToDeposit,
|
|
47288
|
+
accountAddress: marginfiAccount.address,
|
|
47023
47289
|
authority: marginfiAccount.authority,
|
|
47024
|
-
|
|
47025
|
-
|
|
47026
|
-
|
|
47027
|
-
{
|
|
47028
|
-
amount: withdrawOpts.totalPositionAmount,
|
|
47029
|
-
isLending: true
|
|
47030
|
-
},
|
|
47031
|
-
withdrawOpts.withdrawAmount,
|
|
47032
|
-
withdrawOpts.withdrawBank.mintDecimals
|
|
47033
|
-
),
|
|
47034
|
-
isSync: false,
|
|
47290
|
+
group: marginfiAccount.group,
|
|
47291
|
+
driftMarketIndex,
|
|
47292
|
+
driftOracle,
|
|
47035
47293
|
opts: {
|
|
47036
|
-
createAtas: false,
|
|
47037
47294
|
wrapAndUnwrapSol: false,
|
|
47038
47295
|
overrideInferAccounts
|
|
47039
47296
|
}
|
|
@@ -47041,33 +47298,15 @@ async function buildRepayWithCollatFlashloanTx({
|
|
|
47041
47298
|
break;
|
|
47042
47299
|
}
|
|
47043
47300
|
case 6 /* JUPLEND */: {
|
|
47044
|
-
|
|
47045
|
-
if (!jupLendState) {
|
|
47046
|
-
throw TransactionBuildingError.jupLendStateNotFound(
|
|
47047
|
-
withdrawOpts.withdrawBank.address.toBase58(),
|
|
47048
|
-
withdrawOpts.withdrawBank.mint.toBase58(),
|
|
47049
|
-
withdrawOpts.withdrawBank.tokenSymbol
|
|
47050
|
-
);
|
|
47051
|
-
}
|
|
47052
|
-
withdrawIxs = await makeJuplendWithdrawIx2({
|
|
47301
|
+
depositIxs = await makeJuplendDepositIx2({
|
|
47053
47302
|
program,
|
|
47054
|
-
bank:
|
|
47055
|
-
|
|
47056
|
-
|
|
47057
|
-
|
|
47058
|
-
marginfiAccount,
|
|
47303
|
+
bank: depositOpts.depositBank,
|
|
47304
|
+
tokenProgram: depositOpts.tokenProgram,
|
|
47305
|
+
amount: amountToDeposit,
|
|
47306
|
+
accountAddress: marginfiAccount.address,
|
|
47059
47307
|
authority: marginfiAccount.authority,
|
|
47060
|
-
|
|
47061
|
-
withdrawAll: isWholePosition(
|
|
47062
|
-
{
|
|
47063
|
-
amount: withdrawOpts.totalPositionAmount,
|
|
47064
|
-
isLending: true
|
|
47065
|
-
},
|
|
47066
|
-
withdrawOpts.withdrawAmount,
|
|
47067
|
-
withdrawOpts.withdrawBank.mintDecimals
|
|
47068
|
-
),
|
|
47308
|
+
group: marginfiAccount.group,
|
|
47069
47309
|
opts: {
|
|
47070
|
-
createAtas: false,
|
|
47071
47310
|
wrapAndUnwrapSol: false,
|
|
47072
47311
|
overrideInferAccounts
|
|
47073
47312
|
}
|
|
@@ -47075,645 +47314,140 @@ async function buildRepayWithCollatFlashloanTx({
|
|
|
47075
47314
|
break;
|
|
47076
47315
|
}
|
|
47077
47316
|
default: {
|
|
47078
|
-
|
|
47079
|
-
program,
|
|
47080
|
-
bank:
|
|
47081
|
-
|
|
47082
|
-
|
|
47083
|
-
|
|
47084
|
-
marginfiAccount,
|
|
47085
|
-
authority: marginfiAccount.authority,
|
|
47086
|
-
withdrawAll: isWholePosition(
|
|
47087
|
-
{
|
|
47088
|
-
amount: withdrawOpts.totalPositionAmount,
|
|
47089
|
-
isLending: true
|
|
47090
|
-
},
|
|
47091
|
-
withdrawOpts.withdrawAmount,
|
|
47092
|
-
withdrawOpts.withdrawBank.mintDecimals
|
|
47093
|
-
),
|
|
47094
|
-
isSync: false,
|
|
47095
|
-
opts: {
|
|
47096
|
-
createAtas: false,
|
|
47097
|
-
wrapAndUnwrapSol: false,
|
|
47098
|
-
overrideInferAccounts
|
|
47099
|
-
}
|
|
47100
|
-
});
|
|
47101
|
-
break;
|
|
47102
|
-
}
|
|
47103
|
-
}
|
|
47104
|
-
const repayIxs = await makeRepayIx3({
|
|
47105
|
-
program,
|
|
47106
|
-
bank: repayOpts.repayBank,
|
|
47107
|
-
tokenProgram: repayOpts.tokenProgram,
|
|
47108
|
-
amount: amountToRepay,
|
|
47109
|
-
accountAddress: marginfiAccount.address,
|
|
47110
|
-
authority: marginfiAccount.authority,
|
|
47111
|
-
repayAll: isWholePosition(
|
|
47112
|
-
{
|
|
47113
|
-
amount: repayOpts.totalPositionAmount,
|
|
47114
|
-
isLending: true
|
|
47115
|
-
},
|
|
47116
|
-
amountToRepay,
|
|
47117
|
-
repayOpts.repayBank.mintDecimals
|
|
47118
|
-
),
|
|
47119
|
-
isSync: false,
|
|
47120
|
-
opts: {
|
|
47121
|
-
wrapAndUnwrapSol: false,
|
|
47122
|
-
overrideInferAccounts
|
|
47123
|
-
}
|
|
47124
|
-
});
|
|
47125
|
-
const luts = [...addressLookupTableAccounts ?? [], ...swapLookupTables];
|
|
47126
|
-
const allNonFlIxs = [
|
|
47127
|
-
...cuRequestIxs,
|
|
47128
|
-
...withdrawIxs.instructions,
|
|
47129
|
-
...swapInstructions,
|
|
47130
|
-
...repayIxs.instructions
|
|
47131
|
-
];
|
|
47132
|
-
if (swapInstructions.length > 0) {
|
|
47133
|
-
compileFlashloanPrecheck({
|
|
47134
|
-
allIxs: allNonFlIxs,
|
|
47135
|
-
payer: marginfiAccount.authority,
|
|
47136
|
-
luts,
|
|
47137
|
-
sizeConstraint: sizeConstraintUsed,
|
|
47138
|
-
swapIxCount: swapInstructions.length,
|
|
47139
|
-
swapLutCount: swapLookupTables.length
|
|
47140
|
-
});
|
|
47141
|
-
}
|
|
47142
|
-
const flashloanTx = await makeFlashLoanTx({
|
|
47143
|
-
program,
|
|
47144
|
-
marginfiAccount,
|
|
47145
|
-
bankMap,
|
|
47146
|
-
addressLookupTableAccounts: luts,
|
|
47147
|
-
blockhash,
|
|
47148
|
-
ixs: allNonFlIxs,
|
|
47149
|
-
isSync: true
|
|
47150
|
-
});
|
|
47151
|
-
const txSize = getTxSize(flashloanTx);
|
|
47152
|
-
const totalKeys = getTotalAccountKeys(flashloanTx);
|
|
47153
|
-
if (txSize > MAX_TX_SIZE || totalKeys > MAX_ACCOUNT_LOCKS) {
|
|
47154
|
-
throw TransactionBuildingError.swapSizeExceededRepay(
|
|
47155
|
-
txSize,
|
|
47156
|
-
totalKeys,
|
|
47157
|
-
swapOpts.swapConfig?.provider
|
|
47158
|
-
);
|
|
47159
|
-
}
|
|
47160
|
-
return {
|
|
47161
|
-
flashloanTx,
|
|
47162
|
-
setupInstructions,
|
|
47163
|
-
swapQuote,
|
|
47164
|
-
withdrawIxs,
|
|
47165
|
-
repayIxs,
|
|
47166
|
-
amountToRepay
|
|
47167
|
-
};
|
|
47168
|
-
}
|
|
47169
|
-
|
|
47170
|
-
// src/services/account/utils/flashloan-size.utils.ts
|
|
47171
|
-
var SWAP_MERGE_OVERHEAD = 150;
|
|
47172
|
-
var FL_IX_OVERHEAD = 52;
|
|
47173
|
-
function compactU16Size(n) {
|
|
47174
|
-
return n < 128 ? 1 : n < 16384 ? 2 : 3;
|
|
47175
|
-
}
|
|
47176
|
-
function computeV0TxSize(ixs, payerKey, luts) {
|
|
47177
|
-
const keyMap = /* @__PURE__ */ new Map();
|
|
47178
|
-
const payerStr = payerKey.toBase58();
|
|
47179
|
-
keyMap.set(payerStr, { isSigner: true, isWritable: true });
|
|
47180
|
-
const programIds = /* @__PURE__ */ new Set();
|
|
47181
|
-
for (const ix of ixs) {
|
|
47182
|
-
const progStr = ix.programId.toBase58();
|
|
47183
|
-
programIds.add(progStr);
|
|
47184
|
-
if (!keyMap.has(progStr)) {
|
|
47185
|
-
keyMap.set(progStr, { isSigner: false, isWritable: false });
|
|
47186
|
-
}
|
|
47187
|
-
for (const meta of ix.keys) {
|
|
47188
|
-
const keyStr = meta.pubkey.toBase58();
|
|
47189
|
-
const existing = keyMap.get(keyStr);
|
|
47190
|
-
if (existing) {
|
|
47191
|
-
existing.isSigner = existing.isSigner || meta.isSigner;
|
|
47192
|
-
existing.isWritable = existing.isWritable || meta.isWritable;
|
|
47193
|
-
} else {
|
|
47194
|
-
keyMap.set(keyStr, { isSigner: meta.isSigner, isWritable: meta.isWritable });
|
|
47195
|
-
}
|
|
47196
|
-
}
|
|
47197
|
-
}
|
|
47198
|
-
const lutLookup = /* @__PURE__ */ new Map();
|
|
47199
|
-
for (let li = 0; li < luts.length; li++) {
|
|
47200
|
-
const addresses = luts[li].state.addresses;
|
|
47201
|
-
for (let ai = 0; ai < addresses.length; ai++) {
|
|
47202
|
-
const addrStr = addresses[ai].toBase58();
|
|
47203
|
-
if (!lutLookup.has(addrStr)) {
|
|
47204
|
-
lutLookup.set(addrStr, { lutIdx: li, addrIdx: ai });
|
|
47205
|
-
}
|
|
47206
|
-
}
|
|
47207
|
-
}
|
|
47208
|
-
let numStaticKeys = 0;
|
|
47209
|
-
let numWritableStaticKeys = 0;
|
|
47210
|
-
const lutWritableIdxs = luts.map(() => /* @__PURE__ */ new Set());
|
|
47211
|
-
const lutReadonlyIdxs = luts.map(() => /* @__PURE__ */ new Set());
|
|
47212
|
-
for (const [keyStr, props] of keyMap) {
|
|
47213
|
-
if (props.isSigner || programIds.has(keyStr)) {
|
|
47214
|
-
numStaticKeys++;
|
|
47215
|
-
if (props.isWritable) numWritableStaticKeys++;
|
|
47216
|
-
continue;
|
|
47217
|
-
}
|
|
47218
|
-
const lutEntry = lutLookup.get(keyStr);
|
|
47219
|
-
if (lutEntry) {
|
|
47220
|
-
if (props.isWritable) {
|
|
47221
|
-
lutWritableIdxs[lutEntry.lutIdx].add(lutEntry.addrIdx);
|
|
47222
|
-
} else {
|
|
47223
|
-
lutReadonlyIdxs[lutEntry.lutIdx].add(lutEntry.addrIdx);
|
|
47224
|
-
}
|
|
47225
|
-
} else {
|
|
47226
|
-
numStaticKeys++;
|
|
47227
|
-
if (props.isWritable) numWritableStaticKeys++;
|
|
47228
|
-
}
|
|
47229
|
-
}
|
|
47230
|
-
const fixedOverhead = 101;
|
|
47231
|
-
const staticKeysSection = compactU16Size(numStaticKeys) + numStaticKeys * 32;
|
|
47232
|
-
let ixSection = compactU16Size(ixs.length);
|
|
47233
|
-
for (const ix of ixs) {
|
|
47234
|
-
const numAccounts = ix.keys.length;
|
|
47235
|
-
ixSection += 1 + // programId index
|
|
47236
|
-
compactU16Size(numAccounts) + numAccounts + // account key indexes
|
|
47237
|
-
compactU16Size(ix.data.length) + ix.data.length;
|
|
47238
|
-
}
|
|
47239
|
-
let numUsedLuts = 0;
|
|
47240
|
-
let lutSection = 0;
|
|
47241
|
-
for (let li = 0; li < luts.length; li++) {
|
|
47242
|
-
const wCount = lutWritableIdxs[li].size;
|
|
47243
|
-
const rCount = lutReadonlyIdxs[li].size;
|
|
47244
|
-
if (wCount === 0 && rCount === 0) continue;
|
|
47245
|
-
numUsedLuts++;
|
|
47246
|
-
lutSection += 32 + // LUT address
|
|
47247
|
-
compactU16Size(wCount) + wCount + // writable indexes
|
|
47248
|
-
compactU16Size(rCount) + rCount;
|
|
47249
|
-
}
|
|
47250
|
-
lutSection += compactU16Size(numUsedLuts);
|
|
47251
|
-
let totalLutKeys = 0;
|
|
47252
|
-
for (let li = 0; li < luts.length; li++) {
|
|
47253
|
-
totalLutKeys += lutWritableIdxs[li].size + lutReadonlyIdxs[li].size;
|
|
47254
|
-
}
|
|
47255
|
-
const accountCount = numStaticKeys + totalLutKeys;
|
|
47256
|
-
let totalLutWritableKeys = 0;
|
|
47257
|
-
for (let li = 0; li < luts.length; li++) {
|
|
47258
|
-
totalLutWritableKeys += lutWritableIdxs[li].size;
|
|
47259
|
-
}
|
|
47260
|
-
const writableAccountCount = numWritableStaticKeys + totalLutWritableKeys;
|
|
47261
|
-
const size = fixedOverhead + staticKeysSection + ixSection + lutSection + 1;
|
|
47262
|
-
return { size, accountCount, writableAccountCount };
|
|
47263
|
-
}
|
|
47264
|
-
function computeFlashLoanNonSwapBudget({
|
|
47265
|
-
program,
|
|
47266
|
-
marginfiAccount,
|
|
47267
|
-
ixs,
|
|
47268
|
-
bankMap,
|
|
47269
|
-
addressLookupTableAccounts
|
|
47270
|
-
}) {
|
|
47271
|
-
const projectedActiveBanksKeys = computeProjectedActiveBanksNoCpi(
|
|
47272
|
-
marginfiAccount.balances,
|
|
47273
|
-
ixs,
|
|
47274
|
-
program
|
|
47275
|
-
);
|
|
47276
|
-
const projectedActiveBanks = projectedActiveBanksKeys.map((key) => {
|
|
47277
|
-
const b = bankMap.get(key.toBase58());
|
|
47278
|
-
if (!b) throw new Error(`Bank ${key.toBase58()} not found in computeFlashLoanNonSwapBudget`);
|
|
47279
|
-
return b;
|
|
47280
|
-
});
|
|
47281
|
-
const endIndex = ixs.length + 1;
|
|
47282
|
-
const beginFlIx = sync_instructions_default.makeBeginFlashLoanIx(
|
|
47283
|
-
program.programId,
|
|
47284
|
-
{ marginfiAccount: marginfiAccount.address, authority: marginfiAccount.authority },
|
|
47285
|
-
{ endIndex: new BN11__default.default(endIndex) }
|
|
47286
|
-
);
|
|
47287
|
-
const endFlRemainingAccounts = computeHealthAccountMetas(projectedActiveBanks);
|
|
47288
|
-
const endFlIx = sync_instructions_default.makeEndFlashLoanIx(
|
|
47289
|
-
program.programId,
|
|
47290
|
-
{ marginfiAccount: marginfiAccount.address, authority: marginfiAccount.authority },
|
|
47291
|
-
endFlRemainingAccounts.map((pubkey) => ({ pubkey, isSigner: false, isWritable: false }))
|
|
47292
|
-
);
|
|
47293
|
-
const allNonSwapIxs = [beginFlIx, ...ixs, endFlIx];
|
|
47294
|
-
const nonSwapMsg = new web3_js.TransactionMessage({
|
|
47295
|
-
payerKey: marginfiAccount.authority,
|
|
47296
|
-
recentBlockhash: web3_js.PublicKey.default.toBase58(),
|
|
47297
|
-
instructions: allNonSwapIxs
|
|
47298
|
-
}).compileToV0Message(addressLookupTableAccounts);
|
|
47299
|
-
const nonSwapSize = new web3_js.VersionedTransaction(nonSwapMsg).serialize().length;
|
|
47300
|
-
const { header, staticAccountKeys, addressTableLookups } = nonSwapMsg;
|
|
47301
|
-
const nonSwapTotal = staticAccountKeys.length + addressTableLookups.reduce(
|
|
47302
|
-
(s, l) => s + l.writableIndexes.length + l.readonlyIndexes.length,
|
|
47303
|
-
0
|
|
47304
|
-
);
|
|
47305
|
-
const sizeConstraint = MAX_TX_SIZE - nonSwapSize - SWAP_MERGE_OVERHEAD;
|
|
47306
|
-
const maxSwapTotalAccounts = MAX_ACCOUNT_LOCKS - nonSwapTotal;
|
|
47307
|
-
console.log("[flashloan-budget]", {
|
|
47308
|
-
method: "compiled",
|
|
47309
|
-
nonSwapSize,
|
|
47310
|
-
nonSwapTotal,
|
|
47311
|
-
sizeConstraint,
|
|
47312
|
-
maxSwapTotalAccounts
|
|
47313
|
-
});
|
|
47314
|
-
return { sizeConstraint, maxSwapTotalAccounts };
|
|
47315
|
-
}
|
|
47316
|
-
function compileFlashloanPrecheck({
|
|
47317
|
-
allIxs,
|
|
47318
|
-
payer,
|
|
47319
|
-
luts,
|
|
47320
|
-
sizeConstraint,
|
|
47321
|
-
swapIxCount,
|
|
47322
|
-
swapLutCount
|
|
47323
|
-
}) {
|
|
47324
|
-
const msg = new web3_js.TransactionMessage({
|
|
47325
|
-
payerKey: payer,
|
|
47326
|
-
recentBlockhash: web3_js.PublicKey.default.toBase58(),
|
|
47327
|
-
instructions: allIxs
|
|
47328
|
-
}).compileToV0Message(luts);
|
|
47329
|
-
const rawSize = new web3_js.VersionedTransaction(msg).serialize().length;
|
|
47330
|
-
const fullTxSize = rawSize + FL_IX_OVERHEAD;
|
|
47331
|
-
const overshoot = fullTxSize - MAX_TX_SIZE;
|
|
47332
|
-
const { header, staticAccountKeys, addressTableLookups } = msg;
|
|
47333
|
-
const writableStatic = staticAccountKeys.length - header.numReadonlySignedAccounts - header.numReadonlyUnsignedAccounts;
|
|
47334
|
-
const writableLut = addressTableLookups.reduce((s, l) => s + l.writableIndexes.length, 0);
|
|
47335
|
-
const writableAccounts = writableStatic + writableLut;
|
|
47336
|
-
const totalAccounts = staticAccountKeys.length + addressTableLookups.reduce(
|
|
47337
|
-
(s, l) => s + l.writableIndexes.length + l.readonlyIndexes.length,
|
|
47338
|
-
0
|
|
47339
|
-
);
|
|
47340
|
-
console.log("[flashloan-precheck]", {
|
|
47341
|
-
fullTxSize,
|
|
47342
|
-
overshoot,
|
|
47343
|
-
sizeConstraint,
|
|
47344
|
-
writableAccounts,
|
|
47345
|
-
totalAccounts,
|
|
47346
|
-
staticKeys: staticAccountKeys.length,
|
|
47347
|
-
numLuts: addressTableLookups.length,
|
|
47348
|
-
swapIxCount,
|
|
47349
|
-
swapLutCount
|
|
47350
|
-
});
|
|
47351
|
-
return { fullTxSize, overshoot, writableAccounts, totalAccounts };
|
|
47352
|
-
}
|
|
47353
|
-
async function buildBudgetIx(config, program, marginfiAccount, bankMap, bankMetadataMap, overrideInferAccounts) {
|
|
47354
|
-
const { bank, tokenProgram } = config;
|
|
47355
|
-
switch (config.type) {
|
|
47356
|
-
case "borrow":
|
|
47357
|
-
return makeBorrowIx3({
|
|
47358
|
-
program,
|
|
47359
|
-
bank,
|
|
47360
|
-
bankMap,
|
|
47361
|
-
tokenProgram,
|
|
47362
|
-
amount: 1,
|
|
47363
|
-
marginfiAccount,
|
|
47364
|
-
authority: marginfiAccount.authority,
|
|
47365
|
-
isSync: true,
|
|
47366
|
-
opts: { createAtas: false, wrapAndUnwrapSol: false, overrideInferAccounts }
|
|
47367
|
-
});
|
|
47368
|
-
case "repay":
|
|
47369
|
-
return makeRepayIx3({
|
|
47370
|
-
program,
|
|
47371
|
-
bank,
|
|
47372
|
-
tokenProgram,
|
|
47373
|
-
amount: 1,
|
|
47374
|
-
accountAddress: marginfiAccount.address,
|
|
47375
|
-
authority: marginfiAccount.authority,
|
|
47376
|
-
repayAll: false,
|
|
47377
|
-
isSync: true,
|
|
47378
|
-
opts: { wrapAndUnwrapSol: false, overrideInferAccounts }
|
|
47379
|
-
});
|
|
47380
|
-
case "deposit":
|
|
47381
|
-
return buildDepositBudgetIx(
|
|
47382
|
-
config,
|
|
47383
|
-
program,
|
|
47384
|
-
marginfiAccount,
|
|
47385
|
-
bankMetadataMap,
|
|
47386
|
-
overrideInferAccounts
|
|
47387
|
-
);
|
|
47388
|
-
case "withdraw":
|
|
47389
|
-
return buildWithdrawBudgetIx(
|
|
47390
|
-
config,
|
|
47391
|
-
program,
|
|
47392
|
-
marginfiAccount,
|
|
47393
|
-
bankMap,
|
|
47394
|
-
bankMetadataMap,
|
|
47395
|
-
overrideInferAccounts
|
|
47396
|
-
);
|
|
47397
|
-
}
|
|
47398
|
-
}
|
|
47399
|
-
async function buildDepositBudgetIx(config, program, marginfiAccount, bankMetadataMap, overrideInferAccounts) {
|
|
47400
|
-
const { bank, tokenProgram } = config;
|
|
47401
|
-
const opts = { wrapAndUnwrapSol: false, overrideInferAccounts };
|
|
47402
|
-
switch (bank.config.assetTag) {
|
|
47403
|
-
case 3 /* KAMINO */: {
|
|
47404
|
-
const reserve = bankMetadataMap[bank.address.toBase58()]?.kaminoStates?.reserveState;
|
|
47405
|
-
if (!reserve) {
|
|
47406
|
-
throw TransactionBuildingError.kaminoReserveNotFound(
|
|
47407
|
-
bank.address.toBase58(),
|
|
47408
|
-
bank.mint.toBase58(),
|
|
47409
|
-
bank.tokenSymbol
|
|
47410
|
-
);
|
|
47411
|
-
}
|
|
47412
|
-
return makeKaminoDepositIx3({
|
|
47413
|
-
program,
|
|
47414
|
-
bank,
|
|
47415
|
-
tokenProgram,
|
|
47416
|
-
amount: 1,
|
|
47417
|
-
accountAddress: marginfiAccount.address,
|
|
47418
|
-
authority: marginfiAccount.authority,
|
|
47419
|
-
group: marginfiAccount.group,
|
|
47420
|
-
reserve,
|
|
47421
|
-
isSync: true,
|
|
47422
|
-
opts
|
|
47423
|
-
});
|
|
47424
|
-
}
|
|
47425
|
-
case 4 /* DRIFT */: {
|
|
47426
|
-
const driftState = bankMetadataMap[bank.address.toBase58()]?.driftStates;
|
|
47427
|
-
if (!driftState) {
|
|
47428
|
-
throw TransactionBuildingError.driftStateNotFound(
|
|
47429
|
-
bank.address.toBase58(),
|
|
47430
|
-
bank.mint.toBase58(),
|
|
47431
|
-
bank.tokenSymbol
|
|
47432
|
-
);
|
|
47433
|
-
}
|
|
47434
|
-
return makeDriftDepositIx3({
|
|
47435
|
-
program,
|
|
47436
|
-
bank,
|
|
47437
|
-
tokenProgram,
|
|
47438
|
-
amount: 1,
|
|
47439
|
-
accountAddress: marginfiAccount.address,
|
|
47440
|
-
authority: marginfiAccount.authority,
|
|
47441
|
-
group: marginfiAccount.group,
|
|
47442
|
-
driftMarketIndex: driftState.spotMarketState.marketIndex,
|
|
47443
|
-
driftOracle: driftState.spotMarketState.oracle,
|
|
47444
|
-
isSync: true,
|
|
47445
|
-
opts
|
|
47446
|
-
});
|
|
47447
|
-
}
|
|
47448
|
-
case 6 /* JUPLEND */: {
|
|
47449
|
-
return makeJuplendDepositIx2({
|
|
47450
|
-
program,
|
|
47451
|
-
bank,
|
|
47452
|
-
tokenProgram,
|
|
47453
|
-
amount: 1,
|
|
47454
|
-
accountAddress: marginfiAccount.address,
|
|
47455
|
-
authority: marginfiAccount.authority,
|
|
47456
|
-
group: marginfiAccount.group,
|
|
47457
|
-
isSync: true,
|
|
47458
|
-
opts
|
|
47459
|
-
});
|
|
47460
|
-
}
|
|
47461
|
-
default: {
|
|
47462
|
-
return makeDepositIx3({
|
|
47463
|
-
program,
|
|
47464
|
-
bank,
|
|
47465
|
-
tokenProgram,
|
|
47466
|
-
amount: 1,
|
|
47467
|
-
accountAddress: marginfiAccount.address,
|
|
47468
|
-
authority: marginfiAccount.authority,
|
|
47469
|
-
group: marginfiAccount.group,
|
|
47470
|
-
isSync: true,
|
|
47471
|
-
opts
|
|
47472
|
-
});
|
|
47473
|
-
}
|
|
47474
|
-
}
|
|
47475
|
-
}
|
|
47476
|
-
async function buildWithdrawBudgetIx(config, program, marginfiAccount, bankMap, bankMetadataMap, overrideInferAccounts) {
|
|
47477
|
-
const { bank, tokenProgram } = config;
|
|
47478
|
-
const opts = { createAtas: false, wrapAndUnwrapSol: false, overrideInferAccounts };
|
|
47479
|
-
switch (bank.config.assetTag) {
|
|
47480
|
-
case 3 /* KAMINO */: {
|
|
47481
|
-
const reserve = bankMetadataMap[bank.address.toBase58()]?.kaminoStates?.reserveState;
|
|
47482
|
-
if (!reserve) {
|
|
47483
|
-
throw TransactionBuildingError.kaminoReserveNotFound(
|
|
47484
|
-
bank.address.toBase58(),
|
|
47485
|
-
bank.mint.toBase58(),
|
|
47486
|
-
bank.tokenSymbol
|
|
47487
|
-
);
|
|
47488
|
-
}
|
|
47489
|
-
return makeKaminoWithdrawIx3({
|
|
47490
|
-
program,
|
|
47491
|
-
bank,
|
|
47492
|
-
bankMap,
|
|
47493
|
-
tokenProgram,
|
|
47494
|
-
cTokenAmount: 1,
|
|
47495
|
-
marginfiAccount,
|
|
47496
|
-
authority: marginfiAccount.authority,
|
|
47497
|
-
reserve,
|
|
47498
|
-
withdrawAll: false,
|
|
47499
|
-
isSync: true,
|
|
47500
|
-
opts
|
|
47501
|
-
});
|
|
47502
|
-
}
|
|
47503
|
-
case 4 /* DRIFT */: {
|
|
47504
|
-
const driftState = bankMetadataMap[bank.address.toBase58()]?.driftStates;
|
|
47505
|
-
if (!driftState) {
|
|
47506
|
-
throw TransactionBuildingError.driftStateNotFound(
|
|
47507
|
-
bank.address.toBase58(),
|
|
47508
|
-
bank.mint.toBase58(),
|
|
47509
|
-
bank.tokenSymbol
|
|
47510
|
-
);
|
|
47511
|
-
}
|
|
47512
|
-
return makeDriftWithdrawIx3({
|
|
47513
|
-
program,
|
|
47514
|
-
bank,
|
|
47515
|
-
bankMap,
|
|
47516
|
-
tokenProgram,
|
|
47517
|
-
amount: 1,
|
|
47518
|
-
marginfiAccount,
|
|
47519
|
-
authority: marginfiAccount.authority,
|
|
47520
|
-
driftSpotMarket: driftState.spotMarketState,
|
|
47521
|
-
userRewards: driftState.userRewards,
|
|
47522
|
-
withdrawAll: false,
|
|
47523
|
-
isSync: true,
|
|
47524
|
-
opts
|
|
47525
|
-
});
|
|
47526
|
-
}
|
|
47527
|
-
case 6 /* JUPLEND */: {
|
|
47528
|
-
const jupLendState = bankMetadataMap[bank.address.toBase58()]?.jupLendStates;
|
|
47529
|
-
if (!jupLendState) {
|
|
47530
|
-
throw TransactionBuildingError.jupLendStateNotFound(
|
|
47531
|
-
bank.address.toBase58(),
|
|
47532
|
-
bank.mint.toBase58(),
|
|
47533
|
-
bank.tokenSymbol
|
|
47534
|
-
);
|
|
47535
|
-
}
|
|
47536
|
-
return makeJuplendWithdrawIx2({
|
|
47537
|
-
program,
|
|
47538
|
-
bank,
|
|
47539
|
-
bankMap,
|
|
47540
|
-
tokenProgram,
|
|
47541
|
-
amount: 1,
|
|
47542
|
-
marginfiAccount,
|
|
47543
|
-
authority: marginfiAccount.authority,
|
|
47544
|
-
jupLendingState: jupLendState.jupLendingState,
|
|
47545
|
-
withdrawAll: false,
|
|
47546
|
-
opts
|
|
47547
|
-
});
|
|
47548
|
-
}
|
|
47549
|
-
default: {
|
|
47550
|
-
return makeWithdrawIx3({
|
|
47551
|
-
program,
|
|
47552
|
-
bank,
|
|
47553
|
-
bankMap,
|
|
47554
|
-
tokenProgram,
|
|
47555
|
-
amount: 1,
|
|
47556
|
-
marginfiAccount,
|
|
47317
|
+
depositIxs = await makeDepositIx3({
|
|
47318
|
+
program,
|
|
47319
|
+
bank: depositOpts.depositBank,
|
|
47320
|
+
tokenProgram: depositOpts.tokenProgram,
|
|
47321
|
+
amount: amountToDeposit,
|
|
47322
|
+
accountAddress: marginfiAccount.address,
|
|
47557
47323
|
authority: marginfiAccount.authority,
|
|
47558
|
-
|
|
47559
|
-
|
|
47560
|
-
|
|
47324
|
+
group: marginfiAccount.group,
|
|
47325
|
+
opts: {
|
|
47326
|
+
wrapAndUnwrapSol: false,
|
|
47327
|
+
overrideInferAccounts
|
|
47328
|
+
}
|
|
47561
47329
|
});
|
|
47330
|
+
break;
|
|
47562
47331
|
}
|
|
47563
47332
|
}
|
|
47564
|
-
|
|
47565
|
-
|
|
47566
|
-
|
|
47567
|
-
|
|
47568
|
-
|
|
47569
|
-
|
|
47570
|
-
bankMetadataMap,
|
|
47571
|
-
primaryIx,
|
|
47572
|
-
secondaryIx,
|
|
47573
|
-
overrideInferAccounts
|
|
47574
|
-
}) {
|
|
47575
|
-
const cuRequestIxs = [
|
|
47576
|
-
web3_js.ComputeBudgetProgram.setComputeUnitLimit({ units: 12e5 }),
|
|
47577
|
-
web3_js.ComputeBudgetProgram.setComputeUnitPrice({ microLamports: 1 })
|
|
47333
|
+
const luts = [...addressLookupTableAccounts ?? [], ...swapLookupTables];
|
|
47334
|
+
const allNonFlIxs = [
|
|
47335
|
+
...cuRequestIxs,
|
|
47336
|
+
...borrowIxs.instructions,
|
|
47337
|
+
...swapInstructions,
|
|
47338
|
+
...depositIxs.instructions
|
|
47578
47339
|
];
|
|
47579
|
-
|
|
47580
|
-
|
|
47581
|
-
|
|
47582
|
-
|
|
47583
|
-
|
|
47584
|
-
|
|
47585
|
-
|
|
47586
|
-
|
|
47587
|
-
)
|
|
47588
|
-
|
|
47589
|
-
|
|
47590
|
-
program,
|
|
47591
|
-
marginfiAccount,
|
|
47592
|
-
bankMap,
|
|
47593
|
-
bankMetadataMap,
|
|
47594
|
-
overrideInferAccounts
|
|
47595
|
-
)
|
|
47596
|
-
]);
|
|
47597
|
-
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({
|
|
47598
47351
|
program,
|
|
47599
47352
|
marginfiAccount,
|
|
47600
47353
|
bankMap,
|
|
47601
|
-
addressLookupTableAccounts,
|
|
47602
|
-
|
|
47354
|
+
addressLookupTableAccounts: luts,
|
|
47355
|
+
blockhash,
|
|
47356
|
+
ixs: allNonFlIxs
|
|
47603
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
|
+
};
|
|
47604
47375
|
}
|
|
47605
|
-
|
|
47606
|
-
|
|
47607
|
-
|
|
47608
|
-
|
|
47609
|
-
|
|
47610
|
-
|
|
47611
|
-
|
|
47612
|
-
|
|
47613
|
-
|
|
47614
|
-
|
|
47615
|
-
|
|
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(
|
|
47616
47396
|
program,
|
|
47617
47397
|
{
|
|
47618
|
-
marginfiAccount:
|
|
47619
|
-
|
|
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
|
|
47620
47405
|
},
|
|
47621
|
-
{
|
|
47622
|
-
|
|
47623
|
-
|
|
47624
|
-
}
|
|
47625
|
-
async function makeEndFlashLoanIx3(program, marginfiAccountPk, projectedActiveBanks, authority, isSync) {
|
|
47626
|
-
const remainingAccounts = computeHealthAccountMetas(projectedActiveBanks);
|
|
47627
|
-
const ix = isSync && authority ? sync_instructions_default.makeEndFlashLoanIx(
|
|
47406
|
+
{ amount: uiToNative(amount, bank.mintDecimals), repayAll },
|
|
47407
|
+
remainingAccounts
|
|
47408
|
+
) : sync_instructions_default.makeRepayIx(
|
|
47628
47409
|
program.programId,
|
|
47629
47410
|
{
|
|
47630
|
-
marginfiAccount:
|
|
47631
|
-
|
|
47632
|
-
|
|
47633
|
-
|
|
47634
|
-
|
|
47635
|
-
|
|
47636
|
-
isWritable: false
|
|
47637
|
-
}))
|
|
47638
|
-
) : await instructions_default.makeEndFlashLoanIx(
|
|
47639
|
-
program,
|
|
47640
|
-
{
|
|
47641
|
-
marginfiAccount: marginfiAccountPk,
|
|
47642
|
-
authority
|
|
47411
|
+
marginfiAccount: accountAddress,
|
|
47412
|
+
signerTokenAccount: userAta,
|
|
47413
|
+
bank: bank.address,
|
|
47414
|
+
tokenProgram,
|
|
47415
|
+
authority: opts.overrideInferAccounts?.authority ?? authority,
|
|
47416
|
+
group: opts.overrideInferAccounts?.group
|
|
47643
47417
|
},
|
|
47644
|
-
|
|
47645
|
-
|
|
47646
|
-
isSigner: false,
|
|
47647
|
-
isWritable: false
|
|
47648
|
-
}))
|
|
47418
|
+
{ amount: uiToNative(amount, bank.mintDecimals), repayAll },
|
|
47419
|
+
remainingAccounts
|
|
47649
47420
|
);
|
|
47650
|
-
|
|
47421
|
+
repayIxs.push(repayIx);
|
|
47422
|
+
return {
|
|
47423
|
+
instructions: repayIxs,
|
|
47424
|
+
keys: []
|
|
47425
|
+
};
|
|
47651
47426
|
}
|
|
47652
|
-
async function
|
|
47653
|
-
|
|
47654
|
-
|
|
47655
|
-
ixs
|
|
47656
|
-
|
|
47657
|
-
|
|
47658
|
-
|
|
47659
|
-
|
|
47660
|
-
|
|
47661
|
-
}) {
|
|
47662
|
-
const endIndex = ixs.length + 1;
|
|
47663
|
-
const projectedActiveBanksKeys = computeProjectedActiveBanksNoCpi(
|
|
47664
|
-
marginfiAccount.balances,
|
|
47665
|
-
ixs,
|
|
47666
|
-
program
|
|
47667
|
-
);
|
|
47668
|
-
const projectedActiveBanks = projectedActiveBanksKeys.map((account) => {
|
|
47669
|
-
const b = bankMap.get(account.toBase58());
|
|
47670
|
-
if (!b) throw Error(`Bank ${account.toBase58()} not found, in makeFlashLoanTx function`);
|
|
47671
|
-
return b;
|
|
47672
|
-
});
|
|
47673
|
-
const beginFlashLoanIx = await makeBeginFlashLoanIx3(
|
|
47674
|
-
program,
|
|
47675
|
-
marginfiAccount.address,
|
|
47676
|
-
endIndex,
|
|
47677
|
-
marginfiAccount.authority,
|
|
47678
|
-
isSync
|
|
47679
|
-
);
|
|
47680
|
-
const endFlashLoanIx = await makeEndFlashLoanIx3(
|
|
47681
|
-
program,
|
|
47682
|
-
marginfiAccount.address,
|
|
47683
|
-
projectedActiveBanks,
|
|
47684
|
-
marginfiAccount.authority,
|
|
47685
|
-
isSync
|
|
47686
|
-
);
|
|
47687
|
-
const message = new web3_js.TransactionMessage({
|
|
47688
|
-
payerKey: marginfiAccount.authority,
|
|
47689
|
-
recentBlockhash: blockhash,
|
|
47690
|
-
instructions: [...beginFlashLoanIx.instructions, ...ixs, ...endFlashLoanIx.instructions]
|
|
47691
|
-
}).compileToV0Message(addressLookupTableAccounts);
|
|
47692
|
-
const tx = addTransactionMetadata(new web3_js.VersionedTransaction(message), {
|
|
47693
|
-
addressLookupTables: addressLookupTableAccounts,
|
|
47694
|
-
type: "FLASHLOAN" /* FLASHLOAN */,
|
|
47695
|
-
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
|
|
47696
47436
|
});
|
|
47697
|
-
|
|
47698
|
-
tx.sign(signers);
|
|
47699
|
-
}
|
|
47700
|
-
return tx;
|
|
47437
|
+
return solanaTx;
|
|
47701
47438
|
}
|
|
47702
|
-
|
|
47703
|
-
// src/services/account/actions/loop.ts
|
|
47704
|
-
async function makeLoopTx(params) {
|
|
47439
|
+
async function makeRepayWithCollatTx(params) {
|
|
47705
47440
|
const {
|
|
47706
47441
|
program,
|
|
47707
47442
|
marginfiAccount,
|
|
47708
47443
|
bankMap,
|
|
47709
|
-
|
|
47710
|
-
|
|
47444
|
+
withdrawOpts,
|
|
47445
|
+
repayOpts,
|
|
47711
47446
|
bankMetadataMap,
|
|
47712
47447
|
addressLookupTableAccounts,
|
|
47713
47448
|
connection,
|
|
47714
47449
|
oraclePrices,
|
|
47715
|
-
crossbarUrl
|
|
47716
|
-
additionalIxs = []
|
|
47450
|
+
crossbarUrl
|
|
47717
47451
|
} = params;
|
|
47718
47452
|
const blockhash = (await connection.getLatestBlockhash("confirmed")).blockhash;
|
|
47719
47453
|
const setupIxs = await makeSetupIx({
|
|
@@ -47721,34 +47455,34 @@ async function makeLoopTx(params) {
|
|
|
47721
47455
|
authority: marginfiAccount.authority,
|
|
47722
47456
|
tokens: [
|
|
47723
47457
|
{
|
|
47724
|
-
mint:
|
|
47725
|
-
tokenProgram:
|
|
47458
|
+
mint: repayOpts.repayBank.mint,
|
|
47459
|
+
tokenProgram: repayOpts.tokenProgram
|
|
47726
47460
|
},
|
|
47727
47461
|
{
|
|
47728
|
-
mint:
|
|
47729
|
-
tokenProgram:
|
|
47462
|
+
mint: withdrawOpts.withdrawBank.mint,
|
|
47463
|
+
tokenProgram: withdrawOpts.tokenProgram
|
|
47730
47464
|
}
|
|
47731
47465
|
]
|
|
47732
47466
|
});
|
|
47733
|
-
const
|
|
47734
|
-
|
|
47735
|
-
|
|
47736
|
-
[
|
|
47737
|
-
|
|
47467
|
+
const updateJuplendMarketIxs = makeUpdateJupLendRateIxs(
|
|
47468
|
+
marginfiAccount,
|
|
47469
|
+
bankMap,
|
|
47470
|
+
[withdrawOpts.withdrawBank.address],
|
|
47471
|
+
bankMetadataMap
|
|
47738
47472
|
);
|
|
47739
47473
|
const updateDriftMarketIxs = makeUpdateDriftMarketIxs(
|
|
47740
|
-
|
|
47741
|
-
|
|
47742
|
-
[
|
|
47743
|
-
|
|
47474
|
+
marginfiAccount,
|
|
47475
|
+
bankMap,
|
|
47476
|
+
[withdrawOpts.withdrawBank.address],
|
|
47477
|
+
bankMetadataMap
|
|
47744
47478
|
);
|
|
47745
47479
|
const kaminoRefreshIxs = makeRefreshKaminoBanksIxs(
|
|
47746
47480
|
marginfiAccount,
|
|
47747
47481
|
bankMap,
|
|
47748
|
-
[
|
|
47482
|
+
[withdrawOpts.withdrawBank.address, repayOpts.repayBank.address],
|
|
47749
47483
|
bankMetadataMap
|
|
47750
47484
|
);
|
|
47751
|
-
const { flashloanTx, setupInstructions, swapQuote,
|
|
47485
|
+
const { flashloanTx, setupInstructions, swapQuote, amountToRepay, withdrawIxs, repayIxs } = await buildRepayWithCollatFlashloanTx({
|
|
47752
47486
|
...params,
|
|
47753
47487
|
blockhash
|
|
47754
47488
|
});
|
|
@@ -47758,7 +47492,7 @@ async function makeLoopTx(params) {
|
|
|
47758
47492
|
}
|
|
47759
47493
|
if (ix.programId.equals(ASSOCIATED_TOKEN_PROGRAM_ID)) {
|
|
47760
47494
|
const mintKey = ix.keys[3]?.pubkey;
|
|
47761
|
-
if (mintKey?.equals(
|
|
47495
|
+
if (mintKey?.equals(withdrawOpts.withdrawBank.mint) || mintKey?.equals(repayOpts.repayBank.mint)) {
|
|
47762
47496
|
return false;
|
|
47763
47497
|
}
|
|
47764
47498
|
}
|
|
@@ -47770,24 +47504,18 @@ async function makeLoopTx(params) {
|
|
|
47770
47504
|
bankMap,
|
|
47771
47505
|
oraclePrices,
|
|
47772
47506
|
assetShareValueMultiplierByBank: params.assetShareValueMultiplierByBank,
|
|
47773
|
-
instructions: [...
|
|
47507
|
+
instructions: [...withdrawIxs.instructions, ...repayIxs.instructions],
|
|
47774
47508
|
program,
|
|
47775
47509
|
connection,
|
|
47776
47510
|
crossbarUrl
|
|
47777
47511
|
});
|
|
47778
47512
|
let additionalTxs = [];
|
|
47779
|
-
if (
|
|
47780
|
-
setupIxs.push(
|
|
47781
|
-
...makeWrapSolIxs(marginfiAccount.authority, new BigNumber3.BigNumber(depositOpts.inputDepositAmount))
|
|
47782
|
-
);
|
|
47783
|
-
}
|
|
47784
|
-
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) {
|
|
47785
47514
|
const ixs = [
|
|
47786
|
-
...additionalIxs,
|
|
47787
47515
|
...setupIxs,
|
|
47788
47516
|
...kaminoRefreshIxs.instructions,
|
|
47789
47517
|
...updateDriftMarketIxs.instructions,
|
|
47790
|
-
...
|
|
47518
|
+
...updateJuplendMarketIxs.instructions
|
|
47791
47519
|
];
|
|
47792
47520
|
const txs = splitInstructionsToFitTransactions([], ixs, {
|
|
47793
47521
|
blockhash,
|
|
@@ -47817,19 +47545,16 @@ async function makeLoopTx(params) {
|
|
|
47817
47545
|
);
|
|
47818
47546
|
}
|
|
47819
47547
|
const transactions = [...additionalTxs, flashloanTx];
|
|
47820
|
-
return {
|
|
47821
|
-
transactions,
|
|
47822
|
-
actionTxIndex: transactions.length - 1,
|
|
47823
|
-
quoteResponse: swapQuote
|
|
47824
|
-
};
|
|
47548
|
+
return { transactions, swapQuote, amountToRepay };
|
|
47825
47549
|
}
|
|
47826
|
-
async function
|
|
47550
|
+
async function buildRepayWithCollatFlashloanTx({
|
|
47827
47551
|
program,
|
|
47828
47552
|
marginfiAccount,
|
|
47829
47553
|
bankMap,
|
|
47830
|
-
|
|
47831
|
-
|
|
47554
|
+
withdrawOpts,
|
|
47555
|
+
repayOpts,
|
|
47832
47556
|
bankMetadataMap,
|
|
47557
|
+
assetShareValueMultiplierByBank,
|
|
47833
47558
|
addressLookupTableAccounts,
|
|
47834
47559
|
connection,
|
|
47835
47560
|
swapOpts,
|
|
@@ -47840,20 +47565,20 @@ async function buildLoopFlashloanTx({
|
|
|
47840
47565
|
web3_js.ComputeBudgetProgram.setComputeUnitLimit({ units: 12e5 }),
|
|
47841
47566
|
web3_js.ComputeBudgetProgram.setComputeUnitPrice({ microLamports: 1 })
|
|
47842
47567
|
];
|
|
47843
|
-
let
|
|
47568
|
+
let amountToRepay;
|
|
47844
47569
|
let swapInstructions = [];
|
|
47845
47570
|
let setupInstructions = [];
|
|
47846
47571
|
let swapLookupTables = [];
|
|
47847
47572
|
let swapQuote;
|
|
47848
47573
|
let sizeConstraintUsed = 0;
|
|
47849
|
-
if (
|
|
47850
|
-
|
|
47574
|
+
if (repayOpts.repayBank.mint.equals(withdrawOpts.withdrawBank.mint)) {
|
|
47575
|
+
amountToRepay = withdrawOpts.withdrawAmount;
|
|
47851
47576
|
} else {
|
|
47852
47577
|
const destinationTokenAccount = getAssociatedTokenAddressSync(
|
|
47853
|
-
new web3_js.PublicKey(
|
|
47578
|
+
new web3_js.PublicKey(repayOpts.repayBank.mint),
|
|
47854
47579
|
marginfiAccount.authority,
|
|
47855
47580
|
true,
|
|
47856
|
-
|
|
47581
|
+
repayOpts.tokenProgram.equals(TOKEN_2022_PROGRAM_ID) ? TOKEN_2022_PROGRAM_ID : void 0
|
|
47857
47582
|
);
|
|
47858
47583
|
const swapConstraints = await computeFlashloanSwapConstraints({
|
|
47859
47584
|
program,
|
|
@@ -47862,21 +47587,24 @@ async function buildLoopFlashloanTx({
|
|
|
47862
47587
|
bankMetadataMap,
|
|
47863
47588
|
addressLookupTableAccounts: addressLookupTableAccounts ?? [],
|
|
47864
47589
|
primaryIx: {
|
|
47865
|
-
type: "
|
|
47866
|
-
bank:
|
|
47867
|
-
tokenProgram:
|
|
47590
|
+
type: "withdraw",
|
|
47591
|
+
bank: withdrawOpts.withdrawBank,
|
|
47592
|
+
tokenProgram: withdrawOpts.tokenProgram
|
|
47868
47593
|
},
|
|
47869
47594
|
secondaryIx: {
|
|
47870
|
-
type: "
|
|
47871
|
-
bank:
|
|
47872
|
-
tokenProgram:
|
|
47595
|
+
type: "repay",
|
|
47596
|
+
bank: repayOpts.repayBank,
|
|
47597
|
+
tokenProgram: repayOpts.tokenProgram
|
|
47873
47598
|
},
|
|
47874
47599
|
overrideInferAccounts
|
|
47875
47600
|
});
|
|
47876
47601
|
const swapResponse = await getSwapIxsForFlashloan({
|
|
47877
|
-
inputMint:
|
|
47878
|
-
outputMint:
|
|
47879
|
-
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(),
|
|
47880
47608
|
swapMode: "ExactIn",
|
|
47881
47609
|
authority: marginfiAccount.authority,
|
|
47882
47610
|
connection,
|
|
@@ -47886,52 +47614,50 @@ async function buildLoopFlashloanTx({
|
|
|
47886
47614
|
maxSwapTotalAccounts: swapConstraints.maxSwapTotalAccounts
|
|
47887
47615
|
});
|
|
47888
47616
|
sizeConstraintUsed = swapConstraints.sizeConstraint;
|
|
47617
|
+
const { quoteResponse } = swapResponse;
|
|
47618
|
+
const outAmount = nativeToUi(quoteResponse.outAmount, repayOpts.repayBank.mintDecimals);
|
|
47889
47619
|
const outAmountThreshold = nativeToUi(
|
|
47890
|
-
|
|
47891
|
-
|
|
47620
|
+
quoteResponse.otherAmountThreshold,
|
|
47621
|
+
repayOpts.repayBank.mintDecimals
|
|
47892
47622
|
);
|
|
47893
|
-
|
|
47623
|
+
amountToRepay = outAmount > repayOpts.totalPositionAmount ? repayOpts.totalPositionAmount : outAmountThreshold;
|
|
47894
47624
|
swapInstructions = swapResponse.swapInstructions;
|
|
47895
|
-
setupInstructions = swapResponse.setupInstructions;
|
|
47896
47625
|
swapLookupTables = swapResponse.addressLookupTableAddresses;
|
|
47897
|
-
swapQuote =
|
|
47626
|
+
swapQuote = quoteResponse;
|
|
47898
47627
|
}
|
|
47899
|
-
|
|
47900
|
-
|
|
47901
|
-
bank: borrowOpts.borrowBank,
|
|
47902
|
-
bankMap,
|
|
47903
|
-
tokenProgram: borrowOpts.tokenProgram,
|
|
47904
|
-
amount: borrowOpts.borrowAmount,
|
|
47905
|
-
marginfiAccount,
|
|
47906
|
-
authority: marginfiAccount.authority,
|
|
47907
|
-
isSync: false,
|
|
47908
|
-
opts: {
|
|
47909
|
-
createAtas: false,
|
|
47910
|
-
wrapAndUnwrapSol: false,
|
|
47911
|
-
overrideInferAccounts
|
|
47912
|
-
}
|
|
47913
|
-
});
|
|
47914
|
-
let depositIxs;
|
|
47915
|
-
switch (depositOpts.depositBank.config.assetTag) {
|
|
47628
|
+
let withdrawIxs;
|
|
47629
|
+
switch (withdrawOpts.withdrawBank.config.assetTag) {
|
|
47916
47630
|
case 3 /* KAMINO */: {
|
|
47917
|
-
const reserve = bankMetadataMap[
|
|
47631
|
+
const reserve = bankMetadataMap[withdrawOpts.withdrawBank.address.toBase58()]?.kaminoStates?.reserveState;
|
|
47918
47632
|
if (!reserve) {
|
|
47919
47633
|
throw TransactionBuildingError.kaminoReserveNotFound(
|
|
47920
|
-
|
|
47921
|
-
|
|
47922
|
-
|
|
47634
|
+
withdrawOpts.withdrawBank.address.toBase58(),
|
|
47635
|
+
withdrawOpts.withdrawBank.mint.toBase58(),
|
|
47636
|
+
withdrawOpts.withdrawBank.tokenSymbol
|
|
47923
47637
|
);
|
|
47924
47638
|
}
|
|
47925
|
-
|
|
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({
|
|
47926
47642
|
program,
|
|
47927
|
-
bank:
|
|
47928
|
-
|
|
47929
|
-
|
|
47930
|
-
|
|
47643
|
+
bank: withdrawOpts.withdrawBank,
|
|
47644
|
+
bankMap,
|
|
47645
|
+
tokenProgram: withdrawOpts.tokenProgram,
|
|
47646
|
+
cTokenAmount: adjustedAmount,
|
|
47647
|
+
marginfiAccount,
|
|
47931
47648
|
authority: marginfiAccount.authority,
|
|
47932
|
-
group: marginfiAccount.group,
|
|
47933
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,
|
|
47934
47659
|
opts: {
|
|
47660
|
+
createAtas: false,
|
|
47935
47661
|
wrapAndUnwrapSol: false,
|
|
47936
47662
|
overrideInferAccounts
|
|
47937
47663
|
}
|
|
@@ -47939,27 +47665,35 @@ async function buildLoopFlashloanTx({
|
|
|
47939
47665
|
break;
|
|
47940
47666
|
}
|
|
47941
47667
|
case 4 /* DRIFT */: {
|
|
47942
|
-
const driftState = bankMetadataMap[
|
|
47668
|
+
const driftState = bankMetadataMap[withdrawOpts.withdrawBank.address.toBase58()]?.driftStates;
|
|
47943
47669
|
if (!driftState) {
|
|
47944
47670
|
throw TransactionBuildingError.driftStateNotFound(
|
|
47945
|
-
|
|
47946
|
-
|
|
47947
|
-
|
|
47671
|
+
withdrawOpts.withdrawBank.address.toBase58(),
|
|
47672
|
+
withdrawOpts.withdrawBank.mint.toBase58(),
|
|
47673
|
+
withdrawOpts.withdrawBank.tokenSymbol
|
|
47948
47674
|
);
|
|
47949
47675
|
}
|
|
47950
|
-
|
|
47951
|
-
const driftOracle = driftState.spotMarketState.oracle;
|
|
47952
|
-
depositIxs = await makeDriftDepositIx3({
|
|
47676
|
+
withdrawIxs = await makeDriftWithdrawIx3({
|
|
47953
47677
|
program,
|
|
47954
|
-
bank:
|
|
47955
|
-
|
|
47956
|
-
|
|
47957
|
-
|
|
47678
|
+
bank: withdrawOpts.withdrawBank,
|
|
47679
|
+
bankMap,
|
|
47680
|
+
tokenProgram: withdrawOpts.tokenProgram,
|
|
47681
|
+
amount: withdrawOpts.withdrawAmount,
|
|
47682
|
+
marginfiAccount,
|
|
47958
47683
|
authority: marginfiAccount.authority,
|
|
47959
|
-
|
|
47960
|
-
|
|
47961
|
-
|
|
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,
|
|
47962
47695
|
opts: {
|
|
47696
|
+
createAtas: false,
|
|
47963
47697
|
wrapAndUnwrapSol: false,
|
|
47964
47698
|
overrideInferAccounts
|
|
47965
47699
|
}
|
|
@@ -47967,15 +47701,33 @@ async function buildLoopFlashloanTx({
|
|
|
47967
47701
|
break;
|
|
47968
47702
|
}
|
|
47969
47703
|
case 6 /* JUPLEND */: {
|
|
47970
|
-
|
|
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({
|
|
47971
47713
|
program,
|
|
47972
|
-
bank:
|
|
47973
|
-
|
|
47974
|
-
|
|
47975
|
-
|
|
47714
|
+
bank: withdrawOpts.withdrawBank,
|
|
47715
|
+
bankMap,
|
|
47716
|
+
tokenProgram: withdrawOpts.tokenProgram,
|
|
47717
|
+
amount: withdrawOpts.withdrawAmount,
|
|
47718
|
+
marginfiAccount,
|
|
47976
47719
|
authority: marginfiAccount.authority,
|
|
47977
|
-
|
|
47720
|
+
jupLendingState: jupLendState.jupLendingState,
|
|
47721
|
+
withdrawAll: isWholePosition(
|
|
47722
|
+
{
|
|
47723
|
+
amount: withdrawOpts.totalPositionAmount,
|
|
47724
|
+
isLending: true
|
|
47725
|
+
},
|
|
47726
|
+
withdrawOpts.withdrawAmount,
|
|
47727
|
+
withdrawOpts.withdrawBank.mintDecimals
|
|
47728
|
+
),
|
|
47978
47729
|
opts: {
|
|
47730
|
+
createAtas: false,
|
|
47979
47731
|
wrapAndUnwrapSol: false,
|
|
47980
47732
|
overrideInferAccounts
|
|
47981
47733
|
}
|
|
@@ -47983,15 +47735,25 @@ async function buildLoopFlashloanTx({
|
|
|
47983
47735
|
break;
|
|
47984
47736
|
}
|
|
47985
47737
|
default: {
|
|
47986
|
-
|
|
47738
|
+
withdrawIxs = await makeWithdrawIx3({
|
|
47987
47739
|
program,
|
|
47988
|
-
bank:
|
|
47989
|
-
|
|
47990
|
-
|
|
47991
|
-
|
|
47740
|
+
bank: withdrawOpts.withdrawBank,
|
|
47741
|
+
bankMap,
|
|
47742
|
+
tokenProgram: withdrawOpts.tokenProgram,
|
|
47743
|
+
amount: withdrawOpts.withdrawAmount,
|
|
47744
|
+
marginfiAccount,
|
|
47992
47745
|
authority: marginfiAccount.authority,
|
|
47993
|
-
|
|
47746
|
+
withdrawAll: isWholePosition(
|
|
47747
|
+
{
|
|
47748
|
+
amount: withdrawOpts.totalPositionAmount,
|
|
47749
|
+
isLending: true
|
|
47750
|
+
},
|
|
47751
|
+
withdrawOpts.withdrawAmount,
|
|
47752
|
+
withdrawOpts.withdrawBank.mintDecimals
|
|
47753
|
+
),
|
|
47754
|
+
isSync: false,
|
|
47994
47755
|
opts: {
|
|
47756
|
+
createAtas: false,
|
|
47995
47757
|
wrapAndUnwrapSol: false,
|
|
47996
47758
|
overrideInferAccounts
|
|
47997
47759
|
}
|
|
@@ -47999,12 +47761,33 @@ async function buildLoopFlashloanTx({
|
|
|
47999
47761
|
break;
|
|
48000
47762
|
}
|
|
48001
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
|
+
});
|
|
48002
47785
|
const luts = [...addressLookupTableAccounts ?? [], ...swapLookupTables];
|
|
48003
47786
|
const allNonFlIxs = [
|
|
48004
47787
|
...cuRequestIxs,
|
|
48005
|
-
...
|
|
47788
|
+
...withdrawIxs.instructions,
|
|
48006
47789
|
...swapInstructions,
|
|
48007
|
-
...
|
|
47790
|
+
...repayIxs.instructions
|
|
48008
47791
|
];
|
|
48009
47792
|
if (swapInstructions.length > 0) {
|
|
48010
47793
|
compileFlashloanPrecheck({
|
|
@@ -48022,12 +47805,13 @@ async function buildLoopFlashloanTx({
|
|
|
48022
47805
|
bankMap,
|
|
48023
47806
|
addressLookupTableAccounts: luts,
|
|
48024
47807
|
blockhash,
|
|
48025
|
-
ixs: allNonFlIxs
|
|
47808
|
+
ixs: allNonFlIxs,
|
|
47809
|
+
isSync: true
|
|
48026
47810
|
});
|
|
48027
47811
|
const txSize = getTxSize(flashloanTx);
|
|
48028
47812
|
const totalKeys = getTotalAccountKeys(flashloanTx);
|
|
48029
47813
|
if (txSize > MAX_TX_SIZE || totalKeys > MAX_ACCOUNT_LOCKS) {
|
|
48030
|
-
throw TransactionBuildingError.
|
|
47814
|
+
throw TransactionBuildingError.swapSizeExceededRepay(
|
|
48031
47815
|
txSize,
|
|
48032
47816
|
totalKeys,
|
|
48033
47817
|
swapOpts.swapConfig?.provider
|
|
@@ -48037,9 +47821,9 @@ async function buildLoopFlashloanTx({
|
|
|
48037
47821
|
flashloanTx,
|
|
48038
47822
|
setupInstructions,
|
|
48039
47823
|
swapQuote,
|
|
48040
|
-
|
|
48041
|
-
|
|
48042
|
-
|
|
47824
|
+
withdrawIxs,
|
|
47825
|
+
repayIxs,
|
|
47826
|
+
amountToRepay
|
|
48043
47827
|
};
|
|
48044
47828
|
}
|
|
48045
47829
|
|
|
@@ -48470,7 +48254,7 @@ async function buildSwapCollateralFlashloanTx({
|
|
|
48470
48254
|
const txSize = getTxSize(flashloanTx);
|
|
48471
48255
|
const totalKeys = getTotalAccountKeys(flashloanTx);
|
|
48472
48256
|
if (txSize > MAX_TX_SIZE || totalKeys > MAX_ACCOUNT_LOCKS) {
|
|
48473
|
-
throw TransactionBuildingError.
|
|
48257
|
+
throw TransactionBuildingError.swapSizeExceededPositionSwap(
|
|
48474
48258
|
txSize,
|
|
48475
48259
|
totalKeys,
|
|
48476
48260
|
swapOpts.swapConfig?.provider
|
|
@@ -48731,7 +48515,7 @@ async function buildSwapDebtFlashloanTx({
|
|
|
48731
48515
|
const txSize = getTxSize(flashloanTx);
|
|
48732
48516
|
const totalKeys = getTotalAccountKeys(flashloanTx);
|
|
48733
48517
|
if (txSize > MAX_TX_SIZE || totalKeys > MAX_ACCOUNT_LOCKS) {
|
|
48734
|
-
throw TransactionBuildingError.
|
|
48518
|
+
throw TransactionBuildingError.swapSizeExceededPositionSwap(
|
|
48735
48519
|
txSize,
|
|
48736
48520
|
totalKeys,
|
|
48737
48521
|
swapOpts.swapConfig?.provider
|
|
@@ -49401,23 +49185,27 @@ var getTitanSwapIxsForFlashloan = async ({
|
|
|
49401
49185
|
quoteParams.swapMode === "ExactIn" ? quoteParams.outputMint : quoteParams.inputMint
|
|
49402
49186
|
);
|
|
49403
49187
|
const { feeAccount, hasFeeAccount } = await checkTitanFeeAccount(connection, feeMint);
|
|
49188
|
+
const useFeeAccount = hasFeeAccount && !!quoteParams.platformFeeBps;
|
|
49404
49189
|
let finalQuoteParams = quoteParams;
|
|
49405
|
-
if (!
|
|
49406
|
-
|
|
49190
|
+
if (!useFeeAccount) {
|
|
49191
|
+
if (!hasFeeAccount) {
|
|
49192
|
+
console.warn("Warning: Titan fee account ATA does not exist, disabling platform fee");
|
|
49193
|
+
}
|
|
49407
49194
|
finalQuoteParams = {
|
|
49408
49195
|
...quoteParams,
|
|
49409
49196
|
platformFeeBps: void 0
|
|
49410
49197
|
};
|
|
49411
49198
|
}
|
|
49199
|
+
const effectiveFeeAccount = useFeeAccount ? feeAccount : void 0;
|
|
49412
49200
|
if (basePath.startsWith("wss://") || basePath.startsWith("ws://")) {
|
|
49413
49201
|
return getTitanSwapIxsViaWebSocket(
|
|
49414
49202
|
{ quoteParams: finalQuoteParams, authority, connection, destinationTokenAccount, apiConfig },
|
|
49415
|
-
|
|
49203
|
+
effectiveFeeAccount
|
|
49416
49204
|
);
|
|
49417
49205
|
} else {
|
|
49418
49206
|
return getTitanSwapIxsViaHttpProxy(
|
|
49419
49207
|
{ quoteParams: finalQuoteParams, authority, connection, destinationTokenAccount, apiConfig },
|
|
49420
|
-
|
|
49208
|
+
effectiveFeeAccount
|
|
49421
49209
|
);
|
|
49422
49210
|
}
|
|
49423
49211
|
};
|
|
@@ -49593,7 +49381,7 @@ async function getTitanExactOutViaWebSocket(params) {
|
|
|
49593
49381
|
inputMint: new web3_js.PublicKey(inputMint).toBytes(),
|
|
49594
49382
|
outputMint: new web3_js.PublicKey(outputMint).toBytes(),
|
|
49595
49383
|
amount,
|
|
49596
|
-
swapMode: "ExactOut"
|
|
49384
|
+
swapMode: "ExactOut" /* ExactOut */,
|
|
49597
49385
|
slippageBps
|
|
49598
49386
|
},
|
|
49599
49387
|
transaction: {
|
|
@@ -49813,178 +49601,616 @@ var getSwapIxsForFlashloan = async (params) => {
|
|
|
49813
49601
|
lastError = err;
|
|
49814
49602
|
console.warn(`[swap] ${attemptProvider} failed:`, err instanceof Error ? err.message : err);
|
|
49815
49603
|
}
|
|
49816
|
-
}
|
|
49817
|
-
const firstProvider = attempts[0]?.provider ?? "Swap";
|
|
49818
|
-
throw TransactionBuildingError.swapQuoteFailed(
|
|
49819
|
-
firstProvider,
|
|
49820
|
-
inputMint,
|
|
49821
|
-
outputMint,
|
|
49822
|
-
lastError?.message ?? "No swap route available"
|
|
49823
|
-
);
|
|
49824
|
-
};
|
|
49825
|
-
var getExactOutEstimate = async (params) => {
|
|
49826
|
-
const { inputMint, outputMint, amount, swapOpts, connection } = params;
|
|
49827
|
-
const provider = swapOpts.swapConfig?.provider ?? "JUPITER" /* JUPITER */;
|
|
49828
|
-
const attempts = [
|
|
49829
|
-
{ provider, apiConfig: swapOpts.swapConfig?.apiConfig },
|
|
49830
|
-
...swapOpts.swapConfig?.fallbackProviders ?? []
|
|
49831
|
-
];
|
|
49832
|
-
let lastError;
|
|
49833
|
-
for (const { provider: attemptProvider, apiConfig } of attempts) {
|
|
49834
|
-
const fn = getExactOutProviderFn({
|
|
49835
|
-
attemptProvider,
|
|
49836
|
-
inputMint,
|
|
49837
|
-
outputMint,
|
|
49838
|
-
amount,
|
|
49839
|
-
swapOpts,
|
|
49840
|
-
apiConfig
|
|
49841
|
-
});
|
|
49842
|
-
if (!fn) continue;
|
|
49843
|
-
try {
|
|
49844
|
-
return await fn(apiConfig);
|
|
49845
|
-
} catch (err) {
|
|
49846
|
-
if (err instanceof TransactionBuildingError) throw err;
|
|
49847
|
-
lastError = err;
|
|
49848
|
-
console.warn(
|
|
49849
|
-
`[exactout] ${attemptProvider} failed:`,
|
|
49850
|
-
err instanceof Error ? err.message : err
|
|
49851
|
-
);
|
|
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
|
+
});
|
|
49852
50083
|
}
|
|
49853
50084
|
}
|
|
49854
|
-
const firstProvider = attempts[0]?.provider ?? "Swap";
|
|
49855
|
-
throw TransactionBuildingError.swapQuoteFailed(
|
|
49856
|
-
firstProvider,
|
|
49857
|
-
inputMint,
|
|
49858
|
-
outputMint,
|
|
49859
|
-
lastError?.message ?? "No swap route available"
|
|
49860
|
-
);
|
|
49861
|
-
};
|
|
49862
|
-
function mapJupiterQuoteToSwapQuoteResult(quote) {
|
|
49863
|
-
return {
|
|
49864
|
-
inAmount: quote.inAmount,
|
|
49865
|
-
outAmount: quote.outAmount,
|
|
49866
|
-
otherAmountThreshold: quote.otherAmountThreshold,
|
|
49867
|
-
slippageBps: quote.slippageBps,
|
|
49868
|
-
platformFee: quote.platformFee ? {
|
|
49869
|
-
amount: quote.platformFee.amount ?? "0",
|
|
49870
|
-
feeBps: quote.platformFee.feeBps ?? 0
|
|
49871
|
-
} : void 0,
|
|
49872
|
-
priceImpactPct: quote.priceImpactPct,
|
|
49873
|
-
contextSlot: quote.contextSlot,
|
|
49874
|
-
timeTaken: quote.timeTaken,
|
|
49875
|
-
provider: "JUPITER" /* JUPITER */
|
|
49876
|
-
};
|
|
49877
|
-
}
|
|
49878
|
-
|
|
49879
|
-
// src/services/account/utils/jupiter.utils.ts
|
|
49880
|
-
var REFERRAL_PROGRAM_ID = new web3_js.PublicKey("REFER4ZgmyYx9c6He5XfaTMiGfdLwRnkV4RPp9t9iF3");
|
|
49881
|
-
var REFERRAL_ACCOUNT_PUBKEY = new web3_js.PublicKey("Mm7HcujSK2JzPW4eX7g4oqTXbWYDuFxapNMHXe8yp1B");
|
|
49882
|
-
var getFeeAccount = (mint) => {
|
|
49883
|
-
const [feeAccount] = web3_js.PublicKey.findProgramAddressSync(
|
|
49884
|
-
[Buffer.from("referral_ata"), REFERRAL_ACCOUNT_PUBKEY.toBuffer(), mint.toBuffer()],
|
|
49885
|
-
REFERRAL_PROGRAM_ID
|
|
49886
|
-
);
|
|
49887
|
-
return feeAccount.toBase58();
|
|
49888
|
-
};
|
|
49889
|
-
var checkFeeAccount = async (connection, mint) => {
|
|
49890
|
-
const feeAccount = getFeeAccount(mint);
|
|
49891
|
-
const hasFeeAccount = !!await connection.getAccountInfo(new web3_js.PublicKey(feeAccount));
|
|
49892
|
-
return { feeAccount, hasFeeAccount };
|
|
49893
|
-
};
|
|
49894
|
-
function deserializeJupiterInstruction(instruction) {
|
|
49895
|
-
return new web3_js.TransactionInstruction({
|
|
49896
|
-
programId: new web3_js.PublicKey(instruction.programId),
|
|
49897
|
-
keys: instruction.accounts.map((key) => ({
|
|
49898
|
-
pubkey: new web3_js.PublicKey(key.pubkey),
|
|
49899
|
-
isSigner: key.isSigner,
|
|
49900
|
-
isWritable: key.isWritable
|
|
49901
|
-
})),
|
|
49902
|
-
data: Buffer.from(instruction.data, "base64")
|
|
49903
|
-
});
|
|
49904
|
-
}
|
|
49905
|
-
function toJupiterConfig(apiConfig) {
|
|
49906
|
-
if (!apiConfig) return void 0;
|
|
49907
|
-
return {
|
|
49908
|
-
basePath: apiConfig.basePath,
|
|
49909
|
-
apiKey: apiConfig.apiKey ? () => apiConfig.apiKey : void 0,
|
|
49910
|
-
headers: apiConfig.headers
|
|
49911
|
-
};
|
|
49912
50085
|
}
|
|
49913
|
-
|
|
49914
|
-
|
|
49915
|
-
|
|
49916
|
-
|
|
49917
|
-
|
|
49918
|
-
|
|
49919
|
-
|
|
49920
|
-
|
|
49921
|
-
|
|
49922
|
-
|
|
49923
|
-
|
|
49924
|
-
|
|
49925
|
-
|
|
49926
|
-
|
|
49927
|
-
|
|
49928
|
-
|
|
49929
|
-
|
|
49930
|
-
|
|
49931
|
-
|
|
49932
|
-
|
|
49933
|
-
|
|
49934
|
-
|
|
49935
|
-
|
|
49936
|
-
|
|
49937
|
-
|
|
49938
|
-
|
|
49939
|
-
const swapInstructionResponse = await jupiterApiClient.swapInstructionsPost({
|
|
49940
|
-
swapRequest: {
|
|
49941
|
-
quoteResponse: swapQuote,
|
|
49942
|
-
userPublicKey: authority.toBase58(),
|
|
49943
|
-
feeAccount: hasFeeAccount ? feeAccount : void 0,
|
|
49944
|
-
wrapAndUnwrapSol: false,
|
|
49945
|
-
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
|
+
});
|
|
49946
50112
|
}
|
|
49947
|
-
|
|
49948
|
-
|
|
49949
|
-
|
|
49950
|
-
|
|
49951
|
-
|
|
49952
|
-
|
|
49953
|
-
|
|
49954
|
-
|
|
49955
|
-
|
|
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
|
+
});
|
|
49956
50136
|
}
|
|
49957
|
-
|
|
49958
|
-
|
|
49959
|
-
|
|
49960
|
-
|
|
49961
|
-
|
|
49962
|
-
|
|
49963
|
-
|
|
49964
|
-
|
|
49965
|
-
|
|
49966
|
-
|
|
49967
|
-
|
|
49968
|
-
|
|
49969
|
-
|
|
49970
|
-
|
|
49971
|
-
|
|
49972
|
-
|
|
49973
|
-
|
|
49974
|
-
|
|
49975
|
-
|
|
49976
|
-
|
|
49977
|
-
}
|
|
49978
|
-
|
|
49979
|
-
|
|
49980
|
-
|
|
49981
|
-
|
|
49982
|
-
|
|
49983
|
-
|
|
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
|
+
}
|
|
49984
50174
|
}
|
|
49985
|
-
function
|
|
49986
|
-
|
|
49987
|
-
|
|
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
|
+
});
|
|
49988
50214
|
}
|
|
49989
50215
|
|
|
49990
50216
|
// src/services/price/utils/smart-crank.utils.ts
|
|
@@ -50652,18 +50878,15 @@ var fetchPythOracleData = async (banks, opts) => {
|
|
|
50652
50878
|
bankOraclePriceMap: /* @__PURE__ */ new Map()
|
|
50653
50879
|
};
|
|
50654
50880
|
}
|
|
50655
|
-
pythStakedCollateralBanks.map((bank) => [
|
|
50656
|
-
opts.validatorVoteAccountByBank?.[bank.address.toBase58()] ?? "",
|
|
50657
|
-
bank.mint.toBase58()
|
|
50658
|
-
]);
|
|
50659
|
-
const priceCoeffByBank = {};
|
|
50660
50881
|
const combinedPythBanks = [
|
|
50661
50882
|
...pythPushBanks,
|
|
50883
|
+
...pythStakedCollateralBanks,
|
|
50662
50884
|
...pythPushKaminosBanks,
|
|
50663
50885
|
...driftPythPullBanks,
|
|
50664
50886
|
...solendPythPullBanks,
|
|
50665
50887
|
...juplendPythPullBanks
|
|
50666
50888
|
];
|
|
50889
|
+
const priceCoeffByBank = {};
|
|
50667
50890
|
const pythOracleKeys = extractPythOracleKeys(combinedPythBanks);
|
|
50668
50891
|
const uniquePythOracleKeys = Array.from(new Set(pythOracleKeys));
|
|
50669
50892
|
let oraclePrices;
|
|
@@ -51467,6 +51690,78 @@ function computeRemainingCapacity(bank) {
|
|
|
51467
51690
|
};
|
|
51468
51691
|
}
|
|
51469
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
|
+
|
|
51470
51765
|
// src/services/bank/bank.service.ts
|
|
51471
51766
|
async function freezeBankConfigIx(program, bankAddress, bankConfigOpt) {
|
|
51472
51767
|
let bankConfigRaw;
|
|
@@ -51868,6 +52163,613 @@ function dtoToValidatorStakeGroup(validatorStakeGroupDto) {
|
|
|
51868
52163
|
}))
|
|
51869
52164
|
};
|
|
51870
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
|
+
}
|
|
51871
52773
|
async function getKaminoMetadata(options) {
|
|
51872
52774
|
const kaminoBanks = options.banks.filter((b) => b.config.assetTag === 3 /* KAMINO */);
|
|
51873
52775
|
const DEFAULT_PUBKEY = web3_js.PublicKey.default;
|
|
@@ -54565,7 +55467,6 @@ var Project0Client = class _Project0Client {
|
|
|
54565
55467
|
assetShareMultiplierByBank.set(bank.address.toBase58(), new BigNumber3__default.default(1));
|
|
54566
55468
|
break;
|
|
54567
55469
|
case 2 /* STAKED */:
|
|
54568
|
-
assetShareMultiplierByBank.set(bank.address.toBase58(), new BigNumber3__default.default(1));
|
|
54569
55470
|
break;
|
|
54570
55471
|
case 0 /* DEFAULT */:
|
|
54571
55472
|
case 1 /* SOL */:
|
|
@@ -54574,6 +55475,11 @@ var Project0Client = class _Project0Client {
|
|
|
54574
55475
|
break;
|
|
54575
55476
|
}
|
|
54576
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));
|
|
54577
55483
|
const emodePairs = getEmodePairs(banksArray);
|
|
54578
55484
|
return new _Project0Client(
|
|
54579
55485
|
program,
|
|
@@ -54725,6 +55631,16 @@ exports.computeActiveEmodePairs = computeActiveEmodePairs;
|
|
|
54725
55631
|
exports.computeAssetHealthComponent = computeAssetHealthComponent;
|
|
54726
55632
|
exports.computeAssetUsdValue = computeAssetUsdValue;
|
|
54727
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;
|
|
54728
55644
|
exports.computeBaseInterestRate = computeBaseInterestRate;
|
|
54729
55645
|
exports.computeClaimedEmissions = computeClaimedEmissions;
|
|
54730
55646
|
exports.computeClosePositionTokenAmount = computeClosePositionTokenAmount;
|
|
@@ -54755,6 +55671,7 @@ exports.computeQuantity = computeQuantity;
|
|
|
54755
55671
|
exports.computeQuantityUi = computeQuantityUi;
|
|
54756
55672
|
exports.computeRemainingCapacity = computeRemainingCapacity;
|
|
54757
55673
|
exports.computeSmartCrank = computeSmartCrank;
|
|
55674
|
+
exports.computeStakedBankMultipliers = computeStakedBankMultipliers;
|
|
54758
55675
|
exports.computeTotalOutstandingEmissions = computeTotalOutstandingEmissions;
|
|
54759
55676
|
exports.computeTvl = computeTvl;
|
|
54760
55677
|
exports.computeUsdValue = computeUsdValue;
|
|
@@ -54815,6 +55732,7 @@ exports.fetchSwbOraclePricesFromAPI = fetchSwbOraclePricesFromAPI;
|
|
|
54815
55732
|
exports.fetchSwbOraclePricesFromCrossbar = fetchSwbOraclePricesFromCrossbar;
|
|
54816
55733
|
exports.findRandomAvailableAccountIndex = findRandomAvailableAccountIndex;
|
|
54817
55734
|
exports.freezeBankConfigIx = freezeBankConfigIx;
|
|
55735
|
+
exports.generateDummyAccount = generateDummyAccount;
|
|
54818
55736
|
exports.getAccountKeys = getAccountKeys;
|
|
54819
55737
|
exports.getActiveAccountFlags = getActiveAccountFlags;
|
|
54820
55738
|
exports.getActiveBalances = getActiveBalances;
|
|
@@ -54853,6 +55771,7 @@ exports.getOracleSourceFromOracleSetup = getOracleSourceFromOracleSetup;
|
|
|
54853
55771
|
exports.getOracleSourceNameFromKey = getOracleSourceNameFromKey;
|
|
54854
55772
|
exports.getPrice = getPrice;
|
|
54855
55773
|
exports.getPriceWithConfidence = getPriceWithConfidence;
|
|
55774
|
+
exports.getStakedBankMetadataMap = getStakedBankMetadataMap;
|
|
54856
55775
|
exports.getSwapIxsForFlashloan = getSwapIxsForFlashloan;
|
|
54857
55776
|
exports.getTitanExactOutEstimate = getTitanExactOutEstimate;
|
|
54858
55777
|
exports.getTitanSwapIxsForFlashloan = getTitanSwapIxsForFlashloan;
|
|
@@ -54860,6 +55779,7 @@ exports.getTotalAccountKeys = getTotalAccountKeys;
|
|
|
54860
55779
|
exports.getTotalAssetQuantity = getTotalAssetQuantity;
|
|
54861
55780
|
exports.getTotalLiabilityQuantity = getTotalLiabilityQuantity;
|
|
54862
55781
|
exports.getTxSize = getTxSize;
|
|
55782
|
+
exports.getValidatorVoteAccountByBank = getValidatorVoteAccountByBank;
|
|
54863
55783
|
exports.getWritableAccountKeys = getWritableAccountKeys;
|
|
54864
55784
|
exports.groupToDto = groupToDto;
|
|
54865
55785
|
exports.hasAccountFlag = hasAccountFlag;
|
|
@@ -54901,11 +55821,16 @@ exports.makeKaminoDepositTx = makeKaminoDepositTx;
|
|
|
54901
55821
|
exports.makeKaminoWithdrawIx = makeKaminoWithdrawIx3;
|
|
54902
55822
|
exports.makeKaminoWithdrawTx = makeKaminoWithdrawTx;
|
|
54903
55823
|
exports.makeLoopTx = makeLoopTx;
|
|
55824
|
+
exports.makeMergeStakeAccountsTx = makeMergeStakeAccountsTx;
|
|
55825
|
+
exports.makeMintStakedLstIx = makeMintStakedLstIx;
|
|
55826
|
+
exports.makeMintStakedLstTx = makeMintStakedLstTx;
|
|
54904
55827
|
exports.makePoolAddBankIx = makePoolAddBankIx3;
|
|
54905
55828
|
exports.makePoolConfigureBankIx = makePoolConfigureBankIx3;
|
|
54906
55829
|
exports.makePriorityFeeIx = makePriorityFeeIx;
|
|
54907
55830
|
exports.makePriorityFeeMicroIx = makePriorityFeeMicroIx;
|
|
54908
55831
|
exports.makePulseHealthIx = makePulseHealthIx2;
|
|
55832
|
+
exports.makeRedeemStakedLstIx = makeRedeemStakedLstIx;
|
|
55833
|
+
exports.makeRedeemStakedLstTx = makeRedeemStakedLstTx;
|
|
54909
55834
|
exports.makeRefreshKaminoBanksIxs = makeRefreshKaminoBanksIxs;
|
|
54910
55835
|
exports.makeRepayIx = makeRepayIx3;
|
|
54911
55836
|
exports.makeRepayTx = makeRepayTx;
|