# Build with Client and Explorer

Canonical: https://docs.projectbabbage.com/docs/metanet-client/developers

Connect a web app through WalletClient from @bsv/sdk, verify version/network without spending, and handle permissions across desktop and mobile.

Connect a browser application to **Client 0.8.11** on desktop or **Explorer 1.2.1** on mobile using the BRC-100 `WalletClient` API. This guide was checked October 26, 2026. Client 0.8.11 ships with SDK 3.2.1; the example below uses that published version as a reproducible baseline, not a claim that every wallet bundles the same SDK.

## Make a connection without spending

In an existing TypeScript web project:

```bash
npm install @bsv/sdk@3.2.1
```

Add a button and a status element to your page:

```html
<button id="connect-wallet" type="button">Connect wallet</button>
<p id="wallet-status" role="status" aria-live="polite"></p>
```

Then run this code in your browser application's entry module:

```ts
import { WalletClient } from '@bsv/sdk'

const wallet = new WalletClient('auto')
const button = document.querySelector<HTMLButtonElement>('#connect-wallet')!
const status = document.querySelector<HTMLElement>('#wallet-status')!

button.addEventListener('click', async () => {
  button.disabled = true
  status.textContent = 'Waiting for your wallet. Check its window or prompt.'
  try {
    await wallet.waitForAuthentication()
    const [{ version }, { network }] = await Promise.all([
      wallet.getVersion({}),
      wallet.getNetwork({})
    ])
    status.textContent = `Connected: ${version} on ${network}`
  } catch {
    status.textContent = 'Connection did not complete. Open your wallet, check any prompt, then try again.'
  } finally {
    button.disabled = false
  }
})
```

**Expected result:** the page reports the responding wallet version and network. No `createAction`, payment or private-key export is involved. Authentication still requires the user's wallet session; transport discovery is not user consent.

On desktop, serve the project on localhost with Client running and unlocked. On mobile, deploy the page to an HTTPS URL reachable from the phone and open it inside Explorer. `localhost` on the phone refers to the phone, not your development computer. Test production origins as well as development origins because permissions are scoped to the requesting app.

## Request identity only when the feature needs it

After a user chooses a feature that needs their public identity:

```ts
const { publicKey } = await wallet.getPublicKey({ identityKey: true })
```

Explain why it is needed and handle rejection. A returned public key identifies a wallet/profile; it does not alone prove that a server request is authenticated. Use an appropriate challenge/proof or [wallet-signed HTTP authentication](https://docs.projectbabbage.com/docs/guides/wallet/auth) for that purpose. Never ask for a seed, password, recovery key or raw private key.

## Desktop and mobile connection paths

| Environment | Connection path |
| --- | --- |
| Desktop browser with Client running | Local wallet bridge discovered by the SDK |
| Website opened inside Explorer | Wallet bridge in Explorer's WebView |
| Ordinary Safari/Chrome tab on the phone | Does not automatically acquire Explorer's injected wallet |
| Backend/server process | Cannot assume access to a customer's browser wallet; design an explicit authenticated interaction |

Client 0.8.11 reserves loopback ports **3301** (binary wallet wire), **3321** (JSON HTTP) and **2121** (HTTPS bridge). These are local connection details, not public wallet endpoints or ports to forward from a router. Use SDK discovery for normal app code. Another desktop BRC-100 wallet using those ports must be quit before launching Client.

The API is portable across compliant wallets; UX, transport and optional behavior still need testing. Do not hard-code an originator to impersonate another website, bypass permission checks or assume a wallet brand based solely on a successful connection.

## Add one capability at a time

Continue with [permissions](https://docs.projectbabbage.com/docs/guides/wallet/permissions), [transactions](https://docs.projectbabbage.com/docs/guides/wallet/transactions), [encryption](https://docs.projectbabbage.com/docs/guides/wallet/encryption), [signatures](https://docs.projectbabbage.com/docs/guides/wallet/signing) and [certificates](https://docs.projectbabbage.com/docs/guides/wallet/certificates).

For each feature, explain the requested capability before the prompt. Handle rejection, insufficient funds, wrong network, locked wallet, backgrounding and interrupted responses. Preserve a transaction reference or ID when one exists. Never automatically repeat a spend just because a timeout or delivery acknowledgement is missing. Reconcile the original operation first.

Before release, exercise a non-spending connection and identity flow in both Client and Explorer, then a separately approved low-value payment. Verify the recipient's acceptance and app outcome, not just the sender's HTTP success. Check denied/revoked permissions and account/profile changes as well.

## Current references and older examples

- [BRC-100 specification](https://github.com/bitcoin-sv/BRCs/blob/master/wallet/0100.md)
- [Maintained TypeScript SDK and Wallet Toolbox source](https://github.com/bsv-blockchain/ts-stack)
- [SDK documentation](https://bsv-blockchain.github.io/ts-sdk/)
- [Client release notes](https://github.com/p2ppsr/metanet-client-downloads/releases/tag/v0.8.11)

For new integrations, replace old `@babbage/metanet-client`/`MetanetDesktop` tutorial patterns with the current `@bsv/sdk` interface. Do not silently change a production integration: map its actual methods, permission behavior and transaction handling, then verify both wallet paths.
