Wallet Permission Prompt Liveness Contract
An application asking a wallet for permission gets an error if the person does not answer straight away, which is unfair to anyone who stepped away. This says the request waits for them rather than timing out.
Summary
- Why
- Applications were timing out and failing wallet permission requests simply because a user hadn't answered a prompt yet, treating a normal human decision delay as an error.
- What
- BRC-219 is a contract stating that a wallet request waiting on user permission must stay pending until the user decides, and defines when a wallet is or is not compliant with that expectation.
- How
- A developer builds their app to leave a permission-required wallet request open indefinitely (showing its own waiting UI if needed) instead of applying a timeout, trusting that a compliant wallet is either actively showing the user a prompt or has already returned an error.
What this lets you do
- Leave permission-required requests pending without a timeout
- Distinguish a real wallet error from a normal pending decision
- Rely on mobile wallets to preserve prompts through backgrounding and app switching
- Treat any invisible or lost wallet prompt as a wallet bug, not an app bug
- Skip building custom permission-timeout logic in the app
Written by claude-sonnet-5 from the specification text. Where the two differ, the original is correct.
Reference for an AI
Everything an assistant needs to answer questions about BRC-219 accurately, including what it depends on.
The specification
Abstract
This BRC defines the liveness contract for wallet requests that require user permission. When an application sends a valid wallet request and the wallet requires user consent before responding, the request is allowed to remain pending until the user grants or denies the request. Application developers should treat such pending requests as normal wallet behavior, not as failures to be timed out. Wallets, in turn, must ensure that any permission-dependent pending request is visibly and reliably presented to the user on desktop and mobile.
Motivation
Wallet permissions are a user decision, not a server-side availability problem. A user might read the permission details, compare context, switch apps, take a break, or return several minutes later before deciding. Aborting the request because a timer expired breaks the user experience and forces application developers to handle false failures that should never have existed.
The correct abstraction is simple:
- If a wallet request is pending because user permission is required, the wallet must be asking the user.
- If the wallet is not asking the user, the request must not remain pending for permission.
- If a wallet implementation accepts a permission-dependent request but fails to surface the prompt, that is a wallet bug.
- Applications should not be required to paper over invisible or broken wallet prompts with permission timeouts.
This BRC exists to make that contract explicit across desktop wallets, mobile wallets, embedded wallets, browser wallets, and application developers.
Specification
Definitions
- Application: Software that calls a BSV wallet interface, including web apps, native apps, servers, command-line tools, and background workers.
- Wallet: Software that implements a BSV wallet interface and controls keys, permissions, transactions, baskets, certificates, or related user-owned wallet state.
- Permission-required request: A valid wallet request that the wallet cannot complete until the user grants or denies permission.
- Prompt: The wallet-controlled user interface through which the user grants or denies a permission-required request.
- Pending request: A request for which the application has not yet received a success or error response.
- Interactive wallet: A wallet implementation with a user interface capable of asking the user for permission.
- Non-interactive wallet: A wallet implementation without a user interface capable of asking the user for permission, such as a server-side wallet, daemon, or CI wallet.
Core Contract
When an interactive wallet receives a valid permission-required request, it must either:
- present a prompt to the user and keep the application request pending until the user grants or denies it; or
- immediately return an error indicating that the wallet cannot request the required permission.
An interactive wallet must not accept a permission-required request, fail to present a prompt, and leave the application request pending.
Applications should not impose permission-specific timeouts on wallet requests. A pending permission-required request means the wallet is waiting for the user. The application may show its own waiting state, but it should not abort the wallet request merely because the user has not yet answered.
Wallets and wallet communication substrates must not abort a permission-required request solely because a fixed amount of wall-clock time elapsed. If the wallet remains connected and the permission request is still active, the request may remain pending for as long as the user has not made a decision.
The intended binary is explicit: if a connected wallet request appears to "hang" at the application boundary, the application developer should be able to assume that the wallet is asking the user. If that assumption is false, the wallet is non-compliant.
Prompt Visibility Requirements
If the wallet keeps a permission-required request pending, the prompt must be available to the user.
Desktop wallets must make the prompt visible or attention-requesting through normal desktop affordances. This can include focusing or raising the wallet window, opening a modal within an already visible wallet window, bouncing or highlighting the application icon, or otherwise making it clear that the wallet is asking for a decision.
Mobile wallets must present the prompt through a native or application-level surface appropriate for the platform. This can include an in-app modal, bottom sheet, native alert, foregrounded wallet activity, notification-driven return path, or equivalent platform mechanism.
In all cases, the prompt must identify enough context for the user to make a meaningful decision, including the requesting application or origin where available, the requested capability, and whether the request is one-time, persistent, or renewable where such distinction applies.
Grant and Deny Semantics
When the user grants the request, the wallet must complete the original pending application request with the successful result for the requested wallet method.
When the user denies the request, the wallet must complete the original pending application request with an error indicating that permission was denied.
The wallet must not require the application to poll a separate endpoint, retry the original request, or infer the decision from side effects.
Non-Interactive Wallets
Non-interactive wallets must not hang waiting for permission. Since there is no user prompt surface, a non-interactive wallet must either:
- satisfy the request from existing policy, configuration, or pre-granted authority; or
- reject the request with a clear permission or policy error.
Servers, CI systems, and daemons should therefore have deterministic wallet behavior. Permission-pending liveness is an interactive-wallet concept only.
Requests That Do Not Seek Permission
If a request explicitly indicates that permission should not be sought, the wallet must not open a prompt for that request. If the request cannot be completed under existing permissions, the wallet must return a clear error rather than wait for user action.
If a request is a wallet status, readiness, network, version, or authentication probe, the wallet must not use that request to trigger a permission prompt.
Mobile Continuity
Mobile wallets must preserve permission-required requests across ordinary mobile lifecycle events where the wallet process and request context remain alive. Backgrounding, app switching, screen lock, short suspension, orientation changes, and navigation within the wallet must not cause the application request to hang silently.
After resume, the wallet must either:
- keep the original prompt available;
- restore an equivalent prompt for the same pending request; or
- complete the request with a clear cancellation or lifecycle error if the original request can no longer be represented safely.
A mobile wallet must not lose the prompt while leaving the application request pending.
Disconnections and Process Termination
This BRC does not require wallets to preserve an in-memory request after process termination, device restart, browser tab destruction, transport disconnection, or operating-system termination of the wallet process.
If the request context is lost, the wallet or substrate should fail the request clearly when possible. If the communication channel itself is destroyed, normal transport failure rules apply.
Application Developer Expectations
Application developers should treat a connected wallet request as having three broad outcomes:
- success;
- explicit wallet error, including permission denial; or
- a pending user decision when the wallet requires permission.
Applications should avoid adding custom permission timeout handling. If an application displays a waiting screen, it should explain that the user may need to answer a wallet prompt.
Applications may still use ordinary transport-level failure handling for disconnected sockets, closed browser tabs, process exits, HTTP connection failures, or other conditions where the wallet is no longer connected. These are not permission timeouts.
Wallet Developer Requirements
Wallet developers must treat invisible prompts, lost prompts, unresponsive prompt buttons, hidden prompt windows, unresumable mobile prompts, and pending requests without a visible decision path as wallet defects.
Wallets should test and instrument the full permission lifecycle:
- request accepted;
- prompt rendered or otherwise made available;
- grant or deny selected;
- original request resolved or rejected;
- prompt dismissed and wallet state updated.
The purpose of this instrumentation is wallet correctness, not application exception handling.
Compatibility
This BRC is compatible with existing BSV wallet interfaces. It does not define new wallet methods or change the payload shape of existing request and response messages. It clarifies the expected liveness behavior of permission-required requests.
Wallets that currently apply fixed permission-request timeouts should remove them or limit them only to transport/session failure conditions where the wallet is no longer capable of showing a prompt or receiving a user decision.
Applications that currently abort wallet permission requests after a fixed duration should instead leave the wallet request pending and present user-facing guidance to answer the wallet prompt.
Implementations
Interactive desktop wallets can implement this BRC by making every permission-required request produce a visible wallet prompt and by keeping the original application request open until the user grants or denies it.
Interactive mobile wallets can implement this BRC by binding pending permission requests to durable prompt state that survives normal app foreground/background and navigation lifecycle events.
Non-interactive wallets can implement this BRC by enforcing deterministic policy and rejecting requests that require unavailable user consent.