sendbsv-wallet
v0.1.0
Published
In-browser, biometric-gated, BRC-100-native BSV wallet primitive. Layer 1 signing + bundled layer 2 (holdings, activity, sweeper, tip jar, recovery) as default; sub-exports for advanced hosts. PWA-ready, $0 to use, OpenBSV-licensed.
Maintainers
Readme
A mobile-first BSV wallet that runs in any modern browser. Biometric-gated, PWA-installable, BRC-100-native.
Live at wallet.sendbsv.com.
| | |
|---|---|
| npm | sendbsv-wallet · engine bsv-wallet-toolbox-rs — early access (0.x) |
| Repo | https://github.com/BSVanon/SendBSV-Wallet |
| License | Open BSV License |
The wallet
Open wallet.sendbsv.com on your phone, enroll a passkey, and you've got a BSV wallet. Send, receive, sweep to cold storage, request payments, claim a paymail handle, manage profiles and certificates, watch your inbox for incoming requests, view your collectibles.
Face ID / Touch ID / Windows Hello / fingerprint / FIDO2 security key — pick one. The wallet engine signs in-browser using passkey-derived keys; nothing leaves the device. The public BSV overlay network carries your wallet identity to every other device you sign in on with the same passkey.
Install it as a PWA for one-tap launch (Add to Home Screen on iOS, Install on desktop Chrome). No app store, no signup form, no servers asking who you are.
The primitive
The same engine ships as an npm package so any app can plug into it. Five integration surfaces:
- React import — drop
Dashboard,SendSheet,ReceiveSheet, or any of the layer-2 modules into your React app. - Embed button — one
<script>tag and a<sendbsv-pay>custom element. Accept BSV from any HTML page. - Iframe widget — same trust model as the embed button, for hosts with strict CSPs.
- Connect SDK — Promise-based JS API for non-React DApps.
- M2M Fetch — BRC-121 (Simple 402 Payments)
fetch-shaped wrapper for agents, scripts, and browser tabs that pay protected APIs.
Try it locally
pnpm install
pnpm devOpens a dev playground at http://localhost:5173 with three views:
- WASM (live) — the production setup flow driving
bsv-wallet-toolbox-rs. - Dashboard (stub) — every layer-2 component mounted against a stub wallet with seeded data, for fast UI iteration.
- Legacy v0 — earlier component versions, kept for visual reference.
The wiring lives in examples/dev/main.tsx.
Install
pnpm add sendbsv-wallet bsv-wallet-toolbox-rs @bsv/sdk react react-domBoth sendbsv-wallet and its Rust → WASM engine peer dependency bsv-wallet-toolbox-rs are on npm as early access (0.x — the API may change before 1.0).
Quick start (React)
import { Dashboard, SetupFlowWasm } from "sendbsv-wallet";
import "sendbsv-wallet/styles.css";
function App() {
const [wallet, setWallet] = React.useState(null);
if (!wallet) {
return (
<SetupFlowWasm
adminOriginator="your.app.example"
postBeef={async (beef, txids) => { /* wire to ARC */ }}
onComplete={setWallet}
/>
);
}
return <Dashboard wallet={wallet} />;
}SetupFlowWasm handles enrollment (passkey + WebAuthn-PRF → identity → UMP token publish) and unlock (PRF challenge → local SQLite or overlay lookup → wallet ready). It self-detects returning users, so subsequent visits skip onboarding.
When you're wrapping the wallet for third-party DApps, use useSignDrawer + wrap(rawWallet, adminOriginator). Every signed BRC-100 verb routes through a user-approval BottomSheet whenever the originator is external; the wallet's own UI surfaces bypass it.
Integration
React (sendbsv-wallet)
The full surface area lives in src/index.ts. Common imports:
import {
Dashboard,
SetupFlowWasm,
SendSheet,
ReceiveSheet,
InboxScreen,
Holdings,
ActivityLog,
HotColdSweeper,
TipJar,
Collectibles,
useSignDrawer,
wrap
} from "sendbsv-wallet";Embed button — <sendbsv-pay> + window.SendBSV.pay()
<sendbsv-pay
to="[email protected]"
amount="1000"
label="Tip 1000 sats"
></sendbsv-pay>
<script src="https://wallet.sendbsv.com/embed.js"></script>Or programmatically:
const result = await window.SendBSV.pay({
to: "[email protected]",
amount: 1000,
description: "Premium unlock"
});
// result.status === "success" | "declined" | "error"Events on the custom element: sendbsv-success ({ txid, amount }), sendbsv-declined ({ reason: "user_cancelled" | "popup_blocked" }), sendbsv-error ({ message }).
The runtime weighs about 4 KB minified, 2 KB gzipped. Tapping the button opens wallet.sendbsv.com in a popup; the user confirms with their biometric; the result returns via postMessage with origin, source, and envelope version verified. Examples in examples/embed-host/.
Iframe widget
<iframe
src="https://wallet.sendbsv.com/embed/[email protected]&amount=1000"
style="border:none; width:240px; height:80px;"
></iframe>Same popup-signing flow as the embed button. Drop-in for sites that can't add a <script> tag. See examples/widget-host/.
Connect SDK (sendbsv-wallet/connect)
import { SendBSVConnect } from "sendbsv-wallet/connect";
const wallet = new SendBSVConnect();
const result = await wallet.requestPayment({
to: "[email protected]",
amount: 1000,
description: "tip for the article"
});Promise-based. Never rejects — every failure path returns as data on result.status.
M2M Fetch (createM2MFetch)
BRC-121 wrapper around fetch, built on canonical @bsv/402-pay:
import { createM2MFetch } from "sendbsv-wallet";
const m2mFetch = createM2MFetch({
wallet,
maxSpendPerCall: 5000,
maxSpendPerSession: 50_000
});
const data = await m2mFetch("https://api.example.com/premium-endpoint")
.then(r => r.json());For interactive contexts that want user approval on each spend, pair it with useSignDrawer().createM2MApprover().
Architecture
- Engine —
bsv-wallet-toolbox-rs, the canonical Rust port of@bsv/wallet-toolbox, compiled to WASM. Runs in a DedicatedWorker;sqlite-wasminstalls its sahpool VFS for persistence. All 28 BRC-100 methods exposed viaWasmWalletAdapter. - Keys — WebAuthn-PRF derives the wallet root key from a passkey. Apple and Google passkey sync handles cross-device portability for default users; advanced users get a recovery key they can pair to a new-device passkey directly.
- Identity — UMP token published to the public BSV overlay network. Same passkey on a fresh device finds the same wallet.
- L2 storage —
storage.sendbsv.com(Cloudflare Workers + D1 + R2) holds an encrypted SQLite snapshot for cold-start recovery.hydrateOnEmptyruns once on returning-user-with-empty-local-storage. - Messaging — BRC-125 PeerPay routes through
messagebox.babbage.systems, currently fronted bymsgbox.sendbsv.comfor browser CORS.
Development
pnpm install # install deps
pnpm dev # dev playground at http://localhost:5173
pnpm test # vitest unit suite (~2,600 tests)
pnpm tsc --noEmit # type check
pnpm app:build # production app build → dist-app/
pnpm test:e2e # Playwright headless e2eNode 24+ (see .nvmrc). The unit suite uses fake-indexeddb for headless persistence; Playwright runs against the real dist-app/ bundle.
Issues & contributions
Issues and pull requests welcome at https://github.com/BSVanon/SendBSV-Wallet/issues.
For security issues that should not be public, DM @SendBSV on X rather than filing a public issue.
