@haven-fi/solauto-sdk 1.0.814 → 1.0.816
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/generated/instructions/marginfiProtocolInteraction.js +1 -1
- package/dist/generated/instructions/marginfiRebalance.js +1 -1
- package/dist/services/transactions/manager/transactionsManager.d.ts.map +1 -1
- package/dist/services/transactions/manager/transactionsManager.js +5 -3
- package/dist/services/transactions/types/transactionSet.d.ts +1 -0
- package/dist/services/transactions/types/transactionSet.d.ts.map +1 -1
- package/dist/services/transactions/types/transactionSet.js +6 -2
- package/dist/solautoPosition/positionUtils.js +10 -10
- package/dist/utils/jitoUtils.d.ts.map +1 -1
- package/dist/utils/jitoUtils.js +18 -2
- package/dist/utils/marginfi/data.js +6 -6
- package/dist/utils/solanaUtils.d.ts +10 -0
- package/dist/utils/solanaUtils.d.ts.map +1 -1
- package/dist/utils/solanaUtils.js +41 -3
- package/dist/utils/solautoUtils.js +3 -3
- package/local/txSandbox.ts +34 -21
- package/package.json +1 -1
- package/src/generated/instructions/marginfiProtocolInteraction.ts +1 -1
- package/src/generated/instructions/marginfiRebalance.ts +1 -1
- package/src/services/transactions/manager/transactionsManager.ts +25 -6
- package/src/services/transactions/types/transactionSet.ts +12 -2
- package/src/solautoPosition/positionUtils.ts +10 -10
- package/src/utils/jitoUtils.ts +37 -15
- package/src/utils/marginfi/data.ts +6 -6
- package/src/utils/solanaUtils.ts +50 -3
- package/src/utils/solautoUtils.ts +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transactionsManager.d.ts","sourceRoot":"","sources":["../../../../src/services/transactions/manager/transactionsManager.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EACL,kBAAkB,EAElB,kBAAkB,EACnB,MAAM,gBAAgB,CAAC;AACxB,OAAO,
|
|
1
|
+
{"version":3,"file":"transactionsManager.d.ts","sourceRoot":"","sources":["../../../../src/services/transactions/manager/transactionsManager.ts"],"names":[],"mappings":"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"}
|
|
@@ -54,9 +54,11 @@ class TransactionsManager {
|
|
|
54
54
|
if (!item.tx) {
|
|
55
55
|
continue;
|
|
56
56
|
}
|
|
57
|
-
const transaction = item.tx.setAddressLookupTables(await this.lookupTables.getLutInputs(item.lookupTableAddresses));
|
|
58
|
-
if
|
|
59
|
-
|
|
57
|
+
const transaction = (0, utils_1.addTxOptimizations)(this.txHandler.umi, item.tx, 1, 1).setAddressLookupTables(await this.lookupTables.getLutInputs(item.lookupTableAddresses));
|
|
58
|
+
// Check if transaction can be serialized with buffer for Jito tip instruction
|
|
59
|
+
if (!(0, utils_1.canSerializeTransaction)(this.txHandler.umi, transaction, types_2.JITO_TIP_BUFFER_BYTES)) {
|
|
60
|
+
const actualSize = (0, utils_1.getActualTxSize)(this.txHandler.umi, transaction);
|
|
61
|
+
throw new TransactionTooLargeError(`Exceeds max transaction size (actual: ${actualSize ?? "failed to serialize"} + ~${types_2.JITO_TIP_BUFFER_BYTES} bytes for Jito tip)`);
|
|
60
62
|
}
|
|
61
63
|
else {
|
|
62
64
|
let newSet = new types_2.TransactionSet(this.txHandler, this.lookupTables, [
|
|
@@ -2,6 +2,7 @@ import { AddressLookupTableInput, TransactionBuilder } from "@metaplex-foundatio
|
|
|
2
2
|
import { TxHandler } from "../../solauto";
|
|
3
3
|
import { LookupTables } from "./lookupTables";
|
|
4
4
|
import { TransactionItem } from "./transactionItem";
|
|
5
|
+
export declare const JITO_TIP_BUFFER_BYTES = 75;
|
|
5
6
|
export declare class TransactionSet {
|
|
6
7
|
private txHandler;
|
|
7
8
|
lookupTables: LookupTables;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transactionSet.d.ts","sourceRoot":"","sources":["../../../../src/services/transactions/types/transactionSet.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,uBAAuB,EAEvB,kBAAkB,
|
|
1
|
+
{"version":3,"file":"transactionSet.d.ts","sourceRoot":"","sources":["../../../../src/services/transactions/types/transactionSet.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,uBAAuB,EAEvB,kBAAkB,EAEnB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAQpD,eAAO,MAAM,qBAAqB,KAAK,CAAC;AAExC,qBAAa,cAAc;IAEvB,OAAO,CAAC,SAAS;IACV,YAAY,EAAE,YAAY;IAC1B,KAAK,EAAE,eAAe,EAAE;gBAFvB,SAAS,EAAE,SAAS,EACrB,YAAY,EAAE,YAAY,EAC1B,KAAK,GAAE,eAAe,EAAO;IAGhC,SAAS,IAAI,OAAO,CAAC,uBAAuB,EAAE,CAAC;IAY/C,QAAQ,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,OAAO,CAAC;IAiCvD,GAAG,CAAC,GAAG,KAAK,EAAE,eAAe,EAAE;IAM/B,OAAO,CAAC,GAAG,KAAK,EAAE,eAAe,EAAE;IAM7B,KAAK;IAIL,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,KAAK;IAMhD,oBAAoB,IAAI,OAAO,CAAC,kBAAkB,CAAC;IAUzD,YAAY,IAAI,MAAM,EAAE;IAMxB,IAAI,IAAI,MAAM;CAef"}
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.TransactionSet = void 0;
|
|
3
|
+
exports.TransactionSet = exports.JITO_TIP_BUFFER_BYTES = void 0;
|
|
4
4
|
const umi_1 = require("@metaplex-foundation/umi");
|
|
5
5
|
const utils_1 = require("../../../utils");
|
|
6
6
|
const constants_1 = require("../../../constants");
|
|
7
7
|
const MAX_SUPPORTED_ACCOUNT_LOCKS = 64;
|
|
8
|
+
// Buffer for Jito tip instruction (~44 bytes) + potential new accounts in message
|
|
9
|
+
// This accounts for: System Transfer instruction data, Jito tip account (if new), etc.
|
|
10
|
+
exports.JITO_TIP_BUFFER_BYTES = 75;
|
|
8
11
|
class TransactionSet {
|
|
9
12
|
constructor(txHandler, lookupTables, items = []) {
|
|
10
13
|
this.txHandler = txHandler;
|
|
@@ -34,7 +37,8 @@ class TransactionSet {
|
|
|
34
37
|
...this.lutAddresses(),
|
|
35
38
|
...item.lookupTableAddresses,
|
|
36
39
|
]));
|
|
37
|
-
|
|
40
|
+
// Use actual serialization check with buffer for Jito tip instruction
|
|
41
|
+
return (0, utils_1.canSerializeTransaction)(this.txHandler.umi, tx, exports.JITO_TIP_BUFFER_BYTES);
|
|
38
42
|
}
|
|
39
43
|
add(...items) {
|
|
40
44
|
this.items.push(...items.filter((x) => x.tx && x.tx.getInstructions().length > 0));
|
|
@@ -15,7 +15,7 @@ function createSolautoSettings(settings) {
|
|
|
15
15
|
boostToBps: settings.boostToBps,
|
|
16
16
|
repayGap: settings.repayGap,
|
|
17
17
|
repayToBps: settings.repayToBps,
|
|
18
|
-
padding:
|
|
18
|
+
padding: new Array(24).fill(0),
|
|
19
19
|
};
|
|
20
20
|
}
|
|
21
21
|
async function getPositionExBulk(umi, publicKeys) {
|
|
@@ -86,9 +86,9 @@ function createFakePositionState(supply, debt, maxLtvBps, liqThresholdBps) {
|
|
|
86
86
|
borrowFeeBps: 0,
|
|
87
87
|
decimals: supplyDecimals,
|
|
88
88
|
mint: (0, umi_web3js_adapters_1.fromWeb3JsPublicKey)(supply.mint),
|
|
89
|
-
padding1:
|
|
90
|
-
padding2:
|
|
91
|
-
padding: new Uint8Array(
|
|
89
|
+
padding1: new Array(5).fill(0),
|
|
90
|
+
padding2: new Array(8).fill(0),
|
|
91
|
+
padding: new Uint8Array(32),
|
|
92
92
|
},
|
|
93
93
|
debt: {
|
|
94
94
|
amountUsed: {
|
|
@@ -103,9 +103,9 @@ function createFakePositionState(supply, debt, maxLtvBps, liqThresholdBps) {
|
|
|
103
103
|
borrowFeeBps: 0,
|
|
104
104
|
decimals: debtDecimals,
|
|
105
105
|
mint: (0, umi_web3js_adapters_1.fromWeb3JsPublicKey)(debt.mint),
|
|
106
|
-
padding1:
|
|
107
|
-
padding2:
|
|
108
|
-
padding: new Uint8Array(
|
|
106
|
+
padding1: new Array(5).fill(0),
|
|
107
|
+
padding2: new Array(8).fill(0),
|
|
108
|
+
padding: new Uint8Array(32),
|
|
109
109
|
},
|
|
110
110
|
netWorth: {
|
|
111
111
|
baseUnit: supply.price
|
|
@@ -116,8 +116,8 @@ function createFakePositionState(supply, debt, maxLtvBps, liqThresholdBps) {
|
|
|
116
116
|
maxLtvBps,
|
|
117
117
|
liqThresholdBps,
|
|
118
118
|
lastRefreshed: BigInt((0, utils_1.currentUnixSeconds)()),
|
|
119
|
-
padding1:
|
|
120
|
-
padding2:
|
|
121
|
-
padding:
|
|
119
|
+
padding1: new Array(6).fill(0),
|
|
120
|
+
padding2: new Array(4).fill(0),
|
|
121
|
+
padding: new Array(2).fill(0),
|
|
122
122
|
};
|
|
123
123
|
}
|
|
@@ -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;AAkHD,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,CAkH/B"}
|
package/dist/utils/jitoUtils.js
CHANGED
|
@@ -44,10 +44,25 @@ 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
|
+
}
|
|
47
62
|
const simulationResult = await (0, generalUtils_1.retryWithExponentialBackoff)(async () => {
|
|
48
63
|
const res = await (0, generalUtils_1.customRpcCall)(umi, "simulateBundle", [
|
|
49
64
|
{
|
|
50
|
-
encodedTransactions:
|
|
65
|
+
encodedTransactions: serializedTxs,
|
|
51
66
|
},
|
|
52
67
|
{
|
|
53
68
|
encoding: "base64",
|
|
@@ -187,8 +202,9 @@ async function sendJitoBundledTransactions(umi, connection, userSigner, otherSig
|
|
|
187
202
|
(0, generalUtils_1.consoleLog)("Sending Jito bundle...");
|
|
188
203
|
(0, generalUtils_1.consoleLog)("Transactions: ", txs.length);
|
|
189
204
|
(0, generalUtils_1.consoleLog)(txs.map((tx) => tx.getInstructions().map((x) => x.programId.toString())));
|
|
190
|
-
(0, generalUtils_1.consoleLog)("Transaction sizes: ", txs.map((x) => x.getTransactionSize(umi)));
|
|
205
|
+
(0, generalUtils_1.consoleLog)("Transaction sizes (before tip): ", txs.map((x) => x.getTransactionSize(umi)));
|
|
191
206
|
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)));
|
|
192
208
|
const latestBlockhash = (await (0, generalUtils_1.retryWithExponentialBackoff)(async () => await umi.rpc.getLatestBlockhash({ commitment: "confirmed" }))).blockhash;
|
|
193
209
|
if (abortController?.signal.aborted) {
|
|
194
210
|
return;
|
|
@@ -169,9 +169,9 @@ async function getTokenUsage(bank, isAsset, shares, amountUsedAdjustment, priceT
|
|
|
169
169
|
},
|
|
170
170
|
baseAmountMarketPriceUsd: (0, numberUtils_1.toBaseUnit)(marketPrice, constants_1.USD_DECIMALS),
|
|
171
171
|
borrowFeeBps: isAsset ? 0 : (0, numberUtils_1.toBps)(originationFee),
|
|
172
|
-
padding1:
|
|
173
|
-
padding2:
|
|
174
|
-
padding: new Uint8Array(
|
|
172
|
+
padding1: new Array(5).fill(0),
|
|
173
|
+
padding2: new Array(8).fill(0),
|
|
174
|
+
padding: new Uint8Array(32),
|
|
175
175
|
};
|
|
176
176
|
}
|
|
177
177
|
async function getBank(umi, data, marginfiGroup) {
|
|
@@ -287,9 +287,9 @@ async function getMarginfiAccountPositionState(umi, lpUserAccount, marginfiGroup
|
|
|
287
287
|
maxLtvBps,
|
|
288
288
|
liqThresholdBps,
|
|
289
289
|
lastRefreshed: BigInt((0, generalUtils_1.currentUnixSeconds)()),
|
|
290
|
-
padding1:
|
|
291
|
-
padding2:
|
|
292
|
-
padding:
|
|
290
|
+
padding1: new Array(6).fill(0),
|
|
291
|
+
padding2: new Array(4).fill(0),
|
|
292
|
+
padding: new Array(2).fill(0),
|
|
293
293
|
},
|
|
294
294
|
};
|
|
295
295
|
}
|
|
@@ -13,6 +13,16 @@ export declare function getAccountMeta(pubkey: PublicKey, isSigner?: boolean, is
|
|
|
13
13
|
export declare function getWalletSplBalances(conn: Connection, wallet: PublicKey, tokenMints: PublicKey[]): Promise<bigint[]>;
|
|
14
14
|
export declare function getAddressLookupInputs(umi: Umi, lookupTableAddresses: string[]): Promise<AddressLookupTableInput[]>;
|
|
15
15
|
export declare function prependTx(tx: TransactionBuilder, txsToAdd: (TransactionBuilder | WrappedInstruction)[]): TransactionBuilder;
|
|
16
|
+
/**
|
|
17
|
+
* Safely checks if a transaction can be serialized and returns its actual size.
|
|
18
|
+
* Returns undefined if serialization fails.
|
|
19
|
+
*/
|
|
20
|
+
export declare function getActualTxSize(umi: Umi, tx: TransactionBuilder): number | undefined;
|
|
21
|
+
/**
|
|
22
|
+
* Checks if a transaction can fit in a single transaction by actually serializing it.
|
|
23
|
+
* More accurate than getTransactionSize() estimation.
|
|
24
|
+
*/
|
|
25
|
+
export declare function canSerializeTransaction(umi: Umi, tx: TransactionBuilder, buffer?: number): boolean;
|
|
16
26
|
export declare function addTxOptimizations(umi: Umi, tx: TransactionBuilder, computeUnitPrice?: number, computeUnitLimit?: number): TransactionBuilder;
|
|
17
27
|
export declare function assembleFinalTransaction(umi: Umi, transaction: TransactionBuilder, computeUnitPrice?: number, computeUnitLimit?: number): TransactionBuilder;
|
|
18
28
|
export declare function getQnComputeUnitPriceEstimate(umi: Umi, programId: PublicKey, blockheight?: number): Promise<any>;
|
|
@@ -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,sBAqBtD;AAED,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,GAAG,EACR,EAAE,EAAE,kBAAkB,EACtB,gBAAgB,CAAC,EAAE,MAAM,EACzB,gBAAgB,CAAC,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"solanaUtils.d.ts","sourceRoot":"","sources":["../../src/utils/solanaUtils.ts"],"names":[],"mappings":"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"}
|
|
@@ -15,6 +15,8 @@ exports.getAccountMeta = getAccountMeta;
|
|
|
15
15
|
exports.getWalletSplBalances = getWalletSplBalances;
|
|
16
16
|
exports.getAddressLookupInputs = getAddressLookupInputs;
|
|
17
17
|
exports.prependTx = prependTx;
|
|
18
|
+
exports.getActualTxSize = getActualTxSize;
|
|
19
|
+
exports.canSerializeTransaction = canSerializeTransaction;
|
|
18
20
|
exports.addTxOptimizations = addTxOptimizations;
|
|
19
21
|
exports.assembleFinalTransaction = assembleFinalTransaction;
|
|
20
22
|
exports.getQnComputeUnitPriceEstimate = getQnComputeUnitPriceEstimate;
|
|
@@ -124,6 +126,41 @@ function prependTx(tx, txsToAdd) {
|
|
|
124
126
|
return finalTx;
|
|
125
127
|
}
|
|
126
128
|
}
|
|
129
|
+
const MAX_TX_SIZE = 1232;
|
|
130
|
+
// Dummy blockhash for size checking (all zeros, 32 bytes base58 encoded)
|
|
131
|
+
const DUMMY_BLOCKHASH = "11111111111111111111111111111111";
|
|
132
|
+
/**
|
|
133
|
+
* Safely checks if a transaction can be serialized and returns its actual size.
|
|
134
|
+
* Returns undefined if serialization fails.
|
|
135
|
+
*/
|
|
136
|
+
function getActualTxSize(umi, tx) {
|
|
137
|
+
try {
|
|
138
|
+
// Set a dummy blockhash if not already set, just for size checking
|
|
139
|
+
const txWithBlockhash = tx.setBlockhash(DUMMY_BLOCKHASH);
|
|
140
|
+
// Build the transaction and convert to web3.js format
|
|
141
|
+
const builtTx = txWithBlockhash.build(umi);
|
|
142
|
+
const web3Tx = (0, umi_web3js_adapters_1.toWeb3JsTransaction)(builtTx);
|
|
143
|
+
// Actually serialize to get the real size
|
|
144
|
+
const serialized = web3Tx.serialize();
|
|
145
|
+
return serialized.length;
|
|
146
|
+
}
|
|
147
|
+
catch (e) {
|
|
148
|
+
// Serialization failed - transaction is too large or malformed
|
|
149
|
+
(0, generalUtils_1.consoleLog)("Transaction serialization check failed:", e);
|
|
150
|
+
return undefined;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Checks if a transaction can fit in a single transaction by actually serializing it.
|
|
155
|
+
* More accurate than getTransactionSize() estimation.
|
|
156
|
+
*/
|
|
157
|
+
function canSerializeTransaction(umi, tx, buffer = 0) {
|
|
158
|
+
const size = getActualTxSize(umi, tx);
|
|
159
|
+
if (size === undefined) {
|
|
160
|
+
return false;
|
|
161
|
+
}
|
|
162
|
+
return size + buffer <= MAX_TX_SIZE;
|
|
163
|
+
}
|
|
127
164
|
function addTxOptimizations(umi, tx, computeUnitPrice, computeUnitLimit) {
|
|
128
165
|
const computePriceIx = computeUnitPrice !== undefined
|
|
129
166
|
? setComputeUnitPriceUmiIx(umi.identity, computeUnitPrice)
|
|
@@ -134,13 +171,14 @@ function addTxOptimizations(umi, tx, computeUnitPrice, computeUnitLimit) {
|
|
|
134
171
|
const allOptimizations = tx.prepend(computePriceIx).prepend(computeLimitIx);
|
|
135
172
|
const withCuPrice = tx.prepend(computePriceIx);
|
|
136
173
|
const withCuLimit = tx.prepend(computeLimitIx);
|
|
137
|
-
|
|
174
|
+
// Use actual serialization check instead of estimate
|
|
175
|
+
if (canSerializeTransaction(umi, allOptimizations)) {
|
|
138
176
|
return prependTx(tx, [computePriceIx, computeLimitIx]);
|
|
139
177
|
}
|
|
140
|
-
else if (
|
|
178
|
+
else if (canSerializeTransaction(umi, withCuPrice)) {
|
|
141
179
|
return prependTx(tx, [computePriceIx]);
|
|
142
180
|
}
|
|
143
|
-
else if (
|
|
181
|
+
else if (canSerializeTransaction(umi, withCuLimit)) {
|
|
144
182
|
return prependTx(tx, [computeLimitIx]);
|
|
145
183
|
}
|
|
146
184
|
else {
|
|
@@ -278,12 +278,12 @@ class ContextUpdates {
|
|
|
278
278
|
...dca.automation,
|
|
279
279
|
intervalSeconds: BigInt(dca.automation.intervalSeconds),
|
|
280
280
|
unixStartDate: BigInt(dca.automation.unixStartDate),
|
|
281
|
-
padding: new Uint8Array(
|
|
282
|
-
padding1:
|
|
281
|
+
padding: new Uint8Array(32),
|
|
282
|
+
padding1: new Array(4).fill(0),
|
|
283
283
|
},
|
|
284
284
|
dcaInBaseUnit: BigInt(dca.dcaInBaseUnit),
|
|
285
285
|
tokenType: dca.tokenType,
|
|
286
|
-
padding:
|
|
286
|
+
padding: new Array(31).fill(0),
|
|
287
287
|
};
|
|
288
288
|
}
|
|
289
289
|
else if (update.type === "cancellingDca") {
|
package/local/txSandbox.ts
CHANGED
|
@@ -2,11 +2,13 @@ import { Keypair, PublicKey } from "@solana/web3.js";
|
|
|
2
2
|
import { createSignerFromKeypair, publicKey } from "@metaplex-foundation/umi";
|
|
3
3
|
import { fromWeb3JsKeypair } from "@metaplex-foundation/umi-web3js-adapters";
|
|
4
4
|
import {
|
|
5
|
+
buildSwbSubmitResponseTx,
|
|
5
6
|
ClientTransactionsManager,
|
|
6
7
|
consoleLog,
|
|
7
8
|
fetchBank,
|
|
8
9
|
getBatches,
|
|
9
10
|
getClient,
|
|
11
|
+
getMarginfiAccounts,
|
|
10
12
|
getPositionExBulk,
|
|
11
13
|
getSolanaRpcConnection,
|
|
12
14
|
getSolautoManagedPositions,
|
|
@@ -22,8 +24,10 @@ import {
|
|
|
22
24
|
SOLAUTO_TEST_PROGRAM,
|
|
23
25
|
SolautoClient,
|
|
24
26
|
TransactionItem,
|
|
27
|
+
USDC,
|
|
25
28
|
} from "../src";
|
|
26
29
|
import { getSecretKey } from "./shared";
|
|
30
|
+
import { NATIVE_MINT } from "@solana/spl-token";
|
|
27
31
|
|
|
28
32
|
const payForTransaction = true;
|
|
29
33
|
const testProgram = false;
|
|
@@ -49,30 +53,39 @@ export async function main() {
|
|
|
49
53
|
lpEnv,
|
|
50
54
|
});
|
|
51
55
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
56
|
+
await client.initializeNewSolautoPosition({
|
|
57
|
+
// positionId: 1,
|
|
58
|
+
positionId: 99,
|
|
59
|
+
supplyMint: NATIVE_MINT,
|
|
60
|
+
debtMint: new PublicKey(USDC),
|
|
61
|
+
lpPoolAccount: getMarginfiAccounts().defaultGroup,
|
|
62
|
+
// lpPoolAccount: new PublicKey("GEokw9jqbh6d1xUNA3qaeYFFetbSR5Y1nt7C3chwwgSz")
|
|
63
|
+
// lpUserAccount: new PublicKey(
|
|
64
|
+
// "GEokw9jqbh6d1xUNA3qaeYFFetbSR5Y1nt7C3chwwgSz"
|
|
65
|
+
// ),
|
|
66
|
+
});
|
|
59
67
|
|
|
60
68
|
// const transactionItems = [rebalance(client)];
|
|
69
|
+
const transactionItems: TransactionItem[] = [
|
|
70
|
+
new TransactionItem(
|
|
71
|
+
async () =>
|
|
72
|
+
await buildSwbSubmitResponseTx(
|
|
73
|
+
client.connection,
|
|
74
|
+
client.signer,
|
|
75
|
+
new PublicKey(NATIVE_MINT)
|
|
76
|
+
// new PublicKey(JITO_SOL)
|
|
77
|
+
)!
|
|
78
|
+
),
|
|
79
|
+
];
|
|
61
80
|
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
// txRunType: payForTransaction ? "normal" : "only-simulate",
|
|
71
|
-
// priorityFeeSetting: PriorityFeeSetting.Default,
|
|
72
|
-
// retryConfig: { totalRetries: 2 },
|
|
73
|
-
// });
|
|
74
|
-
// const statuses = await txManager.send(transactionItems);
|
|
75
|
-
// consoleLog(statuses);
|
|
81
|
+
const txManager = new ClientTransactionsManager({
|
|
82
|
+
txHandler: client,
|
|
83
|
+
txRunType: payForTransaction ? "normal" : "only-simulate",
|
|
84
|
+
priorityFeeSetting: PriorityFeeSetting.Default,
|
|
85
|
+
retryConfig: { totalRetries: 2 },
|
|
86
|
+
});
|
|
87
|
+
const statuses = await txManager.send(transactionItems);
|
|
88
|
+
consoleLog(statuses);
|
|
76
89
|
}
|
|
77
90
|
|
|
78
91
|
async function refreshAll() {
|
package/package.json
CHANGED
|
@@ -7,15 +7,23 @@ import {
|
|
|
7
7
|
TransactionRunType,
|
|
8
8
|
} from "../../../types";
|
|
9
9
|
import {
|
|
10
|
+
addTxOptimizations,
|
|
11
|
+
canSerializeTransaction,
|
|
10
12
|
consoleLog,
|
|
11
13
|
ErrorsToThrow,
|
|
14
|
+
getActualTxSize,
|
|
12
15
|
retryWithExponentialBackoff,
|
|
13
16
|
sendSingleOptimizedTransaction,
|
|
14
17
|
sendJitoBundledTransactions,
|
|
15
18
|
} from "../../../utils";
|
|
16
19
|
import { TxHandler } from "../../solauto";
|
|
17
20
|
import { getErrorInfo } from "../transactionUtils";
|
|
18
|
-
import {
|
|
21
|
+
import {
|
|
22
|
+
JITO_TIP_BUFFER_BYTES,
|
|
23
|
+
LookupTables,
|
|
24
|
+
TransactionItem,
|
|
25
|
+
TransactionSet,
|
|
26
|
+
} from "../types";
|
|
19
27
|
import { UPDATE_ORACLE_TX_NAME } from "../../../constants";
|
|
20
28
|
|
|
21
29
|
export class TransactionTooLargeError extends Error {
|
|
@@ -112,14 +120,25 @@ export class TransactionsManager<T extends TxHandler> {
|
|
|
112
120
|
continue;
|
|
113
121
|
}
|
|
114
122
|
|
|
115
|
-
const transaction =
|
|
123
|
+
const transaction = addTxOptimizations(
|
|
124
|
+
this.txHandler.umi,
|
|
125
|
+
item.tx,
|
|
126
|
+
1,
|
|
127
|
+
1
|
|
128
|
+
).setAddressLookupTables(
|
|
116
129
|
await this.lookupTables.getLutInputs(item.lookupTableAddresses)
|
|
117
130
|
);
|
|
118
|
-
if
|
|
131
|
+
// Check if transaction can be serialized with buffer for Jito tip instruction
|
|
132
|
+
if (
|
|
133
|
+
!canSerializeTransaction(
|
|
134
|
+
this.txHandler.umi,
|
|
135
|
+
transaction,
|
|
136
|
+
JITO_TIP_BUFFER_BYTES
|
|
137
|
+
)
|
|
138
|
+
) {
|
|
139
|
+
const actualSize = getActualTxSize(this.txHandler.umi, transaction);
|
|
119
140
|
throw new TransactionTooLargeError(
|
|
120
|
-
`Exceeds max transaction size (${
|
|
121
|
-
this.txHandler.umi
|
|
122
|
-
)})`
|
|
141
|
+
`Exceeds max transaction size (actual: ${actualSize ?? "failed to serialize"} + ~${JITO_TIP_BUFFER_BYTES} bytes for Jito tip)`
|
|
123
142
|
);
|
|
124
143
|
} else {
|
|
125
144
|
let newSet = new TransactionSet(this.txHandler, this.lookupTables, [
|
|
@@ -2,15 +2,20 @@ import {
|
|
|
2
2
|
AddressLookupTableInput,
|
|
3
3
|
transactionBuilder,
|
|
4
4
|
TransactionBuilder,
|
|
5
|
+
Umi,
|
|
5
6
|
} from "@metaplex-foundation/umi";
|
|
6
7
|
import { TxHandler } from "../../solauto";
|
|
7
8
|
import { LookupTables } from "./lookupTables";
|
|
8
9
|
import { TransactionItem } from "./transactionItem";
|
|
9
|
-
import { addTxOptimizations } from "../../../utils";
|
|
10
|
+
import { addTxOptimizations, canSerializeTransaction } from "../../../utils";
|
|
10
11
|
import { CHORES_TX_NAME } from "../../../constants";
|
|
11
12
|
|
|
12
13
|
const MAX_SUPPORTED_ACCOUNT_LOCKS = 64;
|
|
13
14
|
|
|
15
|
+
// Buffer for Jito tip instruction (~44 bytes) + potential new accounts in message
|
|
16
|
+
// This accounts for: System Transfer instruction data, Jito tip account (if new), etc.
|
|
17
|
+
export const JITO_TIP_BUFFER_BYTES = 75;
|
|
18
|
+
|
|
14
19
|
export class TransactionSet {
|
|
15
20
|
constructor(
|
|
16
21
|
private txHandler: TxHandler,
|
|
@@ -55,7 +60,12 @@ export class TransactionSet {
|
|
|
55
60
|
])
|
|
56
61
|
);
|
|
57
62
|
|
|
58
|
-
|
|
63
|
+
// Use actual serialization check with buffer for Jito tip instruction
|
|
64
|
+
return canSerializeTransaction(
|
|
65
|
+
this.txHandler.umi,
|
|
66
|
+
tx,
|
|
67
|
+
JITO_TIP_BUFFER_BYTES
|
|
68
|
+
);
|
|
59
69
|
}
|
|
60
70
|
|
|
61
71
|
add(...items: TransactionItem[]) {
|
|
@@ -38,7 +38,7 @@ export function createSolautoSettings(
|
|
|
38
38
|
boostToBps: settings.boostToBps,
|
|
39
39
|
repayGap: settings.repayGap,
|
|
40
40
|
repayToBps: settings.repayToBps,
|
|
41
|
-
padding:
|
|
41
|
+
padding: new Array(24).fill(0),
|
|
42
42
|
};
|
|
43
43
|
}
|
|
44
44
|
|
|
@@ -167,9 +167,9 @@ export function createFakePositionState(
|
|
|
167
167
|
borrowFeeBps: 0,
|
|
168
168
|
decimals: supplyDecimals,
|
|
169
169
|
mint: fromWeb3JsPublicKey(supply.mint),
|
|
170
|
-
padding1:
|
|
171
|
-
padding2:
|
|
172
|
-
padding: new Uint8Array(
|
|
170
|
+
padding1: new Array(5).fill(0),
|
|
171
|
+
padding2: new Array(8).fill(0),
|
|
172
|
+
padding: new Uint8Array(32),
|
|
173
173
|
},
|
|
174
174
|
debt: {
|
|
175
175
|
amountUsed: {
|
|
@@ -186,9 +186,9 @@ export function createFakePositionState(
|
|
|
186
186
|
borrowFeeBps: 0,
|
|
187
187
|
decimals: debtDecimals,
|
|
188
188
|
mint: fromWeb3JsPublicKey(debt.mint),
|
|
189
|
-
padding1:
|
|
190
|
-
padding2:
|
|
191
|
-
padding: new Uint8Array(
|
|
189
|
+
padding1: new Array(5).fill(0),
|
|
190
|
+
padding2: new Array(8).fill(0),
|
|
191
|
+
padding: new Uint8Array(32),
|
|
192
192
|
},
|
|
193
193
|
netWorth: {
|
|
194
194
|
baseUnit: supply.price
|
|
@@ -199,8 +199,8 @@ export function createFakePositionState(
|
|
|
199
199
|
maxLtvBps,
|
|
200
200
|
liqThresholdBps,
|
|
201
201
|
lastRefreshed: BigInt(currentUnixSeconds()),
|
|
202
|
-
padding1:
|
|
203
|
-
padding2:
|
|
204
|
-
padding:
|
|
202
|
+
padding1: new Array(6).fill(0),
|
|
203
|
+
padding2: new Array(4).fill(0),
|
|
204
|
+
padding: new Array(2).fill(0),
|
|
205
205
|
};
|
|
206
206
|
}
|
package/src/utils/jitoUtils.ts
CHANGED
|
@@ -72,18 +72,35 @@ 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
|
+
|
|
75
94
|
const simulationResult = await retryWithExponentialBackoff(async () => {
|
|
76
95
|
const res = await customRpcCall(umi, "simulateBundle", [
|
|
77
96
|
{
|
|
78
|
-
encodedTransactions:
|
|
79
|
-
Buffer.from(x.serialize()).toString("base64")
|
|
80
|
-
),
|
|
97
|
+
encodedTransactions: serializedTxs,
|
|
81
98
|
},
|
|
82
99
|
{
|
|
83
100
|
encoding: "base64",
|
|
84
101
|
commitment: "confirmed",
|
|
85
|
-
preExecutionAccountsConfigs: txs.map((_) => {}),
|
|
86
|
-
postExecutionAccountsConfigs: txs.map((_) => {}),
|
|
102
|
+
preExecutionAccountsConfigs: txs.map((_) => { }),
|
|
103
|
+
postExecutionAccountsConfigs: txs.map((_) => { }),
|
|
87
104
|
skipSigVerify: true,
|
|
88
105
|
},
|
|
89
106
|
]);
|
|
@@ -298,12 +315,17 @@ export async function sendJitoBundledTransactions(
|
|
|
298
315
|
txs.map((tx) => tx.getInstructions().map((x) => x.programId.toString()))
|
|
299
316
|
);
|
|
300
317
|
consoleLog(
|
|
301
|
-
"Transaction sizes: ",
|
|
318
|
+
"Transaction sizes (before tip): ",
|
|
302
319
|
txs.map((x) => x.getTransactionSize(umi))
|
|
303
320
|
);
|
|
304
321
|
|
|
305
322
|
txs[0] = prependTx(txs[0], [getTipInstruction(userSigner, 250_000)]);
|
|
306
323
|
|
|
324
|
+
consoleLog(
|
|
325
|
+
"Transaction sizes (after tip): ",
|
|
326
|
+
txs.map((x) => x.getTransactionSize(umi))
|
|
327
|
+
);
|
|
328
|
+
|
|
307
329
|
const latestBlockhash = (
|
|
308
330
|
await retryWithExponentialBackoff(
|
|
309
331
|
async () => await umi.rpc.getLatestBlockhash({ commitment: "confirmed" })
|
|
@@ -334,16 +356,16 @@ export async function sendJitoBundledTransactions(
|
|
|
334
356
|
|
|
335
357
|
const feeEstimates = usePriorityFee(priorityFeeSetting)
|
|
336
358
|
? await Promise.all(
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
)
|
|
359
|
+
txs.map(
|
|
360
|
+
async (x) =>
|
|
361
|
+
(await getComputeUnitPriceEstimate(
|
|
362
|
+
umi,
|
|
363
|
+
x,
|
|
364
|
+
priorityFeeSetting,
|
|
365
|
+
true
|
|
366
|
+
)) ?? 1000000
|
|
346
367
|
)
|
|
368
|
+
)
|
|
347
369
|
: undefined;
|
|
348
370
|
|
|
349
371
|
if (abortController?.signal.aborted) {
|
|
@@ -288,9 +288,9 @@ async function getTokenUsage(
|
|
|
288
288
|
},
|
|
289
289
|
baseAmountMarketPriceUsd: toBaseUnit(marketPrice, USD_DECIMALS),
|
|
290
290
|
borrowFeeBps: isAsset ? 0 : toBps(originationFee),
|
|
291
|
-
padding1:
|
|
292
|
-
padding2:
|
|
293
|
-
padding: new Uint8Array(
|
|
291
|
+
padding1: new Array(5).fill(0),
|
|
292
|
+
padding2: new Array(8).fill(0),
|
|
293
|
+
padding: new Uint8Array(32),
|
|
294
294
|
};
|
|
295
295
|
}
|
|
296
296
|
|
|
@@ -513,9 +513,9 @@ export async function getMarginfiAccountPositionState(
|
|
|
513
513
|
maxLtvBps,
|
|
514
514
|
liqThresholdBps,
|
|
515
515
|
lastRefreshed: BigInt(currentUnixSeconds()),
|
|
516
|
-
padding1:
|
|
517
|
-
padding2:
|
|
518
|
-
padding:
|
|
516
|
+
padding1: new Array(6).fill(0),
|
|
517
|
+
padding2: new Array(4).fill(0),
|
|
518
|
+
padding: new Array(2).fill(0),
|
|
519
519
|
},
|
|
520
520
|
};
|
|
521
521
|
}
|
package/src/utils/solanaUtils.ts
CHANGED
|
@@ -234,6 +234,51 @@ export function prependTx(
|
|
|
234
234
|
}
|
|
235
235
|
}
|
|
236
236
|
|
|
237
|
+
const MAX_TX_SIZE = 1232;
|
|
238
|
+
|
|
239
|
+
// Dummy blockhash for size checking (all zeros, 32 bytes base58 encoded)
|
|
240
|
+
const DUMMY_BLOCKHASH = "11111111111111111111111111111111";
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Safely checks if a transaction can be serialized and returns its actual size.
|
|
244
|
+
* Returns undefined if serialization fails.
|
|
245
|
+
*/
|
|
246
|
+
export function getActualTxSize(
|
|
247
|
+
umi: Umi,
|
|
248
|
+
tx: TransactionBuilder
|
|
249
|
+
): number | undefined {
|
|
250
|
+
try {
|
|
251
|
+
// Set a dummy blockhash if not already set, just for size checking
|
|
252
|
+
const txWithBlockhash = tx.setBlockhash(DUMMY_BLOCKHASH);
|
|
253
|
+
// Build the transaction and convert to web3.js format
|
|
254
|
+
const builtTx = txWithBlockhash.build(umi);
|
|
255
|
+
const web3Tx = toWeb3JsTransaction(builtTx);
|
|
256
|
+
// Actually serialize to get the real size
|
|
257
|
+
const serialized = web3Tx.serialize();
|
|
258
|
+
return serialized.length;
|
|
259
|
+
} catch (e) {
|
|
260
|
+
// Serialization failed - transaction is too large or malformed
|
|
261
|
+
consoleLog("Transaction serialization check failed:", e);
|
|
262
|
+
return undefined;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Checks if a transaction can fit in a single transaction by actually serializing it.
|
|
268
|
+
* More accurate than getTransactionSize() estimation.
|
|
269
|
+
*/
|
|
270
|
+
export function canSerializeTransaction(
|
|
271
|
+
umi: Umi,
|
|
272
|
+
tx: TransactionBuilder,
|
|
273
|
+
buffer: number = 0
|
|
274
|
+
): boolean {
|
|
275
|
+
const size = getActualTxSize(umi, tx);
|
|
276
|
+
if (size === undefined) {
|
|
277
|
+
return false;
|
|
278
|
+
}
|
|
279
|
+
return size + buffer <= MAX_TX_SIZE;
|
|
280
|
+
}
|
|
281
|
+
|
|
237
282
|
export function addTxOptimizations(
|
|
238
283
|
umi: Umi,
|
|
239
284
|
tx: TransactionBuilder,
|
|
@@ -251,11 +296,13 @@ export function addTxOptimizations(
|
|
|
251
296
|
const allOptimizations = tx.prepend(computePriceIx).prepend(computeLimitIx);
|
|
252
297
|
const withCuPrice = tx.prepend(computePriceIx);
|
|
253
298
|
const withCuLimit = tx.prepend(computeLimitIx);
|
|
254
|
-
|
|
299
|
+
|
|
300
|
+
// Use actual serialization check instead of estimate
|
|
301
|
+
if (canSerializeTransaction(umi, allOptimizations)) {
|
|
255
302
|
return prependTx(tx, [computePriceIx, computeLimitIx]);
|
|
256
|
-
} else if (
|
|
303
|
+
} else if (canSerializeTransaction(umi, withCuPrice)) {
|
|
257
304
|
return prependTx(tx, [computePriceIx]);
|
|
258
|
-
} else if (
|
|
305
|
+
} else if (canSerializeTransaction(umi, withCuLimit)) {
|
|
259
306
|
return prependTx(tx, [computeLimitIx]);
|
|
260
307
|
} else {
|
|
261
308
|
return tx;
|
|
@@ -403,12 +403,12 @@ export class ContextUpdates {
|
|
|
403
403
|
...dca.automation,
|
|
404
404
|
intervalSeconds: BigInt(dca.automation.intervalSeconds),
|
|
405
405
|
unixStartDate: BigInt(dca.automation.unixStartDate),
|
|
406
|
-
padding: new Uint8Array(
|
|
407
|
-
padding1:
|
|
406
|
+
padding: new Uint8Array(32),
|
|
407
|
+
padding1: new Array(4).fill(0),
|
|
408
408
|
},
|
|
409
409
|
dcaInBaseUnit: BigInt(dca.dcaInBaseUnit),
|
|
410
410
|
tokenType: dca.tokenType,
|
|
411
|
-
padding:
|
|
411
|
+
padding: new Array(31).fill(0),
|
|
412
412
|
};
|
|
413
413
|
} else if (update.type === "cancellingDca") {
|
|
414
414
|
this.cancellingDca = update.value;
|