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 enforcesmsg.sender == didAccount). The machine EOA holds the resulting NFT. Both flags are required together; supplying one alone is rejected with exit1.
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=13 → 0.13,
usd_value=150 → 1.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 matchdid:peaq:0xplus 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 to0x{first4}...{last4}.format_timestamp— renders a Unix timestamp as ISO 8601 UTC, or—forNone.format_key_value— alignskey: valuepairs so the colons line up.format_table— left-aligned columnar table with a header separator.print_json— writesjson.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 (...Zor...+HH:MM). Raisesclick.BadParameteron unrecognised input.validate_did_format— requiresdid:peaq:0xfollowed by 40 hex characters.validate_address_format— requires a0x-prefixed 40-hex-character address.read_key_file— reads, strips, and validates a0x-prefixed 64-hex private key file. Raisesclick.ClickExceptionwith exit code1on missing files or invalid content.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6b1bfe5da4935d1d35b6d85affc79835c86391a32972063637dec1f15eab1f48
|
|
| MD5 |
c26a1aea4ccf3b75b1b52ab61e3cada7
|
|
| BLAKE2b-256 |
d0b7eebb04006fe5853bd43846b70987e7a3fc70c4ea4f53e8550c4d24326d04
|
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
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
peaq_os_cli-0.0.1.tar.gz -
Subject digest:
6b1bfe5da4935d1d35b6d85affc79835c86391a32972063637dec1f15eab1f48 - Sigstore transparency entry: 1409805248
- Sigstore integration time:
-
Permalink:
peaqnetwork/peaq-os-cli-py@f08e34c842b166531897574f653c525bb30e8492 -
Branch / Tag:
refs/heads/release/publish-0.0.1 - Owner: https://github.com/peaqnetwork
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
peaq-os-cli-py.yml@f08e34c842b166531897574f653c525bb30e8492 -
Trigger Event:
workflow_dispatch
-
Statement type:
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
36a00cf317d86fabebb9fa79de1ec11ead71d4d9c01c47cebefca6ae9444ae09
|
|
| MD5 |
c24a0e4d6eacf74f4b4dbcba18eda88b
|
|
| BLAKE2b-256 |
bcb39511435a538f02894c8d598d11643e76988caada14f71cc4eadd0be2322d
|
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
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
peaq_os_cli-0.0.1-py3-none-any.whl -
Subject digest:
36a00cf317d86fabebb9fa79de1ec11ead71d4d9c01c47cebefca6ae9444ae09 - Sigstore transparency entry: 1409805277
- Sigstore integration time:
-
Permalink:
peaqnetwork/peaq-os-cli-py@f08e34c842b166531897574f653c525bb30e8492 -
Branch / Tag:
refs/heads/release/publish-0.0.1 - Owner: https://github.com/peaqnetwork
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
peaq-os-cli-py.yml@f08e34c842b166531897574f653c525bb30e8492 -
Trigger Event:
workflow_dispatch
-
Statement type: