New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

eth-keyring-controller

Package Overview
Dependencies
Maintainers
7
Versions
44
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

eth-keyring-controller - npm Package Compare versions

Comparing version 6.2.1 to 7.0.0

CHANGELOG.md

616

index.js

@@ -0,22 +1,29 @@

const { EventEmitter } = require('events');
const bip39 = require('bip39');
const ObservableStore = require('obs-store');
const encryptor = require('browser-passworder');
const { normalize: normalizeAddress } = require('eth-sig-util');
const { EventEmitter } = require('events')
const log = require('loglevel')
const ethUtil = require('ethereumjs-util')
const SimpleKeyring = require('eth-simple-keyring');
const HdKeyring = require('@metamask/eth-hd-keyring');
const { BN } = ethUtil
const bip39 = require('bip39')
const ObservableStore = require('obs-store')
const encryptor = require('browser-passworder')
const { normalize: normalizeAddress } = require('eth-sig-util')
const keyringTypes = [SimpleKeyring, HdKeyring];
const SimpleKeyring = require('eth-simple-keyring')
const HdKeyring = require('eth-hd-keyring')
const KEYRINGS_TYPE_MAP = {
HD_KEYRING: 'HD Key Tree',
SIMPLE_KEYRING: 'Simple Key Pair',
};
/**
* Strip the hex prefix from an address, if present
* @param {string} address - The address that might be hex prefixed.
* @returns {string} The address without a hex prefix.
*/
function stripHexPrefix(address) {
if (address.startsWith('0x')) {
return address.slice(2);
}
return address;
}
const keyringTypes = [
SimpleKeyring,
HdKeyring,
]
class KeyringController extends EventEmitter {
//

@@ -26,7 +33,9 @@ // PUBLIC METHODS

constructor (opts) {
super()
const initState = opts.initState || {}
this.keyringTypes = opts.keyringTypes ? keyringTypes.concat(opts.keyringTypes) : keyringTypes
this.store = new ObservableStore(initState)
constructor(opts) {
super();
const initState = opts.initState || {};
this.keyringTypes = opts.keyringTypes
? keyringTypes.concat(opts.keyringTypes)
: keyringTypes;
this.store = new ObservableStore(initState);
this.memStore = new ObservableStore({

@@ -36,6 +45,6 @@ isUnlocked: false,

keyrings: [],
})
});
this.encryptor = opts.encryptor || encryptor
this.keyrings = []
this.encryptor = opts.encryptor || encryptor;
this.keyrings = [];
}

@@ -55,5 +64,5 @@

*/
fullUpdate () {
this.emit('update', this.memStore.getState())
return this.memStore.getState()
fullUpdate() {
this.emit('update', this.memStore.getState());
return this.memStore.getState();
}

@@ -73,8 +82,7 @@

*/
createNewVaultAndKeychain (password) {
return this.persistAllKeyrings(password)
.then(this.createFirstKeyTree.bind(this))
createNewVaultAndKeychain(password) {
return this.createFirstKeyTree(password)
.then(this.persistAllKeyrings.bind(this, password))
.then(this.setUnlocked.bind(this))
.then(this.fullUpdate.bind(this))
.then(this.fullUpdate.bind(this));
}

@@ -94,32 +102,35 @@

*/
createNewVaultAndRestore (password, seed) {
createNewVaultAndRestore(password, seed) {
if (typeof password !== 'string') {
return Promise.reject(new Error('Password must be text.'))
return Promise.reject(new Error('Password must be text.'));
}
if (!bip39.validateMnemonic(seed)) {
return Promise.reject(new Error('Seed phrase is invalid.'))
const wordlists = Object.values(bip39.wordlists);
if (
wordlists.every((wordlist) => !bip39.validateMnemonic(seed, wordlist))
) {
return Promise.reject(new Error('Seed phrase is invalid.'));
}
this.clearKeyrings()
this.clearKeyrings();
return this.persistAllKeyrings(password)
.then(() => {
return this.addNewKeyring('HD Key Tree', {
return this.addNewKeyring(KEYRINGS_TYPE_MAP.HD_KEYRING, {
mnemonic: seed,
numberOfAccounts: 1,
})
});
})
.then((firstKeyring) => {
return firstKeyring.getAccounts()
return firstKeyring.getAccounts();
})
.then(([firstAccount]) => {
if (!firstAccount) {
throw new Error('KeyringController - First Account not found.')
throw new Error('KeyringController - First Account not found.');
}
return null
return null;
})
.then(this.persistAllKeyrings.bind(this, password))
.then(this.setUnlocked.bind(this))
.then(this.fullUpdate.bind(this))
.then(this.fullUpdate.bind(this));
}

@@ -134,11 +145,11 @@

*/
async setLocked () {
async setLocked() {
// set locked
this.password = null
this.memStore.updateState({ isUnlocked: false })
this.password = null;
this.memStore.updateState({ isUnlocked: false });
// remove keyrings
this.keyrings = []
await this._updateMemStoreKeyrings()
this.emit('lock')
return this.fullUpdate()
this.keyrings = [];
await this._updateMemStoreKeyrings();
this.emit('lock');
return this.fullUpdate();
}

@@ -159,9 +170,8 @@

*/
submitPassword (password) {
return this.unlockKeyrings(password)
.then((keyrings) => {
this.keyrings = keyrings
this.setUnlocked()
return this.fullUpdate()
})
submitPassword(password) {
return this.unlockKeyrings(password).then((keyrings) => {
this.keyrings = keyrings;
this.setUnlocked();
return this.fullUpdate();
});
}

@@ -177,8 +187,8 @@

*/
async verifyPassword (password) {
const encryptedVault = this.store.getState().vault
async verifyPassword(password) {
const encryptedVault = this.store.getState().vault;
if (!encryptedVault) {
throw new Error('Cannot unlock without a previous vault.')
throw new Error('Cannot unlock without a previous vault.');
}
await this.encryptor.decrypt(password, encryptedVault)
await this.encryptor.decrypt(password, encryptedVault);
}

@@ -199,12 +209,18 @@

*/
addNewKeyring (type, opts) {
const Keyring = this.getKeyringClassForType(type)
const keyring = new Keyring(opts)
return keyring.getAccounts()
addNewKeyring(type, opts = {}) {
const Keyring = this.getKeyringClassForType(type);
const keyring = new Keyring(opts);
if (!opts.mnemonic && type === KEYRINGS_TYPE_MAP.HD_KEYRING) {
keyring.generateRandomMnemonic();
keyring.addAccounts();
}
return keyring
.getAccounts()
.then((accounts) => {
return this.checkForDuplicate(type, accounts)
return this.checkForDuplicate(type, accounts);
})
.then(() => {
this.keyrings.push(keyring)
return this.persistAllKeyrings()
this.keyrings.push(keyring);
return this.persistAllKeyrings();
})

@@ -214,4 +230,4 @@ .then(() => this._updateMemStoreKeyrings())

.then(() => {
return keyring
})
return keyring;
});
}

@@ -225,4 +241,4 @@

*/
async removeEmptyKeyrings () {
const validKeyrings = []
async removeEmptyKeyrings() {
const validKeyrings = [];

@@ -233,9 +249,11 @@ // Since getAccounts returns a Promise

await Promise.all(this.keyrings.map(async (keyring) => {
const accounts = await keyring.getAccounts()
if (accounts.length > 0) {
validKeyrings.push(keyring)
}
}))
this.keyrings = validKeyrings
await Promise.all(
this.keyrings.map(async (keyring) => {
const accounts = await keyring.getAccounts();
if (accounts.length > 0) {
validKeyrings.push(keyring);
}
}),
);
this.keyrings = validKeyrings;
}

@@ -253,23 +271,26 @@

*/
checkForDuplicate (type, newAccountArray) {
return this.getAccounts()
.then((accounts) => {
switch (type) {
case 'Simple Key Pair': {
const isIncluded = Boolean(
accounts.find(
(key) => (
key === newAccountArray[0] ||
key === ethUtil.stripHexPrefix(newAccountArray[0])),
),
)
return isIncluded
? Promise.reject(new Error('The account you\'re are trying to import is a duplicate'))
: Promise.resolve(newAccountArray)
}
default: {
return Promise.resolve(newAccountArray)
}
checkForDuplicate(type, newAccountArray) {
return this.getAccounts().then((accounts) => {
switch (type) {
case KEYRINGS_TYPE_MAP.SIMPLE_KEYRING: {
const isIncluded = Boolean(
accounts.find(
(key) =>
key === newAccountArray[0] ||
key === stripHexPrefix(newAccountArray[0]),
),
);
return isIncluded
? Promise.reject(
new Error(
"The account you're are trying to import is a duplicate",
),
)
: Promise.resolve(newAccountArray);
}
})
default: {
return Promise.resolve(newAccountArray);
}
}
});
}

@@ -286,12 +307,13 @@

*/
addNewAccount (selectedKeyring) {
return selectedKeyring.addAccounts(1)
addNewAccount(selectedKeyring) {
return selectedKeyring
.addAccounts(1)
.then((accounts) => {
accounts.forEach((hexAccount) => {
this.emit('newAccount', hexAccount)
})
this.emit('newAccount', hexAccount);
});
})
.then(this.persistAllKeyrings.bind(this))
.then(this._updateMemStoreKeyrings.bind(this))
.then(this.fullUpdate.bind(this))
.then(this.fullUpdate.bind(this));
}

@@ -310,10 +332,9 @@

*/
exportAccount (address) {
exportAccount(address) {
try {
return this.getKeyringForAccount(address)
.then((keyring) => {
return keyring.exportAccount(normalizeAddress(address))
})
return this.getKeyringForAccount(address).then((keyring) => {
return keyring.exportAccount(normalizeAddress(address));
});
} catch (e) {
return Promise.reject(e)
return Promise.reject(e);
}

@@ -332,3 +353,3 @@ }

*/
removeAccount (address) {
removeAccount(address) {
return this.getKeyringForAccount(address)

@@ -338,9 +359,11 @@ .then((keyring) => {

if (typeof keyring.removeAccount === 'function') {
keyring.removeAccount(address)
this.emit('removedAccount', address)
return keyring.getAccounts()
keyring.removeAccount(address);
this.emit('removedAccount', address);
return keyring.getAccounts();
}
return Promise.reject(new Error(
`Keyring ${keyring.type} doesn't support account removal operations`,
))
return Promise.reject(
new Error(
`Keyring ${keyring.type} doesn't support account removal operations`,
),
);
})

@@ -350,5 +373,5 @@ .then((accounts) => {

if (accounts.length === 0) {
return this.removeEmptyKeyrings()
return this.removeEmptyKeyrings();
}
return undefined
return undefined;
})

@@ -359,4 +382,4 @@ .then(this.persistAllKeyrings.bind(this))

.catch((e) => {
return Promise.reject(e)
})
return Promise.reject(e);
});
}

@@ -376,10 +399,9 @@

* @param {Object} opts - Signing options.
* @returns {Promise<Object>} The signed transactio object.
* @returns {Promise<Object>} The signed transaction object.
*/
signTransaction (ethTx, _fromAddress, opts = {}) {
const fromAddress = normalizeAddress(_fromAddress)
return this.getKeyringForAccount(fromAddress)
.then((keyring) => {
return keyring.signTransaction(fromAddress, ethTx, opts)
})
signTransaction(ethTx, _fromAddress, opts = {}) {
const fromAddress = normalizeAddress(_fromAddress);
return this.getKeyringForAccount(fromAddress).then((keyring) => {
return keyring.signTransaction(fromAddress, ethTx, opts);
});
}

@@ -395,8 +417,7 @@

*/
signMessage (msgParams, opts = {}) {
const address = normalizeAddress(msgParams.from)
return this.getKeyringForAccount(address)
.then((keyring) => {
return keyring.signMessage(address, msgParams.data, opts)
})
signMessage(msgParams, opts = {}) {
const address = normalizeAddress(msgParams.from);
return this.getKeyringForAccount(address).then((keyring) => {
return keyring.signMessage(address, msgParams.data, opts);
});
}

@@ -407,3 +428,3 @@

*
* Attempts to sign the provided message paramaters.
* Attempts to sign the provided message parameters.
* Prefixes the hash before signing per the personal sign expectation.

@@ -414,8 +435,7 @@ *

*/
signPersonalMessage (msgParams, opts = {}) {
const address = normalizeAddress(msgParams.from)
return this.getKeyringForAccount(address)
.then((keyring) => {
return keyring.signPersonalMessage(address, msgParams.data, opts)
})
signPersonalMessage(msgParams, opts = {}) {
const address = normalizeAddress(msgParams.from);
return this.getKeyringForAccount(address).then((keyring) => {
return keyring.signPersonalMessage(address, msgParams.data, opts);
});
}

@@ -431,8 +451,7 @@

*/
getEncryptionPublicKey (_address, opts = {}) {
const address = normalizeAddress(_address)
return this.getKeyringForAccount(address)
.then((keyring) => {
return keyring.getEncryptionPublicKey(address, opts)
})
getEncryptionPublicKey(_address, opts = {}) {
const address = normalizeAddress(_address);
return this.getKeyringForAccount(address).then((keyring) => {
return keyring.getEncryptionPublicKey(address, opts);
});
}

@@ -448,8 +467,7 @@

*/
decryptMessage (msgParams, opts = {}) {
const address = normalizeAddress(msgParams.from)
return this.getKeyringForAccount(address)
.then((keyring) => {
return keyring.decryptMessage(address, msgParams.data, opts)
})
decryptMessage(msgParams, opts = {}) {
const address = normalizeAddress(msgParams.from);
return this.getKeyringForAccount(address).then((keyring) => {
return keyring.decryptMessage(address, msgParams.data, opts);
});
}

@@ -464,8 +482,7 @@

*/
signTypedMessage (msgParams, opts = { version: 'V1' }) {
const address = normalizeAddress(msgParams.from)
return this.getKeyringForAccount(address)
.then((keyring) => {
return keyring.signTypedData(address, msgParams.data, opts)
})
signTypedMessage(msgParams, opts = { version: 'V1' }) {
const address = normalizeAddress(msgParams.from);
return this.getKeyringForAccount(address).then((keyring) => {
return keyring.signTypedData(address, msgParams.data, opts);
});
}

@@ -480,6 +497,6 @@

*/
async getAppKeyAddress (_address, origin) {
const address = normalizeAddress(_address)
const keyring = await this.getKeyringForAccount(address)
return keyring.getAppKeyAddress(address, origin)
async getAppKeyAddress(_address, origin) {
const address = normalizeAddress(_address);
const keyring = await this.getKeyringForAccount(address);
return keyring.getAppKeyAddress(address, origin);
}

@@ -494,9 +511,11 @@

*/
async exportAppKeyForAddress (_address, origin) {
const address = normalizeAddress(_address)
const keyring = await this.getKeyringForAccount(address)
async exportAppKeyForAddress(_address, origin) {
const address = normalizeAddress(_address);
const keyring = await this.getKeyringForAccount(address);
if (!('exportAccount' in keyring)) {
throw new Error(`The keyring for address ${_address} does not support exporting.`)
throw new Error(
`The keyring for address ${_address} does not support exporting.`,
);
}
return keyring.exportAccount(address, { withAppKeyOrigin: origin })
return keyring.exportAccount(address, { withAppKeyOrigin: origin });
}

@@ -518,18 +537,20 @@

*
* @returns {Promise<void>} - A promise that resovles if the operation was successful.
* @param {string} password - The keyring controller password.
* @returns {Promise<void>} - A promise that resolves if the operation was successful.
*/
createFirstKeyTree () {
this.clearKeyrings()
return this.addNewKeyring('HD Key Tree', { numberOfAccounts: 1 })
createFirstKeyTree(password) {
this.password = password;
this.clearKeyrings();
return this.addNewKeyring(KEYRINGS_TYPE_MAP.HD_KEYRING)
.then((keyring) => {
return keyring.getAccounts()
return keyring.getAccounts();
})
.then(([firstAccount]) => {
if (!firstAccount) {
throw new Error('KeyringController - No account found on keychain.')
throw new Error('KeyringController - No account found on keychain.');
}
const hexAccount = normalizeAddress(firstAccount)
this.emit('newVault', hexAccount)
return null
})
const hexAccount = normalizeAddress(firstAccount);
this.emit('newVault', hexAccount);
return null;
});
}

@@ -548,27 +569,30 @@

*/
persistAllKeyrings (password = this.password) {
persistAllKeyrings(password = this.password) {
if (typeof password !== 'string') {
return Promise.reject(new Error(
'KeyringController - password is not a string',
))
return Promise.reject(
new Error('KeyringController - password is not a string'),
);
}
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],
}
})
}))
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)
return this.encryptor.encrypt(this.password, serializedKeyrings);
})
.then((encryptedString) => {
this.store.updateState({ vault: encryptedString })
return true
})
this.store.updateState({ vault: encryptedString });
return true;
});
}

@@ -585,14 +609,14 @@

*/
async unlockKeyrings (password) {
const encryptedVault = this.store.getState().vault
async unlockKeyrings(password) {
const encryptedVault = this.store.getState().vault;
if (!encryptedVault) {
throw new Error('Cannot unlock without a previous vault.')
throw new Error('Cannot unlock without a previous vault.');
}
await this.clearKeyrings()
const vault = await this.encryptor.decrypt(password, encryptedVault)
this.password = password
await Promise.all(vault.map(this._restoreKeyring.bind(this)))
await this._updateMemStoreKeyrings()
return this.keyrings
await this.clearKeyrings();
const vault = await this.encryptor.decrypt(password, encryptedVault);
this.password = password;
await Promise.all(vault.map(this._restoreKeyring.bind(this)));
await this._updateMemStoreKeyrings();
return this.keyrings;
}

@@ -610,6 +634,6 @@

*/
async restoreKeyring (serialized) {
const keyring = await this._restoreKeyring(serialized)
await this._updateMemStoreKeyrings()
return keyring
async restoreKeyring(serialized) {
const keyring = await this._restoreKeyring(serialized);
await this._updateMemStoreKeyrings();
return keyring;
}

@@ -626,12 +650,12 @@

*/
async _restoreKeyring (serialized) {
const { type, data } = serialized
async _restoreKeyring(serialized) {
const { type, data } = serialized;
const Keyring = this.getKeyringClassForType(type)
const keyring = new Keyring()
await keyring.deserialize(data)
const Keyring = this.getKeyringClassForType(type);
const keyring = new Keyring();
await keyring.deserialize(data);
// getAccounts also validates the accounts for some keyrings
await keyring.getAccounts()
this.keyrings.push(keyring)
return keyring
await keyring.getAccounts();
this.keyrings.push(keyring);
return keyring;
}

@@ -650,4 +674,4 @@

*/
getKeyringClassForType (type) {
return this.keyringTypes.find((kr) => kr.type === type)
getKeyringClassForType(type) {
return this.keyringTypes.find((kr) => kr.type === type);
}

@@ -663,4 +687,4 @@

*/
getKeyringsByType (type) {
return this.keyrings.filter((keyring) => keyring.type === type)
getKeyringsByType(type) {
return this.keyrings.filter((keyring) => keyring.type === type);
}

@@ -676,11 +700,12 @@

*/
async getAccounts () {
const keyrings = this.keyrings || []
const addrs = await Promise.all(keyrings.map((kr) => kr.getAccounts()))
.then((keyringArrays) => {
return keyringArrays.reduce((res, arr) => {
return res.concat(arr)
}, [])
})
return addrs.map(normalizeAddress)
async getAccounts() {
const keyrings = this.keyrings || [];
const addrs = await Promise.all(
keyrings.map((kr) => kr.getAccounts()),
).then((keyringArrays) => {
return keyringArrays.reduce((res, arr) => {
return res.concat(arr);
}, []);
});
return addrs.map(normalizeAddress);
}

@@ -697,35 +722,31 @@

*/
getKeyringForAccount (address) {
const hexed = normalizeAddress(address)
log.debug(`KeyringController - getKeyringForAccount: ${hexed}`)
getKeyringForAccount(address) {
const hexed = normalizeAddress(address);
return Promise.all(this.keyrings.map((keyring) => {
return Promise.all([
keyring,
keyring.getAccounts(),
])
}))
.then((candidates) => {
const winners = candidates.filter((candidate) => {
const accounts = candidate[1].map(normalizeAddress)
return accounts.includes(hexed)
})
if (winners && winners.length > 0) {
return winners[0][0]
}
return Promise.all(
this.keyrings.map((keyring) => {
return Promise.all([keyring, keyring.getAccounts()]);
}),
).then((candidates) => {
const winners = candidates.filter((candidate) => {
const accounts = candidate[1].map(normalizeAddress);
return accounts.includes(hexed);
});
if (winners && winners.length > 0) {
return winners[0][0];
}
// Adding more info to the error
let errorInfo = 'Error info: '
if (!address) {
errorInfo += 'The address passed in is invalid/empty; '
}
if (!candidates || !candidates.length) {
errorInfo += 'There are no keyrings; '
}
if (!winners || !winners.length) {
errorInfo += 'There are keyrings, but none match the address;'
}
throw new Error(`No keyring found for the requested account. ${errorInfo}`)
})
// Adding more info to the error
let errorInfo = '';
if (!address) {
errorInfo = 'The address passed in is invalid/empty';
} else if (!candidates || !candidates.length) {
errorInfo = 'There are no keyrings';
} else if (!winners || !winners.length) {
errorInfo = 'There are keyrings, but none match the address';
}
throw new Error(
`No keyring found for the requested account. Error info: ${errorInfo}`,
);
});
}

@@ -740,28 +761,12 @@

*/
displayForKeyring (keyring) {
return keyring.getAccounts()
.then((accounts) => {
return {
type: keyring.type,
accounts: accounts.map(normalizeAddress),
}
})
displayForKeyring(keyring) {
return keyring.getAccounts().then((accounts) => {
return {
type: keyring.type,
accounts: accounts.map(normalizeAddress),
};
});
}
/**
* Add Gas Buffer
*
* Adds a healthy buffer of gas to an initial gas estimate.
*
* @param {string} gas - The gas value, as a hex string.
* @returns {string} The buffered gas, as a hex string.
*/
addGasBuffer (gas) {
const gasBuffer = new BN('100000', 10)
const bnGas = new BN(ethUtil.stripHexPrefix(gas), 16)
const correct = bnGas.add(gasBuffer)
return ethUtil.addHexPrefix(correct.toString(16))
}
/**
* Clear Keyrings

@@ -772,19 +777,22 @@ *

*/
/* eslint-disable require-await */
async clearKeyrings () {
async clearKeyrings() {
// clear keyrings from memory
this.keyrings = []
this.keyrings = [];
this.memStore.updateState({
keyrings: [],
})
});
}
/**
* Update Memstore Keyrings
* Update memStore Keyrings
*
* Updates the in-memory keyrings, without persisting.
*/
async _updateMemStoreKeyrings () {
const keyrings = await Promise.all(this.keyrings.map(this.displayForKeyring))
return this.memStore.updateState({ keyrings })
async _updateMemStoreKeyrings() {
const keyrings = await Promise.all(
this.keyrings.map(this.displayForKeyring),
);
return this.memStore.updateState({ keyrings });
}

@@ -799,8 +807,26 @@

*/
setUnlocked () {
this.memStore.updateState({ isUnlocked: true })
this.emit('unlock')
setUnlocked() {
this.memStore.updateState({ isUnlocked: true });
this.emit('unlock');
}
/**
* Forget hardware keyring
*
* Forget hardware and update memorized state.
* @param {Keyring} keyring
*/
forgetKeyring(keyring) {
if (keyring.forgetDevice) {
keyring.forgetDevice();
this.persistAllKeyrings.bind(this)();
this._updateMemStoreKeyrings.bind(this)();
} else {
throw new Error(
`KeyringController - keyring does not have method "forgetDevice", keyring type: ${keyring.type}`,
);
}
}
}
module.exports = KeyringController
module.exports = KeyringController;
{
"name": "eth-keyring-controller",
"version": "6.2.1",
"version": "7.0.0",
"description": "A module for managing various keyrings of Ethereum accounts, encrypting them, and using them.",
"main": "index.js",
"engines": {
"node": ">=12.0.0"
},
"scripts": {
"test": "mocha --timeout 10000 --require test/helper.js test/index.js",
"lint": "eslint . --ext js,json",
"lint:fix": "eslint . --ext js,json --fix"
},
"repository": {
"type": "git",
"url": "git+ssh://git@github.com/MetaMask/KeyringController.git"
},
"keywords": [

@@ -24,37 +11,60 @@ "ethereum",

],
"author": "Dan Finlay <dan@danfinlay.com>",
"license": "ISC",
"homepage": "https://github.com/MetaMask/KeyringController#readme",
"bugs": {
"url": "https://github.com/MetaMask/KeyringController/issues"
},
"homepage": "https://github.com/MetaMask/KeyringController#readme",
"devDependencies": {
"@babel/core": "^7.8.7",
"@metamask/eslint-config": "^3.2.0",
"clone": "^2.1.1",
"eslint": "^6.8.0",
"eslint-plugin-import": "^2.20.1",
"eslint-plugin-json": "^2.1.1",
"eslint-plugin-mocha": "^6.0.0",
"ethereumjs-wallet": "^0.6.3",
"jsdom": "^11.12.0",
"jsdom-global": "^3.0.2",
"mocha": "^7.1.2",
"polyfill-crypto.getrandomvalues": "^1.0.0",
"sinon": "^7.2.7"
"repository": {
"type": "git",
"url": "https://github.com/MetaMask/KeyringController.git"
},
"license": "ISC",
"author": "Dan Finlay <dan@danfinlay.com>",
"main": "index.js",
"files": [
"index.js"
],
"scripts": {
"setup": "yarn install && yarn allow-scripts",
"test": "jest",
"lint:eslint": "eslint . --cache --ext js,ts",
"lint:misc": "prettier '**/*.json' '**/*.md' '!CHANGELOG.md' '**/*.yml' --ignore-path .gitignore",
"lint": "yarn lint:eslint && yarn lint:misc --check",
"lint:fix": "yarn lint:eslint --fix && yarn lint:misc --write"
},
"dependencies": {
"bip39": "^2.4.0",
"bluebird": "^3.5.0",
"@metamask/eth-hd-keyring": "^4.0.2",
"bip39": "^3.0.4",
"browser-passworder": "^2.0.3",
"eth-hd-keyring": "^3.6.0",
"eth-sig-util": "^3.0.1",
"eth-simple-keyring": "^4.2.0",
"ethereumjs-util": "^7.0.9",
"loglevel": "^1.5.0",
"obs-store": "^4.0.3"
},
"files": [
"index.js"
]
"devDependencies": {
"@lavamoat/allow-scripts": "^1.0.6",
"@metamask/auto-changelog": "^2.3.0",
"@metamask/eslint-config": "^7.0.1",
"@metamask/eslint-config-jest": "^7.0.0",
"@metamask/eslint-config-nodejs": "^7.0.1",
"eslint": "^7.29.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-import": "^2.23.4",
"eslint-plugin-jest": "^24.3.6",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-prettier": "^3.4.0",
"ethereumjs-wallet": "^1.0.1",
"jest": "^27.0.6",
"prettier": "^2.3.2",
"prettier-plugin-packagejson": "^2.2.11",
"sinon": "^11.1.1"
},
"engines": {
"node": ">=12.0.0"
},
"lavamoat": {
"allowScripts": {
"@lavamoat/preinstall-always-fail": false,
"keccak": true,
"secp256k1": true
}
}
}

@@ -1,2 +0,2 @@

# Eth Keyring Controller [![CircleCI](https://circleci.com/gh/MetaMask/KeyringController.svg?style=svg)](https://circleci.com/gh/MetaMask/KeyringController)
# Eth Keyring Controller

@@ -8,2 +8,3 @@ A module for managing groups of Ethereum accounts called "Keyrings", defined originally for MetaMask's multiple-account-type feature.

The KeyringController has three main responsibilities:
- Initializing & using (signing with) groups of Ethereum accounts ("keyrings").

@@ -20,4 +21,4 @@ - Keeping track of local nicknames for those individual accounts.

```javascript
const KeyringController = require('eth-keyring-controller')
const SimpleKeyring = require('eth-simple-keyring')
const KeyringController = require('eth-keyring-controller');
const SimpleKeyring = require('eth-simple-keyring');

@@ -27,26 +28,21 @@ const keyringController = new KeyringController({

initState: initState.KeyringController, // Last emitted persisted state.
encryptor: { // An optional object for defining encryption schemes:
// Defaults to Browser-native SubtleCrypto.
encrypt (password, object) {
return new Promise('encrypted!')
encryptor: {
// An optional object for defining encryption schemes:
// Defaults to Browser-native SubtleCrypto.
encrypt(password, object) {
return new Promise('encrypted!');
},
decrypt (password, encryptedString) {
return new Promise({ foo: 'bar' })
decrypt(password, encryptedString) {
return new Promise({ foo: 'bar' });
},
},
})
});
// The KeyringController is also an event emitter:
this.keyringController.on('newAccount', (address) => {
console.log(`New account created: ${address}`)
})
this.keyringController.on('removedAccount', handleThat)
console.log(`New account created: ${address}`);
});
this.keyringController.on('removedAccount', handleThat);
```
## Running tests
```bash
yarn test
```
## Methods

@@ -56,1 +52,16 @@

## Contributing
### Setup
- Install [Node.js](https://nodejs.org) version 12
- If you are using [nvm](https://github.com/creationix/nvm#installation) (recommended) running `nvm use` will automatically choose the right node version for you.
- Install [Yarn v1](https://yarnpkg.com/en/docs/install)
- Run `yarn setup` to install dependencies and run any requried post-install scripts
- **Warning:** Do not use the `yarn` / `yarn install` command directly. Use `yarn setup` instead. The normal install command will skip required post-install scripts, leaving your development environment in an invalid state.
### Testing and Linting
Run `yarn test` to run the tests once.
Run `yarn lint` to run the linter, or run `yarn lint:fix` to run the linter and fix any automatically fixable issues.
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc