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
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 | |
|---|---|---|---|
| anchorregistry-0.2.0.tar.gz | 35.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| anchorregistry-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
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
|