GithubHelp home page GithubHelp logo

ilp's Introduction


ILP Client

A low-level JS Interledger sender/receiver library


npm standard circle codecov snyk

This is a low-level interface to ILP, largely intended for building ILP into other Application layer protocols.

The ILP Client includes:

  • Interledger Payment Request (IPR) Transport Protocol, an interactive protocol in which the receiver specifies the payment details, including the condition
  • Pre-Shared Key (PSK) Transport Protocol, a non-interactive protocol in which the sender creates the payment details and uses a shared secret to generate the conditions
  • Interledger Quoting and the ability to send through multiple ledger types using Ledger Plugins

The ILP Client does not handle:

  • Account discovery
  • Amount negotiation
  • Communication of requests from recipient to sender

Installation

npm install --save ilp ilp-plugin-bells

Note that ledger plugins must be installed alongside this module

Interledger Payment Request (IPR) Transport Protocol

This protocol uses recipient-generated Interledger Payment Requests, which include the condition for the payment. This means that the recipient must first generate a payment request, which the sender then fulfills.

This library handles the generation of payment requests, but not the communication of the request details from the recipient to the sender. In some cases, the sender and receiver might be HTTP servers, in which case HTTP would be used. In other cases, they might be using a different medium of communication.

IPR Sending and Receiving Example

'use strict'

const co = require('co')
const ILP = require('ilp')
const FiveBellsLedgerPlugin = require('ilp-plugin-bells')

const sender = ILP.createSender({
  _plugin: FiveBellsLedgerPlugin,
  prefix: 'ilpdemo.red.',
  account: 'https://red.ilpdemo.org/ledger/accounts/alice',
  password: 'alice'
})

const receiver = ILP.createReceiver({
  _plugin: FiveBellsLedgerPlugin,
  prefix: 'ilpdemo.blue.',
  account: 'https://blue.ilpdemo.org/ledger/accounts/bob',
  password: 'bobbob'
})

co(function * () {
  yield receiver.listen()
  receiver.on('incoming', (transfer, fulfillment) => {
    console.log('received transfer:', transfer)
    console.log('fulfilled transfer hold with fulfillment:', fulfillment)
  })

  const request = receiver.createRequest({
    amount: '10',
  })
  console.log('request:', request)

  // Note the user of this module must implement the method for
  // communicating payment requests from the recipient to the sender
  const paymentParams = yield sender.quoteRequest(request)
  console.log('paymentParams', paymentParams)

  const result = yield sender.payRequest(paymentParams)
  console.log('sender result:', result)
}).catch((err) => {
  console.log(err)
})

Pre-Shared Key (PSK) Transport Protocol

This is a non-interactive protocol in which the sender chooses the payment amount and generates the condition without communicating with the recipient.

PSK uses a secret shared between the sender and receiver. The key can be generated by the receiver and retrieved by the sender using a higher-level protocol such as SPSP, or any other method. In the example below, the pre-shared key is simply passed to the sender inside javascript.

When sending a payment using PSK, the sender generates an HMAC key from the PSK, and HMACs the payment to get the fulfillment, which is hashed to get the condition. The sender also encrypts their optional extra data using AES. On receipt of the payment, the receiver decrypts the extra data, and HMACs the payment to get the fulfillment.

In order to receive payments using PSK, the receiver must also register a reviewPayment handler. reviewPayment is a callback that returns either a promise or a value, and will prevent the receiver from fulfilling a payment if it throws an error. This callback is important, because it stops the receiver from getting unwanted funds.

PSK Sending and Receiving Example

'use strict'

const co = require('co')
const ILP = require('.')
const FiveBellsLedgerPlugin = require('ilp-plugin-bells')

const sender = ILP.createSender({
  _plugin: FiveBellsLedgerPlugin,
  account: 'https://localhost/ledger/accounts/alice',
  password: 'alice'
})

const receiver = ILP.createReceiver({
  _plugin: FiveBellsLedgerPlugin,
  account: 'https://localhost/ledger/accounts/bob',
  password: 'bobbob',
  // A callback can be specified to review incoming payments.
  // This is required when using PSK.
  reviewPayment: (payment, transfer) => {
    if (+transfer.amount > 100) {
      return Promise.reject(new Error('payment is too big!'))
    }
  }
})

co(function * () {
  yield receiver.listen()
  receiver.on('incoming', (transfer, fulfillment) => {
    console.log('received transfer:', transfer)
    console.log('fulfilled transfer hold with fulfillment:', fulfillment)
  })
  // The user of this module is responsible for communicating the
  // PSK parameters from the recipient to the sender
  const pskParams = receiver.generatePskParams()

  // Note the payment is created by the sender
  const request = sender.createRequest({
    destinationAmount: '10',
    destinationAccount: pskParams.destinationAccount,
    sharedSecret: pskParams.sharedSecret
  })
  console.log('request:', request)

  const paymentParams = yield sender.quoteRequest(request)
  console.log('paymentParams', paymentParams)

  const result = yield sender.payRequest(paymentParams)
  console.log('sender result:', result)
}).catch((err) => {
  console.log(err)
})

API Reference

SPSP~Client

SPSP Client

Kind: inner class of SPSP

new Client(opts)

Create an SPSP client.

Param Type Description
opts Object plugin options
opts._plugin function (optional) plugin constructor. Defaults to PluginBells

client.quoteSource ⇒ Promise.<SpspPayment>

Get payment params via SPSP query and ILQP quote, based on source amount

Kind: instance property of Client
Returns: Promise.<SpspPayment> - Resolves with the parameters that can be passed to sendPayment

Param Type Description
receiver String webfinger identifier of receiver
sourceAmount String Amount that you will send

client.quoteDestination ⇒ Promise.<SpspPayment>

Get payment params via SPSP query and ILQP quote, based on destination amount

Kind: instance property of Client
Returns: Promise.<SpspPayment> - Resolves with the parameters that can be passed to sendPayment

Param Type Description
receiver String webfinger identifier of receiver
destinationAmount String Amount that the receiver will get

client.sendPayment ⇒ Promise.<PaymentResult>

Sends a payment using the PaymentParams

Kind: instance property of Client
Returns: Promise.<PaymentResult> - Returns payment result

Param Type Description
payment SpspPayment params, returned by quoteSource or quoteDestination

client.query ⇒ Object

Queries an SPSP endpoint

Kind: instance property of Client
Returns: Object - result Result from SPSP endpoint

Param Type Description
receiver String A URL or an account

SPSP~SpspPayment : Object

Parameters for an SPSP payment

Kind: inner typedef of SPSP
Properties

Name Type Description
id id UUID to ensure idempotence between calls to sendPayment
source_amount string Decimal string, representing the amount that will be paid on the sender's ledger.
destination_amount string Decimal string, representing the amount that the receiver will be credited on their ledger.
destination_account string Receiver's ILP address.
connector_account string The connector's account on the sender's ledger. The initial transfer on the sender's ledger is made to this account.
spsp string SPSP response object, containing details to contruct transfers.
data string extra data to attach to transfer.

Sender~createSender(opts) ⇒ Sender

Returns an ILP Sender to quote and pay for payment requests.

Kind: inner method of Sender

Param Type Default Description
opts._plugin LedgerPlugin Ledger plugin used to connect to the ledger, passed to ilp-core
opts Objct Plugin parameters, passed to ilp-core
[opts.client] ilp-core.Client create a new instance with the plugin and opts ilp-core Client, which can optionally be supplied instead of the previous options
[opts.connectors] Array [] Array of connectors to use, specified by account name on the local ledger (e.g. "connie"). Some ledgers provide recommended connectors while others do not, in which case this would be required to send Interledger payments.
[opts.maxHoldDuration] Number 10 Maximum time in seconds to allow money to be held for
[opts.defaultRequestTimeout] Number 30 Default time in seconds that requests will be valid for
[opts.uuidSeed] Buffer crypto.randomBytes(32) Seed to use for generating transfer UUIDs

createSender~quoteSourceAmount(destinationAddress, sourceAmount) ⇒ Promise.<String>

Get a fixed source amount quote

Kind: inner method of createSender
Returns: Promise.<String> - destinationAmount

Param Type Description
destinationAddress String ILP Address of the receiver
sourceAmount String | Number Amount the sender wants to send

createSender~quoteDestinationAmount(destinationAddress, destinationAmount) ⇒ Promise.<String>

Get a fixed destination amount quote

Kind: inner method of createSender
Returns: Promise.<String> - sourceAmount

Param Type Description
destinationAddress String ILP Address of the receiver
destinationAmount String Amount the receiver should recieve

createSender~quoteRequest(paymentRequest) ⇒ Promise.<PaymentParams>

Quote a request from a receiver

Kind: inner method of createSender
Returns: Promise.<PaymentParams> - Resolves with the parameters that can be passed to payRequest

Param Type Description
paymentRequest Object Payment request generated by an ILP Receiver

createSender~payRequest(paymentParams) ⇒ Promise.<String>

Pay for a payment request. Uses a determinstic transfer id so that paying is idempotent (as long as ledger plugins correctly reject multiple transfers with the same id)

Kind: inner method of createSender
Returns: Promise.<String> - Resolves with the condition fulfillment

Param Type Description
paymentParams PaymentParams Respose from quoteRequest

createSender~createRequest(params) ⇒ Object

Create a payment request using a Pre-Shared Key (PSK).

Kind: inner method of createSender
Returns: Object - Payment request

Param Type Default Description
params Object Parameters for creating payment request
params.destinationAmount String Amount that should arrive in the recipient's account
params.destinationAccount String Target account's ILP address
params.sharedSecret String Shared secret for PSK protocol
[params.id] String uuid.v4() Unique ID for the request (used to ensure conditions are unique per request)
[params.expiresAt] String 30 seconds from now Expiry of request
[params.data] Object Additional data to include in the request

createSender~stopListening() ⇒ Promise.<null>

Disconnect from the ledger and stop listening for events.

Kind: inner method of createSender
Returns: Promise.<null> - Resolves when the sender is disconnected.

Receiver~createReceiver(opts) ⇒ Receiver

Returns an ILP Receiver to create payment requests, listen for incoming transfers, and automatically fulfill conditions of transfers paying for the payment requests created by the Receiver.

Kind: inner method of Receiver

Param Type Default Description
opts._plugin LedgerPlugin Ledger plugin used to connect to the ledger, passed to ilp-core
opts Object Plugin parameters, passed to ilp-core
[opts.client] ilp-core.Client create a new instance with the plugin and opts ilp-core Client, which can optionally be supplied instead of the previous options
[opts.hmacKey] Buffer crypto.randomBytes(32) 32-byte secret used for generating request conditions
[opts.defaultRequestTimeout] Number 30 Default time in seconds that requests will be valid for
[opts.allowOverPayment] Boolean false Allow transfers where the amount is greater than requested
[opts.roundingMode] String Round request amounts with too many decimal places, possible values are "UP", "DOWN", "HALF_UP", "HALF_DOWN" as described in https://mikemcl.github.io/bignumber.js/#constructor-properties
[opts.connectionTimeout] Number 10 Time in seconds to wait for the ledger to connect
[opts.reviewPayment] reviewPaymentCallback called before fulfilling any incoming payments. The receiver doesn't fulfill the payment if reviewPayment rejects. PSK will not be used if reviewPayment is not provided.

createReceiver~getAddress() ⇒ String

Get ILP address

Kind: inner method of createReceiver

createReceiver~createRequest() ⇒ Object

Create a payment request

Kind: inner method of createReceiver

Param Type Default Description
params.amount String Amount to request. It will throw an error if the amount has too many decimal places or significant digits, unless the receiver option roundRequestsAmounts is set
[params.account] String client.getAccount() Optionally specify an account other than the one the receiver would get from the connected plugin
[params.id] String uuid.v4() Unique ID for the request (used to ensure conditions are unique per request)
[params.expiresAt] String 30 seconds from now Expiry of request
[params.data] Object Additional data to include in the request
[params.roundingMode] String receiver.roundingMode Round request amounts with too many decimal places, possible values are "UP", "DOWN", "HALF_UP", "HALF_DOWN" as described in https://mikemcl.github.io/bignumber.js/#constructor-properties

createReceiver~generatePskParams() ⇒ PskParams

Generate shared secret for Pre-Shared Key (PSK) transport protocol.

Kind: inner method of createReceiver

createReceiver~listen() ⇒ Promise.<null>

Listen for incoming transfers and automatically fulfill conditions for transfers corresponding to requests this receiver created.

Kind: inner method of createReceiver
Returns: Promise.<null> - Resolves when the receiver is connected
Emits: incoming, incoming:<requestid>, incoming:psk:<token>

createReceiver~stopListening() ⇒ Promise.<null>

Disconnect from the ledger and stop listening for events.

Kind: inner method of createReceiver
Returns: Promise.<null> - Resolves when the receiver is disconnected.

"incoming"

IncomingTransfer from the ledger plugin and the fulfillment string

Kind: event emitted by Receiver

"incoming:ipr:"

IncomingTransfer from the ledger plugin and the fulfillment string for a specific request

Kind: event emitted by Receiver

"incoming:psk:"

IncomingTransfer from the ledger plugin and the fulfillment string for a specific token

Kind: event emitted by Receiver

Receiver~reviewPaymentCallback ⇒ Promise.<null> | null

Kind: inner typedef of Receiver
Returns: Promise.<null> | null - cancels the payment if it rejects/throws an error.

Param Type Description
payment PaymentRequest payment request object
transfer Transfer transfer object for the payment being reviewed

Receiver~PskParams : Object

Kind: inner typedef of Receiver
Properties

Name Type Description
destinationAccount string Receiver's ILP address
sharedSecret string Base64Url-encoded shared secret

ilp's People

Contributors

adrianhopebailie avatar emschwartz avatar justmoon avatar sentientwaffle avatar vhpoet avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.