Estimated reading time: More than 10 minutes
Signing transactions is the core function of Ledger’s hardware wallets, and it’s a core function of your app. This section presents the fundamentals of transactions and the user experience that is expected for clear signing.
Transaction or message?
Throughout these guidelines and the Ledger documentation, you’ll find references to signing “transactions” and “messages”. Here’s the difference between the two.
A transaction is an operation that affects the state of a blockchain. For example:
- a Bitcoin send;
- an NFT transfer on Ethereum or Polygon.
A message is arbitrary data that can be signed, but that is typically not broadcasted. For example:
- a wallet connection message (public key sharing);
- an authentication to access a service, eg. Opensea;
- a non-parsable payload.
Of course, this is not a strict definition and there are instances of transactions that don’t move funds or messages that do affect the state of a blockchain.
Communicating this difference to your users through your transaction flows brings clarity and reassurance. This chapter focuses on the clear signing of transactions.
Anatomy of a transaction
All transactions must respect the following structure. The single and double arrows represent user navigation within this structure.
Each of these parts are presented in the following sections:
- loading the transaction data;
- presenting context with the transaction prompt;
- reviewing the transaction data;
- signing the transaction;
- and rejecting the transaction.
Loading transaction data
Most transactions and messages should feel instantaneous to load for users.
However, in some cases, the processing and data fetching durations might be noticeable. In these cases, use the standard loader for Ledger Stax. As a rule of thumb, you can present the loader if the loading duration is 1 second or greater.
If the operation type (transaction or message) can be determined in advance, use this in the loading message. Otherwise, use the generic term “operation”.
If the loading duration can be calculated, use a progress bar instead.
Presenting context with the transaction prompt
Once the transaction is ready for review, the user is shown the transaction prompt.
The transaction prompt attracts the user’s attention to Ledger Stax, since it was probably elsewhere while preparing the transaction over a mobile or desktop wallet. Ledger Stax plays a sound to attract the user’s attention (it can be turned off in the OS settings).
The transaction prompt presents the context of the transaction and reassures the user that they’re about to sign the type of operation they asked for. It acts both as an informational step and a safety net, because users can reject the operation as soon as the prompt is displayed, without even reviewing the fields.
The transaction prompt should show:
- the operation type: transaction or message;
- the transaction type: send, delegate, generic signing…;
- the blockchain and/or the network on which the transaction will occur, as well as a pictogram representing this information.
As you can see in the last example above, a generic message that was not fully parsed by the app for clear signing cannot show a rich transaction prompt. Read more on generic message signing in chapter 5.
The prompt sentence must start with “Review”. It is built either:
- dynamically, composing the transaction type and other key informations;
- or statically, by making a legible sentence with the available information for every transaction type.
Presenting transaction fields for review
When the user continues from the transaction prompt, they’re ready to review the transaction data—also called “fields”. These are the key informations that users need you review, and this is what makes clear signing.
The fields are always structured in th same way: rows of key-value pairs.
Always use the bigger font presented above for legibility. Clear-signing a transaction means carefully reviewing all fields, so make your app legible for a wide number of users.
The bars at the top represent the number of pages needed to display the transaction data.Because the signing page counts in this total, the number of bars is equal to the number of field pages plus 1.
Users must be able to navigate back and forth through the transaction fields, by:
- tapping anywhere on the screen to move forward;
- tapping on the back arrow in the top-left to move backwards.
The following example shows the 2 pages of transaction data that correspond to an NFT transfer on Ethereum. The third page would be the signing page, presented in the next section.
Common fields must have very consistent naming, for users to feel familiar across all Ledger Stax apps. For example:
- Prefer “To” over the generic “Address” to distinguish sender and receiver;
- Use “Amount” and “Fees” or “Max fees” consistently.
Signing the transaction
The signing page is always the last one because it ensures that your users went through all the critical fields they needed to review. This page corresponds to the rightmost bar in the navigation stepper.
The transaction summary must present the same data as the transaction prompt, to bring up the context during signing: operation type, blockchain or network, icon, etc. Add any piece of important context you need to communicate to your users right when they sign.
Confirming a transaction always uses the same press-and-hold gesture on the dedicated area of the screen: “Hold to sign”.
Use the default naming for elements of this screen to ensure a coherent experience for users throughout Ledger Stax apps:
- Reuse the information from the transaction prompt;
- Always use the verb “sign” in conjunction with the “transaction” or “message” terms;
- “Hold to sign” and “Reject transaction” must always be used.
As the user holds in the signing area, the black bar moves to indicate progress. After around 2 seconds, the transaction is signed and the user receives a success notification accompanied by a sound.
Giving too much context in the signing area, such as “Hold to send” or “Hold to stake”, would be misleading because your app cannot guarantee that the signed payload reached your user’s phone and was broadcasted.
The notification dismisses automatically after a few seconds, and the user is back on your app’s home screen.
Rejecting a transaction is a safety action that must be accessible at all times. Thus, this action always sits at the bottom of every screen, from the transaction prompt to the signing step. The action has a consistent naming convention to be reliably found.
When users tap on “Reject transaction”, a confirmation modal asks them to confirm. This is to prevent accidental touches.
Upon rejection, a notification confirms their action before leading them back to your app’s home screen.
Upon tapping “Go back to transaction”, the user must navigate back to the transaction page they were currently viewing.
- Use the default transaction structure and allow users to navigate freely within it.
- Use the default signing gesture and wording to make the experience delightful and consistent across all Ledger Stax apps.
- Use clear wording in the transaction prompt and the transaction summary to help users anticipate what they’re about to sign.
- Provide clear feedback during processing and loading times.