Skip to main content

deepidv-chain

Python SDK for the deepidv chain layer — read the public attestation registry, follow the transparency log, and verify offline .dpiv-bundle archives end-to-end.

pip install deepidv-chain
  • Sync and async clients (Client, AsyncClient) over httpx.
  • Offline bundle verification (verify_bundle) — RFC 6962 inclusion + RFC 8785 envelope hash + ECDSA P-256 manifest and STH signatures.
  • Pydantic v2 models throughout. Fully typed (py.typed), passes mypy --strict.
  • Cross-language parity with the Node SDK (@deepidv/chain): byte-identical hashes for the same fixtures.
  • Python 3.9 → 3.13.

Quickstart — sync

from deepidv_chain import Client

with Client("https://staging-api.deepidv.com") as chain:
    # Pull a single attestation by id.
    attestation = chain.get_attestation("attest_01J9X9YQ7W7N2T0M5K8P3R4Q6V")
    print(attestation.record_type, attestation.issuer_id)

    # Page through the public registry.
    page = chain.list_registry({"record_type": "IDV"})
    for summary in page.items:
        print(summary.attestation_id, summary.issued_at)

    # Download the offline-verifiable bundle.
    bundle_bytes = chain.download_bundle(attestation.attestation_id)

Quickstart — async

import asyncio
from deepidv_chain import AsyncClient

async def main():
    async with AsyncClient("https://staging-api.deepidv.com") as chain:
        log = await chain.get_log()
        for segment in log.segments:
            print(segment.segment_id, segment.tree_size)

asyncio.run(main())

Streaming — Server-Sent Events

async with AsyncClient() as chain:
    async for event in chain.stream_attestations():
        print(event.event, event.id, event.data)

The iterator reconnects with exponential backoff on transient disconnects and replays Last-Event-ID so the server can resume. Pass max_reconnect_attempts=0 to disable reconnection.

Offline bundle verification

from deepidv_chain import verify_bundle

with open("attestation.dpiv-bundle", "rb") as f:
    result = verify_bundle(f.read())

if result.valid:
    print("verified:", result.attestation_id)
else:
    for check in result.checks:
        if not check.passed and not check.skipped:
            print(f"FAIL {check.name}: {check.detail}")

verify_bundle runs a 5-of-6 contract end-to-end:

  1. Manifest integrity (sha256sum-compatible).
  2. Manifest signature (chain-master ECDSA P-256).
  3. Envelope hash (sha256(JCS(envelope))).
  4. RFC 6962 inclusion proof reconstructs the STH root.
  5. STH signature (chain-master ECDSA P-256 over the JCS-canonical unsigned form).
  6. TSA timestamp — SKIPPED in v1. Reported as skipped=True, passed=False. The detail string explicitly notes whether timestamp.tsr was present or absent. Never silently treated as a pass. If your policy requires a trusted external timestamp, treat the skip as a non-pass and gate accordingly.

result.envelope is the envelope dict with the per-record privacy salt stripped — safe to render directly. The full envelope (with salt) is what the verifier hashes; do not reconstruct it from result.envelope for a re-hash.

Errors

from deepidv_chain import (
    DeepidvApiError,         # base
    DeepidvAuthError,        # 401 / 403
    DeepidvNotFoundError,    # 404
    DeepidvRateLimitError,   # 429 (carries .retry_after_seconds)
    DeepidvServerError,      # 5xx
)

Every error carries status_code, url, body, and request_id (from the x-request-id response header).

Type checking

The package ships a py.typed marker and is fully type-annotated. The typed surface lives at deepidv_chain (top-level re-exports) and deepidv_chain.types.

from deepidv_chain import AttestationDetail, RegistryFilters

Configuration

Client(
    api_url="https://api.proof.deepidv.com",   # default: staging-api.deepidv.com
    api_key="dpiv_live_...",                   # bearer token; optional for public reads
    timeout=30.0,                              # httpx timeout
    user_agent="my-app/1.0",                   # appended User-Agent
    http_client=my_pre_configured_httpx,       # inject your own httpx.Client
)

The same kwargs apply to AsyncClient (with httpx.AsyncClient).

Cross-language parity

Hashes computed by this SDK are byte-identical to those computed by @deepidv/chain for the same logical input. The shared parity fixtures live in tests/fixtures/jcs-vectors.json and tests/fixtures/envelope-hashes.json. If you discover a divergence, file an issue with the offending input — both SDKs gate releases on parity.

Privacy

  • Bundle-verify return values never include the per-record privacy salt.
  • claim_hash is sha256 over the JCS-canonical claim and is intentionally one-way.
  • The SDK never logs claim bodies, salts, or signatures.

License

Apache-2.0. See LICENSE.

Links

Metadata

Release files for deepidv-chain 1.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for deepidv-chain 1.2.0
File Size Uploaded Provenance
deepidv_chain-1.2.0.tar.gz 34.0 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for deepidv-chain 1.2.0
File Interpreter ABI Platform
deepidv_chain-1.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 64.9 kB

Release files / deepidv_chain-1.2.0.tar.gz

Download URL deepidv_chain-1.2.0.tar.gz
Size 34.0 kB
Tags Source
SHA-256 checksum
How to use checksums
77eb5b7affc309f54eb9586f474652c71e7d33389ae91fb2994540eaf5b04273
BLAKE2b-256 checksum
How to use checksums
2a7f4c59df2ab0cb6d141e0c70fdf8172ca658a1564e3c82913301a36fd4a405
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.13

Release files / deepidv_chain-1.2.0-py3-none-any.whl

Download URL deepidv_chain-1.2.0-py3-none-any.whl
Size 30.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ff3f416ad2fd9dae5705d64cbf1776f339f77ea1dca90795ce280b41ba27a67a
BLAKE2b-256 checksum
How to use checksums
446c37073eceef02838280c17ccd8422cdcdadcdede034029e9d3f396d3ad4bf
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.13

Security for deepidv-chain 1.2.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.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page