Skip to main content

No project description provided

Project description

Here you go — two English README.md files, ready to paste.

They:

  • mirror your working publish_p1.py and verify_tx.py flows,
  • use the public import surface (axiomatic_proofkit, axiomatic_verifier),
  • are early-access friendly and concise.

axiomatic_proofkit/README.md

# axiomatic_proofkit

**Axiomatic ProofKit (Python)** is the client SDK for building and publishing **p1** attestations on Algorand for Axiomatic Oracle.

The goal is a simple, trust-minimized flow:

1. Build a canonical **p1** payload (JCS/ACJ-style JSON).
2. Publish it on-chain as the note field of a **0-ALGO self-transaction**.
3. Keep signing and key management **on the client side**.
4. Allow anyone to independently recompute and verify what was published.

This SDK does **not** depend on any Axiomatic backend.

---

## Installation

Requires **Python 3.10+**.

```bash
pip install axiomatic_proofkit
pip install py-algorand-sdk

Exposed API

From axiomatic_proofkit:

  • build_p1(...)
  • canonical_note_bytes_p1(p1)
  • assert_note_size_ok(p1)
  • build_canonical_input(raw_input, allowed_keys=...)
  • compute_input_hash(canonical_input, allowed_keys=...)
  • publish_p1(p1, from_addr=..., sign=..., network=..., algod=..., wait_rounds=...)
  • PublishError

These are the only functions you need for typical integrations.


Quickstart: publish a p1 to Algorand TestNet

The following example mirrors the internal smoke test used to validate the SDK.

1. Environment

Create a .env file next to your script:

ALGORAND_MNEMONIC=your 25-word mnemonic for a TestNet account
ALGORAND_NETWORK=testnet
# Optional: override default node
# ALGOD_URL=https://testnet-api.algonode.cloud

For production, use a secure signing setup (wallet, KMS, HSM, etc.). This example uses a mnemonic only for demonstration.

2. Example script (publish_p1_example.py)

import os
import sys
import json
import base64
from pathlib import Path

from algosdk import account, mnemonic, encoding, transaction
from algosdk.v2client.algod import AlgodClient

from axiomatic_proofkit import (
    build_p1,
    canonical_note_bytes_p1,
    assert_note_size_ok,
    build_canonical_input,
    compute_input_hash,
    publish_p1,
)

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


def load_env_from_file(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_from_file(ROOT / ".env")

MNEMONIC = os.getenv("ALGORAND_MNEMONIC")
NETWORK = (os.getenv("ALGORAND_NETWORK") or "testnet").strip()
ALGOD_URL = (
    os.getenv("ALGOD_URL")
    or (
        "https://mainnet-api.algonode.cloud"
        if NETWORK == "mainnet"
        else "https://testnet-api.algonode.cloud"
    )
).strip()

if not MNEMONIC:
    print("❌ ALGORAND_MNEMONIC missing.", file=sys.stderr)
    sys.exit(1)


def compute_input_hash_from_golden() -> str:
    """
    If golden/p1_input.json exists, compute its canonical ACJ/JCS hash.
    Otherwise return a deterministic placeholder for the smoke test.
    """
    golden_dir = ROOT / "golden"
    inp_path = golden_dir / "p1_input.json"

    if not inp_path.is_file():
        return "0" * 64

    try:
        raw = json.loads(inp_path.read_text(encoding="utf-8"))
    except Exception as e:
        print(f"⚠️ Unable to read golden/p1_input.json: {e}")
        return "0" * 64

    allowed_keys = list(raw.keys())
    cin = build_canonical_input(raw, allowed_keys=allowed_keys)
    ih = compute_input_hash(cin, allowed_keys=allowed_keys)
    print(f"✅ Golden input hash: {ih}")
    return ih


def main() -> None:
    # 1) Derive private key and address from mnemonic (demo only)
    sk = mnemonic.to_private_key(MNEMONIC)
    addr = account.address_from_private_key(sk)

    # 2) Compute input hash (from golden file if available)
    ih = compute_input_hash_from_golden()

    # 3) Build canonical p1
    p1 = build_p1(
        asset_tag="re:EUR",
        model_version="v2",
        model_hash_hex="",
        input_hash_hex=ih,
        value_eur=550_000,
        uncertainty_low_eur=520_000,
        uncertainty_high_eur=580_000,
        timestamp_epoch=None,  # use "now"
    )

    # 4) Inspect note size and hash
    note_bytes, note_sha, note_len = canonical_note_bytes_p1(p1)
    assert_note_size_ok(p1)
    print(f"P1 note size: {note_len} bytes | sha256: {note_sha}")

    # 5) Client-side signer: keep your keys local
    def sign(unsigned_bytes: bytes) -> bytes:
        """
        unsigned_bytes: msgpack-encoded UnsignedTransaction.
        Return: msgpack bytes of the SignedTransaction.
        """
        tx_dict = encoding.msgpack.unpackb(unsigned_bytes)
        txn = transaction.Transaction.undictify(tx_dict)
        stx = txn.sign(sk)
        stx_b64 = encoding.msgpack_encode(stx)   # base64(msgpack signed)
        return base64.b64decode(stx_b64)         # raw msgpack bytes

    # 6) Algod client (Algonode by default)
    algod = AlgodClient("", ALGOD_URL)

    # 7) Publish p1 as a 0-ALGO self-transaction note
    res = publish_p1(
        p1,
        network=NETWORK,
        algod=algod,
        from_addr=addr,
        sign=sign,
        wait_rounds=4,
    )

    print("PUBLISHED:")
    print(json.dumps(res, indent=2))


if __name__ == "__main__":
    main()

Run:

python publish_p1_example.py

You should see a JSON result with:

  • txid
  • explorer_url
  • note_sha256
  • note_size
  • network

You can open the explorer URL and inspect the on-chain note.


Security notes

  • The sign function is fully controlled by you.

  • For real integrations, replace the inline mnemonic signing with:

    • wallet connectors,
    • custodial services,
    • HSM/KMS,
    • any secure signing flow.
  • The SDK never sends your secrets anywhere and does not rely on Axiomatic servers.

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

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

axiomatic_proofkit-0.1.1.tar.gz (6.8 kB view details)

Uploaded Source

Built Distribution

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

axiomatic_proofkit-0.1.1-py3-none-any.whl (7.8 kB view details)

Uploaded Python 3

File details

Details for the file axiomatic_proofkit-0.1.1.tar.gz.

File metadata

  • Download URL: axiomatic_proofkit-0.1.1.tar.gz
  • Upload date:
  • Size: 6.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.9

File hashes

Hashes for axiomatic_proofkit-0.1.1.tar.gz
Algorithm Hash digest
SHA256 12fac6ff9b049dd8307423073256e54694ccd0f90c6b4babd9b7647bcf7dcc3d
MD5 60947663b73ec59800170e1e71e404c8
BLAKE2b-256 0653bd7afce699913182ba81631f45083562630723073a54cfd08896b925da4d

See more details on using hashes here.

File details

Details for the file axiomatic_proofkit-0.1.1-py3-none-any.whl.

File metadata

File hashes

Hashes for axiomatic_proofkit-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 069d55b997084ff141e6fae4d4d58e07e04772613ff41f2588c800709469d5e7
MD5 a2a38a46c352307662c622803da395fe
BLAKE2b-256 786291a6c7340d698c965cb4d84211cee3c743476502114027490c7b1e3138cb

See more details on using hashes here.

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