Lightning at CardCoins: Lessons Learned & Announcing Support for Lightning Address
It was only six months ago that we announced support for the Lightning Network. It has been an exciting journey. Not without its hiccups, we’ve learned quite a bit–not only about the Lightning Network, but we’ve also gained new insights into our internal systems, what assumptions they were built on and how those assumptions would ultimately inform our approach to integrating the Lightning Network into our codebase.
When we first began building the CardCoins platform, the Lightning Network was still just a whitepaper. While we look back on that exploratory phase of early research fondly, it wasn’t actively considered in our architectural design processes. Consequently, we constructed our platform with the assumption that any additional coins/protocols we might add would generally work in the same way that on-chain Bitcoin operates: the payee provides a public key/address to the payer, who can asynchronously sign and broadcast a transaction.
More specifically, our API and internal state management engine requires a user to submit a wallet address before we have locked in a price for their order (as they have not yet completed their order requirements). Address submission may thus occur anywhere from a few minutes to a few hours before the user’s order is approved. This presents two issues in the context of the Lightning Network: one with invoice generation and another with payment delivery.
While a payee can provide to their payer a one-time-use invoice at any time, the invoices have an expiration and generally include an amount. Unless we were to make non-trivial modifications to our codebase, CardCoins would require a zero-amount invoice (which are made safe by the inclusion of a payment_secret) with a long-lived expiration. While the lightning BOLT specification fundamentally allows wallets to generate such invoices, not all wallets default to or support the functionality.
The second issue we ran up against is related to actual payment delivery. After observing six months of lightning orders, it has become clear that the majority of our lightning users are on mobile devices. While some of our customers use custodial services (e.g. Wallet of Satoshi), many do not. For those users who use non or semi-custodial lightning wallets, they must be online to receive payments. Because they provided to us an invoice at some point prior to order approval, their wallet may be offline at time of payment.
As it relates to the first issue, we opted for restricting invoice submission to those with zero-amounts. In the instances where the invoices expired or were unroutable, we would manually request new invoices from our users. After gathering data about these payment failures and surveying support for zero-amount invoices, we decided to focus our efforts on supporting LNURL, a standardized set of HTTP-based communication protocols that allow users to coordinate the out-of-band generation and exchange of invoices. For example, with LNURL-PAY, instead of providing to a service an invoice, the user provides a bech32 encoded HTTPs URL that can be used to request from the user an invoice at any time.
Because passing around invoices and LNURLs is not the most user friendly, we’ve decided to add support for Lightning Address, a protocol which enables users to provide to us an email-like address which we can use to transparently request an invoice from the user’s wallet with LNURL-PAY. It’s a clean, user-friendly gateway/resolver for a LNURL-aware lightning wallet! As for our treatment of such addresses or invoices, at CardCoins we don’t believe that lightning payouts should be considered a “separate” option from on-chain Bitcoin. Users can paste in a Bitcoin address (we support all modern formats), lightning invoice or Lightning Address all into the same field. No additional user flows or selections required.
For our users with always-on, Lightning Address compatible wallets (whether custodial or non-custodial), our two primary issues are immediately solved! For those users who do not support that (or similar) functionality, we plan to enable invoice submission after order approval. This will increase the likelihood that a user’s wallet is online when we attempt to deliver payment. We also look forward to solutions like the one Matt Corallo proposed which provides the ability for an offline user to outsource payment receipt to a Lightning Service Provider in a non-custodial way.
Besides the issue with offline receiving nodes, most of our routing failures were cleared up once we opened direct channels with some of the popular wallet services we had difficulty delivering payments through/to. And because the CardCoins service only pushes payments out, we haven’t had a strong need to lease or request inbound liquidity from our peers.
Overall, we are excited to continue supporting the Lightning Network as a payout method for our users. Supporting Lighting Address was painless, and we look forward to incorporating other standards that make interacting with the Lightning Network a more user friendly experience for our users (e.g. BOLT12). With all that said, we want to thank all those who help support the Lightning Network. Whether you implement or make proposals to the BOLT spec, write or test wallet software, build tools for lightning users or provide any sort of contributions to the space, thank you.