aboutsummaryrefslogtreecommitdiffstats
path: root/app
diff options
context:
space:
mode:
authorDan Finlay <dan@danfinlay.com>2016-11-30 03:40:49 +0800
committerDan Finlay <dan@danfinlay.com>2016-11-30 03:40:49 +0800
commitb81f00849d53ee780bf26d4d6f79aef4ebdba34c (patch)
tree92492f889dcf12489b05ca73fc7ea99ecc46ea8e /app
parent12906df601fcd549c2671c1cf999f37c30a4490d (diff)
downloadtangerine-wallet-browser-b81f00849d53ee780bf26d4d6f79aef4ebdba34c.tar
tangerine-wallet-browser-b81f00849d53ee780bf26d4d6f79aef4ebdba34c.tar.gz
tangerine-wallet-browser-b81f00849d53ee780bf26d4d6f79aef4ebdba34c.tar.bz2
tangerine-wallet-browser-b81f00849d53ee780bf26d4d6f79aef4ebdba34c.tar.lz
tangerine-wallet-browser-b81f00849d53ee780bf26d4d6f79aef4ebdba34c.tar.xz
tangerine-wallet-browser-b81f00849d53ee780bf26d4d6f79aef4ebdba34c.tar.zst
tangerine-wallet-browser-b81f00849d53ee780bf26d4d6f79aef4ebdba34c.zip
Annotated KeyringController
Diffstat (limited to 'app')
-rw-r--r--app/scripts/keyring-controller.js715
1 files changed, 496 insertions, 219 deletions
diff --git a/app/scripts/keyring-controller.js b/app/scripts/keyring-controller.js
index 5e6b0acbb..7d29fb5d8 100644
--- a/app/scripts/keyring-controller.js
+++ b/app/scripts/keyring-controller.js
@@ -25,6 +25,13 @@ const createId = require('./lib/random-id')
module.exports = class KeyringController extends EventEmitter {
+ // PUBLIC METHODS
+ //
+ // THE FIRST SECTION OF METHODS ARE PUBLIC-FACING,
+ // MEANING THEY ARE USED BY CONSUMERS OF THIS CLASS.
+ //
+ // THEIR SURFACE AREA SHOULD BE CHANGED WITH GREAT CARE.
+
constructor (opts) {
super()
this.configManager = opts.configManager
@@ -46,6 +53,46 @@ module.exports = class KeyringController extends EventEmitter {
})
}
+ // Set Store
+ //
+ // Allows setting the ethStore after the constructor.
+ // This is currently required because of the initialization order
+ // of the ethStore and this class.
+ //
+ // Eventually would be nice to be able to add this in the constructor.
+ setStore (ethStore) {
+ this.ethStore = ethStore
+ }
+
+ // Full Update
+ // returns Promise( @object state )
+ //
+ // Emits the `update` event and
+ // returns a Promise that resolves to the current state.
+ //
+ // Frequently used to end asynchronous chains in this class,
+ // indicating consumers can often either listen for updates,
+ // or accept a state-resolving promise to consume their results.
+ //
+ // Not all methods end with this, that might be a nice refactor.
+ fullUpdate() {
+ this.emit('update')
+ return Promise.resolve(this.getState())
+ }
+
+ // Get State
+ // returns @object state
+ //
+ // This method returns a hash representing the current state
+ // that the keyringController manages.
+ //
+ // It is extended in the MetamaskController along with the EthStore
+ // state, and its own state, to create the metamask state branch
+ // that is passed to the UI.
+ //
+ // This is currently a rare example of a synchronously resolving method
+ // in this class, but will need to be Promisified when we move our
+ // persistence to an async model.
getState () {
const configManager = this.configManager
const address = configManager.getSelectedAccount()
@@ -71,16 +118,30 @@ module.exports = class KeyringController extends EventEmitter {
}
}
- setStore (ethStore) {
- this.ethStore = ethStore
- }
-
+ // Create New Vault And Keychain
+ // @string password - The password to encrypt the vault with
+ //
+ // returns Promise( @object state )
+ //
+ // Destroys any old encrypted storage,
+ // creates a new encrypted store with the given password,
+ // randomly creates a new HD wallet with 1 account,
+ // faucets that account on the testnet.
createNewVaultAndKeychain (password) {
- return this.createNewVault(password)
+ return this.persistAllKeyrings(password)
.then(this.createFirstKeyTree.bind(this))
.then(this.fullUpdate.bind(this))
}
+ // CreateNewVaultAndRestore
+ // @string password - The password to encrypt the vault with
+ // @string seed - The BIP44-compliant seed phrase.
+ //
+ // returns Promise( @object state )
+ //
+ // Destroys any old encrypted storage,
+ // creates a new encrypted store with the given password,
+ // creates a new HD wallet from the given seed with 1 account.
createNewVaultAndRestore (password, seed) {
if (typeof password !== 'string') {
return Promise.reject('Password must be text.')
@@ -92,7 +153,7 @@ module.exports = class KeyringController extends EventEmitter {
this.clearKeyrings()
- return this.createNewVault(password)
+ return this.persistAllKeyrings(password)
.then(() => {
return this.addNewKeyring('HD Key Tree', {
mnemonic: seed,
@@ -112,65 +173,54 @@ module.exports = class KeyringController extends EventEmitter {
.then(this.fullUpdate.bind(this))
}
- migrateOldVaultIfAny (password) {
- const shouldMigrate = !!this.configManager.getWallet() && !this.configManager.getVault()
- return this.idStoreMigrator.migratedVaultForPassword(password)
- .then((serialized) => {
- this.password = password
-
- if (serialized && shouldMigrate) {
- return this.restoreKeyring(serialized)
- .then(keyring => keyring.getAccounts())
- .then((accounts) => {
- this.configManager.setSelectedAccount(accounts[0])
- return this.persistAllKeyrings()
- })
- } else {
- return Promise.resolve()
- }
- })
- }
-
- createNewVault (password) {
- return this.migrateOldVaultIfAny(password)
- .then(() => {
- this.password = password
- return this.persistAllKeyrings()
- })
- .then(() => {
- return password
- })
- }
-
- createFirstKeyTree (password) {
- this.clearKeyrings()
- return this.addNewKeyring('HD Key Tree', {numberOfAccounts: 1})
- .then(() => {
- return this.keyrings[0].getAccounts()
- })
- .then((accounts) => {
- const firstAccount = accounts[0]
- const hexAccount = normalize(firstAccount)
- this.configManager.setSelectedAccount(hexAccount)
- this.emit('newAccount', hexAccount)
- return this.setupAccounts(accounts)
- }).then(() => {
- return this.placeSeedWords()
- })
- .then(this.persistAllKeyrings.bind(this))
- }
-
+ // PlaceSeedWords
+ // returns Promise( @object state )
+ //
+ // Adds the current vault's seed words to the UI's state tree.
+ //
+ // Used when creating a first vault, to allow confirmation.
+ // Also used when revealing the seed words in the confirmation view.
placeSeedWords () {
const firstKeyring = this.keyrings[0]
return firstKeyring.serialize()
.then((serialized) => {
const seedWords = serialized.mnemonic
this.configManager.setSeedWords(seedWords)
- this.emit('update')
- return
+ return this.fullUpdate()
})
}
+ // ClearSeedWordCache
+ //
+ // returns Promise( @string currentSelectedAccount )
+ //
+ // Removes the current vault's seed words from the UI's state tree,
+ // ensuring they are only ever available in the background process.
+ clearSeedWordCache () {
+ this.configManager.setSeedWords(null)
+ return Promise.resolve(this.configManager.getSelectedAccount())
+ }
+
+ // Set Locked
+ // returns Promise( @object state )
+ //
+ // This method deallocates all secrets, and effectively locks metamask.
+ setLocked () {
+ this.password = null
+ this.keyrings = []
+ return this.fullUpdate()
+ }
+
+ // Submit Password
+ // @string password
+ //
+ // returns Promise( @object state )
+ //
+ // Attempts to decrypt the current vault and load its keyrings
+ // into memory.
+ //
+ // Temporarily also migrates any old-style vaults first, as well.
+ // (Pre MetaMask 3.0.0)
submitPassword (password) {
return this.migrateOldVaultIfAny(password)
.then(() => {
@@ -183,11 +233,17 @@ module.exports = class KeyringController extends EventEmitter {
.then(this.fullUpdate.bind(this))
}
- fullUpdate() {
- this.emit('update')
- return Promise.resolve(this.getState())
- }
-
+ // Add New Keyring
+ // @string type
+ // @object opts
+ //
+ // returns Promise( @Keyring keyring )
+ //
+ // Adds a new Keyring of the given `type` to the vault
+ // and the current decrypted Keyrings array.
+ //
+ // All Keyring classes implement a unique `type` string,
+ // and this is used to retrieve them from the keyringTypes array.
addNewKeyring (type, opts) {
const Keyring = this.getKeyringClassForType(type)
const keyring = new Keyring(opts)
@@ -202,43 +258,42 @@ module.exports = class KeyringController extends EventEmitter {
})
}
+ // Add New Account
+ // @number keyRingNum
+ //
+ // returns Promise( @object state )
+ //
+ // Calls the `addAccounts` method on the Keyring
+ // in the kryings array at index `keyringNum`,
+ // and then saves those changes.
addNewAccount (keyRingNum = 0) {
const ring = this.keyrings[keyRingNum]
return ring.addAccounts(1)
.then(this.setupAccounts.bind(this))
.then(this.persistAllKeyrings.bind(this))
+ .then(this.fullUpdate.bind(this))
}
- setupAccounts (accounts) {
- return this.getAccounts()
- .then((loadedAccounts) => {
- const arr = accounts || loadedAccounts
- return Promise.all(arr.map((account) => {
- return this.getBalanceAndNickname(account)
- }))
- })
- }
-
- // Takes an account address and an iterator representing
- // the current number of named accounts.
- getBalanceAndNickname (account) {
- const address = normalize(account)
- this.ethStore.addAccount(address)
- return this.createNickname(address)
- }
-
- createNickname (address) {
- const hexAddress = normalize(address)
- var i = Object.keys(this.identities).length
- const oldNickname = this.configManager.nicknameForWallet(address)
- const name = oldNickname || `Account ${++i}`
- this.identities[hexAddress] = {
- address: hexAddress,
- name,
- }
- return this.saveAccountLabel(hexAddress, name)
+ // Set Selected Account
+ // @string address
+ //
+ // returns Promise( @string address )
+ //
+ // Sets the state's `selectedAccount` value
+ // to the specified address.
+ setSelectedAccount (address) {
+ var addr = normalize(address)
+ this.configManager.setSelectedAccount(addr)
+ Promise.resolve(addr)
}
+ // Save Account Label
+ // @string account
+ // @string label
+ //
+ // returns Promise( @string label )
+ //
+ // Persists a nickname equal to `label` for the specified account.
saveAccountLabel (account, label) {
const address = normalize(account)
const configManager = this.configManager
@@ -247,80 +302,45 @@ module.exports = class KeyringController extends EventEmitter {
return Promise.resolve(label)
}
- persistAllKeyrings () {
- return Promise.all(this.keyrings.map((keyring) => {
- return Promise.all([keyring.type, keyring.serialize()])
- .then((serializedKeyringArray) => {
- // Label the output values on each serialized Keyring:
- return {
- type: serializedKeyringArray[0],
- data: serializedKeyringArray[1],
- }
+ // Export Account
+ // @string address
+ //
+ // returns Promise( @string privateKey )
+ //
+ // Requests the private key from the keyring controlling
+ // the specified address.
+ //
+ // Returns a Promise that may resolve with the private key string.
+ exportAccount (address) {
+ try {
+ return this.getKeyringForAccount(address)
+ .then((keyring) => {
+ return keyring.exportAccount(normalize(address))
})
- }))
- .then((serializedKeyrings) => {
- return this.encryptor.encrypt(this.password, serializedKeyrings)
- })
- .then((encryptedString) => {
- this.configManager.setVault(encryptedString)
- return true
- })
- }
-
- unlockKeyrings (password) {
- const encryptedVault = this.configManager.getVault()
- return this.encryptor.decrypt(password, encryptedVault)
- .then((vault) => {
- this.password = password
- vault.forEach(this.restoreKeyring.bind(this))
- return this.keyrings
- })
- }
-
- restoreKeyring (serialized) {
- const { type, data } = serialized
- const Keyring = this.getKeyringClassForType(type)
- const keyring = new Keyring()
- return keyring.deserialize(data)
- .then(() => {
- return keyring.getAccounts()
- })
- .then((accounts) => {
- return this.setupAccounts(accounts)
- })
- .then(() => {
- this.keyrings.push(keyring)
- return keyring
- })
+ } catch (e) {
+ return Promise.reject(e)
+ }
}
- getKeyringClassForType (type) {
- const Keyring = this.keyringTypes.reduce((res, kr) => {
- if (kr.type === type) {
- return kr
- } else {
- return res
- }
- })
- return Keyring
- }
- getAccounts () {
- const keyrings = this.keyrings || []
- return Promise.all(keyrings.map(kr => kr.getAccounts()))
- .then((keyringArrays) => {
- return keyringArrays.reduce((res, arr) => {
- return res.concat(arr)
- }, [])
- })
- }
+ // SIGNING RELATED METHODS
+ //
+ // SIGN, SUBMIT TX, CANCEL, AND APPROVE.
+ // THIS SECTION INVOLVES THE REQUEST, STORING, AND SIGNING OF DATA
+ // WITH THE KEYS STORED IN THIS CONTROLLER.
- setSelectedAccount (address) {
- var addr = normalize(address)
- this.configManager.setSelectedAccount(addr)
- Promise.resolve(addr)
- }
+ // Add Unconfirmed Transaction
+ // @object txParams
+ // @function onTxDoneCb
+ // @function cb
+ //
+ // Calls back `cb` with @object txData = { txParams }
+ // Calls back `onTxDoneCb` with `true` or an `error` depending on result.
+ //
+ // Prepares the given `txParams` for final confirmation and approval.
+ // Estimates gas and other preparatory steps.
+ // Caches the requesting Dapp's callback, `onTxDoneCb`, for resolution later.
addUnconfirmedTransaction (txParams, onTxDoneCb, cb) {
var self = this
const configManager = this.configManager
@@ -446,28 +466,38 @@ module.exports = class KeyringController extends EventEmitter {
}
}
- addUnconfirmedMessage (msgParams, cb) {
- // create txData obj with parameters and meta data
- var time = (new Date()).getTime()
- var msgId = createId()
- var msgData = {
- id: msgId,
- msgParams: msgParams,
- time: time,
- status: 'unconfirmed',
- }
- messageManager.addMsg(msgData)
- console.log('addUnconfirmedMessage:', msgData)
+ // Cancel Transaction
+ // @string txId
+ // @function cb
+ //
+ // Calls back `cb` with no error if provided.
+ //
+ // Forgets any tx matching `txId`.
+ cancelTransaction (txId, cb) {
+ const configManager = this.configManager
+ var approvalCb = this._unconfTxCbs[txId] || noop
- // keep the cb around for after approval (requires user interaction)
- // This cb fires completion to the Dapp's write operation.
- this._unconfMsgCbs[msgId] = cb
+ // reject tx
+ approvalCb(null, false)
+ // clean up
+ configManager.rejectTx(txId)
+ delete this._unconfTxCbs[txId]
- // signal update
- this.emit('update')
- return msgId
+ if (cb && typeof cb === 'function') {
+ cb()
+ }
}
+ // Approve Transaction
+ // @string txId
+ // @function cb
+ //
+ // Calls back `cb` with no error always.
+ //
+ // Attempts to sign a Transaction with `txId`
+ // and submit it to the blockchain.
+ //
+ // Calls back the cached Dapp's confirmation callback, also.
approveTransaction (txId, cb) {
const configManager = this.configManager
var approvalCb = this._unconfTxCbs[txId] || noop
@@ -480,22 +510,6 @@ module.exports = class KeyringController extends EventEmitter {
delete this._unconfTxCbs[txId]
this.emit('update')
}
-
- cancelTransaction (txId, cb) {
- const configManager = this.configManager
- var approvalCb = this._unconfTxCbs[txId] || noop
-
- // reject tx
- approvalCb(null, false)
- // clean up
- configManager.rejectTx(txId)
- delete this._unconfTxCbs[txId]
-
- if (cb && typeof cb === 'function') {
- cb()
- }
- }
-
signTransaction (txParams, cb) {
try {
const address = normalize(txParams.from)
@@ -534,14 +548,77 @@ module.exports = class KeyringController extends EventEmitter {
}
}
+ // Add Unconfirmed Message
+ // @object msgParams
+ // @function cb
+ //
+ // Does not call back, only emits an `update` event.
+ //
+ // Adds the given `msgParams` and `cb` to a local cache,
+ // for displaying to a user for approval before signing or canceling.
+ addUnconfirmedMessage (msgParams, cb) {
+ // create txData obj with parameters and meta data
+ var time = (new Date()).getTime()
+ var msgId = createId()
+ var msgData = {
+ id: msgId,
+ msgParams: msgParams,
+ time: time,
+ status: 'unconfirmed',
+ }
+ messageManager.addMsg(msgData)
+ console.log('addUnconfirmedMessage:', msgData)
+
+ // keep the cb around for after approval (requires user interaction)
+ // This cb fires completion to the Dapp's write operation.
+ this._unconfMsgCbs[msgId] = cb
+
+ // signal update
+ this.emit('update')
+ return msgId
+ }
+
+ // Cancel Message
+ // @string msgId
+ // @function cb (optional)
+ //
+ // Calls back to cached `unconfMsgCb`.
+ // Calls back to `cb` if provided.
+ //
+ // Forgets any messages matching `msgId`.
+ cancelMessage (msgId, cb) {
+ var approvalCb = this._unconfMsgCbs[msgId] || noop
+
+ // reject tx
+ approvalCb(null, false)
+ // clean up
+ messageManager.rejectMsg(msgId)
+ delete this._unconfTxCbs[msgId]
+
+ if (cb && typeof cb === 'function') {
+ cb()
+ }
+ }
+
+ // Sign Message
+ // @object msgParams
+ // @function cb
+ //
+ // returns Promise(@buffer rawSig)
+ // calls back @function cb with @buffer rawSig
+ // calls back cached Dapp's @function unconfMsgCb.
+ //
+ // Attempts to sign the provided @object msgParams.
signMessage (msgParams, cb) {
try {
+ var approvalCb = this._unconfMsgCbs[msgId] || noop
const address = normalize(msgParams.from)
return this.getKeyringForAccount(address)
.then((keyring) => {
return keyring.signMessage(address, msgParams.data)
}).then((rawSig) => {
cb(null, rawSig)
+ approvalCb(null, true)
return rawSig
})
} catch (e) {
@@ -549,6 +626,224 @@ module.exports = class KeyringController extends EventEmitter {
}
}
+ // PRIVATE METHODS
+ //
+ // THESE METHODS ARE ONLY USED INTERNALLY TO THE KEYRING-CONTROLLER
+ // AND SO MAY BE CHANGED MORE LIBERALLY THAN THE ABOVE METHODS.
+
+ // Migrate Old Vault If Any
+ // @string password
+ //
+ // returns Promise()
+ //
+ // Temporary step used when logging in.
+ // Checks if old style (pre-3.0.0) Metamask Vault exists.
+ // If so, persists that vault in the new vault format
+ // with the provided password, so the other unlock steps
+ // may be completed without interruption.
+ migrateOldVaultIfAny (password) {
+ const shouldMigrate = !!this.configManager.getWallet() && !this.configManager.getVault()
+ return this.idStoreMigrator.migratedVaultForPassword(password)
+ .then((serialized) => {
+ this.password = password
+
+ if (serialized && shouldMigrate) {
+ return this.restoreKeyring(serialized)
+ .then(keyring => keyring.getAccounts())
+ .then((accounts) => {
+ this.configManager.setSelectedAccount(accounts[0])
+ return this.persistAllKeyrings()
+ })
+ } else {
+ return Promise.resolve()
+ }
+ })
+ }
+
+ // Create First Key Tree
+ // returns @Promise
+ //
+ // Clears the vault,
+ // creates a new one,
+ // creates a random new HD Keyring with 1 account,
+ // makes that account the selected account,
+ // faucets that account on testnet,
+ // puts the current seed words into the state tree.
+ createFirstKeyTree () {
+ this.clearKeyrings()
+ return this.addNewKeyring('HD Key Tree', {numberOfAccounts: 1})
+ .then(() => {
+ return this.keyrings[0].getAccounts()
+ })
+ .then((accounts) => {
+ const firstAccount = accounts[0]
+ const hexAccount = normalize(firstAccount)
+ this.configManager.setSelectedAccount(hexAccount)
+ this.emit('newAccount', hexAccount)
+ return this.setupAccounts(accounts)
+ }).then(() => {
+ return this.placeSeedWords()
+ })
+ .then(this.persistAllKeyrings.bind(this))
+ }
+
+ // Setup Accounts
+ // @array accounts
+ //
+ // returns @Promise(@object account)
+ //
+ // Initializes the provided account array
+ // Gives them numerically incremented nicknames,
+ // and adds them to the ethStore for regular balance checking.
+ setupAccounts (accounts) {
+ return this.getAccounts()
+ .then((loadedAccounts) => {
+ const arr = accounts || loadedAccounts
+ return Promise.all(arr.map((account) => {
+ return this.getBalanceAndNickname(account)
+ }))
+ })
+ }
+
+ // Get Balance And Nickname
+ // @string account
+ //
+ // returns Promise( @string label )
+ //
+ // Takes an account address and an iterator representing
+ // the current number of named accounts.
+ getBalanceAndNickname (account) {
+ const address = normalize(account)
+ this.ethStore.addAccount(address)
+ return this.createNickname(address)
+ }
+
+ // Create Nickname
+ // @string address
+ //
+ // returns Promise( @string label )
+ //
+ // Takes an address, and assigns it an incremented nickname, persisting it.
+ createNickname (address) {
+ const hexAddress = normalize(address)
+ var i = Object.keys(this.identities).length
+ const oldNickname = this.configManager.nicknameForWallet(address)
+ const name = oldNickname || `Account ${++i}`
+ this.identities[hexAddress] = {
+ address: hexAddress,
+ name,
+ }
+ return this.saveAccountLabel(hexAddress, name)
+ }
+
+ // Persist All Keyrings
+ // @password string
+ //
+ // returns Promise
+ //
+ // Iterates the current `keyrings` array,
+ // serializes each one into a serialized array,
+ // encrypts that array with the provided `password`,
+ // and persists that encrypted string to storage.
+ persistAllKeyrings (password = this.password) {
+ this.password = password
+ return Promise.all(this.keyrings.map((keyring) => {
+ return Promise.all([keyring.type, keyring.serialize()])
+ .then((serializedKeyringArray) => {
+ // Label the output values on each serialized Keyring:
+ return {
+ type: serializedKeyringArray[0],
+ data: serializedKeyringArray[1],
+ }
+ })
+ }))
+ .then((serializedKeyrings) => {
+ return this.encryptor.encrypt(this.password, serializedKeyrings)
+ })
+ .then((encryptedString) => {
+ this.configManager.setVault(encryptedString)
+ return true
+ })
+ }
+
+ // Unlock Keyrings
+ // @string password
+ //
+ // returns Promise( @array keyrings )
+ //
+ // Attempts to unlock the persisted encrypted storage,
+ // initializing the persisted keyrings to RAM.
+ unlockKeyrings (password) {
+ const encryptedVault = this.configManager.getVault()
+ return this.encryptor.decrypt(password, encryptedVault)
+ .then((vault) => {
+ this.password = password
+ vault.forEach(this.restoreKeyring.bind(this))
+ return this.keyrings
+ })
+ }
+
+ // Restore Keyring
+ // @object serialized
+ //
+ // returns Promise( @Keyring deserialized )
+ //
+ // Attempts to initialize a new keyring from the provided
+ // serialized payload.
+ //
+ // On success, returns the resulting @Keyring instance.
+ restoreKeyring (serialized) {
+ const { type, data } = serialized
+ const Keyring = this.getKeyringClassForType(type)
+ const keyring = new Keyring()
+ return keyring.deserialize(data)
+ .then(() => {
+ return keyring.getAccounts()
+ })
+ .then((accounts) => {
+ return this.setupAccounts(accounts)
+ })
+ .then(() => {
+ this.keyrings.push(keyring)
+ return keyring
+ })
+ }
+
+ // Get Keyring Class For Type
+ // @string type
+ //
+ // Returns @class Keyring
+ //
+ // Searches the current `keyringTypes` array
+ // for a Keyring class whose unique `type` property
+ // matches the provided `type`,
+ // returning it if it exists.
+ getKeyringClassForType (type) {
+ return this.keyringTypes.find(kr => kr.type === type)
+ }
+
+ // Get Accounts
+ // returns Promise( @Array[ @string accounts ] )
+ //
+ // Returns the public addresses of all current accounts
+ // managed by all currently unlocked keyrings.
+ getAccounts () {
+ const keyrings = this.keyrings || []
+ return Promise.all(keyrings.map(kr => kr.getAccounts()))
+ .then((keyringArrays) => {
+ return keyringArrays.reduce((res, arr) => {
+ return res.concat(arr)
+ }, [])
+ })
+ }
+
+ // Get Keyring For Account
+ // @string address
+ //
+ // returns Promise(@Keyring keyring)
+ //
+ // Returns the currently initialized keyring that manages
+ // the specified `address` if one exists.
getKeyringForAccount (address) {
const hexed = normalize(address)
return new Promise((resolve, reject) => {
@@ -576,29 +871,12 @@ module.exports = class KeyringController extends EventEmitter {
})
}
- cancelMessage (msgId, cb) {
- if (cb && typeof cb === 'function') {
- cb()
- }
- }
-
- setLocked () {
- this.password = null
- this.keyrings = []
- return this.fullUpdate()
- }
-
- exportAccount (address) {
- try {
- return this.getKeyringForAccount(address)
- .then((keyring) => {
- return keyring.exportAccount(normalize(address))
- })
- } catch (e) {
- return Promise.reject(e)
- }
- }
-
+ // Add Gas Buffer
+ // @string gas (as hexadecimal value)
+ //
+ // returns @string bufferedGas (as hexadecimal value)
+ //
+ // Adds a healthy buffer of gas to an initial gas estimate.
addGasBuffer (gas) {
const gasBuffer = new BN('100000', 10)
const bnGas = new BN(ethUtil.stripHexPrefix(gas), 16)
@@ -606,11 +884,10 @@ module.exports = class KeyringController extends EventEmitter {
return ethUtil.addHexPrefix(correct.toString(16))
}
- clearSeedWordCache () {
- this.configManager.setSeedWords(null)
- return Promise.resolve(this.configManager.getSelectedAccount())
- }
-
+ // Clear Keyrings
+ //
+ // Deallocates all currently managed keyrings and accounts.
+ // Used before initializing a new vault.
clearKeyrings () {
let accounts
try {