Skip to content

Instantly share code, notes, and snippets.

@braydonf
Last active February 22, 2019 05:13
Show Gist options
  • Save braydonf/79b972eb0be48e9cfe11dc2a6b46699b to your computer and use it in GitHub Desktop.
Save braydonf/79b972eb0be48e9cfe11dc2a6b46699b to your computer and use it in GitHub Desktop.
Bcoin Wallet Strategies

Bcoin Wallet Strategies

This proposes a structure for wallet management stategies for the bcoin wallet.

Motivation

As it is currently you can mix several wallet management strategies within the same wallet in bcoin. This leads to permutations with unintended behavior.

For example, here are a few:

  • HD wallets with many accounts without any transactions that will make address discovery from nearly impossible without the account index information, breaking determinism and shares similarity with a non-HD wallet.
  • HD wallets with extended private keys that can not be fully recovered from seed, as various accounts can be configured differently, including multi-signature, that are not able to be known from the seed alone.
  • A watch-only wallet that can have accounts with unknown and inaccessible private keys. As every wallet needs an account, and every account needs an extended private or public key, accountKey, all wallets will have this HD key, even if it's intended only for use of watching unrelated addresses or private keys.

To resolve this, this proposes having defined stategies for wallets.

Wallet Definitions

Here is an overview of wallet stategy definitions:

/**
 * The purpose for this wallet is for single address and private 
 * keys to be imported and generated. A backup is required every 
 * time there is a new private key generated, this is similar to
 * the very first bitcoin wallet. This wallet can be useful for 
 * sparse use cases of a wallet that may have many addresses for 
 * receiving payments. This also provides the possibility for 
 * arbitrary lookaheads as all that is required is adding more 
 * keys or addresses. This type of wallet is also useful for 
 * recovery of funds using individual private keys without any 
 * specific derivation pattern, for example restoring a wallet 
 * that was backed up in "cold storage", or importing `wallet.dat`
 * file from 2011. This wallet can also function without private 
 * keys and will operate as watch-only, and all signing 
 * capabilities will not be available.
 */

class BasicWallet extends Wallet {
  constructor(options) {
    this.strategy = 'basic';
    this.watchOnly = options.watchOnly; // true or false
    ...
  }
}

/**
 * The purpose of this wallet is to have a single master seed that
 * can be imported or generated, an extended public or private key. 
 * All addresses, private keys and accounts are hierarchically 
 * deterministic from the master seed, and can be completely 
 * restored and imported via the mnemonic phrase (master seed). 
 * Various derivation strategies can be configured for different 
 * types of addresses, for example:
 * 
 *   - P2WPKH (Pay-to-witness-public-key). This uses BIP84 that 
 *     defines an alternative purpose for BIP44 derivation. It uses 
 *     bech32 for segwit addresses. Transactions have less fees and 
 *     the transactions are smaller than the alternatives.
 *   - P2PKH (Pay-to-public-key) This uses BIP44 and is the most 
 *     widely across many wallets as it uses the first address 
 *     encoding base58.
 *   - P2WPKH-nested-in-P2SH (BIP49). Pay-to-witness-public-key-hash
 *     that is nested in a pay-to-script-hash. This is mostly to 
 *     support the recovery of funds, as there are disadvantages, 
 *     including  overall larger transactions sizes. With bech32 
 *     address support this derivation is less relevant.
 * 
 * This wallet can also function watch-only and be without extended 
 * private key and with extended public key. In that case all signing 
 * capabilities will not be available, and should be handled externally 
 * such as an air-gapped computer or hardware device.
 */

class HDWallet extends Wallet {
  constructor(options) {
    this.strategy = 'hd';
    this.derivation = options.derivation; // BIP44, BIP84 or BIP49
    this.watchOnly = options.watchOnly; // true or false
    ...
  }
}

/**
 * The purpose of this wallet is to have a single master seed with
 * a group of cosigners can be imported or added. All addresses
 * and private keys are generated using hierarchically deterministic
 * derivation with the cosigners extendend public keys and the 
 * wallet's extended private key. All addresses, private keys and 
 * can be completely restored and imported via the mnemonic phrase 
 * (master seed) and extended public keys of cosigners. Various 
 * derivation strategies can be configured for different types of 
 * addresses. This wallet can also function watch-only and be without 
 * any extended private key. In that case all signing capabilities 
 * will not be available, and should be handled externally such as 
 * an air-gapped computer or hardware device.
 *
 * The multi-signature stategy is further defined in a draft BIP 
 * titled "Multi-Account Hierarchy for P2WSH Multi-signature 
 * Deterministic Wallet": 
 * https://gist.github.com/braydonf/1b55622fd4a3db682cf322019393eb95
 */

class MultiWallet extends Wallet {
  constructor(options) {
    this.strategy = 'multi';
    this.derivation = options.derivation; // BIPXX
    this.watchOnly = options.watchOnly; // true or false
    ...
  }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment