Skip to main content

Python CLI for peaqOS, the operating system for the machine economy — on-chain identity, credit rating, and omnichain infrastructure for robots and machines.

Project description

peaq-os-cli

Python CLI for peaqOS. Describes install and the console entry point.

Install

python3 -m venv .peaq-os-cli
source .peaq-os-cli/bin/activate
pip install -e ".[dev]"

Run Tests

pytest

Quality Gates

ruff check src tests
black --check src tests
mypy src
pytest -q --cov=src/peaq_os_cli --cov-fail-under=90
flake8 src tests

Console usage

The peaqos script invokes the Click root group in peaq_os_cli.main.

peaqos --help
peaqos --version

Authoritative option text for any subcommand is always available via built-in help:

peaqos <command> -h
peaqos qualify event -h
peaqos qualify mcr -h

Commands

peaqos init

Interactive wizard that writes a .env file in the current working directory.

peaqos init                    # interactive (network, key, URLs, contract addresses)
peaqos init --non-interactive  # read all values from environment variables
peaqos init --force            # overwrite existing .env without confirmation

Example (interactive):

Network (mainnet, testnet) [mainnet]: mainnet
Private key source (paste, generate, wallet): generate
  Address:  0xAbCd...1234
  Key:      0xdeadbeef...
IMPORTANT: Save this private key securely. It will not be shown again.
RPC URL [https://peaq.api.onfinality.io/public]:
MCR API URL [https://mcr.peaq.xyz]:
Gas Station URL [https://depinstation.peaq.xyz]:
Event Registry address: 0xEe6f...78aB
  Config: .env written to /home/operator/project/.env

  Running whoami to verify...
  Address :  0xAbCd...1234
  Network :  mainnet
  RPC URL :  https://peaq.api.onfinality.io/public
  Chain ID:  3338
  MCR API :  https://mcr.peaq.xyz

  Contracts:
    IdentityRegistry:  0x9075...0B6A
    IdentityStaking :  0x7d39...9B8E
    EventRegistry   :  0xEe6f...78aB
    MachineNFT      :  0xaF13...Bd61
    DID Registry    :  0x0000...0800
    Batch Precompile:  0x0000...0805

peaqos whoami

Show the active wallet address, network, chain ID, and all contract addresses.

peaqos whoami

Example:

  Address :  0xAbCd...1234
  Network :  mainnet
  RPC URL :  https://peaq.api.onfinality.io/public
  Chain ID:  3338
  MCR API :  https://mcr.peaq.xyz

  Contracts:
    IdentityRegistry:  0x9075...0B6A
    IdentityStaking :  0x7d39...9B8E
    EventRegistry   :  0xEe6f...78aB
    MachineNFT      :  0xaF13...Bd61
    DID Registry    :  0x0000...0800
    Batch Precompile:  0x0000...0805

peaqos wallet

Manage OWS (Open Wallet Standard) wallets in the local encrypted vault (~/.ows/). Requires the optional OWS dependency: pip install peaq-os-cli[ows].

peaqos wallet create <name> [--words 12|24] [--json]
peaqos wallet import <name> (--mnemonic | --private-key-file <path>) [--index <n>] [--json]
peaqos wallet list [--json]
peaqos wallet show <name-or-id> [--json]
peaqos wallet export <name-or-id>
peaqos wallet delete <name-or-id>
peaqos wallet use <name-or-id>

wallet create — Generate a new mnemonic-backed wallet. Displays addresses for all supported chains (peaq, Base, Ethereum, Solana, Bitcoin, Cosmos, etc.). The mnemonic is never shown; use wallet export to retrieve it.

peaqos wallet create my-machine
peaqos wallet create my-machine --words 24   # 24-word mnemonic
peaqos wallet create my-machine --json       # JSON output

wallet import — Import an existing wallet from a BIP-39 mnemonic (hidden prompt) or a private key file.

peaqos wallet import recovered --mnemonic
peaqos wallet import from-file --private-key-file ./operator.key

wallet list — List all wallets in the vault. Shows Name, ID, peaq Address, Key Type, and Created date.

peaqos wallet list
peaqos wallet list --json   # full WalletInfo array

wallet show — Display full wallet details with addresses for every supported chain family.

peaqos wallet show operator
peaqos wallet show operator --json

wallet export — Export the recovery phrase or private key (requires confirmation).

peaqos wallet export my-machine

wallet delete — Securely delete a wallet from the vault (requires confirmation).

peaqos wallet delete my-machine

wallet use — Set a wallet as the active default by writing PEAQOS_OWS_WALLET to .env. Subsequent commands use this wallet via load_client().

peaqos wallet use operator

Migration from raw keys:

peaqos wallet import my-operator --private-key-file ./operator.key
peaqos wallet use my-operator
peaqos whoami   # address matches the original key

peaqos activate

Run the full machine onboarding flow end-to-end. Six steps: balance check → 2FA enrollment → gas-station funding → register on IdentityRegistry → mint machine NFT → write DID attributes.

Two modes:

  • Self-managed — no proxy flags. The caller's own key signs every step and holds the resulting NFT.
  • Proxy-managed--for <machine-address> --machine-key <path> together. The operator funds and submits register / mint on behalf of the machine, then the machine key signs its own DID attributes (the peaq DID precompile enforces msg.sender == didAccount). The machine EOA holds the resulting NFT. Both flags are required together; supplying one alone is rejected with exit 1.
peaqos activate                                          # self mode
peaqos activate --for 0xMachine --machine-key ./m.key    # proxy mode

Flags:

Flag Purpose
--for Machine EOA address. Presence switches to proxy mode.
--machine-key Path to a file with the machine's 0x-prefixed hex private key.
--doc-url Documentation URL written to the machine DID.
--data-api Raw data API URL written to the machine DID.
--visibility public (default) / private / onchain.
--skip-funding Skip balance check, 2FA, and gas-station funding (steps 1–3).

Private keys must be supplied via file path (--machine-key). Inline key flags are intentionally unsupported — reading from a file keeps the key out of shell history and ps output.

Environment:

Connection / caller identity:

Variable Purpose
PEAQOS_PRIVATE_KEY Operator private key (self or proxy mode caller).
PEAQOS_NETWORK mainnet or testnet.
PEAQOS_RPC_URL Override the default RPC endpoint for the network.
PEAQOS_GAS_STATION_URL Gas-station base URL for steps 2–3.

Contract addresses (all required — missing any yields exit 3):

Variable Contract
IDENTITY_REGISTRY_ADDRESS IdentityRegistry (step 4 register).
IDENTITY_STAKING_ADDRESS Identity staking contract.
EVENT_REGISTRY_ADDRESS Event registry contract.
MACHINE_NFT_ADDRESS Machine NFT (step 5 mint).
DID_REGISTRY_ADDRESS DID registry contract.
BATCH_PRECOMPILE_ADDRESS peaq batch precompile (step 6 batched DID writes).

Idempotent rerun. Every mutating step does a read-before-write precheck: registration consults machineIdOfOwner, mint consults token_id_of + NFT ownerOf, DID writes consult readAttribute. Re-running activate against on-chain state that is already complete submits no transactions and exits 0. A TOCTOU revert (AlreadyRegistered / AlreadyExists) is also recovered as skip rather than surfaced as a network error.

Proxy preconditions. Proxy mode requires the operator to already be registered on IdentityRegistry (i.e. have called activate in self mode first). If not, the command fails with exit 2 (network/chain error) before spending any gas.

Output streams. The final summary (Machine ID, Token ID, DIDs; plus Machine Address and Operator DID in proxy mode) is written to stdout so it can be piped / captured. Progress lines ([1/6], [2/6], …) and per-step info/warning messages go to stderr. Integration tests assert on result.stdout.

Idempotency log. Every step appends a JSONL entry to ./peaqos.log in the working directory with fields like step, status (pending / skipped / failed / confirmed), mode, machine_id, tx_hash, and (for DID writes) machine_did_tx_count=6 / proxy_did_tx_count=2. This file is both a resume marker for partial failures and the audit trail.

Example — first run (self mode):

$ peaqos activate > out.txt 2> err.txt ; echo "exit: $?"
exit: 0

$ cat out.txt
Machine activated successfully.
  Machine ID:   42
  Token ID:     11
  Machine DID:  did:peaq:0xDC5b20847F43d67928F49Cd4f85D696b5A7617B5

$ cat err.txt
[1/6] Balance check
  Operator 0xDC5b...17B5: 1.0000 PEAQ (sufficient)
[2/6] 2FA enrollment - skipped (all wallets funded)
[3/6] Fund from Gas Station - skipped (all wallets funded)
[4/6] Register machine
  Registered. machine_id=42
[5/6] Mint NFT
  Minted NFT for machine_id=42 -> token_id=11 (tx 0xminttx...)
[6/6] Write DID attributes
  Wrote 6 machine DID attributes (tx 0xdidtx...)

Example — rerun is a no-op (exit 0, no tx submitted):

$ peaqos activate 2>&1 1>/dev/null   # stderr only, shows skip path
[1/6] Balance check
  Operator 0xDC5b...17B5: 1.0000 PEAQ (sufficient)
[2/6] 2FA enrollment - skipped (all wallets funded)
[3/6] Fund from Gas Station - skipped (all wallets funded)
[4/6] Register machine
  Already registered (machine_id=42). Skipping.
[5/6] Mint NFT
  Already minted (token_id=11). Skipping.
[6/6] Write DID attributes
  Machine DID attributes already on chain. Skipping.

The stdout summary stays the same on rerun; only the stderr skip messages and the peaqos.log entries flip from confirmed to skipped.

Example — peaqos.log (JSONL, one line per step):

{"step":"register","status":"confirmed","mode":"self","address":"0xDC5b...","machine_id":42,"ts":"2026-04-23T15:00:18Z"}
{"step":"mint_nft","status":"confirmed","machine_id":42,"recipient":"0xDC5b...","token_id":11,"tx_hash":"0xminttx...","ts":"..."}
{"step":"machine_did","status":"confirmed","mode":"self","machine_id":42,"token_id":11,"operator_did":"","machine_did_tx_count":6,"tx_hash":"0xdidtx...","ts":"..."}

On a rerun, the same three rows appear with "status":"skipped" and, for the DID row, "recovered_from":"AttributeAlreadyOnChain".

peaqos show machine

Display the full on-chain profile for a single machine DID — identity, DID attributes, MCR snapshot, and recent event summary.

peaqos show machine did:peaq:0x<40-hex>
peaqos show machine did:peaq:0x<40-hex> --json   # raw JSON to stdout

Example output:

  Machine: did:peaq:0x9a5F1E244c15e491Ae571c5bF77fDD836ddc37C5

    Machine ID:  45
    Operator  :  did:peaq:0x9Eea...641C

    DID Attributes:
      documentation_url:  https://example.com/docs
      data_visibility  :  public

    MCR Snapshot:
      Rating     :  B
      Score      :  31 / 100
      Bond Status:  bonded

    Recent Events:
      Total            :  10
      Last Event       :  2026-04-20T14:30:00Z
      Last Origin Value:  123
      Last Currency    :  HKD
      Last Subunit     :  100
      Last Status      :  ok
      Last USD Value   :  0.13

When the most recent event is a revenue event, the block surfaces the PRO-336 / PRO-334 FX fields. Last USD Value is rendered as USD dollars (Decimal-quantised to 2 places — usd_value=130.13, usd_value=1501.50). When amount_status is "unsupported_currency" or "fx_unavailable", the Last USD Value row shows (em-dash) so the CLI never displays a misleading USD number for a row whose FX state the server flagged as unreliable:

    Recent Events:
      Total            :  10
      Last Event       :  2026-04-20T14:30:00Z
      Last Origin Value:  100
      Last Currency    :  XYZ
      Last Status      :  unsupported_currency
      Last USD Value   :  —

Activity events (eventType=1) omit all five FX lines.

peaqos show operator machines

List every machine managed by a given operator DID in a tabular summary (peaqID, Machine ID, MCR, Rating).

peaqos show operator machines did:peaq:0x<40-hex>
peaqos show operator machines did:peaq:0x<40-hex> --json   # raw JSON to stdout

Example output:

  Operator: did:peaq:0x9Eeab1aCcb1A701aEfAB00F3b8a275a39646641C
  Machines: 3

peaqID                                              Machine ID   MCR   Rating
────────────────────────────────────────────────────────────────────────────
did:peaq:0x9a5F...37C5                              45           31    B
did:peaq:0xAb3D...12F0                              46           75    A
did:peaq:0xC12E...99B1                              47           55    BB

peaqos qualify event

Submit one machine event on-chain via the Event Registry (submitEvent).

Prerequisites

Configure .env in the CLI directory (or export the same variables): private key, RPC URL, and contract addresses. See peaq_os_cli.config.load_client.

Required flags

Flag Meaning
--machine-id Positive integer machine identity.
--type revenue or activity.
--value Non-negative integer as ISO 4217 subunit per PRO-334. BREAKING: pre-PRO-334 callers passed whole-currency amounts; the wire is now subunit. Example: HK$1.23 → --value=123 --currency HKD; ¥100 → --value=100 --currency JPY (JPY has no minor unit). Partner is responsible for the conversion.
--ts Event time: Unix seconds (digits only) or ISO 8601 with timezone (Z or +hh:mm).

Use a timestamp on or before the chain's block time. If --ts is ahead of the network clock, the contract can revert with FutureTimestamp.

Common options

Flag Meaning
--trust self (default), onchain, or hardware.
--source-chain same, peaq, or base (maps to a chain id for the SDK).
--source-tx 32-byte tx hash (hex, 0x optional). Required when --trust is onchain.
--raw-data File path; file bytes are hashed and stored as the event data hash.
--metadata File path; bytes are sent as on-chain metadata.
--currency Per PRO-336 §6 — currency code for revenue events (e.g. USD, HKD, 3-10 uppercase alphanumeric chars). Activity events take "". Omit to use the SDK's smart default ("USD" for revenue, "" for activity).

Examples

# Revenue event (self-reported trust, default source chain)
peaqos qualify event --machine-id 42 --type revenue --value 100 --ts 1735000000
Event submitted.
  Machine ID:  42
  Type:        revenue
  Value:       100
  Trust:       self-reported
  Tx:          0x3f4a8c1e2d9b7f05a6c3e8d1f4b2a7c9e0d5f3b1a8e2c6d9f7b4a1e3c5d8f2b4
  Data Hash:   0xa1b2c3d4e5f67890a1b2c3d4e5f67890a1b2c3d4e5f67890a1b2c3d4e5f67890
# Activity with ISO timestamp
peaqos qualify event --machine-id 42 --type activity --value 0 --ts "2026-04-22T12:00:00Z"

# On-chain-verified event with a source tx hash
peaqos qualify event --machine-id 42 --type revenue --value 200 --ts 1735000000 \
  --trust onchain \
  --source-tx 0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890ab

# Attach a payload file (raw data is hashed on submit)
peaqos qualify event --machine-id 42 --type activity --value 0 --ts 1735000000 \
  --raw-data ./sensor.bin

peaqos qualify mcr

Look up a machine's Machine Credit Rating (MCR) from the MCR HTTP API.

Usage

peaqos qualify mcr <DID> [--json]
  • DID — Must match did:peaq:0x plus exactly 40 hex characters (checksum casing is allowed).
  • --json — Print only JSON to stdout (pretty-printed, indent 2). No banner or prose. Useful for scripts.

In --json mode the object includes the SDK field mcr (rating label, e.g. Provisioned, BBB) and a duplicate key mcr_rating with the same string for tools that expect a *_rating field.

Examples

# Human-readable block (rating, score, bond, events, trend, last updated)
peaqos qualify mcr did:peaq:0x9a5F1E244c15e491Ae571c5bF77fDD836ddc37C5
MCR for did:peaq:0x9a5F1E244c15e491Ae571c5bF77fDD836ddc37C5

  Rating:          A
  Score:           82 / 100
  Bond Status:     bonded

  Events:
    Total:         150
    Revenue:       120
    Activity:      30

  30-Day Revenue:  +12.5%
  Last Updated:    2026-04-20T14:30:00Z
  FX Degraded:     no

FX Degraded: yes (PRO-336 §S6 / PRO-331) means at least one event in the scoring set used a degraded FX source (stale_latest / default_usd_fx_outage). Use it to distinguish a conservative score caused by FX outage from an empty-data machine when gating UI / alerts on data quality.

# Machine-readable JSON for jq / scripts
peaqos qualify mcr did:peaq:0x9a5F1E244c15e491Ae571c5bF77fDD836ddc37C5 --json
{
  "did": "did:peaq:0x9a5F1E244c15e491Ae571c5bF77fDD836ddc37C5",
  "mcr": "A",
  "mcr_rating": "A",
  "mcr_score": 82,
  "bond_status": "bonded",
  "event_count": 150,
  "revenue_event_count": 120,
  "activity_event_count": 30,
  "revenue_trend": "+12.5%",
  "last_updated": 1745152200
}

Typical failures

Situation Exit What you see
Bad or empty DID 1 Validation message
No MCR row for that DID (HTTP 404) 2 Machine not found
API unavailable (HTTP 503) 2 MCR API unavailable
Other HTTP / RPC issues 2 Wrapped SDK or network message

Errors

The CLI maps SDK and network exceptions to stable exit codes:

Exit code Meaning
0 Success
1 User / validation error (bad input, cap, rate limit)
2 Network, RPC, or on-chain error (connection, HTTP, revert)
3 Configuration error (missing env vars, invalid private key)

Subcommands funnel exceptions through peaq_os_cli.errors.handle_sdk_error, which raises click.ClickException with the mapped exit code and a user-friendly message. Known on-chain revert reasons and Faucet API error codes are translated by map_revert_reason and map_faucet_error.

Output formatting

Subcommands render results through peaq_os_cli.formatting to keep human output consistent across the CLI:

  • truncate_address — shortens a hex address to 0x{first4}...{last4}.
  • format_timestamp — renders a Unix timestamp as ISO 8601 UTC, or for None.
  • format_key_value — aligns key: value pairs so the colons line up.
  • format_table — left-aligned columnar table with a header separator.
  • print_json — writes json.dumps(data, indent=2) to stdout for pipe-friendly output.
  • print_step — writes [{step}/{total}] {label} progress lines to stderr, suppressed when the active Click context is quiet.

Utilities

Input parsing and validation helpers in peaq_os_cli.utils:

  • parse_timestamp — accepts pure-digit Unix seconds or ISO 8601 strings with an explicit UTC offset (...Z or ...+HH:MM). Raises click.BadParameter on unrecognised input.
  • validate_did_format — requires did:peaq:0x followed by 40 hex characters.
  • validate_address_format — requires a 0x-prefixed 40-hex-character address.
  • read_key_file — reads, strips, and validates a 0x-prefixed 64-hex private key file. Raises click.ClickException with exit code 1 on missing files or invalid content.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

peaq_os_cli-0.0.1.tar.gz (71.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

peaq_os_cli-0.0.1-py3-none-any.whl (72.7 kB view details)

Uploaded Python 3

File details

Details for the file peaq_os_cli-0.0.1.tar.gz.

File metadata

  • Download URL: peaq_os_cli-0.0.1.tar.gz
  • Upload date:
  • Size: 71.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for peaq_os_cli-0.0.1.tar.gz
Algorithm Hash digest
SHA256 6b1bfe5da4935d1d35b6d85affc79835c86391a32972063637dec1f15eab1f48
MD5 c26a1aea4ccf3b75b1b52ab61e3cada7
BLAKE2b-256 d0b7eebb04006fe5853bd43846b70987e7a3fc70c4ea4f53e8550c4d24326d04

See more details on using hashes here.

Provenance

The following attestation bundles were made for peaq_os_cli-0.0.1.tar.gz:

Publisher: peaq-os-cli-py.yml on peaqnetwork/peaq-os-cli-py

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file peaq_os_cli-0.0.1-py3-none-any.whl.

File metadata

  • Download URL: peaq_os_cli-0.0.1-py3-none-any.whl
  • Upload date:
  • Size: 72.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for peaq_os_cli-0.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 36a00cf317d86fabebb9fa79de1ec11ead71d4d9c01c47cebefca6ae9444ae09
MD5 c24a0e4d6eacf74f4b4dbcba18eda88b
BLAKE2b-256 bcb39511435a538f02894c8d598d11643e76988caada14f71cc4eadd0be2322d

See more details on using hashes here.

Provenance

The following attestation bundles were made for peaq_os_cli-0.0.1-py3-none-any.whl:

Publisher: peaq-os-cli-py.yml on peaqnetwork/peaq-os-cli-py

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page