# Accounts

Some quick examples of using Accounts.

## Dump All JSON Wallet Balances (in current directory)

Load JSON Wallet Balances

    const fs = require('fs');
    const path = require('path');

    const ethers = require('ethers');

    let provider = ethers.getDefaultProvider();

    // Geth
    let dirname = path.join(process.env.HOME, '.ethereum', 'keystore');

    // Parity (use the name of your chain for chainDirectory, such as "homestead")
    //var dirname = path.join(process.env.HOME, '.parity', 'keys', chainDirectory, 'keys');

    let filenames = fs.readdirSync(dirname);

    filenames.forEach(async function(filename) {

        // Get the Wallet JSON
        let data = await fs.readFile(path.join(dirname,filename));

        // Get the Wallet address
        let address = ethers.utils.getJsonWalletAddress(data.toString());

        // Look up the balance
        let balance = await provider.getBalance(address);

        console.log(address + ':' + ethers.utils.formatEther(balance));
    });

## Sweep an Account into Another

This will sweep all the funds from one account’s privateKey and place it in another account, newAddress.

Sweep an Account

    const ethers = require('ethers');

    async function sweep(privateKey, newAddress) {

        let provider = ethers.getDefaultProvider();

        let wallet = new ethers.Wallet(privateKey, provider);

        // Make sure we are sweeping to an EOA, not a contract. The gas required
        // to send to a contract cannot be certain, so we may leave dust behind
        // or not set a high enough gas limit, in which case the transaction will
        // fail.
        let code = await provider.getCode(newAddress);
        if (code !== '0x') { throw new Error('Cannot sweep to a contract'); }

        // Get the current balance
        let balance = await wallet.getBalance();

        // Normally we would let the Wallet populate this for us, but we
        // need to compute EXACTLY how much value to send
        let gasPrice = await provider.getGasPrice();

        // The exact cost (in gas) to send to an Externally Owned Account (EOA)
        let gasLimit = 21000;

        // The balance less exactly the txfee in wei
        let value = balance.sub(gasPrice.mul(gasLimit))

        let tx = await wallet.sendTransaction({
            gasLimit: gasLimit,
            gasPrice: gasPrice,
            to: newAddress,
            value: value
        });

        console.log('Sent in Transaction: ' + tx.hash);
    });

## Coalesce Jaxx Wallets

The Jaxx Wallet (for iOS, Android, desktop, et cetera) uses HD wallets on Ethereum the same way as Bitcoin, which results in each transaction being received by a separate address. As a result, funds get spread across many accounts, making several operations in Ethereum impossible.

This short recipe will coalesce all these accounts into a single one, by sending the funds from each account into a single one.

This also results in paying multiple transaction fees (1 fee per account to merge).

@TODO: This is incomplete!!

TODO

    const ethers = require('ethers');

    let provider = ethers.getDefaultProvider();

    let mnemonic = "radar blur cabbage chef fix engine embark joy scheme fiction master release";
    let hdnode = ethers.utils.HDNode.fromMnemonic(mnemonic);
    let hdnode = hdnode.derivePath("m/44'/60'/0'/0");

     // @TODO

## Access Funds in a Mnemonic Phrase Wallet

@TODO: This is incomplete

TODO

    const ethers = require('ethers');

    let walletPath = {
        "standard": "m/44'/60'/0'/0/0",

        // @TODO: Include some non-standard wallet paths
    };

    let mnemonic = "radar blur cabbage chef fix engine embark joy scheme fiction master release";
    let hdnode = ethers.HDNode.fromMnemonic(mnemonic);
    let node = hdnode.derivePath(walletPath.standard);

    let wallet = new ethers.Wallet(node.privateKey);
    console.log(wallet.address);
    // 0xaC39b311DCEb2A4b2f5d8461c1cdaF756F4F7Ae9

    // @TODO:

## Random Mnemonic

Often you may simply want a random mnemonic that is valid. It is important to note that not all random sets of words are valid; there is a checksum included in the binary encoding of the entropy, so it is important to use a method that correctly encodes this checksum.

Random Mnemonic

    const ethers = require('ethers');

    // All createRandom Wallets are generated from random mnemonics
    let wallet = ethers.Wallet.createRandom();
    let randomMnemonic = wallet.mnemonic;

More Complex Random Mnemonic

    const utils = require('ethers/utils');

    // Chose the length of your mnemonic:
    //   - 16 bytes => 12 words (* this example)
    //   - 20 bytes => 15 words
    //   - 24 bytes => 18 words
    //   - 28 bytes => 21 words
    //   - 32 bytes => 24 words
    let bytes = ethers.utils.random(16);

    // Select the language:
    //   - en, es, fr, ja, ko, it, zh_ch, zh_tw
    let language = ethers.wordlists.en;

    let randomMnemonic = ethers.utils.HDNode.entropyToMnemonic(bytes, language)

## Get Transaction History

Unfortunately, transaction history is not something that is easy to get. It is not indexed by the blockchain, not by a standard node, “out-of-the-box”. At the time of this recipe, the indices to store the entire history are around 800GB. For Parity you may enable tracing and disable pruning, in which case you can use some of the vendor specific JSON-RPC debug methods.

For many cases, you can probably rely on Etherscan, which dedicates large amounts of resources to tracking and storing this information.

Transaction History

    let etherscanProvider = new ethers.providers.EtherscanProvider();

    etherscanProvider.getHistory(address).then((history) => {
        history.forEach((tx) => {
            console.log(tx);
        })
    });

@TODO: Example of signing and verifying a hash in ethers and in Solidity.