These are the SuperScalar UX notes that I wrote some time ago. I am now sharing it here.
NOTE These should be considered as “very rough”. Nobody has any experience with deploying a N>2 non-custodial offchain mechanism that integrates deeply with Lightning. It is entirely possible that my whole approach here is completely wrong-headed and delusional. This is the best I can do with what little knowledge I currently have as of October->November 2024. Hopefully, it can be improved as we go on to actually try implementing SuperScalar for larger groups of actual end-users. Which is to say: if you follow these notes to the letter and end up with horrible UX that makes your mom hate you, that is your fault, not mine ^.^;;;;;;;;
Subject: SuperScalar UX Notes
Preface: The Mobile Phone Environment
These notes are primarily targeted for mobile phone uses.
I am not an expert in the mobile phone environment. However, my initial study suggests the following:
- Messaging applications are common enough that significant
parts of the mobile phone development environment are
focused on timely delivery of messages.
- This is not polled (or if it is polled, it is polled in aggregate amongst all messaging applications; not certain about exact implementation — in Android, for example, timely delivery usually requires Google Services, and iOS seems to rely on similar services provided by Apple).
- There are even cross-platform libraries/systems that make this easy to port across Android and iOS.
- If a human user sends a message to another human user via a mobile-based messaging app, and the other user says “I did not receive it” the usual reaction is disbelief, since in practice message delivery is highly timely and reliable.
- The example of Signal, which has end-to-end encryption,
suggests that when a message is delivered, the app is
given enough CPU power to at least perform decryption
of the message, suggesting that at least some CPU power
is available via this mechanism.
- In SuperScalar, we require that clients also perform MuSig2 signing whenever the LSP signals a change in some subtree, which requires at least one and a half roundtrips (and probably two roundtrips to return the completed signature). I am uncertain at this point if it is possible to send small TCP bytestreams from the mobile app to the LSP during handling of an incoming message.
- The example of Phoenix, which can receive funds even if the phone is locked and otherwise not actively used by the user, suggests that it is possible to compute an ECDSA signature and send it to the LSP at least using some mechanism to wake up the app (conjectured to be a messaging system similar to the above). Note that proper payment according to the BOLT spec requires a grand total of at least 3.5 round trips (2 roundtrips to irrevocably commit to the HTLC, then 1.5 roundtrips to resolve the HTLC) and requires two ECDSA signing sessions each for client and LSP.
The above is from the point-of-view of the actual Bitcoin Lightning wallet app.
From the point of view of the LSP, the LSP can simply expose LSPS5. Any Bitcoin Lightning wallet app which can afford to run a webserver can register webhooks via LSPS5 that then cause messages to be sent to the specific client mobile app, and allow it to work with the SuperScalar provided by the LSP.
The User Concepts
A simple rule of thumb for UX design is: “give the user an interface they are already used to”.
Given that this is financial technology, it makes sense to imitate existing banking apps and common banking practices.
Thus:
- The app provides the equivalent of a “Bitcoin-denominated checking account”.
- The account has an “account limit”.
- The account has “deposit insurance”, which can be either limited coverage (available for free) or unlimited coverage (requires one-time fee to be paid to miners and swap operators).
Expanding on the above:
- The app provides the equivalent of a “Bitcoin-denominated
checking account”.
- Like any checking account, there is a monthly account
maintenance fee.
- Under the hood: This is the amortized cost of managing the UTXOs and liquidity needed in the SuperScalar and other protocols. The LSP can provide a fixed fee regime to the clients; the LSP can manage the risk of actual onchain fee variance by purchasing onchain feerate futures from miners, as described by Jack Mallers, and with a proposed mechanism here.
- The fee may be waived if the account has a large enough
amount consistently over the past month (as is typical
for checking accounts provided by many banks).
- Under the hood: Channel balances imply that the more funds the client owns in the channel, the less funds the LSP owns in the channel. Because of this, the LSP takes on less “cash drag” if the amount in the account is consistently high. (i.e. more of the LSP funds are in earning investments, such as published routing channels, and the earnings there can offset the cost of maintaining the unpublished channel with the client)
- The advantage here, compared to a custodial scheme as in
traditional banking, is that it is possible for a client
to force account closure, even if the LSP has frozen the
client account, and receive their funds onchain (minus
fees taken by miners).
This process takes some amount of time, possibly a month
or two.
- Under the hood: The client forcing account closure is simply triggering a unilateral exit. If we can use the SuperScalar addendum Inversion of Timeout Default, then the client app simply disconnects from the LSP and ignores requests from the LSP to wake up and connect, so that the LSP is forced to evict the unresponsive client by paying for the publication of the path to their unilateral exit.
- Like any checking account, there is a monthly account
maintenance fee.
- The account has an “account limit”.
- This is presented as the inverse of a credit card.
- That is: the “account limit” of a credit card is how much you can spend until you have to receive funds into it (or increase your account limit).
- In contrast, as this is a debit instrument, the
“account limit” of the Bitcoin-denominated checking
account is how much you can receive until you
have to spend it (or increase your account limit).
- Under the hood: the account limit is really just the total channel capacity of all channels between LSP and client, minus the channel reserve requirement imposed by the client on the LSP. The LSP does not impose channel reserves on the client (i.e. 0% reserve on the client side, but non-0 on the LSP side) because the main purpose of the reserve is to prevent theft attempts from being free; the LSP is assumed to have very high uptime, and to have watchtowers with uptime uncorrelated with their actual LN node, so that theft attempts being free do not matter in practice (for the LSP; it matters for the client, hence the non-0 reserve it imposes on the LSP).
- The UI is expected to show the current account balance
and the current account limit in close proximity to each
other, and to provide a simple way to show the
difference between the current balance and the current
limit.
- Under the hood: the difference between the account balance and the account limit is the current inbound liquidity from the LSP to the client.
- The UI allows the user to “upgrade account limit”
for a cost (which may be waived by the LSP if the user
has had a consistently high account balance over the
past month).
- Under the hood: This is really just purchasing inbound liquidity from the LSP. The cost of purchasing the inbound liquidity can be made fixed via the use of onchain feerate futures as described earlier, and if the client has a consistently high account balance in their account, as noted as well more of the LSP funds can be put to earning investments such as published channels, which also offset the cost of upgrading the account limit.
- Under the hood: naively, we might think that the LSP can control exactly the liquidity that is devoted to each user, and thus to hide the details of liquidity management. Unfortunately, this is not the case, as the LSP needs to provide, upfront, some funds of its own, before it can cater to the needs of large users. Suppose some individual user has some large amount of funds inside a SuperScalar. When transitioning from one SuperScalar to the next, the LSP has to put up funds that is at least the account balance of the individual large user, plus some additional margin for future receives of that large user. While this lockup is transient, there is always some risk that the client will force a unilateral exit before moving from the old SuperScalar to the next, thus forcing the LSP to lock up those funds to that client for a month (as changing in-SuperScalar states — i.e. moving liquidity — requires the client cooperation, and the client can refuse to cooperate, the LSP practically risks having the large fund be locked up in a form that cannot be used without a lot of blockspace usage and time for unilateral exit). The risk that the LSP takes on here, is the charge it would have to impose on the client for the larger amount the client can keep in the SuperScalar. This holds true even outside of SuperScalar (though blockspace use in unilateral exit is better outside of SuperScalar), and is the entire reason why we have any kind of pay-for-inbound-liquidity scheme in Lightning. Thus, it is infeasible to not expose the account limit concept to end-users; a higher account balance is a larger risk on the LSP and must be paid for, thus end-users need to be aware that increasing their account limit will be costly, and they should be informed of this before they put any amount in the account.
- Under the hood: Under the Inversion of Timeout Default addendum, part of the security of
clients lies in the fact that the LSP has to
lock in funds equal to or greater than the
account limit of the client.
Provided the client does not ever upgrade its
account limit (expected for most clients)
then it does not need an external UTXO to
pay for onchain fees on unilateral close
(i.e. it does not require exogenous fees, as
the LSP is the one at risk of loss if it
does not unilaterally exit before timeout).
However, it does imply that the LSP cannot
have “fractional reserve” of the account
limit.
Suppose we have clients
A
andB
, promised account limits of 10 units each. Suppose the LSP tries a fraction reserve of account limit, giving each one 7 units of capacity, on the assumption that the total capacity needed by both clients will take no more than 14 in total, in practice. SupposeA
ends up having a balance of 2 units, butB
maxes out its promised account limit of 10 units. The total is 12 units, which appears fine (as the total capacity allocated toA
andB
is 14 units), but the Inversion protection thatB
has only covers up to 7 units in case of LSP misbehavior. The Inversion protection cannot be increased without adding further Decker-Wattenhofer layers in the Inversion protection transaction, which weakens the protection — the protection itself would require further protection of its own mutable state. The only way forB
to protect itself fully would be to move some funds onchain to get an onchain UTXO it can use to pay for P2A exogenous fees. Thus, if the LSP promises an account limit of 10 units, then the LSP definitely needs to provide 10 units, plus a little extra, to each of its channels withA
andB
.
- The account has deposit insurance, which can be
either limited coverage (for free, and the default) or unlimited coverage.
- In case the LSP refuses to give proper service to
the client, the client can force account closure
regardless of what the LSP does.
- For example, if the LSP shuts down without properly allowing clients to withdraw funds, or if the LSP is bought out by an entity that decides to freeze the accounts of some clients.
- The client can always force account closure, though the UI attempts to funnel them through cooperative account closure before letting them force account closure.
- The forced account closure will be covered by the deposit insurance; i.e. the deposit insurance will put the account balance onchain, minus mining fees, if the client forces account closure. The deposit insurance is no-fault; the client does not need to justify why it forced the account closure.
- At the start of the service month, the coverage of the limited coverage scheme is equal to the client account limit at the time, plus some extra amount as a buffer.
- If the client has limited coverage (the default), then the maximum amount the client can safely get from the client-initiated forced account closure is limited by the deposit insurance, minus onchain mining fees. Forced account closure can take a month or more to resolve.
- The limit of the limited coverage is higher than the account limit at the start of the service month, so for most users, limited deposit insurance coverage is sufficient. However, if the client upgrades their account limit and receives more funds into their account, the client may have a total account balance that is greater than the existing coverage.
- The client can get unlimited coverage by moving some funds into a deposit coverage reserve, plus paying onchain mining fees and swap fees. The client can get back those funds into their account (after paying onchain mining fees and swap fees, and only if they have available space under the account limit), but loses unlimited coverage and returns to limited coverage.
- If the client has unlimited coverage, then the client can always get the full amount of the account, minus onchain mining fees. Onchain mining fees for forced account closure with unlimited coverage will be larger than with limited coverage, but forced account closure can take a few days or weeks to resolve instead of the 2 months that the limited coverage resolves.
- Under the hood: the limited coverage comes from the “Inversion of Timeout Defaults” addendum. Under “Inversion of Timeout Defaults” scheme, the LSP potentially loses an amount equal to the account limit, plus some additional amount, if it lets the timeout pass without paying for a unilateral exit or supporting an assisted exit. This total amount (which is the account limit plus a share of liquidity-in-stock) is always greater than the account limit at the start of a new SuperScalar, and is the deposit insurance coverage. However, if the current balance becomes greater than the coverage (because the client bought additional inbound liquidity and received funds), the LSP has an incentive to not pay for unilateral exit of the client, as its liability to that client in the timeout default case is smaller than the amount owned by the client in the account. However however, the client can move some funds onchain (the deposit coverage reserve), which the client can use to pay for unilateral exit. In that case, the client can always enforce its account balance by being able to pay for its own unilateral exit, regardless of the timeout default amount they would get. The onchain funds can be returned to the SuperScalar ownership by a simple swap, but returns the client to having limited coverage.
- The deposit insurance is NOT provided by some third-party entity. It is enforced by the client app directly, using the funds shared between LSP and client.
- The existence of an unlimited deposit coverage is a security detail that impacts larger users. In principle, it can be hidden from the user, but as the deposit coverage reserve is an onchain fund, it must be managed with onchain fees in mind, which vary and are always costly, and cannot be easily moved to offchain. In particular, it is protection against the LSP misbehaving, and thus should really not be handled by the LSP (and thus CANNOT be hidden by the LSP in its monthly maintenance fee — we cannot trust the LSP to implement it correctly! By the same token, we cannot use swap-in-potentiam to quickly move the reserve fund from onchain to offchain — swap-in-potentiam assumes the LSP will willingly cooperate in order to immediately be able to spend using the swap-in-potentiam UTXO, and in a scenario where the client has lost trust in the LSP, it is implausible to use that fund to pay for unilateral closure to protect against LSP misbehavior). It has to be implemented completely by the client software, preferably in open-source code with deterministic compilation. FWIW, this only affects larger users; smaller users can live with the default limited deposit insurance coverage; even if the smaller user upgrades their account limit, if the actual balance does not go above the coverage (which is above the limit at the start of the service month) then the user does not need to switch to unlimited insurance coverage, as on the next service month, the limit of the limited insurance coverage will rise above the new account limit.
- In case the LSP refuses to give proper service to
the client, the client can force account closure
regardless of what the LSP does.
Onboarding Flow
When initially installed, the app simply presents an interface to open an account to the LSP. The app may present an interface to select one among multiple LSPs that provide the needed protocols.
The app provides the options below:
- Standard account open
- The account will be opened within 48 hours.
- Express account open
- The account will open immediately, but with a higher fee, and there is a minimum deposit amount.
- Onchain account open
- The account will open as soon as an onchain address deposit gets N confirmations.
For all types of account opening, the app presents the terms and conditions below:
- Monthly maintenance fee: NN satoshis
- The fee may be waived if you maintain an account balance that is at least NN% of the account limit for the entire month.
- Starting account limit: NNNN satoshis
- Account limit upgrade fee: pay NN satoshis to increase your account limit by NNNN satoshis, at any time.
- The fee may be waived if you maintain an account balance that is at least NN% of the account limit for the entire month.
- Pay next maintenance fee on YYYY-MM-DD HH:MM (TZ).
- Your device must have Internet connectivity and this app must have notification permission at this time. The maintenance fee will be deducted from your account balance.
- If you miss the above payment, you can pay on YYYY-MM-DD HH:MM (TZ), YYYY-MM-DD HH:MM (TZ)…
- If you miss all the above payment windows, your account will be closed and funds will be moved onchain, as protected by your deposit insurance.
- Under the hood: paying the monthly maintenance fee is actually moving from an old, dying SuperScalar in the ladder, to the latest SuperScalar. As SuperScalar constructions are made once a day, those are the times at which you can move from the old SuperScalar to the newest SuperScalar. Thus, the device must be online and capable of receiving messages from the LSP, so that the LSP can invite the client to join the newest SuperScalar, and charge the maintenance fee at that point. Joining the newest SuperScalar requires multiple signing sessions with the client, and thus Internet connectivity and enough CPU to sign everything. If the client misses the monthly payment, the LSP gives them additional opportunities to join the next SuperScalar on succeeding days, up to some limit.
- Under the hood: if the user completely misses the given times, the LSP has to evict them via the unilateral close mechanism, which, if we use the Inversion of Timeout Default addendum, is paid for by the LSP.
Standard Account Open
This is the simplest case: the client requests to be scheduled to open an account on the next available slot the LSP has.
The terms and conditions presented are:
- Your account will open on YYYY-MM-DD HH:MM (TZ).
- Your device must have Internet connectivity and this app must have notification permission at this time.
- If you miss the above opening time, you can open at YYYY-MM-DD HH:MM (TZ).
- You cannot receive or send funds until the account opening time that your device has been online for.
- Under the hood: new SuperScalar mechanisms are constructed daily, and the LSP simply schedules the new client to join the next SuperScalar mechanism, and wakes them up at the appropriate time to complete the signing session. If the client does not come online on the first scheduled day, the LSP allows the client to join on the next scheduled day.
The LSP may also require initial deposit, depending on the risks the LSP is willing to take on in its environment. For instance:
- The LSP may require a minimum initial deposit,
without deducting any amount from it, to prevent
trivial DoS attacks where a botnet just spams the
LSP.
- The initial deposit may be done in multiple receives, with sending disabled until the minimum initial deposit is reached.
- The LSP may deduct an initial fee from the initial deposit, again to deter trivial DoS attacks from funded attackers.
- The LSP may waive the above requirements if it can ban an identifiable individual that attempts to DoS the LSP.
How the above are communicated between the app and the LSP are left as an exercise to the reader.
Express Account Open
In this flow, the LSP charges a higher fee for the account opening, but the account is opened immediately.
The terms and conditions for this opening are:
- You must pay a Lightning invoice with at least NNN satoshis, as initial deposit.
- A fee will be deducted from the initial deposit, of NNN satoshis, or N.N% of the amount deposited, whichever is larger.
- Once paid, the account is opened for sending and receiving. Upgrading the account limit will not be immediately available.
- On YYYY-MM-DD HH:MM (TZ) the account limit can be upgraded at your control.
- Your device must have Internet connectivity and this app must have notification permission at this time.
- If you miss the above time to enable upgrades to your account limit, you can enable account limit upgrades on YYYY-MM-DD HH:MM (TZ).
- Under the hood: the client uses a JIT channel flow,
such as LSPS2.
The minimum size is
min_payment_size_msat
of LSPS2, and the fee scheme ismin_fee_msat
andproportional
of LSPS2. Once the LSPS2 invoice is paid, a non-SuperScalar onchain channel is opened. As the cost of adding new inbound liquidity in an onchain channel is higher, the LSP also invites the client to join the next daily SuperScalar construction, and the app presents this as being unable to increase the account limit until after the app moves the user funds from the onchain JIT channel to a SuperScalar. Once the app has moved user funds into SuperScalar, it enables upgrading of the account limit, i.e. purchasing inbound liquidity within SuperScalar.
Onchain Account Open
In this flow, the app provides an onchain address to be funded by the user. Once the onchain address has a UTXO of at least a minimum size, and the transaction with that output has confirmed with sufficient depth, the channel is opened.
As a bonus, under this flow, if the LSP refuses service and blocks account opening, the deposited funds can be refunded, minus onchain mining fees.
The terms and conditions for this flow are:
- You must make at least one deposit to a given
bc1p
(P2TR, “Taproot”, “bech32m”) onchain address, of at least NNNNNN satoshis.- The account is opened for sending and receiving as soon as the onchain send to the given address has N confirmations.
- A mining fee of NNN satoshis will be deducted from the initial deposit.
- The initial account limit is equal to the initial amount deposited, minus the mining fee.
- Upgrading the account limit will not be immediately available.
- On YYYY-MM-DD HH:MM (TZ) the account limit can be upgraded at your control.
- Your device must have Internet connectivity and this app must have notification permission at this time.
- If you miss the above time to enable upgrades to your account limit, you can enable account limit upgrades on YYYY-MM-DD HH:MM (TZ).
- If the LSP refuses to complete account opening, the initial deposit can be refunded to an onchain address you control, minus mining fees, NNN blocks after the deposit confirms.
- Under the hood: This flow uses swap-in-potentiam. Once the swap-in-potentiam address is funded, with the minimum confirmation depth imposed by the LSP, the app can then open a channel using those funds. Providing a plain address maximizes the number of wallets that can deposit to the address, while allowing “instant” channel opening (i.e. no additional confirmations are needed beyond confirming the deposit to the plain swap-in-potentiam address). Once the swap-in-potentiam address has been funded, the client can present it to the LSP and construct an onchain channel with no additional trust. The ability to refund the onchain amount, in case the LSP refuses to accept the channel, is built into the swap-in-potentiam protocol. As the cost of adding new inbound liquidity in an onchain channel is higher, the LSP also invites the client to join the next daily SuperScalar construction, and the app presents this as being unable to increase the account limit until after the app moves the user funds from the onchain swap-in-potentiam channel to a SuperScalar. Once the app has moved user funds into SuperScalar, it enables upgrading of the account limit, i.e. purchasing inbound liquidity within SuperScalar.
Deposit Insurance Coverage Management
By default, the user gets a limited deposit insurance coverage, that is equal to the account limit at the start of a service month, plus some extra margin. For most users, this is sufficient, as they would not be able to receive more than their current account limit anyway.
However, if the user then upgrades their account limit, and receives funds, then the limited deposit insurance coverage may become lower than their actual account balance.
When the user account balance reaches 90% of the limited deposit insurance coverage, the app can remind the user to switch to unlimited deposit insurance coverage.
To enable unlimited deposit insurance coverage, the app has to move some funds to a locked reserve fund that is separate from the account. Mining and swap fees are also charged to move to this locked reserve fund.
The user may withdraw the locked reserve fund at any time, which returns them to limited deposit insurance coverage.
- If the LSP refuses to provide service, or otherwise attempts to freeze or impede sending, receiving, upgrading account limit, or closing your account, you can, at any time, force the closure of your account despite LSP interference and receive your funds in an onchain wallet.
- Fees involved in onchain operations to enforce the closure of your account are paid by you and deducted from your recovered account.
- Onchain operations to enforce closure require a minimum amount. If your account balance is below the minimum amount after fees, force closure will not recover any of your funds, but neither will the LSP be able to retain your funds.
- If possible, make a good-faith effort to contact the LSP at
<whatever@wherever.com>
with your concerns before initiating force closure.- Under limited deposit insurance coverage:
- Force closure can take 1-2 months before you can move your funds to an onchain wallet.
- Enforcement fees paid to miners are lower.
- The coverage is limited; the limit of the coverage is set at the start of a service month, and set to be higher than your account limit at that time, but if you upgrade your account limit to be higher and then receive funds, your account balance can end up higher than the current coverage. In that case, you may recover less than your account balance, and only up to the limited coverage.
- Under unlimited deposit insurance coverage:
- You need to reserve a fund of NNNNN satoshis, separate from (and funded by) your account balance. Creating and withdrawing this reserve fund requires paying mining and swap fees.
- Force closure is expedited and can take 1-2 weeks instead of months.
- Enforcement fees paid to miners are higher (for the expedited closure and to ensure unlimited coverage).
- Your entire account balance is protected, and your reserve fund, minus enforcement fees, will be included in the onchain withdrawal.
- Under the hood: the Inversion of Timeout Default addendum provides the mechanism for the deposit insurance. The addendum has the deposit insurance coverage — actually the branch where the LSP is punished if it does not provide an exit (unilateral or assisted) to clients before the timeout of the tree — of fixed amount at the start of a SuperScalar mechanism. The assumption here is that the client may not have an external UTXO with which to pay exogenous fees for unilateral exit, and must rely on the punishment branch to force the LSP to give it a unilateral exit. By reserving some funds into an onchain address controlled solely by the client, the client can enforce the unilateral exit directly (due to having an external UTXO to pay exogenous fees with), at the cost of having to pay the unilateral exit for itself instead of the LSP paying for it.
Send And Receive Flow
While most Lightning payments resolve quickly, there is a small chance that they take a long time before they can resolve. Thus, like typical Lightning wallets, a SuperScalar-based app has to show outgoing payments as “pending” with the corresponding funds locked until the payment completes.
Upgrade Account Limit Flow
The app may provide an option that authorizes it to automatically upgrade account limit when the account limit is being approached by the account balance.
When an account limit upgrade is requested by the user, LSP quotes some number of satoshis of cost, in order to increase the account limit by some number of satoshis. The user may request an account limit upgrade at any time. The account limit upgrade may take several minutes to an hour to finalize; the user can send and receive normally even while the account limit upgrade is ongoing.
- Under the hood: As noted, this is actually a purchase of inbound liquidity from the LSP.
- Under the hood: The optimistic case is that the LSP
is able to wake up other client apps in order to
authorize a change in state of a sub-tree of the
SuperScalar construction.
However, if interaction with one of the other
clients times out, the LSP can instead fund an
onchain channel with the client, with a timeout
equal to the timeout of the current SuperScalar the
client is on.
(the timeout on the onchain channel can be
implemented as an
nLockTime
d transaction that can spend the funding transaction output) The LSP takes on this risk (i.e. the price it quoted remains the same, thus, the LSP has to factor in the risk that other client apps do not come online fast enough). If the LSP has already opened an onchain channel, and the other clients do not respond fast enough to some request to increase in-SuperScalar capacity, then the LSP can splice into the existing channel. Basically, onchain is used as a fallback in case of coordination problems (i.e. some clients are offline). - Under the hood: While an account upgrade is ongoing, and the in-SuperScalar channel capacity increase is being negotiated by the LSP with other clients, the client and LSP have to maintain two sets of state in the channel: one for the pre-capacity-increase channel, and one for the post-capacity-increase channel. Other clients that are needed to sign off on the capacity change must also maintain two sets of state with their in-SuperScalar channel. This code would be very similar to handling of multiple states in onchain splicing, and is likely to share code with splicing handling. This allows all involved clients to continue sending and receiving as normal while the account limit upgrade is ongoing.
Monthly Maintenance Fee Flow
The monthly maintenance fee is paid by the user once a month. The app should default to being authorized to automatically pay the monthly maintenance, as per the schedule set by the LSP. This implies that the app controls the keys involved in the Lightning channel.
The LSP sets particular times at which the monthly maintenance fee may be paid. The device must have Internet connectivity at those times, and the app must have notification permission at those times. The LSP will automatically awaken the app at those times, at which point the app authorizes the payment of the monthly maintenance fee.
If the user misses the given time, the LSP also gives the user a few more given times, on succeeding days, at which they can pay the monthly maintenance fee.
The app can display the time at which it will be asked to pay the monthly maintenance fee, as well as the grace period the LSP allows.
The process of monthly maintenance is:
- The client pays the monthly maintenance fee to the LSP, who queues them up for completion of monthly maintenance.
- Once the client has paid the fee, the monthly
maintenance proceeds in two phases:
- Common maintenance phase: For several seconds or minutes, up to an hour or two, the LSP repeatedly attempts to create a set of online clients that are able to cooperatively perform maintenance tasks simultaneously while online. During this time, all the online clients can continue to send and receive funds normally, but cannot negotiate an account limit upgrade while this is ongoing.
- Per-client maintenance phase: The client app arranges to complete the monthly maintenance, while still able to send and receive funds normally, as well as negotiate an account limit upgrade.
If a client has paid the monthly maintenance fee, but is not part of the common maintenance phase (e.g. its Internet connectivity is interrupted between paying the fee and completing the common maintenance phase), the LSP will invite the client to complete the common maintenance phase on the succeeding day(s) until the client can complete the common maintenance phase, or until some timeout, at which point the LSP will force closure of the client account and refund the monthly maintenance fee. The client may also force closure of the client account if the LSP refuses to allow the client to complete the common maintenance phase.
The per-client maintenance phase can be done as long as te client is online and the LSP is cooperating. If the LSP or client refuse to complete the per-client maintenance phase, the other side can force closure of the account to recover funds.
- Common maintenance:
- Under the hood: This is the part where the clients and LSP actually construct a new SuperScalar construction, with all funds initially owned by the LSP, but with in-SuperScalar channels having capacity equal to the current account limits of the clients. This requires multiple MuSig2 signing sessions; if some client does not complete the MuSig2 signing sessions quickly enough, the LSP will restart the opening without that client, until it can get a completed SuperScalar opening with the remaining clients all able to complete necessary signatures.
- Per-client maintenance:
- Under the hood: This is just a swap from the
current SuperScalar to the newly-constructed
SuperScalar tree.
If both client and LSP are online and
cooperative, this should be fast and resolve in
seconds.
- Under the hood: After completion of the common maintenance phase, the LSP will forward payments to the client on the new SuperScalar instead of the old SuperScalar.
- Under the hood: Ideally, the client simply sends the entire account balance from the old SuperScalar to the new SuperScalar. However, if the client has pending sends, the client has to maintain the per-client maintenance state until the LSP has either fulfilled or failed the HTLC (i.e. “resolve” the HTLC, meaning it either fulfilled or failed). If the LSP does not resolve the HTLC of the pending send before the old SuperScalar dies, the LSP is forced to unilaterally close the old SuperScalar under the [Inversion of Timeout Defaults] addendum, and the client can force close of the new SuperScalar as well (by refusing to cooperate with the LSP until the LSP is forced to time out, as per Inversion). If the LSP fulfills all pending HTLCs, then the old SuperScalar will not have any client funds and the client can hand over the private key to the old SuperScalar construction (to allow the LSP to recover funds without publishing the complete unilateral exit). If the LSP fails any pending HTLCs, then the amount is returned to the old SuperScalar, but the client app can immediately move the funds to the new SuperScalar.
- Under the hood: The client temporarily has double its account limit while the old and new SuperScalars are still active, but since the old SuperScalar is dying soon, the client needs to strictly enforce its own account limit while doing per-client maintenance. This occurs if the client has any pending HTLCs being sent; the HTLC amount could still be refunded if the HTLC is failed. As a concrete example: suppose the account limit is 10 units, the client has 9 units, and has a pending send of 1 unit. On transferring to the new SuperScalar, the client moves the 9 units to the new SuperScalar, leaving inbound capacity on the new SuperScalar at 1 unit. If the client receives an HTLC on the new SuperScalar of 1 unit, it MUST reject it until the pending send of 1 unit (on the old SuperScalar) has resolved; otherwise, if it fulfills the incoming HTLC and the pending send ultimately fails and is refunded, the client has to fit 11 units of balance in 10 units of limit.
- Under the hood: This is just a swap from the
current SuperScalar to the newly-constructed
SuperScalar tree.
If both client and LSP are online and
cooperative, this should be fast and resolve in
seconds.
Account Closure
Account closure can be assisted by the LSP, or be forced by the client.
Once the client starts either account closure flow, it can no longer send, receive, or upgrade account limit.
The client can only initiate an assisted account closure if there are no pending sends or receives. However, the client (and LSP) can initiate a forced closure at any time, even if there are pending sends or receives. Pending sends and receives during a forced closure can get resolved offchain, but at the worst case will be resolved on the blockchain.
As account closure involves onchain activity, there are practical minimum amounts that can be used post-closure. If the account balance is below the practical onchain minimum amount, then an assisted account closure is not feasible (the client will end up paying their entire balance as onchain fees).
After completion of account closure, the client is in possession of onchain funds. The client can then sweep those funds onto some onchain address or silent pay address, or can use those funds to reopen the account using the “onchain account open” flow.
Assisted Account Closure
In this flow, the client requests the LSP to close the account, and the LSP must accept this request. In case the LSP declines this request or otherwise does not respond to this request, the client app provides an option to force account closure instead.
In the case that the client has absolutely 0 account balance, the account can be trivially closed.
- Under the hood: if the client has 0 account balance, it can trivially hand over the private key used in the current SuperScalar.
The closure requires two phases, both requiring onchain confirmation. The client sets the number of confirmations that it would consider acceptable, though no more than say 12 confirmations.
- LSP cooperation phase.
- Client claim phase.
The details are:
- LSP cooperation phase.
- Before starting the account closure, the client app provides estimates on how much cost the user will pay based on current onchain feerates, with the warning that onchain feerates can change drastically and that the amount paid may become larger later.
- Under the hood: the client offers HTLC(s) of all funds in its account (i.e. inside SuperScalar) to the LSP. The LSP then takes some onchain fund of equivalent value into an onchain HTLC.
- Under the hood: the client indicates its
desired onchain feerate, and is responsible
for paying some of the costs involved.
The LSP agrees if it considers the onchain
feerate reasonable; if it cannot get agreement,
the client can always fall back to forced
account closure.
The client pre-pays for the onchain fees,
deducting from its account balance as soon
as the LSP indicates acceptance.
The client is responsible for paying:
- Transaction cost of the LSP cooperation
phase.
- 1 transaction input (LSP funds).
- 1 transaction output (LSP change).
- 1 transaction output (onchain HTLC).
- Transaction cost of the LSP timeout
recovery.
- 1 transaction input (onchain HTLC, timeout branch).
- 1 transaction output (LSP funds).
- Transaction cost of the LSP cooperation
phase.
- Under the hood: this phase completes once the onchain HTLC address has confirmed to sufficient depth that the client considers safe.
- Client claim phase.
- Under the hood: the client claims the onchain HTLC, revealing the preimage. This is just a 1-input 1-output transaction.
- Under the hood: the client SHOULD use a “burn” strategy with an RBF-able transaction: it can start at what it considers a reasonable fee, but as the onchain HTLC timeout approaches, the client increases the onchain transaction fee, until at the block just before the the timeout it offers the entire amount as onchain fee to miners.
- Under the hood: this phase completes once the 1-input-1-output claim transaction has confirmed to sufficient depth that the client considers safe. On completion of this phase, the client hands over the private key to the SuperScalar it just exited from.
Forced Account Closure
The client or LSP can initiate an account closure at any time.
There are two forms of forced account closure:
- Forced account closure by timeout.
- Forced account closure by publication.
Which kind of force account closure the client actually uses depends on its current mode of deposit insurance coverage:
- If the client currently has limited deposit
insurance (the default), the client forces account
closure by timeout.
- This takes longer, but the cost on the client is lower.
- Otherwise, the client has unlimited deposit
insurance, and the client forces account closure by
publication.
- The cost on the client is higher, but because it does not wait for a timeout, the client can get its funds earlier.
- Under the hood: in this mode, the client has some funds in an onchain address, which can be used to pay for exogenous fees via P2A outputs on the timeout tree nodes.
As account closure requires moving funds onchain, there is a practical minimum account balance before users can actually recover funds onchain. However, even if the user account balance is below this practical minimum, the LSP cannot get that balance in the forced account closure flow, and the balance will instead go to miners.
For details:
- Under the hood: Ultimately both kinds of forced account closure boil down to forced closure by publication. Under Inversion of Timeout Default addendum, forced account closure by timeout simply has the client wait until the impending death of the SuperScalar it is currently in, and then the LSP is forced to publish the unilateral exit (the “forced closure by publication”) onchain, as otherwise the LSP can lose funds that were locked in the SuperScalar.
- Under the hood: Multiple timeouts are involved in any forced account closure; these timeouts are enforced to allow participants to ensure that the latest state is what is resolved onchain. Forced account closure by timeout can take 1-2 months, while forced account closure by client publication will take a few weeks to a month. Note that the forced account closure by timeout is really waiting for the LSP to perform forced account closure by publication, thus the additional worst-case month is due to having to wait up to a month for the current SuperScalar to time out. If the client has unlimited deposit insurance coverage (i.e. has an exogenous UTXO they can use to pay for exogenous fees) then the client can use forced account closure by publication itself, which shortens the time, but also increases the cost of forced account closure.
Post-closure
Once the client has completed a closure (whether assisted or forced), the client app will have some onchain funds that can be swept.