UNPKG

ilp

Version:

ILP client library for sending and receiving payments

144 lines 5.62 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const bignumber_js_1 = require("bignumber.js"); const crypto = require("crypto"); const promise_1 = require("./promise"); const assert = require("assert"); const createLogger = require('ilp-logger'); const log = createLogger('invoice'); class InvoiceReceiver { constructor(amount, reference = crypto.randomBytes(16).toString('hex'), streamServer) { assert(/^[A-Za-z0-9~_-]*$/.test(reference), 'Reference can only contain valid ILP Address characters.'); this._connectionTag = reference; const { destinationAccount, sharedSecret } = streamServer.generateAddressAndSecret(this._connectionTag); this._expectedAmount = new bignumber_js_1.default(amount); this._assetCode = streamServer.assetCode; this._assetScale = streamServer.assetScale; this._destinationAccount = destinationAccount; this._sharedSecret = sharedSecret; this._receivedData = Buffer.alloc(0); this._dataPromise = new promise_1.UnwrappedPromise(); this._paymentPromise = new promise_1.UnwrappedPromise(); streamServer.on('connection', (connection) => { if (connection.connectionTag === this._connectionTag) { log.debug(`connection opened`); this._streamConnection = connection; connection.on('stream', (stream) => { log.debug(`stream created`); stream.setReceiveMax(this._expectedAmount); stream.on('money', (amountReceived) => { log.trace(`${amountReceived} received`); if (new bignumber_js_1.default(connection.totalReceived).isGreaterThanOrEqualTo(this._expectedAmount)) { this._complete(); } }); stream.on('data', (dataReceived) => { log.trace(`${dataReceived.byteLength} bytes of data received`); this._receivedData = Buffer.concat([this._receivedData, dataReceived]); }); stream.on('end', () => { log.debug(`stream ended`); this._complete(); }); }); } }); } get destinationAccount() { return this._destinationAccount; } get sharedSecret() { return this._sharedSecret; } get amount() { return this._expectedAmount; } get assetScale() { return this._assetScale; } get assetCode() { return this._assetCode; } toJSON() { return serializePayee(this); } receiveData() { return this._dataPromise.promise; } receivePayment(timeout) { if (timeout) { this._timer = setTimeout(() => { this._timeout(); }, timeout); } return this._paymentPromise.promise; } _complete() { if (this._timer) { clearTimeout(this._timer); } if (this._streamConnection) { this._paymentPromise.resolve({ sourceAccount: this._streamConnection.destinationAccount, destinationAccount: this._streamConnection.sourceAccount, received: { amount: this._streamConnection.totalReceived, assetCode: this._streamConnection.sourceAssetCode, assetScale: this._streamConnection.sourceAssetScale }, requested: { amount: this._expectedAmount, assetCode: this._streamConnection.sourceAssetCode, assetScale: this._streamConnection.sourceAssetScale } }); this._dataPromise.resolve(this._receivedData); this._streamConnection.end().catch(e => { log.error('Error closing connection after payment was completed.', e); }); } else { const error = new Error('No incoming STREAM connection.'); this._paymentPromise.reject(error); this._dataPromise.reject(error); } } _timeout() { const error = (this._streamConnection) ? new Error(`Timed out waiting for payment. ` + `Received ${this._streamConnection.totalReceived} payment ` + `and ${this._receivedData.byteLength} bytes of data so far.`) : new Error(`Timed out waiting for connection. `); this._paymentPromise.reject(error); this._dataPromise.reject(error); if (this._streamConnection) { this._streamConnection.end().catch(e => { log.error('Error closing connection after payment timed out.', e); }); } } } exports.InvoiceReceiver = InvoiceReceiver; function serializePayee(receiver) { const invoice = receiver; const balance = (invoice.amount) ? { current: '0', maximum: invoice.amount.toString() } : undefined; const asset_info = (invoice.assetCode && invoice.assetScale) ? { code: invoice.assetCode, scale: invoice.assetScale } : undefined; return { destination_account: invoice.destinationAccount, shared_secret: invoice.sharedSecret.toString('base64'), balance, asset_info }; } exports.serializePayee = serializePayee; //# sourceMappingURL=invoice.js.map