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:
parent
92987b4407
commit
6df64970aa
@ -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)
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user