# Dragonchain Python SDK A self-contained Python SDK for interacting with Dragonchain (Prime) nodes. ## Installation ```bash pip install prime-sdk-python ``` Or, from a local checkout: ```bash pip install -e . ``` Requires Python 3.9+. ## Usage ```python from prime_sdk import DragonchainSDK, TransactionCreateRequest # Initialize the SDK client = DragonchainSDK( "your-public-id", "your-auth-key-id", "your-auth-key", "https://your-dragonchain-endpoint.com", ) # Check system health (raises DragonchainAPIError if unhealthy) client.system.health() # Get system status status = client.system.status() print(f"Chain ID: {status.id}, Level: {status.level}") # Create a transaction resp = client.transaction.create( TransactionCreateRequest( txn_type="my-transaction-type", payload='{"message": "Hello Dragonchain"}', tag="example-tag", ) ) print(f"Created transaction: {resp.transaction_id}") ``` ## Transaction Modes `create` and `create_bulk` return **immediately** with the assigned transaction ID(s). They do **not** wait for block inclusion. Blocks are assembled asynchronously on a ~5-second cycle. ### Fire and Forget Most use cases only need the transaction ID. No polling required. ```python resp = client.transaction.create( TransactionCreateRequest( txn_type="my-transaction-type", payload='{"message": "Hello Dragonchain"}', ) ) print("Transaction ID:", resp.transaction_id) # Done — no need to wait for a block. ``` ### Wait for Block If you need the block ID (e.g. for interchain verification or Daria), poll `get` until `header.block_id` is populated. ```python import time resp = client.transaction.create( TransactionCreateRequest( txn_type="my-transaction-type", payload='{"message": "Hello Dragonchain"}', ) ) while True: txn = client.transaction.get(resp.transaction_id) if txn.header.block_id: print("Block ID:", txn.header.block_id) break time.sleep(2) ``` ## Loading credentials from a file The SDK can read chain credentials from a YAML file: ```yaml default: my-public-id chains: - name: my-chain publicId: my-public-id authKeyId: my-auth-key-id authKey: my-auth-key endpoint: https://chains.dragonchain.com ``` ```python from prime_sdk import DragonchainSDK from prime_sdk.credentials import load_config cfg = load_config("~/.dragonchain/credentials.yaml") chain = cfg.get_default_chain() client = DragonchainSDK( chain.public_id, chain.auth_key_id, chain.auth_key, chain.endpoint ) ``` ## Available Endpoints ### System - `system.health()` — Check system health - `system.status()` — Get system status ### Transaction - `transaction.create(req)` — Create a new transaction - `transaction.create_bulk(req)` — Create multiple transactions - `transaction.get(transaction_id)` — Get transaction by ID - `transaction.list()` — List all transactions ### Transaction Type - `transaction_type.create(req)` — Create a new transaction type - `transaction_type.get(txn_type)` — Get transaction type by name - `transaction_type.list()` — List all transaction types - `transaction_type.delete(txn_type)` — Delete a transaction type ### Smart Contract - `contract.create(req)` — Create a new smart contract - `contract.get(contract_id)` — Get smart contract by ID - `contract.list()` — List all smart contracts - `contract.update(contract_id, req)` — Update a smart contract - `contract.upload(contract_id, filepath)` — Upload smart contract code - `contract.delete(contract_id)` — Delete a smart contract ### Block - `block.get(block_id)` — Get block by ID ### Proof Measure (public, unauthenticated) - `proof_measure.get_security(network, since=None)` — A network's accumulated security since `since` (unix seconds), as a raw measure + USD valuation. `network` = `"BTC"` or `"ETH"`. - `proof_measure.report(req)` — Per-transaction "securedBy" report over interchain anchors. - `proof_measure.health()` — Service liveness. ## Interchain trace `transaction.get_interchain` / `block.get_interchain` trace a prime block to the public-chain anchors covering it. By default they return the **first anchor per chain** (anchor proofs are chained, so the earliest per chain is the meaningful one): ```python # Default: first anchor per chain (ETH, BTC, …) trace = client.block.get_interchain("42") # Up to 3 anchors per chain trace = client.block.get_interchain("42", per_chain=3) # All anchors, only the ETH-mainnet chain ("1"); "0" = BTC trace = client.block.get_interchain("42", per_chain=0, chains=["1"]) ``` ## Proof Measure `proof-measure` is a separate, **public, unauthenticated** Dragonchain service (the measured-immutability / "securedBy" metric) at `https://proof-measure.dragonchain.com`. It needs no credentials. Decimal fields are returned as strings (full precision) and timestamps as int unix seconds. ```python import time from prime_sdk import ProofMeasureClient, ReportRequest, ReportAnchorInput # Via the main SDK (targets the default public endpoint): sec = client.proof_measure.get_security("BTC", int(time.time()) - 3600) print(f"BTC secured by {sec.value_usd_formatted} ({sec.raw.value} {sec.raw.unit})") # Or standalone — no prime credentials needed: pm = ProofMeasureClient() # or ProofMeasureClient("http://localhost:9481") report = pm.report( ReportRequest( transaction_id="tx-123", prime_id="my-prime", block_id="42", anchors=[ ReportAnchorInput(tx_hash="0x...", timestamp=anchor_unix, network="BTC"), ReportAnchorInput(tx_hash="0x...", timestamp=anchor_unix, network="ETH"), ], ) ) print(f"Secured by {report.total_value_usd_formatted} across {len(report.anchors)} anchors") pm.health() ``` ## Authentication The SDK uses HMAC-SHA256 authentication. You need to provide: - `public_id` — Your Dragonchain public ID - `auth_key_id` — Your authentication key ID - `auth_key` — Your authentication key - `base_url` — The base URL of your Dragonchain node (e.g. "https://chains.dragonchain.com") ## Error handling Any non-2xx response raises `prime_sdk.DragonchainAPIError`, which exposes `.status_code` and `.body`: ```python from prime_sdk import DragonchainAPIError try: client.transaction.get("nonexistent-id") except DragonchainAPIError as e: print(e.status_code, e.body) ``` ## License Apache-2.0