Catalog PyPI
PACKAGE EXPLORERView in registry

a2a-protocol-core

PyPI

Open, deterministic protocol core for the DNS of Money A2A payment surface (FAS-1 pay: addressing, canonical hashing, payment-hook client).

a2aai-agentsfas-1iso20022pay-uripaymentsxrpl
Versions collected1
Direct dependencies7From release 0.3.0
Last observed20 Oct, 16:28 UTC

README

Version 0.3.0 documentation

a2a-protocol-core

License: Apache 2.0

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

ModuleA2A refPurpose
addressingFAS-1pay: URI grammar + validation (is_valid_pay_uri)
semantic_normalizerA2A-009collapse synonym verbs → canonical action codes
canonical_hashA2A-008metadata- & vocabulary-stable payment-intent hash
schemasA2A-041payment-hook request/response wire models
clientA2A-041A2APaymentHookClient over /v1/a2a/*
x402_payx402one-call pay: XRP on XRPL ([xrpl]) / USDC on Algorand ([algorand])
screenx402paid counterparty screen — "screen before you pay"
attestation_verifydid:webverify 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.

Downloads & popularity

Awaiting observations

No metric observations yet

Download counts and popularity will appear here as the collector receives them.

Versions 1

Collected releases
VersionPublishedDirect dependenciesOpen version
0.3.021 Jul 20267

Package advisories

0
No matching advisories collected

This describes our collected data; it is not a security assessment.

Repository

PENDING
dnsofmoney/dns-of-money

Shared repository data · GitHub

License detected in repository
Not collected

Repository

PENDING
dnsofmoney/a2a-protocol-core

Shared repository data · GitHub

License detected in repository
Not collected

Metadata history

Meaningful changes
Current collected state Current

Observed since 20 Oct, 16:28 UTC

No superseded metadata states collected. Unchanged observations do not create new revisions.

Record identity

package:09a1533f05e038feac33ccf5539a28c6dd2270d5c4fd61d24b144ae71d7f49de