mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-22 09:23:21 +01:00
Use transactions array in frontend (#20523)
Send the entire transactions array to the frontend rather than currentNetworkTxList and unapprovedTxs.
This commit is contained in:
parent
6ee90ac8b2
commit
07adba5926
@ -27,7 +27,7 @@ const state = {
|
||||
image: {
|
||||
src: 'images/global-menu-block-explorer.svg',
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
tokenList: {
|
||||
'0x514910771af9ca656af840dff83e8264ecf986ca': {
|
||||
@ -314,8 +314,8 @@ const state = {
|
||||
address: '0x9d0ba4ddac06032527b140912ec808ab9451b788',
|
||||
},
|
||||
},
|
||||
unapprovedTxs: {
|
||||
3111025347726181: {
|
||||
transactions: [
|
||||
{
|
||||
id: 3111025347726181,
|
||||
time: 1620710815484,
|
||||
status: 'unapproved',
|
||||
@ -365,7 +365,7 @@ const state = {
|
||||
],
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
addressBook: {
|
||||
undefined: {
|
||||
0: {
|
||||
@ -574,7 +574,7 @@ const state = {
|
||||
},
|
||||
},
|
||||
currentBlockGasLimit: '0x793af4',
|
||||
currentNetworkTxList: [
|
||||
transactions: [
|
||||
{
|
||||
chainId: '0x38',
|
||||
dappSuggestedGasFees: null,
|
||||
|
@ -218,7 +218,6 @@ browser.runtime.onConnectExternal.addListener(async (...args) => {
|
||||
* @property {boolean} isAccountMenuOpen - Represents whether the main account selection UI is currently displayed.
|
||||
* @property {boolean} isNetworkMenuOpen - Represents whether the main network selection UI is currently displayed.
|
||||
* @property {object} identities - An object matching lower-case hex addresses to Identity objects with "address" and "name" (nickname) keys.
|
||||
* @property {object} unapprovedTxs - An object mapping transaction hashes to unapproved transactions.
|
||||
* @property {object} networkConfigurations - A list of network configurations, containing RPC provider details (eg chainId, rpcUrl, rpcPreferences).
|
||||
* @property {Array} addressBook - A list of previously sent to addresses.
|
||||
* @property {object} contractExchangeRates - Info about current token prices.
|
||||
@ -235,7 +234,6 @@ browser.runtime.onConnectExternal.addListener(async (...args) => {
|
||||
* @property {string} networkStatus - Either "unknown", "available", "unavailable", or "blocked", depending on the status of the currently selected network.
|
||||
* @property {object} accounts - An object mapping lower-case hex addresses to objects with "balance" and "address" keys, both storing hex string values.
|
||||
* @property {hex} currentBlockGasLimit - The most recently seen block gas limit, in a lower case hex prefixed string.
|
||||
* @property {TransactionMeta[]} currentNetworkTxList - An array of transactions associated with the currently selected network.
|
||||
* @property {object} unapprovedMsgs - An object of messages pending approval, mapping a unique ID to the options.
|
||||
* @property {number} unapprovedMsgCount - The number of messages in unapprovedMsgs.
|
||||
* @property {object} unapprovedPersonalMsgs - An object of messages pending approval, mapping a unique ID to the options.
|
||||
|
@ -229,7 +229,7 @@ export default class TransactionController extends EventEmitter {
|
||||
isEnabled: () =>
|
||||
Boolean(
|
||||
this.preferencesStore.getState().incomingTransactionsPreferences?.[
|
||||
this._getChainId()
|
||||
this._getCurrentChainId()
|
||||
] && this._hasCompletedOnboarding(),
|
||||
),
|
||||
lastFetchedBlockNumbers: opts.initState?.lastFetchedBlockNumbers || {},
|
||||
@ -2135,16 +2135,12 @@ export default class TransactionController extends EventEmitter {
|
||||
* Updates the memStore in transaction controller
|
||||
*/
|
||||
_updateMemstore() {
|
||||
const { transactions } = this.store.getState();
|
||||
const unapprovedTxs = this.txStateManager.getUnapprovedTxList();
|
||||
|
||||
const currentNetworkTxList = this.txStateManager.getTransactions({
|
||||
const transactions = this.getTransactions({
|
||||
filterToCurrentNetwork: false,
|
||||
limit: MAX_MEMSTORE_TX_LIST_SIZE,
|
||||
});
|
||||
|
||||
this.memStore.updateState({
|
||||
unapprovedTxs,
|
||||
currentNetworkTxList,
|
||||
transactions,
|
||||
});
|
||||
}
|
||||
|
@ -56,10 +56,10 @@ const TRANSACTION_META_MOCK = {
|
||||
hash: '0x1',
|
||||
id: 1,
|
||||
status: TransactionStatus.confirmed,
|
||||
transaction: {
|
||||
time: 123456789,
|
||||
txParams: {
|
||||
from: VALID_ADDRESS,
|
||||
},
|
||||
time: 123456789,
|
||||
};
|
||||
|
||||
async function flushPromises() {
|
||||
@ -186,21 +186,10 @@ describe('Transaction Controller', function () {
|
||||
it('should return a state object with the right keys and data types', function () {
|
||||
const exposedState = txController.getState();
|
||||
assert.ok(
|
||||
'unapprovedTxs' in exposedState,
|
||||
'state should have the key unapprovedTxs',
|
||||
);
|
||||
assert.ok(
|
||||
'currentNetworkTxList' in exposedState,
|
||||
'state should have the key currentNetworkTxList',
|
||||
);
|
||||
assert.ok(
|
||||
typeof exposedState?.unapprovedTxs === 'object',
|
||||
'should be an object',
|
||||
);
|
||||
assert.ok(
|
||||
Array.isArray(exposedState.currentNetworkTxList),
|
||||
'should be an array',
|
||||
'transactions' in exposedState,
|
||||
'state should have the key transactions',
|
||||
);
|
||||
assert.ok(Array.isArray(exposedState.transactions), 'should be an array');
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -283,14 +283,11 @@ export const SENTRY_BACKGROUND_STATE = {
|
||||
tokens: false,
|
||||
},
|
||||
TransactionController: {
|
||||
currentNetworkTxList: false,
|
||||
transactions: false,
|
||||
lastFetchedBlockNumbers: false,
|
||||
},
|
||||
TxController: {
|
||||
currentNetworkTxList: false,
|
||||
transactions: false,
|
||||
unapprovedTxs: false,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -180,57 +180,6 @@
|
||||
}
|
||||
},
|
||||
"cachedBalances": {},
|
||||
"incomingTransactions": {},
|
||||
"unapprovedTxs": {
|
||||
"8393540981007587": {
|
||||
"id": 8393540981007587,
|
||||
"time": 1536268017676,
|
||||
"status": "unapproved",
|
||||
"metamaskNetworkId": "4",
|
||||
"loadingDefaults": false,
|
||||
"txParams": {
|
||||
"from": "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc",
|
||||
"to": "0xc42edfcc21ed14dda456aa0756c153f7985d8813",
|
||||
"value": "0x0",
|
||||
"gas": "0x5208",
|
||||
"gasPrice": "0x3b9aca00"
|
||||
},
|
||||
"history": [
|
||||
{
|
||||
"id": 8393540981007587,
|
||||
"time": 1536268017676,
|
||||
"status": "unapproved",
|
||||
"metamaskNetworkId": "4",
|
||||
"loadingDefaults": true,
|
||||
"txParams": {
|
||||
"from": "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc",
|
||||
"to": "0xc42edfcc21ed14dda456aa0756c153f7985d8813",
|
||||
"value": "0x0",
|
||||
"gas": "0x5208",
|
||||
"gasPrice": "0x3b9aca00"
|
||||
}
|
||||
},
|
||||
[
|
||||
{
|
||||
"op": "replace",
|
||||
"path": "/loadingDefaults",
|
||||
"value": false,
|
||||
"timestamp": 1536268017685
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"op": "add",
|
||||
"path": "/origin",
|
||||
"value": "MetaMask",
|
||||
"note": "#newUnapprovedTransaction - adding the origin",
|
||||
"timestamp": 1536268017686
|
||||
}
|
||||
]
|
||||
],
|
||||
"origin": "MetaMask"
|
||||
}
|
||||
},
|
||||
"selectedAddress": "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc",
|
||||
"accounts": {
|
||||
"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc": {
|
||||
@ -347,7 +296,55 @@
|
||||
"occurrences": 12
|
||||
}
|
||||
},
|
||||
"currentNetworkTxList": [
|
||||
"transactions": [
|
||||
{
|
||||
"id": 8393540981007587,
|
||||
"time": 1536268017676,
|
||||
"status": "unapproved",
|
||||
"metamaskNetworkId": "4",
|
||||
"loadingDefaults": false,
|
||||
"txParams": {
|
||||
"from": "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc",
|
||||
"to": "0xc42edfcc21ed14dda456aa0756c153f7985d8813",
|
||||
"value": "0x0",
|
||||
"gas": "0x5208",
|
||||
"gasPrice": "0x3b9aca00"
|
||||
},
|
||||
"history": [
|
||||
{
|
||||
"id": 8393540981007587,
|
||||
"time": 1536268017676,
|
||||
"status": "unapproved",
|
||||
"metamaskNetworkId": "4",
|
||||
"loadingDefaults": true,
|
||||
"txParams": {
|
||||
"from": "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc",
|
||||
"to": "0xc42edfcc21ed14dda456aa0756c153f7985d8813",
|
||||
"value": "0x0",
|
||||
"gas": "0x5208",
|
||||
"gasPrice": "0x3b9aca00"
|
||||
}
|
||||
},
|
||||
[
|
||||
{
|
||||
"op": "replace",
|
||||
"path": "/loadingDefaults",
|
||||
"value": false,
|
||||
"timestamp": 1536268017685
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"op": "add",
|
||||
"path": "/origin",
|
||||
"value": "MetaMask",
|
||||
"note": "#newUnapprovedTransaction - adding the origin",
|
||||
"timestamp": 1536268017686
|
||||
}
|
||||
]
|
||||
],
|
||||
"origin": "MetaMask"
|
||||
},
|
||||
{
|
||||
"id": 3387511061307736,
|
||||
"time": 1528133130531,
|
||||
|
@ -227,59 +227,6 @@
|
||||
"0xaa36a7": true,
|
||||
"0xe704": true
|
||||
},
|
||||
|
||||
"unapprovedTxs": {
|
||||
"8393540981007587": {
|
||||
"chainId": "0x5",
|
||||
"id": 8393540981007587,
|
||||
"time": 1536268017676,
|
||||
"status": "unapproved",
|
||||
"metamaskNetworkId": "4",
|
||||
"loadingDefaults": false,
|
||||
"txParams": {
|
||||
"data": "0xa9059cbb000000000000000000000000b19ac54efa18cc3a14a5b821bfec73d284bf0c5e0000000000000000000000000000000000000000000000003782dace9d900000",
|
||||
"from": "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc",
|
||||
"to": "0xc42edfcc21ed14dda456aa0756c153f7985d8813",
|
||||
"value": "0x0",
|
||||
"gas": "0x5208",
|
||||
"gasPrice": "0x3b9aca00"
|
||||
},
|
||||
"history": [
|
||||
{
|
||||
"id": 8393540981007587,
|
||||
"time": 1536268017676,
|
||||
"status": "unapproved",
|
||||
"metamaskNetworkId": "4",
|
||||
"loadingDefaults": true,
|
||||
"txParams": {
|
||||
"from": "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc",
|
||||
"to": "0xc42edfcc21ed14dda456aa0756c153f7985d8813",
|
||||
"value": "0x0",
|
||||
"gas": "0x5208",
|
||||
"gasPrice": "0x3b9aca00"
|
||||
}
|
||||
},
|
||||
[
|
||||
{
|
||||
"op": "replace",
|
||||
"path": "/loadingDefaults",
|
||||
"value": false,
|
||||
"timestamp": 1536268017685
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"op": "add",
|
||||
"path": "/origin",
|
||||
"value": "MetaMask",
|
||||
"note": "#newUnapprovedTransaction - adding the origin",
|
||||
"timestamp": 1536268017686
|
||||
}
|
||||
]
|
||||
],
|
||||
"origin": "metamask"
|
||||
}
|
||||
},
|
||||
"selectedAddress": "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc",
|
||||
"accounts": {
|
||||
"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc": {
|
||||
@ -643,7 +590,57 @@
|
||||
"occurrences": 12
|
||||
}
|
||||
},
|
||||
"currentNetworkTxList": [
|
||||
"transactions": [
|
||||
{
|
||||
"chainId": "0x5",
|
||||
"id": 8393540981007587,
|
||||
"time": 1536268017676,
|
||||
"status": "unapproved",
|
||||
"metamaskNetworkId": "4",
|
||||
"loadingDefaults": false,
|
||||
"txParams": {
|
||||
"data": "0xa9059cbb000000000000000000000000b19ac54efa18cc3a14a5b821bfec73d284bf0c5e0000000000000000000000000000000000000000000000003782dace9d900000",
|
||||
"from": "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc",
|
||||
"to": "0xc42edfcc21ed14dda456aa0756c153f7985d8813",
|
||||
"value": "0x0",
|
||||
"gas": "0x5208",
|
||||
"gasPrice": "0x3b9aca00"
|
||||
},
|
||||
"history": [
|
||||
{
|
||||
"id": 8393540981007587,
|
||||
"time": 1536268017676,
|
||||
"status": "unapproved",
|
||||
"metamaskNetworkId": "4",
|
||||
"loadingDefaults": true,
|
||||
"txParams": {
|
||||
"from": "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc",
|
||||
"to": "0xc42edfcc21ed14dda456aa0756c153f7985d8813",
|
||||
"value": "0x0",
|
||||
"gas": "0x5208",
|
||||
"gasPrice": "0x3b9aca00"
|
||||
}
|
||||
},
|
||||
[
|
||||
{
|
||||
"op": "replace",
|
||||
"path": "/loadingDefaults",
|
||||
"value": false,
|
||||
"timestamp": 1536268017685
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"op": "add",
|
||||
"path": "/origin",
|
||||
"value": "MetaMask",
|
||||
"note": "#newUnapprovedTransaction - adding the origin",
|
||||
"timestamp": 1536268017686
|
||||
}
|
||||
]
|
||||
],
|
||||
"origin": "metamask"
|
||||
},
|
||||
{
|
||||
"id": 3387511061307736,
|
||||
"time": 1528133130531,
|
||||
|
@ -218,8 +218,6 @@
|
||||
"allDetectedTokens": {}
|
||||
},
|
||||
"TxController": {
|
||||
"unapprovedTxs": "object",
|
||||
"currentNetworkTxList": "object",
|
||||
"transactions": "object"
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,6 @@
|
||||
"isAccountMenuOpen": false,
|
||||
"isNetworkMenuOpen": false,
|
||||
"identities": "object",
|
||||
"unapprovedTxs": "object",
|
||||
"networkConfigurations": "object",
|
||||
"addressBook": "object",
|
||||
"contractExchangeRates": "object",
|
||||
@ -153,7 +152,6 @@
|
||||
"lastUpdated": "object",
|
||||
"notifications": "object",
|
||||
"accounts": "object",
|
||||
"currentNetworkTxList": "object",
|
||||
"transactions": "object",
|
||||
"unapprovedDecryptMsgs": "object",
|
||||
"unapprovedDecryptMsgCount": 0,
|
||||
|
@ -154,7 +154,7 @@ export const createSwapsMockStore = () => {
|
||||
showFiatInTestnets: true,
|
||||
},
|
||||
currentCurrency: 'ETH',
|
||||
currentNetworkTxList: [
|
||||
transactions: [
|
||||
{
|
||||
id: 6571648590592143,
|
||||
time: 1667403993369,
|
||||
@ -162,7 +162,7 @@ export const createSwapsMockStore = () => {
|
||||
metamaskNetworkId: '5',
|
||||
originalGasEstimate: '0x7548',
|
||||
userEditedGasLimit: false,
|
||||
chainId: '0x5',
|
||||
chainId: CHAIN_IDS.MAINNET,
|
||||
loadingDefaults: false,
|
||||
dappSuggestedGasFees: null,
|
||||
sendFlowHistory: null,
|
||||
|
@ -18,19 +18,6 @@ const mmState = {
|
||||
balance: '0x1F4',
|
||||
},
|
||||
},
|
||||
unapprovedTxs: {
|
||||
8393540981007587: {
|
||||
...mockState.metamask.unapprovedTxs[8393540981007587],
|
||||
txParams: {
|
||||
from: '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc',
|
||||
to: '0xc42edfcc21ed14dda456aa0756c153f7985d8813',
|
||||
value: '0x0',
|
||||
gas: '0x5208',
|
||||
gasPrice: '0x3b9aca00',
|
||||
type: '0x0',
|
||||
},
|
||||
},
|
||||
},
|
||||
preferences: {
|
||||
useNativeCurrencyAsPrimaryCurrency: true,
|
||||
},
|
||||
@ -52,6 +39,15 @@ const mmState = {
|
||||
},
|
||||
};
|
||||
|
||||
mmState.metamask.transactions[0].txParams = {
|
||||
from: '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc',
|
||||
to: '0xc42edfcc21ed14dda456aa0756c153f7985d8813',
|
||||
value: '0x0',
|
||||
gas: '0x5208',
|
||||
gasPrice: '0x3b9aca00',
|
||||
type: '0x0',
|
||||
};
|
||||
|
||||
const render = ({ contextProps, state = mmState } = {}) => {
|
||||
const store = configureStore({ ...state, ...contextProps });
|
||||
|
||||
|
@ -177,12 +177,13 @@ describe('SignatureRequestSIWE (Sign in with Ethereum)', () => {
|
||||
...mockStoreInitialState,
|
||||
metamask: {
|
||||
...mockStoreInitialState.metamask,
|
||||
unapprovedTxs: {
|
||||
...mockStoreInitialState.metamask.unapprovedTxs,
|
||||
'0x12333': {
|
||||
transactions: [
|
||||
...mockStoreInitialState.metamask.transactions,
|
||||
{
|
||||
chainId: mockStoreInitialState.metamask.providerConfig.chainId,
|
||||
status: 'unapproved',
|
||||
},
|
||||
},
|
||||
],
|
||||
unapprovedMsgCount: 2,
|
||||
},
|
||||
});
|
||||
|
@ -9,6 +9,7 @@ const render = () => {
|
||||
const store = configureStore({
|
||||
metamask: {
|
||||
...mockState.metamask,
|
||||
transactions: [],
|
||||
},
|
||||
});
|
||||
return renderWithProvider(<TransactionList />, store);
|
||||
|
@ -44,6 +44,7 @@ import {
|
||||
getSelectedIdentity,
|
||||
getShowProductTour,
|
||||
getTestNetworkBackgroundColor,
|
||||
getUnapprovedTransactions,
|
||||
getSelectedAddress,
|
||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||
getTheme,
|
||||
@ -136,9 +137,10 @@ export const AppHeader = ({ location }) => {
|
||||
matchPath(location.pathname, { path: BUILD_QUOTE_ROUTE, exact: false }),
|
||||
);
|
||||
|
||||
const hasUnapprovedTransactions = useSelector(
|
||||
(state) => Object.keys(state.metamask.unapprovedTxs).length > 0,
|
||||
);
|
||||
const unapprovedTransactions = useSelector(getUnapprovedTransactions);
|
||||
|
||||
const hasUnapprovedTransactions =
|
||||
Object.keys(unapprovedTransactions).length > 0;
|
||||
|
||||
const disableAccountPicker =
|
||||
isConfirmationPage || (isSwapsPage && !isSwapsBuildQuotePage);
|
||||
|
@ -44,6 +44,7 @@ import {
|
||||
getMetaMetricsId,
|
||||
///: END:ONLY_INCLUDE_IN(build-mmi)
|
||||
getSelectedAddress,
|
||||
getUnapprovedTransactions,
|
||||
///: BEGIN:ONLY_INCLUDE_IN(snaps)
|
||||
getUnreadNotificationsCount,
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
@ -69,10 +70,11 @@ export const GlobalMenu = ({ closeMenu, anchorElement }) => {
|
||||
const trackEvent = useContext(MetaMetricsContext);
|
||||
const history = useHistory();
|
||||
const address = useSelector(getSelectedAddress);
|
||||
const unapprovedTransactons = useSelector(getUnapprovedTransactions);
|
||||
|
||||
const hasUnapprovedTransactions =
|
||||
Object.keys(unapprovedTransactons).length > 0;
|
||||
|
||||
const hasUnapprovedTransactions = useSelector(
|
||||
(state) => Object.keys(state.metamask.unapprovedTxs).length > 0,
|
||||
);
|
||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||
const metaMetricsId = useSelector(getMetaMetricsId);
|
||||
const mmiPortfolioUrl = useSelector(getMmiPortfolioUrl);
|
||||
|
@ -51,7 +51,7 @@ describe('AccountListItem', () => {
|
||||
});
|
||||
|
||||
it('enables the settings item when there is no active transaction', async () => {
|
||||
const { getByTestId } = render({ unapprovedTxs: {} });
|
||||
const { getByTestId } = render({ transactions: [] });
|
||||
await waitFor(() => {
|
||||
expect(getByTestId('global-menu-settings')).toBeEnabled();
|
||||
});
|
||||
@ -65,7 +65,7 @@ describe('AccountListItem', () => {
|
||||
});
|
||||
|
||||
it('enables the connected sites item when there is no active transaction', async () => {
|
||||
const { getByTestId } = render({ unapprovedTxs: {} });
|
||||
const { getByTestId } = render({ transactions: [] });
|
||||
await waitFor(() => {
|
||||
expect(getByTestId('global-menu-connected-sites')).toBeEnabled();
|
||||
});
|
||||
|
@ -152,14 +152,14 @@ describe('App State', () => {
|
||||
|
||||
it('shows confirm tx page', () => {
|
||||
const txs = {
|
||||
unapprovedTxs: {
|
||||
1: {
|
||||
transactions: [
|
||||
{
|
||||
id: 1,
|
||||
},
|
||||
2: {
|
||||
{
|
||||
id: 2,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
const oldState = { ...metamaskState, ...txs };
|
||||
const state = reduceApp(oldState, {
|
||||
@ -174,14 +174,14 @@ describe('App State', () => {
|
||||
|
||||
it('completes tx continues to show pending txs current view context', () => {
|
||||
const txs = {
|
||||
unapprovedTxs: {
|
||||
1: {
|
||||
transactions: [
|
||||
{
|
||||
id: 1,
|
||||
},
|
||||
2: {
|
||||
{
|
||||
id: 2,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const oldState = { ...metamaskState, ...txs };
|
||||
|
@ -356,8 +356,8 @@ describe('Confirm Transaction Duck', () => {
|
||||
providerConfig: {
|
||||
chainId: '0x5',
|
||||
},
|
||||
unapprovedTxs: {
|
||||
2603411941761054: {
|
||||
transactions: [
|
||||
{
|
||||
history: [],
|
||||
id: 2603411941761054,
|
||||
loadingDefaults: false,
|
||||
@ -373,7 +373,7 @@ describe('Confirm Transaction Duck', () => {
|
||||
value: '0xde0b6b3a7640000',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
confirmTransaction: {},
|
||||
};
|
||||
|
@ -27,7 +27,7 @@ const initialState = {
|
||||
isAccountMenuOpen: false,
|
||||
isNetworkMenuOpen: false,
|
||||
identities: {},
|
||||
unapprovedTxs: {},
|
||||
transactions: [],
|
||||
networkConfigurations: {},
|
||||
addressBook: [],
|
||||
contractExchangeRates: {},
|
||||
@ -111,8 +111,8 @@ export default function reduceMetamask(state = initialState, action) {
|
||||
|
||||
case actionConstants.UPDATE_TRANSACTION_PARAMS: {
|
||||
const { id: txId, value } = action;
|
||||
let { currentNetworkTxList } = metamaskState;
|
||||
currentNetworkTxList = currentNetworkTxList.map((tx) => {
|
||||
let { transactions } = metamaskState;
|
||||
transactions = transactions.map((tx) => {
|
||||
if (tx.id === txId) {
|
||||
const newTx = { ...tx };
|
||||
newTx.txParams = value;
|
||||
@ -123,7 +123,7 @@ export default function reduceMetamask(state = initialState, action) {
|
||||
|
||||
return {
|
||||
...metamaskState,
|
||||
currentNetworkTxList,
|
||||
transactions,
|
||||
};
|
||||
}
|
||||
|
||||
@ -300,10 +300,6 @@ export function getSendToAccounts(state) {
|
||||
return [...fromAccounts, ...addressBookAccounts];
|
||||
}
|
||||
|
||||
export function getUnapprovedTxs(state) {
|
||||
return state.metamask.unapprovedTxs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function returns true if network details are fetched and it is found to not support EIP-1559
|
||||
*
|
||||
|
@ -9,7 +9,6 @@ import reduceMetamask, {
|
||||
getNativeCurrency,
|
||||
getSendHexDataFeatureFlagState,
|
||||
getSendToAccounts,
|
||||
getUnapprovedTxs,
|
||||
isNotEIP1559Network,
|
||||
} from './metamask';
|
||||
|
||||
@ -91,8 +90,8 @@ describe('MetaMask Reducers', () => {
|
||||
},
|
||||
},
|
||||
},
|
||||
unapprovedTxs: {
|
||||
4768706228115573: {
|
||||
transactions: [
|
||||
{
|
||||
id: 4768706228115573,
|
||||
time: 1487363153561,
|
||||
status: TransactionStatus.unapproved,
|
||||
@ -111,7 +110,7 @@ describe('MetaMask Reducers', () => {
|
||||
maxCost: 'de234b52e4a0800',
|
||||
gasPrice: '4a817c800',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{},
|
||||
),
|
||||
@ -175,7 +174,7 @@ describe('MetaMask Reducers', () => {
|
||||
|
||||
it('updates value of tx by id', () => {
|
||||
const oldState = {
|
||||
currentNetworkTxList: [
|
||||
transactions: [
|
||||
{
|
||||
id: 1,
|
||||
txParams: 'foo',
|
||||
@ -189,7 +188,7 @@ describe('MetaMask Reducers', () => {
|
||||
value: 'bar',
|
||||
});
|
||||
|
||||
expect(state.currentNetworkTxList[0].txParams).toStrictEqual('bar');
|
||||
expect(state.transactions[0].txParams).toStrictEqual('bar');
|
||||
});
|
||||
|
||||
it('close welcome screen', () => {
|
||||
@ -326,30 +325,6 @@ describe('MetaMask Reducers', () => {
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
it('should return the unapproved txs', () => {
|
||||
expect(getUnapprovedTxs(mockState)).toStrictEqual({
|
||||
4768706228115573: {
|
||||
id: 4768706228115573,
|
||||
time: 1487363153561,
|
||||
status: TransactionStatus.unapproved,
|
||||
gasMultiplier: 1,
|
||||
metamaskNetworkId: '5',
|
||||
txParams: {
|
||||
from: '0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb',
|
||||
to: '0x18a3462427bcc9133bb46e88bcbe39cd7ef0e761',
|
||||
value: '0xde0b6b3a7640000',
|
||||
metamaskId: 4768706228115573,
|
||||
metamaskNetworkId: '5',
|
||||
gas: '0x5209',
|
||||
},
|
||||
txFee: '17e0186e60800',
|
||||
txValue: 'de0b6b3a7640000',
|
||||
maxCost: 'de234b52e4a0800',
|
||||
gasPrice: '4a817c800',
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('isNotEIP1559Network()', () => {
|
||||
|
@ -39,6 +39,7 @@ import {
|
||||
getEnsResolutionByAddress,
|
||||
getSelectedAccount,
|
||||
getSelectedAddress,
|
||||
getUnapprovedTransactions,
|
||||
} from '../../selectors';
|
||||
import {
|
||||
disconnectGasFeeEstimatePoller,
|
||||
@ -80,7 +81,6 @@ import {
|
||||
getGasEstimateType,
|
||||
getProviderConfig,
|
||||
getTokens,
|
||||
getUnapprovedTxs,
|
||||
} from '../metamask/metamask';
|
||||
|
||||
import { resetDomainResolution } from '../domains';
|
||||
@ -499,7 +499,7 @@ export const computeEstimatedGasLimit = createAsyncThunk(
|
||||
const { send, metamask } = state;
|
||||
const draftTransaction =
|
||||
send.draftTransactions[send.currentTransactionUUID];
|
||||
const unapprovedTxs = getUnapprovedTxs(state);
|
||||
const unapprovedTxs = getUnapprovedTransactions(state);
|
||||
const isMultiLayerFeeNetwork = getIsMultiLayerFeeNetwork(state);
|
||||
const transaction = unapprovedTxs[draftTransaction.id];
|
||||
const isNonStandardEthChain = getIsNonStandardEthChain(state);
|
||||
@ -1731,7 +1731,7 @@ export function editExistingTransaction(assetType, transactionId) {
|
||||
return async (dispatch, getState) => {
|
||||
await dispatch(actions.clearPreviousDrafts());
|
||||
const state = getState();
|
||||
const unapprovedTransactions = getUnapprovedTxs(state);
|
||||
const unapprovedTransactions = getUnapprovedTransactions(state);
|
||||
const transaction = unapprovedTransactions[transactionId];
|
||||
const account = getTargetAccount(state, transaction.txParams.from);
|
||||
|
||||
@ -2033,7 +2033,7 @@ export function updateSendAsset(
|
||||
getSelectedAddress(state);
|
||||
const account = getTargetAccount(state, sendingAddress);
|
||||
if (type === AssetType.native) {
|
||||
const unapprovedTxs = getUnapprovedTxs(state);
|
||||
const unapprovedTxs = getUnapprovedTransactions(state);
|
||||
const unapprovedTx = unapprovedTxs?.[draftTransaction.id];
|
||||
|
||||
await dispatch(
|
||||
@ -2274,7 +2274,7 @@ export function signTransaction() {
|
||||
// We first must grab the previous transaction object from state and then
|
||||
// merge in the modified txParams. Once the transaction has been modified
|
||||
// we can send that to the background to update the transaction in state.
|
||||
const unapprovedTxs = getUnapprovedTxs(state);
|
||||
const unapprovedTxs = getUnapprovedTransactions(state);
|
||||
const unapprovedTx = cloneDeep(unapprovedTxs[draftTransaction.id]);
|
||||
// We only update the tx params that can be changed via the edit flow UX
|
||||
const eip1559OnlyTxParamsToUpdate = {
|
||||
|
@ -1479,7 +1479,10 @@ describe('Send Slice', () => {
|
||||
'send/computeEstimatedGasLimit/pending',
|
||||
);
|
||||
expect(actionResult[3].type).toStrictEqual(
|
||||
'send/computeEstimatedGasLimit/rejected',
|
||||
'metamask/gas/SET_CUSTOM_GAS_LIMIT',
|
||||
);
|
||||
expect(actionResult[4].type).toStrictEqual(
|
||||
'send/computeEstimatedGasLimit/fulfilled',
|
||||
);
|
||||
});
|
||||
|
||||
@ -1531,7 +1534,10 @@ describe('Send Slice', () => {
|
||||
'send/computeEstimatedGasLimit/pending',
|
||||
);
|
||||
expect(actionResult[3].type).toStrictEqual(
|
||||
'send/computeEstimatedGasLimit/rejected',
|
||||
'metamask/gas/SET_CUSTOM_GAS_LIMIT',
|
||||
);
|
||||
expect(actionResult[4].type).toStrictEqual(
|
||||
'send/computeEstimatedGasLimit/fulfilled',
|
||||
);
|
||||
});
|
||||
|
||||
@ -1568,14 +1574,17 @@ describe('Send Slice', () => {
|
||||
|
||||
const actionResult = store.getActions();
|
||||
|
||||
expect(actionResult).toHaveLength(4);
|
||||
expect(actionResult).toHaveLength(5);
|
||||
expect(actionResult[0].type).toStrictEqual('send/addHistoryEntry');
|
||||
expect(actionResult[1].type).toStrictEqual('send/updateSendAmount');
|
||||
expect(actionResult[2].type).toStrictEqual(
|
||||
'send/computeEstimatedGasLimit/pending',
|
||||
);
|
||||
expect(actionResult[3].type).toStrictEqual(
|
||||
'send/computeEstimatedGasLimit/rejected',
|
||||
'metamask/gas/SET_CUSTOM_GAS_LIMIT',
|
||||
);
|
||||
expect(actionResult[4].type).toStrictEqual(
|
||||
'send/computeEstimatedGasLimit/fulfilled',
|
||||
);
|
||||
});
|
||||
});
|
||||
@ -1636,7 +1645,7 @@ describe('Send Slice', () => {
|
||||
|
||||
const actionResult = store.getActions();
|
||||
|
||||
expect(actionResult).toHaveLength(4);
|
||||
expect(actionResult).toHaveLength(5);
|
||||
|
||||
expect(actionResult[0]).toMatchObject({
|
||||
type: 'send/addHistoryEntry',
|
||||
@ -1657,7 +1666,10 @@ describe('Send Slice', () => {
|
||||
'send/computeEstimatedGasLimit/pending',
|
||||
);
|
||||
expect(actionResult[3].type).toStrictEqual(
|
||||
'send/computeEstimatedGasLimit/rejected',
|
||||
'metamask/gas/SET_CUSTOM_GAS_LIMIT',
|
||||
);
|
||||
expect(actionResult[4].type).toStrictEqual(
|
||||
'send/computeEstimatedGasLimit/fulfilled',
|
||||
);
|
||||
});
|
||||
|
||||
@ -1692,7 +1704,7 @@ describe('Send Slice', () => {
|
||||
|
||||
const actionResult = store.getActions();
|
||||
|
||||
expect(actionResult).toHaveLength(6);
|
||||
expect(actionResult).toHaveLength(7);
|
||||
expect(actionResult[0].type).toStrictEqual('SHOW_LOADING_INDICATION');
|
||||
expect(actionResult[1].type).toStrictEqual('HIDE_LOADING_INDICATION');
|
||||
expect(actionResult[2]).toMatchObject({
|
||||
@ -1719,7 +1731,10 @@ describe('Send Slice', () => {
|
||||
'send/computeEstimatedGasLimit/pending',
|
||||
);
|
||||
expect(actionResult[5].type).toStrictEqual(
|
||||
'send/computeEstimatedGasLimit/rejected',
|
||||
'metamask/gas/SET_CUSTOM_GAS_LIMIT',
|
||||
);
|
||||
expect(actionResult[6].type).toStrictEqual(
|
||||
'send/computeEstimatedGasLimit/fulfilled',
|
||||
);
|
||||
});
|
||||
|
||||
@ -2092,7 +2107,7 @@ describe('Send Slice', () => {
|
||||
await store.dispatch(resetRecipientInput());
|
||||
const actionResult = store.getActions();
|
||||
|
||||
expect(actionResult).toHaveLength(11);
|
||||
expect(actionResult).toHaveLength(12);
|
||||
expect(actionResult[0]).toMatchObject({
|
||||
type: 'send/addHistoryEntry',
|
||||
payload: 'sendFlow - user cleared recipient input',
|
||||
@ -2118,10 +2133,15 @@ describe('Send Slice', () => {
|
||||
'send/computeEstimatedGasLimit/pending',
|
||||
);
|
||||
expect(actionResult[8].type).toStrictEqual(
|
||||
'send/computeEstimatedGasLimit/rejected',
|
||||
'metamask/gas/SET_CUSTOM_GAS_LIMIT',
|
||||
);
|
||||
expect(actionResult[9].type).toStrictEqual(
|
||||
'send/computeEstimatedGasLimit/fulfilled',
|
||||
);
|
||||
expect(actionResult[9].type).toStrictEqual('DNS/resetDomainResolution');
|
||||
expect(actionResult[10].type).toStrictEqual(
|
||||
'DNS/resetDomainResolution',
|
||||
);
|
||||
expect(actionResult[11].type).toStrictEqual(
|
||||
'send/validateRecipientUserInput',
|
||||
);
|
||||
});
|
||||
@ -2238,7 +2258,7 @@ describe('Send Slice', () => {
|
||||
|
||||
const actionResult = store.getActions();
|
||||
|
||||
expect(actionResult).toHaveLength(5);
|
||||
expect(actionResult).toHaveLength(6);
|
||||
expect(actionResult[0].type).toStrictEqual('send/updateAmountMode');
|
||||
expect(actionResult[1].type).toStrictEqual('send/updateSendAmount');
|
||||
expect(actionResult[2]).toMatchObject({
|
||||
@ -2249,7 +2269,10 @@ describe('Send Slice', () => {
|
||||
'send/computeEstimatedGasLimit/pending',
|
||||
);
|
||||
expect(actionResult[4].type).toStrictEqual(
|
||||
'send/computeEstimatedGasLimit/rejected',
|
||||
'metamask/gas/SET_CUSTOM_GAS_LIMIT',
|
||||
);
|
||||
expect(actionResult[5].type).toStrictEqual(
|
||||
'send/computeEstimatedGasLimit/fulfilled',
|
||||
);
|
||||
});
|
||||
});
|
||||
@ -2287,14 +2310,19 @@ describe('Send Slice', () => {
|
||||
it('should pass the correct transaction parameters to addTransactionAndRouteToConfirmationPage', async () => {
|
||||
const tokenTransferTxState = {
|
||||
metamask: {
|
||||
unapprovedTxs: {
|
||||
1: {
|
||||
providerConfig: {
|
||||
chainId: CHAIN_IDS.GOERLI,
|
||||
},
|
||||
transactions: [
|
||||
{
|
||||
id: 1,
|
||||
chainId: CHAIN_IDS.GOERLI,
|
||||
status: 'unapproved',
|
||||
txParams: {
|
||||
value: 'oldTxValue',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
send: {
|
||||
...getInitialSendStateWithExistingTxState({
|
||||
@ -2339,14 +2367,19 @@ describe('Send Slice', () => {
|
||||
it('should create actions for updateTransaction rejecting', async () => {
|
||||
const editStageSignTxState = {
|
||||
metamask: {
|
||||
unapprovedTxs: {
|
||||
1: {
|
||||
providerConfig: {
|
||||
chainId: '0x1',
|
||||
},
|
||||
transactions: [
|
||||
{
|
||||
id: 1,
|
||||
chainId: '0x1',
|
||||
status: 'unapproved',
|
||||
txParams: {
|
||||
value: 'oldTxValue',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
send: {
|
||||
...signTransactionState.send,
|
||||
@ -2405,19 +2438,21 @@ describe('Send Slice', () => {
|
||||
},
|
||||
},
|
||||
tokenList: {},
|
||||
unapprovedTxs: {
|
||||
1: {
|
||||
transactions: [
|
||||
{
|
||||
id: 1,
|
||||
chainId: CHAIN_IDS.GOERLI,
|
||||
status: 'unapproved',
|
||||
txParams: {
|
||||
data: '',
|
||||
from: mockAddress1,
|
||||
to: '0xRecipientAddress',
|
||||
gas: GAS_LIMITS.SIMPLE,
|
||||
gasPrice: '0x3b9aca00', // 1000000000
|
||||
value: '0xde0b6b3a7640000', // 1000000000000000000
|
||||
value: '0xde0b6b3a7640000', // 1000000000000000000,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
send: {
|
||||
// We are going to remove this transaction as a part of the flow,
|
||||
@ -2542,9 +2577,11 @@ describe('Send Slice', () => {
|
||||
},
|
||||
},
|
||||
tokenList: {},
|
||||
unapprovedTxs: {
|
||||
1: {
|
||||
transactions: [
|
||||
{
|
||||
id: 1,
|
||||
chainId: CHAIN_IDS.GOERLI,
|
||||
status: 'unapproved',
|
||||
txParams: {
|
||||
data: generateERC721TransferData({
|
||||
toAddress: BURN_ADDRESS,
|
||||
@ -2558,7 +2595,7 @@ describe('Send Slice', () => {
|
||||
value: '0x0',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
send: {
|
||||
...getInitialSendStateWithExistingTxState({
|
||||
@ -2626,7 +2663,7 @@ describe('Send Slice', () => {
|
||||
status: SEND_STATUSES.VALID,
|
||||
transactionType: '0x0',
|
||||
userInputHexData:
|
||||
editTransactionState.metamask.unapprovedTxs[1].txParams.data,
|
||||
editTransactionState.metamask.transactions[0].txParams.data,
|
||||
},
|
||||
});
|
||||
expect(actionResult[2].type).toStrictEqual('SHOW_LOADING_INDICATION');
|
||||
@ -2726,9 +2763,11 @@ describe('Send Slice', () => {
|
||||
[mockAddress1]: '0x0',
|
||||
},
|
||||
},
|
||||
unapprovedTxs: {
|
||||
1: {
|
||||
transactions: [
|
||||
{
|
||||
id: 1,
|
||||
chainId: CHAIN_IDS.GOERLI,
|
||||
status: 'unapproved',
|
||||
txParams: {
|
||||
data: generateERC20TransferData({
|
||||
toAddress: BURN_ADDRESS,
|
||||
@ -2746,7 +2785,7 @@ describe('Send Slice', () => {
|
||||
value: '0x0',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
send: {
|
||||
...getInitialSendStateWithExistingTxState({
|
||||
@ -2819,7 +2858,7 @@ describe('Send Slice', () => {
|
||||
status: SEND_STATUSES.VALID,
|
||||
transactionType: '0x0',
|
||||
userInputHexData:
|
||||
editTransactionState.metamask.unapprovedTxs[1].txParams.data,
|
||||
editTransactionState.metamask.transactions[0].txParams.data,
|
||||
},
|
||||
});
|
||||
expect(actionResult[2].type).toStrictEqual('SHOW_LOADING_INDICATION');
|
||||
|
@ -17,6 +17,7 @@ import configureStore from './store/store';
|
||||
import {
|
||||
getPermittedAccountsForCurrentTab,
|
||||
getSelectedAddress,
|
||||
getUnapprovedTransactions,
|
||||
} from './selectors';
|
||||
import { ALERT_STATE } from './ducks/alerts';
|
||||
import {
|
||||
@ -152,9 +153,11 @@ async function startApp(metamaskState, backgroundConnection, opts) {
|
||||
const store = configureStore(draftInitialState);
|
||||
reduxStore = store;
|
||||
|
||||
const unapprovedTxs = getUnapprovedTransactions(metamaskState);
|
||||
|
||||
// if unconfirmed txs, start on txConf page
|
||||
const unapprovedTxsAll = txHelper(
|
||||
metamaskState.unapprovedTxs,
|
||||
unapprovedTxs,
|
||||
metamaskState.unapprovedMsgs,
|
||||
metamaskState.unapprovedPersonalMsgs,
|
||||
metamaskState.unapprovedDecryptMsgs,
|
||||
|
@ -4,7 +4,7 @@ import { text } from '@storybook/addon-knobs';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { updateMetamaskState } from '../../store/actions';
|
||||
import { currentNetworkTxListSelector } from '../../selectors/transactions';
|
||||
import { getCurrentNetworkTransactions } from '../../selectors/transactions';
|
||||
import { store, getNewState } from '../../../.storybook/preview';
|
||||
|
||||
import { subjectMetadata } from '../../../.storybook/initial-states/approval-screens/token-approval';
|
||||
@ -15,7 +15,7 @@ export default {
|
||||
title: 'Pages/ConfirmApprove',
|
||||
};
|
||||
|
||||
// transaction ID, maps to entry in state.metamask.currentNetworkTxList
|
||||
// transaction ID, maps to entry in state.metamask.transactions
|
||||
const txId = 7900715443136469;
|
||||
|
||||
const PageSet = ({ children }) => {
|
||||
@ -25,7 +25,7 @@ const PageSet = ({ children }) => {
|
||||
'https://metamask.github.io/test-dapp/metamask-fox.svg',
|
||||
);
|
||||
const state = store.getState();
|
||||
const currentNetworkTxList = useSelector(currentNetworkTxListSelector);
|
||||
const currentNetworkTxList = useSelector(getCurrentNetworkTransactions);
|
||||
const transaction = currentNetworkTxList.find(({ id }) => id === txId);
|
||||
|
||||
useEffect(() => {
|
||||
@ -33,7 +33,7 @@ const PageSet = ({ children }) => {
|
||||
store.dispatch(
|
||||
updateMetamaskState(
|
||||
getNewState(state.metamask, {
|
||||
currentNetworkTxList: [transaction],
|
||||
transactions: [transaction],
|
||||
}),
|
||||
),
|
||||
);
|
||||
|
@ -40,10 +40,12 @@ const sendEther = {
|
||||
},
|
||||
};
|
||||
|
||||
mockState.metamask.unapprovedTxs[sendEther.id] = sendEther;
|
||||
mockState.metamask.transactions.push(sendEther);
|
||||
|
||||
mockState.confirmTransaction = {
|
||||
txData: sendEther,
|
||||
};
|
||||
|
||||
const store = configureStore(mockState);
|
||||
|
||||
export default {
|
||||
|
@ -50,10 +50,12 @@ const sendEther = {
|
||||
},
|
||||
};
|
||||
|
||||
mockState.metamask.unapprovedTxs[sendEther.id] = sendEther;
|
||||
mockState.metamask.transactions.push(sendEther);
|
||||
|
||||
mockState.confirmTransaction = {
|
||||
txData: sendEther,
|
||||
};
|
||||
|
||||
const store = configureStore(mockState);
|
||||
|
||||
describe('ConfirmSendEther', () => {
|
||||
|
@ -18,6 +18,8 @@ import {
|
||||
getSelectedAccount,
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
getTargetSubjectMetadata,
|
||||
getCurrentNetworkTransactions,
|
||||
getUnapprovedTransactions,
|
||||
} from '../../selectors';
|
||||
import { MESSAGE_TYPE } from '../../../shared/constants/app';
|
||||
import { TransactionStatus } from '../../../shared/constants/transaction';
|
||||
@ -53,9 +55,7 @@ const ConfirmTxScreen = ({ match }) => {
|
||||
);
|
||||
const sendTo = useSelector(getSendTo);
|
||||
const {
|
||||
unapprovedTxs,
|
||||
identities,
|
||||
currentNetworkTxList,
|
||||
currentCurrency,
|
||||
unapprovedMsgs,
|
||||
unapprovedPersonalMsgs,
|
||||
@ -63,6 +63,8 @@ const ConfirmTxScreen = ({ match }) => {
|
||||
networkId,
|
||||
blockGasLimit,
|
||||
} = useSelector((state) => state.metamask);
|
||||
const unapprovedTxs = useSelector(getUnapprovedTransactions);
|
||||
const currentNetworkTxList = useSelector(getCurrentNetworkTransactions);
|
||||
const { chainId } = useSelector(getProviderConfig);
|
||||
const { txId: index } = useSelector((state) => state.appState);
|
||||
|
||||
|
@ -41,6 +41,7 @@ import {
|
||||
getUnapprovedTransaction,
|
||||
getFullTxData,
|
||||
getUseCurrencyRateCheck,
|
||||
getUnapprovedTransactions,
|
||||
} from '../../selectors';
|
||||
import { getMostRecentOverviewPage } from '../../ducks/history/history';
|
||||
import {
|
||||
@ -121,14 +122,9 @@ const mapStateToProps = (state, ownProps) => {
|
||||
const gasLoadingAnimationIsShowing = getGasLoadingAnimationIsShowing(state);
|
||||
const isBuyableChain = getIsBuyableChain(state);
|
||||
const { confirmTransaction, metamask } = state;
|
||||
const {
|
||||
conversionRate,
|
||||
identities,
|
||||
addressBook,
|
||||
networkId,
|
||||
unapprovedTxs,
|
||||
nextNonce,
|
||||
} = metamask;
|
||||
const { conversionRate, identities, addressBook, networkId, nextNonce } =
|
||||
metamask;
|
||||
const unapprovedTxs = getUnapprovedTransactions(state);
|
||||
const { chainId } = getProviderConfig(state);
|
||||
const { tokenData, txData, tokenProps, nonce } = confirmTransaction;
|
||||
const { txParams = {}, id: transactionId, type } = txData;
|
||||
|
@ -66,13 +66,14 @@ const baseStore = {
|
||||
},
|
||||
history: { mostRecentOverviewPage: '/' },
|
||||
metamask: {
|
||||
unapprovedTxs: {
|
||||
1: {
|
||||
transactions: [
|
||||
{
|
||||
id: 1,
|
||||
metamaskNetworkId: mockNetworkId,
|
||||
txParams: { ...mockTxParams },
|
||||
status: 'unapproved',
|
||||
},
|
||||
},
|
||||
],
|
||||
gasEstimateType: GasEstimateTypes.legacy,
|
||||
gasFeeEstimates: {
|
||||
low: '0',
|
||||
@ -175,7 +176,7 @@ const baseStore = {
|
||||
const mockedStore = jest.mocked(baseStore);
|
||||
|
||||
const mockedStoreWithConfirmTxParams = (_mockTxParams = mockTxParams) => {
|
||||
mockedStore.metamask.unapprovedTxs[1].txParams = { ..._mockTxParams };
|
||||
mockedStore.metamask.transactions[0].txParams = { ..._mockTxParams };
|
||||
mockedStore.confirmTransaction.txData.txParams = { ..._mockTxParams };
|
||||
};
|
||||
|
||||
|
@ -1,11 +1,12 @@
|
||||
import { connect } from 'react-redux';
|
||||
import { unconfirmedTransactionsListSelector } from '../../selectors';
|
||||
import {
|
||||
getUnapprovedTransactions,
|
||||
unconfirmedTransactionsListSelector,
|
||||
} from '../../selectors';
|
||||
import ConfirmTransactionSwitch from './confirm-transaction-switch.component';
|
||||
|
||||
const mapStateToProps = (state, ownProps) => {
|
||||
const {
|
||||
metamask: { unapprovedTxs },
|
||||
} = state;
|
||||
const unapprovedTxs = getUnapprovedTransactions(state);
|
||||
const {
|
||||
match: { params = {}, url },
|
||||
} = ownProps;
|
||||
|
@ -22,7 +22,7 @@ import {
|
||||
|
||||
import ConfirmTransaction from '.';
|
||||
|
||||
const mockUnapprovedTx = Object.values(_mockState.metamask.unapprovedTxs)[0];
|
||||
const mockUnapprovedTx = _mockState.metamask.transactions[0];
|
||||
|
||||
const middleware = [thunk];
|
||||
|
||||
@ -137,7 +137,7 @@ describe('Confirmation Transaction Page', () => {
|
||||
...mockState,
|
||||
metamask: {
|
||||
...mockState.metamask,
|
||||
unapprovedTxs: {},
|
||||
transactions: [],
|
||||
},
|
||||
});
|
||||
const { container } = renderWithProvider(<ConfirmTransaction />, mockStore);
|
||||
@ -177,12 +177,12 @@ describe('Confirmation Transaction Page', () => {
|
||||
...mockState,
|
||||
metamask: {
|
||||
...mockState.metamask,
|
||||
unapprovedTxs: {
|
||||
[mockUnapprovedTx.id]: {
|
||||
transactions: [
|
||||
{
|
||||
...mockUnapprovedTx,
|
||||
type: 'transfer',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
const { container } = renderWithProvider(
|
||||
@ -237,7 +237,7 @@ describe('Confirmation Transaction Page', () => {
|
||||
it('should not call setTransactionToConfirm when transaction id is not provided', () => {
|
||||
const mockStore = configureMockStore(middleware)({
|
||||
...mockState,
|
||||
metamask: { ...mockState.metamask, unapprovedTxs: {} },
|
||||
metamask: { ...mockState.metamask, transactions: [] },
|
||||
});
|
||||
jest.spyOn(ReactRouterDOM, 'useParams').mockImplementation(() => {
|
||||
return { id: null };
|
||||
@ -272,7 +272,7 @@ describe('Confirmation Transaction Page', () => {
|
||||
...mockState,
|
||||
metamask: {
|
||||
...mockState.metamask,
|
||||
unapprovedTxs: {},
|
||||
transactions: [],
|
||||
},
|
||||
});
|
||||
const replaceSpy = jest.fn();
|
||||
|
@ -25,13 +25,13 @@ setBackgroundConnection({
|
||||
|
||||
describe('Confirm Transaction', () => {
|
||||
const unapprovedTransactionId = Object.keys(
|
||||
mockState.metamask.unapprovedTxs,
|
||||
mockState.metamask.transactions,
|
||||
)[0];
|
||||
it('should render correct information for approve transaction with value', () => {
|
||||
const store = configureMockStore(middleware)({
|
||||
...mockState,
|
||||
confirmTransaction: {
|
||||
txData: mockState.metamask.unapprovedTxs[unapprovedTransactionId],
|
||||
txData: mockState.metamask.transactions[0],
|
||||
},
|
||||
});
|
||||
const { getByText, getByRole } = renderWithProvider(
|
||||
|
@ -51,6 +51,10 @@ describe('success template', () => {
|
||||
type: ApprovalType.ResultSuccess,
|
||||
},
|
||||
},
|
||||
providerConfig: {
|
||||
chainId: '0x1',
|
||||
},
|
||||
transactions: [],
|
||||
},
|
||||
};
|
||||
const store = configureMockStore(middleware)(testStore);
|
||||
|
@ -63,6 +63,7 @@ describe('switch-ethereum-chain confirmation', () => {
|
||||
type: MESSAGE_TYPE.SWITCH_ETHEREUM_CHAIN,
|
||||
},
|
||||
},
|
||||
transactions: [],
|
||||
},
|
||||
};
|
||||
const store = configureMockStore(middleware)(testStore);
|
||||
@ -83,11 +84,12 @@ describe('switch-ethereum-chain confirmation', () => {
|
||||
type: MESSAGE_TYPE.SWITCH_ETHEREUM_CHAIN,
|
||||
},
|
||||
},
|
||||
unapprovedTxs: {
|
||||
1: {
|
||||
transactions: [
|
||||
{
|
||||
id: 1,
|
||||
status: 'unapproved',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -27,6 +27,7 @@ import {
|
||||
transactionFeeSelector,
|
||||
getIsTestnet,
|
||||
getUseCurrencyRateCheck,
|
||||
getUnapprovedTransactions,
|
||||
} from '../../../selectors';
|
||||
|
||||
import { INSUFFICIENT_TOKENS_ERROR } from '../send.constants';
|
||||
@ -62,7 +63,7 @@ export default function GasDisplay({ gasError }) {
|
||||
const useCurrencyRateCheck = useSelector(getUseCurrencyRateCheck);
|
||||
const { showFiatInTestnets, useNativeCurrencyAsPrimaryCurrency } =
|
||||
useSelector(getPreferences);
|
||||
const { unapprovedTxs } = useSelector((state) => state.metamask);
|
||||
const unapprovedTxs = useSelector(getUnapprovedTransactions);
|
||||
const nativeCurrency = useSelector(getNativeCurrency);
|
||||
const { chainId } = providerConfig;
|
||||
const networkName = NETWORK_TO_NAME_MAP[chainId];
|
||||
|
@ -3,7 +3,7 @@ import {
|
||||
getAddressBook,
|
||||
getAddressBookEntry,
|
||||
getMetaMaskAccountsOrdered,
|
||||
currentNetworkTxListSelector,
|
||||
getCurrentNetworkTransactions,
|
||||
} from '../../../../selectors';
|
||||
|
||||
import {
|
||||
@ -35,7 +35,7 @@ function mapStateToProps(state) {
|
||||
|
||||
const addressBook = getAddressBook(state);
|
||||
|
||||
const txList = [...currentNetworkTxListSelector(state)].reverse();
|
||||
const txList = [...getCurrentNetworkTransactions(state)].reverse();
|
||||
|
||||
const nonContacts = addressBook
|
||||
.filter(({ name }) => !name)
|
||||
|
@ -16,7 +16,7 @@ jest.mock('../../../../selectors', () => ({
|
||||
{ name: `account1:mockState` },
|
||||
{ name: `account2:mockState` },
|
||||
],
|
||||
currentNetworkTxListSelector: (s) => `currentNetworkTxListSelector:${s}`,
|
||||
getCurrentNetworkTransactions: (s) => `getCurrentNetworkTransactions:${s}`,
|
||||
}));
|
||||
|
||||
jest.mock('../../../../ducks/domains', () => ({
|
||||
|
@ -65,14 +65,14 @@ const baseStore = {
|
||||
},
|
||||
history: { mostRecentOverviewPage: 'activity' },
|
||||
metamask: {
|
||||
unapprovedTxs: {
|
||||
1: {
|
||||
transactions: [
|
||||
{
|
||||
id: 1,
|
||||
txParams: {
|
||||
value: 'oldTxValue',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
gasEstimateType: GasEstimateTypes.legacy,
|
||||
gasFeeEstimates: {
|
||||
low: '0',
|
||||
@ -108,7 +108,6 @@ const baseStore = {
|
||||
addressBook: {
|
||||
[CHAIN_IDS.GOERLI]: [],
|
||||
},
|
||||
currentNetworkTxList: [],
|
||||
cachedBalances: {
|
||||
[CHAIN_IDS.GOERLI]: {},
|
||||
},
|
||||
|
@ -54,7 +54,7 @@ import {
|
||||
} from '../../ducks/swaps/swaps';
|
||||
import {
|
||||
checkNetworkAndAccountSupports1559,
|
||||
currentNetworkTxListSelector,
|
||||
getCurrentNetworkTransactions,
|
||||
} from '../../selectors';
|
||||
import {
|
||||
AWAITING_SIGNATURES_ROUTE,
|
||||
@ -137,7 +137,7 @@ export default function Swap() {
|
||||
const selectedAccount = useSelector(getSelectedAccount, shallowEqual);
|
||||
const quotes = useSelector(getQuotes, isEqual);
|
||||
const latestAddedTokenTo = useSelector(getLatestAddedTokenTo, isEqual);
|
||||
const txList = useSelector(currentNetworkTxListSelector, shallowEqual);
|
||||
const txList = useSelector(getCurrentNetworkTransactions, shallowEqual);
|
||||
const tradeTxId = useSelector(getTradeTxId);
|
||||
const approveTxId = useSelector(getApproveTxId);
|
||||
const aggregatorMetadata = useSelector(getAggregatorMetadata, shallowEqual);
|
||||
|
@ -73,7 +73,7 @@ const state = {
|
||||
isERC721: false,
|
||||
},
|
||||
],
|
||||
unapprovedTxs: {},
|
||||
transactions: [],
|
||||
keyringTypes: [],
|
||||
keyrings: [
|
||||
{
|
||||
|
@ -30,9 +30,12 @@ import {
|
||||
} from '../../shared/modules/conversion.utils';
|
||||
import { getAveragePriceEstimateInHexWEI } from './custom-gas';
|
||||
import { getCurrentChainId, deprecatedGetCurrentNetworkId } from './selectors';
|
||||
import { checkNetworkAndAccountSupports1559 } from '.';
|
||||
import {
|
||||
checkNetworkAndAccountSupports1559,
|
||||
getUnapprovedTransactions,
|
||||
} from '.';
|
||||
|
||||
const unapprovedTxsSelector = (state) => state.metamask.unapprovedTxs;
|
||||
const unapprovedTxsSelector = (state) => getUnapprovedTransactions(state);
|
||||
const unapprovedMsgsSelector = (state) => state.metamask.unapprovedMsgs;
|
||||
const unapprovedPersonalMsgsSelector = (state) =>
|
||||
state.metamask.unapprovedPersonalMsgs;
|
||||
|
@ -81,9 +81,7 @@ const getStateTree = ({
|
||||
unapprovedMsgs,
|
||||
selectedAddress: SENDERS.ONE,
|
||||
featureFlags: {},
|
||||
transactions: [...incomingTxList],
|
||||
incomingTransactions: [...incomingTxList],
|
||||
currentNetworkTxList: [...txList],
|
||||
transactions: [...incomingTxList, ...txList],
|
||||
incomingTransactionsPreferences: {},
|
||||
},
|
||||
});
|
||||
|
@ -2,17 +2,12 @@
|
||||
import { SubjectType } from '@metamask/subject-metadata-controller';
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
import { ApprovalType } from '@metamask/controller-utils';
|
||||
import {
|
||||
createSelector,
|
||||
createSelectorCreator,
|
||||
defaultMemoize,
|
||||
} from 'reselect';
|
||||
import {
|
||||
///: BEGIN:ONLY_INCLUDE_IN(snaps)
|
||||
memoize,
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
isEqual,
|
||||
} from 'lodash';
|
||||
import { createSelector } from 'reselect';
|
||||
import { addHexPrefix } from '../../app/scripts/lib/util';
|
||||
import {
|
||||
TEST_CHAINS,
|
||||
@ -97,10 +92,16 @@ import {
|
||||
NOTIFICATION_DROP_LEDGER_FIREFOX,
|
||||
NOTIFICATION_OPEN_BETA_SNAPS,
|
||||
} from '../../shared/notifications';
|
||||
import {
|
||||
getCurrentNetworkTransactions,
|
||||
getUnapprovedTransactions,
|
||||
} from './transactions';
|
||||
///: BEGIN:ONLY_INCLUDE_IN(snaps)
|
||||
// eslint-disable-next-line import/order
|
||||
import { SNAPS_VIEW_ROUTE } from '../helpers/constants/routes';
|
||||
import { getPermissionSubjects } from './permissions';
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
import { createDeepEqualSelector } from './util';
|
||||
|
||||
/**
|
||||
* Returns true if the currently selected network is inaccessible or whether no
|
||||
@ -578,7 +579,7 @@ export function getTotalUnapprovedSignatureRequestCount(state) {
|
||||
}
|
||||
|
||||
export function getUnapprovedTxCount(state) {
|
||||
const { unapprovedTxs = {} } = state.metamask;
|
||||
const unapprovedTxs = getUnapprovedTransactions(state);
|
||||
return Object.keys(unapprovedTxs).length;
|
||||
}
|
||||
|
||||
@ -852,8 +853,6 @@ export function getShowWhatsNewPopup(state) {
|
||||
return state.appState.showWhatsNewPopup;
|
||||
}
|
||||
|
||||
const createDeepEqualSelector = createSelectorCreator(defaultMemoize, isEqual);
|
||||
|
||||
export const getMemoizedMetaMaskIdentities = createDeepEqualSelector(
|
||||
getMetaMaskIdentities,
|
||||
(identities) => identities,
|
||||
@ -875,16 +874,10 @@ export const getMemoizedMetadataContractName = createDeepEqualSelector(
|
||||
},
|
||||
);
|
||||
|
||||
export const getUnapprovedTransactions = (state) =>
|
||||
state.metamask.unapprovedTxs;
|
||||
|
||||
export const getCurrentNetworkTransactionList = (state) =>
|
||||
state.metamask.currentNetworkTxList;
|
||||
|
||||
export const getTxData = (state) => state.confirmTransaction.txData;
|
||||
|
||||
export const getUnapprovedTransaction = createDeepEqualSelector(
|
||||
getUnapprovedTransactions,
|
||||
(state) => getUnapprovedTransactions(state),
|
||||
(_, transactionId) => transactionId,
|
||||
(unapprovedTxs, transactionId) => {
|
||||
return (
|
||||
@ -894,7 +887,7 @@ export const getUnapprovedTransaction = createDeepEqualSelector(
|
||||
);
|
||||
|
||||
export const getTransaction = createDeepEqualSelector(
|
||||
getCurrentNetworkTransactionList,
|
||||
(state) => getCurrentNetworkTransactions(state),
|
||||
(_, transactionId) => transactionId,
|
||||
(unapprovedTxs, transactionId) => {
|
||||
return (
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { createSelector } from 'reselect';
|
||||
import { ApprovalType } from '@metamask/controller-utils';
|
||||
import { createSelector } from 'reselect';
|
||||
import {
|
||||
PRIORITY_STATUS_HASH,
|
||||
PENDING_STATUS_HASH,
|
||||
@ -19,32 +19,67 @@ import {
|
||||
getSelectedAddress,
|
||||
} from './selectors';
|
||||
import { hasPendingApprovals, getApprovalRequestsByType } from './approvals';
|
||||
import { createDeepEqualSelector } from './util';
|
||||
|
||||
const INVALID_INITIAL_TRANSACTION_TYPES = [
|
||||
TransactionType.cancel,
|
||||
TransactionType.retry,
|
||||
];
|
||||
|
||||
export const incomingTxListSelector = (state) => {
|
||||
const { incomingTransactionsPreferences } = state.metamask;
|
||||
if (!incomingTransactionsPreferences) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const { networkId } = state.metamask;
|
||||
const { chainId } = getProviderConfig(state);
|
||||
const selectedAddress = getSelectedAddress(state);
|
||||
|
||||
return Object.values(state.metamask.transactions || {}).filter(
|
||||
(tx) =>
|
||||
tx.type === TransactionType.incoming &&
|
||||
tx.txParams.to === selectedAddress &&
|
||||
transactionMatchesNetwork(tx, chainId, networkId),
|
||||
);
|
||||
};
|
||||
export const unapprovedMsgsSelector = (state) => state.metamask.unapprovedMsgs;
|
||||
export const currentNetworkTxListSelector = (state) =>
|
||||
state.metamask.currentNetworkTxList;
|
||||
|
||||
export const getCurrentNetworkTransactions = createDeepEqualSelector(
|
||||
(state) => {
|
||||
const { transactions, networkId } = state.metamask ?? {};
|
||||
|
||||
if (!transactions?.length) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const { chainId } = getProviderConfig(state);
|
||||
|
||||
return transactions.filter((transaction) =>
|
||||
transactionMatchesNetwork(transaction, chainId, networkId),
|
||||
);
|
||||
},
|
||||
(transactions) => transactions,
|
||||
);
|
||||
|
||||
export const getUnapprovedTransactions = createDeepEqualSelector(
|
||||
(state) => {
|
||||
const currentNetworkTransactions = getCurrentNetworkTransactions(state);
|
||||
|
||||
return currentNetworkTransactions
|
||||
.filter(
|
||||
(transaction) => transaction.status === TransactionStatus.unapproved,
|
||||
)
|
||||
.reduce((result, transaction) => {
|
||||
result[transaction.id] = transaction;
|
||||
return result;
|
||||
}, {});
|
||||
},
|
||||
(transactions) => transactions,
|
||||
);
|
||||
|
||||
export const incomingTxListSelector = createDeepEqualSelector(
|
||||
(state) => {
|
||||
const { incomingTransactionsPreferences } = state.metamask;
|
||||
if (!incomingTransactionsPreferences) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const currentNetworkTransactions = getCurrentNetworkTransactions(state);
|
||||
const selectedAddress = getSelectedAddress(state);
|
||||
|
||||
return currentNetworkTransactions.filter(
|
||||
(tx) =>
|
||||
tx.type === TransactionType.incoming &&
|
||||
tx.txParams.to === selectedAddress,
|
||||
);
|
||||
},
|
||||
(transactions) => transactions,
|
||||
);
|
||||
|
||||
export const unapprovedPersonalMsgsSelector = (state) =>
|
||||
state.metamask.unapprovedPersonalMsgs;
|
||||
export const unapprovedDecryptMsgsSelector = (state) =>
|
||||
@ -69,7 +104,7 @@ export const smartTransactionsListSelector = (state) =>
|
||||
|
||||
export const selectedAddressTxListSelector = createSelector(
|
||||
getSelectedAddress,
|
||||
currentNetworkTxListSelector,
|
||||
getCurrentNetworkTransactions,
|
||||
smartTransactionsListSelector,
|
||||
(selectedAddress, transactions = [], smTransactions = []) => {
|
||||
return transactions
|
||||
@ -540,7 +575,7 @@ export const submittedPendingTransactionsSelector = createSelector(
|
||||
);
|
||||
|
||||
const hasUnapprovedTransactionsInCurrentNetwork = (state) => {
|
||||
const { unapprovedTxs } = state.metamask;
|
||||
const unapprovedTxs = getUnapprovedTransactions(state);
|
||||
const unapprovedTxRequests = getApprovalRequestsByType(
|
||||
state,
|
||||
ApprovalType.Transaction,
|
||||
|
@ -106,7 +106,7 @@ describe('Transaction Selectors', () => {
|
||||
});
|
||||
|
||||
describe('transactionsSelector', () => {
|
||||
it('selects the currentNetworkTxList', () => {
|
||||
it('selects the current network transactions', () => {
|
||||
const state = {
|
||||
metamask: {
|
||||
providerConfig: {
|
||||
@ -115,9 +115,10 @@ describe('Transaction Selectors', () => {
|
||||
},
|
||||
featureFlags: {},
|
||||
selectedAddress: '0xAddress',
|
||||
currentNetworkTxList: [
|
||||
transactions: [
|
||||
{
|
||||
id: 0,
|
||||
chainId: CHAIN_IDS.MAINNET,
|
||||
time: 0,
|
||||
txParams: {
|
||||
from: '0xAddress',
|
||||
@ -126,6 +127,7 @@ describe('Transaction Selectors', () => {
|
||||
},
|
||||
{
|
||||
id: 1,
|
||||
chainId: CHAIN_IDS.MAINNET,
|
||||
time: 1,
|
||||
txParams: {
|
||||
from: '0xAddress',
|
||||
@ -136,7 +138,7 @@ describe('Transaction Selectors', () => {
|
||||
},
|
||||
};
|
||||
|
||||
const orderedTxList = state.metamask.currentNetworkTxList.sort(
|
||||
const orderedTxList = state.metamask.transactions.sort(
|
||||
(a, b) => b.time - a.time,
|
||||
);
|
||||
|
||||
@ -177,7 +179,7 @@ describe('Transaction Selectors', () => {
|
||||
},
|
||||
selectedAddress: '0xAddress',
|
||||
featureFlags: {},
|
||||
currentNetworkTxList: [tx1, tx2],
|
||||
transactions: [tx1, tx2],
|
||||
},
|
||||
};
|
||||
|
||||
@ -259,12 +261,7 @@ describe('Transaction Selectors', () => {
|
||||
},
|
||||
selectedAddress: '0xAddress',
|
||||
featureFlags: {},
|
||||
currentNetworkTxList: [
|
||||
submittedTx,
|
||||
unapprovedTx,
|
||||
approvedTx,
|
||||
confirmedTx,
|
||||
],
|
||||
transactions: [submittedTx, unapprovedTx, approvedTx, confirmedTx],
|
||||
},
|
||||
};
|
||||
|
||||
@ -352,12 +349,13 @@ describe('Transaction Selectors', () => {
|
||||
requestState: null,
|
||||
},
|
||||
},
|
||||
unapprovedTxs: {
|
||||
2: {
|
||||
transactions: [
|
||||
{
|
||||
id: '2',
|
||||
chainId: mockNetworkId,
|
||||
status: TransactionStatus.unapproved,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
@ -365,11 +363,13 @@ describe('Transaction Selectors', () => {
|
||||
const result = hasTransactionPendingApprovals(mockedState);
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it('should return false if there is a pending transaction on different network', () => {
|
||||
mockedState.metamask.unapprovedTxs['2'].chainId = 'differentNetworkId';
|
||||
mockedState.metamask.transactions[0].chainId = 'differentNetworkId';
|
||||
const result = hasTransactionPendingApprovals(mockedState);
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
|
||||
it.each([
|
||||
[ApprovalType.EthDecrypt],
|
||||
[ApprovalType.EthGetEncryptionPublicKey],
|
||||
|
7
ui/selectors/util.js
Normal file
7
ui/selectors/util.js
Normal file
@ -0,0 +1,7 @@
|
||||
import { isEqual } from 'lodash';
|
||||
import { createSelectorCreator, defaultMemoize } from 'reselect';
|
||||
|
||||
export const createDeepEqualSelector = createSelectorCreator(
|
||||
defaultMemoize,
|
||||
isEqual,
|
||||
);
|
@ -41,6 +41,7 @@ import {
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
///: BEGIN:ONLY_INCLUDE_IN(keyring-snaps)
|
||||
getPermissionSubjects,
|
||||
getCurrentNetworkTransactions,
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
} from '../selectors';
|
||||
import {
|
||||
@ -2066,7 +2067,8 @@ export function createCancelTransaction(
|
||||
return;
|
||||
}
|
||||
if (newState) {
|
||||
const { currentNetworkTxList } = newState;
|
||||
const currentNetworkTxList =
|
||||
getCurrentNetworkTransactions(newState);
|
||||
const { id } =
|
||||
currentNetworkTxList[currentNetworkTxList.length - 1];
|
||||
newTxId = id;
|
||||
@ -2103,7 +2105,8 @@ export function createSpeedUpTransaction(
|
||||
}
|
||||
|
||||
if (newState) {
|
||||
const { currentNetworkTxList } = newState;
|
||||
const currentNetworkTxList =
|
||||
getCurrentNetworkTransactions(newState);
|
||||
newTx = currentNetworkTxList[currentNetworkTxList.length - 1];
|
||||
resolve(newState);
|
||||
}
|
||||
@ -2135,7 +2138,8 @@ export function createRetryTransaction(
|
||||
return;
|
||||
}
|
||||
if (newState) {
|
||||
const { currentNetworkTxList } = newState;
|
||||
const currentNetworkTxList =
|
||||
getCurrentNetworkTransactions(newState);
|
||||
newTx = currentNetworkTxList[currentNetworkTxList.length - 1];
|
||||
resolve(newState);
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ const defaultState = {
|
||||
},
|
||||
},
|
||||
},
|
||||
currentNetworkTxList: [
|
||||
transactions: [
|
||||
{
|
||||
id: 0,
|
||||
time: 0,
|
||||
@ -232,7 +232,7 @@ describe('#updateCustodyState', () => {
|
||||
},
|
||||
featureFlags: {},
|
||||
selectedAddress: '0xAddress',
|
||||
currentNetworkTxList: [
|
||||
transactions: [
|
||||
{
|
||||
id: 0,
|
||||
time: 0,
|
||||
@ -285,7 +285,7 @@ describe('#updateCustodyState', () => {
|
||||
},
|
||||
featureFlags: {},
|
||||
selectedAddress: '0xAddress',
|
||||
currentNetworkTxList: [
|
||||
transactions: [
|
||||
{
|
||||
id: 0,
|
||||
time: 0,
|
||||
|
@ -12,6 +12,8 @@ import {
|
||||
MessagesIndexedById,
|
||||
} from '../store';
|
||||
import { toChecksumHexAddress } from '../../../shared/modules/hexstring-utils';
|
||||
import { getCurrentNetworkTransactions } from '../../selectors';
|
||||
import { TransactionMeta } from '../../../shared/constants/transaction';
|
||||
|
||||
export function showInteractiveReplacementTokenModal(): ThunkAction<
|
||||
void,
|
||||
@ -57,13 +59,19 @@ export function updateCustodyState(
|
||||
newState: MetaMaskReduxState['metamask'],
|
||||
state: CombinedBackgroundAndReduxState & any,
|
||||
) {
|
||||
if (!newState.currentNetworkTxList || !state.metamask.currentNetworkTxList) {
|
||||
if (!newState.transactions || !state.metamask.transactions) {
|
||||
return;
|
||||
}
|
||||
|
||||
const differentTxs = newState.currentNetworkTxList.filter(
|
||||
(item) =>
|
||||
state.metamask.currentNetworkTxList.filter(
|
||||
const newCurrentNetworkTxList = getCurrentNetworkTransactions({
|
||||
metamask: newState,
|
||||
});
|
||||
|
||||
const oldCurrentNetworkTxList = getCurrentNetworkTransactions(state);
|
||||
|
||||
const differentTxs = newCurrentNetworkTxList.filter(
|
||||
(item: TransactionMeta) =>
|
||||
oldCurrentNetworkTxList.filter(
|
||||
(tx: { [key: string]: any }) =>
|
||||
tx.custodyId === item.custodyId &&
|
||||
tx.custodyStatus !== item.custodyStatus,
|
||||
@ -71,7 +79,7 @@ export function updateCustodyState(
|
||||
);
|
||||
|
||||
const txStateSaysDeepLinkShouldClose = Boolean(
|
||||
differentTxs.find((tx) => {
|
||||
differentTxs.find((tx: TransactionMeta) => {
|
||||
const custodyAccountDetails =
|
||||
state.metamask.custodyAccountDetails[
|
||||
toChecksumHexAddress(tx.txParams.from)
|
||||
|
@ -53,7 +53,7 @@ interface TemporaryBackgroundState {
|
||||
providerConfig: {
|
||||
chainId: string;
|
||||
};
|
||||
currentNetworkTxList: TransactionMeta[];
|
||||
transactions: TransactionMeta[];
|
||||
selectedAddress: string;
|
||||
identities: {
|
||||
[address: string]: {
|
||||
@ -62,9 +62,6 @@ interface TemporaryBackgroundState {
|
||||
};
|
||||
ledgerTransportType: LedgerTransportTypes;
|
||||
unapprovedDecryptMsgs: MessagesIndexedById;
|
||||
unapprovedTxs: {
|
||||
[transactionId: string]: TransactionMeta;
|
||||
};
|
||||
unapprovedMsgs: MessagesIndexedById;
|
||||
unapprovedPersonalMsgs: MessagesIndexedById;
|
||||
unapprovedTypedMessages: MessagesIndexedById;
|
||||
|
Loading…
Reference in New Issue
Block a user