aboutsummaryrefslogtreecommitdiffstats
path: root/app/scripts/lib/inpage-provider.js
diff options
context:
space:
mode:
authorkumavis <aaron@kumavis.me>2016-05-23 06:23:16 +0800
committerkumavis <aaron@kumavis.me>2016-05-23 06:23:16 +0800
commit00e9f3c6ae2d4092f0c9270d113d7e6dd47ddf0b (patch)
tree06711908a618aa911c6a820b039bf748f52c240c /app/scripts/lib/inpage-provider.js
parent27790b38a95e219b7663852150b82387cedb58e2 (diff)
downloadtangerine-wallet-browser-00e9f3c6ae2d4092f0c9270d113d7e6dd47ddf0b.tar.gz
tangerine-wallet-browser-00e9f3c6ae2d4092f0c9270d113d7e6dd47ddf0b.tar.zst
tangerine-wallet-browser-00e9f3c6ae2d4092f0c9270d113d7e6dd47ddf0b.zip
inpage - refactor for modularity
Diffstat (limited to 'app/scripts/lib/inpage-provider.js')
-rw-r--r--app/scripts/lib/inpage-provider.js123
1 files changed, 123 insertions, 0 deletions
diff --git a/app/scripts/lib/inpage-provider.js b/app/scripts/lib/inpage-provider.js
new file mode 100644
index 000000000..66681c3a9
--- /dev/null
+++ b/app/scripts/lib/inpage-provider.js
@@ -0,0 +1,123 @@
+const HttpProvider = require('web3/lib/web3/httpprovider')
+const Streams = require('mississippi')
+const ObjectMultiplex = require('./obj-multiplex')
+const StreamProvider = require('./stream-provider.js')
+const RemoteStore = require('./remote-store.js').RemoteStore
+const MetamaskConfig = require('../config.js')
+
+module.exports = MetamaskInpageProvider
+
+
+function MetamaskInpageProvider(connectionStream){
+ const self = this
+
+ // setup connectionStream multiplexing
+ var multiStream = ObjectMultiplex()
+ Streams.pipe(connectionStream, multiStream, connectionStream, function(err){
+ console.warn('MetamaskInpageProvider - lost connection to MetaMask')
+ if (err) throw err
+ })
+ self.multiStream = multiStream
+
+ // subscribe to metamask public config
+ var publicConfigStore = remoteStoreWithLocalStorageCache('MetaMask-Config')
+ var storeStream = publicConfigStore.createStream()
+ Streams.pipe(storeStream, multiStream.createStream('publicConfig'), storeStream, function(err){
+ console.warn('MetamaskInpageProvider - lost connection to MetaMask publicConfig')
+ if (err) throw err
+ })
+ self.publicConfigStore = publicConfigStore
+
+ // connect to sync provider
+ self.syncProvider = createSyncProvider(publicConfigStore.get('provider'))
+ // subscribe to publicConfig to update the syncProvider on change
+ publicConfigStore.subscribe(function(state){
+ self.syncProvider = createSyncProvider(state.provider)
+ })
+
+ // connect to async provider
+ var asyncProvider = new StreamProvider()
+ Streams.pipe(asyncProvider, multiStream.createStream('provider'), asyncProvider, function(err){
+ console.warn('MetamaskInpageProvider - lost connection to MetaMask provider')
+ if (err) throw err
+ })
+ asyncProvider.on('error', console.error.bind(console))
+ self.asyncProvider = asyncProvider
+ // overwrite own sendAsync method
+ self.sendAsync = asyncProvider.sendAsync.bind(asyncProvider)
+}
+
+MetamaskInpageProvider.prototype.send = function(payload){
+ const self = this
+
+ var result = null
+ switch (payload.method) {
+
+ case 'eth_accounts':
+ // read from localStorage
+ var selectedAddress = self.publicConfigStore.get('selectedAddress')
+ result = selectedAddress ? [selectedAddress] : []
+ break
+
+ case 'eth_coinbase':
+ // read from localStorage
+ var selectedAddress = self.publicConfigStore.get('selectedAddress')
+ result = selectedAddress || '0x0000000000000000000000000000000000000000'
+ break
+
+ // fallback to normal rpc
+ default:
+ return self.syncProvider.send(payload)
+
+ }
+
+ // return the result
+ return {
+ id: payload.id,
+ jsonrpc: payload.jsonrpc,
+ result: result,
+ }
+}
+
+MetamaskInpageProvider.prototype.sendAsync = function(){
+ throw new Error('MetamaskInpageProvider - sendAsync not overwritten')
+}
+
+MetamaskInpageProvider.prototype.isConnected = function(){
+ return true
+}
+
+// util
+
+function createSyncProvider(providerConfig){
+ providerConfig = providerConfig || {}
+ var syncProviderUrl = undefined
+
+ if (providerConfig.rpcTarget) {
+ syncProviderUrl = providerConfig.rpcTarget
+ } else {
+ switch(providerConfig.type) {
+ case 'testnet':
+ syncProviderUrl = MetamaskConfig.network.testnet
+ break
+ case 'mainnet':
+ syncProviderUrl = MetamaskConfig.network.mainnet
+ break
+ default:
+ syncProviderUrl = MetamaskConfig.network.default
+ }
+ }
+ return new HttpProvider(syncProviderUrl)
+}
+
+function remoteStoreWithLocalStorageCache(storageKey){
+ // read local cache
+ var initState = JSON.parse(localStorage[storageKey] || '{}')
+ var store = new RemoteStore(initState)
+ // cache the latest state locally
+ store.subscribe(function(state){
+ localStorage[storageKey] = JSON.stringify(state)
+ })
+
+ return store
+} \ No newline at end of file