Skip to content

wip-abramson/did-btcr2-py

 
 

Repository files navigation

Experimental did:btcr2 Python Library

Warning: This is purely experimental and should not be used for production purposes.

A Python library for creating, managing, and resolving did:btcr2 decentralised identifiers anchored to the Bitcoin blockchain.

Features

  • DID Creation - Create deterministic (key-based) or external (hash-based) DIDs
  • DID Resolution - Resolve DIDs by traversing Bitcoin blockchain history
  • DID Updates - Update DID documents via beacon signals committed to Bitcoin transactions
  • Multiple Networks - Supports Bitcoin mainnet, signet, testnet3, testnet4, regtest, and mutinynet
  • Cryptographic Proofs - BIP340 Schnorr signature proofs with JCS canonicalization

Project Structure

libbtcr2/
├── did.py              # DID identifier encoding/decoding (bech32)
├── did_manager.py      # Core DID lifecycle management
├── resolver.py         # DID resolution from blockchain
├── http_resolver.py    # HTTPS binding DID resolver (FastAPI app)
├── routes.py           # GET/POST /1.0/identifiers/{did} route handlers
├── beacon_manager.py   # Bitcoin beacon signal creation
├── address_manager.py  # Bitcoin address and UTXO management
├── esplora_client.py   # Esplora blockchain API client
├── diddoc/
│   ├── doc.py          # DID document model
│   ├── builder.py      # DID document construction
│   └── updater.py      # DID document updates via JSON-Patch
├── service.py          # Beacon service definitions
├── multikey.py         # Cryptographic key handling
├── models.py           # Pydantic models (resolution results, network config, …)
├── errors.py           # Custom exceptions
├── network_config.py   # Built-in network definitions and Esplora endpoints
└── constants.py        # Global constants and configurations

Setup

Requires Python >= 3.10.

python -m venv venv
source venv/bin/activate

Install from source

pip install -e .

Install from repository

This installs the package from the main branch of the repository. As this is an experimental, proof-of-concept implementation there is no pip package available for the time being.

pip install libbtcr2@git+https://github.com/DCD/did-btcr2-py

Run Tests

pytest

HTTPS Resolver

libbtcr2 ships a conformant DID Core HTTPS binding resolver built on FastAPI. It exposes the standard GET and POST /1.0/identifiers/{did} endpoints and honours the Accept header to return either a full resolution result or a bare DID document.

Starting the server

Use the provided script for a ready-to-run server:

python scripts/serve_resolver.py                    # binds to 0.0.0.0:8080
python scripts/serve_resolver.py --port 9000        # custom port
python scripts/serve_resolver.py --host 127.0.0.1  # localhost only

Configuring network endpoints

Pass a dict[str, BtcNetworkDefinition] to Btcr2Resolver to point the resolver at your own Esplora endpoints. The dict key is the network label encoded in the DID identifier.

from libbtcr2 import BtcNetworkDefinition, Btcr2Resolver
from libbtcr2.http_resolver import Btcr2HttpsResolver

network_definitions = {
    "bitcoin": BtcNetworkDefinition(
        btc_network="bitcoin",
        esplora_api="https://mempool.space/api",
    ),
    "regtest": BtcNetworkDefinition(
        btc_network="regtest",
        esplora_api="http://localhost:3000",
    ),
}

resolver = Btcr2Resolver(btc_network_definitions=network_definitions)
server = Btcr2HttpsResolver(host="0.0.0.0", port=8080, resolver=resolver)
server.run()

The built-in DEFAULT_NETWORK_DEFINITIONS covers bitcoin, signet, mutinynet, and regtest with public Esplora endpoints and is used when no custom definitions are supplied.

API endpoints

Method Path Description
GET /1.0/identifiers/{did} Resolve a DID. Resolution options passed as query parameters.
POST /1.0/identifiers/{did} Resolve a DID. Resolution options passed as a JSON body.

Accept header and response format

Accept header Response body
application/did-resolution Full resolution result: @context, didDocument, didResolutionMetadata, didDocumentMetadata
application/did (or any other value) Bare DID document only
application/did-url-dereferencing Dereferencing result (returns 501 Not Implemented — not yet supported)

Example requests

Resolve a DID (full result):

curl -H "Accept: application/did-resolution" \
  http://localhost:8080/1.0/identifiers/did:btcr2:k1q5p72wesj9vtrtl5vu3l5hdx730vcp08xkn8kvznwf8plk5qpqkv2zg6pg50y
{
  "@context": "https://w3id.org/did-resolution/v1",
  "didDocument": { "id": "did:btcr2:k1q...", ... },
  "didResolutionMetadata": {},
  "didDocumentMetadata": { "network": "bitcoin", "version": 1 }
}

Resolve a DID (bare document):

curl -H "Accept: application/did" \
  http://localhost:8080/1.0/identifiers/did:btcr2:k1q5p72wesj9vtrtl5vu3l5hdx730vcp08xkn8kvznwf8plk5qpqkv2zg6pg50y

Resolve with options via POST:

curl -X POST \
  -H "Accept: application/did-resolution" \
  -H "Content-Type: application/json" \
  -d '{"versionId": 2}' \
  http://localhost:8080/1.0/identifiers/did:btcr2:k1q5p72wesj9vtrtl5vu3l5hdx730vcp08xkn8kvznwf8plk5qpqkv2zg6pg50y

Resolve with sidecar data (external DID, no IPFS):

curl -X POST \
  -H "Accept: application/did-resolution" \
  -H "Content-Type: application/json" \
  -d '{"sidecarData": {"initialDocument": { ... }}}' \
  http://localhost:8080/1.0/identifiers/did:btcr2:x1q...

Embedding in an existing FastAPI app

Btcr2HttpsResolver.app is a plain FastAPI instance, so it can be mounted inside any ASGI application:

from fastapi import FastAPI
from libbtcr2.http_resolver import Btcr2HttpsResolver

app = FastAPI()
btcr2 = Btcr2HttpsResolver()
app.mount("/btcr2", btcr2.app)

Example Scripts

Example scripts are provided in the scripts/ directory:

  • scripts/serve_resolver.py - Start the HTTPS resolver server
  • scripts/regtest_create_deterministic.py - Create a deterministic DID from a secp256k1 key on regtest
  • scripts/regtest_create_external.py - Create an external DID from an intermediate document on regtest
  • scripts/mutinynet_create.py - Create a DID on mutinynet
  • scripts/resolve.py - Resolve a DID and output the resolution result

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages

  • Python 100.0%