-
Notifications
You must be signed in to change notification settings - Fork 109
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ILP Over HTTP #349
Closed
Closed
ILP Over HTTP #349
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
--- | ||
draft: 1 | ||
title: ILP Over HTTP | ||
--- | ||
# ILP Over HTTP | ||
|
||
This spec defines a minimal [Ledger Layer](./0001-interledger-architecture/0001-interledger-architecture.md#ledger-layer) protocol using the Hyper Text Transfer Protocol (HTTP). It includes the Interledger payment fields (such as destination address) alongside those that are local to a specific hop (such as the transfer amount). | ||
|
||
**Note:** This protocol is not to be confused with [HTTP ILP](./0014-http-ilp/0014-http-ilp.md), which defines HTTP headers for communicating payment details on a normal HTTP request to an application server. The values defined in this protocol will be forwarded to the destination ILP address defined in the request. | ||
|
||
## Overview | ||
|
||
It's everything you need to do ILP with just a couple of HTTP headers on a POST request/response. What more do we need to say? | ||
|
||
## Specification | ||
|
||
This protocol SHOULD be used with HTTPS or HTTP/2. It SHOULD NOT be used with insecure HTTP except for testing purposes. | ||
|
||
### Request | ||
|
||
```http | ||
POST / HTTP/1.1 | ||
ILP-Destination: g.crypto.bitcoin.1XPTgDRhN8RFnzniWCddobD9iKZatrvH4.~asdf1234 | ||
ILP-Condition: x73kz0AGyqYqhw/c5LqMhSgpcOLF3rBS8GdR52hLpB8= | ||
ILP-Expiry: 2017-12-07T18:47:59.015Z | ||
ILP-Amount: 1000 | ||
|
||
<body> | ||
``` | ||
|
||
| Field | Type | Modified at Each Hop? | Description | | ||
|---|---|---|---| | ||
| `ILP-Destination` | [ILP Address](./0015-ilp-addresses/0015-ilp-addresses.md) | N | Destination address of the payment | | ||
| `ILP-Condition` | Base64-Encoded String (With Padding), 32 Bytes | N | Execution condition of the payment, which is the Sha256 hash digest of the condition fulfillment | | ||
| `ILP-Expiry` | [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) Timestamp in UTC | Y | Expiry of the transfer | | ||
| `ILP-Amount` | Unsigned 64-Bit Integer | Y | Transfer amount, denominated in the minimum divisible units of the ledger. Note that this is the local transfer amount, **not** the destination amount as in the original [ILP Payment Packet Format](https://github.com/interledger/rfcs/blob/master/0003-interledger-protocol/0003-interledger-protocol.md#ilp-payment-packet-format) | | ||
| `<body>` | Binary, Maximum of 32767 Bytes | N | End-to-end data used by Transport Layer protocols | | ||
|
||
### Response | ||
|
||
#### Success | ||
|
||
```http | ||
HTTP/1.1 200 OK | ||
ILP-Fulfillment: cz/9RGv1PVjhKIOoyPvWkAs8KrBpIJh8UrYsQ8j34CQ= | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same, |
||
|
||
<body> | ||
``` | ||
|
||
| Field | Type | Modified at Each Hop? | Description | | ||
|---|---|---|---| | ||
| `ILP-Fulfillment` | Base64-Encoded String (With Padding), 32 Bytes | N | Preimage of the `ILP-Condition` | | ||
| `<body>` | Binary, Maximum of 32767 Bytes | N | End-to-end data used by Transport Layer protocols | | ||
|
||
#### Error | ||
|
||
HTTP Error Codes MAY be used to indicate certain types of failures, but [ILP Error Codes](./0003-interledger-protocol/0003-interledger-protocol.md#ilp-error-codes) MUST be used and relayed by connectors. | ||
|
||
```http | ||
HTTP/1.1 404 Not Found | ||
ILP-Error-Code: F02 | ||
ILP-Error-Name: Unreachable | ||
ILP-Error-Triggered-By: g.usd.acmebank.user12345.xclkv-909sdf | ||
ILP-Error-Triggered-At: 2017-12-07T19:11:21.917Z | ||
ILP-Error-Forwarded-By: g.usd.acmebank.connector,g.crypto.bitcoin.1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa | ||
|
||
<body> | ||
``` | ||
|
||
| Field | Type | Modified at Each Hop? | Description | | ||
|---|---|---|---| | ||
| `ILP-Error-Code` | [ILP Error Code](./0003-interledger-protocol/0003-interledger-protocol.md#ilp-error-codes) | N | 3-letter code identifying the error | | ||
| `ILP-Error-Name` | String | N | Human-readable name corresponding to the `ILP-Error-Code` | | ||
| `ILP-Error-Triggered-By` | ILP Address | N | Address of the party that initially emitted the error | | ||
| `ILP-Error-Triggered-At` | ISO 8601 Timestamp in UTC | N | Time when the error was initially emitted | | ||
| `ILP-Error-Forwarded-By` | Comma-Separated List of ILP Addresses | Y | List of connectors that relayed this error. Connectors SHOULD append their ILP addresses to the end of this list when relaying the error | | ||
| `<body>` | Binary, Maximum of 32767 Bytes | N | End-to-end data used by Transport Layer Protocols | |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
base64url encode the condition as
x73kz0AGyqYqhw_c5LqMhSgpcOLF3rBS8GdR52hLpB8
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the motivation for using base64url (slightly obscure) vs base64?
Most standards I have come across use base64 unless they need to put the encoded data in a URL.
Also, as @michielbdejong points out, we should be consistent on padding
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we ever anticipate putting a condition into a URL? Given that this is specifying an HTTP binding for ILP-core, it seems like the answer would be, "probably."
If that answer is accurate, then we probably want to be consistent and allow for that (adding conditions to URLs) to happen easily without transformation (?).
For example, might some client (like an admin system or something) want to be able to query an ILP server for transfers, possibly identifying them by condition, like:
GET: /transfers?condition=x73kz0AGyqYqhw_c5LqMhSgpcOLF3rBS8GdR52hLpB8
While we're at it, is there an argument to use HEX encoding here? That way nobody will be confused about whether we used URL encoding or not? (There was some confusion about this in the crypto-conditions spec and @justmoon had a good rationale for when to use which encoding, but can't remember the details -- maybe it was just HEX for the DER?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My vote would either be for normal base64 or hex.
Using a module that supports base64url or rewriting the function that converts it all over the place (see the JS code for examples) is annoying enough that I'd prefer to avoid it. It's just a little bit less common and we're not actively using the condition in any URLs at the moment. A different protocol that has support for features like the one you describe could choose an entirely different encoding format or strategy, so I don't think this protocol needs to be designed with that in mind.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
An advantage of hex is that it's more human-readable when comparing raw buffers in debug output:
Another advantage of hex would be that it would be less confusing to change to hex (obviously different from base64url) than to change from base64url to base64 (more subtle change, easier to confuse).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 to all comments above from @emschwartz, @michielbdejong, and @adrianhopebailie .
I think we have consensus that we should not use Base64Url, and from my perspective I lean slightly towards HEX, but would be fine supporting Base64.
With that in mind, I propose that we use HEX (and if there's even one dissenter saying that we should use Base64, then let's just use that).
Any dissenters?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually I would lean towards normal base64. Since this is specifically for encoding a hash or random 32-byte value, you don't need to do byte comparisons. I would agree with @michielbdejong's point if we were talking about a data field, but the hashes will always be completely different. Base64 saves 20 characters, and while this isn't really optimizing for bytes on the wire, I think we might as well save those characters because we're communicating the same information anyway.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No objections from me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
one thing we should specify for base64 is whether padding is optional or not. Many implementations of base64 (not node.js's version, but the
openssl base64
command, for instance) won't accept it if it doesn't include the=
s for padding.