Escrow-gated task execution for LangGraph agents via the A2A Settlement Exchange.
Settlement actions are graph nodes — create escrow before the task, release on success, refund on failure. Compose the pre-built subgraph into any LangGraph workflow.
LangGraph StateGraph
┌─────────────────────────────────────────────────────────────────┐
│ START → create_escrow → task_node → route_after_task → release │
│ │ → refund │
│ │ │
│ task_success? │
│ True → release_escrow → END │
│ False → refund_escrow → END │
└─────────────────────────────────────────────────────────────────┘
│
┌──────────▼──────────┐
│ Settlement │
│ Exchange │
│ (a2a-settlement) │
└────────────────────┘
pip install langgraph-a2a-settlementOr from source:
git clone https://github.com/a2a-settlement/langgraph-a2a-settlement
cd langgraph-a2a-settlement
pip install -e ".[dev]"from langgraph_a2a_settlement import create_settlement_graph
from langgraph_a2a_settlement.state import SettlementState
def my_task_node(state: SettlementState) -> dict:
# ... do work ...
return {"task_output": result, "task_success": True}
graph = create_settlement_graph(
task_node=my_task_node,
exchange_url="http://localhost:3000/v1",
)
result = graph.invoke({
"requester_id": "agent-alice",
"provider_id": "agent-bob",
"amount": 100,
"task_description": "Analyze Q1 sales data",
"task_input": "Here is the data...",
})| Env Variable | Default | Description |
|---|---|---|
A2A_EXCHANGE_URL |
https://sandbox.a2a-settlement.org |
Exchange base URL (no /v1 — SDK appends it) |
A2ASE_API_KEY |
— | Requester API key (required for settlement) |
A2A_PAYER_API_KEY |
— | Alternative env var for API key |
Or pass exchange_url and api_key in the input state when invoking.
| Export | Description |
|---|---|
create_settlement_graph |
Pre-built graph with escrow-wrapped task execution |
create_escrow_node |
Pre-task node: creates escrow, adds escrow_id to state |
release_escrow_node |
Post-task node: releases escrow on success |
refund_escrow_node |
Post-task node: refunds escrow on failure |
route_after_task |
Conditional edge: release vs refund based on task_success |
SettlementState |
TypedDict state schema for settlement workflows |
The escrow lifecycle maps to LangGraph concepts:
- create_escrow_node — Creates escrow via
SettlementExchangeClient.create_escrow(), addsescrow_idandescrow_status="pending"to state. - task_node — Your user-defined node. Must return
task_success: bool(and optionallytask_output). - route_after_task — Conditional edge: if
task_success→release_escrow, else →refund_escrow. - release_escrow_node / refund_escrow_node — Call
release_escrow()orrefund_escrow()on the exchange.
If escrow creation fails, escrow_status="error" is set and the task still runs; release/refund nodes no-op when escrow_id is missing.
Power users who want to compose settlement into their own graph structure can import nodes directly:
from langgraph_a2a_settlement import (
create_escrow_node,
release_escrow_node,
refund_escrow_node,
route_after_task,
SettlementState,
)| Example | Description |
|---|---|
examples/quickstart.py |
Minimal end-to-end: register agents, fund, run settlement graph, show balances |
examples/multi_step.py |
Multi-node task (research → analyze → summarize) wrapped in a single escrow |
examples/conditional_settlement.py |
Task output determines release vs refund vs dispute path |
pip install -e ".[dev]"
pytest -q| Repo | Framework | Pattern |
|---|---|---|
| a2a-settlement | Core protocol & exchange | SDK, spec |
| a2a-settlement-auth | OAuth | Settlement scopes, spending limits |
| a2a-settlement-mcp | MCP (any client) | Tools — use for MCP-only runtimes |
| crewai-a2a-settlement | CrewAI | SettledCrew / SettledTask |
| litellm-a2a-settlement | LiteLLM | CustomLogger hooks |
| adk-a2a-settlement | Google ADK | to_settled_a2a + SettledRemoteAgent |
| langgraph-a2a-settlement | LangGraph | Graph nodes + create_settlement_graph |
See also: settlebridge-ai (gateway), mcp-trust-gateway (MCP trust), otel-agent-provenance (OTel provenance), a2a-federation-rfc (federation spec).
MIT — see LICENSE.