bsv-brc
Python implementations of BSV BRC protocols.
The higher-level protocol companion to py-sdk (bsv-sdk on PyPI).
While bsv-sdk handles transactions, keys, and SPV — bsv-brc implements the
protocol layer: identity certificates, verifiable key linkage, HTTP mutual
auth + micropayments, and the server-side overlay machinery py-sdk leaves
open (it ships only the overlay client side).
| Package | BRC | What |
|---|---|---|
bsv_brc.brc052 |
BRC-42/43/52/53 | Identity certificates, ECDH key derivation, AES-256-GCM |
bsv_brc.brc094 |
BRC-94 | Verifiable ECDH shared secrets via Schnorr proof |
bsv_brc.brc104 |
BRC-103/104 | ASGI mutual-auth adapter over bsv.auth |
bsv_brc.brc105 |
BRC-105 | HTTP 402 micropayment middleware + client |
bsv_brc.brc22 |
BRC-22 | Server-side overlay topic submission (/submit) |
bsv_brc.brc24 |
BRC-24 | Server-side lookup services — the feed (/lookup) |
bsv_brc.brc87 |
BRC-87 | tm_/ls_ overlay name validation |
bsv_brc.overlay |
— | OverlayEngine (run a node) + OverlayClient (talk to one) |
bsv_brc.integration |
— | build_brc_app: auth + payments pre-stacked |
Install
pip install bsv-brc
For Starlette/FastHTML middleware:
pip install "bsv-brc[starlette]"
Quick examples
Ship a whole BRC app — auth + payments in a few lines
from bsv_brc import build_brc_app, PathPricing
from bsv.keys import PrivateKey
from bsv.wallet.wallet_impl import ProtoWallet
wallet = ProtoWallet(PrivateKey()) # load a persisted key in production
app = build_brc_app(
your_asgi_app,
wallet=wallet, # server identity + payment settle
pricing=PathPricing({"/premium": 100}), # 100 sats on /premium, rest free
)
# Stacks BRC-103/104 auth under BRC-105 payments. The default
# verify_payment maps the client's BRC-29 derivation prefix/suffix to
# wallet.internalize_action() for you — no hand-rolling.
See examples/full_app.py for a complete,
fake-free server with auth, payments and a BRC-22 overlay topic.
Be an overlay node — submit + a queryable feed
bsv-sdk lets you talk to an overlay (LookupResolver,
TopicBroadcaster); bsv-brc lets you be one. Define a topic
(what gets admitted) and a lookup service (the feed), and serve both:
from bsv_brc.brc22 import TopicManager, AdmittanceInstructions
from bsv_brc.brc24 import LookupService, OutputRef
from bsv_brc.overlay import OverlayEngine
from bsv_brc.overlay.adapters.asgi import create_overlay_app
class PostsTopic(TopicManager):
def identify_admissible_outputs(self, beef, previous_coins):
# Decode with Transaction.from_beef(beef); pick which outputs to admit.
return AdmittanceInstructions(outputs_to_admit=[0], coins_to_retain=[])
class PostsFeed(LookupService):
def __init__(self): self.posts = []
def output_admitted(self, topic, txid, output_index, locking_script, satoshis):
self.posts.insert(0, OutputRef(txid, output_index, context=locking_script))
def lookup(self, question):
return self.posts[: (question.query or {}).get("limit", 20)]
engine = OverlayEngine(
topic_managers={"tm_posts": PostsTopic()},
lookup_services={"ls_posts": PostsFeed()},
)
app = create_overlay_app(engine) # POST /submit, POST /lookup
See examples/social_feed.py for a complete
~150-line social feed (the seed of an open-source peck.to).
Talk to an overlay — submit, read, verify
The consumer side, defaulting to overlay.peck.to (swappable):
from bsv_brc import OverlayClient
overlay = OverlayClient() # defaults to https://overlay.peck.to
result = overlay.submit(beef_bytes, ["tm_posts"], require_admission=True)
# result.admitted -> bool; NoAdmissionError on a 200-but-rejected submit
posts = overlay.lookup("ls_posts", {"limit": 20}) # -> [LookupOutput(txid, beef, ...)]
state = overlay.state() # [{topic, count, stateRoot}]
ok = overlay.verify_state("tm_posts", outpoints) # local state_root == node's
Async apps can use the pure build_submit_headers / parse_steak /
parse_lookup_answer / parse_state helpers with their own HTTP client.
BRC-105: Accept micropayments on any endpoint
from starlette.applications import Starlette
from bsv_brc.brc105 import PaymentMiddleware, NonceManager, StaticPricing
nonce_manager = NonceManager(secret=b"your-server-secret")
async def verify_payment(payment, identity_key):
# Call wallet.internalize_action() or your own verification
...
app = Starlette(routes=[...])
app.add_middleware(
PaymentMiddleware,
nonce_manager=nonce_manager,
pricing=StaticPricing(100), # 100 satoshis per request
verify_payment=verify_payment,
)
BRC-94: Prove an ECDH shared secret without revealing private keys
from bsv_brc.brc094 import generate_proof, verify_proof
# Prover side
shared_secret, R, S_prime, z = generate_proof(my_private_key, their_public_key)
# Verifier side — no private keys needed
is_valid = verify_proof(prover_public_key, counterparty_public_key, shared_secret, R, S_prime, z)
BRC-52: Issue an identity certificate
from bsv_brc.brc052 import issue, make_certificate_type
cert = issue(
certifier_private_key=certifier_key,
cert_type=make_certificate_type("example.com/identity/v1"),
subject_key=subject_pubkey_hex,
field_values={"email": "alice@example.com"},
serial_number=serial,
encrypted_field_keys=encrypted_keys_from_client,
)
Roadmap
- BRC-103/104 — Mutual authentication (ASGI adapter over
bsv.auth) - BRC-22 — Server-side overlay topic submission (
/submit) - BRC-24 +
OverlayEngine— Lookup services + a runnable overlay node - BRC-35 — Global KVStore over overlay (pending byte-exact interop check)
- BEEF-backed lookup answers (JSON) +
SqliteOverlayStorage - BRC-87 —
tm_/ls_name validation - Per-topic state root +
GET /stateendpoint — matchesoverlay.peck.to/state - Overlay
OverlayClient(submit / lookup / state / verify) — defaults tooverlay.peck.to - Optional SPV verify on submit (
OverlayEngine(verify_tx=...), injectable ChainTracker) - paymail (→ bsv-compat), peck-anchor client + headers.peck.to ChainTracker (peck-infra lib)
- GASP-style peer sync + on-chain root anchoring
Deliberately out of scope (see CHANGELOG.md): BRC-101 (aspirational,
no normative behavior), BRC-108 (no Mandala/BRC-92/107 token base),
BRC-116 (needs an external sCrypt toolchain).
Development
git clone https://github.com/datamynt/bsv-brc-python.git
cd bsv-brc-python
python3 -m venv .venv && source .venv/bin/activate
pip install -e ".[starlette,dev]"
pytest -v # 197 tests
License
Metadata
Release files for bsv-brc 0.4.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| bsv_brc-0.4.0.tar.gz | 78.3 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| bsv_brc-0.4.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 148.9 kB
Release files / bsv_brc-0.4.0.tar.gz
| Download URL | bsv_brc-0.4.0.tar.gz |
|---|---|
| Size | 78.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
fd0548ec545107255071de046a70af17549810a8e456133bbe61c3f3c5f87351
|
|
BLAKE2b-256 checksum How to use checksums |
f809810ef4492c614bb30181de0e8a8be0da9845169c522652a7a19d2af5cb04
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.7
|
Release files / bsv_brc-0.4.0-py3-none-any.whl
| Download URL | bsv_brc-0.4.0-py3-none-any.whl |
|---|---|
| Size | 70.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
3f51ceab7377a7c2504fc756f19dea42253390f486f7b0da2f6650034e039cbb
|
|
BLAKE2b-256 checksum How to use checksums |
ebc4237be7ef53d9eeb081979c96e58fd2c1b9b882aaeb6108100b2a5cb377ab
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.7
|
Security for bsv-brc 0.4.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.