<?xml version="1.0" encoding="utf-8"?>
  <?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?>
  <!-- generated by https://github.com/cabo/kramdown-rfc2629 version  -->

<!DOCTYPE rfc SYSTEM "rfc2629.dtd" [
<!ENTITY RFC0791 SYSTEM "http://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.0791.xml">
]>

<?rfc toc="yes"?>
<?rfc sortrefs="yes"?>
<?rfc symrefs="yes"?>
<?rfc comments="yes"?>

<rfc docName="draft-thomas-interledger-00" category="info">

  <front>
    <title>The Interledger Protocol</title>

    <author initials="S." surname="Thomas" fullname="Stefan Thomas">
      <organization>Ripple</organization>
      <address>
        <postal>
          <street>300 Montgomery Street</street>
          <city>San Francisco</city>
          <region>CA</region>
          <code>94104</code>
          <country>US</country>
        </postal>
        <phone>-----------------</phone>
        <email>stefan@ripple.com</email>
        <uri>http://www.ripple.com</uri>
      </address>
    </author>
    <author initials="E." surname="Schwartz" fullname="Evan Schwartz">
      <organization>Ripple</organization>
      <address>
        <postal>
          <street>300 Montgomery Street</street>
          <city>San Francisco</city>
          <region>CA</region>
          <code>94104</code>
          <country>US</country>
        </postal>
        <phone>-----------------</phone>
        <email>evan@ripple.com</email>
        <uri>http://www.ripple.com</uri>
      </address>
    </author>
    <author initials="A." surname="Hope-Bailie" fullname="Adrian Hope-Bailie">
      <organization>Ripple</organization>
      <address>
        <postal>
          <street>300 Montgomery Street</street>
          <city>San Francisco</city>
          <region>CA</region>
          <code>94104</code>
          <country>US</country>
        </postal>
        <phone>-----------------</phone>
        <email>adrian@ripple.com</email>
        <uri>http://www.ripple.com</uri>
      </address>
    </author>

    <date year="2016" month="July" day="08"/>

    <area>security</area>
    
    

    <abstract>


<t>This document specifies the Interledger Protocol (ILP). It draws heavily from the definition of the Internet Protocol (IP) defined in <xref target="RFC0791"></xref>. The interledger protocol is the culmination of more than a decade of research in decentralized payment protocols. This work was started in 2004 by Ryan Fugger, augmented by the development of Bitcoin in 2008 and has involved numerous contributors since then.</t>



    </abstract>


    <note title="Feedback">


<t>This specification is a part of the <eref target="https://interledger.org/">Interledger Project</eref> work. Feedback related to this specification should be sent to <eref target="mailto:public-interledger@w3.org">public-interledger@w3.org</eref>.</t>


    </note>


  </front>

  <middle>


<section anchor="introduction-intro" title="Introduction (#intro)">

<t>Payment networks today are siloed and disconnected. Payments are relatively easy within one country or if the sender and recipient have accounts on the same network or ledger. However, sending from one ledger to another is often impossible. Where connections do exist, they are manual, slow, or expensive.</t>

<t>The Interledger Protocol provides for routing payments across different digital asset ledgers while isolating senders and receivers from the risk of intermediary failures. Secure multi-hop payments and automatic routing enables a global network of networks for different types of value that can connect any sender with any receiver.</t>

<section anchor="scope" title="Scope">

<t>The interledger protocol is intentionally limited in scope to provide the functions necessary to deliver a payment from a source to a destination over an interconnected system of ledgers. It includes minimal requirements for underlying ledgers and it does not include public key infrastructure, identity, liquidity management, or other services commonly found in payment protocols.</t>

</section>
<section anchor="definitions" title="Definitions">

<section anchor="transfer" title="Transfer">
<t> Change in ownership of some asset</t>

</section>
<section anchor="ledger" title="Ledger">
<t> System which records transfers</t>

</section>
<section anchor="connector" title="Connector">
<t> System which relays transfers between two ledgers</t>

</section>
<section anchor="payment" title="Payment">
<t> An exchange of assets involving one or more transfers on different ledgers</t>

</section>
</section>
<section anchor="concepts" title="Basic Concepts">

<t>On the Interledger there are two roles. A ledger is a system of accounts, with balances, and the role of the ledger is to record transfers which change the balances of the accounts on the ledger. A connector is a host holding a balance on two or more ledgers. Connectors trade a debit against their balance on one ledger for a credit against their balance on another as a means of facilitating the payment between the two ledgers.</t>

</section>
<section anchor="operation" title="Operation">

<t>The central functions of the interledger protocol are addressing hosts and securing payments across different ledgers.</t>

<t>Each host sending and receiving interledger payments has an interledger module that uses the addresses in the interledger header to transmit interledger payments toward their destinations. Interledger modules share common rules for interpreting addresses. The modules (especially in connectors) also have procedures for making routing decisions and other functions.</t>

<t>The interledger protocol uses transfer holds to ensure that senders’ funds are either delivered to the destination account or returned to the sender’s account. This mechanism is described in greater detail in the <xref target="overview"></xref> and the <eref target="https://interledger.org/interledger.pdf">Interledger Whitepaper</eref>.</t>

<t>The interledger protocol treats each interledger payment as an independent entity unrelated to any other interledger payment. There are no connections or channels (virtual or otherwise).</t>

<t>Interledger payments do not carry a dedicated time-to-live or remaining-hops field. Instead, the amount field acts as an implicit time-to-live: Each time the payment is forwarded, the forwarding connector will take some fee out of the inbound amount. Once a connector recognizes that the inbound amount is worth less (though not necessarily numerically smaller) than the destination amount in the ILP header, it will refuse to forward the payment.</t>

</section>
</section>
<section anchor="overview" title="Overview">

<section anchor="protocols" title="Relation to Other Protocols">

<t>This protocol is called on by hosts through higher level protocol modules in an interledger environment. Interledger protocol modules call on local ledger protocols to carry the interledger payment to the next connector or destination account. In this context a ledger may be a small ledger owned by an individual or organization or a large public ledger such as Bitcoin.</t>

<t>For example, a <eref target="../0009-simple-payment-setup-protocol/">Simple Payment Setup Protocol (SPSP)</eref> module would call the interledger module with the address and other parameters in the interledger packet to send a payment. The interledger module would send a transfer to the next connector or destination account along with the interledger packet and according to the parameters given. The transfer and interledger packet would be received by the next host’s interledger module and handled by each each successive connector and finally the destination’s SPSP module.</t>

</section>
<section anchor="model" title="Model of Operation">

<section anchor="without-holds-optimistic-mode" title="Without Holds (“Optimistic Mode”)">

<t>The protocol MAY be used without the security provided by holds – sometimes referred to as “Optimistic Mode”. The model of operation for transmitting funds from one application to another without holds is illustrated by the following scenario:</t>

<t>We suppose the source and destination have accounts on different ledgers connected by a single connector.</t>

<figure><artwork><![CDATA[
    (1)                                               (11)
Application                                       Application
       \                                              /
       (2)                    (6)                  (10)
Interledger Module    Interledger Module    Interledger Module
          \               /       \                /
           (3)          (5)       (7)            (9)
          LLI-1       LLI-1      LLI-2         LLI-2
             \   (4)   /             \    (8)   /
          Local Ledger 1           Local Ledger 2
]]></artwork></figure>

<t><list style="numbers">
  <t>The sending application chooses an amount and calls on its local interledger module to send that amount as a payment and passes the destination address and other parameters as arguments of the call.</t>
  <t>The interledger module prepares an ILP packet and attaches the data to it. The interledger module determines a destination account on the local ledger for this interledger address. In this case it is the account of a connector. It passes the chosen amount and the local destination account to the local ledger interface.</t>
  <t>The local ledger interface creates a local ledger transfer, then authorizes this transfer on the local ledger.</t>
  <t>The ledger executes the transfer and notifies the connector.</t>
  <t>The connector host’s local ledger interface receives the notification and passes it to the interledger module.</t>
  <t>The connector’s interledger module extracts the ILP packet from the notification and determines from the interledger address that the payment is to be forwarded to another account in a second ledger. The interledger module converts the amount according to its locally available liquidity and determines the local account on the other ledger corresponding to the destination host. It calls on the local ledger interface for the destination ledger to send the transfer, which includes the same ILP packet.</t>
  <t>This local ledger interface creates a local ledger transfer and authorizes it.</t>
  <t>The ledger executes the transfer and notifies the destination host.</t>
  <t>The destination host’s local ledger interface receives the notification and passes it to the interledger module.</t>
  <t>The interledger module extracts the ILP packet and determines that the payment is for an application in this host. It passes the transfer data to the application.</t>
  <t>The destination application receives the notification of incoming funds and reacts accordingly.</t>
</list></t>

<section anchor="with-holds-universal-mode" title="With Holds (“Universal Mode”)">

<t>The protocol MAY be used with transfer holds to ensure a sender’s funds are delivered to the destination or returned to the sender’s account. The model of operation is illustrated with the following example:</t>

<figure><artwork><![CDATA[
  (1,21)                                               (11)
Application                                        Application
       \                                               /
     (2,20)                 (6,16)                 (10,12)
Interledger Module    Interledger Module    Interledger Module
          \               /       \                 /
         (3,19)       (5,17)     (7,15)         (9,13)
          LLI-1       LLI-1       LLI-2         LLI-2
             \  (4,18) /             \  (8,14)   /
          Local Ledger 1           Local Ledger 2
]]></artwork></figure>

<t><list style="numbers">
  <t>The sending application uses a higher-level protocol to negotiate the address, an amount, and a cryptographic condition with the destination. It calls on the interledger module to send a payment with these parameters.</t>
  <t>The interledger module prepares the ILP packet, chooses the account to send the local ledger transfer to, and passes them to the local ledger interface.</t>
  <t>The local ledger interface creates a local ledger transfer, including the crytographic condition, then authorizes this transfer on the local ledger.</t>
  <t>The ledger puts the sender’s funds on hold – it does not transfer the funds to the connector – and notifies the connector.</t>
  <t>The connector host’s local ledger interface receives the notification and passes it to the interledger module.</t>
  <t>The connector’s interledger module extracts the ILP packet and determines that it should forward the payment. The interledger module calls on the destination ledger’s local ledger interface to send the second transfer, including the same condition as the sender’s transfer.</t>
  <t>The local ledger interface creates a local ledger transfer, including the crytographic condition, then authorizes this transfer on the local ledger.</t>
  <t>The ledger puts the connector’s funds on hold – it does not transfer the funds to the destination – and notifies the destination host.</t>
  <t>The destination host’s local ledger interface receives the notification and passes it to the interledger module.</t>
  <t>The interledger module extracts the ILP packet and determines that the payment is for an application in this host. It passes the transfer data to the application.</t>
  <t>The destination application receives the notification and recognizes that funds are on hold pending the condition fulfillment. It checks the details of the incoming transfer against what was agreed upon with the sender. If checks pass, the application produces the condition fulfillment and passes it to the interledger module.</t>
  <t>The destination’s interledger module passes the fulfillment to the local ledger interface.</t>
  <t>The local ledger interface submits the fulfillment to the ledger.</t>
  <t>The destination ledger validates the fulfillment against the held transfer’s condition. If the fulfillment is valid and the transfer is not expired, the ledger executes the transfer and notifies the destination host and the connector.</t>
  <t>The connector’s local ledger interface receives the fulfillment notification and passes it to the interledger module.</t>
  <t>The connector’s interledger module receives the fulfillment and passes it to the local ledger interface corresponding to the source ledger.</t>
  <t>This ledger interface submits the fulfillment to the source ledger.</t>
  <t>The source ledger validates the fulfillment against the held transfer’s condition. If the fulfillment is valid and the transfer is not expired, the ledger executes the transfer and notifies the connector and the sender’s host.</t>
  <t>The sender’s local ledger interface receives the fulfillment notification and passes it to the interledger module.</t>
  <t>The sender’s interledger module receives the fulfillment notification and passes it to the application.</t>
  <t>The sender’s application receives the fulfillment notification and reacts accordingly.</t>
</list></t>

</section>
</section>
</section>
<section anchor="function" title="Function Description">

<t>The purpose of the interledger protocol is to enable hosts to route payments through an interconnected set of ledgers. This is done by passing the payments from one interledger module to another until the destination is reached. The interledger modules reside in hosts and connectors in the interledger system. The payments are routed from one interledger module to another through individual ledgers based on the interpretation of an interledger address. Thus, a central component of the interledger protocol is the interledger address.</t>

<t>When routing payments with relatively large amounts, the connectors and the intermediary ledgers they choose in the routing process may not be trusted. Holds provided by underlying ledgers MAY be used to protect the sender and receivers from this risk. In this case, the ILP packet contains a cryptographic condition and expiration date.</t>

<section anchor="addressing" title="Addressing">

<t>As with the <xref target="RFC0791"></xref>, interledger distinguishes between names, addresses, and routes.
&gt; “A name indicates what we seek. An address indicates where it is. A route indicates how to get there. The internet protocol deals primarily with addresses. It is the task of higher level (i.e., end-to-end or application) protocols to make the mapping from names to addresses.”</t>

<t>The interledger module translates interledger addresses to local ledger addresses. Connectors and local ledger interfaces are responsible for translating addresses into interledger routes and local routes, respectively.</t>

<t>Addresses are hierarchically structured strings consisting of segments delimited by the period (<spanx style="verb">.</spanx>) character. In order to distinguish the present address format from future or alternative versions, the protocol prefix <spanx style="verb">ilp:</spanx> MUST be used:</t>

<t><spanx style="verb">
ilp:us.bank1.bob
</spanx></t>

<t>Care must be taken in mapping interledger addresses to local ledger accounts. Examples of address mappings may be found in “Address Mappings” ((TODO)).</t>

</section>
<section anchor="connectors" title="Connectors">

<t>Connectors implement the interledger protocol to forward payments between ledgers. Connectors also implement other protocols to coordinate routing and other interledger control information.</t>

</section>
</section>
<section anchor="specification" title="Specification">

<section anchor="ilp-header" title="ILP Header Format">

<t>Here is a summary of the fields in the ILP header format:</t>

<texttable>
      <ttcol align='left'>Field</ttcol>
      <ttcol align='left'>Type</ttcol>
      <ttcol align='left'>Short Description</ttcol>
      <c>version</c>
      <c>INTEGER(0..255)</c>
      <c>ILP protocol version (currently <spanx style="verb">1</spanx>)</c>
      <c>destinationAddress</c>
      <c>IlpAddress</c>
      <c>Address corresponding to the destination account</c>
      <c>destinationAmount</c>
      <c>IlpAmount</c>
      <c>Amount the destination account should receive, denominated in the asset of the destination ledger</c>
      <c>condition</c>
      <c>OCTET STRING</c>
      <c>See <xref target="draft-thomas-crypto-conditions-00"></xref>. The condition may be included in the packet or may be transmitted through the ledger layer.</c>
      <c>expiresAt</c>
      <c>IlpTimestamp</c>
      <c>Maximum expiry time of the last transfer that the recipient will accept</c>
</texttable>

<section anchor="version" title="version">

<figure><artwork><![CDATA[
INTEGER(0..255)
]]></artwork></figure>

<t>The version of the Interledger Protocol being used. This document describes version <spanx style="verb">1</spanx>.</t>

</section>
<section anchor="destinationaddress" title="destinationAddress">

<figure><artwork><![CDATA[
IlpAddress :== SEQUENCE OF OCTET STRING
]]></artwork></figure>

<t>Hierarchical routing label.</t>

</section>
<section anchor="destinationamount" title="destinationAmount">

<figure><artwork><![CDATA[
IlpAmount :== SEQUENCE { mantissa INTEGER, exponent INTEGER(-128..127) }
]]></artwork></figure>

<t>Base 10 encoded amount.</t>

</section>
<section anchor="condition" title="condition">

<figure><artwork><![CDATA[
IlpCondition :== Condition</code>
]]></artwork></figure>

<t>Crypto-condition in binary format as defined in <xref target="draft-thomas-crypto-conditions-00"></xref>.</t>

<t>When processing a transfer carrying a condition a ledger MUST place a hold on the funds. While the funds are on hold, neither the sender nor recipient are able to access them. Upon receiving a condition fulfillment, a ledger MUST transfer the funds to the recipient if the funds are held, the fulfillment is a valid fulfillment of the transfer condition and the transfer has not yet expired. (“Universal Mode”)</t>

<t>The condition is an optional field. If no condition is provided, the funds are immediately credited to the recipient of the transfer. (“Optimistic Mode”)</t>

</section>
<section anchor="expiresat" title="expiresAt">

<figure><artwork><![CDATA[
IlpExpiry :== GeneralizedTime
]]></artwork></figure>

<t>Ledgers MAY require that all transfers with a condition also carry an expiry timestamp. Ledgers MUST reject transfers that carry an expiry timestamp, but no condition. Ledgers MUST reject transfers whose expiry transfer time has been reached or exceeded and whose condition has not yet been fulfilled. When rejecting a transfer, the ledger MUST lift the hold and make the funds available to the sender again.</t>

</section>
</section>
</section>
<section anchor="holds" title="Holds Without Native Ledger Support">

<t>Not all ledgers support held transfers. In the case of a ledger that doesn’t, the sender and recipient of the local ledger transfer MAY choose a commonly trusted party to carry out the hold functions. There are three options:</t>

<t><list style="numbers">
  <t>The sender MAY trust the receiver. The sender will perform a regular transfer in the first step and the receiver will perform a transfer back if the condition has not been met in time.</t>
  <t>The receiver MAY trust the sender. The sender will notify the receiver about the intent to transfer. If the receiver provides a fulfillment for the condition before the expiry date, the sender will perform a regular transfer to the receiver.</t>
  <t>The sender and receiver MAY appoint a mutually trusted third-party which has an account on the local ledger. The sender performs a regular transfer into a neutral third-party account. In the first step, funds are transfered into the account belonging to the neutral third-party.
### Payment Channels</t>
</list></t>

</section>
</section>


  </middle>

  <back>

    <references title='Normative References'>

<reference anchor="draft-thomas-crypto-conditions-00" >
  <front>
    <title>Crypto Conditions</title>
    <author initials="S." surname="Thomas" fullname="Stefan Thomas">
      <organization>Ripple</organization>
    </author>
    <date year="2016" month="July"/>
  </front>
</reference>


    </references>

    <references title='Informative References'>

&RFC0791;


    </references>


<section anchor="security-considerations" title="Security Considerations">

<t>TODO</t>

</section>
<section anchor="appendix-e" title="IANA Considerations">

<t>TODO</t>

</section>


  </back>
</rfc>

