anchorregistry
Trustless Python client for the AnchorRegistry provenance chain on Base (Ethereum L2).
anchorregistry reads provenance records directly from the Base blockchain — no intermediary API, no account, no API key. It is the same library used in AnchorRegistry's own production backend.
Verify what existed, when, and who registered it — directly from the chain.
SPDX-Anchor: anchorregistry.ai/AR-2026-pJ53j6K
Installation
pip install anchorregistry
# With DataFrame support
pip install anchorregistry[analytics]
Requires Python 3.11+
Quickstart
from anchorregistry import configure, get_by_arid
configure(network="sepolia")
record = get_by_arid("AR-2026-dPXazj6")
print(record["title"]) # test sepolia anchor
print(record["author"]) # Ian Moore (may be empty on test anchors)
print(record["manifest_hash"])
print(record["data"]["url"]) # https://anchorregistry.com/
Usage
Query by AR-ID
from anchorregistry import get_by_arid
record = get_by_arid("AR-2026-dPXazj6")
Query by registrant wallet
from anchorregistry import get_by_registrant
records = get_by_registrant("0xc7a7afde1177fbf0bb265ea5a616d1b8d7ed8c44")
Query by tree
from anchorregistry import get_by_tree
records = get_by_tree("0xf07140ce4deaf3b5dac859091a079f82e9656f173593feda7895d940b8fa5d13")
Query by artifact type
from anchorregistry import get_by_type
from anchorregistry.enums import ArtifactType
records = get_by_type(ArtifactType.CODE)
Full registry harvest
from anchorregistry import get_all
records = get_all() # full registry
records = get_all(from_block=10000000) # from block
records = get_all(from_block=10000000, to_block=10500000) # block range
Verify file integrity
from anchorregistry import verify
result = verify("AR-2026-dPXazj6") # record only
result = verify("AR-2026-dPXazj6", file_path="./myfile.py") # + SHA256 check
print(result["hash_match"]) # True / False
Generate watermark tag
from anchorregistry import watermark
line = watermark("AR-2026-yPZBgoP", artifact_type="CODE")
# → "SPDX-Anchor: anchorregistry.ai/AR-2026-yPZBgoP"
line = watermark("AR-2026-dPXazj6", artifact_type="RESEARCH")
# → "DAPX-Anchor: anchorregistry.ai/AR-2026-dPXazj6"
# Resolves type from chain if not provided
line = watermark("AR-2026-dPXazj6")
Authenticate anchor ownership
from anchorregistry import authenticate_anchor
result = authenticate_anchor("0xf4accdf917e8cf2b9e0ceb0b281fba1c1a176f8922fb5eb432bfa0a5664b0680", "AR-2026-dPXazj6")
print(result["authenticated"]) # True / False
The ownership token (K) is a 0x-prefixed bytes32 hex string generated client-side at registration time via keccak256(salt). It is never transmitted on-chain — only the commitment keccak256(K || arId) is stored.
Authenticate a full tree
from anchorregistry import authenticate_tree
result = authenticate_tree("0xf4accdf917e8cf2b9e0ceb0b281fba1c1a176f8922fb5eb432bfa0a5664b0680", "AR-2026-dPXazj6")
print(result["authenticated"]) # True if tree ownership + all anchors verified
print(result["anchors_verified"]) # count of verified user-initiated anchors
print(result["governance_count"]) # governance anchors (skipped, bytes32(0))
Two-layer verification: Layer 1 checks tree ownership via keccak256(K || rootArId) == treeId, Layer 2 verifies every user-initiated anchor's tokenCommitment in the tree.
Analytics — load into DataFrame
from anchorregistry import get_all, to_dataframe
df = to_dataframe(get_all())
df[df.artifact_type_name == "CODE"]
df[df.author == "Ian Moore"]
df.groupby("artifact_type_name").count()
Network Configuration
Works identically against Base mainnet and Sepolia testnet.
from anchorregistry import configure
# Mainnet (default)
configure(network="base")
# Sepolia testnet
configure(network="sepolia")
# Custom RPC
configure(network="base", rpc_url="https://my-rpc-node.com")
Or via environment variables:
export NETWORK=sepolia
export BASE_RPC_URL=https://my-rpc-node.com
export ANCHOR_REGISTRY_ADDRESS=0x...
Record Structure
Every record follows a consistent two-level structure regardless of artifact type:
{
# Universal fields — identical for every type
"ar_id": "AR-2026-dPXazj6",
"registered": True,
"artifact_type_index": 1,
"artifact_type_name": "RESEARCH",
"tx": "0x826f62...",
"block": 40225238,
"registrant": "0xc7a7af...",
"manifest_hash": "...",
"parent_ar_id": "",
"descriptor": "test sepolia anchor",
"title": "test sepolia anchor",
"author": "Ian Moore",
"tree_id": "0xf07140...",
"token_commitment": "0xf07140...", # keccak256(K || arId), bytes32(0) for governance
# Type-specific fields — only fields for this artifact type
"data": {
"doi": "",
"institution": "",
"co_authors": "",
"url": "https://anchorregistry.com/"
}
}
Watermark Standards
AnchorRegistry defines two watermark standards for embedding a provenance signal in any artifact:
SPDX-Anchor — for software (code, packages, repositories)
SPDX-Anchor: anchorregistry.ai/AR-2026-XXXXXXX
DAPX-Anchor — for all other artifacts (research, data, models, media, legal, proofs)
DAPX-Anchor: anchorregistry.ai/AR-2026-XXXXXXX
One line signals membership in a provenance tree — queryable by humans and AI agents alike.
Exported Constants
from anchorregistry import ARTIFACT_TYPE_MAP, READ_ABI, CONTRACT_ADDRESS, DEPLOY_BLOCK
ARTIFACT_TYPE_MAP and READ_ABI are the canonical source of truth for AnchorRegistry type ordering and ABI — used by AnchorRegistry's production backend directly.
Design
- Trustless. Reads directly from Base blockchain events via RPC. No AnchorRegistry servers involved.
- Read-only. Registration happens through anchorregistry.com. This package only reads.
- No auth required. Verification is open and free to anyone with an RPC endpoint.
- Production parity. The same library powering the AnchorRegistry backend — not a wrapper.
- Network-agnostic. Works identically against Base mainnet and Sepolia testnet.
- Built on Base. Base settles to Ethereum mainnet — provenance anchors inherit Ethereum-grade finality.
Testing
Unit tests (no RPC required)
python3 -m pytest tests/ -v --ignore=tests/test_client.py
Full suite with Sepolia integration tests
Create a .env file with your Sepolia RPC endpoint:
SEPOLIA_RPC_URL=https://sepolia.infura.io/v3/YOUR_KEY
For authentication integration tests, also set:
ANCHOR_OWNERSHIP_TOKEN=0x... # 0x-prefixed bytes32 hex (keccak256 token)
ANCHOR_ROOT_AR_ID=AR-2026-... # root AR-ID for the ownership token
Then run:
set -a && source .env && set +a && python3 -m pytest tests/ -v
Integration tests in test_client.py are automatically skipped when SEPOLIA_RPC_URL is not set. Authentication tests are additionally skipped when ANCHOR_OWNERSHIP_TOKEN and ANCHOR_ROOT_AR_ID are not set.
References
The cryptographic commitment scheme and security proofs underlying this implementation are formally described in:
Trustless Provenance Trees: A Game-Theoretic Framework for Operator-Gated Blockchain Registries Ian C. Moore — arXiv:2604.03434 [cs.GT], April 2026 https://arxiv.org/abs/2604.03434
Status
Alpha. Core library under active development against Sepolia testnet. API surface stable per spec. Not yet published to PyPI.
License
Business Source License 1.1 (BUSL-1.1)
Change Date: March 12, 2028 → Apache License 2.0
Licensor: Ian Moore
Links
- Website: anchorregistry.com
- Verify: anchorregistry.ai
- Docs: anchorregistry.readthedocs.io
- PyPI: pypi.org/project/anchorregistry
- Source: github.com/anchorregistry/ar-python
Metadata
Release files for anchorregistry 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| anchorregistry-0.2.0.tar.gz | 35.8 kB | Without provenance | Details for anchorregistry-0.2.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| anchorregistry-0.2.0-py3-none-any.whl | Python 3 | none | any | Details for anchorregistry-0.2.0-py3-none-any.whl |
Total release size: 68.0 kB
Release files / anchorregistry-0.2.0.tar.gz
| Download URL | anchorregistry-0.2.0.tar.gz |
|---|---|
| Size | 35.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
8a58790e770278bbbab0223a1c48bd232d1c57a05f765e44bf31ffb73197955f
|
|
BLAKE2b-256 checksum How to use checksums |
198917ee7535e6b805293aa576d10ca163673f27b0a8da21e869da4b18370aea
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.15
|
Release files / anchorregistry-0.2.0-py3-none-any.whl
| Download URL | anchorregistry-0.2.0-py3-none-any.whl |
|---|---|
| Size | 32.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
9d90a0949dee55d06ee864866180bf7afba0e8f4613e501d3ac5c174cce8a652
|
|
BLAKE2b-256 checksum How to use checksums |
002672cc66d02996dfe575d324e95654f4e541ebb5e27f3c8cfec39c99aa9859
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.15
|
Security for anchorregistry 0.2.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.