# Shared patterns for BSV interfaces

Patterns every BSV flow needs the same way. Each section summarises a guide page and links to it; where the guide gives exact words, they are used here.

## Payment states

Four states for a payment handed from one wallet to another, plus one for money arriving at a plain address. Acceptance is the main event; mining completes it quietly.

| State | What happened | Label |
|---|---|---|
| Accepted by the recipient | Their wallet verified and accepted it | **Paid** or **Received** |
| Broadcast, not yet mined | Miners have it; the first-seen rule applies | **Settling**, only for amounts large enough to matter |
| Mined | In a block, with a merkle proof | **Complete**, quietly |
| Failed | Rejected, or a conflicting spend was seen first | **Failed**, with a plain reason |
| Incoming at a plain address | Watching the chain, no handover | **Incoming** until mined |

- NEVER show a confirmation counter for an everyday payment. It tells the user your "Paid" was provisional.
- NEVER show "Sending" for something that has not been sent, such as a shared payment waiting for a signature.
- In the SDK: with `acceptDelayedBroadcast: false`, failures arrive as `WERR_REVIEW_ACTIONS`, whose `reviewActionResults[].status` is `doubleSpend` or `invalidTx` (failed) or `serviceError` (not failed: queued, and the wallet retries).

_Source: [Activity](https://www.bitcoinsv.design/guide/daily-spending-wallet/activity/)_

## Loading labels

Say what is happening, in the user's terms, and name the person where there is one. An unlabelled spinner reads as "something is wrong".

| What is happening | What to say |
|---|---|
| Resolving a typed handle | **Finding Anna…** |
| The wallet's own prompt is open | **Waiting for your wallet…** |
| Handing the payment over | **Handing payment to Anna's wallet…** |
| The recipient's wallet accepted it | **Paid** |

- NEVER use a full-screen loader for a step that takes a second, or a spinner with no words.

_Source: [Sending](https://www.bitcoinsv.design/guide/daily-spending-wallet/sending/)_

## Errors

Plain words on top, the code underneath for support. Above all, say whether money moved. It usually did not, and that is what the user wants to know first.

| What happened | Signal | What to say |
|---|---|---|
| User cancelled in their wallet | The wallet call rejects | "You cancelled the payment. Nothing was sent." Return to the review screen with everything filled in. |
| Not enough money | `WERR_INSUFFICIENT_FUNDS` | The shortfall, from `moreSatoshisNeeded`: "You need 1,200 more sats." |
| Same money spent elsewhere first | `reviewActionResults[].status` is `doubleSpend` | This payment did not go through and nothing left the wallet for it. Suggest checking recent activity. |
| Rejected | `invalidTx` | The reason in a sentence, and that nothing was sent. |
| Network unreachable | `serviceError`: the wallet queued it and will retry | Not a failure yet. Show it as waiting to go through, and do not invite the user to pay again. |
| Handle does not resolve | Lookup fails | Which part failed: no such handle, domain unreachable, or certificate did not check out. |
| Recipient cannot take a peer-to-peer payment | Only a plain address is offered | It can still go, with weaker confirmation. Say so rather than downgrading silently. |

- NEVER put an error code in the headline.

_Source: [Sending](https://www.bitcoinsv.design/guide/daily-spending-wallet/sending/)_

## Amounts

- Satoshis are the unit. Write them in words and group the digits for the reader's locale: **12,500 sats**.
- One unit per screen, with local currency beside or above it, labelled as an estimate where it is one.
- NEVER show long decimals ("0.00012500 BSV"), a satoshi glyph, an abbreviation ("12.5k") or an ellipsis inside a number.
- Say **Bitcoin SV** or **BSV** on screen, never "bitcoin" alone, and label address fields **BSV address**.

_Source: [Amounts and units](https://www.bitcoinsv.design/guide/patterns/amounts-and-units/)_

## Who is on the other end

- Show the person: profile name and avatar first, the handle smaller beneath. The handle is resolved before the confirm button, and the resolution is the check.
- The identity key is what the wallet checks, not what the user reads. Keep it in the details, and when a saved contact's key changes, say so and make the user acknowledge it before paying.
- NEVER show a derived payment address in the main flow. It is a one-time internal value.

_Source: [Sending](https://www.bitcoinsv.design/guide/daily-spending-wallet/sending/)_

## Fees

- NEVER show a fee picker, a fee estimate, a "high fees" warning, fee bumping or a stuck-transaction state. A fee is less than 1p and is not a decision.
- Leave the fee off the review screen for ordinary payments and put it in the transaction details. If it is shown, show it in local currency: "Fee: less than 1p".
- Consider paying it on the user's behalf and never mentioning it.

_Source: [Send fees](https://www.bitcoinsv.design/guide/daily-spending-wallet/sending/send-fees/)_

## Before anything irreversible

- Let the weight of a confirmation follow its consequence: whether it can be undone, the amount against what the wallet holds, whether the recipient is new, whether it grants something that keeps working.
- Say what cannot be undone before the button, not after.
- NEVER use one confirmation style for everything. People learn its shape within a week and stop reading it.

_Source: [Getting to know your users](https://www.bitcoinsv.design/guide/designing-products/getting-to-know-your-users/)_
