@haven-fi/solauto-sdk 1.0.744 → 1.0.746
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/dist/services/transactions/manager/transactionsManager.d.ts +3 -3
- package/dist/services/transactions/manager/transactionsManager.d.ts.map +1 -1
- package/dist/services/transactions/manager/transactionsManager.js +102 -132
- package/local/txSandbox.ts +1 -1
- package/package.json +1 -1
- package/src/services/transactions/manager/transactionsManager.ts +179 -215
- package/tests/unit/accounts.ts +3 -2
package/README.md
CHANGED
@@ -6,6 +6,7 @@ Solauto is a program on the Solana blockchain that lets you manage leveraged lon
|
|
6
6
|
|
7
7
|
```typescript
|
8
8
|
import { PublicKey } from "@solana/web3.js";
|
9
|
+
import { NATIVE_MINT } from "@solana/spl-token";
|
9
10
|
import * as solauto from "@haven-fi/solauto-sdk";
|
10
11
|
|
11
12
|
// Create new Solauto client
|
@@ -15,8 +16,8 @@ const client = solauto.getClient(solauto.LendingPlatform.MARGINFI, {
|
|
15
16
|
});
|
16
17
|
|
17
18
|
// Initialize the client
|
18
|
-
const supplyMint =
|
19
|
-
const debtMint = new PublicKey(USDC);
|
19
|
+
const supplyMint = NATIVE_MINT;
|
20
|
+
const debtMint = new PublicKey(solauto.USDC);
|
20
21
|
await client.initializeNewSolautoPosition({
|
21
22
|
positionId: 1,
|
22
23
|
lpPoolAccount: solauto.getMarginfiAccounts().defaultGroup,
|
@@ -75,7 +76,6 @@ const statuses = txManager.send(transactionItems);
|
|
75
76
|
## Rebalancing an existing position
|
76
77
|
|
77
78
|
```typescript
|
78
|
-
import { PublicKey } from "@solana/web3.js";
|
79
79
|
import * as solauto from "@haven-fi/solauto-sdk";
|
80
80
|
|
81
81
|
// Create new Solauto client
|
@@ -59,12 +59,12 @@ export declare class TransactionsManager<T extends TxHandler> {
|
|
59
59
|
private updateStatusForSets;
|
60
60
|
send(items: TransactionItem[]): Promise<TransactionManagerStatuses>;
|
61
61
|
private shouldProceedToSend;
|
62
|
-
private
|
63
|
-
private sendJitoBundle;
|
62
|
+
private refreshItemSets;
|
64
63
|
private processTransactionsAtomically;
|
64
|
+
private sendJitoBundle;
|
65
65
|
private processTransactionSet;
|
66
|
-
private refreshItemSets;
|
67
66
|
protected sendTransaction(tx: TransactionBuilder, name: string, attemptNum: number, priorityFeeSetting?: PriorityFeeSetting, txRunType?: TransactionRunType): Promise<void>;
|
67
|
+
private captureErrorInfo;
|
68
68
|
}
|
69
69
|
export {};
|
70
70
|
//# sourceMappingURL=transactionsManager.d.ts.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"transactionsManager.d.ts","sourceRoot":"","sources":["../../../../src/services/transactions/manager/transactionsManager.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EACL,kBAAkB,EAElB,kBAAkB,EACnB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAEL,aAAa,EAId,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE1C,OAAO,EAAE,YAAY,EAAE,eAAe,EAAkB,MAAM,UAAU,CAAC;AAEzE,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;IAE5C,kBAAkB,SAAmB;gBAEzB,IAAI,EAAE,uBAAuB,CAAC,CAAC,CAAC;YAoB9B,uBAAuB;IA0CrC,OAAO,CAAC,YAAY;YA+BN,aAAa;IAoB3B,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;
|
1
|
+
{"version":3,"file":"transactionsManager.d.ts","sourceRoot":"","sources":["../../../../src/services/transactions/manager/transactionsManager.ts"],"names":[],"mappings":"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"}
|
@@ -46,7 +46,7 @@ class TransactionsManager {
|
|
46
46
|
}
|
47
47
|
async assembleTransactionSets(items) {
|
48
48
|
let transactionSets = [];
|
49
|
-
|
49
|
+
(0, utils_1.consoleLog)(`Reassembling ${items.length} items`);
|
50
50
|
const txItems = items.sort((a, b) => a.orderPrio - b.orderPrio);
|
51
51
|
for (let i = txItems.length - 1; i >= 0;) {
|
52
52
|
let item = txItems[i];
|
@@ -101,7 +101,7 @@ class TransactionsManager {
|
|
101
101
|
this.statuses.push(args);
|
102
102
|
}
|
103
103
|
}
|
104
|
-
|
104
|
+
(0, utils_1.consoleLog)(`${args.name} ${args.attemptNum} is ${args.status.toString().toLowerCase()}`);
|
105
105
|
this.statusCallback?.([...this.statuses]);
|
106
106
|
}
|
107
107
|
async debugAccounts(itemSet, tx) {
|
@@ -110,11 +110,11 @@ class TransactionsManager {
|
|
110
110
|
for (const ix of tx.getInstructions()) {
|
111
111
|
const ixAccounts = ix.keys.map((x) => x.pubkey);
|
112
112
|
const accountsNotInLut = ixAccounts.filter((x) => !lutAccounts.includes(x));
|
113
|
-
|
113
|
+
(0, utils_1.consoleLog)(`Program ${ix.programId}, data len: ${ix.data.length}, LUT accounts data: ${ix.keys.filter((x) => lutAccounts.includes(x.pubkey)).length * 3}`);
|
114
114
|
if (accountsNotInLut.length > 0) {
|
115
|
-
|
115
|
+
(0, utils_1.consoleLog)(`${accountsNotInLut.length} accounts not in LUT:`);
|
116
116
|
for (const key of accountsNotInLut) {
|
117
|
-
|
117
|
+
(0, utils_1.consoleLog)(key.toString());
|
118
118
|
}
|
119
119
|
}
|
120
120
|
}
|
@@ -126,10 +126,10 @@ class TransactionsManager {
|
|
126
126
|
}
|
127
127
|
return this.priorityFeeSetting;
|
128
128
|
}
|
129
|
-
updateStatusForSets(
|
130
|
-
|
129
|
+
updateStatusForSets(txNames, args, txSigs, reset) {
|
130
|
+
txNames.forEach((name, i) => {
|
131
131
|
this.updateStatus({
|
132
|
-
name
|
132
|
+
name,
|
133
133
|
txSig: txSigs && txSigs.length > i ? txSigs[i] : undefined,
|
134
134
|
...args,
|
135
135
|
}, reset);
|
@@ -144,14 +144,14 @@ class TransactionsManager {
|
|
144
144
|
await item.initialize();
|
145
145
|
}
|
146
146
|
}
|
147
|
-
|
147
|
+
(0, utils_1.consoleLog)("Transaction items:", items.length);
|
148
148
|
return await this.assembleTransactionSets(items);
|
149
149
|
}, this.totalRetries);
|
150
|
-
this.updateStatusForSets(itemSets, {
|
150
|
+
this.updateStatusForSets(itemSets.map((x) => x.name()), {
|
151
151
|
status: TransactionStatus.Queued,
|
152
152
|
attemptNum: 0,
|
153
153
|
});
|
154
|
-
|
154
|
+
(0, utils_1.consoleLog)("Initial item sets:", itemSets.length);
|
155
155
|
if (this.atomically) {
|
156
156
|
await this.processTransactionsAtomically(itemSets);
|
157
157
|
}
|
@@ -165,14 +165,14 @@ class TransactionsManager {
|
|
165
165
|
return this.statuses;
|
166
166
|
}
|
167
167
|
shouldProceedToSend(itemSets, attemptNum) {
|
168
|
-
if (
|
168
|
+
if (itemSets.length === 0) {
|
169
169
|
return false;
|
170
170
|
}
|
171
171
|
const newItemSetNames = itemSets.flatMap((x) => x.items.map((y) => y.name ?? ""));
|
172
172
|
if (newItemSetNames.length === 1 &&
|
173
173
|
newItemSetNames[0] === this.updateOracleTxName) {
|
174
174
|
(0, utils_1.consoleLog)("Skipping unnecessary oracle update");
|
175
|
-
this.updateStatusForSets(itemSets, {
|
175
|
+
this.updateStatusForSets(itemSets.map((x) => x.name()), {
|
176
176
|
status: TransactionStatus.Skipped,
|
177
177
|
attemptNum,
|
178
178
|
});
|
@@ -180,113 +180,109 @@ class TransactionsManager {
|
|
180
180
|
}
|
181
181
|
return true;
|
182
182
|
}
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
183
|
+
async refreshItemSets(itemSets, attemptNum, prevError, currentIndex) {
|
184
|
+
if (currentIndex !== undefined) {
|
185
|
+
const itemSet = itemSets[currentIndex];
|
186
|
+
await itemSet.reset();
|
187
|
+
await itemSet.refetchAll(attemptNum, prevError);
|
188
|
+
}
|
189
|
+
else {
|
190
|
+
await Promise.all(itemSets.map((itemSet) => itemSet.reset()));
|
191
|
+
for (const itemSet of itemSets) {
|
192
|
+
await itemSet.refetchAll(attemptNum, prevError);
|
193
|
+
}
|
194
|
+
}
|
195
|
+
const newItemSets = await this.assembleTransactionSets(currentIndex !== undefined
|
196
|
+
? [
|
197
|
+
...itemSets[currentIndex].items,
|
198
|
+
...itemSets.slice(currentIndex + 1).flatMap((set) => set.items),
|
199
|
+
]
|
200
|
+
: itemSets.flatMap((set) => set.items));
|
201
|
+
if (currentIndex !== undefined && newItemSets.length > 1) {
|
202
|
+
itemSets.splice(currentIndex, itemSets.length - currentIndex, ...newItemSets);
|
203
|
+
const startOfQueuedStatuses = this.statuses.findIndex((x) => x.status === TransactionStatus.Queued);
|
204
|
+
this.statuses.splice(startOfQueuedStatuses, this.statuses.length - startOfQueuedStatuses, ...newItemSets.map((x, i) => ({
|
205
|
+
name: x.name(),
|
206
|
+
attemptNum: i === 0 ? attemptNum : 0,
|
207
|
+
status: i === 0 ? TransactionStatus.Processing : TransactionStatus.Queued,
|
208
|
+
})));
|
209
|
+
}
|
210
|
+
return newItemSets;
|
211
|
+
}
|
212
|
+
async processTransactionsAtomically(itemSets) {
|
213
|
+
await (0, utils_1.retryWithExponentialBackoff)(async (attemptNum, prevError) => {
|
214
|
+
if (prevError &&
|
215
|
+
this.statuses.filter((x) => x.simulationSuccessful).length >
|
216
|
+
this.signableRetries) {
|
217
|
+
throw prevError;
|
218
|
+
}
|
219
|
+
this.priorityFeeSetting = this.getUpdatedPriorityFeeSetting(prevError, attemptNum);
|
220
|
+
if (attemptNum > 0) {
|
221
|
+
const refreshedSets = await this.refreshItemSets(itemSets, attemptNum, prevError);
|
222
|
+
if (!refreshedSets || !refreshedSets.length) {
|
223
|
+
return;
|
224
|
+
}
|
225
|
+
else {
|
226
|
+
itemSets = refreshedSets;
|
227
|
+
}
|
228
|
+
}
|
229
|
+
if (!this.shouldProceedToSend(itemSets, attemptNum)) {
|
230
|
+
return;
|
231
|
+
}
|
232
|
+
await this.sendJitoBundle(itemSets, attemptNum);
|
233
|
+
}, this.totalRetries, this.retryDelay, this.errorsToThrow);
|
189
234
|
}
|
190
235
|
async sendJitoBundle(itemSets, attemptNum) {
|
191
236
|
let transactions = [];
|
237
|
+
let txNames = [];
|
192
238
|
try {
|
193
239
|
for (const set of itemSets) {
|
194
240
|
transactions.push(await set.getSingleTransaction());
|
195
241
|
}
|
196
242
|
transactions = transactions.filter((x) => x.getInstructions().length > 0);
|
243
|
+
txNames = itemSets.map((x) => x.name());
|
197
244
|
if (transactions.length === 0) {
|
198
|
-
this.updateStatusForSets(
|
245
|
+
this.updateStatusForSets(txNames, {
|
199
246
|
status: TransactionStatus.Skipped,
|
200
247
|
attemptNum,
|
201
248
|
});
|
202
249
|
return;
|
203
250
|
}
|
204
|
-
this.updateStatusForSets(
|
251
|
+
this.updateStatusForSets(txNames, {
|
205
252
|
status: TransactionStatus.Processing,
|
206
253
|
attemptNum,
|
207
254
|
}, undefined, true);
|
208
255
|
for (const itemSet of itemSets) {
|
209
256
|
await this.debugAccounts(itemSet, await itemSet.getSingleTransaction());
|
210
257
|
}
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
catch (e) {
|
221
|
-
error = e;
|
222
|
-
}
|
223
|
-
if (error ||
|
224
|
-
(this.txRunType !== "only-simulate" &&
|
225
|
-
(!Boolean(txSigs) || txSigs?.length === 0) &&
|
226
|
-
!this.abortController?.signal.aborted)) {
|
227
|
-
this.updateStatusForSets(itemSets, {
|
258
|
+
const txSigs = await (0, utils_1.sendJitoBundledTransactions)(this.txHandler.umi, this.txHandler.connection, this.txHandler.signer, this.txHandler.otherSigners, transactions, this.txRunType, this.priorityFeeSetting, () => this.updateStatusForSets(txNames, {
|
259
|
+
status: TransactionStatus.Processing,
|
260
|
+
attemptNum,
|
261
|
+
simulationSuccessful: true,
|
262
|
+
}), this.abortController);
|
263
|
+
if (this.txRunType !== "only-simulate" &&
|
264
|
+
(!Boolean(txSigs) || txSigs?.length === 0) &&
|
265
|
+
!this.abortController?.signal.aborted) {
|
266
|
+
this.updateStatusForSets(txNames, {
|
228
267
|
status: TransactionStatus.Failed,
|
229
268
|
attemptNum,
|
230
|
-
moreInfo: error?.message,
|
231
269
|
}, txSigs);
|
232
|
-
throw error ? error : new Error("Unknown error");
|
233
270
|
}
|
234
|
-
this.updateStatusForSets(
|
271
|
+
this.updateStatusForSets(txNames, { status: TransactionStatus.Successful, attemptNum }, txSigs);
|
235
272
|
}
|
236
273
|
catch (e) {
|
237
|
-
this.
|
238
|
-
const errorDetails = (0, transactionUtils_1.getErrorInfo)(this.txHandler.umi, transactions, e, itemSets.filter((x) => this.statuses.find((y) => x.name() === y.name && y.attemptNum === attemptNum)?.simulationSuccessful).length === itemSets.length, this.priorityFeeSetting);
|
239
|
-
const errorString = `${errorDetails.errorName ?? "Unknown error"}: ${errorDetails.errorInfo?.split("\n")[0] ?? "unknown"}`;
|
240
|
-
const errorInfo = errorDetails.errorName || errorDetails.errorInfo
|
241
|
-
? errorString
|
242
|
-
: e.message;
|
243
|
-
this.updateStatusForSets(itemSets, {
|
244
|
-
status: errorDetails.canBeIgnored
|
245
|
-
? TransactionStatus.Skipped
|
246
|
-
: TransactionStatus.Failed,
|
247
|
-
attemptNum,
|
248
|
-
moreInfo: errorInfo,
|
249
|
-
});
|
250
|
-
(0, utils_1.consoleLog)(errorString);
|
251
|
-
if (!errorDetails.canBeIgnored) {
|
252
|
-
throw new Error(errorInfo);
|
253
|
-
}
|
274
|
+
this.captureErrorInfo(transactions, txNames, attemptNum, e);
|
254
275
|
}
|
255
276
|
}
|
256
|
-
async processTransactionsAtomically(itemSets) {
|
257
|
-
await (0, utils_1.retryWithExponentialBackoff)(async (retryNum, prevError) => {
|
258
|
-
if (prevError &&
|
259
|
-
this.statuses.filter((x) => x.simulationSuccessful).length >
|
260
|
-
this.signableRetries) {
|
261
|
-
throw prevError;
|
262
|
-
}
|
263
|
-
const attemptNum = Math.max(...itemSets.map((x) => this.getTrueAttemptNum(x?.name() ?? "")));
|
264
|
-
this.priorityFeeSetting = this.getUpdatedPriorityFeeSetting(prevError, attemptNum);
|
265
|
-
if (retryNum > 0) {
|
266
|
-
const refreshedSets = await this.refreshItemSets(itemSets, attemptNum, prevError);
|
267
|
-
if (!refreshedSets || !refreshedSets.length) {
|
268
|
-
return;
|
269
|
-
}
|
270
|
-
else {
|
271
|
-
itemSets = refreshedSets;
|
272
|
-
}
|
273
|
-
}
|
274
|
-
if (!this.shouldProceedToSend(itemSets, attemptNum)) {
|
275
|
-
return;
|
276
|
-
}
|
277
|
-
await this.sendJitoBundle(itemSets, attemptNum);
|
278
|
-
}, this.totalRetries, this.retryDelay, this.errorsToThrow);
|
279
|
-
}
|
280
277
|
async processTransactionSet(itemSets, currentIndex) {
|
281
278
|
let itemSet = itemSets[currentIndex];
|
282
|
-
await (0, utils_1.retryWithExponentialBackoff)(async (
|
279
|
+
await (0, utils_1.retryWithExponentialBackoff)(async (attemptNum, prevError) => {
|
283
280
|
if (prevError &&
|
284
281
|
this.statuses.filter((x) => x.simulationSuccessful).length >
|
285
282
|
this.signableRetries) {
|
286
283
|
throw prevError;
|
287
284
|
}
|
288
|
-
|
289
|
-
if (currentIndex > 0 || retryNum > 0) {
|
285
|
+
if (currentIndex > 0 || attemptNum > 0) {
|
290
286
|
const refreshedSets = await this.refreshItemSets(itemSets, attemptNum, prevError, currentIndex);
|
291
287
|
itemSet = refreshedSets ? refreshedSets[0] : undefined;
|
292
288
|
}
|
@@ -308,35 +304,6 @@ class TransactionsManager {
|
|
308
304
|
}
|
309
305
|
}, this.totalRetries, this.retryDelay, this.errorsToThrow);
|
310
306
|
}
|
311
|
-
async refreshItemSets(itemSets, attemptNum, prevError, currentIndex) {
|
312
|
-
if (currentIndex !== undefined) {
|
313
|
-
const itemSet = itemSets[currentIndex];
|
314
|
-
await itemSet.reset();
|
315
|
-
await itemSet.refetchAll(attemptNum, prevError);
|
316
|
-
}
|
317
|
-
else {
|
318
|
-
await Promise.all(itemSets.map((itemSet) => itemSet.reset()));
|
319
|
-
for (const itemSet of itemSets) {
|
320
|
-
await itemSet.refetchAll(attemptNum, prevError);
|
321
|
-
}
|
322
|
-
}
|
323
|
-
const newItemSets = await this.assembleTransactionSets(currentIndex !== undefined
|
324
|
-
? [
|
325
|
-
...itemSets[currentIndex].items,
|
326
|
-
...itemSets.slice(currentIndex + 1).flatMap((set) => set.items),
|
327
|
-
]
|
328
|
-
: itemSets.flatMap((set) => set.items));
|
329
|
-
if (currentIndex !== undefined && newItemSets.length > 1) {
|
330
|
-
itemSets.splice(currentIndex, itemSets.length - currentIndex, ...newItemSets);
|
331
|
-
const startOfQueuedStatuses = this.statuses.findIndex((x) => x.status === TransactionStatus.Queued);
|
332
|
-
this.statuses.splice(startOfQueuedStatuses, this.statuses.length - startOfQueuedStatuses, ...newItemSets.map((x, i) => ({
|
333
|
-
name: x.name(),
|
334
|
-
attemptNum: i === 0 ? attemptNum : 0,
|
335
|
-
status: i === 0 ? TransactionStatus.Processing : TransactionStatus.Queued,
|
336
|
-
})));
|
337
|
-
}
|
338
|
-
return newItemSets;
|
339
|
-
}
|
340
307
|
async sendTransaction(tx, name, attemptNum, priorityFeeSetting, txRunType) {
|
341
308
|
this.updateStatus({
|
342
309
|
name,
|
@@ -358,24 +325,27 @@ class TransactionsManager {
|
|
358
325
|
});
|
359
326
|
}
|
360
327
|
catch (e) {
|
361
|
-
this.
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
this.
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
328
|
+
this.captureErrorInfo([tx], [name], attemptNum, e);
|
329
|
+
}
|
330
|
+
}
|
331
|
+
captureErrorInfo(transactions, txNames, attemptNum, error) {
|
332
|
+
(0, utils_1.consoleLog)("Capturing error info...");
|
333
|
+
const errorDetails = (0, transactionUtils_1.getErrorInfo)(this.txHandler.umi, transactions, error, txNames.filter((x) => this.statuses.find((y) => x === y.name && y.attemptNum === attemptNum)
|
334
|
+
?.simulationSuccessful).length === txNames.length, this.priorityFeeSetting);
|
335
|
+
const errorString = `${errorDetails.errorName ?? "Unknown error"}: ${errorDetails.errorInfo?.split("\n")[0] ?? "unknown"}`;
|
336
|
+
const errorInfo = errorDetails.errorName || errorDetails.errorInfo
|
337
|
+
? errorString
|
338
|
+
: error.message;
|
339
|
+
this.updateStatusForSets(txNames, {
|
340
|
+
status: errorDetails.canBeIgnored
|
341
|
+
? TransactionStatus.Skipped
|
342
|
+
: TransactionStatus.Failed,
|
343
|
+
attemptNum,
|
344
|
+
moreInfo: errorInfo,
|
345
|
+
});
|
346
|
+
(0, utils_1.consoleLog)(errorString);
|
347
|
+
if (!errorDetails.canBeIgnored) {
|
348
|
+
throw new Error(errorInfo);
|
379
349
|
}
|
380
350
|
}
|
381
351
|
}
|
package/local/txSandbox.ts
CHANGED
package/package.json
CHANGED
@@ -101,7 +101,7 @@ export class TransactionsManager<T extends TxHandler> {
|
|
101
101
|
items: TransactionItem[]
|
102
102
|
): Promise<TransactionSet[]> {
|
103
103
|
let transactionSets: TransactionSet[] = [];
|
104
|
-
|
104
|
+
consoleLog(`Reassembling ${items.length} items`);
|
105
105
|
|
106
106
|
const txItems = items.sort((a, b) => a.orderPrio - b.orderPrio);
|
107
107
|
|
@@ -164,7 +164,7 @@ export class TransactionsManager<T extends TxHandler> {
|
|
164
164
|
this.statuses.push(args);
|
165
165
|
}
|
166
166
|
}
|
167
|
-
|
167
|
+
consoleLog(
|
168
168
|
`${args.name} ${args.attemptNum} is ${args.status.toString().toLowerCase()}`
|
169
169
|
);
|
170
170
|
this.statusCallback?.([...this.statuses]);
|
@@ -178,13 +178,13 @@ export class TransactionsManager<T extends TxHandler> {
|
|
178
178
|
const accountsNotInLut = ixAccounts.filter(
|
179
179
|
(x) => !lutAccounts.includes(x)
|
180
180
|
);
|
181
|
-
|
181
|
+
consoleLog(
|
182
182
|
`Program ${ix.programId}, data len: ${ix.data.length}, LUT accounts data: ${ix.keys.filter((x) => lutAccounts.includes(x.pubkey)).length * 3}`
|
183
183
|
);
|
184
184
|
if (accountsNotInLut.length > 0) {
|
185
|
-
|
185
|
+
consoleLog(`${accountsNotInLut.length} accounts not in LUT:`);
|
186
186
|
for (const key of accountsNotInLut) {
|
187
|
-
|
187
|
+
consoleLog(key.toString());
|
188
188
|
}
|
189
189
|
}
|
190
190
|
}
|
@@ -207,15 +207,15 @@ export class TransactionsManager<T extends TxHandler> {
|
|
207
207
|
}
|
208
208
|
|
209
209
|
private updateStatusForSets(
|
210
|
-
|
210
|
+
txNames: string[],
|
211
211
|
args: Omit<TransactionManagerStatus, "name">,
|
212
212
|
txSigs?: string[],
|
213
213
|
reset?: boolean
|
214
214
|
) {
|
215
|
-
|
215
|
+
txNames.forEach((name, i) => {
|
216
216
|
this.updateStatus(
|
217
217
|
{
|
218
|
-
name
|
218
|
+
name,
|
219
219
|
txSig: txSigs && txSigs.length > i ? txSigs[i] : undefined,
|
220
220
|
...args,
|
221
221
|
},
|
@@ -236,15 +236,18 @@ export class TransactionsManager<T extends TxHandler> {
|
|
236
236
|
await item.initialize();
|
237
237
|
}
|
238
238
|
}
|
239
|
-
|
239
|
+
consoleLog("Transaction items:", items.length);
|
240
240
|
return await this.assembleTransactionSets(items);
|
241
241
|
}, this.totalRetries);
|
242
242
|
|
243
|
-
this.updateStatusForSets(
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
243
|
+
this.updateStatusForSets(
|
244
|
+
itemSets.map((x) => x.name()),
|
245
|
+
{
|
246
|
+
status: TransactionStatus.Queued,
|
247
|
+
attemptNum: 0,
|
248
|
+
}
|
249
|
+
);
|
250
|
+
consoleLog("Initial item sets:", itemSets.length);
|
248
251
|
|
249
252
|
if (this.atomically) {
|
250
253
|
await this.processTransactionsAtomically(itemSets);
|
@@ -260,7 +263,7 @@ export class TransactionsManager<T extends TxHandler> {
|
|
260
263
|
}
|
261
264
|
|
262
265
|
private shouldProceedToSend(itemSets: TransactionSet[], attemptNum: number) {
|
263
|
-
if (
|
266
|
+
if (itemSets.length === 0) {
|
264
267
|
return false;
|
265
268
|
}
|
266
269
|
|
@@ -272,37 +275,123 @@ export class TransactionsManager<T extends TxHandler> {
|
|
272
275
|
newItemSetNames[0] === this.updateOracleTxName
|
273
276
|
) {
|
274
277
|
consoleLog("Skipping unnecessary oracle update");
|
275
|
-
this.updateStatusForSets(
|
276
|
-
|
277
|
-
|
278
|
-
|
278
|
+
this.updateStatusForSets(
|
279
|
+
itemSets.map((x) => x.name()),
|
280
|
+
{
|
281
|
+
status: TransactionStatus.Skipped,
|
282
|
+
attemptNum,
|
283
|
+
}
|
284
|
+
);
|
279
285
|
return false;
|
280
286
|
}
|
281
287
|
|
282
288
|
return true;
|
283
289
|
}
|
284
290
|
|
285
|
-
private
|
286
|
-
|
287
|
-
|
291
|
+
private async refreshItemSets(
|
292
|
+
itemSets: TransactionSet[],
|
293
|
+
attemptNum: number,
|
294
|
+
prevError?: Error,
|
295
|
+
currentIndex?: number
|
296
|
+
): Promise<TransactionSet[] | undefined> {
|
297
|
+
if (currentIndex !== undefined) {
|
298
|
+
const itemSet = itemSets[currentIndex];
|
299
|
+
await itemSet.reset();
|
300
|
+
await itemSet.refetchAll(attemptNum, prevError);
|
301
|
+
} else {
|
302
|
+
await Promise.all(itemSets.map((itemSet) => itemSet.reset()));
|
303
|
+
for (const itemSet of itemSets) {
|
304
|
+
await itemSet.refetchAll(attemptNum, prevError);
|
305
|
+
}
|
306
|
+
}
|
307
|
+
|
308
|
+
const newItemSets = await this.assembleTransactionSets(
|
309
|
+
currentIndex !== undefined
|
310
|
+
? [
|
311
|
+
...itemSets[currentIndex].items,
|
312
|
+
...itemSets.slice(currentIndex + 1).flatMap((set) => set.items),
|
313
|
+
]
|
314
|
+
: itemSets.flatMap((set) => set.items)
|
315
|
+
);
|
316
|
+
|
317
|
+
if (currentIndex !== undefined && newItemSets.length > 1) {
|
318
|
+
itemSets.splice(
|
319
|
+
currentIndex,
|
320
|
+
itemSets.length - currentIndex,
|
321
|
+
...newItemSets
|
322
|
+
);
|
323
|
+
const startOfQueuedStatuses = this.statuses.findIndex(
|
324
|
+
(x) => x.status === TransactionStatus.Queued
|
325
|
+
);
|
326
|
+
this.statuses.splice(
|
327
|
+
startOfQueuedStatuses,
|
328
|
+
this.statuses.length - startOfQueuedStatuses,
|
329
|
+
...newItemSets.map((x, i) => ({
|
330
|
+
name: x.name(),
|
331
|
+
attemptNum: i === 0 ? attemptNum : 0,
|
332
|
+
status:
|
333
|
+
i === 0 ? TransactionStatus.Processing : TransactionStatus.Queued,
|
334
|
+
}))
|
335
|
+
);
|
336
|
+
}
|
337
|
+
|
338
|
+
return newItemSets;
|
339
|
+
}
|
340
|
+
|
341
|
+
private async processTransactionsAtomically(itemSets: TransactionSet[]) {
|
342
|
+
await retryWithExponentialBackoff(
|
343
|
+
async (attemptNum, prevError) => {
|
344
|
+
if (
|
345
|
+
prevError &&
|
346
|
+
this.statuses.filter((x) => x.simulationSuccessful).length >
|
347
|
+
this.signableRetries
|
348
|
+
) {
|
349
|
+
throw prevError;
|
350
|
+
}
|
351
|
+
|
352
|
+
this.priorityFeeSetting = this.getUpdatedPriorityFeeSetting(
|
353
|
+
prevError,
|
354
|
+
attemptNum
|
355
|
+
);
|
356
|
+
|
357
|
+
if (attemptNum > 0) {
|
358
|
+
const refreshedSets = await this.refreshItemSets(
|
359
|
+
itemSets,
|
360
|
+
attemptNum,
|
361
|
+
prevError
|
362
|
+
);
|
363
|
+
if (!refreshedSets || !refreshedSets.length) {
|
364
|
+
return;
|
365
|
+
} else {
|
366
|
+
itemSets = refreshedSets;
|
367
|
+
}
|
368
|
+
}
|
369
|
+
|
370
|
+
if (!this.shouldProceedToSend(itemSets, attemptNum)) {
|
371
|
+
return;
|
372
|
+
}
|
373
|
+
|
374
|
+
await this.sendJitoBundle(itemSets, attemptNum);
|
375
|
+
},
|
376
|
+
this.totalRetries,
|
377
|
+
this.retryDelay,
|
378
|
+
this.errorsToThrow
|
288
379
|
);
|
289
|
-
const attemptNum =
|
290
|
-
prevAttempts.length -
|
291
|
-
prevAttempts.filter((x) => x.status === TransactionStatus.Skipped)
|
292
|
-
?.length;
|
293
|
-
return attemptNum;
|
294
380
|
}
|
295
381
|
|
296
382
|
private async sendJitoBundle(itemSets: TransactionSet[], attemptNum: number) {
|
297
383
|
let transactions: TransactionBuilder[] = [];
|
384
|
+
let txNames: string[] = [];
|
298
385
|
|
299
386
|
try {
|
300
387
|
for (const set of itemSets) {
|
301
388
|
transactions.push(await set.getSingleTransaction());
|
302
389
|
}
|
303
390
|
transactions = transactions.filter((x) => x.getInstructions().length > 0);
|
391
|
+
|
392
|
+
txNames = itemSets.map((x) => x.name());
|
304
393
|
if (transactions.length === 0) {
|
305
|
-
this.updateStatusForSets(
|
394
|
+
this.updateStatusForSets(txNames, {
|
306
395
|
status: TransactionStatus.Skipped,
|
307
396
|
attemptNum,
|
308
397
|
});
|
@@ -310,7 +399,7 @@ export class TransactionsManager<T extends TxHandler> {
|
|
310
399
|
}
|
311
400
|
|
312
401
|
this.updateStatusForSets(
|
313
|
-
|
402
|
+
txNames,
|
314
403
|
{
|
315
404
|
status: TransactionStatus.Processing,
|
316
405
|
attemptNum,
|
@@ -322,139 +411,55 @@ export class TransactionsManager<T extends TxHandler> {
|
|
322
411
|
await this.debugAccounts(itemSet, await itemSet.getSingleTransaction());
|
323
412
|
}
|
324
413
|
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
this.
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
}),
|
342
|
-
this.abortController
|
343
|
-
);
|
344
|
-
} catch (e: any) {
|
345
|
-
error = e as Error;
|
346
|
-
}
|
414
|
+
const txSigs = await sendJitoBundledTransactions(
|
415
|
+
this.txHandler.umi,
|
416
|
+
this.txHandler.connection,
|
417
|
+
this.txHandler.signer,
|
418
|
+
this.txHandler.otherSigners,
|
419
|
+
transactions,
|
420
|
+
this.txRunType,
|
421
|
+
this.priorityFeeSetting,
|
422
|
+
() =>
|
423
|
+
this.updateStatusForSets(txNames, {
|
424
|
+
status: TransactionStatus.Processing,
|
425
|
+
attemptNum,
|
426
|
+
simulationSuccessful: true,
|
427
|
+
}),
|
428
|
+
this.abortController
|
429
|
+
);
|
347
430
|
|
348
431
|
if (
|
349
|
-
|
350
|
-
(
|
351
|
-
|
352
|
-
!this.abortController?.signal.aborted)
|
432
|
+
this.txRunType !== "only-simulate" &&
|
433
|
+
(!Boolean(txSigs) || txSigs?.length === 0) &&
|
434
|
+
!this.abortController?.signal.aborted
|
353
435
|
) {
|
354
436
|
this.updateStatusForSets(
|
355
|
-
|
437
|
+
txNames,
|
356
438
|
{
|
357
439
|
status: TransactionStatus.Failed,
|
358
440
|
attemptNum,
|
359
|
-
moreInfo: error?.message,
|
360
441
|
},
|
361
442
|
txSigs
|
362
443
|
);
|
363
|
-
throw error ? error : new Error("Unknown error");
|
364
444
|
}
|
365
445
|
|
366
446
|
this.updateStatusForSets(
|
367
|
-
|
447
|
+
txNames,
|
368
448
|
{ status: TransactionStatus.Successful, attemptNum },
|
369
449
|
txSigs
|
370
450
|
);
|
371
451
|
} catch (e: any) {
|
372
|
-
this.
|
373
|
-
const errorDetails = getErrorInfo(
|
374
|
-
this.txHandler.umi,
|
375
|
-
transactions,
|
376
|
-
e,
|
377
|
-
itemSets.filter(
|
378
|
-
(x) =>
|
379
|
-
this.statuses.find(
|
380
|
-
(y) => x.name() === y.name && y.attemptNum === attemptNum
|
381
|
-
)?.simulationSuccessful
|
382
|
-
).length === itemSets.length,
|
383
|
-
this.priorityFeeSetting
|
384
|
-
);
|
385
|
-
|
386
|
-
const errorString = `${errorDetails.errorName ?? "Unknown error"}: ${errorDetails.errorInfo?.split("\n")[0] ?? "unknown"}`;
|
387
|
-
const errorInfo =
|
388
|
-
errorDetails.errorName || errorDetails.errorInfo
|
389
|
-
? errorString
|
390
|
-
: e.message;
|
391
|
-
this.updateStatusForSets(itemSets, {
|
392
|
-
status: errorDetails.canBeIgnored
|
393
|
-
? TransactionStatus.Skipped
|
394
|
-
: TransactionStatus.Failed,
|
395
|
-
attemptNum,
|
396
|
-
moreInfo: errorInfo,
|
397
|
-
});
|
398
|
-
consoleLog(errorString);
|
399
|
-
|
400
|
-
if (!errorDetails.canBeIgnored) {
|
401
|
-
throw new Error(errorInfo);
|
402
|
-
}
|
452
|
+
this.captureErrorInfo(transactions, txNames, attemptNum, e);
|
403
453
|
}
|
404
454
|
}
|
405
455
|
|
406
|
-
private async processTransactionsAtomically(itemSets: TransactionSet[]) {
|
407
|
-
await retryWithExponentialBackoff(
|
408
|
-
async (retryNum, prevError) => {
|
409
|
-
if (
|
410
|
-
prevError &&
|
411
|
-
this.statuses.filter((x) => x.simulationSuccessful).length >
|
412
|
-
this.signableRetries
|
413
|
-
) {
|
414
|
-
throw prevError;
|
415
|
-
}
|
416
|
-
|
417
|
-
const attemptNum = Math.max(
|
418
|
-
...itemSets.map((x) => this.getTrueAttemptNum(x?.name() ?? ""))
|
419
|
-
);
|
420
|
-
|
421
|
-
this.priorityFeeSetting = this.getUpdatedPriorityFeeSetting(
|
422
|
-
prevError,
|
423
|
-
attemptNum
|
424
|
-
);
|
425
|
-
|
426
|
-
if (retryNum > 0) {
|
427
|
-
const refreshedSets = await this.refreshItemSets(
|
428
|
-
itemSets,
|
429
|
-
attemptNum,
|
430
|
-
prevError
|
431
|
-
);
|
432
|
-
if (!refreshedSets || !refreshedSets.length) {
|
433
|
-
return;
|
434
|
-
} else {
|
435
|
-
itemSets = refreshedSets;
|
436
|
-
}
|
437
|
-
}
|
438
|
-
|
439
|
-
if (!this.shouldProceedToSend(itemSets, attemptNum)) {
|
440
|
-
return;
|
441
|
-
}
|
442
|
-
|
443
|
-
await this.sendJitoBundle(itemSets, attemptNum);
|
444
|
-
},
|
445
|
-
this.totalRetries,
|
446
|
-
this.retryDelay,
|
447
|
-
this.errorsToThrow
|
448
|
-
);
|
449
|
-
}
|
450
|
-
|
451
456
|
private async processTransactionSet(
|
452
457
|
itemSets: TransactionSet[],
|
453
458
|
currentIndex: number
|
454
459
|
) {
|
455
460
|
let itemSet: TransactionSet | undefined = itemSets[currentIndex];
|
456
461
|
await retryWithExponentialBackoff(
|
457
|
-
async (
|
462
|
+
async (attemptNum, prevError) => {
|
458
463
|
if (
|
459
464
|
prevError &&
|
460
465
|
this.statuses.filter((x) => x.simulationSuccessful).length >
|
@@ -463,8 +468,7 @@ export class TransactionsManager<T extends TxHandler> {
|
|
463
468
|
throw prevError;
|
464
469
|
}
|
465
470
|
|
466
|
-
|
467
|
-
if (currentIndex > 0 || retryNum > 0) {
|
471
|
+
if (currentIndex > 0 || attemptNum > 0) {
|
468
472
|
const refreshedSets = await this.refreshItemSets(
|
469
473
|
itemSets,
|
470
474
|
attemptNum,
|
@@ -504,56 +508,6 @@ export class TransactionsManager<T extends TxHandler> {
|
|
504
508
|
);
|
505
509
|
}
|
506
510
|
|
507
|
-
private async refreshItemSets(
|
508
|
-
itemSets: TransactionSet[],
|
509
|
-
attemptNum: number,
|
510
|
-
prevError?: Error,
|
511
|
-
currentIndex?: number
|
512
|
-
): Promise<TransactionSet[] | undefined> {
|
513
|
-
if (currentIndex !== undefined) {
|
514
|
-
const itemSet = itemSets[currentIndex];
|
515
|
-
await itemSet.reset();
|
516
|
-
await itemSet.refetchAll(attemptNum, prevError);
|
517
|
-
} else {
|
518
|
-
await Promise.all(itemSets.map((itemSet) => itemSet.reset()));
|
519
|
-
for (const itemSet of itemSets) {
|
520
|
-
await itemSet.refetchAll(attemptNum, prevError);
|
521
|
-
}
|
522
|
-
}
|
523
|
-
|
524
|
-
const newItemSets = await this.assembleTransactionSets(
|
525
|
-
currentIndex !== undefined
|
526
|
-
? [
|
527
|
-
...itemSets[currentIndex].items,
|
528
|
-
...itemSets.slice(currentIndex + 1).flatMap((set) => set.items),
|
529
|
-
]
|
530
|
-
: itemSets.flatMap((set) => set.items)
|
531
|
-
);
|
532
|
-
|
533
|
-
if (currentIndex !== undefined && newItemSets.length > 1) {
|
534
|
-
itemSets.splice(
|
535
|
-
currentIndex,
|
536
|
-
itemSets.length - currentIndex,
|
537
|
-
...newItemSets
|
538
|
-
);
|
539
|
-
const startOfQueuedStatuses = this.statuses.findIndex(
|
540
|
-
(x) => x.status === TransactionStatus.Queued
|
541
|
-
);
|
542
|
-
this.statuses.splice(
|
543
|
-
startOfQueuedStatuses,
|
544
|
-
this.statuses.length - startOfQueuedStatuses,
|
545
|
-
...newItemSets.map((x, i) => ({
|
546
|
-
name: x.name(),
|
547
|
-
attemptNum: i === 0 ? attemptNum : 0,
|
548
|
-
status:
|
549
|
-
i === 0 ? TransactionStatus.Processing : TransactionStatus.Queued,
|
550
|
-
}))
|
551
|
-
);
|
552
|
-
}
|
553
|
-
|
554
|
-
return newItemSets;
|
555
|
-
}
|
556
|
-
|
557
511
|
protected async sendTransaction(
|
558
512
|
tx: TransactionBuilder,
|
559
513
|
name: string,
|
@@ -592,35 +546,45 @@ export class TransactionsManager<T extends TxHandler> {
|
|
592
546
|
txSig: txSig ? bs58.encode(txSig) : undefined,
|
593
547
|
});
|
594
548
|
} catch (e: any) {
|
595
|
-
this.
|
596
|
-
|
597
|
-
|
598
|
-
[tx],
|
599
|
-
e,
|
600
|
-
this.statuses.find(
|
601
|
-
(x) => x.name === name && x.attemptNum === attemptNum
|
602
|
-
)?.simulationSuccessful,
|
603
|
-
priorityFeeSetting
|
604
|
-
);
|
549
|
+
this.captureErrorInfo([tx], [name], attemptNum, e);
|
550
|
+
}
|
551
|
+
}
|
605
552
|
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
553
|
+
private captureErrorInfo(
|
554
|
+
transactions: TransactionBuilder[],
|
555
|
+
txNames: string[],
|
556
|
+
attemptNum: number,
|
557
|
+
error: any
|
558
|
+
) {
|
559
|
+
consoleLog("Capturing error info...");
|
560
|
+
const errorDetails = getErrorInfo(
|
561
|
+
this.txHandler.umi,
|
562
|
+
transactions,
|
563
|
+
error,
|
564
|
+
txNames.filter(
|
565
|
+
(x) =>
|
566
|
+
this.statuses.find((y) => x === y.name && y.attemptNum === attemptNum)
|
567
|
+
?.simulationSuccessful
|
568
|
+
).length === txNames.length,
|
569
|
+
this.priorityFeeSetting
|
570
|
+
);
|
620
571
|
|
621
|
-
|
622
|
-
|
623
|
-
|
572
|
+
const errorString = `${errorDetails.errorName ?? "Unknown error"}: ${errorDetails.errorInfo?.split("\n")[0] ?? "unknown"}`;
|
573
|
+
const errorInfo =
|
574
|
+
errorDetails.errorName || errorDetails.errorInfo
|
575
|
+
? errorString
|
576
|
+
: error.message;
|
577
|
+
this.updateStatusForSets(txNames, {
|
578
|
+
status: errorDetails.canBeIgnored
|
579
|
+
? TransactionStatus.Skipped
|
580
|
+
: TransactionStatus.Failed,
|
581
|
+
attemptNum,
|
582
|
+
moreInfo: errorInfo,
|
583
|
+
});
|
584
|
+
consoleLog(errorString);
|
585
|
+
|
586
|
+
if (!errorDetails.canBeIgnored) {
|
587
|
+
throw new Error(errorInfo);
|
624
588
|
}
|
625
589
|
}
|
626
590
|
}
|
package/tests/unit/accounts.ts
CHANGED
@@ -24,7 +24,6 @@ async function hasTokenAccounts(wallet: PublicKey) {
|
|
24
24
|
)
|
25
25
|
);
|
26
26
|
for (let i = 0; i < tokenAccounts.length; i++) {
|
27
|
-
console.log(tokenAccounts[i].publicKey.toString());
|
28
27
|
if (!tokenAccounts[i].exists) {
|
29
28
|
console.log(
|
30
29
|
`Missing ${wallet.toString()} TA for `,
|
@@ -55,7 +54,9 @@ describe("Assert Solauto fee token accounts are created", async () => {
|
|
55
54
|
!ismAccounts.find((x) => group.equals(toWeb3JsPublicKey(x.group)))
|
56
55
|
);
|
57
56
|
|
58
|
-
|
57
|
+
if (missingIsmAccounts.length > 0) {
|
58
|
+
console.log("Missing ISM accounts", missingIsmAccounts);
|
59
|
+
}
|
59
60
|
assert(missingIsmAccounts.length === 0);
|
60
61
|
});
|
61
62
|
});
|