diff --git a/LSPS3/README.md b/LSPS3/README.md new file mode 100644 index 0000000..51a8754 --- /dev/null +++ b/LSPS3/README.md @@ -0,0 +1,317 @@ +# LSPS3 JIT Channel Negotiation + +|Name | `base_api` | +|--------|--------------------------| +|Version | 1 | + +## Motivation + +A "JIT Channel" is a 0-conf channel opened in response to an incoming payment +from the public network to a client, via the LSP. +This allows a client with no Lightning channels to start receiving on +Lightning, and have the cost of their inbound liquidity be deducted from their +first received payment. + +### Trust Models + +As of this version, the trust model is that the LSP trusts clients to actually +claim their payment once the channel is opened and the payment is forwarded. + +If the client does not claim the payment, and the funding transaction confirms, +then the LSP will have its funds locked in a channel that was not paid for. +Even if the LSP disables all other use of the channel until the payment paying +for the channel is claimed, the client may then refuse all mutual close attempts +in retaliation (by disconnecting), and force the LSP to unilaterally close, +which locks the funds until the `to_self_delay` (indicated by the client, and +imposed on the LSP) has passed. + +LSPs that implement this API SHOULD include mitigations to allow them to +determine if clients can be trusted, or to detect and protect against attacks +on the LSP. +How those mitigations are performed is beyond the scope of this specification. + +### Amounts + +All amounts in this protocol are specified in millisatoshi. + +All millisatoshi values MUST be represented as a string and MUST NOT be +represented as integer values. + +> **Rationale** JSON numbers are specified to only fit IEEE double-precision +> numbers, which have a 53 bit mantissa. +> The maximum number of millisatoshis (21 million BTC) cannot be specified in +> 53 bits. +> In addition, actual JSON parsers may use a smaller size for parsed integers; +> for instance, as signed 32 bit numbers. +> The largest safe value is 2,147,483,647; 2,147,483,647msat = BTC0.021,474,836,47 +> which is too low. + +### Actors + +'LSP' is the API provider. +'Client' is the API client. +'Payer' is who pays for the initial receive of the client. + +## Flow (LSP Trusts Client Model) + +Overview: + +* The client determines that it would like to receive over Lightning, but + it has no inbound capacity, and the client cannot pre-buy this capacity + (for instance, it also has no outbound capacity or onchain funds). +* The client determines the parameters of a particular LSP via a `GET` + request. +* The client requests for a JIT channel, specifying how much it will + receive, via a `POST` request. +* The LSP returns an SCID, which identifies this request to the LSP. +* The client generates an invoice, which includes the above SCID and the + LSP node ID as a routehint. +* The client hands the invoice to whoever it will receive funds from. +* The payment is forwarded to the LSP. +* The LSP recognizes the next hop SCID as being a JIT channel request, + and opens a 0-confirmation channel to the client, which must be + connected to the LSP at that time. +* The LSP forwards the payment to the client, deducting the channel + opening fee. +* The client claims the payment. + +### 1. API Information + +`GET /lsp/jitchannel` is the entrypoint for each client using the API. +It indicates supported versions of this protocol, as well as any limits the +LSP imposes, and parameters for payment. + +The client MUST pull `GET /lsp/jitchannel` to read: + +- the supported `versions` of the LSP. +- the `opening_fee` of the LSP and its related parameters. + +The client MUST then determine protocol compatibility, and also determine +if the fee imposed by the LSP is acceptable. + +Example `GET /lsp/jitchannel` response: + +```JSON +{ + "versions": [1], + "opening_fee": "546000", + "opening_fee_valid_until": "2023-02-23T08:47:30.511Z", + "opening_fee_promise": "abcdefghijklmnopqrstuvwxyz", + "min_payment_size": "1000", + "max_payment_size": "1000000" +} +``` + +`versions` is the set of API versions the LSP supports. +When the client later contacts the LSP, it indicates a single specific +API version, which MUST be one of those indicated in this set. + +`opening_fee` is how much the LSP will charge to open a JIT channel, in +millisatoshis. + +`opening_fee_valid_until` is a datetime up to which the offered +`opening_fee` is valid. + +`opening_fee_promise` is an arbitrary string that proves to the LSP +that it previously promised a specific `opening_fee` with a specific +`eopning_fee_valid_until`. + +LSPs: + +* SHOULD use a cryptographically-verifiable method of generating + `opening_fee_promise`, such as a MAC of some serialization of the + `opening_fee` and the `opening_fee_valid_until`, then encoded in + hexadecimal or other text encoding. +* MUST ensure the promise is no longer than 512 bytes. +* SHOULD avoid characters outside of the printable ASCII range. + +Clients: + +* MUST abort this flow if `opening_fee_promise` exceeds 512 bytes. +* MUST NOT parse or interpret this string, and only provide it + verbatim later. + +> **Rationale** By using a promise that must be remembered by the +> client, the LSP does not have to remember what it offered via this +> API, reducing state storage, especially if the client then decides +> that the `opening_fee` is too high and ultimately decides not to +> continue this flow. +> By using a cryptographically-verifiable method, the LSP can ensure +> that it will only honour `opening_fee`s it actually promised. +> A size limit is imposed so that LSPs cannot burden clients with +> unreasonable storage requirements. + +`min_payment_size` and `max_payment_size` are the limits of the +payment size, inclusive. +These are in millisatoshis. +The payment size is the amount that the client will receive on the +JIT Channel. + +The client MUST ignore any additional fields it does not recognize. + +> **Rationale** This allows future versions of this spec to add new +> fields to this response, without causing problems for clients that +> only support the current version. + +### 2. Request JIT Channel + +The client constructs a request body for a `POST /lsp/jitchannel` +request, depending on their need. + +Example `POST /lsp/jitchannel` request: + +```JSON +{ + "version": 1, + "opening_fee": "546000", + "opening_fee_valid_until": "2023-02-23T08:47:30.511Z", + "opening_fee_promise": "abcdefghijklmnopqrstuvwxyz", + "payment_size": "42000", + "client_node_id": "03d4e028a0d4a90868ec202ab684fb0085779defea9ca7553e06146557631eec20" +} +``` + +`version` is the version of this spec that will be used for this +interaction. + +`opening_fee`, `opening_fee_valid_until`, and `opening_fee_promise` +are the parameters acquired from the previous step. +Clients MUST copy them verbatim from some previous +`GET /lsp/jitchannel` response. +LSPs SHOULD check that the `opening_fee_promise` does in fact +prove that it previously promised the specified `opening_fee` and +`opening_fee_valid_until`. +LSPs SHOULD check that the `opening_fee_valid_until` is not a +past datetime. + +`payment_size` is the amount that the client wants to receive. + +The client MUST ensure that `payment_size` is within the previous +`min_payment_size` and `max_payment_size` parameters from the LSP. +The LSP MUST validate that the `payment_size` is within the previous +`min_payment_size` and `max_payment_size` parameters from the LSP. + +The client MAY use a "subtractive" computation to get the +`payment_size`. +For example, the client may want to charge some payer an exact +amount of 1,000,000 millisatoshis, but the LSP indicated an +`opening_fee` of 546,000 millisatoshis. +In that case, the client should specify 454,000 millisatoshis for +`payment_size`, so that the invoice charges 1,000,000 millisatoshis +total. + +`client_node_id` is the node ID of the client. + +The LSP can then respond with a response object or an error +object. +The client can differentiate between these two objects by checking +for an `error` field, which exists and is the Boolean value +`true` if the object is an error object. + +Example successful `POST /lsp/jitchannel` response: + +```JSON +{ + "jit_channel_scid": "1x4815x29451", + "lsp_node_id": "03864ef025fde8fb587d989186ce6a4a186895ee44a926bfc370e2c366597a3f8f", + "lsp_cltv_expiry_delta" : 144, + "lsp_connection_strings": [ + "03864ef025fde8fb587d989186ce6a4a186895ee44a926bfc370e2c366597a3f8f@3.33.236.230:9735" + ] +} +``` + +`jit_channel_scid` is the SCID to use for creating the routehint in +the invoice, `lsp_node_id` is the node for that routehint hop, and +`lsp_cltv_expiry_delta` is the CLTV delta for that routehint hop. + +`lsp_connection_strings` is how the client should connect to the +LSP. + +### 3. Invoice Generation + +The client then generates a [BOLT11][] invoice. + +[BOLT11]: https://github.com/lightning/bolts/blob/f7dcc32694b8cd4f3a1768b904f58cb177168f29/11-payment-encoding.md + +* `amount` is the sum of `payment_size` and `opening_fee`. + Note that `payment_size` and `opening_fee` are in millisatoshis, + but the BOLT11 `amount` uses metric Bitcoin units. +* The sum of `timestamp` and `x`/`expiry` fields is equal to + or less than `opening_fee_valid_until`. +* `n` is the client node ID. +* `r` contains a single routehint with a single hop: + * `pubkey` is the `lsp_node_id`. + * `short_channel_id` is the `jit_channel_scid`. + * `fee_base_msat` and `fee_proportional_millionths` are 0. + * `cltv_expiry_delta` is `lsp_cltv_expiry_delta`. + +All other fields are to be filled in by the client. + +The client MAY indicate multipart (`basic_mpp`) support, if it +supports multipart. + +### 4. Payment + +The client MUST connect to the LSP via an indicated +`lsp_connection_strings`, and then issue the generated invoice +to the payer of the client. + +The payer can then generate one or more outgoing payment parts to +deliver the total amount to the LSP. + +The LSP, when it receives a forward where the next hop has an +SCID matching an issued `jit_channel_scid`: + +* MUST wait for payment parts until all parts sum up to at least + `payment_size` plus `opening_fee`. +* MUST NOT fail with `mpp_timeout`, as the final hop is the client + and that error is only allowed at the final hop. +* MUST fail with `unknown_next_peer` if all parts have not + summed up to at least `payment_size` plus `opening_fee` AND + `opening_fee_valid_until` has passed. +* MAY fail with `unknown_next_peer` if it receives too many payment + parts. +* When all conditions below are true, MUST continue to the next + step: + * The current time is strictly less than `opening_fee_valid_until`. + * All received payment parts sum up to at least `payment_size` + plus `opening_fee`. + * The client is connected. + +### 5. Channel Opening And Forwarding + +The LSP requests a channel open to the client. +The LSP MUST set `option_zeroconf` in the channel opening. + +The channel size must be sufficient, including up to 1% LSP-side +channel reserve, to forward the `payment_size` to the client. + +The LSP then forwards parts to the client as soon as both client +and LSP have signalled `channel_ready` for the new channel. +The LSP rewrites onions to deduct, in total, `opening_fee` from +all parts it received, and to forward to the newly-opened channel. + +The LSP MUST ensure that each forwarded part forwards at least +one millisatoshi. +The LSP MUST ensure that all parts forwarded sum up to at least +`payment_size`. + +For example, the LSP can use the algorithm below to determine +how much to forward for each incoming payment part, while ensuring +that both the above properties are preserved. + +* Put the payment parts in an array in arbitrary order. +* For each part: + * Get the `part_amount`, the incoming amount for the part. + * If `part_amount - 1 >= opening_fee`, then forward + `part_amount - opening_fee` for this part, then forward + the rest of the parts verbatim, if any. + * Else subtract `opening_fee = opening_fee - (part_amount - 1)`, + then forward 1 millisatoshi for this part. +* The above loop will not reach past the last part unless + the number of parts exceeds the minimum `payment_size`. + +Once the client has received payment parts that sum up to at +least `payment_size`, it MUST claim at least one payment part. +Once that is done, the protocol flow is complete.