aboutsummaryrefslogtreecommitdiffstats
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/scripts/background.js5
-rw-r--r--app/scripts/lib/idStore.js231
2 files changed, 95 insertions, 141 deletions
diff --git a/app/scripts/background.js b/app/scripts/background.js
index 17238f227..fb2fad54b 100644
--- a/app/scripts/background.js
+++ b/app/scripts/background.js
@@ -62,7 +62,7 @@ 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)
+ console.log('MetaMaskPlugin - RPC complete:', payload, '->', response)
try {
remotePort.postMessage(response)
} catch (_) {
@@ -84,9 +84,8 @@ function handleInternalCommunication(remotePort){
createNewVault: idStore.createNewVault.bind(idStore),
submitPassword: idStore.submitPassword.bind(idStore),
setSelectedAddress: idStore.setSelectedAddress.bind(idStore),
- signTransaction: idStore.signTransaction.bind(idStore),
+ approveTransaction: idStore.approveTransaction.bind(idStore),
cancelTransaction: idStore.cancelTransaction.bind(idStore),
- sendTransaction: idStore.sendTransaction.bind(idStore),
setLocked: idStore.setLocked.bind(idStore),
})
duplex.pipe(connection).pipe(duplex)
diff --git a/app/scripts/lib/idStore.js b/app/scripts/lib/idStore.js
index d26a7391c..366372442 100644
--- a/app/scripts/lib/idStore.js
+++ b/app/scripts/lib/idStore.js
@@ -1,7 +1,8 @@
const EventEmitter = require('events').EventEmitter
const inherits = require('util').inherits
const Transaction = require('ethereumjs-tx')
-const KeyStore = require('eth-lightwallet').keystore
+const LightwalletKeyStore = require('eth-lightwallet').keystore
+const LightwalletSigner = require('eth-lightwallet').signing
const async = require('async')
const clone = require('clone')
const extend = require('xtend')
@@ -18,6 +19,10 @@ function IdentityStore(ethStore) {
// we just use the ethStore to auto-add accounts
self._ethStore = ethStore
+ // lightwallet key store
+ self._keyStore = null
+ // lightwallet wrapper
+ self._idmgmt = null
self._currentState = {
selectedAddress: null,
@@ -36,11 +41,13 @@ IdentityStore.prototype.createNewVault = function(password, cb){
const self = this
delete self._keyStore
delete window.localStorage['lightwallet']
- var keyStore = self._getKeyStore(password)
- var seedWords = keyStore.getSeed(password)
- self._loadIdentities()
- self._didUpdate()
- cb(null, seedWords)
+ var keyStore = self._createIdmgmt(password, function(err){
+ if (err) return cb(err)
+ var seedWords = self._idmgmt.getSeed()
+ self._loadIdentities()
+ self._didUpdate()
+ cb(null, seedWords)
+ })
}
@@ -69,141 +76,93 @@ IdentityStore.prototype.setSelectedAddress = function(address){
self._didUpdate()
}
-IdentityStore.prototype.addUnconfirmedTransaction = function(txParams, cb){
- var self = this
-
- var time = (new Date()).getTime()
- var txId = createId()
- self._currentState.unconfTxs[txId] = {
- id: txId,
- txParams: txParams,
- time: time,
- status: 'unconfirmed',
- }
- console.log('addUnconfirmedTransaction:', txParams)
-
- // temp - just sign the tx
- // otherwise we need to keep the cb around
- // signTransaction(txId, cb)
- self._unconfTxCbs[txId] = cb
-
- // signal update
- self._didUpdate()
-}
-
-
-
IdentityStore.prototype.setLocked = function(){
const self = this
delete self._keyStore
+ delete self._idmgmt
}
IdentityStore.prototype.submitPassword = function(password, cb){
const self = this
- console.log('submitPassword:', password)
self._tryPassword(password, function(err){
- if (err) console.log('bad password:', password, err)
if (err) return cb(err)
- console.log('good password:', password)
// load identities before returning...
self._loadIdentities()
cb()
})
}
-IdentityStore.prototype.signTransaction = function(password, txId, cb){
- const self = this
-
- var txData = self._currentState.unconfTxs[txId]
- var txParams = txData.txParams
+// comes from dapp via zero-client hooked-wallet provider
+IdentityStore.prototype.addUnconfirmedTransaction = function(txParams, cb){
+ var self = this
- self._signTransaction(password, txParams, function(err, rawTx, txHash){
- if (err) {
- cb(err)
- txData.status = 'error'
- txData.error = err
- self._didUpdate()
- return
- }
+ // create txData obj with parameters and meta data
+ var time = (new Date()).getTime()
+ var txId = createId()
+ var txData = {
+ id: txId,
+ txParams: txParams,
+ time: time,
+ status: 'unconfirmed',
+ }
+ self._currentState.unconfTxs[txId] = txData
+ console.log('addUnconfirmedTransaction:', txData)
- txData.rawTx = rawTx
- txData.hash = txHash
- txData.status = 'signed'
+ // keep the cb around for after approval (requires user interaction)
+ self._unconfTxCbs[txId] = cb
- // confirm tx signed
- cb()
- self._didUpdate()
- })
+ // signal update
+ self._didUpdate()
}
-IdentityStore.prototype.sendTransaction = function(txId, cb){
+// comes from metamask ui
+IdentityStore.prototype.approveTransaction = function(txId, cb){
const self = this
var txData = self._currentState.unconfTxs[txId]
+ var txParams = txData.txParams
+ var approvalCb = self._unconfTxCbs[txId] || noop
- if (!txData || txData.status !== 'signed') {
- return cb(new Error('IdentityStore - Transaction not signed:', txId))
- }
-
- var rawTx = txData.rawTx
-
- // for now just remove it
- delete self._currentState.unconfTxs[txData.id]
-
- // rpc callback
- var txSigCb = self._unconfTxCbs[txId] || noop
- txSigCb(null, rawTx)
-
- // confirm tx sent
+ // accept tx
cb()
+ approvalCb(null, true)
+ // clean up
+ delete self._currentState.unconfTxs[txId]
+ delete self._unconfTxCbs[txId]
self._didUpdate()
}
+// comes from metamask ui
IdentityStore.prototype.cancelTransaction = function(txId){
const self = this
var txData = self._currentState.unconfTxs[txId]
+ var approvalCb = self._unconfTxCbs[txId] || noop
+
+ // reject tx
+ approvalCb(null, false)
+ // clean up
delete self._currentState.unconfTxs[txId]
+ delete self._unconfTxCbs[txId]
self._didUpdate()
}
-//
-// private
-//
-
-// internal - actually signs the tx
-IdentityStore.prototype._signTransaction = function(password, txParams, cb){
+// performs the actual signing, no autofill of params
+IdentityStore.prototype.signTransaction = function(txParams, cb){
const self = this
try {
- // console.log('signing tx:', txParams)
- var tx = new Transaction({
- nonce: txParams.nonce,
- to: txParams.to,
- value: txParams.value,
- data: txParams.data,
- gasPrice: txParams.gasPrice,
- gasLimit: txParams.gas,
- })
-
- var serializedTx = self._keyStore.signTx(tx.serialize(), password, self._currentState.selectedAddress)
-
- // // deserialize and dump values to confirm configuration
- // var verifyTx = new Transaction(tx.serialize())
- // console.log('signed transaction:', {
- // to: '0x'+verifyTx.to.toString('hex'),
- // from: '0x'+verifyTx.from.toString('hex'),
- // nonce: '0x'+verifyTx.nonce.toString('hex'),
- // value: (ethUtil.bufferToInt(verifyTx.value)/1e18)+' ether',
- // data: '0x'+verifyTx.data.toString('hex'),
- // gasPrice: '0x'+verifyTx.gasPrice.toString('hex'),
- // gasLimit: '0x'+verifyTx.gasLimit.toString('hex'),
- // })
- cb(null, serializedTx, tx.hash())
+ console.log('signing tx...', txParams)
+ var rawTx = self._idmgmt.signTx(txParams)
+ cb(null, rawTx)
} catch (err) {
cb(err)
}
}
+//
+// private
+//
+
IdentityStore.prototype._didUpdate = function(){
const self = this
self.emit('update', self.getState())
@@ -211,8 +170,7 @@ IdentityStore.prototype._didUpdate = function(){
IdentityStore.prototype._isUnlocked = function(){
const self = this
- // var result = Boolean(password)
- var result = Boolean(self._keyStore)
+ var result = Boolean(self._keyStore) && Boolean(self._idmgmt)
return result
}
@@ -242,48 +200,45 @@ IdentityStore.prototype._loadIdentities = function(){
IdentityStore.prototype._tryPassword = function(password, cb){
const self = this
- var keyStore = self._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()
+ self._createIdmgmt(password, cb)
}
-IdentityStore.prototype._getKeyStore = function(password){
+IdentityStore.prototype._createIdmgmt = function(password, cb){
const self = this
var keyStore = null
- var serializedKeystore = window.localStorage['lightwallet']
- // returning user
- if (serializedKeystore) {
- keyStore = KeyStore.deserialize(serializedKeystore)
- // first time here
- } else {
- console.log('creating new keystore with password:', password)
- var secretSeed = KeyStore.generateRandomSeed()
- keyStore = new KeyStore(secretSeed, password)
- keyStore.generateNewAddress(password, 3)
- self._saveKeystore(keyStore)
- }
- keyStore.passwordProvider = function getPassword(cb){
- cb(null, password)
- }
- self._keyStore = keyStore
- return keyStore
-}
-
-IdentityStore.prototype._saveKeystore = function(keyStore){
- const self = this
- window.localStorage['lightwallet'] = keyStore.serialize()
- console.log('saved to localStorage')
+ LightwalletKeyStore.deriveKeyFromPassword(password, function(err, derrivedKey){
+ if (err) return cb(err)
+ var serializedKeystore = window.localStorage['lightwallet']
+ // returning user
+ if (serializedKeystore) {
+ keyStore = LightwalletKeyStore.deserialize(serializedKeystore)
+ var isCorrect = keyStore.isDerivedKeyCorrect(derrivedKey)
+ if (!isCorrect) return cb(new Error('Lightwallet - password incorrect'))
+ // first time here
+ } else {
+ var secretSeed = LightwalletKeyStore.generateRandomSeed()
+ keyStore = new LightwalletKeyStore(secretSeed, derrivedKey)
+ keyStore.generateNewAddress(derrivedKey, 3)
+ window.localStorage['lightwallet'] = keyStore.serialize()
+ console.log('saved to keystore localStorage')
+ }
+ self._keyStore = keyStore
+ self._idmgmt = {
+ getAddresses: function(){
+ return keyStore.getAddresses().map(function(address){ return '0x'+address })
+ },
+ signTx: function(txParams){
+ txParams.gasLimit = txParams.gas
+ var tx = new Transaction(txParams)
+ var rawTx = '0x'+tx.serialize().toString('hex')
+ return '0x'+LightwalletSigner.signTx(keyStore, derrivedKey, rawTx, txParams.from)
+ },
+ getSeed: function(){
+ return keyStore.getSeed(derrivedKey)
+ },
+ }
+ cb()
+ })
}
// util