Metadata-Version: 2.4
Name: ardyn
Version: 0.2.2
Summary: Official Python client for the Ardyn Liability Verification Substrate API
Project-URL: Homepage, https://ardyn.ai
Project-URL: Documentation, https://docs.ardyn.ai
Project-URL: Repository, https://github.com/Kylewilson04/ardyn
Author-email: Ardyn Intelligence <sdk@ardyn.ai>
License-Expression: MIT
Keywords: ai,attestation,autonomous-systems,certification,liability,mcp,verification
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.9
Requires-Dist: httpx>=0.24.0
Provides-Extra: dev
Requires-Dist: pytest-asyncio>=0.21; extra == 'dev'
Requires-Dist: pytest>=7.0; extra == 'dev'
Requires-Dist: respx>=0.20; extra == 'dev'
Description-Content-Type: text/markdown

# Ardyn Python SDK

Official Python client for the [Ardyn Liability Verification Substrate](https://ardyn.ai) API.

## Installation

```bash
pip install ardyn
```

## Quick Start

> **New customer?** Create your account self-service — no Ardyn involvement required.
> See [Self-Service Onboarding](#self-service-onboarding) below to obtain your API key,
> then use it here.

```python
import asyncio
from ardyn import ArdynClient

async def main():
    async with ArdynClient(
        gateway_url="https://api.ardyn.ai",
        api_key="your-api-key",   # obtained from self-service onboarding (see below)
    ) as client:
        # Register an agent on AMD SEV-SNP hardware (production path)
        agent = await client.register_agent(
            platform="amd_sev_snp",
            capabilities=["sev_snp_report"],
            public_key="your-ed25519-public-key-hex",
        )
        print(f"Agent ID: {agent.agent_id}")

        # Activate the agent — self-service, no Ardyn approval required
        activated = await client.activate_agent(agent.agent_id)
        print(f"Agent status: {activated.status}")  # -> Active

        # Create an attestation (issues a DDC)
        attestation = await client.attest(
            tool_name="web_search",
            input_hash="sha256:abc123...",
            output_hash="sha256:def456...",
        )
        print(f"Attestation ID: {attestation.attestation_id}")
        print(f"DDC ID: {attestation.ddc_id}")

        # Verify a DDC (convenience — trusts the gateway)
        result = await client.verify(attestation.ddc_id)
        print(f"Valid: {result.valid}")

        # Trustless verify: re-derive the verdict from raw evidence
        # Requires the raw hardware report bytes — no trust in Ardyn.
        # Use the standalone ardyn-verify CLI:
        #   ardyn-verify --input ddc_response.json --allowlist allowlist.json

asyncio.run(main())
```

## Trustless Verification

The gateway's `verify()` is a convenience — it trusts the gateway. For cryptographic certainty,
use the standalone `ardyn-verify` CLI, which re-derives every claim from raw hardware evidence:

```bash
# Install the verifier (Rust binary)
cargo install ardyn-verify

# Verify a DDC offline — zero trust in Ardyn or any remote service
ardyn-verify --input ddc.json

# AMD SEV-SNP: trustless hardware re-verification with measurement allowlist
ardyn-verify --input ddc.json --allowlist measurements.json

# NVIDIA GPU CC: trustless GPU attestation re-verification
ardyn-verify --input ddc.json --nvidia-rim rim.json
```

The verifier checks:
- Issuer Ed25519 signature (pins the embedded public key)
- Schema version and provenance gate
- Hardware report re-verification (VCEK chain for AMD, device cert chain for NVIDIA)
- Measurement allowlist match
- Coherence score recomputation

**Where verification happens:**
| Path | Trust Model | Use Case |
|------|------------|----------|
| `client.verify(ddc_id)` | Trusts gateway | Quick check |
| `ardyn-verify --input` | Zero-trust local | Audit, compliance, court-admissible |
| `ardyn-verify --allowlist` | Trustless hardware | Prove execution on specific known-good code |

```

## Self-Service Onboarding

Create your account and obtain an API key without contacting Ardyn. The gateway
exposes public self-service onboarding endpoints:

```bash
# 1. Register — starts onboarding, sends a verification email + 2FA setup
curl -X POST https://api.ardyn.ai/onboarding/register \
  -H "Content-Type: application/json" \
  -d '{"email": "you@company.com", "organization": "My Company", "plan": "pro"}'

# 2. Verify email (link in the email) and verify 2FA to activate the tenant
curl -X POST https://api.ardyn.ai/onboarding/verify-2fa \
  -H "Content-Type: application/json" \
  -d '{"tenant_id": "<from step 1>", "code": "<TOTP code>"}'
# -> returns your api_key (unless payment is required, in which case next_step="payment")

# 3. Check status any time
curl https://api.ardyn.ai/onboarding/status/<tenant_id>
```

The returned `api_key` is what you pass to `ArdynClient(api_key=...)`. The
admin-only `register_tenant` method exists for internal/operator use only and is
**not** part of the customer onboarding path.

## Features

- **Async-first**: Built on `httpx` for modern async Python
- **Type-safe**: Full type annotations and dataclass models
- **Auto-retry**: Exponential backoff on transient failures (3 attempts: 1s, 2s, 4s)
- **Connection pooling**: Efficient HTTP/2 connection reuse
- **Comprehensive errors**: Typed exceptions for auth, not-found, validation, and server errors

## API Reference

### `ArdynClient`

```python
ArdynClient(
    gateway_url: str,        # Base URL of the Ardyn gateway
    api_key: str,            # API key for authentication
    timeout: float = 30.0,   # Request timeout in seconds
    max_retries: int = 3,    # Max retry attempts
)
```

### Methods

| Method | Description |
|--------|-------------|
| `register_tenant(name, config?)` | **Internal/operator use only** (admin route) — customers onboard via the self-service flow above |
| `register_agent(platform, capabilities, public_key, manifest_signature?, cert_fingerprint?)` | Register an agent |
| `activate_agent(agent_id)` | Activate your own agent (tenant self-service — no Ardyn approval) |
| `heartbeat(agent_id, status, uptime_secs, attestations_performed, agent_instance_id?)` | Send agent heartbeat |
| `attest(tool_name, input_hash, output_hash, metadata?)` | Create attestation |
| `submit_proof(request_id, agent_id, proof_type, proof_data, timestamp, signature, input_hash?, output_hash?)` | Submit proof |
| `verify(ddc_id)` | Verify a DDC |
| `get_usage(tenant_id)` | Get usage statistics |
| `get_settlement(tenant_id, period)` | Get settlement details |
| `get_dashboard(tenant_id)` | Get dashboard data |
| `health()` | Check gateway health |

### Error Types

- `ArdynError` - Base exception
- `AuthError` - Authentication failed (401/403)
- `NotFoundError` - Resource not found (404)
- `ValidationError` - Request validation failed (400/422)
- `ServerError` - Server error (5xx)

## Development

```bash
# Install dev dependencies
pip install -e ".[dev]"

# Run tests
pytest tests/
```

## License

MIT
