From 490a34f22b983a362e9db4f272087429c003b6fe Mon Sep 17 00:00:00 2001 From: dan437 <80175477+dan437@users.noreply.github.com> Date: Thu, 12 May 2022 15:40:48 +0200 Subject: [PATCH 1/5] Add support for a new cancellation reason: PREVIOUS_TX_CANCELLED --- src/types.ts | 4 ++++ src/utils.test.ts | 11 +++++++++++ src/utils.ts | 1 + 3 files changed, 16 insertions(+) diff --git a/src/types.ts b/src/types.ts index 573f7358..54d19b5b 100644 --- a/src/types.ts +++ b/src/types.ts @@ -26,6 +26,7 @@ export enum SmartTransactionCancellationReason { INVALID_NONCE = 'invalid_nonce', USER_CANCELLED = 'user_cancelled', NOT_CANCELLED = 'not_cancelled', + PREVIOUS_TX_CANCELLED = 'previous_tx_cancelled', } export enum SmartTransactionStatuses { @@ -39,6 +40,7 @@ export enum SmartTransactionStatuses { CANCELLED_DEADLINE_MISSED = 'cancelled_deadline_missed', CANCELLED_INVALID_NONCE = 'cancelled_invalid_nonce', CANCELLED_USER_CANCELLED = 'cancelled_user_cancelled', + CANCELLED_PREVIOUS_TX_CANCELLED = 'cancelled_previous_tx_cancelled', RESOLVED = 'resolved', } @@ -53,6 +55,8 @@ export const cancellationReasonToStatusMap = { SmartTransactionStatuses.CANCELLED_INVALID_NONCE, [SmartTransactionCancellationReason.USER_CANCELLED]: SmartTransactionStatuses.CANCELLED_USER_CANCELLED, + [SmartTransactionCancellationReason.PREVIOUS_TX_CANCELLED]: + SmartTransactionStatuses.CANCELLED_PREVIOUS_TX_CANCELLED, }; export interface SmartTransactionsStatus { diff --git a/src/utils.test.ts b/src/utils.test.ts index 565088ad..b2281948 100644 --- a/src/utils.test.ts +++ b/src/utils.test.ts @@ -157,6 +157,17 @@ describe('src/utils.js', () => { SmartTransactionStatuses.CANCELLED_USER_CANCELLED, ); }); + + it('returns cancellation state "CANCELLED_PREVIOUS_TX_CANCELLED" if cancellationReason provided', () => { + const statusResponse = { + ...createStatusResponse(), + cancellationReason: + SmartTransactionCancellationReason.PREVIOUS_TX_CANCELLED, + }; + expect(utils.calculateStatus(statusResponse)).toStrictEqual( + SmartTransactionStatuses.CANCELLED_PREVIOUS_TX_CANCELLED, + ); + }); }); describe('getStxProcessingTime', () => { diff --git a/src/utils.ts b/src/utils.ts index d8e3e042..877f4ff5 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -63,6 +63,7 @@ export const calculateStatus = (stxStatus: SmartTransactionsStatus) => { SmartTransactionCancellationReason.DEADLINE_MISSED, SmartTransactionCancellationReason.INVALID_NONCE, SmartTransactionCancellationReason.USER_CANCELLED, + SmartTransactionCancellationReason.PREVIOUS_TX_CANCELLED, ]; if (stxStatus?.minedTx === SmartTransactionMinedTx.NOT_MINED) { if ( From cf2bebb1c4f2b73ed6a27daeee590b1af2b3e53a Mon Sep 17 00:00:00 2001 From: dan437 <80175477+dan437@users.noreply.github.com> Date: Mon, 16 May 2022 13:32:27 +0200 Subject: [PATCH 2/5] Get approval and trade fees within one API call --- src/SmartTransactionsController.ts | 46 +++++++++++++++++++++++++----- src/types.ts | 7 ++++- 2 files changed, 45 insertions(+), 8 deletions(-) diff --git a/src/SmartTransactionsController.ts b/src/SmartTransactionsController.ts index 77ab5813..c45812d4 100644 --- a/src/SmartTransactionsController.ts +++ b/src/SmartTransactionsController.ts @@ -19,6 +19,7 @@ import { SmartTransactionStatuses, Fees, EstimatedGas, + IndividualTxFees, } from './types'; import { getAPIRequestURL, @@ -50,7 +51,10 @@ export interface SmartTransactionsControllerState extends BaseState { smartTransactions: Record; userOptIn: boolean | undefined; liveness: boolean | undefined; - fees: Fees | undefined; + fees: { + approvalTxFees: IndividualTxFees | undefined; + tradeTxFees: IndividualTxFees | undefined; + }; estimatedGas: { txData: EstimatedGas | undefined; approvalTxData: EstimatedGas | undefined; @@ -122,7 +126,10 @@ export default class SmartTransactionsController extends BaseController< smartTransactionsState: { smartTransactions: {}, userOptIn: undefined, - fees: undefined, + fees: { + approvalTxFees: undefined, + tradeTxFees: undefined, + }, liveness: true, estimatedGas: { txData: undefined, @@ -469,25 +476,50 @@ export default class SmartTransactionsController extends BaseController< }; } - async getFees(unsignedTransaction: UnsignedTransaction): Promise { + async getFees( + unsignedTransaction: UnsignedTransaction, + approveTxParams: UnsignedTransaction, + ): Promise { const { chainId } = this.config; - + const transactions = []; + if (approveTxParams) { + const unsignedApprovalTransactionWithNonce = await this.addNonceToTransaction( + approveTxParams, + ); + transactions.push(unsignedApprovalTransactionWithNonce); + } const unsignedTransactionWithNonce = await this.addNonceToTransaction( unsignedTransaction, ); + transactions.push(unsignedTransactionWithNonce); const data = await this.fetch(getAPIRequestURL(APIType.GET_FEES, chainId), { method: 'POST', body: JSON.stringify({ - tx: unsignedTransactionWithNonce, + txs: transactions, }), }); + let approvalTxFees; + let tradeTxFees; + if (approveTxParams) { + approvalTxFees = data?.txs[0]; + tradeTxFees = data?.txs[1]; + } else { + tradeTxFees = data?.txs[0]; + } + this.update({ smartTransactionsState: { ...this.state.smartTransactionsState, - fees: data, + fees: { + approvalTxFees, + tradeTxFees, + }, }, }); - return data; + return { + approvalTxFees, + tradeTxFees, + }; } async estimateGas( diff --git a/src/types.ts b/src/types.ts index 54d19b5b..6b87e49a 100644 --- a/src/types.ts +++ b/src/types.ts @@ -96,7 +96,7 @@ export interface Fee { maxPriorityFeePerGas: number; } -export interface Fees { +export interface IndividualTxFees { fees: Fee[]; cancelFees: Fee[]; feeEstimate: number; @@ -104,6 +104,11 @@ export interface Fees { gasUsed: number; } +export interface Fees { + approvalTxFees: IndividualTxFees | undefined; + tradeTxFees: IndividualTxFees | undefined; +} + export interface EstimatedGas { gasUsed: number; gasLimit: number; From d8b86b2efc7d240ebc69ebd7d272dfdf4bc19b30 Mon Sep 17 00:00:00 2001 From: dan437 <80175477+dan437@users.noreply.github.com> Date: Mon, 16 May 2022 13:49:11 +0200 Subject: [PATCH 3/5] Remove code related to "estimatedGas", update UTs for "getFees", refactoring --- src/SmartTransactionsController.test.ts | 200 ++++++++++++++---------- src/SmartTransactionsController.ts | 64 +------- src/types.ts | 8 +- 3 files changed, 121 insertions(+), 151 deletions(-) diff --git a/src/SmartTransactionsController.test.ts b/src/SmartTransactionsController.test.ts index 7f100415..b61156a2 100644 --- a/src/SmartTransactionsController.test.ts +++ b/src/SmartTransactionsController.test.ts @@ -47,59 +47,104 @@ const createUnsignedTransaction = () => { const createGetFeesApiResponse = () => { return { - cancelFees: [ - { maxFeePerGas: 2100001000, maxPriorityFeePerGas: 466503987 }, - { maxFeePerGas: 2310003200, maxPriorityFeePerGas: 513154852 }, - { maxFeePerGas: 2541005830, maxPriorityFeePerGas: 564470851 }, - { maxFeePerGas: 2795108954, maxPriorityFeePerGas: 620918500 }, - { maxFeePerGas: 3074622644, maxPriorityFeePerGas: 683010971 }, - { maxFeePerGas: 3382087983, maxPriorityFeePerGas: 751312751 }, - { maxFeePerGas: 3720300164, maxPriorityFeePerGas: 826444778 }, - { maxFeePerGas: 4092333900, maxPriorityFeePerGas: 909090082 }, - { maxFeePerGas: 4501571383, maxPriorityFeePerGas: 1000000000 }, - { maxFeePerGas: 4951733023, maxPriorityFeePerGas: 1100001000 }, - { maxFeePerGas: 5446911277, maxPriorityFeePerGas: 1210002200 }, - { maxFeePerGas: 5991607851, maxPriorityFeePerGas: 1331003630 }, - { maxFeePerGas: 6590774628, maxPriorityFeePerGas: 1464105324 }, - { maxFeePerGas: 7249858682, maxPriorityFeePerGas: 1610517320 }, - { maxFeePerGas: 7974851800, maxPriorityFeePerGas: 1771570663 }, - { maxFeePerGas: 8772344955, maxPriorityFeePerGas: 1948729500 }, - { maxFeePerGas: 9649588222, maxPriorityFeePerGas: 2143604399 }, - { maxFeePerGas: 10614556694, maxPriorityFeePerGas: 2357966983 }, - { maxFeePerGas: 11676022978, maxPriorityFeePerGas: 2593766039 }, - ], - feeEstimate: 42000000000000, - fees: [ - { maxFeePerGas: 2310003200, maxPriorityFeePerGas: 513154852 }, - { maxFeePerGas: 2541005830, maxPriorityFeePerGas: 564470850 }, - { maxFeePerGas: 2795108954, maxPriorityFeePerGas: 620918500 }, - { maxFeePerGas: 3074622644, maxPriorityFeePerGas: 683010970 }, - { maxFeePerGas: 3382087983, maxPriorityFeePerGas: 751312751 }, - { maxFeePerGas: 3720300163, maxPriorityFeePerGas: 826444777 }, - { maxFeePerGas: 4092333900, maxPriorityFeePerGas: 909090082 }, - { maxFeePerGas: 4501571382, maxPriorityFeePerGas: 999999999 }, - { maxFeePerGas: 4951733022, maxPriorityFeePerGas: 1100001000 }, - { maxFeePerGas: 5446911277, maxPriorityFeePerGas: 1210002200 }, - { maxFeePerGas: 5991607851, maxPriorityFeePerGas: 1331003630 }, - { maxFeePerGas: 6590774627, maxPriorityFeePerGas: 1464105324 }, - { maxFeePerGas: 7249858681, maxPriorityFeePerGas: 1610517320 }, - { maxFeePerGas: 7974851800, maxPriorityFeePerGas: 1771570662 }, - { maxFeePerGas: 8772344954, maxPriorityFeePerGas: 1948729500 }, - { maxFeePerGas: 9649588222, maxPriorityFeePerGas: 2143604398 }, - { maxFeePerGas: 10614556693, maxPriorityFeePerGas: 2357966982 }, - { maxFeePerGas: 11676022977, maxPriorityFeePerGas: 2593766039 }, - { maxFeePerGas: 12843636951, maxPriorityFeePerGas: 2853145236 }, + txs: [ + { + // Approval tx. + cancelFees: [ + { maxFeePerGas: 2100001000, maxPriorityFeePerGas: 466503987 }, + { maxFeePerGas: 2310003200, maxPriorityFeePerGas: 513154852 }, + { maxFeePerGas: 2541005830, maxPriorityFeePerGas: 564470851 }, + { maxFeePerGas: 2795108954, maxPriorityFeePerGas: 620918500 }, + { maxFeePerGas: 3074622644, maxPriorityFeePerGas: 683010971 }, + { maxFeePerGas: 3382087983, maxPriorityFeePerGas: 751312751 }, + { maxFeePerGas: 3720300164, maxPriorityFeePerGas: 826444778 }, + { maxFeePerGas: 4092333900, maxPriorityFeePerGas: 909090082 }, + { maxFeePerGas: 4501571383, maxPriorityFeePerGas: 1000000000 }, + { maxFeePerGas: 4951733023, maxPriorityFeePerGas: 1100001000 }, + { maxFeePerGas: 5446911277, maxPriorityFeePerGas: 1210002200 }, + { maxFeePerGas: 5991607851, maxPriorityFeePerGas: 1331003630 }, + { maxFeePerGas: 6590774628, maxPriorityFeePerGas: 1464105324 }, + { maxFeePerGas: 7249858682, maxPriorityFeePerGas: 1610517320 }, + { maxFeePerGas: 7974851800, maxPriorityFeePerGas: 1771570663 }, + { maxFeePerGas: 8772344955, maxPriorityFeePerGas: 1948729500 }, + { maxFeePerGas: 9649588222, maxPriorityFeePerGas: 2143604399 }, + { maxFeePerGas: 10614556694, maxPriorityFeePerGas: 2357966983 }, + { maxFeePerGas: 11676022978, maxPriorityFeePerGas: 2593766039 }, + ], + feeEstimate: 42000000000000, + fees: [ + { maxFeePerGas: 2310003200, maxPriorityFeePerGas: 513154852 }, + { maxFeePerGas: 2541005830, maxPriorityFeePerGas: 564470850 }, + { maxFeePerGas: 2795108954, maxPriorityFeePerGas: 620918500 }, + { maxFeePerGas: 3074622644, maxPriorityFeePerGas: 683010970 }, + { maxFeePerGas: 3382087983, maxPriorityFeePerGas: 751312751 }, + { maxFeePerGas: 3720300163, maxPriorityFeePerGas: 826444777 }, + { maxFeePerGas: 4092333900, maxPriorityFeePerGas: 909090082 }, + { maxFeePerGas: 4501571382, maxPriorityFeePerGas: 999999999 }, + { maxFeePerGas: 4951733022, maxPriorityFeePerGas: 1100001000 }, + { maxFeePerGas: 5446911277, maxPriorityFeePerGas: 1210002200 }, + { maxFeePerGas: 5991607851, maxPriorityFeePerGas: 1331003630 }, + { maxFeePerGas: 6590774627, maxPriorityFeePerGas: 1464105324 }, + { maxFeePerGas: 7249858681, maxPriorityFeePerGas: 1610517320 }, + { maxFeePerGas: 7974851800, maxPriorityFeePerGas: 1771570662 }, + { maxFeePerGas: 8772344954, maxPriorityFeePerGas: 1948729500 }, + { maxFeePerGas: 9649588222, maxPriorityFeePerGas: 2143604398 }, + { maxFeePerGas: 10614556693, maxPriorityFeePerGas: 2357966982 }, + { maxFeePerGas: 11676022977, maxPriorityFeePerGas: 2593766039 }, + { maxFeePerGas: 12843636951, maxPriorityFeePerGas: 2853145236 }, + ], + gasLimit: 21000, + gasUsed: 21000, + }, + { + // Trade tx. + cancelFees: [ + { maxFeePerGas: 2100001000, maxPriorityFeePerGas: 466503987 }, + { maxFeePerGas: 2310003200, maxPriorityFeePerGas: 513154852 }, + { maxFeePerGas: 2541005830, maxPriorityFeePerGas: 564470851 }, + { maxFeePerGas: 2795108954, maxPriorityFeePerGas: 620918500 }, + { maxFeePerGas: 3074622644, maxPriorityFeePerGas: 683010971 }, + { maxFeePerGas: 3382087983, maxPriorityFeePerGas: 751312751 }, + { maxFeePerGas: 3720300164, maxPriorityFeePerGas: 826444778 }, + { maxFeePerGas: 4092333900, maxPriorityFeePerGas: 909090082 }, + { maxFeePerGas: 4501571383, maxPriorityFeePerGas: 1000000000 }, + { maxFeePerGas: 4951733023, maxPriorityFeePerGas: 1100001000 }, + { maxFeePerGas: 5446911277, maxPriorityFeePerGas: 1210002200 }, + { maxFeePerGas: 5991607851, maxPriorityFeePerGas: 1331003630 }, + { maxFeePerGas: 6590774628, maxPriorityFeePerGas: 1464105324 }, + { maxFeePerGas: 7249858682, maxPriorityFeePerGas: 1610517320 }, + { maxFeePerGas: 7974851800, maxPriorityFeePerGas: 1771570663 }, + { maxFeePerGas: 8772344955, maxPriorityFeePerGas: 1948729500 }, + { maxFeePerGas: 9649588222, maxPriorityFeePerGas: 2143604399 }, + { maxFeePerGas: 10614556694, maxPriorityFeePerGas: 2357966983 }, + { maxFeePerGas: 11676022978, maxPriorityFeePerGas: 2593766039 }, + ], + feeEstimate: 42000000000000, + fees: [ + { maxFeePerGas: 2310003200, maxPriorityFeePerGas: 513154852 }, + { maxFeePerGas: 2541005830, maxPriorityFeePerGas: 564470850 }, + { maxFeePerGas: 2795108954, maxPriorityFeePerGas: 620918500 }, + { maxFeePerGas: 3074622644, maxPriorityFeePerGas: 683010970 }, + { maxFeePerGas: 3382087983, maxPriorityFeePerGas: 751312751 }, + { maxFeePerGas: 3720300163, maxPriorityFeePerGas: 826444777 }, + { maxFeePerGas: 4092333900, maxPriorityFeePerGas: 909090082 }, + { maxFeePerGas: 4501571382, maxPriorityFeePerGas: 999999999 }, + { maxFeePerGas: 4951733022, maxPriorityFeePerGas: 1100001000 }, + { maxFeePerGas: 5446911277, maxPriorityFeePerGas: 1210002200 }, + { maxFeePerGas: 5991607851, maxPriorityFeePerGas: 1331003630 }, + { maxFeePerGas: 6590774627, maxPriorityFeePerGas: 1464105324 }, + { maxFeePerGas: 7249858681, maxPriorityFeePerGas: 1610517320 }, + { maxFeePerGas: 7974851800, maxPriorityFeePerGas: 1771570662 }, + { maxFeePerGas: 8772344954, maxPriorityFeePerGas: 1948729500 }, + { maxFeePerGas: 9649588222, maxPriorityFeePerGas: 2143604398 }, + { maxFeePerGas: 10614556693, maxPriorityFeePerGas: 2357966982 }, + { maxFeePerGas: 11676022977, maxPriorityFeePerGas: 2593766039 }, + { maxFeePerGas: 12843636951, maxPriorityFeePerGas: 2853145236 }, + ], + gasLimit: 21000, + gasUsed: 21000, + }, ], - gasLimit: 21000, - gasUsed: 21000, - }; -}; - -const createEstimateGasApiResponse = () => { - return { - feeEstimate: 42000000000000, - gasLimit: 21000, - gasUsed: 21000, }; }; @@ -255,12 +300,11 @@ describe('SmartTransactionsController', () => { [CHAIN_IDS.ETHEREUM]: [], }, userOptIn: undefined, - fees: undefined, - liveness: true, - estimatedGas: { - approvalTxData: undefined, - txData: undefined, + fees: { + approvalTxFees: undefined, + tradeTxFees: undefined, }, + liveness: true, }, }); }); @@ -391,15 +435,20 @@ describe('SmartTransactionsController', () => { describe('getFees', () => { it('gets unsigned transactions and estimates based on an unsigned transaction', async () => { - const unsignedTransaction = createUnsignedTransaction(); + const tradeTx = createUnsignedTransaction(); + const approvalTx = createUnsignedTransaction(); const getFeesApiResponse = createGetFeesApiResponse(); nock(API_BASE_URL) .post(`/networks/${ethereumChainIdDec}/getFees`) .reply(200, getFeesApiResponse); const fees = await smartTransactionsController.getFees( - unsignedTransaction, + tradeTx, + approvalTx, ); - expect(fees).toStrictEqual(getFeesApiResponse); + expect(fees).toMatchObject({ + approvalTxFees: getFeesApiResponse.txs[0], + tradeTxFees: getFeesApiResponse.txs[1], + }); }); }); @@ -451,12 +500,11 @@ describe('SmartTransactionsController', () => { [CHAIN_IDS.ETHEREUM]: [pendingTransaction], }, userOptIn: undefined, - fees: undefined, - liveness: true, - estimatedGas: { - approvalTxData: undefined, - txData: undefined, + fees: { + approvalTxFees: undefined, + tradeTxFees: undefined, }, + liveness: true, }, }); }); @@ -488,10 +536,9 @@ describe('SmartTransactionsController', () => { ], }, userOptIn: undefined, - fees: undefined, - estimatedGas: { - approvalTxData: undefined, - txData: undefined, + fees: { + approvalTxFees: undefined, + tradeTxFees: undefined, }, liveness: true, }, @@ -688,19 +735,4 @@ describe('SmartTransactionsController', () => { expect(actual).toBe(false); }); }); - - describe('estimateGas', () => { - it('gets estimated gas for a transaction', async () => { - const unsignedTransaction = createUnsignedTransaction(); - const estimateGasApiResponse = createEstimateGasApiResponse(); - nock(API_BASE_URL) - .post(`/networks/${ethereumChainIdDec}/estimateGas`) - .reply(200, estimateGasApiResponse); - const estimatedGas = await smartTransactionsController.estimateGas( - unsignedTransaction, - null, - ); - expect(estimatedGas).toStrictEqual(estimateGasApiResponse); - }); - }); }); diff --git a/src/SmartTransactionsController.ts b/src/SmartTransactionsController.ts index c45812d4..e69cd06e 100644 --- a/src/SmartTransactionsController.ts +++ b/src/SmartTransactionsController.ts @@ -18,7 +18,6 @@ import { SmartTransactionsStatus, SmartTransactionStatuses, Fees, - EstimatedGas, IndividualTxFees, } from './types'; import { @@ -55,10 +54,6 @@ export interface SmartTransactionsControllerState extends BaseState { approvalTxFees: IndividualTxFees | undefined; tradeTxFees: IndividualTxFees | undefined; }; - estimatedGas: { - txData: EstimatedGas | undefined; - approvalTxData: EstimatedGas | undefined; - }; }; } @@ -131,10 +126,6 @@ export default class SmartTransactionsController extends BaseController< tradeTxFees: undefined, }, liveness: true, - estimatedGas: { - txData: undefined, - approvalTxData: undefined, - }, }, }; @@ -478,13 +469,13 @@ export default class SmartTransactionsController extends BaseController< async getFees( unsignedTransaction: UnsignedTransaction, - approveTxParams: UnsignedTransaction, + approvalTx: UnsignedTransaction, ): Promise { const { chainId } = this.config; const transactions = []; - if (approveTxParams) { + if (approvalTx) { const unsignedApprovalTransactionWithNonce = await this.addNonceToTransaction( - approveTxParams, + approvalTx, ); transactions.push(unsignedApprovalTransactionWithNonce); } @@ -500,7 +491,7 @@ export default class SmartTransactionsController extends BaseController< }); let approvalTxFees; let tradeTxFees; - if (approveTxParams) { + if (approvalTx) { approvalTxFees = data?.txs[0]; tradeTxFees = data?.txs[1]; } else { @@ -522,53 +513,6 @@ export default class SmartTransactionsController extends BaseController< }; } - async estimateGas( - unsignedTransaction: UnsignedTransaction, - approveTxParams: UnsignedTransaction, - ): Promise { - const { chainId } = this.config; - - let approvalTxData; - if (approveTxParams) { - const unsignedApprovalTransactionWithNonce = await this.addNonceToTransaction( - approveTxParams, - ); - approvalTxData = await this.fetch( - getAPIRequestURL(APIType.ESTIMATE_GAS, chainId), - { - method: 'POST', - body: JSON.stringify({ - tx: unsignedApprovalTransactionWithNonce, - }), - }, - ); - } - const unsignedTransactionWithNonce = await this.addNonceToTransaction( - unsignedTransaction, - ); - const data = await this.fetch( - getAPIRequestURL(APIType.ESTIMATE_GAS, chainId), - { - method: 'POST', - body: JSON.stringify({ - tx: unsignedTransactionWithNonce, - ...(approveTxParams && { pending_txs: [approveTxParams] }), - }), - }, - ); - this.update({ - smartTransactionsState: { - ...this.state.smartTransactionsState, - estimatedGas: { - txData: data, - approvalTxData, - }, - }, - }); - - return data; - } - // * After this successful call client must add a nonce representative to // * transaction controller external transactions list async submitSignedTransactions({ diff --git a/src/types.ts b/src/types.ts index 6b87e49a..221ecc99 100644 --- a/src/types.ts +++ b/src/types.ts @@ -109,13 +109,7 @@ export interface Fees { tradeTxFees: IndividualTxFees | undefined; } -export interface EstimatedGas { - gasUsed: number; - gasLimit: number; - feeEstimate: number; -} - -// TODO: maybe grab the type from transactions controller? +// TODO export type UnsignedTransaction = any; // TODO From 6216b96ea8173d67b5a8f88ae4eff6e76ebfbbc9 Mon Sep 17 00:00:00 2001 From: dan437 <80175477+dan437@users.noreply.github.com> Date: Mon, 16 May 2022 13:57:17 +0200 Subject: [PATCH 4/5] Renaming --- src/SmartTransactionsController.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/SmartTransactionsController.ts b/src/SmartTransactionsController.ts index e69cd06e..46005138 100644 --- a/src/SmartTransactionsController.ts +++ b/src/SmartTransactionsController.ts @@ -468,7 +468,7 @@ export default class SmartTransactionsController extends BaseController< } async getFees( - unsignedTransaction: UnsignedTransaction, + tradeTx: UnsignedTransaction, approvalTx: UnsignedTransaction, ): Promise { const { chainId } = this.config; @@ -479,10 +479,10 @@ export default class SmartTransactionsController extends BaseController< ); transactions.push(unsignedApprovalTransactionWithNonce); } - const unsignedTransactionWithNonce = await this.addNonceToTransaction( - unsignedTransaction, + const unsignedTradeTransactionWithNonce = await this.addNonceToTransaction( + tradeTx, ); - transactions.push(unsignedTransactionWithNonce); + transactions.push(unsignedTradeTransactionWithNonce); const data = await this.fetch(getAPIRequestURL(APIType.GET_FEES, chainId), { method: 'POST', body: JSON.stringify({ From 35a1c621a19e228a27662006cd6f6d22cf2b66c7 Mon Sep 17 00:00:00 2001 From: dan437 <80175477+dan437@users.noreply.github.com> Date: Tue, 17 May 2022 18:12:42 +0200 Subject: [PATCH 5/5] If there is an approval tx, the trade tx's nonce is increased by 1 --- src/SmartTransactionsController.ts | 14 +++++++++++--- src/utils.test.ts | 7 +++++++ src/utils.ts | 7 +++++++ 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/SmartTransactionsController.ts b/src/SmartTransactionsController.ts index 46005138..77bd4600 100644 --- a/src/SmartTransactionsController.ts +++ b/src/SmartTransactionsController.ts @@ -30,6 +30,7 @@ import { getStxProcessingTime, handleFetch, isSmartTransactionCancellable, + incrementNonceInHex, } from './utils'; import { CHAIN_IDS } from './constants'; @@ -473,15 +474,22 @@ export default class SmartTransactionsController extends BaseController< ): Promise { const { chainId } = this.config; const transactions = []; + let unsignedTradeTransactionWithNonce; if (approvalTx) { const unsignedApprovalTransactionWithNonce = await this.addNonceToTransaction( approvalTx, ); transactions.push(unsignedApprovalTransactionWithNonce); + unsignedTradeTransactionWithNonce = { + ...tradeTx, + // If there is an approval tx, the trade tx's nonce is increased by 1. + nonce: incrementNonceInHex(unsignedApprovalTransactionWithNonce.nonce), + }; + } else { + unsignedTradeTransactionWithNonce = await this.addNonceToTransaction( + tradeTx, + ); } - const unsignedTradeTransactionWithNonce = await this.addNonceToTransaction( - tradeTx, - ); transactions.push(unsignedTradeTransactionWithNonce); const data = await this.fetch(getAPIRequestURL(APIType.GET_FEES, chainId), { method: 'POST', diff --git a/src/utils.test.ts b/src/utils.test.ts index b2281948..e1246d30 100644 --- a/src/utils.test.ts +++ b/src/utils.test.ts @@ -223,4 +223,11 @@ describe('src/utils.js', () => { expect(utils.isSmartTransactionCancellable(stxStatus)).toBe(false); }); }); + + describe('incrementNonceInHex', () => { + it('returns "0x57" if we pass "0x56"', () => { + const incrementedNonce = utils.incrementNonceInHex('0x56'); + expect(incrementedNonce).toStrictEqual('0x57'); + }); + }); }); diff --git a/src/utils.ts b/src/utils.ts index 877f4ff5..4e504e80 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,5 +1,7 @@ import jsonDiffer from 'fast-json-patch'; import { cloneDeep } from 'lodash'; +import { BigNumber } from 'bignumber.js'; +import { ethers } from 'ethers'; import { APIType, SmartTransaction, @@ -184,3 +186,8 @@ export const isSmartTransactionCancellable = ( SmartTransactionCancellationReason.NOT_CANCELLED) ); }; + +export const incrementNonceInHex = (nonceInHex: string): string => { + const nonceInDec = new BigNumber(nonceInHex, 16).toString(10); + return ethers.utils.hexlify(Number(nonceInDec) + 1); +};