inpage - use publicConfigStore for selectedAccount and sync provider

This commit is contained in:
kumavis 2016-04-15 13:04:17 -07:00
parent d840e81a10
commit d6114292d0
3 changed files with 93 additions and 34 deletions

View File

@ -71,13 +71,6 @@ provider.on('block', function(block){
var ethStore = new EthStore(provider)
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(){
var state = extend(
ethStore.getState(),
@ -87,6 +80,47 @@ function getState(){
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
function onRpcRequest(remoteStream, payload){
// console.log('MetaMaskPlugin - incoming payload:', payload)

View File

@ -9,7 +9,7 @@ const Web3 = require('web3')
delete window.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.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()
storeStream.pipe(mx.createStream('publicConfig')).pipe(storeStream)
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 accounts cache
var accountsCache = JSON.parse(localStorage['MetaMask-Accounts'] || '[]')
web3.eth.defaultAccount = accountsCache[0]
global.publicConfigStore = publicConfigStore
setInterval(populateAccountsCache, 4000)
function populateAccountsCache(){
remoteProvider.sendAsync(createPayload({
method: 'eth_accounts',
params: [],
isMetamaskInternal: true,
}), function(err, response){
if (err) return console.error('MetaMask - Error polling accounts')
// update localStorage
var accounts = response.result
if (accounts.toString() !== accountsCache.toString()) {
accountsCache = accounts
web3.eth.defaultAccount = accountsCache[0]
localStorage['MetaMask-Accounts'] = JSON.stringify(accounts)
}
})
}
// set web3 defaultAcount
publicConfigStore.subscribe(function(state){
web3.eth.defaultAccount = state.selectedAddress
})
// handle synchronous methods via standard http provider
var syncProvider = new Web3.providers.HttpProvider(RPC_URL)
// setup sync http provider
var providerConfig = publicConfigStore.get('provider') || {}
var providerUrl = providerConfig.rpcTarget ? providerConfig.rpcTarget : DEFAULT_RPC_URL
var syncProvider = new Web3.providers.HttpProvider(providerUrl)
publicConfigStore.subscribe(function(state){
if (!state.provider) return
if (!state.provider.rpcTarget || state.provider.rpcTarget === providerUrl) return
providerUrl = state.provider.rpcTarget
syncProvider = new Web3.providers.HttpProvider(providerUrl)
})
// handle sync methods
remoteProvider.send = function(payload){
var result = null
switch (payload.method) {
case 'eth_accounts':
// read from localStorage
result = accountsCache
var selectedAddress = publicConfigStore.get('selectedAddress')
result = selectedAddress ? [selectedAddress] : []
break
case 'eth_coinbase':
// read from localStorage
result = accountsCache[0] || '0x0000000000000000000000000000000000000000'
var selectedAddress = publicConfigStore.get('selectedAddress')
result = selectedAddress || '0x0000000000000000000000000000000000000000'
break
// fallback to normal rpc

View File

@ -15,6 +15,8 @@ const migrations = require('./migrations')
*/
module.exports = ConfigManager
function ConfigManager() {
// ConfigManager is observable and will emit updates
this._subs = []
/* The migrator exported on the config-manager
* has two methods the user should be concerned with:
@ -47,6 +49,7 @@ ConfigManager.prototype.setConfig = function(config) {
var data = this.migrator.getData()
data.config = config
this.setData(data)
this._emitUpdates(config)
}
ConfigManager.prototype.getConfig = function() {
@ -127,6 +130,30 @@ ConfigManager.prototype.clearWallet = function() {
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() {
var oldData = getOldStyleData()