bitpay / node-bitpay-client

A Node.js module and command line client for interacting with BitPay's Cryptographically Secure API
102 stars 95 forks source link

Expose notification mechanism used by BitPay's invoice pages, if possible #55

Closed javgh closed 9 years ago

javgh commented 9 years ago

Hi there,

I'm currently trying to integrate the BitPay API into a Bitcoin POS system that I'm building. For this system, I would like to get notified as soon as possible once an invoice has been paid. From what I can tell, I have two choices:

Both of these options don't seem that attractive to me. The POS itself can't really be reliably reached with a callback and requiring a server just for the callback seems like overkill. Having to run a browser and load the invoice page is also something I'd like to avoid, as this is running on an embedded system.

So ideally, I would like to initiate a connection myself to the BitPay server and subscribe to updates for an invoice. In other words, the same mechanism that the invoice page uses, just without all the extra stuff around it. Digging a bit in the source code, it seems some kind of "event bus" exists, that one can theoretically subscribe to. In the API documentation at https://bitpay.com/api#resource-Applications I also see a call to /invoices/:invoiceId/events with the description "Get a bus token which can be used to subscribe to invoice events". However, I couldn't find any further documentation about this.

I would appreciate it very much, if either:

Thanks!

tacticalchihuahua commented 9 years ago

@javgh - I think that integration of the event source API would be of great value to the library. I will take some time this week to get it implemented.

In the meantime, this should get you up and running:

var bitpay  = require('bitpay');
var privKey = 'xxxxxxxxxxxxx';
var client  = bitpay.createClient(privKey);

// tokens are loaded
client.on('ready', function() {
  // get the invoice event bus token
  client.as('public').get('invoices/' + invoiceId + '/events', function(err, buspass) {
    var params = {
      token: buspass.token,
      events: ['payment'],
      action: 'subscribe'
    };
    // client "verb" methods always return a readable stream
    client.as('public').get('events', params).pipe(new EventStreamHandler());
  });
});

In the example, EventStreamHandler would be a stream.Writable, where you would parse the messages and handle them accordingly.

javgh commented 9 years ago

Cool, I give that a try, thanks!