Skip to content

Latest commit

 

History

History
144 lines (91 loc) · 6.15 KB

0014-http-ilp.md

File metadata and controls

144 lines (91 loc) · 6.15 KB
title draft
HTTP-ILP
1

HTTP-ILP

A standard for paid HTTP requests.

Design Goals

Design a protocol to pay for HTTP requests.

Criteria:

  • Minimum number of roundtrips
  • Interaction with HTTP server is via HTTP (actually HTTPS) calls only - we want to tie into the existing load balancing and security infrastructure (HTTPS), no need to run any JavaScript/Websocket client on the HTTP server or other shenanigans

Flows

1. Setup

Scenario

Ankita is a server admin who owns a file hosting service at myservice.example and would like to provide an API where her users can upload files without having to register first. In order to enable this in a standards-compliant way, she decides to use HTTP-ILP.

1.1. Server admin installs an ILP payment module

After deciding to use HTTP-ILP, Ankita searches the web on instructions on how to set this up. She finds an open-source HTTP-ILP server module which is compatible with the REST framework (Koa) that she is already using, for instance koa-ilp.

She installs the HTTP-ILP server module. The module provides middleware which she adds to the different API endpoints in order to set prices for each one.

According to the documentation of the HTTP-ILP server module, she learns that she can pass an Interledgerjs plugin to the module, to receive payments.

1.2. Server admin sets up a new receiver

Ankita creates a dedicated subaccount under her account at her Interledger service provider, and takes a note of that subaccount's credentials.

1.3. Server admin enters credentials into the HTTP-ILP server module config

Next, Ankita logs back into her server and edits a config file of the HTTP-ILP server module to enter the plugin type and credentials she obtained:

export PLUGIN_NAME=ilp-plugin-btp-client
export PLUGIN_CONFIG={"server":"btp+wss://ankita+filepay:fxPERNaS4FGlC8H7eg6UfYVlglmFynFc8nh5la9PBGM@nexus.justmoon.com"}

Next, she restarts her server to load the new configuration.

1.4. Paid HTTP server fetches receiver information

When the HTTP-ILP server module loads up, it calls plugin#connect so that the plugin gets a subscription to its ledger. Through this subscription, the plugin can listen for incoming payments. The module then uses plugin#getAccount to look up the Interledger address from the plugin and caches it in memory for a certain period.

This completes the setup process. The server is now ready to receive paid API requests.

2. Client interaction

Scenario

Marat is a graphic designer who would like to upload a mockup image to share with a client. His friend recommended a tool which doesn't require any signup or configuration and uses his existing ILP account to pay for the storage and bandwidth fees.

Sequence Diagram

2.1. Client generates a server-specific token from the hostname and its local secret:

The uploader tool contains an HTTP-ILP client module like superagent-ilp or ilp-curl. This client module may for instance generate and locally save a client_secret using 256 bits of cryptographically secure randomness.

Before making the paid HTTP request, the HTTP-ILP client module generates a token, for instance using such a client_secret and the hostname of the server it is about to make a request to:

  • Token: HMAC(SHA256, client_secret, hostname)

2.1. Client attempts to call API using token

The paid HTTP request is fired off:

OPTIONS /upload HTTP/1.1
Host: myservice.example
Pay-Token: 7y0SfeN7lCuq0GFF5UsMYZofIjJ7LrvPvsePVWSv450
Unhash-Content-Length: 123

Note that the client hasn't paid at this point and is only making the request to solicit a response from the server, that's why the OPTIONS verb is used. In this example, Unhash-Content-Length is an application-specific header which describes the request which the client intends to make.

2.2. Server responds with payment details

The server returns an HTTP code of 204 No Content and includes response headers showing the amount, an ILP address and a shared secret. The amount expresses how much the request would have cost, as a decimal string and counted in the base unit of the ledger to which the ILP address belongs.

HTTP/1.1 204 No Content
Pay: 10 us.nexus.ankita.~recv.filepay SkTcFTZCBKgP6A6QOUVcwWCCgYIP4rJPHlIzreavHdU
Pay-Balance: 0

The client can now use the shared secret to create a condition to pay this host. The shared secret may for instance be generated by the server as follows:

  • Shared Secret: HMAC(SHA256, receiver_secret, token)

The shared_secret is now a shared secret between the client and server, but will be unknown to any third-party connectors between them.

2.3. Client initiates an ILP payment to refill its balance

In order to refill its balance, the client now creates an ILP payment with the following properties:

  • Destination: us.nexus.ankita.~recv.filepay
  • Amount: 100
  • Condition: SHA256(fulfillment)
  • Memo: pay_token

The fulfillment is generated from the shared secret using PSK.

When the prepared payment reaches the server, it is fulfilled and the token's balance is increased.

There is a chance that the HTTP-ILP server module will process the payment, but the fulfillment doesn't make it all the way back to the sender.

2.6. Sender/client receives the fulfillment.

Once the HTTP-ILP client module receives the fulfillment, it will now retry its original request:

POST /upload HTTP/1.1
Host: myservice.example
Pay-Token: 7y0SfeN7lCuq0GFF5UsMYZofIjJ7LrvPvsePVWSv450
[...]

The request succeeds:

HTTP/1.1 200 OK
Pay: 10 us.nexus.ankita.~recv.filepay SkTcFTZCBKgP6A6QOUVcwWCCgYIP4rJPHlIzreavHdU
Pay-Balance: 90

Notice how the 100 units credit from the payment was added to the balance and the 10 unit cost for the current request was subtracted.