1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-12-23 01:39:44 +01:00

tx sig - it works again

This commit is contained in:
kumavis 2016-03-02 22:58:23 -08:00
parent 92987b4407
commit 6df64970aa
2 changed files with 102 additions and 148 deletions

View File

@ -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)

View File

@ -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){
// comes from dapp via zero-client hooked-wallet provider
IdentityStore.prototype.addUnconfirmedTransaction = function(txParams, cb){
var self = this
// 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)
// keep the cb around for after approval (requires user interaction)
self._unconfTxCbs[txId] = cb
// signal update
self._didUpdate()
}
// 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
self._signTransaction(password, txParams, function(err, rawTx, txHash){
if (err) {
cb(err)
txData.status = 'error'
txData.error = err
self._didUpdate()
return
}
txData.rawTx = rawTx
txData.hash = txHash
txData.status = 'signed'
// confirm tx signed
cb()
self._didUpdate()
})
}
IdentityStore.prototype.sendTransaction = function(txId, cb){
const self = this
var txData = self._currentState.unconfTxs[txId]
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()
}
// performs the actual signing, no autofill of params
IdentityStore.prototype.signTransaction = function(txParams, cb){
const self = this
try {
console.log('signing tx...', txParams)
var rawTx = self._idmgmt.signTx(txParams)
cb(null, rawTx)
} catch (err) {
cb(err)
}
}
//
// private
//
// internal - actually signs the tx
IdentityStore.prototype._signTransaction = function(password, 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())
} catch (err) {
cb(err)
}
}
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