-
Notifications
You must be signed in to change notification settings - Fork 5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
16 changed files
with
351 additions
and
132 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,194 @@ | ||
import { NetworkType } from '@metamask/controller-utils'; | ||
import { | ||
CHAIN_IDS, | ||
CHAIN_ID_TO_RPC_URL_MAP, | ||
LINEA_SEPOLIA_DISPLAY_NAME, | ||
NETWORK_TYPES, | ||
TEST_NETWORK_TICKER_MAP, | ||
} from '../../../shared/constants/network'; | ||
import { migrate, version } from './119'; | ||
|
||
const oldVersion = 118; | ||
|
||
const ethereumProviderConfig = { | ||
chainId: '0x1', | ||
rpcPrefs: { | ||
blockExplorerUrl: 'https://etherscan.io', | ||
}, | ||
ticker: 'ETH', | ||
type: 'mainnet', | ||
}; | ||
|
||
const ethereumNetworksMetadata = { | ||
mainnet: { | ||
EIPS: { | ||
'1559': true, | ||
}, | ||
status: 'available', | ||
}, | ||
}; | ||
const ethereumOldState = { | ||
CurrencyController: { | ||
currencyRates: { | ||
ETH: { | ||
conversionDate: 1708532473.416, | ||
conversionRate: 2918.02, | ||
usdConversionRate: 2918.02, | ||
}, | ||
GoerliETH: { | ||
conversionDate: 1708532466.732, | ||
conversionRate: 2918.02, | ||
usdConversionRate: 2918.02, | ||
}, | ||
}, | ||
currentCurrency: 'usd', | ||
}, | ||
NetworkController: { | ||
networkConfigurations: {}, | ||
networksMetadata: ethereumNetworksMetadata, | ||
providerConfig: ethereumProviderConfig, | ||
selectedNetworkClientId: 'mainnet', | ||
}, | ||
}; | ||
|
||
const lineaGoerliState = { | ||
NetworkController: { | ||
networkConfigurations: {}, | ||
networksMetadata: { | ||
'linea-goerli': { | ||
EIPS: { | ||
'1559': true, | ||
}, | ||
status: 'available', | ||
}, | ||
}, | ||
providerConfig: { | ||
chainId: CHAIN_IDS.LINEA_GOERLI, | ||
rpcPrefs: {}, | ||
ticker: TEST_NETWORK_TICKER_MAP[NETWORK_TYPES.LINEA_GOERLI], | ||
type: NETWORK_TYPES.LINEA_GOERLI, | ||
}, | ||
selectedNetworkClientId: NETWORK_TYPES.LINEA_GOERLI, | ||
}, | ||
}; | ||
|
||
describe('migration #119', () => { | ||
it('updates the version metadata', async () => { | ||
const oldStorage = { | ||
meta: { version: oldVersion }, | ||
data: {}, | ||
}; | ||
|
||
const newStorage = await migrate(oldStorage); | ||
|
||
expect(newStorage.meta).toStrictEqual({ version }); | ||
}); | ||
|
||
it('does nothing if no preferences state', async () => { | ||
const oldState = { | ||
OtherController: {}, | ||
}; | ||
|
||
const transformedState = await migrate({ | ||
meta: { version: oldVersion }, | ||
data: oldState, | ||
}); | ||
|
||
expect(transformedState.data).toEqual(oldState); | ||
}); | ||
|
||
it('Should return state if chainId is not linea-goerli', async () => { | ||
const transformedState = await migrate({ | ||
meta: { version: oldVersion }, | ||
data: ethereumOldState, | ||
}); | ||
|
||
expect(transformedState.data).toEqual(ethereumOldState); | ||
}); | ||
|
||
it('Should return state if there is no NetworkController in state', async () => { | ||
const { NetworkController, ...state } = ethereumOldState; | ||
const transformedState = await migrate({ | ||
meta: { version: oldVersion }, | ||
data: state, | ||
}); | ||
|
||
expect(transformedState.data).toEqual(state); | ||
}); | ||
|
||
it('Should return state if there is no provider in NetworkController', async () => { | ||
const state = { | ||
...ethereumOldState, | ||
NetworkController: {}, | ||
}; | ||
const transformedState = await migrate({ | ||
meta: { version: oldVersion }, | ||
data: state, | ||
}); | ||
|
||
expect(transformedState.data).toEqual(state); | ||
}); | ||
|
||
it('Should return state if there is no chainId in provider in NetworkController', async () => { | ||
const state = { | ||
...ethereumOldState, | ||
NetworkController: { | ||
providerConfig: {}, | ||
}, | ||
}; | ||
const transformedState = await migrate({ | ||
meta: { version: oldVersion }, | ||
data: state, | ||
}); | ||
|
||
expect(transformedState.data).toEqual(state); | ||
}); | ||
|
||
it('Should return state if chainId is not linea-goerli', async () => { | ||
const transformedState = await migrate({ | ||
meta: { version: oldVersion }, | ||
data: ethereumOldState, | ||
}); | ||
|
||
expect(transformedState.data).toEqual(ethereumOldState); | ||
}); | ||
|
||
it('Should update NetworkController to Linea Sepolia if chainId is on Linea Goerli', async () => { | ||
const expectedNetworkControllerState = { | ||
networkConfigurations: {}, | ||
networksMetadata: { | ||
'linea-sepolia': { | ||
EIPS: { | ||
'1559': true, | ||
}, | ||
status: 'available', | ||
}, | ||
'linea-goerli': { | ||
EIPS: { | ||
'1559': true, | ||
}, | ||
status: 'available', | ||
}, | ||
}, | ||
providerConfig: { | ||
type: NetworkType['linea-sepolia'], | ||
rpcPrefs: {}, | ||
chainId: CHAIN_IDS.LINEA_SEPOLIA, | ||
nickname: LINEA_SEPOLIA_DISPLAY_NAME, | ||
rpcUrl: CHAIN_ID_TO_RPC_URL_MAP[CHAIN_IDS.LINEA_SEPOLIA], | ||
providerType: NETWORK_TYPES.LINEA_SEPOLIA, | ||
ticker: TEST_NETWORK_TICKER_MAP[NETWORK_TYPES.LINEA_SEPOLIA], | ||
id: NETWORK_TYPES.LINEA_SEPOLIA, | ||
}, | ||
selectedNetworkClientId: 'linea-sepolia', | ||
}; | ||
const transformedState = await migrate({ | ||
meta: { version: oldVersion }, | ||
data: lineaGoerliState, | ||
}); | ||
|
||
expect(transformedState.data).toEqual({ | ||
NetworkController: expectedNetworkControllerState, | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
import { cloneDeep, isObject } from 'lodash'; | ||
import { NetworkType } from '@metamask/controller-utils'; | ||
import { hasProperty } from '@metamask/utils'; | ||
import { NetworkStatus } from '@metamask/network-controller'; | ||
import { | ||
CHAIN_IDS, | ||
CHAIN_ID_TO_RPC_URL_MAP, | ||
NETWORK_TYPES, | ||
TEST_NETWORK_TICKER_MAP, | ||
LINEA_SEPOLIA_DISPLAY_NAME, | ||
} from '../../../shared/constants/network'; | ||
|
||
type VersionedData = { | ||
meta: { version: number }; | ||
data: Record<string, unknown>; | ||
}; | ||
|
||
export const version = 119; | ||
|
||
/** | ||
* Migrates the user network to Linea Sepolia if the user is on Linea Goerli network. | ||
* | ||
* @param originalVersionedData - Versioned MetaMask extension state, exactly what we persist to dist. | ||
* @param originalVersionedData.meta - State metadata. | ||
* @param originalVersionedData.meta.version - The current state version. | ||
* @param originalVersionedData.data - The persisted MetaMask state, keyed by controller. | ||
* @returns Updated versioned MetaMask extension state. | ||
*/ | ||
export async function migrate( | ||
originalVersionedData: VersionedData, | ||
): Promise<VersionedData> { | ||
const versionedData = cloneDeep(originalVersionedData); | ||
versionedData.meta.version = version; | ||
transformState(versionedData.data); | ||
return versionedData; | ||
} | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
function transformState(state: Record<string, any>) { | ||
const NetworkController = state?.NetworkController || {}; | ||
const provider = NetworkController?.providerConfig || {}; | ||
|
||
if (provider?.chainId !== CHAIN_IDS.LINEA_GOERLI) { | ||
return state; | ||
} | ||
const networkControllerState = state.NetworkController; | ||
|
||
if ( | ||
hasProperty(state, 'NetworkController') && | ||
isObject(state.NetworkController) && | ||
hasProperty(state.NetworkController, 'providerConfig') && | ||
isObject(state.NetworkController.providerConfig) && | ||
hasProperty(state.NetworkController.providerConfig, 'chainId') && | ||
state.NetworkController.providerConfig.chainId === CHAIN_IDS.LINEA_GOERLI | ||
) { | ||
networkControllerState.providerConfig = { | ||
type: NetworkType['linea-sepolia'], | ||
rpcPrefs: {}, | ||
chainId: CHAIN_IDS.LINEA_SEPOLIA, | ||
nickname: LINEA_SEPOLIA_DISPLAY_NAME, | ||
rpcUrl: CHAIN_ID_TO_RPC_URL_MAP[CHAIN_IDS.LINEA_SEPOLIA], | ||
providerType: NETWORK_TYPES.LINEA_SEPOLIA, | ||
ticker: TEST_NETWORK_TICKER_MAP[NETWORK_TYPES.LINEA_SEPOLIA], | ||
id: NETWORK_TYPES.LINEA_SEPOLIA, | ||
}; | ||
networkControllerState.selectedNetworkClientId = | ||
NETWORK_TYPES.LINEA_SEPOLIA; | ||
networkControllerState.networksMetadata = { | ||
...networkControllerState.networksMetadata, | ||
'linea-sepolia': { | ||
EIPS: { | ||
'1559': true, | ||
}, | ||
status: NetworkStatus.Available, | ||
}, | ||
}; | ||
} | ||
return { | ||
...state, | ||
NetworkController: networkControllerState, | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.