bitpay/copay — pull request #1043 by chjj (2014-08-05 00:48:39+00:00)
Title: WIP: Payment Protocol (BIP-70)

So here is payment protocol in copay.

[![payment protocol in copay](https://i.imgur.com/SagvioU.png)](https://i.imgur.com/SagvioU.png)

[![payment protocol sent in copay](https://i.imgur.com/2tD4mQl.png)](https://i.imgur.com/2tD4mQl.png)

The major changes involved an addition to the core Wallet model (essentially mirroring `createTx`/`sendTx` for payment protocol), and checking for a payment protocol URI in the `address` directive.

It works very simply: a user pastes a payment protocol URI into the address field. Copay automatically recognizes it as a payment protocol uri and fetches the payment request from the server. It then caches the payment request (hereon known as `merchant data`), and attaches it to the transaction proposal so every copayer can get a look at it and potentially build the transaction (based on the outputs sent by the server) which gets sent to the payment server once enough copayers have signed.

In our case (for testing), you could paste (BIP-72):

```
bitcoin:?r=https://localhost:3000/-/request
```

Or, a backwardly compatible URI:

```
bitcoin:2NBzZdFBoQymDgfzH2Pmnthser1E71MmU47?amount=0.00003&r=https://localhost:3000/-/request
```

NOTE: This requires the latest bitcore HEAD to be in `lib/` and `node_modules/`.

**Some Issues:**

- Angular form validation does not like when I forcefully alter the `amount` field and disable it after receiving outputs and totaling up the values. I have to manually set the form's and fields' `$valid` and `$invalid` properties.

- Forcefully altering the form to suit payment protocol just feels ugly and there might be a more angular-y way to do it.

- Angular's http module cannot send binary data, ArrayBuffers, or ArrayBuffer views. We have to overwrite it with our own superior xhr function.

- The browser does **not** like XHR'ing servers with self-signed certs **even if this cert is added to the trusted certs in the browser** (tested with chromium and firefox) and even if the CORS headers on the payment server are all in order. The way around this *in testing* is to run the payment protocol server within the copay server itself: `$ USE_HTTPS=1 npm start` (see the code in app.js). Another way around it would be to use the copay server as an http proxy to do requests with strict ssl disabled - obviously not ideal.

- Protobufjs sometimes only allows js Numbers for amounts of satoshis (`refund_outputs` for example). This can hurt us when dealing with bignums. However, in the case of `refund_outputs`, the server with probably just ignore the amount anyway.

Other than that, I'm happy to say everything works. I've spent the day writing 12 tests for payment protocol, testing every aspect. The tests themselves mock a payment server which should run in the browser and node (however, I've only tested them in node). The paypro branch is rebased onto master, and I will continue to rebase and force push until this is merged.