A2A Cart Store (AP2 + Skyfire)
A minimal, runnable example that demonstrates AP2 ↔ uAgents Payment Protocol bridging using the A2A Outbound adapter.
Repo: a2a-cart-store
Overview
- A2A/AP2 store (JSON‑RPC) with:
list
,add
,remove
,cart
,checkout
- uAgent adapter (SingleA2AAdapter) forwards chat and bridges payments
- Payment handshake (uAgents):
RequestPayment → Commit/Reject → Complete/Cancel
- Skyfire method is used at checkout so UI offers Skyfire Pay
Note: Use a unique agent name and description when starting your adapter/uAgent to derive a unique address and avoid collisions.
Prerequisites
- Python 3.10+
Installation
python3 -m venv .venv && source .venv/bin/activate
pip install "uagents-adapter[a2a-outbound]==0.6.0" "a2a-sdk[http-server]"
# example deps
pip install -r /Users/abhi/Desktop/a2p\ protocol/examples-a2a/requirements.txt \
-r /Users/abhi/Desktop/a2p\ protocol/examples-a2a/a2a-cart-store/requirements.txt
Environment
Create .env
(examples root or cart-store folder):
# Ports
STORE_A2A_PORT=10031
STORE_UAGENT_PORT=8230
# Skyfire (to show Skyfire Pay)
JWKS_URL=https://app.skyfire.xyz/.well-known/jwks.json
JWT_ISSUER=https://app.skyfire.xyz
SELLER_ACCOUNT_ID=YOUR_SKYFIRE_ACCOUNT_ID
SELLER_SERVICE_ID=YOUR_SKYFIRE_SERVICE_ID
SKYFIRE_TOKENS_CHARGE_API_URL=https://api.skyfire.xyz/api/v1/tokens/charge
SELLER_SKYFIRE_API_KEY=YOUR_SKYFIRE_API_KEY
Run
cd /Users/abhi/Desktop/a2p\ protocol/examples-a2a/a2a-cart-store
python3 av_adapter.py
By default this starts:
- A2A server at http://localhost:10031 (default; set STORE_A2A_PORT to change)
- uAgent at http://localhost:8230 (default; set STORE_UAGENT_PORT to change)
Commands to test on ASI1 or other uAgents Client
list
orcatalog
add <sku> [qty] [<sku> [qty]] ...
(e.g.,add book 1 pen 2 watch 1
)
remove <sku>
cart
checkout
Expected Output
- After
checkout
the adapter returns aRequestPayment
withpayment_method="skyfire"
and the UI shows a Skyfire Pay option. - On payment approval the adapter emits
CompletePayment
; on failure it emitsCancelPayment
.
How it works (AP2 ↔ PaymentProtocol mapping)
- CartMandate → RequestPayment (amount/currency from AP2 total;
payment_method
from AP2method_data
; includecart_hash
) - CommitPayment → PaymentMandate (token from
transaction_id
; total from funds) - PaymentSuccess → CompletePayment; PaymentFailure → CancelPayment; RejectPayment → DenyCartMandate
Files
av_adapter.py
: bootsSingleA2AAdapter
, loads.env
, forwards chat, bridges payments.store_executor.py
: store logic; builds AP2CartMandate
oncheckout
; validates/charges onPaymentMandate
.skyfire_payment.py
: Skyfire JWT verify (JWKS) + charge helper; returns atransaction_id
on success.requirements.txt
: pins adapter and A2A SDK plus libraries used by the executor.
Troubleshooting
- Variable URLs in docs: use fixed defaults instead of
${VAR}
in MDX. - Skyfire errors: confirm all env values and network reachability to JWKS/charge endpoints.
- Ensure
payment_request.method_data
is non‑empty (example setssupported_methods="skyfire"
).