feature/default_network_editable
brunobar79 6 years ago
parent e6d64cecf8
commit 2355573340
  1. 81
      app/scripts/eth-ledger-keyring-listener.js

@ -4,11 +4,9 @@ const ethUtil = require('ethereumjs-util')
const sigUtil = require('eth-sig-util')
const Transaction = require('ethereumjs-tx')
// HD path differs from eth-hd-keyring - MEW, Parity, Geth and Official Ledger clients use same unusual derivation for Ledger
const hdPathString = `44'/60'/0'`
const type = 'Ledger Hardware'
const ORIGIN = 'https://localhost:3000'
const BRIDGE_URL = 'https://localhost:3000'
const pathBase = 'm'
const MAX_INDEX = 1000
@ -28,18 +26,15 @@ class LedgerKeyring extends EventEmitter {
setupIframe () {
this.iframe = document.createElement('iframe')
this.iframe.src = ORIGIN
console.log('Injecting ledger iframe')
this.iframe.src = BRIDGE_URL
document.head.appendChild(this.iframe)
}
sendMessage (msg, cb) {
console.log('[LEDGER]: SENDING MESSAGE TO IFRAME', msg)
this.iframe.contentWindow.postMessage({...msg, target: 'LEDGER-IFRAME'}, '*')
window.addEventListener('message', ({ origin, data }) => {
if (origin !== ORIGIN) return false
if (origin !== BRIDGE_URL) return false
if (data && data.action && data.action === `${msg.action}-reply`) {
console.log('[LEDGER]: GOT MESAGE FROM IFRAME', data)
cb(data)
}
})
@ -75,7 +70,7 @@ class LedgerKeyring extends EventEmitter {
hdPath: this.hdPath,
},
},
({action, success, payload}) => {
({success, payload}) => {
if (success) {
this.hdk.publicKey = new Buffer(payload.publicKey, 'hex')
this.hdk.chainCode = new Buffer(payload.chainCode, 'hex')
@ -87,10 +82,6 @@ class LedgerKeyring extends EventEmitter {
})
}
setAccountToUnlock (index) {
this.unlockedAccount = parseInt(index, 10)
}
addAccounts (n = 1) {
return new Promise((resolve, reject) => {
@ -173,36 +164,44 @@ class LedgerKeyring extends EventEmitter {
// tx is an instance of the ethereumjs-transaction class.
async signTransaction (address, tx) {
return new Promise((resolve, reject) => {
this.unlock()
.then(_ => {
const newTx = new Transaction({
from: this._normalize(address),
to: this._normalize(tx.to),
value: this._normalize(tx.value),
data: this._normalize(tx.data),
chainId: tx._chainId,
nonce: this._normalize(tx.nonce),
gasLimit: this._normalize(tx.gasLimit),
gasPrice: this._normalize(tx.gasPrice),
v: ethUtil.bufferToHex(tx.getChainId()),
r: '0x00',
s: '0x00',
})
this.sendMessage({
action: 'ledger-sign-transaction',
params: {
tx: {
from: this._normalize(address),
to: this._normalize(tx.to),
value: this._normalize(tx.value),
data: this._normalize(tx.data),
chainId: tx._chainId,
nonce: this._fixNonce(this._normalize(tx.nonce)),
gasLimit: this._normalize(tx.gasLimit),
gasPrice: this._normalize(tx.gasPrice),
},
path: this._pathFromAddress(address),
tx: newTx.serialize().toString('hex'),
hdPath: this._pathFromAddress(address),
},
},
({action, success, payload}) => {
({success, payload}) => {
if (success) {
const signedTx = new Transaction(payload.txData)
// Validate that the signature matches the right address
const addressSignedWith = ethUtil.toChecksumAddress(`0x${signedTx.from.toString('hex')}`)
const correctAddress = ethUtil.toChecksumAddress(address)
if (addressSignedWith !== correctAddress) {
reject('signature doesnt match the right address')
newTx.v = Buffer.from(payload.v, 'hex')
newTx.r = Buffer.from(payload.r, 'hex')
newTx.s = Buffer.from(payload.s, 'hex')
const valid = newTx.verifySignature()
if (valid) {
resolve(newTx)
} else {
reject('The transaction signature is not valid')
}
resolve(signedTx)
} else {
reject(payload)
}
@ -225,19 +224,18 @@ class LedgerKeyring extends EventEmitter {
this.sendMessage({
action: 'ledger-sign-personal-message',
params: {
path: this._pathFromAddress(withAccount ),
hdPath: this._pathFromAddress(withAccount),
message: bufferMsg,
},
},
({action, success, payload}) => {
({success, payload}) => {
if (success) {
const { result } = payload
let v = result['v'] - 27
let v = payload['v'] - 27
v = v.toString(16)
if (v.length < 2) {
v = `0${v}`
}
const signature = `0x${result['r']}${result['s']}${v}`
const signature = `0x${payload['r']}${payload['s']}${v}`
const addressSignedWith = sigUtil.recoverPersonalSignature({data: message, sig: signature})
if (ethUtil.toChecksumAddress(addressSignedWith) !== ethUtil.toChecksumAddress(withAccount)) {
reject('signature doesnt match the right address')
@ -316,13 +314,6 @@ class LedgerKeyring extends EventEmitter {
return str
}
_fixNonce (nonce) {
if (nonce === '0x') {
return `${nonce}0`
}
return nonce
}
}
LedgerKeyring.type = type

Loading…
Cancel
Save