Skip to content

datamynt/bsv-brc-python

Repository files navigation

bsv-brc

PyPI version Python versions Tests License

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 /state endpoint — matches overlay.peck.to /state
  • Overlay OverlayClient (submit / lookup / state / verify) — defaults to overlay.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

Open BSV License

About

Python implementations of BSV BRC protocols — identity certificates (BRC-52), verifiable key linkage (BRC-94), HTTP micropayments (BRC-105), and more.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages