aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkumavis <aaron@kumavis.me>2016-01-17 08:22:54 +0800
committerkumavis <aaron@kumavis.me>2016-01-17 08:22:54 +0800
commit722acdad35e229c80ebb59a8d6672c430016a7b2 (patch)
treeff7bee46fa538a9b7199ce51466e7480709cb1b4
parent7347a66eb0f4d5ab7f7d95e3657179408f4319f9 (diff)
downloadtangerine-wallet-browser-722acdad35e229c80ebb59a8d6672c430016a7b2.tar
tangerine-wallet-browser-722acdad35e229c80ebb59a8d6672c430016a7b2.tar.gz
tangerine-wallet-browser-722acdad35e229c80ebb59a8d6672c430016a7b2.tar.bz2
tangerine-wallet-browser-722acdad35e229c80ebb59a8d6672c430016a7b2.tar.lz
tangerine-wallet-browser-722acdad35e229c80ebb59a8d6672c430016a7b2.tar.xz
tangerine-wallet-browser-722acdad35e229c80ebb59a8d6672c430016a7b2.tar.zst
tangerine-wallet-browser-722acdad35e229c80ebb59a8d6672c430016a7b2.zip
breakout idmgmt
-rw-r--r--app/scripts/background.js234
-rw-r--r--app/scripts/lib/idmgmt.js233
-rw-r--r--app/scripts/lib/metamask-provider.js10
3 files changed, 251 insertions, 226 deletions
diff --git a/app/scripts/background.js b/app/scripts/background.js
index 48f14172e..ca6b5abbc 100644
--- a/app/scripts/background.js
+++ b/app/scripts/background.js
@@ -1,17 +1,25 @@
const Dnode = require('dnode')
-const KeyStore = require('eth-lightwallet').keystore
const PortStream = require('./lib/port-stream.js')
const MetaMaskProvider = require('./lib/metamask-provider')
+const IdentityManager = require('./lib/idmgmt')
console.log('ready to roll')
+var wallet = IdentityManager()
+
// setup provider
var zeroClient = MetaMaskProvider({
- rpcUrl: 'https://testrpc.metamask.io/',
- getAccounts: getAccounts,
- sendTransaction: confirmTransaction,
+ rpcUrl: 'https://rawtestrpc.metamask.io/',
+ getAccounts: wallet.getAccounts.bind(wallet),
+ sendTransaction: wallet.confirmTransaction.bind(wallet),
+})
+
+wallet.setProvider(zeroClient)
+zeroClient.on('block', function(block){
+ wallet.newBlock(block)
})
+
// setup messaging
chrome.runtime.onConnect.addListener(connectRemote)
function connectRemote(remotePort){
@@ -27,13 +35,7 @@ function connectRemote(remotePort){
function handleInternalCommunication(remotePort){
var duplex = new PortStream(remotePort)
- var remote = Dnode({
- getState: getState,
- setLocked: setLocked,
- submitPassword: submitPassword,
- setSelectedAddress: setSelectedAddress,
- signTransaction: signTransaction,
- })
+ var remote = Dnode(wallet)
duplex.pipe(remote).pipe(duplex)
}
@@ -51,159 +53,6 @@ function onRpcRequest(remotePort, payload){
})
}
-// 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) {
-// var serialized = data[key]
-// var tx = deserializeTx(serialized)
-// var hash = simpleHash(serialized)
-// unsignedTxs[hash] = tx
-// }
-// updateBadge()
-// })
-
-// // listen to storage changes
-// chrome.storage.onChanged.addListener(function(changes, namespace) {
-// for (key in changes) {
-// var storageChange = changes[key]
-// if (storageChange.oldValue && !storageChange.newValue) {
-// // was removed
-// removeTransaction(storageChange.oldValue)
-// } else if (!storageChange.oldValue && storageChange.newValue) {
-// // was added
-// addTransaction(deserializeTx(storageChange.newValue))
-// }
-// }
-// })
-
// setup badge text
// updateBadge()
@@ -231,60 +80,3 @@ function unlockKeystore(cb){
// }
// }
-
-// function addTransaction(tx){
-// var serialized = serializeTx(tx)
-// var hash = simpleHash(serialized)
-// unsignedTxs[hash] = tx
-// var data = {}
-// data[hash] = serialized
-// chrome.storage.sync.set(data)
-// // trigger ui changes
-// updateBadge()
-// }
-
-// function removeTransaction(serialized){
-// var hash = simpleHash(serialized)
-// delete unsignedTxs[hash]
-// var data = {}
-// data[hash] = undefined
-// chrome.storage.sync.set(data)
-// // trigger ui changes
-// updateBadge()
-// }
-
-// function exportUnsignedTxs(remote){
-// console.log('exporting txs!', unsignedTxs)
-// var data = {
-// type: 'importUnsignedTxs',
-// payload: getValues(unsignedTxs),
-// }
-// remote.postMessage(data)
-// }
-
-// function simpleHash(input) {
-// var hash = 0, i, chr, len
-// if (input.length == 0) return hash
-// for (i = 0, len = input.length; i < len; i++) {
-// chr = input.charCodeAt(i)
-// hash = ((hash << 5) - hash) + chr
-// hash |= 0 // Convert to 32bit integer
-// }
-// return hash
-// }
-
-// function serializeTx(tx){
-// return JSON.stringify(tx)
-// }
-
-// function deserializeTx(tx){
-// return JSON.parse(tx)
-// }
-
-// function getValues(obj){
-// var output = []
-// for (var key in obj) {
-// output.push(obj[key])
-// }
-// return output
-// } \ No newline at end of file
diff --git a/app/scripts/lib/idmgmt.js b/app/scripts/lib/idmgmt.js
new file mode 100644
index 000000000..b13116a45
--- /dev/null
+++ b/app/scripts/lib/idmgmt.js
@@ -0,0 +1,233 @@
+const EventEmitter = require('events').EventEmitter
+const async = require('async')
+const KeyStore = require('eth-lightwallet').keystore
+const createPayload = require('web3-provider-engine/util/create-payload')
+var selectedAddress = null
+var identities = {}
+
+module.exports = IdentityManager
+
+
+var provider = null
+var pubsub = new EventEmitter()
+
+function IdentityManager(opts){
+ opts = opts || {}
+ providerEngine = opts.providerEngine
+
+ return {
+ // plugin popup
+ getState: getState,
+ subscribe: subscribe,
+ submitPassword: submitPassword,
+ setSelectedAddress: setSelectedAddress,
+ signTransaction: signTransaction,
+ setLocked: setLocked,
+ // eth rpc
+ getAccounts: getAccounts,
+ confirmTransaction: confirmTransaction,
+ // etc
+ newBlock: newBlock,
+ setProvider: setProvider,
+ }
+}
+
+function setProvider(_provider){
+ provider = _provider
+}
+
+function newBlock(block){
+ pubsub.emit('block', block)
+ updateIdentities()
+}
+
+// on new block, update our accounts (but only if we're unlocked)
+function subscribe(cb){
+ pubsub.on('block', sendUpdateState)
+ function sendUpdateState(){
+ if (!isUnlocked()) return
+ updateIdentities(function(){
+ var state = _getState()
+ cb(state)
+ })
+ }
+}
+
+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
+ // load identities before returning...
+ loadIdentities()
+ var state = _getState()
+ cb(null, state)
+ // trigger an update but dont wait for it
+ updateIdentities()
+ })
+}
+
+// get the current selected address
+function getAccounts(cb){
+ var result = selectedAddress ? [selectedAddress] : []
+ console.log('getAccounts:', result)
+ cb(null, result)
+}
+
+function getIdentities(){
+ return identities
+}
+
+// load identities from keyStore
+function loadIdentities(){
+ if (!isUnlocked()) throw new Error('not unlocked')
+ var keyStore = getKeyStore()
+ var addresses = keyStore.getAddresses().map(function(address){ return '0x'+address })
+ addresses.forEach(function(address){
+ var identity = {
+ name: 'Wally',
+ img: 'QmW6hcwYzXrNkuHrpvo58YeZvbZxUddv69ATSHY3BHpPdd',
+ address: address,
+ balance: null,
+ txCount: null,
+ }
+ identities[address] = identity
+ })
+}
+
+// foreach in identities, update balance + nonce
+function updateIdentities(cb){
+ cb = cb || function(){}
+ if (!isUnlocked()) return cb(new Error('Not unlocked.'))
+ var addresses = Object.keys(identities)
+ async.map(addresses, updateIdentity, cb)
+}
+
+// gets latest info from the network for the identity
+function updateIdentity(address, cb){
+ async.parallel([
+ getAccountBalance.bind(null, address),
+ getTxCount.bind(null, address),
+ ], function(err, result){
+ if (err) return cb(err)
+ var identity = identities[address]
+ identity.balance = result[0]
+ identity.txCount = result[1]
+ cb()
+ })
+}
+
+function getTxCount(address, cb){
+ provider.sendAsync(createPayload({
+ method: 'eth_getTransactionCount',
+ params: [address],
+ }), function(err, res){
+ if (err) return cb(err)
+ if (res.error) return cb(res.error)
+ cb(null, res.result)
+ })
+}
+
+function getAccountBalance(address, cb){
+ provider.sendAsync(createPayload({
+ method: 'eth_getBalance',
+ params: [address],
+ }), function(err, res){
+ if (err) return cb(err)
+ if (res.error) return cb(res.error)
+ cb(null, res.result)
+ })
+}
+
+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)
+} \ No newline at end of file
diff --git a/app/scripts/lib/metamask-provider.js b/app/scripts/lib/metamask-provider.js
index d7d06d3f1..09326e3c1 100644
--- a/app/scripts/lib/metamask-provider.js
+++ b/app/scripts/lib/metamask-provider.js
@@ -42,11 +42,11 @@ function metamaskProvider(opts){
}))
// log new blocks
- // engine.on('block', function(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()