@metamask/smart-transactions-controller 2.0.0 → 2.3.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.
@@ -0,0 +1,64 @@
1
+ /// <reference types="node" />
2
+ import { BaseConfig, BaseController, BaseState, NetworkState } from '@metamask/controllers';
3
+ import { SmartTransaction, SignedTransaction, SignedCanceledTransaction, UnsignedTransaction, SmartTransactionStatuses, Fees, IndividualTxFees } from './types';
4
+ export declare const DEFAULT_INTERVAL: number;
5
+ export interface SmartTransactionsControllerConfig extends BaseConfig {
6
+ interval: number;
7
+ clientId: string;
8
+ chainId: string;
9
+ supportedChainIds: string[];
10
+ }
11
+ export interface SmartTransactionsControllerState extends BaseState {
12
+ smartTransactionsState: {
13
+ smartTransactions: Record<string, SmartTransaction[]>;
14
+ userOptIn: boolean | undefined;
15
+ liveness: boolean | undefined;
16
+ fees: {
17
+ approvalTxFees: IndividualTxFees | undefined;
18
+ tradeTxFees: IndividualTxFees | undefined;
19
+ };
20
+ };
21
+ }
22
+ export default class SmartTransactionsController extends BaseController<SmartTransactionsControllerConfig, SmartTransactionsControllerState> {
23
+ timeoutHandle?: NodeJS.Timeout;
24
+ private getNonceLock;
25
+ private getNetwork;
26
+ ethersProvider: any;
27
+ confirmExternalTransaction: any;
28
+ private trackMetaMetricsEvent;
29
+ private fetch;
30
+ constructor({ onNetworkStateChange, getNonceLock, getNetwork, provider, confirmExternalTransaction, trackMetaMetricsEvent, }: {
31
+ onNetworkStateChange: (listener: (networkState: NetworkState) => void) => void;
32
+ getNonceLock: any;
33
+ getNetwork: any;
34
+ provider: any;
35
+ confirmExternalTransaction: any;
36
+ trackMetaMetricsEvent: any;
37
+ }, config?: Partial<SmartTransactionsControllerConfig>, state?: Partial<SmartTransactionsControllerState>);
38
+ checkPoll(state: any): void;
39
+ initializeSmartTransactionsForChainId(): void;
40
+ poll(interval?: number): Promise<void>;
41
+ stop(): Promise<void>;
42
+ setOptInState(state: boolean | undefined): void;
43
+ trackStxStatusChange(smartTransaction: SmartTransaction, prevSmartTransaction?: SmartTransaction): void;
44
+ isNewSmartTransaction(smartTransactionUuid: string): boolean;
45
+ updateSmartTransaction(smartTransaction: SmartTransaction): void;
46
+ updateSmartTransactions(): Promise<void>;
47
+ confirmSmartTransaction(smartTransaction: SmartTransaction): Promise<void>;
48
+ fetchSmartTransactionsStatus(uuids: string[]): Promise<SmartTransaction[]>;
49
+ addNonceToTransaction(transaction: UnsignedTransaction): Promise<UnsignedTransaction>;
50
+ clearFees(): Fees;
51
+ getFees(tradeTx: UnsignedTransaction, approvalTx: UnsignedTransaction): Promise<Fees>;
52
+ submitSignedTransactions({ txParams, signedTransactions, signedCanceledTransactions, }: {
53
+ signedTransactions: SignedTransaction[];
54
+ signedCanceledTransactions: SignedCanceledTransaction[];
55
+ txParams?: any;
56
+ }): Promise<any>;
57
+ cancelSmartTransaction(uuid: string): Promise<void>;
58
+ fetchLiveness(): Promise<boolean>;
59
+ setStatusRefreshInterval(interval: number): Promise<void>;
60
+ getTransactions({ addressFrom, status, }: {
61
+ addressFrom: string;
62
+ status: SmartTransactionStatuses;
63
+ }): SmartTransaction[];
64
+ }
@@ -0,0 +1,401 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.DEFAULT_INTERVAL = void 0;
7
+ const controllers_1 = require("@metamask/controllers");
8
+ const bignumber_js_1 = require("bignumber.js");
9
+ const ethers_1 = require("ethers");
10
+ const mapValues_1 = __importDefault(require("lodash/mapValues"));
11
+ const cloneDeep_1 = __importDefault(require("lodash/cloneDeep"));
12
+ const types_1 = require("./types");
13
+ const utils_1 = require("./utils");
14
+ const constants_1 = require("./constants");
15
+ const { safelyExecute } = controllers_1.util;
16
+ const SECOND = 1000;
17
+ exports.DEFAULT_INTERVAL = SECOND * 5;
18
+ class SmartTransactionsController extends controllers_1.BaseController {
19
+ constructor({ onNetworkStateChange, getNonceLock, getNetwork, provider, confirmExternalTransaction, trackMetaMetricsEvent, }, config, state) {
20
+ super(config, state);
21
+ this.defaultConfig = {
22
+ interval: exports.DEFAULT_INTERVAL,
23
+ chainId: constants_1.CHAIN_IDS.ETHEREUM,
24
+ clientId: 'default',
25
+ supportedChainIds: [constants_1.CHAIN_IDS.ETHEREUM, constants_1.CHAIN_IDS.RINKEBY],
26
+ };
27
+ this.defaultState = {
28
+ smartTransactionsState: {
29
+ smartTransactions: {},
30
+ userOptIn: undefined,
31
+ fees: {
32
+ approvalTxFees: undefined,
33
+ tradeTxFees: undefined,
34
+ },
35
+ liveness: true,
36
+ },
37
+ };
38
+ this.getNonceLock = getNonceLock;
39
+ this.getNetwork = getNetwork;
40
+ this.ethersProvider = new ethers_1.ethers.providers.Web3Provider(provider);
41
+ this.confirmExternalTransaction = confirmExternalTransaction;
42
+ this.trackMetaMetricsEvent = trackMetaMetricsEvent;
43
+ this.initialize();
44
+ this.initializeSmartTransactionsForChainId();
45
+ onNetworkStateChange(({ provider: newProvider }) => {
46
+ const { chainId } = newProvider;
47
+ this.configure({ chainId });
48
+ this.initializeSmartTransactionsForChainId();
49
+ this.checkPoll(this.state);
50
+ this.ethersProvider = new ethers_1.ethers.providers.Web3Provider(provider);
51
+ });
52
+ this.subscribe((currentState) => this.checkPoll(currentState));
53
+ }
54
+ /* istanbul ignore next */
55
+ async fetch(request, options) {
56
+ const { clientId } = this.config;
57
+ const fetchOptions = Object.assign(Object.assign({}, options), { headers: Object.assign({ 'Content-Type': 'application/json' }, (clientId && { 'X-Client-Id': clientId })) });
58
+ return utils_1.handleFetch(request, fetchOptions);
59
+ }
60
+ checkPoll(state) {
61
+ const { smartTransactions } = state.smartTransactionsState;
62
+ const currentSmartTransactions = smartTransactions[this.config.chainId];
63
+ const pendingTransactions = currentSmartTransactions === null || currentSmartTransactions === void 0 ? void 0 : currentSmartTransactions.filter(utils_1.isSmartTransactionPending);
64
+ if (!this.timeoutHandle && (pendingTransactions === null || pendingTransactions === void 0 ? void 0 : pendingTransactions.length) > 0) {
65
+ this.poll();
66
+ }
67
+ else if (this.timeoutHandle && (pendingTransactions === null || pendingTransactions === void 0 ? void 0 : pendingTransactions.length) === 0) {
68
+ this.stop();
69
+ }
70
+ }
71
+ initializeSmartTransactionsForChainId() {
72
+ var _a;
73
+ if (this.config.supportedChainIds.includes(this.config.chainId)) {
74
+ const { smartTransactionsState } = this.state;
75
+ this.update({
76
+ smartTransactionsState: Object.assign(Object.assign({}, smartTransactionsState), { smartTransactions: Object.assign(Object.assign({}, smartTransactionsState.smartTransactions), { [this.config.chainId]: (_a = smartTransactionsState.smartTransactions[this.config.chainId]) !== null && _a !== void 0 ? _a : [] }) }),
77
+ });
78
+ }
79
+ }
80
+ async poll(interval) {
81
+ const { chainId, supportedChainIds } = this.config;
82
+ interval && this.configure({ interval }, false, false);
83
+ this.timeoutHandle && clearInterval(this.timeoutHandle);
84
+ if (!supportedChainIds.includes(chainId)) {
85
+ return;
86
+ }
87
+ await safelyExecute(() => this.updateSmartTransactions());
88
+ this.timeoutHandle = setInterval(() => {
89
+ safelyExecute(() => this.updateSmartTransactions());
90
+ }, this.config.interval);
91
+ }
92
+ async stop() {
93
+ this.timeoutHandle && clearInterval(this.timeoutHandle);
94
+ this.timeoutHandle = undefined;
95
+ }
96
+ setOptInState(state) {
97
+ this.update({
98
+ smartTransactionsState: Object.assign(Object.assign({}, this.state.smartTransactionsState), { userOptIn: state }),
99
+ });
100
+ }
101
+ trackStxStatusChange(smartTransaction, prevSmartTransaction) {
102
+ var _a, _b;
103
+ if (!prevSmartTransaction) {
104
+ return; // Don't track the first STX, because it doesn't have all necessary params.
105
+ }
106
+ let updatedSmartTransaction = cloneDeep_1.default(smartTransaction);
107
+ updatedSmartTransaction = Object.assign(Object.assign({}, cloneDeep_1.default(prevSmartTransaction)), updatedSmartTransaction);
108
+ if (!updatedSmartTransaction.swapMetaData ||
109
+ (updatedSmartTransaction.status === prevSmartTransaction.status &&
110
+ prevSmartTransaction.swapMetaData)) {
111
+ return; // If status hasn't changed, don't track it again.
112
+ }
113
+ const sensitiveProperties = {
114
+ uuid: updatedSmartTransaction.uuid,
115
+ stx_status: updatedSmartTransaction.status,
116
+ token_from_address: (_a = updatedSmartTransaction.txParams) === null || _a === void 0 ? void 0 : _a.from,
117
+ token_from_symbol: updatedSmartTransaction.sourceTokenSymbol,
118
+ token_to_address: (_b = updatedSmartTransaction.txParams) === null || _b === void 0 ? void 0 : _b.to,
119
+ token_to_symbol: updatedSmartTransaction.destinationTokenSymbol,
120
+ processing_time: utils_1.getStxProcessingTime(updatedSmartTransaction.time),
121
+ stx_enabled: true,
122
+ current_stx_enabled: true,
123
+ stx_user_opt_in: true,
124
+ };
125
+ this.trackMetaMetricsEvent({
126
+ event: 'STX Status Updated',
127
+ category: 'swaps',
128
+ sensitiveProperties,
129
+ });
130
+ }
131
+ isNewSmartTransaction(smartTransactionUuid) {
132
+ const { chainId } = this.config;
133
+ const { smartTransactionsState } = this.state;
134
+ const { smartTransactions } = smartTransactionsState;
135
+ const currentSmartTransactions = smartTransactions[chainId];
136
+ const currentIndex = currentSmartTransactions === null || currentSmartTransactions === void 0 ? void 0 : currentSmartTransactions.findIndex((stx) => stx.uuid === smartTransactionUuid);
137
+ return currentIndex === -1 || currentIndex === undefined;
138
+ }
139
+ updateSmartTransaction(smartTransaction) {
140
+ const { chainId } = this.config;
141
+ const { smartTransactionsState } = this.state;
142
+ const { smartTransactions } = smartTransactionsState;
143
+ const currentSmartTransactions = smartTransactions[chainId];
144
+ const currentIndex = currentSmartTransactions === null || currentSmartTransactions === void 0 ? void 0 : currentSmartTransactions.findIndex((stx) => stx.uuid === smartTransaction.uuid);
145
+ const isNewSmartTransaction = this.isNewSmartTransaction(smartTransaction.uuid);
146
+ this.trackStxStatusChange(smartTransaction, isNewSmartTransaction
147
+ ? undefined
148
+ : currentSmartTransactions[currentIndex]);
149
+ if (isNewSmartTransaction) {
150
+ // add smart transaction
151
+ const cancelledNonceIndex = currentSmartTransactions.findIndex((stx) => {
152
+ var _a, _b, _c;
153
+ return ((_a = stx.txParams) === null || _a === void 0 ? void 0 : _a.nonce) === ((_b = smartTransaction.txParams) === null || _b === void 0 ? void 0 : _b.nonce) &&
154
+ ((_c = stx.status) === null || _c === void 0 ? void 0 : _c.startsWith('cancelled'));
155
+ });
156
+ const snapshot = cloneDeep_1.default(smartTransaction);
157
+ const history = [snapshot];
158
+ const historifiedSmartTransaction = Object.assign(Object.assign({}, smartTransaction), { history });
159
+ const nextSmartTransactions = cancelledNonceIndex > -1
160
+ ? currentSmartTransactions
161
+ .slice(0, cancelledNonceIndex)
162
+ .concat(currentSmartTransactions.slice(cancelledNonceIndex + 1))
163
+ .concat(historifiedSmartTransaction)
164
+ : currentSmartTransactions.concat(historifiedSmartTransaction);
165
+ this.update({
166
+ smartTransactionsState: Object.assign(Object.assign({}, smartTransactionsState), { smartTransactions: Object.assign(Object.assign({}, smartTransactionsState.smartTransactions), { [chainId]: nextSmartTransactions }) }),
167
+ });
168
+ return;
169
+ }
170
+ if ((smartTransaction.status === types_1.SmartTransactionStatuses.SUCCESS ||
171
+ smartTransaction.status === types_1.SmartTransactionStatuses.REVERTED) &&
172
+ !smartTransaction.confirmed) {
173
+ // confirm smart transaction
174
+ const currentSmartTransaction = currentSmartTransactions[currentIndex];
175
+ const nextSmartTransaction = Object.assign(Object.assign({}, currentSmartTransaction), smartTransaction);
176
+ this.confirmSmartTransaction(nextSmartTransaction);
177
+ }
178
+ this.update({
179
+ smartTransactionsState: Object.assign(Object.assign({}, smartTransactionsState), { smartTransactions: Object.assign(Object.assign({}, smartTransactionsState.smartTransactions), { [chainId]: smartTransactionsState.smartTransactions[chainId].map((item, index) => {
180
+ return index === currentIndex
181
+ ? Object.assign(Object.assign({}, item), smartTransaction) : item;
182
+ }) }) }),
183
+ });
184
+ }
185
+ async updateSmartTransactions() {
186
+ const { smartTransactions } = this.state.smartTransactionsState;
187
+ const { chainId } = this.config;
188
+ const currentSmartTransactions = smartTransactions === null || smartTransactions === void 0 ? void 0 : smartTransactions[chainId];
189
+ const transactionsToUpdate = currentSmartTransactions
190
+ .filter(utils_1.isSmartTransactionPending)
191
+ .map((smartTransaction) => smartTransaction.uuid);
192
+ if (transactionsToUpdate.length > 0) {
193
+ this.fetchSmartTransactionsStatus(transactionsToUpdate);
194
+ }
195
+ }
196
+ async confirmSmartTransaction(smartTransaction) {
197
+ var _a, _b, _c;
198
+ const txHash = (_a = smartTransaction.statusMetadata) === null || _a === void 0 ? void 0 : _a.minedHash;
199
+ try {
200
+ const transactionReceipt = await this.ethersProvider.getTransactionReceipt(txHash);
201
+ const transaction = await this.ethersProvider.getTransaction(txHash);
202
+ const maxFeePerGas = (_b = transaction.maxFeePerGas) === null || _b === void 0 ? void 0 : _b.toHexString();
203
+ const maxPriorityFeePerGas = (_c = transaction.maxPriorityFeePerGas) === null || _c === void 0 ? void 0 : _c.toHexString();
204
+ if (transactionReceipt === null || transactionReceipt === void 0 ? void 0 : transactionReceipt.blockNumber) {
205
+ const blockData = await this.ethersProvider.getBlock(transactionReceipt === null || transactionReceipt === void 0 ? void 0 : transactionReceipt.blockNumber, false);
206
+ const baseFeePerGas = blockData === null || blockData === void 0 ? void 0 : blockData.baseFeePerGas.toHexString();
207
+ const txReceipt = mapValues_1.default(transactionReceipt, (value) => {
208
+ if (value instanceof ethers_1.ethers.BigNumber) {
209
+ return value.toHexString();
210
+ }
211
+ return value;
212
+ });
213
+ const updatedTxParams = Object.assign(Object.assign({}, smartTransaction.txParams), { maxFeePerGas,
214
+ maxPriorityFeePerGas });
215
+ // call confirmExternalTransaction
216
+ const originalTxMeta = Object.assign(Object.assign({}, smartTransaction), { id: smartTransaction.uuid, status: 'confirmed', hash: txHash, txParams: updatedTxParams });
217
+ // create txMeta snapshot for history
218
+ const snapshot = utils_1.snapshotFromTxMeta(originalTxMeta);
219
+ // recover previous tx state obj
220
+ const previousState = utils_1.replayHistory(originalTxMeta.history);
221
+ // generate history entry and add to history
222
+ const entry = utils_1.generateHistoryEntry(previousState, snapshot, 'txStateManager: setting status to confirmed');
223
+ const txMeta = entry.length > 0
224
+ ? Object.assign(Object.assign({}, originalTxMeta), { history: originalTxMeta.history.concat(entry) }) : originalTxMeta;
225
+ this.confirmExternalTransaction(txMeta, txReceipt, baseFeePerGas);
226
+ this.trackMetaMetricsEvent({
227
+ event: 'STX Confirmed',
228
+ category: 'swaps',
229
+ });
230
+ this.updateSmartTransaction(Object.assign(Object.assign({}, smartTransaction), { confirmed: true }));
231
+ }
232
+ }
233
+ catch (e) {
234
+ this.trackMetaMetricsEvent({
235
+ event: 'STX Confirmation Failed',
236
+ category: 'swaps',
237
+ });
238
+ console.error('confirm error', e);
239
+ }
240
+ }
241
+ // ! Ask backend API to accept list of uuids as params
242
+ async fetchSmartTransactionsStatus(uuids) {
243
+ const { chainId } = this.config;
244
+ const params = new URLSearchParams({
245
+ uuids: uuids.join(','),
246
+ });
247
+ const url = `${utils_1.getAPIRequestURL(types_1.APIType.BATCH_STATUS, chainId)}?${params.toString()}`;
248
+ const data = await this.fetch(url);
249
+ Object.entries(data).forEach(([uuid, stxStatus]) => {
250
+ this.updateSmartTransaction({
251
+ statusMetadata: stxStatus,
252
+ status: utils_1.calculateStatus(stxStatus),
253
+ cancellable: utils_1.isSmartTransactionCancellable(stxStatus),
254
+ uuid,
255
+ });
256
+ });
257
+ return data;
258
+ }
259
+ async addNonceToTransaction(transaction) {
260
+ const nonceLock = await this.getNonceLock(transaction.from);
261
+ const nonce = nonceLock.nextNonce;
262
+ nonceLock.releaseLock();
263
+ return Object.assign(Object.assign({}, transaction), { nonce: `0x${nonce.toString(16)}` });
264
+ }
265
+ clearFees() {
266
+ const fees = {
267
+ approvalTxFees: undefined,
268
+ tradeTxFees: undefined,
269
+ };
270
+ this.update({
271
+ smartTransactionsState: Object.assign(Object.assign({}, this.state.smartTransactionsState), { fees }),
272
+ });
273
+ return fees;
274
+ }
275
+ async getFees(tradeTx, approvalTx) {
276
+ const { chainId } = this.config;
277
+ const transactions = [];
278
+ let unsignedTradeTransactionWithNonce;
279
+ if (approvalTx) {
280
+ const unsignedApprovalTransactionWithNonce = await this.addNonceToTransaction(approvalTx);
281
+ transactions.push(unsignedApprovalTransactionWithNonce);
282
+ unsignedTradeTransactionWithNonce = Object.assign(Object.assign({}, tradeTx), {
283
+ // If there is an approval tx, the trade tx's nonce is increased by 1.
284
+ nonce: utils_1.incrementNonceInHex(unsignedApprovalTransactionWithNonce.nonce) });
285
+ }
286
+ else {
287
+ unsignedTradeTransactionWithNonce = await this.addNonceToTransaction(tradeTx);
288
+ }
289
+ transactions.push(unsignedTradeTransactionWithNonce);
290
+ const data = await this.fetch(utils_1.getAPIRequestURL(types_1.APIType.GET_FEES, chainId), {
291
+ method: 'POST',
292
+ body: JSON.stringify({
293
+ txs: transactions,
294
+ }),
295
+ });
296
+ let approvalTxFees;
297
+ let tradeTxFees;
298
+ if (approvalTx) {
299
+ approvalTxFees = data === null || data === void 0 ? void 0 : data.txs[0];
300
+ tradeTxFees = data === null || data === void 0 ? void 0 : data.txs[1];
301
+ }
302
+ else {
303
+ tradeTxFees = data === null || data === void 0 ? void 0 : data.txs[0];
304
+ }
305
+ this.update({
306
+ smartTransactionsState: Object.assign(Object.assign({}, this.state.smartTransactionsState), { fees: {
307
+ approvalTxFees,
308
+ tradeTxFees,
309
+ } }),
310
+ });
311
+ return {
312
+ approvalTxFees,
313
+ tradeTxFees,
314
+ };
315
+ }
316
+ // * After this successful call client must add a nonce representative to
317
+ // * transaction controller external transactions list
318
+ async submitSignedTransactions({ txParams, signedTransactions, signedCanceledTransactions, }) {
319
+ const { chainId } = this.config;
320
+ const data = await this.fetch(utils_1.getAPIRequestURL(types_1.APIType.SUBMIT_TRANSACTIONS, chainId), {
321
+ method: 'POST',
322
+ body: JSON.stringify({
323
+ rawTxs: signedTransactions,
324
+ rawCancelTxs: signedCanceledTransactions,
325
+ }),
326
+ });
327
+ const time = Date.now();
328
+ const metamaskNetworkId = this.getNetwork();
329
+ let preTxBalance;
330
+ try {
331
+ const preTxBalanceBN = await this.ethersProvider.getBalance(txParams === null || txParams === void 0 ? void 0 : txParams.from);
332
+ preTxBalance = new bignumber_js_1.BigNumber(preTxBalanceBN.toHexString()).toString(16);
333
+ }
334
+ catch (e) {
335
+ console.error('ethers error', e);
336
+ }
337
+ const nonceLock = await this.getNonceLock(txParams === null || txParams === void 0 ? void 0 : txParams.from);
338
+ const nonce = ethers_1.ethers.utils.hexlify(nonceLock.nextNonce);
339
+ if (txParams && !(txParams === null || txParams === void 0 ? void 0 : txParams.nonce)) {
340
+ txParams.nonce = nonce;
341
+ }
342
+ const { nonceDetails } = nonceLock;
343
+ this.updateSmartTransaction({
344
+ chainId,
345
+ nonceDetails,
346
+ metamaskNetworkId,
347
+ preTxBalance,
348
+ status: types_1.SmartTransactionStatuses.PENDING,
349
+ time,
350
+ txParams,
351
+ uuid: data.uuid,
352
+ cancellable: true,
353
+ });
354
+ nonceLock.releaseLock();
355
+ return data;
356
+ }
357
+ // TODO: This should return if the cancellation was on chain or not (for nonce management)
358
+ // After this successful call client must update nonce representative
359
+ // in transaction controller external transactions list
360
+ async cancelSmartTransaction(uuid) {
361
+ const { chainId } = this.config;
362
+ await this.fetch(utils_1.getAPIRequestURL(types_1.APIType.CANCEL, chainId), {
363
+ method: 'POST',
364
+ body: JSON.stringify({ uuid }),
365
+ });
366
+ }
367
+ async fetchLiveness() {
368
+ const { chainId } = this.config;
369
+ let liveness = false;
370
+ try {
371
+ const response = await this.fetch(utils_1.getAPIRequestURL(types_1.APIType.LIVENESS, chainId));
372
+ liveness = Boolean(response.lastBlock);
373
+ }
374
+ catch (e) {
375
+ console.log('"fetchLiveness" API call failed');
376
+ }
377
+ this.update({
378
+ smartTransactionsState: Object.assign(Object.assign({}, this.state.smartTransactionsState), { liveness }),
379
+ });
380
+ return liveness;
381
+ }
382
+ async setStatusRefreshInterval(interval) {
383
+ if (interval !== this.config.interval) {
384
+ this.configure({ interval }, false, false);
385
+ }
386
+ }
387
+ getTransactions({ addressFrom, status, }) {
388
+ const { smartTransactions } = this.state.smartTransactionsState;
389
+ const { chainId } = this.config;
390
+ const currentSmartTransactions = smartTransactions === null || smartTransactions === void 0 ? void 0 : smartTransactions[chainId];
391
+ if (!currentSmartTransactions || currentSmartTransactions.length === 0) {
392
+ return [];
393
+ }
394
+ return currentSmartTransactions.filter((stx) => {
395
+ var _a;
396
+ return stx.status === status && ((_a = stx.txParams) === null || _a === void 0 ? void 0 : _a.from) === addressFrom;
397
+ });
398
+ }
399
+ }
400
+ exports.default = SmartTransactionsController;
401
+ //# sourceMappingURL=SmartTransactionsController.js.map
@@ -0,0 +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 Fees,\n IndividualTxFees,\n} from './types';\nimport {\n getAPIRequestURL,\n isSmartTransactionPending,\n calculateStatus,\n snapshotFromTxMeta,\n replayHistory,\n generateHistoryEntry,\n getStxProcessingTime,\n handleFetch,\n isSmartTransactionCancellable,\n incrementNonceInHex,\n} from './utils';\nimport { CHAIN_IDS } from './constants';\n\nconst { safelyExecute } = util;\n\nconst SECOND = 1000;\nexport const DEFAULT_INTERVAL = SECOND * 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 liveness: boolean | undefined;\n fees: {\n approvalTxFees: IndividualTxFees | undefined;\n tradeTxFees: IndividualTxFees | 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: {\n approvalTxFees: undefined,\n tradeTxFees: undefined,\n },\n liveness: true,\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, stxStatus]) => {\n this.updateSmartTransaction({\n statusMetadata: stxStatus as SmartTransactionsStatus,\n status: calculateStatus(stxStatus as SmartTransactionsStatus),\n cancellable: isSmartTransactionCancellable(\n stxStatus as SmartTransactionsStatus,\n ),\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 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 ): Promise<Fees> {\n const { chainId } = this.config;\n const transactions = [];\n let unsignedTradeTransactionWithNonce;\n if (approvalTx) {\n const unsignedApprovalTransactionWithNonce = await this.addNonceToTransaction(\n approvalTx,\n );\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 {\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 fees: {\n approvalTxFees,\n tradeTxFees,\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 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 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"]}
@@ -0,0 +1,6 @@
1
+ export declare const API_BASE_URL = "https://transaction.metaswap.codefi.network";
2
+ export declare const CHAIN_IDS: {
3
+ ETHEREUM: string;
4
+ RINKEBY: string;
5
+ BSC: string;
6
+ };
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CHAIN_IDS = exports.API_BASE_URL = void 0;
4
+ exports.API_BASE_URL = 'https://transaction.metaswap.codefi.network';
5
+ exports.CHAIN_IDS = {
6
+ ETHEREUM: '0x1',
7
+ RINKEBY: '0x4',
8
+ BSC: '0x38',
9
+ };
10
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,YAAY,GAAG,6CAA6C,CAAC;AAC7D,QAAA,SAAS,GAAG;IACvB,QAAQ,EAAE,KAAK;IACf,OAAO,EAAE,KAAK;IACd,GAAG,EAAE,MAAM;CACZ,CAAC","sourcesContent":["export const API_BASE_URL = 'https://transaction.metaswap.codefi.network';\nexport const CHAIN_IDS = {\n ETHEREUM: '0x1',\n RINKEBY: '0x4',\n BSC: '0x38',\n};\n"]}
@@ -0,0 +1,3 @@
1
+ import 'isomorphic-fetch';
2
+ import SmartTransactionsController from './SmartTransactionsController';
3
+ export default SmartTransactionsController;
package/dist/index.js ADDED
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ // eslint-disable-next-line import/no-unassigned-import
7
+ require("isomorphic-fetch");
8
+ const SmartTransactionsController_1 = __importDefault(require("./SmartTransactionsController"));
9
+ exports.default = SmartTransactionsController_1.default;
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;AAAA,uDAAuD;AACvD,4BAA0B;AAC1B,gGAAwE;AAExE,kBAAe,qCAA2B,CAAC","sourcesContent":["// eslint-disable-next-line import/no-unassigned-import\nimport 'isomorphic-fetch';\nimport SmartTransactionsController from './SmartTransactionsController';\n\nexport default SmartTransactionsController;\n"]}
@@ -0,0 +1,97 @@
1
+ /** API */
2
+ export declare enum APIType {
3
+ 'GET_FEES' = 0,
4
+ 'ESTIMATE_GAS' = 1,
5
+ 'SUBMIT_TRANSACTIONS' = 2,
6
+ 'CANCEL' = 3,
7
+ 'BATCH_STATUS' = 4,
8
+ 'LIVENESS' = 5
9
+ }
10
+ /** SmartTransactions */
11
+ export declare enum SmartTransactionMinedTx {
12
+ NOT_MINED = "not_mined",
13
+ SUCCESS = "success",
14
+ CANCELLED = "cancelled",
15
+ REVERTED = "reverted",
16
+ UNKNOWN = "unknown"
17
+ }
18
+ export declare enum SmartTransactionCancellationReason {
19
+ WOULD_REVERT = "would_revert",
20
+ TOO_CHEAP = "too_cheap",
21
+ DEADLINE_MISSED = "deadline_missed",
22
+ INVALID_NONCE = "invalid_nonce",
23
+ USER_CANCELLED = "user_cancelled",
24
+ NOT_CANCELLED = "not_cancelled",
25
+ PREVIOUS_TX_CANCELLED = "previous_tx_cancelled"
26
+ }
27
+ export declare enum SmartTransactionStatuses {
28
+ PENDING = "pending",
29
+ SUCCESS = "success",
30
+ REVERTED = "reverted",
31
+ UNKNOWN = "unknown",
32
+ CANCELLED = "cancelled",
33
+ CANCELLED_WOULD_REVERT = "cancelled_would_revert",
34
+ CANCELLED_TOO_CHEAP = "cancelled_too_cheap",
35
+ CANCELLED_DEADLINE_MISSED = "cancelled_deadline_missed",
36
+ CANCELLED_INVALID_NONCE = "cancelled_invalid_nonce",
37
+ CANCELLED_USER_CANCELLED = "cancelled_user_cancelled",
38
+ CANCELLED_PREVIOUS_TX_CANCELLED = "cancelled_previous_tx_cancelled",
39
+ RESOLVED = "resolved"
40
+ }
41
+ export declare const cancellationReasonToStatusMap: {
42
+ would_revert: SmartTransactionStatuses;
43
+ too_cheap: SmartTransactionStatuses;
44
+ deadline_missed: SmartTransactionStatuses;
45
+ invalid_nonce: SmartTransactionStatuses;
46
+ user_cancelled: SmartTransactionStatuses;
47
+ previous_tx_cancelled: SmartTransactionStatuses;
48
+ };
49
+ export interface SmartTransactionsStatus {
50
+ error?: string;
51
+ cancellationFeeWei: number;
52
+ cancellationReason?: SmartTransactionCancellationReason;
53
+ deadlineRatio: number;
54
+ minedHash: string | undefined;
55
+ minedTx: SmartTransactionMinedTx;
56
+ isSettled: boolean;
57
+ }
58
+ export interface SmartTransaction {
59
+ uuid: string;
60
+ chainId?: string;
61
+ destinationTokenAddress?: string;
62
+ destinationTokenDecimals?: string;
63
+ destinationTokenSymbol?: string;
64
+ history?: any;
65
+ metamaskNetworkId?: string;
66
+ nonceDetails?: any;
67
+ origin?: string;
68
+ preTxBalance?: string;
69
+ status?: string;
70
+ statusMetadata?: SmartTransactionsStatus;
71
+ sourceTokenSymbol?: string;
72
+ swapMetaData?: any;
73
+ swapTokenValue?: string;
74
+ time?: number;
75
+ txParams?: any;
76
+ type?: string;
77
+ confirmed?: boolean;
78
+ cancellable?: boolean;
79
+ }
80
+ export interface Fee {
81
+ maxFeePerGas: number;
82
+ maxPriorityFeePerGas: number;
83
+ }
84
+ export interface IndividualTxFees {
85
+ fees: Fee[];
86
+ cancelFees: Fee[];
87
+ feeEstimate: number;
88
+ gasLimit: number;
89
+ gasUsed: number;
90
+ }
91
+ export interface Fees {
92
+ approvalTxFees: IndividualTxFees | undefined;
93
+ tradeTxFees: IndividualTxFees | undefined;
94
+ }
95
+ export declare type UnsignedTransaction = any;
96
+ export declare type SignedTransaction = any;
97
+ export declare type SignedCanceledTransaction = any;
package/dist/types.js ADDED
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ /** API */
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.cancellationReasonToStatusMap = exports.SmartTransactionStatuses = exports.SmartTransactionCancellationReason = exports.SmartTransactionMinedTx = exports.APIType = void 0;
5
+ var APIType;
6
+ (function (APIType) {
7
+ APIType[APIType["GET_FEES"] = 0] = "GET_FEES";
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";
13
+ })(APIType = exports.APIType || (exports.APIType = {}));
14
+ /** SmartTransactions */
15
+ var SmartTransactionMinedTx;
16
+ (function (SmartTransactionMinedTx) {
17
+ SmartTransactionMinedTx["NOT_MINED"] = "not_mined";
18
+ SmartTransactionMinedTx["SUCCESS"] = "success";
19
+ SmartTransactionMinedTx["CANCELLED"] = "cancelled";
20
+ SmartTransactionMinedTx["REVERTED"] = "reverted";
21
+ SmartTransactionMinedTx["UNKNOWN"] = "unknown";
22
+ })(SmartTransactionMinedTx = exports.SmartTransactionMinedTx || (exports.SmartTransactionMinedTx = {}));
23
+ var SmartTransactionCancellationReason;
24
+ (function (SmartTransactionCancellationReason) {
25
+ SmartTransactionCancellationReason["WOULD_REVERT"] = "would_revert";
26
+ SmartTransactionCancellationReason["TOO_CHEAP"] = "too_cheap";
27
+ SmartTransactionCancellationReason["DEADLINE_MISSED"] = "deadline_missed";
28
+ SmartTransactionCancellationReason["INVALID_NONCE"] = "invalid_nonce";
29
+ SmartTransactionCancellationReason["USER_CANCELLED"] = "user_cancelled";
30
+ SmartTransactionCancellationReason["NOT_CANCELLED"] = "not_cancelled";
31
+ SmartTransactionCancellationReason["PREVIOUS_TX_CANCELLED"] = "previous_tx_cancelled";
32
+ })(SmartTransactionCancellationReason = exports.SmartTransactionCancellationReason || (exports.SmartTransactionCancellationReason = {}));
33
+ var SmartTransactionStatuses;
34
+ (function (SmartTransactionStatuses) {
35
+ SmartTransactionStatuses["PENDING"] = "pending";
36
+ SmartTransactionStatuses["SUCCESS"] = "success";
37
+ SmartTransactionStatuses["REVERTED"] = "reverted";
38
+ SmartTransactionStatuses["UNKNOWN"] = "unknown";
39
+ SmartTransactionStatuses["CANCELLED"] = "cancelled";
40
+ SmartTransactionStatuses["CANCELLED_WOULD_REVERT"] = "cancelled_would_revert";
41
+ SmartTransactionStatuses["CANCELLED_TOO_CHEAP"] = "cancelled_too_cheap";
42
+ SmartTransactionStatuses["CANCELLED_DEADLINE_MISSED"] = "cancelled_deadline_missed";
43
+ SmartTransactionStatuses["CANCELLED_INVALID_NONCE"] = "cancelled_invalid_nonce";
44
+ SmartTransactionStatuses["CANCELLED_USER_CANCELLED"] = "cancelled_user_cancelled";
45
+ SmartTransactionStatuses["CANCELLED_PREVIOUS_TX_CANCELLED"] = "cancelled_previous_tx_cancelled";
46
+ SmartTransactionStatuses["RESOLVED"] = "resolved";
47
+ })(SmartTransactionStatuses = exports.SmartTransactionStatuses || (exports.SmartTransactionStatuses = {}));
48
+ exports.cancellationReasonToStatusMap = {
49
+ [SmartTransactionCancellationReason.WOULD_REVERT]: SmartTransactionStatuses.CANCELLED_WOULD_REVERT,
50
+ [SmartTransactionCancellationReason.TOO_CHEAP]: SmartTransactionStatuses.CANCELLED_TOO_CHEAP,
51
+ [SmartTransactionCancellationReason.DEADLINE_MISSED]: SmartTransactionStatuses.CANCELLED_DEADLINE_MISSED,
52
+ [SmartTransactionCancellationReason.INVALID_NONCE]: SmartTransactionStatuses.CANCELLED_INVALID_NONCE,
53
+ [SmartTransactionCancellationReason.USER_CANCELLED]: SmartTransactionStatuses.CANCELLED_USER_CANCELLED,
54
+ [SmartTransactionCancellationReason.PREVIOUS_TX_CANCELLED]: SmartTransactionStatuses.CANCELLED_PREVIOUS_TX_CANCELLED,
55
+ };
56
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
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,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":["/** 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 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 interface SmartTransactionsStatus {\n error?: string;\n cancellationFeeWei: number;\n cancellationReason?: SmartTransactionCancellationReason;\n deadlineRatio: number;\n minedHash: string | undefined;\n minedTx: SmartTransactionMinedTx;\n isSettled: boolean;\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 IndividualTxFees {\n fees: Fee[];\n cancelFees: Fee[];\n feeEstimate: number;\n gasLimit: number;\n gasUsed: number;\n}\n\nexport interface 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"]}
@@ -0,0 +1,39 @@
1
+ import { APIType, SmartTransaction, SmartTransactionsStatus, SmartTransactionStatuses } from './types';
2
+ export declare function isSmartTransactionPending(smartTransaction: SmartTransaction): boolean;
3
+ export declare const isSmartTransactionStatusResolved: (stxStatus: SmartTransactionsStatus | string) => boolean;
4
+ export declare function getAPIRequestURL(apiType: APIType, chainId: string): string;
5
+ export declare const calculateStatus: (stxStatus: SmartTransactionsStatus) => SmartTransactionStatuses;
6
+ /**
7
+ Generates an array of history objects sense the previous state.
8
+ The object has the keys
9
+ op (the operation performed),
10
+ path (the key and if a nested object then each key will be separated with a `/`)
11
+ value
12
+ with the first entry having the note and a timestamp when the change took place
13
+ @param {Object} previousState - the previous state of the object
14
+ @param {Object} newState - the update object
15
+ @param {string} [note] - a optional note for the state change
16
+ @returns {Array}
17
+ */
18
+ export declare function generateHistoryEntry(previousState: any, newState: any, note: string): any;
19
+ /**
20
+ Recovers previous txMeta state obj
21
+ @returns {Object}
22
+ */
23
+ export declare function replayHistory(_shortHistory: any): any;
24
+ /**
25
+ * Snapshot {@code txMeta}
26
+ * @param {Object} txMeta - the tx metadata object
27
+ * @returns {Object} a deep clone without history
28
+ */
29
+ export declare function snapshotFromTxMeta(txMeta: any): any;
30
+ /**
31
+ * Returns processing time for an STX in seconds.
32
+ * @param {number} smartTransactionSubmittedtime
33
+ * @returns {number} Processing time in seconds.
34
+ */
35
+ export declare const getStxProcessingTime: (smartTransactionSubmittedtime: number | undefined) => number | undefined;
36
+ export declare const mapKeysToCamel: (obj: Record<string, any>) => Record<string, any>;
37
+ export declare function handleFetch(request: string, options?: RequestInit): Promise<any>;
38
+ export declare const isSmartTransactionCancellable: (stxStatus: SmartTransactionsStatus) => boolean;
39
+ export declare const incrementNonceInHex: (nonceInHex: string) => string;
package/dist/utils.js ADDED
@@ -0,0 +1,182 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.incrementNonceInHex = exports.isSmartTransactionCancellable = exports.handleFetch = exports.mapKeysToCamel = exports.getStxProcessingTime = exports.snapshotFromTxMeta = exports.replayHistory = exports.generateHistoryEntry = exports.calculateStatus = exports.getAPIRequestURL = exports.isSmartTransactionStatusResolved = exports.isSmartTransactionPending = void 0;
7
+ const fast_json_patch_1 = __importDefault(require("fast-json-patch"));
8
+ const lodash_1 = __importDefault(require("lodash"));
9
+ const bignumber_js_1 = require("bignumber.js");
10
+ const ethers_1 = require("ethers");
11
+ const types_1 = require("./types");
12
+ const constants_1 = require("./constants");
13
+ function isSmartTransactionPending(smartTransaction) {
14
+ return smartTransaction.status === types_1.SmartTransactionStatuses.PENDING;
15
+ }
16
+ exports.isSmartTransactionPending = isSmartTransactionPending;
17
+ const isSmartTransactionStatusResolved = (stxStatus) => stxStatus === 'uuid_not_found';
18
+ exports.isSmartTransactionStatusResolved = isSmartTransactionStatusResolved;
19
+ // TODO use actual url once API is defined
20
+ function getAPIRequestURL(apiType, chainId) {
21
+ const chainIdDec = parseInt(chainId, 16);
22
+ switch (apiType) {
23
+ case types_1.APIType.GET_FEES: {
24
+ return `${constants_1.API_BASE_URL}/networks/${chainIdDec}/getFees`;
25
+ }
26
+ case types_1.APIType.ESTIMATE_GAS: {
27
+ return `${constants_1.API_BASE_URL}/networks/${chainIdDec}/estimateGas`;
28
+ }
29
+ case types_1.APIType.SUBMIT_TRANSACTIONS: {
30
+ return `${constants_1.API_BASE_URL}/networks/${chainIdDec}/submitTransactions`;
31
+ }
32
+ case types_1.APIType.CANCEL: {
33
+ return `${constants_1.API_BASE_URL}/networks/${chainIdDec}/cancel`;
34
+ }
35
+ case types_1.APIType.BATCH_STATUS: {
36
+ return `${constants_1.API_BASE_URL}/networks/${chainIdDec}/batchStatus`;
37
+ }
38
+ case types_1.APIType.LIVENESS: {
39
+ return `${constants_1.API_BASE_URL}/networks/${chainIdDec}/health`;
40
+ }
41
+ default: {
42
+ throw new Error(`Invalid APIType`); // It can never get here thanks to TypeScript.
43
+ }
44
+ }
45
+ }
46
+ exports.getAPIRequestURL = getAPIRequestURL;
47
+ const calculateStatus = (stxStatus) => {
48
+ if (exports.isSmartTransactionStatusResolved(stxStatus)) {
49
+ return types_1.SmartTransactionStatuses.RESOLVED;
50
+ }
51
+ const cancellations = [
52
+ types_1.SmartTransactionCancellationReason.WOULD_REVERT,
53
+ types_1.SmartTransactionCancellationReason.TOO_CHEAP,
54
+ types_1.SmartTransactionCancellationReason.DEADLINE_MISSED,
55
+ types_1.SmartTransactionCancellationReason.INVALID_NONCE,
56
+ types_1.SmartTransactionCancellationReason.USER_CANCELLED,
57
+ types_1.SmartTransactionCancellationReason.PREVIOUS_TX_CANCELLED,
58
+ ];
59
+ if ((stxStatus === null || stxStatus === void 0 ? void 0 : stxStatus.minedTx) === types_1.SmartTransactionMinedTx.NOT_MINED) {
60
+ if (stxStatus.cancellationReason ===
61
+ types_1.SmartTransactionCancellationReason.NOT_CANCELLED) {
62
+ return types_1.SmartTransactionStatuses.PENDING;
63
+ }
64
+ const isCancellation = cancellations.findIndex((cancellation) => cancellation === stxStatus.cancellationReason) > -1;
65
+ if (stxStatus.cancellationReason && isCancellation) {
66
+ if (!stxStatus.isSettled) {
67
+ return types_1.SmartTransactionStatuses.PENDING;
68
+ }
69
+ return types_1.cancellationReasonToStatusMap[stxStatus.cancellationReason];
70
+ }
71
+ }
72
+ else if ((stxStatus === null || stxStatus === void 0 ? void 0 : stxStatus.minedTx) === types_1.SmartTransactionMinedTx.SUCCESS) {
73
+ return types_1.SmartTransactionStatuses.SUCCESS;
74
+ }
75
+ else if ((stxStatus === null || stxStatus === void 0 ? void 0 : stxStatus.minedTx) === types_1.SmartTransactionMinedTx.CANCELLED) {
76
+ return types_1.SmartTransactionStatuses.CANCELLED;
77
+ }
78
+ else if ((stxStatus === null || stxStatus === void 0 ? void 0 : stxStatus.minedTx) === types_1.SmartTransactionMinedTx.REVERTED) {
79
+ return types_1.SmartTransactionStatuses.REVERTED;
80
+ }
81
+ else if ((stxStatus === null || stxStatus === void 0 ? void 0 : stxStatus.minedTx) === types_1.SmartTransactionMinedTx.UNKNOWN) {
82
+ return types_1.SmartTransactionStatuses.UNKNOWN;
83
+ }
84
+ return types_1.SmartTransactionStatuses.UNKNOWN;
85
+ };
86
+ exports.calculateStatus = calculateStatus;
87
+ /**
88
+ Generates an array of history objects sense the previous state.
89
+ The object has the keys
90
+ op (the operation performed),
91
+ path (the key and if a nested object then each key will be separated with a `/`)
92
+ value
93
+ with the first entry having the note and a timestamp when the change took place
94
+ @param {Object} previousState - the previous state of the object
95
+ @param {Object} newState - the update object
96
+ @param {string} [note] - a optional note for the state change
97
+ @returns {Array}
98
+ */
99
+ function generateHistoryEntry(previousState, newState, note) {
100
+ const entry = fast_json_patch_1.default.compare(previousState, newState);
101
+ // Add a note to the first op, since it breaks if we append it to the entry
102
+ if (entry[0]) {
103
+ if (note) {
104
+ entry[0].note = note;
105
+ }
106
+ entry[0].timestamp = Date.now();
107
+ }
108
+ return entry;
109
+ }
110
+ exports.generateHistoryEntry = generateHistoryEntry;
111
+ /**
112
+ Recovers previous txMeta state obj
113
+ @returns {Object}
114
+ */
115
+ function replayHistory(_shortHistory) {
116
+ const shortHistory = lodash_1.default.cloneDeep(_shortHistory);
117
+ return shortHistory.reduce((val, entry) => fast_json_patch_1.default.applyPatch(val, entry).newDocument);
118
+ }
119
+ exports.replayHistory = replayHistory;
120
+ /**
121
+ * Snapshot {@code txMeta}
122
+ * @param {Object} txMeta - the tx metadata object
123
+ * @returns {Object} a deep clone without history
124
+ */
125
+ function snapshotFromTxMeta(txMeta) {
126
+ const shallow = Object.assign({}, txMeta);
127
+ delete shallow.history;
128
+ return lodash_1.default.cloneDeep(shallow);
129
+ }
130
+ exports.snapshotFromTxMeta = snapshotFromTxMeta;
131
+ /**
132
+ * Returns processing time for an STX in seconds.
133
+ * @param {number} smartTransactionSubmittedtime
134
+ * @returns {number} Processing time in seconds.
135
+ */
136
+ const getStxProcessingTime = (smartTransactionSubmittedtime) => {
137
+ if (!smartTransactionSubmittedtime) {
138
+ return undefined;
139
+ }
140
+ return Math.round((Date.now() - smartTransactionSubmittedtime) / 1000);
141
+ };
142
+ exports.getStxProcessingTime = getStxProcessingTime;
143
+ const mapKeysToCamel = (obj) => {
144
+ if (!lodash_1.default.isObject(obj)) {
145
+ return obj;
146
+ }
147
+ const mappedValues = lodash_1.default.mapValues(obj, (val) => {
148
+ if (lodash_1.default.isArray(val)) {
149
+ return val.map(exports.mapKeysToCamel);
150
+ }
151
+ else if (lodash_1.default.isObject(val)) {
152
+ return exports.mapKeysToCamel(val);
153
+ }
154
+ return val;
155
+ });
156
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
157
+ return lodash_1.default.mapKeys(mappedValues, (value, key) => lodash_1.default.camelCase(key));
158
+ };
159
+ exports.mapKeysToCamel = mapKeysToCamel;
160
+ async function handleFetch(request, options) {
161
+ const response = await fetch(request, options);
162
+ const json = await response.json();
163
+ if (!response.ok) {
164
+ console.log(`response`, response);
165
+ throw new Error(`Fetch error:${JSON.stringify(Object.assign({ status: response.status }, exports.mapKeysToCamel(json)))}`);
166
+ }
167
+ return json;
168
+ }
169
+ exports.handleFetch = handleFetch;
170
+ const isSmartTransactionCancellable = (stxStatus) => {
171
+ return (stxStatus.minedTx === types_1.SmartTransactionMinedTx.NOT_MINED &&
172
+ (!stxStatus.cancellationReason ||
173
+ stxStatus.cancellationReason ===
174
+ types_1.SmartTransactionCancellationReason.NOT_CANCELLED));
175
+ };
176
+ exports.isSmartTransactionCancellable = isSmartTransactionCancellable;
177
+ const incrementNonceInHex = (nonceInHex) => {
178
+ const nonceInDec = new bignumber_js_1.BigNumber(nonceInHex, 16).toString(10);
179
+ return ethers_1.ethers.utils.hexlify(Number(nonceInDec) + 1);
180
+ };
181
+ exports.incrementNonceInHex = incrementNonceInHex;
182
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +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 _ from 'lodash';\nimport { BigNumber } from 'bignumber.js';\nimport { ethers } from 'ethers';\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 stxStatus: SmartTransactionsStatus | string,\n) => stxStatus === '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 = (stxStatus: SmartTransactionsStatus) => {\n if (isSmartTransactionStatusResolved(stxStatus)) {\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 SmartTransactionCancellationReason.PREVIOUS_TX_CANCELLED,\n ];\n if (stxStatus?.minedTx === SmartTransactionMinedTx.NOT_MINED) {\n if (\n stxStatus.cancellationReason ===\n SmartTransactionCancellationReason.NOT_CANCELLED\n ) {\n return SmartTransactionStatuses.PENDING;\n }\n\n const isCancellation =\n cancellations.findIndex(\n (cancellation) => cancellation === stxStatus.cancellationReason,\n ) > -1;\n if (stxStatus.cancellationReason && isCancellation) {\n if (!stxStatus.isSettled) {\n return SmartTransactionStatuses.PENDING;\n }\n return cancellationReasonToStatusMap[stxStatus.cancellationReason];\n }\n } else if (stxStatus?.minedTx === SmartTransactionMinedTx.SUCCESS) {\n return SmartTransactionStatuses.SUCCESS;\n } else if (stxStatus?.minedTx === SmartTransactionMinedTx.CANCELLED) {\n return SmartTransactionStatuses.CANCELLED;\n } else if (stxStatus?.minedTx === SmartTransactionMinedTx.REVERTED) {\n return SmartTransactionStatuses.REVERTED;\n } else if (stxStatus?.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 const mapKeysToCamel = (\n obj: Record<string, any>,\n): Record<string, any> => {\n if (!_.isObject(obj)) {\n return obj;\n }\n const mappedValues = _.mapValues(obj, (val: Record<string, any>) => {\n if (_.isArray(val)) {\n return val.map(mapKeysToCamel);\n } else if (_.isObject(val)) {\n return mapKeysToCamel(val);\n }\n return val;\n });\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n return _.mapKeys(mappedValues, (value, key) => _.camelCase(key));\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 console.log(`response`, response);\n throw new Error(\n `Fetch error:${JSON.stringify({\n status: response.status,\n ...mapKeysToCamel(json),\n })}`,\n );\n }\n return json;\n}\n\nexport const isSmartTransactionCancellable = (\n stxStatus: SmartTransactionsStatus,\n): boolean => {\n return (\n stxStatus.minedTx === SmartTransactionMinedTx.NOT_MINED &&\n (!stxStatus.cancellationReason ||\n stxStatus.cancellationReason ===\n SmartTransactionCancellationReason.NOT_CANCELLED)\n );\n};\n\nexport const incrementNonceInHex = (nonceInHex: string): string => {\n const nonceInDec = new BigNumber(nonceInHex, 16).toString(10);\n return ethers.utils.hexlify(Number(nonceInDec) + 1);\n};\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metamask/smart-transactions-controller",
3
- "version": "2.0.0",
3
+ "version": "2.3.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": "^29.0.1",
29
+ "@metamask/controllers": "^30.0.0",
30
30
  "@types/lodash": "^4.14.176",
31
31
  "bignumber.js": "^9.0.1",
32
32
  "ethers": "^5.5.1",
@@ -39,7 +39,7 @@
39
39
  "@metamask/auto-changelog": "^2.3.0",
40
40
  "@metamask/eslint-config": "^8.0.0",
41
41
  "@metamask/eslint-config-jest": "^8.0.0",
42
- "@metamask/eslint-config-nodejs": "^8.0.0",
42
+ "@metamask/eslint-config-nodejs": "^9.0.0",
43
43
  "@metamask/eslint-config-typescript": "^8.0.0",
44
44
  "@types/jest": "^26.0.13",
45
45
  "@types/node": "^16.7.8",
package/CHANGELOG.md DELETED
@@ -1,104 +0,0 @@
1
- # Changelog
2
- All notable changes to this project will be documented in this file.
3
-
4
- The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
5
- and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
-
7
- ## [Unreleased]
8
-
9
- ## [2.0.0]
10
- ### Added
11
- - "estimateGas" -> "getFees", support a new cancellation reason, refactoring ([#69](https://github.com/MetaMask/smart-transactions-controller/pull/69))
12
- - chore(deps): bump @metamask/controllers from 28.0.0 to 29.0.1 ([#68](https://github.com/MetaMask/smart-transactions-controller/pull/68))
13
- - If mined status is not mined and cancel reason not set, then show the cancel link, refactoring ([#66](https://github.com/MetaMask/smart-transactions-controller/pull/66))
14
- - chore(deps): bump @metamask/controllers from 27.1.1 to 28.0.0 ([#65](https://github.com/MetaMask/smart-transactions-controller/pull/65))
15
-
16
- ## [1.10.0]
17
- ### Added
18
- - 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))
19
- - chore(deps): bump @metamask/controllers from 25.1.0 to 27.1.1 ([#62](https://github.com/MetaMask/smart-transactions-controller/pull/62))
20
- - Add tracking of the "current_stx_enabled" param ([#58](https://github.com/MetaMask/smart-transactions-controller/pull/58))
21
-
22
- ## [1.9.1]
23
- ### Added
24
- - Use the "confirmExternalTransaction" fn directly ([#56](https://github.com/MetaMask/smart-transactions-controller/pull/56))
25
-
26
- ## [1.9.0]
27
- ### Added
28
- - Only accept the "getNonceLock" fn and not the whole "nonceTracker" ([#54](https://github.com/MetaMask/smart-transactions-controller/pull/54))
29
-
30
- ## [1.8.0]
31
- ### Added
32
- - Do not update an STX which doesn't exist anymore, add UTs ([#52](https://github.com/MetaMask/smart-transactions-controller/pull/52))
33
-
34
- ## [1.7.0]
35
- ### Added
36
- - Fix UTs, change threshold ([#49](https://github.com/MetaMask/smart-transactions-controller/pull/49))
37
-
38
- ## [1.6.0]
39
- ### Added
40
- - Change cancellable interval to be 1 minute ([#47](https://github.com/MetaMask/smart-transactions-controller/pull/47))
41
- - Estimate approval transaction along with swaps transaction ([#46](https://github.com/MetaMask/smart-transactions-controller/pull/46))
42
- - chore(deps): bump @metamask/controllers from 20.1.0 to 25.1.0 ([#44](https://github.com/MetaMask/smart-transactions-controller/pull/44))
43
- - Add support for approveTxParams ([#45](https://github.com/MetaMask/smart-transactions-controller/pull/45))
44
- - Add method for estimateGas ([#43](https://github.com/MetaMask/smart-transactions-controller/pull/43))
45
-
46
- ## [1.5.0]
47
- ### Added
48
- - Add "fees" and "liveness" into the smartTransactionsState, update version ([#41](https://github.com/MetaMask/smart-transactions-controller/pull/41))
49
-
50
- ## [1.4.0]
51
- ### Added
52
- - Add isomorphic-fetch to stx controller ([#38](https://github.com/MetaMask/smart-transactions-controller/pull/38))
53
- - feat: create new handleFetch with custom error handling ([#35](https://github.com/MetaMask/smart-transactions-controller/pull/35))
54
- - Unblock submit if ethers errors ([#30](https://github.com/MetaMask/smart-transactions-controller/pull/30))
55
- - Parse chain ids from hex to dec instead of mapping them ([#31](https://github.com/MetaMask/smart-transactions-controller/pull/31))
56
- - chore(deps): bump @metamask/controllers from 20.0.0 to 20.1.0 ([#28](https://github.com/MetaMask/smart-transactions-controller/pull/28))
57
- - getTransactions -> getFees, refactoring ([#27](https://github.com/MetaMask/smart-transactions-controller/pull/27))
58
- - chore(deps): bump @metamask/controllers from 19.0.0 to 20.0.0 ([#24](https://github.com/MetaMask/smart-transactions-controller/pull/24))
59
- - Switch license with MetaMask license ([#25](https://github.com/MetaMask/smart-transactions-controller/pull/25))
60
-
61
- ## [1.3.0]
62
- ### Added
63
- - Use the production version of the Transaction APIs repo ([#37](https://github.com/MetaMask/smart-transactions-controller/pull/37))
64
-
65
- ## [1.2.0]
66
- ### Added
67
- - Add more unit tests for SmartTransactionsController ([#23](https://github.com/MetaMask/smart-transactions-controller/pull/23))
68
- - chore(deps): bump @metamask/controllers from 16.0.0 to 19.0.0 ([#18](https://github.com/MetaMask/smart-transactions-controller/pull/18))
69
- - Add cancelled status to stx after successful cancel request ([#21](https://github.com/MetaMask/smart-transactions-controller/pull/21))
70
- - 1.1.0 ([#22](https://github.com/MetaMask/smart-transactions-controller/pull/22))
71
-
72
- ## [1.1.0]
73
- ### Added
74
- - Tracking of STX status changes ([#20](https://github.com/MetaMask/smart-transactions-controller/pull/20))
75
- - Remove cancelled transaction when new trx with same nonce submitted ([#19](https://github.com/MetaMask/smart-transactions-controller/pull/19))
76
- - chore: modify polling and clean up tests ([#17](https://github.com/MetaMask/smart-transactions-controller/pull/17))
77
- - State changes + getTransactions fn ([#16](https://github.com/MetaMask/smart-transactions-controller/pull/16))
78
- - Add updatedTxParams and confirm history event ([#15](https://github.com/MetaMask/smart-transactions-controller/pull/15))
79
- - Smart Transactions List ([#13](https://github.com/MetaMask/smart-transactions-controller/pull/13))
80
-
81
- ## [1.0.0]
82
- ### Added
83
- - Adds nonce to a tx, adds `yarn build:link` support, updates functions for API calls, refactoring ([#8](https://github.com/MetaMask/smart-transactions-controller/pull/8))
84
- - Add many unit tests, support for the batch_status API, refactoring ([#6](https://github.com/MetaMask/smart-transactions-controller/pull/6))
85
- - Bump @metamask/controllers from 15.1.0 to 16.0.0
86
- - Bump @metamask/controllers from 15.0.0 to 15.1.0 ([#4](https://github.com/MetaMask/smart-transactions-controller/pull/4))
87
- - Add initial methods ([#3](https://github.com/MetaMask/smart-transactions-controller/pull/3))
88
- - Add initial SmartTransactionsController ([#1](https://github.com/MetaMask/smart-transactions-controller/pull/1))
89
- - Initial commit
90
-
91
- [Unreleased]: https://github.com/MetaMask/smart-transactions-controller/compare/v2.0.0...HEAD
92
- [2.0.0]: https://github.com/MetaMask/smart-transactions-controller/compare/v1.10.0...v2.0.0
93
- [1.10.0]: https://github.com/MetaMask/smart-transactions-controller/compare/v1.9.1...v1.10.0
94
- [1.9.1]: https://github.com/MetaMask/smart-transactions-controller/compare/v1.9.0...v1.9.1
95
- [1.9.0]: https://github.com/MetaMask/smart-transactions-controller/compare/v1.8.0...v1.9.0
96
- [1.8.0]: https://github.com/MetaMask/smart-transactions-controller/compare/v1.7.0...v1.8.0
97
- [1.7.0]: https://github.com/MetaMask/smart-transactions-controller/compare/v1.6.0...v1.7.0
98
- [1.6.0]: https://github.com/MetaMask/smart-transactions-controller/compare/v1.5.0...v1.6.0
99
- [1.5.0]: https://github.com/MetaMask/smart-transactions-controller/compare/v1.4.0...v1.5.0
100
- [1.4.0]: https://github.com/MetaMask/smart-transactions-controller/compare/v1.3.0...v1.4.0
101
- [1.3.0]: https://github.com/MetaMask/smart-transactions-controller/compare/v1.2.0...v1.3.0
102
- [1.2.0]: https://github.com/MetaMask/smart-transactions-controller/compare/v1.1.0...v1.2.0
103
- [1.1.0]: https://github.com/MetaMask/smart-transactions-controller/compare/v1.0.0...v1.1.0
104
- [1.0.0]: https://github.com/MetaMask/smart-transactions-controller/releases/tag/v1.0.0