Skip to content

Commit f23ad0b

Browse files
authored
Add updateEditableParams in Transaction Controller (#2056)
## Explanation This PR adds an `updateEditableParams` method which allows the clients to update specific properties in the `TransactionParams` ### `@metamask/transaction-controller` - **ADDED**: `updateEditableParams` method to allow clients to update specific transaction parameters.
1 parent 77a7e38 commit f23ad0b

2 files changed

Lines changed: 133 additions & 0 deletions

File tree

packages/transaction-controller/src/TransactionController.test.ts

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3853,4 +3853,68 @@ describe('TransactionController', () => {
38533853
expect(updatedTransaction?.hash).toStrictEqual(transactionMeta.hash);
38543854
});
38553855
});
3856+
3857+
describe('updateEditableParams', () => {
3858+
const transactionId = '1';
3859+
const params = {
3860+
data: '0x0',
3861+
from: ACCOUNT_2_MOCK,
3862+
gas: '0x0',
3863+
gasPrice: '0x50fd51da',
3864+
to: ACCOUNT_MOCK,
3865+
value: '0x0',
3866+
};
3867+
3868+
const baseTransaction = {
3869+
id: transactionId,
3870+
chainId: toHex(5),
3871+
status: TransactionStatus.unapproved as const,
3872+
time: 123456789,
3873+
txParams: {
3874+
data: 'originalData',
3875+
gas: '50000',
3876+
gasPrice: '1000000000',
3877+
from: ACCOUNT_MOCK,
3878+
to: ACCOUNT_2_MOCK,
3879+
value: '5000000000000000000',
3880+
},
3881+
};
3882+
const transactionMeta: TransactionMeta = {
3883+
...baseTransaction,
3884+
history: [{ ...baseTransaction }],
3885+
};
3886+
3887+
it('updates editable params and returns updated transaction metadata', async () => {
3888+
const controller = newController();
3889+
controller.state.transactions.push(transactionMeta);
3890+
3891+
const updatedTransaction = await controller.updateEditableParams(
3892+
transactionId,
3893+
params,
3894+
);
3895+
3896+
expect(updatedTransaction?.txParams).toStrictEqual(params);
3897+
});
3898+
3899+
it('throws an error if no transaction metadata is found', async () => {
3900+
const controller = newController();
3901+
await expect(
3902+
controller.updateEditableParams(transactionId, params),
3903+
).rejects.toThrow(
3904+
'Cannot update editable params as no transaction metadata found',
3905+
);
3906+
});
3907+
3908+
it('throws an error if the transaction is not unapproved', async () => {
3909+
const controller = newController();
3910+
controller.state.transactions.push({
3911+
...transactionMeta,
3912+
status: TransactionStatus.submitted as const,
3913+
});
3914+
await expect(controller.updateEditableParams(transactionId, params))
3915+
.rejects
3916+
.toThrow(`TransactionsController: Can only call updateEditableParams on an unapproved transaction.
3917+
Current tx status: ${TransactionStatus.submitted}`);
3918+
});
3919+
});
38563920
});

packages/transaction-controller/src/TransactionController.ts

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1377,6 +1377,75 @@ export class TransactionController extends BaseController<
13771377
return this.nonceTracker.getNonceLock(address);
13781378
}
13791379

1380+
/**
1381+
* Updates the editable parameters of a transaction.
1382+
*
1383+
* @param txId - The ID of the transaction to update.
1384+
* @param params - The editable parameters to update.
1385+
* @param params.data - Data to pass with the transaction.
1386+
* @param params.gas - Maximum number of units of gas to use for the transaction.
1387+
* @param params.gasPrice - Price per gas for legacy transactions.
1388+
* @param params.from - Address to send the transaction from.
1389+
* @param params.to - Address to send the transaction to.
1390+
* @param params.value - Value associated with the transaction.
1391+
* @returns The updated transaction metadata.
1392+
*/
1393+
async updateEditableParams(
1394+
txId: string,
1395+
{
1396+
data,
1397+
gas,
1398+
gasPrice,
1399+
from,
1400+
to,
1401+
value,
1402+
}: {
1403+
data?: string;
1404+
gas?: string;
1405+
gasPrice?: string;
1406+
from?: string;
1407+
to?: string;
1408+
value?: string;
1409+
},
1410+
) {
1411+
const transactionMeta = this.getTransaction(txId);
1412+
if (!transactionMeta) {
1413+
throw new Error(
1414+
`Cannot update editable params as no transaction metadata found`,
1415+
);
1416+
}
1417+
1418+
validateIfTransactionUnapproved(transactionMeta, 'updateEditableParams');
1419+
1420+
const editableParams = {
1421+
txParams: {
1422+
data,
1423+
from,
1424+
to,
1425+
value,
1426+
gas,
1427+
gasPrice,
1428+
},
1429+
} as Partial<TransactionMeta>;
1430+
1431+
editableParams.txParams = pickBy(
1432+
editableParams.txParams,
1433+
) as TransactionParams;
1434+
1435+
const updatedTransaction = merge(transactionMeta, editableParams);
1436+
const { type } = await determineTransactionType(
1437+
updatedTransaction.txParams,
1438+
this.ethQuery,
1439+
);
1440+
updatedTransaction.type = type;
1441+
1442+
this.updateTransaction(
1443+
updatedTransaction,
1444+
`Update Editable Params for ${txId}`,
1445+
);
1446+
return this.getTransaction(txId);
1447+
}
1448+
13801449
/**
13811450
* Signs and returns the raw transaction data for provided transaction params list.
13821451
*

0 commit comments

Comments
 (0)