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:
parent
a06ee45404
commit
76ce348a04
@ -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
|
||||||
|
@ -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) {
|
||||||
|
@ -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 () {}
|
||||||
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
||||||
}
|
|
@ -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
|
||||||
|
@ -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')
|
||||||
|
15
mock-dev.js
15
mock-dev.js
@ -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
|
||||||
|
@ -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",
|
||||||
|
@ -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')
|
||||||
|
@ -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 })
|
|
||||||
}
|
}
|
@ -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() } })
|
|
||||||
}
|
|
||||||
|
@ -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:
|
||||||
|
Loading…
Reference in New Issue
Block a user