Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/SmartTransactionsController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@
getTxHash,
getSmartTransactionMetricsProperties,
getSmartTransactionMetricsSensitiveProperties,
shouldMarkRegularTransactionAsFailed,
markRegularTransactionAsFailed,
shouldMarkRegularTransactionsAsFailed,
markRegularTransactionsAsFailed,
} from './utils';

const SECOND = 1000;
Expand Down Expand Up @@ -335,9 +335,9 @@
isSmartTransactionPending,
);
if (!this.timeoutHandle && pendingTransactions?.length > 0) {
this.poll();

Check warning on line 338 in src/SmartTransactionsController.ts

View workflow job for this annotation

GitHub Actions / Build, lint, and test / Lint (18.x)

Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the `void` operator

Check warning on line 338 in src/SmartTransactionsController.ts

View workflow job for this annotation

GitHub Actions / Build, lint, and test / Lint (20.x)

Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the `void` operator
} else if (this.timeoutHandle && pendingTransactions?.length === 0) {
this.stop();

Check warning on line 340 in src/SmartTransactionsController.ts

View workflow job for this annotation

GitHub Actions / Build, lint, and test / Lint (18.x)

Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the `void` operator

Check warning on line 340 in src/SmartTransactionsController.ts

View workflow job for this annotation

GitHub Actions / Build, lint, and test / Lint (20.x)

Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the `void` operator
}
}

Expand All @@ -362,7 +362,7 @@
}

this.timeoutHandle = setInterval(() => {
safelyExecute(async () => this.updateSmartTransactions());

Check warning on line 365 in src/SmartTransactionsController.ts

View workflow job for this annotation

GitHub Actions / Build, lint, and test / Lint (18.x)

Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the `void` operator

Check warning on line 365 in src/SmartTransactionsController.ts

View workflow job for this annotation

GitHub Actions / Build, lint, and test / Lint (20.x)

Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the `void` operator
}, this.#interval);
await safelyExecute(async () => this.updateSmartTransactions());
}
Expand Down Expand Up @@ -429,7 +429,7 @@
ethQuery = new EthQuery(provider);
}

this.#createOrUpdateSmartTransaction(smartTransaction, {

Check warning on line 432 in src/SmartTransactionsController.ts

View workflow job for this annotation

GitHub Actions / Build, lint, and test / Lint (18.x)

Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the `void` operator

Check warning on line 432 in src/SmartTransactionsController.ts

View workflow job for this annotation

GitHub Actions / Build, lint, and test / Lint (20.x)

Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the `void` operator
chainId,
ethQuery,
});
Expand Down Expand Up @@ -561,13 +561,13 @@
);

if (
shouldMarkRegularTransactionAsFailed({
shouldMarkRegularTransactionsAsFailed({
smartTransaction: nextSmartTransaction,
clientId: this.#clientId,
getFeatureFlags: this.#getFeatureFlags,
})
) {
markRegularTransactionAsFailed({
markRegularTransactionsAsFailed({
smartTransaction: nextSmartTransaction,
getRegularTransactions: () =>
this.messenger.call('TransactionController:getTransactions'),
Expand Down
76 changes: 62 additions & 14 deletions src/utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -403,7 +403,7 @@ describe('src/utils.js', () => {
});
});

describe('shouldMarkRegularTransactionAsFailed', () => {
describe('shouldMarkRegularTransactionsAsFailed', () => {
const createSmartTransaction = (status: SmartTransactionStatuses) => ({
uuid: 'test-uuid',
status,
Expand All @@ -428,7 +428,7 @@ describe('src/utils.js', () => {
});

it('returns true for "cancelled" status when feature flag is enabled', () => {
const result = utils.shouldMarkRegularTransactionAsFailed({
const result = utils.shouldMarkRegularTransactionsAsFailed({
smartTransaction: createSmartTransaction(
SmartTransactionStatuses.CANCELLED,
),
Expand All @@ -439,7 +439,7 @@ describe('src/utils.js', () => {
});

it('returns true for "cancelled_user_cancelled" status when feature flag is enabled', () => {
const result = utils.shouldMarkRegularTransactionAsFailed({
const result = utils.shouldMarkRegularTransactionsAsFailed({
smartTransaction: createSmartTransaction(
SmartTransactionStatuses.CANCELLED_USER_CANCELLED,
),
Expand All @@ -450,7 +450,7 @@ describe('src/utils.js', () => {
});

it('returns true for "unknown" status when feature flag is enabled', () => {
const result = utils.shouldMarkRegularTransactionAsFailed({
const result = utils.shouldMarkRegularTransactionsAsFailed({
smartTransaction: createSmartTransaction(
SmartTransactionStatuses.UNKNOWN,
),
Expand All @@ -461,7 +461,7 @@ describe('src/utils.js', () => {
});

it('returns true for "resolved" status when feature flag is enabled', () => {
const result = utils.shouldMarkRegularTransactionAsFailed({
const result = utils.shouldMarkRegularTransactionsAsFailed({
smartTransaction: createSmartTransaction(
SmartTransactionStatuses.RESOLVED,
),
Expand All @@ -472,7 +472,7 @@ describe('src/utils.js', () => {
});

it('returns false for "pending" status when feature flag is enabled', () => {
const result = utils.shouldMarkRegularTransactionAsFailed({
const result = utils.shouldMarkRegularTransactionsAsFailed({
smartTransaction: createSmartTransaction(
SmartTransactionStatuses.PENDING,
),
Expand All @@ -483,7 +483,7 @@ describe('src/utils.js', () => {
});

it('returns false for "success" status when feature flag is enabled', () => {
const result = utils.shouldMarkRegularTransactionAsFailed({
const result = utils.shouldMarkRegularTransactionsAsFailed({
smartTransaction: createSmartTransaction(
SmartTransactionStatuses.SUCCESS,
),
Expand All @@ -494,7 +494,7 @@ describe('src/utils.js', () => {
});

it('returns false when feature flag is disabled regardless of status', () => {
const result = utils.shouldMarkRegularTransactionAsFailed({
const result = utils.shouldMarkRegularTransactionsAsFailed({
smartTransaction: createSmartTransaction(
SmartTransactionStatuses.CANCELLED,
),
Expand All @@ -509,7 +509,7 @@ describe('src/utils.js', () => {
...createSmartTransaction(SmartTransactionStatuses.CANCELLED),
transactionId: undefined,
};
const result = utils.shouldMarkRegularTransactionAsFailed({
const result = utils.shouldMarkRegularTransactionsAsFailed({
smartTransaction,
clientId: ClientId.Extension,
getFeatureFlags: mockGetFeatureFlags(true),
Expand All @@ -518,7 +518,7 @@ describe('src/utils.js', () => {
});

it('returns true for mobile client when mobile feature flag is enabled', () => {
const result = utils.shouldMarkRegularTransactionAsFailed({
const result = utils.shouldMarkRegularTransactionsAsFailed({
smartTransaction: createSmartTransaction(
SmartTransactionStatuses.CANCELLED,
),
Expand All @@ -529,7 +529,7 @@ describe('src/utils.js', () => {
});
});

describe('markRegularTransactionAsFailed', () => {
describe('markRegularTransactionsAsFailed', () => {
const createSmartTransaction = (status: SmartTransactionStatuses) => ({
uuid: 'test-uuid',
status,
Expand Down Expand Up @@ -561,7 +561,7 @@ describe('src/utils.js', () => {
it('updates transaction with failed status and error message', () => {
const updateTransactionMock = jest.fn();

utils.markRegularTransactionAsFailed({
utils.markRegularTransactionsAsFailed({
smartTransaction: createSmartTransaction(
SmartTransactionStatuses.CANCELLED,
),
Expand All @@ -587,7 +587,7 @@ describe('src/utils.js', () => {
const getRegularTransactionsMock = jest.fn(() => []);

expect(() =>
utils.markRegularTransactionAsFailed({
utils.markRegularTransactionsAsFailed({
smartTransaction: createSmartTransaction(
SmartTransactionStatuses.CANCELLED,
),
Expand All @@ -610,7 +610,7 @@ describe('src/utils.js', () => {
},
};

utils.markRegularTransactionAsFailed({
utils.markRegularTransactionsAsFailed({
smartTransaction: createSmartTransaction(
SmartTransactionStatuses.CANCELLED,
),
Expand All @@ -620,5 +620,53 @@ describe('src/utils.js', () => {

expect(updateTransactionMock).not.toHaveBeenCalled();
});

it('marks multiple transactions as failed when txHashes match', () => {
const updateTransactionMock = jest.fn();
const transaction1: TransactionMeta = {
...mockTransaction,
id: '456',
hash: '0xhash1',
};
const transaction2: TransactionMeta = {
...mockTransaction,
id: '789',
hash: '0xhash2',
};
const smartTransaction = {
...createSmartTransaction(SmartTransactionStatuses.CANCELLED),
txHashes: ['0xhash1', '0xhash2'],
};

utils.markRegularTransactionsAsFailed({
smartTransaction,
getRegularTransactions: () => [transaction1, transaction2],
updateTransaction: updateTransactionMock,
});

expect(updateTransactionMock).toHaveBeenCalledTimes(2);
expect(updateTransactionMock).toHaveBeenCalledWith(
{
...transaction1,
status: TransactionStatus.failed,
error: {
name: 'SmartTransactionFailed',
message: 'Smart transaction failed with status: cancelled',
},
},
'Smart transaction status: cancelled',
);
expect(updateTransactionMock).toHaveBeenCalledWith(
{
...transaction2,
status: TransactionStatus.failed,
error: {
name: 'SmartTransactionFailed',
message: 'Smart transaction failed with status: cancelled',
},
},
'Smart transaction status: cancelled',
);
});
});
});
43 changes: 26 additions & 17 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@
: smartTransactionsFeatureFlags?.mobileReturnTxHashAsap;
};

export const shouldMarkRegularTransactionAsFailed = ({
export const shouldMarkRegularTransactionsAsFailed = ({
smartTransaction,
clientId,
getFeatureFlags,
Expand Down Expand Up @@ -271,7 +271,7 @@
return Boolean(returnTxHashAsapEnabled && transactionId);
};

export const markRegularTransactionAsFailed = ({
export const markRegularTransactionsAsFailed = ({
smartTransaction,
getRegularTransactions,
updateTransaction,
Expand All @@ -280,23 +280,32 @@
getRegularTransactions: TransactionControllerGetTransactionsAction['handler'];
updateTransaction: TransactionControllerUpdateTransactionAction['handler'];
}) => {
const { transactionId, status } = smartTransaction;
const originalTransaction = getRegularTransactions().find(
(transaction) => transaction.id === transactionId,
const { transactionId, status, txHashes } = smartTransaction;

const transactionsToFail = getRegularTransactions().filter(
(tx) => (tx.hash && txHashes?.includes(tx.hash)) || tx.id === transactionId,
);
if (!originalTransaction) {

if (!transactionsToFail.length) {
throw new Error('Cannot find regular transaction to mark it as failed');
}
if (originalTransaction.status === TransactionStatus.failed) {
return; // Already marked as failed.

for (const tx of transactionsToFail) {
if (tx.status === TransactionStatus.failed) {
continue; // Already marked as failed.
}
const updatedTransaction: TransactionMeta = {
...tx,
status: TransactionStatus.failed,
error: {
name: 'SmartTransactionFailed',
message: `Smart transaction failed with status: ${status}`,

Check warning on line 302 in src/utils.ts

View workflow job for this annotation

GitHub Actions / Build, lint, and test / Lint (18.x)

Invalid type "string | undefined" of template literal expression

Check warning on line 302 in src/utils.ts

View workflow job for this annotation

GitHub Actions / Build, lint, and test / Lint (20.x)

Invalid type "string | undefined" of template literal expression
},
};

updateTransaction(
updatedTransaction,
`Smart transaction status: ${status}`,

Check warning on line 308 in src/utils.ts

View workflow job for this annotation

GitHub Actions / Build, lint, and test / Lint (18.x)

Invalid type "string | undefined" of template literal expression

Check warning on line 308 in src/utils.ts

View workflow job for this annotation

GitHub Actions / Build, lint, and test / Lint (20.x)

Invalid type "string | undefined" of template literal expression
);
}
const updatedTransaction: TransactionMeta = {
...originalTransaction,
status: TransactionStatus.failed,
error: {
name: 'SmartTransactionFailed',
message: `Smart transaction failed with status: ${status}`,
},
};
updateTransaction(updatedTransaction, `Smart transaction status: ${status}`);
};
Loading