mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
Fix swaps when initial network not Mainnet (#9745)
This is a continuation of #9726, which did not fix the problem described. If the initial network when the extension is started is something other than Mainnet, the swaps controller will never successfully retrieve swap quotes. This is because `ethers` will continue to communicate with whichever network the provider was initially on. We tried fixing this by hard-coding the `chainId` to Mainnet's `chainId` when constructing the Ethers provider, but this did not work. I suspect this failed because the `provider` we pass to `ethers` is not compliant with EIP 1193, as `ethers` doubtless expects it to be. Instead the entire `ethers` provider is now reconstructed each time the network changes. This mirrors the approach we take in some other controllers.
This commit is contained in:
parent
336282d7d5
commit
1294955d81
@ -18,7 +18,6 @@ import {
|
||||
fetchTradesInfo as defaultFetchTradesInfo,
|
||||
fetchSwapsFeatureLiveness as defaultFetchSwapsFeatureLiveness,
|
||||
} from '../../../ui/app/pages/swaps/swaps.util'
|
||||
import { MAINNET_CHAIN_ID } from './network/enums'
|
||||
|
||||
const METASWAP_ADDRESS = '0x881d40237659c251811cec9c364ef91dc08d300c'
|
||||
|
||||
@ -71,6 +70,7 @@ const initialState = {
|
||||
export default class SwapsController {
|
||||
constructor ({
|
||||
getBufferedGasLimit,
|
||||
networkController,
|
||||
provider,
|
||||
getProviderConfig,
|
||||
tokenRatesStore,
|
||||
@ -92,8 +92,14 @@ export default class SwapsController {
|
||||
|
||||
this.indexOfNewestCallInFlight = 0
|
||||
|
||||
// The chain ID is hard-coded as Mainnet because swaps is only used on Mainnet
|
||||
this.ethersProvider = new ethers.providers.Web3Provider(provider, parseInt(MAINNET_CHAIN_ID, 16))
|
||||
this.ethersProvider = new ethers.providers.Web3Provider(provider)
|
||||
this._currentNetwork = networkController.store.getState().network
|
||||
networkController.on('networkDidChange', (network) => {
|
||||
if (network !== 'loading' && network !== this._currentNetwork) {
|
||||
this._currentNetwork = network
|
||||
this.ethersProvider = new ethers.providers.Web3Provider(provider)
|
||||
}
|
||||
})
|
||||
|
||||
this._setupSwapsLivenessFetching()
|
||||
}
|
||||
|
@ -311,6 +311,7 @@ export default class MetamaskController extends EventEmitter {
|
||||
|
||||
this.swapsController = new SwapsController({
|
||||
getBufferedGasLimit: this.txController.txGasUtil.getBufferedGasLimit.bind(this.txController.txGasUtil),
|
||||
networkController: this.networkController,
|
||||
provider: this.provider,
|
||||
getProviderConfig: this.networkController.getProviderConfig.bind(this.networkController),
|
||||
tokenRatesStore: this.tokenRatesController.store,
|
||||
|
@ -4,6 +4,7 @@ import sinon from 'sinon'
|
||||
import { ethers } from 'ethers'
|
||||
import BigNumber from 'bignumber.js'
|
||||
import ObservableStore from 'obs-store'
|
||||
import { ROPSTEN_NETWORK_ID, MAINNET_NETWORK_ID } from '../../../../app/scripts/controllers/network/enums'
|
||||
import { createTestProviderTools } from '../../../stub/provider'
|
||||
import SwapsController, { utils } from '../../../../app/scripts/controllers/swaps'
|
||||
|
||||
@ -75,6 +76,19 @@ const MOCK_GET_BUFFERED_GAS_LIMIT = async () => ({
|
||||
simulationFails: undefined,
|
||||
})
|
||||
|
||||
function getMockNetworkController () {
|
||||
return {
|
||||
store: {
|
||||
getState: () => {
|
||||
return {
|
||||
network: ROPSTEN_NETWORK_ID,
|
||||
}
|
||||
},
|
||||
},
|
||||
on: sinon.stub().withArgs('networkDidChange').callsArgAsync(1),
|
||||
}
|
||||
}
|
||||
|
||||
const EMPTY_INIT_STATE = {
|
||||
swapsState: {
|
||||
quotes: {},
|
||||
@ -104,6 +118,7 @@ describe('SwapsController', function () {
|
||||
const getSwapsController = () => {
|
||||
return new SwapsController({
|
||||
getBufferedGasLimit: MOCK_GET_BUFFERED_GAS_LIMIT,
|
||||
networkController: getMockNetworkController(),
|
||||
provider,
|
||||
getProviderConfig: MOCK_GET_PROVIDER_CONFIG,
|
||||
tokenRatesStore: MOCK_TOKEN_RATES_STORE,
|
||||
@ -141,6 +156,78 @@ describe('SwapsController', function () {
|
||||
MOCK_GET_PROVIDER_CONFIG,
|
||||
)
|
||||
})
|
||||
|
||||
it('should replace ethers instance when network changes', function () {
|
||||
const networkController = getMockNetworkController()
|
||||
const swapsController = new SwapsController({
|
||||
getBufferedGasLimit: MOCK_GET_BUFFERED_GAS_LIMIT,
|
||||
networkController,
|
||||
provider,
|
||||
getProviderConfig: MOCK_GET_PROVIDER_CONFIG,
|
||||
tokenRatesStore: MOCK_TOKEN_RATES_STORE,
|
||||
fetchTradesInfo: fetchTradesInfoStub,
|
||||
fetchSwapsFeatureLiveness: fetchSwapsFeatureLivenessStub,
|
||||
})
|
||||
const currentEthersInstance = swapsController.ethersProvider
|
||||
const onNetworkDidChange = networkController.on.getCall(0).args[1]
|
||||
|
||||
onNetworkDidChange(MAINNET_NETWORK_ID)
|
||||
|
||||
const newEthersInstance = swapsController.ethersProvider
|
||||
assert.notStrictEqual(
|
||||
currentEthersInstance,
|
||||
newEthersInstance,
|
||||
'Ethers provider should be replaced',
|
||||
)
|
||||
})
|
||||
|
||||
it('should not replace ethers instance when network changes to loading', function () {
|
||||
const networkController = getMockNetworkController()
|
||||
const swapsController = new SwapsController({
|
||||
getBufferedGasLimit: MOCK_GET_BUFFERED_GAS_LIMIT,
|
||||
networkController,
|
||||
provider,
|
||||
getProviderConfig: MOCK_GET_PROVIDER_CONFIG,
|
||||
tokenRatesStore: MOCK_TOKEN_RATES_STORE,
|
||||
fetchTradesInfo: fetchTradesInfoStub,
|
||||
fetchSwapsFeatureLiveness: fetchSwapsFeatureLivenessStub,
|
||||
})
|
||||
const currentEthersInstance = swapsController.ethersProvider
|
||||
const onNetworkDidChange = networkController.on.getCall(0).args[1]
|
||||
|
||||
onNetworkDidChange('loading')
|
||||
|
||||
const newEthersInstance = swapsController.ethersProvider
|
||||
assert.strictEqual(
|
||||
currentEthersInstance,
|
||||
newEthersInstance,
|
||||
'Ethers provider should not be replaced',
|
||||
)
|
||||
})
|
||||
|
||||
it('should not replace ethers instance when network changes to the same network', function () {
|
||||
const networkController = getMockNetworkController()
|
||||
const swapsController = new SwapsController({
|
||||
getBufferedGasLimit: MOCK_GET_BUFFERED_GAS_LIMIT,
|
||||
networkController,
|
||||
provider,
|
||||
getProviderConfig: MOCK_GET_PROVIDER_CONFIG,
|
||||
tokenRatesStore: MOCK_TOKEN_RATES_STORE,
|
||||
fetchTradesInfo: fetchTradesInfoStub,
|
||||
fetchSwapsFeatureLiveness: fetchSwapsFeatureLivenessStub,
|
||||
})
|
||||
const currentEthersInstance = swapsController.ethersProvider
|
||||
const onNetworkDidChange = networkController.on.getCall(0).args[1]
|
||||
|
||||
onNetworkDidChange(ROPSTEN_NETWORK_ID)
|
||||
|
||||
const newEthersInstance = swapsController.ethersProvider
|
||||
assert.strictEqual(
|
||||
currentEthersInstance,
|
||||
newEthersInstance,
|
||||
'Ethers provider should not be replaced',
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('API', function () {
|
||||
|
Loading…
Reference in New Issue
Block a user