> For the complete documentation index, see [llms.txt](https://bsv.brc.dev/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://bsv.brc.dev/opinions/0137.md).

# Device-Aware Wallet Onboarding and Fallback Login for BRC-100 Applications

Crumbs (<bitcoinsvradar@gmail.com>)

## Abstract

This document specifies a standardized sign-in experience for applications built on the [BRC-100](/wallet/0100.md) wallet-to-application interface. It defines how an application SHOULD greet an arriving user with a single, coherent login surface organized into four named buckets — **Magic Link**, **Social Login**, **Web3 Login** (multi-chain wallets via WalletConnect plus BSV wallets such as HandCash), and **Metanet Login** (verified self-custody on BRC-100) — so that the user can (a) sign in via whichever method they already trust, (b) be guided, if they choose, to install the *best* BRC-100 wallet for their specific operating system in as few steps as possible, and (c) later migrate any non-Metanet account to Metanet without data loss when self-custody becomes valuable to them.

The compatible-wallet list is not hard-coded into each application. Instead it is resolved at runtime from a **wallet catalog endpoint** keyed by the user's detected operating system, so the recommended wallets stay current without an application redeploy. The catalog defines three ordering modes (rating-ranked, random-from-catalog, and a hardcoded trusted shortlist rendered in random order when no endpoint is configured), so applications can choose between curated endorsement and ecosystem-neutral presentation. Throughout, the protocol itself stays invisible to the user: the specification term "BRC-100" MUST NOT appear in user-facing surfaces, and each bucket is referred to by its plain-language name (see §1). This BRC builds directly on the zero-friction, mobile-first onboarding principles of [BRC-110](/opinions/0110.md) and extends them to a cross-platform, multi-method, multi-chain world where not every user arrives wallet-first — or on BSV at all.

The key words MUST, MUST NOT, SHOULD, SHOULD NOT, and MAY in this document are to be interpreted as described in RFC 2119.

***

## Motivation

BRC-100 gives applications a clean, wallet-agnostic interface to a user's keys. But the interface assumes a wallet is already present. In practice the largest cohort of arriving users has **no BRC-100 wallet at all**, and a second cohort has one but on a platform the application did not anticipate. Today each application solves this independently, producing three recurring failures:

1. **The dead end.** The application calls into a wallet substrate, finds none, and shows a raw error ("No wallet available over any communication substrate"). The user has no idea what to install, for which device, or why. They leave.
2. **The wrong recommendation.** The application links to a single wallet — usually a desktop browser extension — regardless of whether the user is on iOS, Android, Windows, macOS, or Linux. A mobile user is sent to a Chrome extension they cannot install.
3. **The all-or-nothing gate.** The application refuses any access without a BRC-100 wallet, even for actions (browsing, reading, commenting, custodial payments) that do not require self-custody. Users who are not ready to install a wallet are turned away entirely.

Empirical onboarding research is unambiguous that each additional step and each unexplained error materially reduces completion ([NN/g: How to Report Errors in Forms](https://www.nngroup.com/articles/errors-forms-design-guidelines/)), and that progressive disclosure outperforms front-loaded commitment ([NN/g: Progressive Disclosure](https://www.nngroup.com/articles/progressive-disclosure/)). A standard that makes the *correct* device-aware path the *default* path — and that degrades gracefully when the user is not wallet-ready — removes the per-application reinvention and raises completion across the ecosystem.

***

## Specification

A conforming application MUST present sign-in through a single login surface and MUST resolve its wallet recommendations dynamically. The requirements below are organized into eleven subsections.

### 1. Single Login Surface and Bucket Hierarchy

The application MUST expose all authentication options through one surface (a modal, sheet, or page). That surface MUST be organized into FOUR named buckets, presented in this order from lowest-friction to most-self-sovereign:

1. **Magic Link** — passwordless email link.
2. **Social Login** — federated identity providers (e.g. Google, GitHub, Apple).
3. **Web3 Login** — multi-chain wallet sign-in. This bucket combines two families and MUST present them together rather than in separate menus:
   * **BSV wallets that are not (yet) self-custody on BRC-100**, e.g. HandCash and equivalent custodial / partially-custodial BSV wallets;
   * **Non-BSV chain wallets** (Ethereum and EVM L2s, Solana, Bitcoin, Cosmos, TON, etc.) reached via WalletConnect — see §11.
4. **Metanet Login** — verified self-custody sign-in via a BRC-100-compatible wallet (see §6).

The surface MUST NOT require the user to choose self-custody before seeing the lower-friction buckets, and MUST NOT hide the Metanet path behind an unrelated menu. All four buckets MUST resolve to the **same authenticated application session**, so that downstream code is indifferent to which bucket was used (see §9). Users who sign in via any bucket *other than Metanet Login* MUST be able to migrate their account to Metanet later (§10); the migration entry point MUST live in account settings and SHOULD NOT be forced during the first session — the value of self-custody is clearest *after* the user has accrued something worth keeping.

**User-facing terminology.** Protocol-level identifiers MUST NOT appear in any user-facing surface. Specifically, the strings `BRC-100`, `BRC-103`, `BRC-104`, "BRC-42/43", "substrate", "WalletConnect" (in copy describing the user's action — the technology may be cited in a footnote or "powered by" attribution), and similar specification jargon MUST NOT be shown to end users in buttons, labels, headings, tooltips, toasts, or error copy — they are implementation detail. The bucket labels SHOULD use the plain, outcome-oriented names above: **"Magic Link"**, **"Social Login"**, **"Web3 Login"**, **"Metanet Login"**. The verified handshake of §6 MUST be presented to users as "Metanet Login," never as a "BRC-100 challenge" or "substrate connection." Protocol identifiers remain appropriate in developer-facing material — documentation, SDKs, configuration, and logs — but the line between developer surfaces and user surfaces MUST be maintained.

### 2. Device and Operating-System Detection

Before recommending any wallet, the application MUST determine the user's operating system from the client environment, resolving at minimum: `ios`, `android`, `macos`, `windows`, and `linux`. Detection MUST check mobile platforms before desktop ones, because (a) iPadOS reports a desktop-like user agent and (b) Android user agents contain the token `Linux`. When the platform cannot be determined, the application SHOULD fall back to the desktop wallet set, as it is the broadest. Detection MUST run on the client and MUST NOT block the initial render of the login surface.

### 3. Wallet Catalog Resolution

The set of recommended wallets MUST be resolved at runtime from a **wallet catalog endpoint** rather than compiled into the application, so the recommendations can be curated centrally and updated without redeploying every application.

A conforming catalog endpoint MUST accept, at minimum, a wallet-category selector and an operating-system selector, and MUST return ONLY the wallets compatible with that operating system — a wallet that ships no install path for the requested OS (e.g. HODOS Browser or Yours Wallet on Android, today) MUST NOT appear in that OS's response. Each returned entry MUST carry enough information to render an install card and to know whether the wallet speaks BRC-100. The abstract response shape is:

```jsonc
// GET <catalog>?category=wallet&os=<ios|android|macos|windows|linux>
{
  "wallets": [
    {
      "name": "BSV Browser",
      "icon": "https://.../bsv-browser.png",  // square, renders edge-to-edge
      "installUrl": "https://.../install-for-this-os",
      "brc100": true,                          // speaks the BRC-100 substrate
      "custodial": false,                      // self-custody vs custodial
      "rating": 4.6                            // 0–5, used for default ordering
    }
  ]
}
```

The application MUST treat the catalog as the source of truth for *which* wallets to show for the detected OS, and SHOULD cache the result for the duration of the session. The catalog SHOULD be loaded lazily (on demand, when the user needs it) rather than on every page load.

**Ordering policy.** Three modes are defined for the order in which the returned wallets are rendered. A conforming application MUST implement at least the default mode for whichever configuration applies and MUST surface the chosen mode to the integrating developer through the §8 component contract:

1. **Rating-ranked** *(default whenever a catalog endpoint is configured)* — the application MUST render the wallets in the order returned by the catalog. The catalog endpoint is expected to sort by an aggregate community rating (the `rating` field above is informational; the canonical order is the response order). This keeps the "most-loved wallets first" policy controlled by the curator, not by each application.
2. **Random-from-catalog** *(opt-in)* — the integrating developer MAY request that the catalog response be shuffled client-side before rendering. This is appropriate for applications that want to avoid implicit endorsement of any single wallet and instead expose users to the full compatible set without preferential placement. When this mode is selected, the application MUST still discard wallets the catalog filtered out for the detected OS (i.e. randomize *within* the compatible set; never re-introduce incompatible ones).
3. **Hardcoded trusted shortlist, random** *(fallback when NO catalog endpoint is configured)* — the conforming library MUST ship a small, curated shortlist of trusted BRC-100 wallets baked into the source, partitioned by OS, and render them in **random** order. The shortlist MUST be OS-filtered identically to a catalog response (no Android-only suggestions on iOS, etc.) and MUST be small enough to audit at a glance. The random order in this mode is deliberate — it prevents the library's authors from acting as a de-facto ranking authority when the curating endpoint is absent.

In all three modes the §5 "no second card per item / icon fills the card / one-tap install" rendering constraints apply unchanged.

**Reference implementation.** BSV Radar exposes such a catalog. The human-facing listing is:

```
https://bsvradar.com/apps?category=wallet&os=android
```

and the same filtered set is available programmatically (JSON) by querying its app-filter endpoint with the identical parameters, e.g.:

```
https://bsvradar.com/api/apps/filter?category=wallet&os=android
```

Swapping the `os` value (`ios`, `android`, `macos`, `windows`, `linux`) returns the wallets BSV Radar has catalogued as compatible with that platform. Applications MAY point at this endpoint directly or at any catalog that satisfies the contract above.

### 4. The Connect Decision Flow

When the user invokes "Connect a wallet", the application MUST follow a deterministic decision flow that prefers an *already-installed* wallet and only falls back to onboarding when none is reachable:

```
User taps "Connect a wallet"
        │
        ▼
Attempt BRC-100 substrate connection (auto-detect, §6)
        │
   ┌────┴─────────────────────────────┐
   │ substrate present                │ no substrate reachable
   ▼                                   ▼
Verified login (§6)            Detect OS (§2)
   │                                   │
   ▼                                   ▼
Same app session (§9)          Resolve catalog for OS (§3)
                                       │
                                       ▼
                               Show No-Wallet view (§5):
                               device-appropriate install cards
                                       │
                       ┌───────────────┴───────────────┐
                       ▼                                ▼
              User installs a wallet           User backs out to fallbacks (§7)
              and re-opens the app             (social / email / custodial)
              in that wallet's browser                 │
                       │                               ▼
                       ▼                        Same app session (§9)
              Substrate now present → §6
```

The application MUST attempt substrate detection *before* presenting any install recommendation, so that a MetaNet user who already has a wallet is never shown an unnecessary install screen.

### 5. The No-Wallet (Onboarding) View

When no substrate is reachable, the application MUST present an onboarding view, not a raw error. This view:

1. MUST state plainly that no wallet was detected.
2. MUST render only the wallets returned by the catalog for the user's detected OS (§3), as a grid of tappable cards. Each card MUST show the wallet's icon and name and MUST link to that wallet's install location for the user's platform.
3. MUST require as few steps as possible: ideally the path from "no wallet" to "installing a recommended, compatible wallet" is a single tap on a single card.
4. SHOULD communicate the next action after installation. Where a recommended wallet is itself a browser (e.g. a mobile BSV browser), the view MUST tell the user that they will need to re-open the application *inside the wallet's browser* for the substrate to become available — because a wallet installed as a separate app is not reachable from the user's current browser.
5. MUST NOT strand the user: the onboarding view MUST allow the user to return to the fallback methods (§7) so that declining to install a wallet does not end the session.

### 6. Connecting an Existing BRC-100 Wallet

For users who already have a wallet, the application MUST connect over the BRC-100 substrate using automatic substrate selection, and MUST perform a **verified** login rather than merely reading a claimed identity key. A bare identity key proves nothing — anyone can assert any key — so the application MUST run a challenge–response:

1. The application reads the user's identity public key from the wallet.
2. The server issues a single-use, short-lived nonce bound to that identity key.
3. The wallet signs the nonce. The signature MUST be produced so that it is **publicly verifiable** (i.e. derived for the "anyone" counterparty), because a signature scoped to the signer alone cannot be verified server-side.
4. The server verifies the BRC-42/43-derived signature against the identity key, marks the nonce consumed, and only then establishes the session.

This handshake aligns with the mutual-authentication model of the [BRC-103](/peer-to-peer/0103.md) / [BRC-104](/peer-to-peer/0104.md) family; applications MAY instead use that family's transport directly where available. Protocol identifiers used in the signature MUST satisfy the wallet's constraints (BRC-43 requires protocol names of at least five characters) and MUST be identical on the signing and verifying sides.

### 7. Fallback Login Buckets and Graceful Degradation

The application MUST offer at least one non-Metanet login method so that a user who will not (yet) install a self-custody BRC-100 wallet can still use the application. The three non-Metanet buckets of §1 — **Magic Link**, **Social Login**, and **Web3 Login** — are the conforming fallbacks. The Web3 Login bucket combines two families that MUST be presented together: BSV wallets that are not (yet) self-custody on BRC-100 (e.g. HandCash) *and* non-BSV chain wallets reached via WalletConnect (§11). The application:

1. MUST grant fallback users access to every feature that does not strictly require self-custody (browsing, reading, social actions, and — where a custodial provider is connected — custodial payments).
2. MUST clearly mark features that genuinely require a self-custody BRC-100 wallet, and SHOULD offer an in-context upgrade path to connect one later rather than blocking outright.
3. MUST treat a custodial wallet whose authentication token is itself a private key (such as HandCash Connect) as a server-side secret: such a token MUST be held only in an `httpOnly` cookie or equivalent and MUST NOT be persisted in a database or exposed to client scripts.
4. SHOULD allow a user authenticated by one method to later associate an additional method (including a verified BRC-100 identity) with the same account, surfacing each connected method as a distinct verified credential. The full upgrade from a fallback account to a self-custody account is specified in §10.

### 8. Standardized Login Component Contract

To make the above available to application developers "out of the box," this BRC defines an abstract contract that a reusable login component SHOULD implement. The contract hides substrate detection, OS detection, catalog resolution, and fallback wiring behind a single entry point so that an integrating developer gets correct behavior by default:

```ts
interface WalletOnboardingConfig {
  // Wallet catalog endpoint (§3). When omitted the library falls back
  // to its hardcoded trusted shortlist, rendered in random order.
  catalogUrl?: (os: Platform) => string
  // Ordering policy for the catalog response (§3). Defaults to "rating"
  // when a catalogUrl is configured, and to "random" (with the
  // hardcoded shortlist) when it is not.
  walletOrdering?: "rating" | "random"

  // Verified Metanet login (§6): returns a session on success.
  verifyWallet: (identityKey: string) => Promise<Session>

  // The Magic Link bucket (§1, §7). Omit to disable.
  magicLink?: { send: (email: string) => Promise<Session> }
  // The Social Login bucket (§1, §7), in display order. The first is the
  // recommended "primary" provider.
  social?: SocialProvider[]           // e.g. ["google", "github", "apple"]

  // The Web3 Login bucket (§1, §7, §11) — BSV custodial wallets PLUS
  // non-BSV chain wallets via WalletConnect, presented together.
  web3?: {
    // BSV wallets that aren't self-custody on BRC-100 (e.g. HandCash).
    bsv?: BsvCustodialProvider[]
    // Non-BSV multi-chain wallets via WalletConnect (§11). When set,
    // the library renders the WalletConnect picker alongside the BSV
    // entries in the same Web3 bucket.
    walletConnect?: {
      projectId: string                // WalletConnect Cloud project ID
      chains?: Caip2[]                 // e.g. ["eip155:1", "solana:…"]
      // Optional namespaces override (advanced; defaults to a sensible
      // multi-chain set covering Ethereum + EVM L2s, Solana, Bitcoin,
      // Cosmos, and TON — see §11).
      namespaces?: WalletConnectNamespaces
    }
  }

  // Optional: features gated on Metanet self-custody, for graceful
  // degradation (§7.2). All non-Metanet buckets get the same baseline
  // access; only these features prompt for migration (§10).
  selfCustodyFeatures?: string[]
}

type Platform = "ios" | "android" | "macos" | "windows" | "linux"

// A single call drives the §4 decision flow end to end.
declare function connect(config: WalletOnboardingConfig): Promise<Session>

// Account migration (§10): available once the user is signed in via any
// non-Metanet bucket (Magic Link, Social Login, or Web3 Login) and has
// no verified Metanet identity linked yet. Drives the §6 connection,
// links the identity to the existing account, ports the data, and
// optionally erases the email/PII.
declare function migrateToMetanet(opts: { requestEmailRemoval: boolean }): Promise<{
  identityKey: string
  piiRemoved: boolean
}>
```

A conforming component MUST, given only this configuration: detect the OS, attempt substrate connection first, perform verified login when a wallet is present, resolve and render the device-appropriate onboarding grid when it is not, and expose the configured fallbacks throughout. The component MUST degrade safely if the catalog endpoint is unreachable — it MUST still offer the fallback methods rather than presenting a dead end.

### 9. Feature Disclosure and Session Continuity

Regardless of method, every successful login MUST resolve to one application session of the same shape, so application code never branches on "how did this user log in." The login surface SHOULD briefly communicate the value of holding keys on-chain (self-custody, portability across BRC-100 applications, resistance to deplatforming), consistent with the value-communication guidance of [BRC-110](/opinions/0110.md), but MUST NOT make that disclosure a barrier to completing a fallback login. When a fallback user later connects a verified wallet (§7.4), the application SHOULD preserve their existing data and identity rather than creating a parallel account; the migration that performs this upgrade is specified in §10.

### 10. Account Migration to Metanet (Solving the Chicken-and-Egg Problem)

BRC-100 applications want their users in self-custody, but requiring a wallet *before* first use excludes the majority of arrivals and creates a chicken-and-egg deadlock: a user will not install a wallet for an application they have not tried, and cannot try the application without a wallet. The three non-Metanet buckets of §1 / §7 (Magic Link, Social Login, Web3 Login) break the deadlock on entry — the user joins with a method they already have. This section breaks the *other* half: it specifies how an account created via any of those buckets is later upgraded, **without data loss**, into a Metanet (self-custody, BRC-100) account. The user thus onboards friction-free, accrues real value in the application, and then graduates to self-custody on their own timeline — by which point installing a wallet has obvious, concrete benefit rather than being an unexplained upfront tax.

**Entry point.** An application that supports migration MUST expose the control in account settings, available to any user who is signed in via **any of the three non-Metanet buckets** (Magic Link, Social Login, or Web3 Login) and does not yet have a verified Metanet identity linked. The control MUST live in account settings — not in the first-session login flow — and SHOULD be labelled **"Migrate to Metanet"** or **"Migrate Account to Metanet"** (consistent with the user-facing terminology rule of §1 — it MUST NOT be labelled "Link BRC-100 identity," "Link wallet to my account," or similar protocol jargon).

**Migration sequence.** On invocation the application MUST:

1. Keep the user signed in via their existing method while the migration runs, so the account being upgraded is unambiguous.
2. Run the verified BRC-100 connection of §6 — installing a wallet first via §3–§5 if the user has none. This is where the chicken-and-egg problem is resolved in practice: the user already has an account, data, and history, so connecting a wallet now carries them forward rather than starting from zero.
3. On successful verification, **link** the verified identity key to the *existing* account record. The application MUST NOT create a new, parallel account; all of the user's data, history, reputation, relationships, and balances MUST remain attached to the same account.
4. Re-home the user's data into the self-custody model: the data MUST become associated with the user's identity key, and any data the user is entitled to hold themselves SHOULD be re-keyed so that it is encrypted to and/or signed by that identity, consistent with the relevant BRC data-storage conventions, so that the *user* — not the application operator — becomes the root of authority over it.
5. Guarantee that, after migration, the user can sign in with the wallet alone and reach the same account and the same data, with no dependence on the original fallback method.

**Email / PII removal (opt-in).** Because wallet authentication no longer requires an email address, migration MUST give the user explicit control over the personal data collected solely for the fallback method:

1. During or immediately after migration the application MUST present an explicit opt-in to remove the user's email address (and any other PII collected only to support the fallback method) from the application.
2. The opt-in MUST default to *off*. The application MUST NOT delete any PII silently or as an unavoidable side effect of migrating.
3. The application MUST NOT make email removal a precondition of migration. A user MAY migrate to self-custody and retain their email (for example, to keep receiving email notifications).
4. If the user opts in, the application MUST erase or irreversibly anonymize that PII once migration is confirmed complete, retaining it no longer than any legally mandated window, and MUST surface the consequence before erasing — chiefly that, with the email removed, the wallet becomes the sole means of access and recovery.
5. The application SHOULD confirm that the user has backed up their wallet before erasing recovery PII, and SHOULD warn that this step is not reversible.

Migration is a one-way upgrade in spirit: once an account is in self-custody with PII removed, the application holds no fallback credential to fall back to, which is the intended end state. Applications MAY continue to allow additional verified credentials to be associated with the account (§7.4) after migration.

### 11. Web3 Login via WalletConnect (Multi-Chain)

The Web3 Login bucket of §1 / §7 is designed so that a user who already holds a wallet on *any* mainstream chain can sign in without first switching ecosystems. This is achieved by bundling [WalletConnect](https://docs.walletconnect.network/) as the multi-chain transport. WalletConnect is a chain-agnostic session protocol ([CAIP-25](https://chainagnostic.org/CAIPs/caip-25) / [CAIP-2](https://chainagnostic.org/CAIPs/caip-2) namespaces) that lets the application open a single connection request that the user can satisfy with whichever WalletConnect-compatible wallet they already have installed.

**What you get out of the box.** A conforming implementation of this section MUST cover, at minimum, the five most-trafficked ecosystem families that WalletConnect already exposes — no per-chain manual integration required:

1. **Ethereum and EVM L2s** — Ethereum mainnet, Polygon, Base, Arbitrum, Optimism, BNB Chain. Wallets: MetaMask, Coinbase Wallet, Trust Wallet, Rainbow, and any other WalletConnect-compatible EVM wallet.
2. **Solana** — Phantom, Solflare.
3. **Bitcoin (BTC)** — Xverse, Leather, and other BTC wallets that ship WalletConnect support.
4. **Cosmos** (and IBC chains) — Keplr.
5. **TON** (The Open Network) — Tonkeeper.

The set above is the minimum; the conforming component SHOULD also expose any additional namespaces WalletConnect's project supports at the time of integration, since adding chains is a configuration change rather than new code.

**Presentation.** The Web3 Login bucket MUST render BSV custodial wallets (e.g. HandCash) **alongside** the WalletConnect entry point in a single bucket, not in a separate menu. To the user, the choice is "I have a wallet — sign me in"; the BRC-100 / Metanet path is a *separate* bucket (Metanet Login), and the per-chain distinction is made *inside* WalletConnect's own wallet picker rather than by the host application. This presentation contract MUST hold regardless of the §3 ordering policy.

**Connection flow.** A WalletConnect Web3 Login MUST end in the same authenticated application session as every other bucket (§9):

1. The application opens a WalletConnect session request for the configured namespaces (see the §8 interface).
2. The user satisfies the request from their existing wallet on any supported chain.
3. On approval, the application receives the account address(es) and a session key.
4. The application MUST verify control of the connecting account before establishing the session — typically by issuing a SIWE-style (or chain-equivalent) message via WalletConnect's `personal_sign` / `signMessage` flow against a single-use nonce, and verifying the signature server-side against the returned address.
5. The application upserts the user keyed by `(chainNamespace, address)` ([CAIP-10](https://chainagnostic.org/CAIPs/caip-10)), opens a session, and surfaces it through the same bridge used elsewhere.

**Access tier.** Web3 Login users MUST receive the **same baseline access** as Magic Link and Social Login users (§7.1). Web3 Login is *not* Metanet self-custody on BSV; the connecting wallet may be on a chain that cannot satisfy the application's BRC-100-gated features. Such features MUST be marked per §7.2 and the user MUST be offered the §10 migration path to Metanet.

**Migration parity.** A user who signs in via Web3 Login MUST be able to migrate to Metanet exactly as a Magic Link or Social Login user does (§10) — installing a BRC-100 wallet per §3–§5, linking the verified identity to the existing account, optionally erasing the email/PII collected for the WalletConnect address (typically none, beyond the address itself). The fact that the user had *some* wallet on another chain does not exempt them from the migration UX, nor does it short-circuit it.

***

## Implementations

* **BSV Radar** ([bsvradar.com](https://bsvradar.com)) implements the full flow: a single sign-in surface with Google/GitHub as primary/secondary methods, a "Connect a wallet" path offering BRC-100 wallets (BSV Browser, Metanet Explorer) and the custodial HandCash, BRC-100 verified login via a nonce challenge, and an OS-aware no-wallet grid whose cards are resolved from its own wallet catalog (`/apps?category=wallet&os=<os>`). HandCash's authToken is kept only in an `httpOnly` cookie; wallet identities are verified server-side.
* **Wallet catalog** — any directory that exposes wallets filterable by `category=wallet` and `os=<platform>` and returns per-OS install links and BRC-100/custodial flags can serve as the catalog of §3. BSV Radar's app-filter endpoint is one such implementation.

***

## References

* [BRC-100: Wallet-to-Application Interface](/wallet/0100.md)
* [BRC-103: Peer-to-Peer Mutual Authentication and Certificate Exchange](/peer-to-peer/0103.md)
* [BRC-104: HTTP Transport for BRC-103 Mutual Authentication](/peer-to-peer/0104.md)
* [BRC-110: Zero-Friction, Mobile-First Onboarding for MetaNet-Enabled Apps](/opinions/0110.md)
* [WalletConnect documentation](https://docs.walletconnect.network/)
* [CAIP-2: Blockchain ID Specification](https://chainagnostic.org/CAIPs/caip-2)
* [CAIP-10: Account ID Specification](https://chainagnostic.org/CAIPs/caip-10)
* [CAIP-25: JSON-RPC Provider Authorization](https://chainagnostic.org/CAIPs/caip-25)
* [NN/g: Progressive Disclosure](https://www.nngroup.com/articles/progressive-disclosure/)
* [NN/g: How to Report Errors in Forms](https://www.nngroup.com/articles/errors-forms-design-guidelines/)
* [NN/g: The Paradox of Choice in User Interfaces](https://www.nngroup.com/articles/too-many-options/)
* [Baymard Institute: Checkout Usability](https://baymard.com/research/checkout-usability)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://bsv.brc.dev/opinions/0137.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
