@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.
@@ -58,7 +58,7 @@ function marginfiProtocolInteraction(context, input) {
58
58
  },
59
59
  marginfiGroup: {
60
60
  index: 7,
61
- isWritable: false,
61
+ isWritable: true,
62
62
  value: input.marginfiGroup ?? null,
63
63
  },
64
64
  marginfiAccount: {
@@ -82,7 +82,7 @@ function marginfiRebalance(context, input) {
82
82
  },
83
83
  marginfiGroup: {
84
84
  index: 10,
85
- isWritable: false,
85
+ isWritable: true,
86
86
  value: input.marginfiGroup ?? null,
87
87
  },
88
88
  marginfiAccount: {
@@ -1 +1 @@
1
- {"version":3,"file":"transactionsManager.d.ts","sourceRoot":"","sources":["../../../../src/services/transactions/manager/transactionsManager.ts"],"names":[],"mappings":"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"}
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,EAIL,aAAa,EAKd,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE1C,OAAO,EAEL,YAAY,EACZ,eAAe,EAEhB,MAAM,UAAU,CAAC;AAGlB,qBAAa,wBAAyB,SAAQ,KAAK;gBACrC,OAAO,EAAE,MAAM;CAK5B;AAED,oBAAY,iBAAiB;IAC3B,OAAO,YAAY;IACnB,UAAU,eAAe;IACzB,MAAM,WAAW;IACjB,UAAU,eAAe;IACzB,MAAM,WAAW;CAClB;AAED,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,iBAAiB,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,0BAA0B,GAAG,wBAAwB,EAAE,CAAC;AAEpE,UAAU,WAAW;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,uBAAuB,CAAC,CAAC,SAAS,SAAS;IAC1D,SAAS,EAAE,CAAC,CAAC;IACb,cAAc,CAAC,EAAE,CAAC,QAAQ,EAAE,0BAA0B,KAAK,IAAI,CAAC;IAChE,SAAS,CAAC,EAAE,kBAAkB,CAAC;IAC/B,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACxC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,eAAe,CAAC,EAAE,eAAe,CAAC;CACnC;AAED,qBAAa,mBAAmB,CAAC,CAAC,SAAS,SAAS;IAClD,SAAS,CAAC,SAAS,EAAE,CAAC,CAAC;IACvB,SAAS,CAAC,cAAc,CAAC,EAAE,CAAC,QAAQ,EAAE,0BAA0B,KAAK,IAAI,CAAC;IAC1E,SAAS,CAAC,SAAS,CAAC,EAAE,kBAAkB,CAAC;IACzC,SAAS,CAAC,kBAAkB,EAAE,kBAAkB,CAAC;IACjD,SAAS,CAAC,UAAU,EAAE,OAAO,CAAC;IAC9B,SAAS,CAAC,aAAa,CAAC,EAAE,aAAa,CAAC;IACxC,SAAS,CAAC,QAAQ,EAAE,0BAA0B,CAAM;IACpD,SAAS,CAAC,YAAY,EAAE,YAAY,CAAC;IACrC,SAAS,CAAC,eAAe,EAAE,MAAM,CAAC;IAClC,SAAS,CAAC,YAAY,EAAE,MAAM,CAAC;IAC/B,SAAS,CAAC,UAAU,EAAE,MAAM,CAAC;IAC7B,SAAS,CAAC,eAAe,CAAC,EAAE,eAAe,CAAC;gBAEhC,IAAI,EAAE,uBAAuB,CAAC,CAAC,CAAC;YAoB9B,uBAAuB;IAwDrC,OAAO,CAAC,YAAY;YAiCN,aAAa;IAwB3B,SAAS,CAAC,4BAA4B,CACpC,SAAS,EAAE,KAAK,GAAG,SAAS,EAC5B,UAAU,EAAE,MAAM;IAcpB,OAAO,CAAC,mBAAmB;IAkBd,IAAI,CACf,KAAK,EAAE,eAAe,EAAE,GACvB,OAAO,CAAC,0BAA0B,CAAC;IAoCtC,OAAO,CAAC,mBAAmB;YA0Bb,eAAe;YAkDf,6BAA6B;YAyC7B,cAAc;YA0Ed,qBAAqB;cAuDnB,eAAe,CAC7B,EAAE,EAAE,kBAAkB,EACtB,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,EAClB,kBAAkB,CAAC,EAAE,kBAAkB,EACvC,SAAS,CAAC,EAAE,kBAAkB;IAqChC,OAAO,CAAC,gBAAgB;CAuCzB"}
@@ -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 (!transaction.fitsInOneTransaction(this.txHandler.umi)) {
59
- throw new TransactionTooLargeError(`Exceeds max transaction size (${transaction.getTransactionSize(this.txHandler.umi)})`);
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,EACnB,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;AAMpD,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;IA4BvD,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
+ {"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
- return tx.fitsInOneTransaction(this.txHandler.umi);
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;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"}
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"}
@@ -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: txs.map((x) => Buffer.from(x.serialize()).toString("base64")),
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":"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"}
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
- if (allOptimizations.fitsInOneTransaction(umi)) {
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 (withCuPrice.fitsInOneTransaction(umi)) {
178
+ else if (canSerializeTransaction(umi, withCuPrice)) {
141
179
  return prependTx(tx, [computePriceIx]);
142
180
  }
143
- else if (withCuLimit.fitsInOneTransaction(umi)) {
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") {
@@ -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
- // await client.initializeExistingSolautoPosition({
53
- // positionId: 1,
54
- // authority: new PublicKey("61rtn5tzVkesapo6Cz83SPoShUfAePSxJsqniuF2wRKC"),
55
- // // lpUserAccount: new PublicKey(
56
- // // "GEokw9jqbh6d1xUNA3qaeYFFetbSR5Y1nt7C3chwwgSz"
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 account = await fetchBank(umi, publicKey("Ac4KV5K5isDqtABtg6h5DiwzZMe3Sp9bc3pBiCUvUpaQ"));
63
- console.log(account.config.oracleKeys[0]);
64
- console.log(account.config.oracleKeys[1]);
65
- console.log(account.config.oracleKeys[2]);
66
- console.log(account.config.oracleKeys[3]);
67
-
68
- // const txManager = new ClientTransactionsManager({
69
- // txHandler: client,
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@haven-fi/solauto-sdk",
3
- "version": "1.0.814",
3
+ "version": "1.0.816",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "description": "Typescript SDK for the Solauto program on the Solana blockchain",
@@ -139,7 +139,7 @@ export function marginfiProtocolInteraction(
139
139
  },
140
140
  marginfiGroup: {
141
141
  index: 7,
142
- isWritable: false as boolean,
142
+ isWritable: true as boolean,
143
143
  value: input.marginfiGroup ?? null,
144
144
  },
145
145
  marginfiAccount: {
@@ -188,7 +188,7 @@ export function marginfiRebalance(
188
188
  },
189
189
  marginfiGroup: {
190
190
  index: 10,
191
- isWritable: false as boolean,
191
+ isWritable: true as boolean,
192
192
  value: input.marginfiGroup ?? null,
193
193
  },
194
194
  marginfiAccount: {
@@ -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 { LookupTables, TransactionItem, TransactionSet } from "../types";
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 = item.tx.setAddressLookupTables(
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 (!transaction.fitsInOneTransaction(this.txHandler.umi)) {
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 (${transaction.getTransactionSize(
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
- return tx.fitsInOneTransaction(this.txHandler.umi);
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
  }
@@ -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: txs.map((x) =>
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
- txs.map(
338
- async (x) =>
339
- (await getComputeUnitPriceEstimate(
340
- umi,
341
- x,
342
- priorityFeeSetting,
343
- true
344
- )) ?? 1000000
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
  }
@@ -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
- if (allOptimizations.fitsInOneTransaction(umi)) {
299
+
300
+ // Use actual serialization check instead of estimate
301
+ if (canSerializeTransaction(umi, allOptimizations)) {
255
302
  return prependTx(tx, [computePriceIx, computeLimitIx]);
256
- } else if (withCuPrice.fitsInOneTransaction(umi)) {
303
+ } else if (canSerializeTransaction(umi, withCuPrice)) {
257
304
  return prependTx(tx, [computePriceIx]);
258
- } else if (withCuLimit.fitsInOneTransaction(umi)) {
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;