@metamask/smart-transactions-controller 1.4.0 → 1.10.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 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
+ ## [1.10.0]
10
+ ### Added
11
+ - Handle the "cancelled" status, lower status polling interval from 10s to 5s, don't mark a tx as cancelled immediately, track uuid ([#63](https://github.com/MetaMask/smart-transactions-controller/pull/63))
12
+ - chore(deps): bump @metamask/controllers from 25.1.0 to 27.1.1 ([#62](https://github.com/MetaMask/smart-transactions-controller/pull/62))
13
+ - Add tracking of the "current_stx_enabled" param ([#58](https://github.com/MetaMask/smart-transactions-controller/pull/58))
14
+
15
+ ## [1.9.1]
16
+ ### Added
17
+ - Use the "confirmExternalTransaction" fn directly ([#56](https://github.com/MetaMask/smart-transactions-controller/pull/56))
18
+
19
+ ## [1.9.0]
20
+ ### Added
21
+ - Only accept the "getNonceLock" fn and not the whole "nonceTracker" ([#54](https://github.com/MetaMask/smart-transactions-controller/pull/54))
22
+
23
+ ## [1.8.0]
24
+ ### Added
25
+ - Do not update an STX which doesn't exist anymore, add UTs ([#52](https://github.com/MetaMask/smart-transactions-controller/pull/52))
26
+
27
+ ## [1.7.0]
28
+ ### Added
29
+ - Fix UTs, change threshold ([#49](https://github.com/MetaMask/smart-transactions-controller/pull/49))
30
+
31
+ ## [1.6.0]
32
+ ### Added
33
+ - Change cancellable interval to be 1 minute ([#47](https://github.com/MetaMask/smart-transactions-controller/pull/47))
34
+ - Estimate approval transaction along with swaps transaction ([#46](https://github.com/MetaMask/smart-transactions-controller/pull/46))
35
+ - chore(deps): bump @metamask/controllers from 20.1.0 to 25.1.0 ([#44](https://github.com/MetaMask/smart-transactions-controller/pull/44))
36
+ - Add support for approveTxParams ([#45](https://github.com/MetaMask/smart-transactions-controller/pull/45))
37
+ - Add method for estimateGas ([#43](https://github.com/MetaMask/smart-transactions-controller/pull/43))
38
+
39
+ ## [1.5.0]
40
+ ### Added
41
+ - Add "fees" and "liveness" into the smartTransactionsState, update version ([#41](https://github.com/MetaMask/smart-transactions-controller/pull/41))
42
+
9
43
  ## [1.4.0]
10
44
  ### Added
11
45
  - Add isomorphic-fetch to stx controller ([#38](https://github.com/MetaMask/smart-transactions-controller/pull/38))
@@ -47,7 +81,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
47
81
  - Add initial SmartTransactionsController ([#1](https://github.com/MetaMask/smart-transactions-controller/pull/1))
48
82
  - Initial commit
49
83
 
50
- [Unreleased]: https://github.com/MetaMask/smart-transactions-controller/compare/v1.4.0...HEAD
84
+ [Unreleased]: https://github.com/MetaMask/smart-transactions-controller/compare/v1.10.0...HEAD
85
+ [1.10.0]: https://github.com/MetaMask/smart-transactions-controller/compare/v1.9.1...v1.10.0
86
+ [1.9.1]: https://github.com/MetaMask/smart-transactions-controller/compare/v1.9.0...v1.9.1
87
+ [1.9.0]: https://github.com/MetaMask/smart-transactions-controller/compare/v1.8.0...v1.9.0
88
+ [1.8.0]: https://github.com/MetaMask/smart-transactions-controller/compare/v1.7.0...v1.8.0
89
+ [1.7.0]: https://github.com/MetaMask/smart-transactions-controller/compare/v1.6.0...v1.7.0
90
+ [1.6.0]: https://github.com/MetaMask/smart-transactions-controller/compare/v1.5.0...v1.6.0
91
+ [1.5.0]: https://github.com/MetaMask/smart-transactions-controller/compare/v1.4.0...v1.5.0
51
92
  [1.4.0]: https://github.com/MetaMask/smart-transactions-controller/compare/v1.3.0...v1.4.0
52
93
  [1.3.0]: https://github.com/MetaMask/smart-transactions-controller/compare/v1.2.0...v1.3.0
53
94
  [1.2.0]: https://github.com/MetaMask/smart-transactions-controller/compare/v1.1.0...v1.2.0
@@ -1,6 +1,6 @@
1
1
  /// <reference types="node" />
2
2
  import { BaseConfig, BaseController, BaseState, NetworkState } from '@metamask/controllers';
3
- import { SmartTransaction, SignedTransaction, SignedCanceledTransaction, UnsignedTransaction, SmartTransactionStatuses, Fee } from './types';
3
+ import { SmartTransaction, SignedTransaction, SignedCanceledTransaction, UnsignedTransaction, SmartTransactionStatuses, Fees, EstimatedGas } from './types';
4
4
  export declare const DEFAULT_INTERVAL: number;
5
5
  export declare const CANCELLABLE_INTERVAL: number;
6
6
  export interface SmartTransactionsControllerConfig extends BaseConfig {
@@ -13,22 +13,28 @@ export interface SmartTransactionsControllerState extends BaseState {
13
13
  smartTransactionsState: {
14
14
  smartTransactions: Record<string, SmartTransaction[]>;
15
15
  userOptIn: boolean | undefined;
16
+ liveness: boolean | undefined;
17
+ fees: Fees | undefined;
18
+ estimatedGas: {
19
+ txData: EstimatedGas | undefined;
20
+ approvalTxData: EstimatedGas | undefined;
21
+ };
16
22
  };
17
23
  }
18
24
  export default class SmartTransactionsController extends BaseController<SmartTransactionsControllerConfig, SmartTransactionsControllerState> {
19
25
  timeoutHandle?: NodeJS.Timeout;
20
- private nonceTracker;
26
+ private getNonceLock;
21
27
  private getNetwork;
22
28
  ethersProvider: any;
23
- txController: any;
29
+ confirmExternalTransaction: any;
24
30
  private trackMetaMetricsEvent;
25
31
  private fetch;
26
- constructor({ onNetworkStateChange, nonceTracker, getNetwork, provider, txController, trackMetaMetricsEvent, }: {
32
+ constructor({ onNetworkStateChange, getNonceLock, getNetwork, provider, confirmExternalTransaction, trackMetaMetricsEvent, }: {
27
33
  onNetworkStateChange: (listener: (networkState: NetworkState) => void) => void;
28
- nonceTracker: any;
34
+ getNonceLock: any;
29
35
  getNetwork: any;
30
36
  provider: any;
31
- txController: any;
37
+ confirmExternalTransaction: any;
32
38
  trackMetaMetricsEvent: any;
33
39
  }, config?: Partial<SmartTransactionsControllerConfig>, state?: Partial<SmartTransactionsControllerState>);
34
40
  checkPoll(state: any): void;
@@ -37,18 +43,14 @@ export default class SmartTransactionsController extends BaseController<SmartTra
37
43
  stop(): Promise<void>;
38
44
  setOptInState(state: boolean | undefined): void;
39
45
  trackStxStatusChange(smartTransaction: SmartTransaction, prevSmartTransaction?: SmartTransaction): void;
46
+ isNewSmartTransaction(smartTransactionUuid: string): boolean;
40
47
  updateSmartTransaction(smartTransaction: SmartTransaction): void;
41
48
  updateSmartTransactions(): Promise<void>;
42
49
  confirmSmartTransaction(smartTransaction: SmartTransaction): Promise<void>;
43
50
  fetchSmartTransactionsStatus(uuids: string[]): Promise<SmartTransaction[]>;
44
51
  addNonceToTransaction(transaction: UnsignedTransaction): Promise<UnsignedTransaction>;
45
- getFees(unsignedTransaction: UnsignedTransaction): Promise<{
46
- fees: Fee[];
47
- cancelFees: Fee[];
48
- feeEstimate: number;
49
- gasLimit: number;
50
- gasUsed: number;
51
- }>;
52
+ getFees(unsignedTransaction: UnsignedTransaction): Promise<Fees>;
53
+ estimateGas(unsignedTransaction: UnsignedTransaction, approveTxParams: UnsignedTransaction): Promise<EstimatedGas>;
52
54
  submitSignedTransactions({ txParams, signedTransactions, signedCanceledTransactions, }: {
53
55
  signedTransactions: SignedTransaction[];
54
56
  signedCanceledTransactions: SignedCanceledTransaction[];
@@ -16,10 +16,11 @@ const { safelyExecute } = controllers_1.util;
16
16
  // TODO: JSDoc all methods
17
17
  // TODO: Remove all comments (* ! ?)
18
18
  const SECOND = 1000;
19
- exports.DEFAULT_INTERVAL = SECOND * 10;
20
- exports.CANCELLABLE_INTERVAL = SECOND * 10.5;
19
+ const MINUTE = SECOND * 60;
20
+ exports.DEFAULT_INTERVAL = SECOND * 5;
21
+ exports.CANCELLABLE_INTERVAL = MINUTE;
21
22
  class SmartTransactionsController extends controllers_1.BaseController {
22
- constructor({ onNetworkStateChange, nonceTracker, getNetwork, provider, txController, trackMetaMetricsEvent, }, config, state) {
23
+ constructor({ onNetworkStateChange, getNonceLock, getNetwork, provider, confirmExternalTransaction, trackMetaMetricsEvent, }, config, state) {
23
24
  super(config, state);
24
25
  this.defaultConfig = {
25
26
  interval: exports.DEFAULT_INTERVAL,
@@ -31,12 +32,18 @@ class SmartTransactionsController extends controllers_1.BaseController {
31
32
  smartTransactionsState: {
32
33
  smartTransactions: {},
33
34
  userOptIn: undefined,
35
+ fees: undefined,
36
+ liveness: true,
37
+ estimatedGas: {
38
+ txData: undefined,
39
+ approvalTxData: undefined,
40
+ },
34
41
  },
35
42
  };
36
- this.nonceTracker = nonceTracker;
43
+ this.getNonceLock = getNonceLock;
37
44
  this.getNetwork = getNetwork;
38
45
  this.ethersProvider = new ethers_1.ethers.providers.Web3Provider(provider);
39
- this.txController = txController;
46
+ this.confirmExternalTransaction = confirmExternalTransaction;
40
47
  this.trackMetaMetricsEvent = trackMetaMetricsEvent;
41
48
  this.initialize();
42
49
  this.initializeSmartTransactionsForChainId();
@@ -109,6 +116,7 @@ class SmartTransactionsController extends controllers_1.BaseController {
109
116
  return; // If status hasn't changed, don't track it again.
110
117
  }
111
118
  const sensitiveProperties = {
119
+ uuid: updatedSmartTransaction.uuid,
112
120
  stx_status: updatedSmartTransaction.status,
113
121
  token_from_address: (_a = updatedSmartTransaction.txParams) === null || _a === void 0 ? void 0 : _a.from,
114
122
  token_from_symbol: updatedSmartTransaction.sourceTokenSymbol,
@@ -116,6 +124,7 @@ class SmartTransactionsController extends controllers_1.BaseController {
116
124
  token_to_symbol: updatedSmartTransaction.destinationTokenSymbol,
117
125
  processing_time: utils_1.getStxProcessingTime(updatedSmartTransaction.time),
118
126
  stx_enabled: true,
127
+ current_stx_enabled: true,
119
128
  stx_user_opt_in: true,
120
129
  };
121
130
  this.trackMetaMetricsEvent({
@@ -124,13 +133,21 @@ class SmartTransactionsController extends controllers_1.BaseController {
124
133
  sensitiveProperties,
125
134
  });
126
135
  }
136
+ isNewSmartTransaction(smartTransactionUuid) {
137
+ const { chainId } = this.config;
138
+ const { smartTransactionsState } = this.state;
139
+ const { smartTransactions } = smartTransactionsState;
140
+ const currentSmartTransactions = smartTransactions[chainId];
141
+ const currentIndex = currentSmartTransactions === null || currentSmartTransactions === void 0 ? void 0 : currentSmartTransactions.findIndex((stx) => stx.uuid === smartTransactionUuid);
142
+ return currentIndex === -1 || currentIndex === undefined;
143
+ }
127
144
  updateSmartTransaction(smartTransaction) {
128
145
  const { chainId } = this.config;
129
146
  const { smartTransactionsState } = this.state;
130
147
  const { smartTransactions } = smartTransactionsState;
131
148
  const currentSmartTransactions = smartTransactions[chainId];
132
- const currentIndex = currentSmartTransactions === null || currentSmartTransactions === void 0 ? void 0 : currentSmartTransactions.findIndex((st) => st.uuid === smartTransaction.uuid);
133
- const isNewSmartTransaction = currentIndex === -1 || currentIndex === undefined;
149
+ const currentIndex = currentSmartTransactions === null || currentSmartTransactions === void 0 ? void 0 : currentSmartTransactions.findIndex((stx) => stx.uuid === smartTransaction.uuid);
150
+ const isNewSmartTransaction = this.isNewSmartTransaction(smartTransaction.uuid);
134
151
  this.trackStxStatusChange(smartTransaction, isNewSmartTransaction
135
152
  ? undefined
136
153
  : currentSmartTransactions[currentIndex]);
@@ -210,7 +227,7 @@ class SmartTransactionsController extends controllers_1.BaseController {
210
227
  const entry = utils_1.generateHistoryEntry(previousState, snapshot, 'txStateManager: setting status to confirmed');
211
228
  const txMeta = entry.length > 0
212
229
  ? Object.assign(Object.assign({}, originalTxMeta), { history: originalTxMeta.history.concat(entry) }) : originalTxMeta;
213
- this.txController.confirmExternalTransaction(txMeta, txReceipt, baseFeePerGas);
230
+ this.confirmExternalTransaction(txMeta, txReceipt, baseFeePerGas);
214
231
  this.trackMetaMetricsEvent({
215
232
  event: 'STX Confirmed',
216
233
  category: 'swaps',
@@ -244,7 +261,7 @@ class SmartTransactionsController extends controllers_1.BaseController {
244
261
  return data;
245
262
  }
246
263
  async addNonceToTransaction(transaction) {
247
- const nonceLock = await this.nonceTracker.getNonceLock(transaction.from);
264
+ const nonceLock = await this.getNonceLock(transaction.from);
248
265
  const nonce = nonceLock.nextNonce;
249
266
  nonceLock.releaseLock();
250
267
  return Object.assign(Object.assign({}, transaction), { nonce: `0x${nonce.toString(16)}` });
@@ -254,7 +271,37 @@ class SmartTransactionsController extends controllers_1.BaseController {
254
271
  const unsignedTransactionWithNonce = await this.addNonceToTransaction(unsignedTransaction);
255
272
  const data = await this.fetch(utils_1.getAPIRequestURL(types_1.APIType.GET_FEES, chainId), {
256
273
  method: 'POST',
257
- body: JSON.stringify({ tx: unsignedTransactionWithNonce }),
274
+ body: JSON.stringify({
275
+ tx: unsignedTransactionWithNonce,
276
+ }),
277
+ });
278
+ this.update({
279
+ smartTransactionsState: Object.assign(Object.assign({}, this.state.smartTransactionsState), { fees: data }),
280
+ });
281
+ return data;
282
+ }
283
+ async estimateGas(unsignedTransaction, approveTxParams) {
284
+ const { chainId } = this.config;
285
+ let approvalTxData;
286
+ if (approveTxParams) {
287
+ const unsignedApprovalTransactionWithNonce = await this.addNonceToTransaction(approveTxParams);
288
+ approvalTxData = await this.fetch(utils_1.getAPIRequestURL(types_1.APIType.ESTIMATE_GAS, chainId), {
289
+ method: 'POST',
290
+ body: JSON.stringify({
291
+ tx: unsignedApprovalTransactionWithNonce,
292
+ }),
293
+ });
294
+ }
295
+ const unsignedTransactionWithNonce = await this.addNonceToTransaction(unsignedTransaction);
296
+ const data = await this.fetch(utils_1.getAPIRequestURL(types_1.APIType.ESTIMATE_GAS, chainId), {
297
+ method: 'POST',
298
+ body: JSON.stringify(Object.assign({ tx: unsignedTransactionWithNonce }, (approveTxParams && { pending_txs: [approveTxParams] }))),
299
+ });
300
+ this.update({
301
+ smartTransactionsState: Object.assign(Object.assign({}, this.state.smartTransactionsState), { estimatedGas: {
302
+ txData: data,
303
+ approvalTxData,
304
+ } }),
258
305
  });
259
306
  return data;
260
307
  }
@@ -279,7 +326,7 @@ class SmartTransactionsController extends controllers_1.BaseController {
279
326
  catch (e) {
280
327
  console.error('ethers error', e);
281
328
  }
282
- const nonceLock = await this.nonceTracker.getNonceLock(txParams === null || txParams === void 0 ? void 0 : txParams.from);
329
+ const nonceLock = await this.getNonceLock(txParams === null || txParams === void 0 ? void 0 : txParams.from);
283
330
  const nonce = ethers_1.ethers.utils.hexlify(nonceLock.nextNonce);
284
331
  if (txParams && !(txParams === null || txParams === void 0 ? void 0 : txParams.nonce)) {
285
332
  txParams.nonce = nonce;
@@ -297,33 +344,44 @@ class SmartTransactionsController extends controllers_1.BaseController {
297
344
  cancellable: true,
298
345
  });
299
346
  setTimeout(() => {
300
- this.updateSmartTransaction({
301
- uuid: data.uuid,
302
- cancellable: false,
303
- });
347
+ if (!this.isNewSmartTransaction(data.uuid)) {
348
+ // Only do this for an existing smart transaction. If an STX is not in the list anymore
349
+ // (e.g. because it was cancelled and a new one was submitted, which deletes the first one),
350
+ // do not try to update the old one, because it would create a new one with most
351
+ // of the required STX params missing. It would only have "uuid" and "cancellable" params.
352
+ this.updateSmartTransaction({
353
+ uuid: data.uuid,
354
+ cancellable: false,
355
+ });
356
+ }
304
357
  }, exports.CANCELLABLE_INTERVAL);
305
358
  nonceLock.releaseLock();
306
359
  return data;
307
360
  }
308
- // ! This should return if the cancellation was on chain or not (for nonce management)
309
- // * After this successful call client must update nonce representative
310
- // * in transaction controller external transactions list
311
- // ! Ask backend API to make this endpoint a POST
361
+ // TODO: This should return if the cancellation was on chain or not (for nonce management)
362
+ // After this successful call client must update nonce representative
363
+ // in transaction controller external transactions list
312
364
  async cancelSmartTransaction(uuid) {
313
365
  const { chainId } = this.config;
314
366
  await this.fetch(utils_1.getAPIRequestURL(types_1.APIType.CANCEL, chainId), {
315
367
  method: 'POST',
316
368
  body: JSON.stringify({ uuid }),
317
369
  });
318
- this.updateSmartTransaction({
319
- uuid,
320
- status: types_1.SmartTransactionStatuses.CANCELLED_USER_CANCELLED,
321
- });
322
370
  }
323
371
  async fetchLiveness() {
324
372
  const { chainId } = this.config;
325
- const response = await this.fetch(utils_1.getAPIRequestURL(types_1.APIType.LIVENESS, chainId));
326
- return Boolean(response.lastBlock);
373
+ let liveness = false;
374
+ try {
375
+ const response = await this.fetch(utils_1.getAPIRequestURL(types_1.APIType.LIVENESS, chainId));
376
+ liveness = Boolean(response.lastBlock);
377
+ }
378
+ catch (e) {
379
+ console.log('"fetchLiveness" API call failed');
380
+ }
381
+ this.update({
382
+ smartTransactionsState: Object.assign(Object.assign({}, this.state.smartTransactionsState), { liveness }),
383
+ });
384
+ return liveness;
327
385
  }
328
386
  async setStatusRefreshInterval(interval) {
329
387
  if (interval !== this.config.interval) {
@@ -1 +1 @@
1
- {"version":3,"file":"SmartTransactionsController.js","sourceRoot":"","sources":["../src/SmartTransactionsController.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n BaseConfig,\n BaseController,\n BaseState,\n NetworkState,\n util,\n} from '@metamask/controllers';\nimport { BigNumber } from 'bignumber.js';\nimport { ethers } from 'ethers';\nimport mapValues from 'lodash/mapValues';\nimport cloneDeep from 'lodash/cloneDeep';\nimport {\n APIType,\n SmartTransaction,\n SignedTransaction,\n SignedCanceledTransaction,\n UnsignedTransaction,\n SmartTransactionsStatus,\n SmartTransactionStatuses,\n Fee,\n} from './types';\nimport {\n getAPIRequestURL,\n isSmartTransactionPending,\n calculateStatus,\n snapshotFromTxMeta,\n replayHistory,\n generateHistoryEntry,\n getStxProcessingTime,\n handleFetch,\n} from './utils';\nimport { CHAIN_IDS } from './constants';\n\nconst { safelyExecute } = util;\n\n// TODO: JSDoc all methods\n// TODO: Remove all comments (* ! ?)\nconst SECOND = 1000;\n\nexport const DEFAULT_INTERVAL = SECOND * 10;\nexport const CANCELLABLE_INTERVAL = SECOND * 10.5;\n\nexport interface SmartTransactionsControllerConfig extends BaseConfig {\n interval: number;\n clientId: string;\n chainId: string;\n supportedChainIds: string[];\n}\n\nexport interface SmartTransactionsControllerState extends BaseState {\n smartTransactionsState: {\n smartTransactions: Record<string, SmartTransaction[]>;\n userOptIn: boolean | undefined;\n };\n}\n\nexport default class SmartTransactionsController extends BaseController<\n SmartTransactionsControllerConfig,\n SmartTransactionsControllerState\n> {\n public timeoutHandle?: NodeJS.Timeout;\n\n private nonceTracker: any;\n\n private getNetwork: any;\n\n public ethersProvider: any;\n\n public txController: any;\n\n private trackMetaMetricsEvent: any;\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 nonceTracker,\n getNetwork,\n provider,\n txController,\n trackMetaMetricsEvent,\n }: {\n onNetworkStateChange: (\n listener: (networkState: NetworkState) => void,\n ) => void;\n nonceTracker: any;\n getNetwork: any;\n provider: any;\n txController: any;\n trackMetaMetricsEvent: any;\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.RINKEBY],\n };\n\n this.defaultState = {\n smartTransactionsState: {\n smartTransactions: {},\n userOptIn: undefined,\n },\n };\n\n this.nonceTracker = nonceTracker;\n this.getNetwork = getNetwork;\n this.ethersProvider = new ethers.providers.Web3Provider(provider);\n this.txController = txController;\n this.trackMetaMetricsEvent = trackMetaMetricsEvent;\n\n this.initialize();\n this.initializeSmartTransactionsForChainId();\n\n onNetworkStateChange(({ provider: newProvider }) => {\n const { chainId } = newProvider;\n this.configure({ chainId });\n this.initializeSmartTransactionsForChainId();\n this.checkPoll(this.state);\n this.ethersProvider = new ethers.providers.Web3Provider(provider);\n });\n\n this.subscribe((currentState: any) => this.checkPoll(currentState));\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(() => this.updateSmartTransactions());\n this.timeoutHandle = setInterval(() => {\n safelyExecute(() => 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 userOptIn: 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_address: updatedSmartTransaction.txParams?.from,\n token_from_symbol: updatedSmartTransaction.sourceTokenSymbol,\n token_to_address: updatedSmartTransaction.txParams?.to,\n token_to_symbol: updatedSmartTransaction.destinationTokenSymbol,\n processing_time: getStxProcessingTime(updatedSmartTransaction.time),\n stx_enabled: true,\n stx_user_opt_in: true,\n };\n\n this.trackMetaMetricsEvent({\n event: 'STX Status Updated',\n category: 'swaps',\n sensitiveProperties,\n });\n }\n\n updateSmartTransaction(smartTransaction: SmartTransaction): void {\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 (st) => st.uuid === smartTransaction.uuid,\n );\n const isNewSmartTransaction =\n currentIndex === -1 || currentIndex === undefined;\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 this.confirmSmartTransaction(nextSmartTransaction);\n }\n\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 async updateSmartTransactions() {\n const { smartTransactions } = this.state.smartTransactionsState;\n const { chainId } = this.config;\n\n const currentSmartTransactions = smartTransactions?.[chainId];\n\n const transactionsToUpdate: string[] = currentSmartTransactions\n .filter(isSmartTransactionPending)\n .map((smartTransaction) => smartTransaction.uuid);\n\n if (transactionsToUpdate.length > 0) {\n this.fetchSmartTransactionsStatus(transactionsToUpdate);\n }\n }\n\n async confirmSmartTransaction(smartTransaction: SmartTransaction) {\n const txHash = smartTransaction.statusMetadata?.minedHash;\n try {\n const transactionReceipt = await this.ethersProvider.getTransactionReceipt(\n txHash,\n );\n const transaction = await this.ethersProvider.getTransaction(txHash);\n const maxFeePerGas = transaction.maxFeePerGas?.toHexString();\n const maxPriorityFeePerGas = transaction.maxPriorityFeePerGas?.toHexString();\n if (transactionReceipt?.blockNumber) {\n const blockData = await this.ethersProvider.getBlock(\n transactionReceipt?.blockNumber,\n false,\n );\n const baseFeePerGas = blockData?.baseFeePerGas.toHexString();\n const txReceipt = mapValues(transactionReceipt, (value) => {\n if (value instanceof ethers.BigNumber) {\n return value.toHexString();\n }\n return value;\n });\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 this.txController.confirmExternalTransaction(\n txMeta,\n txReceipt,\n baseFeePerGas,\n );\n\n this.trackMetaMetricsEvent({\n event: 'STX Confirmed',\n category: 'swaps',\n });\n\n this.updateSmartTransaction({\n ...smartTransaction,\n confirmed: true,\n });\n }\n } catch (e) {\n this.trackMetaMetricsEvent({\n event: 'STX Confirmation Failed',\n category: 'swaps',\n });\n console.error('confirm error', e);\n }\n }\n\n // ! Ask backend API to accept list of uuids as params\n async fetchSmartTransactionsStatus(\n uuids: string[],\n ): Promise<SmartTransaction[]> {\n const { chainId } = this.config;\n\n const params = new URLSearchParams({\n uuids: uuids.join(','),\n });\n\n const url = `${getAPIRequestURL(\n APIType.BATCH_STATUS,\n chainId,\n )}?${params.toString()}`;\n\n const data = await this.fetch(url);\n\n Object.entries(data).forEach(([uuid, smartTransaction]) => {\n this.updateSmartTransaction({\n statusMetadata: smartTransaction as SmartTransactionsStatus,\n status: calculateStatus(smartTransaction as SmartTransactionsStatus),\n uuid,\n });\n });\n\n return data;\n }\n\n async addNonceToTransaction(\n transaction: UnsignedTransaction,\n ): Promise<UnsignedTransaction> {\n const nonceLock = await this.nonceTracker.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 async getFees(\n unsignedTransaction: UnsignedTransaction,\n ): Promise<{\n fees: Fee[];\n cancelFees: Fee[];\n feeEstimate: number;\n gasLimit: number;\n gasUsed: number;\n }> {\n const { chainId } = this.config;\n\n const unsignedTransactionWithNonce = await this.addNonceToTransaction(\n unsignedTransaction,\n );\n const data = await this.fetch(getAPIRequestURL(APIType.GET_FEES, chainId), {\n method: 'POST',\n body: JSON.stringify({ tx: unsignedTransactionWithNonce }),\n });\n\n return data;\n }\n\n // * After this successful call client must add a nonce representative to\n // * transaction controller external transactions list\n async submitSignedTransactions({\n txParams,\n signedTransactions,\n signedCanceledTransactions,\n }: {\n signedTransactions: SignedTransaction[];\n signedCanceledTransactions: SignedCanceledTransaction[];\n txParams?: any;\n }) {\n const { chainId } = this.config;\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 const metamaskNetworkId = this.getNetwork();\n let preTxBalance;\n try {\n const preTxBalanceBN = await this.ethersProvider.getBalance(\n txParams?.from,\n );\n preTxBalance = new BigNumber(preTxBalanceBN.toHexString()).toString(16);\n } catch (e) {\n console.error('ethers error', e);\n }\n const nonceLock = await this.nonceTracker.getNonceLock(txParams?.from);\n const nonce = ethers.utils.hexlify(nonceLock.nextNonce);\n if (txParams && !txParams?.nonce) {\n txParams.nonce = nonce;\n }\n const { nonceDetails } = nonceLock;\n\n this.updateSmartTransaction({\n chainId,\n nonceDetails,\n metamaskNetworkId,\n preTxBalance,\n status: SmartTransactionStatuses.PENDING,\n time,\n txParams,\n uuid: data.uuid,\n cancellable: true,\n });\n\n setTimeout(() => {\n this.updateSmartTransaction({\n uuid: data.uuid,\n cancellable: false,\n });\n }, CANCELLABLE_INTERVAL);\n nonceLock.releaseLock();\n return data;\n }\n\n // ! 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 // ! Ask backend API to make this endpoint a POST\n async cancelSmartTransaction(uuid: string): Promise<void> {\n const { chainId } = this.config;\n await this.fetch(getAPIRequestURL(APIType.CANCEL, chainId), {\n method: 'POST',\n body: JSON.stringify({ uuid }),\n });\n\n this.updateSmartTransaction({\n uuid,\n status: SmartTransactionStatuses.CANCELLED_USER_CANCELLED,\n });\n }\n\n async fetchLiveness(): Promise<boolean> {\n const { chainId } = this.config;\n const response = await this.fetch(\n getAPIRequestURL(APIType.LIVENESS, chainId),\n );\n return Boolean(response.lastBlock);\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":["import {\n BaseConfig,\n BaseController,\n BaseState,\n NetworkState,\n util,\n} from '@metamask/controllers';\nimport { BigNumber } from 'bignumber.js';\nimport { ethers } from 'ethers';\nimport mapValues from 'lodash/mapValues';\nimport cloneDeep from 'lodash/cloneDeep';\nimport {\n APIType,\n SmartTransaction,\n SignedTransaction,\n SignedCanceledTransaction,\n UnsignedTransaction,\n SmartTransactionsStatus,\n SmartTransactionStatuses,\n Fees,\n EstimatedGas,\n} from './types';\nimport {\n getAPIRequestURL,\n isSmartTransactionPending,\n calculateStatus,\n snapshotFromTxMeta,\n replayHistory,\n generateHistoryEntry,\n getStxProcessingTime,\n handleFetch,\n} from './utils';\nimport { CHAIN_IDS } from './constants';\n\nconst { safelyExecute } = util;\n\n// TODO: JSDoc all methods\n// TODO: Remove all comments (* ! ?)\nconst SECOND = 1000;\nconst MINUTE = SECOND * 60;\n\nexport const DEFAULT_INTERVAL = SECOND * 5;\nexport const CANCELLABLE_INTERVAL = MINUTE;\n\nexport interface SmartTransactionsControllerConfig extends BaseConfig {\n interval: number;\n clientId: string;\n chainId: string;\n supportedChainIds: string[];\n}\n\nexport interface SmartTransactionsControllerState extends BaseState {\n smartTransactionsState: {\n smartTransactions: Record<string, SmartTransaction[]>;\n userOptIn: boolean | undefined;\n liveness: boolean | undefined;\n fees: Fees | undefined;\n estimatedGas: {\n txData: EstimatedGas | undefined;\n approvalTxData: EstimatedGas | undefined;\n };\n };\n}\n\nexport default class SmartTransactionsController extends BaseController<\n SmartTransactionsControllerConfig,\n SmartTransactionsControllerState\n> {\n public timeoutHandle?: NodeJS.Timeout;\n\n private getNonceLock: any;\n\n private getNetwork: any;\n\n public ethersProvider: any;\n\n public confirmExternalTransaction: any;\n\n private trackMetaMetricsEvent: any;\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 getNetwork,\n provider,\n confirmExternalTransaction,\n trackMetaMetricsEvent,\n }: {\n onNetworkStateChange: (\n listener: (networkState: NetworkState) => void,\n ) => void;\n getNonceLock: any;\n getNetwork: any;\n provider: any;\n confirmExternalTransaction: any;\n trackMetaMetricsEvent: any;\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.RINKEBY],\n };\n\n this.defaultState = {\n smartTransactionsState: {\n smartTransactions: {},\n userOptIn: undefined,\n fees: undefined,\n liveness: true,\n estimatedGas: {\n txData: undefined,\n approvalTxData: undefined,\n },\n },\n };\n\n this.getNonceLock = getNonceLock;\n this.getNetwork = getNetwork;\n this.ethersProvider = new ethers.providers.Web3Provider(provider);\n this.confirmExternalTransaction = confirmExternalTransaction;\n this.trackMetaMetricsEvent = trackMetaMetricsEvent;\n\n this.initialize();\n this.initializeSmartTransactionsForChainId();\n\n onNetworkStateChange(({ provider: newProvider }) => {\n const { chainId } = newProvider;\n this.configure({ chainId });\n this.initializeSmartTransactionsForChainId();\n this.checkPoll(this.state);\n this.ethersProvider = new ethers.providers.Web3Provider(provider);\n });\n\n this.subscribe((currentState: any) => this.checkPoll(currentState));\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(() => this.updateSmartTransactions());\n this.timeoutHandle = setInterval(() => {\n safelyExecute(() => 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 userOptIn: 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 uuid: updatedSmartTransaction.uuid,\n stx_status: updatedSmartTransaction.status,\n token_from_address: updatedSmartTransaction.txParams?.from,\n token_from_symbol: updatedSmartTransaction.sourceTokenSymbol,\n token_to_address: updatedSmartTransaction.txParams?.to,\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: 'STX Status Updated',\n category: 'swaps',\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(smartTransaction: SmartTransaction): void {\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 === smartTransaction.uuid,\n );\n const isNewSmartTransaction = this.isNewSmartTransaction(\n smartTransaction.uuid,\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 this.confirmSmartTransaction(nextSmartTransaction);\n }\n\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 async updateSmartTransactions() {\n const { smartTransactions } = this.state.smartTransactionsState;\n const { chainId } = this.config;\n\n const currentSmartTransactions = smartTransactions?.[chainId];\n\n const transactionsToUpdate: string[] = currentSmartTransactions\n .filter(isSmartTransactionPending)\n .map((smartTransaction) => smartTransaction.uuid);\n\n if (transactionsToUpdate.length > 0) {\n this.fetchSmartTransactionsStatus(transactionsToUpdate);\n }\n }\n\n async confirmSmartTransaction(smartTransaction: SmartTransaction) {\n const txHash = smartTransaction.statusMetadata?.minedHash;\n try {\n const transactionReceipt = await this.ethersProvider.getTransactionReceipt(\n txHash,\n );\n const transaction = await this.ethersProvider.getTransaction(txHash);\n const maxFeePerGas = transaction.maxFeePerGas?.toHexString();\n const maxPriorityFeePerGas = transaction.maxPriorityFeePerGas?.toHexString();\n if (transactionReceipt?.blockNumber) {\n const blockData = await this.ethersProvider.getBlock(\n transactionReceipt?.blockNumber,\n false,\n );\n const baseFeePerGas = blockData?.baseFeePerGas.toHexString();\n const txReceipt = mapValues(transactionReceipt, (value) => {\n if (value instanceof ethers.BigNumber) {\n return value.toHexString();\n }\n return value;\n });\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 this.confirmExternalTransaction(txMeta, txReceipt, baseFeePerGas);\n\n this.trackMetaMetricsEvent({\n event: 'STX Confirmed',\n category: 'swaps',\n });\n\n this.updateSmartTransaction({\n ...smartTransaction,\n confirmed: true,\n });\n }\n } catch (e) {\n this.trackMetaMetricsEvent({\n event: 'STX Confirmation Failed',\n category: 'swaps',\n });\n console.error('confirm error', e);\n }\n }\n\n // ! Ask backend API to accept list of uuids as params\n async fetchSmartTransactionsStatus(\n uuids: string[],\n ): Promise<SmartTransaction[]> {\n const { chainId } = this.config;\n\n const params = new URLSearchParams({\n uuids: uuids.join(','),\n });\n\n const url = `${getAPIRequestURL(\n APIType.BATCH_STATUS,\n chainId,\n )}?${params.toString()}`;\n\n const data = await this.fetch(url);\n\n Object.entries(data).forEach(([uuid, smartTransaction]) => {\n this.updateSmartTransaction({\n statusMetadata: smartTransaction as SmartTransactionsStatus,\n status: calculateStatus(smartTransaction as SmartTransactionsStatus),\n uuid,\n });\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 async getFees(unsignedTransaction: UnsignedTransaction): Promise<Fees> {\n const { chainId } = this.config;\n\n const unsignedTransactionWithNonce = await this.addNonceToTransaction(\n unsignedTransaction,\n );\n const data = await this.fetch(getAPIRequestURL(APIType.GET_FEES, chainId), {\n method: 'POST',\n body: JSON.stringify({\n tx: unsignedTransactionWithNonce,\n }),\n });\n this.update({\n smartTransactionsState: {\n ...this.state.smartTransactionsState,\n fees: data,\n },\n });\n return data;\n }\n\n async estimateGas(\n unsignedTransaction: UnsignedTransaction,\n approveTxParams: UnsignedTransaction,\n ): Promise<EstimatedGas> {\n const { chainId } = this.config;\n\n let approvalTxData;\n if (approveTxParams) {\n const unsignedApprovalTransactionWithNonce = await this.addNonceToTransaction(\n approveTxParams,\n );\n approvalTxData = await this.fetch(\n getAPIRequestURL(APIType.ESTIMATE_GAS, chainId),\n {\n method: 'POST',\n body: JSON.stringify({\n tx: unsignedApprovalTransactionWithNonce,\n }),\n },\n );\n }\n const unsignedTransactionWithNonce = await this.addNonceToTransaction(\n unsignedTransaction,\n );\n const data = await this.fetch(\n getAPIRequestURL(APIType.ESTIMATE_GAS, chainId),\n {\n method: 'POST',\n body: JSON.stringify({\n tx: unsignedTransactionWithNonce,\n ...(approveTxParams && { pending_txs: [approveTxParams] }),\n }),\n },\n );\n this.update({\n smartTransactionsState: {\n ...this.state.smartTransactionsState,\n estimatedGas: {\n txData: data,\n approvalTxData,\n },\n },\n });\n\n return data;\n }\n\n // * After this successful call client must add a nonce representative to\n // * transaction controller external transactions list\n async submitSignedTransactions({\n txParams,\n signedTransactions,\n signedCanceledTransactions,\n }: {\n signedTransactions: SignedTransaction[];\n signedCanceledTransactions: SignedCanceledTransaction[];\n txParams?: any;\n }) {\n const { chainId } = this.config;\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 const metamaskNetworkId = this.getNetwork();\n let preTxBalance;\n try {\n const preTxBalanceBN = await this.ethersProvider.getBalance(\n txParams?.from,\n );\n preTxBalance = new BigNumber(preTxBalanceBN.toHexString()).toString(16);\n } catch (e) {\n console.error('ethers error', e);\n }\n const nonceLock = await this.getNonceLock(txParams?.from);\n const nonce = ethers.utils.hexlify(nonceLock.nextNonce);\n if (txParams && !txParams?.nonce) {\n txParams.nonce = nonce;\n }\n const { nonceDetails } = nonceLock;\n\n this.updateSmartTransaction({\n chainId,\n nonceDetails,\n metamaskNetworkId,\n preTxBalance,\n status: SmartTransactionStatuses.PENDING,\n time,\n txParams,\n uuid: data.uuid,\n cancellable: true,\n });\n\n setTimeout(() => {\n if (!this.isNewSmartTransaction(data.uuid)) {\n // Only do this for an existing smart transaction. If an STX is not in the list anymore\n // (e.g. because it was cancelled and a new one was submitted, which deletes the first one),\n // do not try to update the old one, because it would create a new one with most\n // of the required STX params missing. It would only have \"uuid\" and \"cancellable\" params.\n this.updateSmartTransaction({\n uuid: data.uuid,\n cancellable: false,\n });\n }\n }, CANCELLABLE_INTERVAL);\n nonceLock.releaseLock();\n return data;\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(uuid: string): Promise<void> {\n const { chainId } = this.config;\n await this.fetch(getAPIRequestURL(APIType.CANCEL, chainId), {\n method: 'POST',\n body: JSON.stringify({ uuid }),\n });\n }\n\n async fetchLiveness(): Promise<boolean> {\n const { chainId } = this.config;\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 (e) {\n console.log('\"fetchLiveness\" API call failed');\n }\n\n this.update({\n smartTransactionsState: {\n ...this.state.smartTransactionsState,\n liveness,\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,10 +1,11 @@
1
1
  /** API */
2
2
  export declare enum APIType {
3
3
  'GET_FEES' = 0,
4
- 'SUBMIT_TRANSACTIONS' = 1,
5
- 'CANCEL' = 2,
6
- 'BATCH_STATUS' = 3,
7
- 'LIVENESS' = 4
4
+ 'ESTIMATE_GAS' = 1,
5
+ 'SUBMIT_TRANSACTIONS' = 2,
6
+ 'CANCEL' = 3,
7
+ 'BATCH_STATUS' = 4,
8
+ 'LIVENESS' = 5
8
9
  }
9
10
  /** SmartTransactions */
10
11
  export declare enum SmartTransactionMinedTx {
@@ -27,6 +28,7 @@ export declare enum SmartTransactionStatuses {
27
28
  SUCCESS = "success",
28
29
  REVERTED = "reverted",
29
30
  UNKNOWN = "unknown",
31
+ CANCELLED = "cancelled",
30
32
  CANCELLED_WOULD_REVERT = "cancelled_would_revert",
31
33
  CANCELLED_TOO_CHEAP = "cancelled_too_cheap",
32
34
  CANCELLED_DEADLINE_MISSED = "cancelled_deadline_missed",
@@ -75,6 +77,18 @@ export interface Fee {
75
77
  maxFeePerGas: number;
76
78
  maxPriorityFeePerGas: number;
77
79
  }
80
+ export interface Fees {
81
+ fees: Fee[];
82
+ cancelFees: Fee[];
83
+ feeEstimate: number;
84
+ gasLimit: number;
85
+ gasUsed: number;
86
+ }
87
+ export interface EstimatedGas {
88
+ gasUsed: number;
89
+ gasLimit: number;
90
+ feeEstimate: number;
91
+ }
78
92
  export declare type UnsignedTransaction = any;
79
93
  export declare type SignedTransaction = any;
80
94
  export declare type SignedCanceledTransaction = any;
package/dist/types.js CHANGED
@@ -5,10 +5,11 @@ exports.cancellationReasonToStatusMap = exports.SmartTransactionStatuses = expor
5
5
  var APIType;
6
6
  (function (APIType) {
7
7
  APIType[APIType["GET_FEES"] = 0] = "GET_FEES";
8
- APIType[APIType["SUBMIT_TRANSACTIONS"] = 1] = "SUBMIT_TRANSACTIONS";
9
- APIType[APIType["CANCEL"] = 2] = "CANCEL";
10
- APIType[APIType["BATCH_STATUS"] = 3] = "BATCH_STATUS";
11
- APIType[APIType["LIVENESS"] = 4] = "LIVENESS";
8
+ APIType[APIType["ESTIMATE_GAS"] = 1] = "ESTIMATE_GAS";
9
+ APIType[APIType["SUBMIT_TRANSACTIONS"] = 2] = "SUBMIT_TRANSACTIONS";
10
+ APIType[APIType["CANCEL"] = 3] = "CANCEL";
11
+ APIType[APIType["BATCH_STATUS"] = 4] = "BATCH_STATUS";
12
+ APIType[APIType["LIVENESS"] = 5] = "LIVENESS";
12
13
  })(APIType = exports.APIType || (exports.APIType = {}));
13
14
  /** SmartTransactions */
14
15
  var SmartTransactionMinedTx;
@@ -34,6 +35,7 @@ var SmartTransactionStatuses;
34
35
  SmartTransactionStatuses["SUCCESS"] = "success";
35
36
  SmartTransactionStatuses["REVERTED"] = "reverted";
36
37
  SmartTransactionStatuses["UNKNOWN"] = "unknown";
38
+ SmartTransactionStatuses["CANCELLED"] = "cancelled";
37
39
  SmartTransactionStatuses["CANCELLED_WOULD_REVERT"] = "cancelled_would_revert";
38
40
  SmartTransactionStatuses["CANCELLED_TOO_CHEAP"] = "cancelled_too_cheap";
39
41
  SmartTransactionStatuses["CANCELLED_DEADLINE_MISSED"] = "cancelled_deadline_missed";
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";AAAA,UAAU;;;AAEV,IAAY,OAMX;AAND,WAAY,OAAO;IACjB,6CAAU,CAAA;IACV,mEAAqB,CAAA;IACrB,yCAAQ,CAAA;IACR,qDAAc,CAAA;IACd,6CAAU,CAAA;AACZ,CAAC,EANW,OAAO,GAAP,eAAO,KAAP,eAAO,QAMlB;AAED,wBAAwB;AAExB,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,kCAOX;AAPD,WAAY,kCAAkC;IAC5C,mEAA6B,CAAA;IAC7B,6DAAuB,CAAA;IACvB,yEAAmC,CAAA;IACnC,qEAA+B,CAAA;IAC/B,uEAAiC,CAAA;IACjC,qEAA+B,CAAA;AACjC,CAAC,EAPW,kCAAkC,GAAlC,0CAAkC,KAAlC,0CAAkC,QAO7C;AAED,IAAY,wBAWX;AAXD,WAAY,wBAAwB;IAClC,+CAAmB,CAAA;IACnB,+CAAmB,CAAA;IACnB,iDAAqB,CAAA;IACrB,+CAAmB,CAAA;IACnB,6EAAiD,CAAA;IACjD,uEAA2C,CAAA;IAC3C,mFAAuD,CAAA;IACvD,+EAAmD,CAAA;IACnD,iFAAqD,CAAA;IACrD,iDAAqB,CAAA;AACvB,CAAC,EAXW,wBAAwB,GAAxB,gCAAwB,KAAxB,gCAAwB,QAWnC;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;CACpD,CAAC","sourcesContent":["/** API */\n\nexport enum APIType {\n 'GET_FEES',\n 'SUBMIT_TRANSACTIONS',\n 'CANCEL',\n 'BATCH_STATUS',\n 'LIVENESS',\n}\n\n/** SmartTransactions */\n\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}\n\nexport enum SmartTransactionStatuses {\n PENDING = 'pending',\n SUCCESS = 'success',\n REVERTED = 'reverted',\n UNKNOWN = 'unknown',\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 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};\n\nexport interface SmartTransactionsStatus {\n error?: string;\n cancellationFeeWei: number;\n cancellationReason?: SmartTransactionCancellationReason;\n deadlineRatio: number;\n minedHash: string | undefined;\n minedTx: SmartTransactionMinedTx;\n}\n\nexport interface SmartTransaction {\n uuid: string;\n chainId?: string;\n destinationTokenAddress?: string;\n destinationTokenDecimals?: string;\n destinationTokenSymbol?: string;\n history?: any;\n metamaskNetworkId?: string;\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;\n txParams?: any;\n type?: string;\n confirmed?: boolean;\n cancellable?: boolean;\n}\n\nexport interface Fee {\n maxFeePerGas: number;\n maxPriorityFeePerGas: number;\n}\n\n// TODO: maybe grab the type from transactions controller?\nexport type UnsignedTransaction = any;\n\n// TODO\nexport type SignedTransaction = any;\n\n// TODO\nexport type SignedCanceledTransaction = any;\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";AAAA,UAAU;;;AAEV,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;AAExB,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,kCAOX;AAPD,WAAY,kCAAkC;IAC5C,mEAA6B,CAAA;IAC7B,6DAAuB,CAAA;IACvB,yEAAmC,CAAA;IACnC,qEAA+B,CAAA;IAC/B,uEAAiC,CAAA;IACjC,qEAA+B,CAAA;AACjC,CAAC,EAPW,kCAAkC,GAAlC,0CAAkC,KAAlC,0CAAkC,QAO7C;AAED,IAAY,wBAYX;AAZD,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,iDAAqB,CAAA;AACvB,CAAC,EAZW,wBAAwB,GAAxB,gCAAwB,KAAxB,gCAAwB,QAYnC;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;CACpD,CAAC","sourcesContent":["/** API */\n\nexport enum APIType {\n 'GET_FEES',\n 'ESTIMATE_GAS',\n 'SUBMIT_TRANSACTIONS',\n 'CANCEL',\n 'BATCH_STATUS',\n 'LIVENESS',\n}\n\n/** SmartTransactions */\n\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}\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 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};\n\nexport interface SmartTransactionsStatus {\n error?: string;\n cancellationFeeWei: number;\n cancellationReason?: SmartTransactionCancellationReason;\n deadlineRatio: number;\n minedHash: string | undefined;\n minedTx: SmartTransactionMinedTx;\n}\n\nexport interface SmartTransaction {\n uuid: string;\n chainId?: string;\n destinationTokenAddress?: string;\n destinationTokenDecimals?: string;\n destinationTokenSymbol?: string;\n history?: any;\n metamaskNetworkId?: string;\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;\n txParams?: any;\n type?: string;\n confirmed?: boolean;\n cancellable?: boolean;\n}\n\nexport interface Fee {\n maxFeePerGas: number;\n maxPriorityFeePerGas: number;\n}\n\nexport interface Fees {\n fees: Fee[];\n cancelFees: Fee[];\n feeEstimate: number;\n gasLimit: number;\n gasUsed: number;\n}\n\nexport interface EstimatedGas {\n gasUsed: number;\n gasLimit: number;\n feeEstimate: number;\n}\n\n// TODO: maybe grab the type from transactions controller?\nexport type UnsignedTransaction = any;\n\n// TODO\nexport type SignedTransaction = any;\n\n// TODO\nexport type SignedCanceledTransaction = any;\n"]}
package/dist/utils.js CHANGED
@@ -21,6 +21,9 @@ function getAPIRequestURL(apiType, chainId) {
21
21
  case types_1.APIType.GET_FEES: {
22
22
  return `${constants_1.API_BASE_URL}/networks/${chainIdDec}/getFees`;
23
23
  }
24
+ case types_1.APIType.ESTIMATE_GAS: {
25
+ return `${constants_1.API_BASE_URL}/networks/${chainIdDec}/estimateGas`;
26
+ }
24
27
  case types_1.APIType.SUBMIT_TRANSACTIONS: {
25
28
  return `${constants_1.API_BASE_URL}/networks/${chainIdDec}/submitTransactions`;
26
29
  }
@@ -63,6 +66,9 @@ const calculateStatus = (status) => {
63
66
  else if ((status === null || status === void 0 ? void 0 : status.minedTx) === types_1.SmartTransactionMinedTx.SUCCESS) {
64
67
  return types_1.SmartTransactionStatuses.SUCCESS;
65
68
  }
69
+ else if ((status === null || status === void 0 ? void 0 : status.minedTx) === types_1.SmartTransactionMinedTx.CANCELLED) {
70
+ return types_1.SmartTransactionStatuses.CANCELLED;
71
+ }
66
72
  else if ((status === null || status === void 0 ? void 0 : status.minedTx) === types_1.SmartTransactionMinedTx.REVERTED) {
67
73
  return types_1.SmartTransactionStatuses.REVERTED;
68
74
  }
package/dist/utils.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"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","sourcesContent":["import jsonDiffer from 'fast-json-patch';\nimport { cloneDeep } from 'lodash';\nimport {\n APIType,\n SmartTransaction,\n SmartTransactionsStatus,\n SmartTransactionStatuses,\n SmartTransactionCancellationReason,\n SmartTransactionMinedTx,\n cancellationReasonToStatusMap,\n} from './types';\nimport { API_BASE_URL } from './constants';\n\nexport function isSmartTransactionPending(smartTransaction: SmartTransaction) {\n return smartTransaction.status === SmartTransactionStatuses.PENDING;\n}\n\nexport const isSmartTransactionStatusResolved = (\n status: SmartTransactionsStatus | string,\n) => status === 'uuid_not_found';\n\n// TODO use actual url once API is defined\nexport function getAPIRequestURL(apiType: APIType, chainId: string): string {\n const chainIdDec = parseInt(chainId, 16);\n switch (apiType) {\n case APIType.GET_FEES: {\n return `${API_BASE_URL}/networks/${chainIdDec}/getFees`;\n }\n\n case APIType.SUBMIT_TRANSACTIONS: {\n return `${API_BASE_URL}/networks/${chainIdDec}/submitTransactions`;\n }\n\n case APIType.CANCEL: {\n return `${API_BASE_URL}/networks/${chainIdDec}/cancel`;\n }\n\n case APIType.BATCH_STATUS: {\n return `${API_BASE_URL}/networks/${chainIdDec}/batchStatus`;\n }\n\n case APIType.LIVENESS: {\n return `${API_BASE_URL}/networks/${chainIdDec}/health`;\n }\n\n default: {\n throw new Error(`Invalid APIType`); // It can never get here thanks to TypeScript.\n }\n }\n}\n\nexport const calculateStatus = (status: SmartTransactionsStatus) => {\n if (isSmartTransactionStatusResolved(status)) {\n return SmartTransactionStatuses.RESOLVED;\n }\n const cancellations = [\n SmartTransactionCancellationReason.WOULD_REVERT,\n SmartTransactionCancellationReason.TOO_CHEAP,\n SmartTransactionCancellationReason.DEADLINE_MISSED,\n SmartTransactionCancellationReason.INVALID_NONCE,\n SmartTransactionCancellationReason.USER_CANCELLED,\n ];\n if (status?.minedTx === SmartTransactionMinedTx.NOT_MINED) {\n if (\n status.cancellationReason ===\n SmartTransactionCancellationReason.NOT_CANCELLED\n ) {\n return SmartTransactionStatuses.PENDING;\n }\n\n const isCancellation =\n cancellations.findIndex(\n (cancellation) => cancellation === status.cancellationReason,\n ) > -1;\n if (status.cancellationReason && isCancellation) {\n return cancellationReasonToStatusMap[status.cancellationReason];\n }\n } else if (status?.minedTx === SmartTransactionMinedTx.SUCCESS) {\n return SmartTransactionStatuses.SUCCESS;\n } else if (status?.minedTx === SmartTransactionMinedTx.REVERTED) {\n return SmartTransactionStatuses.REVERTED;\n } else if (status?.minedTx === SmartTransactionMinedTx.UNKNOWN) {\n return SmartTransactionStatuses.UNKNOWN;\n }\n return SmartTransactionStatuses.UNKNOWN;\n};\n\n/**\n Generates an array of history objects sense the previous state.\n The object has the keys\n op (the operation performed),\n path (the key and if a nested object then each key will be separated with a `/`)\n value\n with the first entry having the note and a timestamp when the change took place\n @param {Object} previousState - the previous state of the object\n @param {Object} newState - the update object\n @param {string} [note] - a optional note for the state change\n @returns {Array}\n*/\nexport function generateHistoryEntry(\n previousState: any,\n newState: any,\n note: string,\n) {\n const entry: any = jsonDiffer.compare(previousState, newState);\n // Add a note to the first op, since it breaks if we append it to the entry\n if (entry[0]) {\n if (note) {\n entry[0].note = note;\n }\n\n entry[0].timestamp = Date.now();\n }\n return entry;\n}\n\n/**\n Recovers previous txMeta state obj\n @returns {Object}\n*/\nexport function replayHistory(_shortHistory: any) {\n const shortHistory = cloneDeep(_shortHistory);\n return shortHistory.reduce(\n (val: any, entry: any) => jsonDiffer.applyPatch(val, entry).newDocument,\n );\n}\n\n/**\n * Snapshot {@code txMeta}\n * @param {Object} txMeta - the tx metadata object\n * @returns {Object} a deep clone without history\n */\nexport function snapshotFromTxMeta(txMeta: any) {\n const shallow = { ...txMeta };\n delete shallow.history;\n return cloneDeep(shallow);\n}\n\n/**\n * Returns processing time for an STX in seconds.\n * @param {number} smartTransactionSubmittedtime\n * @returns {number} Processing time in seconds.\n */\nexport const getStxProcessingTime = (\n smartTransactionSubmittedtime: number | undefined,\n): number | undefined => {\n if (!smartTransactionSubmittedtime) {\n return undefined;\n }\n return Math.round((Date.now() - smartTransactionSubmittedtime) / 1000);\n};\n\nexport async function handleFetch(request: string, options?: RequestInit) {\n const response = await fetch(request, options);\n const json = await response.json();\n if (!response.ok) {\n const { error: type, error_details: message } = json;\n console.log(`response`, response);\n throw new Error(\n `Fetch error:${JSON.stringify({\n status: response.status,\n type,\n message,\n })}`,\n );\n }\n return json;\n}\n"]}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"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","sourcesContent":["import jsonDiffer from 'fast-json-patch';\nimport { cloneDeep } from 'lodash';\nimport {\n APIType,\n SmartTransaction,\n SmartTransactionsStatus,\n SmartTransactionStatuses,\n SmartTransactionCancellationReason,\n SmartTransactionMinedTx,\n cancellationReasonToStatusMap,\n} from './types';\nimport { API_BASE_URL } from './constants';\n\nexport function isSmartTransactionPending(smartTransaction: SmartTransaction) {\n return smartTransaction.status === SmartTransactionStatuses.PENDING;\n}\n\nexport const isSmartTransactionStatusResolved = (\n status: SmartTransactionsStatus | string,\n) => status === 'uuid_not_found';\n\n// TODO use actual url once API is defined\nexport function getAPIRequestURL(apiType: APIType, chainId: string): string {\n const chainIdDec = parseInt(chainId, 16);\n switch (apiType) {\n case APIType.GET_FEES: {\n return `${API_BASE_URL}/networks/${chainIdDec}/getFees`;\n }\n\n case APIType.ESTIMATE_GAS: {\n return `${API_BASE_URL}/networks/${chainIdDec}/estimateGas`;\n }\n\n case APIType.SUBMIT_TRANSACTIONS: {\n return `${API_BASE_URL}/networks/${chainIdDec}/submitTransactions`;\n }\n\n case APIType.CANCEL: {\n return `${API_BASE_URL}/networks/${chainIdDec}/cancel`;\n }\n\n case APIType.BATCH_STATUS: {\n return `${API_BASE_URL}/networks/${chainIdDec}/batchStatus`;\n }\n\n case APIType.LIVENESS: {\n return `${API_BASE_URL}/networks/${chainIdDec}/health`;\n }\n\n default: {\n throw new Error(`Invalid APIType`); // It can never get here thanks to TypeScript.\n }\n }\n}\n\nexport const calculateStatus = (status: SmartTransactionsStatus) => {\n if (isSmartTransactionStatusResolved(status)) {\n return SmartTransactionStatuses.RESOLVED;\n }\n const cancellations = [\n SmartTransactionCancellationReason.WOULD_REVERT,\n SmartTransactionCancellationReason.TOO_CHEAP,\n SmartTransactionCancellationReason.DEADLINE_MISSED,\n SmartTransactionCancellationReason.INVALID_NONCE,\n SmartTransactionCancellationReason.USER_CANCELLED,\n ];\n if (status?.minedTx === SmartTransactionMinedTx.NOT_MINED) {\n if (\n status.cancellationReason ===\n SmartTransactionCancellationReason.NOT_CANCELLED\n ) {\n return SmartTransactionStatuses.PENDING;\n }\n\n const isCancellation =\n cancellations.findIndex(\n (cancellation) => cancellation === status.cancellationReason,\n ) > -1;\n if (status.cancellationReason && isCancellation) {\n return cancellationReasonToStatusMap[status.cancellationReason];\n }\n } else if (status?.minedTx === SmartTransactionMinedTx.SUCCESS) {\n return SmartTransactionStatuses.SUCCESS;\n } else if (status?.minedTx === SmartTransactionMinedTx.CANCELLED) {\n return SmartTransactionStatuses.CANCELLED;\n } else if (status?.minedTx === SmartTransactionMinedTx.REVERTED) {\n return SmartTransactionStatuses.REVERTED;\n } else if (status?.minedTx === SmartTransactionMinedTx.UNKNOWN) {\n return SmartTransactionStatuses.UNKNOWN;\n }\n return SmartTransactionStatuses.UNKNOWN;\n};\n\n/**\n Generates an array of history objects sense the previous state.\n The object has the keys\n op (the operation performed),\n path (the key and if a nested object then each key will be separated with a `/`)\n value\n with the first entry having the note and a timestamp when the change took place\n @param {Object} previousState - the previous state of the object\n @param {Object} newState - the update object\n @param {string} [note] - a optional note for the state change\n @returns {Array}\n*/\nexport function generateHistoryEntry(\n previousState: any,\n newState: any,\n note: string,\n) {\n const entry: any = jsonDiffer.compare(previousState, newState);\n // Add a note to the first op, since it breaks if we append it to the entry\n if (entry[0]) {\n if (note) {\n entry[0].note = note;\n }\n\n entry[0].timestamp = Date.now();\n }\n return entry;\n}\n\n/**\n Recovers previous txMeta state obj\n @returns {Object}\n*/\nexport function replayHistory(_shortHistory: any) {\n const shortHistory = cloneDeep(_shortHistory);\n return shortHistory.reduce(\n (val: any, entry: any) => jsonDiffer.applyPatch(val, entry).newDocument,\n );\n}\n\n/**\n * Snapshot {@code txMeta}\n * @param {Object} txMeta - the tx metadata object\n * @returns {Object} a deep clone without history\n */\nexport function snapshotFromTxMeta(txMeta: any) {\n const shallow = { ...txMeta };\n delete shallow.history;\n return cloneDeep(shallow);\n}\n\n/**\n * Returns processing time for an STX in seconds.\n * @param {number} smartTransactionSubmittedtime\n * @returns {number} Processing time in seconds.\n */\nexport const getStxProcessingTime = (\n smartTransactionSubmittedtime: number | undefined,\n): number | undefined => {\n if (!smartTransactionSubmittedtime) {\n return undefined;\n }\n return Math.round((Date.now() - smartTransactionSubmittedtime) / 1000);\n};\n\nexport async function handleFetch(request: string, options?: RequestInit) {\n const response = await fetch(request, options);\n const json = await response.json();\n if (!response.ok) {\n const { error: type, error_details: message } = json;\n console.log(`response`, response);\n throw new Error(\n `Fetch error:${JSON.stringify({\n status: response.status,\n type,\n message,\n })}`,\n );\n }\n return json;\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metamask/smart-transactions-controller",
3
- "version": "1.4.0",
3
+ "version": "1.10.0",
4
4
  "description": "MetaMask controller for Smart Transactions.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -26,7 +26,7 @@
26
26
  "build:link": "yarn build && cd dist && yarn link && rm -rf node_modules && cd .."
27
27
  },
28
28
  "dependencies": {
29
- "@metamask/controllers": "^20.0.0",
29
+ "@metamask/controllers": "^27.1.1",
30
30
  "@types/lodash": "^4.14.176",
31
31
  "bignumber.js": "^9.0.1",
32
32
  "ethers": "^5.5.1",