This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
The BSV SDK is a comprehensive Python library for developing scalable applications on the BSV Blockchain. It provides a peer-to-peer approach adhering to SPV (Simplified Payment Verification) with focus on privacy and scalability.
Repository: https://github.com/bitcoin-sv/py-sdk Package name: bsv-sdk Current version: 1.0.8 Python requirement: >=3.9
pip install -r requirements.txt# Run full test suite with coverage
pytest --cov=bsv --cov-report=html
# Run specific test file
pytest tests/test_transaction.py
# Run tests with asyncio
pytest tests/bsv/auth/test_auth_peer_basic.py# Build distribution packages (requires python3 -m build)
make build
# Or directly:
python3 -m buildmake upload_test # Upload to TestPyPI
make upload # Upload to PyPIThe bsv package is organized into functional submodules:
-
Core Transaction Components (
bsv/transaction.py,bsv/transaction_input.py,bsv/transaction_output.py)Transaction: Main transaction class with serialization, signing, fee calculation, and broadcasting- Supports BEEF (Bitcoin Encapsulated Format) and EF (Extended Format) serialization
- SPV validation through merkle paths
-
Script System (
bsv/script/)ScriptTemplate: Abstract base for locking/unlocking scripts- Built-in templates:
P2PKH,P2PK,OpReturn,BareMultisig,RPuzzle Script: Low-level script operationsSpend: Script validation engine
-
Keys & Cryptography (
bsv/keys.py,bsv/curve.py,bsv/hash.py)PrivateKey,PublicKey: ECDSA key management- Support for compressed/uncompressed keys
- WIF format support
-
HD Wallets (
bsv/hd/)- Full BIP32/39/44 implementation
- Hierarchical deterministic key derivation
- Mnemonic phrase support (multiple languages via
hd/wordlist/)
-
Authentication (
bsv/auth/)Peer: Central authentication protocol implementationCertificate: Certificate handling and verificationSessionManager: Session lifecycle managementTransport: Communication layer abstraction- PKI-based authentication between peers
-
Wallet (
bsv/wallet/)WalletInterface: Abstract wallet interfaceWalletImpl: Full wallet implementationKeyDeriver: Protocol-based key derivationCachedKeyDeriver: Optimized key derivation with caching
-
Broadcasting (
bsv/broadcasters/)Broadcaster: Interface for transaction broadcastingarc.py: ARC broadcaster implementationwhatsonchain.py: WhatsOnChain broadcasterdefault_broadcaster.py: Default broadcaster selection
-
Chain Tracking (
bsv/chaintrackers/)ChainTracker: Interface for chain state verificationwhatsonchain.py: WhatsOnChain chain trackerdefault.py: Default chain tracker
-
Storage (
bsv/storage/)Uploader,Downloader: File upload/download utilities- Integration with blockchain storage
-
Keystore (
bsv/keystore/)- Key persistence and retention management
- Local key-value store implementation
-
BEEF Support (
bsv/beef/)build_beef_v2_from_raw_hexes: BEEF format construction- Transaction validation with merkle proofs
-
Utilities (
bsv/utils.py)Reader,Writer: Binary serialization helpers- Varint encoding/decoding
- Address utilities
Lazy Imports: The bsv/__init__.py is intentionally minimal to avoid circular imports. Import specific modules where needed:
from bsv.keys import PrivateKey
from bsv.transaction import TransactionAsync Operations: Transaction broadcasting and verification are async:
await tx.broadcast()
await tx.verify(chaintracker)Template Pattern: Script types use templates that provide lock() and unlock() methods:
script_template = P2PKH()
locking_script = script_template.lock(address)
unlocking_template = script_template.unlock(private_key)Source Transactions: Inputs require source transactions for fee calculation and verification. The SDK tracks UTXOs through linked source transactions rather than external UTXO databases.
SIGHASH Handling: Each transaction input has a sighash field (defaults to SIGHASH.ALL | SIGHASH.FORKID) used during signing.
Tests are organized in two locations:
- Root-level tests (
tests/): Classic test structure with direct imports - Nested tests (
tests/bsv/): Mirror thebsv/package structure
Test organization by feature:
tests/bsv/primitives/: Core cryptographic primitivestests/bsv/transaction/: Transaction building and validationtests/bsv/auth/: Full authentication protocol test suitetests/bsv/wallet/: Wallet implementation teststests/bsv/storage/: Storage system teststests/bsv/broadcasters/: Broadcaster integration tests
Running single test: Use standard pytest patterns:
pytest tests/bsv/auth/test_auth_peer_basic.py::test_function_name
pytest -k "test_pattern"- PEP 8 compliance: Follow Python standard style guide
- Type hints: Use where appropriate (not comprehensive in current codebase)
- Docstrings: Document functions, classes, and modules
- Comments: Annotate complex logic
- Test-Driven Development: Write tests before or alongside implementation where smart, quick, and reasonable. This helps ensure correctness and prevents regressions.
- Run
pytest --cov=bsv --cov-report=htmlto verify test coverage before committing - All PRs should maintain or improve current test coverage
The SDK implements Assembly (ASM) representation of Bitcoin Script via Script.from_asm() and Script.to_asm() methods.
BRC-106 Standard: https://github.com/bitcoin-sv/BRCs/blob/master/scripts/0106.md
Key requirements from BRC-106:
- Use full English names for op-codes (e.g., "OP_FALSE" not "OP_0")
- Output should always use the most human-readable format
- Multiple input names should parse to the same hex value
- Ensure deterministic translation across different SDKs (Py-SDK, TS-SDK, Go-SDK)
Current Implementation (bsv/script/script.py:140-191):
from_asm(): Accepts both "OP_FALSE" and "OP_0", converts to b'\x00'to_asm(): Currently outputs "OP_0" for b'\x00' (see OPCODE_VALUE_NAME_DICT override at constants.py:343)
Note: The current to_asm() output may need adjustment to fully comply with BRC-106's human-readability requirement (should output "OP_FALSE" instead of "OP_0").
# Parse ASM string to Script
script = Script.from_asm("OP_DUP OP_HASH160 abcd1234 OP_EQUALVERIFY OP_CHECKSIG")
# Convert Script to ASM representation
asm_string = script.to_asm()
# Access script chunks
for chunk in script.chunks:
print(chunk) # Prints opcode name or hex data- The SDK uses
coincurvefor ECDSA operations (not pure Python) - Encryption uses
pycryptodomex(not standardpycryptodome) - Network operations require
aiohttpfor async HTTP - Tests require
pytest-asynciofor async test support - Coverage configuration excludes tests and setup.py (see
.coveragerc) - Git branches:
masteris main branch,develop-portis development branch
priv_key = PrivateKey(wif_string)
source_tx = Transaction.from_hex(hex_string)
tx_input = TransactionInput(
source_transaction=source_tx,
source_txid=source_tx.txid(),
source_output_index=0,
unlocking_script_template=P2PKH().unlock(priv_key)
)
tx_output = TransactionOutput(
locking_script=P2PKH().lock(priv_key.address()),
change=True
)
tx = Transaction([tx_input], [tx_output])
tx.fee() # Calculate and distribute fees
tx.sign() # Sign all inputs
await tx.broadcast() # Broadcast to network# Parse BEEF
tx = Transaction.from_beef(beef_hex)
# Create BEEF
beef_bytes = tx.to_beef()# P2PKH
p2pkh = P2PKH()
lock_script = p2pkh.lock(address_string)
unlock_template = p2pkh.unlock(private_key)
# OP_RETURN
op_return = OpReturn()
data_script = op_return.lock(['Hello', b'World'])
# Multisig
multisig = BareMultisig()
lock_script = multisig.lock([pubkey1, pubkey2, pubkey3], threshold=2)
unlock_template = multisig.unlock([privkey1, privkey2])