From 87370e1306401aa4a960a4070535a83aade57e86 Mon Sep 17 00:00:00 2001 From: adrianhopebailie Date: Thu, 8 Feb 2018 22:15:05 +0200 Subject: [PATCH] Interledger Payment Method Signed-off-by: adrianhopebailie --- proposals/interledger-payment-method.html | 348 +------------------ proposals/interledger/.pr_preview.json | 5 + proposals/interledger/README.md | 163 +++++++++ proposals/interledger/index.html | 400 ++++++++++++++++++++++ proposals/interledger/tidyconfig.txt | 5 + 5 files changed, 588 insertions(+), 333 deletions(-) create mode 100644 proposals/interledger/.pr_preview.json create mode 100644 proposals/interledger/README.md create mode 100644 proposals/interledger/index.html create mode 100644 proposals/interledger/tidyconfig.txt diff --git a/proposals/interledger-payment-method.html b/proposals/interledger-payment-method.html index 2e69268..01fd893 100644 --- a/proposals/interledger-payment-method.html +++ b/proposals/interledger-payment-method.html @@ -1,333 +1,15 @@ - - - - Interledger Payment Method - - - - - - -
-

- The Interledger Protocol payment method specification describes the data formats used by the PaymentRequest API [[!PAYMENT-REQUEST-API]] to support payments using the Interledger Protocol [[!INTERLEDGER]]. It defines two supported methods for initiating an Interledger payment via the API; using the Simple Payment Setup Protocol [[!SPSP]] and the Interledger Payment Request [[!IPR]]. -

-
- -
-

- The working group maintains a - list of all bug reports that the group has not yet addressed. - Pull requests with proposed specification text for outstanding issues are strongly encouraged. -

-

- This specification was contributed by the - Interledger Payments Community Group. -

-
-

Sending comments on this document

-

If you wish to make comments regarding this document, please raise them as - GitHub issues. - Only send comments by email if you are unable to raise issues on GitHub (see - links below). All comments are welcome.

-
-
- -
-

Introduction

-

- This specification is a Payment Method specification for use with the PaymentRequest API [[!PAYMENT-REQUEST-API]]. - With it, payees can request payers to make payment to them via the Interledger Protocol.

-
- -
-

Dependencies

-

- This specification relies on several other underlying specifications. -

-
-
Payment Request API
-
The terms PaymentRequest constructor, and PaymentAddress - are defined by the PaymentRequest API specification [[!PAYMENT-REQUEST-API]].
-
Payment Method Identifiers
-
The term Payment - Method Identifier is defined by the Payment Method Identifiers specification - [[!METHOD-IDENTIFIERS]].
-
Web IDL
-
The IDL in this specification is defined by Web IDL [[!WEBIDL]].
-
RFC6920 - Naming Things with Hashes
-
[[!RFC6920]] defines the named information (ni) format for URIs. This format is used to encode the Condition passed in an InterledgerPaymentRequest.
-
Interledger Protocol
-
The terms ILP Packet, ILP Address, ILP Addresses, ILP Error Code, ILP Error Code Name, Fulfillment and Condition are defined in the Interledger Protocol Specification [[!INTERLEDGER]].
-
Simple Payment Setup Protocol
-
The Simple Payment Setup Protocol and the term SPSP Endpoint are defined in the SPSP specification [[!SPSP]].
-
Interledger Payment Request
-
The term Interledger Payment Request is defined in the IPR specification [[!IPR]].
-
- -

Interledger Types

-

The Interledger Protocol [[!INTERLEDGER]] defines a number of types. The corresponding WebIDL typedefs represent these:

-
-        typedef DOMString InterledgerAddress;
-        typedef sequence<InterledgerAddress> InterledgerAddresses;
-        typedef unsigned long long InterledgerAmount;
-        typedef sequence<octet> InterledgerPacket;
-        typedef USVString InterledgerConditionUri;
-        typedef sequence<octet> InterledgerFulfillment;
-      
-
-
InterledgerAddress
-
An InterledgerAddress is a restricted DOMString. It is an IA5String string with only the following characters allowed: hyphen "-", period ".", underscore "_", tilde "~" and alpha-numeric characters "0".."9", "A".."Z" and "a".."z".
-
InterledgerAddresses
-
An InterledgerAddresses object is a sequence of InterledgerAddress.
-
InterledgerAmount
-
An InterledgerAmount is an unsigned 64-byte integer.
-
InterledgerPacket
-
An InterledgerPacket is a sequence of octets conforming to the format of an ILP Packet defined in the Interledger Protocol specification.
-
InterledgerConditionUri
-
An InterledgerConditionUri is a URI conforming to the Named Information (ni) format defined in [[!RFC6920]]. It encodes a hash that is the Condition used for an Interledger payment.
-
InterledgerFulfillment
-
An InterledgerFulfillment is a sequence of octets representing the Fulfillment of an Interledger payment.
-
-
- -
-

Payment Method Identifier

-

The payment method identifier string for the Interledger Payment Method is interledger.

-
- -
-

Payment Method Specific Data for the PaymentRequest constructor

-

This section describes payment method specific data that is supplied as part of the data - argument to the PaymentRequest constructor.

- -
-

InterledgerPaymentRequest

-

Payee's using the Interledger Payment Request payment method must provide an instance of an InterledgerPaymentRequest as the data argument to the PaymentRequest constructor. -

- We should get feedback on the best type to use for the packet. It is not intended to be passed by reference so a sequence type seems appropriate but it's not clear how this would be exposed in a browser or used by a developer writing Javascript code that builds an InterledgerPaymentRequest object. -
-
-        dictionary InterledgerPaymentRequest {
-          unsigned short version;
-          InterledgerPacket packet;
-          InterledgerCondition condition;
-        };
-      
-

- The InterledgerPaymentRequest dictionary contains the following fields: -

-
-
version
-
The version field indicates the version of the Interledger Payment Request [[!IPR]] specification that this request conforms to.
-
packet
-
The packet field contains the ILP Packet constructed by the payee. This is a binary field and should conform to the Interledger Protocol specification [[!INTERLEDGER]] definition for an ILP Packet.
-
condition
-
The condition field is the Condition that is used by the payer to send the Interledger payment. The field MUST be a URI conforming to the Named Information (ni) format defined in [[!RFC6920]].
-
-
- -
-

SimplePaymentSetupProtocolRequest

-

Payee's using the Simple Payment Setup Protocol payment method must provide an instance of a SimplePaymentSetupProtocolRequest as the data argument to the PaymentRequest constructor. -

-        dictionary SimplePaymentSetupProtocolRequest {
-          unsigned short version;
-          USVString spspEndpoint;
-        };
-      
-

- The SimplePaymentSetupProtocolRequest dictionary contains the following fields: -

-
-
version
-
The version field indicates the version of the Simple Payment Setup Protocol [[!SPSP]] specification that this request conforms to.
-
spspEndpoint
-
The spspEndpoint field is the SPSP Endpoint URL that is used by the payer to setup the payment as defined by the Simple Payment Setup Protocol [[!SPSP]].
-
-
-
- -
-

Payment Method Response

-

The InterledgerResponse dictionary contains the response from the - PaymentRequest API when a user accepts payment with an Interledger Protocol payment method.

- -
-

InterledgerResponse

-
-          interface InterledgerError {
-            attribute DOMString errorCode;
-            attribute DOMString errorName;
-            attribute InterledgerAddress triggeredBy;
-            attribute InterledgerAddresses forwardedBy;
-            attribute DOMString triggeredAt;
-          };
-
-          dictionary InterledgerResponse {
-            InterledgerError? error;
-            InterledgerAddress payeeAddress;
-            InterledgerAmount payeeAmount;
-            InterledgerFulfillment fulfillment;
-          };
-        
- -

- The InterledgerResponse dictionary contains the following fields: -

- -
-
error
-
The error field will contain an InterledgerError if there was an error processing the payment.
-
payeeAddress
-
The payeeAddress field contains the ILP Address of the payee.
-
payeeAmount
-
The payeeAmount field contains the amount that was delivered to the payee. The amount is an unsigned UInt64 as described in the Interledger Protocol specification [[!INTERLEDGER]].
-
fulfillment
-
The fulfillment field contains the Fulfillment that was returned by the payee during the Interledger payment.
-
- -
-

InterledgerError

-

- The InterledgerError interface contains the following attributes: -

- -
-
errorCode
-
The errorCode is an ILP Error Code.
-
errorName
-
The errorName is an ILP Error Code Name.
-
triggeredBy
-
The triggeredBy member contains the ILP Address of the entities that originally emitted the error.
-
forwardedBy
-
The forwardedBy member contains the ILP Addresses of the entities that forwarded the error message to the payer.
-
triggeredAt
-
The triggeredAt member contains the timestamp of error formatted as an ISO 8601 compliant string.
-
-
-
-
- -
-

Security and Privacy Considerations

- -

Web sites using the Interledger protocol should understand the security implications of sharing the Fulfillment prematurely and that doing so may put them at risk of non-delivery of funds.

- -
- - - - + + + + + + + Page Redirection + + + + If you are not redirected automatically, follow this link to the new spec. + + \ No newline at end of file diff --git a/proposals/interledger/.pr_preview.json b/proposals/interledger/.pr_preview.json new file mode 100644 index 0000000..eaef230 --- /dev/null +++ b/proposals/interledger/.pr_preview.json @@ -0,0 +1,5 @@ + +{ + "src_file": "index.html", + "type": "respec" +} \ No newline at end of file diff --git a/proposals/interledger/README.md b/proposals/interledger/README.md new file mode 100644 index 0000000..00f4fe8 --- /dev/null +++ b/proposals/interledger/README.md @@ -0,0 +1,163 @@ +# Interledger Payment Method + +Interledger is an open protocol suite for sending payments across different payment networks. It defines a set of standards for payment initiation, account addressing, reconciliation and proof-of-payment as well as a protocol for synchronizing multiple independent transfers on multiple payment networks to facilitate a single end-to-end payment. + +## Vision + +The Interledger protocol (ILP) is modelled on the Internet protocols, in that it is a protocol for inter-networking multiple networks. As more participants, in more payment networks, adopt the ILP standards a new open, global, payment network will emerge that is overlaid over all existing and new payment networks. This may include open networks built on modern technology stacks such as Bitcoin, Ethereum and XRP but also closed networks such as legacy ACH and card systems. + +Initially the Interledger standards can be adopted within small sub-nets or even for payments between known counter-parties so that in time these networks are able to connect to form the global Interledger. + +## Interledger + +The Interledger protocol is a standard for payment messages that can be passed over any payment network. + +Participants in a payment (called **connectors**) provide connectivity between two networks by accepting an Interledger request packet from a peer on one network, routing the message onwards to a peer on another network and then passing the subsequent response (or error) back to the sending peer. + +An Interledger request packet contains 4 headers and a body of payment data that is only intended to be processed by the receiver (it will often be encrypted). The headers include: + 1. An ILP Address that is used to route the packet, + 2. An amount that must be paid from the sender to the next peer who the packet is sent to, + 3. An expiry before which the response must be received for the payment to be completed successfully, and + 4. A condition that must be fulfilled in the response for the response to be considered valid. + +In forwarding an Interledger request the connector agrees to accept payment of the amount specified in the ILP packet, from the peer sending the packet, and commits to paying the amount they place in the outgoing packet to the peer they send it to; if the payment is completed successfully. + +The payment is considered *complete* (from the perspective of this connector) if they receive and forward a _valid_ Interledger response packet to the peer that sent the request, *before* the expiry that was specified in the request. + +Requests contain a 32-byte **condition** (a SHA-256 hash of an unknown 32-byte pre-image) and _valid_ responses contain the **fulfillment** of that condition (the correct 32-byte pre-image for the hash in the request). + +Connectors will copy the **address**, **condition** and **data** from an incoming packet directly into the outgoing packet but will specify a new: + + - **amount** that will be paid to the next peer, in the currency of the account between these peers. If the currency of the incoming request and outgoing response differ then the connector will apply an appropriate exchange rate. The connector will also apply any fees they wish to charge so the outgoing amount may be less than the incoming amount even where the currency is the same. + + - **expiry** that is less than the expiry for the incoming request. The difference between these two values is the time that the connector considers "safe" to process the response and forward it on. In doing this they avoid the risk that they will receive a valid response just before it expires (and therefore owe their upstream peer money) but not have enough time to pass this downstream before the expiry of the incoming request (therefore lose out on the money owed to them for forwarding the request). + +The mechanism for clearing and settlement of these payments between peers is not defined by the protocol so it is left to peers to define the terms of their accounts with one another; whether these are pre-funded or not and over which network these payments are cleared and settled. + +## Benefits + +Beyond the potential of inter-networking multiple payments networks, using the Interledger standard offers significant benefits to any real-time payment interactions. + +Specifically the protocol defines a set of simple standards that have the potential to increase the interoperability between participants in the following areas: + +### Account Discovery and Routing + +Interledger defines a universal addressing scheme for accounts. Any system of value can use the ILP Addressing scheme to identify its accounts and in doing so, make these discoverable and addressable outside of the system's operational domain. + +The system is hierarchical in nature (similar to PANs, IBANs and IP Addresses) to make routing a payment to the destination account simple. + +However, unlike many other addressing schemes, ILP Addresses are variable length allowing a great deal of flexibility and unencumbered growth of the address space while still being space efficient in messages. + +Most importantly, due to their hierarchical form, data can be appended as a suffix to an address without altering which account the address points to. The result is that a new address can be used for every payment, dramatically improving the scope for innovative reconciliation solutions. + +Example: + +A receiver whose account has the ILP Address `g.coinbase.145b3dEskk1a7Uw4gWBdpa8NFEwbfz2MgT` could request a sender to send to `g.coinbase.145b3dEskk1a7Uw4gWBdpa8NFEwbfz2MgT.12345`. This payment will be routed to the receiver who will be able to infer contextual information from the address suffix (`12345`). + +More details on addressing can be found in [ILP RFC 15 - Interledger Addresses](https://interledger.org/rfcs/0015-ilp-addresses/) + +### Invoices, Receipts and Reconciliation + +One of the biggest challenges in payments processing is the exchange of commercial information related to a payment and the reconciliation of a payment with other commercial artifacts such as invoices and receipts. + +The execution of a payment in ILP is dependent on the exchange of a secret (called a **fulfillment**) between the receiver and the sender. The receiver only makes the fulfillment public when they are certain they will receive the payment, therefore the sender can use the fulfillment as proof (with some limitations) that the receiver was paid. + +The recommended mechanism for generating the fulfillment is to perform an HMAC of the payment data, thereby cryptographically binding the fulfillment to the payment itself. + +Before initiating the payment, the sender will get a SHA-256 hash digest (a non-reversible function) of the fulfillment (called the **condition**) and attach this to the payment. + +These two simple pieces of data can then be used during reconciliation of the payment both between connectors when clearing and settling their accounts and between the payer and payee. The fulfillment and the condition are both unique but also cryptographically bound to the payment details. If any of the payment details are altered the fulfillment and therefore the condition will not be valid. + +This leaves applications open to define appropriate formats for digital invoices and receipts but provides a well defined standard for identifiers that can be derived from the document content itself and leveraged in various ways to facilitate document discovery, sharing and reconciliation. (Example: content-based addressing for commercial documents) + +### Payment Orchestration + +Interledger defines an orchestration that can be applied over any funding source and any recipient account so makes for a versatile standard for payment messages. + +1. Payee provides account details (ILP Address) and payment request (amount, condition and payment data) +2. Payer initiates ILP payment to the address provided, using the condition provided and payment data in an end-to-end encrypted packet +3. Payment is routed over one or more payment networks by connectors +4. Payee decrypts payment data, verifies integrity and responds with the fulfillment and any response data (also encrypted). +5. Payment response is passed back to payer via the same route as the request +6. Payer verifies fulfillment and decrypts response data. + +## Payment Pointers + +The Interledger payment method leverages **Payment Pointers**, a standard for payee identifiers that can be resolved to an HTTPS endpoint where payers are able to discover information about a payment. + +More information about payment pointers can be found in [ILP RFC 26 - Payment Pointers](https://interledger.org/rfcs/0026-payment-pointers/). + +## Flow + +The flow of the Interledger payment method when used with the Payment Request API will be as follows: + +### Payment Request + +The payee website will call the Payment Request API providing a payment pointer for the payment. This may be a single-use pointer with some transaction reference in the pointer or a multi-use pointer that the payee reuses in multiple payment requests. + +Example: + - A single-use pointer `$payments.amazon.com/38215454-da56-448e-bb06-85fc15dddf76` + - A multi-use pointer `$bobshardware.stripe.com` or `$merchants.stripe.com/bobshardware` + +```javascript +const supportedPaymentMethods = [ + { + supportedMethods: 'interledger', + data: { + payee: '$bobshardware.stripe.com' + } + } +]; +``` + +### Payment Handler + +A Payment Handler that is capable of making ILP payments will parse and resolve the payment pointer and then request the payment information from the resolved receiver endpoint. + +Example Request: + +```http +GET /.well-known/pay HTTP/1.1 +Host: bobshardware.stripe.com +Accept: application/spsp+json +``` + +Example Response: + +```http +HTTP/1.1 200 OK +Content-Type: application/spsp+json + +{ + "destination_account": "g.stripe.bobshardware.38215454da56448ebb...", + "shared_secret": "6jR5iNIVRvqeasJeCty6C-YB5X9FhSOUPCL_5nha5Vs", + "maximum_destination_amount": "100000", + "minimum_destination_amount": "10", + "ledger_info": { + "currency_code": "USD", + "currency_scale": 2 + }, + "receiver_info": { + "name": "Bob's Hardware", + "image_url": "https://bobshardware.stripe.com/logo.jpg" + } +} +``` + +The Payment Handler may perform the necessary authentication of the user and use the provided `receiver_info` to assist the user in verifying the payee. + +Following this it will perform the ILP payment which will result in either an ILP error or a fulfillment. + + +### Payment Response + + +After completing the ILP payment to the provided address the response data to the merchant will include the address that was paid and the fulfillment. + +This data can be used by the website to consult a back-end API to further verify that the payment was completed as expected. + +## Opportunities + +As `interledger` is an open payment method it will require explicit implementation by browsers. This is an opportunity for browsers to assist in securing the payment by implementing the Payment Pointer protocol in the browser and simply returning the result of this to the Payment Handler. + +In this way the browser can perform additional security steps such as filtering the receiver endpoint URL against known malicious origins, ensuring that the certificates used by the receiver endpoint meet strict security standards or enforcing further security measures such as requiring that the origin of the receiver endpoint is the same as (or explicitly trusted by) the origin of the Payment Request API caller. \ No newline at end of file diff --git a/proposals/interledger/index.html b/proposals/interledger/index.html new file mode 100644 index 0000000..d586aca --- /dev/null +++ b/proposals/interledger/index.html @@ -0,0 +1,400 @@ + + + + + Interledger Payment Method + + + + + + + +
+

+ This specification describes data structures and formats, and a simple + processing model, to facilitate payments on the Web using the standards + defined by the Interledger + Protocol [[!interledger-protocol]]. +

+
+
+

+ The working group maintains a list of all bug reports + that the group has not yet addressed. Pull requests with proposed + specification text for outstanding issues are strongly encouraged. +

+

+ This specification was contributed by the Interledger Payments + Community Group. +

+
+

+ Sending comments on this document +

+

+ If you wish to make comments regarding this document, please raise + them as GitHub + issues. Only send comments by email if you are unable to raise + issues on GitHub (see links below). All comments are welcome. +

+
+
+
+

+ Introduction +

+

+ This specification defines the "interledger" payment method for use, + for instance, with the Payment Request + API. With it, merchants can request a payment that follows the + Interledger standards. +

+

+ The Interledger Protocol defines a number of standards that + can be universally applied to all payments, irrespective of the network + used to initiate or receive the payment. These include a universal + addressing scheme for any destination account, a two-phase + request/response orchestration for payment authorization, and a + standard message "signature" scheme using simple SHA-256 hash digests. +

+
+
+

+ Payment Method Identifier +

+

+ The standardized + payment method identifier for this specification is + "interledger". +

+
+
+

+ Model +

+

+ This section defines concepts used in this specification. +

+
+

+ Interledger Addresses +

+

+ An Interledger Address is an address for any account on + any payment network that can be the target of a payment. This + includes traditional payment accounts like bank accounts (identified + by an IBAN or account number), or card accounts (identified by a + PAN), but also accounts on newer networks such as distributed ledgers + and crypto-currency systems. It is defined in the + [[!interledger-addresses]] specification. +

+

+ The scheme is a hierarchical addressing scheme where addresses are + expressed as case-sensitive, ASCII strings containing one or more + segments delimited by the period character. Their hierarchical nature + makes them well-suited for routing payments while their large allowed + size means that new addresses can be created per payment and + reference data included in the suffix. +

+
+
+

+ Conditions, Fulfillments and Errors +

+

+ The Condition is a 32-byte number that is the result of + performing the one-way SHA-256 hash operation on the 32-byte + Fulfillment. The Condition is provided by the payer + in an Interledger payment. The Fulfillment is returned by the + payee in an Interledger payment. +

+

+ In the case of a failed payment an error will be returned with an + appropriate Interledger Error Code to indicate the cause + of the failure. +

+

+ More details on the role of conditions and fulfillments and details + of the different error codes can be found in the + [[!interledger-protocol]] specification. +

+
+
+

+ Payment Pointer +

+

+ A Payment Pointer is an identifer, that can be used to + resolve and discover the details of a payment. It may resolve to the + details of an entity or a specific obligation that can be paid (such + as an invoice). +

+

+ Specifically, a Payment Pointer is resolved to a payment + setup protocol receiver endpoint as defined in the + [[!payment-pointers]] specification. +

+
+
+

+ Flow +

+

+ An Interledger payment is initiated by the payer upon receipt of a + Payment Pointer from the payee. The payer (or their agent) + uses this to resolve a payment setup protocol receiver + endpoint which it queries for the details of the payment. +

+

+ The payer then completes an Interledger payment and returns the + Interledger Address and Fulfillment to the payee to + allow them to verify the payment has been completed successfully. +

+
+
+
+

+ InterledgerRequest dictionary +

+
+        dictionary InterledgerRequest {
+          DOMString payee;
+        };
+      
+

+ The InterledgerRequest dictionary contains the following + members: +

+
+
+ payee +
+
+ A Payment Pointer that MUST be used to resolve the details of + the payee and the payment. +
+
+
+
+

+ Interfacing with a payment handler +

+

+ The steps to complete a payment with a payment handler with + InterledgerRequest data are given by the following + algorithm. If the end user successfully completes the payment the + algorithm returns an Interledger Address and a + Fulfillment in an InterledgerResponse. +

+
    +
  1. Let response be an InterledgerResponse. +
  2. +
  3. Perform the steps defined in [[!payment-pointers]] to resolve the + payment details from the Payment Pointer at + data["payee"]. +
  4. +
  5. Complete a payment to the Interledger Address derived from + those payment details. +
  6. +
  7. Set + response["payeeAddress"] to the Interledger + Address the payment was sent to. +
  8. +
  9. If the payment was successful + set response["fulfillment"] to the Fulfillment + returned upon completing the payment. +
  10. +
  11. Else, let error be + an InterledgerError and: +
      +
    1. Set + error["errorCode"] to the Interledger Error + Code returned in the failed payment. +
    2. +
    3. Set + error["triggeredBy"] to the Interledger + Address indicated in the failed payment as the source of the + error. +
    4. +
    5. Set + response["error"] to error. +
    6. +
    +
  12. +
  13. Return response. +
  14. +
+
+
+

+ InterledgerResponse +

+
+        interface InterledgerError {
+          attribute DOMString errorCode;
+          attribute DOMString triggeredBy;
+        };
+
+        dictionary InterledgerResponse {
+          DOMString payeeAddress;
+          DOMString? fulfillment;
+          InterledgerError? error;
+        };
+      
+

+ The InterledgerResponse dictionary contains the following + fields: +

+
+
+ payeeAddress +
+
+ The payeeAddress field contains the ILP Address of the + payee. +
+
+ fulfillment +
+
+ The fulfillment field contains the Fulfillment + that was returned by the payee during the Interledger payment. The + 32-bytes are returned as a Base64 encoded string per [[!RFC4648]]. +
+
+ error +
+
+ The error field will contain an InterledgerError + if there was an error processing the payment. +
+
+
+

+ InterledgerError +

+

+ The InterledgerError interface contains the following + attributes: +

+
+
+ errorCode +
+
+ The errorCode is an Interledger Error Code. +
+
+ triggeredBy +
+
+ The triggeredBy member contains the Interledger + Address of the entities that originally emitted the error. +
+
+
+
+
+

+ There is only one class of product that can claim conformance to this + specification: a payment handler. +

+

+ A conforming payment handler MUST: +

+ +
+
+

+ Security and Privacy Considerations +

+

+ Web sites using the Interledger protocol should understand the security + implications of sharing the Fulfillment prematurely and that + doing so may put them at risk of non-delivery of funds. +

+
+ + diff --git a/proposals/interledger/tidyconfig.txt b/proposals/interledger/tidyconfig.txt new file mode 100644 index 0000000..8de98a2 --- /dev/null +++ b/proposals/interledger/tidyconfig.txt @@ -0,0 +1,5 @@ +char-encoding: utf8 +indent: yes +wrap: 80 +tidy-mark: no +newline: LF