@metamask/smart-transactions-controller 7.0.0 → 8.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 +7 -1
- package/README.md +2 -2
- package/dist/SmartTransactionsController.d.ts +5 -2
- package/dist/SmartTransactionsController.js +24 -4
- package/dist/SmartTransactionsController.js.map +1 -1
- package/dist/types.d.ts +8 -1
- package/dist/types.js +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +4 -2
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [8.0.0]
|
|
10
|
+
### Changed
|
|
11
|
+
- **BREAKING:** The constructor now requires a `getTransactions` option, which can be used to get a list of existing transactions ([#301](https://github.com/MetaMask/smart-transactions-controller/pull/301))
|
|
12
|
+
- Ensure that a transaction does not get re-confirmed if it is already confirmed or submitted. MetaMask Swaps are confirmed from this controller, other transaction types are most of the time confirmed from the TransactionController. ([#301](https://github.com/MetaMask/smart-transactions-controller/pull/301))
|
|
13
|
+
|
|
9
14
|
## [7.0.0]
|
|
10
15
|
### Added
|
|
11
16
|
- **BREAKING:** Track fees and liveness for multiple chains by adding `feesByChainId` and `livenessByChainId` properties to SmartTransactionsControllerState ([#237](https://github.com/MetaMask/smart-transactions-controller/pull/237))
|
|
@@ -243,7 +248,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
243
248
|
- Add initial SmartTransactionsController ([#1](https://github.com/MetaMask/smart-transactions-controller/pull/1))
|
|
244
249
|
- Initial commit
|
|
245
250
|
|
|
246
|
-
[Unreleased]: https://github.com/MetaMask/smart-transactions-controller/compare/
|
|
251
|
+
[Unreleased]: https://github.com/MetaMask/smart-transactions-controller/compare/v8.0.0...HEAD
|
|
252
|
+
[8.0.0]: https://github.com/MetaMask/smart-transactions-controller/compare/v7.0.0...v8.0.0
|
|
247
253
|
[7.0.0]: https://github.com/MetaMask/smart-transactions-controller/compare/v6.2.2...v7.0.0
|
|
248
254
|
[6.2.2]: https://github.com/MetaMask/smart-transactions-controller/compare/v6.2.1...v6.2.2
|
|
249
255
|
[6.2.1]: https://github.com/MetaMask/smart-transactions-controller/compare/v6.2.0...v6.2.1
|
package/README.md
CHANGED
|
@@ -14,8 +14,8 @@ or
|
|
|
14
14
|
|
|
15
15
|
### Setup
|
|
16
16
|
|
|
17
|
-
- Install [Node.js](https://nodejs.org)
|
|
18
|
-
- If you are using [nvm](https://github.com/creationix/nvm#installation) (recommended) running `nvm use` will automatically choose the right node version for you.
|
|
17
|
+
- Install the current LTS version of [Node.js](https://nodejs.org)
|
|
18
|
+
- If you are using [nvm](https://github.com/creationix/nvm#installation) (recommended) running `nvm install` will install the latest suitable version and running `nvm use` will automatically choose the right node version for you.
|
|
19
19
|
- Install [Yarn v3](https://yarnpkg.com/getting-started/install)
|
|
20
20
|
- Run `yarn install` to install dependencies and run any required post-install scripts
|
|
21
21
|
|
|
@@ -4,8 +4,9 @@ import type { BaseConfig, BaseState } from '@metamask/base-controller';
|
|
|
4
4
|
import type { Provider } from '@metamask/eth-query';
|
|
5
5
|
import type { NetworkClientId, NetworkController, NetworkState } from '@metamask/network-controller';
|
|
6
6
|
import { StaticIntervalPollingControllerV1 } from '@metamask/polling-controller';
|
|
7
|
+
import type { TransactionMeta } from '@metamask/transaction-controller';
|
|
7
8
|
import EventEmitter from 'events';
|
|
8
|
-
import type { Fees, Hex, IndividualTxFees, SignedCanceledTransaction, SignedTransaction, SmartTransaction, SmartTransactionsStatus, UnsignedTransaction } from './types';
|
|
9
|
+
import type { Fees, Hex, IndividualTxFees, SignedCanceledTransaction, SignedTransaction, SmartTransaction, SmartTransactionsStatus, UnsignedTransaction, GetTransactionsOptions } from './types';
|
|
9
10
|
import { SmartTransactionStatuses } from './types';
|
|
10
11
|
export declare const DEFAULT_INTERVAL: number;
|
|
11
12
|
export declare type SmartTransactionsControllerConfig = BaseConfig & {
|
|
@@ -39,15 +40,17 @@ export default class SmartTransactionsController extends StaticIntervalPollingCo
|
|
|
39
40
|
private readonly getNonceLock;
|
|
40
41
|
private ethQuery;
|
|
41
42
|
confirmExternalTransaction: any;
|
|
43
|
+
getRegularTransactions: (options?: GetTransactionsOptions) => TransactionMeta[];
|
|
42
44
|
private readonly trackMetaMetricsEvent;
|
|
43
45
|
eventEmitter: EventEmitter;
|
|
44
46
|
private readonly getNetworkClientById;
|
|
45
47
|
private fetch;
|
|
46
|
-
constructor({ onNetworkStateChange, getNonceLock, provider, confirmExternalTransaction, trackMetaMetricsEvent, getNetworkClientById, }: {
|
|
48
|
+
constructor({ onNetworkStateChange, getNonceLock, provider, confirmExternalTransaction, getTransactions, trackMetaMetricsEvent, getNetworkClientById, }: {
|
|
47
49
|
onNetworkStateChange: (listener: (networkState: NetworkState) => void) => void;
|
|
48
50
|
getNonceLock: any;
|
|
49
51
|
provider: Provider;
|
|
50
52
|
confirmExternalTransaction: any;
|
|
53
|
+
getTransactions: (options?: GetTransactionsOptions) => TransactionMeta[];
|
|
51
54
|
trackMetaMetricsEvent: any;
|
|
52
55
|
getNetworkClientById: NetworkController['getNetworkClientById'];
|
|
53
56
|
}, config?: Partial<SmartTransactionsControllerConfig>, state?: Partial<SmartTransactionsControllerState>);
|
|
@@ -7,7 +7,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
7
7
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
8
8
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
9
9
|
};
|
|
10
|
-
var _SmartTransactionsController_instances, _SmartTransactionsController_updateSmartTransaction, _SmartTransactionsController_confirmSmartTransaction, _SmartTransactionsController_getChainId, _SmartTransactionsController_getEthQuery;
|
|
10
|
+
var _SmartTransactionsController_instances, _SmartTransactionsController_updateSmartTransaction, _SmartTransactionsController_doesTransactionNeedConfirmation, _SmartTransactionsController_confirmSmartTransaction, _SmartTransactionsController_getChainId, _SmartTransactionsController_getEthQuery;
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.DEFAULT_INTERVAL = void 0;
|
|
13
13
|
// eslint-disable-next-line import/no-nodejs-modules
|
|
@@ -15,6 +15,7 @@ const bytes_1 = require("@ethersproject/bytes");
|
|
|
15
15
|
const controller_utils_1 = require("@metamask/controller-utils");
|
|
16
16
|
const eth_query_1 = __importDefault(require("@metamask/eth-query"));
|
|
17
17
|
const polling_controller_1 = require("@metamask/polling-controller");
|
|
18
|
+
const transaction_controller_1 = require("@metamask/transaction-controller");
|
|
18
19
|
const bignumber_js_1 = require("bignumber.js");
|
|
19
20
|
// eslint-disable-next-line import/no-nodejs-modules
|
|
20
21
|
const events_1 = __importDefault(require("events"));
|
|
@@ -26,7 +27,7 @@ const SECOND = 1000;
|
|
|
26
27
|
exports.DEFAULT_INTERVAL = SECOND * 5;
|
|
27
28
|
const ETH_QUERY_ERROR_MSG = '`ethQuery` is not defined on SmartTransactionsController';
|
|
28
29
|
class SmartTransactionsController extends polling_controller_1.StaticIntervalPollingControllerV1 {
|
|
29
|
-
constructor({ onNetworkStateChange, getNonceLock, provider, confirmExternalTransaction, trackMetaMetricsEvent, getNetworkClientById, }, config, state) {
|
|
30
|
+
constructor({ onNetworkStateChange, getNonceLock, provider, confirmExternalTransaction, getTransactions, trackMetaMetricsEvent, getNetworkClientById, }, config, state) {
|
|
30
31
|
super(config, state);
|
|
31
32
|
_SmartTransactionsController_instances.add(this);
|
|
32
33
|
/**
|
|
@@ -70,6 +71,7 @@ class SmartTransactionsController extends polling_controller_1.StaticIntervalPol
|
|
|
70
71
|
this.getNonceLock = getNonceLock;
|
|
71
72
|
this.ethQuery = undefined;
|
|
72
73
|
this.confirmExternalTransaction = confirmExternalTransaction;
|
|
74
|
+
this.getRegularTransactions = getTransactions;
|
|
73
75
|
this.trackMetaMetricsEvent = trackMetaMetricsEvent;
|
|
74
76
|
this.getNetworkClientById = getNetworkClientById;
|
|
75
77
|
this.initializeSmartTransactionsForChainId();
|
|
@@ -439,6 +441,22 @@ _SmartTransactionsController_instances = new WeakSet(), _SmartTransactionsContro
|
|
|
439
441
|
});
|
|
440
442
|
}
|
|
441
443
|
this.eventEmitter.emit(`${smartTransaction.uuid}:smartTransaction`, smartTransaction);
|
|
444
|
+
}, _SmartTransactionsController_doesTransactionNeedConfirmation = function _SmartTransactionsController_doesTransactionNeedConfirmation(txHash) {
|
|
445
|
+
if (!txHash) {
|
|
446
|
+
return true;
|
|
447
|
+
}
|
|
448
|
+
const transactions = this.getRegularTransactions();
|
|
449
|
+
const foundTransaction = transactions === null || transactions === void 0 ? void 0 : transactions.find((tx) => {
|
|
450
|
+
var _a;
|
|
451
|
+
return ((_a = tx.hash) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === txHash.toLowerCase();
|
|
452
|
+
});
|
|
453
|
+
if (!foundTransaction) {
|
|
454
|
+
return true;
|
|
455
|
+
}
|
|
456
|
+
// If a found transaction is either confirmed or submitted, it doesn't need confirmation from the STX controller.
|
|
457
|
+
// When it's in the submitted state, the TransactionController checks its status and confirms it,
|
|
458
|
+
// so no need to confirm it again here.
|
|
459
|
+
return ![transaction_controller_1.TransactionStatus.confirmed, transaction_controller_1.TransactionStatus.submitted].includes(foundTransaction.status);
|
|
442
460
|
}, _SmartTransactionsController_confirmSmartTransaction = async function _SmartTransactionsController_confirmSmartTransaction(smartTransaction, { chainId = this.config.chainId, ethQuery = this.ethQuery, }) {
|
|
443
461
|
var _a;
|
|
444
462
|
if (ethQuery === undefined) {
|
|
@@ -456,7 +474,7 @@ _SmartTransactionsController_instances = new WeakSet(), _SmartTransactionsContro
|
|
|
456
474
|
const updatedTxParams = Object.assign(Object.assign({}, smartTransaction.txParams), { maxFeePerGas,
|
|
457
475
|
maxPriorityFeePerGas });
|
|
458
476
|
// call confirmExternalTransaction
|
|
459
|
-
const originalTxMeta = Object.assign(Object.assign({}, smartTransaction), { id: smartTransaction.uuid, status:
|
|
477
|
+
const originalTxMeta = Object.assign(Object.assign({}, smartTransaction), { id: smartTransaction.uuid, status: transaction_controller_1.TransactionStatus.confirmed, hash: txHash, txParams: updatedTxParams });
|
|
460
478
|
// create txMeta snapshot for history
|
|
461
479
|
const snapshot = (0, utils_1.snapshotFromTxMeta)(originalTxMeta);
|
|
462
480
|
// recover previous tx state obj
|
|
@@ -465,7 +483,9 @@ _SmartTransactionsController_instances = new WeakSet(), _SmartTransactionsContro
|
|
|
465
483
|
const entry = (0, utils_1.generateHistoryEntry)(previousState, snapshot, 'txStateManager: setting status to confirmed');
|
|
466
484
|
const txMeta = entry.length > 0
|
|
467
485
|
? Object.assign(Object.assign({}, originalTxMeta), { history: originalTxMeta.history.concat(entry) }) : originalTxMeta;
|
|
468
|
-
this.
|
|
486
|
+
if (__classPrivateFieldGet(this, _SmartTransactionsController_instances, "m", _SmartTransactionsController_doesTransactionNeedConfirmation).call(this, txHash)) {
|
|
487
|
+
this.confirmExternalTransaction(txMeta, transactionReceipt, baseFeePerGas);
|
|
488
|
+
}
|
|
469
489
|
this.trackMetaMetricsEvent({
|
|
470
490
|
event: constants_1.MetaMetricsEventName.StxConfirmed,
|
|
471
491
|
category: constants_1.MetaMetricsEventCategory.Transactions,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SmartTransactionsController.js","sourceRoot":"","sources":["../src/SmartTransactionsController.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,oDAAoD;AACpD,gDAA+C;AAE/C,iEAAkE;AAElE,oEAA2C;AAM3C,qEAAiF;AACjF,+CAAyC;AACzC,oDAAoD;AACpD,oDAAkC;AAClC,iEAAyC;AAEzC,2CAIqB;AAWrB,mCAA4D;AAC5D,mCAYiB;AAEjB,MAAM,MAAM,GAAG,IAAI,CAAC;AACP,QAAA,gBAAgB,GAAG,MAAM,GAAG,CAAC,CAAC;AAC3C,MAAM,mBAAmB,GACvB,0DAA0D,CAAC;AA0B7D,MAAqB,2BAA4B,SAAQ,sDAGxD;IAkCC,YACE,EACE,oBAAoB,EACpB,YAAY,EACZ,QAAQ,EACR,0BAA0B,EAC1B,qBAAqB,EACrB,oBAAoB,GAUrB,EACD,MAAmD,EACnD,KAAiD;QAEjD,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;;QAtDvB;;WAEG;QACM,SAAI,GAAG,6BAA6B,CAAC;QAqD5C,IAAI,CAAC,aAAa,GAAG;YACnB,QAAQ,EAAE,wBAAgB;YAC1B,OAAO,EAAE,qBAAS,CAAC,QAAQ;YAC3B,QAAQ,EAAE,SAAS;YACnB,iBAAiB,EAAE,CAAC,qBAAS,CAAC,QAAQ,EAAE,qBAAS,CAAC,MAAM,CAAC;SAC1D,CAAC;QAEF,IAAI,CAAC,YAAY,GAAG;YAClB,sBAAsB,EAAE;gBACtB,iBAAiB,EAAE,EAAE;gBACrB,SAAS,EAAE,SAAS;gBACpB,WAAW,EAAE,SAAS;gBACtB,IAAI,EAAE;oBACJ,cAAc,EAAE,SAAS;oBACzB,WAAW,EAAE,SAAS;iBACvB;gBACD,QAAQ,EAAE,IAAI;gBACd,iBAAiB,EAAE;oBACjB,CAAC,qBAAS,CAAC,QAAQ,CAAC,EAAE,IAAI;oBAC1B,CAAC,qBAAS,CAAC,MAAM,CAAC,EAAE,IAAI;iBACzB;gBACD,aAAa,EAAE;oBACb,CAAC,qBAAS,CAAC,QAAQ,CAAC,EAAE;wBACpB,cAAc,EAAE,SAAS;wBACzB,WAAW,EAAE,SAAS;qBACvB;oBACD,CAAC,qBAAS,CAAC,MAAM,CAAC,EAAE;wBAClB,cAAc,EAAE,SAAS;wBACzB,WAAW,EAAE,SAAS;qBACvB;iBACF;aACF;SACF,CAAC;QAEF,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC7C,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;QACjC,IAAI,CAAC,QAAQ,GAAG,SAAS,CAAC;QAC1B,IAAI,CAAC,0BAA0B,GAAG,0BAA0B,CAAC;QAC7D,IAAI,CAAC,qBAAqB,GAAG,qBAAqB,CAAC;QACnD,IAAI,CAAC,oBAAoB,GAAG,oBAAoB,CAAC;QAEjD,IAAI,CAAC,qCAAqC,EAAE,CAAC;QAE7C,oBAAoB,CAAC,CAAC,EAAE,cAAc,EAAE,WAAW,EAAE,EAAE,EAAE;YACvD,MAAM,EAAE,OAAO,EAAE,GAAG,WAAW,CAAC;YAChC,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;YAC5B,IAAI,CAAC,qCAAqC,EAAE,CAAC;YAC7C,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC3B,IAAI,CAAC,QAAQ,GAAG,IAAI,mBAAQ,CAAC,QAAQ,CAAC,CAAC;QACzC,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,SAAS,CAAC,CAAC,YAAiB,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC;QACpE,IAAI,CAAC,YAAY,GAAG,IAAI,gBAAY,EAAE,CAAC;IACzC,CAAC;IA3FD,0BAA0B;IAClB,KAAK,CAAC,KAAK,CAAC,OAAe,EAAE,OAAqB;QACxD,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC;QACjC,MAAM,YAAY,mCACb,OAAO,KACV,OAAO,kBACL,cAAc,EAAE,kBAAkB,IAC/B,CAAC,QAAQ,IAAI,EAAE,aAAa,EAAE,QAAQ,EAAE,CAAC,IAE/C,CAAC;QAEF,OAAO,IAAA,mBAAW,EAAC,OAAO,EAAE,YAAY,CAAC,CAAC;IAC5C,CAAC;IAiFD,KAAK,CAAC,YAAY,CAAC,eAAuB;QACxC,gFAAgF;QAChF,qFAAqF;QACrF,+FAA+F;QAC/F,wBAAwB;QACxB,MAAM,OAAO,GAAG,uBAAA,IAAI,uFAAY,MAAhB,IAAI,EAAa,EAAE,eAAe,EAAE,CAAC,CAAC;QACtD,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE;YACpD,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;SAC1B;QACD,OAAO,IAAI,CAAC,uBAAuB,CAAC,EAAE,eAAe,EAAE,CAAC,CAAC;IAC3D,CAAC;IAED,SAAS,CAAC,KAAU;QAClB,MAAM,EAAE,iBAAiB,EAAE,GAAG,KAAK,CAAC,sBAAsB,CAAC;QAC3D,MAAM,wBAAwB,GAAG,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACxE,MAAM,mBAAmB,GAAG,wBAAwB,aAAxB,wBAAwB,uBAAxB,wBAAwB,CAAE,MAAM,CAC1D,iCAAyB,CAC1B,CAAC;QACF,IAAI,CAAC,IAAI,CAAC,aAAa,IAAI,CAAA,mBAAmB,aAAnB,mBAAmB,uBAAnB,mBAAmB,CAAE,MAAM,IAAG,CAAC,EAAE;YAC1D,IAAI,CAAC,IAAI,EAAE,CAAC;SACb;aAAM,IAAI,IAAI,CAAC,aAAa,IAAI,CAAA,mBAAmB,aAAnB,mBAAmB,uBAAnB,mBAAmB,CAAE,MAAM,MAAK,CAAC,EAAE;YAClE,IAAI,CAAC,IAAI,EAAE,CAAC;SACb;IACH,CAAC;IAED,qCAAqC;;QACnC,IAAI,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE;YAC/D,MAAM,EAAE,sBAAsB,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC;YAC9C,IAAI,CAAC,MAAM,CAAC;gBACV,sBAAsB,kCACjB,sBAAsB,KACzB,iBAAiB,kCACZ,sBAAsB,CAAC,iBAAiB,KAC3C,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,EACnB,MAAA,sBAAsB,CAAC,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,mCAC7D,EAAE,MAEP;aACF,CAAC,CAAC;SACJ;IACH,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,QAAiB;QAC1B,MAAM,EAAE,OAAO,EAAE,iBAAiB,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC;QACnD,QAAQ,IAAI,IAAI,CAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;QACvD,IAAI,CAAC,aAAa,IAAI,aAAa,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QACxD,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE;YACxC,OAAO;SACR;QACD,MAAM,IAAA,gCAAa,EAAC,KAAK,IAAI,EAAE,CAAC,IAAI,CAAC,uBAAuB,EAAE,CAAC,CAAC;QAChE,IAAI,CAAC,aAAa,GAAG,WAAW,CAAC,GAAG,EAAE;YACpC,IAAA,gCAAa,EAAC,KAAK,IAAI,EAAE,CAAC,IAAI,CAAC,uBAAuB,EAAE,CAAC,CAAC;QAC5D,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC3B,CAAC;IAED,KAAK,CAAC,IAAI;QACR,IAAI,CAAC,aAAa,IAAI,aAAa,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QACxD,IAAI,CAAC,aAAa,GAAG,SAAS,CAAC;IACjC,CAAC;IAED,aAAa,CAAC,KAA0B;QACtC,IAAI,CAAC,MAAM,CAAC;YACV,sBAAsB,kCACjB,IAAI,CAAC,KAAK,CAAC,sBAAsB,KACpC,WAAW,EAAE,KAAK,GACnB;SACF,CAAC,CAAC;IACL,CAAC;IAED,oBAAoB,CAClB,gBAAkC,EAClC,oBAAuC;QAEvC,IAAI,CAAC,oBAAoB,EAAE;YACzB,OAAO,CAAC,2EAA2E;SACpF;QAED,IAAI,uBAAuB,GAAG,IAAA,mBAAS,EAAC,gBAAgB,CAAC,CAAC;QAC1D,uBAAuB,mCAClB,IAAA,mBAAS,EAAC,oBAAoB,CAAC,GAC/B,uBAAuB,CAC3B,CAAC;QAEF,IACE,CAAC,uBAAuB,CAAC,YAAY;YACrC,CAAC,uBAAuB,CAAC,MAAM,KAAK,oBAAoB,CAAC,MAAM;gBAC7D,oBAAoB,CAAC,YAAY,CAAC,EACpC;YACA,OAAO,CAAC,kDAAkD;SAC3D;QAED,MAAM,mBAAmB,GAAG;YAC1B,UAAU,EAAE,uBAAuB,CAAC,MAAM;YAC1C,iBAAiB,EAAE,uBAAuB,CAAC,iBAAiB;YAC5D,eAAe,EAAE,uBAAuB,CAAC,sBAAsB;YAC/D,eAAe,EAAE,IAAA,4BAAoB,EAAC,uBAAuB,CAAC,IAAI,CAAC;YACnE,WAAW,EAAE,IAAI;YACjB,mBAAmB,EAAE,IAAI;YACzB,eAAe,EAAE,IAAI;SACtB,CAAC;QAEF,IAAI,CAAC,qBAAqB,CAAC;YACzB,KAAK,EAAE,gCAAoB,CAAC,gBAAgB;YAC5C,QAAQ,EAAE,oCAAwB,CAAC,YAAY;YAC/C,mBAAmB;SACpB,CAAC,CAAC;IACL,CAAC;IAED,qBAAqB,CAAC,oBAA4B;QAChD,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC;QAChC,MAAM,EAAE,sBAAsB,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC;QAC9C,MAAM,EAAE,iBAAiB,EAAE,GAAG,sBAAsB,CAAC;QACrD,MAAM,wBAAwB,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAC;QAC5D,MAAM,YAAY,GAAG,wBAAwB,aAAxB,wBAAwB,uBAAxB,wBAAwB,CAAE,SAAS,CACtD,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,oBAAoB,CAC3C,CAAC;QACF,OAAO,YAAY,KAAK,CAAC,CAAC,IAAI,YAAY,KAAK,SAAS,CAAC;IAC3D,CAAC;IAED,sBAAsB,CACpB,gBAAkC,EAClC,EAAE,eAAe,KAA4C,EAAE;QAE/D,IAAI,EACF,QAAQ,EACR,MAAM,EAAE,EAAE,OAAO,EAAE,GACpB,GAAG,IAAI,CAAC;QACT,IAAI,eAAe,EAAE;YACnB,MAAM,aAAa,GAAG,IAAI,CAAC,oBAAoB,CAAC,eAAe,CAAC,CAAC;YACjE,OAAO,GAAG,aAAa,CAAC,aAAa,CAAC,OAAO,CAAC;YAC9C,QAAQ,GAAG,IAAI,mBAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;SACjD;QAED,uBAAA,IAAI,mGAAwB,MAA5B,IAAI,EAAyB,gBAAgB,EAAE;YAC7C,OAAO;YACP,QAAQ;SACT,CAAC,CAAC;IACL,CAAC;IAoGD,KAAK,CAAC,uBAAuB,CAAC,EAC5B,eAAe,MAGb,EAAE;QACJ,MAAM,EAAE,iBAAiB,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,sBAAsB,CAAC;QAChE,MAAM,OAAO,GAAG,uBAAA,IAAI,uFAAY,MAAhB,IAAI,EAAa,EAAE,eAAe,EAAE,CAAC,CAAC;QACtD,MAAM,2BAA2B,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAC;QAE/D,MAAM,oBAAoB,GAAa,2BAA2B;aAC/D,MAAM,CAAC,iCAAyB,CAAC;aACjC,GAAG,CAAC,CAAC,gBAAgB,EAAE,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC;QAEpD,IAAI,oBAAoB,CAAC,MAAM,GAAG,CAAC,EAAE;YACnC,IAAI,CAAC,4BAA4B,CAAC,oBAAoB,EAAE;gBACtD,eAAe;aAChB,CAAC,CAAC;SACJ;IACH,CAAC;IA+FD,sDAAsD;IACtD,KAAK,CAAC,4BAA4B,CAChC,KAAe,EACf,EAAE,eAAe,KAA4C,EAAE;QAE/D,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC;YACjC,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC;SACvB,CAAC,CAAC;QACH,MAAM,OAAO,GAAG,uBAAA,IAAI,uFAAY,MAAhB,IAAI,EAAa,EAAE,eAAe,EAAE,CAAC,CAAC;QACtD,MAAM,QAAQ,GAAG,uBAAA,IAAI,wFAAa,MAAjB,IAAI,EAAc,EAAE,eAAe,EAAE,CAAC,CAAC;QACxD,MAAM,GAAG,GAAG,GAAG,IAAA,wBAAgB,EAC7B,eAAO,CAAC,YAAY,EACpB,OAAO,CACR,IAAI,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC;QAEzB,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAGlC,CAAC;QAEF,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE,EAAE;YACjD,MAAM,gBAAgB,GAAG;gBACvB,cAAc,EAAE,SAAS;gBACzB,MAAM,EAAE,IAAA,uBAAe,EAAC,SAAS,CAAC;gBAClC,WAAW,EAAE,IAAA,qCAA6B,EAAC,SAAS,CAAC;gBACrD,IAAI;aACL,CAAC;YACF,uBAAA,IAAI,mGAAwB,MAA5B,IAAI,EAAyB,gBAAgB,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC;QACxE,CAAC,CAAC,CAAC;QAEH,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,CAAC,qBAAqB,CACzB,WAAgC;QAEhC,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QAC5D,MAAM,KAAK,GAAG,SAAS,CAAC,SAAS,CAAC;QAClC,SAAS,CAAC,WAAW,EAAE,CAAC;QACxB,uCACK,WAAW,KACd,KAAK,EAAE,KAAK,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,IAChC;IACJ,CAAC;IAED,SAAS;QACP,MAAM,IAAI,GAAG;YACX,cAAc,EAAE,SAAS;YACzB,WAAW,EAAE,SAAS;SACvB,CAAC;QACF,IAAI,CAAC,MAAM,CAAC;YACV,sBAAsB,kCACjB,IAAI,CAAC,KAAK,CAAC,sBAAsB,KACpC,IAAI,GACL;SACF,CAAC,CAAC;QACH,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,CAAC,OAAO,CACX,OAA4B,EAC5B,UAAgC,EAChC,EAAE,eAAe,KAA4C,EAAE;QAE/D,MAAM,OAAO,GAAG,uBAAA,IAAI,uFAAY,MAAhB,IAAI,EAAa,EAAE,eAAe,EAAE,CAAC,CAAC;QACtD,MAAM,YAAY,GAAG,EAAE,CAAC;QACxB,IAAI,iCAAiC,CAAC;QACtC,IAAI,UAAU,EAAE;YACd,MAAM,oCAAoC,GACxC,MAAM,IAAI,CAAC,qBAAqB,CAAC,UAAU,CAAC,CAAC;YAC/C,YAAY,CAAC,IAAI,CAAC,oCAAoC,CAAC,CAAC;YACxD,iCAAiC,mCAC5B,OAAO;gBACV,sEAAsE;gBACtE,KAAK,EAAE,IAAA,2BAAmB,EAAC,oCAAoC,CAAC,KAAK,CAAC,GACvE,CAAC;SACH;aAAM,IAAI,OAAO,CAAC,KAAK,EAAE;YACxB,iCAAiC,GAAG,OAAO,CAAC;SAC7C;aAAM;YACL,iCAAiC,GAAG,MAAM,IAAI,CAAC,qBAAqB,CAClE,OAAO,CACR,CAAC;SACH;QACD,YAAY,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC;QACrD,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,IAAA,wBAAgB,EAAC,eAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,EAAE;YACzE,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,GAAG,EAAE,YAAY;aAClB,CAAC;SACH,CAAC,CAAC;QACH,IAAI,cAAc,CAAC;QACnB,IAAI,WAAW,CAAC;QAChB,IAAI,UAAU,EAAE;YACd,cAAc,GAAG,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,GAAG,CAAC,CAAC,CAAC,CAAC;YAC9B,WAAW,GAAG,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,GAAG,CAAC,CAAC,CAAC,CAAC;SAC5B;aAAM;YACL,WAAW,GAAG,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,GAAG,CAAC,CAAC,CAAC,CAAC;SAC5B;QAED,IAAI,CAAC,MAAM,CAAC;YACV,sBAAsB,gDACjB,IAAI,CAAC,KAAK,CAAC,sBAAsB,GACjC,CAAC,OAAO,KAAK,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI;gBACrC,IAAI,EAAE;oBACJ,cAAc;oBACd,WAAW;iBACZ;aACF,CAAC,KACF,aAAa,kCACR,IAAI,CAAC,KAAK,CAAC,sBAAsB,CAAC,aAAa,KAClD,CAAC,OAAO,CAAC,EAAE;wBACT,cAAc;wBACd,WAAW;qBACZ,MAEJ;SACF,CAAC,CAAC;QAEH,OAAO;YACL,cAAc;YACd,WAAW;SACZ,CAAC;IACJ,CAAC;IAED,yEAAyE;IACzE,sDAAsD;IACtD,KAAK,CAAC,wBAAwB,CAAC,EAC7B,eAAe,EACf,QAAQ,EACR,kBAAkB,EAClB,0BAA0B,EAC1B,eAAe,GAOhB;;QACC,MAAM,OAAO,GAAG,uBAAA,IAAI,uFAAY,MAAhB,IAAI,EAAa,EAAE,eAAe,EAAE,CAAC,CAAC;QACtD,MAAM,QAAQ,GAAG,uBAAA,IAAI,wFAAa,MAAjB,IAAI,EAAc,EAAE,eAAe,EAAE,CAAC,CAAC;QACxD,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,KAAK,CAC3B,IAAA,wBAAgB,EAAC,eAAO,CAAC,mBAAmB,EAAE,OAAO,CAAC,EACtD;YACE,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,MAAM,EAAE,kBAAkB;gBAC1B,YAAY,EAAE,0BAA0B;aACzC,CAAC;SACH,CACF,CAAC;QACF,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACxB,IAAI,YAAY,CAAC;QACjB,IAAI;YACF,MAAM,cAAc,GAAG,MAAM,IAAA,wBAAK,EAAC,QAAQ,EAAE,YAAY,EAAE;gBACzD,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,IAAI;aACf,CAAC,CAAC;YACH,YAAY,GAAG,IAAI,wBAAS,CAAC,cAAc,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;SAC3D;QAAC,OAAO,KAAK,EAAE;YACd,OAAO,CAAC,KAAK,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAC;SACxC;QAED,MAAM,aAAa,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC;QACtC,IAAI,KAAK,CAAC;QACV,IAAI,SAAS,CAAC;QACd,IAAI,YAAY,GAAG,EAAE,CAAC;QAEtB,IAAI,aAAa,EAAE;YACjB,SAAS,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,IAAI,CAAC,CAAC;YACpD,KAAK,GAAG,IAAA,eAAO,EAAC,SAAS,CAAC,SAAS,CAAC,CAAC;YACrC,YAAY,GAAG,SAAS,CAAC,YAAY,CAAC;YACtC,IAAI,QAAQ,EAAE;gBACZ,MAAA,QAAQ,CAAC,KAAK,oCAAd,QAAQ,CAAC,KAAK,GAAK,KAAK,EAAC;aAC1B;SACF;QACD,MAAM,yBAAyB,mCAC1B,IAAI,KACP,MAAM,EAAE,IAAA,iBAAS,EAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,GACzC,CAAC;QAEF,IAAI;YACF,uBAAA,IAAI,mGAAwB,MAA5B,IAAI,EACF;gBACE,OAAO;gBACP,YAAY;gBACZ,YAAY;gBACZ,MAAM,EAAE,gCAAwB,CAAC,OAAO;gBACxC,IAAI;gBACJ,QAAQ;gBACR,IAAI,EAAE,yBAAyB,CAAC,IAAI;gBACpC,MAAM,EAAE,yBAAyB,CAAC,MAAM;gBACxC,WAAW,EAAE,IAAI;gBACjB,IAAI,EAAE,CAAA,eAAe,aAAf,eAAe,uBAAf,eAAe,CAAE,IAAI,KAAI,MAAM;aACtC,EACD,EAAE,OAAO,EAAE,QAAQ,EAAE,CACtB,CAAC;SACH;gBAAS;YACR,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,WAAW,EAAE,CAAC;SAC1B;QAED,OAAO,yBAAyB,CAAC;IACnC,CAAC;IA0BD,0FAA0F;IAC1F,qEAAqE;IACrE,uDAAuD;IACvD,KAAK,CAAC,sBAAsB,CAC1B,IAAY,EACZ,EACE,eAAe,MAGb,EAAE;QAEN,MAAM,OAAO,GAAG,uBAAA,IAAI,uFAAY,MAAhB,IAAI,EAAa,EAAE,eAAe,EAAE,CAAC,CAAC;QACtD,MAAM,IAAI,CAAC,KAAK,CAAC,IAAA,wBAAgB,EAAC,eAAO,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE;YAC1D,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,CAAC;SAC/B,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,EAClB,eAAe,MAGb,EAAE;QACJ,MAAM,OAAO,GAAG,uBAAA,IAAI,uFAAY,MAAhB,IAAI,EAAa,EAAE,eAAe,EAAE,CAAC,CAAC;QACtD,IAAI,QAAQ,GAAG,KAAK,CAAC;QACrB,IAAI;YACF,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,KAAK,CAC/B,IAAA,wBAAgB,EAAC,eAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,CAC5C,CAAC;YACF,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;SACxC;QAAC,OAAO,KAAK,EAAE;YACd,OAAO,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC;SAChD;QAED,IAAI,CAAC,MAAM,CAAC;YACV,sBAAsB,gDACjB,IAAI,CAAC,KAAK,CAAC,sBAAsB,GACjC,CAAC,OAAO,KAAK,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,QAAQ,EAAE,CAAC,KACpD,iBAAiB,kCACZ,IAAI,CAAC,KAAK,CAAC,sBAAsB,CAAC,iBAAiB,KACtD,CAAC,OAAO,CAAC,EAAE,QAAQ,MAEtB;SACF,CAAC,CAAC;QAEH,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,KAAK,CAAC,wBAAwB,CAAC,QAAgB;QAC7C,IAAI,QAAQ,KAAK,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE;YACrC,IAAI,CAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;SAC5C;IACH,CAAC;IAED,eAAe,CAAC,EACd,WAAW,EACX,MAAM,GAIP;QACC,MAAM,EAAE,iBAAiB,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,sBAAsB,CAAC;QAChE,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC;QAChC,MAAM,wBAAwB,GAAG,iBAAiB,aAAjB,iBAAiB,uBAAjB,iBAAiB,CAAG,OAAO,CAAC,CAAC;QAC9D,IAAI,CAAC,wBAAwB,IAAI,wBAAwB,CAAC,MAAM,KAAK,CAAC,EAAE;YACtE,OAAO,EAAE,CAAC;SACX;QAED,OAAO,wBAAwB,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE;;YAC7C,OAAO,GAAG,CAAC,MAAM,KAAK,MAAM,IAAI,CAAA,MAAA,GAAG,CAAC,QAAQ,0CAAE,IAAI,MAAK,WAAW,CAAC;QACrE,CAAC,CAAC,CAAC;IACL,CAAC;CACF;AA7vBD,8CA6vBC;8GA9fC,KAAK,8DACH,gBAAkC,EAClC,EACE,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,EAC7B,QAAQ,GAAG,IAAI,CAAC,QAAQ,GAIzB;;IAED,MAAM,EAAE,sBAAsB,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC;IAC9C,MAAM,EAAE,iBAAiB,EAAE,GAAG,sBAAsB,CAAC;IACrD,MAAM,wBAAwB,GAAG,MAAA,iBAAiB,CAAC,OAAO,CAAC,mCAAI,EAAE,CAAC;IAClE,MAAM,YAAY,GAAG,wBAAwB,aAAxB,wBAAwB,uBAAxB,wBAAwB,CAAE,SAAS,CACtD,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,gBAAgB,CAAC,IAAI,CAC5C,CAAC;IACF,MAAM,qBAAqB,GAAG,IAAI,CAAC,qBAAqB,CACtD,gBAAgB,CAAC,IAAI,CACtB,CAAC;IACF,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS,EAAE;QAC/B,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;KACtC;IAED,IAAI,CAAC,oBAAoB,CACvB,gBAAgB,EAChB,qBAAqB;QACnB,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,wBAAwB,CAAC,YAAY,CAAC,CAC3C,CAAC;IAEF,IAAI,qBAAqB,EAAE;QACzB,wBAAwB;QACxB,MAAM,mBAAmB,GAAG,wBAAwB,aAAxB,wBAAwB,uBAAxB,wBAAwB,CAAE,SAAS,CAC7D,CAAC,GAAqB,EAAE,EAAE;;YACxB,OAAA,CAAA,MAAA,GAAG,CAAC,QAAQ,0CAAE,KAAK,OAAK,MAAA,gBAAgB,CAAC,QAAQ,0CAAE,KAAK,CAAA;iBACxD,MAAA,GAAG,CAAC,MAAM,0CAAE,UAAU,CAAC,WAAW,CAAC,CAAA,CAAA;SAAA,CACtC,CAAC;QACF,MAAM,QAAQ,GAAG,IAAA,mBAAS,EAAC,gBAAgB,CAAC,CAAC;QAC7C,MAAM,OAAO,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC3B,MAAM,2BAA2B,mCAAQ,gBAAgB,KAAE,OAAO,GAAE,CAAC;QACrE,MAAM,qBAAqB,GACzB,mBAAmB,GAAG,CAAC,CAAC;YACtB,CAAC,CAAC,wBAAwB;iBACrB,KAAK,CAAC,CAAC,EAAE,mBAAmB,CAAC;iBAC7B,MAAM,CAAC,wBAAwB,CAAC,KAAK,CAAC,mBAAmB,GAAG,CAAC,CAAC,CAAC;iBAC/D,MAAM,CAAC,2BAA2B,CAAC;YACxC,CAAC,CAAC,wBAAwB,CAAC,MAAM,CAAC,2BAA2B,CAAC,CAAC;QACnE,IAAI,CAAC,MAAM,CAAC;YACV,sBAAsB,kCACjB,sBAAsB,KACzB,iBAAiB,kCACZ,sBAAsB,CAAC,iBAAiB,KAC3C,CAAC,OAAO,CAAC,EAAE,qBAAqB,MAEnC;SACF,CAAC,CAAC;QACH,OAAO;KACR;IAED,IACE,CAAC,gBAAgB,CAAC,MAAM,KAAK,gCAAwB,CAAC,OAAO;QAC3D,gBAAgB,CAAC,MAAM,KAAK,gCAAwB,CAAC,QAAQ,CAAC;QAChE,CAAC,gBAAgB,CAAC,SAAS,EAC3B;QACA,4BAA4B;QAC5B,MAAM,uBAAuB,GAAG,wBAAwB,CAAC,YAAY,CAAC,CAAC;QACvE,MAAM,oBAAoB,mCACrB,uBAAuB,GACvB,gBAAgB,CACpB,CAAC;QACF,MAAM,uBAAA,IAAI,oGAAyB,MAA7B,IAAI,EAA0B,oBAAoB,EAAE;YACxD,OAAO;YACP,QAAQ;SACT,CAAC,CAAC;KACJ;SAAM;QACL,IAAI,CAAC,MAAM,CAAC;YACV,sBAAsB,kCACjB,sBAAsB,KACzB,iBAAiB,kCACZ,sBAAsB,CAAC,iBAAiB,KAC3C,CAAC,OAAO,CAAC,EAAE,sBAAsB,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC,GAAG,CAC9D,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;wBACd,OAAO,KAAK,KAAK,YAAY;4BAC3B,CAAC,iCAAM,IAAI,GAAK,gBAAgB,EAChC,CAAC,CAAC,IAAI,CAAC;oBACX,CAAC,CACF,MAEJ;SACF,CAAC,CAAC;KACJ;IAED,IAAI,CAAC,YAAY,CAAC,IAAI,CACpB,GAAG,gBAAgB,CAAC,IAAI,mBAAmB,EAC3C,gBAAgB,CACjB,CAAC;AACJ,CAAC,yDAsBD,KAAK,+DACH,gBAAkC,EAClC,EACE,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,EAC7B,QAAQ,GAAG,IAAI,CAAC,QAAQ,GAIzB;;IAED,IAAI,QAAQ,KAAK,SAAS,EAAE;QAC1B,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;KACtC;IACD,MAAM,MAAM,GAAG,MAAA,gBAAgB,CAAC,cAAc,0CAAE,SAAS,CAAC;IAC1D,IAAI;QACF,MAAM,kBAAkB,GAIb,MAAM,IAAA,wBAAK,EAAC,QAAQ,EAAE,uBAAuB,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;QACpE,MAAM,WAAW,GAGN,MAAM,IAAA,wBAAK,EAAC,QAAQ,EAAE,sBAAsB,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;QAEnE,MAAM,YAAY,GAAG,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,YAAY,CAAC;QAC/C,MAAM,oBAAoB,GAAG,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,oBAAoB,CAAC;QAC/D,IAAI,kBAAkB,aAAlB,kBAAkB,uBAAlB,kBAAkB,CAAE,WAAW,EAAE;YACnC,MAAM,SAAS,GAAsC,MAAM,IAAA,wBAAK,EAC9D,QAAQ,EACR,kBAAkB,EAClB,CAAC,kBAAkB,aAAlB,kBAAkB,uBAAlB,kBAAkB,CAAE,WAAW,EAAE,KAAK,CAAC,CACzC,CAAC;YACF,MAAM,aAAa,GAAG,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,aAAa,CAAC;YAC/C,MAAM,eAAe,mCAChB,gBAAgB,CAAC,QAAQ,KAC5B,YAAY;gBACZ,oBAAoB,GACrB,CAAC;YACF,kCAAkC;YAClC,MAAM,cAAc,mCACf,gBAAgB,KACnB,EAAE,EAAE,gBAAgB,CAAC,IAAI,EACzB,MAAM,EAAE,WAAW,EACnB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,eAAe,GAC1B,CAAC;YACF,qCAAqC;YACrC,MAAM,QAAQ,GAAG,IAAA,0BAAkB,EAAC,cAAc,CAAC,CAAC;YACpD,gCAAgC;YAChC,MAAM,aAAa,GAAG,IAAA,qBAAa,EAAC,cAAc,CAAC,OAAO,CAAC,CAAC;YAC5D,4CAA4C;YAC5C,MAAM,KAAK,GAAG,IAAA,4BAAoB,EAChC,aAAa,EACb,QAAQ,EACR,6CAA6C,CAC9C,CAAC;YACF,MAAM,MAAM,GACV,KAAK,CAAC,MAAM,GAAG,CAAC;gBACd,CAAC,iCACM,cAAc,KACjB,OAAO,EAAE,cAAc,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAEjD,CAAC,CAAC,cAAc,CAAC;YAErB,IAAI,CAAC,0BAA0B,CAC7B,MAAM,EACN,kBAAkB,EAClB,aAAa,CACd,CAAC;YAEF,IAAI,CAAC,qBAAqB,CAAC;gBACzB,KAAK,EAAE,gCAAoB,CAAC,YAAY;gBACxC,QAAQ,EAAE,oCAAwB,CAAC,YAAY;aAChD,CAAC,CAAC;YAEH,uBAAA,IAAI,mGAAwB,MAA5B,IAAI,kCAEG,gBAAgB,KACnB,SAAS,EAAE,IAAI,KAEjB,EAAE,OAAO,EAAE,QAAQ,EAAE,CACtB,CAAC;SACH;KACF;IAAC,OAAO,KAAK,EAAE;QACd,IAAI,CAAC,qBAAqB,CAAC;YACzB,KAAK,EAAE,gCAAoB,CAAC,qBAAqB;YACjD,QAAQ,EAAE,oCAAwB,CAAC,YAAY;SAChD,CAAC,CAAC;QACH,OAAO,CAAC,KAAK,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC;KACvC;AACH,CAAC,6FA6MW,EACV,eAAe,MAC0B,EAAE;IAC3C,OAAO,eAAe;QACpB,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,eAAe,CAAC,CAAC,aAAa,CAAC,OAAO;QAClE,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC;AAC1B,CAAC,+FAEY,EACX,eAAe,MAGb,EAAE;IACJ,IAAI,eAAe,EAAE;QACnB,OAAO,IAAI,mBAAQ,CAAC,IAAI,CAAC,oBAAoB,CAAC,eAAe,CAAC,CAAC,QAAQ,CAAC,CAAC;KAC1E;IAED,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS,EAAE;QAC/B,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;KACtC;IAED,OAAO,IAAI,CAAC,QAAQ,CAAC;AACvB,CAAC","sourcesContent":["// eslint-disable-next-line import/no-nodejs-modules\nimport { hexlify } from '@ethersproject/bytes';\nimport type { BaseConfig, BaseState } from '@metamask/base-controller';\nimport { query, safelyExecute } from '@metamask/controller-utils';\nimport type { Provider } from '@metamask/eth-query';\nimport EthQuery from '@metamask/eth-query';\nimport type {\n NetworkClientId,\n NetworkController,\n NetworkState,\n} from '@metamask/network-controller';\nimport { StaticIntervalPollingControllerV1 } from '@metamask/polling-controller';\nimport { BigNumber } from 'bignumber.js';\n// eslint-disable-next-line import/no-nodejs-modules\nimport EventEmitter from 'events';\nimport cloneDeep from 'lodash/cloneDeep';\n\nimport {\n CHAIN_IDS,\n MetaMetricsEventCategory,\n MetaMetricsEventName,\n} from './constants';\nimport type {\n Fees,\n Hex,\n IndividualTxFees,\n SignedCanceledTransaction,\n SignedTransaction,\n SmartTransaction,\n SmartTransactionsStatus,\n UnsignedTransaction,\n} from './types';\nimport { APIType, SmartTransactionStatuses } from './types';\nimport {\n calculateStatus,\n generateHistoryEntry,\n getAPIRequestURL,\n getStxProcessingTime,\n handleFetch,\n incrementNonceInHex,\n isSmartTransactionCancellable,\n isSmartTransactionPending,\n replayHistory,\n snapshotFromTxMeta,\n getTxHash,\n} from './utils';\n\nconst SECOND = 1000;\nexport const DEFAULT_INTERVAL = SECOND * 5;\nconst ETH_QUERY_ERROR_MSG =\n '`ethQuery` is not defined on SmartTransactionsController';\n\nexport type SmartTransactionsControllerConfig = BaseConfig & {\n interval: number;\n clientId: string;\n chainId: Hex;\n supportedChainIds: string[];\n};\n\ntype FeeEstimates = {\n approvalTxFees: IndividualTxFees | undefined;\n tradeTxFees: IndividualTxFees | undefined;\n};\n\nexport type SmartTransactionsControllerState = BaseState & {\n smartTransactionsState: {\n smartTransactions: Record<Hex, SmartTransaction[]>;\n userOptIn: boolean | undefined;\n userOptInV2: boolean | undefined;\n liveness: boolean | undefined;\n fees: FeeEstimates;\n feesByChainId: Record<Hex, FeeEstimates>;\n livenessByChainId: Record<Hex, boolean>;\n };\n};\n\nexport default class SmartTransactionsController extends StaticIntervalPollingControllerV1<\n SmartTransactionsControllerConfig,\n SmartTransactionsControllerState\n> {\n /**\n * Name of this controller used during composition\n */\n override name = 'SmartTransactionsController';\n\n public timeoutHandle?: NodeJS.Timeout;\n\n private readonly getNonceLock: any;\n\n private ethQuery: EthQuery | undefined;\n\n public confirmExternalTransaction: any;\n\n private readonly trackMetaMetricsEvent: any;\n\n public eventEmitter: EventEmitter;\n\n private readonly getNetworkClientById: NetworkController['getNetworkClientById'];\n\n /* istanbul ignore next */\n private async fetch(request: string, options?: RequestInit) {\n const { clientId } = this.config;\n const fetchOptions = {\n ...options,\n headers: {\n 'Content-Type': 'application/json',\n ...(clientId && { 'X-Client-Id': clientId }),\n },\n };\n\n return handleFetch(request, fetchOptions);\n }\n\n constructor(\n {\n onNetworkStateChange,\n getNonceLock,\n provider,\n confirmExternalTransaction,\n trackMetaMetricsEvent,\n getNetworkClientById,\n }: {\n onNetworkStateChange: (\n listener: (networkState: NetworkState) => void,\n ) => void;\n getNonceLock: any;\n provider: Provider;\n confirmExternalTransaction: any;\n trackMetaMetricsEvent: any;\n getNetworkClientById: NetworkController['getNetworkClientById'];\n },\n config?: Partial<SmartTransactionsControllerConfig>,\n state?: Partial<SmartTransactionsControllerState>,\n ) {\n super(config, state);\n\n this.defaultConfig = {\n interval: DEFAULT_INTERVAL,\n chainId: CHAIN_IDS.ETHEREUM,\n clientId: 'default',\n supportedChainIds: [CHAIN_IDS.ETHEREUM, CHAIN_IDS.GOERLI],\n };\n\n this.defaultState = {\n smartTransactionsState: {\n smartTransactions: {},\n userOptIn: undefined,\n userOptInV2: undefined,\n fees: {\n approvalTxFees: undefined,\n tradeTxFees: undefined,\n },\n liveness: true,\n livenessByChainId: {\n [CHAIN_IDS.ETHEREUM]: true,\n [CHAIN_IDS.GOERLI]: true,\n },\n feesByChainId: {\n [CHAIN_IDS.ETHEREUM]: {\n approvalTxFees: undefined,\n tradeTxFees: undefined,\n },\n [CHAIN_IDS.GOERLI]: {\n approvalTxFees: undefined,\n tradeTxFees: undefined,\n },\n },\n },\n };\n\n this.initialize();\n this.setIntervalLength(this.config.interval);\n this.getNonceLock = getNonceLock;\n this.ethQuery = undefined;\n this.confirmExternalTransaction = confirmExternalTransaction;\n this.trackMetaMetricsEvent = trackMetaMetricsEvent;\n this.getNetworkClientById = getNetworkClientById;\n\n this.initializeSmartTransactionsForChainId();\n\n onNetworkStateChange(({ providerConfig: newProvider }) => {\n const { chainId } = newProvider;\n this.configure({ chainId });\n this.initializeSmartTransactionsForChainId();\n this.checkPoll(this.state);\n this.ethQuery = new EthQuery(provider);\n });\n\n this.subscribe((currentState: any) => this.checkPoll(currentState));\n this.eventEmitter = new EventEmitter();\n }\n\n async _executePoll(networkClientId: string): Promise<void> {\n // if this is going to be truly UI driven polling we shouldn't really reach here\n // with a networkClientId that is not supported, but for now I'll add a check in case\n // wondering if we should add some kind of predicate to the polling controller to check whether\n // we should poll or not\n const chainId = this.#getChainId({ networkClientId });\n if (!this.config.supportedChainIds.includes(chainId)) {\n return Promise.resolve();\n }\n return this.updateSmartTransactions({ networkClientId });\n }\n\n checkPoll(state: any) {\n const { smartTransactions } = state.smartTransactionsState;\n const currentSmartTransactions = smartTransactions[this.config.chainId];\n const pendingTransactions = currentSmartTransactions?.filter(\n isSmartTransactionPending,\n );\n if (!this.timeoutHandle && pendingTransactions?.length > 0) {\n this.poll();\n } else if (this.timeoutHandle && pendingTransactions?.length === 0) {\n this.stop();\n }\n }\n\n initializeSmartTransactionsForChainId() {\n if (this.config.supportedChainIds.includes(this.config.chainId)) {\n const { smartTransactionsState } = this.state;\n this.update({\n smartTransactionsState: {\n ...smartTransactionsState,\n smartTransactions: {\n ...smartTransactionsState.smartTransactions,\n [this.config.chainId]:\n smartTransactionsState.smartTransactions[this.config.chainId] ??\n [],\n },\n },\n });\n }\n }\n\n async poll(interval?: number): Promise<void> {\n const { chainId, supportedChainIds } = this.config;\n interval && this.configure({ interval }, false, false);\n this.timeoutHandle && clearInterval(this.timeoutHandle);\n if (!supportedChainIds.includes(chainId)) {\n return;\n }\n await safelyExecute(async () => this.updateSmartTransactions());\n this.timeoutHandle = setInterval(() => {\n safelyExecute(async () => this.updateSmartTransactions());\n }, this.config.interval);\n }\n\n async stop() {\n this.timeoutHandle && clearInterval(this.timeoutHandle);\n this.timeoutHandle = undefined;\n }\n\n setOptInState(state: boolean | undefined): void {\n this.update({\n smartTransactionsState: {\n ...this.state.smartTransactionsState,\n userOptInV2: state,\n },\n });\n }\n\n trackStxStatusChange(\n smartTransaction: SmartTransaction,\n prevSmartTransaction?: SmartTransaction,\n ) {\n if (!prevSmartTransaction) {\n return; // Don't track the first STX, because it doesn't have all necessary params.\n }\n\n let updatedSmartTransaction = cloneDeep(smartTransaction);\n updatedSmartTransaction = {\n ...cloneDeep(prevSmartTransaction),\n ...updatedSmartTransaction,\n };\n\n if (\n !updatedSmartTransaction.swapMetaData ||\n (updatedSmartTransaction.status === prevSmartTransaction.status &&\n prevSmartTransaction.swapMetaData)\n ) {\n return; // If status hasn't changed, don't track it again.\n }\n\n const sensitiveProperties = {\n stx_status: updatedSmartTransaction.status,\n token_from_symbol: updatedSmartTransaction.sourceTokenSymbol,\n token_to_symbol: updatedSmartTransaction.destinationTokenSymbol,\n processing_time: getStxProcessingTime(updatedSmartTransaction.time),\n stx_enabled: true,\n current_stx_enabled: true,\n stx_user_opt_in: true,\n };\n\n this.trackMetaMetricsEvent({\n event: MetaMetricsEventName.StxStatusUpdated,\n category: MetaMetricsEventCategory.Transactions,\n sensitiveProperties,\n });\n }\n\n isNewSmartTransaction(smartTransactionUuid: string): boolean {\n const { chainId } = this.config;\n const { smartTransactionsState } = this.state;\n const { smartTransactions } = smartTransactionsState;\n const currentSmartTransactions = smartTransactions[chainId];\n const currentIndex = currentSmartTransactions?.findIndex(\n (stx) => stx.uuid === smartTransactionUuid,\n );\n return currentIndex === -1 || currentIndex === undefined;\n }\n\n updateSmartTransaction(\n smartTransaction: SmartTransaction,\n { networkClientId }: { networkClientId?: NetworkClientId } = {},\n ) {\n let {\n ethQuery,\n config: { chainId },\n } = this;\n if (networkClientId) {\n const networkClient = this.getNetworkClientById(networkClientId);\n chainId = networkClient.configuration.chainId;\n ethQuery = new EthQuery(networkClient.provider);\n }\n\n this.#updateSmartTransaction(smartTransaction, {\n chainId,\n ethQuery,\n });\n }\n\n async #updateSmartTransaction(\n smartTransaction: SmartTransaction,\n {\n chainId = this.config.chainId,\n ethQuery = this.ethQuery,\n }: {\n chainId: Hex;\n ethQuery: EthQuery | undefined;\n },\n ): Promise<void> {\n const { smartTransactionsState } = this.state;\n const { smartTransactions } = smartTransactionsState;\n const currentSmartTransactions = smartTransactions[chainId] ?? [];\n const currentIndex = currentSmartTransactions?.findIndex(\n (stx) => stx.uuid === smartTransaction.uuid,\n );\n const isNewSmartTransaction = this.isNewSmartTransaction(\n smartTransaction.uuid,\n );\n if (this.ethQuery === undefined) {\n throw new Error(ETH_QUERY_ERROR_MSG);\n }\n\n this.trackStxStatusChange(\n smartTransaction,\n isNewSmartTransaction\n ? undefined\n : currentSmartTransactions[currentIndex],\n );\n\n if (isNewSmartTransaction) {\n // add smart transaction\n const cancelledNonceIndex = currentSmartTransactions?.findIndex(\n (stx: SmartTransaction) =>\n stx.txParams?.nonce === smartTransaction.txParams?.nonce &&\n stx.status?.startsWith('cancelled'),\n );\n const snapshot = cloneDeep(smartTransaction);\n const history = [snapshot];\n const historifiedSmartTransaction = { ...smartTransaction, history };\n const nextSmartTransactions =\n cancelledNonceIndex > -1\n ? currentSmartTransactions\n .slice(0, cancelledNonceIndex)\n .concat(currentSmartTransactions.slice(cancelledNonceIndex + 1))\n .concat(historifiedSmartTransaction)\n : currentSmartTransactions.concat(historifiedSmartTransaction);\n this.update({\n smartTransactionsState: {\n ...smartTransactionsState,\n smartTransactions: {\n ...smartTransactionsState.smartTransactions,\n [chainId]: nextSmartTransactions,\n },\n },\n });\n return;\n }\n\n if (\n (smartTransaction.status === SmartTransactionStatuses.SUCCESS ||\n smartTransaction.status === SmartTransactionStatuses.REVERTED) &&\n !smartTransaction.confirmed\n ) {\n // confirm smart transaction\n const currentSmartTransaction = currentSmartTransactions[currentIndex];\n const nextSmartTransaction = {\n ...currentSmartTransaction,\n ...smartTransaction,\n };\n await this.#confirmSmartTransaction(nextSmartTransaction, {\n chainId,\n ethQuery,\n });\n } else {\n this.update({\n smartTransactionsState: {\n ...smartTransactionsState,\n smartTransactions: {\n ...smartTransactionsState.smartTransactions,\n [chainId]: smartTransactionsState.smartTransactions[chainId].map(\n (item, index) => {\n return index === currentIndex\n ? { ...item, ...smartTransaction }\n : item;\n },\n ),\n },\n },\n });\n }\n\n this.eventEmitter.emit(\n `${smartTransaction.uuid}:smartTransaction`,\n smartTransaction,\n );\n }\n\n async updateSmartTransactions({\n networkClientId,\n }: {\n networkClientId?: NetworkClientId;\n } = {}): Promise<void> {\n const { smartTransactions } = this.state.smartTransactionsState;\n const chainId = this.#getChainId({ networkClientId });\n const smartTransactionsForChainId = smartTransactions[chainId];\n\n const transactionsToUpdate: string[] = smartTransactionsForChainId\n .filter(isSmartTransactionPending)\n .map((smartTransaction) => smartTransaction.uuid);\n\n if (transactionsToUpdate.length > 0) {\n this.fetchSmartTransactionsStatus(transactionsToUpdate, {\n networkClientId,\n });\n }\n }\n\n async #confirmSmartTransaction(\n smartTransaction: SmartTransaction,\n {\n chainId = this.config.chainId,\n ethQuery = this.ethQuery,\n }: {\n chainId: Hex;\n ethQuery: EthQuery | undefined;\n },\n ) {\n if (ethQuery === undefined) {\n throw new Error(ETH_QUERY_ERROR_MSG);\n }\n const txHash = smartTransaction.statusMetadata?.minedHash;\n try {\n const transactionReceipt: {\n maxFeePerGas?: string;\n maxPriorityFeePerGas?: string;\n blockNumber: string;\n } | null = await query(ethQuery, 'getTransactionReceipt', [txHash]);\n const transaction: {\n maxFeePerGas?: string;\n maxPriorityFeePerGas?: string;\n } | null = await query(ethQuery, 'getTransactionByHash', [txHash]);\n\n const maxFeePerGas = transaction?.maxFeePerGas;\n const maxPriorityFeePerGas = transaction?.maxPriorityFeePerGas;\n if (transactionReceipt?.blockNumber) {\n const blockData: { baseFeePerGas?: string } | null = await query(\n ethQuery,\n 'getBlockByNumber',\n [transactionReceipt?.blockNumber, false],\n );\n const baseFeePerGas = blockData?.baseFeePerGas;\n const updatedTxParams = {\n ...smartTransaction.txParams,\n maxFeePerGas,\n maxPriorityFeePerGas,\n };\n // call confirmExternalTransaction\n const originalTxMeta = {\n ...smartTransaction,\n id: smartTransaction.uuid,\n status: 'confirmed',\n hash: txHash,\n txParams: updatedTxParams,\n };\n // create txMeta snapshot for history\n const snapshot = snapshotFromTxMeta(originalTxMeta);\n // recover previous tx state obj\n const previousState = replayHistory(originalTxMeta.history);\n // generate history entry and add to history\n const entry = generateHistoryEntry(\n previousState,\n snapshot,\n 'txStateManager: setting status to confirmed',\n );\n const txMeta =\n entry.length > 0\n ? {\n ...originalTxMeta,\n history: originalTxMeta.history.concat(entry),\n }\n : originalTxMeta;\n\n this.confirmExternalTransaction(\n txMeta,\n transactionReceipt,\n baseFeePerGas,\n );\n\n this.trackMetaMetricsEvent({\n event: MetaMetricsEventName.StxConfirmed,\n category: MetaMetricsEventCategory.Transactions,\n });\n\n this.#updateSmartTransaction(\n {\n ...smartTransaction,\n confirmed: true,\n },\n { chainId, ethQuery },\n );\n }\n } catch (error) {\n this.trackMetaMetricsEvent({\n event: MetaMetricsEventName.StxConfirmationFailed,\n category: MetaMetricsEventCategory.Transactions,\n });\n console.error('confirm error', error);\n }\n }\n\n // ! Ask backend API to accept list of uuids as params\n async fetchSmartTransactionsStatus(\n uuids: string[],\n { networkClientId }: { networkClientId?: NetworkClientId } = {},\n ): Promise<Record<string, SmartTransactionsStatus>> {\n const params = new URLSearchParams({\n uuids: uuids.join(','),\n });\n const chainId = this.#getChainId({ networkClientId });\n const ethQuery = this.#getEthQuery({ networkClientId });\n const url = `${getAPIRequestURL(\n APIType.BATCH_STATUS,\n chainId,\n )}?${params.toString()}`;\n\n const data = (await this.fetch(url)) as Record<\n string,\n SmartTransactionsStatus\n >;\n\n Object.entries(data).forEach(([uuid, stxStatus]) => {\n const smartTransaction = {\n statusMetadata: stxStatus,\n status: calculateStatus(stxStatus),\n cancellable: isSmartTransactionCancellable(stxStatus),\n uuid,\n };\n this.#updateSmartTransaction(smartTransaction, { chainId, ethQuery });\n });\n\n return data;\n }\n\n async addNonceToTransaction(\n transaction: UnsignedTransaction,\n ): Promise<UnsignedTransaction> {\n const nonceLock = await this.getNonceLock(transaction.from);\n const nonce = nonceLock.nextNonce;\n nonceLock.releaseLock();\n return {\n ...transaction,\n nonce: `0x${nonce.toString(16)}`,\n };\n }\n\n clearFees(): Fees {\n const fees = {\n approvalTxFees: undefined,\n tradeTxFees: undefined,\n };\n this.update({\n smartTransactionsState: {\n ...this.state.smartTransactionsState,\n fees,\n },\n });\n return fees;\n }\n\n async getFees(\n tradeTx: UnsignedTransaction,\n approvalTx?: UnsignedTransaction,\n { networkClientId }: { networkClientId?: NetworkClientId } = {},\n ): Promise<Fees> {\n const chainId = this.#getChainId({ networkClientId });\n const transactions = [];\n let unsignedTradeTransactionWithNonce;\n if (approvalTx) {\n const unsignedApprovalTransactionWithNonce =\n await this.addNonceToTransaction(approvalTx);\n transactions.push(unsignedApprovalTransactionWithNonce);\n unsignedTradeTransactionWithNonce = {\n ...tradeTx,\n // If there is an approval tx, the trade tx's nonce is increased by 1.\n nonce: incrementNonceInHex(unsignedApprovalTransactionWithNonce.nonce),\n };\n } else if (tradeTx.nonce) {\n unsignedTradeTransactionWithNonce = tradeTx;\n } else {\n unsignedTradeTransactionWithNonce = await this.addNonceToTransaction(\n tradeTx,\n );\n }\n transactions.push(unsignedTradeTransactionWithNonce);\n const data = await this.fetch(getAPIRequestURL(APIType.GET_FEES, chainId), {\n method: 'POST',\n body: JSON.stringify({\n txs: transactions,\n }),\n });\n let approvalTxFees;\n let tradeTxFees;\n if (approvalTx) {\n approvalTxFees = data?.txs[0];\n tradeTxFees = data?.txs[1];\n } else {\n tradeTxFees = data?.txs[0];\n }\n\n this.update({\n smartTransactionsState: {\n ...this.state.smartTransactionsState,\n ...(chainId === this.config.chainId && {\n fees: {\n approvalTxFees,\n tradeTxFees,\n },\n }),\n feesByChainId: {\n ...this.state.smartTransactionsState.feesByChainId,\n [chainId]: {\n approvalTxFees,\n tradeTxFees,\n },\n },\n },\n });\n\n return {\n approvalTxFees,\n tradeTxFees,\n };\n }\n\n // * After this successful call client must add a nonce representative to\n // * transaction controller external transactions list\n async submitSignedTransactions({\n transactionMeta,\n txParams,\n signedTransactions,\n signedCanceledTransactions,\n networkClientId,\n }: {\n signedTransactions: SignedTransaction[];\n signedCanceledTransactions: SignedCanceledTransaction[];\n transactionMeta?: any;\n txParams?: any;\n networkClientId?: NetworkClientId;\n }) {\n const chainId = this.#getChainId({ networkClientId });\n const ethQuery = this.#getEthQuery({ networkClientId });\n const data = await this.fetch(\n getAPIRequestURL(APIType.SUBMIT_TRANSACTIONS, chainId),\n {\n method: 'POST',\n body: JSON.stringify({\n rawTxs: signedTransactions,\n rawCancelTxs: signedCanceledTransactions,\n }),\n },\n );\n const time = Date.now();\n let preTxBalance;\n try {\n const preTxBalanceBN = await query(ethQuery, 'getBalance', [\n txParams?.from,\n ]);\n preTxBalance = new BigNumber(preTxBalanceBN).toString(16);\n } catch (error) {\n console.error('provider error', error);\n }\n\n const requiresNonce = !txParams.nonce;\n let nonce;\n let nonceLock;\n let nonceDetails = {};\n\n if (requiresNonce) {\n nonceLock = await this.getNonceLock(txParams?.from);\n nonce = hexlify(nonceLock.nextNonce);\n nonceDetails = nonceLock.nonceDetails;\n if (txParams) {\n txParams.nonce ??= nonce;\n }\n }\n const submitTransactionResponse = {\n ...data,\n txHash: getTxHash(signedTransactions[0]),\n };\n\n try {\n this.#updateSmartTransaction(\n {\n chainId,\n nonceDetails,\n preTxBalance,\n status: SmartTransactionStatuses.PENDING,\n time,\n txParams,\n uuid: submitTransactionResponse.uuid,\n txHash: submitTransactionResponse.txHash,\n cancellable: true,\n type: transactionMeta?.type || 'swap',\n },\n { chainId, ethQuery },\n );\n } finally {\n nonceLock?.releaseLock();\n }\n\n return submitTransactionResponse;\n }\n\n #getChainId({\n networkClientId,\n }: { networkClientId?: NetworkClientId } = {}): Hex {\n return networkClientId\n ? this.getNetworkClientById(networkClientId).configuration.chainId\n : this.config.chainId;\n }\n\n #getEthQuery({\n networkClientId,\n }: {\n networkClientId?: NetworkClientId;\n } = {}): EthQuery {\n if (networkClientId) {\n return new EthQuery(this.getNetworkClientById(networkClientId).provider);\n }\n\n if (this.ethQuery === undefined) {\n throw new Error(ETH_QUERY_ERROR_MSG);\n }\n\n return this.ethQuery;\n }\n\n // TODO: This should return if the cancellation was on chain or not (for nonce management)\n // After this successful call client must update nonce representative\n // in transaction controller external transactions list\n async cancelSmartTransaction(\n uuid: string,\n {\n networkClientId,\n }: {\n networkClientId?: NetworkClientId;\n } = {},\n ): Promise<void> {\n const chainId = this.#getChainId({ networkClientId });\n await this.fetch(getAPIRequestURL(APIType.CANCEL, chainId), {\n method: 'POST',\n body: JSON.stringify({ uuid }),\n });\n }\n\n async fetchLiveness({\n networkClientId,\n }: {\n networkClientId?: NetworkClientId;\n } = {}): Promise<boolean> {\n const chainId = this.#getChainId({ networkClientId });\n let liveness = false;\n try {\n const response = await this.fetch(\n getAPIRequestURL(APIType.LIVENESS, chainId),\n );\n liveness = Boolean(response.lastBlock);\n } catch (error) {\n console.log('\"fetchLiveness\" API call failed');\n }\n\n this.update({\n smartTransactionsState: {\n ...this.state.smartTransactionsState,\n ...(chainId === this.config.chainId && { liveness }),\n livenessByChainId: {\n ...this.state.smartTransactionsState.livenessByChainId,\n [chainId]: liveness,\n },\n },\n });\n\n return liveness;\n }\n\n async setStatusRefreshInterval(interval: number): Promise<void> {\n if (interval !== this.config.interval) {\n this.configure({ interval }, false, false);\n }\n }\n\n getTransactions({\n addressFrom,\n status,\n }: {\n addressFrom: string;\n status: SmartTransactionStatuses;\n }): SmartTransaction[] {\n const { smartTransactions } = this.state.smartTransactionsState;\n const { chainId } = this.config;\n const currentSmartTransactions = smartTransactions?.[chainId];\n if (!currentSmartTransactions || currentSmartTransactions.length === 0) {\n return [];\n }\n\n return currentSmartTransactions.filter((stx) => {\n return stx.status === status && stx.txParams?.from === addressFrom;\n });\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"SmartTransactionsController.js","sourceRoot":"","sources":["../src/SmartTransactionsController.ts"],"names":[],"mappings":"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","sourcesContent":["// eslint-disable-next-line import/no-nodejs-modules\nimport { hexlify } from '@ethersproject/bytes';\nimport type { BaseConfig, BaseState } from '@metamask/base-controller';\nimport { query, safelyExecute } from '@metamask/controller-utils';\nimport type { Provider } from '@metamask/eth-query';\nimport EthQuery from '@metamask/eth-query';\nimport type {\n NetworkClientId,\n NetworkController,\n NetworkState,\n} from '@metamask/network-controller';\nimport { StaticIntervalPollingControllerV1 } from '@metamask/polling-controller';\nimport type { TransactionMeta } from '@metamask/transaction-controller';\nimport { TransactionStatus } from '@metamask/transaction-controller';\nimport { BigNumber } from 'bignumber.js';\n// eslint-disable-next-line import/no-nodejs-modules\nimport EventEmitter from 'events';\nimport cloneDeep from 'lodash/cloneDeep';\n\nimport {\n CHAIN_IDS,\n MetaMetricsEventCategory,\n MetaMetricsEventName,\n} from './constants';\nimport type {\n Fees,\n Hex,\n IndividualTxFees,\n SignedCanceledTransaction,\n SignedTransaction,\n SmartTransaction,\n SmartTransactionsStatus,\n UnsignedTransaction,\n GetTransactionsOptions,\n} from './types';\nimport { APIType, SmartTransactionStatuses } from './types';\nimport {\n calculateStatus,\n generateHistoryEntry,\n getAPIRequestURL,\n getStxProcessingTime,\n handleFetch,\n incrementNonceInHex,\n isSmartTransactionCancellable,\n isSmartTransactionPending,\n replayHistory,\n snapshotFromTxMeta,\n getTxHash,\n} from './utils';\n\nconst SECOND = 1000;\nexport const DEFAULT_INTERVAL = SECOND * 5;\nconst ETH_QUERY_ERROR_MSG =\n '`ethQuery` is not defined on SmartTransactionsController';\n\nexport type SmartTransactionsControllerConfig = BaseConfig & {\n interval: number;\n clientId: string;\n chainId: Hex;\n supportedChainIds: string[];\n};\n\ntype FeeEstimates = {\n approvalTxFees: IndividualTxFees | undefined;\n tradeTxFees: IndividualTxFees | undefined;\n};\n\nexport type SmartTransactionsControllerState = BaseState & {\n smartTransactionsState: {\n smartTransactions: Record<Hex, SmartTransaction[]>;\n userOptIn: boolean | undefined;\n userOptInV2: boolean | undefined;\n liveness: boolean | undefined;\n fees: FeeEstimates;\n feesByChainId: Record<Hex, FeeEstimates>;\n livenessByChainId: Record<Hex, boolean>;\n };\n};\n\nexport default class SmartTransactionsController extends StaticIntervalPollingControllerV1<\n SmartTransactionsControllerConfig,\n SmartTransactionsControllerState\n> {\n /**\n * Name of this controller used during composition\n */\n override name = 'SmartTransactionsController';\n\n public timeoutHandle?: NodeJS.Timeout;\n\n private readonly getNonceLock: any;\n\n private ethQuery: EthQuery | undefined;\n\n public confirmExternalTransaction: any;\n\n public getRegularTransactions: (\n options?: GetTransactionsOptions,\n ) => TransactionMeta[];\n\n private readonly trackMetaMetricsEvent: any;\n\n public eventEmitter: EventEmitter;\n\n private readonly getNetworkClientById: NetworkController['getNetworkClientById'];\n\n /* istanbul ignore next */\n private async fetch(request: string, options?: RequestInit) {\n const { clientId } = this.config;\n const fetchOptions = {\n ...options,\n headers: {\n 'Content-Type': 'application/json',\n ...(clientId && { 'X-Client-Id': clientId }),\n },\n };\n\n return handleFetch(request, fetchOptions);\n }\n\n constructor(\n {\n onNetworkStateChange,\n getNonceLock,\n provider,\n confirmExternalTransaction,\n getTransactions,\n trackMetaMetricsEvent,\n getNetworkClientById,\n }: {\n onNetworkStateChange: (\n listener: (networkState: NetworkState) => void,\n ) => void;\n getNonceLock: any;\n provider: Provider;\n confirmExternalTransaction: any;\n getTransactions: (options?: GetTransactionsOptions) => TransactionMeta[];\n trackMetaMetricsEvent: any;\n getNetworkClientById: NetworkController['getNetworkClientById'];\n },\n config?: Partial<SmartTransactionsControllerConfig>,\n state?: Partial<SmartTransactionsControllerState>,\n ) {\n super(config, state);\n\n this.defaultConfig = {\n interval: DEFAULT_INTERVAL,\n chainId: CHAIN_IDS.ETHEREUM,\n clientId: 'default',\n supportedChainIds: [CHAIN_IDS.ETHEREUM, CHAIN_IDS.GOERLI],\n };\n\n this.defaultState = {\n smartTransactionsState: {\n smartTransactions: {},\n userOptIn: undefined,\n userOptInV2: undefined,\n fees: {\n approvalTxFees: undefined,\n tradeTxFees: undefined,\n },\n liveness: true,\n livenessByChainId: {\n [CHAIN_IDS.ETHEREUM]: true,\n [CHAIN_IDS.GOERLI]: true,\n },\n feesByChainId: {\n [CHAIN_IDS.ETHEREUM]: {\n approvalTxFees: undefined,\n tradeTxFees: undefined,\n },\n [CHAIN_IDS.GOERLI]: {\n approvalTxFees: undefined,\n tradeTxFees: undefined,\n },\n },\n },\n };\n\n this.initialize();\n this.setIntervalLength(this.config.interval);\n this.getNonceLock = getNonceLock;\n this.ethQuery = undefined;\n this.confirmExternalTransaction = confirmExternalTransaction;\n this.getRegularTransactions = getTransactions;\n this.trackMetaMetricsEvent = trackMetaMetricsEvent;\n this.getNetworkClientById = getNetworkClientById;\n\n this.initializeSmartTransactionsForChainId();\n\n onNetworkStateChange(({ providerConfig: newProvider }) => {\n const { chainId } = newProvider;\n this.configure({ chainId });\n this.initializeSmartTransactionsForChainId();\n this.checkPoll(this.state);\n this.ethQuery = new EthQuery(provider);\n });\n\n this.subscribe((currentState: any) => this.checkPoll(currentState));\n this.eventEmitter = new EventEmitter();\n }\n\n async _executePoll(networkClientId: string): Promise<void> {\n // if this is going to be truly UI driven polling we shouldn't really reach here\n // with a networkClientId that is not supported, but for now I'll add a check in case\n // wondering if we should add some kind of predicate to the polling controller to check whether\n // we should poll or not\n const chainId = this.#getChainId({ networkClientId });\n if (!this.config.supportedChainIds.includes(chainId)) {\n return Promise.resolve();\n }\n return this.updateSmartTransactions({ networkClientId });\n }\n\n checkPoll(state: any) {\n const { smartTransactions } = state.smartTransactionsState;\n const currentSmartTransactions = smartTransactions[this.config.chainId];\n const pendingTransactions = currentSmartTransactions?.filter(\n isSmartTransactionPending,\n );\n if (!this.timeoutHandle && pendingTransactions?.length > 0) {\n this.poll();\n } else if (this.timeoutHandle && pendingTransactions?.length === 0) {\n this.stop();\n }\n }\n\n initializeSmartTransactionsForChainId() {\n if (this.config.supportedChainIds.includes(this.config.chainId)) {\n const { smartTransactionsState } = this.state;\n this.update({\n smartTransactionsState: {\n ...smartTransactionsState,\n smartTransactions: {\n ...smartTransactionsState.smartTransactions,\n [this.config.chainId]:\n smartTransactionsState.smartTransactions[this.config.chainId] ??\n [],\n },\n },\n });\n }\n }\n\n async poll(interval?: number): Promise<void> {\n const { chainId, supportedChainIds } = this.config;\n interval && this.configure({ interval }, false, false);\n this.timeoutHandle && clearInterval(this.timeoutHandle);\n if (!supportedChainIds.includes(chainId)) {\n return;\n }\n await safelyExecute(async () => this.updateSmartTransactions());\n this.timeoutHandle = setInterval(() => {\n safelyExecute(async () => this.updateSmartTransactions());\n }, this.config.interval);\n }\n\n async stop() {\n this.timeoutHandle && clearInterval(this.timeoutHandle);\n this.timeoutHandle = undefined;\n }\n\n setOptInState(state: boolean | undefined): void {\n this.update({\n smartTransactionsState: {\n ...this.state.smartTransactionsState,\n userOptInV2: state,\n },\n });\n }\n\n trackStxStatusChange(\n smartTransaction: SmartTransaction,\n prevSmartTransaction?: SmartTransaction,\n ) {\n if (!prevSmartTransaction) {\n return; // Don't track the first STX, because it doesn't have all necessary params.\n }\n\n let updatedSmartTransaction = cloneDeep(smartTransaction);\n updatedSmartTransaction = {\n ...cloneDeep(prevSmartTransaction),\n ...updatedSmartTransaction,\n };\n\n if (\n !updatedSmartTransaction.swapMetaData ||\n (updatedSmartTransaction.status === prevSmartTransaction.status &&\n prevSmartTransaction.swapMetaData)\n ) {\n return; // If status hasn't changed, don't track it again.\n }\n\n const sensitiveProperties = {\n stx_status: updatedSmartTransaction.status,\n token_from_symbol: updatedSmartTransaction.sourceTokenSymbol,\n token_to_symbol: updatedSmartTransaction.destinationTokenSymbol,\n processing_time: getStxProcessingTime(updatedSmartTransaction.time),\n stx_enabled: true,\n current_stx_enabled: true,\n stx_user_opt_in: true,\n };\n\n this.trackMetaMetricsEvent({\n event: MetaMetricsEventName.StxStatusUpdated,\n category: MetaMetricsEventCategory.Transactions,\n sensitiveProperties,\n });\n }\n\n isNewSmartTransaction(smartTransactionUuid: string): boolean {\n const { chainId } = this.config;\n const { smartTransactionsState } = this.state;\n const { smartTransactions } = smartTransactionsState;\n const currentSmartTransactions = smartTransactions[chainId];\n const currentIndex = currentSmartTransactions?.findIndex(\n (stx) => stx.uuid === smartTransactionUuid,\n );\n return currentIndex === -1 || currentIndex === undefined;\n }\n\n updateSmartTransaction(\n smartTransaction: SmartTransaction,\n { networkClientId }: { networkClientId?: NetworkClientId } = {},\n ) {\n let {\n ethQuery,\n config: { chainId },\n } = this;\n if (networkClientId) {\n const networkClient = this.getNetworkClientById(networkClientId);\n chainId = networkClient.configuration.chainId;\n ethQuery = new EthQuery(networkClient.provider);\n }\n\n this.#updateSmartTransaction(smartTransaction, {\n chainId,\n ethQuery,\n });\n }\n\n async #updateSmartTransaction(\n smartTransaction: SmartTransaction,\n {\n chainId = this.config.chainId,\n ethQuery = this.ethQuery,\n }: {\n chainId: Hex;\n ethQuery: EthQuery | undefined;\n },\n ): Promise<void> {\n const { smartTransactionsState } = this.state;\n const { smartTransactions } = smartTransactionsState;\n const currentSmartTransactions = smartTransactions[chainId] ?? [];\n const currentIndex = currentSmartTransactions?.findIndex(\n (stx) => stx.uuid === smartTransaction.uuid,\n );\n const isNewSmartTransaction = this.isNewSmartTransaction(\n smartTransaction.uuid,\n );\n if (this.ethQuery === undefined) {\n throw new Error(ETH_QUERY_ERROR_MSG);\n }\n\n this.trackStxStatusChange(\n smartTransaction,\n isNewSmartTransaction\n ? undefined\n : currentSmartTransactions[currentIndex],\n );\n\n if (isNewSmartTransaction) {\n // add smart transaction\n const cancelledNonceIndex = currentSmartTransactions?.findIndex(\n (stx: SmartTransaction) =>\n stx.txParams?.nonce === smartTransaction.txParams?.nonce &&\n stx.status?.startsWith('cancelled'),\n );\n const snapshot = cloneDeep(smartTransaction);\n const history = [snapshot];\n const historifiedSmartTransaction = { ...smartTransaction, history };\n const nextSmartTransactions =\n cancelledNonceIndex > -1\n ? currentSmartTransactions\n .slice(0, cancelledNonceIndex)\n .concat(currentSmartTransactions.slice(cancelledNonceIndex + 1))\n .concat(historifiedSmartTransaction)\n : currentSmartTransactions.concat(historifiedSmartTransaction);\n this.update({\n smartTransactionsState: {\n ...smartTransactionsState,\n smartTransactions: {\n ...smartTransactionsState.smartTransactions,\n [chainId]: nextSmartTransactions,\n },\n },\n });\n return;\n }\n\n if (\n (smartTransaction.status === SmartTransactionStatuses.SUCCESS ||\n smartTransaction.status === SmartTransactionStatuses.REVERTED) &&\n !smartTransaction.confirmed\n ) {\n // confirm smart transaction\n const currentSmartTransaction = currentSmartTransactions[currentIndex];\n const nextSmartTransaction = {\n ...currentSmartTransaction,\n ...smartTransaction,\n };\n await this.#confirmSmartTransaction(nextSmartTransaction, {\n chainId,\n ethQuery,\n });\n } else {\n this.update({\n smartTransactionsState: {\n ...smartTransactionsState,\n smartTransactions: {\n ...smartTransactionsState.smartTransactions,\n [chainId]: smartTransactionsState.smartTransactions[chainId].map(\n (item, index) => {\n return index === currentIndex\n ? { ...item, ...smartTransaction }\n : item;\n },\n ),\n },\n },\n });\n }\n\n this.eventEmitter.emit(\n `${smartTransaction.uuid}:smartTransaction`,\n smartTransaction,\n );\n }\n\n async updateSmartTransactions({\n networkClientId,\n }: {\n networkClientId?: NetworkClientId;\n } = {}): Promise<void> {\n const { smartTransactions } = this.state.smartTransactionsState;\n const chainId = this.#getChainId({ networkClientId });\n const smartTransactionsForChainId = smartTransactions[chainId];\n\n const transactionsToUpdate: string[] = smartTransactionsForChainId\n .filter(isSmartTransactionPending)\n .map((smartTransaction) => smartTransaction.uuid);\n\n if (transactionsToUpdate.length > 0) {\n this.fetchSmartTransactionsStatus(transactionsToUpdate, {\n networkClientId,\n });\n }\n }\n\n #doesTransactionNeedConfirmation(txHash: string | undefined): boolean {\n if (!txHash) {\n return true;\n }\n const transactions = this.getRegularTransactions();\n const foundTransaction = transactions?.find((tx) => {\n return tx.hash?.toLowerCase() === txHash.toLowerCase();\n });\n if (!foundTransaction) {\n return true;\n }\n // If a found transaction is either confirmed or submitted, it doesn't need confirmation from the STX controller.\n // When it's in the submitted state, the TransactionController checks its status and confirms it,\n // so no need to confirm it again here.\n return ![TransactionStatus.confirmed, TransactionStatus.submitted].includes(\n foundTransaction.status,\n );\n }\n\n async #confirmSmartTransaction(\n smartTransaction: SmartTransaction,\n {\n chainId = this.config.chainId,\n ethQuery = this.ethQuery,\n }: {\n chainId: Hex;\n ethQuery: EthQuery | undefined;\n },\n ) {\n if (ethQuery === undefined) {\n throw new Error(ETH_QUERY_ERROR_MSG);\n }\n const txHash = smartTransaction.statusMetadata?.minedHash;\n try {\n const transactionReceipt: {\n maxFeePerGas?: string;\n maxPriorityFeePerGas?: string;\n blockNumber: string;\n } | null = await query(ethQuery, 'getTransactionReceipt', [txHash]);\n const transaction: {\n maxFeePerGas?: string;\n maxPriorityFeePerGas?: string;\n } | null = await query(ethQuery, 'getTransactionByHash', [txHash]);\n\n const maxFeePerGas = transaction?.maxFeePerGas;\n const maxPriorityFeePerGas = transaction?.maxPriorityFeePerGas;\n if (transactionReceipt?.blockNumber) {\n const blockData: { baseFeePerGas?: string } | null = await query(\n ethQuery,\n 'getBlockByNumber',\n [transactionReceipt?.blockNumber, false],\n );\n const baseFeePerGas = blockData?.baseFeePerGas;\n const updatedTxParams = {\n ...smartTransaction.txParams,\n maxFeePerGas,\n maxPriorityFeePerGas,\n };\n // call confirmExternalTransaction\n const originalTxMeta = {\n ...smartTransaction,\n id: smartTransaction.uuid,\n status: TransactionStatus.confirmed,\n hash: txHash,\n txParams: updatedTxParams,\n };\n // create txMeta snapshot for history\n const snapshot = snapshotFromTxMeta(originalTxMeta);\n // recover previous tx state obj\n const previousState = replayHistory(originalTxMeta.history);\n // generate history entry and add to history\n const entry = generateHistoryEntry(\n previousState,\n snapshot,\n 'txStateManager: setting status to confirmed',\n );\n const txMeta =\n entry.length > 0\n ? {\n ...originalTxMeta,\n history: originalTxMeta.history.concat(entry),\n }\n : originalTxMeta;\n\n if (this.#doesTransactionNeedConfirmation(txHash)) {\n this.confirmExternalTransaction(\n txMeta,\n transactionReceipt,\n baseFeePerGas,\n );\n }\n\n this.trackMetaMetricsEvent({\n event: MetaMetricsEventName.StxConfirmed,\n category: MetaMetricsEventCategory.Transactions,\n });\n\n this.#updateSmartTransaction(\n {\n ...smartTransaction,\n confirmed: true,\n },\n { chainId, ethQuery },\n );\n }\n } catch (error) {\n this.trackMetaMetricsEvent({\n event: MetaMetricsEventName.StxConfirmationFailed,\n category: MetaMetricsEventCategory.Transactions,\n });\n console.error('confirm error', error);\n }\n }\n\n // ! Ask backend API to accept list of uuids as params\n async fetchSmartTransactionsStatus(\n uuids: string[],\n { networkClientId }: { networkClientId?: NetworkClientId } = {},\n ): Promise<Record<string, SmartTransactionsStatus>> {\n const params = new URLSearchParams({\n uuids: uuids.join(','),\n });\n const chainId = this.#getChainId({ networkClientId });\n const ethQuery = this.#getEthQuery({ networkClientId });\n const url = `${getAPIRequestURL(\n APIType.BATCH_STATUS,\n chainId,\n )}?${params.toString()}`;\n\n const data = (await this.fetch(url)) as Record<\n string,\n SmartTransactionsStatus\n >;\n\n Object.entries(data).forEach(([uuid, stxStatus]) => {\n const smartTransaction = {\n statusMetadata: stxStatus,\n status: calculateStatus(stxStatus),\n cancellable: isSmartTransactionCancellable(stxStatus),\n uuid,\n };\n this.#updateSmartTransaction(smartTransaction, { chainId, ethQuery });\n });\n\n return data;\n }\n\n async addNonceToTransaction(\n transaction: UnsignedTransaction,\n ): Promise<UnsignedTransaction> {\n const nonceLock = await this.getNonceLock(transaction.from);\n const nonce = nonceLock.nextNonce;\n nonceLock.releaseLock();\n return {\n ...transaction,\n nonce: `0x${nonce.toString(16)}`,\n };\n }\n\n clearFees(): Fees {\n const fees = {\n approvalTxFees: undefined,\n tradeTxFees: undefined,\n };\n this.update({\n smartTransactionsState: {\n ...this.state.smartTransactionsState,\n fees,\n },\n });\n return fees;\n }\n\n async getFees(\n tradeTx: UnsignedTransaction,\n approvalTx?: UnsignedTransaction,\n { networkClientId }: { networkClientId?: NetworkClientId } = {},\n ): Promise<Fees> {\n const chainId = this.#getChainId({ networkClientId });\n const transactions = [];\n let unsignedTradeTransactionWithNonce;\n if (approvalTx) {\n const unsignedApprovalTransactionWithNonce =\n await this.addNonceToTransaction(approvalTx);\n transactions.push(unsignedApprovalTransactionWithNonce);\n unsignedTradeTransactionWithNonce = {\n ...tradeTx,\n // If there is an approval tx, the trade tx's nonce is increased by 1.\n nonce: incrementNonceInHex(unsignedApprovalTransactionWithNonce.nonce),\n };\n } else if (tradeTx.nonce) {\n unsignedTradeTransactionWithNonce = tradeTx;\n } else {\n unsignedTradeTransactionWithNonce = await this.addNonceToTransaction(\n tradeTx,\n );\n }\n transactions.push(unsignedTradeTransactionWithNonce);\n const data = await this.fetch(getAPIRequestURL(APIType.GET_FEES, chainId), {\n method: 'POST',\n body: JSON.stringify({\n txs: transactions,\n }),\n });\n let approvalTxFees;\n let tradeTxFees;\n if (approvalTx) {\n approvalTxFees = data?.txs[0];\n tradeTxFees = data?.txs[1];\n } else {\n tradeTxFees = data?.txs[0];\n }\n\n this.update({\n smartTransactionsState: {\n ...this.state.smartTransactionsState,\n ...(chainId === this.config.chainId && {\n fees: {\n approvalTxFees,\n tradeTxFees,\n },\n }),\n feesByChainId: {\n ...this.state.smartTransactionsState.feesByChainId,\n [chainId]: {\n approvalTxFees,\n tradeTxFees,\n },\n },\n },\n });\n\n return {\n approvalTxFees,\n tradeTxFees,\n };\n }\n\n // * After this successful call client must add a nonce representative to\n // * transaction controller external transactions list\n async submitSignedTransactions({\n transactionMeta,\n txParams,\n signedTransactions,\n signedCanceledTransactions,\n networkClientId,\n }: {\n signedTransactions: SignedTransaction[];\n signedCanceledTransactions: SignedCanceledTransaction[];\n transactionMeta?: any;\n txParams?: any;\n networkClientId?: NetworkClientId;\n }) {\n const chainId = this.#getChainId({ networkClientId });\n const ethQuery = this.#getEthQuery({ networkClientId });\n const data = await this.fetch(\n getAPIRequestURL(APIType.SUBMIT_TRANSACTIONS, chainId),\n {\n method: 'POST',\n body: JSON.stringify({\n rawTxs: signedTransactions,\n rawCancelTxs: signedCanceledTransactions,\n }),\n },\n );\n const time = Date.now();\n let preTxBalance;\n try {\n const preTxBalanceBN = await query(ethQuery, 'getBalance', [\n txParams?.from,\n ]);\n preTxBalance = new BigNumber(preTxBalanceBN).toString(16);\n } catch (error) {\n console.error('provider error', error);\n }\n\n const requiresNonce = !txParams.nonce;\n let nonce;\n let nonceLock;\n let nonceDetails = {};\n\n if (requiresNonce) {\n nonceLock = await this.getNonceLock(txParams?.from);\n nonce = hexlify(nonceLock.nextNonce);\n nonceDetails = nonceLock.nonceDetails;\n if (txParams) {\n txParams.nonce ??= nonce;\n }\n }\n const submitTransactionResponse = {\n ...data,\n txHash: getTxHash(signedTransactions[0]),\n };\n\n try {\n this.#updateSmartTransaction(\n {\n chainId,\n nonceDetails,\n preTxBalance,\n status: SmartTransactionStatuses.PENDING,\n time,\n txParams,\n uuid: submitTransactionResponse.uuid,\n txHash: submitTransactionResponse.txHash,\n cancellable: true,\n type: transactionMeta?.type || 'swap',\n },\n { chainId, ethQuery },\n );\n } finally {\n nonceLock?.releaseLock();\n }\n\n return submitTransactionResponse;\n }\n\n #getChainId({\n networkClientId,\n }: { networkClientId?: NetworkClientId } = {}): Hex {\n return networkClientId\n ? this.getNetworkClientById(networkClientId).configuration.chainId\n : this.config.chainId;\n }\n\n #getEthQuery({\n networkClientId,\n }: {\n networkClientId?: NetworkClientId;\n } = {}): EthQuery {\n if (networkClientId) {\n return new EthQuery(this.getNetworkClientById(networkClientId).provider);\n }\n\n if (this.ethQuery === undefined) {\n throw new Error(ETH_QUERY_ERROR_MSG);\n }\n\n return this.ethQuery;\n }\n\n // TODO: This should return if the cancellation was on chain or not (for nonce management)\n // After this successful call client must update nonce representative\n // in transaction controller external transactions list\n async cancelSmartTransaction(\n uuid: string,\n {\n networkClientId,\n }: {\n networkClientId?: NetworkClientId;\n } = {},\n ): Promise<void> {\n const chainId = this.#getChainId({ networkClientId });\n await this.fetch(getAPIRequestURL(APIType.CANCEL, chainId), {\n method: 'POST',\n body: JSON.stringify({ uuid }),\n });\n }\n\n async fetchLiveness({\n networkClientId,\n }: {\n networkClientId?: NetworkClientId;\n } = {}): Promise<boolean> {\n const chainId = this.#getChainId({ networkClientId });\n let liveness = false;\n try {\n const response = await this.fetch(\n getAPIRequestURL(APIType.LIVENESS, chainId),\n );\n liveness = Boolean(response.lastBlock);\n } catch (error) {\n console.log('\"fetchLiveness\" API call failed');\n }\n\n this.update({\n smartTransactionsState: {\n ...this.state.smartTransactionsState,\n ...(chainId === this.config.chainId && { liveness }),\n livenessByChainId: {\n ...this.state.smartTransactionsState.livenessByChainId,\n [chainId]: liveness,\n },\n },\n });\n\n return liveness;\n }\n\n async setStatusRefreshInterval(interval: number): Promise<void> {\n if (interval !== this.config.interval) {\n this.configure({ interval }, false, false);\n }\n }\n\n getTransactions({\n addressFrom,\n status,\n }: {\n addressFrom: string;\n status: SmartTransactionStatuses;\n }): SmartTransaction[] {\n const { smartTransactions } = this.state.smartTransactionsState;\n const { chainId } = this.config;\n const currentSmartTransactions = smartTransactions?.[chainId];\n if (!currentSmartTransactions || currentSmartTransactions.length === 0) {\n return [];\n }\n\n return currentSmartTransactions.filter((stx) => {\n return stx.status === status && stx.txParams?.from === addressFrom;\n });\n }\n}\n"]}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { TransactionMeta } from '@metamask/transaction-controller';
|
|
1
2
|
/** API */
|
|
2
3
|
export declare enum APIType {
|
|
3
4
|
'GET_FEES' = 0,
|
|
@@ -51,7 +52,7 @@ export declare type SmartTransactionsStatus = {
|
|
|
51
52
|
cancellationFeeWei: number;
|
|
52
53
|
cancellationReason?: SmartTransactionCancellationReason;
|
|
53
54
|
deadlineRatio: number;
|
|
54
|
-
minedHash: string
|
|
55
|
+
minedHash: string;
|
|
55
56
|
minedTx: SmartTransactionMinedTx;
|
|
56
57
|
isSettled: boolean;
|
|
57
58
|
};
|
|
@@ -97,3 +98,9 @@ export declare type UnsignedTransaction = any;
|
|
|
97
98
|
export declare type SignedTransaction = any;
|
|
98
99
|
export declare type SignedCanceledTransaction = any;
|
|
99
100
|
export declare type Hex = `0x${string}`;
|
|
101
|
+
export declare type GetTransactionsOptions = {
|
|
102
|
+
searchCriteria?: any;
|
|
103
|
+
initialList?: TransactionMeta[];
|
|
104
|
+
filterToCurrentNetwork?: boolean;
|
|
105
|
+
limit?: number;
|
|
106
|
+
};
|
package/dist/types.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
/** API */
|
|
3
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
3
|
exports.cancellationReasonToStatusMap = exports.SmartTransactionStatuses = exports.SmartTransactionCancellationReason = exports.SmartTransactionMinedTx = exports.APIType = void 0;
|
|
4
|
+
/** API */
|
|
5
5
|
var APIType;
|
|
6
6
|
(function (APIType) {
|
|
7
7
|
APIType[APIType["GET_FEES"] = 0] = "GET_FEES";
|
package/dist/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";;;AAEA,UAAU;AACV,IAAY,OAOX;AAPD,WAAY,OAAO;IACjB,6CAAU,CAAA;IACV,qDAAc,CAAA;IACd,mEAAqB,CAAA;IACrB,yCAAQ,CAAA;IACR,qDAAc,CAAA;IACd,6CAAU,CAAA;AACZ,CAAC,EAPW,OAAO,GAAP,eAAO,KAAP,eAAO,QAOlB;AAED,wBAAwB;AACxB,IAAY,uBAMX;AAND,WAAY,uBAAuB;IACjC,kDAAuB,CAAA;IACvB,8CAAmB,CAAA;IACnB,kDAAuB,CAAA;IACvB,gDAAqB,CAAA;IACrB,8CAAmB,CAAA;AACrB,CAAC,EANW,uBAAuB,GAAvB,+BAAuB,KAAvB,+BAAuB,QAMlC;AAED,IAAY,kCAQX;AARD,WAAY,kCAAkC;IAC5C,mEAA6B,CAAA;IAC7B,6DAAuB,CAAA;IACvB,yEAAmC,CAAA;IACnC,qEAA+B,CAAA;IAC/B,uEAAiC,CAAA;IACjC,qEAA+B,CAAA;IAC/B,qFAA+C,CAAA;AACjD,CAAC,EARW,kCAAkC,GAAlC,0CAAkC,KAAlC,0CAAkC,QAQ7C;AAED,IAAY,wBAaX;AAbD,WAAY,wBAAwB;IAClC,+CAAmB,CAAA;IACnB,+CAAmB,CAAA;IACnB,iDAAqB,CAAA;IACrB,+CAAmB,CAAA;IACnB,mDAAuB,CAAA;IACvB,6EAAiD,CAAA;IACjD,uEAA2C,CAAA;IAC3C,mFAAuD,CAAA;IACvD,+EAAmD,CAAA;IACnD,iFAAqD,CAAA;IACrD,+FAAmE,CAAA;IACnE,iDAAqB,CAAA;AACvB,CAAC,EAbW,wBAAwB,GAAxB,gCAAwB,KAAxB,gCAAwB,QAanC;AAEY,QAAA,6BAA6B,GAAG;IAC3C,CAAC,kCAAkC,CAAC,YAAY,CAAC,EAC/C,wBAAwB,CAAC,sBAAsB;IACjD,CAAC,kCAAkC,CAAC,SAAS,CAAC,EAC5C,wBAAwB,CAAC,mBAAmB;IAC9C,CAAC,kCAAkC,CAAC,eAAe,CAAC,EAClD,wBAAwB,CAAC,yBAAyB;IACpD,CAAC,kCAAkC,CAAC,aAAa,CAAC,EAChD,wBAAwB,CAAC,uBAAuB;IAClD,CAAC,kCAAkC,CAAC,cAAc,CAAC,EACjD,wBAAwB,CAAC,wBAAwB;IACnD,CAAC,kCAAkC,CAAC,qBAAqB,CAAC,EACxD,wBAAwB,CAAC,+BAA+B;CAC3D,CAAC","sourcesContent":["import type { TransactionMeta } from '@metamask/transaction-controller';\n\n/** API */\nexport enum APIType {\n 'GET_FEES',\n 'ESTIMATE_GAS',\n 'SUBMIT_TRANSACTIONS',\n 'CANCEL',\n 'BATCH_STATUS',\n 'LIVENESS',\n}\n\n/** SmartTransactions */\nexport enum SmartTransactionMinedTx {\n NOT_MINED = 'not_mined',\n SUCCESS = 'success',\n CANCELLED = 'cancelled',\n REVERTED = 'reverted',\n UNKNOWN = 'unknown',\n}\n\nexport enum SmartTransactionCancellationReason {\n WOULD_REVERT = 'would_revert',\n TOO_CHEAP = 'too_cheap',\n DEADLINE_MISSED = 'deadline_missed',\n INVALID_NONCE = 'invalid_nonce',\n USER_CANCELLED = 'user_cancelled',\n NOT_CANCELLED = 'not_cancelled',\n PREVIOUS_TX_CANCELLED = 'previous_tx_cancelled',\n}\n\nexport enum SmartTransactionStatuses {\n PENDING = 'pending',\n SUCCESS = 'success',\n REVERTED = 'reverted',\n UNKNOWN = 'unknown',\n CANCELLED = 'cancelled',\n CANCELLED_WOULD_REVERT = 'cancelled_would_revert',\n CANCELLED_TOO_CHEAP = 'cancelled_too_cheap',\n CANCELLED_DEADLINE_MISSED = 'cancelled_deadline_missed',\n CANCELLED_INVALID_NONCE = 'cancelled_invalid_nonce',\n CANCELLED_USER_CANCELLED = 'cancelled_user_cancelled',\n CANCELLED_PREVIOUS_TX_CANCELLED = 'cancelled_previous_tx_cancelled',\n RESOLVED = 'resolved',\n}\n\nexport const cancellationReasonToStatusMap = {\n [SmartTransactionCancellationReason.WOULD_REVERT]:\n SmartTransactionStatuses.CANCELLED_WOULD_REVERT,\n [SmartTransactionCancellationReason.TOO_CHEAP]:\n SmartTransactionStatuses.CANCELLED_TOO_CHEAP,\n [SmartTransactionCancellationReason.DEADLINE_MISSED]:\n SmartTransactionStatuses.CANCELLED_DEADLINE_MISSED,\n [SmartTransactionCancellationReason.INVALID_NONCE]:\n SmartTransactionStatuses.CANCELLED_INVALID_NONCE,\n [SmartTransactionCancellationReason.USER_CANCELLED]:\n SmartTransactionStatuses.CANCELLED_USER_CANCELLED,\n [SmartTransactionCancellationReason.PREVIOUS_TX_CANCELLED]:\n SmartTransactionStatuses.CANCELLED_PREVIOUS_TX_CANCELLED,\n};\n\nexport type SmartTransactionsStatus = {\n error?: string;\n cancellationFeeWei: number;\n cancellationReason?: SmartTransactionCancellationReason;\n deadlineRatio: number;\n minedHash: string;\n minedTx: SmartTransactionMinedTx;\n isSettled: boolean;\n};\n\nexport type SmartTransaction = {\n uuid: string;\n txHash?: string;\n chainId?: string;\n destinationTokenAddress?: string;\n destinationTokenDecimals?: string;\n destinationTokenSymbol?: string;\n history?: any;\n nonceDetails?: any;\n origin?: string;\n preTxBalance?: string;\n status?: string;\n statusMetadata?: SmartTransactionsStatus;\n sourceTokenSymbol?: string;\n swapMetaData?: any;\n swapTokenValue?: string;\n time?: number; // @deprecated We should use creationTime instead.\n creationTime?: number;\n txParams?: any;\n type?: string;\n confirmed?: boolean;\n cancellable?: boolean;\n};\n\nexport type Fee = {\n maxFeePerGas: number;\n maxPriorityFeePerGas: number;\n};\n\nexport type IndividualTxFees = {\n fees: Fee[];\n cancelFees: Fee[];\n feeEstimate: number;\n gasLimit: number;\n gasUsed: number;\n};\n\nexport type Fees = {\n approvalTxFees: IndividualTxFees | undefined;\n tradeTxFees: IndividualTxFees | undefined;\n};\n\n// TODO\nexport type UnsignedTransaction = any;\n\n// TODO\nexport type SignedTransaction = any;\n\n// TODO\nexport type SignedCanceledTransaction = any;\n\nexport type Hex = `0x${string}`;\n\nexport type GetTransactionsOptions = {\n searchCriteria?: any;\n initialList?: TransactionMeta[];\n filterToCurrentNetwork?: boolean;\n limit?: number;\n};\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@metamask/smart-transactions-controller",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "8.0.0",
|
|
4
4
|
"description": "Improves success rates for swaps by trialing transactions privately and finding minimum fees",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
"test:watch": "jest --watchAll"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
+
"@babel/runtime": "^7.24.1",
|
|
28
29
|
"@ethereumjs/tx": "^5.2.1",
|
|
29
30
|
"@ethereumjs/util": "^9.0.2",
|
|
30
31
|
"@ethersproject/bytes": "^5.7.0",
|
|
@@ -33,6 +34,7 @@
|
|
|
33
34
|
"@metamask/eth-query": "^4.0.0",
|
|
34
35
|
"@metamask/network-controller": "^17.2.0",
|
|
35
36
|
"@metamask/polling-controller": "^5.0.0",
|
|
37
|
+
"@metamask/transaction-controller": "^25.1.0",
|
|
36
38
|
"bignumber.js": "^9.0.1",
|
|
37
39
|
"events": "^3.3.0",
|
|
38
40
|
"fast-json-patch": "^3.1.0",
|
|
@@ -47,7 +49,7 @@
|
|
|
47
49
|
"@metamask/eslint-config-typescript": "^12.1.0",
|
|
48
50
|
"@types/jest": "^26.0.24",
|
|
49
51
|
"@types/lodash": "^4.14.194",
|
|
50
|
-
"@types/node": "^
|
|
52
|
+
"@types/node": "^18.19.17",
|
|
51
53
|
"@types/sinon": "^9.0.10",
|
|
52
54
|
"@typescript-eslint/eslint-plugin": "^5.33.0",
|
|
53
55
|
"@typescript-eslint/parser": "^5.33.0",
|