1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-11-22 01:47:00 +01:00

Convert store.js to typescript and redux toolkit (#17508)

This commit is contained in:
Brad Decker 2023-02-02 13:32:44 -06:00 committed by GitHub
parent c1f9c778c9
commit deb9343ff0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 195 additions and 56 deletions

View File

@ -406,6 +406,7 @@
"@types/pump": "^1.1.1",
"@types/react": "^16.9.53",
"@types/react-dom": "^17.0.11",
"@types/remote-redux-devtools": "^0.5.5",
"@types/watchify": "^3.11.1",
"@types/yargs": "^17.0.8",
"@typescript-eslint/eslint-plugin": "^5.30.7",

View File

@ -23,39 +23,55 @@ import {
hexToDecimal,
} from '../../../shared/modules/conversion.utils';
export default function reduceMetamask(state = {}, action) {
const metamaskState = {
isInitialized: false,
isUnlocked: false,
isAccountMenuOpen: false,
identities: {},
unapprovedTxs: {},
frequentRpcList: [],
addressBook: [],
contractExchangeRates: {},
pendingTokens: {},
customNonceValue: '',
useBlockie: false,
featureFlags: {},
welcomeScreenSeen: false,
currentLocale: '',
currentBlockGasLimit: '',
preferences: {
autoLockTimeLimit: undefined,
showFiatInTestnets: false,
showTestNetworks: false,
useNativeCurrencyAsPrimaryCurrency: true,
},
firstTimeFlowType: null,
completedOnboarding: false,
knownMethodData: {},
participateInMetaMetrics: null,
nextNonce: null,
conversionRate: null,
nativeCurrency: 'ETH',
...state,
};
const initialState = {
isInitialized: false,
isUnlocked: false,
isAccountMenuOpen: false,
identities: {},
unapprovedTxs: {},
frequentRpcList: [],
addressBook: [],
contractExchangeRates: {},
pendingTokens: {},
customNonceValue: '',
useBlockie: false,
featureFlags: {},
welcomeScreenSeen: false,
currentLocale: '',
currentBlockGasLimit: '',
preferences: {
autoLockTimeLimit: undefined,
showFiatInTestnets: false,
showTestNetworks: false,
useNativeCurrencyAsPrimaryCurrency: true,
},
firstTimeFlowType: null,
completedOnboarding: false,
knownMethodData: {},
participateInMetaMetrics: null,
nextNonce: null,
conversionRate: null,
nativeCurrency: 'ETH',
};
/**
* Temporary types for this slice so that inferrence of MetaMask state tree can
* occur
*
* @param {typeof initialState} state - State
* @param {any} action
* @returns {typeof initialState}
*/
export default function reduceMetamask(state = initialState, action) {
// I don't think we should be spreading initialState into this. Once the
// state tree has begun by way of the first reduce call the initialState is
// set. The only time it should be used again is if we reset the state with a
// deliberate action. However, our tests are *relying upon the initialState
// tree above to be spread into the reducer as a way of hydrating the state
// for this slice*. I attempted to remove this and it caused nearly 40 test
// failures. We are going to refactor this slice anyways, possibly removing
// it so we will fix this issue when that time comes.
const metamaskState = { ...initialState, ...state };
switch (action.type) {
case actionConstants.UPDATE_METAMASK_STATE:
return { ...metamaskState, ...action.value };

View File

@ -1,20 +0,0 @@
import { createStore, applyMiddleware } from 'redux';
import thunkMiddleware from 'redux-thunk';
import { composeWithDevTools } from 'remote-redux-devtools';
import rootReducer from '../ducks';
export default function configureStore(initialState) {
let storeEnhancers = applyMiddleware(thunkMiddleware);
if (process.env.METAMASK_DEBUG && !process.env.IN_TEST) {
const composeEnhancers = composeWithDevTools({
name: 'MetaMask',
hostname: 'localhost',
port: 8000,
realtime: Boolean(process.env.METAMASK_DEBUG),
});
storeEnhancers = composeEnhancers(storeEnhancers);
}
return createStore(rootReducer, initialState, storeEnhancers);
}

132
ui/store/store.ts Normal file
View File

@ -0,0 +1,132 @@
import { StoreEnhancer } from 'redux';
import { configureStore as baseConfigureStore } from '@reduxjs/toolkit';
import devtoolsEnhancer from 'remote-redux-devtools';
import { ApprovalControllerState } from '@metamask/approval-controller';
import { GasEstimateType, GasFeeEstimates } from '@metamask/gas-fee-controller';
import rootReducer from '../ducks';
import { LedgerTransportTypes } from '../../shared/constants/hardware-wallets';
import { TransactionMeta } from '../../shared/constants/transaction';
/**
* This interface is temporary and is copied from the message-manager.js file
* and is the 'msgParams' key of the interface declared there. We should get a
* universal Message type to use for this, the Message manager and all
* the other types of messages.
*
* TODO: Replace this
*/
export interface TemporaryMessageDataType {
id: number;
type: string;
msgParams: {
metamaskId: number;
data: string;
};
}
interface MessagesIndexedById {
[id: string]: TemporaryMessageDataType;
}
/**
* This interface is a temporary interface to describe the state tree that is
* sent from the background. Ideally we can build this using Types in the
* backend when we compose the stores, then we can import it here and use it.
*
* Some of this is duplicated in the metamask redux duck. In *most* cases the
* state received from the background takes precedence over anything in the
* metamask reducer.
*/
interface TemporaryBackgroundState {
addressBook: {
[chainId: string]: {
name: string;
}[];
};
provider: {
chainId: string;
};
currentNetworkTxList: TransactionMeta[];
selectedAddress: string;
identities: {
[address: string]: {
balance: string;
};
};
ledgerTransportType: LedgerTransportTypes;
unapprovedDecryptMsgs: MessagesIndexedById;
unapprovedTxs: {
[transactionId: string]: TransactionMeta;
};
unapprovedMsgs: MessagesIndexedById;
unapprovedPersonalMsgs: MessagesIndexedById;
unapprovedTypedMessages: MessagesIndexedById;
network: string;
pendingApprovals: ApprovalControllerState['pendingApprovals'];
knownMethodData?: {
[fourBytePrefix: string]: Record<string, unknown>;
};
gasFeeEstimates: GasFeeEstimates;
gasEstimateType: GasEstimateType;
}
type RootReducerReturnType = ReturnType<typeof rootReducer>;
type CombinedBackgroundAndReduxState = RootReducerReturnType & {
activeTab: {
origin: string;
};
metamask: RootReducerReturnType['metamask'] & TemporaryBackgroundState;
};
export default function configureStore(preloadedState: any) {
const debugModeEnabled = Boolean(process.env.METAMASK_DEBUG);
const isDev = debugModeEnabled && !process.env.IN_TEST;
const enhancers: StoreEnhancer[] = [];
if (isDev) {
enhancers.push(
devtoolsEnhancer({
name: 'MetaMask',
hostname: 'localhost',
port: 8000,
realtime: true,
}) as StoreEnhancer,
);
}
return baseConfigureStore({
reducer: rootReducer as () => CombinedBackgroundAndReduxState,
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware({
/**
* We do not persist the redux tree for rehydration, so checking for
* serializable state keys is not relevant for now. Any state that persists
* is managed in the background. We may at some point want this, but we can
* gradually implement by using the ignore options to ignore those actions
* and state keys that are not serializable, preventing us from adding new
* actions and state that would violate our ability to persist state keys.
* NOTE: redux-thunk is included by default in the middleware below.
*/
serializableCheck: false,
/**
* immutableCheck controls whether we get warnings about mutation of
* state, which will be true in dev. However in test lavamoat complains
* about something the middleware is doing. It would be good to figure
* that out and enable this in test environments so that mutation
* causes E2E failures.
*/
immutableCheck: isDev
? {
warnAfter: 100,
}
: false,
}),
devTools: false,
enhancers,
preloadedState,
});
}
type Store = ReturnType<typeof configureStore>;
export type MetaMaskReduxState = ReturnType<Store['getState']>;
export type MetaMaskReduxDispatch = Store['dispatch'];

View File

@ -7432,6 +7432,15 @@ __metadata:
languageName: node
linkType: hard
"@types/remote-redux-devtools@npm:^0.5.5":
version: 0.5.5
resolution: "@types/remote-redux-devtools@npm:0.5.5"
dependencies:
redux: ^4.0.0
checksum: 1ff59a41e194b8785ba358109a3b5cf30d91a868e04cce57d912344ec5f6e38b647fec7194f621abebac97492dfb344ac6e535654ea05da60c5f78704c108634
languageName: node
linkType: hard
"@types/responselike@npm:*, @types/responselike@npm:^1.0.0":
version: 1.0.0
resolution: "@types/responselike@npm:1.0.0"
@ -24133,6 +24142,7 @@ __metadata:
"@types/pump": ^1.1.1
"@types/react": ^16.9.53
"@types/react-dom": ^17.0.11
"@types/remote-redux-devtools": ^0.5.5
"@types/watchify": ^3.11.1
"@types/yargs": ^17.0.8
"@typescript-eslint/eslint-plugin": ^5.30.7
@ -29154,12 +29164,12 @@ __metadata:
languageName: node
linkType: hard
"redux@npm:^4.0.5, redux@npm:^4.1.0":
version: 4.1.1
resolution: "redux@npm:4.1.1"
"redux@npm:^4.0.0, redux@npm:^4.0.5, redux@npm:^4.1.0":
version: 4.2.1
resolution: "redux@npm:4.2.1"
dependencies:
"@babel/runtime": ^7.9.2
checksum: 99519438a5d20b69404ad3816307ccc189f16df04b64c50d82c415ec488ea68b656d7a2fc81b6345e8d90f095344dfea68246500f72613d76464986660bc0485
checksum: f63b9060c3a1d930ae775252bb6e579b42415aee7a23c4114e21a0b4ba7ec12f0ec76936c00f546893f06e139819f0e2855e0d55ebfce34ca9c026241a6950dd
languageName: node
linkType: hard