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