Skip to content

Latest commit

 

History

History
952 lines (818 loc) · 40.3 KB

README.md

File metadata and controls

952 lines (818 loc) · 40.3 KB

LSPS2 JIT Channel Negotiation

Name jit_channels
Version 1
Status For Implementation

Motivation

A "JIT Channel" is a 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, there are two trust models:

  • The LSP trusts clients to actually claim their payment once the channel is opened and the payment is forwarded.
  • The client trusts LSPs to actually open a real channel with a valid funding transaction and valid funding outpoint.

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. The LSP can protect against this (i.e. LSP does not trust the client) by simply not broadcasting the funding transaction until after it gets the preimage.

Similarly, the LSP may provide a random number for the transaction ID of the funding transaction during opening, and then refuse to forward any Lightning transactions out of the channel, then forwarding as "normal" over the invalid channel and then receiving the preimage. The client is then unable to claim its received funds, even though the LSP would be able to claim the funds from incoming forward. Even if the client wanted to unilaterally drop the channel on-chain, as the funding transaction is not valid and will never appear on the blockchain, it will be unable to claim the funds. The client can protect against this (i.e. client does not trust the LSP) by simply not providing the preimage until it sees the funding transaction has been broadcast and is in its own local mempool.

Additional protection for the client against the LSP double-spending an unconfirmed funding transaction can be had by utilizing LSPS3, if the LSP supports this.

If neither the client nor the LSP trust each other, they will deadlock: the untrusting LSP withholds the funding transaction until it sees the payment preimage, the untrusting client withholds the preimage until it sees the funding transaction. (Or with LSPS3, the LSP withholds the LSPS3 response, the client waits for the LSPS3 response)

The only way to break this deadlock without invoking trust, is to use the blockchain to ensure confirmation of some contract that ensures that the funding transaction is broadcastable if and only if the preimage is provided to the LSP. This can be done trivially by using an HTLC where the hashlock branch is signed by both LSP and client, and the LSP provides the witness required to spend from the hashlock branch into the channel funding outpoint, with the client providing its signature and the preimage in order to get the channel funding outpoint confirmed.

Unfotunately, an inherent assumption of JIT channels is that the channel is unconfirmed and the payment immediately routed to the client. This prevents use of the slow blockchain layer to handle trust. With that option not useable, either the LSP trusts the client, or the client trusts the LSP.

The LSP SHOULD default to "LSP trusts client" model. In particular, a too-trusting LSP being attacked may treat its losses as part of the cost of doing business (effectively losing just on-chain fees and the use of capital while locked in an unpaid channel), whereas a too-trusting client being attacked would face actual loss of funds.

The LSP MAY signal a "client trusts LSP" model, and a field is specified for the LSP to do this. The LSP might do this for example if it detects that it is being attacked and needs to protect its funds, even though most of the time it is in "LSP trusts client" model.

A client that does not want to trust any LSP can simply refuse to use an LSP that signals "client trusts LSP".

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.

Actors

The 'LSP' is the API provider. The 'client' is the API client. The '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 on-chain funds).
  • The client determines the parameters of a particular LSP via a lsps2.getinfo request.
    • The LSP also indicates how long those parameters are valid for, which also defines a timeout for the rest of this flow; if the flow does not complete in that timeout, the parameters are no longer valid and the LSP will refuse to open the channel.
  • The client requests for a JIT channel, specifying how much it will receive, via a lsps2.buy 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.

Rationale An alternative flow would be for the client to provide a payment hash for the LSP to recognize, instead of the LSP providing a SCID for the client to use in its invoice. However, this has drawbacks for some future modifications of the Lightning protocol:

  • Protocols where the payer generates the payment preimage and gives the preimage to the payee inside the encrypted onion are incompatible with having the client (the payee) provide the payment hash to the LSP beforehand.
    • Current plans for asynchronous receive use such a scheme.
  • PTLCs are supposed to improve privacy by having each hop have a different blinding factor, but for the LSP to recognize the payment point, it would have to know the blinding factor towards the client, which reduces the privacy of the client in a multipath payment.
    • PTLCs would allow a payer to buy a private key from a payee (client in this context); normally the per-hop blinding factors would hide the sold private key from forwarding nodes, but due to the LSP having to know the exact payment point and the blinding factor towards the client / payee, it would also learn the sold private key.

0. API Version

The client can determine the versions supported by the LSP via the lsps2.getversions call.

This call takes no parameters {} and has no defined errors.

lsps2.getversions has a result like the below:

{
  "versions": [1]
}

versions is the set of LSPS2 versions the LSP supports. When the client later contacts the LSP, it indicates a single specific version, which MUST be one of those indicated in this set.

The client MUST determine protocol compatibility (if it supports a version that the LSP also supports).

1. API Information

lsps2.getinfo 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 request lsps2.getinfo to read the opening_fee of the LSP and its related parameters.

lsps2.getinfo takes the parameters:

{
  "version": 1,
  "token": "SECRETDISCOUNTCOUPON100"
}

version is the version of this spec that will be used for this interaction.

token is an optional, arbitrary JSON string. This parameter is intended for use between the client and the LSP; it may be used to negotiate for a better feerate than the LSP otherwise offers (i.e. a "discount coupon"), or for the LSP to actually offer this service to the client (i.e. an "API key") instead of failing to provide any offers, or for any other purpose.

lsps2.getinfo has the following errors defined (error code numbers in parantheses):

  • unsupported_version (1) - the LSP does not support the version indicated by the client.
  • unrecognized_or_stale_token (2) - the client provided the token, and the LSP does not recognize it, or the token has expired.

Example lsps2.getinfo result:

{
    "opening_fee_params_menu": [
        {
            "min_fee_msat": "546000",
            "proportional": 1200,
            "valid_until": "2023-02-23T08:47:30.511Z",
            "min_lifetime": 1008,
            "max_client_to_self_delay": 2016,
            "promise": "abcdefghijklmnopqrstuvwxyz"
        },
        {
            "min_fee_msat": "1092000",
            "proportional": 2400,
            "valid_until": "2023-02-27T21:23:57.984Z",
            "min_lifetime": 1008,
            "max_client_to_self_delay": 2016,
            "promise": "abcdefghijklmnopqrstuvwxyz"
        }
    ],
    "min_payment_size_msat": "1000",
    "max_payment_size_msat": "1000000",
}

The opening_fee_params_menu is an array of opening_fee_params objects. The LSP MAY return an empty array; in which case, the client currently cannot use JIT Channels with this LSP.

An opening_fee_params object describes how much the LSP will charge for a channel open, and until when the described feerates will be considered valid. An opening_fee_params object MUST have all of the following fields, and MUST NOT have any additional fields:

  • min_fee_msat is the minimum fee to be paid by the client to the LSP. It is a string containing the decimal encoding of a number of millisatoshis.
  • proportional is a parts-per-million number that describes how many millisatoshis to charge for every 1 million millisatoshis of payment size for the first payment. If the proportional fee is less than the min_fee_msat, then the min_fee_msat is paid instead of the proportional times payment size divided by 1 million.
  • valid_until is a datetime (as an ISO8601 string) up to which this specific opening_fee_params is valid, and also serves as the timeout for the JIT Channel flow, if this particular object is selected.
  • min_lifetime is a number of blocks that the LSP promises it will keep the channel alive without closing, after confirmation. The LSP MUST NOT close the channel if both conditions below are satisfied:
    • It was paid via a JIT channel payment to open this channel (i.e. the client released the preimage to the HTLC(s) that have had the value of the opening feee deducted), AND
    • The channel funding transaction confirmation depth is below the min_lifetime.
  • max_client_to_self_delay is a maximum number of blocks that the client is allowed to set its to_self_delay parameter. The client-side to_self_delay is the delay imposed on the LSP to recover the funds in case the LSP has to perform a unilateral close on the channel and defines the security of the client against malign or hacked LSPs.
  • promise is an arbitrary LSP-generated string that proves to the LSP that it has promised a specific opening_fee_params with the specific min_fee_msat, proportional, valid_until, min_lifetime, and max_client_to_self_delay.

Rationale A "minimum" fee is used instead of an additive base fee as this mimics similar financial services.

A time limit (valid_until) on the offerred feerates is needed as channel opening is an on-chain activity, and on-chain feerates need to be reflected in the channel opening feerates the LSP charges. The LSP cannot predict future on-chain feerates, and thus must estimate how long its current on-chain feerate estimates are valid for. The LSP may offer multiple parameter sets with varying time limits.

Both min_lifetime and max_client_to_self_delay in total impose a maximum limit on how long a client can lock the funds of the LSP without giving the LSP any opportunity to earn from forwards. Both parameters are placed in the opening_fee_params object as they are part of the service that the LSP is promising. Although neither parameter is necessary to compute opening_fee, they do define what the client is paying for with that fee.

The LSP, when ordering the opening_fee_params_menu array, MUST order by the following rules:

  • The 0th item MAY have any parameters.
  • Each succeeding item MUST, compared to the previous item:
    • Have a larger min_fee_msat, and equal proportional.
    • Have a larger proportional, and equal min_fee_msat.
    • Have a larger min_fee_msat, AND larger proportional.

Rationale This simplifies how the client expresses the expected opening fee to the user, as it assures the client that the order of the feerates is strictly increasing.

The LSP, when generating the promise field:

  • SHOULD use a cryptographically-verifiable method of generating promise, such as a MAC of some deterministic serialization of the other opening_fee_params keys, then encoded in hexadecimal, base64, or other text encoding. The specific requirements are:
    • Verifiable - the LSP must be able to verify that it issued the promise before. It does not have to be third-party-verifiable (i.e. it is OK if only the LSP can do this verification using private information only the LSP knows).
    • Unforgeable - only the LSP can generate the promise. Knowledge of the promise for one set of parameters should not allow anyone else to generate the promise for a different set of parameters.
    • Committing - the promise commits to a specific set of parameters; if any of the parameters is changed, the promise validation would fail.
  • MUST ensure the promise is no longer than 512 bytes (not including the " delimiters) when encoded as a UTF8-encoded JSON string.
  • MUST avoid characters outside of the printable ASCII range.
  • MUST avoid characters that would require escapes in JSON format.

Rationale The method to generate promise is left vague in order to allow LSP implementors the flexibility to structure their code as necessary. The above specification suggests the use of any MAC, which would cover the above requirements, and requires a symmetric key known only by the LSP. Alternately, an LSP might be componentized and use private-public key cryptography, with a signature as the promise, so that the component that generates opening_fee_params objects is the only one with access to a specific private key, while the rest of the LSP, including the lsps2.buy component, only knows the public key. Another alternative for a componentized LSP would be to have the opening_fee_params generator know the public key of the opening_fee_params validator; the generator creates an ephemeral keypair and uses the ephemeral privkey with the validator pubkey in a Diffie-Hellman scheme to create a session key for a MAC, then concatenate the ephemeral pubkey with the MAC as the promise; the validator takes its private key and uses it with the ephemeral pubkey in a Diffie-Hellman scheme to regenerate the same session key and validates the MAC.

Clients, when reading the promise feild:

  • MUST abort this flow if promise exceeds 512 bytes (not including the " delimiters) when encoded as a UTF8-encoded JSON string.
  • 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 resulting 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_params it actually offered. A size limit is imposed so that LSPs cannot burden clients with unreasonable storage requirements.

LSPs MUST NOT add any other fields to an opening_fee_params object.

Clients MUST fail and abort the flow if a opening_fee_params object has unrecognized fields.

Rationale If additional fields are deemed necessary for a future version of this specification, then the version should be increased, and a new schema defined for the later version.

Clients that expect this version of LSPS2 will compute the opening_fee in the manner indicated in this specification, and any additional fields may imply an extension that may mislead the client into computing the wrong opening_fee.

If the LSP wants to include other information in the opening_fee_params, and that information does not affect how the opening_fee is calculated, then the LSP can actually just embed this information in the promise; the LSP can also commit to that additional information in the MAC or signature or whatever cryptographic construct it uses to validate, and the length of the promise can be used to determine whether this information exists or not, and the LSP can cut the added information in this promise from the cryptographic commitment.

min_payment_size_msat and max_payment_size_msat are the limits of the payment size, inclusive. These are strings containing decimal numbers, in millisatoshis. The payment size is the amount that the payer will send to the client, not including the forwarding fees of nodes along the way.

The client now takes the opening_fee_params and the expected payment_size_msat, to compute the opening_fee, and determine if the resulting opening_fee is reasonable.

Computing The opening_fee

For a given payment_size_msat (in millisatoshis) and a selected opening_fee_params object, both client and LSP MUST compute the opening_fee (in millisatoshis) as follows:

opening_fee = ((payment_size_msat * proportional) + 999999) / 10000000
if opening_fee < min_fee_msat:
    opening_fee = min_fee_msat
  • All numbers MUST be computed in unsigned 64-bit integers.
    • Clients and LSPs MAY use arbitarry-precision integers, such as Haskell Integer type or bignums in Lisplike languages, IF AND ONLY IF they check for overflow of unsigned 64-bit at each basic arithmetic operation.
  • Integer division MUST round down; the + 9999999 causes this to round up.
  • Arithmetic overflow MUST cause the computation to fail and abort this flow (the client SHOULD report the failure to the user, the LSP SHOULD error the client request in the next step).
    • Unsigned integer division cannot overflow.
    • Addition overflow can be detected by comparing the sum to an addend: if the sum is less than one addend, overflow has occurred and the flow must be aborted.
    • Multiplication overflow can be detected by checking that the first factor is nonzero, and dividing the product by the first factor does not result in the second factor.
    • The check MUST be done on EACH addition and multiplication operation, including those with constants.

The C routine compute_opening_fee below performs the computation, and indicates an error (returns -1) and sets errno if the computation fails, otherwise returns 0 on success.

#include<errno.h>
#include<stdint.h>

static inline int
ov_add (uint64_t *sum, uint64_t a, uint64_t b) {
  *sum = a + b;
  if (*sum < a)
  {
    errno = EDOM;
    return -1;
  }
  return 0;
}
static inline int
ov_mul (uint64_t *prod, uint64_t a, uint64_t b) {
  *prod = a * b;
  if ((a != 0) && ((*prod / a) != b))
  {
    errno = EDOM;
    return -1;
  }
  return 0;
}

int
compute_opening_fee(uint64_t* opening_fee, uint64_t payment_size_msat,
		    uinr64_t opening_fee_min_fee_msat,
		    uint64_t opening_fee_proportional) {
  uint64_t tmp;
  if (0 != ov_mul (&tmp, payment_size_msat, opening_fee_proportional))
    return -1;
  if (0 != ov_add (&tmp, tmp, 999999))
    return -1;
  /* C specifies division rounds towards 0.  */
  tmp = tmp / 1000000;
  *opening_fee = tmp;
  if (*opening_fee < opening_fee_min_fee_msat)
    *opening_fee = opening_fee_min_fee_msat;
  return 0;
}

Below is a similar implementation in Rust, with overflow errors signalled as None:

fn compute_opening_fee(payment_size_msat: u64,
                       opening_fee_min_fee_msat: u64,
                       opening_fee_proportional: u64) -> Option<u64> {
  let t1 = payment_size_msat.checked_mul(opening_fee_proportional)?;
  let t2 = t1.checked_add(999999)?;
  let t3 = t2.checked_div(1000000)?;
  let t4 = std::cmp::max(t3, opening_fee_min_fee_msat);
  Some(t4)
}

Rationale The computation is described in excruciating detail in order to ensure that both LSP and client agree on the result of computation of the opening_fee. In C, signed integer overflow is undefined behavior, and even if neither LSP nor client is written in C, they may be written in a language whose implementation is an interpreter written in C or using C libraries, which may also trigger the same undefined behavior on signed integer overflow, thus unsigned integers are specified, which, in C, are specifically modulo 2 to the number of bits. Arithmetic overflow is problematic and may lead to unexpectedly low opening_fee charges for high payment_size_msat and high opening_fee_params.proportional, thus must be specifically detected and cause an abort in this flow rather than continue and cause problems for the LSP. Most modern microprocessors have dedicated instructions to detect overflow, and most modern compilers can recognize the above code and optimize those down to these dedicated instructions at high optimization settings; in particular, the division in the overflow-detecting multiplication routine is optimized away and replaced with a simple overflow-flag check.

2. Request JIT Channel

The client constructs a request body for a lsps2.buy request, depending on their need.

The client is identified by the LSP from the BOLT8 connection that this LSPS API is used on, which identifies and authenticates the client node ID (also known as client identity public key). The LSP identifies the client as "connected" if there is a BOLT8 tunnel that has been identified as having the same peer as the client node ID.

Example lsps2.buy request parameters:

{
    "version": 1,
    "opening_fee_params": {
        "base_msat": "546000",
        "proportional": 1200,
        "valid_until": "2023-02-23T08:47:30.511Z",
        "min_lifetime": 1008,
        "max_client_to_self_delay": 2016,
        "promise": "abcdefghijklmnopqrstuvwxyz"
    },
    "payment_size_msat": "42000"
}

version is the version of this spec that will be used for this interaction.

opening_fee_params is the object acquired from the previous step. Clients MUST copy it verbatim from an entry of opening_fee_params_menu from a result of a lsps2.getinfo call. LSPs MUST check that the opening_fee_params.promise does in fact prove that it previously promised the specified opening_fee_params. LSPs MUST check that the opening_fee_params.valid_until is not a past datetime.

payment_size_msat is an optional amount denominated in millisatoshis that the client wants to receive:

  • If the client wants to issue a variable-amount invoice ("0-amount invoice") the client MUST leave out this parameter, but MUST indicate to the payer to NOT use multipath payments.
    • "no-MPP+var-invoice" mode.
  • If the client wants to issue a fixed-amount invoice, the client SHOULD provide this parameter, and if it does, MAY indicate to the payer to USE multipath payments.
    • "MPP+fixed-invoice" mode.

The client MUST ensure that payment_size_msat is within the previous min_payment_size_msat and max_payment_size_msat parameters from the LSP. The LSP MUST validate that the payment_size_msat is within the previous min_payment_size_msat and max_payment_size_msat parameters from the LSP.

If the payment_size_msat is specified in the request, the LSP:

  • MUST compute the opening_fee and check that the computation did not hit an overflow failure.
    • MUST check that the resulting opening_fee is strictly less than the payment_size_msat.
  • SHOULD check that it has sufficient incoming liquidity from the public network to be able to receive at least payment_size_msat, if it was specified.

The following errors are specified for lsps2.buy:

  • unsupported_version (1) - the LSP does not support the specified version.
  • invalid_opening_fee_params (2) - the valid_until field of the opening_fee_params is already past, OR the promise did not match the parameters.
  • payment_size_too_small (3) - the payment_size_msat was specified, and the resulting opening_fee is equal or greater than the payment_size_msat.
  • payment_size_too_large (4) - the payment_size_msat was specified, and the LSP hit an overflow error while calculating the opening_fee, OR the LSP has insufficient incoming liquidity from the public network to receive the payment_size_msat.

If there were no errors, the LSP then provides a normal result to the lsps2.buy API.

Example successful lsps2.buy result:

{
    "jit_channel_scid": "1x4815x29451",
    "lsp_cltv_expiry_delta" : 144,
    "client_trusts_lsp": false
}

jit_channel_scid is the SCID to use for creating the routehint in the invoice, and lsp_cltv_expiry_delta is the CLTV delta for that routehint hop.

client_trusts_lsp is an optional Boolean. If not specified, it defaults to false. If specified and true, the client MUST trust the LSP to actually create and confirm a valid channel funding transaction.

The client MAY abort the flow if the LSP specified client_trusts_lsp as true in the result.

3. Invoice Generation

The client MAY then generate a BOLT11 invoice.

If the client generates a BOLT11 invoice, the client MUST set the following:

  • The sum of timestamp and x/expiry fields is equal to or less than opening_fee_params.valid_until.
  • n is the client node ID, or any public key whose private key the client knows.
  • r contains a single routehint with a single hop:
    • pubkey is the LSP public 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.
  • c contains a min_final_cltv_expiry_delta that is at least +2 higher than its normal setting.
    • The client MUST impose its normal setting on actual received payment. For example, suppose the client normally uses a min_final_cltv_expiry_delta of 144. For a JIT Channels invoice, it sets it to 146 in the invoice, but only still expects 144 when the payment reaches it even for JIT Channels invoices.
  • Depending on if the client specified a payment_size_msat in the previous lsps2.buy call:
    • If payment_size_msat specified ("MPP+fixed-invoice" mode), set the invoice amount to payment_size_msat and enable the basic_mpp feature.
    • If payment_size_msat unspecified ("no-MPP+var-invoice" mode), do not specify an invoice amount, and disable the basic_mpp feature.

All other fields are to be filled in by the client.

Rationale In-Lightning feerates can be folded into the opening_fee for the initial payment. The channel is not open yet, thus the client cannot know what the actual feerates the LSP would impose at the time this invoice is generated, so it must be fixed at this point. Multipart payments are specifically disallowed, as the total amount of a multipart payment is encrypted in the onion such that only the rceiver (the client) can decode it, and the LSP cannot thus determine what the total amount from the payer would be. By forcing a non-multipart payment, the LSP can treat the first arriving HTLC to be forwarded to the jit_channel_scid as the total payment.

Bitcoin blocks may be mined at any time. When a payer sends out a payment, it must "lock in" a specific blockheight for the timeout of the HTLC arriving to the client, but if a block is mined between when the payer sends out the payment and when the client receives it, then the timeout may now be below the normal min_final_cltv_expiry_delta of the client. BOLT requires that the payee fail this with incorrect_or_unknown_payment_details with a height indicating the new current blockheight, but the LSP cannot differentiate between this failure (which would cause the payer to retry with renewed timeouts), versus a deliberate attempt by the payer and client to waste LSP resources (which should cause the LSP to deny future service to this client). By adding a small +2 margin here, we greatly reduce the incidence of such an accident.

Forward Compatibility With Post-BOLT11 Payment Schemes

Ultimately, the client MUST provide the information below to the payer:

  • The client node ID (or any public key whose private key the client knows).
  • The jit_channel_scid.
  • The LSP node ID.
  • The lsp_cltv_expiry_delta.
  • The expiry for the payment.
  • Whether it can use MPP or not.

However, the client MAY provide this information to the payer by means other than BOLT11 invoice, including in a form that is not decodable by the payer, but which can be decoded by another LN participant.

The only necessary requirement is for the LSP to see an incoming HTLC onion that indicates the jit_channel_scid as the next hop, and as long as the client is able to cause the payer to do this, it is would be compatible with this protocol.

Non-normative For example, the client node ID, the jit_channel_scid, the LSP node ID, and the lsp_cltv_expiry_delta can be encoded as the last hop of a blinded path, for example in a BOLT12 offer or invoice. The payer would not have direct access to the information, but the introduction point of the blinded path would be able to start the decoding of the blinded path.

4. Payment

The client MAY issue the generated invoice to the payer of the client, or equivalently inform the payer of the necessary information.

The payer can then generate an outgoing payment part to deliver the paid amount to the LSP. If the client selected "MPP+fixed-invoice" mode, the payer can generate multiple outgoing payments parts.

In "MPP+fixed-invoice" mode, the LSP, if it receives a forward where the next hop is jit_channel_scid:

  • SHOULD wait for payment parts of a single payment hash until all parts sum up to at least payment_size_msat.
  • 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_msat AND opening_fee_params.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_params.valid_until.
    • All received payment parts sum up to at least payment_size_msat plus opening_fee.
    • The client is connected.

In "no-MPP+var-invoice" mode, the LSP, if it receives a forward where the next hop is jit_channel_scid, before opening_fee_params.valid_until:

  • MUST set payment_size_msat as the forwarded value of the HTLC.
  • MUST compute the opening_fee based on the payment_size_msat, and if the computation overflows, MUST fail with unknown_next_peer.
  • MUST check that opening_fee + htlc_minimum_msat < payment_size_msat, and if that fails, MUST fail with unknown_next_peer.

5. Channel Opening And Forwarding

The LSP requests a channel open to the client.

The LSP selects the channel size. The LSP MUST ensure the channel is large enough to transmit the payment_size_msat - opening_fee, plus any reserve needed on the LSP side.

The LSP and client MUST negotiate these options and parameters:

  • option_zeroconf is set.
  • option_scid_alias is set.
  • announce_channel is false.
  • The client-provided to_self_delay is less than or equal to the agreed-upon max_client_to_self_delay.

Rationale option_zeroconf is set so that the payment can be immediately forwarded to the client and resolved as soon as the opening negotiation completes; if the client and LSP had to wait for confirmation, the incoming payment would have to be locked for an extended period, which is indistinguishable from a channel jamming attack. option_zeroconf cannot be set unless announce_channel is false. option_scid_alias needs to be set so that the channel can be referred to on future invoices before the channel confirms.

Future versions of this API may be able to utilize Asynchronous Receive (currently being developed as of this version) to be able to get around the option_zeroconf requirement, by treating the receiver / client as offline until the client is online and the JIT channel to it is deeply confirmed, if the LSP and client negotiate a non-option_zeroconf channel for the JIT channel. A non-option_zeroconf JIT channel could also be later published with announce_channel = true.

Clients MAY reject the channel open attempt if any other parameters or options are not desired by the client (for example, it MAY reject non-zero channel reserve requirements imposed on the client by the LSP). Rejection is via the error Lightning BOLT message.

LSPs MUST fail the payment with unknown_next_peer in case the client rejects the channel open via an error.

If the client disconnects before the LSP can receive funding_signed from the client, the LSP MUST fail the incoming payment parts with temporary_channel_failure, then return to the previous step (waiting for payment).

Rationale The client might have crashed at this point, and recovery might take an inordinate amount of time. However, use of the temporary_channel_failure error informs the payer that the error is temporary and it can retry later, if the client is online at that point.

Client disconnection will prevent the LSP from broadcasting the funding transaction and the LSP may re-allocate the UTXOs spent in the funding transaction for a different payment. Thus, the correct behavior is to abort the payment, so that the LSP funds may be re-used in a new channel to the same client if the payer retries, or so that the LSP funds may be re-used for a different client if the payer gives up on paying the client.

Clients MUST NOT expect that jit_channel_scid is the same as the alias SCID. Clients MUST NOT expect that jit_channel_scid is different from the alias SCID.

Depending on the client_trusts_lsp from the lsps2.buy result, after the client has sent funding_signed:

  • If client_trusts_lsp is specified and true:
    • The LSP MAY wait for the client to send the preimage to the incoming payment via a update_fulfill_htlc before broadcasting the funding transaction.
    • If the LSP supports LSPS3. the LSP MUST fail a lsps3.getpromise call of the channel funding transaction with the error conditions_apply.
    • The client MUST NOT wait for the LSP to broadcast the funding transaction before sending the preimage via a update_fulfill_htlc.
    • The client and LSP MUST immediately send channel_ready.
  • If client_trusts_lsp is unspecified or false:
    • The client MAY wait for the funding transaction to appear in its mempool or the mempool of a trusted node, or confirmed in a block, before sending channel_ready.
    • If the LSP supports LSPS3, the LSP MUST succeed the lsps3.getpromise call of the channel funding transaction.
    • If the LSP supports LSPS3, the client MAY call the lsps3.getpromise API on the channel funding transaction, and MAY wait for a response to that call before sending channel_ready.
    • The LSP MUST immediately broadcast the channel funding transaction and send channel_ready.
    • The client MAY immediately send channel_ready (i.e. the client trusts the LSP, even though the LSP does not require that trust).

As soon as both client and LSP have sent channel_ready for the new channel, the LSP then forwards payment parts to the client. In "no-MPP+var-invoice" mode there is only one payment part.

The LSP generates non-standard forwards, where the amount received by the client is smaller than specified in the onion; the client MUST accept the non-standard forward(s), provided they sum to at least payment_size_msat - opening_fee.

The LSP MUST ensure that each forwarded part forwards at least htlc_minimum_msat millisatoshis. The LSP MUST ensure that all parts forwarded sum up to at least payment_size_msat - opening_fee.

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 - htlc_minimum_msat >= 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 - htlc_minimum_msat), then forward htlc_minimum_msat for this part.
  • The above loop will not reach past the last part unless the number of parts times htlc_minimum_msat exceeds the payment_size_msat. This case should be checked beforehand and cause the payment to be failed due to too many payment parts.

Once the client has received payment parts that sum up to at least payment_size_msat, it MUST claim at least one payment part. Once that is done, the protocol flow is considered complete.

The parts that the client receives are non-standard, as the amount in the onion would not be the same as the amount sent by the LSP. Clients MUST suppress such checks for parts it recognizes as having been received to pay for a JIT Channel open. Clients would need some mechanism to recognize such payments, such as by flagging such payments in its invoice database, putting such payments in a separate invoice database, or adding special flags inside the metadata or payment_secret of the invoice, or by changing how payment_secret is computed based on whether the invoice is to pay for a JIT Channel or not and trying both ways.

6. Post-opening Normal Operation

After the channel has been opened and an alias has been specified, the client MUST use the alias for future invoices on the channel, as normal for users of zero-confirmation channels. Note that use of alias forces the alias to always be used, even after the channel is confirmed.

Invoices issued after the channel open MUST use the feerates negotiated for the new channel.

Rationale While it is desirable that the client would be able to issue multiple invoices before the channel is opened, this may require that the alias be identical to the jit_channel_scid, which might not be feasible under some setups. In particular, jit_channel_scid may be stored in a database that has strict time limits from the opening_fee_params.valid_until, while the alias SCID would remain valid while the channel is open. In addition, the "normal" Lightning base and proportional channel fees would need to be applied to the initial payment(s). This version of this API therefore requires that the client first be paid once via the jit_channel_scid before it can be issue further invoices with the alias.

Future versions of this API may allow for more flexibility on the client side, including support for variable-amount invoices, multiple incoming payments being stalled until the opening_fee is achieved and the channel can be opened, and so on.

LSPs MUST consider the jit_channel_scid as yet another alias for the specified client, up to until the valid_until time selected. LSPs MUST consider this alias not just for forwarded payments, but also for onion messages.