@haven-fi/solauto-sdk 1.0.685 → 1.0.687

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.
Files changed (54) hide show
  1. package/README.md +8 -6
  2. package/dist/constants/solautoConstants.d.ts +1 -0
  3. package/dist/constants/solautoConstants.d.ts.map +1 -1
  4. package/dist/constants/solautoConstants.js +2 -1
  5. package/dist/services/transactions/index.d.ts +3 -2
  6. package/dist/services/transactions/index.d.ts.map +1 -1
  7. package/dist/services/transactions/index.js +2 -1
  8. package/dist/services/transactions/manager/clientTransactionsManager.d.ts +10 -0
  9. package/dist/services/transactions/manager/clientTransactionsManager.d.ts.map +1 -0
  10. package/dist/services/transactions/manager/clientTransactionsManager.js +75 -0
  11. package/dist/services/transactions/manager/index.d.ts +3 -0
  12. package/dist/services/transactions/manager/index.d.ts.map +1 -0
  13. package/dist/services/transactions/manager/index.js +18 -0
  14. package/dist/services/transactions/manager/transactionsManager.d.ts +64 -0
  15. package/dist/services/transactions/manager/transactionsManager.d.ts.map +1 -0
  16. package/dist/services/transactions/{transactionsManager.js → manager/transactionsManager.js} +21 -211
  17. package/dist/services/transactions/types/index.d.ts +4 -0
  18. package/dist/services/transactions/types/index.d.ts.map +1 -0
  19. package/dist/services/transactions/types/index.js +19 -0
  20. package/dist/services/transactions/types/lookupTables.d.ts +10 -0
  21. package/dist/services/transactions/types/lookupTables.d.ts.map +1 -0
  22. package/dist/services/transactions/types/lookupTables.js +25 -0
  23. package/dist/services/transactions/types/transactionItem.d.ts +16 -0
  24. package/dist/services/transactions/types/transactionItem.d.ts.map +1 -0
  25. package/dist/services/transactions/types/transactionItem.js +31 -0
  26. package/dist/services/transactions/types/transactionSet.d.ts +20 -0
  27. package/dist/services/transactions/types/transactionSet.d.ts.map +1 -0
  28. package/dist/services/transactions/types/transactionSet.js +79 -0
  29. package/dist/solautoPosition/positionUtils.js +1 -1
  30. package/dist/solautoPosition/solautoPositionEx.d.ts.map +1 -1
  31. package/dist/solautoPosition/solautoPositionEx.js +2 -1
  32. package/dist/utils/instructionUtils.d.ts.map +1 -1
  33. package/dist/utils/instructionUtils.js +3 -3
  34. package/dist/utils/switchboardUtils.d.ts +1 -0
  35. package/dist/utils/switchboardUtils.d.ts.map +1 -1
  36. package/dist/utils/switchboardUtils.js +10 -0
  37. package/local/txSandbox.ts +17 -23
  38. package/package.json +3 -1
  39. package/src/constants/solautoConstants.ts +2 -0
  40. package/src/services/transactions/index.ts +3 -2
  41. package/src/services/transactions/manager/clientTransactionsManager.ts +141 -0
  42. package/src/services/transactions/manager/index.ts +2 -0
  43. package/src/services/transactions/{transactionsManager.ts → manager/transactionsManager.ts} +46 -354
  44. package/src/services/transactions/types/index.ts +3 -0
  45. package/src/services/transactions/types/lookupTables.ts +37 -0
  46. package/src/services/transactions/types/transactionItem.ts +43 -0
  47. package/src/services/transactions/types/transactionSet.ts +114 -0
  48. package/src/solautoPosition/positionUtils.ts +1 -1
  49. package/src/solautoPosition/solautoPositionEx.ts +11 -12
  50. package/src/utils/instructionUtils.ts +6 -3
  51. package/src/utils/switchboardUtils.ts +17 -2
  52. package/tests/transactions/shared.ts +6 -3
  53. package/dist/services/transactions/transactionsManager.d.ts +0 -68
  54. package/dist/services/transactions/transactionsManager.d.ts.map +0 -1
@@ -1,41 +1,21 @@
1
1
  import bs58 from "bs58";
2
- import {
3
- PublicKey,
4
- TransactionExpiredBlockheightExceededError,
5
- } from "@solana/web3.js";
6
- import {
7
- AddressLookupTableInput,
8
- transactionBuilder,
9
- TransactionBuilder,
10
- Umi,
11
- } from "@metaplex-foundation/umi";
2
+ import { TransactionExpiredBlockheightExceededError } from "@solana/web3.js";
3
+ import { TransactionBuilder } from "@metaplex-foundation/umi";
12
4
  import {
13
5
  PriorityFeeSetting,
14
6
  priorityFeeSettingValues,
15
- TransactionItemInputs,
16
7
  TransactionRunType,
17
- } from "../../types";
18
- import {
19
- SOLAUTO_PROD_PROGRAM,
20
- SOLAUTO_TEST_PROGRAM,
21
- SWITCHBOARD_PRICE_FEED_IDS,
22
- } from "../../constants";
8
+ } from "../../../types";
23
9
  import {
24
10
  consoleLog,
25
11
  ErrorsToThrow,
26
12
  retryWithExponentialBackoff,
27
- addTxOptimizations,
28
- getAddressLookupInputs,
29
13
  sendSingleOptimizedTransaction,
30
- buildSwbSubmitResponseTx,
31
- getSwitchboardFeedData,
32
14
  sendJitoBundledTransactions,
33
- } from "../../utils";
34
- import { SolautoClient, ReferralStateManager, TxHandler } from "../solauto";
35
- import { getErrorInfo, getTransactionChores } from "./transactionUtils";
36
-
37
- const CHORES_TX_NAME = "account chores";
38
- const MAX_SUPPORTED_ACCOUNT_LOCKS = 64;
15
+ } from "../../../utils";
16
+ import { TxHandler } from "../../solauto";
17
+ import { getErrorInfo } from "../transactionUtils";
18
+ import { LookupTables, TransactionItem, TransactionSet } from "../types";
39
19
 
40
20
  export class TransactionTooLargeError extends Error {
41
21
  constructor(message: string) {
@@ -45,183 +25,6 @@ export class TransactionTooLargeError extends Error {
45
25
  }
46
26
  }
47
27
 
48
- class LookupTables {
49
- cache: AddressLookupTableInput[] = [];
50
-
51
- constructor(
52
- public defaultLuts: string[],
53
- private umi: Umi
54
- ) {}
55
-
56
- async getLutInputs(
57
- additionalAddresses?: string[]
58
- ): Promise<AddressLookupTableInput[]> {
59
- const addresses = [...this.defaultLuts, ...(additionalAddresses ?? [])];
60
- const currentCacheAddresses = this.cache.map((x) => x.publicKey.toString());
61
-
62
- const missingAddresses = addresses.filter(
63
- (x) => !currentCacheAddresses.includes(x)
64
- );
65
- if (missingAddresses) {
66
- const additionalInputs = await getAddressLookupInputs(
67
- this.umi,
68
- missingAddresses
69
- );
70
- this.cache.push(...additionalInputs);
71
- }
72
-
73
- return this.cache;
74
- }
75
-
76
- reset() {
77
- this.cache = this.cache.filter((x) =>
78
- this.defaultLuts.includes(x.publicKey.toString())
79
- );
80
- }
81
- }
82
-
83
- export class TransactionItem {
84
- lookupTableAddresses!: string[];
85
- tx?: TransactionBuilder;
86
- initialized: boolean = false;
87
- orderPrio: number = 0;
88
-
89
- constructor(
90
- public fetchTx: (
91
- attemptNum: number,
92
- prevError?: Error
93
- ) => Promise<TransactionItemInputs | undefined>,
94
- public name?: string
95
- ) {}
96
-
97
- async initialize() {
98
- await this.refetch(0);
99
- this.initialized = true;
100
- }
101
-
102
- async refetch(attemptNum: number, prevError?: Error) {
103
- const resp = await this.fetchTx(attemptNum, prevError);
104
- this.tx = resp?.tx;
105
- this.lookupTableAddresses = resp?.lookupTableAddresses ?? [];
106
- this.orderPrio = resp?.orderPrio ?? 0;
107
- }
108
-
109
- uniqueAccounts(): string[] {
110
- return Array.from(
111
- new Set(
112
- this.tx!.getInstructions()
113
- .map((x) => [
114
- x.programId.toString(),
115
- ...x.keys.map((y) => y.pubkey.toString()),
116
- ])
117
- .flat()
118
- )
119
- );
120
- }
121
- }
122
-
123
- class TransactionSet {
124
- constructor(
125
- private txHandler: TxHandler,
126
- public lookupTables: LookupTables,
127
- public items: TransactionItem[] = []
128
- ) {}
129
-
130
- async lutInputs(): Promise<AddressLookupTableInput[]> {
131
- const lutInputs = await this.lookupTables.getLutInputs(this.lutAddresses());
132
-
133
- return lutInputs.filter(
134
- (lut, index, self) =>
135
- index ===
136
- self.findIndex(
137
- (item) => item.publicKey.toString() === lut.publicKey.toString()
138
- )
139
- );
140
- }
141
-
142
- async fitsWith(item: TransactionItem): Promise<boolean> {
143
- if (!item.tx) {
144
- return true;
145
- }
146
-
147
- const accountLocks = Array.from(
148
- new Set([
149
- ...this.items.map((x) => x.uniqueAccounts()),
150
- ...item.uniqueAccounts(),
151
- ])
152
- ).length;
153
- if (accountLocks > MAX_SUPPORTED_ACCOUNT_LOCKS) {
154
- return false;
155
- }
156
-
157
- const singleTx = await this.getSingleTransaction();
158
- const tx = addTxOptimizations(this.txHandler.umi, singleTx, 1, 1)
159
- .add(item.tx)
160
- .setAddressLookupTables(
161
- await this.lookupTables.getLutInputs([
162
- ...this.lutAddresses(),
163
- ...item.lookupTableAddresses,
164
- ])
165
- );
166
-
167
- return tx.fitsInOneTransaction(this.txHandler.umi);
168
- }
169
-
170
- add(...items: TransactionItem[]) {
171
- this.items.push(
172
- ...items.filter((x) => x.tx && x.tx.getInstructions().length > 0)
173
- );
174
- }
175
-
176
- prepend(...items: TransactionItem[]) {
177
- this.items.unshift(
178
- ...items.filter((x) => x.tx && x.tx.getInstructions().length > 0)
179
- );
180
- }
181
-
182
- async reset() {
183
- await this.txHandler.resetLiveTxUpdates();
184
- }
185
-
186
- async refetchAll(attemptNum: number, prevError?: Error) {
187
- for (const item of this.items) {
188
- await item.refetch(attemptNum, prevError);
189
- }
190
- }
191
-
192
- async getSingleTransaction(): Promise<TransactionBuilder> {
193
- const transactions = this.items
194
- .filter((x) => x.tx && x.tx.getInstructions().length > 0)
195
- .map((x) => x.tx!);
196
-
197
- return transactionBuilder()
198
- .add(transactions)
199
- .setAddressLookupTables(await this.lutInputs());
200
- }
201
-
202
- lutAddresses(): string[] {
203
- return Array.from(
204
- new Set(this.items.map((x) => x.lookupTableAddresses).flat())
205
- );
206
- }
207
-
208
- name(): string {
209
- let names = this.items
210
- .filter((x) => x.tx && Boolean(x.name))
211
- .map((x) => x.name!.toLowerCase());
212
- if (names.length > 1) {
213
- names = names.filter((x) => x !== CHORES_TX_NAME);
214
- }
215
- if (names.length >= 3) {
216
- return [names.slice(0, -1).join(", "), names[names.length - 1]].join(
217
- ", and "
218
- );
219
- } else {
220
- return names.join(" & ");
221
- }
222
- }
223
- }
224
-
225
28
  export enum TransactionStatus {
226
29
  Skipped = "Skipped",
227
30
  Processing = "Processing",
@@ -245,33 +48,48 @@ interface RetryConfig {
245
48
  retryDelay?: number;
246
49
  }
247
50
 
248
- export class TransactionsManager {
249
- private statuses: TransactionManagerStatuses = [];
250
- private lookupTables: LookupTables;
251
- private signableRetries: number;
252
- private totalRetries: number;
253
- private retryDelay: number;
51
+ export interface TransactionManagerArgs<T extends TxHandler> {
52
+ txHandler: T;
53
+ statusCallback?: (statuses: TransactionManagerStatuses) => void;
54
+ txRunType?: TransactionRunType;
55
+ priorityFeeSetting?: PriorityFeeSetting;
56
+ atomically?: boolean;
57
+ errorsToThrow?: ErrorsToThrow;
58
+ retryConfig?: RetryConfig;
59
+ }
60
+
61
+ export class TransactionsManager<T extends TxHandler> {
62
+ protected txHandler: T;
63
+ protected statusCallback?: (statuses: TransactionManagerStatuses) => void;
64
+ protected txRunType?: TransactionRunType;
65
+ protected priorityFeeSetting: PriorityFeeSetting;
66
+ protected atomically: boolean;
67
+ protected errorsToThrow?: ErrorsToThrow;
68
+ protected statuses: TransactionManagerStatuses = [];
69
+ protected lookupTables: LookupTables;
70
+ protected signableRetries: number;
71
+ protected totalRetries: number;
72
+ protected retryDelay: number;
254
73
 
255
74
  updateOracleTxName = "update oracle";
256
75
 
257
- constructor(
258
- private txHandler: SolautoClient | ReferralStateManager,
259
- private statusCallback?: (statuses: TransactionManagerStatuses) => void,
260
- private txType?: TransactionRunType,
261
- private priorityFeeSetting: PriorityFeeSetting = PriorityFeeSetting.Min,
262
- private atomically: boolean = true,
263
- private errorsToThrow?: ErrorsToThrow,
264
- retryConfig?: RetryConfig
265
- ) {
76
+ constructor(args: TransactionManagerArgs<T>) {
77
+ this.txHandler = args.txHandler;
78
+ this.statusCallback = args.statusCallback;
79
+ this.txRunType = args.txRunType;
80
+ this.priorityFeeSetting = args.priorityFeeSetting ?? PriorityFeeSetting.Min;
81
+ this.atomically = args.atomically ?? true;
82
+ this.errorsToThrow = args.errorsToThrow;
83
+
266
84
  this.lookupTables = new LookupTables(
267
85
  this.txHandler.defaultLookupTables(),
268
86
  this.txHandler.umi
269
87
  );
270
88
  this.signableRetries =
271
- retryConfig?.signableRetries ?? retryConfig?.totalRetries ?? 4;
89
+ args.retryConfig?.signableRetries ?? args.retryConfig?.totalRetries ?? 4;
272
90
  this.totalRetries =
273
- retryConfig?.totalRetries ?? retryConfig?.signableRetries ?? 4;
274
- this.retryDelay = retryConfig?.retryDelay ?? 150;
91
+ args.retryConfig?.totalRetries ?? args.retryConfig?.signableRetries ?? 4;
92
+ this.retryDelay = args.retryConfig?.retryDelay ?? 150;
275
93
  }
276
94
 
277
95
  private async assembleTransactionSets(
@@ -381,7 +199,7 @@ export class TransactionsManager {
381
199
  }
382
200
  }
383
201
 
384
- private getUpdatedPriorityFeeSetting(
202
+ protected getUpdatedPriorityFeeSetting(
385
203
  prevError: Error | undefined,
386
204
  attemptNum: number
387
205
  ) {
@@ -417,132 +235,6 @@ export class TransactionsManager {
417
235
  });
418
236
  }
419
237
 
420
- private async updateLut(tx: TransactionBuilder, newLut: boolean) {
421
- const lutInputs = await this.lookupTables.getLutInputs();
422
- const updateLutTxName = `${newLut ? "create" : "update"} lookup table`;
423
- await retryWithExponentialBackoff(
424
- async (attemptNum, prevError) =>
425
- await this.sendTransaction(
426
- tx.setAddressLookupTables(lutInputs),
427
- updateLutTxName,
428
- attemptNum,
429
- this.getUpdatedPriorityFeeSetting(prevError, attemptNum),
430
- "skip-simulation"
431
- ),
432
- this.signableRetries,
433
- 150,
434
- this.errorsToThrow
435
- );
436
- await this.txHandler.refetchReferralState();
437
- }
438
-
439
- public async clientSend(
440
- transactions: TransactionItem[]
441
- ): Promise<TransactionManagerStatuses> {
442
- const items = [...transactions];
443
- const client = this.txHandler as SolautoClient;
444
-
445
- const updateLut = await client.updateLookupTable();
446
-
447
- if (updateLut && (updateLut?.new || updateLut.accountsToAdd.length > 4)) {
448
- await this.updateLut(updateLut.tx, updateLut.new);
449
- }
450
- this.lookupTables.defaultLuts = client.defaultLookupTables();
451
-
452
- for (const item of items) {
453
- await item.initialize();
454
- }
455
-
456
- const allAccounts = items.flatMap((item) => {
457
- return (
458
- item.tx
459
- ?.getInstructions()
460
- .filter((ix) => {
461
- return (
462
- ix.programId.toString() === SOLAUTO_PROD_PROGRAM.toString() ||
463
- ix.programId.toString() === SOLAUTO_TEST_PROGRAM.toString()
464
- );
465
- })
466
- .flatMap((ix) => {
467
- return ix.keys.map((key) => key.pubkey.toString());
468
- }) ?? []
469
- );
470
- });
471
-
472
- const swbOracle = allAccounts.find((x) =>
473
- Object.values(SWITCHBOARD_PRICE_FEED_IDS)
474
- .map((x) => x.feedId)
475
- .includes(x ?? "")
476
- );
477
- if (swbOracle) {
478
- const mint = new PublicKey(
479
- Object.keys(SWITCHBOARD_PRICE_FEED_IDS).find(
480
- (x) => SWITCHBOARD_PRICE_FEED_IDS[x].feedId === swbOracle
481
- )!
482
- );
483
- const stale = (await getSwitchboardFeedData(client.connection, [mint]))[0]
484
- .stale;
485
-
486
- if (stale) {
487
- this.txHandler.log("Requires oracle update...");
488
- const swbTx = new TransactionItem(
489
- async () =>
490
- buildSwbSubmitResponseTx(client.connection, client.signer, mint),
491
- this.updateOracleTxName
492
- );
493
- await swbTx.initialize();
494
- items.unshift(swbTx);
495
- }
496
- }
497
-
498
- let [choresBefore, choresAfter] = await getTransactionChores(
499
- client,
500
- transactionBuilder().add(
501
- items
502
- .filter((x) => x.tx && x.tx.getInstructions().length > 0)
503
- .map((x) => x.tx!)
504
- )
505
- );
506
- if (updateLut && !updateLut?.new) {
507
- choresBefore = choresBefore.prepend(updateLut.tx);
508
- }
509
- if (choresBefore.getInstructions().length > 0) {
510
- const chore = new TransactionItem(
511
- async () => ({ tx: choresBefore }),
512
- CHORES_TX_NAME
513
- );
514
- await chore.initialize();
515
- items.unshift(chore);
516
- this.txHandler.log(
517
- "Chores before: ",
518
- choresBefore.getInstructions().length
519
- );
520
- }
521
- if (choresAfter.getInstructions().length > 0) {
522
- const chore = new TransactionItem(
523
- async () => ({ tx: choresAfter }),
524
- CHORES_TX_NAME
525
- );
526
- await chore.initialize();
527
- items.push(chore);
528
- this.txHandler.log(
529
- "Chores after: ",
530
- choresAfter.getInstructions().length
531
- );
532
- }
533
-
534
- const result = await this.send(items).catch((e) => {
535
- client.resetLiveTxUpdates(false);
536
- throw e;
537
- });
538
-
539
- if (this.txType !== "only-simulate") {
540
- await client.resetLiveTxUpdates();
541
- }
542
-
543
- return result;
544
- }
545
-
546
238
  public async send(
547
239
  items: TransactionItem[]
548
240
  ): Promise<TransactionManagerStatuses> {
@@ -641,7 +333,7 @@ export class TransactionsManager {
641
333
  this.txHandler.signer,
642
334
  this.txHandler.otherSigners,
643
335
  transactions,
644
- this.txType,
336
+ this.txRunType,
645
337
  this.getUpdatedPriorityFeeSetting(prevError, attemptNum),
646
338
  () =>
647
339
  this.updateStatusForSets(
@@ -658,7 +350,7 @@ export class TransactionsManager {
658
350
 
659
351
  if (
660
352
  error ||
661
- (this.txType !== "only-simulate" &&
353
+ (this.txRunType !== "only-simulate" &&
662
354
  (!Boolean(txSigs) || txSigs?.length === 0))
663
355
  ) {
664
356
  this.updateStatusForSets(
@@ -825,12 +517,12 @@ export class TransactionsManager {
825
517
  return newItemSets;
826
518
  }
827
519
 
828
- private async sendTransaction(
520
+ protected async sendTransaction(
829
521
  tx: TransactionBuilder,
830
522
  txName: string,
831
523
  attemptNum: number,
832
524
  priorityFeeSetting?: PriorityFeeSetting,
833
- txType?: TransactionRunType
525
+ txRunType?: TransactionRunType
834
526
  ) {
835
527
  this.updateStatus(txName, TransactionStatus.Processing, attemptNum);
836
528
  try {
@@ -838,7 +530,7 @@ export class TransactionsManager {
838
530
  this.txHandler.umi,
839
531
  this.txHandler.connection,
840
532
  tx,
841
- txType ?? this.txType,
533
+ txRunType ?? this.txRunType,
842
534
  priorityFeeSetting,
843
535
  () =>
844
536
  this.updateStatus(
@@ -0,0 +1,3 @@
1
+ export * from "./lookupTables";
2
+ export * from "./transactionItem";
3
+ export * from "./transactionSet";
@@ -0,0 +1,37 @@
1
+ import { AddressLookupTableInput, Umi } from "@metaplex-foundation/umi";
2
+ import { getAddressLookupInputs } from "../../../utils";
3
+
4
+ export class LookupTables {
5
+ cache: AddressLookupTableInput[] = [];
6
+
7
+ constructor(
8
+ public defaultLuts: string[],
9
+ private umi: Umi
10
+ ) {}
11
+
12
+ async getLutInputs(
13
+ additionalAddresses?: string[]
14
+ ): Promise<AddressLookupTableInput[]> {
15
+ const addresses = [...this.defaultLuts, ...(additionalAddresses ?? [])];
16
+ const currentCacheAddresses = this.cache.map((x) => x.publicKey.toString());
17
+
18
+ const missingAddresses = addresses.filter(
19
+ (x) => !currentCacheAddresses.includes(x)
20
+ );
21
+ if (missingAddresses) {
22
+ const additionalInputs = await getAddressLookupInputs(
23
+ this.umi,
24
+ missingAddresses
25
+ );
26
+ this.cache.push(...additionalInputs);
27
+ }
28
+
29
+ return this.cache;
30
+ }
31
+
32
+ reset() {
33
+ this.cache = this.cache.filter((x) =>
34
+ this.defaultLuts.includes(x.publicKey.toString())
35
+ );
36
+ }
37
+ }
@@ -0,0 +1,43 @@
1
+ import { TransactionBuilder } from "@metaplex-foundation/umi";
2
+ import { TransactionItemInputs } from "../../../types";
3
+
4
+ export class TransactionItem {
5
+ lookupTableAddresses!: string[];
6
+ tx?: TransactionBuilder;
7
+ initialized: boolean = false;
8
+ orderPrio: number = 0;
9
+
10
+ constructor(
11
+ public fetchTx: (
12
+ attemptNum: number,
13
+ prevError?: Error
14
+ ) => Promise<TransactionItemInputs | undefined>,
15
+ public name?: string,
16
+ public oracleInteractor?: boolean
17
+ ) {}
18
+
19
+ async initialize() {
20
+ await this.refetch(0);
21
+ this.initialized = true;
22
+ }
23
+
24
+ async refetch(attemptNum: number, prevError?: Error) {
25
+ const resp = await this.fetchTx(attemptNum, prevError);
26
+ this.tx = resp?.tx;
27
+ this.lookupTableAddresses = resp?.lookupTableAddresses ?? [];
28
+ this.orderPrio = resp?.orderPrio ?? 0;
29
+ }
30
+
31
+ uniqueAccounts(): string[] {
32
+ return Array.from(
33
+ new Set(
34
+ this.tx!.getInstructions()
35
+ .map((x) => [
36
+ x.programId.toString(),
37
+ ...x.keys.map((y) => y.pubkey.toString()),
38
+ ])
39
+ .flat()
40
+ )
41
+ );
42
+ }
43
+ }
@@ -0,0 +1,114 @@
1
+ import {
2
+ AddressLookupTableInput,
3
+ transactionBuilder,
4
+ TransactionBuilder,
5
+ } from "@metaplex-foundation/umi";
6
+ import { TxHandler } from "../../solauto";
7
+ import { LookupTables } from "./lookupTables";
8
+ import { TransactionItem } from "./transactionItem";
9
+ import { addTxOptimizations } from "../../../utils";
10
+ import { CHORES_TX_NAME } from "../../../constants";
11
+
12
+ const MAX_SUPPORTED_ACCOUNT_LOCKS = 64;
13
+
14
+ export class TransactionSet {
15
+ constructor(
16
+ private txHandler: TxHandler,
17
+ public lookupTables: LookupTables,
18
+ public items: TransactionItem[] = []
19
+ ) {}
20
+
21
+ async lutInputs(): Promise<AddressLookupTableInput[]> {
22
+ const lutInputs = await this.lookupTables.getLutInputs(this.lutAddresses());
23
+
24
+ return lutInputs.filter(
25
+ (lut, index, self) =>
26
+ index ===
27
+ self.findIndex(
28
+ (item) => item.publicKey.toString() === lut.publicKey.toString()
29
+ )
30
+ );
31
+ }
32
+
33
+ async fitsWith(item: TransactionItem): Promise<boolean> {
34
+ if (!item.tx) {
35
+ return true;
36
+ }
37
+
38
+ const accountLocks = Array.from(
39
+ new Set([
40
+ ...this.items.map((x) => x.uniqueAccounts()),
41
+ ...item.uniqueAccounts(),
42
+ ])
43
+ ).length;
44
+ if (accountLocks > MAX_SUPPORTED_ACCOUNT_LOCKS) {
45
+ return false;
46
+ }
47
+
48
+ const singleTx = await this.getSingleTransaction();
49
+ const tx = addTxOptimizations(this.txHandler.umi, singleTx, 1, 1)
50
+ .add(item.tx)
51
+ .setAddressLookupTables(
52
+ await this.lookupTables.getLutInputs([
53
+ ...this.lutAddresses(),
54
+ ...item.lookupTableAddresses,
55
+ ])
56
+ );
57
+
58
+ return tx.fitsInOneTransaction(this.txHandler.umi);
59
+ }
60
+
61
+ add(...items: TransactionItem[]) {
62
+ this.items.push(
63
+ ...items.filter((x) => x.tx && x.tx.getInstructions().length > 0)
64
+ );
65
+ }
66
+
67
+ prepend(...items: TransactionItem[]) {
68
+ this.items.unshift(
69
+ ...items.filter((x) => x.tx && x.tx.getInstructions().length > 0)
70
+ );
71
+ }
72
+
73
+ async reset() {
74
+ await this.txHandler.resetLiveTxUpdates();
75
+ }
76
+
77
+ async refetchAll(attemptNum: number, prevError?: Error) {
78
+ for (const item of this.items) {
79
+ await item.refetch(attemptNum, prevError);
80
+ }
81
+ }
82
+
83
+ async getSingleTransaction(): Promise<TransactionBuilder> {
84
+ const transactions = this.items
85
+ .filter((x) => x.tx && x.tx.getInstructions().length > 0)
86
+ .map((x) => x.tx!);
87
+
88
+ return transactionBuilder()
89
+ .add(transactions)
90
+ .setAddressLookupTables(await this.lutInputs());
91
+ }
92
+
93
+ lutAddresses(): string[] {
94
+ return Array.from(
95
+ new Set(this.items.map((x) => x.lookupTableAddresses).flat())
96
+ );
97
+ }
98
+
99
+ name(): string {
100
+ let names = this.items
101
+ .filter((x) => x.tx && Boolean(x.name))
102
+ .map((x) => x.name!.toLowerCase());
103
+ if (names.length > 1) {
104
+ names = names.filter((x) => x !== CHORES_TX_NAME);
105
+ }
106
+ if (names.length >= 3) {
107
+ return [names.slice(0, -1).join(", "), names[names.length - 1]].join(
108
+ ", and "
109
+ );
110
+ } else {
111
+ return names.join(" & ");
112
+ }
113
+ }
114
+ }
@@ -198,7 +198,7 @@ export function createFakePositionState(
198
198
  },
199
199
  maxLtvBps,
200
200
  liqThresholdBps,
201
- lastRefreshed: BigInt(currentUnixSeconds() - 100),
201
+ lastRefreshed: BigInt(currentUnixSeconds()),
202
202
  padding1: [],
203
203
  padding2: [],
204
204
  padding: [],