diff options
author | brunobar79 <brunobar79@gmail.com> | 2018-08-12 13:34:01 +0800 |
---|---|---|
committer | brunobar79 <brunobar79@gmail.com> | 2018-08-12 13:34:01 +0800 |
commit | 0b9b892c6b27c55a016378387cb8d227957f8528 (patch) | |
tree | 4a712f3e7536a2b8852863d893887b73a31a9291 /app/scripts | |
parent | 2355573340d0287582d0cd6a467e13126fbddd7c (diff) | |
download | tangerine-wallet-browser-0b9b892c6b27c55a016378387cb8d227957f8528.tar tangerine-wallet-browser-0b9b892c6b27c55a016378387cb8d227957f8528.tar.gz tangerine-wallet-browser-0b9b892c6b27c55a016378387cb8d227957f8528.tar.bz2 tangerine-wallet-browser-0b9b892c6b27c55a016378387cb8d227957f8528.tar.lz tangerine-wallet-browser-0b9b892c6b27c55a016378387cb8d227957f8528.tar.xz tangerine-wallet-browser-0b9b892c6b27c55a016378387cb8d227957f8528.tar.zst tangerine-wallet-browser-0b9b892c6b27c55a016378387cb8d227957f8528.zip |
this should be ready to go
Diffstat (limited to 'app/scripts')
-rw-r--r-- | app/scripts/eth-ledger-keyring-listener.js | 320 | ||||
-rw-r--r-- | app/scripts/metamask-controller.js | 6 |
2 files changed, 3 insertions, 323 deletions
diff --git a/app/scripts/eth-ledger-keyring-listener.js b/app/scripts/eth-ledger-keyring-listener.js deleted file mode 100644 index 91507455a..000000000 --- a/app/scripts/eth-ledger-keyring-listener.js +++ /dev/null @@ -1,320 +0,0 @@ -const {EventEmitter} = require('events') -const HDKey = require('hdkey') -const ethUtil = require('ethereumjs-util') -const sigUtil = require('eth-sig-util') -const Transaction = require('ethereumjs-tx') - -const hdPathString = `44'/60'/0'` -const type = 'Ledger Hardware' -const BRIDGE_URL = 'https://localhost:3000' -const pathBase = 'm' -const MAX_INDEX = 1000 - -class LedgerKeyring extends EventEmitter { - constructor (opts = {}) { - super() - this.type = type - this.page = 0 - this.perPage = 5 - this.unlockedAccount = 0 - this.hdk = new HDKey() - this.paths = {} - this.iframe = null - this.setupIframe() - this.deserialize(opts) - } - - setupIframe () { - this.iframe = document.createElement('iframe') - this.iframe.src = BRIDGE_URL - document.head.appendChild(this.iframe) - } - - sendMessage (msg, cb) { - this.iframe.contentWindow.postMessage({...msg, target: 'LEDGER-IFRAME'}, '*') - window.addEventListener('message', ({ origin, data }) => { - if (origin !== BRIDGE_URL) return false - if (data && data.action && data.action === `${msg.action}-reply`) { - cb(data) - } - }) - } - - serialize () { - return Promise.resolve({hdPath: this.hdPath, accounts: this.accounts}) - } - - deserialize (opts = {}) { - this.hdPath = opts.hdPath || hdPathString - this.unlocked = opts.unlocked || false - this.accounts = opts.accounts || [] - return Promise.resolve() - } - - isUnlocked () { - return this.unlocked - } - - setAccountToUnlock (index) { - this.unlockedAccount = parseInt(index, 10) - } - - unlock () { - - if (this.isUnlocked()) return Promise.resolve('already unlocked') - - return new Promise((resolve, reject) => { - this.sendMessage({ - action: 'ledger-unlock', - params: { - hdPath: this.hdPath, - }, - }, - ({success, payload}) => { - if (success) { - this.hdk.publicKey = new Buffer(payload.publicKey, 'hex') - this.hdk.chainCode = new Buffer(payload.chainCode, 'hex') - resolve('just unlocked') - } else { - reject(payload.error || 'Unknown error') - } - }) - }) - } - - addAccounts (n = 1) { - - return new Promise((resolve, reject) => { - this.unlock() - .then(_ => { - const from = this.unlockedAccount - const to = from + n - this.accounts = [] - - for (let i = from; i < to; i++) { - const address = this._addressFromIndex(pathBase, i) - this.accounts.push(address) - this.page = 0 - } - resolve(this.accounts) - }) - .catch(e => { - reject(e) - }) - }) - } - - getFirstPage () { - this.page = 0 - return this.__getPage(1) - } - - getNextPage () { - return this.__getPage(1) - } - - getPreviousPage () { - return this.__getPage(-1) - } - - __getPage (increment) { - - this.page += increment - - if (this.page <= 0) { this.page = 1 } - - return new Promise((resolve, reject) => { - this.unlock() - .then(_ => { - - const from = (this.page - 1) * this.perPage - const to = from + this.perPage - - const accounts = [] - - for (let i = from; i < to; i++) { - const address = this._addressFromIndex(pathBase, i) - accounts.push({ - address: address, - balance: null, - index: i, - }) - this.paths[ethUtil.toChecksumAddress(address)] = i - - } - resolve(accounts) - }) - .catch(e => { - reject(e) - }) - }) - } - - getAccounts () { - return Promise.resolve(this.accounts.slice()) - } - - removeAccount (address) { - if (!this.accounts.map(a => a.toLowerCase()).includes(address.toLowerCase())) { - throw new Error(`Address ${address} not found in this keyring`) - } - this.accounts = this.accounts.filter(a => a.toLowerCase() !== address.toLowerCase()) - } - - - // 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: newTx.serialize().toString('hex'), - hdPath: this._pathFromAddress(address), - }, - }, - ({success, payload}) => { - if (success) { - - 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') - } - } else { - reject(payload) - } - }) - }) - }) - } - - async signMessage (withAccount, data) { - throw new Error('Not supported on this device') - } - - // For personal_sign, we need to prefix the message: - async signPersonalMessage (withAccount, message) { - const humanReadableMsg = this._toAscii(message) - const bufferMsg = Buffer.from(humanReadableMsg).toString('hex') - return new Promise((resolve, reject) => { - this.unlock() - .then(_ => { - this.sendMessage({ - action: 'ledger-sign-personal-message', - params: { - hdPath: this._pathFromAddress(withAccount), - message: bufferMsg, - }, - }, - ({success, payload}) => { - if (success) { - let v = payload['v'] - 27 - v = v.toString(16) - if (v.length < 2) { - v = `0${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') - } - resolve(signature) - } else { - reject(payload) - } - }) - }) - }) - } - - async signTypedData (withAccount, typedData) { - throw new Error('Not supported on this device') - } - - async exportAccount (address) { - throw new Error('Not supported on this device') - } - - forgetDevice () { - this.accounts = [] - this.unlocked = false - this.page = 0 - this.unlockedAccount = 0 - this.paths = {} - } - - /* PRIVATE METHODS */ - - _padLeftEven (hex) { - return hex.length % 2 !== 0 ? `0${hex}` : hex - } - - _normalize (buf) { - return this._padLeftEven(ethUtil.bufferToHex(buf).toLowerCase()) - } - - _addressFromIndex (pathBase, i) { - const dkey = this.hdk.derive(`${pathBase}/${i}`) - const address = ethUtil - .publicToAddress(dkey.publicKey, true) - .toString('hex') - return ethUtil.toChecksumAddress(address) - } - - _pathFromAddress (address) { - const checksummedAddress = ethUtil.toChecksumAddress(address) - let index = this.paths[checksummedAddress] - if (typeof index === 'undefined') { - for (let i = 0; i < MAX_INDEX; i++) { - if (checksummedAddress === this._addressFromIndex(pathBase, i)) { - index = i - break - } - } - } - - if (typeof index === 'undefined') { - throw new Error('Unknown address') - } - return `${this.hdPath}/${index}` - } - - _toAscii (hex) { - let str = '' - let i = 0; const l = hex.length - if (hex.substring(0, 2) === '0x') { - i = 2 - } - for (; i < l; i += 2) { - const code = parseInt(hex.substr(i, 2), 16) - str += String.fromCharCode(code) - } - - return str - } -} - -LedgerKeyring.type = type -module.exports = LedgerKeyring diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index c79e5141e..fed00077e 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -49,7 +49,7 @@ const seedPhraseVerifier = require('./lib/seed-phrase-verifier') const cleanErrorStack = require('./lib/cleanErrorStack') const log = require('loglevel') const TrezorKeyring = require('eth-trezor-keyring') -const LedgerKeyring = require('./eth-ledger-keyring-listener') +const LedgerBridgeKeyring = require('eth-ledger-bridge-keyring') module.exports = class MetamaskController extends EventEmitter { @@ -128,7 +128,7 @@ module.exports = class MetamaskController extends EventEmitter { }) // key mgmt - const additionalKeyrings = [TrezorKeyring, LedgerKeyring] + const additionalKeyrings = [TrezorKeyring, LedgerBridgeKeyring] this.keyringController = new KeyringController({ keyringTypes: additionalKeyrings, initState: initState.KeyringController, @@ -546,7 +546,7 @@ module.exports = class MetamaskController extends EventEmitter { keyringName = TrezorKeyring.type break case 'ledger': - keyringName = LedgerKeyring.type + keyringName = LedgerBridgeKeyring.type break default: throw new Error('MetamaskController:connectHardware - Unknown device') |