Nukez

Docs · Verify

Verify & attest.

Verification and attestation reference.

Use this page to choose the correct verification path: storage state, on-chain attestation, per-file Merkle proof, receipt hash verification, or the full verification bundle. Each surface is available through PyNukez and the underlying gateway endpoints.

verify_storageStorage state

Reports verified, attested, Merkle root, file count, and public verify URL.

attestProof anchor

Computes the file-set Merkle root and records the attestation result.

merkle-proofFile inclusion

Returns a per-file proof path that can be recomputed independently.

nukez-merkle-v1Canonical spec

Normative algorithm and test vectors for external verifiers. Open spec →

Storage state

Verify the receipt's storage state

Use this first to understand whether a receipt is attested and whether the current file set verifies.

python
from pynukez import Nukez client = Nukez(keypair_path="~/.config/solana/id.json")receipt_id = "9494f0778940d18e" v = client.verify_storage(receipt_id)print("verified:   ", v.verified)print("attested:   ", v.attested)print("merkle_root:", v.merkle_root)print("verify_url: ", v.verify_url) # HTTP equivalent:# POST https://api.nukez.xyz/v1/storage/verify# body: {"receipt_id": receipt_id}

Code notes

Storage verification reports whether a receipt has an attested Merkle root and whether the stored file set currently verifies. Be precise about what a routine green attestation proves: it is a presence-and-consistency proof, meaning the manifest entries exist in storage and their recorded content hashes form the Ed25519-signed Merkle root. It does not re-hash the stored bytes. The stricter byte-level check is GET /v1/storage/recompute-verify, which re-downloads every file and re-hashes it; that endpoint requires a payer-signed envelope with locker:read and is strictly read-only (in PyNukez, client.recompute_verify signs it for you). On confirmed lockers the gateway runs an attestation automatically after every successful file confirm via the managed background queue — by the time you fetch the verification bundle for a freshly-confirmed locker, content_proof and on_chain_anchor are already populated. The explicit POST /v1/storage/attest endpoint (signed envelope, op locker:attest) exists for two cases only: forcing a fresh anchor right now, and clients that want a synchronous-style result instead of polling verify. Before any files are uploaded, verified and attested are false with no Merkle root — this is the steady-state for empty lockers, not a failure.

Use verify_storage for storage/content attestation state. Use verify_receipt_hash when you specifically want to verify the receipt object hash.

Attestation

Anchor the file-set Merkle root

Attestation computes the proof root and anchors it on Solana. Current anchors are published by the gateway's own key. Historical anchors were recorded through the gateway's Switchboard flow.

python
att = client.attest(receipt_id=receipt_id, sync=True)print("status:      ", att.status)print("push_ok:     ", att.push_ok)print("merkle_root: ", att.merkle_root)print("tx_signature:", att.tx_signature)print("slot:        ", att.switchboard_slot) # HTTP equivalent:# POST /v1/storage/attest is a signed-envelope endpoint (op locker:attest);# see /docs/http/helpers for a portable signer (signed_call) that wraps it.# GET  https://api.nukez.xyz/v1/attest-code?receipt_id=$RECEIPT_ID## Note: the gateway auto-attests after every file confirm (the managed background queue),# so on freshly-confirmed lockers the attestation is already populated by# the time you fetch /v1/storage/verification-bundle. Explicit attest calls# are only needed to force an anchor immediately (sync result).

Code notes

Attestation builds the file-set Merkle root and anchors the result. The anchor object in the response names the kind of anchor. Current anchors have the type solana_sas_v1 or solana_memo_v2: the gateway signs a version-two evidence envelope, and then publishes an SPL Memo that carries the Merkle root and the statement digest in a transaction signed by the gateway's published key. The solana_sas_v1 type also writes a Solana Attestation Service account for the receipt. Historical anchors have the type switchboard_v2, and they keep their original Switchboard feed and memo. Read the transaction from anchor.tx first, and fall back to switchboard_tx only when the response has no anchor object. With sync=True the request stays open, but the gateway no longer performs the on-chain push inside the request: it enqueues the job through the same managed queue path the async mode uses and then polls the persisted attestation server-side until it reaches a terminal state. If the poll ceiling (90 seconds by default) expires while the job is still in flight, the call returns a 202-style response that points at /v1/storage/verify for continued polling. The status field moves through pending, computed, pushing, and complete; a truthy merkle_root is the completion signal pollers should key on.

A computed Merkle root can exist before the on-chain anchor is complete. That is the "computed" and "pushing" stretch of the lifecycle. Retry or poll rather than treating that transient state as proof failure.

Inclusion proof

Recompute a file's Merkle path

Use this when a verifier needs to prove that a specific file is included in the attested root.

python
import hashlib proof = client.get_merkle_proof(receipt_id=receipt_id, filename="Anza.pdf") entry = proof["file_entry"]content_hash = entry["content_hash"].removeprefix("sha256:")leaf_material = f'{proof["filename"]}:{entry["size_bytes"]}:{content_hash}'current = hashlib.sha256(leaf_material.encode("utf-8")).hexdigest() for step in proof["proof"]:    sibling = step["hash"].removeprefix("sha256:")    if step["position"] == "right":        current = hashlib.sha256((current + sibling).encode("utf-8")).hexdigest()    else:        current = hashlib.sha256((sibling + current).encode("utf-8")).hexdigest() assert "sha256:" + current == proof["merkle_root"]

Code notes

Merkle proof verification is the core independent check: recompute the leaf from filename, size, and content hash, walk the proof path in order, and compare the final hash to the attested Merkle root.

Raw HTTP endpoint: GET /v1/storage/merkle-proof?receipt_id={id}&filename={filename}.

Receipt object

Compare stored and computed receipt hashes

Use receipt hash verification to check the receipt object itself.

python
check = client.verify_receipt_hash(receipt_id) print("stored:  ", check.stored_hash)print("computed:", check.computed_hash)print("matches: ", check.matches) # HTTP equivalent:# GET https://api.nukez.xyz/v1/receipts/{receipt_id}# GET https://api.nukez.xyz/v1/receipts/{receipt_id}/verify

Code notes

Receipt-hash verification is separate from storage verification. It checks whether the stored receipt hash matches the receipt object as recomputed by the gateway/client.

Receipt hash verification proves the receipt object. It does not replace per-file content hash or Merkle inclusion checks.

Proof bundle

Export a full verification package

Use the bundle endpoint when another system needs enough data to verify independently.

http
curl -sS \  "https://api.nukez.xyz/v1/storage/verification-bundle?receipt_id=$RECEIPT_ID" \  | jq . # Useful fields:# receipt_id# content_proof.merkle_root# merkle_algorithm.leaf_formula# verify_yourself.steps# verify_page_url

Code notes

The verification bundle is the high-level package for independent verification. It includes the receipt, content proof, Merkle algorithm details, and a verify-yourself checklist so another system can recompute the result without trusting the UI.

Use the bundle when exporting proof data to another verifier, model, agent, or audit workflow.

Evidence bundle

Save a portable proof and check it offline

Use the evidence bundle when a verifier must check the signed envelope and the on-chain anchor without trusting the gateway.

http
curl -sS \  "https://api.nukez.xyz/v1/storage/evidence-bundle?receipt_id=$RECEIPT_ID" \  > bundle.json # The gateway's statement-signing keys. Pin the key out of band.curl -sS "https://api.nukez.xyz/v1/keys" | jq . # Offline facts: the Merkle root, the statement digest, and the signature.nukez-verify bundle.json --pin <ed25519 public key hex> # Online facts as well, against a Solana RPC endpoint that you choose.nukez-verify bundle.json --pin <ed25519 public key hex> --rpc <your rpc url>

Code notes

The evidence bundle is the portable proof for the anchors that the gateway publishes itself. The endpoint is public and needs no authentication. The bundle holds the file list, the commitment, the signed version-two envelope, the anchor object, the separate verification facts, and the gateway's signing keys. Records that were anchored in the Switchboard era are exported in the same document with bundle_version 1, their original signature, and their original meaning. The nukez-verify command checks a saved bundle and reports each fact separately as passed, failed, not_checked, or unavailable. It never folds the facts into one verified flag. The anchor proves that the gateway's published key committed this exact snapshot on Solana at this slot, and, with the attestation account, that the current commitment is readable on-chain at a predictable address. It does not prove that a third party inspected the files.

The nukez-verify command is installed with the PyNukez package. The on-chain checks are online by nature, because a saved transaction alone does not prove finality.

For the narrative walkthrough, open the verification guide.

§ next