@0dotxyz/p0-ts-sdk 2.2.0-alpha.4 → 2.2.0-alpha.6
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 +2245 -911
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +374 -176
- package/dist/index.d.ts +374 -176
- package/dist/index.js +2231 -913
- package/dist/index.js.map +1 -1
- package/dist/vendor.cjs +365 -0
- package/dist/vendor.cjs.map +1 -1
- package/dist/vendor.d.cts +288 -3
- package/dist/vendor.d.ts +288 -3
- package/dist/vendor.js +356 -2
- package/dist/vendor.js.map +1 -1
- package/package.json +4 -4
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';
|
|
@@ -10,6 +10,8 @@ import { Buffer as Buffer$1 } from 'buffer';
|
|
|
10
10
|
import { deserialize } from 'borsh';
|
|
11
11
|
import * as borsh from '@coral-xyz/borsh';
|
|
12
12
|
import { struct as struct$1, bool as bool$1, publicKey as publicKey$1, array as array$1, u64 as u64$1, u8 as u8$1, u32 as u32$1, u128 } from '@coral-xyz/borsh';
|
|
13
|
+
import WebSocket from 'ws';
|
|
14
|
+
import { Encoder, Decoder } from '@msgpack/msgpack';
|
|
13
15
|
import { SwapApi, Configuration, createJupiterApiClient } from '@jup-ag/api';
|
|
14
16
|
import { AnchorUtils, PullFeed } from '@switchboard-xyz/on-demand';
|
|
15
17
|
import { CrossbarClient } from '@switchboard-xyz/common';
|
|
@@ -89,12 +91,15 @@ function getConfig(environment = "production", overrides) {
|
|
|
89
91
|
|
|
90
92
|
// src/errors/transaction-building.errors.ts
|
|
91
93
|
var TransactionBuildingErrorCode = /* @__PURE__ */ ((TransactionBuildingErrorCode2) => {
|
|
92
|
-
TransactionBuildingErrorCode2["
|
|
93
|
-
TransactionBuildingErrorCode2["
|
|
94
|
+
TransactionBuildingErrorCode2["SWAP_SIZE_EXCEEDED_LOOP"] = "SWAP_SIZE_EXCEEDED_LOOP";
|
|
95
|
+
TransactionBuildingErrorCode2["SWAP_SIZE_EXCEEDED_REPAY"] = "SWAP_SIZE_EXCEEDED_REPAY";
|
|
96
|
+
TransactionBuildingErrorCode2["SWAP_SIZE_EXCEEDED_POSITION_SWAP"] = "SWAP_SIZE_EXCEEDED_POSITION_SWAP";
|
|
94
97
|
TransactionBuildingErrorCode2["ORACLE_CRANK_FAILED"] = "ORACLE_CRANK_FAILED";
|
|
95
98
|
TransactionBuildingErrorCode2["KAMINO_RESERVE_NOT_FOUND"] = "KAMINO_RESERVE_NOT_FOUND";
|
|
96
99
|
TransactionBuildingErrorCode2["DRIFT_STATE_NOT_FOUND"] = "DRIFT_STATE_NOT_FOUND";
|
|
97
100
|
TransactionBuildingErrorCode2["JUPLEND_STATE_NOT_FOUND"] = "JUPLEND_STATE_NOT_FOUND";
|
|
101
|
+
TransactionBuildingErrorCode2["SWITCHBOARD_FEED_UPDATE_FAILED"] = "SWITCHBOARD_FEED_UPDATE_FAILED";
|
|
102
|
+
TransactionBuildingErrorCode2["SWAP_QUOTE_FAILED"] = "SWAP_QUOTE_FAILED";
|
|
98
103
|
return TransactionBuildingErrorCode2;
|
|
99
104
|
})(TransactionBuildingErrorCode || {});
|
|
100
105
|
var TransactionBuildingError = class _TransactionBuildingError extends Error {
|
|
@@ -109,21 +114,25 @@ var TransactionBuildingError = class _TransactionBuildingError extends Error {
|
|
|
109
114
|
Error.captureStackTrace(this, _TransactionBuildingError);
|
|
110
115
|
}
|
|
111
116
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
117
|
+
static swapSizeExceededLoop(bytes, accountKeys, provider) {
|
|
118
|
+
return new _TransactionBuildingError(
|
|
119
|
+
"SWAP_SIZE_EXCEEDED_LOOP" /* SWAP_SIZE_EXCEEDED_LOOP */,
|
|
120
|
+
`${provider ?? "Swap"} instruction size exceeds available transaction size`,
|
|
121
|
+
{ bytes, accountKeys, provider }
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
static swapSizeExceededRepay(bytes, accountKeys, provider) {
|
|
116
125
|
return new _TransactionBuildingError(
|
|
117
|
-
"
|
|
118
|
-
"
|
|
119
|
-
{ bytes, accountKeys }
|
|
126
|
+
"SWAP_SIZE_EXCEEDED_REPAY" /* SWAP_SIZE_EXCEEDED_REPAY */,
|
|
127
|
+
`${provider ?? "Swap"} instruction size exceeds available transaction size`,
|
|
128
|
+
{ bytes, accountKeys, provider }
|
|
120
129
|
);
|
|
121
130
|
}
|
|
122
|
-
static
|
|
131
|
+
static swapSizeExceededPositionSwap(bytes, accountKeys, provider) {
|
|
123
132
|
return new _TransactionBuildingError(
|
|
124
|
-
"
|
|
125
|
-
"
|
|
126
|
-
{ bytes, accountKeys }
|
|
133
|
+
"SWAP_SIZE_EXCEEDED_POSITION_SWAP" /* SWAP_SIZE_EXCEEDED_POSITION_SWAP */,
|
|
134
|
+
`${provider ?? "Swap"} instruction size exceeds available transaction size`,
|
|
135
|
+
{ bytes, accountKeys, provider }
|
|
127
136
|
);
|
|
128
137
|
}
|
|
129
138
|
/**
|
|
@@ -167,6 +176,26 @@ var TransactionBuildingError = class _TransactionBuildingError extends Error {
|
|
|
167
176
|
{ bankAddress, bankMint, bankSymbol }
|
|
168
177
|
);
|
|
169
178
|
}
|
|
179
|
+
/**
|
|
180
|
+
* Failed to update Switchboard price feeds
|
|
181
|
+
*/
|
|
182
|
+
static switchboardFeedUpdateFailed(oracleKeys, reason) {
|
|
183
|
+
return new _TransactionBuildingError(
|
|
184
|
+
"SWITCHBOARD_FEED_UPDATE_FAILED" /* SWITCHBOARD_FEED_UPDATE_FAILED */,
|
|
185
|
+
`Switchboard feed update failed: ${reason}`,
|
|
186
|
+
{ oracleKeys, reason }
|
|
187
|
+
);
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Failed to get a swap quote from any provider
|
|
191
|
+
*/
|
|
192
|
+
static swapQuoteFailed(provider, inputMint, outputMint, reason) {
|
|
193
|
+
return new _TransactionBuildingError(
|
|
194
|
+
"SWAP_QUOTE_FAILED" /* SWAP_QUOTE_FAILED */,
|
|
195
|
+
`${provider} swap quote failed for ${inputMint} \u2192 ${outputMint}: ${reason}`,
|
|
196
|
+
{ provider, inputMint, outputMint, reason }
|
|
197
|
+
);
|
|
198
|
+
}
|
|
170
199
|
/**
|
|
171
200
|
* Generic escape hatch for custom errors
|
|
172
201
|
*/
|
|
@@ -319,6 +348,7 @@ var MAX_U64 = BigInt("18446744073709551615").toString();
|
|
|
319
348
|
|
|
320
349
|
// src/constants/transaction.consts.ts
|
|
321
350
|
var MAX_TX_SIZE = 1232;
|
|
351
|
+
var MAX_ACCOUNT_LOCKS = 64;
|
|
322
352
|
var BUNDLE_TX_SIZE = 81;
|
|
323
353
|
var PRIORITY_TX_SIZE = 44;
|
|
324
354
|
var WSOL_MINT = new PublicKey("So11111111111111111111111111111111111111112");
|
|
@@ -14867,8 +14897,40 @@ function getTxSize(tx) {
|
|
|
14867
14897
|
const signaturesSize = (numRequiredSignatures - numSigners) * 64 + 1;
|
|
14868
14898
|
try {
|
|
14869
14899
|
const baseTxSize = isVersioned ? tx.serialize().length : tx.serialize({ requireAllSignatures: false, verifySignatures: false }).length;
|
|
14870
|
-
|
|
14871
|
-
|
|
14900
|
+
const totalSize = baseTxSize + feePayerSize + signaturesSize;
|
|
14901
|
+
if (isVersioned && totalSize > 1232) {
|
|
14902
|
+
const { header, staticAccountKeys, addressTableLookups } = tx.message;
|
|
14903
|
+
const lutWritable = addressTableLookups.reduce((s, l) => s + l.writableIndexes.length, 0);
|
|
14904
|
+
const lutReadonly = addressTableLookups.reduce((s, l) => s + l.readonlyIndexes.length, 0);
|
|
14905
|
+
console.warn("[getTxSize] oversized TX", {
|
|
14906
|
+
totalSize,
|
|
14907
|
+
overshoot: totalSize - 1232,
|
|
14908
|
+
staticKeys: staticAccountKeys.length,
|
|
14909
|
+
numSignatures: header.numRequiredSignatures,
|
|
14910
|
+
numLuts: addressTableLookups.length,
|
|
14911
|
+
lutWritable,
|
|
14912
|
+
lutReadonly,
|
|
14913
|
+
totalAccounts: staticAccountKeys.length + lutWritable + lutReadonly
|
|
14914
|
+
});
|
|
14915
|
+
}
|
|
14916
|
+
return totalSize;
|
|
14917
|
+
} catch (err) {
|
|
14918
|
+
if (isVersioned) {
|
|
14919
|
+
const { header, staticAccountKeys, addressTableLookups } = tx.message;
|
|
14920
|
+
const lutWritable = addressTableLookups.reduce((s, l) => s + l.writableIndexes.length, 0);
|
|
14921
|
+
const lutReadonly = addressTableLookups.reduce((s, l) => s + l.readonlyIndexes.length, 0);
|
|
14922
|
+
console.warn("[getTxSize] serialize failed", {
|
|
14923
|
+
error: err.message,
|
|
14924
|
+
staticKeys: staticAccountKeys.length,
|
|
14925
|
+
numSignatures: header.numRequiredSignatures,
|
|
14926
|
+
numLuts: addressTableLookups.length,
|
|
14927
|
+
lutWritable,
|
|
14928
|
+
lutReadonly,
|
|
14929
|
+
totalAccounts: staticAccountKeys.length + lutWritable + lutReadonly
|
|
14930
|
+
});
|
|
14931
|
+
} else {
|
|
14932
|
+
console.warn("[getTxSize] serialize failed", { error: err.message });
|
|
14933
|
+
}
|
|
14872
14934
|
return 9999;
|
|
14873
14935
|
}
|
|
14874
14936
|
}
|
|
@@ -14883,6 +14945,47 @@ function getAccountKeys(tx, lookupTableAccounts) {
|
|
|
14883
14945
|
} else {
|
|
14884
14946
|
return tx.compileMessage().getAccountKeys().length;
|
|
14885
14947
|
}
|
|
14948
|
+
} catch (err) {
|
|
14949
|
+
console.warn("[getAccountKeys] decompile failed", { error: err.message });
|
|
14950
|
+
return 9999;
|
|
14951
|
+
}
|
|
14952
|
+
}
|
|
14953
|
+
function getWritableAccountKeys(tx) {
|
|
14954
|
+
const isVersioned = isV0Tx(tx);
|
|
14955
|
+
try {
|
|
14956
|
+
if (isVersioned) {
|
|
14957
|
+
const { header, staticAccountKeys, addressTableLookups } = tx.message;
|
|
14958
|
+
const writableStatic = staticAccountKeys.length - header.numReadonlySignedAccounts - header.numReadonlyUnsignedAccounts;
|
|
14959
|
+
const writableLut = addressTableLookups.reduce(
|
|
14960
|
+
(sum, lookup) => sum + lookup.writableIndexes.length,
|
|
14961
|
+
0
|
|
14962
|
+
);
|
|
14963
|
+
return writableStatic + writableLut;
|
|
14964
|
+
} else {
|
|
14965
|
+
const message = tx.compileMessage();
|
|
14966
|
+
const { numRequiredSignatures, numReadonlySignedAccounts, numReadonlyUnsignedAccounts } = message.header;
|
|
14967
|
+
const totalKeys = message.accountKeys.length;
|
|
14968
|
+
const writableSigned = numRequiredSignatures - numReadonlySignedAccounts;
|
|
14969
|
+
const writableUnsigned = totalKeys - numRequiredSignatures - numReadonlyUnsignedAccounts;
|
|
14970
|
+
return writableSigned + writableUnsigned;
|
|
14971
|
+
}
|
|
14972
|
+
} catch {
|
|
14973
|
+
return 9999;
|
|
14974
|
+
}
|
|
14975
|
+
}
|
|
14976
|
+
function getTotalAccountKeys(tx) {
|
|
14977
|
+
const isVersioned = isV0Tx(tx);
|
|
14978
|
+
try {
|
|
14979
|
+
if (isVersioned) {
|
|
14980
|
+
const { staticAccountKeys, addressTableLookups } = tx.message;
|
|
14981
|
+
const lutAccounts = addressTableLookups.reduce(
|
|
14982
|
+
(sum, lookup) => sum + lookup.writableIndexes.length + lookup.readonlyIndexes.length,
|
|
14983
|
+
0
|
|
14984
|
+
);
|
|
14985
|
+
return staticAccountKeys.length + lutAccounts;
|
|
14986
|
+
} else {
|
|
14987
|
+
return tx.compileMessage().accountKeys.length;
|
|
14988
|
+
}
|
|
14886
14989
|
} catch {
|
|
14887
14990
|
return 9999;
|
|
14888
14991
|
}
|
|
@@ -20120,6 +20223,14 @@ var HealthCacheSimulationError = class _HealthCacheSimulationError extends Error
|
|
|
20120
20223
|
}
|
|
20121
20224
|
};
|
|
20122
20225
|
|
|
20226
|
+
// src/services/account/types/action.types.ts
|
|
20227
|
+
var SwapProvider = /* @__PURE__ */ ((SwapProvider2) => {
|
|
20228
|
+
SwapProvider2["JUPITER"] = "JUPITER";
|
|
20229
|
+
SwapProvider2["TITAN"] = "TITAN";
|
|
20230
|
+
SwapProvider2["DFLOW"] = "DFLOW";
|
|
20231
|
+
return SwapProvider2;
|
|
20232
|
+
})(SwapProvider || {});
|
|
20233
|
+
|
|
20123
20234
|
// src/services/account/utils/deserialize.utils.ts
|
|
20124
20235
|
var EMPTY_HEALTH_CACHE = {
|
|
20125
20236
|
assetValue: {
|
|
@@ -44168,6 +44279,346 @@ function makeUpdateJupLendRate({ lendingState }) {
|
|
|
44168
44279
|
lendingState.rewardsRateModel
|
|
44169
44280
|
);
|
|
44170
44281
|
}
|
|
44282
|
+
var SUBPROTOCOL = "v1.api.titan.ag";
|
|
44283
|
+
var UINT64_MAX = (1n << 64n) - 1n;
|
|
44284
|
+
function toBigInt(value) {
|
|
44285
|
+
if (typeof value === "bigint") {
|
|
44286
|
+
if (value < 0n || value > UINT64_MAX) {
|
|
44287
|
+
throw new RangeError(`Amount out of uint64 range: ${value}`);
|
|
44288
|
+
}
|
|
44289
|
+
return value;
|
|
44290
|
+
}
|
|
44291
|
+
if (!Number.isInteger(value)) {
|
|
44292
|
+
throw new TypeError(`Amount must be a whole number, got ${value}`);
|
|
44293
|
+
}
|
|
44294
|
+
if (value < 0) {
|
|
44295
|
+
throw new RangeError(`Amount must be non-negative, got ${value}`);
|
|
44296
|
+
}
|
|
44297
|
+
return BigInt(value);
|
|
44298
|
+
}
|
|
44299
|
+
var ConnectionClosed = class _ConnectionClosed extends Error {
|
|
44300
|
+
code;
|
|
44301
|
+
reason;
|
|
44302
|
+
constructor(code, reason) {
|
|
44303
|
+
super(`Client WebSocket closed with code ${code}: ${reason}`);
|
|
44304
|
+
this.name = "ConnectionClosed";
|
|
44305
|
+
Object.setPrototypeOf(this, _ConnectionClosed.prototype);
|
|
44306
|
+
this.code = code;
|
|
44307
|
+
this.reason = reason;
|
|
44308
|
+
}
|
|
44309
|
+
};
|
|
44310
|
+
var ErrorResponse = class _ErrorResponse extends Error {
|
|
44311
|
+
response;
|
|
44312
|
+
constructor(response) {
|
|
44313
|
+
super(`Request ${response.requestId} failed with code ${response.code}: ${response.message}`);
|
|
44314
|
+
this.name = "ErrorResponse";
|
|
44315
|
+
Object.setPrototypeOf(this, _ErrorResponse.prototype);
|
|
44316
|
+
this.response = response;
|
|
44317
|
+
}
|
|
44318
|
+
};
|
|
44319
|
+
var StreamError = class _StreamError extends Error {
|
|
44320
|
+
streamId;
|
|
44321
|
+
errorCode;
|
|
44322
|
+
errorMessage;
|
|
44323
|
+
constructor(packet) {
|
|
44324
|
+
const code = packet.errorCode ?? 0;
|
|
44325
|
+
const message = packet.errorMessage ?? "";
|
|
44326
|
+
super(`Stream ${packet.id} ended with error code ${code}: ${message}`);
|
|
44327
|
+
this.name = "StreamError";
|
|
44328
|
+
Object.setPrototypeOf(this, _StreamError.prototype);
|
|
44329
|
+
this.streamId = packet.id;
|
|
44330
|
+
this.errorCode = code;
|
|
44331
|
+
this.errorMessage = message;
|
|
44332
|
+
}
|
|
44333
|
+
};
|
|
44334
|
+
var encoder = new Encoder({ useBigInt64: true });
|
|
44335
|
+
var decoder = new Decoder({ useBigInt64: true });
|
|
44336
|
+
var V1Client = class _V1Client {
|
|
44337
|
+
socket;
|
|
44338
|
+
nextId = 0;
|
|
44339
|
+
_closed = false;
|
|
44340
|
+
_closing = false;
|
|
44341
|
+
pending = /* @__PURE__ */ new Map();
|
|
44342
|
+
streams = /* @__PURE__ */ new Map();
|
|
44343
|
+
streamStopping = /* @__PURE__ */ new Map();
|
|
44344
|
+
closeListeners = [];
|
|
44345
|
+
// --- Static connect ---
|
|
44346
|
+
static connect(url) {
|
|
44347
|
+
return new Promise((resolve, reject) => {
|
|
44348
|
+
const ws = new WebSocket(url, [SUBPROTOCOL]);
|
|
44349
|
+
ws.binaryType = "arraybuffer";
|
|
44350
|
+
const onOpen = () => {
|
|
44351
|
+
ws.off("error", onError);
|
|
44352
|
+
ws.off("close", onClose);
|
|
44353
|
+
resolve(new _V1Client(ws));
|
|
44354
|
+
};
|
|
44355
|
+
const onError = (err) => {
|
|
44356
|
+
ws.off("open", onOpen);
|
|
44357
|
+
ws.off("close", onClose);
|
|
44358
|
+
reject(err);
|
|
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);
|
|
44372
|
+
});
|
|
44373
|
+
}
|
|
44374
|
+
// --- Constructor ---
|
|
44375
|
+
constructor(socket) {
|
|
44376
|
+
this.socket = socket;
|
|
44377
|
+
this.socket.on("message", (data) => {
|
|
44378
|
+
this.handleMessage(data);
|
|
44379
|
+
});
|
|
44380
|
+
this.socket.on("close", (code, reason) => {
|
|
44381
|
+
this.handleClose(code, reason.toString());
|
|
44382
|
+
});
|
|
44383
|
+
this.socket.on("error", (err) => {
|
|
44384
|
+
this.handleError(err);
|
|
44385
|
+
});
|
|
44386
|
+
}
|
|
44387
|
+
nextRequestId() {
|
|
44388
|
+
return this.nextId++;
|
|
44389
|
+
}
|
|
44390
|
+
// --- Public API ---
|
|
44391
|
+
get closed() {
|
|
44392
|
+
return this._closed;
|
|
44393
|
+
}
|
|
44394
|
+
close() {
|
|
44395
|
+
if (this._closed) return Promise.resolve();
|
|
44396
|
+
return new Promise((resolve, reject) => {
|
|
44397
|
+
this.closeListeners.push({ resolve, reject });
|
|
44398
|
+
if (!this._closing) {
|
|
44399
|
+
this._closing = true;
|
|
44400
|
+
this.socket.close();
|
|
44401
|
+
}
|
|
44402
|
+
});
|
|
44403
|
+
}
|
|
44404
|
+
newSwapQuoteStream(params) {
|
|
44405
|
+
const requestId = this.nextRequestId();
|
|
44406
|
+
const promise = new Promise(
|
|
44407
|
+
(resolve, reject) => {
|
|
44408
|
+
this.pending.set(requestId, {
|
|
44409
|
+
resolve,
|
|
44410
|
+
reject,
|
|
44411
|
+
kind: "NewSwapQuoteStream"
|
|
44412
|
+
});
|
|
44413
|
+
}
|
|
44414
|
+
);
|
|
44415
|
+
const normalized = {
|
|
44416
|
+
...params,
|
|
44417
|
+
swap: { ...params.swap, amount: toBigInt(params.swap.amount) }
|
|
44418
|
+
};
|
|
44419
|
+
const message = {
|
|
44420
|
+
id: requestId,
|
|
44421
|
+
data: { NewSwapQuoteStream: normalized }
|
|
44422
|
+
};
|
|
44423
|
+
this.send(message);
|
|
44424
|
+
return promise;
|
|
44425
|
+
}
|
|
44426
|
+
stopStream(streamId) {
|
|
44427
|
+
const requestId = this.nextRequestId();
|
|
44428
|
+
const promise = new Promise((resolve, reject) => {
|
|
44429
|
+
this.pending.set(requestId, {
|
|
44430
|
+
resolve,
|
|
44431
|
+
reject,
|
|
44432
|
+
kind: "StopStream"
|
|
44433
|
+
});
|
|
44434
|
+
});
|
|
44435
|
+
const message = {
|
|
44436
|
+
id: requestId,
|
|
44437
|
+
data: { StopStream: { id: streamId } }
|
|
44438
|
+
};
|
|
44439
|
+
this.send(message);
|
|
44440
|
+
return promise;
|
|
44441
|
+
}
|
|
44442
|
+
// --- Send ---
|
|
44443
|
+
send(message) {
|
|
44444
|
+
try {
|
|
44445
|
+
const encoded = encoder.encode(message);
|
|
44446
|
+
this.socket.send(encoded);
|
|
44447
|
+
} catch (err) {
|
|
44448
|
+
const req = this.pending.get(message.id);
|
|
44449
|
+
if (req) {
|
|
44450
|
+
this.pending.delete(message.id);
|
|
44451
|
+
req.reject(err);
|
|
44452
|
+
}
|
|
44453
|
+
}
|
|
44454
|
+
}
|
|
44455
|
+
// --- Message handling ---
|
|
44456
|
+
handleMessage(raw) {
|
|
44457
|
+
let buf;
|
|
44458
|
+
if (raw instanceof ArrayBuffer) {
|
|
44459
|
+
buf = new Uint8Array(raw);
|
|
44460
|
+
} else if (Buffer.isBuffer(raw)) {
|
|
44461
|
+
buf = new Uint8Array(raw.buffer, raw.byteOffset, raw.byteLength);
|
|
44462
|
+
} else if (Array.isArray(raw)) {
|
|
44463
|
+
buf = new Uint8Array(Buffer.concat(raw));
|
|
44464
|
+
} else {
|
|
44465
|
+
return;
|
|
44466
|
+
}
|
|
44467
|
+
let message;
|
|
44468
|
+
try {
|
|
44469
|
+
message = decoder.decode(buf);
|
|
44470
|
+
} catch {
|
|
44471
|
+
this.socket.close(3002, "failed to decode message");
|
|
44472
|
+
return;
|
|
44473
|
+
}
|
|
44474
|
+
if ("Response" in message) {
|
|
44475
|
+
this.handleResponse(message.Response);
|
|
44476
|
+
} else if ("Error" in message) {
|
|
44477
|
+
this.handleResponseError(message.Error);
|
|
44478
|
+
} else if ("StreamData" in message) {
|
|
44479
|
+
this.handleStreamData(message.StreamData);
|
|
44480
|
+
} else if ("StreamEnd" in message) {
|
|
44481
|
+
this.handleStreamEnd(message.StreamEnd);
|
|
44482
|
+
}
|
|
44483
|
+
}
|
|
44484
|
+
handleResponse(msg) {
|
|
44485
|
+
const req = this.pending.get(msg.requestId);
|
|
44486
|
+
if (!req) return;
|
|
44487
|
+
this.pending.delete(msg.requestId);
|
|
44488
|
+
if ("NewSwapQuoteStream" in msg.data && req.kind === "NewSwapQuoteStream") {
|
|
44489
|
+
const streamInfo = msg.stream;
|
|
44490
|
+
if (!streamInfo) {
|
|
44491
|
+
req.reject(new Error("No stream associated with NewSwapQuoteStream response"));
|
|
44492
|
+
return;
|
|
44493
|
+
}
|
|
44494
|
+
const stream = new ReadableStream({
|
|
44495
|
+
start: (controller) => {
|
|
44496
|
+
this.streams.set(streamInfo.id, controller);
|
|
44497
|
+
},
|
|
44498
|
+
cancel: () => {
|
|
44499
|
+
return this.cancelStream(streamInfo.id);
|
|
44500
|
+
}
|
|
44501
|
+
});
|
|
44502
|
+
const result = {
|
|
44503
|
+
response: msg.data.NewSwapQuoteStream,
|
|
44504
|
+
stream,
|
|
44505
|
+
streamId: streamInfo.id
|
|
44506
|
+
};
|
|
44507
|
+
req.resolve(result);
|
|
44508
|
+
} else if ("StreamStopped" in msg.data && req.kind === "StopStream") {
|
|
44509
|
+
req.resolve(msg.data.StreamStopped);
|
|
44510
|
+
} else {
|
|
44511
|
+
req.reject(new Error(`Unexpected response type for ${req.kind}`));
|
|
44512
|
+
}
|
|
44513
|
+
}
|
|
44514
|
+
handleResponseError(error) {
|
|
44515
|
+
const req = this.pending.get(error.requestId);
|
|
44516
|
+
if (!req) return;
|
|
44517
|
+
this.pending.delete(error.requestId);
|
|
44518
|
+
req.reject(new ErrorResponse(error));
|
|
44519
|
+
}
|
|
44520
|
+
handleStreamData(packet) {
|
|
44521
|
+
const controller = this.streams.get(packet.id);
|
|
44522
|
+
if (!controller) return;
|
|
44523
|
+
if (packet.payload.SwapQuotes !== void 0) {
|
|
44524
|
+
controller.enqueue(packet.payload.SwapQuotes);
|
|
44525
|
+
}
|
|
44526
|
+
}
|
|
44527
|
+
handleStreamEnd(packet) {
|
|
44528
|
+
const controller = this.streams.get(packet.id);
|
|
44529
|
+
if (!controller) return;
|
|
44530
|
+
this.streams.delete(packet.id);
|
|
44531
|
+
this.streamStopping.delete(packet.id);
|
|
44532
|
+
if (packet.errorCode !== void 0) {
|
|
44533
|
+
controller.error(new StreamError(packet));
|
|
44534
|
+
} else {
|
|
44535
|
+
controller.close();
|
|
44536
|
+
}
|
|
44537
|
+
}
|
|
44538
|
+
async cancelStream(streamId) {
|
|
44539
|
+
if (this.streamStopping.get(streamId) || !this.streams.has(streamId)) return;
|
|
44540
|
+
this.streamStopping.set(streamId, true);
|
|
44541
|
+
await this.stopStream(streamId);
|
|
44542
|
+
}
|
|
44543
|
+
// --- Connection lifecycle ---
|
|
44544
|
+
rejectAll(error) {
|
|
44545
|
+
for (const req of this.pending.values()) {
|
|
44546
|
+
req.reject(error);
|
|
44547
|
+
}
|
|
44548
|
+
this.pending.clear();
|
|
44549
|
+
for (const controller of this.streams.values()) {
|
|
44550
|
+
controller.error(error);
|
|
44551
|
+
}
|
|
44552
|
+
this.streams.clear();
|
|
44553
|
+
this.streamStopping.clear();
|
|
44554
|
+
}
|
|
44555
|
+
handleClose(code, reason) {
|
|
44556
|
+
this._closed = true;
|
|
44557
|
+
this.rejectAll(new ConnectionClosed(code, reason));
|
|
44558
|
+
for (const listener of this.closeListeners) {
|
|
44559
|
+
listener.resolve();
|
|
44560
|
+
}
|
|
44561
|
+
this.closeListeners = [];
|
|
44562
|
+
}
|
|
44563
|
+
handleError(err) {
|
|
44564
|
+
this.rejectAll(err);
|
|
44565
|
+
this.socket.close(3002);
|
|
44566
|
+
}
|
|
44567
|
+
};
|
|
44568
|
+
function deserializeSerializedInstruction(ix) {
|
|
44569
|
+
return new TransactionInstruction({
|
|
44570
|
+
programId: new PublicKey(Buffer.from(ix.p, "base64")),
|
|
44571
|
+
keys: ix.a.map((account) => ({
|
|
44572
|
+
pubkey: new PublicKey(Buffer.from(account.p, "base64")),
|
|
44573
|
+
isSigner: account.s,
|
|
44574
|
+
isWritable: account.w
|
|
44575
|
+
})),
|
|
44576
|
+
data: Buffer.from(ix.d, "base64")
|
|
44577
|
+
});
|
|
44578
|
+
}
|
|
44579
|
+
function selectBestRoute(quotes, swapMode) {
|
|
44580
|
+
const routes = Object.values(quotes);
|
|
44581
|
+
if (routes.length === 0) return null;
|
|
44582
|
+
return routes.reduce((best, route) => {
|
|
44583
|
+
if (swapMode === "ExactIn") {
|
|
44584
|
+
return route.outAmount > best.outAmount ? route : best;
|
|
44585
|
+
} else {
|
|
44586
|
+
return route.inAmount < best.inAmount ? route : best;
|
|
44587
|
+
}
|
|
44588
|
+
});
|
|
44589
|
+
}
|
|
44590
|
+
function buildSwapQuoteResult(route, swapMode) {
|
|
44591
|
+
const slippageBps = route.slippageBps;
|
|
44592
|
+
let otherAmountThreshold;
|
|
44593
|
+
if (swapMode === "ExactIn") {
|
|
44594
|
+
otherAmountThreshold = String(Math.floor(route.outAmount * (1 - slippageBps / 1e4)));
|
|
44595
|
+
} else {
|
|
44596
|
+
otherAmountThreshold = String(Math.ceil(route.inAmount * (1 + slippageBps / 1e4)));
|
|
44597
|
+
}
|
|
44598
|
+
return {
|
|
44599
|
+
inAmount: String(route.inAmount),
|
|
44600
|
+
outAmount: String(route.outAmount),
|
|
44601
|
+
otherAmountThreshold,
|
|
44602
|
+
slippageBps,
|
|
44603
|
+
platformFee: route.platformFee ? {
|
|
44604
|
+
amount: String(route.platformFee.amount),
|
|
44605
|
+
feeBps: route.platformFee.fee_bps
|
|
44606
|
+
} : void 0,
|
|
44607
|
+
contextSlot: route.contextSlot,
|
|
44608
|
+
timeTaken: route.timeTaken
|
|
44609
|
+
};
|
|
44610
|
+
}
|
|
44611
|
+
async function resolveLookupTables(connection, lutPubkeys) {
|
|
44612
|
+
if (lutPubkeys.length === 0) return [];
|
|
44613
|
+
const lutAccountsRaw = await connection.getMultipleAccountsInfo(lutPubkeys);
|
|
44614
|
+
return lutAccountsRaw.map((accountInfo, index) => {
|
|
44615
|
+
if (!accountInfo) return null;
|
|
44616
|
+
return new AddressLookupTableAccount({
|
|
44617
|
+
key: lutPubkeys[index],
|
|
44618
|
+
state: AddressLookupTableAccount.deserialize(accountInfo.data)
|
|
44619
|
+
});
|
|
44620
|
+
}).filter((account) => account !== null);
|
|
44621
|
+
}
|
|
44171
44622
|
|
|
44172
44623
|
// src/vendor/klend/utils/klend/interest-rate.utils.ts
|
|
44173
44624
|
function getKaminoTotalSupply(reserve) {
|
|
@@ -46689,18 +47140,18 @@ async function buildLoopFlashloanTx({
|
|
|
46689
47140
|
overrideInferAccounts,
|
|
46690
47141
|
blockhash
|
|
46691
47142
|
}) {
|
|
46692
|
-
const swapResult = [];
|
|
46693
47143
|
const cuRequestIxs = [
|
|
46694
47144
|
ComputeBudgetProgram.setComputeUnitLimit({ units: 12e5 }),
|
|
46695
47145
|
ComputeBudgetProgram.setComputeUnitPrice({ microLamports: 1 })
|
|
46696
47146
|
];
|
|
47147
|
+
let amountToDeposit;
|
|
47148
|
+
let swapInstructions = [];
|
|
47149
|
+
let setupInstructions = [];
|
|
47150
|
+
let swapLookupTables = [];
|
|
47151
|
+
let swapQuote;
|
|
47152
|
+
let sizeConstraintUsed = 0;
|
|
46697
47153
|
if (depositOpts.depositBank.mint.equals(borrowOpts.borrowBank.mint)) {
|
|
46698
|
-
|
|
46699
|
-
amountToDeposit: borrowOpts.borrowAmount + (depositOpts.loopMode === "DEPOSIT" ? depositOpts.inputDepositAmount : 0),
|
|
46700
|
-
swapInstructions: [],
|
|
46701
|
-
setupInstructions: [],
|
|
46702
|
-
swapLookupTables: []
|
|
46703
|
-
});
|
|
47154
|
+
amountToDeposit = borrowOpts.borrowAmount + (depositOpts.loopMode === "DEPOSIT" ? depositOpts.inputDepositAmount : 0);
|
|
46704
47155
|
} else {
|
|
46705
47156
|
const destinationTokenAccount = getAssociatedTokenAddressSync(
|
|
46706
47157
|
new PublicKey(depositOpts.depositBank.mint),
|
|
@@ -46708,36 +47159,46 @@ async function buildLoopFlashloanTx({
|
|
|
46708
47159
|
true,
|
|
46709
47160
|
depositOpts.tokenProgram.equals(TOKEN_2022_PROGRAM_ID) ? TOKEN_2022_PROGRAM_ID : void 0
|
|
46710
47161
|
);
|
|
46711
|
-
const
|
|
46712
|
-
|
|
46713
|
-
|
|
46714
|
-
|
|
46715
|
-
|
|
46716
|
-
|
|
46717
|
-
|
|
46718
|
-
|
|
46719
|
-
|
|
46720
|
-
|
|
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
|
|
46721
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",
|
|
46722
47185
|
authority: marginfiAccount.authority,
|
|
46723
47186
|
connection,
|
|
46724
47187
|
destinationTokenAccount,
|
|
46725
|
-
|
|
46726
|
-
|
|
46727
|
-
|
|
46728
|
-
const outAmountThreshold = nativeToUi(
|
|
46729
|
-
response.quoteResponse.otherAmountThreshold,
|
|
46730
|
-
depositOpts.depositBank.mintDecimals
|
|
46731
|
-
);
|
|
46732
|
-
const amountToDeposit = outAmountThreshold + (depositOpts.loopMode === "DEPOSIT" ? depositOpts.inputDepositAmount : 0);
|
|
46733
|
-
swapResult.push({
|
|
46734
|
-
amountToDeposit,
|
|
46735
|
-
swapInstructions: [response.swapInstruction],
|
|
46736
|
-
setupInstructions: response.setupInstructions,
|
|
46737
|
-
swapLookupTables: response.addressLookupTableAddresses,
|
|
46738
|
-
quoteResponse: response.quoteResponse
|
|
46739
|
-
});
|
|
47188
|
+
swapOpts,
|
|
47189
|
+
sizeConstraint: swapConstraints.sizeConstraint,
|
|
47190
|
+
maxSwapTotalAccounts: swapConstraints.maxSwapTotalAccounts
|
|
46740
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;
|
|
46741
47202
|
}
|
|
46742
47203
|
const borrowIxs = await makeBorrowIx3({
|
|
46743
47204
|
program,
|
|
@@ -46754,140 +47215,136 @@ async function buildLoopFlashloanTx({
|
|
|
46754
47215
|
overrideInferAccounts
|
|
46755
47216
|
}
|
|
46756
47217
|
});
|
|
46757
|
-
|
|
46758
|
-
|
|
46759
|
-
|
|
46760
|
-
|
|
46761
|
-
|
|
46762
|
-
|
|
46763
|
-
|
|
46764
|
-
|
|
46765
|
-
|
|
46766
|
-
|
|
46767
|
-
case 3 /* KAMINO */: {
|
|
46768
|
-
const reserve = bankMetadataMap[depositOpts.depositBank.address.toBase58()]?.kaminoStates?.reserveState;
|
|
46769
|
-
if (!reserve) {
|
|
46770
|
-
throw TransactionBuildingError.kaminoReserveNotFound(
|
|
46771
|
-
depositOpts.depositBank.address.toBase58(),
|
|
46772
|
-
depositOpts.depositBank.mint.toBase58(),
|
|
46773
|
-
depositOpts.depositBank.tokenSymbol
|
|
46774
|
-
);
|
|
46775
|
-
}
|
|
46776
|
-
depositIxs = await makeKaminoDepositIx3({
|
|
46777
|
-
program,
|
|
46778
|
-
bank: depositOpts.depositBank,
|
|
46779
|
-
tokenProgram: depositOpts.tokenProgram,
|
|
46780
|
-
amount: amountToDeposit,
|
|
46781
|
-
accountAddress: marginfiAccount.address,
|
|
46782
|
-
authority: marginfiAccount.authority,
|
|
46783
|
-
group: marginfiAccount.group,
|
|
46784
|
-
reserve,
|
|
46785
|
-
opts: {
|
|
46786
|
-
wrapAndUnwrapSol: false,
|
|
46787
|
-
overrideInferAccounts
|
|
46788
|
-
}
|
|
46789
|
-
});
|
|
46790
|
-
break;
|
|
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
|
+
);
|
|
46791
47228
|
}
|
|
46792
|
-
|
|
46793
|
-
|
|
46794
|
-
|
|
46795
|
-
|
|
46796
|
-
|
|
46797
|
-
|
|
46798
|
-
|
|
46799
|
-
|
|
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
|
|
46800
47241
|
}
|
|
46801
|
-
|
|
46802
|
-
|
|
46803
|
-
depositIxs = await makeDriftDepositIx3({
|
|
46804
|
-
program,
|
|
46805
|
-
bank: depositOpts.depositBank,
|
|
46806
|
-
tokenProgram: depositOpts.tokenProgram,
|
|
46807
|
-
amount: amountToDeposit,
|
|
46808
|
-
accountAddress: marginfiAccount.address,
|
|
46809
|
-
authority: marginfiAccount.authority,
|
|
46810
|
-
group: marginfiAccount.group,
|
|
46811
|
-
driftMarketIndex,
|
|
46812
|
-
driftOracle,
|
|
46813
|
-
opts: {
|
|
46814
|
-
wrapAndUnwrapSol: false,
|
|
46815
|
-
overrideInferAccounts
|
|
46816
|
-
}
|
|
46817
|
-
});
|
|
46818
|
-
break;
|
|
46819
|
-
}
|
|
46820
|
-
case 6 /* JUPLEND */: {
|
|
46821
|
-
depositIxs = await makeJuplendDepositIx2({
|
|
46822
|
-
program,
|
|
46823
|
-
bank: depositOpts.depositBank,
|
|
46824
|
-
tokenProgram: depositOpts.tokenProgram,
|
|
46825
|
-
amount: amountToDeposit,
|
|
46826
|
-
accountAddress: marginfiAccount.address,
|
|
46827
|
-
authority: marginfiAccount.authority,
|
|
46828
|
-
group: marginfiAccount.group,
|
|
46829
|
-
opts: {
|
|
46830
|
-
wrapAndUnwrapSol: false,
|
|
46831
|
-
overrideInferAccounts
|
|
46832
|
-
}
|
|
46833
|
-
});
|
|
46834
|
-
break;
|
|
46835
|
-
}
|
|
46836
|
-
default: {
|
|
46837
|
-
depositIxs = await makeDepositIx3({
|
|
46838
|
-
program,
|
|
46839
|
-
bank: depositOpts.depositBank,
|
|
46840
|
-
tokenProgram: depositOpts.tokenProgram,
|
|
46841
|
-
amount: amountToDeposit,
|
|
46842
|
-
accountAddress: marginfiAccount.address,
|
|
46843
|
-
authority: marginfiAccount.authority,
|
|
46844
|
-
group: marginfiAccount.group,
|
|
46845
|
-
opts: {
|
|
46846
|
-
wrapAndUnwrapSol: false,
|
|
46847
|
-
overrideInferAccounts
|
|
46848
|
-
}
|
|
46849
|
-
});
|
|
46850
|
-
break;
|
|
46851
|
-
}
|
|
47242
|
+
});
|
|
47243
|
+
break;
|
|
46852
47244
|
}
|
|
46853
|
-
|
|
46854
|
-
|
|
46855
|
-
|
|
46856
|
-
|
|
46857
|
-
|
|
46858
|
-
|
|
46859
|
-
|
|
46860
|
-
|
|
46861
|
-
const flashloanTx = await makeFlashLoanTx({
|
|
46862
|
-
...flashloanParams,
|
|
46863
|
-
ixs: [
|
|
46864
|
-
...cuRequestIxs,
|
|
46865
|
-
...borrowIxs.instructions,
|
|
46866
|
-
...swapInstructions,
|
|
46867
|
-
...depositIxs.instructions
|
|
46868
|
-
]
|
|
46869
|
-
});
|
|
46870
|
-
const txSize = getTxSize(flashloanTx);
|
|
46871
|
-
const keySize = getAccountKeys(flashloanTx, luts);
|
|
46872
|
-
const isLast = index === swapResult.length - 1;
|
|
46873
|
-
if (txSize > MAX_TX_SIZE || keySize > 64) {
|
|
46874
|
-
if (isLast) {
|
|
46875
|
-
throw TransactionBuildingError.jupiterSwapSizeExceededLoop(txSize, keySize);
|
|
46876
|
-
} else {
|
|
46877
|
-
continue;
|
|
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
|
+
);
|
|
46878
47253
|
}
|
|
46879
|
-
|
|
46880
|
-
|
|
46881
|
-
|
|
46882
|
-
|
|
46883
|
-
|
|
46884
|
-
|
|
46885
|
-
|
|
46886
|
-
|
|
46887
|
-
|
|
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;
|
|
46888
47304
|
}
|
|
46889
47305
|
}
|
|
46890
|
-
|
|
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
|
+
};
|
|
46891
47348
|
}
|
|
46892
47349
|
async function makeRepayIx3({
|
|
46893
47350
|
program,
|
|
@@ -47077,18 +47534,18 @@ async function buildRepayWithCollatFlashloanTx({
|
|
|
47077
47534
|
overrideInferAccounts,
|
|
47078
47535
|
blockhash
|
|
47079
47536
|
}) {
|
|
47080
|
-
const swapResult = [];
|
|
47081
47537
|
const cuRequestIxs = [
|
|
47082
47538
|
ComputeBudgetProgram.setComputeUnitLimit({ units: 12e5 }),
|
|
47083
47539
|
ComputeBudgetProgram.setComputeUnitPrice({ microLamports: 1 })
|
|
47084
47540
|
];
|
|
47541
|
+
let amountToRepay;
|
|
47542
|
+
let swapInstructions = [];
|
|
47543
|
+
let setupInstructions = [];
|
|
47544
|
+
let swapLookupTables = [];
|
|
47545
|
+
let swapQuote;
|
|
47546
|
+
let sizeConstraintUsed = 0;
|
|
47085
47547
|
if (repayOpts.repayBank.mint.equals(withdrawOpts.withdrawBank.mint)) {
|
|
47086
|
-
|
|
47087
|
-
amountToRepay: withdrawOpts.withdrawAmount,
|
|
47088
|
-
swapInstructions: [],
|
|
47089
|
-
setupInstructions: [],
|
|
47090
|
-
swapLookupTables: []
|
|
47091
|
-
});
|
|
47548
|
+
amountToRepay = withdrawOpts.withdrawAmount;
|
|
47092
47549
|
} else {
|
|
47093
47550
|
const destinationTokenAccount = getAssociatedTokenAddressSync(
|
|
47094
47551
|
new PublicKey(repayOpts.repayBank.mint),
|
|
@@ -47096,41 +47553,50 @@ async function buildRepayWithCollatFlashloanTx({
|
|
|
47096
47553
|
true,
|
|
47097
47554
|
repayOpts.tokenProgram.equals(TOKEN_2022_PROGRAM_ID) ? TOKEN_2022_PROGRAM_ID : void 0
|
|
47098
47555
|
);
|
|
47099
|
-
const
|
|
47100
|
-
|
|
47101
|
-
|
|
47102
|
-
|
|
47103
|
-
|
|
47104
|
-
|
|
47105
|
-
|
|
47106
|
-
|
|
47107
|
-
|
|
47108
|
-
|
|
47109
|
-
|
|
47110
|
-
|
|
47111
|
-
|
|
47556
|
+
const swapConstraints = await computeFlashloanSwapConstraints({
|
|
47557
|
+
program,
|
|
47558
|
+
marginfiAccount,
|
|
47559
|
+
bankMap,
|
|
47560
|
+
bankMetadataMap,
|
|
47561
|
+
addressLookupTableAccounts: addressLookupTableAccounts ?? [],
|
|
47562
|
+
primaryIx: {
|
|
47563
|
+
type: "withdraw",
|
|
47564
|
+
bank: withdrawOpts.withdrawBank,
|
|
47565
|
+
tokenProgram: withdrawOpts.tokenProgram
|
|
47566
|
+
},
|
|
47567
|
+
secondaryIx: {
|
|
47568
|
+
type: "repay",
|
|
47569
|
+
bank: repayOpts.repayBank,
|
|
47570
|
+
tokenProgram: repayOpts.tokenProgram
|
|
47112
47571
|
},
|
|
47572
|
+
overrideInferAccounts
|
|
47573
|
+
});
|
|
47574
|
+
const swapResponse = await getSwapIxsForFlashloan({
|
|
47575
|
+
inputMint: withdrawOpts.withdrawBank.mint.toBase58(),
|
|
47576
|
+
outputMint: repayOpts.repayBank.mint.toBase58(),
|
|
47577
|
+
amount: uiToNative(
|
|
47578
|
+
withdrawOpts.withdrawAmount,
|
|
47579
|
+
withdrawOpts.withdrawBank.mintDecimals
|
|
47580
|
+
).toNumber(),
|
|
47581
|
+
swapMode: "ExactIn",
|
|
47113
47582
|
authority: marginfiAccount.authority,
|
|
47114
47583
|
connection,
|
|
47115
47584
|
destinationTokenAccount,
|
|
47116
|
-
|
|
47117
|
-
|
|
47118
|
-
|
|
47119
|
-
const { swapInstruction, addressLookupTableAddresses, quoteResponse } = response;
|
|
47120
|
-
const outAmount = nativeToUi(quoteResponse.outAmount, repayOpts.repayBank.mintDecimals);
|
|
47121
|
-
const outAmountThreshold = nativeToUi(
|
|
47122
|
-
quoteResponse.otherAmountThreshold,
|
|
47123
|
-
repayOpts.repayBank.mintDecimals
|
|
47124
|
-
);
|
|
47125
|
-
const amountToRepay = outAmount > repayOpts.totalPositionAmount ? repayOpts.totalPositionAmount : outAmountThreshold;
|
|
47126
|
-
swapResult.push({
|
|
47127
|
-
amountToRepay,
|
|
47128
|
-
swapInstructions: [swapInstruction],
|
|
47129
|
-
setupInstructions: [],
|
|
47130
|
-
swapLookupTables: addressLookupTableAddresses,
|
|
47131
|
-
quoteResponse
|
|
47132
|
-
});
|
|
47585
|
+
swapOpts,
|
|
47586
|
+
sizeConstraint: swapConstraints.sizeConstraint,
|
|
47587
|
+
maxSwapTotalAccounts: swapConstraints.maxSwapTotalAccounts
|
|
47133
47588
|
});
|
|
47589
|
+
sizeConstraintUsed = swapConstraints.sizeConstraint;
|
|
47590
|
+
const { quoteResponse } = swapResponse;
|
|
47591
|
+
const outAmount = nativeToUi(quoteResponse.outAmount, repayOpts.repayBank.mintDecimals);
|
|
47592
|
+
const outAmountThreshold = nativeToUi(
|
|
47593
|
+
quoteResponse.otherAmountThreshold,
|
|
47594
|
+
repayOpts.repayBank.mintDecimals
|
|
47595
|
+
);
|
|
47596
|
+
amountToRepay = outAmount > repayOpts.totalPositionAmount ? repayOpts.totalPositionAmount : outAmountThreshold;
|
|
47597
|
+
swapInstructions = swapResponse.swapInstructions;
|
|
47598
|
+
swapLookupTables = swapResponse.addressLookupTableAddresses;
|
|
47599
|
+
swapQuote = quoteResponse;
|
|
47134
47600
|
}
|
|
47135
47601
|
let withdrawIxs;
|
|
47136
47602
|
switch (withdrawOpts.withdrawBank.config.assetTag) {
|
|
@@ -47268,68 +47734,70 @@ async function buildRepayWithCollatFlashloanTx({
|
|
|
47268
47734
|
break;
|
|
47269
47735
|
}
|
|
47270
47736
|
}
|
|
47271
|
-
|
|
47272
|
-
|
|
47273
|
-
|
|
47274
|
-
|
|
47275
|
-
|
|
47276
|
-
|
|
47277
|
-
|
|
47278
|
-
|
|
47279
|
-
|
|
47280
|
-
|
|
47281
|
-
|
|
47282
|
-
|
|
47283
|
-
|
|
47284
|
-
|
|
47285
|
-
|
|
47286
|
-
|
|
47287
|
-
|
|
47288
|
-
|
|
47289
|
-
|
|
47290
|
-
wrapAndUnwrapSol: false,
|
|
47291
|
-
overrideInferAccounts
|
|
47292
|
-
}
|
|
47293
|
-
});
|
|
47294
|
-
const luts = [...addressLookupTableAccounts ?? [], ...swapLookupTables];
|
|
47295
|
-
const flashloanParams = {
|
|
47296
|
-
program,
|
|
47297
|
-
marginfiAccount,
|
|
47298
|
-
bankMap,
|
|
47299
|
-
addressLookupTableAccounts: luts,
|
|
47300
|
-
blockhash
|
|
47301
|
-
};
|
|
47302
|
-
const flashloanTx = await makeFlashLoanTx({
|
|
47303
|
-
...flashloanParams,
|
|
47304
|
-
ixs: [
|
|
47305
|
-
...cuRequestIxs,
|
|
47306
|
-
...withdrawIxs.instructions,
|
|
47307
|
-
...swapInstructions,
|
|
47308
|
-
...repayIxs.instructions
|
|
47309
|
-
],
|
|
47310
|
-
isSync: true
|
|
47311
|
-
});
|
|
47312
|
-
const txSize = getTxSize(flashloanTx);
|
|
47313
|
-
const keySize = getAccountKeys(flashloanTx, luts);
|
|
47314
|
-
const isLast = index === swapResult.length - 1;
|
|
47315
|
-
if (txSize > MAX_TX_SIZE || keySize > 64) {
|
|
47316
|
-
if (isLast) {
|
|
47317
|
-
throw TransactionBuildingError.jupiterSwapSizeExceededRepay(txSize, keySize);
|
|
47318
|
-
} else {
|
|
47319
|
-
continue;
|
|
47320
|
-
}
|
|
47321
|
-
} else {
|
|
47322
|
-
return {
|
|
47323
|
-
flashloanTx,
|
|
47324
|
-
setupInstructions,
|
|
47325
|
-
swapQuote: quoteResponse,
|
|
47326
|
-
withdrawIxs,
|
|
47327
|
-
repayIxs,
|
|
47328
|
-
amountToRepay
|
|
47329
|
-
};
|
|
47737
|
+
const repayIxs = await makeRepayIx3({
|
|
47738
|
+
program,
|
|
47739
|
+
bank: repayOpts.repayBank,
|
|
47740
|
+
tokenProgram: repayOpts.tokenProgram,
|
|
47741
|
+
amount: amountToRepay,
|
|
47742
|
+
accountAddress: marginfiAccount.address,
|
|
47743
|
+
authority: marginfiAccount.authority,
|
|
47744
|
+
repayAll: isWholePosition(
|
|
47745
|
+
{
|
|
47746
|
+
amount: repayOpts.totalPositionAmount,
|
|
47747
|
+
isLending: true
|
|
47748
|
+
},
|
|
47749
|
+
amountToRepay,
|
|
47750
|
+
repayOpts.repayBank.mintDecimals
|
|
47751
|
+
),
|
|
47752
|
+
isSync: false,
|
|
47753
|
+
opts: {
|
|
47754
|
+
wrapAndUnwrapSol: false,
|
|
47755
|
+
overrideInferAccounts
|
|
47330
47756
|
}
|
|
47757
|
+
});
|
|
47758
|
+
const luts = [...addressLookupTableAccounts ?? [], ...swapLookupTables];
|
|
47759
|
+
const allNonFlIxs = [
|
|
47760
|
+
...cuRequestIxs,
|
|
47761
|
+
...withdrawIxs.instructions,
|
|
47762
|
+
...swapInstructions,
|
|
47763
|
+
...repayIxs.instructions
|
|
47764
|
+
];
|
|
47765
|
+
if (swapInstructions.length > 0) {
|
|
47766
|
+
compileFlashloanPrecheck({
|
|
47767
|
+
allIxs: allNonFlIxs,
|
|
47768
|
+
payer: marginfiAccount.authority,
|
|
47769
|
+
luts,
|
|
47770
|
+
sizeConstraint: sizeConstraintUsed,
|
|
47771
|
+
swapIxCount: swapInstructions.length,
|
|
47772
|
+
swapLutCount: swapLookupTables.length
|
|
47773
|
+
});
|
|
47331
47774
|
}
|
|
47332
|
-
|
|
47775
|
+
const flashloanTx = await makeFlashLoanTx({
|
|
47776
|
+
program,
|
|
47777
|
+
marginfiAccount,
|
|
47778
|
+
bankMap,
|
|
47779
|
+
addressLookupTableAccounts: luts,
|
|
47780
|
+
blockhash,
|
|
47781
|
+
ixs: allNonFlIxs,
|
|
47782
|
+
isSync: true
|
|
47783
|
+
});
|
|
47784
|
+
const txSize = getTxSize(flashloanTx);
|
|
47785
|
+
const totalKeys = getTotalAccountKeys(flashloanTx);
|
|
47786
|
+
if (txSize > MAX_TX_SIZE || totalKeys > MAX_ACCOUNT_LOCKS) {
|
|
47787
|
+
throw TransactionBuildingError.swapSizeExceededRepay(
|
|
47788
|
+
txSize,
|
|
47789
|
+
totalKeys,
|
|
47790
|
+
swapOpts.swapConfig?.provider
|
|
47791
|
+
);
|
|
47792
|
+
}
|
|
47793
|
+
return {
|
|
47794
|
+
flashloanTx,
|
|
47795
|
+
setupInstructions,
|
|
47796
|
+
swapQuote,
|
|
47797
|
+
withdrawIxs,
|
|
47798
|
+
repayIxs,
|
|
47799
|
+
amountToRepay
|
|
47800
|
+
};
|
|
47333
47801
|
}
|
|
47334
47802
|
|
|
47335
47803
|
// src/services/account/actions/emissions.ts
|
|
@@ -47483,11 +47951,16 @@ async function buildSwapCollateralFlashloanTx({
|
|
|
47483
47951
|
actualWithdrawAmount,
|
|
47484
47952
|
withdrawBank.mintDecimals
|
|
47485
47953
|
);
|
|
47486
|
-
const swapResult = [];
|
|
47487
47954
|
const cuRequestIxs = [
|
|
47488
47955
|
ComputeBudgetProgram.setComputeUnitLimit({ units: 12e5 }),
|
|
47489
47956
|
ComputeBudgetProgram.setComputeUnitPrice({ microLamports: 1 })
|
|
47490
47957
|
];
|
|
47958
|
+
let amountToDeposit;
|
|
47959
|
+
let swapInstructions = [];
|
|
47960
|
+
let setupInstructions = [];
|
|
47961
|
+
let swapLookupTables = [];
|
|
47962
|
+
let swapQuote;
|
|
47963
|
+
let sizeConstraintUsed = 0;
|
|
47491
47964
|
let withdrawIxs;
|
|
47492
47965
|
switch (withdrawOpts.withdrawBank.config.assetTag) {
|
|
47493
47966
|
case 3 /* KAMINO */: {
|
|
@@ -47597,12 +48070,7 @@ async function buildSwapCollateralFlashloanTx({
|
|
|
47597
48070
|
}
|
|
47598
48071
|
}
|
|
47599
48072
|
if (depositBank.mint.equals(withdrawBank.mint)) {
|
|
47600
|
-
|
|
47601
|
-
amountToDeposit: actualWithdrawAmount,
|
|
47602
|
-
swapInstructions: [],
|
|
47603
|
-
setupInstructions: [],
|
|
47604
|
-
swapLookupTables: []
|
|
47605
|
-
});
|
|
48073
|
+
amountToDeposit = actualWithdrawAmount;
|
|
47606
48074
|
} else {
|
|
47607
48075
|
const destinationTokenAccount = getAssociatedTokenAddressSync(
|
|
47608
48076
|
depositBank.mint,
|
|
@@ -47610,175 +48078,168 @@ async function buildSwapCollateralFlashloanTx({
|
|
|
47610
48078
|
true,
|
|
47611
48079
|
depositTokenProgram.equals(TOKEN_2022_PROGRAM_ID) ? TOKEN_2022_PROGRAM_ID : void 0
|
|
47612
48080
|
);
|
|
47613
|
-
const
|
|
47614
|
-
|
|
47615
|
-
|
|
47616
|
-
|
|
47617
|
-
|
|
47618
|
-
|
|
47619
|
-
|
|
47620
|
-
|
|
47621
|
-
|
|
47622
|
-
|
|
47623
|
-
|
|
48081
|
+
const swapConstraints = await computeFlashloanSwapConstraints({
|
|
48082
|
+
program,
|
|
48083
|
+
marginfiAccount,
|
|
48084
|
+
bankMap,
|
|
48085
|
+
bankMetadataMap,
|
|
48086
|
+
addressLookupTableAccounts: addressLookupTableAccounts ?? [],
|
|
48087
|
+
primaryIx: { type: "withdraw", bank: withdrawBank, tokenProgram: withdrawTokenProgram },
|
|
48088
|
+
secondaryIx: { type: "deposit", bank: depositBank, tokenProgram: depositTokenProgram },
|
|
48089
|
+
overrideInferAccounts
|
|
48090
|
+
});
|
|
48091
|
+
const swapResponses = await getSwapIxsForFlashloan({
|
|
48092
|
+
inputMint: withdrawBank.mint.toBase58(),
|
|
48093
|
+
outputMint: depositBank.mint.toBase58(),
|
|
48094
|
+
amount: uiToNative(actualWithdrawAmount, withdrawBank.mintDecimals).toNumber(),
|
|
48095
|
+
swapMode: "ExactIn",
|
|
47624
48096
|
authority: marginfiAccount.authority,
|
|
47625
48097
|
connection,
|
|
47626
48098
|
destinationTokenAccount,
|
|
47627
|
-
|
|
47628
|
-
|
|
47629
|
-
|
|
47630
|
-
const outAmountThreshold = nativeToUi(
|
|
47631
|
-
response.quoteResponse.otherAmountThreshold,
|
|
47632
|
-
depositBank.mintDecimals
|
|
47633
|
-
);
|
|
47634
|
-
swapResult.push({
|
|
47635
|
-
amountToDeposit: outAmountThreshold,
|
|
47636
|
-
swapInstructions: [response.swapInstruction],
|
|
47637
|
-
setupInstructions: response.setupInstructions,
|
|
47638
|
-
swapLookupTables: response.addressLookupTableAddresses,
|
|
47639
|
-
quoteResponse: response.quoteResponse
|
|
47640
|
-
});
|
|
48099
|
+
swapOpts,
|
|
48100
|
+
sizeConstraint: swapConstraints.sizeConstraint,
|
|
48101
|
+
maxSwapTotalAccounts: swapConstraints.maxSwapTotalAccounts
|
|
47641
48102
|
});
|
|
47642
|
-
|
|
47643
|
-
|
|
47644
|
-
|
|
47645
|
-
|
|
48103
|
+
sizeConstraintUsed = swapConstraints.sizeConstraint;
|
|
48104
|
+
amountToDeposit = nativeToUi(
|
|
48105
|
+
swapResponses.quoteResponse.otherAmountThreshold,
|
|
48106
|
+
depositBank.mintDecimals
|
|
47646
48107
|
);
|
|
48108
|
+
swapInstructions = swapResponses.swapInstructions;
|
|
48109
|
+
setupInstructions = swapResponses.setupInstructions;
|
|
48110
|
+
swapLookupTables = swapResponses.addressLookupTableAddresses;
|
|
48111
|
+
swapQuote = swapResponses.quoteResponse;
|
|
47647
48112
|
}
|
|
47648
|
-
|
|
47649
|
-
|
|
47650
|
-
|
|
47651
|
-
|
|
47652
|
-
|
|
47653
|
-
|
|
47654
|
-
|
|
47655
|
-
|
|
47656
|
-
|
|
47657
|
-
|
|
47658
|
-
case 3 /* KAMINO */: {
|
|
47659
|
-
const reserve = bankMetadataMap[depositBank.address.toBase58()]?.kaminoStates?.reserveState;
|
|
47660
|
-
if (!reserve) {
|
|
47661
|
-
throw TransactionBuildingError.kaminoReserveNotFound(
|
|
47662
|
-
depositBank.address.toBase58(),
|
|
47663
|
-
depositBank.mint.toBase58(),
|
|
47664
|
-
depositBank.tokenSymbol
|
|
47665
|
-
);
|
|
47666
|
-
}
|
|
47667
|
-
depositIxs = await makeKaminoDepositIx3({
|
|
47668
|
-
program,
|
|
47669
|
-
bank: depositBank,
|
|
47670
|
-
tokenProgram: depositTokenProgram,
|
|
47671
|
-
amount: amountToDeposit,
|
|
47672
|
-
accountAddress: marginfiAccount.address,
|
|
47673
|
-
authority: marginfiAccount.authority,
|
|
47674
|
-
group: marginfiAccount.group,
|
|
47675
|
-
reserve,
|
|
47676
|
-
opts: {
|
|
47677
|
-
wrapAndUnwrapSol: false,
|
|
47678
|
-
overrideInferAccounts
|
|
47679
|
-
}
|
|
47680
|
-
});
|
|
47681
|
-
break;
|
|
48113
|
+
let depositIxs;
|
|
48114
|
+
switch (depositBank.config.assetTag) {
|
|
48115
|
+
case 3 /* KAMINO */: {
|
|
48116
|
+
const reserve = bankMetadataMap[depositBank.address.toBase58()]?.kaminoStates?.reserveState;
|
|
48117
|
+
if (!reserve) {
|
|
48118
|
+
throw TransactionBuildingError.kaminoReserveNotFound(
|
|
48119
|
+
depositBank.address.toBase58(),
|
|
48120
|
+
depositBank.mint.toBase58(),
|
|
48121
|
+
depositBank.tokenSymbol
|
|
48122
|
+
);
|
|
47682
48123
|
}
|
|
47683
|
-
|
|
47684
|
-
|
|
47685
|
-
|
|
47686
|
-
|
|
47687
|
-
|
|
47688
|
-
|
|
47689
|
-
|
|
47690
|
-
|
|
48124
|
+
depositIxs = await makeKaminoDepositIx3({
|
|
48125
|
+
program,
|
|
48126
|
+
bank: depositBank,
|
|
48127
|
+
tokenProgram: depositTokenProgram,
|
|
48128
|
+
amount: amountToDeposit,
|
|
48129
|
+
accountAddress: marginfiAccount.address,
|
|
48130
|
+
authority: marginfiAccount.authority,
|
|
48131
|
+
group: marginfiAccount.group,
|
|
48132
|
+
reserve,
|
|
48133
|
+
opts: {
|
|
48134
|
+
wrapAndUnwrapSol: false,
|
|
48135
|
+
overrideInferAccounts
|
|
47691
48136
|
}
|
|
47692
|
-
|
|
47693
|
-
|
|
47694
|
-
depositIxs = await makeDriftDepositIx3({
|
|
47695
|
-
program,
|
|
47696
|
-
bank: depositBank,
|
|
47697
|
-
tokenProgram: depositTokenProgram,
|
|
47698
|
-
amount: amountToDeposit,
|
|
47699
|
-
accountAddress: marginfiAccount.address,
|
|
47700
|
-
authority: marginfiAccount.authority,
|
|
47701
|
-
group: marginfiAccount.group,
|
|
47702
|
-
driftMarketIndex,
|
|
47703
|
-
driftOracle,
|
|
47704
|
-
opts: {
|
|
47705
|
-
wrapAndUnwrapSol: false,
|
|
47706
|
-
overrideInferAccounts
|
|
47707
|
-
}
|
|
47708
|
-
});
|
|
47709
|
-
break;
|
|
47710
|
-
}
|
|
47711
|
-
case 6 /* JUPLEND */: {
|
|
47712
|
-
depositIxs = await makeJuplendDepositIx2({
|
|
47713
|
-
program,
|
|
47714
|
-
bank: depositBank,
|
|
47715
|
-
tokenProgram: depositTokenProgram,
|
|
47716
|
-
amount: amountToDeposit,
|
|
47717
|
-
accountAddress: marginfiAccount.address,
|
|
47718
|
-
authority: marginfiAccount.authority,
|
|
47719
|
-
group: marginfiAccount.group,
|
|
47720
|
-
opts: {
|
|
47721
|
-
wrapAndUnwrapSol: false,
|
|
47722
|
-
overrideInferAccounts
|
|
47723
|
-
}
|
|
47724
|
-
});
|
|
47725
|
-
break;
|
|
47726
|
-
}
|
|
47727
|
-
default: {
|
|
47728
|
-
depositIxs = await makeDepositIx3({
|
|
47729
|
-
program,
|
|
47730
|
-
bank: depositBank,
|
|
47731
|
-
tokenProgram: depositTokenProgram,
|
|
47732
|
-
amount: amountToDeposit,
|
|
47733
|
-
accountAddress: marginfiAccount.address,
|
|
47734
|
-
authority: marginfiAccount.authority,
|
|
47735
|
-
group: marginfiAccount.group,
|
|
47736
|
-
opts: {
|
|
47737
|
-
wrapAndUnwrapSol: false,
|
|
47738
|
-
overrideInferAccounts
|
|
47739
|
-
}
|
|
47740
|
-
});
|
|
47741
|
-
break;
|
|
47742
|
-
}
|
|
48137
|
+
});
|
|
48138
|
+
break;
|
|
47743
48139
|
}
|
|
47744
|
-
|
|
47745
|
-
|
|
47746
|
-
|
|
47747
|
-
|
|
47748
|
-
|
|
47749
|
-
|
|
47750
|
-
|
|
47751
|
-
|
|
47752
|
-
const flashloanTx = await makeFlashLoanTx({
|
|
47753
|
-
...flashloanParams,
|
|
47754
|
-
ixs: [
|
|
47755
|
-
...cuRequestIxs,
|
|
47756
|
-
...withdrawIxs.instructions,
|
|
47757
|
-
...swapInstructions,
|
|
47758
|
-
...depositIxs.instructions
|
|
47759
|
-
],
|
|
47760
|
-
isSync: true
|
|
47761
|
-
});
|
|
47762
|
-
const txSize = getTxSize(flashloanTx);
|
|
47763
|
-
const keySize = getAccountKeys(flashloanTx, luts);
|
|
47764
|
-
const isLast = index === swapResult.length - 1;
|
|
47765
|
-
if (txSize > MAX_TX_SIZE || keySize > 64) {
|
|
47766
|
-
if (isLast) {
|
|
47767
|
-
throw TransactionBuildingError.jupiterSwapSizeExceededLoop(txSize, keySize);
|
|
47768
|
-
} else {
|
|
47769
|
-
continue;
|
|
48140
|
+
case 4 /* DRIFT */: {
|
|
48141
|
+
const driftState = bankMetadataMap[depositBank.address.toBase58()]?.driftStates;
|
|
48142
|
+
if (!driftState) {
|
|
48143
|
+
throw TransactionBuildingError.driftStateNotFound(
|
|
48144
|
+
depositBank.address.toBase58(),
|
|
48145
|
+
depositBank.mint.toBase58(),
|
|
48146
|
+
depositBank.tokenSymbol
|
|
48147
|
+
);
|
|
47770
48148
|
}
|
|
47771
|
-
|
|
47772
|
-
|
|
47773
|
-
|
|
47774
|
-
|
|
47775
|
-
|
|
47776
|
-
|
|
47777
|
-
|
|
47778
|
-
|
|
48149
|
+
const driftMarketIndex = driftState.spotMarketState.marketIndex;
|
|
48150
|
+
const driftOracle = driftState.spotMarketState.oracle;
|
|
48151
|
+
depositIxs = await makeDriftDepositIx3({
|
|
48152
|
+
program,
|
|
48153
|
+
bank: depositBank,
|
|
48154
|
+
tokenProgram: depositTokenProgram,
|
|
48155
|
+
amount: amountToDeposit,
|
|
48156
|
+
accountAddress: marginfiAccount.address,
|
|
48157
|
+
authority: marginfiAccount.authority,
|
|
48158
|
+
group: marginfiAccount.group,
|
|
48159
|
+
driftMarketIndex,
|
|
48160
|
+
driftOracle,
|
|
48161
|
+
opts: {
|
|
48162
|
+
wrapAndUnwrapSol: false,
|
|
48163
|
+
overrideInferAccounts
|
|
48164
|
+
}
|
|
48165
|
+
});
|
|
48166
|
+
break;
|
|
48167
|
+
}
|
|
48168
|
+
case 6 /* JUPLEND */: {
|
|
48169
|
+
depositIxs = await makeJuplendDepositIx2({
|
|
48170
|
+
program,
|
|
48171
|
+
bank: depositBank,
|
|
48172
|
+
tokenProgram: depositTokenProgram,
|
|
48173
|
+
amount: amountToDeposit,
|
|
48174
|
+
accountAddress: marginfiAccount.address,
|
|
48175
|
+
authority: marginfiAccount.authority,
|
|
48176
|
+
group: marginfiAccount.group,
|
|
48177
|
+
opts: {
|
|
48178
|
+
wrapAndUnwrapSol: false,
|
|
48179
|
+
overrideInferAccounts
|
|
48180
|
+
}
|
|
48181
|
+
});
|
|
48182
|
+
break;
|
|
47779
48183
|
}
|
|
48184
|
+
default: {
|
|
48185
|
+
depositIxs = await makeDepositIx3({
|
|
48186
|
+
program,
|
|
48187
|
+
bank: depositBank,
|
|
48188
|
+
tokenProgram: depositTokenProgram,
|
|
48189
|
+
amount: amountToDeposit,
|
|
48190
|
+
accountAddress: marginfiAccount.address,
|
|
48191
|
+
authority: marginfiAccount.authority,
|
|
48192
|
+
group: marginfiAccount.group,
|
|
48193
|
+
opts: {
|
|
48194
|
+
wrapAndUnwrapSol: false,
|
|
48195
|
+
overrideInferAccounts
|
|
48196
|
+
}
|
|
48197
|
+
});
|
|
48198
|
+
break;
|
|
48199
|
+
}
|
|
48200
|
+
}
|
|
48201
|
+
const luts = [...addressLookupTableAccounts ?? [], ...swapLookupTables];
|
|
48202
|
+
const allNonFlIxs = [
|
|
48203
|
+
...cuRequestIxs,
|
|
48204
|
+
...withdrawIxs.instructions,
|
|
48205
|
+
...swapInstructions,
|
|
48206
|
+
...depositIxs.instructions
|
|
48207
|
+
];
|
|
48208
|
+
if (swapInstructions.length > 0) {
|
|
48209
|
+
compileFlashloanPrecheck({
|
|
48210
|
+
allIxs: allNonFlIxs,
|
|
48211
|
+
payer: marginfiAccount.authority,
|
|
48212
|
+
luts,
|
|
48213
|
+
sizeConstraint: sizeConstraintUsed,
|
|
48214
|
+
swapIxCount: swapInstructions.length,
|
|
48215
|
+
swapLutCount: swapLookupTables.length
|
|
48216
|
+
});
|
|
47780
48217
|
}
|
|
47781
|
-
|
|
48218
|
+
const flashloanTx = await makeFlashLoanTx({
|
|
48219
|
+
program,
|
|
48220
|
+
marginfiAccount,
|
|
48221
|
+
bankMap,
|
|
48222
|
+
addressLookupTableAccounts: luts,
|
|
48223
|
+
blockhash,
|
|
48224
|
+
ixs: allNonFlIxs,
|
|
48225
|
+
isSync: true
|
|
48226
|
+
});
|
|
48227
|
+
const txSize = getTxSize(flashloanTx);
|
|
48228
|
+
const totalKeys = getTotalAccountKeys(flashloanTx);
|
|
48229
|
+
if (txSize > MAX_TX_SIZE || totalKeys > MAX_ACCOUNT_LOCKS) {
|
|
48230
|
+
throw TransactionBuildingError.swapSizeExceededPositionSwap(
|
|
48231
|
+
txSize,
|
|
48232
|
+
totalKeys,
|
|
48233
|
+
swapOpts.swapConfig?.provider
|
|
48234
|
+
);
|
|
48235
|
+
}
|
|
48236
|
+
return {
|
|
48237
|
+
flashloanTx,
|
|
48238
|
+
setupInstructions,
|
|
48239
|
+
swapQuote,
|
|
48240
|
+
withdrawIxs,
|
|
48241
|
+
depositIxs
|
|
48242
|
+
};
|
|
47782
48243
|
}
|
|
47783
48244
|
async function makeSwapDebtTx(params) {
|
|
47784
48245
|
const {
|
|
@@ -47916,7 +48377,6 @@ async function buildSwapDebtFlashloanTx({
|
|
|
47916
48377
|
throw new Error("repayAmount must be greater than 0");
|
|
47917
48378
|
}
|
|
47918
48379
|
const actualRepayAmount = Math.min(repayAmount ?? totalPositionAmount, totalPositionAmount);
|
|
47919
|
-
const swapResult = [];
|
|
47920
48380
|
const cuRequestIxs = [
|
|
47921
48381
|
ComputeBudgetProgram.setComputeUnitLimit({ units: 12e5 }),
|
|
47922
48382
|
ComputeBudgetProgram.setComputeUnitPrice({ microLamports: 1 })
|
|
@@ -47927,313 +48387,120 @@ async function buildSwapDebtFlashloanTx({
|
|
|
47927
48387
|
true,
|
|
47928
48388
|
repayTokenProgram.equals(TOKEN_2022_PROGRAM_ID) ? TOKEN_2022_PROGRAM_ID : void 0
|
|
47929
48389
|
);
|
|
47930
|
-
const
|
|
47931
|
-
const estimateQuote = await jupiterApiClient.quoteGet({
|
|
48390
|
+
const { otherAmountThreshold } = await getExactOutEstimate({
|
|
47932
48391
|
inputMint: borrowBank.mint.toBase58(),
|
|
47933
48392
|
outputMint: repayBank.mint.toBase58(),
|
|
47934
48393
|
amount: uiToNative(actualRepayAmount, repayBank.mintDecimals).toNumber(),
|
|
47935
|
-
|
|
47936
|
-
|
|
47937
|
-
slippageBps: swapOpts.jupiterOptions?.slippageBps
|
|
48394
|
+
swapOpts,
|
|
48395
|
+
connection
|
|
47938
48396
|
});
|
|
47939
|
-
const estimatedBorrowAmount = nativeToUi(
|
|
47940
|
-
|
|
47941
|
-
|
|
47942
|
-
|
|
47943
|
-
|
|
47944
|
-
|
|
47945
|
-
|
|
47946
|
-
|
|
47947
|
-
|
|
47948
|
-
|
|
47949
|
-
|
|
47950
|
-
|
|
47951
|
-
|
|
47952
|
-
|
|
47953
|
-
|
|
48397
|
+
const estimatedBorrowAmount = nativeToUi(otherAmountThreshold, borrowBank.mintDecimals);
|
|
48398
|
+
const swapConstraints = await computeFlashloanSwapConstraints({
|
|
48399
|
+
program,
|
|
48400
|
+
marginfiAccount,
|
|
48401
|
+
bankMap,
|
|
48402
|
+
bankMetadataMap,
|
|
48403
|
+
addressLookupTableAccounts: addressLookupTableAccounts ?? [],
|
|
48404
|
+
primaryIx: { type: "borrow", bank: borrowBank, tokenProgram: borrowTokenProgram },
|
|
48405
|
+
secondaryIx: { type: "repay", bank: repayBank, tokenProgram: repayTokenProgram },
|
|
48406
|
+
overrideInferAccounts
|
|
48407
|
+
});
|
|
48408
|
+
const swapResponses = await getSwapIxsForFlashloan({
|
|
48409
|
+
inputMint: borrowBank.mint.toBase58(),
|
|
48410
|
+
outputMint: repayBank.mint.toBase58(),
|
|
48411
|
+
amount: uiToNative(estimatedBorrowAmount, borrowBank.mintDecimals).toNumber(),
|
|
48412
|
+
swapMode: "ExactIn",
|
|
47954
48413
|
authority: marginfiAccount.authority,
|
|
47955
48414
|
connection,
|
|
47956
48415
|
destinationTokenAccount,
|
|
47957
|
-
|
|
48416
|
+
swapOpts,
|
|
48417
|
+
sizeConstraint: swapConstraints.sizeConstraint,
|
|
48418
|
+
maxSwapTotalAccounts: swapConstraints.maxSwapTotalAccounts
|
|
47958
48419
|
});
|
|
47959
|
-
|
|
47960
|
-
|
|
47961
|
-
|
|
47962
|
-
|
|
47963
|
-
|
|
47964
|
-
|
|
47965
|
-
|
|
47966
|
-
|
|
47967
|
-
|
|
47968
|
-
|
|
47969
|
-
|
|
47970
|
-
|
|
47971
|
-
|
|
47972
|
-
|
|
47973
|
-
|
|
47974
|
-
|
|
48420
|
+
const { quoteResponse } = swapResponses;
|
|
48421
|
+
const outAmount = nativeToUi(quoteResponse.outAmount, repayBank.mintDecimals);
|
|
48422
|
+
const outAmountThreshold = nativeToUi(quoteResponse.otherAmountThreshold, repayBank.mintDecimals);
|
|
48423
|
+
const amountToRepay = outAmount > totalPositionAmount ? totalPositionAmount : outAmountThreshold;
|
|
48424
|
+
const borrowAmount = nativeToUi(quoteResponse.inAmount, borrowBank.mintDecimals);
|
|
48425
|
+
const borrowIxs = await makeBorrowIx3({
|
|
48426
|
+
program,
|
|
48427
|
+
bank: borrowBank,
|
|
48428
|
+
bankMap,
|
|
48429
|
+
tokenProgram: borrowTokenProgram,
|
|
48430
|
+
amount: borrowAmount,
|
|
48431
|
+
marginfiAccount,
|
|
48432
|
+
authority: marginfiAccount.authority,
|
|
48433
|
+
isSync: true,
|
|
48434
|
+
opts: {
|
|
48435
|
+
createAtas: false,
|
|
48436
|
+
wrapAndUnwrapSol: false,
|
|
48437
|
+
overrideInferAccounts
|
|
48438
|
+
}
|
|
47975
48439
|
});
|
|
47976
|
-
|
|
47977
|
-
|
|
47978
|
-
|
|
47979
|
-
|
|
47980
|
-
|
|
47981
|
-
|
|
47982
|
-
|
|
48440
|
+
const repayIxs = await makeRepayIx3({
|
|
48441
|
+
program,
|
|
48442
|
+
bank: repayBank,
|
|
48443
|
+
tokenProgram: repayTokenProgram,
|
|
48444
|
+
amount: amountToRepay,
|
|
48445
|
+
accountAddress: marginfiAccount.address,
|
|
48446
|
+
authority: marginfiAccount.authority,
|
|
48447
|
+
repayAll: isWholePosition(
|
|
48448
|
+
{
|
|
48449
|
+
amount: totalPositionAmount,
|
|
48450
|
+
isLending: false
|
|
48451
|
+
},
|
|
47983
48452
|
amountToRepay,
|
|
47984
|
-
|
|
47985
|
-
|
|
47986
|
-
|
|
47987
|
-
|
|
47988
|
-
|
|
47989
|
-
|
|
47990
|
-
const borrowIxs = await makeBorrowIx3({
|
|
47991
|
-
program,
|
|
47992
|
-
bank: borrowBank,
|
|
47993
|
-
bankMap,
|
|
47994
|
-
tokenProgram: borrowTokenProgram,
|
|
47995
|
-
amount: borrowAmount,
|
|
47996
|
-
marginfiAccount,
|
|
47997
|
-
authority: marginfiAccount.authority,
|
|
47998
|
-
isSync: true,
|
|
47999
|
-
opts: {
|
|
48000
|
-
createAtas: false,
|
|
48001
|
-
wrapAndUnwrapSol: false,
|
|
48002
|
-
overrideInferAccounts
|
|
48003
|
-
}
|
|
48004
|
-
});
|
|
48005
|
-
const repayIxs = await makeRepayIx3({
|
|
48006
|
-
program,
|
|
48007
|
-
bank: repayBank,
|
|
48008
|
-
tokenProgram: repayTokenProgram,
|
|
48009
|
-
amount: amountToRepay,
|
|
48010
|
-
accountAddress: marginfiAccount.address,
|
|
48011
|
-
authority: marginfiAccount.authority,
|
|
48012
|
-
repayAll: isWholePosition(
|
|
48013
|
-
{
|
|
48014
|
-
amount: totalPositionAmount,
|
|
48015
|
-
isLending: false
|
|
48016
|
-
},
|
|
48017
|
-
amountToRepay,
|
|
48018
|
-
repayBank.mintDecimals
|
|
48019
|
-
),
|
|
48020
|
-
isSync: true,
|
|
48021
|
-
opts: {
|
|
48022
|
-
wrapAndUnwrapSol: false,
|
|
48023
|
-
overrideInferAccounts
|
|
48024
|
-
}
|
|
48025
|
-
});
|
|
48026
|
-
const luts = [...addressLookupTableAccounts ?? [], ...swapLookupTables];
|
|
48027
|
-
const flashloanParams = {
|
|
48028
|
-
program,
|
|
48029
|
-
marginfiAccount,
|
|
48030
|
-
bankMap,
|
|
48031
|
-
addressLookupTableAccounts: luts,
|
|
48032
|
-
blockhash
|
|
48033
|
-
};
|
|
48034
|
-
const flashloanTx = await makeFlashLoanTx({
|
|
48035
|
-
...flashloanParams,
|
|
48036
|
-
ixs: [
|
|
48037
|
-
...cuRequestIxs,
|
|
48038
|
-
...borrowIxs.instructions,
|
|
48039
|
-
...swapInstructions,
|
|
48040
|
-
...repayIxs.instructions
|
|
48041
|
-
],
|
|
48042
|
-
isSync: true
|
|
48043
|
-
});
|
|
48044
|
-
const txSize = getTxSize(flashloanTx);
|
|
48045
|
-
const keySize = getAccountKeys(flashloanTx, luts);
|
|
48046
|
-
const isLast = index === swapResult.length - 1;
|
|
48047
|
-
if (txSize > MAX_TX_SIZE || keySize > 64) {
|
|
48048
|
-
if (isLast) {
|
|
48049
|
-
throw TransactionBuildingError.jupiterSwapSizeExceededLoop(txSize, keySize);
|
|
48050
|
-
} else {
|
|
48051
|
-
continue;
|
|
48052
|
-
}
|
|
48053
|
-
} else {
|
|
48054
|
-
return {
|
|
48055
|
-
flashloanTx,
|
|
48056
|
-
setupInstructions,
|
|
48057
|
-
swapQuote: quoteResponse,
|
|
48058
|
-
borrowIxs,
|
|
48059
|
-
repayIxs
|
|
48060
|
-
};
|
|
48061
|
-
}
|
|
48062
|
-
}
|
|
48063
|
-
throw new Error("Failed to build swap debt flashloan tx");
|
|
48064
|
-
}
|
|
48065
|
-
var SYSVAR_CLOCK_ID2 = new PublicKey("SysvarC1ock11111111111111111111111111111111");
|
|
48066
|
-
async function makeMintStakedLstIx(params) {
|
|
48067
|
-
const { amount, authority, stakeAccountPk, validator, connection } = params;
|
|
48068
|
-
const pool = findPoolAddress(validator);
|
|
48069
|
-
const lstMint = findPoolMintAddress(pool);
|
|
48070
|
-
const poolStakeAuth = findPoolStakeAuthorityAddress(pool);
|
|
48071
|
-
const lstAta = getAssociatedTokenAddressSync(lstMint, authority);
|
|
48072
|
-
const [lstAccInfo, stakeAccInfoParsed, rentExemptReserve] = await Promise.all([
|
|
48073
|
-
connection.getAccountInfo(lstAta),
|
|
48074
|
-
connection.getParsedAccountInfo(stakeAccountPk),
|
|
48075
|
-
connection.getMinimumBalanceForRentExemption(StakeProgram.space)
|
|
48076
|
-
]);
|
|
48077
|
-
const stakeAccParsed = stakeAccInfoParsed?.value?.data;
|
|
48078
|
-
const amountLamports = Math.round(Number(amount) * LAMPORTS_PER_SOL);
|
|
48079
|
-
const stakeAccLamports = Number(stakeAccParsed?.parsed?.info?.stake?.delegation?.stake ?? 0);
|
|
48080
|
-
const isFullStake = amountLamports >= stakeAccLamports;
|
|
48081
|
-
const instructions2 = [];
|
|
48082
|
-
const signers = [];
|
|
48083
|
-
if (!lstAccInfo) {
|
|
48084
|
-
instructions2.push(
|
|
48085
|
-
createAssociatedTokenAccountInstruction(authority, lstAta, authority, lstMint)
|
|
48086
|
-
);
|
|
48087
|
-
}
|
|
48088
|
-
let targetStakePubkey;
|
|
48089
|
-
if (!isFullStake) {
|
|
48090
|
-
const splitStakeAccount = Keypair.generate();
|
|
48091
|
-
signers.push(splitStakeAccount);
|
|
48092
|
-
targetStakePubkey = splitStakeAccount.publicKey;
|
|
48093
|
-
instructions2.push(
|
|
48094
|
-
...StakeProgram.split(
|
|
48095
|
-
{
|
|
48096
|
-
stakePubkey: stakeAccountPk,
|
|
48097
|
-
authorizedPubkey: authority,
|
|
48098
|
-
splitStakePubkey: splitStakeAccount.publicKey,
|
|
48099
|
-
lamports: amountLamports
|
|
48100
|
-
},
|
|
48101
|
-
rentExemptReserve
|
|
48102
|
-
).instructions
|
|
48103
|
-
);
|
|
48104
|
-
} else {
|
|
48105
|
-
targetStakePubkey = stakeAccountPk;
|
|
48106
|
-
}
|
|
48107
|
-
const [authorizeStakerIx, authorizeWithdrawIx] = await Promise.all([
|
|
48108
|
-
StakeProgram.authorize({
|
|
48109
|
-
stakePubkey: targetStakePubkey,
|
|
48110
|
-
authorizedPubkey: authority,
|
|
48111
|
-
newAuthorizedPubkey: poolStakeAuth,
|
|
48112
|
-
stakeAuthorizationType: StakeAuthorizationLayout.Staker
|
|
48113
|
-
}).instructions,
|
|
48114
|
-
StakeProgram.authorize({
|
|
48115
|
-
stakePubkey: targetStakePubkey,
|
|
48116
|
-
authorizedPubkey: authority,
|
|
48117
|
-
newAuthorizedPubkey: poolStakeAuth,
|
|
48118
|
-
stakeAuthorizationType: StakeAuthorizationLayout.Withdrawer
|
|
48119
|
-
}).instructions
|
|
48120
|
-
]);
|
|
48121
|
-
[authorizeStakerIx[0], authorizeWithdrawIx[0]].forEach((ix) => {
|
|
48122
|
-
if (ix) {
|
|
48123
|
-
ix.keys = ix.keys.map((key) => ({
|
|
48124
|
-
...key,
|
|
48125
|
-
isWritable: key.pubkey.equals(SYSVAR_CLOCK_ID2) ? false : key.isWritable
|
|
48126
|
-
}));
|
|
48453
|
+
repayBank.mintDecimals
|
|
48454
|
+
),
|
|
48455
|
+
isSync: true,
|
|
48456
|
+
opts: {
|
|
48457
|
+
wrapAndUnwrapSol: false,
|
|
48458
|
+
overrideInferAccounts
|
|
48127
48459
|
}
|
|
48128
48460
|
});
|
|
48129
|
-
|
|
48130
|
-
|
|
48131
|
-
|
|
48132
|
-
|
|
48133
|
-
|
|
48134
|
-
|
|
48135
|
-
|
|
48136
|
-
|
|
48137
|
-
|
|
48138
|
-
|
|
48139
|
-
|
|
48140
|
-
|
|
48141
|
-
|
|
48142
|
-
const blockhash = providedBlockhash ?? (await connection.getLatestBlockhash("confirmed")).blockhash;
|
|
48143
|
-
const message = new TransactionMessage({
|
|
48144
|
-
payerKey: params.authority,
|
|
48145
|
-
recentBlockhash: blockhash,
|
|
48146
|
-
instructions: instructions2
|
|
48147
|
-
}).compileToV0Message(luts);
|
|
48148
|
-
const tx = new VersionedTransaction(message);
|
|
48149
|
-
return addTransactionMetadata(tx, {
|
|
48150
|
-
signers: keys,
|
|
48151
|
-
addressLookupTables: luts,
|
|
48152
|
-
type: "DEPOSIT_STAKE" /* DEPOSIT_STAKE */
|
|
48153
|
-
});
|
|
48154
|
-
}
|
|
48155
|
-
async function makeRedeemStakedLstIx(params) {
|
|
48156
|
-
const { amount, authority, validator, connection } = params;
|
|
48157
|
-
const pool = findPoolAddress(validator);
|
|
48158
|
-
const lstMint = findPoolMintAddress(pool);
|
|
48159
|
-
const mintAuthority = findPoolMintAuthorityAddress(pool);
|
|
48160
|
-
const lstAta = getAssociatedTokenAddressSync(lstMint, authority);
|
|
48161
|
-
const rentExemption = await connection.getMinimumBalanceForRentExemption(
|
|
48162
|
-
StakeProgram.space
|
|
48163
|
-
);
|
|
48164
|
-
const stakeAmount = new BigNumber3(new BigNumber3(amount).toString());
|
|
48165
|
-
const instructions2 = [];
|
|
48166
|
-
const signers = [];
|
|
48167
|
-
const stakeAccount = Keypair.generate();
|
|
48168
|
-
signers.push(stakeAccount);
|
|
48169
|
-
instructions2.push(
|
|
48170
|
-
SystemProgram.createAccount({
|
|
48171
|
-
fromPubkey: authority,
|
|
48172
|
-
newAccountPubkey: stakeAccount.publicKey,
|
|
48173
|
-
lamports: rentExemption,
|
|
48174
|
-
space: StakeProgram.space,
|
|
48175
|
-
programId: StakeProgram.programId
|
|
48176
|
-
})
|
|
48177
|
-
);
|
|
48178
|
-
instructions2.push(
|
|
48179
|
-
createApproveInstruction(
|
|
48180
|
-
lstAta,
|
|
48181
|
-
mintAuthority,
|
|
48182
|
-
authority,
|
|
48183
|
-
BigInt(stakeAmount.multipliedBy(1e9).toFixed(0))
|
|
48184
|
-
)
|
|
48185
|
-
);
|
|
48186
|
-
const withdrawStakeIx = await SinglePoolInstruction.withdrawStake(
|
|
48187
|
-
pool,
|
|
48188
|
-
stakeAccount.publicKey,
|
|
48189
|
-
authority,
|
|
48190
|
-
lstAta,
|
|
48191
|
-
stakeAmount
|
|
48192
|
-
);
|
|
48193
|
-
instructions2.push(withdrawStakeIx);
|
|
48194
|
-
return { instructions: instructions2, keys: signers };
|
|
48195
|
-
}
|
|
48196
|
-
async function makeRedeemStakedLstTx(params) {
|
|
48197
|
-
const { connection, luts, blockhash: providedBlockhash } = params;
|
|
48198
|
-
const { instructions: instructions2, keys } = await makeRedeemStakedLstIx(params);
|
|
48199
|
-
const blockhash = providedBlockhash ?? (await connection.getLatestBlockhash("confirmed")).blockhash;
|
|
48200
|
-
const message = new TransactionMessage({
|
|
48201
|
-
payerKey: params.authority,
|
|
48202
|
-
recentBlockhash: blockhash,
|
|
48203
|
-
instructions: instructions2
|
|
48204
|
-
}).compileToV0Message(luts);
|
|
48205
|
-
const tx = new VersionedTransaction(message);
|
|
48206
|
-
return addTransactionMetadata(tx, {
|
|
48207
|
-
signers: keys,
|
|
48208
|
-
addressLookupTables: luts,
|
|
48209
|
-
type: "WITHDRAW_STAKE" /* WITHDRAW_STAKE */
|
|
48210
|
-
});
|
|
48211
|
-
}
|
|
48212
|
-
async function makeMergeStakeAccountsTx(params) {
|
|
48213
|
-
const {
|
|
48214
|
-
authority,
|
|
48215
|
-
sourceStakeAccount,
|
|
48216
|
-
destinationStakeAccount,
|
|
48217
|
-
connection,
|
|
48461
|
+
const luts = [
|
|
48462
|
+
...addressLookupTableAccounts ?? [],
|
|
48463
|
+
...swapResponses.addressLookupTableAddresses
|
|
48464
|
+
];
|
|
48465
|
+
const allNonFlIxs = [
|
|
48466
|
+
...cuRequestIxs,
|
|
48467
|
+
...borrowIxs.instructions,
|
|
48468
|
+
...swapResponses.swapInstructions,
|
|
48469
|
+
...repayIxs.instructions
|
|
48470
|
+
];
|
|
48471
|
+
compileFlashloanPrecheck({
|
|
48472
|
+
allIxs: allNonFlIxs,
|
|
48473
|
+
payer: marginfiAccount.authority,
|
|
48218
48474
|
luts,
|
|
48219
|
-
|
|
48220
|
-
|
|
48221
|
-
|
|
48222
|
-
|
|
48223
|
-
|
|
48224
|
-
|
|
48225
|
-
|
|
48226
|
-
|
|
48227
|
-
|
|
48228
|
-
|
|
48229
|
-
|
|
48230
|
-
|
|
48231
|
-
}).compileToV0Message(luts);
|
|
48232
|
-
const tx = new VersionedTransaction(message);
|
|
48233
|
-
return addTransactionMetadata(tx, {
|
|
48234
|
-
addressLookupTables: luts,
|
|
48235
|
-
type: "MERGE_STAKE_ACCOUNTS" /* MERGE_STAKE_ACCOUNTS */
|
|
48475
|
+
sizeConstraint: swapConstraints.sizeConstraint,
|
|
48476
|
+
swapIxCount: swapResponses.swapInstructions.length,
|
|
48477
|
+
swapLutCount: swapResponses.addressLookupTableAddresses.length
|
|
48478
|
+
});
|
|
48479
|
+
const flashloanTx = await makeFlashLoanTx({
|
|
48480
|
+
program,
|
|
48481
|
+
marginfiAccount,
|
|
48482
|
+
bankMap,
|
|
48483
|
+
addressLookupTableAccounts: luts,
|
|
48484
|
+
blockhash,
|
|
48485
|
+
ixs: allNonFlIxs,
|
|
48486
|
+
isSync: true
|
|
48236
48487
|
});
|
|
48488
|
+
const txSize = getTxSize(flashloanTx);
|
|
48489
|
+
const totalKeys = getTotalAccountKeys(flashloanTx);
|
|
48490
|
+
if (txSize > MAX_TX_SIZE || totalKeys > MAX_ACCOUNT_LOCKS) {
|
|
48491
|
+
throw TransactionBuildingError.swapSizeExceededPositionSwap(
|
|
48492
|
+
txSize,
|
|
48493
|
+
totalKeys,
|
|
48494
|
+
swapOpts.swapConfig?.provider
|
|
48495
|
+
);
|
|
48496
|
+
}
|
|
48497
|
+
return {
|
|
48498
|
+
flashloanTx,
|
|
48499
|
+
setupInstructions: swapResponses.setupInstructions,
|
|
48500
|
+
swapQuote: quoteResponse,
|
|
48501
|
+
borrowIxs,
|
|
48502
|
+
repayIxs
|
|
48503
|
+
};
|
|
48237
48504
|
}
|
|
48238
48505
|
|
|
48239
48506
|
// src/services/account/services/account-simulation.service.ts
|
|
@@ -48859,17 +49126,528 @@ function computeMaxWithdrawForBank(params) {
|
|
|
48859
49126
|
const maxWithdraw = initUntiedCollateralForBank.div(initWeightedPrice);
|
|
48860
49127
|
return maxWithdraw;
|
|
48861
49128
|
}
|
|
49129
|
+
var TITAN_FEE_WALLET = new PublicKey("6ryqDDCwKFZfSiHQrYRkjTEarbsLjg9TmuFg1RJorBk3");
|
|
49130
|
+
var getTitanFeeAccount = (mint) => {
|
|
49131
|
+
return getAssociatedTokenAddressSync(mint, TITAN_FEE_WALLET, true);
|
|
49132
|
+
};
|
|
49133
|
+
var checkTitanFeeAccount = async (connection, mint) => {
|
|
49134
|
+
const feeAccount = getTitanFeeAccount(mint);
|
|
49135
|
+
const hasFeeAccount = !!await connection.getAccountInfo(feeAccount);
|
|
49136
|
+
return { feeAccount, hasFeeAccount, feeWallet: TITAN_FEE_WALLET };
|
|
49137
|
+
};
|
|
49138
|
+
function deserializeTitanInstruction(ix) {
|
|
49139
|
+
return new TransactionInstruction({
|
|
49140
|
+
programId: new PublicKey(ix.p),
|
|
49141
|
+
keys: ix.a.map((account) => ({
|
|
49142
|
+
pubkey: new PublicKey(account.p),
|
|
49143
|
+
isSigner: account.s,
|
|
49144
|
+
isWritable: account.w
|
|
49145
|
+
})),
|
|
49146
|
+
data: Buffer.from(ix.d)
|
|
49147
|
+
});
|
|
49148
|
+
}
|
|
49149
|
+
var getTitanSwapIxsForFlashloan = async ({
|
|
49150
|
+
quoteParams,
|
|
49151
|
+
authority,
|
|
49152
|
+
connection,
|
|
49153
|
+
destinationTokenAccount,
|
|
49154
|
+
apiConfig
|
|
49155
|
+
}) => {
|
|
49156
|
+
const basePath = apiConfig?.basePath ?? "";
|
|
49157
|
+
const feeMint = new PublicKey(
|
|
49158
|
+
quoteParams.swapMode === "ExactIn" ? quoteParams.outputMint : quoteParams.inputMint
|
|
49159
|
+
);
|
|
49160
|
+
const { feeAccount, hasFeeAccount } = await checkTitanFeeAccount(connection, feeMint);
|
|
49161
|
+
let finalQuoteParams = quoteParams;
|
|
49162
|
+
if (!hasFeeAccount) {
|
|
49163
|
+
console.warn("Warning: Titan fee account ATA does not exist, disabling platform fee");
|
|
49164
|
+
finalQuoteParams = {
|
|
49165
|
+
...quoteParams,
|
|
49166
|
+
platformFeeBps: void 0
|
|
49167
|
+
};
|
|
49168
|
+
}
|
|
49169
|
+
if (basePath.startsWith("wss://") || basePath.startsWith("ws://")) {
|
|
49170
|
+
return getTitanSwapIxsViaWebSocket(
|
|
49171
|
+
{ quoteParams: finalQuoteParams, authority, connection, destinationTokenAccount, apiConfig },
|
|
49172
|
+
hasFeeAccount ? feeAccount : void 0
|
|
49173
|
+
);
|
|
49174
|
+
} else {
|
|
49175
|
+
return getTitanSwapIxsViaHttpProxy(
|
|
49176
|
+
{ quoteParams: finalQuoteParams, authority, connection, destinationTokenAccount, apiConfig },
|
|
49177
|
+
hasFeeAccount ? feeAccount : void 0
|
|
49178
|
+
);
|
|
49179
|
+
}
|
|
49180
|
+
};
|
|
49181
|
+
async function getTitanSwapIxsViaWebSocket(params, feeAccount) {
|
|
49182
|
+
const { quoteParams, authority, connection, destinationTokenAccount, apiConfig } = params;
|
|
49183
|
+
const {
|
|
49184
|
+
inputMint,
|
|
49185
|
+
outputMint,
|
|
49186
|
+
amount,
|
|
49187
|
+
swapMode,
|
|
49188
|
+
slippageBps,
|
|
49189
|
+
platformFeeBps,
|
|
49190
|
+
directRoutesOnly,
|
|
49191
|
+
sizeConstraint,
|
|
49192
|
+
maxSwapAccounts,
|
|
49193
|
+
maxSwapTotalAccounts
|
|
49194
|
+
} = quoteParams;
|
|
49195
|
+
const wsUrl = apiConfig?.basePath;
|
|
49196
|
+
if (!wsUrl) {
|
|
49197
|
+
throw new Error("Titan WebSocket URL is required (apiConfig.basePath)");
|
|
49198
|
+
}
|
|
49199
|
+
const txParams = {
|
|
49200
|
+
userPublicKey: authority.toBytes(),
|
|
49201
|
+
outputAccount: destinationTokenAccount.toBytes()
|
|
49202
|
+
};
|
|
49203
|
+
if (feeAccount && platformFeeBps) {
|
|
49204
|
+
txParams.feeBps = platformFeeBps;
|
|
49205
|
+
txParams.feeAccount = feeAccount.toBytes();
|
|
49206
|
+
}
|
|
49207
|
+
const client = await V1Client.connect(wsUrl);
|
|
49208
|
+
try {
|
|
49209
|
+
const { stream } = await client.newSwapQuoteStream({
|
|
49210
|
+
swap: {
|
|
49211
|
+
inputMint: new PublicKey(inputMint).toBytes(),
|
|
49212
|
+
outputMint: new PublicKey(outputMint).toBytes(),
|
|
49213
|
+
amount,
|
|
49214
|
+
swapMode,
|
|
49215
|
+
slippageBps,
|
|
49216
|
+
onlyDirectRoutes: directRoutesOnly,
|
|
49217
|
+
addSizeConstraint: sizeConstraint !== void 0,
|
|
49218
|
+
sizeConstraint,
|
|
49219
|
+
accountsLimitWritable: maxSwapAccounts,
|
|
49220
|
+
accountsLimitTotal: maxSwapTotalAccounts
|
|
49221
|
+
},
|
|
49222
|
+
transaction: txParams,
|
|
49223
|
+
update: {
|
|
49224
|
+
num_quotes: 3
|
|
49225
|
+
}
|
|
49226
|
+
});
|
|
49227
|
+
const reader = stream.getReader();
|
|
49228
|
+
const { value: swapQuotes, done } = await reader.read();
|
|
49229
|
+
reader.releaseLock();
|
|
49230
|
+
if (done || !swapQuotes) {
|
|
49231
|
+
throw new Error("Titan swap quote stream ended without data");
|
|
49232
|
+
}
|
|
49233
|
+
const quotes = swapQuotes;
|
|
49234
|
+
const bestRoute = selectBestRoute(quotes.quotes, swapMode);
|
|
49235
|
+
if (!bestRoute) {
|
|
49236
|
+
throw new Error(`No Titan swap routes found for ${inputMint} -> ${outputMint}`);
|
|
49237
|
+
}
|
|
49238
|
+
const swapInstructions = bestRoute.instructions.map(deserializeTitanInstruction);
|
|
49239
|
+
const lutPubkeys = bestRoute.addressLookupTables.map((lutBytes) => new PublicKey(lutBytes));
|
|
49240
|
+
const addressLookupTableAddresses = await resolveLookupTables(connection, lutPubkeys);
|
|
49241
|
+
const quoteResponse = {
|
|
49242
|
+
...buildSwapQuoteResult(bestRoute, swapMode),
|
|
49243
|
+
provider: "TITAN" /* TITAN */
|
|
49244
|
+
};
|
|
49245
|
+
return {
|
|
49246
|
+
swapInstructions,
|
|
49247
|
+
setupInstructions: [],
|
|
49248
|
+
addressLookupTableAddresses,
|
|
49249
|
+
quoteResponse
|
|
49250
|
+
};
|
|
49251
|
+
} finally {
|
|
49252
|
+
if (!client.closed) {
|
|
49253
|
+
await client.close();
|
|
49254
|
+
}
|
|
49255
|
+
}
|
|
49256
|
+
}
|
|
49257
|
+
async function getTitanSwapIxsViaHttpProxy(params, feeAccount) {
|
|
49258
|
+
const { quoteParams, authority, connection, destinationTokenAccount, apiConfig } = params;
|
|
49259
|
+
const {
|
|
49260
|
+
inputMint,
|
|
49261
|
+
outputMint,
|
|
49262
|
+
amount,
|
|
49263
|
+
swapMode,
|
|
49264
|
+
slippageBps,
|
|
49265
|
+
platformFeeBps,
|
|
49266
|
+
directRoutesOnly,
|
|
49267
|
+
sizeConstraint,
|
|
49268
|
+
maxSwapAccounts,
|
|
49269
|
+
maxSwapTotalAccounts
|
|
49270
|
+
} = quoteParams;
|
|
49271
|
+
const basePath = apiConfig?.basePath;
|
|
49272
|
+
if (!basePath) {
|
|
49273
|
+
throw new Error("Titan proxy URL is required (apiConfig.basePath)");
|
|
49274
|
+
}
|
|
49275
|
+
const txBody = {
|
|
49276
|
+
userPublicKey: authority.toBase58(),
|
|
49277
|
+
outputAccount: destinationTokenAccount.toBase58()
|
|
49278
|
+
};
|
|
49279
|
+
if (feeAccount && platformFeeBps) {
|
|
49280
|
+
txBody.feeBps = platformFeeBps;
|
|
49281
|
+
txBody.feeAccount = feeAccount.toBase58();
|
|
49282
|
+
}
|
|
49283
|
+
const response = await fetch(`${basePath}/swap-quote`, {
|
|
49284
|
+
method: "POST",
|
|
49285
|
+
headers: {
|
|
49286
|
+
"Content-Type": "application/json",
|
|
49287
|
+
...apiConfig?.headers ?? {}
|
|
49288
|
+
},
|
|
49289
|
+
body: JSON.stringify({
|
|
49290
|
+
swap: {
|
|
49291
|
+
inputMint,
|
|
49292
|
+
outputMint,
|
|
49293
|
+
amount,
|
|
49294
|
+
swapMode,
|
|
49295
|
+
slippageBps,
|
|
49296
|
+
onlyDirectRoutes: directRoutesOnly,
|
|
49297
|
+
addSizeConstraint: sizeConstraint !== void 0,
|
|
49298
|
+
sizeConstraint,
|
|
49299
|
+
accountsLimitWritable: maxSwapAccounts,
|
|
49300
|
+
accountsLimitTotal: maxSwapTotalAccounts
|
|
49301
|
+
},
|
|
49302
|
+
transaction: txBody
|
|
49303
|
+
})
|
|
49304
|
+
});
|
|
49305
|
+
if (!response.ok) {
|
|
49306
|
+
const errorData = await response.json().catch(() => ({}));
|
|
49307
|
+
throw new Error(
|
|
49308
|
+
`Titan proxy error (${response.status}): ${errorData.message ?? response.statusText}`
|
|
49309
|
+
);
|
|
49310
|
+
}
|
|
49311
|
+
const data = await response.json();
|
|
49312
|
+
const bestRoute = selectBestRoute(data.quotes, swapMode);
|
|
49313
|
+
if (!bestRoute) {
|
|
49314
|
+
throw new Error(`No Titan swap routes found for ${inputMint} -> ${outputMint}`);
|
|
49315
|
+
}
|
|
49316
|
+
const swapInstructions = bestRoute.instructions.map(deserializeSerializedInstruction);
|
|
49317
|
+
const lutPubkeys = bestRoute.addressLookupTables.map(
|
|
49318
|
+
(b64) => new PublicKey(Buffer.from(b64, "base64"))
|
|
49319
|
+
);
|
|
49320
|
+
const addressLookupTableAddresses = await resolveLookupTables(connection, lutPubkeys);
|
|
49321
|
+
const quoteResponse = {
|
|
49322
|
+
...buildSwapQuoteResult(bestRoute, swapMode),
|
|
49323
|
+
provider: "TITAN" /* TITAN */
|
|
49324
|
+
};
|
|
49325
|
+
return {
|
|
49326
|
+
swapInstructions,
|
|
49327
|
+
setupInstructions: [],
|
|
49328
|
+
addressLookupTableAddresses,
|
|
49329
|
+
quoteResponse
|
|
49330
|
+
};
|
|
49331
|
+
}
|
|
49332
|
+
var getTitanExactOutEstimate = async (params) => {
|
|
49333
|
+
const basePath = params.apiConfig?.basePath ?? "";
|
|
49334
|
+
if (basePath.startsWith("wss://") || basePath.startsWith("ws://")) {
|
|
49335
|
+
return getTitanExactOutViaWebSocket(params);
|
|
49336
|
+
} else {
|
|
49337
|
+
return getTitanExactOutViaHttpProxy(params);
|
|
49338
|
+
}
|
|
49339
|
+
};
|
|
49340
|
+
async function getTitanExactOutViaWebSocket(params) {
|
|
49341
|
+
const { inputMint, outputMint, amount, slippageBps, apiConfig } = params;
|
|
49342
|
+
const wsUrl = apiConfig?.basePath;
|
|
49343
|
+
if (!wsUrl) {
|
|
49344
|
+
throw new Error("Titan WebSocket URL is required (apiConfig.basePath)");
|
|
49345
|
+
}
|
|
49346
|
+
const client = await V1Client.connect(wsUrl);
|
|
49347
|
+
try {
|
|
49348
|
+
const { stream } = await client.newSwapQuoteStream({
|
|
49349
|
+
swap: {
|
|
49350
|
+
inputMint: new PublicKey(inputMint).toBytes(),
|
|
49351
|
+
outputMint: new PublicKey(outputMint).toBytes(),
|
|
49352
|
+
amount,
|
|
49353
|
+
swapMode: "ExactOut" /* ExactOut */,
|
|
49354
|
+
slippageBps
|
|
49355
|
+
},
|
|
49356
|
+
transaction: {
|
|
49357
|
+
userPublicKey: new Uint8Array(32)
|
|
49358
|
+
// placeholder, not executing
|
|
49359
|
+
},
|
|
49360
|
+
update: {
|
|
49361
|
+
num_quotes: 1
|
|
49362
|
+
}
|
|
49363
|
+
});
|
|
49364
|
+
const reader = stream.getReader();
|
|
49365
|
+
const { value: swapQuotes, done } = await reader.read();
|
|
49366
|
+
reader.releaseLock();
|
|
49367
|
+
if (done || !swapQuotes) {
|
|
49368
|
+
throw new Error("Titan ExactOut estimate stream ended without data");
|
|
49369
|
+
}
|
|
49370
|
+
const quotes = swapQuotes;
|
|
49371
|
+
const bestRoute = selectBestRoute(quotes.quotes, "ExactOut");
|
|
49372
|
+
if (!bestRoute) {
|
|
49373
|
+
throw new Error(`No Titan ExactOut routes found for ${inputMint} -> ${outputMint}`);
|
|
49374
|
+
}
|
|
49375
|
+
const quoteResult = {
|
|
49376
|
+
...buildSwapQuoteResult(bestRoute, "ExactOut"),
|
|
49377
|
+
provider: "TITAN" /* TITAN */
|
|
49378
|
+
};
|
|
49379
|
+
return {
|
|
49380
|
+
otherAmountThreshold: quoteResult.otherAmountThreshold,
|
|
49381
|
+
quoteResult
|
|
49382
|
+
};
|
|
49383
|
+
} finally {
|
|
49384
|
+
if (!client.closed) {
|
|
49385
|
+
await client.close();
|
|
49386
|
+
}
|
|
49387
|
+
}
|
|
49388
|
+
}
|
|
49389
|
+
async function getTitanExactOutViaHttpProxy(params) {
|
|
49390
|
+
const { inputMint, outputMint, amount, slippageBps, apiConfig } = params;
|
|
49391
|
+
const basePath = apiConfig?.basePath;
|
|
49392
|
+
if (!basePath) {
|
|
49393
|
+
throw new Error("Titan proxy URL is required (apiConfig.basePath)");
|
|
49394
|
+
}
|
|
49395
|
+
const response = await fetch(`${basePath}/exact-out-estimate`, {
|
|
49396
|
+
method: "POST",
|
|
49397
|
+
headers: {
|
|
49398
|
+
"Content-Type": "application/json",
|
|
49399
|
+
...apiConfig?.headers ?? {}
|
|
49400
|
+
},
|
|
49401
|
+
body: JSON.stringify({
|
|
49402
|
+
inputMint,
|
|
49403
|
+
outputMint,
|
|
49404
|
+
amount,
|
|
49405
|
+
slippageBps
|
|
49406
|
+
})
|
|
49407
|
+
});
|
|
49408
|
+
if (!response.ok) {
|
|
49409
|
+
const errorData = await response.json().catch(() => ({}));
|
|
49410
|
+
throw new Error(
|
|
49411
|
+
`Titan proxy error (${response.status}): ${errorData.message ?? response.statusText}`
|
|
49412
|
+
);
|
|
49413
|
+
}
|
|
49414
|
+
const data = await response.json();
|
|
49415
|
+
const quoteResult = {
|
|
49416
|
+
inAmount: String(data.inAmount),
|
|
49417
|
+
outAmount: String(data.outAmount),
|
|
49418
|
+
otherAmountThreshold: data.otherAmountThreshold,
|
|
49419
|
+
slippageBps: data.slippageBps,
|
|
49420
|
+
provider: "TITAN" /* TITAN */
|
|
49421
|
+
};
|
|
49422
|
+
return {
|
|
49423
|
+
otherAmountThreshold: data.otherAmountThreshold,
|
|
49424
|
+
quoteResult
|
|
49425
|
+
};
|
|
49426
|
+
}
|
|
49427
|
+
|
|
49428
|
+
// src/services/account/utils/swap.utils.ts
|
|
49429
|
+
function getSwapProviderFn({
|
|
49430
|
+
attemptProvider,
|
|
49431
|
+
maxSwapTotalAccounts,
|
|
49432
|
+
inputMint,
|
|
49433
|
+
outputMint,
|
|
49434
|
+
amount,
|
|
49435
|
+
swapMode,
|
|
49436
|
+
authority,
|
|
49437
|
+
connection,
|
|
49438
|
+
destinationTokenAccount,
|
|
49439
|
+
swapOpts,
|
|
49440
|
+
sizeConstraint
|
|
49441
|
+
}) {
|
|
49442
|
+
switch (attemptProvider) {
|
|
49443
|
+
case "TITAN" /* TITAN */:
|
|
49444
|
+
return (apiConfig) => getTitanSwapIxsForFlashloan({
|
|
49445
|
+
quoteParams: {
|
|
49446
|
+
inputMint,
|
|
49447
|
+
outputMint,
|
|
49448
|
+
amount,
|
|
49449
|
+
swapMode,
|
|
49450
|
+
slippageBps: swapOpts.swapConfig?.slippageBps,
|
|
49451
|
+
platformFeeBps: swapOpts.swapConfig?.platformFeeBps,
|
|
49452
|
+
directRoutesOnly: swapOpts.swapConfig?.directRoutesOnly,
|
|
49453
|
+
sizeConstraint,
|
|
49454
|
+
maxSwapTotalAccounts
|
|
49455
|
+
},
|
|
49456
|
+
authority,
|
|
49457
|
+
connection,
|
|
49458
|
+
destinationTokenAccount,
|
|
49459
|
+
apiConfig
|
|
49460
|
+
});
|
|
49461
|
+
case "JUPITER" /* JUPITER */:
|
|
49462
|
+
return (apiConfig) => getJupiterSwapIxsForFlashloan({
|
|
49463
|
+
quoteParams: {
|
|
49464
|
+
inputMint,
|
|
49465
|
+
outputMint,
|
|
49466
|
+
amount,
|
|
49467
|
+
swapMode,
|
|
49468
|
+
dynamicSlippage: swapOpts.swapConfig ? swapOpts.swapConfig.slippageMode === "DYNAMIC" : true,
|
|
49469
|
+
slippageBps: swapOpts.swapConfig?.slippageBps,
|
|
49470
|
+
platformFeeBps: swapOpts.swapConfig?.platformFeeBps,
|
|
49471
|
+
onlyDirectRoutes: swapOpts.swapConfig?.directRoutesOnly ?? false
|
|
49472
|
+
},
|
|
49473
|
+
authority,
|
|
49474
|
+
connection,
|
|
49475
|
+
destinationTokenAccount,
|
|
49476
|
+
apiConfig,
|
|
49477
|
+
maxSwapAccounts: maxSwapTotalAccounts
|
|
49478
|
+
});
|
|
49479
|
+
default:
|
|
49480
|
+
return void 0;
|
|
49481
|
+
}
|
|
49482
|
+
}
|
|
49483
|
+
function getExactOutProviderFn({
|
|
49484
|
+
attemptProvider,
|
|
49485
|
+
inputMint,
|
|
49486
|
+
outputMint,
|
|
49487
|
+
amount,
|
|
49488
|
+
swapOpts,
|
|
49489
|
+
apiConfig
|
|
49490
|
+
}) {
|
|
49491
|
+
switch (attemptProvider) {
|
|
49492
|
+
case "TITAN" /* TITAN */:
|
|
49493
|
+
return () => getTitanExactOutEstimate({
|
|
49494
|
+
inputMint,
|
|
49495
|
+
outputMint,
|
|
49496
|
+
amount,
|
|
49497
|
+
slippageBps: swapOpts.swapConfig?.slippageBps,
|
|
49498
|
+
apiConfig
|
|
49499
|
+
});
|
|
49500
|
+
case "JUPITER" /* JUPITER */:
|
|
49501
|
+
return async () => {
|
|
49502
|
+
const configParams = toJupiterConfig(apiConfig);
|
|
49503
|
+
const jupiterApiClient = configParams?.basePath ? new SwapApi(new Configuration(configParams)) : createJupiterApiClient(configParams);
|
|
49504
|
+
const estimateQuote = await jupiterApiClient.quoteGet({
|
|
49505
|
+
inputMint,
|
|
49506
|
+
outputMint,
|
|
49507
|
+
amount,
|
|
49508
|
+
swapMode: "ExactOut",
|
|
49509
|
+
dynamicSlippage: swapOpts.swapConfig ? swapOpts.swapConfig.slippageMode === "DYNAMIC" : true,
|
|
49510
|
+
slippageBps: swapOpts.swapConfig?.slippageBps
|
|
49511
|
+
});
|
|
49512
|
+
const quoteResult = mapJupiterQuoteToSwapQuoteResult(estimateQuote);
|
|
49513
|
+
return { otherAmountThreshold: quoteResult.otherAmountThreshold, quoteResult };
|
|
49514
|
+
};
|
|
49515
|
+
default:
|
|
49516
|
+
return void 0;
|
|
49517
|
+
}
|
|
49518
|
+
}
|
|
49519
|
+
var getSwapIxsForFlashloan = async (params) => {
|
|
49520
|
+
const {
|
|
49521
|
+
inputMint,
|
|
49522
|
+
outputMint,
|
|
49523
|
+
amount,
|
|
49524
|
+
swapMode,
|
|
49525
|
+
authority,
|
|
49526
|
+
connection,
|
|
49527
|
+
destinationTokenAccount,
|
|
49528
|
+
swapOpts,
|
|
49529
|
+
sizeConstraint,
|
|
49530
|
+
maxSwapTotalAccounts
|
|
49531
|
+
} = params;
|
|
49532
|
+
if (swapOpts.swapIxs) {
|
|
49533
|
+
return {
|
|
49534
|
+
swapInstructions: swapOpts.swapIxs.instructions,
|
|
49535
|
+
setupInstructions: [],
|
|
49536
|
+
addressLookupTableAddresses: swapOpts.swapIxs.lookupTables,
|
|
49537
|
+
quoteResponse: {
|
|
49538
|
+
inAmount: String(amount),
|
|
49539
|
+
outAmount: "0",
|
|
49540
|
+
otherAmountThreshold: "0",
|
|
49541
|
+
slippageBps: 0
|
|
49542
|
+
}
|
|
49543
|
+
};
|
|
49544
|
+
}
|
|
49545
|
+
const provider = swapOpts.swapConfig?.provider ?? "JUPITER" /* JUPITER */;
|
|
49546
|
+
const attempts = [
|
|
49547
|
+
{ provider, apiConfig: swapOpts.swapConfig?.apiConfig },
|
|
49548
|
+
...swapOpts.swapConfig?.fallbackProviders ?? []
|
|
49549
|
+
];
|
|
49550
|
+
let lastError;
|
|
49551
|
+
for (const { provider: attemptProvider, apiConfig } of attempts) {
|
|
49552
|
+
const fn = getSwapProviderFn({
|
|
49553
|
+
attemptProvider,
|
|
49554
|
+
maxSwapTotalAccounts: params.maxSwapTotalAccounts,
|
|
49555
|
+
inputMint,
|
|
49556
|
+
outputMint,
|
|
49557
|
+
amount,
|
|
49558
|
+
swapMode,
|
|
49559
|
+
authority,
|
|
49560
|
+
connection,
|
|
49561
|
+
destinationTokenAccount,
|
|
49562
|
+
swapOpts,
|
|
49563
|
+
sizeConstraint
|
|
49564
|
+
});
|
|
49565
|
+
if (!fn) continue;
|
|
49566
|
+
try {
|
|
49567
|
+
return await fn(apiConfig);
|
|
49568
|
+
} catch (err) {
|
|
49569
|
+
if (err instanceof TransactionBuildingError) throw err;
|
|
49570
|
+
lastError = err;
|
|
49571
|
+
console.warn(`[swap] ${attemptProvider} failed:`, err instanceof Error ? err.message : err);
|
|
49572
|
+
}
|
|
49573
|
+
}
|
|
49574
|
+
const firstProvider = attempts[0]?.provider ?? "Swap";
|
|
49575
|
+
throw TransactionBuildingError.swapQuoteFailed(
|
|
49576
|
+
firstProvider,
|
|
49577
|
+
inputMint,
|
|
49578
|
+
outputMint,
|
|
49579
|
+
lastError?.message ?? "No swap route available"
|
|
49580
|
+
);
|
|
49581
|
+
};
|
|
49582
|
+
var getExactOutEstimate = async (params) => {
|
|
49583
|
+
const { inputMint, outputMint, amount, swapOpts, connection } = params;
|
|
49584
|
+
const provider = swapOpts.swapConfig?.provider ?? "JUPITER" /* JUPITER */;
|
|
49585
|
+
const attempts = [
|
|
49586
|
+
{ provider, apiConfig: swapOpts.swapConfig?.apiConfig },
|
|
49587
|
+
...swapOpts.swapConfig?.fallbackProviders ?? []
|
|
49588
|
+
];
|
|
49589
|
+
let lastError;
|
|
49590
|
+
for (const { provider: attemptProvider, apiConfig } of attempts) {
|
|
49591
|
+
const fn = getExactOutProviderFn({
|
|
49592
|
+
attemptProvider,
|
|
49593
|
+
inputMint,
|
|
49594
|
+
outputMint,
|
|
49595
|
+
amount,
|
|
49596
|
+
swapOpts,
|
|
49597
|
+
apiConfig
|
|
49598
|
+
});
|
|
49599
|
+
if (!fn) continue;
|
|
49600
|
+
try {
|
|
49601
|
+
return await fn(apiConfig);
|
|
49602
|
+
} catch (err) {
|
|
49603
|
+
if (err instanceof TransactionBuildingError) throw err;
|
|
49604
|
+
lastError = err;
|
|
49605
|
+
console.warn(
|
|
49606
|
+
`[exactout] ${attemptProvider} failed:`,
|
|
49607
|
+
err instanceof Error ? err.message : err
|
|
49608
|
+
);
|
|
49609
|
+
}
|
|
49610
|
+
}
|
|
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
|
|
48862
49637
|
var REFERRAL_PROGRAM_ID = new PublicKey("REFER4ZgmyYx9c6He5XfaTMiGfdLwRnkV4RPp9t9iF3");
|
|
48863
49638
|
var REFERRAL_ACCOUNT_PUBKEY = new PublicKey("Mm7HcujSK2JzPW4eX7g4oqTXbWYDuFxapNMHXe8yp1B");
|
|
48864
49639
|
var getFeeAccount = (mint) => {
|
|
48865
|
-
const referralProgramPubkey = REFERRAL_PROGRAM_ID;
|
|
48866
|
-
const referralAccountPubkey = REFERRAL_ACCOUNT_PUBKEY;
|
|
48867
49640
|
const [feeAccount] = PublicKey.findProgramAddressSync(
|
|
48868
|
-
[Buffer.from("referral_ata"),
|
|
48869
|
-
|
|
49641
|
+
[Buffer.from("referral_ata"), REFERRAL_ACCOUNT_PUBKEY.toBuffer(), mint.toBuffer()],
|
|
49642
|
+
REFERRAL_PROGRAM_ID
|
|
48870
49643
|
);
|
|
48871
49644
|
return feeAccount.toBase58();
|
|
48872
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
|
+
};
|
|
48873
49651
|
function deserializeJupiterInstruction(instruction) {
|
|
48874
49652
|
return new TransactionInstruction({
|
|
48875
49653
|
programId: new PublicKey(instruction.programId),
|
|
@@ -48881,17 +49659,26 @@ function deserializeJupiterInstruction(instruction) {
|
|
|
48881
49659
|
data: Buffer.from(instruction.data, "base64")
|
|
48882
49660
|
});
|
|
48883
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
|
+
}
|
|
48884
49670
|
var getJupiterSwapIxsForFlashloan = async ({
|
|
48885
49671
|
quoteParams,
|
|
48886
49672
|
authority,
|
|
48887
49673
|
connection,
|
|
48888
49674
|
destinationTokenAccount,
|
|
48889
|
-
|
|
49675
|
+
apiConfig,
|
|
49676
|
+
maxSwapAccounts
|
|
48890
49677
|
}) => {
|
|
49678
|
+
const configParams = toJupiterConfig(apiConfig);
|
|
48891
49679
|
const jupiterApiClient = configParams?.basePath ? new SwapApi(new Configuration(configParams)) : createJupiterApiClient(configParams);
|
|
48892
49680
|
const feeMint = quoteParams.swapMode === "ExactIn" ? quoteParams.outputMint : quoteParams.inputMint;
|
|
48893
|
-
const feeAccount =
|
|
48894
|
-
const hasFeeAccount = !!await connection.getAccountInfo(new PublicKey(feeAccount));
|
|
49681
|
+
const { feeAccount, hasFeeAccount } = await checkFeeAccount(connection, new PublicKey(feeMint));
|
|
48895
49682
|
const project0JupiterLut = (await connection.getAddressLookupTable(ADDRESS_LOOKUP_TABLE_FOR_SWAP))?.value;
|
|
48896
49683
|
let finalQuoteParams = quoteParams;
|
|
48897
49684
|
if (!hasFeeAccount) {
|
|
@@ -48901,67 +49688,45 @@ var getJupiterSwapIxsForFlashloan = async ({
|
|
|
48901
49688
|
platformFeeBps: void 0
|
|
48902
49689
|
};
|
|
48903
49690
|
}
|
|
48904
|
-
const
|
|
48905
|
-
const
|
|
48906
|
-
|
|
48907
|
-
|
|
48908
|
-
|
|
48909
|
-
|
|
48910
|
-
|
|
48911
|
-
|
|
48912
|
-
|
|
48913
|
-
|
|
48914
|
-
|
|
48915
|
-
|
|
48916
|
-
|
|
48917
|
-
|
|
48918
|
-
|
|
48919
|
-
|
|
48920
|
-
feeAccount: hasFeeAccount ? feeAccount : void 0,
|
|
48921
|
-
wrapAndUnwrapSol: false,
|
|
48922
|
-
destinationTokenAccount: destinationTokenAccount.toBase58()
|
|
48923
|
-
}
|
|
48924
|
-
})
|
|
48925
|
-
)
|
|
48926
|
-
);
|
|
48927
|
-
const lutAddresses = swapInstructionResponses.map(
|
|
48928
|
-
(swapInstructionResponse) => swapInstructionResponse.addressLookupTableAddresses
|
|
48929
|
-
);
|
|
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;
|
|
48930
49707
|
const lutAccountsRaw = await connection.getMultipleAccountsInfo(
|
|
48931
|
-
lutAddresses.
|
|
49708
|
+
lutAddresses.map((address) => new PublicKey(address))
|
|
48932
49709
|
);
|
|
48933
|
-
|
|
48934
|
-
|
|
48935
|
-
|
|
48936
|
-
|
|
48937
|
-
|
|
48938
|
-
|
|
48939
|
-
|
|
48940
|
-
|
|
48941
|
-
const addressesStartIndex = currentIndex;
|
|
48942
|
-
const addressesEndIndex = addressesStartIndex + addressesLength;
|
|
48943
|
-
currentIndex = addressesEndIndex;
|
|
48944
|
-
const lutAccounts = lutAccountsRaw.slice(addressesStartIndex, addressesEndIndex);
|
|
48945
|
-
const addressLookupTableAccounts = lutAccounts.map((accountInfo, index) => {
|
|
48946
|
-
const addressLookupTableAddress = address[index];
|
|
48947
|
-
if (!accountInfo || !addressLookupTableAddress) {
|
|
48948
|
-
return null;
|
|
48949
|
-
}
|
|
48950
|
-
return new AddressLookupTableAccount({
|
|
48951
|
-
key: new PublicKey(addressLookupTableAddress),
|
|
48952
|
-
state: AddressLookupTableAccount.deserialize(accountInfo.data)
|
|
48953
|
-
});
|
|
48954
|
-
}).filter((account) => account !== null).concat(project0JupiterLut ? [project0JupiterLut] : []);
|
|
48955
|
-
const instruction = deserializeJupiterInstruction(response.swapInstruction);
|
|
48956
|
-
const setupInstructions = response.setupInstructions.map(deserializeJupiterInstruction);
|
|
48957
|
-
jupiterSwapIxs.push({
|
|
48958
|
-
swapInstruction: instruction,
|
|
48959
|
-
setupInstructions,
|
|
48960
|
-
addressLookupTableAddresses: addressLookupTableAccounts,
|
|
48961
|
-
quoteResponse: quote
|
|
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)
|
|
48962
49718
|
});
|
|
48963
|
-
}
|
|
48964
|
-
|
|
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
|
+
};
|
|
48965
49730
|
};
|
|
48966
49731
|
|
|
48967
49732
|
// src/services/account/utils/misc.utils.ts
|
|
@@ -48979,6 +49744,440 @@ function isWholePosition(position, amount, mintDecimals) {
|
|
|
48979
49744
|
const closePositionTokenAmount = computeClosePositionTokenAmount(position, mintDecimals);
|
|
48980
49745
|
return amount >= closePositionTokenAmount;
|
|
48981
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
|
+
}
|
|
50051
|
+
}
|
|
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
|
+
});
|
|
50078
|
+
}
|
|
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
|
+
});
|
|
50102
|
+
}
|
|
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
|
+
}
|
|
50140
|
+
}
|
|
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
|
+
});
|
|
50180
|
+
}
|
|
48982
50181
|
|
|
48983
50182
|
// src/services/price/utils/smart-crank.utils.ts
|
|
48984
50183
|
async function computeSmartCrank({
|
|
@@ -50182,7 +51381,7 @@ function computeMaxLeverage(depositBank, borrowBank, opts) {
|
|
|
50182
51381
|
ltv
|
|
50183
51382
|
};
|
|
50184
51383
|
}
|
|
50185
|
-
function computeLoopingParams(principal, targetLeverage, depositBank, borrowBank,
|
|
51384
|
+
function computeLoopingParams(principal, targetLeverage, depositBank, borrowBank, depositPriceUsd, borrowPriceUsd, opts) {
|
|
50186
51385
|
const initialCollateral = toBigNumber(principal);
|
|
50187
51386
|
const { maxLeverage } = computeMaxLeverage(depositBank, borrowBank, opts);
|
|
50188
51387
|
let clampedLeverage = targetLeverage;
|
|
@@ -50197,7 +51396,7 @@ function computeLoopingParams(principal, targetLeverage, depositBank, borrowBank
|
|
|
50197
51396
|
}
|
|
50198
51397
|
const totalDepositAmount = initialCollateral.times(new BigNumber3(clampedLeverage));
|
|
50199
51398
|
const additionalDepositAmount = totalDepositAmount.minus(initialCollateral);
|
|
50200
|
-
const totalBorrowAmount = additionalDepositAmount.times(
|
|
51399
|
+
const totalBorrowAmount = additionalDepositAmount.times(new BigNumber3(depositPriceUsd)).div(new BigNumber3(borrowPriceUsd));
|
|
50201
51400
|
return {
|
|
50202
51401
|
totalBorrowAmount: totalBorrowAmount.decimalPlaces(
|
|
50203
51402
|
borrowBank.mintDecimals,
|
|
@@ -51241,6 +52440,230 @@ function getValidatorVoteAccountByBank() {
|
|
|
51241
52440
|
}
|
|
51242
52441
|
return _voteAccountByBank;
|
|
51243
52442
|
}
|
|
52443
|
+
async function computeStakedBankMultipliers(stakedBanks, connection) {
|
|
52444
|
+
const multiplierByBank = /* @__PURE__ */ new Map();
|
|
52445
|
+
if (stakedBanks.length === 0) {
|
|
52446
|
+
return multiplierByBank;
|
|
52447
|
+
}
|
|
52448
|
+
const metadataMap = getStakedBankMetadataMap();
|
|
52449
|
+
const stakedBankAddresses = [];
|
|
52450
|
+
const poolStakeAddresses = [];
|
|
52451
|
+
const lstMintAddresses = [];
|
|
52452
|
+
for (const bank of stakedBanks) {
|
|
52453
|
+
const metadata = metadataMap.get(bank.address.toBase58());
|
|
52454
|
+
if (!metadata) {
|
|
52455
|
+
multiplierByBank.set(bank.address.toBase58(), new BigNumber3(1));
|
|
52456
|
+
continue;
|
|
52457
|
+
}
|
|
52458
|
+
const pool = findPoolAddress(new PublicKey(metadata.validatorVoteAccount));
|
|
52459
|
+
stakedBankAddresses.push(bank.address.toBase58());
|
|
52460
|
+
poolStakeAddresses.push(findPoolStakeAddress(pool));
|
|
52461
|
+
lstMintAddresses.push(findPoolMintAddress(pool));
|
|
52462
|
+
}
|
|
52463
|
+
if (stakedBankAddresses.length === 0) {
|
|
52464
|
+
return multiplierByBank;
|
|
52465
|
+
}
|
|
52466
|
+
const allAddresses = [
|
|
52467
|
+
...poolStakeAddresses.map((a) => a.toBase58()),
|
|
52468
|
+
...lstMintAddresses.map((a) => a.toBase58())
|
|
52469
|
+
];
|
|
52470
|
+
const accountInfos = await chunkedGetRawMultipleAccountInfoOrdered(connection, allAddresses);
|
|
52471
|
+
const poolStakeInfos = accountInfos.slice(0, poolStakeAddresses.length);
|
|
52472
|
+
const lstMintInfos = accountInfos.slice(poolStakeAddresses.length);
|
|
52473
|
+
for (let i = 0; i < stakedBankAddresses.length; i++) {
|
|
52474
|
+
const bankAddr = stakedBankAddresses[i];
|
|
52475
|
+
const poolStakeInfo = poolStakeInfos[i];
|
|
52476
|
+
const lstMintInfo = lstMintInfos[i];
|
|
52477
|
+
if (!poolStakeInfo || !lstMintInfo) {
|
|
52478
|
+
multiplierByBank.set(bankAddr, new BigNumber3(1));
|
|
52479
|
+
continue;
|
|
52480
|
+
}
|
|
52481
|
+
const stakeLamports = poolStakeInfo.lamports;
|
|
52482
|
+
const supplyBuffer = lstMintInfo.data.slice(36, 44);
|
|
52483
|
+
const lstMintSupply = Number(Buffer.from(supplyBuffer).readBigUInt64LE(0));
|
|
52484
|
+
if (lstMintSupply === 0) {
|
|
52485
|
+
multiplierByBank.set(bankAddr, new BigNumber3(1));
|
|
52486
|
+
continue;
|
|
52487
|
+
}
|
|
52488
|
+
const adjustedStake = Math.max(stakeLamports - LAMPORTS_PER_SOL, 0);
|
|
52489
|
+
const multiplier = new BigNumber3(adjustedStake).dividedBy(lstMintSupply);
|
|
52490
|
+
multiplierByBank.set(bankAddr, multiplier);
|
|
52491
|
+
}
|
|
52492
|
+
return multiplierByBank;
|
|
52493
|
+
}
|
|
52494
|
+
var SYSVAR_CLOCK_ID2 = new PublicKey("SysvarC1ock11111111111111111111111111111111");
|
|
52495
|
+
async function makeMintStakedLstIx(params) {
|
|
52496
|
+
const { amount, authority, stakeAccountPk, validator, connection } = params;
|
|
52497
|
+
const pool = findPoolAddress(validator);
|
|
52498
|
+
const lstMint = findPoolMintAddress(pool);
|
|
52499
|
+
const poolStakeAuth = findPoolStakeAuthorityAddress(pool);
|
|
52500
|
+
const lstAta = getAssociatedTokenAddressSync(lstMint, authority);
|
|
52501
|
+
const [lstAccInfo, stakeAccInfoParsed, rentExemptReserve] = await Promise.all([
|
|
52502
|
+
connection.getAccountInfo(lstAta),
|
|
52503
|
+
connection.getParsedAccountInfo(stakeAccountPk),
|
|
52504
|
+
connection.getMinimumBalanceForRentExemption(StakeProgram.space)
|
|
52505
|
+
]);
|
|
52506
|
+
const stakeAccParsed = stakeAccInfoParsed?.value?.data;
|
|
52507
|
+
const amountLamports = Math.round(Number(amount) * LAMPORTS_PER_SOL);
|
|
52508
|
+
const stakeAccLamports = Number(stakeAccParsed?.parsed?.info?.stake?.delegation?.stake ?? 0);
|
|
52509
|
+
const isFullStake = amountLamports >= stakeAccLamports;
|
|
52510
|
+
const instructions2 = [];
|
|
52511
|
+
const signers = [];
|
|
52512
|
+
if (!lstAccInfo) {
|
|
52513
|
+
instructions2.push(
|
|
52514
|
+
createAssociatedTokenAccountInstruction(authority, lstAta, authority, lstMint)
|
|
52515
|
+
);
|
|
52516
|
+
}
|
|
52517
|
+
let targetStakePubkey;
|
|
52518
|
+
if (!isFullStake) {
|
|
52519
|
+
const splitStakeAccount = Keypair.generate();
|
|
52520
|
+
signers.push(splitStakeAccount);
|
|
52521
|
+
targetStakePubkey = splitStakeAccount.publicKey;
|
|
52522
|
+
instructions2.push(
|
|
52523
|
+
...StakeProgram.split(
|
|
52524
|
+
{
|
|
52525
|
+
stakePubkey: stakeAccountPk,
|
|
52526
|
+
authorizedPubkey: authority,
|
|
52527
|
+
splitStakePubkey: splitStakeAccount.publicKey,
|
|
52528
|
+
lamports: amountLamports
|
|
52529
|
+
},
|
|
52530
|
+
rentExemptReserve
|
|
52531
|
+
).instructions
|
|
52532
|
+
);
|
|
52533
|
+
} else {
|
|
52534
|
+
targetStakePubkey = stakeAccountPk;
|
|
52535
|
+
}
|
|
52536
|
+
const [authorizeStakerIx, authorizeWithdrawIx] = await Promise.all([
|
|
52537
|
+
StakeProgram.authorize({
|
|
52538
|
+
stakePubkey: targetStakePubkey,
|
|
52539
|
+
authorizedPubkey: authority,
|
|
52540
|
+
newAuthorizedPubkey: poolStakeAuth,
|
|
52541
|
+
stakeAuthorizationType: StakeAuthorizationLayout.Staker
|
|
52542
|
+
}).instructions,
|
|
52543
|
+
StakeProgram.authorize({
|
|
52544
|
+
stakePubkey: targetStakePubkey,
|
|
52545
|
+
authorizedPubkey: authority,
|
|
52546
|
+
newAuthorizedPubkey: poolStakeAuth,
|
|
52547
|
+
stakeAuthorizationType: StakeAuthorizationLayout.Withdrawer
|
|
52548
|
+
}).instructions
|
|
52549
|
+
]);
|
|
52550
|
+
[authorizeStakerIx[0], authorizeWithdrawIx[0]].forEach((ix) => {
|
|
52551
|
+
if (ix) {
|
|
52552
|
+
ix.keys = ix.keys.map((key) => ({
|
|
52553
|
+
...key,
|
|
52554
|
+
isWritable: key.pubkey.equals(SYSVAR_CLOCK_ID2) ? false : key.isWritable
|
|
52555
|
+
}));
|
|
52556
|
+
}
|
|
52557
|
+
});
|
|
52558
|
+
instructions2.push(...authorizeStakerIx, ...authorizeWithdrawIx);
|
|
52559
|
+
const depositStakeIx = await SinglePoolInstruction.depositStake(
|
|
52560
|
+
pool,
|
|
52561
|
+
targetStakePubkey,
|
|
52562
|
+
lstAta,
|
|
52563
|
+
authority
|
|
52564
|
+
);
|
|
52565
|
+
instructions2.push(depositStakeIx);
|
|
52566
|
+
return { instructions: instructions2, keys: signers };
|
|
52567
|
+
}
|
|
52568
|
+
async function makeMintStakedLstTx(params) {
|
|
52569
|
+
const { connection, luts, blockhash: providedBlockhash } = params;
|
|
52570
|
+
const { instructions: instructions2, keys } = await makeMintStakedLstIx(params);
|
|
52571
|
+
const blockhash = providedBlockhash ?? (await connection.getLatestBlockhash("confirmed")).blockhash;
|
|
52572
|
+
const message = new TransactionMessage({
|
|
52573
|
+
payerKey: params.authority,
|
|
52574
|
+
recentBlockhash: blockhash,
|
|
52575
|
+
instructions: instructions2
|
|
52576
|
+
}).compileToV0Message(luts);
|
|
52577
|
+
const tx = new VersionedTransaction(message);
|
|
52578
|
+
return addTransactionMetadata(tx, {
|
|
52579
|
+
signers: keys,
|
|
52580
|
+
addressLookupTables: luts,
|
|
52581
|
+
type: "DEPOSIT_STAKE" /* DEPOSIT_STAKE */
|
|
52582
|
+
});
|
|
52583
|
+
}
|
|
52584
|
+
async function makeRedeemStakedLstIx(params) {
|
|
52585
|
+
const { amount, authority, validator, connection } = params;
|
|
52586
|
+
const pool = findPoolAddress(validator);
|
|
52587
|
+
const lstMint = findPoolMintAddress(pool);
|
|
52588
|
+
const mintAuthority = findPoolMintAuthorityAddress(pool);
|
|
52589
|
+
const lstAta = getAssociatedTokenAddressSync(lstMint, authority);
|
|
52590
|
+
const rentExemption = await connection.getMinimumBalanceForRentExemption(
|
|
52591
|
+
StakeProgram.space
|
|
52592
|
+
);
|
|
52593
|
+
const stakeAmount = new BigNumber3(new BigNumber3(amount).toString());
|
|
52594
|
+
const instructions2 = [];
|
|
52595
|
+
const signers = [];
|
|
52596
|
+
const stakeAccount = Keypair.generate();
|
|
52597
|
+
signers.push(stakeAccount);
|
|
52598
|
+
instructions2.push(
|
|
52599
|
+
SystemProgram.createAccount({
|
|
52600
|
+
fromPubkey: authority,
|
|
52601
|
+
newAccountPubkey: stakeAccount.publicKey,
|
|
52602
|
+
lamports: rentExemption,
|
|
52603
|
+
space: StakeProgram.space,
|
|
52604
|
+
programId: StakeProgram.programId
|
|
52605
|
+
})
|
|
52606
|
+
);
|
|
52607
|
+
instructions2.push(
|
|
52608
|
+
createApproveInstruction(
|
|
52609
|
+
lstAta,
|
|
52610
|
+
mintAuthority,
|
|
52611
|
+
authority,
|
|
52612
|
+
BigInt(stakeAmount.multipliedBy(1e9).toFixed(0))
|
|
52613
|
+
)
|
|
52614
|
+
);
|
|
52615
|
+
const withdrawStakeIx = await SinglePoolInstruction.withdrawStake(
|
|
52616
|
+
pool,
|
|
52617
|
+
stakeAccount.publicKey,
|
|
52618
|
+
authority,
|
|
52619
|
+
lstAta,
|
|
52620
|
+
stakeAmount
|
|
52621
|
+
);
|
|
52622
|
+
instructions2.push(withdrawStakeIx);
|
|
52623
|
+
return { instructions: instructions2, keys: signers };
|
|
52624
|
+
}
|
|
52625
|
+
async function makeRedeemStakedLstTx(params) {
|
|
52626
|
+
const { connection, luts, blockhash: providedBlockhash } = params;
|
|
52627
|
+
const { instructions: instructions2, keys } = await makeRedeemStakedLstIx(params);
|
|
52628
|
+
const blockhash = providedBlockhash ?? (await connection.getLatestBlockhash("confirmed")).blockhash;
|
|
52629
|
+
const message = new TransactionMessage({
|
|
52630
|
+
payerKey: params.authority,
|
|
52631
|
+
recentBlockhash: blockhash,
|
|
52632
|
+
instructions: instructions2
|
|
52633
|
+
}).compileToV0Message(luts);
|
|
52634
|
+
const tx = new VersionedTransaction(message);
|
|
52635
|
+
return addTransactionMetadata(tx, {
|
|
52636
|
+
signers: keys,
|
|
52637
|
+
addressLookupTables: luts,
|
|
52638
|
+
type: "WITHDRAW_STAKE" /* WITHDRAW_STAKE */
|
|
52639
|
+
});
|
|
52640
|
+
}
|
|
52641
|
+
async function makeMergeStakeAccountsTx(params) {
|
|
52642
|
+
const {
|
|
52643
|
+
authority,
|
|
52644
|
+
sourceStakeAccount,
|
|
52645
|
+
destinationStakeAccount,
|
|
52646
|
+
connection,
|
|
52647
|
+
luts,
|
|
52648
|
+
blockhash: providedBlockhash
|
|
52649
|
+
} = params;
|
|
52650
|
+
const mergeIx = StakeProgram.merge({
|
|
52651
|
+
stakePubkey: destinationStakeAccount,
|
|
52652
|
+
sourceStakePubKey: sourceStakeAccount,
|
|
52653
|
+
authorizedPubkey: authority
|
|
52654
|
+
}).instructions;
|
|
52655
|
+
const blockhash = providedBlockhash ?? (await connection.getLatestBlockhash("confirmed")).blockhash;
|
|
52656
|
+
const message = new TransactionMessage({
|
|
52657
|
+
payerKey: authority,
|
|
52658
|
+
recentBlockhash: blockhash,
|
|
52659
|
+
instructions: mergeIx
|
|
52660
|
+
}).compileToV0Message(luts);
|
|
52661
|
+
const tx = new VersionedTransaction(message);
|
|
52662
|
+
return addTransactionMetadata(tx, {
|
|
52663
|
+
addressLookupTables: luts,
|
|
52664
|
+
type: "MERGE_STAKE_ACCOUNTS" /* MERGE_STAKE_ACCOUNTS */
|
|
52665
|
+
});
|
|
52666
|
+
}
|
|
51244
52667
|
async function getKaminoMetadata(options) {
|
|
51245
52668
|
const kaminoBanks = options.banks.filter((b) => b.config.assetTag === 3 /* KAMINO */);
|
|
51246
52669
|
const DEFAULT_PUBKEY = PublicKey.default;
|
|
@@ -52664,7 +54087,7 @@ var MarginfiAccount = class _MarginfiAccount {
|
|
|
52664
54087
|
* @param params.oraclePrices - Map of current oracle prices
|
|
52665
54088
|
* @param params.depositOpts - Deposit configuration (bank, amount, mode)
|
|
52666
54089
|
* @param params.borrowOpts - Borrow configuration (bank, amount)
|
|
52667
|
-
* @param params.swapOpts -
|
|
54090
|
+
* @param params.swapOpts - Swap configuration (venue, slippage, fees)
|
|
52668
54091
|
* @param params.addressLookupTableAccounts - Address lookup tables
|
|
52669
54092
|
* @param params.overrideInferAccounts - Optional account overrides
|
|
52670
54093
|
* @param params.additionalIxs - Additional instructions to include
|
|
@@ -52702,7 +54125,7 @@ var MarginfiAccount = class _MarginfiAccount {
|
|
|
52702
54125
|
* @param params.oraclePrices - Map of current oracle prices
|
|
52703
54126
|
* @param params.withdrawOpts - Withdraw configuration (bank, amount)
|
|
52704
54127
|
* @param params.repayOpts - Repay configuration (bank, optional amount)
|
|
52705
|
-
* @param params.swapOpts -
|
|
54128
|
+
* @param params.swapOpts - Swap configuration (venue, slippage, fees)
|
|
52706
54129
|
* @param params.addressLookupTableAccounts - Address lookup tables
|
|
52707
54130
|
* @param params.overrideInferAccounts - Optional account overrides
|
|
52708
54131
|
* @param params.additionalIxs - Additional instructions to include
|
|
@@ -52742,7 +54165,7 @@ var MarginfiAccount = class _MarginfiAccount {
|
|
|
52742
54165
|
* @param params.oraclePrices - Map of current oracle prices
|
|
52743
54166
|
* @param params.withdrawOpts - Withdraw configuration (bank, amount, tokenProgram)
|
|
52744
54167
|
* @param params.depositOpts - Deposit configuration (bank, tokenProgram)
|
|
52745
|
-
* @param params.swapOpts -
|
|
54168
|
+
* @param params.swapOpts - Swap configuration (venue, slippage, fees)
|
|
52746
54169
|
* @param params.addressLookupTableAccounts - Address lookup tables
|
|
52747
54170
|
* @param params.overrideInferAccounts - Optional account overrides
|
|
52748
54171
|
* @param params.additionalIxs - Additional instructions to include
|
|
@@ -52782,7 +54205,7 @@ var MarginfiAccount = class _MarginfiAccount {
|
|
|
52782
54205
|
* @param params.oraclePrices - Map of current oracle prices
|
|
52783
54206
|
* @param params.repayOpts - Repay configuration (bank, amount, tokenProgram)
|
|
52784
54207
|
* @param params.borrowOpts - Borrow configuration (bank, tokenProgram)
|
|
52785
|
-
* @param params.swapOpts -
|
|
54208
|
+
* @param params.swapOpts - Swap configuration (venue, slippage, fees)
|
|
52786
54209
|
* @param params.addressLookupTableAccounts - Address lookup tables
|
|
52787
54210
|
* @param params.overrideInferAccounts - Optional account overrides
|
|
52788
54211
|
* @param params.additionalIxs - Additional instructions to include
|
|
@@ -53677,66 +55100,6 @@ var MarginfiAccountWrapper = class {
|
|
|
53677
55100
|
return this.account.getHealthCheckAccounts(this.client.bankMap, mandatoryBanks, excludedBanks);
|
|
53678
55101
|
}
|
|
53679
55102
|
// ----------------------------------------------------------------------------
|
|
53680
|
-
// Native stake actions
|
|
53681
|
-
// Note: These call standalone action functions directly rather than routing
|
|
53682
|
-
// through this.account because they interact with the SPL stake pool program,
|
|
53683
|
-
// not the marginfi program. No MarginfiAccount state is needed.
|
|
53684
|
-
// ----------------------------------------------------------------------------
|
|
53685
|
-
/**
|
|
53686
|
-
* Creates a transaction to mint LST from a native stake account.
|
|
53687
|
-
*
|
|
53688
|
-
* Converts a native stake account (or a portion of it) into LST tokens
|
|
53689
|
-
* by depositing the stake into the single-validator pool.
|
|
53690
|
-
*
|
|
53691
|
-
* @param amount - SOL amount to convert (in UI units)
|
|
53692
|
-
* @param stakeAccountPk - The stake account to convert
|
|
53693
|
-
* @param validator - The validator vote account
|
|
53694
|
-
*/
|
|
53695
|
-
async makeMintStakedLstTx(amount, stakeAccountPk, validator) {
|
|
53696
|
-
return makeMintStakedLstTx({
|
|
53697
|
-
amount,
|
|
53698
|
-
authority: this.authority,
|
|
53699
|
-
stakeAccountPk,
|
|
53700
|
-
validator,
|
|
53701
|
-
connection: this.client.program.provider.connection,
|
|
53702
|
-
luts: this.client.addressLookupTables
|
|
53703
|
-
});
|
|
53704
|
-
}
|
|
53705
|
-
/**
|
|
53706
|
-
* Creates a transaction to redeem LST tokens back to a native stake account.
|
|
53707
|
-
*
|
|
53708
|
-
* Burns LST tokens and withdraws the underlying stake into a new stake account.
|
|
53709
|
-
*
|
|
53710
|
-
* @param amount - LST amount to redeem (in UI units)
|
|
53711
|
-
* @param validator - The validator vote account
|
|
53712
|
-
*/
|
|
53713
|
-
async makeRedeemStakedLstTx(amount, validator) {
|
|
53714
|
-
return makeRedeemStakedLstTx({
|
|
53715
|
-
amount,
|
|
53716
|
-
authority: this.authority,
|
|
53717
|
-
validator,
|
|
53718
|
-
connection: this.client.program.provider.connection,
|
|
53719
|
-
luts: this.client.addressLookupTables
|
|
53720
|
-
});
|
|
53721
|
-
}
|
|
53722
|
-
/**
|
|
53723
|
-
* Creates a transaction to merge two stake accounts.
|
|
53724
|
-
*
|
|
53725
|
-
* Both accounts must share the same authorized staker/withdrawer and vote account.
|
|
53726
|
-
*
|
|
53727
|
-
* @param sourceStakeAccount - The stake account to merge from (will be consumed)
|
|
53728
|
-
* @param destinationStakeAccount - The stake account to merge into
|
|
53729
|
-
*/
|
|
53730
|
-
async makeMergeStakeAccountsTx(sourceStakeAccount, destinationStakeAccount) {
|
|
53731
|
-
return makeMergeStakeAccountsTx({
|
|
53732
|
-
authority: this.authority,
|
|
53733
|
-
sourceStakeAccount,
|
|
53734
|
-
destinationStakeAccount,
|
|
53735
|
-
connection: this.client.program.provider.connection,
|
|
53736
|
-
luts: this.client.addressLookupTables
|
|
53737
|
-
});
|
|
53738
|
-
}
|
|
53739
|
-
// ----------------------------------------------------------------------------
|
|
53740
55103
|
// Helper methods
|
|
53741
55104
|
// ----------------------------------------------------------------------------
|
|
53742
55105
|
/**
|
|
@@ -54006,56 +55369,11 @@ var Project0Client = class _Project0Client {
|
|
|
54006
55369
|
break;
|
|
54007
55370
|
}
|
|
54008
55371
|
});
|
|
54009
|
-
const
|
|
54010
|
-
|
|
54011
|
-
|
|
54012
|
-
|
|
54013
|
-
|
|
54014
|
-
const lstMintAddresses = [];
|
|
54015
|
-
for (const bank of stakedBanks) {
|
|
54016
|
-
const metadata = metadataMap.get(bank.address.toBase58());
|
|
54017
|
-
if (!metadata) {
|
|
54018
|
-
assetShareMultiplierByBank.set(bank.address.toBase58(), new BigNumber3(1));
|
|
54019
|
-
continue;
|
|
54020
|
-
}
|
|
54021
|
-
const pool = findPoolAddress(new PublicKey(metadata.validatorVoteAccount));
|
|
54022
|
-
stakedBankAddresses.push(bank.address.toBase58());
|
|
54023
|
-
poolStakeAddresses.push(findPoolStakeAddress(pool));
|
|
54024
|
-
lstMintAddresses.push(findPoolMintAddress(pool));
|
|
54025
|
-
}
|
|
54026
|
-
if (stakedBankAddresses.length > 0) {
|
|
54027
|
-
const allAddresses = [
|
|
54028
|
-
...poolStakeAddresses.map((a) => a.toBase58()),
|
|
54029
|
-
...lstMintAddresses.map((a) => a.toBase58())
|
|
54030
|
-
];
|
|
54031
|
-
const accountInfos = await chunkedGetRawMultipleAccountInfoOrdered(
|
|
54032
|
-
connection,
|
|
54033
|
-
allAddresses
|
|
54034
|
-
);
|
|
54035
|
-
const poolStakeInfos = accountInfos.slice(0, poolStakeAddresses.length);
|
|
54036
|
-
const lstMintInfos = accountInfos.slice(poolStakeAddresses.length);
|
|
54037
|
-
for (let i = 0; i < stakedBankAddresses.length; i++) {
|
|
54038
|
-
const bankAddr = stakedBankAddresses[i];
|
|
54039
|
-
const poolStakeInfo = poolStakeInfos[i];
|
|
54040
|
-
const lstMintInfo = lstMintInfos[i];
|
|
54041
|
-
if (!poolStakeInfo || !lstMintInfo) {
|
|
54042
|
-
assetShareMultiplierByBank.set(bankAddr, new BigNumber3(1));
|
|
54043
|
-
continue;
|
|
54044
|
-
}
|
|
54045
|
-
const stakeLamports = poolStakeInfo.lamports;
|
|
54046
|
-
const supplyBuffer = lstMintInfo.data.slice(36, 44);
|
|
54047
|
-
const lstMintSupply = Number(Buffer.from(supplyBuffer).readBigUInt64LE(0));
|
|
54048
|
-
if (lstMintSupply === 0) {
|
|
54049
|
-
assetShareMultiplierByBank.set(bankAddr, new BigNumber3(1));
|
|
54050
|
-
continue;
|
|
54051
|
-
}
|
|
54052
|
-
const LAMPORTS_PER_SOL5 = 1e9;
|
|
54053
|
-
const adjustedStake = Math.max(stakeLamports - LAMPORTS_PER_SOL5, 0);
|
|
54054
|
-
const multiplier = new BigNumber3(adjustedStake).dividedBy(lstMintSupply);
|
|
54055
|
-
assetShareMultiplierByBank.set(bankAddr, multiplier);
|
|
54056
|
-
}
|
|
54057
|
-
}
|
|
54058
|
-
}
|
|
55372
|
+
const stakedMultipliers = await computeStakedBankMultipliers(
|
|
55373
|
+
banksArray.filter((b) => b.config.assetTag === 2 /* STAKED */),
|
|
55374
|
+
connection
|
|
55375
|
+
);
|
|
55376
|
+
stakedMultipliers.forEach((v, k) => assetShareMultiplierByBank.set(k, v));
|
|
54059
55377
|
const emodePairs = getEmodePairs(banksArray);
|
|
54060
55378
|
return new _Project0Client(
|
|
54061
55379
|
program,
|
|
@@ -54097,6 +55415,6 @@ var EmodeSettings = class _EmodeSettings {
|
|
|
54097
55415
|
}
|
|
54098
55416
|
};
|
|
54099
55417
|
|
|
54100
|
-
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_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, 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, composeRemainingAccounts, computeAccountValue, computeActiveEmodePairs, computeAssetHealthComponent, computeAssetUsdValue, computeBalanceUsdValue, computeBaseInterestRate, computeClaimedEmissions, computeClosePositionTokenAmount, computeEmodeImpacts, 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, 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, getHealthCacheStatusDescription, getHealthSimulationTransactions, getJupLendFTokenMultiplier, getJupLendMetadata, getJupLendStatesDto, getJupiterSwapIxsForFlashloan, getKaminoCTokenMultiplier, getKaminoMetadata, getKaminoStatesDto, getLiabilityQuantity, getLiabilityShares, getLiabilityWeight, getOracleSourceFromBank, getOracleSourceFromOracleSetup, getOracleSourceNameFromKey, getPrice, getPriceWithConfidence, getStakedBankMetadataMap, getTotalAssetQuantity, getTotalLiabilityQuantity, getTxSize, getValidatorVoteAccountByBank, 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, 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, toNumber, uiToNative, uiToNativeBigNumber, validatorStakeGroupToDto, wrappedI80F48toBigNumber };
|
|
55418
|
+
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, 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, 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 };
|
|
54101
55419
|
//# sourceMappingURL=index.js.map
|
|
54102
55420
|
//# sourceMappingURL=index.js.map
|