a2a-protocol-core
The open, deterministic protocol core of the DNS of Money
agent-to-agent (A2A) payment surface — the dependency-light layer external AI
agents adopt to resolve, hash, and initiate pay: payments.
The intelligence lives in the calling agent. This package serves deterministic, inspectable primitives — no rail selection, no scoring, no model anywhere in the money path.
Install
pip install a2a-protocol-core
Runtime deps are intentionally minimal: pydantic and requests.
What's in here
| Module | A2A ref | Purpose |
|---|---|---|
addressing |
FAS-1 | pay: URI grammar + validation (is_valid_pay_uri) |
semantic_normalizer |
A2A-009 | collapse synonym verbs → canonical action codes |
canonical_hash |
A2A-008 | metadata- & vocabulary-stable payment-intent hash |
schemas |
A2A-041 | payment-hook request/response wire models |
client |
A2A-041 | A2APaymentHookClient over /v1/a2a/* |
x402_pay |
x402 | one-call pay: XRP on XRPL ([xrpl]) / USDC on Algorand ([algorand]) |
screen |
x402 | paid counterparty screen — "screen before you pay" |
attestation_verify |
did:web | verify the attestation's Ed25519 proof ([verify]) |
Quick start
from a2a_protocol_core import (
A2APaymentHookClient,
compute_canonical_hash,
normalize_message,
)
# Your agent describes intent however it likes...
intent = {"action": "send", "amount": "2.50", "currency": "USD", "alias": "pay:agent.compute"}
# ...which collapses to a stable hash regardless of wording ("send" == "transfer" == "pay").
semantic_hash = compute_canonical_hash(normalize_message(intent))
client = A2APaymentHookClient(base_url="https://api.dnsofmoney.com")
result = client.trigger(
job_id="job-001",
provider_pay_address="pay:agent.compute",
requester_pay_address="pay:vendor.alpha",
amount="2.50",
currency="USD",
semantic_hash=semantic_hash,
)
print(result.settlement_result.status, result.iso_message_ref)
See examples/trigger_payment_hook.py.
Pay a pay: alias in one call (non-custodial)
Resolve the price, pay from your own wallet, and get back a signed resolve/verify/OFAC-screen attestation — one function, and your seed never leaves your process:
pip install "a2a-protocol-core[xrpl]"
from a2a_protocol_core import pay_alias_xrp
result = pay_alias_xrp(
base_url="https://api.dnsofmoney.com",
alias="pay:vendor.alpha",
amount_xrp="0.10",
seed="s...", # YOUR XRPL wallet seed — signs locally, never transmitted
api_key="fas_live_...", # attributes the settle leg
)
print(result.tx_hash, result.summary.verdict) # e.g. "A1B2…", "CLEAR"
Already settled the payment through your own wallet stack (or a Coinbase Agentic
Wallet)? Skip the signing and just fetch the attestation — no [xrpl] extra:
from a2a_protocol_core import attest_settled_payment
result = attest_settled_payment(
base_url="https://api.dnsofmoney.com",
alias="pay:vendor.alpha",
amount_xrp="0.10",
tx_hash="A1B2C3...", # your already-validated XRPL tx
api_key="fas_live_...",
)
DNS of Money verifies an already-settled transaction and returns metadata — it never holds your keys or your funds.
Pay in USDC on Algorand (the priced endpoints)
DNS of Money's own paid endpoints declare their price in USDC on Algorand.
pay_alias_usdc_algorand (or the rail-dispatching pay_alias) signs the USDC
transfer leg locally via the official x402 client mechanisms — omit the
amount and the server quotes its declared, enforced price:
pip install "a2a-protocol-core[algorand]"
from a2a_protocol_core import pay_alias_usdc_algorand
result = pay_alias_usdc_algorand(
base_url="https://api.dnsofmoney.com",
alias="pay:dnsofmoney",
api_key="fas_live_...",
mnemonic="...your 25-word Algorand mnemonic...", # signs locally, never sent
)
print(result.tx_hash, result.summary.verdict)
Screen before you pay
Pay the screening fee, get an OFAC + resolution attestation about a
caller-named target — a pay: alias or a raw any-chain address — before you
send it money:
from a2a_protocol_core import screen
result = screen(
base_url="https://api.dnsofmoney.com",
target="pay:vendor.alpha",
api_key="fas_live_...",
algorand_mnemonic="...", # fee is USDC on Algorand (server-priced)
verify=True, # also check the attestation signature
)
if result.verdict == "CLEAR":
... # proceed to pay the vendor
Verify the attestation yourself
Attestations are W3C Verifiable Credentials signed eddsa-jcs-2022 by a
did:web issuer. verify_attestation resolves the issuer's DID document,
enforces assertionMethod authorization, and checks the Ed25519 signature —
so the proof chain ends at your process, not at TLS:
pip install "a2a-protocol-core[verify]"
from a2a_protocol_core import verify_attestation
v = verify_attestation(result.attestation, expected_issuer="did:web:dnsofmoney.com")
assert v.verified
An unsigned attestation fails verification by design.
Why canonical hashing?
Two agents describing the same payment with different words ("send" vs
"transfer") or different session/trace metadata must produce the same
intent fingerprint. compute_canonical_hash excludes non-semantic noise
(session/request/trace ids, timestamps, idempotency keys, memos) and
normalizes the action verb, so the hash captures what is being paid — not
how it was phrased. That fingerprint binds an agent's intent to a settlement
without trusting free text.
Design constraints
- Deterministic only. Nothing here selects or scores a rail.
- Off the money path. The hash and client describe and carry intent; the deterministic core (server-side) resolves, generates ISO 20022, and settles.
- Dependency-light. Safe to embed in an agent runtime.
Development
pip install -e ".[dev]"
pytest
ruff check src tests
License
Apache-2.0 — permissive with an explicit patent grant. See LICENSE.
Metadata
Release files for a2a-protocol-core 0.3.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 |
|---|---|---|---|---|
| a2a_protocol_core-0.3.0.tar.gz | 40.7 kB | With provenance | Details for a2a_protocol_core-0.3.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| a2a_protocol_core-0.3.0-py3-none-any.whl | Python 3 | none | any | Details for a2a_protocol_core-0.3.0-py3-none-any.whl |
Total release size: 70.1 kB
Release files / a2a_protocol_core-0.3.0.tar.gz
| Download URL | a2a_protocol_core-0.3.0.tar.gz |
|---|---|
| Size | 40.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
72295a67fa50883855873337bada788b50bff2b24612886f1a2c9c74321b7be0
|
|
BLAKE2b-256 checksum How to use checksums |
309cf26c7325fbf2a7a90889ffad2dcf8de731eac4902cf5389622f1b689ef53
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 21, 2026.
Transparency logRelease files / a2a_protocol_core-0.3.0-py3-none-any.whl
| Download URL | a2a_protocol_core-0.3.0-py3-none-any.whl |
|---|---|
| Size | 29.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c5e296dfaf9521fcbe63d3150eeb23f3944fdf1341e544b9d773d629703fad4c
|
|
BLAKE2b-256 checksum How to use checksums |
c3851d360d1f92de9236334d0461cf5adc4fdb14a8f1774b6d6166e5ee8d0305
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 21, 2026.
Transparency logSecurity for a2a-protocol-core 0.3.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.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for a2a_protocol_core-0.3.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 21, 2026.
Transparency logA 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.