Metadata-Version: 2.4
Name: peaq-os-sdk
Version: 0.4.0
Summary: Python SDK for peaqOS, the operating system for the machine economy — on-chain identity, credit rating, and omnichain infrastructure for robots and machines.
Author-email: peaqOS <info@peaq.xyz>
License: Apache-2.0
Project-URL: Homepage, https://www.peaq.xyz
Project-URL: Documentation, https://docs.peaq.xyz
Project-URL: Repository, https://github.com/peaqnetwork/peaq-os-sdk-py
Project-URL: Issues, https://github.com/peaqnetwork/peaq-os-sdk-py/issues
Keywords: peaq,peaqos,peaq-os,machine-economy,depin,robotics,ai-agents,blockchain,omnichain,peaqid,did,machine-nft,machine-tokenization,machine-credit-rating,mcr,sdk,python
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: cryptography>=43.0.0
Requires-Dist: pycryptodome>=3.20.0
Requires-Dist: PyNaCl>=1.5.0
Requires-Dist: web3>=6.0
Requires-Dist: eth-account
Requires-Dist: requests
Requires-Dist: posthog>=3.0
Provides-Extra: ows
Requires-Dist: open-wallet-standard>=1.3.2; extra == "ows"
Provides-Extra: solana
Requires-Dist: solders>=0.21.0; extra == "solana"
Requires-Dist: solana>=0.36.0; extra == "solana"
Provides-Extra: p2p
Requires-Dist: libp2p<1.0,>=0.6.0; extra == "p2p"
Provides-Extra: x402
Requires-Dist: x402>=2.14.0; extra == "x402"
Provides-Extra: dev
Requires-Dist: pytest; extra == "dev"
Requires-Dist: pytest-cov; extra == "dev"
Requires-Dist: mypy; extra == "dev"
Requires-Dist: ruff; extra == "dev"
Requires-Dist: black; extra == "dev"
Requires-Dist: build; extra == "dev"
Requires-Dist: flake8; extra == "dev"
Requires-Dist: python-dotenv; extra == "dev"
Requires-Dist: solders>=0.21.0; extra == "dev"
Requires-Dist: solana>=0.36.0; extra == "dev"
Requires-Dist: x402>=2.14.0; extra == "dev"
Requires-Dist: open-wallet-standard>=1.3.2; extra == "dev"
Dynamic: license-file

# peaq-os-sdk

Python SDK for the peaqOS protocol. Provides a typed wrapper around the peaq on-chain capabilities so integrators can onboard machines, submit events, mint NFTs, and query credit ratings without writing raw `web3.py` boilerplate.

---

## Install

```bash
pip install peaq-os-sdk
```

Dependencies installed automatically: `web3`, `eth-account`, `requests`, `posthog`.

For OWS wallet management (optional):

```bash
pip install peaq-os-sdk[ows]
```

For Solana transaction signing via OWS (optional):

```bash
pip install peaq-os-sdk[ows,solana]
```

For Stream buyer SPL token payments (optional):

```bash
pip install peaq-os-sdk[solana]
```

The `solana` extra installs `solders` (native SOL transfers and signing) and `solana` (provides `spl.token` for SPL transfers such as USDC).

For P2P stream delivery (optional):

```bash
pip install peaq-os-sdk[p2p]
```

The `p2p` extra enables machine-to-machine P2P delivery via the `peaqos-p2p` transport (`P2PDeliveryChannel` seller, `P2PDeliveryReceiver` buyer).

### Solana signing from an OWS wallet

When `open-wallet-standard` and `solders` are installed, construct a standalone
Solana signer from a vault wallet that has a Solana account:

```python
from solders.hash import Hash
from solders.keypair import Keypair
from solders.message import Message
from solders.pubkey import Pubkey
from solders.system_program import TransferParams, transfer
from solders.transaction import Transaction

from peaq_os_sdk import PeaqosClient, SOLANA_MAINNET_CHAIN_ID

signer = PeaqosClient.solana_signer_from_wallet("my-wallet", "s3cret")
print(signer.address, signer.chain_id)  # chain_id == SOLANA_MAINNET_CHAIN_ID

from_pubkey = Pubkey.from_string(signer.address)
instruction = transfer(
    TransferParams(
        from_pubkey=from_pubkey,
        to_pubkey=Keypair().pubkey(),
        lamports=1_000,
    ),
)
message = Message.new_with_blockhash([instruction], from_pubkey, Hash.default())
tx = Transaction.new_unsigned(message)

signed = signer.sign_transaction(tx)
# broadcast with your Solana RPC client using signed.serialize()
```

By default (`ows_signing=True`), the ed25519 key is decrypted only per sign via OWS.
Pass `ows_signing=False` to decrypt at construction and sign locally with
`solders`. See [`docs/06_WALLET.md`](docs/06_WALLET.md) for details.

### Requirements

- Python `>= 3.10`
- A peaq RPC endpoint
- A funded wallet for the proxy operator (or for the machine itself, in self-managed mode)

---

## Quick start

```python
from peaq_os_sdk import PeaqosClient

client = PeaqosClient(
    rpc_url="https://peaq.api.onfinality.io/public",
    private_key="0xYOUR_PRIVATE_KEY",
    identity_registry="0x...",
    identity_staking="0x...",
    event_registry="0x...",
    machine_nft="0x...",
    did_registry="0x...",
    batch_precompile="0x...",
)

print("signer address:", client.address)
```

`PeaqosClient` is the only class consumers instantiate. All feature methods hang off it. The constructor performs synchronous validation and wires up the underlying `Web3` provider + signing account — no network I/O is issued at construction time.

[**Read More here >>**](docs/01_QUICK_START.md)

---

## MCR queries

Three read-only methods talk to the off-chain MCR API server at `client.api_url` (override via the `api_url` kwarg or `PEAQOS_MCR_API_URL`; defaults to `http://127.0.0.1:8000`). All three validate the DID prefix (`did:peaq:0x…`) locally and share a single `requests.Session` for connection pooling.

| Method | HTTP endpoint | Returns |
|---|---|---|
| `client.query_mcr(did)` | `GET /mcr/{did}` | `MCRResponse` TypedDict |
| `client.query_machine(did)` | `GET /machine/{did}` | `MachineProfileResponse` (NFT metadata JSON v1.0 as `dict[str, Any]`) |
| `client.query_operator_machines(did)` | `GET /operator/{did}/machines` | `OperatorMachinesResponse` |

`MCRResponse`:

```python
{
    "did": str,
    "machine_id": int,
    "mcr_score": int | None,    # 0–100, None if Provisioned
    "mcr": str,                 # "AAA" | "AA" | "A" | "BBB" | "BB" | "B" | "NR" | "Provisioned"
    "bond_status": str,         # "bonded" | "unbonded"
    "negative_flag": bool,      # active negative event flag
    "event_count": int,
    "revenue_event_count": int,
    "activity_event_count": int,
    "revenue_trend": str,       # "up" | "stable" | "down" | "insufficient"
    "total_revenue": float,
    "average_revenue_per_event": float,
    "last_updated": int | None,
}
```

`OperatorMachinesResponse` carries `operator_did`, a `machines` list of `{did, machine_id, mcr_score, mcr, negative_flag}` entries, and a `pagination` object. `MachineProfileResponse` returns structured NFT metadata with a validated `peaqos` sub-object. Every failure path is an `ApiError` with a stable `.code` (`NOT_FOUND`, `SERVICE_UNAVAILABLE`, `SERVER_ERROR`, `HTTP_ERROR`, `BAD_RESPONSE`, `TIMEOUT`, `NETWORK_ERROR`). See [docs/03_QUERIES.md](docs/03_QUERIES.md) for the full endpoint and error reference.

---

## Smart account deployment

ERC-4337 smart accounts are provisioned via the `MachineAccountFactory` contract using CREATE2 — the deployed address is deterministic from `(owner, machine, daily_limit, salt)`, so the same tuple always resolves to the same address.

| Method | On-chain | Returns |
|---|---|---|
| `client.get_smart_account_address(owner, machine, daily_limit, salt)` | view call — no gas | predicted address |
| `client.deploy_smart_account(owner, machine, daily_limit, salt)` | `createAccount` tx | deployed address |

Because CREATE2 is deterministic, `predicted == deployed` for the same inputs — callers can preview the address, pre-fund it, or display it in a UI before paying gas. Configure the factory address via the optional `machine_account_factory` kwarg on `PeaqosClient` or the `MACHINE_ACCOUNT_FACTORY_ADDRESS` env var. See [docs/04_SMART_ACCOUNTS.md](docs/04_SMART_ACCOUNTS.md) for parameter rules and receipt-decoding error codes.

---

## Cross-chain NFT bridging

Machine NFTs move between peaq and Base over LayerZero v2. Two chains are recognised today; direction is inferred from the `source` / `destination` arguments.

| Chain | `SUPPORTED_CHAINS` id | `LAYERZERO_EIDS` |
|---|---|---|
| `"peaq"` | 3338 | **30302** |
| `"base"` | 8453 | **30184** |

| Direction | Source contract | Effect | `dstEid` |
|---|---|---|---|
| peaq → base | `MachineNFTAdapter` on peaq | NFT locked on peaq, minted on Base | `30184` |
| base → peaq | `MachineNFTBase` on Base | NFT burned on Base, unlocked on peaq | `30302` |

`client.bridge_nft(...)` estimates the LayerZero messaging fee via `quoteSend` **before** broadcasting and attaches that fee as `msg.value` on the actual `send` transaction so the message is correctly paid for. `PeaqosClient.wait_for_bridge_arrival(...)` is a static method (no client instance needed) that polls `MachineNFT.ownerOf(token_id)` on the destination every 10 seconds and returns `True` on arrival or `False` at timeout (default 300 s). See [docs/05_BRIDGE.md](docs/05_BRIDGE.md) for the full walkthrough including `options` handling, Base-source setup, and the complete error-code table.

---

## Telemetry

The SDK collects anonymous, aggregate usage telemetry via PostHog to measure install counts, onboarding success rates, and MCR query volume. **No PII is collected** — GeoIP is disabled, IP addresses are nulled, and all UUIDs are randomly generated.

Telemetry is enabled by default and can be disabled via environment variables:

| Env var | Effect |
|---|---|
| `DO_NOT_TRACK=1` | Disables telemetry unconditionally (industry standard) |
| `PEAQOS_TELEMETRY=0` | Disables telemetry (project-specific toggle) |

`DO_NOT_TRACK=1` always takes precedence. When telemetry is disabled, no PostHog client is created and no events are sent.

Analytics events are captured automatically from existing SDK methods — no additional API calls are needed:

```python
client = PeaqosClient(...)                         # peaqos_sdk_initialize (first install only)
addr, key = PeaqosClient.generate_keypair()        # peaqos_sdk_generate_keypair (via active instance)
machine_id = client.register_machine()             # peaqos_sdk_generate_wallet
tx = client.write_machine_did_attributes(...)      # peaqos_sdk_generate_did
tx = client.mint_nft(machine_id, addr)             # peaqos_sdk_generate_nft
mcr = client.query_mcr("did:peaq:0x...")           # peaqos_sdk_mcr_request
client.close()                                     # flush queued events
```

All analytics calls are fire-and-forget — they never block or raise. See [docs/10_ANALYTICS.md](docs/10_ANALYTICS.md) for the full event reference and privacy details.

---

## Documentation

Per-feature deep-dives live under [`docs/`](docs/):

- [**Quick Start**](docs/01_QUICK_START.md) — client initialization, configuration, environment variables, types, exception classes, validation, utilities, and constants.
- [**Machine identity & registration**](docs/02_REGISTRATION.md) — faucet 2FA enrollment, gas-station funding, self-managed and proxy-managed registration. Includes the full faucet error reference and the on-chain revert mapping.
- [**MCR queries**](docs/03_QUERIES.md) — `query_mcr`, `query_machine`, `query_operator_machines`, response shapes, rating tiers, and the full HTTP error-code table.
- [**Smart account deployment**](docs/04_SMART_ACCOUNTS.md) — `deploy_smart_account` and `get_smart_account_address`, CREATE2 determinism, parameter rules, and receipt-decoding error codes.
- [**Cross-chain NFT bridging**](docs/05_BRIDGE.md) — `bridge_nft` direction handling (peaq ↔ Base via LayerZero v2), supported chain IDs and LayerZero EIDs, LayerZero fee estimation, and `wait_for_bridge_arrival` polling semantics.
- [**Event submission**](docs/03_EVENTS.md) — single and batch event submission, pipeline details, limits, hashing, metadata mode, and rate-limiting behavior.
- [**NFT minting & DID attributes**](docs/04_NFT_AND_DID.md) — minting machine NFTs, querying token IDs, writing machine and proxy DID attributes atomically via the Batch precompile. Covers attribute key reference, data visibility options, and the atomic batch guarantee.
- [**OWS wallet lifecycle**](docs/06_WALLET.md) — create, import, list, get, export, and delete encrypted wallets via the Open Wallet Standard. Multi-chain accounts, passphrase management, vault storage, OWS-native EVM signing via `from_wallet()`, and Solana signing via `solana_signer_from_wallet()`.
- [**Orchestration service**](docs/07_ORCHESTRATION.md) *(experimental)* — `client.orchestration`, policies, observability, market lifecycle, pagination, challenge-sign workflows, planned type stubs, and live integration tests.
- [**Stream data signing & encryption**](docs/08_STREAM.md) *(experimental)* — local field-level privacy rules, EIP-191 data package signing, and verification (Phase 2 Step 2; no network/distribution).
- [**Stream data chunking**](docs/09_CHUNKING.md) *(experimental)* — per-chunk XChaCha20-Poly1305 encryption, inline Ed25519 signatures, owner/operator/machine key wrapping, and separate buyer access docs; `build_chunk_chain` / `verify_chunk_chain` / `decrypt_chunk` / `create_buyer_access_entry` / `build_buyer_access_files`.
- [**Analytics & telemetry**](docs/10_ANALYTICS.md) — anonymous usage telemetry, event inventory, opt-out, privacy guarantees, and onboarding flow integration.
- [**Stream distribution**](docs/11_DISTRIBUTION.md) *(experimental)* — seller-side payment confirmation and delivery (`distribute_data`, `PollingConfirmationProvider`, `S3DeliveryChannel`) plus buyer-side token payment (`transfer_token`, `submit_payment_proof`, `pay_and_submit_proof`) on peaq, Base, and Solana.
- [**P2P delivery**](docs/14_P2P_DELIVERY.md) *(experimental)* — machine-to-machine delivery via the `peaqos-p2p` transport: `P2PDeliveryChannel` (seller) and `P2PDeliveryReceiver` (buyer) with verify-before-decrypt chunk reception, session routing, and replay protection.
- [**Stream delivery setup**](docs/12_STREAM_DELIVERY_SETUP.md) *(in development)* — pre-purchase payment rails discovery, delivery transports discovery, delivery capability registration, and stream listing purchase field updates.
- [**Stream purchases**](docs/13_STREAM_PURCHASES.md) *(in development)* — full purchase lifecycle: creation with buyer identity, payment intent, payment proof, delivery retrieval, and purchase events.

---

## Development

```bash
git clone https://github.com/peaqnetwork/peaq-os-sdk-py.git
cd peaq-os-sdk-py
python3 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
```

### Activate `.env` for Testing
```
set -a
source .env
set +a
```

### Quality gates

```bash
ruff check src tests       # lint — zero warnings
black --check src tests    # formatting
mypy src                   # strict type check, zero errors
pytest -q                  # all green
```

The unit tests are hermetic — they mock `Web3` and `requests.Session` with handwritten stubs and never touch the network.

### Optional integration tests

The repo ships an opt-in suite that talks to a real peaq devnet. It is skipped silently in normal `pytest -q` and only runs when the required environment variables are supplied.

**Registration integration suite** ([`tests/integration/registration/test_registration_integration.py`](tests/integration/registration/test_registration_integration.py)) — three end-to-end tests for the self-managed flow, proxy-managed flow, and double-registration revert. Gated behind the `integration` marker plus seven environment variables:

```bash
PEAQOS_RPC_URL=https://peaq.api.onfinality.io/public
PEAQOS_PRIVATE_KEY=0xYOUR_FUNDED_TREASURY_KEY
IDENTITY_REGISTRY_ADDRESS=0xYOUR_DEPLOYED_REGISTRY_ADDRESS
IDENTITY_STAKING_ADDRESS=0xYOUR_DEPLOYED_STAKING_ADDRESS
PEAQOS_OWNER_ADDRESS=5GrwvaEF...
PEAQOS_FAUCET_URL=https://depinstation.peaq.xyz
PEAQOS_2FA_CODE=123456
```

```bash
pytest -m integration tests/integration/
```

See [docs/02_REGISTRATION.md → Integration tests](docs/02_REGISTRATION.md#integration-tests) for the full breakdown of what each test verifies and operational warnings.

**NFT & DID integration suite** ([`tests/integration/nft_did/test_nft_and_did_integration.py`](tests/integration/nft_did/test_nft_and_did_integration.py)) — end-to-end tests for the full NFT lifecycle, atomic DID writes, and atomicity guarantee verification (all-or-nothing batch semantics). Includes 7 tests across minting, token queries, machine DID attributes, proxy DID attributes, and atomic revert scenarios. Requires the same env vars as the registration suite plus:

```bash
EVENT_REGISTRY_ADDRESS=0x...
MACHINE_NFT_ADDRESS=0x...
DID_REGISTRY_ADDRESS=0x0000000000000000000000000000000000000800
BATCH_PRECOMPILE_ADDRESS=0x0000000000000000000000000000000000000805
```

See [docs/04_NFT_AND_DID.md](docs/04_NFT_AND_DID.md) for the full breakdown.

**OWS wallet integration suite** ([`tests/integration/wallet/test_wallet_integration.py`](tests/integration/wallet/test_wallet_integration.py)) — six end-to-end tests for wallet lifecycle (create, list, get, delete), create-export-reimport round-trip, private key import, empty vault, and error paths. Gated behind `PEAQOS_INTEGRATION=1` and requires the `open-wallet-standard` package:

```bash
pip install peaq-os-sdk[ows]
PEAQOS_INTEGRATION=1 pytest -m integration tests/integration/wallet/
```

See [docs/06_WALLET.md](docs/06_WALLET.md) for the full wallet API reference.

**Orchestration live API suite** ([`tests/integration/orchestration/test_orchestration_integration.py`](tests/integration/orchestration/test_orchestration_integration.py)) — health, readiness, machine lifecycle, market lifecycle, policy CRUD, and audit-event listing against a real orchestration deployment. Gated behind `PEAQOS_ORCHESTRATION_INTEGRATION=1`:

```bash
PEAQOS_ORCHESTRATION_INTEGRATION=1
PEAQOS_ORCHESTRATION_URL=https://markets.peaq.xyz
PEAQOS_API_KEY=your-platform-api-key
pytest -m integration tests/integration/orchestration/test_orchestration_integration.py
```

Optional overrides: `PEAQOS_ORCHESTRATION_PROVIDER_KEY`, `PEAQOS_ORCHESTRATION_ENDPOINT_URL`, `PEAQOS_ORCHESTRATION_MARKET_SERVICE_TYPE`, `PEAQOS_ORCHESTRATION_MARKET_OPERATION`, `PEAQOS_ORCHESTRATION_MARKET_ORDER_INPUT` (JSON object), `PEAQOS_ORCHESTRATION_MARKET_PAYMENT_RAIL`. See [docs/07_ORCHESTRATION.md → Integration tests](docs/07_ORCHESTRATION.md#integration-tests).

A separate **mocked** market lifecycle test lives in [`tests/integration/orchestration/test_market_lifecycle_integration.py`](tests/integration/orchestration/test_market_lifecycle_integration.py) and runs without orchestration env vars.

`PEAQOS_PRIVATE_KEY` must match `^0x[0-9a-fA-F]{64}$`. **Never commit a real key. Never run the suite against mainnet.**

### Build

```bash
python -m build
```

Produces `dist/peaq_os_sdk-<version>-py3-none-any.whl` and `dist/peaq_os_sdk-<version>.tar.gz` for downstream testing.

## License

See [LICENSE](./LICENSE) for details.
