The Javascript client library for Interledger
- Simple Payment Setup Protocol Version 1 (SPSPv1), a higher level interface for sending ILP payments, which requires the receiver to have an SPSP server.
- Pre-Shared Key Version 1 (PSKv1) Transport Protocol, a non-interactive protocol in which the sender creates the payment details and uses a shared secret to generate the conditions
- Interledger Payment Request Version 2 (IPRv2) Transport Protocol, an interactive protocol in which the receiver specifies the payment details, including the condition
- Interledger Quoting and the ability to send through multiple ledger types using Ledger Plugins
`npm install --save ilp ilp-plugin
Note that ledger plugins must be installed alongside this module.
If you are sending to an SPSPv1 receiver with a [email protected]
identifier, the SPSPv1 module
provides a high-level interface:
'use strict'
const SPSP = require('ilp').SPSP
const Plugin = require('ilp-plugin')
const plugin = new Plugin()
;(async function () {
await plugin.connect()
console.log('plugin connected')
const payment = await SPSP.quote(plugin, {
receiver: '[email protected]',
sourceAmount: '1'
})
console.log('got SPSP payment details:', payment)
// we can attach an arbitrary JSON object to the payment if we want it
// to be sent to the receiver.
payment.memo = { message: 'hello!' }
await SPSP.sendPayment(plugin, payment)
console.log('receiver claimed funds!')
})()
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.
'use strict'
const uuid = require('uuid')
const ILP = require('ilp')
const PluginBtp = require('ilp-plugin-btp')
const sender = new PluginBtp({
server: 'btp+wss://:[email protected]'
})
const receiver = new PluginBtp({
server: 'btp+wss://:[email protected]'
})
;(async function () {
// --- RECEIVER START ---
await receiver.connect()
const receiverSecret = Buffer.from('secret_seed')
const listener = await ILP.PSK.listen(receiver, { receiverSecret }, (params) => {
console.log('got transfer:', params.transfer)
console.log('fulfilling.')
return params.fulfill()
})
console.log('receiver connected')
// Note the user of this module must implement the method for
// communicating sharedSecret and destinationAccount from the recipient
// to the sender
const { sharedSecret, destinationAccount } = listener.generateParams()
// --- RECEIVER END ---
// --- SENDER START ---
// the sender can generate these, via the sharedSecret and destinationAccount
// given to them by the receiver.
const { packet, condition } = ILP.PSK.createPacketAndCondition({
sharedSecret,
destinationAccount,
destinationAmount: '10', // denominated in the ledger's base unit
})
const quote = await ILP.ILQP.quoteByPacket(sender, packet)
console.log('got quote:', quote)
await sender.sendTransfer({
id: uuid(),
to: quote.connectorAccount,
amount: quote.sourceAmount,
expiresAt: quote.expiresAt,
executionCondition: condition,
ilp: packet
})
sender.on('outgoing_fulfill', (transfer, fulfillment) => {
console.log(transfer.id, 'was fulfilled with', fulfillment)
stopListening()
})
// --- SENDER END ---
})()
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.
'use strict'
const uuid = require('uuid')
const ILP = require('ilp')
const PluginBtp = require('ilp-plugin-btp')
const sender = new PluginBtp({
server: 'btp+wss://:[email protected]'
})
const receiver = new PluginBtp({
server: 'btp+wss://:[email protected]'
})
;(async function () {
const stopListening = await ILP.IPR.listen(receiver, {
receiverSecret: Buffer.from('secret', 'utf8')
}, async function ({ transfer, fulfill }) {
console.log('got transfer:', transfer)
console.log('claiming incoming funds...')
await fulfill()
console.log('funds received!')
})
// `ipr` is a buffer with the encoded IPR
const ipr = ILP.IPR.createIPR({
receiverSecret: Buffer.from('secret', 'utf8'),
destinationAccount: receiver.getAccount(),
// denominated in the ledger's base unit
destinationAmount: '10',
})
// Note the user of this module must implement the method for communicating
// packet and condition from the recipient to the sender.
// In practice, The rest of this example would happen on the sender's side.
const { packet, condition } = ILP.IPR.decodeIPR(ipr)
const quote = await ILP.ILQP.quoteByPacket(sender, packet)
console.log('got quote:', quote)
await sender.sendTransfer({
id: uuid(),
to: quote.connectorAccount,
amount: quote.sourceAmount,
expiresAt: quote.expiresAt,
executionCondition: condition,
ilp: packet
})
sender.on('outgoing_fulfill', (transfer, fulfillment) => {
console.log(transfer.id, 'was fulfilled with', fulfillment)
})
})()
Query an SPSP endpoint and get SPSP details
Kind: inner constant of SPSP
Returns: Promise.<SpspResponse>
- SPSP SPSP response from server
Param | Type | Description |
---|---|---|
receiver | String |
webfinger account identifier (eg. '[email protected]') or URL to SPSP endpoint. |
Validate a server's SPSP response, and throw an error if it's wrong.
Kind: inner method of SPSP
Param | Type | Description |
---|---|---|
SPSP | Promise.<SpspResponse> |
SPSP response from server |
Quote to an SPSP receiver
Kind: inner method of SPSP
Returns: Promise.<SpspPayment>
- SPSP payment object to be sent.
Param | Type | Default | Description |
---|---|---|---|
plugin | Object |
Ledger plugin used for quoting. | |
params | Object |
Quote parameters | |
params.receiver | String |
webfinger account identifier (eg. '[email protected]') or URL to SPSP endpoint. | |
[params.sourceAmount] | String |
source amount to quote. This is a decimal, NOT an integer. It will be shifted by the sending ledger's scale to get the integer amount. | |
[params.destinationAmount] | String |
destination amount to quote. This is a decimal, NOT an integer. It will be shifted by the receiving ledger's scale to get the integer amount. | |
[params.id] | String |
uuid() |
id to use for payment. sending a payment with the same id twice will be idempotent. If left unspecified, the id will be generated randomly. |
[params.timeout] | Number |
5000 |
how long to wait for a quote response (ms). |
[params.spspResponse] | SpspResponse |
SPSP.query(params.receiver) |
SPSP response. The receiver endpoint will be queried automatically if this isn't supplied. |
Quote to an SPSP receiver
Kind: inner method of SPSP
Returns: Promise.<Object>
- result The result of the payment.String
- result.fulfillment The fulfillment of the payment.
Param | Type | Description |
---|---|---|
plugin | Object |
Ledger plugin used for quoting. |
payment | SpspPayment |
SPSP Payment returned from SPSP.quote. |
/** Parameters for an SPSP payment
Kind: inner typedef of SPSP
Properties
Name | Type | Default | 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. | |
spsp | string |
SPSP response object, containing details to contruct transfers. | |
publicHeaders | Object |
{} |
public headers for PSK data. The key-value pairs represent header names and values. |
headers | Object |
{} |
headers for PSK data. The key-value pairs represent header names and values. |
memo | Object |
{} |
arbitrary JSON object for additional data. |
SPSP query response
Kind: inner typedef of SPSP
Properties
Name | Type | Description |
---|---|---|
destination_account | string |
The ILP address which will receive payments. |
shared_secret | string |
Base64url encoded 16-byte shared secret for use in PSK. |
maximum_destination_amount | string |
Integer string representing the maximum that the receiver will be willing to accept. |
minimum_destination_amount | string |
Integer string representing the minimum that the receiver will be willing to accept. |
ledger_info | Object |
An object containing the receiver's ledger metadata. |
ledger_info.currency_code | string |
The currency code of the receiver's ledger. |
ledger_info.currency_scale | string |
The currency scale of the receiver's ledger. |
receiver_info | Object |
Additional information containing arbitrary fields. |
Kind: inner method of ILQP
Param | Type | Description |
---|---|---|
plugin | Object |
The LedgerPlugin used to send quote request |
query | Object |
|
query.sourceAddress | String |
Sender's address |
query.destinationAddress | String |
Recipient's address |
[query.sourceAmount] | String |
Either the sourceAmount or destinationAmount must be specified. This value is a string representation of an integer, expressed in the lowest indivisible unit supported by the ledger. |
[query.destinationAmount] | String |
Either the sourceAmount or destinationAmount must be specified. This value is a string representation of an integer, expressed in the lowest indivisible unit supported by the ledger. |
[query.destinationExpiryDuration] | String | Number |
Number of seconds between when the destination transfer is proposed and when it expires. |
Create a payment request using a Pre-Shared Key (PSK).
Kind: inner method of PSK
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. This value is a string representation of an integer, expressed in the lowest indivisible unit supported by the ledger. | |
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 |
none |
Expiry of request |
[params.data] | Buffer |
|
Additional data to include in the request |
[params.headers] | Object |
|
Additional headers for private PSK details. The key-value pairs represent header names and values. |
[params.publicHeaders] | Object |
|
Additional headers for public PSK details. The key-value pairs represent header names and values. |
[params.disableEncryption] | Boolean |
false |
Turns off encryption of private memos and data |
[params.minFulfillRetryWait] | Number |
250 |
Minimum amount of time (in ms) to wait before retrying fulfillment |
[params.maxFulfillRetryWait] | Number |
1000 |
Maximum amount of time (in ms) to wait before retrying fulfillment |
Generate shared secret for Pre-Shared Key (PSK) transport protocol.
Kind: inner method of PSK
Param | Type | Description |
---|---|---|
params | Object |
Parameters for creating PSK params |
params.destinationAccount | String |
The ILP address that will receive PSK payments |
params.receiverSecret | Buffer |
secret used to generate the shared secret and the extra segments of destinationAccount |
Listen on a plugin for incoming PSK payments, and auto-generate fulfillments.
Kind: inner method of PSK
Returns: Object
- Payment request
Param | Type | Default | Description |
---|---|---|---|
plugin | Object |
Ledger plugin to listen on | |
params | Object |
Parameters for creating payment request | |
params.sharedSecret | Buffer |
Secret to generate fulfillments with | |
[params.allowOverPayment] | Buffer |
false |
Accept payments with higher amounts than expected |
callback | IncomingCallback |
Called after an incoming payment is validated. |
Listen on a ILP plugin bells factory for incoming PSK payments, and auto-generate fulfillments.
Kind: inner method of PSK
Returns: Object
- Payment request
Param | Type | Default | Description |
---|---|---|---|
factory | Object |
Plugin bells factory to listen on | |
params | Object |
Parameters for creating payment request | |
params.receiverSecret | Buffer |
secret used to generate the shared secret and the extra segments of destinationAccount | |
[params.allowOverPayment] | Boolean |
false |
Accept payments with higher amounts than expected |
callback | IncomingCallback |
Called after an incoming payment is validated. |
Kind: inner typedef of PSK
Param | Type | Description |
---|---|---|
params | Object |
|
params.transfer | Object |
Raw transfer object emitted by plugin |
params.data | Object |
Decrypted data parsed from transfer |
params.destinationAccount | String |
destinationAccount parsed from ILP packet |
params.destinationAmount | String |
destinationAmount parsed from ILP packet |
params.fulfill | function |
async function that fulfills the transfer when it is called |
Create a packet and condition
Kind: inner method of IPR
Returns: Object
- Packet and condition for use in the IPR protocol.
Param | Type | Default | Description |
---|---|---|---|
params | Object |
Parameters for creating payment request | |
params.destinationAmount | String |
Amount that should arrive in the recipient's account. This value is a string representation of an integer, expressed in the lowest indivisible unit supported by the ledger. | |
params.destinationAccount | String |
Target account's ILP address | |
params.receiverSecret | Buffer |
Secret for generating IPR packets | |
[params.id] | String |
uuid.v4() |
Unique ID for the request (used to ensure conditions are unique per request) |
[params.expiresAt] | String |
60 seconds from now |
Expiry of request |
[params.data] | Buffer |
|
Additional data to include in the request |
[params.headers] | Object |
|
Additional headers for private details. The key-value pairs represent header names and values. |
[params.publicHeaders] | Object |
|
Additional headers for public details. The key-value pairs represent header names and values. |
[params.disableEncryption] | Boolean |
false |
Turns off encryption of private memos and data |
[params.minFulfillRetryWait] | Number |
250 |
Minimum amount of time (in ms) to wait before retrying fulfillment |
[params.maxFulfillRetryWait] | Number |
1000 |
Maximum amount of time (in ms) to wait before retrying fulfillment |
Create an encoded IPR for use in the IPR transport protocol
Kind: inner method of IPR
Returns: Buffer
- encoded IPR buffer
Param | Type | Description |
---|---|---|
params | Object |
Parameters for encoding IPR |
params.packet | String |
ILP packet of this IPR |
params.condition | String |
condition of this IPR |
Decode an IPR buffer for use in the IPR transport protocol
Kind: inner method of IPR
Returns: Object
- Decoded IPR parameters, containing 'packet' and 'condition' as base64url strings.
Param | Type | Description |
---|---|---|
ipr | Buffer |
encoded IPR buffer |
Create a payment request for use in the IPR transport protocol.
Kind: inner method of IPR
Returns: Buffer
- encoded IPR buffer for use in the IPR protocol
Param | Type | Default | Description |
---|---|---|---|
params | Object |
Parameters for creating payment request | |
params.destinationAmount | String |
Amount that should arrive in the recipient's account. This value is a string representation of an integer, expressed in the lowest indivisible unit supported by the ledger. | |
params.destinationAccount | String |
Target account's ILP address | |
params.receiverSecret | Buffer |
Secret for generating IPR packets | |
[params.id] | String |
uuid.v4() |
Unique ID for the request (used to ensure conditions are unique per request) |
[params.expiresAt] | String |
60 seconds from now |
Expiry of request |
[params.data] | Buffer |
|
Additional data to include in the request |
[params.headers] | Object |
|
Additional headers for private details. The key-value pairs represent header names and values. |
[params.publicHeaders] | Object |
|
Additional headers for public details. The key-value pairs represent header names and values. |
[params.disableEncryption] | Object |
false |
Turns off encryption of private memos and data |
Listen on a plugin for incoming IPR payments, and auto-generate fulfillments.
Kind: inner method of IPR
Returns: Object
- Payment request
Param | Type | Default | Description |
---|---|---|---|
plugin | Object |
Ledger plugin to listen on | |
params | Object |
Parameters for creating payment request | |
params.secret | Buffer |
Secret to generate fulfillments with | |
[params.allowOverPayment] | Buffer |
false |
Accept payments with higher amounts than expected |
callback | IncomingCallback |
Called after an incoming payment is validated. |
Listen on a ILP plugin bells factory for incoming IPR payments, and auto-generate fulfillments.
Kind: inner method of IPR
Returns: Object
- Payment request
Param | Type | Default | Description |
---|---|---|---|
factory | Object |
Plugin bells factory to listen on | |
params | Object |
Parameters for creating payment request | |
params.generateReceiverSecret | function |
function that returns receiver secret for a given username | |
[params.allowOverPayment] | Boolean |
false |
Accept payments with higher amounts than expected |
callback | IncomingCallback |
Called after an incoming payment is validated. |
Kind: inner typedef of IPR
Param | Type | Description |
---|---|---|
params | Object |
|
params.transfer | Object |
Raw transfer object emitted by plugin |
params.data | Object |
Decrypted data parsed from transfer |
params.destinationAccount | String |
destinationAccount parsed from ILP packet |
params.destinationAmount | String |
destinationAmount parsed from ILP packet |
params.fulfill | function |
async function that fulfills the transfer when it is called |