@haven-fi/solauto-sdk 1.0.817 → 1.0.819
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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jitoUtils.d.ts","sourceRoot":"","sources":["../../src/utils/jitoUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,SAAS,EAIV,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,MAAM,EACN,kBAAkB,EAClB,GAAG,EAEH,kBAAkB,EACnB,MAAM,0BAA0B,CAAC;AAGlC,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAiBlE,wBAAgB,mBAAmB,IAAI,SAAS,CAG/C;
|
|
1
|
+
{"version":3,"file":"jitoUtils.d.ts","sourceRoot":"","sources":["../../src/utils/jitoUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,SAAS,EAIV,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,MAAM,EACN,kBAAkB,EAClB,GAAG,EAEH,kBAAkB,EACnB,MAAM,0BAA0B,CAAC;AAGlC,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAiBlE,wBAAgB,mBAAmB,IAAI,SAAS,CAG/C;AAiGD,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,kBAAkB;;;;IAkB/D;AAqHD,wBAAsB,2BAA2B,CAC/C,GAAG,EAAE,GAAG,EACR,UAAU,EAAE,UAAU,EACtB,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,EAAE,EACtB,YAAY,EAAE,kBAAkB,EAAE,EAClC,MAAM,CAAC,EAAE,kBAAkB,EAC3B,kBAAkB,GAAE,kBAA2C,EAC/D,cAAc,CAAC,EAAE,MAAM,IAAI,EAC3B,eAAe,CAAC,EAAE,eAAe,GAChC,OAAO,CAAC,MAAM,EAAE,GAAG,SAAS,CAAC,CA6G/B"}
|
package/dist/utils/jitoUtils.js
CHANGED
|
@@ -44,25 +44,10 @@ function parseJitoErrorMessage(message) {
|
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
async function simulateJitoBundle(umi, txs) {
|
|
47
|
-
// Pre-serialize transactions to catch size errors before simulation
|
|
48
|
-
const serializedTxs = [];
|
|
49
|
-
for (let i = 0; i < txs.length; i++) {
|
|
50
|
-
try {
|
|
51
|
-
const serialized = txs[i].serialize();
|
|
52
|
-
if (serialized.length > 1232) {
|
|
53
|
-
throw new Error(`Transaction ${i} is too large: ${serialized.length} bytes (max: 1232)`);
|
|
54
|
-
}
|
|
55
|
-
serializedTxs.push(Buffer.from(serialized).toString("base64"));
|
|
56
|
-
}
|
|
57
|
-
catch (e) {
|
|
58
|
-
(0, generalUtils_1.consoleLog)(`Failed to serialize transaction ${i}:`, e);
|
|
59
|
-
throw new Error(`Failed to serialize transaction ${i}: ${e.message || e}`);
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
47
|
const simulationResult = await (0, generalUtils_1.retryWithExponentialBackoff)(async () => {
|
|
63
48
|
const res = await (0, generalUtils_1.customRpcCall)(umi, "simulateBundle", [
|
|
64
49
|
{
|
|
65
|
-
encodedTransactions:
|
|
50
|
+
encodedTransactions: txs.map((x) => Buffer.from(x.serialize()).toString("base64")),
|
|
66
51
|
},
|
|
67
52
|
{
|
|
68
53
|
encoding: "base64",
|
|
@@ -202,9 +187,8 @@ async function sendJitoBundledTransactions(umi, connection, userSigner, otherSig
|
|
|
202
187
|
(0, generalUtils_1.consoleLog)("Sending Jito bundle...");
|
|
203
188
|
(0, generalUtils_1.consoleLog)("Transactions: ", txs.length);
|
|
204
189
|
(0, generalUtils_1.consoleLog)(txs.map((tx) => tx.getInstructions().map((x) => x.programId.toString())));
|
|
205
|
-
(0, generalUtils_1.consoleLog)("Transaction sizes
|
|
190
|
+
(0, generalUtils_1.consoleLog)("Transaction sizes: ", txs.map((x) => x.getTransactionSize(umi)));
|
|
206
191
|
txs[0] = (0, solanaUtils_1.prependTx)(txs[0], [getTipInstruction(userSigner, 250000)]);
|
|
207
|
-
(0, generalUtils_1.consoleLog)("Transaction sizes (after tip): ", txs.map((x) => x.getTransactionSize(umi)));
|
|
208
192
|
const latestBlockhash = (await (0, generalUtils_1.retryWithExponentialBackoff)(async () => await umi.rpc.getLatestBlockhash({ commitment: "confirmed" }))).blockhash;
|
|
209
193
|
if (abortController?.signal.aborted) {
|
|
210
194
|
return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"solanaUtils.d.ts","sourceRoot":"","sources":["../../src/utils/solanaUtils.ts"],"names":[],"mappings":"AACA,OAAO,EAIL,UAAU,EACV,SAAS,EAKT,sBAAsB,EAEvB,MAAM,iBAAiB,CAAC;AAMzB,OAAO,EACL,WAAW,EACX,uBAAuB,EACvB,MAAM,EACN,kBAAkB,EAClB,GAAG,EACH,kBAAkB,EAGnB,MAAM,0BAA0B,CAAC;AAQlC,OAAO,EAAE,kBAAkB,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAgB9E,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,MAAM,EACd,SAAS,CAAC,EAAE,SAAS,EACrB,KAAK,CAAC,EAAE,UAAU,GACjB,CAAC,UAAU,EAAE,GAAG,CAAC,CAWnB;AAED,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,MAAM,EACd,EAAE,EAAE,sBAAsB,GACzB,kBAAkB,CAMpB;AAED,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,MAAM,EACd,eAAe,EAAE,MAAM,GACtB,kBAAkB,CAOpB;AAED,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACf,kBAAkB,CAOpB;AAED,wBAAgB,iCAAiC,CAC/C,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,SAAS,EACjB,IAAI,EAAE,SAAS,GACd,kBAAkB,CAUpB;AAED,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,SAAS,EACtB,QAAQ,EAAE,MAAM,GACf,kBAAkB,CASpB;AAED,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,SAAS,EACvB,SAAS,EAAE,SAAS,GACnB,kBAAkB,CAKpB;AAED,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,SAAS,EACjB,IAAI,EAAE,SAAS,EACf,SAAS,EAAE,SAAS,EACpB,MAAM,EAAE,MAAM,GACb,kBAAkB,CAKpB;AAED,wBAAgB,cAAc,CAC5B,MAAM,EAAE,SAAS,EACjB,QAAQ,GAAE,OAAe,EACzB,UAAU,GAAE,OAAe,GAC1B,WAAW,CAEb;AAED,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,SAAS,EACjB,UAAU,EAAE,SAAS,EAAE,GACtB,OAAO,CAAC,MAAM,EAAE,CAAC,CAcnB;AAED,wBAAsB,sBAAsB,CAC1C,GAAG,EAAE,GAAG,EACR,oBAAoB,EAAE,MAAM,EAAE,GAC7B,OAAO,CAAC,uBAAuB,EAAE,CAAC,CAmBpC;AAED,wBAAgB,SAAS,CACvB,EAAE,EAAE,kBAAkB,EACtB,QAAQ,EAAE,CAAC,kBAAkB,GAAG,kBAAkB,CAAC,EAAE,
|
|
1
|
+
{"version":3,"file":"solanaUtils.d.ts","sourceRoot":"","sources":["../../src/utils/solanaUtils.ts"],"names":[],"mappings":"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"}
|
|
@@ -112,7 +112,11 @@ function prependTx(tx, txsToAdd) {
|
|
|
112
112
|
const keccakIdx = instructions.findIndex((x) => x.programId.toString() === "KeccakSecp256k11111111111111111111111111111");
|
|
113
113
|
if (keccakIdx !== -1) {
|
|
114
114
|
const [beforeKeccak, afterKeccak] = tx.splitByIndex(keccakIdx + 1);
|
|
115
|
-
|
|
115
|
+
// IMPORTANT: Preserve lookup tables from original transaction
|
|
116
|
+
const lookupTables = tx.options.addressLookupTables ?? [];
|
|
117
|
+
let finalTx = (0, umi_1.transactionBuilder)()
|
|
118
|
+
.setAddressLookupTables(lookupTables)
|
|
119
|
+
.add(beforeKeccak);
|
|
116
120
|
for (const txToAdd of txsToAdd) {
|
|
117
121
|
finalTx = finalTx.append(txToAdd);
|
|
118
122
|
}
|
|
@@ -142,12 +146,10 @@ function getActualTxSize(umi, tx) {
|
|
|
142
146
|
const web3Tx = (0, umi_web3js_adapters_1.toWeb3JsTransaction)(builtTx);
|
|
143
147
|
// Actually serialize to get the real size
|
|
144
148
|
const serialized = web3Tx.serialize();
|
|
145
|
-
(0, generalUtils_1.consoleLog)("[getActualTxSize] Serialization successful, size:", serialized.length);
|
|
146
149
|
return serialized.length;
|
|
147
150
|
}
|
|
148
151
|
catch (e) {
|
|
149
152
|
// Serialization failed - transaction is too large or malformed
|
|
150
|
-
(0, generalUtils_1.consoleLog)("[getActualTxSize] Serialization FAILED:", e?.message || e);
|
|
151
153
|
return undefined;
|
|
152
154
|
}
|
|
153
155
|
}
|
|
@@ -156,19 +158,13 @@ function getActualTxSize(umi, tx) {
|
|
|
156
158
|
* More accurate than getTransactionSize() estimation.
|
|
157
159
|
*/
|
|
158
160
|
function canSerializeTransaction(umi, tx, buffer = 0) {
|
|
159
|
-
(0, generalUtils_1.consoleLog)("[canSerializeTransaction] Checking with buffer:", buffer);
|
|
160
161
|
const size = getActualTxSize(umi, tx);
|
|
161
162
|
if (size === undefined) {
|
|
162
|
-
(0, generalUtils_1.consoleLog)("[canSerializeTransaction] Failed - size undefined");
|
|
163
163
|
return false;
|
|
164
164
|
}
|
|
165
|
-
|
|
166
|
-
(0, generalUtils_1.consoleLog)(`[canSerializeTransaction] Size: ${size}, buffer: ${buffer}, max: ${MAX_TX_SIZE}, fits: ${fits}`);
|
|
167
|
-
return fits;
|
|
165
|
+
return size + buffer <= MAX_TX_SIZE;
|
|
168
166
|
}
|
|
169
167
|
function addTxOptimizations(umi, tx, computeUnitPrice, computeUnitLimit) {
|
|
170
|
-
(0, generalUtils_1.consoleLog)(`[addTxOptimizations] Called with price=${computeUnitPrice}, limit=${computeUnitLimit}`);
|
|
171
|
-
(0, generalUtils_1.consoleLog)(`[addTxOptimizations] Input tx estimated size: ${tx.getTransactionSize(umi)}`);
|
|
172
168
|
const computePriceIx = computeUnitPrice !== undefined
|
|
173
169
|
? setComputeUnitPriceUmiIx(umi.identity, computeUnitPrice)
|
|
174
170
|
: (0, umi_1.transactionBuilder)();
|
|
@@ -178,31 +174,22 @@ function addTxOptimizations(umi, tx, computeUnitPrice, computeUnitLimit) {
|
|
|
178
174
|
const allOptimizations = tx.prepend(computePriceIx).prepend(computeLimitIx);
|
|
179
175
|
const withCuPrice = tx.prepend(computePriceIx);
|
|
180
176
|
const withCuLimit = tx.prepend(computeLimitIx);
|
|
181
|
-
(0, generalUtils_1.consoleLog)("[addTxOptimizations] Checking if all optimizations fit...");
|
|
182
177
|
// Use actual serialization check instead of estimate
|
|
183
178
|
if (canSerializeTransaction(umi, allOptimizations)) {
|
|
184
|
-
(0, generalUtils_1.consoleLog)("[addTxOptimizations] All optimizations fit, adding both");
|
|
185
179
|
return prependTx(tx, [computePriceIx, computeLimitIx]);
|
|
186
180
|
}
|
|
187
|
-
(
|
|
188
|
-
if (canSerializeTransaction(umi, withCuPrice)) {
|
|
189
|
-
(0, generalUtils_1.consoleLog)("[addTxOptimizations] Only CU price fits, adding it");
|
|
181
|
+
else if (canSerializeTransaction(umi, withCuPrice)) {
|
|
190
182
|
return prependTx(tx, [computePriceIx]);
|
|
191
183
|
}
|
|
192
|
-
(
|
|
193
|
-
if (canSerializeTransaction(umi, withCuLimit)) {
|
|
194
|
-
(0, generalUtils_1.consoleLog)("[addTxOptimizations] Only CU limit fits, adding it");
|
|
184
|
+
else if (canSerializeTransaction(umi, withCuLimit)) {
|
|
195
185
|
return prependTx(tx, [computeLimitIx]);
|
|
196
186
|
}
|
|
197
|
-
|
|
198
|
-
|
|
187
|
+
else {
|
|
188
|
+
return tx;
|
|
189
|
+
}
|
|
199
190
|
}
|
|
200
191
|
function assembleFinalTransaction(umi, transaction, computeUnitPrice, computeUnitLimit) {
|
|
201
|
-
(0, generalUtils_1.consoleLog)(`[assembleFinalTransaction] Input tx instructions: ${transaction.getInstructions().length}`);
|
|
202
|
-
(0, generalUtils_1.consoleLog)(`[assembleFinalTransaction] Input tx estimated size: ${transaction.getTransactionSize(umi)}`);
|
|
203
192
|
const tx = addTxOptimizations(umi, transaction, computeUnitPrice, computeUnitLimit);
|
|
204
|
-
(0, generalUtils_1.consoleLog)(`[assembleFinalTransaction] After optimizations, instructions: ${tx.getInstructions().length}`);
|
|
205
|
-
(0, generalUtils_1.consoleLog)(`[assembleFinalTransaction] After optimizations, estimated size: ${tx.getTransactionSize(umi)}`);
|
|
206
193
|
const marginfiStartFlSerializer = (0, marginfi_1.getLendingAccountStartFlashloanInstructionDataSerializer)();
|
|
207
194
|
const marginfiStartFlDiscriminator = marginfiStartFlSerializer
|
|
208
195
|
.serialize({
|
|
@@ -236,46 +223,10 @@ function assembleFinalTransaction(umi, transaction, computeUnitPrice, computeUni
|
|
|
236
223
|
}
|
|
237
224
|
catch { }
|
|
238
225
|
}
|
|
239
|
-
(0, generalUtils_1.consoleLog)(`[assembleFinalTransaction] Final tx estimated size: ${tx.getTransactionSize(umi)}`);
|
|
240
226
|
return tx;
|
|
241
227
|
}
|
|
242
228
|
async function simulateTransaction(umi, connection, transaction) {
|
|
243
|
-
(0,
|
|
244
|
-
(0, generalUtils_1.consoleLog)("[simulateTransaction] Estimated size:", transaction.getTransactionSize(umi));
|
|
245
|
-
(0, generalUtils_1.consoleLog)("[simulateTransaction] Instructions:", transaction.getInstructions().length);
|
|
246
|
-
let builtTx;
|
|
247
|
-
try {
|
|
248
|
-
builtTx = transaction.build(umi);
|
|
249
|
-
(0, generalUtils_1.consoleLog)("[simulateTransaction] Built UMI transaction successfully");
|
|
250
|
-
}
|
|
251
|
-
catch (e) {
|
|
252
|
-
(0, generalUtils_1.consoleLog)("[simulateTransaction] Failed to build UMI transaction:", e);
|
|
253
|
-
throw e;
|
|
254
|
-
}
|
|
255
|
-
let web3Tx;
|
|
256
|
-
try {
|
|
257
|
-
web3Tx = (0, umi_web3js_adapters_1.toWeb3JsTransaction)(builtTx);
|
|
258
|
-
(0, generalUtils_1.consoleLog)("[simulateTransaction] Converted to web3.js transaction");
|
|
259
|
-
}
|
|
260
|
-
catch (e) {
|
|
261
|
-
(0, generalUtils_1.consoleLog)("[simulateTransaction] Failed to convert to web3.js:", e);
|
|
262
|
-
throw e;
|
|
263
|
-
}
|
|
264
|
-
// Try to serialize before simulation to catch the error with better context
|
|
265
|
-
try {
|
|
266
|
-
const serialized = web3Tx.serialize();
|
|
267
|
-
(0, generalUtils_1.consoleLog)("[simulateTransaction] Pre-serialization successful, size:", serialized.length);
|
|
268
|
-
}
|
|
269
|
-
catch (e) {
|
|
270
|
-
(0, generalUtils_1.consoleLog)("[simulateTransaction] Pre-serialization FAILED:", e);
|
|
271
|
-
(0, generalUtils_1.consoleLog)("[simulateTransaction] Message accounts:", web3Tx.message.staticAccountKeys.length);
|
|
272
|
-
(0, generalUtils_1.consoleLog)("[simulateTransaction] Message instructions:", web3Tx.message.compiledInstructions.length);
|
|
273
|
-
if ("addressTableLookups" in web3Tx.message) {
|
|
274
|
-
(0, generalUtils_1.consoleLog)("[simulateTransaction] Address table lookups:", web3Tx.message.addressTableLookups?.length ?? 0);
|
|
275
|
-
}
|
|
276
|
-
throw new Error(`Transaction serialization failed before simulation: ${e.message || e}`);
|
|
277
|
-
}
|
|
278
|
-
const simulationResult = await connection.simulateTransaction(web3Tx, {
|
|
229
|
+
const simulationResult = await connection.simulateTransaction((0, umi_web3js_adapters_1.toWeb3JsTransaction)(transaction.build(umi)), {
|
|
279
230
|
sigVerify: false,
|
|
280
231
|
commitment: "confirmed",
|
|
281
232
|
});
|
package/package.json
CHANGED
package/src/utils/jitoUtils.ts
CHANGED
|
@@ -72,29 +72,12 @@ function parseJitoErrorMessage(message: string) {
|
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
async function simulateJitoBundle(umi: Umi, txs: VersionedTransaction[]) {
|
|
75
|
-
// Pre-serialize transactions to catch size errors before simulation
|
|
76
|
-
const serializedTxs: string[] = [];
|
|
77
|
-
for (let i = 0; i < txs.length; i++) {
|
|
78
|
-
try {
|
|
79
|
-
const serialized = txs[i].serialize();
|
|
80
|
-
if (serialized.length > 1232) {
|
|
81
|
-
throw new Error(
|
|
82
|
-
`Transaction ${i} is too large: ${serialized.length} bytes (max: 1232)`
|
|
83
|
-
);
|
|
84
|
-
}
|
|
85
|
-
serializedTxs.push(Buffer.from(serialized).toString("base64"));
|
|
86
|
-
} catch (e: any) {
|
|
87
|
-
consoleLog(`Failed to serialize transaction ${i}:`, e);
|
|
88
|
-
throw new Error(
|
|
89
|
-
`Failed to serialize transaction ${i}: ${e.message || e}`
|
|
90
|
-
);
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
75
|
const simulationResult = await retryWithExponentialBackoff(async () => {
|
|
95
76
|
const res = await customRpcCall(umi, "simulateBundle", [
|
|
96
77
|
{
|
|
97
|
-
encodedTransactions:
|
|
78
|
+
encodedTransactions: txs.map((x) =>
|
|
79
|
+
Buffer.from(x.serialize()).toString("base64")
|
|
80
|
+
),
|
|
98
81
|
},
|
|
99
82
|
{
|
|
100
83
|
encoding: "base64",
|
|
@@ -315,17 +298,12 @@ export async function sendJitoBundledTransactions(
|
|
|
315
298
|
txs.map((tx) => tx.getInstructions().map((x) => x.programId.toString()))
|
|
316
299
|
);
|
|
317
300
|
consoleLog(
|
|
318
|
-
"Transaction sizes
|
|
301
|
+
"Transaction sizes: ",
|
|
319
302
|
txs.map((x) => x.getTransactionSize(umi))
|
|
320
303
|
);
|
|
321
304
|
|
|
322
305
|
txs[0] = prependTx(txs[0], [getTipInstruction(userSigner, 250_000)]);
|
|
323
306
|
|
|
324
|
-
consoleLog(
|
|
325
|
-
"Transaction sizes (after tip): ",
|
|
326
|
-
txs.map((x) => x.getTransactionSize(umi))
|
|
327
|
-
);
|
|
328
|
-
|
|
329
307
|
const latestBlockhash = (
|
|
330
308
|
await retryWithExponentialBackoff(
|
|
331
309
|
async () => await umi.rpc.getLatestBlockhash({ commitment: "confirmed" })
|
package/src/utils/solanaUtils.ts
CHANGED
|
@@ -220,7 +220,11 @@ export function prependTx(
|
|
|
220
220
|
);
|
|
221
221
|
if (keccakIdx !== -1) {
|
|
222
222
|
const [beforeKeccak, afterKeccak] = tx.splitByIndex(keccakIdx + 1);
|
|
223
|
-
|
|
223
|
+
// IMPORTANT: Preserve lookup tables from original transaction
|
|
224
|
+
const lookupTables = tx.options.addressLookupTables ?? [];
|
|
225
|
+
let finalTx = transactionBuilder()
|
|
226
|
+
.setAddressLookupTables(lookupTables)
|
|
227
|
+
.add(beforeKeccak);
|
|
224
228
|
for (const txToAdd of txsToAdd) {
|
|
225
229
|
finalTx = finalTx.append(txToAdd);
|
|
226
230
|
}
|
|
@@ -255,11 +259,9 @@ export function getActualTxSize(
|
|
|
255
259
|
const web3Tx = toWeb3JsTransaction(builtTx);
|
|
256
260
|
// Actually serialize to get the real size
|
|
257
261
|
const serialized = web3Tx.serialize();
|
|
258
|
-
consoleLog("[getActualTxSize] Serialization successful, size:", serialized.length);
|
|
259
262
|
return serialized.length;
|
|
260
|
-
} catch (e
|
|
263
|
+
} catch (e) {
|
|
261
264
|
// Serialization failed - transaction is too large or malformed
|
|
262
|
-
consoleLog("[getActualTxSize] Serialization FAILED:", e?.message || e);
|
|
263
265
|
return undefined;
|
|
264
266
|
}
|
|
265
267
|
}
|
|
@@ -273,17 +275,11 @@ export function canSerializeTransaction(
|
|
|
273
275
|
tx: TransactionBuilder,
|
|
274
276
|
buffer: number = 0
|
|
275
277
|
): boolean {
|
|
276
|
-
consoleLog("[canSerializeTransaction] Checking with buffer:", buffer);
|
|
277
278
|
const size = getActualTxSize(umi, tx);
|
|
278
279
|
if (size === undefined) {
|
|
279
|
-
consoleLog("[canSerializeTransaction] Failed - size undefined");
|
|
280
280
|
return false;
|
|
281
281
|
}
|
|
282
|
-
|
|
283
|
-
consoleLog(
|
|
284
|
-
`[canSerializeTransaction] Size: ${size}, buffer: ${buffer}, max: ${MAX_TX_SIZE}, fits: ${fits}`
|
|
285
|
-
);
|
|
286
|
-
return fits;
|
|
282
|
+
return size + buffer <= MAX_TX_SIZE;
|
|
287
283
|
}
|
|
288
284
|
|
|
289
285
|
export function addTxOptimizations(
|
|
@@ -292,13 +288,6 @@ export function addTxOptimizations(
|
|
|
292
288
|
computeUnitPrice?: number,
|
|
293
289
|
computeUnitLimit?: number
|
|
294
290
|
) {
|
|
295
|
-
consoleLog(
|
|
296
|
-
`[addTxOptimizations] Called with price=${computeUnitPrice}, limit=${computeUnitLimit}`
|
|
297
|
-
);
|
|
298
|
-
consoleLog(
|
|
299
|
-
`[addTxOptimizations] Input tx estimated size: ${tx.getTransactionSize(umi)}`
|
|
300
|
-
);
|
|
301
|
-
|
|
302
291
|
const computePriceIx =
|
|
303
292
|
computeUnitPrice !== undefined
|
|
304
293
|
? setComputeUnitPriceUmiIx(umi.identity, computeUnitPrice)
|
|
@@ -311,24 +300,16 @@ export function addTxOptimizations(
|
|
|
311
300
|
const withCuPrice = tx.prepend(computePriceIx);
|
|
312
301
|
const withCuLimit = tx.prepend(computeLimitIx);
|
|
313
302
|
|
|
314
|
-
consoleLog("[addTxOptimizations] Checking if all optimizations fit...");
|
|
315
303
|
// Use actual serialization check instead of estimate
|
|
316
304
|
if (canSerializeTransaction(umi, allOptimizations)) {
|
|
317
|
-
consoleLog("[addTxOptimizations] All optimizations fit, adding both");
|
|
318
305
|
return prependTx(tx, [computePriceIx, computeLimitIx]);
|
|
319
|
-
}
|
|
320
|
-
consoleLog("[addTxOptimizations] Checking if just CU price fits...");
|
|
321
|
-
if (canSerializeTransaction(umi, withCuPrice)) {
|
|
322
|
-
consoleLog("[addTxOptimizations] Only CU price fits, adding it");
|
|
306
|
+
} else if (canSerializeTransaction(umi, withCuPrice)) {
|
|
323
307
|
return prependTx(tx, [computePriceIx]);
|
|
324
|
-
}
|
|
325
|
-
consoleLog("[addTxOptimizations] Checking if just CU limit fits...");
|
|
326
|
-
if (canSerializeTransaction(umi, withCuLimit)) {
|
|
327
|
-
consoleLog("[addTxOptimizations] Only CU limit fits, adding it");
|
|
308
|
+
} else if (canSerializeTransaction(umi, withCuLimit)) {
|
|
328
309
|
return prependTx(tx, [computeLimitIx]);
|
|
310
|
+
} else {
|
|
311
|
+
return tx;
|
|
329
312
|
}
|
|
330
|
-
consoleLog("[addTxOptimizations] Nothing fits, returning original tx");
|
|
331
|
-
return tx;
|
|
332
313
|
}
|
|
333
314
|
|
|
334
315
|
export function assembleFinalTransaction(
|
|
@@ -337,13 +318,6 @@ export function assembleFinalTransaction(
|
|
|
337
318
|
computeUnitPrice?: number,
|
|
338
319
|
computeUnitLimit?: number
|
|
339
320
|
) {
|
|
340
|
-
consoleLog(
|
|
341
|
-
`[assembleFinalTransaction] Input tx instructions: ${transaction.getInstructions().length}`
|
|
342
|
-
);
|
|
343
|
-
consoleLog(
|
|
344
|
-
`[assembleFinalTransaction] Input tx estimated size: ${transaction.getTransactionSize(umi)}`
|
|
345
|
-
);
|
|
346
|
-
|
|
347
321
|
const tx = addTxOptimizations(
|
|
348
322
|
umi,
|
|
349
323
|
transaction,
|
|
@@ -351,13 +325,6 @@ export function assembleFinalTransaction(
|
|
|
351
325
|
computeUnitLimit
|
|
352
326
|
);
|
|
353
327
|
|
|
354
|
-
consoleLog(
|
|
355
|
-
`[assembleFinalTransaction] After optimizations, instructions: ${tx.getInstructions().length}`
|
|
356
|
-
);
|
|
357
|
-
consoleLog(
|
|
358
|
-
`[assembleFinalTransaction] After optimizations, estimated size: ${tx.getTransactionSize(umi)}`
|
|
359
|
-
);
|
|
360
|
-
|
|
361
328
|
const marginfiStartFlSerializer =
|
|
362
329
|
getLendingAccountStartFlashloanInstructionDataSerializer();
|
|
363
330
|
const marginfiStartFlDiscriminator = marginfiStartFlSerializer
|
|
@@ -407,9 +374,6 @@ export function assembleFinalTransaction(
|
|
|
407
374
|
} catch {}
|
|
408
375
|
}
|
|
409
376
|
|
|
410
|
-
consoleLog(
|
|
411
|
-
`[assembleFinalTransaction] Final tx estimated size: ${tx.getTransactionSize(umi)}`
|
|
412
|
-
);
|
|
413
377
|
return tx;
|
|
414
378
|
}
|
|
415
379
|
|
|
@@ -418,66 +382,13 @@ async function simulateTransaction(
|
|
|
418
382
|
connection: Connection,
|
|
419
383
|
transaction: TransactionBuilder
|
|
420
384
|
): Promise<RpcResponseAndContext<SimulatedTransactionResponse>> {
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
consoleLog(
|
|
427
|
-
"[simulateTransaction] Instructions:",
|
|
428
|
-
transaction.getInstructions().length
|
|
429
|
-
);
|
|
430
|
-
|
|
431
|
-
let builtTx;
|
|
432
|
-
try {
|
|
433
|
-
builtTx = transaction.build(umi);
|
|
434
|
-
consoleLog("[simulateTransaction] Built UMI transaction successfully");
|
|
435
|
-
} catch (e: any) {
|
|
436
|
-
consoleLog("[simulateTransaction] Failed to build UMI transaction:", e);
|
|
437
|
-
throw e;
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
let web3Tx;
|
|
441
|
-
try {
|
|
442
|
-
web3Tx = toWeb3JsTransaction(builtTx);
|
|
443
|
-
consoleLog("[simulateTransaction] Converted to web3.js transaction");
|
|
444
|
-
} catch (e: any) {
|
|
445
|
-
consoleLog("[simulateTransaction] Failed to convert to web3.js:", e);
|
|
446
|
-
throw e;
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
// Try to serialize before simulation to catch the error with better context
|
|
450
|
-
try {
|
|
451
|
-
const serialized = web3Tx.serialize();
|
|
452
|
-
consoleLog(
|
|
453
|
-
"[simulateTransaction] Pre-serialization successful, size:",
|
|
454
|
-
serialized.length
|
|
455
|
-
);
|
|
456
|
-
} catch (e: any) {
|
|
457
|
-
consoleLog("[simulateTransaction] Pre-serialization FAILED:", e);
|
|
458
|
-
consoleLog(
|
|
459
|
-
"[simulateTransaction] Message accounts:",
|
|
460
|
-
web3Tx.message.staticAccountKeys.length
|
|
461
|
-
);
|
|
462
|
-
consoleLog(
|
|
463
|
-
"[simulateTransaction] Message instructions:",
|
|
464
|
-
web3Tx.message.compiledInstructions.length
|
|
465
|
-
);
|
|
466
|
-
if ("addressTableLookups" in web3Tx.message) {
|
|
467
|
-
consoleLog(
|
|
468
|
-
"[simulateTransaction] Address table lookups:",
|
|
469
|
-
(web3Tx.message as any).addressTableLookups?.length ?? 0
|
|
470
|
-
);
|
|
385
|
+
const simulationResult = await connection.simulateTransaction(
|
|
386
|
+
toWeb3JsTransaction(transaction.build(umi)),
|
|
387
|
+
{
|
|
388
|
+
sigVerify: false,
|
|
389
|
+
commitment: "confirmed",
|
|
471
390
|
}
|
|
472
|
-
|
|
473
|
-
`Transaction serialization failed before simulation: ${e.message || e}`
|
|
474
|
-
);
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
const simulationResult = await connection.simulateTransaction(web3Tx, {
|
|
478
|
-
sigVerify: false,
|
|
479
|
-
commitment: "confirmed",
|
|
480
|
-
});
|
|
391
|
+
);
|
|
481
392
|
if (simulationResult.value.err) {
|
|
482
393
|
simulationResult.value.logs?.forEach((x: any) => {
|
|
483
394
|
consoleLog(x);
|