@metamask/transaction-controller 4.0.1 → 6.0.0
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/CHANGELOG.md +38 -2
- package/dist/TransactionController.d.ts +34 -8
- package/dist/TransactionController.d.ts.map +1 -0
- package/dist/TransactionController.js +98 -28
- package/dist/TransactionController.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/mocks/txsMock.d.ts +1 -0
- package/dist/mocks/txsMock.d.ts.map +1 -0
- package/dist/mocks/txsMock.js +9 -8
- package/dist/mocks/txsMock.js.map +1 -1
- package/dist/utils.d.ts +13 -1
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +30 -1
- package/dist/utils.js.map +1 -1
- package/package.json +19 -10
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,40 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [6.0.0]
|
|
10
|
+
### Added
|
|
11
|
+
- Update transaction controller to automatically initiate, finalize, and cancel approval requests as transactions move through states ([#1241](https://github.com/MetaMask/core/pull/1241))
|
|
12
|
+
- The `ApprovalController:addRequest` action will be called when a new transaction is initiated
|
|
13
|
+
- The `ApprovalController:rejectRequest` action will be called if a transaction fails
|
|
14
|
+
- The `ApprovalController:acceptRequest` action will be called when a transaction is approved
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
- **BREAKING:** Bump to Node 16 ([#1262](https://github.com/MetaMask/core/pull/1262))
|
|
18
|
+
- **BREAKING:** Update `@metamask/network-controller` dependency and peer dependency ([#1367](https://github.com/MetaMask/core/pull/1367))
|
|
19
|
+
- This affects the `getNetworkState` and `onNetworkStateChange` constructor parameters
|
|
20
|
+
- **BREAKING:** Change format of chain ID in state to `Hex` ([#1367](https://github.com/MetaMask/core/pull/1367))
|
|
21
|
+
- The `chainId` property of the `Transaction` type has been changed from `number` to `Hex`
|
|
22
|
+
- The `chainId` property of the `TransactionMeta` type has been changed from a decimal `string` to `Hex`, and the `transaction` property has been updated along with the `Transaction` type (as described above).
|
|
23
|
+
- The state property `transactions` is an array of `TransactionMeta` objects, so it has changed according to the description above.
|
|
24
|
+
- This requires a state migration: each entry should have the `chainId` property converted from a decimal `string` to `Hex`, and the `transaction.chainId` property changed from `number` to `Hex`.
|
|
25
|
+
- The `addTransaction` and `estimateGas` methods now expect the first parameter (`transaction`) to use type `Hex` for the `chainId` property.
|
|
26
|
+
- The `updateTransaction` method now expects the `transactionMeta` parameter to use type `Hex` for the `chainId` property (and for the nested `transaction.chainId` property)
|
|
27
|
+
- **BREAKING:** Add `messenger` as required constructor parameter ([#1241](https://github.com/MetaMask/core/pull/1241))
|
|
28
|
+
- **BREAKING:** Add `@metamask/approval-controller` as a dependency and peer dependency ([#1241](https://github.com/MetaMask/core/pull/1241), [#1393](https://github.com/MetaMask/core/pull/1393))
|
|
29
|
+
- Add `@metamask/utils` dependency ([#1367](https://github.com/MetaMask/core/pull/1367))
|
|
30
|
+
|
|
31
|
+
### Fixed
|
|
32
|
+
- Fix inaccurate hard-coded `chainId` on incoming token transactions ([#1366](https://github.com/MetaMask/core/pull/1366))
|
|
33
|
+
|
|
34
|
+
## [5.0.0]
|
|
35
|
+
### Changed
|
|
36
|
+
- **BREAKING**: peerDeps: @metamask/network-controller@6.0.0->8.0.0 ([#1196](https://github.com/MetaMask/core/pull/1196))
|
|
37
|
+
- deps: eth-rpc-errors@4.0.0->4.0.2 ([#1215](https://github.com/MetaMask/core/pull/1215))
|
|
38
|
+
- Add nonce tracker to transactions controller ([#1147](https://github.com/MetaMask/core/pull/1147))
|
|
39
|
+
- Previously this controller would get the next nonce by calling `eth_getTransactionCount` with a block reference of `pending`. The next nonce would then be returned from our middleware (within `web3-provider-engine`).
|
|
40
|
+
- Instead we're now using the nonce tracker to get the next nonce, dropping our reliance on this `eth_getTransactionCount` middleware. This will let us drop that middleware in a future update without impacting the transaction controller.
|
|
41
|
+
- This should result in no functional changes, except that the nonce middleware is no longer required.
|
|
42
|
+
|
|
9
43
|
## [4.0.1]
|
|
10
44
|
### Changed
|
|
11
45
|
- Use `NetworkType` enum for chain configuration ([#1132](https://github.com/MetaMask/core/pull/1132))
|
|
@@ -23,7 +57,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
23
57
|
### Changed
|
|
24
58
|
- **BREAKING**: Drop Etherscan API support for Ropsten, Rinkeby, and Kovan ([#1041](https://github.com/MetaMask/controllers/pull/1041))
|
|
25
59
|
- Rename this repository to `core` ([#1031](https://github.com/MetaMask/controllers/pull/1031))
|
|
26
|
-
- Update `@metamask/controller-utils` package ([#1041](https://github.com/MetaMask/controllers/pull/1041))
|
|
60
|
+
- Update `@metamask/controller-utils` package ([#1041](https://github.com/MetaMask/controllers/pull/1041))
|
|
27
61
|
|
|
28
62
|
## [2.0.0]
|
|
29
63
|
### Changed
|
|
@@ -39,7 +73,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
39
73
|
|
|
40
74
|
All changes listed after this point were applied to this package following the monorepo conversion.
|
|
41
75
|
|
|
42
|
-
[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/transaction-controller@
|
|
76
|
+
[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/transaction-controller@6.0.0...HEAD
|
|
77
|
+
[6.0.0]: https://github.com/MetaMask/core/compare/@metamask/transaction-controller@5.0.0...@metamask/transaction-controller@6.0.0
|
|
78
|
+
[5.0.0]: https://github.com/MetaMask/core/compare/@metamask/transaction-controller@4.0.1...@metamask/transaction-controller@5.0.0
|
|
43
79
|
[4.0.1]: https://github.com/MetaMask/core/compare/@metamask/transaction-controller@4.0.0...@metamask/transaction-controller@4.0.1
|
|
44
80
|
[4.0.0]: https://github.com/MetaMask/core/compare/@metamask/transaction-controller@3.0.0...@metamask/transaction-controller@4.0.0
|
|
45
81
|
[3.0.0]: https://github.com/MetaMask/core/compare/@metamask/transaction-controller@2.0.0...@metamask/transaction-controller@3.0.0
|
|
@@ -2,8 +2,10 @@
|
|
|
2
2
|
import { EventEmitter } from 'events';
|
|
3
3
|
import Common from '@ethereumjs/common';
|
|
4
4
|
import { TypedTransaction } from '@ethereumjs/tx';
|
|
5
|
-
import {
|
|
6
|
-
import
|
|
5
|
+
import type { Hex } from '@metamask/utils';
|
|
6
|
+
import { BaseController, BaseConfig, BaseState, RestrictedControllerMessenger } from '@metamask/base-controller';
|
|
7
|
+
import type { NetworkState, ProviderProxy, BlockTrackerProxy } from '@metamask/network-controller';
|
|
8
|
+
import { AcceptRequest as AcceptApprovalRequest, AddApprovalRequest, RejectRequest as RejectApprovalRequest } from '@metamask/approval-controller';
|
|
7
9
|
/**
|
|
8
10
|
* @type Result
|
|
9
11
|
* @property result - Promise resolving to a new transaction hash
|
|
@@ -37,7 +39,7 @@ export interface FetchAllOptions {
|
|
|
37
39
|
* @property value - Value associated with this transaction
|
|
38
40
|
*/
|
|
39
41
|
export interface Transaction {
|
|
40
|
-
chainId?:
|
|
42
|
+
chainId?: Hex;
|
|
41
43
|
data?: string;
|
|
42
44
|
from: string;
|
|
43
45
|
gas?: string;
|
|
@@ -90,7 +92,7 @@ declare type TransactionMetaBase = {
|
|
|
90
92
|
};
|
|
91
93
|
id: string;
|
|
92
94
|
networkID?: string;
|
|
93
|
-
chainId?:
|
|
95
|
+
chainId?: Hex;
|
|
94
96
|
origin?: string;
|
|
95
97
|
rawTransaction?: string;
|
|
96
98
|
time: number;
|
|
@@ -212,15 +214,30 @@ export declare const CANCEL_RATE = 1.5;
|
|
|
212
214
|
* Multiplier used to determine a transaction's increased gas fee during speed up
|
|
213
215
|
*/
|
|
214
216
|
export declare const SPEED_UP_RATE = 1.1;
|
|
217
|
+
/**
|
|
218
|
+
* The name of the {@link TransactionController}.
|
|
219
|
+
*/
|
|
220
|
+
declare const controllerName = "TransactionController";
|
|
221
|
+
/**
|
|
222
|
+
* The external actions available to the {@link TransactionController}.
|
|
223
|
+
*/
|
|
224
|
+
declare type AllowedActions = AddApprovalRequest | AcceptApprovalRequest | RejectApprovalRequest;
|
|
225
|
+
/**
|
|
226
|
+
* The messenger of the {@link TransactionController}.
|
|
227
|
+
*/
|
|
228
|
+
export declare type TransactionControllerMessenger = RestrictedControllerMessenger<typeof controllerName, AllowedActions, never, AllowedActions['type'], never>;
|
|
215
229
|
/**
|
|
216
230
|
* Controller responsible for submitting and managing transactions.
|
|
217
231
|
*/
|
|
218
232
|
export declare class TransactionController extends BaseController<TransactionConfig, TransactionState> {
|
|
219
233
|
private ethQuery;
|
|
234
|
+
private nonceTracker;
|
|
220
235
|
private registry;
|
|
236
|
+
private provider;
|
|
221
237
|
private handle?;
|
|
222
238
|
private mutex;
|
|
223
239
|
private getNetworkState;
|
|
240
|
+
private messagingSystem;
|
|
224
241
|
private failTransaction;
|
|
225
242
|
private registryLookup;
|
|
226
243
|
/**
|
|
@@ -252,14 +269,18 @@ export declare class TransactionController extends BaseController<TransactionCon
|
|
|
252
269
|
* @param options - The controller options.
|
|
253
270
|
* @param options.getNetworkState - Gets the state of the network controller.
|
|
254
271
|
* @param options.onNetworkStateChange - Allows subscribing to network controller state changes.
|
|
255
|
-
* @param options.
|
|
272
|
+
* @param options.provider - The provider used to create the underlying EthQuery instance.
|
|
273
|
+
* @param options.blockTracker - The block tracker used to poll for new blocks data.
|
|
274
|
+
* @param options.messenger - The controller messenger.
|
|
256
275
|
* @param config - Initial options used to configure this controller.
|
|
257
276
|
* @param state - Initial state to set on this controller.
|
|
258
277
|
*/
|
|
259
|
-
constructor({ getNetworkState, onNetworkStateChange,
|
|
278
|
+
constructor({ getNetworkState, onNetworkStateChange, provider, blockTracker, messenger, }: {
|
|
260
279
|
getNetworkState: () => NetworkState;
|
|
261
280
|
onNetworkStateChange: (listener: (state: NetworkState) => void) => void;
|
|
262
|
-
|
|
281
|
+
provider: ProviderProxy;
|
|
282
|
+
blockTracker: BlockTrackerProxy;
|
|
283
|
+
messenger: TransactionControllerMessenger;
|
|
263
284
|
}, config?: Partial<TransactionConfig>, state?: Partial<TransactionState>);
|
|
264
285
|
/**
|
|
265
286
|
* Starts a new polling interval.
|
|
@@ -317,7 +338,7 @@ export declare class TransactionController extends BaseController<TransactionCon
|
|
|
317
338
|
* and emitting a `<tx.id>:finished` hub event.
|
|
318
339
|
*
|
|
319
340
|
* @param transactionID - The ID of the transaction to cancel.
|
|
320
|
-
* @param gasValues - The gas values to use for the cancellation
|
|
341
|
+
* @param gasValues - The gas values to use for the cancellation transaction.
|
|
321
342
|
*/
|
|
322
343
|
stopTransaction(transactionID: string, gasValues?: GasPriceValue | FeeMarketEIP1559Values): Promise<void>;
|
|
323
344
|
/**
|
|
@@ -462,5 +483,10 @@ export declare class TransactionController extends BaseController<TransactionCon
|
|
|
462
483
|
* @returns Whether the gas data is outdated.
|
|
463
484
|
*/
|
|
464
485
|
private isGasDataOutdated;
|
|
486
|
+
private requestApproval;
|
|
487
|
+
private acceptApproval;
|
|
488
|
+
private rejectApproval;
|
|
489
|
+
private getApprovalId;
|
|
465
490
|
}
|
|
466
491
|
export default TransactionController;
|
|
492
|
+
//# sourceMappingURL=TransactionController.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TransactionController.d.ts","sourceRoot":"","sources":["../src/TransactionController.ts"],"names":[],"mappings":"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"}
|
|
@@ -24,6 +24,7 @@ const uuid_1 = require("uuid");
|
|
|
24
24
|
const async_mutex_1 = require("async-mutex");
|
|
25
25
|
const base_controller_1 = require("@metamask/base-controller");
|
|
26
26
|
const controller_utils_1 = require("@metamask/controller-utils");
|
|
27
|
+
const nonce_tracker_1 = __importDefault(require("nonce-tracker"));
|
|
27
28
|
const utils_1 = require("./utils");
|
|
28
29
|
const HARDFORK = 'london';
|
|
29
30
|
/**
|
|
@@ -59,6 +60,10 @@ exports.CANCEL_RATE = 1.5;
|
|
|
59
60
|
* Multiplier used to determine a transaction's increased gas fee during speed up
|
|
60
61
|
*/
|
|
61
62
|
exports.SPEED_UP_RATE = 1.1;
|
|
63
|
+
/**
|
|
64
|
+
* The name of the {@link TransactionController}.
|
|
65
|
+
*/
|
|
66
|
+
const controllerName = 'TransactionController';
|
|
62
67
|
/**
|
|
63
68
|
* Controller responsible for submitting and managing transactions.
|
|
64
69
|
*/
|
|
@@ -69,11 +74,13 @@ class TransactionController extends base_controller_1.BaseController {
|
|
|
69
74
|
* @param options - The controller options.
|
|
70
75
|
* @param options.getNetworkState - Gets the state of the network controller.
|
|
71
76
|
* @param options.onNetworkStateChange - Allows subscribing to network controller state changes.
|
|
72
|
-
* @param options.
|
|
77
|
+
* @param options.provider - The provider used to create the underlying EthQuery instance.
|
|
78
|
+
* @param options.blockTracker - The block tracker used to poll for new blocks data.
|
|
79
|
+
* @param options.messenger - The controller messenger.
|
|
73
80
|
* @param config - Initial options used to configure this controller.
|
|
74
81
|
* @param state - Initial state to set on this controller.
|
|
75
82
|
*/
|
|
76
|
-
constructor({ getNetworkState, onNetworkStateChange,
|
|
83
|
+
constructor({ getNetworkState, onNetworkStateChange, provider, blockTracker, messenger, }, config, state) {
|
|
77
84
|
super(config, state);
|
|
78
85
|
this.mutex = new async_mutex_1.Mutex();
|
|
79
86
|
this.normalizeTokenTx = (txMeta, currentNetworkID, currentChainId) => {
|
|
@@ -87,7 +94,7 @@ class TransactionController extends base_controller_1.BaseController {
|
|
|
87
94
|
status: TransactionStatus.confirmed,
|
|
88
95
|
time,
|
|
89
96
|
transaction: {
|
|
90
|
-
chainId:
|
|
97
|
+
chainId: currentChainId,
|
|
91
98
|
from,
|
|
92
99
|
gas,
|
|
93
100
|
gasPrice,
|
|
@@ -121,14 +128,20 @@ class TransactionController extends base_controller_1.BaseController {
|
|
|
121
128
|
transactions: [],
|
|
122
129
|
};
|
|
123
130
|
this.initialize();
|
|
124
|
-
|
|
131
|
+
this.provider = provider;
|
|
132
|
+
this.messagingSystem = messenger;
|
|
125
133
|
this.getNetworkState = getNetworkState;
|
|
126
134
|
this.ethQuery = new eth_query_1.default(provider);
|
|
127
135
|
this.registry = new eth_method_registry_1.default({ provider });
|
|
136
|
+
this.nonceTracker = new nonce_tracker_1.default({
|
|
137
|
+
provider,
|
|
138
|
+
blockTracker,
|
|
139
|
+
getPendingTransactions: (address) => (0, utils_1.getAndFormatTransactionsForNonceTracker)(address, TransactionStatus.submitted, this.state.transactions),
|
|
140
|
+
getConfirmedTransactions: (address) => (0, utils_1.getAndFormatTransactionsForNonceTracker)(address, TransactionStatus.confirmed, this.state.transactions),
|
|
141
|
+
});
|
|
128
142
|
onNetworkStateChange(() => {
|
|
129
|
-
|
|
130
|
-
this.
|
|
131
|
-
this.registry = new eth_method_registry_1.default({ provider: newProvider });
|
|
143
|
+
this.ethQuery = new eth_query_1.default(this.provider);
|
|
144
|
+
this.registry = new eth_method_registry_1.default({ provider: this.provider });
|
|
132
145
|
});
|
|
133
146
|
this.poll();
|
|
134
147
|
}
|
|
@@ -234,13 +247,13 @@ class TransactionController extends base_controller_1.BaseController {
|
|
|
234
247
|
*/
|
|
235
248
|
addTransaction(transaction, origin, deviceConfirmedOn) {
|
|
236
249
|
return __awaiter(this, void 0, void 0, function* () {
|
|
237
|
-
const { providerConfig,
|
|
250
|
+
const { providerConfig, networkId } = this.getNetworkState();
|
|
238
251
|
const { transactions } = this.state;
|
|
239
252
|
transaction = (0, utils_1.normalizeTransaction)(transaction);
|
|
240
253
|
(0, utils_1.validateTransaction)(transaction);
|
|
241
254
|
const transactionMeta = {
|
|
242
255
|
id: (0, uuid_1.v1)(),
|
|
243
|
-
networkID:
|
|
256
|
+
networkID: networkId !== null && networkId !== void 0 ? networkId : undefined,
|
|
244
257
|
chainId: providerConfig.chainId,
|
|
245
258
|
origin,
|
|
246
259
|
status: TransactionStatus.unapproved,
|
|
@@ -278,6 +291,7 @@ class TransactionController extends base_controller_1.BaseController {
|
|
|
278
291
|
transactions.push(transactionMeta);
|
|
279
292
|
this.update({ transactions: this.trimTransactionsForState(transactions) });
|
|
280
293
|
this.hub.emit(`unapprovedTransaction`, transactionMeta);
|
|
294
|
+
this.requestApproval(transactionMeta);
|
|
281
295
|
return { result, transactionMeta };
|
|
282
296
|
});
|
|
283
297
|
}
|
|
@@ -297,14 +311,14 @@ class TransactionController extends base_controller_1.BaseController {
|
|
|
297
311
|
* @returns {Common} common configuration object
|
|
298
312
|
*/
|
|
299
313
|
getCommonConfiguration() {
|
|
300
|
-
const {
|
|
314
|
+
const { networkId, providerConfig: { type: chain, chainId, nickname: name }, } = this.getNetworkState();
|
|
301
315
|
if (chain !== controller_utils_1.RPC) {
|
|
302
316
|
return new common_1.default({ chain, hardfork: HARDFORK });
|
|
303
317
|
}
|
|
304
318
|
const customChainParams = {
|
|
305
319
|
name,
|
|
306
|
-
chainId: parseInt(chainId,
|
|
307
|
-
networkId: parseInt(networkId, undefined),
|
|
320
|
+
chainId: parseInt(chainId, 16),
|
|
321
|
+
networkId: networkId === null ? NaN : parseInt(networkId, undefined),
|
|
308
322
|
};
|
|
309
323
|
return common_1.default.forCustomChain(controller_utils_1.NetworkType.mainnet, customChainParams, HARDFORK);
|
|
310
324
|
}
|
|
@@ -321,30 +335,36 @@ class TransactionController extends base_controller_1.BaseController {
|
|
|
321
335
|
const { transactions } = this.state;
|
|
322
336
|
const releaseLock = yield this.mutex.acquire();
|
|
323
337
|
const { providerConfig } = this.getNetworkState();
|
|
324
|
-
const { chainId
|
|
338
|
+
const { chainId } = providerConfig;
|
|
325
339
|
const index = transactions.findIndex(({ id }) => transactionID === id);
|
|
326
340
|
const transactionMeta = transactions[index];
|
|
327
|
-
const { nonce } = transactionMeta
|
|
341
|
+
const { transaction: { nonce, from }, } = transactionMeta;
|
|
342
|
+
let nonceLock;
|
|
328
343
|
try {
|
|
329
|
-
const { from } = transactionMeta.transaction;
|
|
330
344
|
if (!this.sign) {
|
|
331
345
|
releaseLock();
|
|
332
346
|
this.failTransaction(transactionMeta, new Error('No sign method defined.'));
|
|
347
|
+
this.rejectApproval(transactionMeta);
|
|
333
348
|
return;
|
|
334
349
|
}
|
|
335
|
-
else if (!
|
|
350
|
+
else if (!chainId) {
|
|
336
351
|
releaseLock();
|
|
337
352
|
this.failTransaction(transactionMeta, new Error('No chainId defined.'));
|
|
353
|
+
this.rejectApproval(transactionMeta);
|
|
338
354
|
return;
|
|
339
355
|
}
|
|
340
|
-
const chainId = parseInt(currentChainId, undefined);
|
|
341
356
|
const { approved: status } = TransactionStatus;
|
|
342
|
-
|
|
343
|
-
|
|
357
|
+
let nonceToUse = nonce;
|
|
358
|
+
// if a nonce already exists on the transactionMeta it means this is a speedup or cancel transaction
|
|
359
|
+
// so we want to reuse that nonce and hope that it beats the previous attempt to chain. Otherwise use a new locked nonce
|
|
360
|
+
if (!nonceToUse) {
|
|
361
|
+
nonceLock = yield this.nonceTracker.getNonceLock(from);
|
|
362
|
+
nonceToUse = (0, ethereumjs_util_1.addHexPrefix)(nonceLock.nextNonce.toString(16));
|
|
363
|
+
}
|
|
344
364
|
transactionMeta.status = status;
|
|
345
|
-
transactionMeta.transaction.nonce =
|
|
365
|
+
transactionMeta.transaction.nonce = nonceToUse;
|
|
346
366
|
transactionMeta.transaction.chainId = chainId;
|
|
347
|
-
const baseTxParams = Object.assign(Object.assign({}, transactionMeta.transaction), { gasLimit: transactionMeta.transaction.gas
|
|
367
|
+
const baseTxParams = Object.assign(Object.assign({}, transactionMeta.transaction), { gasLimit: transactionMeta.transaction.gas });
|
|
348
368
|
const isEIP1559 = (0, utils_1.isEIP1559Transaction)(transactionMeta.transaction);
|
|
349
369
|
const txParams = isEIP1559
|
|
350
370
|
? Object.assign(Object.assign({}, baseTxParams), { maxFeePerGas: transactionMeta.transaction.maxFeePerGas, maxPriorityFeePerGas: transactionMeta.transaction.maxPriorityFeePerGas, estimatedBaseFee: transactionMeta.transaction.estimatedBaseFee,
|
|
@@ -368,11 +388,17 @@ class TransactionController extends base_controller_1.BaseController {
|
|
|
368
388
|
transactionMeta.status = TransactionStatus.submitted;
|
|
369
389
|
this.updateTransaction(transactionMeta);
|
|
370
390
|
this.hub.emit(`${transactionMeta.id}:finished`, transactionMeta);
|
|
391
|
+
this.acceptApproval(transactionMeta);
|
|
371
392
|
}
|
|
372
393
|
catch (error) {
|
|
373
394
|
this.failTransaction(transactionMeta, error);
|
|
395
|
+
this.rejectApproval(transactionMeta);
|
|
374
396
|
}
|
|
375
397
|
finally {
|
|
398
|
+
// must set transaction to submitted/failed before releasing lock
|
|
399
|
+
if (nonceLock) {
|
|
400
|
+
nonceLock.releaseLock();
|
|
401
|
+
}
|
|
376
402
|
releaseLock();
|
|
377
403
|
}
|
|
378
404
|
});
|
|
@@ -392,13 +418,14 @@ class TransactionController extends base_controller_1.BaseController {
|
|
|
392
418
|
this.hub.emit(`${transactionMeta.id}:finished`, transactionMeta);
|
|
393
419
|
const transactions = this.state.transactions.filter(({ id }) => id !== transactionID);
|
|
394
420
|
this.update({ transactions: this.trimTransactionsForState(transactions) });
|
|
421
|
+
this.rejectApproval(transactionMeta);
|
|
395
422
|
}
|
|
396
423
|
/**
|
|
397
424
|
* Attempts to cancel a transaction based on its ID by setting its status to "rejected"
|
|
398
425
|
* and emitting a `<tx.id>:finished` hub event.
|
|
399
426
|
*
|
|
400
427
|
* @param transactionID - The ID of the transaction to cancel.
|
|
401
|
-
* @param gasValues - The gas values to use for the cancellation
|
|
428
|
+
* @param gasValues - The gas values to use for the cancellation transaction.
|
|
402
429
|
*/
|
|
403
430
|
stopTransaction(transactionID, gasValues) {
|
|
404
431
|
var _a, _b;
|
|
@@ -458,6 +485,7 @@ class TransactionController extends base_controller_1.BaseController {
|
|
|
458
485
|
yield (0, controller_utils_1.query)(this.ethQuery, 'sendRawTransaction', [rawTransaction]);
|
|
459
486
|
transactionMeta.status = TransactionStatus.cancelled;
|
|
460
487
|
this.hub.emit(`${transactionMeta.id}:finished`, transactionMeta);
|
|
488
|
+
this.rejectApproval(transactionMeta);
|
|
461
489
|
});
|
|
462
490
|
}
|
|
463
491
|
/**
|
|
@@ -531,7 +559,8 @@ class TransactionController extends base_controller_1.BaseController {
|
|
|
531
559
|
const gasPrice = typeof providedGasPrice === 'undefined'
|
|
532
560
|
? yield (0, controller_utils_1.query)(this.ethQuery, 'gasPrice')
|
|
533
561
|
: providedGasPrice;
|
|
534
|
-
const {
|
|
562
|
+
const { providerConfig } = this.getNetworkState();
|
|
563
|
+
const isCustomNetwork = providerConfig.type === controller_utils_1.NetworkType.rpc;
|
|
535
564
|
// 1. If gas is already defined on the transaction, use it
|
|
536
565
|
if (typeof gas !== 'undefined') {
|
|
537
566
|
return { gas, gasPrice };
|
|
@@ -595,7 +624,7 @@ class TransactionController extends base_controller_1.BaseController {
|
|
|
595
624
|
queryTransactionStatuses() {
|
|
596
625
|
return __awaiter(this, void 0, void 0, function* () {
|
|
597
626
|
const { transactions } = this.state;
|
|
598
|
-
const { providerConfig,
|
|
627
|
+
const { providerConfig, networkId: currentNetworkID } = this.getNetworkState();
|
|
599
628
|
const { chainId: currentChainId } = providerConfig;
|
|
600
629
|
let gotUpdates = false;
|
|
601
630
|
yield (0, controller_utils_1.safelyExecute)(() => Promise.all(transactions.map((meta, index) => __awaiter(this, void 0, void 0, function* () {
|
|
@@ -644,7 +673,7 @@ class TransactionController extends base_controller_1.BaseController {
|
|
|
644
673
|
this.update({ transactions: [] });
|
|
645
674
|
return;
|
|
646
675
|
}
|
|
647
|
-
const { providerConfig,
|
|
676
|
+
const { providerConfig, networkId: currentNetworkID } = this.getNetworkState();
|
|
648
677
|
const { chainId: currentChainId } = providerConfig;
|
|
649
678
|
const newTransactions = this.state.transactions.filter(({ networkID, chainId }) => {
|
|
650
679
|
// Using fallback to networkID only when there is no chainId present. Should be removed when networkID is completely removed.
|
|
@@ -667,12 +696,13 @@ class TransactionController extends base_controller_1.BaseController {
|
|
|
667
696
|
*/
|
|
668
697
|
fetchAll(address, opt) {
|
|
669
698
|
return __awaiter(this, void 0, void 0, function* () {
|
|
670
|
-
const { providerConfig,
|
|
699
|
+
const { providerConfig, networkId: currentNetworkID } = this.getNetworkState();
|
|
671
700
|
const { chainId: currentChainId, type: networkType } = providerConfig;
|
|
672
701
|
const { transactions } = this.state;
|
|
673
702
|
const supportedNetworkIds = ['1', '5', '11155111'];
|
|
674
703
|
/* istanbul ignore next */
|
|
675
|
-
if (
|
|
704
|
+
if (currentNetworkID === null ||
|
|
705
|
+
supportedNetworkIds.indexOf(currentNetworkID) === -1) {
|
|
676
706
|
return undefined;
|
|
677
707
|
}
|
|
678
708
|
const [etherscanTxResponse, etherscanTokenResponse] = yield (0, utils_1.handleTransactionFetch)(networkType, address, this.config.txHistoryLimit, opt);
|
|
@@ -738,7 +768,7 @@ class TransactionController extends base_controller_1.BaseController {
|
|
|
738
768
|
const txsToKeep = transactions.reverse().filter((tx) => {
|
|
739
769
|
const { chainId, networkID, status, transaction, time } = tx;
|
|
740
770
|
if (transaction) {
|
|
741
|
-
const key = `${transaction.nonce}-${chainId
|
|
771
|
+
const key = `${transaction.nonce}-${chainId ? (0, controller_utils_1.convertHexToDecimal)(chainId) : networkID}-${new Date(time).toDateString()}`;
|
|
742
772
|
if (nonceNetworkSet.has(key)) {
|
|
743
773
|
return true;
|
|
744
774
|
}
|
|
@@ -921,6 +951,46 @@ class TransactionController extends base_controller_1.BaseController {
|
|
|
921
951
|
isGasDataOutdated(remoteGasUsed, localGasUsed) {
|
|
922
952
|
return remoteGasUsed !== localGasUsed;
|
|
923
953
|
}
|
|
954
|
+
requestApproval(txMeta, { shouldShowRequest } = { shouldShowRequest: true }) {
|
|
955
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
956
|
+
const id = this.getApprovalId(txMeta);
|
|
957
|
+
const { origin } = txMeta;
|
|
958
|
+
const type = controller_utils_1.ApprovalType.Transaction;
|
|
959
|
+
const requestData = { txId: txMeta.id };
|
|
960
|
+
try {
|
|
961
|
+
yield this.messagingSystem.call('ApprovalController:addRequest', {
|
|
962
|
+
id,
|
|
963
|
+
origin: origin || controller_utils_1.ORIGIN_METAMASK,
|
|
964
|
+
type,
|
|
965
|
+
requestData,
|
|
966
|
+
}, shouldShowRequest);
|
|
967
|
+
}
|
|
968
|
+
catch (error) {
|
|
969
|
+
console.info('Failed to request transaction approval', error);
|
|
970
|
+
}
|
|
971
|
+
});
|
|
972
|
+
}
|
|
973
|
+
acceptApproval(txMeta) {
|
|
974
|
+
const id = this.getApprovalId(txMeta);
|
|
975
|
+
try {
|
|
976
|
+
this.messagingSystem.call('ApprovalController:acceptRequest', id);
|
|
977
|
+
}
|
|
978
|
+
catch (error) {
|
|
979
|
+
console.info('Failed to accept transaction approval request', error);
|
|
980
|
+
}
|
|
981
|
+
}
|
|
982
|
+
rejectApproval(txMeta) {
|
|
983
|
+
const id = this.getApprovalId(txMeta);
|
|
984
|
+
try {
|
|
985
|
+
this.messagingSystem.call('ApprovalController:rejectRequest', id, new Error('Rejected'));
|
|
986
|
+
}
|
|
987
|
+
catch (error) {
|
|
988
|
+
console.info('Failed to reject transaction approval request', error);
|
|
989
|
+
}
|
|
990
|
+
}
|
|
991
|
+
getApprovalId(txMeta) {
|
|
992
|
+
return String(txMeta.id);
|
|
993
|
+
}
|
|
924
994
|
}
|
|
925
995
|
exports.TransactionController = TransactionController;
|
|
926
996
|
exports.default = TransactionController;
|