mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
sign transactions is pretty close
This commit is contained in:
parent
d1880073f6
commit
68d97211ff
@ -4,10 +4,11 @@ const ethUtil = require('ethereumjs-util')
|
||||
|
||||
const hdPathString = `m/44'/60'/0'/0`
|
||||
const keyringType = 'Trezor Hardware'
|
||||
|
||||
const Transaction = require('ethereumjs-tx')
|
||||
const pathBase = 'm'
|
||||
const TrezorConnect = require('./trezor-connect.js')
|
||||
const HDKey = require('hdkey')
|
||||
const TREZOR_FIRMWARE_VERSION = '1.4.0'
|
||||
const TREZOR_MIN_FIRMWARE_VERSION = '1.5.2'
|
||||
const log = require('loglevel')
|
||||
|
||||
class TrezorKeyring extends EventEmitter {
|
||||
@ -19,7 +20,7 @@ class TrezorKeyring extends EventEmitter {
|
||||
this.deserialize(opts)
|
||||
this.page = 0
|
||||
this.perPage = 5
|
||||
this.accountToUnlock = 0
|
||||
this.unlockedAccount = 0
|
||||
}
|
||||
|
||||
serialize () {
|
||||
@ -53,13 +54,13 @@ class TrezorKeyring extends EventEmitter {
|
||||
reject(response.error || 'Unknown error')
|
||||
}
|
||||
},
|
||||
TREZOR_FIRMWARE_VERSION
|
||||
TREZOR_MIN_FIRMWARE_VERSION
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
setAccountToUnlock (index) {
|
||||
this.accountToUnlock = parseInt(index, 10)
|
||||
this.unlockedAccount = parseInt(index, 10)
|
||||
}
|
||||
|
||||
addAccounts (n = 1) {
|
||||
@ -67,18 +68,13 @@ class TrezorKeyring extends EventEmitter {
|
||||
return new Promise((resolve, reject) => {
|
||||
return this.unlock()
|
||||
.then(_ => {
|
||||
const pathBase = 'm'
|
||||
const from = this.accountToUnlock
|
||||
const from = this.unlockedAccount
|
||||
const to = from + 1
|
||||
|
||||
this.accounts = []
|
||||
|
||||
for (let i = from; i < to; i++) {
|
||||
const dkey = this.hdk.derive(`${pathBase}/${i}`)
|
||||
const address = ethUtil
|
||||
.publicToAddress(dkey.publicKey, true)
|
||||
.toString('hex')
|
||||
this.accounts.push(ethUtil.toChecksumAddress(address))
|
||||
|
||||
this.accounts.push(this.getEthAddress(pathBase, i))
|
||||
this.page = 0
|
||||
}
|
||||
resolve(this.accounts)
|
||||
@ -94,19 +90,16 @@ class TrezorKeyring extends EventEmitter {
|
||||
return new Promise((resolve, reject) => {
|
||||
return this.unlock()
|
||||
.then(_ => {
|
||||
const pathBase = 'm'
|
||||
|
||||
const from = this.page === 0 ? 0 : (this.page - 1) * this.perPage
|
||||
const to = from + this.perPage
|
||||
|
||||
const accounts = []
|
||||
|
||||
for (let i = from; i < to; i++) {
|
||||
const dkey = this.hdk.derive(`${pathBase}/${i}`)
|
||||
const address = ethUtil
|
||||
.publicToAddress(dkey.publicKey, true)
|
||||
.toString('hex')
|
||||
|
||||
accounts.push({
|
||||
address: ethUtil.toChecksumAddress(address),
|
||||
address: this.getEthAddress(pathBase, i),
|
||||
balance: 0,
|
||||
index: i,
|
||||
})
|
||||
@ -134,40 +127,75 @@ class TrezorKeyring extends EventEmitter {
|
||||
return Promise.resolve(this.accounts.slice())
|
||||
}
|
||||
|
||||
padLeftEven (hex) {
|
||||
return hex.length % 2 !== 0 ? `0${hex}` : hex
|
||||
}
|
||||
|
||||
cleanData (buf) {
|
||||
return this.padLeftEven(ethUtil.bufferToHex(buf).substring(2).toLowerCase())
|
||||
}
|
||||
|
||||
getEthAddress (pathBase, i) {
|
||||
const dkey = this.hdk.derive(`${pathBase}/${i}`)
|
||||
const address = ethUtil
|
||||
.publicToAddress(dkey.publicKey, true)
|
||||
.toString('hex')
|
||||
return ethUtil.toChecksumAddress(address)
|
||||
}
|
||||
|
||||
// tx is an instance of the ethereumjs-transaction class.
|
||||
async signTransaction (address, tx) {
|
||||
throw new Error('Not supported on this device')
|
||||
/*
|
||||
await this.lock.acquire()
|
||||
try {
|
||||
|
||||
// Look before we leap
|
||||
await this._checkCorrectTrezorAttached()
|
||||
return new Promise((resolve, reject) => {
|
||||
log.debug('sign transaction ', address, tx)
|
||||
const account = `m/44'/60'/0'/${this.unlockedAccount}`
|
||||
|
||||
let accountId = await this._findAddressId(address)
|
||||
let eth = await this._getEth()
|
||||
tx.v = tx._chainId
|
||||
let TrezorSig = await eth.signTransaction(
|
||||
this._derivePath(accountId),
|
||||
tx.serialize().toString('hex')
|
||||
)
|
||||
tx.v = parseInt(TrezorSig.v, 16)
|
||||
tx.r = '0x' + TrezorSig.r
|
||||
tx.s = '0x' + TrezorSig.s
|
||||
const txData = {
|
||||
account,
|
||||
nonce: this.cleanData(tx.nonce),
|
||||
gasPrice: this.cleanData(tx.gasPrice),
|
||||
gasLimit: this.cleanData(tx.gasLimit),
|
||||
to: this.cleanData(tx.to),
|
||||
value: this.cleanData(tx.value),
|
||||
data: this.cleanData(tx.data),
|
||||
chainId: tx._chainId,
|
||||
}
|
||||
|
||||
// Since look before we leap check is racy, also check that signature is for account expected
|
||||
let addressSignedWith = ethUtil.bufferToHex(tx.getSenderAddress())
|
||||
if (addressSignedWith.toLowerCase() !== address.toLowerCase()) {
|
||||
throw new Error(
|
||||
`Signature is for ${addressSignedWith} but expected ${address} - is the correct Trezor device attached?`
|
||||
)
|
||||
}
|
||||
TrezorConnect.ethereumSignTx(
|
||||
txData.account,
|
||||
txData.nonce,
|
||||
txData.gasPrice,
|
||||
txData.gasLimit,
|
||||
txData.to,
|
||||
txData.value,
|
||||
txData.data === '' ? null : txData.data,
|
||||
txData.chainId,
|
||||
response => {
|
||||
if (response.success) {
|
||||
tx.v = `0x${response.v.toString(16)}`
|
||||
tx.r = `0x${response.r}`
|
||||
tx.s = `0x${response.s}`
|
||||
log.debug('about to create new tx with data', tx)
|
||||
|
||||
return tx
|
||||
const signedTx = new Transaction(tx)
|
||||
|
||||
} finally {
|
||||
await this.lock.release()
|
||||
}*/
|
||||
log.debug('signature is valid?', signedTx.verifySignature())
|
||||
|
||||
const addressSignedWith = ethUtil.toChecksumAddress(`0x${signedTx.from.toString('hex')}`)
|
||||
const correctAddress = ethUtil.toChecksumAddress(address)
|
||||
if (addressSignedWith !== correctAddress) {
|
||||
// throw new Error('signature doesnt match the right address')
|
||||
log.error('signature doesnt match the right address', addressSignedWith, correctAddress)
|
||||
}
|
||||
|
||||
resolve(signedTx)
|
||||
|
||||
} else {
|
||||
throw new Error(response.error || 'Unknown error')
|
||||
}
|
||||
},
|
||||
TREZOR_MIN_FIRMWARE_VERSION)
|
||||
})
|
||||
}
|
||||
|
||||
async signMessage (withAccount, data) {
|
||||
|
Loading…
Reference in New Issue
Block a user