Javascript Ledger Plugin Interface
The Interledger Protocol is a protocol suite for connecting blockchains and other ledgers.
This spec defines a Javascript ledger abstraction interface for Interledger clients and connectors to communicate and route payments across different ledger protocols. While the exact methods and events defined here are specific to the Javascript implementation, this may be used as a guide for ledger abstractions in other languages.
To send ILP payments through a new ledger, one must implement a ledger plugin that exposes the interface defined below. This can be used with the ILP Client and Connector and should work out of the box.
This spec depends on the ILP spec.
Class: LedgerPlugin
class LedgerPlugin
Methods
| | Name |
|:–|:–|
| new
| LedgerPlugin ( opts ) |
| | connect ( options ) ⇒ Promise.<null>
|
| | disconnect ( ) ⇒ Promise.<null>
|
| | isConnected ( ) ⇒ Boolean
|
| | getInfo ( ) ⇒ [LedgerInfo](#class-ledgerinfo)
|
| | getAccount ( ) ⇒ String
|
| | getBalance ( ) ⇒ Promise.<String>
|
| | getFulfillment ( transferId ) ⇒ Promise.<String>
|
| | sendTransfer ( transfer ) ⇒ Promise.<null>
|
| | sendRequest ( message ) ⇒ Promise.<[Message](#class-message)>
|
| | fulfillCondition ( transferId, fulfillment, ilp ) ⇒ Promise.<null>
|
| | rejectIncomingTransfer ( transferId, reason ) ⇒ Promise.<null>
|
| | registerRequestHandler ( requestHandler ) ⇒ null
|
| | deregisterRequestHandler ( ) ⇒ null
|
Events
| Name | Handler |
|:–|:–|
| connect | ( ) ⇒
|
| disconnect | ( ) ⇒
|
| error | ( ) ⇒
|
| incoming_transfer | ( transfer:[IncomingTransfer](#class-transfer) ) ⇒
|
| incoming_prepare | ( transfer:[IncomingTransfer](#class-transfer) ) ⇒
|
| incoming_fulfill | ( transfer:[IncomingTransfer](#class-transfer), fulfillment:String, ilp:String ) ⇒
|
| incoming_reject | ( transfer:[IncomingTransfer](#class-transfer), rejectionReason:[RejectionMessage](#class-rejectionmessage) ) ⇒
|
| incoming_cancel | ( transfer:[IncomingTransfer](#class-transfer), cancellationReason:[RejectionMessage](#class-rejectionmessage) ) ⇒
|
| incoming_request | ( message:[Message](#class-message) ) ⇒
|
| incoming_response | ( message:[Message](#class-message) ) ⇒
|
| outgoing_transfer | ( transfer:[outgoingTransfer](#class-transfer) ) ⇒
|
| outgoing_prepare | ( transfer:[outgoingTransfer](#class-transfer) ) ⇒
|
| outgoing_fulfill | ( transfer:[outgoingTransfer](#class-transfer), fulfillment:String ) ⇒
|
| outgoing_reject | ( transfer:[outgoingTransfer](#class-transfer), rejectionReason:[RejectionMessage](#class-rejectionmessage) ) ⇒
|
| outgoing_cancel | ( transfer:[outgoingTransfer](#class-transfer), cancellationReason:[RejectionMessage](#class-rejectionmessage) ) ⇒
|
| outgoing_request | ( message:[Message](#class-message) ) ⇒
|
| outgoing_response | ( message:[Message](#class-message) ) ⇒
|
| info_change | ( info:[LedgerInfo](#class-ledgerinfo) ) ⇒
|
Errors
| Name | Description | |:–|:–| | InvalidFieldsError | Arguments or configuration were invalidated client-side | | UnreachableError | An error occured due to connection failure | | TransferNotFoundError | A requested transfer does not exist and cannot be fetched | | MissingFulfillmentError | A transfer has not yet been fulfilled, so the fulfillment cannot be fetched | | DuplicateIdError | A transfer with the same ID and different fields has been sent | | AlreadyRolledBackError | A requested transfer has already been timed out or rejected and cannot be modified | | AlreadyFulfilledError | A requested transfer has already been fulfilled and cannot be modified | | TransferNotConditionalError | A requested transfer is not conditional and cannot be rejected/fulfilled/etc. | | NotAcceptedError | An operation has been rejected due to ledger-side logic | | InsufficientBalanceError | An operation has been rejected because the source balance isn’t high enough | | AccountNotFoundError | An operation has been rejected because the account does not exist | | NoSubscriptionsError | A transfer or message cannot be delivered because there are no active websockets | | RequestHandlerAlreadyRegisteredError | The current request handler callback must be unset before a new one can be registered |
Instance Management
new LedgerPlugin
new LedgerPlugin( **opts** : [PluginOptions](#class-pluginoptions) )
Create a new instance of the plugin. Each instance typically corresponds to a different ledger. However, some plugins MAY deviate from a strict one-to-one relationship and MAY use one instance for multiple (similar) ledgers or multiple instances to talk to the same ledger.
Throws InvalidFieldsError
if the constructor is given incorrect arguments.
Parameters
| Name | Type | Description |
|:–|:–|:–|
| opts | [PluginOptions](#class-pluginoptions)
| Object containing ledger-related settings. May contain plugin-specific fields. |
Example
const ledgerPlugin = new LedgerPlugin({
// auth parameters are defined by the plugin
_store: {
// persistence may be required for internal use by some ledger plugins
// (e.g. when the ledger has reduced memo capability and we can only put an ID in the memo)
// Store a value under a key
put: (key, value) => {
// Returns Promise.<null>
},
// Fetch a value by key
get: (key) => {
// Returns Promise.<Object>
},
// Delete a value by key
del: (key) => {
// Returns Promise.<null>
}
}
})
For a detailed description of these properties, please see PluginOptions
.
Connection Management
connect
ledgerPlugin.connect( options:[ConnectOptions](#class-connectoptions ) ⇒ Promise.<null>
options
is optional.
Initiate ledger event subscriptions. Once connect
is called the ledger plugin MUST attempt to subscribe to and report ledger events. Once the connection is established, the ledger plugin should emit the connect
event. If the connection is lost, the ledger plugin SHOULD emit the disconnect
event. The plugin should ensure that the information returned by getInfo
and getAccount
is available and cached before emitting the connect
event.
Rejects with InvalidFieldsError
if credentials are missing, and NotAcceptedError
if credentials are rejected.
Rejects with TypeError
if options.timeout
is passed but is not a Number
.
disconnect
ledgerPlugin.disconnect() ⇒ Promise.<null>
Unsubscribe from ledger events.
isConnected
ledgerPlugin.isConnected() ⇒ Boolean
Query whether the plugin is currently connected.
getInfo
ledgerPlugin.getInfo() ⇒ [LedgerInfo](#class-ledgerinfo)
Retrieve some metadata about the ledger. Plugin must be connected, otherwise the function should throw.
Example Return Value
{
"prefix": "us.fed.some-bank.",
"currencyCode": "USD",
"currencyScale": 4,
"connectors": [ "us.fed.some-bank.chloe" ]
}
For a detailed description of these properties, please see LedgerInfo
.
getAccount
ledgerPlugin.getAccount() ⇒ String
Get the ledger plugin’s ILP address. This is given to senders to receive transfers to this account. Plugin must be connected, otherwise the function should throw.
The mapping from the ILP address to the local ledger address is dependent on the ledger / ledger plugin. An ILP address could be the <ledger prefix>.<account name or number>
, or a token could be used in place of the actual account name or number.
Example Return Value
us.fed.some-bank.my-account
getBalance
ledgerPlugin.getBalance() ⇒ Promise.<String>
Return a (base-ten) integer string (..., '-3', '-2', '-1', '0', '1', '2', '3', ...
) representing the current balance, in the ledger’s base unit. For example, on a ledger with currencyCode
‘USD’ and currencyScale
6,
the base unit would be micro-dollars.
A balance of ‘1230000’ should then be interpreted as equivalent to 1.23 US dollars. The maximum and minimum balance are up to the ledger to determine. Plugin must be connected, otherwise the promise should reject.
getFulfillment
ledgerPlugin.getFulfillment( transferId ) ⇒ Promise.<String>
Return the fulfillment of a transfer if it has already been executed.
Rejects with MissingFulfillmentError
if the transfer exists but is not yet
fulfilled. Rejects with TransferNotFoundError
if no conditional transfer is found
with the given ID. Rejects with AlreadyRolledBackError
if the transfer has been rolled back
and will not be fulfilled. Rejects with TransferNotConditionalError
if transfer is not
conditional.
Event: connect
ledgerPlugin.on('connect', () ⇒ )
Emitted whenever a connection is successfully established.
Event: disconnect
ledgerPlugin.on('disconnect', () ⇒ )
Emitted when the connection has been terminated or lost.
Event: error
ledgerPlugin.on('error', ( **err**:Error ) ⇒ )
General event for fatal exceptions. Emitted when the plugin experienced an unexpected unrecoverable condition. Once triggered, this instance of the plugin MUST NOT be used anymore.
Ledger Transfers
Note that all transfers will have transferId
’s to allow the plugin user to correlate actions related to a single transfer. The transferId
will be the same as the ID used by the underlying ledger wherever possible or applicable. If the ledger does not have transfer IDs, the plugin may generate one and use the store
passed in to the constructor to persist them.
sendTransfer
ledgerPlugin.sendTransfer( **transfer**:[Transfer](#class-transfer) ) ⇒ Promise.<null>
Plugin must be connected, otherwise the promise should reject. Initiates a ledger-local transfer. A transfer can
contain money and/or information. If there is a problem with the structure or
validity of the transfer, then sendTransfer
should reject with an error.
If the transfer is accepted by the ledger, however, then
further errors will be in the form of "reject"
events.
All plugins MUST implement zero-amount transfers, but some ledger plugins MAY implement zero-amount transfers differently than other transfers.
Parameters
| Name | Type | Description |
|:–|:–|:–|
| transfer | [Transfer](#class-transfer)
| Properties of the transfer to be created |
When sending transfers, the id, amount and to fields are required.
Returns
Promise.<null>
A promise which resolves when the transfer has been submitted (but not necessarily accepted.)
Rejects with InvalidFieldsError
if required fields are missing from the transfer or malformed. Rejects with DuplicateIdError
if a transfer with
the given ID and different already exists. Rejects with InsufficientBalanceError
if the transfer is rejected due to the source balance being too low. Rejects with AccountNotFoundError
if the destination account does not exist. Rejects with NotAcceptedError
if the transfer is otherwise rejected by the ledger.
Example
p.sendTransfer({
id: 'd86b0299-e2fa-4713-833a-96a6a75271b8',
to: 'example.ledger.connector',
amount: '10',
noteToSelf: {},
executionCondition: '47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU',
expiresAt: '2016-05-18T12:00:00.000Z'
})
For a detailed description of these properties, please see Class: Transfer
.
sendRequest
ledgerPlugin.sendRequest( **message**:[Message](#class-message) ) ⇒ Promise.<[Message](#class-message)>
Plugin must be connected, otherwise the promise should reject. Sends a ledger-local message. Returns a promise for a response message from the other side.
If there is a problem with the structure or validity of the message, then sendRequest
should reject with an error.
Messaging is used by connectors for quoting and broadcasting routes.
Parameters
| Name | Type | Description |
|:–|:–|:–|
| message | [Message](#class-message)
| Properties of the message to be created |
When sending messages, the to and ilp fields are required.
Returns
Promise.<[Message](#class-message)>
A promise which resolves when a response message has been received.
Rejects with InvalidFieldsError
if required fields are missing from the message or malformed.
Rejects with NotAcceptedError
if the message is rejected by the ledger.
Rejects with NoSubscriptionsError
if the message cannot be delivered because there is nobody listening to messages addressed to the given account.
Example
p.sendRequest({
to: 'example.ledger.connector',
ilp: '...base64url-encoded data...',
custom: { foo: 'bar' }
})
For a detailed description of these properties, please see Message
.
fulfillCondition
ledgerPlugin.fulfillCondition( **transferId**:String, **fulfillment**:String, **ilp**:String ) ⇒ Promise.<null>
Submit a fulfillment to a ledger. Plugin must be connected, otherwise the promise should reject.
The fulfillment
is an arbitrary 32-byte buffer and is provided as a base64url-encoded string.
The ilp
is an optional ILP packet that will transmitted alongside the fulfillment. It is provided as a base64url-encoded string.
Rejects with InvalidFieldsError
if the fulfillment is malformed. Rejects with TransferNotFoundError
if the fulfillment
if no conditional transfer with the given ID exists. Rejects with AlreadyRolledBackError
if the transfer has already been
rolled back. Rejects with NotAcceptedError
if the fulfillment is formatted correctly, but does not match the condition
of the specified transfer. Rejects with TransferNotConditionalError
if transfer is not conditional.
rejectIncomingTransfer
ledgerPlugin.rejectIncomingTransfer( **transferId**:String, **reason**:[RejectionMessage](#class-rejectionmessage) ) ⇒ Promise.<null>
Reject an incoming transfer that is held pending the fulfillment of its executionCondition
before the expiresAt
time. reason
MAY be supplied to provide details on why the transfer was rejected.
Rejects with TransferNotFoundError
if there is no conditional transfer with the
given ID. Rejects with AlreadyFulfilledError
if the specified transfer has already been
fulfilled. Rejects with NotAcceptedError
if you are not authorized
to reject the transfer (e.g. if you are the sender). Rejects with TransferNotConditionalError
if transfer is not conditional.
This MAY be used by receivers or connectors to reject incoming funds if they will not fulfill the condition or are unable to forward the payment. Previous hops in an Interledger transfer would have their money returned before the expiry and the sender or previous connectors MAY retry and reroute the transfer through an alternate path.
registerRequestHandler
ledgerPlugin.registerRequestHandler( **requestHandler**: ( request: [Message](#class-message) ) ⇒ Promise<[Message](#class-message)> ) ⇒ null
Set the callback which is used to handle incoming request messages. The callback expects one parameter (the request Message) and returns a promise for the response Message.
If a request handler is already set, this method throws a RequestHandlerAlreadyRegisteredError
. In order to change the request handler, the old handler must first be removed via deregisterRequestHandler
. This is to ensure that handler are not overwritten by accident.
deregisterRequestHandler
ledgerPlugin.deregisterRequestHandler( ) ⇒ null
Removes the currently used request handler. This has the same effect as if registerRequestHandler
had never been called.
If not request handler is currently set, this method does nothing.
Event: *_transfer
ledgerPlugin.on('incoming_transfer',
(
**transfer**:[Transfer](#class-transfer),
) ⇒
)
ledgerPlugin.on('outgoing_transfer',
(
**transfer**:[Transfer](#class-transfer),
) ⇒
)
Emitted after an outgoing/incoming transfer which does not have a condition is executed on the ledger.
This indicates that the funds have already been transferred. In order to prevent unexpected incoming funds, a ledger MAY allow users to forbid incoming transfers without conditions.
If the event is outgoing_transfer
, then it means you sent the transfer. incoming_transfer
means somebody sent funds
to you.
Event: *_prepare
ledgerPlugin.on('incoming_prepare',
(
**transfer**:[Transfer](#class-transfer),
) ⇒
)
ledgerPlugin.on('outgoing_prepare',
(
**transfer**:[Transfer](#class-transfer),
) ⇒
)
Emitted when an outgoing/incoming transfer containing a condition is prepared.
Note that the *_prepare
event DOES NOT indicate that money has been transferred. The final status will only be known when either the _fulfill](#event-_fulfill) or [_cancel events are emitted.
The ledger plugin MUST authenticate the source for all incoming transfers, whether they include money or not.
If the event is outgoing_prepare
, then it means you prepared the transfer. incoming_prepare
means someone prepared
a transfer to you.
Event: *_fulfill
ledgerPlugin.on('incoming_fulfill',
(
**transfer**:[Transfer](#class-transfer),
**fulfillment**:String,
**ilp**:String
) ⇒
)
ledgerPlugin.on('outgoing_fulfill',
(
**transfer**:[Transfer](#class-transfer),
**fulfillment**:String,
**ilp**:String
) ⇒
)
Emitted when an outgoing/incoming transfer with a condition is fulfilled. The fulfillment
and ilp
are provided as a base64url-encoded string.
This indicates that funds have been transferred. In order to prevent unexpected incoming funds, a ledger MAY forbid accounts from fulfilling a transfer who are not the transfer’s receiver.
If the event is incoming_fulfill
, then it means you fulfilled the transfer. outgoing_fulfill
means the receiver
of your outgoing transfer has fulfilled the condition.
Event: *_reject
ledgerPlugin.on('incoming_reject',
(
**transfer**:[Transfer](#class-transfer),
**reason**:[RejectionMessage](#class-rejectionmessage)
) ⇒
)
ledgerPlugin.on('outgoing_reject',
(
**transfer**:[Transfer](#class-transfer),
**reason**:[RejectionMessage](#class-rejectionmessage)
) ⇒
)
Emitted when an outgoing/incoming transfer is rejected by the receiver.
This indicates that a transfer has been manually cancelled before the timeout by the receiver. A message can be passed along with the rejection.
If the event is incoming_reject
, then it means you rejected the transfer. outgoing_reject
means that
the receiver of your outgoing transfer has rejected it.
Event: *_cancel
ledgerPlugin.on('incoming_cancel',
(
**transfer**:[Transfer](#class-transfer),
**reason**:[RejectionMessage](#class-rejectionmessage)
) ⇒
)
ledgerPlugin.on('outgoing_cancel',
(
**transfer**:[Transfer](#class-transfer),
**reason**:[RejectionMessage](#class-rejectionmessage)
) ⇒
)
Emitted when an outgoing/incoming transfer is rejected by the ledger.
This will happen on a timeout, triggered by the ledger and not by the receiver.
If the event is incoming_cancel
, an incoming transfer was timed out by the ledger. outgoing_cancel
means that a transfer you created has timed out.
Event: *_request
ledgerPlugin.on('incoming_request',
(
**message**:[Message](#class-message),
) ⇒
)
ledgerPlugin.on('outgoing_request',
(
**message**:[Message](#class-message),
) ⇒
)
Emitted when an incoming request message arrives from another ledger participant (incoming_request
) or one is sent (outgoing_request
).
Hosts MUST NOT use these events to respond to requests. In order to provide responses, provide a request handler via registerRequestHandler
. Note that there can only be one request handler active for a plugin at a time, but an unlimited number of (passive) event listeners.
Event: *_response
ledgerPlugin.on('incoming_response',
(
**message**:[Message](#class-message),
) ⇒
)
ledgerPlugin.on('outgoing_response',
(
**message**:[Message](#class-message),
) ⇒
)
Emitted when a response message is sent (outgoing_response
) or received (incoming_response
).
Event: info_change
ledgerPlugin.on('info_change',
(
**info**:[LedgerInfo](#class-ledgerinfo)
) ⇒
)
Emitted any time the plugin’s LedgerInfo
cache changes.
Class: Transfer
class Transfer
The Transfer
class is used to describe local ledger transfers. Fields can be
left undefined (but not any other false-y value) if unused.
Fields
| Type | Name | Description |
|:–|:–|:–|
| String
| id | UUID used as an external identifier |
| String
| from | ILP Address of the source account |
| String
| to | ILP Address of the destination account |
| String
| ledger | ILP Address prefix of the ledger |
| String
| amount | Integer transfer amount, in the ledger’s base unit |
| String
| ilp | Base64-encoded ILP packet |
| Object
| noteToSelf | (Optional) host-provided memo that should be stored with the transfer |
| String
| executionCondition | Cryptographic hold condition |
| String
| expiresAt | Expiry time of the cryptographic hold |
| Object
| custom | (Optional) object containing ledger plugin specific options |
Fields
Transfer#id
**id**:String
External unique identifier used by the host.
The ID is always chosen by the sending host. The ledger plugin MAY use a different identifier internally, but MUST fail if the external ID has already been used. In the case of a connector, the ID will be deterministically chosen from the hash of the ledger and transfer IDs of the inbound transfer that triggered this outbound transfer.
Ledger plugins that support scalability (e.g. running multiple instances of a connector using the same settings) MUST ensure that external transfer IDs are unique globally, i.e. across all machines and instances. Otherwise a connector could accidentally process two outgoing payments for one incoming payment.
Transfer#account
**account**:String
The ILP Address of a local account.
Deprecated: Use from
/to
instead.
Transfer#from
**from**:String
The ILP Address of the source or debit account.
Transfer#to
**to**:String
The ILP Address of the destination or credit account.
Transfer#ledger
**ledger**:String
ILP Address prefix of the ledger that this transfer is going through on.
Transfer#amount
**amount**:String
An integer amount, represented as a string of base-ten digits. MUST be >= 0
and < 2^64
.
Transfer#ilp
**ilp**:String
An ILP packet, denoting the payment’s final destination.
If the ilp
data is too large, the ledger plugin MUST reject with a MaximumIlpDataSizeExceededError
.
Transfer#noteToSelf (OPTIONAL)
**noteToSelf**:Object
An optional, arbitrary plain JavaScript object containing details the host needs to persist with the transfer in order to be able to react to transfer events like condition fulfillment later.
Ledger plugins MAY attach the noteToSelf
to the transfer and let the ledger store it. Otherwise it MAY use the store
in order to persist this field. Regardless of the implementation, the ledger plugin MUST ensure that all instances of the transfer carry the same noteToSelf
, even across different machines.
Ledger plugins MUST ensure that the data in the noteToSelf
either isn’t shared with any untrusted party or encrypted before it is shared.
Transfer#executionCondition
**executionCondition**:String
A cryptographic challenge used for implementing holds. The underlying ledger MUST hold the transfer until the condition has been fulfilled or the expiresAt
time has been reached.
Conditions are the base64url-encoded SHA-256 hash of a random, pseudo-random or deterministically generated 32-byte preimage called the fulfillment.
Ledger plugins that do not support holds MUST reject with an HoldsNotSupportedError
if this parameter is provided.
Transfer#expiresAt
**expiresAt**:String
An ISO 8601 timestamp representing the expiry date for the transfer.
Ledger plugins that do not support holds or do not support expiries MUST reject with an ExpiryNotSupportedError
if this parameter is provided.
Transfer#custom (OPTIONAL)
**custom**:Object
Optional object that ledger plugins MAY use to accept and/or set additional fields for other features they support. The object MUST be serializable, i.e. only plain JSON types are allowed anywhere in the object or sub-objects.
If the custom
data is too large, the ledger plugin MUST reject with a MaximumCustomDataSizeExceededError
.
Example
{
id: '94adc29e-26cd-471b-987e-8d41e8773864',
account: 'example.ledger.bob',
from: 'example.ledger.bob',
to: 'example.ledger.alice',
ledger: 'example.ledger.',
amount: '100',
noteToSelf: /* ... */,
custom: {
alternateAccount: 'bob-savings',
executionPriority: 9
}
}
Class: Message
class Message
The Message
class is used to describe local ledger message. All fields are required.
Fields
| Type | Name | Description |
|:–|:–|:–|
| String
| id | Unique message identifier |
| String
| from | ILP Address of the source account |
| String
| to | ILP Address of the destination account |
| String
| ledger | ILP Address prefix of the ledger |
| String
| ilp | (Optional if custom
is present) base64-encoded ILP packet |
| Object
| custom | (Optional) object containing ledger plugin specific options |
Message#id
**id**:String
Unique message identifier chosen by the sending host. Request and response messages contain the same ID.
Message#from
**from**:String
The ILP Address of the source or debit account.
Message#to
**to**:String
The ILP Address of the destination or credit account.
Message#ledger
**to**:String
The ILP Prefix of the ledger being used to transfer the message.
Message#ilp
**ilp**:String
An ILP packet, used for communication among ledger participants.
Include either this field, or the custom
field, or both.
If the ilp
data is too large, the ledger plugin MUST reject with a MaximumIlpDataSizeExceededError
.
Message#custom (OPTIONAL)
**custom**:Object
An optional, arbitrary plain JavaScript object containing additional custom data to be sent. The object MUST be serializable to JSON. Ledger plugins SHOULD treat this data as opaque.
If the custom
data is too large, the ledger plugin MUST reject with a MaximumCustomDataSizeExceededError
.
Example
{
account: 'example.ledger.bob',
from: 'example.ledger.alice',
to: 'example.ledger.bob',
ledger: 'example.ledger.',
ilp: '',
custom: { /* ... */ }
}
Class: LedgerInfo
class LedgerInfo
Metadata describing the ledger. This data is returned by the getInfo
method.
Fields
| Type | Name | Description |
|:–|:–|:–|
| String
| prefix | The plugin’s ILP address prefix |
| String
| currencyCode | ISO 4217 three-letter currency code |
| Number
| currencyScale | Integer (..., -2, -1, 0, 1, 2, ...)
, such that one of the ledger’s base units equals 10^-<currencyScale> <currencyCode>
|
| String[]
| connectors | ILP addresses of recommended connectors |
| String
| minBalance | Integer String, for instance "0"
, indicating the minimum balance. Optional, defaults to zero. |
| String
| maxBalance | Integer String, for instance "1000000000000"
, indicating the maximum balance. Optional, defaults to plus infinity. |
Fields
LedgerInfo#prefix
**prefix**:String
The ledger plugin’s ILP address prefix. This is used to determine whether a given ILP address is local to this ledger plugin and thus can be reached using this plugin’s sendTransfer
method.
The prefix may be configured, automatically detected, or hard-coded, depending on the ledger. For example, a Bitcoin ledger plugin may have the address hard-coded, while a five-bells-ledger
would use an API call to get the prefix.
LedgerInfo#currencyCode
**currencyCode**:String
The ISO 4217 currency code (if any) used by the ledger. A custom all-caps three-letter code, not used by ISO 4217, otherwise. Ledger administrators who choose a custom currency code MAY request a custom currency symbol for their chosen currency code be listed by software modules that map currency codes to currency symbols, for instance on node package manager (npm) in the case of JavaScript. To translate an integer amount or balance from the ledger, the currencyCode by itself is not enough. It has to be used in combination with the currencyScale (below) to determine how many of the ledger’s base units correspond to one currency unit.
LedgerInfo#currencyScale
**currencyScale**:String
The order of magnitude to express one full currency unit in ledger’s base units. For instance, if the integer values represented on the ledger are to be interpreted as
dollar-cents (for the purpose of settling a user’s account balance, for instance), then the ledger’s
currencyCode is USD
and its currencyScale is 2
.
LedgerInfo#connectors
**connectors**:String[]
The ILP addresses of recommended connectors.
LedgerInfo#minBalance (OPTIONAL)
**minBalance**:String
A minimum balance limits how much the ledger trusts the account holder.
This field is optional; when not present, the minimum balance should be assumed to be 0
.
When a plugin does return a minBalance
field, it should be an Integer String, measured in the ledger’s base unit,
comparable to the balance
Integer Strings for which the getBalance
method returns a Promise.
Applications using the plugin can expect transfers to fail if they would make the balance go below the minimum.
LedgerInfo#maxBalance (OPTIONAL)
**maxBalance**:String
A maximum balance limits how much the account holder trusts the ledger.
This field is optional; when not present, the maximum balance should be assumed to be +Infinity
.
When a plugin does return a maxBalance
field, it should be an Integer String, measured in the ledger’s base unit,
comparable to the balance
Integer Strings for which the getBalance
method returns a Promise.
Applications using the plugin can expect transfers to fail if they would make the balance exceed the maximum.
Class: PluginOptions
class PluginOptions
Plugin options are passed in to the LedgerPlugin
constructor when a plugin is being instantiated. The fields are ledger
specific. Any fields which cannot be represented as strings are preceded with
an underscore, and listed in the table below.
Special Fields
| Type | Name | Description |
|:–|:–|:–|
| Object
| _store | Persistence layer callbacks |
Fields
PluginOptions#_store
**_store**:Object
Provides callback hooks to the host’s persistence layer.
Persistence MAY be required for internal use by some ledger plugins. For this purpose hosts MAY be configured with a persistence layer.
Method names are based on the popular LevelUP/LevelDOWN packages.
Example
{
// Store a value under a key
put: (key, value) => {
// Returns Promise.<null>
},
// Fetch a value by key
get: (key) => {
// Returns Promise.<Object>
},
// Delete a value by key
del: (key) => {
// Returns Promise.<null>
}
}
Class: ConnectOptions
class ConnectOptions
Fields
| Type | Name | Description |
|:–|:–|:–|
| Number
| timeout | milliseconds |
Fields
ConnectOptions#timeout
**timeout**:Number
The number of milliseconds that the plugin should spend trying to connect before giving up.
If falsy, use the plugin’s default timeout.
If Infinity
, there is no timeout.
Class: RejectionMessage
class RejectionMessage
Fields
| Field | Type | Description |
|:——————|:————|:————|
| code
| String | Machine-readable error code |
| name
| String | Human-readable description of the error code |
| message
| String | Description of the error |
| triggered_by
| ILP Address or ILP Prefix | ILP address or ledger prefix from which the rejection originates |
| forwarded_by
| ILP Address | (optional) The address of the last connector to forward the rejection |
| triggered_at
| GeneralizedTime | (optional) The time the rejection occurred. |
| additional_info
| Object | Additional details about the error |