mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-22 17:33:23 +01:00
migration #9 - break out CurrencyController substate
This commit is contained in:
parent
b233e7e37c
commit
9e4ef45b6a
@ -250,53 +250,6 @@ ConfigManager.prototype.getTOSHash = function () {
|
||||
return data.TOSHash
|
||||
}
|
||||
|
||||
ConfigManager.prototype.setCurrentFiat = function (currency) {
|
||||
var data = this.getData()
|
||||
data.fiatCurrency = currency
|
||||
this.setData(data)
|
||||
}
|
||||
|
||||
ConfigManager.prototype.getCurrentFiat = function () {
|
||||
var data = this.getData()
|
||||
return data.fiatCurrency || 'USD'
|
||||
}
|
||||
|
||||
ConfigManager.prototype.updateConversionRate = function () {
|
||||
var data = this.getData()
|
||||
return fetch(`https://www.cryptonator.com/api/ticker/eth-${data.fiatCurrency}`)
|
||||
.then(response => response.json())
|
||||
.then((parsedResponse) => {
|
||||
this.setConversionPrice(parsedResponse.ticker.price)
|
||||
this.setConversionDate(parsedResponse.timestamp)
|
||||
}).catch((err) => {
|
||||
console.warn('MetaMask - Failed to query currency conversion.')
|
||||
this.setConversionPrice(0)
|
||||
this.setConversionDate('N/A')
|
||||
})
|
||||
}
|
||||
|
||||
ConfigManager.prototype.setConversionPrice = function (price) {
|
||||
var data = this.getData()
|
||||
data.conversionRate = Number(price)
|
||||
this.setData(data)
|
||||
}
|
||||
|
||||
ConfigManager.prototype.setConversionDate = function (datestring) {
|
||||
var data = this.getData()
|
||||
data.conversionDate = datestring
|
||||
this.setData(data)
|
||||
}
|
||||
|
||||
ConfigManager.prototype.getConversionRate = function () {
|
||||
var data = this.getData()
|
||||
return (data.conversionRate) || 0
|
||||
}
|
||||
|
||||
ConfigManager.prototype.getConversionDate = function () {
|
||||
var data = this.getData()
|
||||
return (data.conversionDate) || 'N/A'
|
||||
}
|
||||
|
||||
ConfigManager.prototype.getShapeShiftTxList = function () {
|
||||
var data = this.getData()
|
||||
var shapeShiftTxList = data.shapeShiftTxList ? data.shapeShiftTxList : []
|
||||
|
70
app/scripts/lib/controllers/currency.js
Normal file
70
app/scripts/lib/controllers/currency.js
Normal file
@ -0,0 +1,70 @@
|
||||
const ObservableStore = require('obs-store')
|
||||
const extend = require('xtend')
|
||||
|
||||
// every ten minutes
|
||||
const POLLING_INTERVAL = 600000
|
||||
|
||||
class CurrencyController {
|
||||
|
||||
constructor (opts = {}) {
|
||||
const initState = extend({
|
||||
currentCurrency: 'USD',
|
||||
conversionRate: 0,
|
||||
conversionDate: 'N/A',
|
||||
}, opts.initState)
|
||||
this.store = new ObservableStore(initState)
|
||||
}
|
||||
|
||||
//
|
||||
// PUBLIC METHODS
|
||||
//
|
||||
|
||||
getCurrentCurrency () {
|
||||
return this.store.getState().currentCurrency
|
||||
}
|
||||
|
||||
setCurrentCurrency (currentCurrency) {
|
||||
this.store.updateState({ currentCurrency })
|
||||
}
|
||||
|
||||
getConversionRate () {
|
||||
return this.store.getState().conversionRate
|
||||
}
|
||||
|
||||
setConversionRate (conversionRate) {
|
||||
this.store.updateState({ conversionRate })
|
||||
}
|
||||
|
||||
getConversionDate () {
|
||||
return this.store.getState().conversionDate
|
||||
}
|
||||
|
||||
setConversionDate (conversionDate) {
|
||||
this.store.updateState({ conversionDate })
|
||||
}
|
||||
|
||||
updateConversionRate () {
|
||||
const currentCurrency = this.getCurrentCurrency()
|
||||
return fetch(`https://www.cryptonator.com/api/ticker/eth-${currentCurrency}`)
|
||||
.then(response => response.json())
|
||||
.then((parsedResponse) => {
|
||||
this.setConversionRate(Number(parsedResponse.ticker.price))
|
||||
this.setConversionDate(Number(parsedResponse.timestamp))
|
||||
}).catch((err) => {
|
||||
console.warn('MetaMask - Failed to query currency conversion.')
|
||||
this.setConversionRate(0)
|
||||
this.setConversionDate('N/A')
|
||||
})
|
||||
}
|
||||
|
||||
scheduleConversionInterval () {
|
||||
if (this.conversionInterval) {
|
||||
clearInterval(this.conversionInterval)
|
||||
}
|
||||
this.conversionInterval = setInterval(() => {
|
||||
this.updateConversionRate()
|
||||
}, POLLING_INTERVAL)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = CurrencyController
|
@ -97,9 +97,6 @@ IdentityStore.prototype.getState = function () {
|
||||
isDisclaimerConfirmed: configManager.getConfirmedDisclaimer(),
|
||||
selectedAddress: configManager.getSelectedAccount(),
|
||||
shapeShiftTxList: configManager.getShapeShiftTxList(),
|
||||
currentFiat: configManager.getCurrentFiat(),
|
||||
conversionRate: configManager.getConversionRate(),
|
||||
conversionDate: configManager.getConversionDate(),
|
||||
gasMultiplier: configManager.getGasMultiplier(),
|
||||
}))
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ const MetaMaskProvider = require('web3-provider-engine/zero.js')
|
||||
const setupMultiplex = require('./lib/stream-utils.js').setupMultiplex
|
||||
const KeyringController = require('./keyring-controller')
|
||||
const PreferencesController = require('./lib/controllers/preferences')
|
||||
const CurrencyController = require('./lib/controllers/currency')
|
||||
const NoticeController = require('./notice-controller')
|
||||
const MessageManager = require('./lib/message-manager')
|
||||
const TxManager = require('./transaction-manager')
|
||||
@ -41,13 +42,19 @@ module.exports = class MetamaskController extends EventEmitter {
|
||||
this.configManager = new ConfigManager({
|
||||
store: this.store,
|
||||
})
|
||||
this.configManager.updateConversionRate()
|
||||
|
||||
// preferences controller
|
||||
this.preferencesController = new PreferencesController({
|
||||
initState: initState.PreferencesController,
|
||||
})
|
||||
|
||||
// currency controller
|
||||
this.currencyController = new CurrencyController({
|
||||
initState: initState.CurrencyController,
|
||||
})
|
||||
this.currencyController.updateConversionRate()
|
||||
this.currencyController.scheduleConversionInterval()
|
||||
|
||||
// rpc provider
|
||||
this.provider = this.initializeProvider(opts)
|
||||
this.provider.on('block', this.logBlock.bind(this))
|
||||
@ -97,8 +104,6 @@ module.exports = class MetamaskController extends EventEmitter {
|
||||
|
||||
this.checkTOSChange()
|
||||
|
||||
this.scheduleConversionInterval()
|
||||
|
||||
// TEMPORARY UNTIL FULL DEPRECATION:
|
||||
this.idStoreMigrator = new IdStoreMigrator({
|
||||
configManager: this.configManager,
|
||||
@ -114,11 +119,15 @@ module.exports = class MetamaskController extends EventEmitter {
|
||||
this.txManager.store.subscribe((state) => {
|
||||
this.store.updateState({ TransactionManager: state })
|
||||
})
|
||||
this.currencyController.store.subscribe((state) => {
|
||||
this.store.updateState({ CurrencyController: state })
|
||||
})
|
||||
|
||||
// manual mem state subscriptions
|
||||
this.ethStore.subscribe(this.sendUpdate.bind(this))
|
||||
this.networkStore.subscribe(this.sendUpdate.bind(this))
|
||||
this.keyringController.memStore.subscribe(this.sendUpdate.bind(this))
|
||||
this.currencyController.store.subscribe(this.sendUpdate.bind(this))
|
||||
this.txManager.memStore.subscribe(this.sendUpdate.bind(this))
|
||||
this.messageManager.memStore.subscribe(this.sendUpdate.bind(this))
|
||||
}
|
||||
@ -189,15 +198,13 @@ module.exports = class MetamaskController extends EventEmitter {
|
||||
this.messageManager.memStore.getState(),
|
||||
this.keyringController.memStore.getState(),
|
||||
this.preferencesController.store.getState(),
|
||||
this.currencyController.store.getState(),
|
||||
this.noticeController.memStore.getState(),
|
||||
// config manager
|
||||
this.configManager.getConfig(),
|
||||
{
|
||||
shapeShiftTxList: this.configManager.getShapeShiftTxList(),
|
||||
lostAccounts: this.configManager.getLostAccounts(),
|
||||
currentFiat: this.configManager.getCurrentFiat(),
|
||||
conversionRate: this.configManager.getConversionRate(),
|
||||
conversionDate: this.configManager.getConversionDate(),
|
||||
isDisclaimerConfirmed: this.configManager.getConfirmedDisclaimer(),
|
||||
seedWords: this.configManager.getSeedWords(),
|
||||
}
|
||||
@ -223,7 +230,7 @@ module.exports = class MetamaskController extends EventEmitter {
|
||||
useEtherscanProvider: this.useEtherscanProvider.bind(this),
|
||||
agreeToDisclaimer: this.agreeToDisclaimer.bind(this),
|
||||
resetDisclaimer: this.resetDisclaimer.bind(this),
|
||||
setCurrentFiat: this.setCurrentFiat.bind(this),
|
||||
setCurrentCurrency: this.setCurrentCurrency.bind(this),
|
||||
setTOSHash: this.setTOSHash.bind(this),
|
||||
checkTOSChange: this.checkTOSChange.bind(this),
|
||||
setGasMultiplier: this.setGasMultiplier.bind(this),
|
||||
@ -550,31 +557,21 @@ module.exports = class MetamaskController extends EventEmitter {
|
||||
this.verifyNetwork()
|
||||
}
|
||||
|
||||
setCurrentFiat (fiat, cb) {
|
||||
setCurrentCurrency (currencyCode, cb) {
|
||||
try {
|
||||
this.configManager.setCurrentFiat(fiat)
|
||||
this.configManager.updateConversionRate()
|
||||
this.scheduleConversionInterval()
|
||||
this.currencyController.setCurrentCurrency(currencyCode)
|
||||
this.currencyController.updateConversionRate()
|
||||
const data = {
|
||||
conversionRate: this.configManager.getConversionRate(),
|
||||
currentFiat: this.configManager.getCurrentFiat(),
|
||||
conversionDate: this.configManager.getConversionDate(),
|
||||
conversionRate: this.currencyController.getConversionRate(),
|
||||
currentFiat: this.currencyController.getCurrentCurrency(),
|
||||
conversionDate: this.currencyController.getConversionDate(),
|
||||
}
|
||||
cb(data)
|
||||
cb(null, data)
|
||||
} catch (err) {
|
||||
cb(null, err)
|
||||
cb(err)
|
||||
}
|
||||
}
|
||||
|
||||
scheduleConversionInterval () {
|
||||
if (this.conversionInterval) {
|
||||
clearInterval(this.conversionInterval)
|
||||
}
|
||||
this.conversionInterval = setInterval(() => {
|
||||
this.configManager.updateConversionRate()
|
||||
}, 300000)
|
||||
}
|
||||
|
||||
buyEth (address, amount) {
|
||||
if (!amount) amount = '5'
|
||||
|
||||
|
40
app/scripts/migrations/009.js
Normal file
40
app/scripts/migrations/009.js
Normal file
@ -0,0 +1,40 @@
|
||||
const version = 9
|
||||
|
||||
/*
|
||||
|
||||
This migration breaks out the CurrencyController substate
|
||||
|
||||
*/
|
||||
|
||||
const merge = require('deep-merge')
|
||||
|
||||
module.exports = {
|
||||
version,
|
||||
|
||||
migrate: function (versionedData) {
|
||||
versionedData.meta.version = version
|
||||
try {
|
||||
const state = versionedData.data
|
||||
const newState = transformState(state)
|
||||
versionedData.data = newState
|
||||
} catch (err) {
|
||||
console.warn(`MetaMask Migration #${version}` + err.stack)
|
||||
}
|
||||
return Promise.resolve(versionedData)
|
||||
},
|
||||
}
|
||||
|
||||
function transformState (state) {
|
||||
const newState = merge(state, {
|
||||
CurrencyController: {
|
||||
currentCurrency: state.currentFiat || 'USD',
|
||||
conversionRate: state.conversionRate,
|
||||
conversionDate: state.conversionDate,
|
||||
},
|
||||
})
|
||||
delete newState.currentFiat
|
||||
delete newState.conversionRate
|
||||
delete newState.conversionDate
|
||||
|
||||
return newState
|
||||
}
|
@ -19,4 +19,5 @@ module.exports = [
|
||||
require('./006'),
|
||||
require('./007'),
|
||||
require('./008'),
|
||||
require('./009'),
|
||||
]
|
||||
|
@ -45,6 +45,7 @@
|
||||
"clone": "^1.0.2",
|
||||
"copy-to-clipboard": "^2.0.0",
|
||||
"debounce": "^1.0.0",
|
||||
"deep-merge": "^1.0.0",
|
||||
"denodeify": "^1.2.1",
|
||||
"disc": "^1.3.2",
|
||||
"dnode": "^1.2.2",
|
||||
|
@ -14,81 +14,6 @@ describe('config-manager', function() {
|
||||
configManager = configManagerGen()
|
||||
})
|
||||
|
||||
describe('currency conversions', function() {
|
||||
|
||||
describe('#setCurrentFiat', function() {
|
||||
it('should return USD as default', function() {
|
||||
assert.equal(configManager.getCurrentFiat(), 'USD')
|
||||
})
|
||||
|
||||
it('should be able to set to other currency', function() {
|
||||
assert.equal(configManager.getCurrentFiat(), 'USD')
|
||||
configManager.setCurrentFiat('JPY')
|
||||
var result = configManager.getCurrentFiat()
|
||||
assert.equal(result, 'JPY')
|
||||
})
|
||||
})
|
||||
|
||||
describe('#getConversionRate', function() {
|
||||
it('should return undefined if non-existent', function() {
|
||||
var result = configManager.getConversionRate()
|
||||
assert.ok(!result)
|
||||
})
|
||||
})
|
||||
|
||||
describe('#updateConversionRate', function() {
|
||||
it('should retrieve an update for ETH to USD and set it in memory', function(done) {
|
||||
this.timeout(15000)
|
||||
var usdMock = nock('https://www.cryptonator.com')
|
||||
.get('/api/ticker/eth-USD')
|
||||
.reply(200, '{"ticker":{"base":"ETH","target":"USD","price":"11.02456145","volume":"44948.91745289","change":"-0.01472534"},"timestamp":1472072136,"success":true,"error":""}')
|
||||
|
||||
assert.equal(configManager.getConversionRate(), 0)
|
||||
var promise = new Promise(
|
||||
function (resolve, reject) {
|
||||
configManager.setCurrentFiat('USD')
|
||||
configManager.updateConversionRate().then(function() {
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
|
||||
promise.then(function() {
|
||||
var result = configManager.getConversionRate()
|
||||
assert.equal(typeof result, 'number')
|
||||
done()
|
||||
}).catch(function(err) {
|
||||
console.log(err)
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
it('should work for JPY as well.', function() {
|
||||
this.timeout(15000)
|
||||
assert.equal(configManager.getConversionRate(), 0)
|
||||
|
||||
var jpyMock = nock('https://www.cryptonator.com')
|
||||
.get('/api/ticker/eth-JPY')
|
||||
.reply(200, '{"ticker":{"base":"ETH","target":"JPY","price":"11.02456145","volume":"44948.91745289","change":"-0.01472534"},"timestamp":1472072136,"success":true,"error":""}')
|
||||
|
||||
|
||||
var promise = new Promise(
|
||||
function (resolve, reject) {
|
||||
configManager.setCurrentFiat('JPY')
|
||||
configManager.updateConversionRate().then(function() {
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
|
||||
promise.then(function() {
|
||||
var result = configManager.getConversionRate()
|
||||
assert.equal(typeof result, 'number')
|
||||
}).catch(function(err) {
|
||||
console.log(err)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('confirmation', function() {
|
||||
|
||||
describe('#getConfirmedDisclaimer', function() {
|
||||
|
87
test/unit/currency-controller-test.js
Normal file
87
test/unit/currency-controller-test.js
Normal file
@ -0,0 +1,87 @@
|
||||
// polyfill fetch
|
||||
global.fetch = global.fetch || require('isomorphic-fetch')
|
||||
|
||||
const assert = require('assert')
|
||||
const extend = require('xtend')
|
||||
const rp = require('request-promise')
|
||||
const nock = require('nock')
|
||||
const CurrencyController = require('../../app/scripts/lib/controllers/currency')
|
||||
|
||||
describe('config-manager', function() {
|
||||
var currencyController
|
||||
|
||||
beforeEach(function() {
|
||||
currencyController = new CurrencyController()
|
||||
})
|
||||
|
||||
describe('currency conversions', function() {
|
||||
|
||||
describe('#setCurrentCurrency', function() {
|
||||
it('should return USD as default', function() {
|
||||
assert.equal(currencyController.getCurrentCurrency(), 'USD')
|
||||
})
|
||||
|
||||
it('should be able to set to other currency', function() {
|
||||
assert.equal(currencyController.getCurrentCurrency(), 'USD')
|
||||
currencyController.setCurrentCurrency('JPY')
|
||||
var result = currencyController.getCurrentCurrency()
|
||||
assert.equal(result, 'JPY')
|
||||
})
|
||||
})
|
||||
|
||||
describe('#getConversionRate', function() {
|
||||
it('should return undefined if non-existent', function() {
|
||||
var result = currencyController.getConversionRate()
|
||||
assert.ok(!result)
|
||||
})
|
||||
})
|
||||
|
||||
describe('#updateConversionRate', function() {
|
||||
it('should retrieve an update for ETH to USD and set it in memory', function(done) {
|
||||
this.timeout(15000)
|
||||
var usdMock = nock('https://www.cryptonator.com')
|
||||
.get('/api/ticker/eth-USD')
|
||||
.reply(200, '{"ticker":{"base":"ETH","target":"USD","price":"11.02456145","volume":"44948.91745289","change":"-0.01472534"},"timestamp":1472072136,"success":true,"error":""}')
|
||||
|
||||
assert.equal(currencyController.getConversionRate(), 0)
|
||||
currencyController.setCurrentCurrency('USD')
|
||||
currencyController.updateConversionRate()
|
||||
.then(function() {
|
||||
var result = currencyController.getConversionRate()
|
||||
console.log('currencyController.getConversionRate:', result)
|
||||
assert.equal(typeof result, 'number')
|
||||
done()
|
||||
}).catch(function(err) {
|
||||
done(err)
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
it('should work for JPY as well.', function() {
|
||||
this.timeout(15000)
|
||||
assert.equal(currencyController.getConversionRate(), 0)
|
||||
|
||||
var jpyMock = nock('https://www.cryptonator.com')
|
||||
.get('/api/ticker/eth-JPY')
|
||||
.reply(200, '{"ticker":{"base":"ETH","target":"JPY","price":"11.02456145","volume":"44948.91745289","change":"-0.01472534"},"timestamp":1472072136,"success":true,"error":""}')
|
||||
|
||||
|
||||
var promise = new Promise(
|
||||
function (resolve, reject) {
|
||||
currencyController.setCurrentCurrency('JPY')
|
||||
currencyController.updateConversionRate().then(function() {
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
|
||||
promise.then(function() {
|
||||
var result = currencyController.getConversionRate()
|
||||
assert.equal(typeof result, 'number')
|
||||
}).catch(function(err) {
|
||||
done(err)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
})
|
@ -325,12 +325,16 @@ function showInfoPage () {
|
||||
}
|
||||
}
|
||||
|
||||
function setCurrentFiat (fiat) {
|
||||
function setCurrentFiat (currencyCode) {
|
||||
return (dispatch) => {
|
||||
dispatch(this.showLoadingIndication())
|
||||
if (global.METAMASK_DEBUG) console.log(`background.setCurrentFiat`)
|
||||
background.setCurrentFiat(fiat, (data, err) => {
|
||||
background.setCurrentCurrency(currencyCode, (err, data) => {
|
||||
dispatch(this.hideLoadingIndication())
|
||||
if (err) {
|
||||
console.error(err.stack)
|
||||
return dispatch(actions.displayWarning(err.message))
|
||||
}
|
||||
dispatch({
|
||||
type: this.SET_CURRENT_FIAT,
|
||||
value: {
|
||||
|
Loading…
Reference in New Issue
Block a user