@haven-fi/solauto-sdk 1.0.238 → 1.0.240

Sign up to get free protection for your applications and to get access to all the features.
@@ -35,18 +35,22 @@ export declare class TransactionsManager {
35
35
  private txHandler;
36
36
  private statusCallback?;
37
37
  private txType?;
38
- private mustBeAtomic?;
38
+ private priorityFeeSetting;
39
39
  private errorsToThrow?;
40
40
  private retries;
41
41
  private retryDelay;
42
42
  private statuses;
43
43
  private lookupTables;
44
- constructor(txHandler: SolautoClient | ReferralStateManager, statusCallback?: ((statuses: TransactionManagerStatuses) => void) | undefined, txType?: TransactionRunType | undefined, mustBeAtomic?: boolean | undefined, errorsToThrow?: ErrorsToThrow | undefined, retries?: number, retryDelay?: number);
44
+ constructor(txHandler: SolautoClient | ReferralStateManager, statusCallback?: ((statuses: TransactionManagerStatuses) => void) | undefined, txType?: TransactionRunType | undefined, priorityFeeSetting?: PriorityFeeSetting, errorsToThrow?: ErrorsToThrow | undefined, retries?: number, retryDelay?: number);
45
45
  private assembleTransactionSets;
46
46
  private updateStatus;
47
47
  private debugAccounts;
48
- clientSend(transactions: TransactionItem[], prioritySetting?: PriorityFeeSetting): Promise<TransactionManagerStatuses>;
49
- send(items: TransactionItem[], prioritySetting?: PriorityFeeSetting, initialized?: boolean): Promise<TransactionManagerStatuses>;
48
+ private getUpdatedPriorityFeeSetting;
49
+ private updateStatusForSets;
50
+ clientSend(transactions: TransactionItem[]): Promise<TransactionManagerStatuses>;
51
+ send(items: TransactionItem[], initialized?: boolean): Promise<TransactionManagerStatuses>;
52
+ private processTransactionSet;
53
+ private refreshItemSet;
50
54
  private sendTransaction;
51
55
  }
52
56
  //# sourceMappingURL=transactionsManager.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"transactionsManager.d.ts","sourceRoot":"","sources":["../../src/transactions/transactionsManager.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,kBAAkB,EAEnB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAKzD,OAAO,EACL,aAAa,EAEd,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACL,kBAAkB,EAClB,qBAAqB,EACrB,kBAAkB,EACnB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,oBAAoB,EAAa,MAAM,YAAY,CAAC;AAG7D,qBAAa,wBAAyB,SAAQ,KAAK;gBACrC,OAAO,EAAE,MAAM;CAK5B;AAqCD,qBAAa,eAAe;IAKjB,OAAO,EAAE,CACd,UAAU,EAAE,MAAM,KACf,OAAO,CAAC,qBAAqB,GAAG,SAAS,CAAC;IACxC,IAAI,CAAC,EAAE,MAAM;IAPtB,oBAAoB,EAAG,MAAM,EAAE,CAAC;IAChC,EAAE,CAAC,EAAE,kBAAkB,CAAC;gBAGf,OAAO,EAAE,CACd,UAAU,EAAE,MAAM,KACf,OAAO,CAAC,qBAAqB,GAAG,SAAS,CAAC,EACxC,IAAI,CAAC,EAAE,MAAM,YAAA;IAGhB,UAAU;IAIV,OAAO,CAAC,UAAU,EAAE,MAAM;IAMhC,cAAc,IAAI,MAAM,EAAE;CAY3B;AAgFD,oBAAY,iBAAiB;IAC3B,OAAO,YAAY;IACnB,UAAU,eAAe;IACzB,MAAM,WAAW;IACjB,UAAU,eAAe;IACzB,MAAM,WAAW;CAClB;AAED,MAAM,MAAM,0BAA0B,GAAG;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,EAAE,CAAC;AAEJ,qBAAa,mBAAmB;IAK5B,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,cAAc,CAAC;IACvB,OAAO,CAAC,MAAM,CAAC;IACf,OAAO,CAAC,YAAY,CAAC;IACrB,OAAO,CAAC,aAAa,CAAC;IACtB,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,UAAU;IAVpB,OAAO,CAAC,QAAQ,CAAkC;IAClD,OAAO,CAAC,YAAY,CAAe;gBAGzB,SAAS,EAAE,aAAa,GAAG,oBAAoB,EAC/C,cAAc,CAAC,GAAE,CAAC,QAAQ,EAAE,0BAA0B,KAAK,IAAI,aAAA,EAC/D,MAAM,CAAC,EAAE,kBAAkB,YAAA,EAC3B,YAAY,CAAC,EAAE,OAAO,YAAA,EACtB,aAAa,CAAC,EAAE,aAAa,YAAA,EAC7B,OAAO,GAAE,MAAU,EACnB,UAAU,GAAE,MAAY;YAQpB,uBAAuB;IAwCrC,OAAO,CAAC,YAAY;YA8CN,aAAa;IAoBd,UAAU,CACrB,YAAY,EAAE,eAAe,EAAE,EAC/B,eAAe,CAAC,EAAE,kBAAkB,GACnC,OAAO,CAAC,0BAA0B,CAAC;IAyEzB,IAAI,CACf,KAAK,EAAE,eAAe,EAAE,EACxB,eAAe,CAAC,EAAE,kBAAkB,EACpC,WAAW,CAAC,EAAE,OAAO,GACpB,OAAO,CAAC,0BAA0B,CAAC;YAwGxB,eAAe;CAkD9B"}
1
+ {"version":3,"file":"transactionsManager.d.ts","sourceRoot":"","sources":["../../src/transactions/transactionsManager.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,kBAAkB,EAEnB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAKzD,OAAO,EACL,aAAa,EAEd,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACL,kBAAkB,EAElB,qBAAqB,EACrB,kBAAkB,EACnB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,oBAAoB,EAAa,MAAM,YAAY,CAAC;AAI7D,qBAAa,wBAAyB,SAAQ,KAAK;gBACrC,OAAO,EAAE,MAAM;CAK5B;AAqCD,qBAAa,eAAe;IAKjB,OAAO,EAAE,CACd,UAAU,EAAE,MAAM,KACf,OAAO,CAAC,qBAAqB,GAAG,SAAS,CAAC;IACxC,IAAI,CAAC,EAAE,MAAM;IAPtB,oBAAoB,EAAG,MAAM,EAAE,CAAC;IAChC,EAAE,CAAC,EAAE,kBAAkB,CAAC;gBAGf,OAAO,EAAE,CACd,UAAU,EAAE,MAAM,KACf,OAAO,CAAC,qBAAqB,GAAG,SAAS,CAAC,EACxC,IAAI,CAAC,EAAE,MAAM,YAAA;IAGhB,UAAU;IAIV,OAAO,CAAC,UAAU,EAAE,MAAM;IAMhC,cAAc,IAAI,MAAM,EAAE;CAY3B;AAgFD,oBAAY,iBAAiB;IAC3B,OAAO,YAAY;IACnB,UAAU,eAAe;IACzB,MAAM,WAAW;IACjB,UAAU,eAAe;IACzB,MAAM,WAAW;CAClB;AAED,MAAM,MAAM,0BAA0B,GAAG;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,EAAE,CAAC;AAEJ,qBAAa,mBAAmB;IAK5B,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,cAAc,CAAC;IACvB,OAAO,CAAC,MAAM,CAAC;IACf,OAAO,CAAC,kBAAkB;IAC1B,OAAO,CAAC,aAAa,CAAC;IACtB,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,UAAU;IAVpB,OAAO,CAAC,QAAQ,CAAkC;IAClD,OAAO,CAAC,YAAY,CAAe;gBAGzB,SAAS,EAAE,aAAa,GAAG,oBAAoB,EAC/C,cAAc,CAAC,GAAE,CAAC,QAAQ,EAAE,0BAA0B,KAAK,IAAI,aAAA,EAC/D,MAAM,CAAC,EAAE,kBAAkB,YAAA,EAC3B,kBAAkB,GAAE,kBAA2C,EAC/D,aAAa,CAAC,EAAE,aAAa,YAAA,EAC7B,OAAO,GAAE,MAAU,EACnB,UAAU,GAAE,MAAY;YAQpB,uBAAuB;IAwCrC,OAAO,CAAC,YAAY;YA8CN,aAAa;IAoB3B,OAAO,CAAC,4BAA4B;IAUpC,OAAO,CAAC,mBAAmB;IAMd,UAAU,CACrB,YAAY,EAAE,eAAe,EAAE,GAC9B,OAAO,CAAC,0BAA0B,CAAC;IAyEzB,IAAI,CACf,KAAK,EAAE,eAAe,EAAE,EACxB,WAAW,CAAC,EAAE,OAAO,GACpB,OAAO,CAAC,0BAA0B,CAAC;YA6BxB,qBAAqB;YAiDrB,cAAc;YAqBd,eAAe;CAkD9B"}
@@ -9,11 +9,13 @@ const umi_1 = require("@metaplex-foundation/umi");
9
9
  const solanaUtils_1 = require("../utils/solanaUtils");
10
10
  const generalUtils_1 = require("../utils/generalUtils");
11
11
  const transactionUtils_1 = require("./transactionUtils");
12
+ const types_1 = require("../types");
13
+ const web3_js_1 = require("@solana/web3.js");
12
14
  // import { sendJitoBundledTransactions } from "../utils/jitoUtils";
13
15
  class TransactionTooLargeError extends Error {
14
16
  constructor(message) {
15
17
  super(message);
16
- this.name = 'TransactionTooLargeError';
18
+ this.name = "TransactionTooLargeError";
17
19
  Object.setPrototypeOf(this, TransactionTooLargeError.prototype);
18
20
  }
19
21
  }
@@ -127,11 +129,11 @@ var TransactionStatus;
127
129
  TransactionStatus["Failed"] = "Failed";
128
130
  })(TransactionStatus || (exports.TransactionStatus = TransactionStatus = {}));
129
131
  class TransactionsManager {
130
- constructor(txHandler, statusCallback, txType, mustBeAtomic, errorsToThrow, retries = 4, retryDelay = 150) {
132
+ constructor(txHandler, statusCallback, txType, priorityFeeSetting = types_1.PriorityFeeSetting.Min, errorsToThrow, retries = 4, retryDelay = 150) {
131
133
  this.txHandler = txHandler;
132
134
  this.statusCallback = statusCallback;
133
135
  this.txType = txType;
134
- this.mustBeAtomic = mustBeAtomic;
136
+ this.priorityFeeSetting = priorityFeeSetting;
135
137
  this.errorsToThrow = errorsToThrow;
136
138
  this.retries = retries;
137
139
  this.retryDelay = retryDelay;
@@ -222,7 +224,19 @@ class TransactionsManager {
222
224
  }
223
225
  }
224
226
  }
225
- async clientSend(transactions, prioritySetting) {
227
+ getUpdatedPriorityFeeSetting(prevError) {
228
+ if (prevError instanceof web3_js_1.TransactionExpiredBlockheightExceededError) {
229
+ const currIdx = types_1.priorityFeeSettingValues.indexOf(this.priorityFeeSetting);
230
+ return types_1.priorityFeeSettingValues[Math.min(types_1.priorityFeeSettingValues.length - 1, currIdx + 1)];
231
+ }
232
+ return this.priorityFeeSetting;
233
+ }
234
+ updateStatusForSets(itemSets) {
235
+ itemSets.forEach((itemSet) => {
236
+ this.updateStatus(itemSet.name(), TransactionStatus.Queued, 0);
237
+ });
238
+ }
239
+ async clientSend(transactions) {
226
240
  const items = [...transactions];
227
241
  const client = this.txHandler;
228
242
  const updateLookupTable = await client.updateLookupTable();
@@ -230,7 +244,7 @@ class TransactionsManager {
230
244
  if (updateLookupTable &&
231
245
  updateLookupTable.updateLutTx.getInstructions().length > 0 &&
232
246
  updateLookupTable?.needsToBeIsolated) {
233
- await (0, generalUtils_1.retryWithExponentialBackoff)(async (attemptNum) => await this.sendTransaction(updateLookupTable.updateLutTx, updateLutTxName, attemptNum, prioritySetting), 3, 150, this.errorsToThrow);
247
+ await (0, generalUtils_1.retryWithExponentialBackoff)(async (attemptNum, prevError) => await this.sendTransaction(updateLookupTable.updateLutTx, updateLutTxName, attemptNum, this.getUpdatedPriorityFeeSetting(prevError)), 3, 150, this.errorsToThrow);
234
248
  }
235
249
  this.lookupTables.defaultLuts = client.defaultLookupTables();
236
250
  for (const item of items) {
@@ -254,7 +268,7 @@ class TransactionsManager {
254
268
  items.push(chore);
255
269
  this.txHandler.log("Chores after: ", choresAfter.getInstructions().length);
256
270
  }
257
- const result = await this.send(items, prioritySetting, true).catch((e) => {
271
+ const result = await this.send(items, true).catch((e) => {
258
272
  client.resetLiveTxUpdates(false);
259
273
  throw e;
260
274
  });
@@ -263,7 +277,7 @@ class TransactionsManager {
263
277
  }
264
278
  return result;
265
279
  }
266
- async send(items, prioritySetting, initialized) {
280
+ async send(items, initialized) {
267
281
  this.statuses = [];
268
282
  this.lookupTables.reset();
269
283
  if (!initialized) {
@@ -272,73 +286,58 @@ class TransactionsManager {
272
286
  }
273
287
  }
274
288
  const itemSets = await this.assembleTransactionSets(items);
275
- const statusesStartIdx = this.statuses.length;
276
- for (const itemSet of itemSets) {
277
- this.updateStatus(itemSet.name(), TransactionStatus.Queued, 0);
289
+ this.updateStatusForSets(itemSets);
290
+ if (this.txType === "only-simulate" && itemSets.length > 1) {
291
+ this.txHandler.log("Only simulate and more than 1 transaction. Skipping...");
292
+ return [];
278
293
  }
279
- if (this.mustBeAtomic && itemSets.length > 1) {
280
- throw new Error(`${itemSets.length} transactions required but jito bundles are not currently supported`);
281
- // itemSets.forEach((set) => {
282
- // this.updateStatus(set.name(), TransactionStatus.Processing);
283
- // });
284
- // await sendJitoBundledTransactions(
285
- // this.client,
286
- // await Promise.all(itemSets.map((x) => x.getSingleTransaction())),
287
- // this.simulateOnly
288
- // );
289
- // TODO: check if successful or not
290
- // itemSets.forEach((set) => {
291
- // this.updateStatus(set.name(), TransactionStatus.Successful);
292
- // });
294
+ let currentIndex = 0;
295
+ while (currentIndex < itemSets.length) {
296
+ await this.processTransactionSet(itemSets, currentIndex);
297
+ currentIndex++;
293
298
  }
294
- else if (this.txType !== "only-simulate" || itemSets.length === 1) {
295
- for (let i = 0; i < itemSets.length; i++) {
296
- const getFreshItemSet = async (itemSet, attemptNum) => {
297
- await itemSet.refetchAll(attemptNum);
298
- const newItemSets = await this.assembleTransactionSets([
299
- ...itemSet.items,
300
- ...itemSets
301
- .slice(i + 1)
302
- .map((x) => x.items)
303
- .flat(),
304
- ]);
305
- if (newItemSets.length > 1) {
306
- this.statuses.splice(statusesStartIdx + i, itemSets.length - i, ...newItemSets.map((x) => ({
307
- name: x.name(),
308
- status: TransactionStatus.Queued,
309
- attemptNum: 0,
310
- })));
311
- this.txHandler.log(this.statuses);
312
- itemSets.splice(i + 1, itemSets.length - i - 1, ...newItemSets.slice(1));
313
- }
314
- return newItemSets.length > 0 ? newItemSets[0] : undefined;
315
- };
316
- let itemSet = itemSets[i];
317
- await (0, generalUtils_1.retryWithExponentialBackoff)(async (attemptNum) => {
318
- itemSet =
319
- i > 0 || attemptNum > 0
320
- ? await getFreshItemSet(itemSet, attemptNum)
321
- : itemSet;
322
- if (!itemSet) {
323
- return;
324
- }
325
- const tx = await itemSet.getSingleTransaction();
326
- if (tx.getInstructions().length === 0) {
327
- this.updateStatus(itemSet.name(), TransactionStatus.Skipped, attemptNum);
328
- }
329
- else {
330
- await this.debugAccounts(itemSet, tx);
331
- await this.sendTransaction(tx, itemSet.name(), attemptNum, prioritySetting);
332
- }
333
- }, this.retries, this.retryDelay, this.errorsToThrow);
299
+ return this.statuses;
300
+ }
301
+ async processTransactionSet(itemSets, currentIndex) {
302
+ let itemSet = itemSets[currentIndex];
303
+ await (0, generalUtils_1.retryWithExponentialBackoff)(async (attemptNum, prevError) => {
304
+ if (currentIndex > 0 || attemptNum > 0) {
305
+ itemSet = await this.refreshItemSet(itemSets, currentIndex, attemptNum);
306
+ }
307
+ if (!itemSet)
308
+ return;
309
+ const tx = await itemSet.getSingleTransaction();
310
+ if (tx.getInstructions().length === 0) {
311
+ this.updateStatus(itemSet.name(), TransactionStatus.Skipped, attemptNum);
312
+ }
313
+ else {
314
+ await this.debugAccounts(itemSet, tx);
315
+ await this.sendTransaction(tx, itemSet.name(), attemptNum, this.getUpdatedPriorityFeeSetting(prevError));
334
316
  }
317
+ }, this.retries, this.retryDelay, this.errorsToThrow).catch((e) => {
318
+ if (itemSet) {
319
+ this.updateStatus(itemSet.name(), TransactionStatus.Failed, this.retries);
320
+ }
321
+ throw e;
322
+ });
323
+ }
324
+ async refreshItemSet(itemSets, currentIndex, attemptNum) {
325
+ const itemSet = itemSets[currentIndex];
326
+ await itemSet.refetchAll(attemptNum);
327
+ const newItemSets = await this.assembleTransactionSets([
328
+ ...itemSet.items,
329
+ ...itemSets.slice(currentIndex + 1).flatMap((set) => set.items),
330
+ ]);
331
+ if (newItemSets.length > 1) {
332
+ itemSets.splice(currentIndex + 1, itemSets.length - currentIndex - 1, ...newItemSets.slice(1));
333
+ this.updateStatusForSets(newItemSets.slice(1));
335
334
  }
336
- return this.statuses;
335
+ return newItemSets[0];
337
336
  }
338
- async sendTransaction(tx, txName, attemptNum, prioritySetting) {
337
+ async sendTransaction(tx, txName, attemptNum, priorityFeeSetting) {
339
338
  this.updateStatus(txName, TransactionStatus.Processing, attemptNum);
340
339
  try {
341
- const txSig = await (0, solanaUtils_1.sendSingleOptimizedTransaction)(this.txHandler.umi, this.txHandler.connection, tx, this.txType, prioritySetting, () => this.updateStatus(txName, TransactionStatus.Processing, attemptNum, undefined, true));
340
+ const txSig = await (0, solanaUtils_1.sendSingleOptimizedTransaction)(this.txHandler.umi, this.txHandler.connection, tx, this.txType, priorityFeeSetting, () => this.updateStatus(txName, TransactionStatus.Processing, attemptNum, undefined, true));
342
341
  this.updateStatus(txName, TransactionStatus.Successful, attemptNum, txSig ? bs58_1.default.encode(txSig) : undefined);
343
342
  }
344
343
  catch (e) {
@@ -18,6 +18,7 @@ export declare enum PriorityFeeSetting {
18
18
  Default = "Medium",
19
19
  High = "High"
20
20
  }
21
+ export declare const priorityFeeSettingValues: PriorityFeeSetting[];
21
22
  export type RebalanceAction = "boost" | "repay" | "dca";
22
23
  export type TransactionRunType = "skip-simulation" | "only-simulate" | "normal";
23
24
  export interface TransactionItemInputs {
@@ -1 +1 @@
1
- {"version":3,"file":"solauto.d.ts","sourceRoot":"","sources":["../../src/types/solauto.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAE9D,MAAM,WAAW,sBAAsB;IACrC,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,SAAS,EAAE,SAAS,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,YAAY,CAAC;IAC3B,eAAe,EAAE,eAAe,CAAC;IACjC,eAAe,CAAC,EAAE,SAAS,CAAC;IAC5B,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED,oBAAY,kBAAkB;IAC5B,IAAI,SAAS;IACb,GAAG,QAAQ;IACX,GAAG,QAAQ;IACX,OAAO,WAAW;IAClB,IAAI,SAAS;CACd;AAED,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,OAAO,GAAG,KAAK,CAAC;AAExD,MAAM,MAAM,kBAAkB,GAAG,iBAAiB,GAAG,eAAe,GAAG,QAAQ,CAAC;AAEhF,MAAM,WAAW,qBAAqB;IACpC,EAAE,EAAE,kBAAkB,CAAC;IACvB,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;CACjC"}
1
+ {"version":3,"file":"solauto.d.ts","sourceRoot":"","sources":["../../src/types/solauto.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAE9D,MAAM,WAAW,sBAAsB;IACrC,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,SAAS,EAAE,SAAS,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,YAAY,CAAC;IAC3B,eAAe,EAAE,eAAe,CAAC;IACjC,eAAe,CAAC,EAAE,SAAS,CAAC;IAC5B,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED,oBAAY,kBAAkB;IAC5B,IAAI,SAAS;IACb,GAAG,QAAQ;IACX,GAAG,QAAQ;IACX,OAAO,WAAW;IAClB,IAAI,SAAS;CACd;AAED,eAAO,MAAM,wBAAwB,EAAwC,kBAAkB,EAAE,CAAC;AAElG,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,OAAO,GAAG,KAAK,CAAC;AAExD,MAAM,MAAM,kBAAkB,GAAG,iBAAiB,GAAG,eAAe,GAAG,QAAQ,CAAC;AAEhF,MAAM,WAAW,qBAAqB;IACpC,EAAE,EAAE,kBAAkB,CAAC;IACvB,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;CACjC"}
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.PriorityFeeSetting = void 0;
3
+ exports.priorityFeeSettingValues = exports.PriorityFeeSetting = void 0;
4
4
  var PriorityFeeSetting;
5
5
  (function (PriorityFeeSetting) {
6
6
  PriorityFeeSetting["None"] = "None";
@@ -9,3 +9,4 @@ var PriorityFeeSetting;
9
9
  PriorityFeeSetting["Default"] = "Medium";
10
10
  PriorityFeeSetting["High"] = "High";
11
11
  })(PriorityFeeSetting || (exports.PriorityFeeSetting = PriorityFeeSetting = {}));
12
+ exports.priorityFeeSettingValues = Object.values(PriorityFeeSetting);
@@ -10,5 +10,5 @@ export declare function arraysAreEqual(arrayA: number[], arrayB: number[]): bool
10
10
  export declare function fetchTokenPrices(mints: PublicKey[]): Promise<number[]>;
11
11
  export declare function safeGetPrice(mint: PublicKey | UmiPublicKey | undefined): number | undefined;
12
12
  export type ErrorsToThrow = Array<new (...args: any[]) => Error>;
13
- export declare function retryWithExponentialBackoff<T>(fn: (attemptNum: number) => Promise<T>, retries?: number, delay?: number, errorsToThrow?: ErrorsToThrow): Promise<T>;
13
+ export declare function retryWithExponentialBackoff<T>(fn: (attemptNum: number, prevErr?: Error) => Promise<T>, retries?: number, delay?: number, errorsToThrow?: ErrorsToThrow): Promise<T>;
14
14
  //# sourceMappingURL=generalUtils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"generalUtils.d.ts","sourceRoot":"","sources":["../../src/utils/generalUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EACL,eAAe,EAEf,GAAG,EACH,SAAS,IAAI,YAAY,EAC1B,MAAM,0BAA0B,CAAC;AAKlC,wBAAgB,UAAU,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,CAI/C;AACD,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;AAED,wBAAgB,iBAAiB,IAAI,MAAM,CAO1C;AAED,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAED,wBAAsB,uBAAuB,CAC3C,GAAG,EAAE,GAAG,EACR,EAAE,EAAE,SAAS,GACZ,OAAO,CAAC,OAAO,CAAC,CAKlB;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAEnE;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAU1E;AAED,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAsD5E;AAED,wBAAgB,YAAY,CAC1B,IAAI,EAAE,SAAS,GAAG,YAAY,GAAG,SAAS,GACzC,MAAM,GAAG,SAAS,CAKpB;AAED,MAAM,MAAM,aAAa,GAAG,KAAK,CAAC,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,KAAK,CAAC,CAAC;AAEjE,wBAAgB,2BAA2B,CAAC,CAAC,EAC3C,EAAE,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,EACtC,OAAO,GAAE,MAAU,EACnB,KAAK,GAAE,MAAY,EACnB,aAAa,CAAC,EAAE,aAAa,GAC5B,OAAO,CAAC,CAAC,CAAC,CA8BZ"}
1
+ {"version":3,"file":"generalUtils.d.ts","sourceRoot":"","sources":["../../src/utils/generalUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EACL,eAAe,EAEf,GAAG,EACH,SAAS,IAAI,YAAY,EAC1B,MAAM,0BAA0B,CAAC;AAKlC,wBAAgB,UAAU,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,CAI/C;AACD,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;AAED,wBAAgB,iBAAiB,IAAI,MAAM,CAO1C;AAED,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAED,wBAAsB,uBAAuB,CAC3C,GAAG,EAAE,GAAG,EACR,EAAE,EAAE,SAAS,GACZ,OAAO,CAAC,OAAO,CAAC,CAKlB;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAEnE;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAU1E;AAED,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAsD5E;AAED,wBAAgB,YAAY,CAC1B,IAAI,EAAE,SAAS,GAAG,YAAY,GAAG,SAAS,GACzC,MAAM,GAAG,SAAS,CAKpB;AAED,MAAM,MAAM,aAAa,GAAG,KAAK,CAAC,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,KAAK,CAAC,CAAC;AAEjE,wBAAgB,2BAA2B,CAAC,CAAC,EAC3C,EAAE,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,EACvD,OAAO,GAAE,MAAU,EACnB,KAAK,GAAE,MAAY,EACnB,aAAa,CAAC,EAAE,aAAa,GAC5B,OAAO,CAAC,CAAC,CAAC,CA8BZ"}
@@ -97,8 +97,8 @@ function safeGetPrice(mint) {
97
97
  }
98
98
  function retryWithExponentialBackoff(fn, retries = 5, delay = 150, errorsToThrow) {
99
99
  return new Promise((resolve, reject) => {
100
- const attempt = (attemptNum) => {
101
- fn(attemptNum)
100
+ const attempt = (attemptNum, prevErr) => {
101
+ fn(attemptNum, prevErr)
102
102
  .then(resolve)
103
103
  .catch((error) => {
104
104
  attemptNum++;
@@ -111,7 +111,7 @@ function retryWithExponentialBackoff(fn, retries = 5, delay = 150, errorsToThrow
111
111
  consoleLog(error);
112
112
  setTimeout(() => {
113
113
  consoleLog("Retrying...");
114
- return attempt(attemptNum);
114
+ return attempt(attemptNum, error);
115
115
  }, delay);
116
116
  delay *= 2;
117
117
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@haven-fi/solauto-sdk",
3
- "version": "1.0.238",
3
+ "version": "1.0.240",
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",
@@ -17,16 +17,18 @@ import {
17
17
  import { getErrorInfo, getTransactionChores } from "./transactionUtils";
18
18
  import {
19
19
  PriorityFeeSetting,
20
+ priorityFeeSettingValues,
20
21
  TransactionItemInputs,
21
22
  TransactionRunType,
22
23
  } from "../types";
23
24
  import { ReferralStateManager, TxHandler } from "../clients";
25
+ import { TransactionExpiredBlockheightExceededError } from "@solana/web3.js";
24
26
  // import { sendJitoBundledTransactions } from "../utils/jitoUtils";
25
27
 
26
28
  export class TransactionTooLargeError extends Error {
27
29
  constructor(message: string) {
28
30
  super(message);
29
- this.name = 'TransactionTooLargeError';
31
+ this.name = "TransactionTooLargeError";
30
32
  Object.setPrototypeOf(this, TransactionTooLargeError.prototype);
31
33
  }
32
34
  }
@@ -204,10 +206,10 @@ export class TransactionsManager {
204
206
  private txHandler: SolautoClient | ReferralStateManager,
205
207
  private statusCallback?: (statuses: TransactionManagerStatuses) => void,
206
208
  private txType?: TransactionRunType,
207
- private mustBeAtomic?: boolean,
209
+ private priorityFeeSetting: PriorityFeeSetting = PriorityFeeSetting.Min,
208
210
  private errorsToThrow?: ErrorsToThrow,
209
211
  private retries: number = 4,
210
- private retryDelay: number = 150,
212
+ private retryDelay: number = 150
211
213
  ) {
212
214
  this.lookupTables = new LookupTables(
213
215
  this.txHandler.defaultLookupTables(),
@@ -321,9 +323,24 @@ export class TransactionsManager {
321
323
  }
322
324
  }
323
325
 
326
+ private getUpdatedPriorityFeeSetting(prevError?: Error) {
327
+ if (prevError instanceof TransactionExpiredBlockheightExceededError) {
328
+ const currIdx = priorityFeeSettingValues.indexOf(this.priorityFeeSetting);
329
+ return priorityFeeSettingValues[
330
+ Math.min(priorityFeeSettingValues.length - 1, currIdx + 1)
331
+ ];
332
+ }
333
+ return this.priorityFeeSetting;
334
+ }
335
+
336
+ private updateStatusForSets(itemSets: TransactionSet[]) {
337
+ itemSets.forEach((itemSet) => {
338
+ this.updateStatus(itemSet.name(), TransactionStatus.Queued, 0);
339
+ });
340
+ }
341
+
324
342
  public async clientSend(
325
- transactions: TransactionItem[],
326
- prioritySetting?: PriorityFeeSetting
343
+ transactions: TransactionItem[]
327
344
  ): Promise<TransactionManagerStatuses> {
328
345
  const items = [...transactions];
329
346
  const client = this.txHandler as SolautoClient;
@@ -336,12 +353,12 @@ export class TransactionsManager {
336
353
  updateLookupTable?.needsToBeIsolated
337
354
  ) {
338
355
  await retryWithExponentialBackoff(
339
- async (attemptNum) =>
356
+ async (attemptNum, prevError) =>
340
357
  await this.sendTransaction(
341
358
  updateLookupTable.updateLutTx,
342
359
  updateLutTxName,
343
360
  attemptNum,
344
- prioritySetting
361
+ this.getUpdatedPriorityFeeSetting(prevError)
345
362
  ),
346
363
  3,
347
364
  150,
@@ -385,7 +402,7 @@ export class TransactionsManager {
385
402
  );
386
403
  }
387
404
 
388
- const result = await this.send(items, prioritySetting, true).catch((e) => {
405
+ const result = await this.send(items, true).catch((e) => {
389
406
  client.resetLiveTxUpdates(false);
390
407
  throw e;
391
408
  });
@@ -399,7 +416,6 @@ export class TransactionsManager {
399
416
 
400
417
  public async send(
401
418
  items: TransactionItem[],
402
- prioritySetting?: PriorityFeeSetting,
403
419
  initialized?: boolean
404
420
  ): Promise<TransactionManagerStatuses> {
405
421
  this.statuses = [];
@@ -412,104 +428,99 @@ export class TransactionsManager {
412
428
  }
413
429
 
414
430
  const itemSets = await this.assembleTransactionSets(items);
415
- const statusesStartIdx = this.statuses.length;
416
- for (const itemSet of itemSets) {
417
- this.updateStatus(itemSet.name(), TransactionStatus.Queued, 0);
418
- }
431
+ this.updateStatusForSets(itemSets);
419
432
 
420
- if (this.mustBeAtomic && itemSets.length > 1) {
421
- throw new Error(
422
- `${itemSets.length} transactions required but jito bundles are not currently supported`
433
+ if (this.txType === "only-simulate" && itemSets.length > 1) {
434
+ this.txHandler.log(
435
+ "Only simulate and more than 1 transaction. Skipping..."
423
436
  );
424
- // itemSets.forEach((set) => {
425
- // this.updateStatus(set.name(), TransactionStatus.Processing);
426
- // });
427
- // await sendJitoBundledTransactions(
428
- // this.client,
429
- // await Promise.all(itemSets.map((x) => x.getSingleTransaction())),
430
- // this.simulateOnly
431
- // );
432
- // TODO: check if successful or not
433
- // itemSets.forEach((set) => {
434
- // this.updateStatus(set.name(), TransactionStatus.Successful);
435
- // });
436
- } else if (this.txType !== "only-simulate" || itemSets.length === 1) {
437
- for (let i = 0; i < itemSets.length; i++) {
438
- const getFreshItemSet = async (
439
- itemSet: TransactionSet,
440
- attemptNum: number
441
- ) => {
442
- await itemSet.refetchAll(attemptNum);
443
- const newItemSets = await this.assembleTransactionSets([
444
- ...itemSet.items,
445
- ...itemSets
446
- .slice(i + 1)
447
- .map((x) => x.items)
448
- .flat(),
449
- ]);
450
- if (newItemSets.length > 1) {
451
- this.statuses.splice(
452
- statusesStartIdx + i,
453
- itemSets.length - i,
454
- ...newItemSets.map((x) => ({
455
- name: x.name(),
456
- status: TransactionStatus.Queued,
457
- attemptNum: 0,
458
- }))
459
- );
460
- this.txHandler.log(this.statuses);
461
- itemSets.splice(
462
- i + 1,
463
- itemSets.length - i - 1,
464
- ...newItemSets.slice(1)
465
- );
466
- }
467
- return newItemSets.length > 0 ? newItemSets[0] : undefined;
468
- };
469
-
470
- let itemSet: TransactionSet | undefined = itemSets[i];
471
- await retryWithExponentialBackoff(
472
- async (attemptNum) => {
473
- itemSet =
474
- i > 0 || attemptNum > 0
475
- ? await getFreshItemSet(itemSet!, attemptNum)
476
- : itemSet;
477
- if (!itemSet) {
478
- return;
479
- }
480
- const tx = await itemSet.getSingleTransaction();
481
-
482
- if (tx.getInstructions().length === 0) {
483
- this.updateStatus(
484
- itemSet.name(),
485
- TransactionStatus.Skipped,
486
- attemptNum
487
- );
488
- } else {
489
- await this.debugAccounts(itemSet, tx);
490
- await this.sendTransaction(
491
- tx,
492
- itemSet.name(),
493
- attemptNum,
494
- prioritySetting
495
- );
496
- }
497
- },
437
+ return [];
438
+ }
439
+
440
+ let currentIndex = 0;
441
+ while (currentIndex < itemSets.length) {
442
+ await this.processTransactionSet(itemSets, currentIndex);
443
+ currentIndex++;
444
+ }
445
+
446
+ return this.statuses;
447
+ }
448
+
449
+ private async processTransactionSet(
450
+ itemSets: TransactionSet[],
451
+ currentIndex: number
452
+ ) {
453
+ let itemSet: TransactionSet | undefined = itemSets[currentIndex];
454
+
455
+ await retryWithExponentialBackoff(
456
+ async (attemptNum, prevError) => {
457
+ if (currentIndex > 0 || attemptNum > 0) {
458
+ itemSet = await this.refreshItemSet(
459
+ itemSets,
460
+ currentIndex,
461
+ attemptNum
462
+ );
463
+ }
464
+ if (!itemSet) return;
465
+
466
+ const tx = await itemSet.getSingleTransaction();
467
+ if (tx.getInstructions().length === 0) {
468
+ this.updateStatus(
469
+ itemSet.name(),
470
+ TransactionStatus.Skipped,
471
+ attemptNum
472
+ );
473
+ } else {
474
+ await this.debugAccounts(itemSet, tx);
475
+ await this.sendTransaction(
476
+ tx,
477
+ itemSet.name(),
478
+ attemptNum,
479
+ this.getUpdatedPriorityFeeSetting(prevError)
480
+ );
481
+ }
482
+ },
483
+ this.retries,
484
+ this.retryDelay,
485
+ this.errorsToThrow
486
+ ).catch((e) => {
487
+ if (itemSet) {
488
+ this.updateStatus(
489
+ itemSet.name(),
490
+ TransactionStatus.Failed,
498
491
  this.retries,
499
- this.retryDelay,
500
- this.errorsToThrow
501
492
  );
502
493
  }
503
- }
494
+ throw e;
495
+ });
496
+ }
504
497
 
505
- return this.statuses;
498
+ private async refreshItemSet(
499
+ itemSets: TransactionSet[],
500
+ currentIndex: number,
501
+ attemptNum: number
502
+ ): Promise<TransactionSet | undefined> {
503
+ const itemSet = itemSets[currentIndex];
504
+ await itemSet.refetchAll(attemptNum);
505
+
506
+ const newItemSets = await this.assembleTransactionSets([
507
+ ...itemSet.items,
508
+ ...itemSets.slice(currentIndex + 1).flatMap((set) => set.items),
509
+ ]);
510
+
511
+ if (newItemSets.length > 1) {
512
+ itemSets.splice(currentIndex + 1, itemSets.length - currentIndex - 1, ...newItemSets.slice(1));
513
+ this.updateStatusForSets(newItemSets.slice(1));
514
+ }
515
+
516
+ return newItemSets[0];
506
517
  }
507
518
 
508
519
  private async sendTransaction(
509
520
  tx: TransactionBuilder,
510
521
  txName: string,
511
522
  attemptNum: number,
512
- prioritySetting?: PriorityFeeSetting
523
+ priorityFeeSetting?: PriorityFeeSetting
513
524
  ) {
514
525
  this.updateStatus(txName, TransactionStatus.Processing, attemptNum);
515
526
  try {
@@ -518,7 +529,7 @@ export class TransactionsManager {
518
529
  this.txHandler.connection,
519
530
  tx,
520
531
  this.txType,
521
- prioritySetting,
532
+ priorityFeeSetting,
522
533
  () =>
523
534
  this.updateStatus(
524
535
  txName,
@@ -21,6 +21,8 @@ export enum PriorityFeeSetting {
21
21
  High = "High",
22
22
  }
23
23
 
24
+ export const priorityFeeSettingValues = Object.values(PriorityFeeSetting) as PriorityFeeSetting[];
25
+
24
26
  export type RebalanceAction = "boost" | "repay" | "dca";
25
27
 
26
28
  export type TransactionRunType = "skip-simulation" | "only-simulate" | "normal";
@@ -125,14 +125,14 @@ export function safeGetPrice(
125
125
  export type ErrorsToThrow = Array<new (...args: any[]) => Error>;
126
126
 
127
127
  export function retryWithExponentialBackoff<T>(
128
- fn: (attemptNum: number) => Promise<T>,
128
+ fn: (attemptNum: number, prevErr?: Error) => Promise<T>,
129
129
  retries: number = 5,
130
130
  delay: number = 150,
131
131
  errorsToThrow?: ErrorsToThrow
132
132
  ): Promise<T> {
133
133
  return new Promise((resolve, reject) => {
134
- const attempt = (attemptNum: number) => {
135
- fn(attemptNum)
134
+ const attempt = (attemptNum: number, prevErr?: Error) => {
135
+ fn(attemptNum, prevErr)
136
136
  .then(resolve)
137
137
  .catch((error: Error) => {
138
138
  attemptNum++;
@@ -149,7 +149,7 @@ export function retryWithExponentialBackoff<T>(
149
149
  consoleLog(error);
150
150
  setTimeout(() => {
151
151
  consoleLog("Retrying...");
152
- return attempt(attemptNum);
152
+ return attempt(attemptNum, error);
153
153
  }, delay);
154
154
  delay *= 2;
155
155
  } else {
@@ -14,9 +14,10 @@ import {
14
14
  toBaseUnit,
15
15
  } from "../../src/utils/numberUtils";
16
16
  import { NATIVE_MINT } from "@solana/spl-token";
17
- import { fetchTokenPrices } from "../../src/utils/generalUtils";
17
+ import { consoleLog, fetchTokenPrices } from "../../src/utils/generalUtils";
18
18
  import {
19
19
  TransactionItem,
20
+ TransactionManagerStatuses,
20
21
  TransactionsManager,
21
22
  } from "../../src/transactions/transactionsManager";
22
23
  import { PublicKey } from "@solana/web3.js";
@@ -29,8 +30,7 @@ describe("Solauto Marginfi tests", async () => {
29
30
  // const signer = setupTest("solauto-manager");
30
31
 
31
32
  const payForTransactions = false;
32
- const useJitoBundle = false;
33
- const positionId = 1;
33
+ const positionId = 2;
34
34
 
35
35
  it("open - deposit - borrow - rebalance to 0 - withdraw - close", async () => {
36
36
  const client = new SolautoMarginfiClient(
@@ -49,8 +49,8 @@ describe("Solauto Marginfi tests", async () => {
49
49
  // marginfiAccount: new PublicKey(
50
50
  // "4nNvUXF5YqHFcH2nGweSiuvy1ct7V5FXfoCLKFYUN36z"
51
51
  // ),
52
- // supplyMint: NATIVE_MINT,
53
- // debtMint: new PublicKey(USDC),
52
+ supplyMint: NATIVE_MINT,
53
+ debtMint: new PublicKey(USDC),
54
54
  });
55
55
 
56
56
  const transactionItems: TransactionItem[] = [];
@@ -78,7 +78,7 @@ describe("Solauto Marginfi tests", async () => {
78
78
  // // const [supplyPrice] = await fetchTokenPrices([supply]);
79
79
  // return {
80
80
  // tx: client.protocolInteraction(
81
- // solautoAction("Deposit", [toBaseUnit(9, supplyDecimals)])
81
+ // solautoAction("Deposit", [toBaseUnit(0.5, supplyDecimals)])
82
82
  // ),
83
83
  // };
84
84
  // }, "deposit")
@@ -117,6 +117,14 @@ describe("Solauto Marginfi tests", async () => {
117
117
  )
118
118
  );
119
119
 
120
+ // transactionItems.push(
121
+ // new TransactionItem(
122
+ // async (attemptNum) =>
123
+ // await buildSolautoRebalanceTransaction(client, 0, attemptNum),
124
+ // "rebalance"
125
+ // )
126
+ // );
127
+
120
128
  // transactionItems.push(
121
129
  // new TransactionItem(
122
130
  // async () => ({
@@ -137,11 +145,15 @@ describe("Solauto Marginfi tests", async () => {
137
145
  // )
138
146
  // );
139
147
 
140
- await new TransactionsManager(
148
+ const statuses = await new TransactionsManager(
141
149
  client,
142
- undefined,
150
+ (statuses: TransactionManagerStatuses) => {
151
+ console.log(statuses);
152
+ },
143
153
  !payForTransactions ? "only-simulate" : "normal",
144
- useJitoBundle
145
- ).clientSend(transactionItems, PriorityFeeSetting.Min);
154
+ PriorityFeeSetting.Low
155
+ ).clientSend(transactionItems);
156
+
157
+ // console.log(statuses);
146
158
  });
147
159
  });