Whether we’re sending emails, physical mail, or following someone on social media, we primarily think in terms of names and faces, and not the respective address or user ID.
Invoices, node IDs and other transaction endpoints in bitcoin and Lightning are highly unintuitive. Abstracting them via a contact list can create a much smoother user experience. There are many payment request formats, each with unique properties and varying levels of maturity and adoption, requiring unique design solutions. This page uses the more approachable term “address”, along with various UI techniques, to abstract these complexities for users.
Let’s go over common user interactions around managing contacts. This will illustrate how such a feature could work, and helps explain the underlying design problems and decisions.
Adding a contact #
The most basic interaction is that a user manually adds a contact by entering their name and an address. This is likely not the most common user flow, as most contacts will be created with incoming payment requests, as illustrated further below. But wallets should generally support manual options, as users may not be able to avoid them.
You may choose to require user verification (like PIN entry) when adding or updating contacts. This reduces the risk that contact information is tampered with and payments are sent to wrong addresses.
Contact editing #
The contacts screen should offer various features for editing and organization.
Importing an address #
This scenario can be initiated by copying a Lightning address to the clipboard, scanning a QR code, or tapping a payment link (see payment entry points). An address is passed into the application and, where it’s recognized and appropriate options are shown to the user. In the example below, the user adds the address as a new contact.
Importing a payment request #
This sequence is similar to the one above. The difference is that a payment request was passed into the application, which contains different data and also includes a specific user action, and therefore requires different user flows. The one below shows how a user has scanned a payment request and assigns a contact to the payment.
Some payment request formats may include an address that can receive repeatedly. In this case, the address is added to the contact for future use. For single use payment requests, only the payment is linked.
Payment requests may also contain recipient names. These can be used to suggest the name for a new contact to the user. Names can be spoofed, so they should not be automatically assigned without user approval.
Note that automating matching of contacts to payment requests is a sensitive matter. If it cannot be based on unspoofable identifiers, then users should have to review and approve the match.
Sending from the home screen #
Initiating a payment can be as simple as entering an amount and tapping a contact that has a re-usable address associated. Otherwise, an extra step is needed to manually enter a destination address.
Adding a contact to an outgoing invoice #
Contacts can also be assigned to invoices that will be paid by others.
Adding a contact to a completed payment #
When browsing the activity screen, users may come across payments they want to assign contacts to. While applications should try to automatically make connections between payments and contacts by matching addresses, this is not possible oftentimes.
A contact card for the wallet owner #
Most contact books include a special card for the user. It is typically shown at the top of the contact list, and used for quick sharing with others. In addition to listing any addresses your wallet provides, you might choose to let users enter external addresses from other wallets for convenience.
Using contacts in context #
Contacts are closely intertwined with sending, requesting, and the activity screen. When designing these user flows, pay close attention to how they connect. The less convenient it is for users to assign contacts, the less likely they are to use this feature and the higher the chance that they are exposed to the complexities of the various payment request formats.
Your application should also try to provide convenient backup for contacts, for example, via automatic cloud backup.
Supporting various payment request formats #
Based on your use case, your application may choose to only support certain payment request formats. It should still recognize all formats, and provide the user with appropriate feedback. You may also choose to add warnings before permitting use of certain formats if there are privacy and security risks the user should be aware of.
Below are different examples of how you can communicate around the type of support your application provides for different formats.
The next section looks at security considerations when designing a daily spending wallet.