We are happy to introduce a set of related open source projects that aim to provide a foundation for Multisignature HD Bitcoin Wallet developments.

*Bitcore Wallet Modules*

The first project is bitcore-wallet-service (BWS), a daemon that
facilitates multisig HD wallet creation and operation through a simple and intuitive REST API. BWS can usually be installed within minutes and can accommodate all the needed infrastructure for peers in a multisig wallet to communicate and operate.

The second project is the client library bitcore-wallet-client. The library provides methods for safely accessing BWS and creating peer keys. Responses are validated by the client library:

  • Addresses are derived independently from the extended public keys
  • Transaction proposals are signed and validated by peers
  • During creation, new peers are validated through a secret shared key, unknown by BWS.

The third project is a Command Line Interface based multisig HD Bitcoin wallet, bitcore-wallet.bitcore-wallet is a fully featured bitcoin wallet that uses bitcore-wallet-client and bitcore-wallet-service. It can be used as a reference for developers working on wallets and agents, but with features such as simple one time backup, customizable multisig, and air-gapped operation support, it can also be a powerful wallet for advanced users.

Where to Start?

We are really excited about this software suite. Interoperation between wallets and agents based on BWS opens a thrilling world of possibilities.

We welcome developers to start testing BWS. If you have any questions or concerns, join us at our lab's forum at labs.bitpay.com/c/bitcore. We will be happy to assist you on your project.

Go ahead and clone our Bitcore Wallet to start testing the suite.

Wallet Session Demo

Start by running a local BWS instance:

 npm install bitcore-wallet-service
 cd bitcore-wallet-service
 npm start

Then install wallet:

 npm install -g bitcore-wallet

Let's create a shared wallet between Alice and Bob. Use -t for creating a testnet wallet and -f <file> for setting the where to store the credentials (Add -p to encrypt the credentials file):

$ wallet -f alice.dat create mySharedWallet 2-2 alice -t  
 * Testnet Wallet Created.
   - Secret to share:

Join the new wallet from other peer and create an address for funding the wallet (also supports -p):

$ /wallet -f bob.dat join 49Bm3gumuTCRBTegCpV6w3KwGPvuJDLTenhh1AYKyhmV7ejRpcMQJBSax1DKjjcSB8z7bZCfJuT
 * Wallet Joined. mySharedWallet

$ ./wallet -f bob.dat address
info Your wallet has just been completed. Please backup your wallet file or use the export command.
* New Address 2MyUeaMMUF2ABTBsPs4qbyxh4TwTDHcceFR

Send some testnet bitcoin to it using other wallet. The wallet's balance can be checked with wallet balance or wallet status. Then a transaction proposal can be created and signed by Bob:

$ ./wallet -f bob.dat send n2TBMPzPECGUfcT2EByiTJ12TPZkhN2mN5 1000bit "test transaction"
 * Tx created: ID 01425477795759382a94af-af77-46ed-bf20-d03e50f66e82 [pending] RequiredSignatures: 2

# no arguments to sign all pending TXs
$ ./wallet -f bob.dat sign

And reviewed and signed by the Alice:

$ ./wallet -f alice.dat status
 * Wallet mySharedWallet [testnet]: 2-of-2 complete
 * Copayers: john, ematiu
 * Balance 10,000 bit (Locked: 10,000 bit)
 * TX Proposals:
	6e82 ["test transaction" by ematiu] 1,000 bit => n2TBMPzPECGUfcT2EByiTJ12TPZkhN2mN5
		Actions:  ematiu ✓
		Missing signatures: 1

# Sign with `wallet sign`, reject it with `wallet reject`
$ ./wallet -f alice.dat sign
Transaction signed by you.

$ ./wallet -f alice.dat status
 * Wallet mySharedWallet [testnet]: 2-of-2 complete
 * Copayers: john, ematiu
 * Balance 10,000 bit (Locked: 10,000 bit)
 * TX Proposals:
	6e82 ["test transaction" by ematiu] 1,000 bit => n2TBMPzPECGUfcT2EByiTJ12TPZkhN2mN5
		Actions:  ematiu ✓. john ✓
		Ready to broadcast

Finally, broadcast it to the bitcoin network!

$ ./wallet -f john.dat broadcast
Transaction Broadcasted: TXID: 8bf855c2e087575cab6db143267dec929fe6b744ad9d7c4f64cf208569a99644

Done! All wallet commands can be listed with

$ ./wallet --help

Wallets and Agents

BWS supports signing and non-signing agents.

Agents can be given a wallet secret, join the wallet during creation, and act with the same status of a regular peer. This would be the case for a signing agent that authorize wallets transactions following certain rules.

Agents can also be created by cloning one peer's data (and optionally removing its private key). By removing the private key, the resulting agent won't be able to sign transactions. Here are some examples of apps that could be built on top of BWS:

Non-signing agents:
  • Balance notification agents
  • Accounting apps
  • Recurring billing
  • Bill paying
  • Signing Agents:
  • Rule-based transaction limiters / signers

We are planning to extend agent support in following releases.

The Wallet Service and Copay

Nine months ago, we started the open source project Copay, a Multisig HD Wallet. With BWS we think we can take Copay to the next level.

In the next weeks we will be modifying Copay to use BWS. All of Copay's peers will coordinate their operation though BWS. This will allow:

  • smoother operation on mobile clients
  • better network usage
  • simpler one-time backups
  • asynchronous wallet creation
  • and overall a much more robust operation.

A public BWS instance will be provided by BitPay for general use. Users will be able to use the public instance or run their own. All wallets and agents developed on top of BWS will interoperate with Copay transparently.

What if a BWS instance is compromised or disappears?

BWS instances do not hold peers' private keys. If the instance becomes unavailable for any reason, peers could easily recreate the wallet on other BWS instance. With the required quorum, funds could be accessed. Funds cannot be compromised if someone were to take control of the BWS instance.

Peers also verify all sensitive BWS responses. Wallet addresses are derived by peers and transaction proposals are signed and independently verified by peers as well.

BWS instances do hold the extended public key of the wallets they accommodate, so an attacker could access the wallet's transaction history (note that there is not linkage to real IDs) and also future movements. For privacy reasons, the BWS instance must be kept safe. In the case of an intrusion, wallets should be swiped and funds moved to new wallets. There is an ongoing effort to remove the extended public keys from BWS. This will generate some other problems, so it requires further study and will be probably be optional .

Future Work on BWS

Our short list of to do's for the next release of BWS v0.2 are:

  • Add websocket layer to notify connected copayers about notifications.
  • Remove extended public keys from service's instance for enhanced wallet privacy.
  • Agent access control: Provide a complete API for allowing agents to access a wallet, with different access permissions.