BRC-100 Wallet Interface

BRC-100 is the boundary between application code and wallet code. Apps describe what they want; wallets decide how to select outputs, apply permissions, derive keys, sign, broadcast, and track state.

BRC-100 desktop and mobile request flows

Why This Boundary Exists

Without BRC-100, every app would need custom wallet integrations and every wallet would need custom app adapters. BRC-100 gives both sides one stable contract:

  • Apps can call wallet.createAction, wallet.getPublicKey, wallet.encrypt, and other methods without learning a specific wallet product.
  • Wallets can implement one interface and expose it over localhost, postMessage, JSON APIs, native bridges, or in-process objects.
  • Other language implementations can target the same method shapes and test against the same conformance vectors.

Desktop Flow

On desktop, a web app uses @bsv/simple/browser or WalletClient from @bsv/sdk.

  1. The app calls a BRC-100 method such as createAction.
  2. WalletClient finds the available wallet substrate.
  3. BSV Desktop receives the request over a localhost wallet server.
  4. The wallet may call Wallet Infra, for example https://store-us-1.bsvb.tech, to read and update wallet state.
  5. Keys remain in the desktop wallet process.
  6. The wallet returns the action result, such as txid, tx, noSendChange, sendWithResults, or signableTransaction.

Mobile Flow

On mobile, BSV Browser embeds the web app and exposes the same method surface through a bridge.

  1. The app calls the same BRC-100 method.
  2. The browser WebView sends the request to native code over postMessage.
  3. The native wallet selects outputs from its local database and signs on the device.
  4. The wallet may still use network services such as ARC or Chaintracks for broadcast, headers, and proofs.
  5. The result returns to the web app through the bridge.

The application does not need separate business logic for desktop and mobile if it stays on the BRC-100 interface.

Method Groups

GroupPurposeMethod reference
ActionsCreate, sign, abort, list, and internalize transactions.createAction, signAction, internalizeAction
OutputsQuery and relinquish tracked outputs in baskets.listOutputs, relinquishOutput
Keys and cryptoDerive public keys, encrypt/decrypt, HMAC, signatures, key linkage.getPublicKey, encrypt, createSignature
CertificatesAcquire, list, prove, relinquish, and discover identity certificates.acquireCertificate, proveCertificate
Wallet stateAuthentication, chain height, headers, network, version.getHeight, getVersion

Action Lifecycle

createAction has two common outcomes:

OutcomeWhat the app receivesWhat happens next
Immediate actiontxid and/or txWallet had enough information to fund, sign, and process the transaction.
Signable actionsignableTransaction: { tx, reference }App signs specific inputs or creates unlocking scripts, then calls signAction({ reference, spends }).

noSend and sendWith support chained batches. A wallet can create several actions without broadcasting them, pass change forward through noSendChange, and later send them together.

Labels vs Tags

ConceptScopeUsed by
LabelsWhole action/transactioncreateAction({ labels }), listActions({ labels })
TagsSpecific outputcreateAction({ outputs: [{ tags }] }), listOutputs({ tags })
BasketsNamed output containerslistOutputs({ basket }), internalizeAction basket insertions

Do not use labels as output tags or tags as action labels. They are different indexes.

Implementation Sources

  • Human-readable method reference: BRC-100 Wallet Interface
  • Machine-readable schema: specs/sdk/brc-100-wallet.json
  • Type source: packages/sdk/src/wallet/Wallet.interfaces.ts
  • Reference implementation: packages/wallet/wallet-toolbox/src/Wallet.ts
  • Wallet examples: packages/wallet/wallet-toolbox-examples/src/