diff --git a/app/scripts/controllers/preferences.js b/app/scripts/controllers/preferences.js index b21cdfb36be8..2faf8220b1c4 100644 --- a/app/scripts/controllers/preferences.js +++ b/app/scripts/controllers/preferences.js @@ -408,7 +408,11 @@ class PreferencesController { rpcList.splice(index, 1) } if (url !== 'http://localhost:8545') { - rpcList.push({ rpcUrl: url, chainId, ticker, nickname }) + let checkedChainId + if (!!chainId && !Number.isNaN(parseInt(chainId))) { + checkedChainId = chainId + } + rpcList.push({ rpcUrl: url, chainId: checkedChainId, ticker, nickname }) } this.store.updateState({ frequentRpcListDetail: rpcList }) return Promise.resolve(rpcList) diff --git a/app/scripts/migrations/030.js b/app/scripts/migrations/030.js new file mode 100644 index 000000000000..19b686c589d2 --- /dev/null +++ b/app/scripts/migrations/030.js @@ -0,0 +1,47 @@ +// next version number +const version = 30 + +/* + +removes invalid chaids from preferences and networkController for custom rpcs + +*/ + +const clone = require('clone') + +module.exports = { + version, + + migrate: async function (originalVersionedData) { + const versionedData = clone(originalVersionedData) + versionedData.meta.version = version + const state = versionedData.data + const newState = transformState(state) + versionedData.data = newState + return versionedData + }, +} + +function transformState (state) { + const newState = state + + const frequentRpcListDetail = newState.PreferencesController.frequentRpcListDetail + if (frequentRpcListDetail) { + frequentRpcListDetail.forEach((rpc, index) => { + if (!!rpc.chainId && Number.isNaN(parseInt(rpc.chainId))) { + delete frequentRpcListDetail[index].chainId + } + }) + newState.PreferencesController.frequentRpcListDetail = frequentRpcListDetail + } + + if (newState.NetworkController.network && Number.isNaN(parseInt(newState.NetworkController.network))) { + delete newState.NetworkController.network + } + + if (newState.NetworkController.provider && newState.NetworkController.provider.chainId && Number.isNaN(parseInt(newState.NetworkController.provider.chainId))) { + delete newState.NetworkController.provider.chainId + } + + return newState +} diff --git a/app/scripts/migrations/index.js b/app/scripts/migrations/index.js index 9344b77ed3b0..99cca94b8ab0 100644 --- a/app/scripts/migrations/index.js +++ b/app/scripts/migrations/index.js @@ -40,4 +40,5 @@ module.exports = [ require('./027'), require('./028'), require('./029'), + require('./030'), ] diff --git a/test/unit/migrations/030-test.js b/test/unit/migrations/030-test.js new file mode 100644 index 000000000000..ca410342fb22 --- /dev/null +++ b/test/unit/migrations/030-test.js @@ -0,0 +1,37 @@ +const assert = require('assert') +const migrationTemplate = require('../../../app/scripts/migrations/030.js') +const storage = { + meta: {}, + data: { + NetworkController: { + network: 'fail', + provider: { + chainId: 'fail', + nickname: '', + rpcTarget: 'https://api.myetherwallet.com/eth', + ticker: 'ETH', + type: 'rinkeby', + }, + }, + PreferencesController: { + frequentRpcListDetail: [ + {chainId: 'fail', nickname: '', rpcUrl: 'http://127.0.0.1:8545', ticker: ''}, + {chainId: '1', nickname: '', rpcUrl: 'https://api.myetherwallet.com/eth', ticker: 'ETH'}, + ], + }, + }, +} + +describe('storage is migrated successfully', () => { + it('should work', (done) => { + migrationTemplate.migrate(storage) + .then((migratedData) => { + assert.equal(migratedData.meta.version, 30) + assert.equal(migratedData.data.PreferencesController.frequentRpcListDetail[0].chainId, undefined) + assert.equal(migratedData.data.PreferencesController.frequentRpcListDetail[1].chainId, '1') + assert.equal(migratedData.data.NetworkController.provider.chainId, undefined) + assert.equal(migratedData.data.NetworkController.network, undefined) + done() + }).catch(done) + }) +}) diff --git a/ui/app/components/pages/settings/settings-tab/settings-tab.component.js b/ui/app/components/pages/settings/settings-tab/settings-tab.component.js index eee472a00e94..16afa85cbe99 100644 --- a/ui/app/components/pages/settings/settings-tab/settings-tab.component.js +++ b/ui/app/components/pages/settings/settings-tab/settings-tab.component.js @@ -232,6 +232,9 @@ export default class SettingsTab extends PureComponent { const { setRpcTarget, displayWarning } = this.props if (validUrl.isWebUri(newRpc)) { + if (!!chainId && Number.isNaN(parseInt(chainId))) { + return displayWarning(`${this.context.t('invalidInput')} chainId`) + } setRpcTarget(newRpc, chainId, ticker, nickname) } else { const appendedRpc = `http://${newRpc}`