mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
able to add accounts
This commit is contained in:
parent
78a1cd3314
commit
8e842a8947
@ -1,11 +1,16 @@
|
|||||||
const extension = require('extensionizer')
|
const extension = require('extensionizer')
|
||||||
const {EventEmitter} = require('events')
|
const {EventEmitter} = require('events')
|
||||||
|
const HDKey = require('hdkey')
|
||||||
|
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
|
// HD path differs from eth-hd-keyring - MEW, Parity, Geth and Official Ledger clients use same unusual derivation for Ledger
|
||||||
const hdPathString = `m/44'/60'/0'`
|
const hdPathString = `m/44'/60'/0'`
|
||||||
const type = 'Ledger Hardware Keyring'
|
const type = 'Ledger Hardware Keyring'
|
||||||
const ORIGIN = 'http://localhost:9000'
|
const ORIGIN = 'https://localhost:3000'
|
||||||
|
const pathBase = 'm'
|
||||||
|
|
||||||
class LedgerKeyring extends EventEmitter {
|
class LedgerKeyring extends EventEmitter {
|
||||||
constructor (opts = {}) {
|
constructor (opts = {}) {
|
||||||
@ -14,6 +19,7 @@ class LedgerKeyring extends EventEmitter {
|
|||||||
this.page = 0
|
this.page = 0
|
||||||
this.perPage = 5
|
this.perPage = 5
|
||||||
this.unlockedAccount = 0
|
this.unlockedAccount = 0
|
||||||
|
this.hdk = new HDKey()
|
||||||
this.paths = {}
|
this.paths = {}
|
||||||
this.iframe = null
|
this.iframe = null
|
||||||
this.setupIframe()
|
this.setupIframe()
|
||||||
@ -26,10 +32,6 @@ class LedgerKeyring extends EventEmitter {
|
|||||||
console.log('Injecting ledger iframe')
|
console.log('Injecting ledger iframe')
|
||||||
document.head.appendChild(this.iframe)
|
document.head.appendChild(this.iframe)
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
Passing messages from iframe to background script
|
|
||||||
*/
|
|
||||||
console.log('[LEDGER]: LEDGER FROM-IFRAME LISTENER READY')
|
console.log('[LEDGER]: LEDGER FROM-IFRAME LISTENER READY')
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -78,32 +80,39 @@ class LedgerKeyring extends EventEmitter {
|
|||||||
},
|
},
|
||||||
({action, success, payload}) => {
|
({action, success, payload}) => {
|
||||||
if (success) {
|
if (success) {
|
||||||
resolve(payload)
|
this.hdk.publicKey = new Buffer(payload.publicKey, 'hex')
|
||||||
|
this.hdk.chainCode = new Buffer(payload.chainCode, 'hex')
|
||||||
|
resolve('just unlocked')
|
||||||
} else {
|
} else {
|
||||||
reject(payload)
|
reject(payload.error || 'Unknown error')
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async addAccounts (n = 1) {
|
setAccountToUnlock (index) {
|
||||||
|
this.unlockedAccount = parseInt(index, 10)
|
||||||
|
}
|
||||||
|
|
||||||
|
addAccounts (n = 1) {
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this.unlock()
|
this.unlock()
|
||||||
.then(_ => {
|
.then(_ => {
|
||||||
this.sendMessage({
|
const from = this.unlockedAccount
|
||||||
action: 'ledger-add-account',
|
const to = from + n
|
||||||
params: {
|
this.accounts = []
|
||||||
n,
|
|
||||||
},
|
for (let i = from; i < to; i++) {
|
||||||
},
|
const address = this._addressFromIndex(pathBase, i)
|
||||||
({action, success, payload}) => {
|
this.accounts.push(address)
|
||||||
if (success) {
|
this.page = 0
|
||||||
resolve(payload)
|
}
|
||||||
} else {
|
resolve(this.accounts)
|
||||||
reject(payload)
|
})
|
||||||
}
|
.catch(e => {
|
||||||
|
reject(e)
|
||||||
})
|
})
|
||||||
})
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,20 +138,27 @@ class LedgerKeyring extends EventEmitter {
|
|||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this.unlock()
|
this.unlock()
|
||||||
.then(_ => {
|
.then(_ => {
|
||||||
this.sendMessage({
|
|
||||||
action: 'ledger-get-page',
|
const from = (this.page - 1) * this.perPage
|
||||||
params: {
|
const to = from + this.perPage
|
||||||
page: this.page,
|
|
||||||
},
|
const accounts = []
|
||||||
},
|
|
||||||
({action, success, payload}) => {
|
for (let i = from; i < to; i++) {
|
||||||
if (success) {
|
const address = this._addressFromIndex(pathBase, i)
|
||||||
resolve(payload)
|
accounts.push({
|
||||||
} else {
|
address: address,
|
||||||
reject(payload)
|
balance: null,
|
||||||
}
|
index: i,
|
||||||
})
|
})
|
||||||
})
|
this.paths[ethUtil.toChecksumAddress(address)] = i
|
||||||
|
|
||||||
|
}
|
||||||
|
resolve(accounts)
|
||||||
|
})
|
||||||
|
.catch(e => {
|
||||||
|
reject(e)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,6 +173,7 @@ class LedgerKeyring extends EventEmitter {
|
|||||||
this.accounts = this.accounts.filter(a => a.toLowerCase() !== address.toLowerCase())
|
this.accounts = this.accounts.filter(a => a.toLowerCase() !== address.toLowerCase())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// tx is an instance of the ethereumjs-transaction class.
|
// tx is an instance of the ethereumjs-transaction class.
|
||||||
async signTransaction (address, tx) {
|
async signTransaction (address, tx) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
@ -224,6 +241,56 @@ class LedgerKeyring extends EventEmitter {
|
|||||||
this.unlockedAccount = 0
|
this.unlockedAccount = 0
|
||||||
this.paths = {}
|
this.paths = {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* PRIVATE METHODS */
|
||||||
|
|
||||||
|
_padLeftEven (hex) {
|
||||||
|
return hex.length % 2 !== 0 ? `0${hex}` : hex
|
||||||
|
}
|
||||||
|
|
||||||
|
_normalize (buf) {
|
||||||
|
return this._padLeftEven(ethUtil.bufferToHex(buf).substring(2).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
|
LedgerKeyring.type = type
|
||||||
|
@ -615,7 +615,7 @@ module.exports = class MetamaskController extends EventEmitter {
|
|||||||
*
|
*
|
||||||
* @returns {} keyState
|
* @returns {} keyState
|
||||||
*/
|
*/
|
||||||
async unlockHardwareWalletAccount (deviceName, index) {
|
async unlockHardwareWalletAccount (index, deviceName) {
|
||||||
const keyring = await this.getKeyringForDevice(deviceName)
|
const keyring = await this.getKeyringForDevice(deviceName)
|
||||||
|
|
||||||
keyring.setAccountToUnlock(index)
|
keyring.setAccountToUnlock(index)
|
||||||
|
@ -11,7 +11,7 @@ class AccountList extends Component {
|
|||||||
renderHeader () {
|
renderHeader () {
|
||||||
return (
|
return (
|
||||||
h('div.hw-connect', [
|
h('div.hw-connect', [
|
||||||
h('h3.hw-connect__title', {}, this.context.t('selectAnAccount')),
|
h('h3.hw-connect__title', {}, `${this.props.device.toUpperCase()} - ${this.context.t('selectAnAccount')}`),
|
||||||
h('p.hw-connect__msg', {}, this.context.t('selectAnAccountHelp')),
|
h('p.hw-connect__msg', {}, this.context.t('selectAnAccountHelp')),
|
||||||
])
|
])
|
||||||
)
|
)
|
||||||
|
@ -128,13 +128,13 @@ class ConnectHardwareForm extends Component {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
onUnlockAccount = () => {
|
onUnlockAccount = (device) => {
|
||||||
|
|
||||||
if (this.state.selectedAccount === null) {
|
if (this.state.selectedAccount === null) {
|
||||||
this.setState({ error: this.context.t('accountSelectionRequired') })
|
this.setState({ error: this.context.t('accountSelectionRequired') })
|
||||||
}
|
}
|
||||||
|
|
||||||
this.props.unlockHardwareWalletAccount(this.state.selectedAccount, this.state.device)
|
this.props.unlockHardwareWalletAccount(this.state.selectedAccount, device)
|
||||||
.then(_ => {
|
.then(_ => {
|
||||||
this.props.history.push(DEFAULT_ROUTE)
|
this.props.history.push(DEFAULT_ROUTE)
|
||||||
}).catch(e => {
|
}).catch(e => {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user