diff --git a/README.md b/README.md index b6f2ac3..523fc4e 100644 --- a/README.md +++ b/README.md @@ -12,9 +12,9 @@ You will have to pollute your system a little for this to work. Luckily, it work ### Start -Change the mnemonic to your own in `.env.example` and rename `.env.example` to `.env`. - -- Run `node start.js` with optional flags +1. Clone repo and modify the mnemonic in the `.env` file. +2. If you want to add some pre-created private keys, add them to the `.mykeys` file. +3. Run `node start.js`. Optionally, pass in a `v` argument to autogenerate that many validators (`v=10`) and/or the `mykeys` argument to make the script read the keys specified in step 2. The blockchain database will be stored in the `deploy/db` subfolder. The `deploy/keys` subfolder will have keys for relevant accounts generated, including the address to the deposit contract. The `deploy/faucet` folder will contain a simple web UI for a faucet. @@ -22,20 +22,20 @@ The blockchain database will be stored in the `deploy/db` subfolder. The `deploy Augment `start.js` with flags, .e.g. `node start.js v=50 mykeys`: -- `v` : Number of validators to generate. These validators will be generated with 32.1 ether each and will auto-deposit 32 ether to the deposit contract. Their private keys will be in `deploy/keys` @TODO, `account_keys_path` in Ganache seems bugged. -- `mykeys`: This is a boolean flag, so just include it to activate it. Passing this in will make the boostrapper read a `.mykeys.json` file in the root of the project, looking for private keys. The file should be a JSON object of address=>privkey pairs, `0x` included. These keys will then also be included as validators: they will be given 32.1 ether and deposit it into the contract. See `.mykeys.example` for example. +- `v` : Number of validators to generate. These validators will be generated with 32.1 ether each and will auto-deposit 32 ether to the deposit contract. Their private keys will be in `deploy/keys`. Defaults to 10 if omitted, but only triggers default is `mykeys` argument not provided. +- `mykeys`: This is a boolean flag, so just include it to activate it. Passing this in will make the boostrapper read a `.mykeys.json` file in the root of the project, looking for private keys. The file should be a JSON object of (address => privkey) pairs, `0x` included. These keys will then also be included as validators: they will be given 32.1 ether and deposit it into the contract. See `.mykeys.example` for example. ### Hosting -To host the generated blockchain online, upload the `deploy` folder somewhere and `cd` into it. +The generator is deterministic. You always end up with the same addresses, accounts and balances if you use the same mnemonic and `.mykeys` list. Thus, to host it somewhere, simply clone this repo to the server and run it the same way you do locally. -- Run Ganache from the existing database with `yarn run ganache`. This auto-reads from `./db` and opens up web3/RPC so others can connect to your Ganache and try being validators. -- Run the faucet with `yarn run faucet --port 8080`. The faucet will be hosted on port 8080. -- @TODO Run the simple UI for validators to deposit Ether and check their balance with `yarn run validator-ui`. +- `node start.js` will run the blockchain and start the server in listen mode with RPC/Web3 allowed +- `yarn run faucet --port 8080` will host the ether faucet at `localhost:8080` +- `yarn run validator-ui --port 8081` will host the validator UI at `localhost:8081` // @TODO ### Other commands -- To clean the DB and start over delete `deploy/db/*` or run `yarn run clean`. +- To clean the DB and start over run `yarn run clean`. ## Contributing diff --git a/package.json b/package.json index cf1ee79..899f06b 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ "author": "Bruno Škvorc ", "license": "MIT", "dependencies": { + "@chainsafe/bls-js": "^0.1.5", "dotenv": "^8.0.0", "ethers": "^4.0.33", "ganache-cli": "^6.5.0" diff --git a/start.js b/start.js index a2e8fdb..e9ebcff 100644 --- a/start.js +++ b/start.js @@ -1,11 +1,14 @@ require('dotenv').config(); - const ethers = require('ethers'); const fs = require('fs'); +const keypair = require('@chainsafe/bls-js/lib/keypair'); +const privateKey = require('@chainsafe/bls-js/lib/privateKey'); +// Deposit contract data const deposit_contract_bytecode = "0x740100000000000000000000000000000000000000006020526f7fffffffffffffffffffffffffffffff6040527fffffffffffffffffffffffffffffffff8000000000000000000000000000000060605274012a05f1fffffffffffffffffffffffffdabf41c006080527ffffffffffffffffffffffffed5fa0e000000000000000000000000000000000060a052341561009857600080fd5b6101406000601f818352015b600061014051602081106100b757600080fd5b600260c052602060c020015460208261016001015260208101905061014051602081106100e357600080fd5b600260c052602060c020015460208261016001015260208101905080610160526101609050602060c0825160208401600060025af161012157600080fd5b60c0519050606051600161014051018060405190131561014057600080fd5b809190121561014e57600080fd5b6020811061015b57600080fd5b600260c052602060c02001555b81516001018083528114156100a4575b505061124d56600035601c52740100000000000000000000000000000000000000006020526f7fffffffffffffffffffffffffffffff6040527fffffffffffffffffffffffffffffffff8000000000000000000000000000000060605274012a05f1fffffffffffffffffffffffffdabf41c006080527ffffffffffffffffffffffffed5fa0e000000000000000000000000000000000060a052600015610277575b6101605261014052600061018052610140516101a0526101c060006008818352015b61018051600860008112156100da578060000360020a82046100e1565b8060020a82025b905090506101805260ff6101a051166101e052610180516101e0516101805101101561010c57600080fd5b6101e0516101805101610180526101a0517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff86000811215610155578060000360020a820461015c565b8060020a82025b905090506101a0525b81516001018083528114156100bd575b50506018600860208206610200016020828401111561019357600080fd5b60208061022082610180600060046015f15050818152809050905090508051602001806102c0828460006004600a8704601201f16101d057600080fd5b50506102c05160206001820306601f82010390506103206102c0516008818352015b826103205111156102025761021e565b6000610320516102e001535b81516001018083528114156101f2575b50505060206102a05260406102c0510160206001820306601f8201039050610280525b6000610280511115156102535761026f565b602061028051036102a001516020610280510361028052610241565b610160515650005b63863a311b600051141561050957341561029057600080fd5b6000610140526101405161016052600154610180526101a060006020818352015b60016001610180511614156103325760006101a051602081106102d357600080fd5b600060c052602060c02001546020826102400101526020810190506101605160208261024001015260208101905080610240526102409050602060c0825160208401600060025af161032457600080fd5b60c0519050610160526103a0565b6000610160516020826101c00101526020810190506101a0516020811061035857600080fd5b600260c052602060c02001546020826101c0010152602081019050806101c0526101c09050602060c0825160208401600060025af161039657600080fd5b60c0519050610160525b61018060026103ae57600080fd5b60028151048152505b81516001018083528114156102b1575b505060006101605160208261046001015260208101905061014051610160516101805163806732896102e05260015461030052610300516006580161009b565b506103605260006103c0525b6103605160206001820306601f82010390506103c0511015156104355761044e565b6103c05161038001526103c0516020016103c052610413565b61018052610160526101405261036060088060208461046001018260208501600060046012f150508051820191505060006018602082066103e0016020828401111561049957600080fd5b60208061040082610140600060046015f150508181528090509050905060188060208461046001018260208501600060046014f150508051820191505080610460526104609050602060c0825160208401600060025af16104f957600080fd5b60c051905060005260206000f350005b63621fd130600051141561061c57341561052257600080fd5b63806732896101405260015461016052610160516006580161009b565b506101c0526000610220525b6101c05160206001820306601f82010390506102205110151561056d57610586565b610220516101e00152610220516020016102205261054b565b6101c0805160200180610280828460006004600a8704601201f16105a957600080fd5b50506102805160206001820306601f82010390506102e0610280516008818352015b826102e05111156105db576105f7565b60006102e0516102a001535b81516001018083528114156105cb575b5050506020610260526040610280510160206001820306601f8201039050610260f350005b63c47e300d60005114156110c857605060043560040161014037603060043560040135111561064a57600080fd5b60406024356004016101c037602060243560040135111561066a57600080fd5b608060443560040161022037606060443560040135111561068a57600080fd5b63ffffffff6001541061069c57600080fd5b633b9aca006102e0526102e0516106b257600080fd5b6102e05134046102c052633b9aca006102c05110156106d057600080fd5b603061014051146106e057600080fd5b60206101c051146106f057600080fd5b6060610220511461070057600080fd5b610140610360525b6103605151602061036051016103605261036061036051101561072a57610708565b6380673289610380526102c0516103a0526103a0516006580161009b565b50610400526000610460525b6104005160206001820306601f8201039050610460511015156107765761078f565b6104605161042001526104605160200161046052610754565b610340610360525b61036051526020610360510361036052610140610360511015156107ba57610797565b610400805160200180610300828460006004600a8704601201f16107dd57600080fd5b5050610140610480525b61048051516020610480510161048052610480610480511015610809576107e7565b63806732896104a0526001546104c0526104c0516006580161009b565b50610520526000610580525b6105205160206001820306601f8201039050610580511015156108545761086d565b6105805161054001526105805160200161058052610832565b610460610480525b610480515260206104805103610480526101406104805110151561089857610875565b6105208051602001806105a0828460006004600a8704601201f16108bb57600080fd5b505060a06106205261062051610660526101408051602001806106205161066001828460006004600a8704601201f16108f357600080fd5b505061062051610660015160206001820306601f8201039050610620516106600161060081516040818352015b83610600511015156109315761094e565b6000610600516020850101535b8151600101808352811415610920575b50505050602061062051610660015160206001820306601f82010390506106205101016106205261062051610680526101c08051602001806106205161066001828460006004600a8704601201f16109a557600080fd5b505061062051610660015160206001820306601f8201039050610620516106600161060081516020818352015b83610600511015156109e357610a00565b6000610600516020850101535b81516001018083528114156109d2575b50505050602061062051610660015160206001820306601f820103905061062051010161062052610620516106a0526103008051602001806106205161066001828460006004600a8704601201f1610a5757600080fd5b505061062051610660015160206001820306601f8201039050610620516106600161060081516020818352015b8361060051101515610a9557610ab2565b6000610600516020850101535b8151600101808352811415610a84575b50505050602061062051610660015160206001820306601f820103905061062051010161062052610620516106c0526102208051602001806106205161066001828460006004600a8704601201f1610b0957600080fd5b505061062051610660015160206001820306601f8201039050610620516106600161060081516060818352015b8361060051101515610b4757610b64565b6000610600516020850101535b8151600101808352811415610b36575b50505050602061062051610660015160206001820306601f820103905061062051010161062052610620516106e0526105a08051602001806106205161066001828460006004600a8704601201f1610bbb57600080fd5b505061062051610660015160206001820306601f8201039050610620516106600161060081516020818352015b8361060051101515610bf957610c16565b6000610600516020850101535b8151600101808352811415610be8575b50505050602061062051610660015160206001820306601f8201039050610620510101610620527f649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c561062051610660a160006107005260006101406030806020846107c001018260208501600060046016f150508051820191505060006010602082066107400160208284011115610cad57600080fd5b60208061076082610700600060046015f15050818152809050905090506010806020846107c001018260208501600060046013f1505080518201915050806107c0526107c09050602060c0825160208401600060025af1610d0d57600080fd5b60c0519050610720526000600060406020820661086001610220518284011115610d3657600080fd5b606080610880826020602088068803016102200160006004601bf1505081815280905090509050602060c0825160208401600060025af1610d7657600080fd5b60c0519050602082610a600101526020810190506000604060206020820661092001610220518284011115610daa57600080fd5b606080610940826020602088068803016102200160006004601bf15050818152809050905090506020806020846109e001018260208501600060046015f1505080518201915050610700516020826109e0010152602081019050806109e0526109e09050602060c0825160208401600060025af1610e2757600080fd5b60c0519050602082610a6001015260208101905080610a6052610a609050602060c0825160208401600060025af1610e5e57600080fd5b60c0519050610840526000600061072051602082610b000101526020810190506101c0602080602084610b0001018260208501600060046015f150508051820191505080610b0052610b009050602060c0825160208401600060025af1610ec457600080fd5b60c0519050602082610c800101526020810190506000610300600880602084610c0001018260208501600060046012f15050805182019150506000601860208206610b800160208284011115610f1957600080fd5b602080610ba082610700600060046015f1505081815280905090509050601880602084610c0001018260208501600060046014f150508051820191505061084051602082610c0001015260208101905080610c0052610c009050602060c0825160208401600060025af1610f8c57600080fd5b60c0519050602082610c8001015260208101905080610c8052610c809050602060c0825160208401600060025af1610fc357600080fd5b60c0519050610ae0526001805460018254011015610fe057600080fd5b6001815401815550600154610d0052610d2060006020818352015b60016001610d005116141561103057610ae051610d20516020811061101f57600080fd5b600060c052602060c02001556110c4565b6000610d20516020811061104357600080fd5b600060c052602060c0200154602082610d40010152602081019050610ae051602082610d4001015260208101905080610d4052610d409050602060c0825160208401600060025af161109457600080fd5b60c0519050610ae052610d0060026110ab57600080fd5b60028151048152505b8151600101808352811415610ffb575b5050005b60006000fd5b61017f61124d0361017f60003961017f61124d036000f3"; const deposit_contract_abi = '[{"name": "DepositEvent", "inputs": [{"type": "bytes", "name": "pubkey", "indexed": false}, {"type": "bytes", "name": "withdrawal_credentials", "indexed": false}, {"type": "bytes", "name": "amount", "indexed": false}, {"type": "bytes", "name": "signature", "indexed": false}, {"type": "bytes", "name": "index", "indexed": false}], "anonymous": false, "type": "event"}, {"outputs": [], "inputs": [], "constant": false, "payable": false, "type": "constructor"}, {"name": "get_hash_tree_root", "outputs": [{"type": "bytes32", "name": "out"}], "inputs": [], "constant": true, "payable": false, "type": "function", "gas": 91707}, {"name": "get_deposit_count", "outputs": [{"type": "bytes", "name": "out"}], "inputs": [], "constant": true, "payable": false, "type": "function", "gas": 10463}, {"name": "deposit", "outputs": [], "inputs": [{"type": "bytes", "name": "pubkey"}, {"type": "bytes", "name": "withdrawal_credentials"}, {"type": "bytes", "name": "signature"}], "constant": false, "payable": true, "type": "function", "gas": 1334230}]'; +// Command-line arguments parser var args = process.argv.slice(2); var arglist = {}; args.forEach(function (val, index, array) { @@ -17,14 +20,23 @@ args.forEach(function (val, index, array) { } }); +// @TODO make faucet balance configurable const startupOptions = { "mnemonic": process.env.mnemonic, "default_balance_ether": 1000000, "total_accounts": 1, "db_path": "./deploy/db", - "account_keys_path": "./deploy/keys/validators.json" + "network_id": 666, + "account_keys_path": "./deploy/keys/validators.json" // Does not work yet: https://github.com/trufflesuite/ganache-cli/issues/663 }; +// Default to 10 accounts if no options provided +if (!arglist.v && !arglist.mykeys) { + console.log("No number of auto-generated accounts specified, and no custom keys provided. Defaulting to 10 accounts."); + arglist.v = 10; +} + +// Generate `v` number of accounts with 32.1 ether each var accounts = []; if (arglist.v && arglist.v > 0) { accounts.push({"balance": 0xD3C21BCECCEDA1000000}); @@ -35,10 +47,12 @@ if (arglist.v && arglist.v > 0) { startupOptions.accounts = accounts; } +// Feed all accounts in `.mykeys` with 32.1 ether var myAccounts = []; +var mykeys; if (arglist.mykeys) { try { - var mykeys = require("./.mykeys.json"); + mykeys = require("./.mykeys.json"); } catch (e) { console.error("Did you make sure .mykeys exists in this folder before running the command with the mykeys flag?"); @@ -62,13 +76,13 @@ if (arglist.mykeys) { } } -let unlockedAccounts = +// Bootstrap Ganache console.log("Bootstrapping with options:"); console.log(startupOptions); - const ganache = require("ganache-cli"); const provider = new ethers.providers.Web3Provider(ganache.provider(startupOptions)); +// Seed and export faucet account var faucetAmount; provider.listAccounts().then(function(result){ provider.getBalance(result[0]).then(function(balanceResult) { @@ -90,6 +104,7 @@ provider.listAccounts().then(function(result){ }); +// Deploy deposit contract, precompiled, save its address into a file async function deployDepositContract(pk) { let factory = new ethers.ContractFactory(deposit_contract_abi, deposit_contract_bytecode, new ethers.Wallet(pk, provider)); let contract = await factory.deploy(); @@ -106,28 +121,87 @@ async function deployDepositContract(pk) { } async function makeValidatorDeposits() { - console.log("Starting validator deposits") - provider.listAccounts().then(function(result) { - // Remove first one (faucet account) - var accounts = result.splice(1); - - for (var i = 1; i < accounts.length; i++) { - let signer = provider.getSigner(accounts[i]); - - // TODO deposits, need to figure out BLS - + let accountMasterList = []; + + if (arglist.v) { + console.log("Generating keys for "+ arglist.v +" auto-generated accounts"); + for (var i = 0; i <= arglist.v; i++) { + let mnemonicWallet = new ethers.Wallet.fromMnemonic(process.env.mnemonic, "m/44'/60'/0'/0/"+i); + let pk = mnemonicWallet.privateKey; + + let bls_key_sign = new keypair.Keypair(privateKey.PrivateKey.fromHexString(pk)).privateKey.toHexString(); + let bls_key_withdraw = new keypair.Keypair(privateKey.PrivateKey.fromHexString(invertHex(pk))).privateKey.toHexString(); + + accountMasterList.push({ + address: mnemonicWallet.address, + pk: pk, + bls_key_sign: bls_key_sign, + bls_key_withdraw, bls_key_withdraw + }); + } + } + + if (arglist.mykeys) { + console.log("Generating keys for " + Object.keys(mykeys).length + " pre-provided accounts"); + for (var key in mykeys) { + if (mykeys.hasOwnProperty(key)) { + console.log("Generating for account " + key); + let pkWallet = new ethers.Wallet(mykeys[key]); + pk = pkWallet.privateKey; + + let bls_key_sign = new keypair.Keypair(privateKey.PrivateKey.fromHexString(pk)).privateKey.toHexString(); + let bls_key_withdraw = new keypair.Keypair(privateKey.PrivateKey.fromHexString(invertHex(pk))).privateKey.toHexString(); + + accountMasterList.push({ + address: key, + pk: pk, + bls_key_sign: bls_key_sign, + bls_key_withdraw, bls_key_withdraw + }); + } + } + } + + console.log("Saving keys to file"); + fs.writeFile("deploy/keys/validators.json", JSON.stringify(accountMasterList), function(err) { + if(err) { + return console.log(err); + } + console.log("Validator list saved in deploy/keys/validators.json."); + }); + + console.log("Starting validator deposits"); + accountMasterList.forEach(function(item) { + + // @TODO + //let signer = provider.getSigner(item.address); + /* + 1. Generate bls/eth2 privkey and pubkey for signing (random). This gives me the signing pubkey of 48 bytes length. + 2. Generate bls/eth2 privkey and pubkey for withdrawal (random) + 3. Put the deposit data together: pubkey is the signing pubkey, withdrawal credentials is the sha256 hash of the withdrawal pubkey (32 bytes), but the first byte of the hash is replaced with the prefix (currently 0 for version 0), breaking the hash, while signature is technically bls_sign(signing_privkey, signing_root(deposit_data)) but due to the circular dependency the signature here is actually ignored (!!) which is not detailed in the spec, and can be nothing, null, or random data. + 4. Signature for Deposit call is then again bls_sign(signing_privkey, signing_root(deposit_data)) which should produce 96 bytes. + */ + + // Example simple tx // signer.sendTransaction({ // to: accounts[0], // value: ethers.utils.parseEther('15.0') // }).then(function(txReceipt) { // provider.getBalance(accounts[0]).then(console.log); // }.bind(accounts)); - - } - - // for (var i = 0; i < accounts.length; i++) { - // provider.getBalance(accounts[i]).then(console.log); - // } }); + + + + const server = ganache.server(startupOptions); + server.listen(8545, function(err, blockchain) { + // The server starts, you can connect to it with RPC now. + console.log("Server is running, feel free to connect!"); + }); +} + +function invertHex(hexString) { + hexString = hexString.replace("0x", ""); + return "0x" + hexString.split("").reverse().join(""); } \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index a6b25c4..76789b2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,21 @@ # yarn lockfile v1 +"@chainsafe/amcl@0.1.0": + version "0.1.0" + resolved "https://registry.yarnpkg.com/@chainsafe/amcl/-/amcl-0.1.0.tgz#8a49445402561e3dcf9d536b78e2dc225b159b22" + integrity sha512-XzVLRxAqkkFeLA9T3ro1gn8llV3y6FIN38bRgmp5HvOJyfBprotKa6973J7BL7X566R6uztoNweK8ng40G08tw== + +"@chainsafe/bls-js@^0.1.5": + version "0.1.5" + resolved "https://registry.yarnpkg.com/@chainsafe/bls-js/-/bls-js-0.1.5.tgz#00fed1ef879aa4668092e7010fa21f5bf19f569e" + integrity sha512-etAnBTthmeub8igCx08Ww3TQRkK93bwM8nUNE5LNE3W1s1tySka7qsYcdmOKICJNTa7ARV/MbVnBg1nAUwntZQ== + dependencies: + "@chainsafe/amcl" "0.1.0" + assert "^1.4.1" + js-sha256 "^0.9.0" + secure-random "^1.1.1" + "@types/node@^10.3.2": version "10.14.13" resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.13.tgz#ac786d623860adf39a3f51d629480aacd6a6eec7" @@ -22,6 +37,14 @@ ansi-regex@^3.0.0: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= +assert@^1.4.1: + version "1.5.0" + resolved "https://registry.yarnpkg.com/assert/-/assert-1.5.0.tgz#55c109aaf6e0aefdb3dc4b71240c70bf574b18eb" + integrity sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA== + dependencies: + object-assign "^4.1.1" + util "0.10.3" + bn.js@4.11.8, bn.js@^4.4.0: version "4.11.8" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" @@ -156,6 +179,11 @@ hash.js@^1.0.0: inherits "^2.0.3" minimalistic-assert "^1.0.1" +inherits@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" + integrity sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE= + inherits@^2.0.1, inherits@^2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" @@ -188,6 +216,11 @@ isexe@^2.0.0: resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= +js-sha256@^0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/js-sha256/-/js-sha256-0.9.0.tgz#0b89ac166583e91ef9123644bd3c5334ce9d0966" + integrity sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA== + js-sha3@0.5.7: version "0.5.7" resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.5.7.tgz#0d4ffd8002d5333aabaf4a23eed2f6374c9f28e7" @@ -245,6 +278,11 @@ number-is-nan@^1.0.0: resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= +object-assign@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= + os-locale@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-2.1.0.tgz#42bc2900a6b5b8bd17376c8e882b65afccf24bf2" @@ -308,6 +346,11 @@ scrypt-js@2.0.4: resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-2.0.4.tgz#32f8c5149f0797672e551c07e230f834b6af5f16" integrity sha512-4KsaGcPnuhtCZQCxFxN3GVYIhKFPTdLd8PLC552XwbMndtD0cjRFAhDuuydXQ0h08ZfPgzqe6EKHozpuH74iDw== +secure-random@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/secure-random/-/secure-random-1.1.2.tgz#ed103b460a851632d420d46448b2a900a41e7f7c" + integrity sha512-H2bdSKERKdBV1SwoqYm6C0y+9EA94v6SUBOWO8kDndc4NoUih7Dv6Tsgma7zO1lv27wIvjlD0ZpMQk7um5dheQ== + set-blocking@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" @@ -384,6 +427,13 @@ strip-eof@^1.0.0: resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= +util@0.10.3: + version "0.10.3" + resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" + integrity sha1-evsa/lCAUkZInj23/g7TeTNqwPk= + dependencies: + inherits "2.0.1" + uuid@2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/uuid/-/uuid-2.0.1.tgz#c2a30dedb3e535d72ccf82e343941a50ba8533ac"