Skip to main content

Axiomatic Verifier (Python) is the SDK for independently verifying on-chain p1 Proof-of-Valuation (PoVal) attestations (and related formats) published on Algorand.

Given a transaction ID, it:

  1. Fetches the transaction via an Algorand Indexer.
  2. Extracts and parses the note.
  3. Re-canonicalizes the JSON (JCS/ACJ-style).
  4. Recomputes the SHA-256.
  5. Applies lightweight validation rules (schema, hash, timestamp).
  6. Returns a structured JSON-style result.

There is no dependency on any Axiomatic backend: anyone can verify.


Who is this for?

Use axiomatic_verifier if you:

  • Need to verify PoVal attestations issued by Axiomatic Oracle or compatible tooling.
  • Build Python-based dashboards, risk engines, monitoring or audit scripts.
  • Want to validate p1 notes (and selected legacy formats) directly from Algorand.

If you need to create and publish p1 attestations, see axiomatic_proofkit.


Typical use cases

  1. RWA dashboards and explorers

    • Given a txid, show whether a PoVal attestation is valid and fresh.
    • Display v, u, ts, model metadata and hashes.
  2. Risk / compliance engines

    • Check that incoming PoVal proofs are well-formed, hash-consistent and within a time window.
    • Combine verified, reason, mode and timestamps into your own policies.
  3. Back-office audit scripts

    • Periodically scan a set of transactions.
    • Verify notes and export structured data for further analysis.

Installation

Requires Python 3.10+.

pip install axiomatic_verifier

requests is installed automatically as a dependency.


Exposed API

From axiomatic_verifier:

  • verify_tx(txid, network="testnet", indexer_url=None, max_skew_past_sec=..., max_skew_future_sec=...)

Utility helpers:

  • to_jcs_bytes(obj)
  • sha256_hex(b)

verify_tx always returns a dict-like structure (plain dict).


Quickstart: verify a p1 transaction

This example mirrors the internal smoke test and is suitable as a public snippet.

1. Environment (optional)

Create a .env file next to your script (optional):

ALGORAND_NETWORK=testnet
# INDEXER_URL=https://testnet-idx.algonode.cloud

If INDEXER_URL is not set, the SDK will default to Algonode:

  • https://mainnet-idx.algonode.cloud for mainnet
  • https://testnet-idx.algonode.cloud for testnet

2. Example script (verify_tx_example.py)

import os
import sys
import json
from pathlib import Path

from axiomatic_verifier import verify_tx

ROOT = Path(__file__).resolve().parent


def load_env(env_path: Path) -> None:
    try:
        for line in env_path.read_text(encoding="utf-8").splitlines():
            if not line or line.strip().startswith("#") or "=" not in line:
                continue
            if "=" not in line:
                continue
            k, v = line.split("=", 1)
            k, v = k.strip(), v.strip()
            if k and (k not in os.environ):
                os.environ[k] = v
    except FileNotFoundError:
        pass


load_env(ROOT / ".env")


def main() -> None:
    if len(sys.argv) < 2:
        print("Usage:", file=sys.stderr)
        print("  python verify_tx_example.py <TXID>", file=sys.stderr)
        sys.exit(1)

    txid = sys.argv[1].strip()
    network = (os.getenv("ALGORAND_NETWORK") or "testnet").strip()

    # Default Indexer: Algonode (can be overridden via INDEXER_URL)
    indexer_url = (
        os.getenv("INDEXER_URL")
        or (
            "https://mainnet-idx.algonode.cloud"
            if network == "mainnet"
            else "https://testnet-idx.algonode.cloud"
        )
    ).strip()

    res = verify_tx(
        txid=txid,
        network=network,
        indexer_url=indexer_url,
        # Example policy: accept p1 issued within the last hour,
        # and up to 5 minutes in the future (clock skew).
        max_skew_past_sec=3600,
        max_skew_future_sec=300,
    )

    print(json.dumps(res, indent=2, ensure_ascii=False))


if __name__ == "__main__":
    main()

Run:

python verify_tx_example.py <TXID>

Use a txid produced by axiomatic_proofkit or the Node ProofKit on the same network.


Response model

verify_tx always returns a dict. Typical shapes:

Valid p1

{
  "txid": "...",
  "verified": true,
  "mode": "p1",
  "reason": null,
  "note_sha256": "...",
  "rebuilt_sha256": "...",
  "confirmed_round": 57318625,
  "explorer_url": "https://testnet.explorer.perawallet.app/tx/...",
  "note": {
    "s": "p1",
    "a": "re:EUR",
    "mv": "v2",
    "mh": "",
    "ih": "...",
    "v": 550000.0,
    "u": [520000.0, 580000.0],
    "ts": 1762609210
  }
}

Stale / out-of-window p1

{
  "txid": "...",
  "verified": false,
  "mode": "p1",
  "reason": "ts_out_of_window",
  "note_sha256": "...",
  "rebuilt_sha256": "...",
  "explorer_url": "..."
}

Meaning: the attestation is structurally and cryptographically correct, but ts is outside the allowed time window (max_skew_past_sec / max_skew_future_sec).

Unsupported / missing note

{
  "txid": "...",
  "verified": false,
  "mode": "unknown",
  "reason": "unsupported_or_empty_note",
  "explorer_url": "..."
}

Legacy formats (if enabled in your version) are reported with:

{
  "txid": "...",
  "verified": true,
  "mode": "legacy",
  "reason": null,
  "note": { "ref": "...", "schema_version": "..." }
}

Canonical JSON helpers (optional)

You can use the bundled JCS/ACJ-style helpers for your own golden tests:

from axiomatic_verifier import to_jcs_bytes, sha256_hex
import json

with open("p1.json", "r", encoding="utf-8") as f:
    obj = json.load(f)

b = to_jcs_bytes(obj)
print(sha256_hex(b))

This lets you confirm that your own tooling matches the canonicalization used on-chain.


Security and policy notes

  • axiomatic_verifier does not execute any business logic for you.

  • Treat its output as structured signals:

    • verified, reason, mode,
    • hashes, timestamps, explorer/indexer links,
    • the decoded note.
  • You are expected to layer your own risk / policy logic on top:

    • which models and asset tags are allowed,
    • which issuers (addresses) you trust,
    • how strict your time windows should be.

This is an early-access verifier: feedback and issues are very welcome.

Metadata

Release files for axiomatic-verifier 0.1.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for axiomatic-verifier 0.1.2
File Size Uploaded
axiomatic_verifier-0.1.2.tar.gz 5.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for axiomatic-verifier 0.1.2
File Interpreter ABI Platform
axiomatic_verifier-0.1.2-py3-none-any.whl Python 3 none any Details

Total release size: 11.8 kB

Release files / axiomatic_verifier-0.1.2.tar.gz

Download URL axiomatic_verifier-0.1.2.tar.gz
Size 5.5 kB
Tags Source
SHA-256 checksum
How to use checksums
68e7c570044583a553ec8c4fc9b53b782aa0308753006ccf1fb604cfd356f8f3
BLAKE2b-256 checksum
How to use checksums
1ecd4606b97ae9dfa28e85ea393c61da5cefb02463ceeb0f3db154a2099b9248
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.9

Release files / axiomatic_verifier-0.1.2-py3-none-any.whl

Download URL axiomatic_verifier-0.1.2-py3-none-any.whl
Size 6.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a69a0742159783215b19d9a12b587264de96f76062b56e590681592e1a8e3d5a
BLAKE2b-256 checksum
How to use checksums
f0f0f13eaa83e7369c369476afde2e3c78ea990eba4be370c55d1ed3cf12fc8a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.9

Release history Release notifications | RSS feed

This release

0.1.2 This release

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page