aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkumavis <aaron@kumavis.me>2016-01-15 18:03:42 +0800
committerkumavis <aaron@kumavis.me>2016-01-15 18:03:42 +0800
commit7347a66eb0f4d5ab7f7d95e3657179408f4319f9 (patch)
tree397654c26a511ec07d9e914ff85ffb32f2eb1db4
parent3eaf027e30a3a28d75fb8f93cd30387a777c5814 (diff)
downloadtangerine-wallet-browser-7347a66eb0f4d5ab7f7d95e3657179408f4319f9.tar
tangerine-wallet-browser-7347a66eb0f4d5ab7f7d95e3657179408f4319f9.tar.gz
tangerine-wallet-browser-7347a66eb0f4d5ab7f7d95e3657179408f4319f9.tar.bz2
tangerine-wallet-browser-7347a66eb0f4d5ab7f7d95e3657179408f4319f9.tar.lz
tangerine-wallet-browser-7347a66eb0f4d5ab7f7d95e3657179408f4319f9.tar.xz
tangerine-wallet-browser-7347a66eb0f4d5ab7f7d95e3657179408f4319f9.tar.zst
tangerine-wallet-browser-7347a66eb0f4d5ab7f7d95e3657179408f4319f9.zip
integrate metamask-ui with id mgmt
-rw-r--r--app/scripts/background.js175
-rw-r--r--app/scripts/contentscript.js2
-rw-r--r--app/scripts/lib/metamask-provider.js23
-rw-r--r--app/scripts/popup.js25
-rw-r--r--package.json2
5 files changed, 199 insertions, 28 deletions
diff --git a/app/scripts/background.js b/app/scripts/background.js
index 7ddd258e2..48f14172e 100644
--- a/app/scripts/background.js
+++ b/app/scripts/background.js
@@ -1,33 +1,184 @@
+const Dnode = require('dnode')
+const KeyStore = require('eth-lightwallet').keystore
+const PortStream = require('./lib/port-stream.js')
const MetaMaskProvider = require('./lib/metamask-provider')
-// const PortStream = require('./lib/port-stream.js')
-const identitiesUrl = 'https://alpha.metamask.io/identities/'
-// var unsignedTxs = {}
+console.log('ready to roll')
-var zeroClient = MetaMaskProvider()
+// setup provider
+var zeroClient = MetaMaskProvider({
+ rpcUrl: 'https://testrpc.metamask.io/',
+ getAccounts: getAccounts,
+ sendTransaction: confirmTransaction,
+})
// setup messaging
chrome.runtime.onConnect.addListener(connectRemote)
-// chrome.runtime.onConnectExternal.addListener(connectRemote)
function connectRemote(remotePort){
+ var isMetaMaskInternalProcess = (remotePort.name === 'popup')
+ if (isMetaMaskInternalProcess) {
+ // communication with popup
+ handleInternalCommunication(remotePort)
+ } else {
+ // communication with page
+ handleExternalCommunication(remotePort)
+ }
+}
+
+function handleInternalCommunication(remotePort){
+ var duplex = new PortStream(remotePort)
+ var remote = Dnode({
+ getState: getState,
+ setLocked: setLocked,
+ submitPassword: submitPassword,
+ setSelectedAddress: setSelectedAddress,
+ signTransaction: signTransaction,
+ })
+ duplex.pipe(remote).pipe(duplex)
+}
+
+function handleExternalCommunication(remotePort){
remotePort.onMessage.addListener(onRpcRequest.bind(null, remotePort))
}
+// handle rpc requests
function onRpcRequest(remotePort, payload){
+ // console.log('MetaMaskPlugin - incoming payload:', payload)
zeroClient.sendAsync(payload, function onPayloadHandled(err, response){
if (err) throw err
console.log('MetaMaskPlugin - RPC complete:', payload, '->', response)
- // if (response.result === true) debugger
- // if (typeof response !== 'object') {
- // if (!response) {
- // console.warn('-------------------------------')
- // console.warn(payload, '->', response)
- // console.warn('-------------------------------')
- // }
remotePort.postMessage(response)
})
}
+// id mgmt
+var selectedAddress = null
+
+function getState(cb){
+ var result = _getState()
+ cb(null, result)
+}
+
+function _getState(cb){
+ var unlocked = isUnlocked()
+ var result = {
+ isUnlocked: unlocked,
+ identities: unlocked ? getIdentities() : {},
+ selectedAddress: selectedAddress,
+ }
+ return result
+}
+
+function isUnlocked(){
+ var password = window.sessionStorage['password']
+ var result = Boolean(password)
+ return result
+}
+
+function setLocked(){
+ delete window.sessionStorage['password']
+}
+
+function setSelectedAddress(address, cb){
+ selectedAddress = address
+ cb(null, _getState())
+}
+
+function submitPassword(password, cb){
+ console.log('submitPassword:', password)
+ tryPassword(password, function(err){
+ if (err) console.log('bad password:', password, err)
+ if (err) return cb(err)
+ console.log('good password:', password)
+ window.sessionStorage['password'] = password
+ cb(null, _getState())
+ })
+}
+
+function getAccounts(cb){
+ var identities = getIdentities()
+ var result = selectedAddress ? [selectedAddress] : []
+ cb(null, result)
+}
+
+function getIdentities(cb){
+ var keyStore = getKeyStore()
+ var addresses = keyStore.getAddresses()
+ var accountStore = {}
+ addresses.map(function(address){
+ address = '0x'+address
+ accountStore[address] = {
+ name: 'Wally',
+ img: 'QmW6hcwYzXrNkuHrpvo58YeZvbZxUddv69ATSHY3BHpPdd',
+ address: address,
+ balance: 10.005,
+ txCount: 16,
+ }
+ })
+ return accountStore
+}
+
+function tryPassword(password, cb){
+ var keyStore = getKeyStore(password)
+ var address = keyStore.getAddresses()[0]
+ if (!address) return cb(new Error('KeyStore - No address to check.'))
+ var hdPathString = keyStore.defaultHdPathString
+ try {
+ var encKey = keyStore.generateEncKey(password)
+ var encPrivKey = keyStore.ksData[hdPathString].encPrivKeys[address]
+ var privKey = KeyStore._decryptKey(encPrivKey, encKey)
+ var addrFromPrivKey = KeyStore._computeAddressFromPrivKey(privKey)
+ } catch (err) {
+ return cb(err)
+ }
+ if (addrFromPrivKey !== address) return cb(new Error('KeyStore - Decrypting private key failed!'))
+ cb()
+}
+
+function confirmTransaction(txParams, cb){
+ console.log('confirmTransaction:', txParams)
+}
+
+function signTransaction(txParams, cb){
+ console.log('signTransaction:', txParams)
+}
+
+var keyStore = null
+function getKeyStore(password){
+ if (keyStore) return keyStore
+ password = password || getPassword()
+ var serializedKeystore = window.localStorage['lightwallet']
+ // returning user
+ if (serializedKeystore) {
+ keyStore = KeyStore.deserialize(serializedKeystore)
+ // first time here
+ } else {
+ var defaultPassword = 'test'
+ console.log('creating new keystore with default password:', defaultPassword)
+ var secretSeed = KeyStore.generateRandomSeed()
+ keyStore = new KeyStore(secretSeed, defaultPassword)
+ keyStore.generateNewAddress(defaultPassword, 3)
+ saveKeystore()
+ }
+ keyStore.passwordProvider = unlockKeystore
+ return keyStore
+}
+
+function saveKeystore(){
+ window.localStorage['lightwallet'] = keyStore.serialize()
+}
+
+function getPassword(){
+ var password = window.sessionStorage['password']
+ if (!password) throw new Error('No password found...')
+}
+
+function unlockKeystore(cb){
+ var password = getPassword()
+ console.warn('unlocking keystore...')
+ cb(null, password)
+}
+
// // load from storage
// chrome.storage.sync.get(function(data){
// for (var key in data) {
diff --git a/app/scripts/contentscript.js b/app/scripts/contentscript.js
index 065c9f7d0..1b0de3375 100644
--- a/app/scripts/contentscript.js
+++ b/app/scripts/contentscript.js
@@ -14,7 +14,7 @@ var pageStream = new LocalMessageDuplexStream({
name: 'contentscript',
target: 'inpage',
})
-var pluginPort = chrome.runtime.connect({name: 'metamask'})
+var pluginPort = chrome.runtime.connect({name: 'contentscript'})
var pluginStream = new PortStream(pluginPort)
// forward communication across
diff --git a/app/scripts/lib/metamask-provider.js b/app/scripts/lib/metamask-provider.js
index fea6d1f9f..d7d06d3f1 100644
--- a/app/scripts/lib/metamask-provider.js
+++ b/app/scripts/lib/metamask-provider.js
@@ -3,7 +3,7 @@ const CacheSubprovider = require('web3-provider-engine/subproviders/cache.js')
const StaticSubprovider = require('web3-provider-engine/subproviders/static.js')
const FilterSubprovider = require('web3-provider-engine/subproviders/filters.js')
const VmSubprovider = require('web3-provider-engine/subproviders/vm.js')
-const LightWalletSubprovider = require('web3-provider-engine/subproviders/lightwallet.js')
+const HookedWalletSubprovider = require('web3-provider-engine/subproviders/hooked-wallet.js')
const RpcSubprovider = require('web3-provider-engine/subproviders/rpc.js')
module.exports = metamaskProvider
@@ -22,7 +22,7 @@ function metamaskProvider(opts){
eth_hashrate: '0x0',
eth_mining: false,
eth_syncing: true,
- })
+ }))
// filters
engine.addProvider(new FilterSubprovider())
@@ -31,21 +31,22 @@ function metamaskProvider(opts){
engine.addProvider(new VmSubprovider())
// id mgmt
- engine.addProvider(new LightWalletSubprovider())
+ engine.addProvider(new HookedWalletSubprovider({
+ getAccounts: opts.getAccounts,
+ sendTransaction: opts.sendTransaction,
+ }))
// data source
engine.addProvider(new RpcSubprovider({
- rpcUrl: 'https://testrpc.metamask.io/',
+ rpcUrl: opts.rpcUrl,
}))
// log new blocks
- engine.on('block', function(block){
- // lazy hack - move caching and current block to engine
- engine.currentBlock = block
- console.log('================================')
- console.log('BLOCK CHANGED:', '#'+block.number.toString('hex'), '0x'+block.hash.toString('hex'))
- console.log('================================')
- })
+ // engine.on('block', function(block){
+ // console.log('================================')
+ // console.log('BLOCK CHANGED:', '#'+block.number.toString('hex'), '0x'+block.hash.toString('hex'))
+ // console.log('================================')
+ // })
// start polling for blocks
engine.start()
diff --git a/app/scripts/popup.js b/app/scripts/popup.js
index 03530ce66..a7e33e7ff 100644
--- a/app/scripts/popup.js
+++ b/app/scripts/popup.js
@@ -1,13 +1,30 @@
+const Dnode = require('dnode')
const MetaMaskUi = require('metamask-ui')
const MetaMaskUiCss = require('metamask-ui/css')
const injectCss = require('inject-css')
+const PortStream = require('./lib/port-stream.js')
-var container = document.getElementById('app-content')
+// setup communication with background
+var pluginPort = chrome.runtime.connect({name: 'popup'})
+var duplex = new PortStream(pluginPort)
+var background = Dnode({
+ // setUnconfirmedTxs: setUnconfirmedTxs,
+})
+duplex.pipe(background).pipe(duplex)
+background.once('remote', setupApp)
+// setup app
var css = MetaMaskUiCss()
injectCss(css)
-var app = MetaMaskUi({
- container: container,
-})
+function setupApp(accountManager){
+
+ var container = document.getElementById('app-content')
+
+ var app = MetaMaskUi({
+ container: container,
+ accountManager: accountManager,
+ })
+
+} \ No newline at end of file
diff --git a/package.json b/package.json
index 237cedf00..d40353cbc 100644
--- a/package.json
+++ b/package.json
@@ -8,6 +8,8 @@
},
"dependencies": {
"async": "^1.4.0",
+ "dnode": "^1.2.2",
+ "eth-lightwallet": "^1.0.1",
"ethereumjs-tx": "^0.6.7",
"ethereumjs-util": "^1.3.5",
"inject-css": "^0.1.1",