Metadata-Version: 2.5
Name: flop-sdk
Version: 0.2.0
Summary: FLOP Network SDK for Python - HTLC workflows, PoUI proofs, and account management
Project-URL: Homepage, https://github.com/flop-labs/flop-core
Project-URL: Documentation, https://github.com/flop-labs/flop-core/docs
Project-URL: Repository, https://github.com/flop-labs/flop-core
Author-email: FLOP Network <dev@flop.network>
License: MIT OR Apache-2.0
License-File: LICENSE
Keywords: ai,blockchain,flop,htlc,inference,substrate,tee
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Libraries
Requires-Python: >=3.10
Requires-Dist: aiohttp>=3.9.0
Requires-Dist: langfuse<3,>=2.0.0
Requires-Dist: pydantic>=2.0.0
Requires-Dist: substrate-interface>=1.0.0
Requires-Dist: typing-extensions>=4.0.0
Provides-Extra: dev
Requires-Dist: pytest-asyncio>=0.21.0; extra == 'dev'
Requires-Dist: pytest-cov>=4.1.0; extra == 'dev'
Requires-Dist: pytest>=7.4.0; extra == 'dev'
Requires-Dist: ruff>=0.1.0; extra == 'dev'
Requires-Dist: ty==0.0.85; extra == 'dev'
Description-Content-Type: text/markdown

# flop-sdk

Ordinary HTLC creation requires a registered EconomicCritical appraisal profile.
Supply `tee_requirements` / `teeRequirements` as `{profile: {profile_id, version}, model_hash, measurement_hash}` (32-byte hex hashes), or its canonical 100-byte SCALE hex.
The runtime checks that the registered profile and immutable commitments match its policy; there is no simulator default.
For the examples, set `FLOP_HTLC_TEE_REQUIREMENTS` to that canonical hex from your network's registered profile.

FLOP Network SDK for Python — HTLC workflows, PoUI proofs, and account management.

`SUPPORTED_SPEC_VERSIONS` admits exactly `1013000`, `1014000` through `1014005`, and `1014007`
through `1014011`. `SUPPORTED_SPEC_VERSION_RANGE` retains its exported shape as the envelope
`1013000..1014011`; versions inside it that are not listed, `1014006` among them, are not
admitted. Qualification covers
runtime `1013000` at `44a5fedc88614b9a6e8c97605c2ec943faf47d9d`, the
registrar runtime `1014000` at `e4f01cc849fa6c768d5c0f9c111dffb450ea4fa9`
(PR #2726), runtime `1014001` at `de4e2779dbf6f8d25348953ce0992ef8e89756bd`
(PR #2803), runtime `1014002`, the #2637 devnet hybrid-verifier fast path, and runtime
`1014003` at `9035450361681a69c6c02c9c53e47351999ef6f8` (PR #3096). Candidate runtime
`1014004` (1.14.4, PR #3006) has source compatibility coverage for uploader-funded
qualification. Candidate runtime `1014005` (1.14.5) has source compatibility coverage for the
preactivation FCU name replacement. Candidate runtimes `1014007` (1.14.7, integer accounting,
transaction version 2) through `1014011` (funding-time FCU economic snapshots) have source
compatibility coverage for the preactivation FCU accounting, resale and activation changes.
Source coverage does not qualify physical latency or deployment.
Other versions require separate qualification.
`FlopClient` checks on connect and before each HTTP RPC because HTTP has no
runtime-upgrade subscription. `SubstrateClient` checks on connect, before metadata
refresh/signing, and again before submission, including for cached signed extrinsics.
An unsupported runtime raises `FLOPError` with code `RUNTIME_INCOMPATIBLE` and the
qualified versions. Upgrade with `uv pip install --upgrade flop-sdk` to a release
that supports the chain's runtime; allowlist changes require compatibility validation.

## Installation

```bash
pip install flop-sdk
```

### Development Dependencies

```bash
pip install flop-sdk[dev]
```

## Quick Start

```python
import asyncio
import os
from flop_sdk import FlopClient, SubstrateClient, generate_htlc_secrets


async def main():
    # Connect to FLOP node
    async with FlopClient() as client:
        # Check node health
        health = await client.health()
        print(f"Node healthy: {not health.is_syncing}")

        # Generate HTLC secrets
        pre_image, hash_lock = generate_htlc_secrets()

        signer = SubstrateClient()
        htlc_id, tx_hash = signer.create_htlc(
            agent="my-agent",
            task={
                "model": "llama-3-8b",
                "prompt": "Hello",
                "tee_requirements": os.environ["FLOP_HTLC_TEE_REQUIREMENTS"],
            },
            hash_lock=hash_lock,
            reward_amount=5.0,
            timeout_blocks=60,
        )
        signer.close()
        print(f"HTLC submitted: {htlc_id}, tx: {tx_hash}")

        # Query the submitted HTLC
        status = await client.check_htlc_status(hash_lock)
        print(f"HTLC status: {status.status if status else 'not found'}")

        # Wait for settlement after a signed submission
        status = await client.wait_for_settlement(hash_lock, timeout_seconds=30)

        if status:
            print(f"Settled by: {status.miner}")
            print(f"G_n used: {status.gn_used}")
        else:
            print("Timeout - funds refunded")


asyncio.run(main())
```

## Substrate Client (Signed Transactions)

For on-chain operations requiring signed transactions, use `SubstrateClient`. It signs locally and submits through `author_submitExtrinsic`; the HTTP `FlopClient` only queries HTLC state.

```python
import os
from flop_sdk import SubstrateClient, SubstrateOptions, create_agent_wallet, generate_htlc_secrets

# Initialize with account seed
client = SubstrateClient(SubstrateOptions(rpc_url="http://127.0.0.1:16111", seed="alice"))

print(f"Account: {client.address}")
print(f"Balance: {client.get_balance()} FLOP")

# Create HTLC on-chain
pre_image, hash_lock = generate_htlc_secrets()
htlc_id, tx_hash = client.create_htlc(
    agent="my-agent",
    task={
        "model": "llama-3-8b",
        "prompt": "Hello",
        "tee_requirements": os.environ["FLOP_HTLC_TEE_REQUIREMENTS"],
    },
    hash_lock=hash_lock,
    reward_amount=5.0,
    timeout_blocks=60,
)

print(f"HTLC: {htlc_id}, TX: {tx_hash}")

# Redeem HTLC (miner side)
tee_quote = {"version": "1.0", "gn_weight": 1450, "attestation": "deadbeef"}
tx_hash = client.redeem_htlc(htlc_id, pre_image, tee_quote)
print(f"Redeemed: {tx_hash}")

client.close()
```

## Agent Wallet & Session Keys

```python
from flop_sdk import (
    SubstrateClient,
    create_agent_wallet,
    fund_agent_wallet,
    create_session,
    execute_via_session,
)

client = SubstrateClient(seed="alice")

# Create agent wallet with spending limits
wallet = create_agent_wallet(
    client,
    agent_id="trading-agent-01",
    daily_limit=100.0,
    allowed_pallets=["htlc", "poui"],
)

# Fund the wallet
tx_hash = fund_agent_wallet(client, wallet.address, 50.0)

# Create session key for delegated access
session = create_session(
    client,
    wallet.address,
    spending_limit=10.0,
    expires_in_seconds=3600,  # 1 hour
)

# Execute via session (no need for full key)
tx_hash = execute_via_session(
    client,
    session.session_key,
    pallet="HasStation",
    method="create_htlc",
    args={...},
)
```

## API Reference

### FlopClient (Async HTTP)

High-level async HTTP client for RPC queries.

```python
async with FlopClient(
    options=FlopClientOptions(
        rpc_url="http://127.0.0.1:16111/rpc",
    )
) as client:
    # Health check
    health = await client.health()

    # Get balance
    balance = await client.get_balance("flop1qyq...")

    # Check HTLC status
    status = await client.check_htlc_status(hash_lock)

    # Wait for settlement
    settled = await client.wait_for_settlement(hash_lock, timeout_seconds=30)

    # Get account info
    info = await client.get_account_info("flop1qyq...")

    # HTLC writes require SubstrateClient (below)
```

### SubstrateClient (Signed Transactions)

Low-level Substrate client for on-chain operations.

```python
client = SubstrateClient(
    rpc_url="http://127.0.0.1:16111",
    seed="alice",  # or mnemonic, or //Alice format
)

# Account info
print(f"Address: {client.address}")
print(f"Balance: {client.get_balance()} FLOP")

# HTLC operations
htlc_id, tx_hash = client.create_htlc(...)
tx_hash = client.redeem_htlc(htlc_id, pre_image, tee_quote)
status = client.check_htlc_status(hash_lock)

client.close()
```

### Wallet Functions

```python
# Create agent wallet
wallet = create_agent_wallet(client, agent_id, daily_limit=100.0)

# Fund wallet
fund_agent_wallet(client, wallet.address, amount)

# Transfer between wallets
agent_transfer(client, from_wallet, to_address, amount)

# Withdraw to owner
owner_withdraw(client, wallet.address, amount)

# Session management
session = create_session(client, wallet.address, spending_limit=10.0)
revoke_session(client, session.session_key)
execute_via_session(client, session.session_key, pallet, method, args)
```

### Utilities

```python
from flop_sdk import (
    generate_htlc_secrets,
    sign_message,
    format_flop,
    flop_to_raw,
    raw_to_flop,
    format_address,
    validate_address,
    generate_agent_id,
)

# Generate HTLC secrets
pre_image, hash_lock = generate_htlc_secrets()

# Format amounts
print(format_flop(5.0))  # "5.00 FLOP"
print(flop_to_raw(5.0))  # 5000000000000000000
print(raw_to_flop(5000000000000000000))  # 5.0

# Address utilities
print(format_address("flop1qyq...z9a"))  # "flop1qyq...z9a"
print(validate_address("flop1qyq..."))  # True

# Generate agent ID
agent_id = generate_agent_id("trader")  # "trader_1234567890_abcd1234"
```

## Types

```python
from flop_sdk import (
    HtlcStatus,
    ComputeTask,
    HtlcInfo,
    CreateHtlcResult,
    HealthResponse,
    AccountInfo,
    WalletInfo,
    SessionInfo,
)

# HTLC status enum
status = HtlcStatus.CREATED  # or SETTLED, REFUNDED

# Compute task
task = ComputeTask(
    model="llama-3-8b",
    prompt="Hello, world!",
    max_tokens=100,
    temperature=0.7,
)

# HTLC info
htlc = HtlcInfo(
    htlc_id="htlc_abc123",
    hash_lock="0x...",
    status=HtlcStatus.SETTLED,
    agent="my-agent",
    reward_amount=5.0,
    timeout_block=160,
    miner="flop1qyq...",
    gn_used=1450.75,
)
```

## Error Handling

```python
import os
from flop_sdk import SubstrateClient, generate_htlc_secrets

client = SubstrateClient()
_, hash_lock = generate_htlc_secrets()
try:
    htlc_id, tx_hash = client.create_htlc(
        agent="my-agent",
        task={
            "model": "llama-3-8b",
            "prompt": "Hello",
            "tee_requirements": os.environ["FLOP_HTLC_TEE_REQUIREMENTS"],
        },
        hash_lock=hash_lock,
        reward_amount=5.0,
    )
except Exception as e:
    print(f"Signed extrinsic submission failed: {e}")
finally:
    client.close()
```

## Complete Example

```python
import asyncio
from flop_sdk import (
    FlopClient,
    SubstrateClient,
    create_agent_wallet,
    fund_agent_wallet,
    generate_htlc_secrets,
)


async def main():
    # Async client for queries
    async with FlopClient() as rpc_client:
        # Check node health
        health = await rpc_client.health()
        print(f"✓ Node synced: {not health.is_syncing}")

    # Substrate client for transactions
    client = SubstrateClient(rpc_url="http://127.0.0.1:16111", seed="alice")

    print(f"✓ Connected: {client.address}")
    print(f"✓ Balance: {client.get_balance()} FLOP")

    # Create agent wallet
    wallet = create_agent_wallet(
        client,
        agent_id="trading-agent-01",
        daily_limit=100.0,
    )
    print(f"✓ Wallet created: {wallet.address}")

    # Fund wallet
    fund_agent_wallet(client, wallet.address, 50.0)
    print(f"✓ Wallet funded")

    # Generate HTLC secrets
    pre_image, hash_lock = generate_htlc_secrets()

    # Create HTLC on-chain
    htlc_id, tx_hash = client.create_htlc(
        agent="trading-agent-01",
        task={"model": "llama-3-8b", "prompt": "Analyze BTC trend"},
        hash_lock=hash_lock,
        reward_amount=5.0,
        timeout_blocks=60,
    )
    print(f"✓ HTLC created: {htlc_id}")
    print(f"✓ Transaction: {tx_hash}")

    # Check status
    status = client.check_htlc_status(hash_lock)
    print(f"✓ Status: {status['status']}")

    client.close()


if __name__ == "__main__":
    asyncio.run(main())
```

## Development

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

# Run tests
pytest

# Run tests with coverage
pytest --cov=src/

# Format code
black src/ tests/
ruff check --fix src/ tests/

# Type checking
mypy src/

# Run all checks
ruff format --check . && ruff check . && ty check src examples && pytest
```

## Requirements

- Python 3.10+
- aiohttp>=3.9.0 (async HTTP)
- substrate-interface>=1.0.0 (Substrate RPC)
- pydantic>=2.0.0 (data validation)

## NVIDIA GPU Operators

For miners operating NVIDIA GPUs to earn rewards, see the complete guide:

- **[NVIDIA GPU Operator SDK Guide](../../docs/NVIDIA_GPU_OPERATOR_SDK.md)** - Complete SDK guide for NVIDIA H100/H200/Blackwell with TEE attestation
- [Miner Guide](../../docs/MINER_GUIDE.md) - General mining setup and workflows

Quick example for GPU operators:

```python
from flop_sdk import SubstrateClient
from flop_sdk.tee import NvidiaTeeBridge, generate_tee_quote

# Initialize miner client
client = SubstrateClient(rpc_url="http://127.0.0.1:16111", seed="//Miner")
tee_bridge = NvidiaTeeBridge(simulator_mode=True)  # Set False for production

# Monitor for HTLCs
htlc = client.check_htlc_status(hash_lock)
if htlc and htlc.status == "CREATED":
    # Execute inference on NVIDIA GPU
    result = execute_on_gpu(htlc.task)  # Your GPU execution logic
    
    # Generate TEE quote
    tee_quote = generate_tee_quote(
        miner_address=client.address,
        htlc_hash_lock=htlc.hash_lock,
        model_hash=htlc.task["model"],
        gn_weight=result.gn_weight,
        tee_type="NVIDIA_HOPPER_CC",  # or "NVIDIA_RUBIN_CC", "CPU_WRAPPED_TEE"
    )
    
    # Redeem HTLC with TEE quote
    tx_hash = client.redeem_htlc(
        htlc_id=htlc.htlc_id,
        pre_image=pre_image,
        tee_quote=tee_quote,
    )
    print(f"✓ HTLC redeemed: {tx_hash}")
    
    # Submit PoUI proof batch (optional, for additional rewards)
    proofs = generate_stark_proofs(result)
    task_hash = generate_task_hash(htlc)
    tx_hash = client.submit_poui(proofs, result.gn_weight, task_hash)
    print(f"✓ PoUI proof submitted: {tx_hash}")
```

### TEE Quote Format

```python
tee_quote = {
    "version": "1.0",
    "miner_address": "flop1...",
    "task_reference": {
        "htlc_hash_lock": "0x...",
        "model_hash": "sha256:...",
        "task_timestamp": 1234567890,
    },
    "compute_output": {
        "gn_weight": 1450.0,  # G_n weight (BFLOPs)
        "execution_time_ms": 435,
        "encrypted_result": "0x...",
    },
    "attestation": {
        "tee_type": "NVIDIA_HOPPER_CC",
        "hardware_pubkey": "0x...",
        "quote_hex": "0x...",  # Raw TEE quote
        "signature": "0x...",  # Miner signature
    },
}
```

### Supported TEE Types

| TEE Type | Hardware | Production Ready |
|----------|----------|------------------|
| `NVIDIA_HOPPER_CC` | H100, H200 | ✅ Yes |
| `NVIDIA_RUBIN_CC` | B100, B200 | ✅ Yes |
| `CPU_WRAPPED_TEE` | RTX 4090+ + AMD SEV/Intel TDX | ⚠️ Testnet only |

### TEE Verification

The `NvidiaTeeBridge` validates TEE quotes with:

- **Timestamp freshness:** Quotes must be < 60 seconds old
- **Signature verification:** Validates miner signature
- **Replay protection:** Tracks task hashes to prevent double-spending
- **Hardware verification:** Checks hardware keys against registry (production only)

```python
from flop_sdk.tee import NvidiaTeeBridge, PouiPayload

bridge = NvidiaTeeBridge(simulator_mode=False)

# Register known hardware keys (production)
bridge.register_hardware_key("0x...")

# Verify TEE quote
payload: PouiPayload = parse_tee_quote(quote_json)
result = bridge.verify(payload)

if result.valid:
    print(f"✓ TEE verified: {result.gn_weight} G_n")
else:
    print(f"✗ Verification failed: {result.error}")
```

For complete setup instructions, hardware requirements, and production deployment guide:

- **[NVIDIA GPU Operator SDK Guide](../../docs/NVIDIA_GPU_OPERATOR_SDK.md)** - Complete API reference, dstack integration, production workflows
- **[NVIDIA GPU Operator Guide](../../docs/tutorials/NVIDIA_GPU_OPERATOR_GUIDE.md)** - Hardware setup, TEE configuration, monitoring

## License

Apache-2.0 © FLOP Network

## Links

- [FLOP Network Documentation](https://github.com/flop-labs/flop-core)
- [RPC API Reference](../../docs/RPC_API.md)
- [TypeScript SDK](../typescript/README.md)
