1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-12-23 09:52:26 +01:00

obs-store - use published module

This commit is contained in:
kumavis 2017-01-24 19:47:00 -08:00
parent a06ee45404
commit 76ce348a04
16 changed files with 112 additions and 326 deletions

View File

@ -2,10 +2,11 @@ const urlUtil = require('url')
const Dnode = require('dnode') const Dnode = require('dnode')
const eos = require('end-of-stream') const eos = require('end-of-stream')
const asyncQ = require('async-q') const asyncQ = require('async-q')
const pipe = require('pump')
const LocalStorageStore = require('obs-store/lib/localStorage')
const storeTransform = require('obs-store/lib/transform')
const Migrator = require('./lib/migrator/') const Migrator = require('./lib/migrator/')
const migrations = require('./lib/migrations/') const migrations = require('./migrations/')
const LocalStorageStore = require('./lib/observable/local-storage')
const synchronizeStore = require('./lib/observable/util/sync')
const PortStream = require('./lib/port-stream.js') const PortStream = require('./lib/port-stream.js')
const notification = require('./lib/notifications.js') const notification = require('./lib/notifications.js')
const messageManager = require('./lib/message-manager') const messageManager = require('./lib/message-manager')
@ -40,12 +41,12 @@ function loadStateFromPersistence() {
let initialState = migrator.generateInitialState(firstTimeState) let initialState = migrator.generateInitialState(firstTimeState)
return asyncQ.waterfall([ return asyncQ.waterfall([
// read from disk // read from disk
() => Promise.resolve(diskStore.get() || initialState), () => Promise.resolve(diskStore.getState() || initialState),
// migrate data // migrate data
(versionedData) => migrator.migrateData(versionedData), (versionedData) => migrator.migrateData(versionedData),
// write to disk // write to disk
(versionedData) => { (versionedData) => {
diskStore.put(versionedData) diskStore.putState(versionedData)
return Promise.resolve(versionedData) return Promise.resolve(versionedData)
}, },
// resolve to just data // resolve to just data
@ -70,11 +71,17 @@ function setupController (initState) {
global.metamaskController = controller global.metamaskController = controller
// setup state persistence // setup state persistence
synchronizeStore(controller.store, diskStore, (state) => { pipe(
let versionedData = diskStore.get() controller.store,
storeTransform(versionifyData),
diskStore
)
function versionifyData(state) {
let versionedData = diskStore.getState()
versionedData.data = state versionedData.data = state
return versionedData return versionedData
}) }
// //
// connect to other contexts // connect to other contexts

View File

@ -21,14 +21,14 @@ function ConfigManager (opts) {
} }
ConfigManager.prototype.setConfig = function (config) { ConfigManager.prototype.setConfig = function (config) {
var data = this.store.get() var data = this.getData()
data.config = config data.config = config
this.setData(data) this.setData(data)
this._emitUpdates(config) this._emitUpdates(config)
} }
ConfigManager.prototype.getConfig = function () { ConfigManager.prototype.getConfig = function () {
var data = this.store.get() var data = this.getData()
if ('config' in data) { if ('config' in data) {
return data.config return data.config
} else { } else {
@ -71,15 +71,15 @@ ConfigManager.prototype.getProvider = function () {
} }
ConfigManager.prototype.setData = function (data) { ConfigManager.prototype.setData = function (data) {
this.store.put(data) this.store.putState(data)
} }
ConfigManager.prototype.getData = function () { ConfigManager.prototype.getData = function () {
return this.store.get() return this.store.getState()
} }
ConfigManager.prototype.setWallet = function (wallet) { ConfigManager.prototype.setWallet = function (wallet) {
var data = this.store.get() var data = this.getData()
data.wallet = wallet data.wallet = wallet
this.setData(data) this.setData(data)
} }
@ -96,11 +96,11 @@ ConfigManager.prototype.getVault = function () {
} }
ConfigManager.prototype.getKeychains = function () { ConfigManager.prototype.getKeychains = function () {
return this.store.get().keychains || [] return this.getData().keychains || []
} }
ConfigManager.prototype.setKeychains = function (keychains) { ConfigManager.prototype.setKeychains = function (keychains) {
var data = this.store.get() var data = this.getData()
data.keychains = keychains data.keychains = keychains
this.setData(data) this.setData(data)
} }
@ -117,19 +117,19 @@ ConfigManager.prototype.setSelectedAccount = function (address) {
} }
ConfigManager.prototype.getWallet = function () { ConfigManager.prototype.getWallet = function () {
return this.store.get().wallet return this.getData().wallet
} }
// Takes a boolean // Takes a boolean
ConfigManager.prototype.setShowSeedWords = function (should) { ConfigManager.prototype.setShowSeedWords = function (should) {
var data = this.store.get() var data = this.getData()
data.showSeedWords = should data.showSeedWords = should
this.setData(data) this.setData(data)
} }
ConfigManager.prototype.getShouldShowSeedWords = function () { ConfigManager.prototype.getShouldShowSeedWords = function () {
var data = this.store.get() var data = this.getData()
return data.showSeedWords return data.showSeedWords
} }
@ -141,7 +141,7 @@ ConfigManager.prototype.setSeedWords = function (words) {
ConfigManager.prototype.getSeedWords = function () { ConfigManager.prototype.getSeedWords = function () {
var data = this.getData() var data = this.getData()
return ('seedWords' in data) && data.seedWords return data.seedWords
} }
ConfigManager.prototype.getCurrentRpcAddress = function () { ConfigManager.prototype.getCurrentRpcAddress = function () {
@ -163,16 +163,12 @@ ConfigManager.prototype.getCurrentRpcAddress = function () {
} }
} }
ConfigManager.prototype.setData = function (data) {
this.store.put(data)
}
// //
// Tx // Tx
// //
ConfigManager.prototype.getTxList = function () { ConfigManager.prototype.getTxList = function () {
var data = this.store.get() var data = this.getData()
if (data.transactions !== undefined) { if (data.transactions !== undefined) {
return data.transactions return data.transactions
} else { } else {
@ -181,7 +177,7 @@ ConfigManager.prototype.getTxList = function () {
} }
ConfigManager.prototype.setTxList = function (txList) { ConfigManager.prototype.setTxList = function (txList) {
var data = this.store.get() var data = this.getData()
data.transactions = txList data.transactions = txList
this.setData(data) this.setData(data)
} }
@ -214,7 +210,7 @@ ConfigManager.prototype.setNicknameForWallet = function (account, nickname) {
ConfigManager.prototype.getSalt = function () { ConfigManager.prototype.getSalt = function () {
var data = this.getData() var data = this.getData()
return ('salt' in data) && data.salt return data.salt
} }
ConfigManager.prototype.setSalt = function (salt) { ConfigManager.prototype.setSalt = function (salt) {
@ -248,7 +244,7 @@ ConfigManager.prototype.setConfirmedDisclaimer = function (confirmed) {
ConfigManager.prototype.getConfirmedDisclaimer = function () { ConfigManager.prototype.getConfirmedDisclaimer = function () {
var data = this.getData() var data = this.getData()
return ('isDisclaimerConfirmed' in data) && data.isDisclaimerConfirmed return data.isDisclaimerConfirmed
} }
ConfigManager.prototype.setTOSHash = function (hash) { ConfigManager.prototype.setTOSHash = function (hash) {
@ -259,7 +255,7 @@ ConfigManager.prototype.setTOSHash = function (hash) {
ConfigManager.prototype.getTOSHash = function () { ConfigManager.prototype.getTOSHash = function () {
var data = this.getData() var data = this.getData()
return ('TOSHash' in data) && data.TOSHash return data.TOSHash
} }
ConfigManager.prototype.setCurrentFiat = function (currency) { ConfigManager.prototype.setCurrentFiat = function (currency) {
@ -270,7 +266,7 @@ ConfigManager.prototype.setCurrentFiat = function (currency) {
ConfigManager.prototype.getCurrentFiat = function () { ConfigManager.prototype.getCurrentFiat = function () {
var data = this.getData() var data = this.getData()
return ('fiatCurrency' in data) && data.fiatCurrency return data.fiatCurrency
} }
ConfigManager.prototype.updateConversionRate = function () { ConfigManager.prototype.updateConversionRate = function () {
@ -301,12 +297,12 @@ ConfigManager.prototype.setConversionDate = function (datestring) {
ConfigManager.prototype.getConversionRate = function () { ConfigManager.prototype.getConversionRate = function () {
var data = this.getData() var data = this.getData()
return (('conversionRate' in data) && data.conversionRate) || 0 return (data.conversionRate) || 0
} }
ConfigManager.prototype.getConversionDate = function () { ConfigManager.prototype.getConversionDate = function () {
var data = this.getData() var data = this.getData()
return (('conversionDate' in data) && data.conversionDate) || 'N/A' return (data.conversionDate) || 'N/A'
} }
ConfigManager.prototype.getShapeShiftTxList = function () { ConfigManager.prototype.getShapeShiftTxList = function () {
@ -345,7 +341,7 @@ ConfigManager.prototype.createShapeShiftTx = function (depositAddress, depositTy
ConfigManager.prototype.getGasMultiplier = function () { ConfigManager.prototype.getGasMultiplier = function () {
var data = this.getData() var data = this.getData()
return ('gasMultiplier' in data) && data.gasMultiplier return data.gasMultiplier
} }
ConfigManager.prototype.setGasMultiplier = function (gasMultiplier) { ConfigManager.prototype.setGasMultiplier = function (gasMultiplier) {

View File

@ -1,7 +1,7 @@
const Streams = require('mississippi') const pipe = require('pump')
const StreamProvider = require('web3-stream-provider') const StreamProvider = require('web3-stream-provider')
const LocalStorageStore = require('obs-store')
const ObjectMultiplex = require('./obj-multiplex') const ObjectMultiplex = require('./obj-multiplex')
const RemoteStore = require('./observable/remote')
const createRandomId = require('./random-id') const createRandomId = require('./random-id')
module.exports = MetamaskInpageProvider module.exports = MetamaskInpageProvider
@ -10,33 +10,30 @@ function MetamaskInpageProvider (connectionStream) {
const self = this const self = this
// setup connectionStream multiplexing // setup connectionStream multiplexing
var multiStream = ObjectMultiplex() var multiStream = self.multiStream = ObjectMultiplex()
Streams.pipe(connectionStream, multiStream, connectionStream, function (err) { pipe(
let warningMsg = 'MetamaskInpageProvider - lost connection to MetaMask' connectionStream,
if (err) warningMsg += '\n' + err.stack multiStream,
console.warn(warningMsg) connectionStream,
}) (err) => logStreamDisconnectWarning('MetaMask', err)
self.multiStream = multiStream )
// subscribe to metamask public config // subscribe to metamask public config (one-way)
var publicConfigStore = remoteStoreWithLocalStorageCache('MetaMask-Config') self.publicConfigStore = new LocalStorageStore({ storageKey: 'MetaMask-Config' })
var storeStream = publicConfigStore.createStream() pipe(
Streams.pipe(storeStream, multiStream.createStream('publicConfig'), storeStream, function (err) { multiStream.createStream('publicConfig'),
let warningMsg = 'MetamaskInpageProvider - lost connection to MetaMask publicConfig' self.publicConfigStore,
if (err) warningMsg += '\n' + err.stack (err) => logStreamDisconnectWarning('MetaMask PublicConfigStore', err)
console.warn(warningMsg) )
})
self.publicConfigStore = publicConfigStore
// connect to async provider // connect to async provider
var asyncProvider = new StreamProvider() const asyncProvider = self.asyncProvider = new StreamProvider()
Streams.pipe(asyncProvider, multiStream.createStream('provider'), asyncProvider, function (err) { pipe(
let warningMsg = 'MetamaskInpageProvider - lost connection to MetaMask provider' asyncProvider,
if (err) warningMsg += '\n' + err.stack multiStream.createStream('provider'),
console.warn(warningMsg) asyncProvider,
}) (err) => logStreamDisconnectWarning('MetaMask RpcProvider', err)
asyncProvider.on('error', console.error.bind(console)) )
self.asyncProvider = asyncProvider
self.idMap = {} self.idMap = {}
// handle sendAsync requests via asyncProvider // handle sendAsync requests via asyncProvider
@ -72,13 +69,13 @@ MetamaskInpageProvider.prototype.send = function (payload) {
case 'eth_accounts': case 'eth_accounts':
// read from localStorage // read from localStorage
selectedAccount = self.publicConfigStore.get().selectedAccount selectedAccount = self.publicConfigStore.getState().selectedAccount
result = selectedAccount ? [selectedAccount] : [] result = selectedAccount ? [selectedAccount] : []
break break
case 'eth_coinbase': case 'eth_coinbase':
// read from localStorage // read from localStorage
selectedAccount = self.publicConfigStore.get().selectedAccount selectedAccount = self.publicConfigStore.getState().selectedAccount
result = selectedAccount || '0x0000000000000000000000000000000000000000' result = selectedAccount || '0x0000000000000000000000000000000000000000'
break break
@ -115,24 +112,6 @@ MetamaskInpageProvider.prototype.isMetaMask = true
// util // util
function remoteStoreWithLocalStorageCache (storageKey) {
// read local cache
let initState
try {
initState = JSON.parse(localStorage[storageKey] || '{}')
} catch (err) {
initState = {}
}
// intialize store
const store = new RemoteStore(initState)
// write local cache
store.subscribe(function (state) {
localStorage[storageKey] = JSON.stringify(state)
})
return store
}
function eachJsonMessage (payload, transformFn) { function eachJsonMessage (payload, transformFn) {
if (Array.isArray(payload)) { if (Array.isArray(payload)) {
return payload.map(transformFn) return payload.map(transformFn)
@ -141,4 +120,10 @@ function eachJsonMessage (payload, transformFn) {
} }
} }
function logStreamDisconnectWarning(remoteLabel, err){
let warningMsg = `MetamaskInpageProvider - lost connection to ${remoteLabel}`
if (err) warningMsg += '\n' + err.stack
console.warn(warningMsg)
}
function noop () {} function noop () {}

View File

@ -1,50 +0,0 @@
const Dnode = require('dnode')
const ObservableStore = require('./index')
const endOfStream = require('end-of-stream')
//
// HostStore
//
// plays host to many RemoteStores and sends its state over a stream
//
class HostStore extends ObservableStore {
constructor (initState, opts) {
super(initState)
this._opts = opts || {}
}
createStream () {
const self = this
// setup remotely exposed api
let remoteApi = {}
if (!self._opts.readOnly) {
remoteApi.put = (newState) => self.put(newState)
}
// listen for connection to remote
const dnode = Dnode(remoteApi)
dnode.on('remote', (remote) => {
// setup update subscription lifecycle
const updateHandler = (state) => remote.put(state)
self._onConnect(updateHandler)
endOfStream(dnode, () => self._onDisconnect(updateHandler))
})
return dnode
}
_onConnect (updateHandler) {
// subscribe to updates
this.subscribe(updateHandler)
// send state immediately
updateHandler(this.get())
}
_onDisconnect (updateHandler) {
// unsubscribe to updates
this.unsubscribe(updateHandler)
}
}
module.exports = HostStore

View File

@ -1,41 +0,0 @@
const EventEmitter = require('events').EventEmitter
class ObservableStore extends EventEmitter {
constructor (initialState) {
super()
this._state = initialState
}
// wrapper around internal get
get () {
return this._state
}
// wrapper around internal put
put (newState) {
this._put(newState)
}
// subscribe to changes
subscribe (handler) {
this.on('update', handler)
}
// unsubscribe to changes
unsubscribe (handler) {
this.removeListener('update', handler)
}
//
// private
//
_put (newState) {
this._state = newState
this.emit('update', newState)
}
}
module.exports = ObservableStore

View File

@ -1,37 +0,0 @@
const ObservableStore = require('./index')
//
// LocalStorageStore
//
// uses localStorage instead of a cache
//
class LocalStorageStore extends ObservableStore {
constructor (opts) {
super()
delete this._state
this._opts = opts || {}
if (!this._opts.storageKey) {
throw new Error('LocalStorageStore - no "storageKey" specified')
}
this._storageKey = this._opts.storageKey
}
get() {
try {
return JSON.parse(global.localStorage[this._storageKey])
} catch (err) {
return undefined
}
}
_put(newState) {
global.localStorage[this._storageKey] = JSON.stringify(newState)
this.emit('update', newState)
}
}
module.exports = LocalStorageStore

View File

@ -1,51 +0,0 @@
const Dnode = require('dnode')
const ObservableStore = require('./index')
const endOfStream = require('end-of-stream')
//
// RemoteStore
//
// connects to a HostStore and receives its latest state
//
class RemoteStore extends ObservableStore {
constructor (initState, opts) {
super(initState)
this._opts = opts || {}
this._remote = null
}
put (newState) {
if (!this._remote) throw new Error('RemoteStore - "put" called before connection to HostStore')
this._put(newState)
this._remote.put(newState)
}
createStream () {
const self = this
const dnode = Dnode({
put: (newState) => self._put(newState),
})
// listen for connection to remote
dnode.once('remote', (remote) => {
// setup connection lifecycle
self._onConnect(remote)
endOfStream(dnode, () => self._onDisconnect())
})
return dnode
}
_onConnect (remote) {
this._remote = remote
this.emit('connected')
}
_onDisconnect () {
this._remote = null
this.emit('disconnected')
}
}
module.exports = RemoteStore

View File

@ -1,24 +0,0 @@
//
// synchronizeStore(inStore, outStore, stateTransform)
//
// keeps outStore synchronized with inStore, via an optional stateTransform
//
module.exports = synchronizeStore
function synchronizeStore(inStore, outStore, stateTransform) {
stateTransform = stateTransform || transformNoop
const initState = stateTransform(inStore.get())
outStore.put(initState)
inStore.subscribe((inState) => {
const outState = stateTransform(inState)
outStore.put(outState)
})
return outStore
}
function transformNoop(state) {
return state
}

View File

@ -1,6 +1,9 @@
const EventEmitter = require('events') const EventEmitter = require('events')
const extend = require('xtend') const extend = require('xtend')
const promiseToCallback = require('promise-to-callback') const promiseToCallback = require('promise-to-callback')
const pipe = require('pump')
const ObservableStore = require('obs-store')
const storeTransform = require('obs-store/lib/transform')
const EthStore = require('./lib/eth-store') const EthStore = require('./lib/eth-store')
const MetaMaskProvider = require('web3-provider-engine/zero.js') const MetaMaskProvider = require('web3-provider-engine/zero.js')
const KeyringController = require('./keyring-controller') const KeyringController = require('./keyring-controller')
@ -13,9 +16,6 @@ const extension = require('./lib/extension')
const autoFaucet = require('./lib/auto-faucet') const autoFaucet = require('./lib/auto-faucet')
const nodeify = require('./lib/nodeify') const nodeify = require('./lib/nodeify')
const IdStoreMigrator = require('./lib/idStore-migrator') const IdStoreMigrator = require('./lib/idStore-migrator')
const ObservableStore = require('./lib/observable/')
const HostStore = require('./lib/observable/host')
const synchronizeStore = require('./lib/observable/util/sync')
const accountImporter = require('./account-import-strategies') const accountImporter = require('./account-import-strategies')
const version = require('../manifest.json').version const version = require('../manifest.json').version
@ -258,18 +258,21 @@ module.exports = class MetamaskController extends EventEmitter {
initPublicConfigStore () { initPublicConfigStore () {
// get init state // get init state
var initPublicState = this.store.get() const publicConfigStore = new ObservableStore()
var publicConfigStore = new HostStore(initPublicState, { readOnly: true })
// sync publicConfigStore with transform // sync publicConfigStore with transform
synchronizeStore(this.store, publicConfigStore, selectPublicState) pipe(
this.store,
storeTransform(selectPublicState),
publicConfigStore
)
function selectPublicState(state) { function selectPublicState(state) {
let result = { selectedAccount: undefined } const result = { selectedAccount: undefined }
try { try {
result.selectedAccount = state.config.selectedAccount result.selectedAccount = state.config.selectedAccount
} catch (err) { } catch (_) {
console.warn('Error in "selectPublicState": ' + err.message) // thats fine, im sure it will be there next time...
} }
return result return result
} }
@ -314,9 +317,11 @@ module.exports = class MetamaskController extends EventEmitter {
this.opts.showUnconfirmedMessage(msgParams, msgId) this.opts.showUnconfirmedMessage(msgParams, msgId)
} }
setupPublicConfig (stream) { setupPublicConfig (outStream) {
var storeStream = this.publicConfigStore.createStream() pipe(
stream.pipe(storeStream).pipe(stream) this.publicConfigStore,
outStream
)
} }
// Log blocks // Log blocks

View File

@ -7,7 +7,7 @@ which we dont have access to at the time of this writing.
*/ */
const ObservableStore = require('../../app/scripts/lib/observable/') const ObservableStore = require('obs-store')
const ConfigManager = require('../../app/scripts/lib/config-manager') const ConfigManager = require('../../app/scripts/lib/config-manager')
const IdentityStoreMigrator = require('../../app/scripts/lib/idStore-migrator') const IdentityStoreMigrator = require('../../app/scripts/lib/idStore-migrator')
const KeyringController = require('../../app/scripts/lib/keyring-controller') const KeyringController = require('../../app/scripts/lib/keyring-controller')

View File

@ -18,6 +18,8 @@ if (!global.localStorage) global.localStorage
const extend = require('xtend') const extend = require('xtend')
const render = require('react-dom').render const render = require('react-dom').render
const h = require('react-hyperscript') const h = require('react-hyperscript')
const pipe = require('mississippi').pipe
const LocalStorageStore = require('obs-store/lib/localStorage')
const Root = require('./ui/app/root') const Root = require('./ui/app/root')
const configureStore = require('./ui/app/store') const configureStore = require('./ui/app/store')
const actions = require('./ui/app/actions') const actions = require('./ui/app/actions')
@ -25,8 +27,6 @@ const states = require('./development/states')
const Selector = require('./development/selector') const Selector = require('./development/selector')
const MetamaskController = require('./app/scripts/metamask-controller') const MetamaskController = require('./app/scripts/metamask-controller')
const firstTimeState = require('./app/scripts/first-time-state') const firstTimeState = require('./app/scripts/first-time-state')
const LocalStorageStore = require('./app/scripts/lib/observable/local-storage')
const synchronizeStore = require('./app/scripts/lib/observable/util/sync')
const extension = require('./development/mockExtension') const extension = require('./development/mockExtension')
const noop = function () {} const noop = function () {}
@ -61,8 +61,8 @@ const injectCss = require('inject-css')
let dataStore = new LocalStorageStore({ storageKey: STORAGE_KEY }) let dataStore = new LocalStorageStore({ storageKey: STORAGE_KEY })
// initial state for first time users // initial state for first time users
if (!dataStore.get()) { if (!dataStore.getState()) {
dataStore.put(firstTimeState) dataStore.putState(firstTimeState)
} }
const controller = new MetamaskController({ const controller = new MetamaskController({
@ -71,11 +71,14 @@ const controller = new MetamaskController({
unlockAccountMessage: noop, unlockAccountMessage: noop,
showUnapprovedTx: noop, showUnapprovedTx: noop,
// initial state // initial state
initState: dataStore.get(), initState: dataStore.getState(),
}) })
// setup state persistence // setup state persistence
synchronizeStore(controller.store, dataStore) pipe(
controller.store,
dataStore
)
// //
// User Interface // User Interface

View File

@ -70,6 +70,7 @@
"mississippi": "^1.2.0", "mississippi": "^1.2.0",
"mkdirp": "^0.5.1", "mkdirp": "^0.5.1",
"multiplex": "^6.7.0", "multiplex": "^6.7.0",
"obs-store": "^2.2.3",
"once": "^1.3.3", "once": "^1.3.3",
"ping-pong-stream": "^1.0.0", "ping-pong-stream": "^1.0.0",
"pojo-migrator": "^2.1.0", "pojo-migrator": "^2.1.0",
@ -77,6 +78,7 @@
"post-message-stream": "^1.0.0", "post-message-stream": "^1.0.0",
"promise-filter": "^1.1.0", "promise-filter": "^1.1.0",
"promise-to-callback": "^1.0.0", "promise-to-callback": "^1.0.0",
"pump": "^1.0.2",
"pumpify": "^1.3.4", "pumpify": "^1.3.4",
"qrcode-npm": "0.0.3", "qrcode-npm": "0.0.3",
"react": "^15.0.2", "react": "^15.0.2",

View File

@ -1,4 +1,4 @@
const ObservableStore = require('../../../app/scripts/lib/observable/') const ObservableStore = require('obs-store')
const ConfigManager = require('../../../app/scripts/lib/config-manager') const ConfigManager = require('../../../app/scripts/lib/config-manager')
const IdStoreMigrator = require('../../../app/scripts/lib/idStore-migrator') const IdStoreMigrator = require('../../../app/scripts/lib/idStore-migrator')
const SimpleKeyring = require('../../../app/scripts/keyrings/simple') const SimpleKeyring = require('../../../app/scripts/keyrings/simple')

View File

@ -1,11 +1,10 @@
const ObservableStore = require('obs-store')
const clone = require('clone')
const ConfigManager = require('../../app/scripts/lib/config-manager') const ConfigManager = require('../../app/scripts/lib/config-manager')
const LocalStorageStore = require('../../app/scripts/lib/observable/local-storage')
const firstTimeState = require('../../app/scripts/first-time-state') const firstTimeState = require('../../app/scripts/first-time-state')
const STORAGE_KEY = 'metamask-config' const STORAGE_KEY = 'metamask-config'
module.exports = function() { module.exports = function() {
let dataStore = new LocalStorageStore({ storageKey: STORAGE_KEY }) let store = new ObservableStore(clone(firstTimeState))
// initial state for first time users return new ConfigManager({ store })
if (!dataStore.get()) dataStore.put(firstTimeState)
return new ConfigManager({ store: dataStore })
} }

View File

@ -1,27 +1,23 @@
// polyfill fetch // polyfill fetch
global.fetch = global.fetch || require('isomorphic-fetch') global.fetch = global.fetch || require('isomorphic-fetch')
// pollyfill localStorage support into JSDom
global.localStorage = global.localStorage || polyfillLocalStorage()
const assert = require('assert') const assert = require('assert')
const extend = require('xtend') const extend = require('xtend')
const rp = require('request-promise') const rp = require('request-promise')
const nock = require('nock') const nock = require('nock')
const configManagerGen = require('../lib/mock-config-manager') const configManagerGen = require('../lib/mock-config-manager')
const STORAGE_KEY = 'metamask-persistance-key'
describe('config-manager', function() { describe('config-manager', function() {
var configManager var configManager
beforeEach(function() { beforeEach(function() {
global.localStorage.clear()
configManager = configManagerGen() configManager = configManagerGen()
}) })
describe('currency conversions', function() { describe('currency conversions', function() {
describe('#getCurrentFiat', function() { describe('#getCurrentFiat', function() {
it('should return false if no previous key exists', function() { it('should return undefined if no previous key exists', function() {
var result = configManager.getCurrentFiat() var result = configManager.getCurrentFiat()
assert.ok(!result) assert.ok(!result)
}) })
@ -29,14 +25,14 @@ describe('config-manager', function() {
describe('#setCurrentFiat', function() { describe('#setCurrentFiat', function() {
it('should make getCurrentFiat return true once set', function() { it('should make getCurrentFiat return true once set', function() {
assert.equal(configManager.getCurrentFiat(), false) assert.equal(configManager.getCurrentFiat(), undefined)
configManager.setCurrentFiat('USD') configManager.setCurrentFiat('USD')
var result = configManager.getCurrentFiat() var result = configManager.getCurrentFiat()
assert.equal(result, 'USD') assert.equal(result, 'USD')
}) })
it('should work with other currencies as well', function() { it('should work with other currencies as well', function() {
assert.equal(configManager.getCurrentFiat(), false) assert.equal(configManager.getCurrentFiat(), undefined)
configManager.setCurrentFiat('JPY') configManager.setCurrentFiat('JPY')
var result = configManager.getCurrentFiat() var result = configManager.getCurrentFiat()
assert.equal(result, 'JPY') assert.equal(result, 'JPY')
@ -44,7 +40,7 @@ describe('config-manager', function() {
}) })
describe('#getConversionRate', function() { describe('#getConversionRate', function() {
it('should return false if non-existent', function() { it('should return undefined if non-existent', function() {
var result = configManager.getConversionRate() var result = configManager.getConversionRate()
assert.ok(!result) assert.ok(!result)
}) })
@ -57,7 +53,7 @@ describe('config-manager', function() {
.get('/api/ticker/eth-USD') .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":""}') .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(), false) assert.equal(configManager.getConversionRate(), 0)
var promise = new Promise( var promise = new Promise(
function (resolve, reject) { function (resolve, reject) {
configManager.setCurrentFiat('USD') configManager.setCurrentFiat('USD')
@ -78,7 +74,7 @@ describe('config-manager', function() {
it('should work for JPY as well.', function() { it('should work for JPY as well.', function() {
this.timeout(15000) this.timeout(15000)
assert.equal(configManager.getConversionRate(), false) assert.equal(configManager.getConversionRate(), 0)
var jpyMock = nock('https://www.cryptonator.com') var jpyMock = nock('https://www.cryptonator.com')
.get('/api/ticker/eth-JPY') .get('/api/ticker/eth-JPY')
@ -106,7 +102,7 @@ describe('config-manager', function() {
describe('confirmation', function() { describe('confirmation', function() {
describe('#getConfirmedDisclaimer', function() { describe('#getConfirmedDisclaimer', function() {
it('should return false if no previous key exists', function() { it('should return undefined if no previous key exists', function() {
var result = configManager.getConfirmedDisclaimer() var result = configManager.getConfirmedDisclaimer()
assert.ok(!result) assert.ok(!result)
}) })
@ -114,16 +110,16 @@ describe('config-manager', function() {
describe('#setConfirmedDisclaimer', function() { describe('#setConfirmedDisclaimer', function() {
it('should make getConfirmedDisclaimer return true once set', function() { it('should make getConfirmedDisclaimer return true once set', function() {
assert.equal(configManager.getConfirmedDisclaimer(), false) assert.equal(configManager.getConfirmedDisclaimer(), undefined)
configManager.setConfirmedDisclaimer(true) configManager.setConfirmedDisclaimer(true)
var result = configManager.getConfirmedDisclaimer() var result = configManager.getConfirmedDisclaimer()
assert.equal(result, true) assert.equal(result, true)
}) })
it('should be able to set false', function() { it('should be able to set undefined', function() {
configManager.setConfirmedDisclaimer(false) configManager.setConfirmedDisclaimer(undefined)
var result = configManager.getConfirmedDisclaimer() var result = configManager.getConfirmedDisclaimer()
assert.equal(result, false) assert.equal(result, undefined)
}) })
it('should persist to local storage', function() { it('should persist to local storage', function() {
@ -240,7 +236,3 @@ describe('config-manager', function() {
}) })
}) })
}) })
function polyfillLocalStorage(){
return Object.create({ clear: function(){ global.localStorage = polyfillLocalStorage() } })
}

View File

@ -1,9 +1,9 @@
const async = require('async') const async = require('async')
const assert = require('assert') const assert = require('assert')
const ObservableStore = require('obs-store')
const ethUtil = require('ethereumjs-util') const ethUtil = require('ethereumjs-util')
const BN = ethUtil.BN const BN = ethUtil.BN
const ConfigManager = require('../../app/scripts/lib/config-manager') const ConfigManager = require('../../app/scripts/lib/config-manager')
const ObservableStore = require('../../app/scripts/lib/observable/')
const delegateCallCode = require('../lib/example-code.json').delegateCallCode const delegateCallCode = require('../lib/example-code.json').delegateCallCode
// The old way: // The old way: