Observed since 20 Oct, 16:28 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
Open, deterministic protocol core for the DNS of Money A2A payment surface (FAS-1 pay: addressing, canonical hashing, payment-hook client).
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.
pip install a2a-protocol-core
Runtime deps are intentionally minimal: pydantic and requests.
| 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]) |
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: 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.
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)
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
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.
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.
pip install -e ".[dev]"
pytest
ruff check src tests
Apache-2.0 — permissive with an explicit patent grant. See LICENSE.
Download counts and popularity will appear here as the collector receives them.
| Version | Published | Direct dependencies | Open version |
|---|---|---|---|
| 0.3.0 | 21 Jul 2026 | 7 |
This describes our collected data; it is not a security assessment.
Shared repository data · GitHub
Observed since 20 Oct, 16:28 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package:09a1533f05e038feac33ccf5539a28c6dd2270d5c4fd61d24b144ae71d7f49de