From b7f8657ab5c01c70eff3e19afd334f07b6415c34 Mon Sep 17 00:00:00 2001 From: Kevin Serrano Date: Thu, 22 Jun 2017 12:32:08 -0700 Subject: [PATCH 1/5] Add infura network status to our UI state. --- app/scripts/controllers/infura.js | 42 ++++++++++++++++++++++++++++++ app/scripts/metamask-controller.js | 15 ++++++++++- 2 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 app/scripts/controllers/infura.js diff --git a/app/scripts/controllers/infura.js b/app/scripts/controllers/infura.js new file mode 100644 index 000000000..e0dad0bc1 --- /dev/null +++ b/app/scripts/controllers/infura.js @@ -0,0 +1,42 @@ +const ObservableStore = require('obs-store') +const extend = require('xtend') + +// every ten minutes +const POLLING_INTERVAL = 300000 + +class InfuraController { + + constructor (opts = {}) { + const initState = extend({ + infuraNetworkStatus: {}, + }, opts.initState) + this.store = new ObservableStore(initState) + } + + // + // PUBLIC METHODS + // + + // Responsible for retrieving the status of Infura's nodes. Can return either + // ok, degraded, or down. + checkInfuraNetworkStatus () { + return fetch('https://api.infura.io/v1/status/metamask') + .then(response => response.json()) + .then((parsedResponse) => { + this.store.updateState({ + infuraNetworkStatus: parsedResponse, + }) + }) + } + + scheduleInfuraNetworkCheck() { + if (this.conversionInterval) { + clearInterval(this.conversionInterval) + } + this.conversionInterval = setInterval(() => { + this.checkInfuraNetworkStatus() + }, POLLING_INTERVAL) + } +} + +module.exports = InfuraController diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index de9a15924..05ba7ecea 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -15,6 +15,7 @@ const CurrencyController = require('./controllers/currency') const NoticeController = require('./notice-controller') const ShapeShiftController = require('./controllers/shapeshift') const AddressBookController = require('./controllers/address-book') +const InfuraController = require('./controllers/infura') const MessageManager = require('./lib/message-manager') const PersonalMessageManager = require('./lib/personal-message-manager') const TransactionController = require('./controllers/transactions') @@ -44,8 +45,8 @@ module.exports = class MetamaskController extends EventEmitter { this.store = new ObservableStore(initState) // network store - this.networkController = new NetworkController(initState.NetworkController) + // config manager this.configManager = new ConfigManager({ store: this.store, @@ -63,6 +64,13 @@ module.exports = class MetamaskController extends EventEmitter { this.currencyController.updateConversionRate() this.currencyController.scheduleConversionInterval() + // infura controller + this.infuraController = new InfuraController({ + initState: initState.InfuraController, + }) + this.infuraController.scheduleInfuraNetworkCheck() + + // rpc provider this.provider = this.initializeProvider() @@ -147,6 +155,9 @@ module.exports = class MetamaskController extends EventEmitter { this.networkController.store.subscribe((state) => { this.store.updateState({ NetworkController: state }) }) + this.infuraController.store.subscribe((state) => { + this.store.updateState({ InfuraController: state }) + }) // manual mem state subscriptions this.networkController.store.subscribe(this.sendUpdate.bind(this)) @@ -160,6 +171,7 @@ module.exports = class MetamaskController extends EventEmitter { this.currencyController.store.subscribe(this.sendUpdate.bind(this)) this.noticeController.memStore.subscribe(this.sendUpdate.bind(this)) this.shapeshiftController.store.subscribe(this.sendUpdate.bind(this)) + this.infuraController.store.subscribe(this.sendUpdate.bind(this)) } // @@ -237,6 +249,7 @@ module.exports = class MetamaskController extends EventEmitter { this.addressBookController.store.getState(), this.currencyController.store.getState(), this.noticeController.memStore.getState(), + this.infuraController.store.getState(), // config manager this.configManager.getConfig(), this.shapeshiftController.store.getState(), From f9f0f6f9ef3ec2f4e311316e3dd7339e21482f40 Mon Sep 17 00:00:00 2001 From: Kevin Serrano Date: Thu, 22 Jun 2017 12:32:34 -0700 Subject: [PATCH 2/5] Add infura network status to our UI state. --- app/scripts/controllers/infura.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/scripts/controllers/infura.js b/app/scripts/controllers/infura.js index e0dad0bc1..98375b446 100644 --- a/app/scripts/controllers/infura.js +++ b/app/scripts/controllers/infura.js @@ -29,7 +29,7 @@ class InfuraController { }) } - scheduleInfuraNetworkCheck() { + scheduleInfuraNetworkCheck () { if (this.conversionInterval) { clearInterval(this.conversionInterval) } From 199663c0a46990ef08e3e1c0faf692f868f0bc6d Mon Sep 17 00:00:00 2001 From: Kevin Serrano Date: Thu, 22 Jun 2017 12:51:53 -0700 Subject: [PATCH 3/5] Add test for infura controller. --- test/unit/infura-controller-test.js | 34 +++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 test/unit/infura-controller-test.js diff --git a/test/unit/infura-controller-test.js b/test/unit/infura-controller-test.js new file mode 100644 index 000000000..0665c498e --- /dev/null +++ b/test/unit/infura-controller-test.js @@ -0,0 +1,34 @@ +// polyfill fetch +global.fetch = global.fetch || require('isomorphic-fetch') + +const assert = require('assert') +const nock = require('nock') +const InfuraController = require('../../app/scripts/controllers/infura') + +describe('infura-controller', function () { + var infuraController + + beforeEach(function () { + infuraController = new InfuraController() + }) + + describe('network status queries', function () { + describe('#checkInfuraNetworkStatus', function () { + it('should return an object reflecting the network statuses', function () { + this.timeout(15000) + nock('https://api.infura.io') + .get('/v1/status/metamask') + .reply(200, '{"mainnet": "ok", "ropsten": "degraded", "kovan": "down", "rinkeby": "ok"}') + + infuraController.checkInfuraNetworkStatus() + .then(() => { + const networkStatus = infuraController.store.getState().infuraNetworkStatus + assert.equal(Object.keys(networkStatus).length, 4) + assert.equal(networkStatus.mainnet, 'ok') + assert.equal(networkStatus.ropsten, 'degraded') + assert.equal(networkStatus.kovan, 'down') + }) + }) + }) + }) +}) From 1ddcbaad5bdd554d9711a9a7cdb29e71703325f3 Mon Sep 17 00:00:00 2001 From: frankiebee Date: Thu, 22 Jun 2017 13:46:08 -0700 Subject: [PATCH 4/5] add `done` and stub fetch --- test/unit/infura-controller-test.js | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/test/unit/infura-controller-test.js b/test/unit/infura-controller-test.js index 0665c498e..75bd031ff 100644 --- a/test/unit/infura-controller-test.js +++ b/test/unit/infura-controller-test.js @@ -1,8 +1,9 @@ // polyfill fetch -global.fetch = global.fetch || require('isomorphic-fetch') - +global.fetch = global.fetch || function () {return Promise.resolve({ + json: () => { return Promise.resolve({"mainnet": "ok", "ropsten": "degraded", "kovan": "down", "rinkeby": "ok"}) }, + }) +} const assert = require('assert') -const nock = require('nock') const InfuraController = require('../../app/scripts/controllers/infura') describe('infura-controller', function () { @@ -14,20 +15,20 @@ describe('infura-controller', function () { describe('network status queries', function () { describe('#checkInfuraNetworkStatus', function () { - it('should return an object reflecting the network statuses', function () { + it('should return an object reflecting the network statuses', function (done) { this.timeout(15000) - nock('https://api.infura.io') - .get('/v1/status/metamask') - .reply(200, '{"mainnet": "ok", "ropsten": "degraded", "kovan": "down", "rinkeby": "ok"}') - infuraController.checkInfuraNetworkStatus() .then(() => { const networkStatus = infuraController.store.getState().infuraNetworkStatus + const networkStatus2 = infuraController.store.getState() assert.equal(Object.keys(networkStatus).length, 4) assert.equal(networkStatus.mainnet, 'ok') assert.equal(networkStatus.ropsten, 'degraded') assert.equal(networkStatus.kovan, 'down') }) + .then(() => done()) + .catch(done) + }) }) }) From 42a2bcb1325bd5763a6402d5c2d6634053da908b Mon Sep 17 00:00:00 2001 From: frankiebee Date: Thu, 22 Jun 2017 13:58:55 -0700 Subject: [PATCH 5/5] remove option fetch --- test/unit/infura-controller-test.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/unit/infura-controller-test.js b/test/unit/infura-controller-test.js index 75bd031ff..7a2a114f9 100644 --- a/test/unit/infura-controller-test.js +++ b/test/unit/infura-controller-test.js @@ -1,5 +1,5 @@ // polyfill fetch -global.fetch = global.fetch || function () {return Promise.resolve({ +global.fetch = function () {return Promise.resolve({ json: () => { return Promise.resolve({"mainnet": "ok", "ropsten": "degraded", "kovan": "down", "rinkeby": "ok"}) }, }) } @@ -20,7 +20,6 @@ describe('infura-controller', function () { infuraController.checkInfuraNetworkStatus() .then(() => { const networkStatus = infuraController.store.getState().infuraNetworkStatus - const networkStatus2 = infuraController.store.getState() assert.equal(Object.keys(networkStatus).length, 4) assert.equal(networkStatus.mainnet, 'ok') assert.equal(networkStatus.ropsten, 'degraded')