inpage - use publicConfigStore for selectedAccount and sync provider

feature/default_network_editable
kumavis 9 years ago
parent d840e81a10
commit d6114292d0
  1. 48
      app/scripts/background.js
  2. 54
      app/scripts/inpage.js
  3. 27
      app/scripts/lib/config-manager.js

@ -71,13 +71,6 @@ provider.on('block', function(block){
var ethStore = new EthStore(provider) var ethStore = new EthStore(provider)
idStore.setStore(ethStore) idStore.setStore(ethStore)
// copy idStore substate into public store
var publicConfigStore = new HostStore()
idStore.on('update', function(state){
publicConfigStore.set('selectedAddress', state.selectedAddress)
})
function getState(){ function getState(){
var state = extend( var state = extend(
ethStore.getState(), ethStore.getState(),
@ -87,6 +80,47 @@ function getState(){
return state return state
} }
//
// public store
//
// get init state
var initPublicState = extend(
idStoreToPublic(idStore.getState()),
configToPublic(configManager.getConfig())
)
var publicConfigStore = new HostStore(initPublicState)
// subscribe to changes
configManager.subscribe(function(state){
storeSetFromObj(publicConfigStore, configToPublic(state))
})
idStore.on('update', function(state){
storeSetFromObj(publicConfigStore, idStoreToPublic(state))
})
// idStore substate
function idStoreToPublic(state){
return {
selectedAddress: state.selectedAddress,
}
}
// config substate
function configToPublic(state){
return {
provider: state.provider,
}
}
// dump obj into store
function storeSetFromObj(store, obj){
Object.keys(obj).forEach(function(key){
store.set(key, obj[key])
})
}
// handle rpc requests // handle rpc requests
function onRpcRequest(remoteStream, payload){ function onRpcRequest(remoteStream, payload){
// console.log('MetaMaskPlugin - incoming payload:', payload) // console.log('MetaMaskPlugin - incoming payload:', payload)

@ -9,7 +9,7 @@ const Web3 = require('web3')
delete window.Web3 delete window.Web3
window.MetamaskWeb3 = Web3 window.MetamaskWeb3 = Web3
const RPC_URL = 'https://testrpc.metamask.io/' const DEFAULT_RPC_URL = 'https://rpc.metamask.io/'
// //
@ -27,12 +27,13 @@ var remoteProvider = new StreamProvider()
remoteProvider.pipe(mx.createStream('provider')).pipe(remoteProvider) remoteProvider.pipe(mx.createStream('provider')).pipe(remoteProvider)
remoteProvider.on('error', console.error.bind(console)) remoteProvider.on('error', console.error.bind(console))
var publicConfigStore = new RemoteStore() var initState = JSON.parse(localStorage['MetaMask-Config'] || '{}')
var publicConfigStore = new RemoteStore(initState)
var storeStream = publicConfigStore.createStream() var storeStream = publicConfigStore.createStream()
storeStream.pipe(mx.createStream('publicConfig')).pipe(storeStream) storeStream.pipe(mx.createStream('publicConfig')).pipe(storeStream)
publicConfigStore.subscribe(function(state){ publicConfigStore.subscribe(function(state){
console.log('store updated:', state) localStorage['MetaMask-Config'] = JSON.stringify(state)
}) })
@ -52,42 +53,39 @@ console.log('MetaMask - injected web3')
// handle synchronous requests // handle synchronous requests
// //
// handle accounts cache global.publicConfigStore = publicConfigStore
var accountsCache = JSON.parse(localStorage['MetaMask-Accounts'] || '[]')
web3.eth.defaultAccount = accountsCache[0] // set web3 defaultAcount
publicConfigStore.subscribe(function(state){
setInterval(populateAccountsCache, 4000) web3.eth.defaultAccount = state.selectedAddress
function populateAccountsCache(){ })
remoteProvider.sendAsync(createPayload({
method: 'eth_accounts', // setup sync http provider
params: [], var providerConfig = publicConfigStore.get('provider') || {}
isMetamaskInternal: true, var providerUrl = providerConfig.rpcTarget ? providerConfig.rpcTarget : DEFAULT_RPC_URL
}), function(err, response){ var syncProvider = new Web3.providers.HttpProvider(providerUrl)
if (err) return console.error('MetaMask - Error polling accounts') publicConfigStore.subscribe(function(state){
// update localStorage if (!state.provider) return
var accounts = response.result if (!state.provider.rpcTarget || state.provider.rpcTarget === providerUrl) return
if (accounts.toString() !== accountsCache.toString()) { providerUrl = state.provider.rpcTarget
accountsCache = accounts syncProvider = new Web3.providers.HttpProvider(providerUrl)
web3.eth.defaultAccount = accountsCache[0] })
localStorage['MetaMask-Accounts'] = JSON.stringify(accounts)
}
})
}
// handle synchronous methods via standard http provider // handle sync methods
var syncProvider = new Web3.providers.HttpProvider(RPC_URL)
remoteProvider.send = function(payload){ remoteProvider.send = function(payload){
var result = null var result = null
switch (payload.method) { switch (payload.method) {
case 'eth_accounts': case 'eth_accounts':
// read from localStorage // read from localStorage
result = accountsCache var selectedAddress = publicConfigStore.get('selectedAddress')
result = selectedAddress ? [selectedAddress] : []
break break
case 'eth_coinbase': case 'eth_coinbase':
// read from localStorage // read from localStorage
result = accountsCache[0] || '0x0000000000000000000000000000000000000000' var selectedAddress = publicConfigStore.get('selectedAddress')
result = selectedAddress || '0x0000000000000000000000000000000000000000'
break break
// fallback to normal rpc // fallback to normal rpc

@ -15,6 +15,8 @@ const migrations = require('./migrations')
*/ */
module.exports = ConfigManager module.exports = ConfigManager
function ConfigManager() { function ConfigManager() {
// ConfigManager is observable and will emit updates
this._subs = []
/* The migrator exported on the config-manager /* The migrator exported on the config-manager
* has two methods the user should be concerned with: * has two methods the user should be concerned with:
@ -47,6 +49,7 @@ ConfigManager.prototype.setConfig = function(config) {
var data = this.migrator.getData() var data = this.migrator.getData()
data.config = config data.config = config
this.setData(data) this.setData(data)
this._emitUpdates(config)
} }
ConfigManager.prototype.getConfig = function() { ConfigManager.prototype.getConfig = function() {
@ -127,6 +130,30 @@ ConfigManager.prototype.clearWallet = function() {
this.setData(data) this.setData(data)
} }
ConfigManager.prototype.setData = function(data) {
this.migrator.saveData(data)
}
// observable
ConfigManager.prototype.subscribe = function(fn){
this._subs.push(fn)
var unsubscribe = this.unsubscribe.bind(this, fn)
return unsubscribe
}
ConfigManager.prototype.unsubscribe = function(fn){
var index = this._subs.indexOf(fn)
if (index !== -1) this._subs.splice(index, 1)
}
ConfigManager.prototype._emitUpdates = function(state){
this._subs.forEach(function(handler){
handler(state)
})
}
function loadData() { function loadData() {
var oldData = getOldStyleData() var oldData = getOldStyleData()

Loading…
Cancel
Save