open-agentpay 0.2.4__tar.gz → 0.2.8__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. {open_agentpay-0.2.4 → open_agentpay-0.2.8}/.gitignore +18 -6
  2. {open_agentpay-0.2.4 → open_agentpay-0.2.8}/PKG-INFO +30 -12
  3. {open_agentpay-0.2.4 → open_agentpay-0.2.8}/README.md +27 -9
  4. {open_agentpay-0.2.4 → open_agentpay-0.2.8}/pyproject.toml +3 -3
  5. {open_agentpay-0.2.4 → open_agentpay-0.2.8}/src/agentpay/__init__.py +1 -1
  6. {open_agentpay-0.2.4 → open_agentpay-0.2.8}/src/agentpay/budget/__init__.py +2 -0
  7. {open_agentpay-0.2.4 → open_agentpay-0.2.8}/src/agentpay/client/client.py +36 -36
  8. {open_agentpay-0.2.4 → open_agentpay-0.2.8}/src/agentpay/client/transport.py +68 -56
  9. {open_agentpay-0.2.4 → open_agentpay-0.2.8}/src/agentpay/core/models.py +29 -8
  10. {open_agentpay-0.2.4 → open_agentpay-0.2.8}/src/agentpay/policy/__init__.py +2 -0
  11. {open_agentpay-0.2.4 → open_agentpay-0.2.8}/src/agentpay/policy/config.py +8 -0
  12. {open_agentpay-0.2.4 → open_agentpay-0.2.8}/src/agentpay/policy/db.py +1 -0
  13. {open_agentpay-0.2.4 → open_agentpay-0.2.8}/src/agentpay/policy/errors.py +3 -5
  14. {open_agentpay-0.2.4 → open_agentpay-0.2.8}/src/agentpay/policy/evaluator.py +60 -29
  15. {open_agentpay-0.2.4 → open_agentpay-0.2.8}/src/agentpay/policy/metered.py +5 -5
  16. {open_agentpay-0.2.4 → open_agentpay-0.2.8}/src/agentpay/policy/models.py +31 -3
  17. {open_agentpay-0.2.4 → open_agentpay-0.2.8}/src/agentpay/policy/sqlite_engine.py +123 -133
  18. {open_agentpay-0.2.4 → open_agentpay-0.2.8}/src/agentpay/client/__init__.py +0 -0
  19. {open_agentpay-0.2.4 → open_agentpay-0.2.8}/src/agentpay/client/errors.py +0 -0
  20. {open_agentpay-0.2.4 → open_agentpay-0.2.8}/src/agentpay/client/interfaces.py +0 -0
  21. {open_agentpay-0.2.4 → open_agentpay-0.2.8}/src/agentpay/client/signer.py +0 -0
  22. {open_agentpay-0.2.4 → open_agentpay-0.2.8}/src/agentpay/core/__init__.py +0 -0
  23. {open_agentpay-0.2.4 → open_agentpay-0.2.8}/src/agentpay/core/codecs.py +0 -0
  24. {open_agentpay-0.2.4 → open_agentpay-0.2.8}/src/agentpay/core/errors.py +0 -0
  25. {open_agentpay-0.2.4 → open_agentpay-0.2.8}/src/agentpay/core/interop.py +0 -0
  26. {open_agentpay-0.2.4 → open_agentpay-0.2.8}/src/agentpay/core/state.py +0 -0
  27. {open_agentpay-0.2.4 → open_agentpay-0.2.8}/src/agentpay/evm/__init__.py +0 -0
  28. {open_agentpay-0.2.4 → open_agentpay-0.2.8}/src/agentpay/evm/constants.py +0 -0
  29. {open_agentpay-0.2.4 → open_agentpay-0.2.8}/src/agentpay/evm/eip3009.py +0 -0
  30. {open_agentpay-0.2.4 → open_agentpay-0.2.8}/src/agentpay/evm/rpc.py +0 -0
  31. {open_agentpay-0.2.4 → open_agentpay-0.2.8}/src/agentpay/integrations/__init__.py +0 -0
  32. {open_agentpay-0.2.4 → open_agentpay-0.2.8}/src/agentpay/integrations/langchain/__init__.py +0 -0
  33. {open_agentpay-0.2.4 → open_agentpay-0.2.8}/src/agentpay/integrations/langchain/http.py +0 -0
  34. {open_agentpay-0.2.4 → open_agentpay-0.2.8}/src/agentpay/integrations/langchain/tool.py +0 -0
  35. {open_agentpay-0.2.4 → open_agentpay-0.2.8}/src/agentpay/policy/interfaces.py +0 -0
  36. {open_agentpay-0.2.4 → open_agentpay-0.2.8}/src/agentpay/protocol/__init__.py +0 -0
  37. {open_agentpay-0.2.4 → open_agentpay-0.2.8}/src/agentpay/protocol/codecs.py +0 -0
  38. {open_agentpay-0.2.4 → open_agentpay-0.2.8}/src/agentpay/protocol/errors.py +0 -0
  39. {open_agentpay-0.2.4 → open_agentpay-0.2.8}/src/agentpay/protocol/interop.py +0 -0
  40. {open_agentpay-0.2.4 → open_agentpay-0.2.8}/src/agentpay/protocol/models.py +0 -0
  41. {open_agentpay-0.2.4 → open_agentpay-0.2.8}/src/agentpay/protocol/state.py +0 -0
  42. {open_agentpay-0.2.4 → open_agentpay-0.2.8}/src/agentpay/signer/__init__.py +0 -0
  43. {open_agentpay-0.2.4 → open_agentpay-0.2.8}/src/agentpay/state/__init__.py +0 -0
  44. {open_agentpay-0.2.4 → open_agentpay-0.2.8}/src/agentpay/state/buyer_coordinator.py +0 -0
  45. {open_agentpay-0.2.4 → open_agentpay-0.2.8}/src/agentpay/state/errors.py +0 -0
  46. {open_agentpay-0.2.4 → open_agentpay-0.2.8}/src/agentpay/state/guards.py +0 -0
  47. {open_agentpay-0.2.4 → open_agentpay-0.2.8}/src/agentpay/state/reconciliation.py +0 -0
  48. {open_agentpay-0.2.4 → open_agentpay-0.2.8}/src/agentpay/testing/__init__.py +0 -0
  49. {open_agentpay-0.2.4 → open_agentpay-0.2.8}/src/agentpay/testing/mock_seller.py +0 -0
@@ -18,6 +18,7 @@ Thumbs.db
18
18
 
19
19
  # Node.js & pnpm
20
20
  node_modules/
21
+ package-lock.json
21
22
  npm-debug.log*
22
23
  yarn-debug.log*
23
24
  yarn-error.log*
@@ -82,8 +83,8 @@ release.properties
82
83
  out/
83
84
 
84
85
  # Visual Studio Code
85
- .vscode/*
86
- !.vscode/settings.json
86
+ **/.vscode/*
87
+ !**/.vscode/settings.json
87
88
  !.vscode/tasks.json
88
89
  !.vscode/launch.json
89
90
  !.vscode/extensions.json
@@ -119,8 +120,9 @@ docs/.vitepress/cache/
119
120
  docs/.vitepress/dist/
120
121
  internal-docs/
121
122
 
122
- # Local gateway config with runtime credentials
123
- gateway-go/configs/gateway.yaml
123
+ # Local gateway/facilitator configs with runtime credentials
124
+ services/gateway/configs/gateway.yaml
125
+ services/facilitator/configs/facilitator.yaml
124
126
 
125
127
  # 同步产物不进 Git;手写的 index.md 与 reports/ 要进
126
128
  docs/specs/*.md
@@ -135,5 +137,15 @@ docs/zh/specs/adr/
135
137
  !docs/zh/specs/reports/
136
138
  !docs/zh/specs/reports/**
137
139
 
138
- # Agent skills
139
- .agents/skills/
140
+ # Agent skills & local assistant configs
141
+ .agents/
142
+ skills-lock.json
143
+
144
+ # Next.js build output
145
+ .next/
146
+ *.tsbuildinfo
147
+
148
+ # Internal specifications & proprietary strategy docs (local only, do not push to public GitHub)
149
+ specs/roadmap.md
150
+ specs/zh/roadmap.md
151
+ specs/zh/cn-enterprise-firewall-and-finops-strategy.md
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: open-agentpay
3
- Version: 0.2.4
3
+ Version: 0.2.8
4
4
  Summary: The Open-Source Payment Infrastructure & Financial Firewall for Autonomous AI Agents
5
- Project-URL: Homepage, https://github.com/open-agentpay/AgentPay
6
- Project-URL: Documentation, https://open-agentpay.github.io/AgentPay/
5
+ Project-URL: Homepage, https://openagentpay.dev/
6
+ Project-URL: Documentation, https://openagentpay.dev/
7
7
  Project-URL: Repository, https://github.com/open-agentpay/AgentPay
8
8
  Author: AgentPay Contributors
9
9
  License-Expression: Apache-2.0
@@ -33,7 +33,7 @@ Requires-Dist: langchain-core>=0.1.0; extra == 'langchain'
33
33
  Description-Content-Type: text/markdown
34
34
 
35
35
  <p align="center">
36
- <a href="https://open-agentpay.github.io/AgentPay/">
36
+ <a href="https://openagentpay.dev/">
37
37
  <img src="https://raw.githubusercontent.com/open-agentpay/AgentPay/main/docs/public/logo.png" alt="AgentPay Logo" width="120" height="120" />
38
38
  </a>
39
39
  </p>
@@ -46,7 +46,7 @@ Description-Content-Type: text/markdown
46
46
 
47
47
  <p align="center">
48
48
  <a href="https://pypi.org/project/open-agentpay/"><img src="https://img.shields.io/pypi/v/open-agentpay.svg" alt="PyPI Version"></a>
49
- <a href="https://open-agentpay.github.io/AgentPay/"><img src="https://img.shields.io/badge/Docs-Live-blue?logo=vitepress&logoColor=white" alt="Documentation"></a>
49
+ <a href="https://openagentpay.dev/"><img src="https://img.shields.io/badge/Docs-Live-blue?logo=vitepress&logoColor=white" alt="Documentation"></a>
50
50
  <a href="https://x.com/OpenAgentPay"><img src="https://img.shields.io/badge/Follow-%40OpenAgentPay-black?logo=x&logoColor=white" alt="Follow @OpenAgentPay"></a>
51
51
  <a href="https://github.com/open-agentpay/AgentPay/blob/main/LICENSE"><img src="https://img.shields.io/badge/License-Apache_2.0-blue.svg" alt="License: Apache-2.0"></a>
52
52
  <a href="https://github.com/open-agentpay/AgentPay"><img src="https://img.shields.io/badge/Protocol-x402_V2-orange.svg" alt="x402 V2"></a>
@@ -55,7 +55,7 @@ Description-Content-Type: text/markdown
55
55
  </p>
56
56
 
57
57
  <p align="center">
58
- <a href="https://open-agentpay.github.io/AgentPay/">📚 Documentation</a> •
58
+ <a href="https://openagentpay.dev/">📚 Documentation</a> •
59
59
  <a href="https://github.com/open-agentpay/AgentPay">💻 GitHub Repository</a> •
60
60
  <a href="https://x.com/OpenAgentPay">🐦 Follow on X (@OpenAgentPay)</a> •
61
61
  <a href="https://github.com/open-agentpay/AgentPay/issues">🐛 Report Issue</a>
@@ -65,7 +65,7 @@ Description-Content-Type: text/markdown
65
65
 
66
66
  ## 💡 What is AgentPay?
67
67
 
68
- **AgentPay** equips autonomous AI agents with micro-payments (Circle USDC on Arbitrum Sepolia & Base) governed by an in-process, non-custodial **Financial Firewall**. It transparently intercepts `HTTP 402 Payment Required` responses, validates policy limits, and signs off-chain authorizations—protecting agent wallets against runaway loops and LLM hallucinations.
68
+ **AgentPay** equips autonomous AI agents with micro-payments (Circle USDC on Arbitrum Sepolia & Base Sepolia) governed by an in-process, non-custodial **Financial Firewall**. It transparently intercepts `HTTP 402 Payment Required` responses, validates policy limits, and signs off-chain authorizations—protecting agent wallets against runaway loops and LLM hallucinations.
69
69
 
70
70
  > 📦 **Package Name Note**: The canonical PyPI distribution is [`open-agentpay`](https://pypi.org/project/open-agentpay/) (official aliases: `agentpay-core`, `agentpay-firewall`). Regardless of which package you install, you import `agentpay` in Python code.
71
71
 
@@ -89,16 +89,21 @@ pip install "open-agentpay[langchain]"
89
89
  Transparently intercepts HTTP 402 challenges, enforces local policy limits, and signs off-chain EIP-712/EIP-3009 authorizations:
90
90
 
91
91
  ```python
92
+ import os
92
93
  from agentpay import AgentPayClient, LocalSigner
93
94
  from agentpay.policy import SQLitePolicyEngine, PolicyConfig
94
95
 
95
96
  # 1. Initialize local signer (non-custodial private key, 0 gas required)
96
- signer = LocalSigner("0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80")
97
+ # ⚠️ TESTNET DEVELOPMENT ONLY: This fallback key is Hardhat/Anvil's public Account 0 key.
98
+ # NEVER transfer mainnet funds to this address! In production, inject via environment variable:
99
+ private_key = os.getenv("AGENT_PRIVATE_KEY", "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80")
100
+ signer = LocalSigner(private_key)
97
101
 
98
102
  # 2. Configure local financial firewall
99
103
  policy = SQLitePolicyEngine.create_in_memory(
100
104
  PolicyConfig(
101
105
  id="agent_firewall",
106
+ name="Agent Firewall",
102
107
  wallet_address=signer.address,
103
108
  max_per_tx_base_units=100_000, # Max $0.10 per call
104
109
  rolling_budget_24h_base_units=1_000_000, # Daily cap $1.00
@@ -119,13 +124,26 @@ print(response.json())
119
124
  For sub-millisecond execution using a pre-funded virtual ledger:
120
125
 
121
126
  ```python
127
+ import os
122
128
  from agentpay import AgentPayClient, LocalSigner
123
129
  from agentpay.policy import SQLitePolicyEngine, PolicyConfig
124
130
 
131
+ private_key = os.getenv("AGENT_PRIVATE_KEY", "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80")
132
+ signer = LocalSigner(private_key)
125
133
  client = AgentPayClient(
126
- signer=LocalSigner("0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"),
127
- policy=SQLitePolicyEngine.create_in_memory(PolicyConfig(...)),
134
+ signer=signer,
135
+ policy=SQLitePolicyEngine.create_in_memory(
136
+ PolicyConfig(
137
+ id="wallet_firewall",
138
+ name="Wallet Firewall",
139
+ wallet_address=signer.address,
140
+ max_per_tx_base_units=100_000,
141
+ rolling_budget_24h_base_units=5_000_000,
142
+ whitelist_domains=frozenset(["gateway.seller.com"]),
143
+ )
144
+ ),
128
145
  headers={"Authorization": "Bearer agp_live_your_api_key"},
146
+ wallet_challenge_mode=True,
129
147
  )
130
148
 
131
149
  response = client.get("https://gateway.seller.com/v1/compute")
@@ -176,7 +194,7 @@ asyncio.run(main())
176
194
  |---|---|
177
195
  | **Zero-Trust Financial Firewall** | Enforces per-transaction caps, 24-hour rolling budgets, lifetime limits, and payee whitelists outside the LLM prompt. |
178
196
  | **Autonomous Circuit Breaker** | Automatically halts agent loops and freezes spending when request frequency exceeds safety thresholds (`circuit_max_rpm`). |
179
- | **Gasless Off-Chain Settlements** | AI Agents hold only Circle USDC; gas is sponsored on Arbitrum Sepolia & Base via EIP-3009 off-chain authorizations. |
197
+ | **Gasless Off-Chain Settlements** | AI Agents hold only Circle USDC; gas is sponsored on Arbitrum Sepolia & Base Sepolia via EIP-3009 off-chain authorizations. |
180
198
  | **Agent Session & Audit Observability** | Automatic tracking headers (`X-Agent-Session-ID`, `X-Agent-Task-ID`) connect tool spending to tasks in the AgentPay Console. |
181
199
  | **Fail-Closed Guarantees** | Any policy violation, budget overrun, or upstream failure aborts safely with zero funds deducted. |
182
200
 
@@ -184,7 +202,7 @@ asyncio.run(main())
184
202
 
185
203
  ## 📖 Documentation & Community
186
204
 
187
- - **Official Documentation**: [https://open-agentpay.github.io/AgentPay/](https://open-agentpay.github.io/AgentPay/)
205
+ - **Official Documentation**: [https://openagentpay.dev/](https://openagentpay.dev/)
188
206
  - **GitHub Repository**: [https://github.com/open-agentpay/AgentPay](https://github.com/open-agentpay/AgentPay)
189
207
  - **Twitter / X**: [@OpenAgentPay](https://x.com/OpenAgentPay)
190
208
  - **Issue Tracker**: [GitHub Issues](https://github.com/open-agentpay/AgentPay/issues)
@@ -1,5 +1,5 @@
1
1
  <p align="center">
2
- <a href="https://open-agentpay.github.io/AgentPay/">
2
+ <a href="https://openagentpay.dev/">
3
3
  <img src="https://raw.githubusercontent.com/open-agentpay/AgentPay/main/docs/public/logo.png" alt="AgentPay Logo" width="120" height="120" />
4
4
  </a>
5
5
  </p>
@@ -12,7 +12,7 @@
12
12
 
13
13
  <p align="center">
14
14
  <a href="https://pypi.org/project/open-agentpay/"><img src="https://img.shields.io/pypi/v/open-agentpay.svg" alt="PyPI Version"></a>
15
- <a href="https://open-agentpay.github.io/AgentPay/"><img src="https://img.shields.io/badge/Docs-Live-blue?logo=vitepress&logoColor=white" alt="Documentation"></a>
15
+ <a href="https://openagentpay.dev/"><img src="https://img.shields.io/badge/Docs-Live-blue?logo=vitepress&logoColor=white" alt="Documentation"></a>
16
16
  <a href="https://x.com/OpenAgentPay"><img src="https://img.shields.io/badge/Follow-%40OpenAgentPay-black?logo=x&logoColor=white" alt="Follow @OpenAgentPay"></a>
17
17
  <a href="https://github.com/open-agentpay/AgentPay/blob/main/LICENSE"><img src="https://img.shields.io/badge/License-Apache_2.0-blue.svg" alt="License: Apache-2.0"></a>
18
18
  <a href="https://github.com/open-agentpay/AgentPay"><img src="https://img.shields.io/badge/Protocol-x402_V2-orange.svg" alt="x402 V2"></a>
@@ -21,7 +21,7 @@
21
21
  </p>
22
22
 
23
23
  <p align="center">
24
- <a href="https://open-agentpay.github.io/AgentPay/">📚 Documentation</a> •
24
+ <a href="https://openagentpay.dev/">📚 Documentation</a> •
25
25
  <a href="https://github.com/open-agentpay/AgentPay">💻 GitHub Repository</a> •
26
26
  <a href="https://x.com/OpenAgentPay">🐦 Follow on X (@OpenAgentPay)</a> •
27
27
  <a href="https://github.com/open-agentpay/AgentPay/issues">🐛 Report Issue</a>
@@ -31,7 +31,7 @@
31
31
 
32
32
  ## 💡 What is AgentPay?
33
33
 
34
- **AgentPay** equips autonomous AI agents with micro-payments (Circle USDC on Arbitrum Sepolia & Base) governed by an in-process, non-custodial **Financial Firewall**. It transparently intercepts `HTTP 402 Payment Required` responses, validates policy limits, and signs off-chain authorizations—protecting agent wallets against runaway loops and LLM hallucinations.
34
+ **AgentPay** equips autonomous AI agents with micro-payments (Circle USDC on Arbitrum Sepolia & Base Sepolia) governed by an in-process, non-custodial **Financial Firewall**. It transparently intercepts `HTTP 402 Payment Required` responses, validates policy limits, and signs off-chain authorizations—protecting agent wallets against runaway loops and LLM hallucinations.
35
35
 
36
36
  > 📦 **Package Name Note**: The canonical PyPI distribution is [`open-agentpay`](https://pypi.org/project/open-agentpay/) (official aliases: `agentpay-core`, `agentpay-firewall`). Regardless of which package you install, you import `agentpay` in Python code.
37
37
 
@@ -55,16 +55,21 @@ pip install "open-agentpay[langchain]"
55
55
  Transparently intercepts HTTP 402 challenges, enforces local policy limits, and signs off-chain EIP-712/EIP-3009 authorizations:
56
56
 
57
57
  ```python
58
+ import os
58
59
  from agentpay import AgentPayClient, LocalSigner
59
60
  from agentpay.policy import SQLitePolicyEngine, PolicyConfig
60
61
 
61
62
  # 1. Initialize local signer (non-custodial private key, 0 gas required)
62
- signer = LocalSigner("0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80")
63
+ # ⚠️ TESTNET DEVELOPMENT ONLY: This fallback key is Hardhat/Anvil's public Account 0 key.
64
+ # NEVER transfer mainnet funds to this address! In production, inject via environment variable:
65
+ private_key = os.getenv("AGENT_PRIVATE_KEY", "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80")
66
+ signer = LocalSigner(private_key)
63
67
 
64
68
  # 2. Configure local financial firewall
65
69
  policy = SQLitePolicyEngine.create_in_memory(
66
70
  PolicyConfig(
67
71
  id="agent_firewall",
72
+ name="Agent Firewall",
68
73
  wallet_address=signer.address,
69
74
  max_per_tx_base_units=100_000, # Max $0.10 per call
70
75
  rolling_budget_24h_base_units=1_000_000, # Daily cap $1.00
@@ -85,13 +90,26 @@ print(response.json())
85
90
  For sub-millisecond execution using a pre-funded virtual ledger:
86
91
 
87
92
  ```python
93
+ import os
88
94
  from agentpay import AgentPayClient, LocalSigner
89
95
  from agentpay.policy import SQLitePolicyEngine, PolicyConfig
90
96
 
97
+ private_key = os.getenv("AGENT_PRIVATE_KEY", "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80")
98
+ signer = LocalSigner(private_key)
91
99
  client = AgentPayClient(
92
- signer=LocalSigner("0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"),
93
- policy=SQLitePolicyEngine.create_in_memory(PolicyConfig(...)),
100
+ signer=signer,
101
+ policy=SQLitePolicyEngine.create_in_memory(
102
+ PolicyConfig(
103
+ id="wallet_firewall",
104
+ name="Wallet Firewall",
105
+ wallet_address=signer.address,
106
+ max_per_tx_base_units=100_000,
107
+ rolling_budget_24h_base_units=5_000_000,
108
+ whitelist_domains=frozenset(["gateway.seller.com"]),
109
+ )
110
+ ),
94
111
  headers={"Authorization": "Bearer agp_live_your_api_key"},
112
+ wallet_challenge_mode=True,
95
113
  )
96
114
 
97
115
  response = client.get("https://gateway.seller.com/v1/compute")
@@ -142,7 +160,7 @@ asyncio.run(main())
142
160
  |---|---|
143
161
  | **Zero-Trust Financial Firewall** | Enforces per-transaction caps, 24-hour rolling budgets, lifetime limits, and payee whitelists outside the LLM prompt. |
144
162
  | **Autonomous Circuit Breaker** | Automatically halts agent loops and freezes spending when request frequency exceeds safety thresholds (`circuit_max_rpm`). |
145
- | **Gasless Off-Chain Settlements** | AI Agents hold only Circle USDC; gas is sponsored on Arbitrum Sepolia & Base via EIP-3009 off-chain authorizations. |
163
+ | **Gasless Off-Chain Settlements** | AI Agents hold only Circle USDC; gas is sponsored on Arbitrum Sepolia & Base Sepolia via EIP-3009 off-chain authorizations. |
146
164
  | **Agent Session & Audit Observability** | Automatic tracking headers (`X-Agent-Session-ID`, `X-Agent-Task-ID`) connect tool spending to tasks in the AgentPay Console. |
147
165
  | **Fail-Closed Guarantees** | Any policy violation, budget overrun, or upstream failure aborts safely with zero funds deducted. |
148
166
 
@@ -150,7 +168,7 @@ asyncio.run(main())
150
168
 
151
169
  ## 📖 Documentation & Community
152
170
 
153
- - **Official Documentation**: [https://open-agentpay.github.io/AgentPay/](https://open-agentpay.github.io/AgentPay/)
171
+ - **Official Documentation**: [https://openagentpay.dev/](https://openagentpay.dev/)
154
172
  - **GitHub Repository**: [https://github.com/open-agentpay/AgentPay](https://github.com/open-agentpay/AgentPay)
155
173
  - **Twitter / X**: [@OpenAgentPay](https://x.com/OpenAgentPay)
156
174
  - **Issue Tracker**: [GitHub Issues](https://github.com/open-agentpay/AgentPay/issues)
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "open-agentpay"
7
- version = "0.2.4"
7
+ version = "0.2.8"
8
8
  description = "The Open-Source Payment Infrastructure & Financial Firewall for Autonomous AI Agents"
9
9
  readme = "README.md"
10
10
  license = "Apache-2.0"
@@ -44,8 +44,8 @@ dev = [
44
44
  ]
45
45
 
46
46
  [project.urls]
47
- Homepage = "https://github.com/open-agentpay/AgentPay"
48
- Documentation = "https://open-agentpay.github.io/AgentPay/"
47
+ Homepage = "https://openagentpay.dev/"
48
+ Documentation = "https://openagentpay.dev/"
49
49
  Repository = "https://github.com/open-agentpay/AgentPay"
50
50
 
51
51
  [tool.hatch.build.targets.wheel]
@@ -3,7 +3,7 @@ AgentPay Python SDK
3
3
  The Open-Source Payment Infrastructure & Financial Firewall for Autonomous AI Agents.
4
4
  """
5
5
 
6
- __version__ = "0.2.4"
6
+ __version__ = "0.2.8"
7
7
 
8
8
  from agentpay.client import (
9
9
  AgentPayClient,
@@ -14,6 +14,7 @@ from agentpay.policy.models import (
14
14
  PolicyConfig,
15
15
  PolicyDecision,
16
16
  ReservationToken,
17
+ WhitelistMode,
17
18
  )
18
19
 
19
20
  # Backward compatibility / convenient domain aliases
@@ -34,4 +35,5 @@ __all__ = [
34
35
  "PolicyEvaluationResult",
35
36
  "PolicyStatus",
36
37
  "ReservationToken",
38
+ "WhitelistMode",
37
39
  ]
@@ -57,22 +57,22 @@ class AgentPayClient(httpx.Client):
57
57
  """
58
58
 
59
59
  def __init__(
60
- self,
61
- signer: ISigner,
62
- policy: IPolicyEngine,
63
- *,
64
- transport: httpx.BaseTransport | None = None,
65
- auto_retry_on_402: bool = True,
66
- raise_on_policy_rejection: bool = False,
67
- clock: Callable[[], int] | None = None,
68
- unmetered_credential_policy: CredentialMode = "block",
69
- credential_headers: tuple[str, ...] = DEFAULT_CREDENTIAL_HEADERS,
70
- credential_value_prefixes: tuple[str, ...] = DEFAULT_CREDENTIAL_VALUE_PREFIXES,
71
- estimate_cost: Callable[[httpx.Request], int] | None = None,
72
- actual_cost: Callable[[httpx.Response], int | None] | None = None,
73
- credential_ttl_seconds: int = 60,
74
- wallet_challenge_mode: bool = False,
75
- **kwargs: Any,
60
+ self,
61
+ signer: ISigner,
62
+ policy: IPolicyEngine,
63
+ *,
64
+ transport: httpx.BaseTransport | None = None,
65
+ auto_retry_on_402: bool = True,
66
+ raise_on_policy_rejection: bool = False,
67
+ clock: Callable[[], int] | None = None,
68
+ unmetered_credential_policy: CredentialMode = "block",
69
+ credential_headers: tuple[str, ...] = DEFAULT_CREDENTIAL_HEADERS,
70
+ credential_value_prefixes: tuple[str, ...] = DEFAULT_CREDENTIAL_VALUE_PREFIXES,
71
+ estimate_cost: Callable[[httpx.Request], int] | None = None,
72
+ actual_cost: Callable[[httpx.Response], int | None] | None = None,
73
+ credential_ttl_seconds: int = 60,
74
+ wallet_challenge_mode: bool = False,
75
+ **kwargs: Any,
76
76
  ) -> None:
77
77
  inner_kwargs = _inner_transport_kwargs(kwargs)
78
78
 
@@ -101,10 +101,10 @@ class AgentPayClient(httpx.Client):
101
101
  super().__init__(transport=agent_transport, **kwargs)
102
102
 
103
103
  def async_client(
104
- self,
105
- *,
106
- transport: httpx.AsyncBaseTransport | None = None,
107
- **kwargs: Any,
104
+ self,
105
+ *,
106
+ transport: httpx.AsyncBaseTransport | None = None,
107
+ **kwargs: Any,
108
108
  ) -> AsyncAgentPayClient:
109
109
  """Create an AsyncAgentPayClient sharing the same signer, policy and firewall options."""
110
110
  options = {**self._agentpay_options, **{k: v for k, v in kwargs.items() if k in self._agentpay_options}}
@@ -127,22 +127,22 @@ class AsyncAgentPayClient(httpx.AsyncClient):
127
127
  """
128
128
 
129
129
  def __init__(
130
- self,
131
- signer: ISigner,
132
- policy: IPolicyEngine,
133
- *,
134
- transport: httpx.AsyncBaseTransport | None = None,
135
- auto_retry_on_402: bool = True,
136
- raise_on_policy_rejection: bool = False,
137
- clock: Callable[[], int] | None = None,
138
- unmetered_credential_policy: CredentialMode = "block",
139
- credential_headers: tuple[str, ...] = DEFAULT_CREDENTIAL_HEADERS,
140
- credential_value_prefixes: tuple[str, ...] = DEFAULT_CREDENTIAL_VALUE_PREFIXES,
141
- estimate_cost: Callable[[httpx.Request], int] | None = None,
142
- actual_cost: Callable[[httpx.Response], int | None] | None = None,
143
- credential_ttl_seconds: int = 60,
144
- wallet_challenge_mode: bool = False,
145
- **kwargs: Any,
130
+ self,
131
+ signer: ISigner,
132
+ policy: IPolicyEngine,
133
+ *,
134
+ transport: httpx.AsyncBaseTransport | None = None,
135
+ auto_retry_on_402: bool = True,
136
+ raise_on_policy_rejection: bool = False,
137
+ clock: Callable[[], int] | None = None,
138
+ unmetered_credential_policy: CredentialMode = "block",
139
+ credential_headers: tuple[str, ...] = DEFAULT_CREDENTIAL_HEADERS,
140
+ credential_value_prefixes: tuple[str, ...] = DEFAULT_CREDENTIAL_VALUE_PREFIXES,
141
+ estimate_cost: Callable[[httpx.Request], int] | None = None,
142
+ actual_cost: Callable[[httpx.Response], int | None] | None = None,
143
+ credential_ttl_seconds: int = 60,
144
+ wallet_challenge_mode: bool = False,
145
+ **kwargs: Any,
146
146
  ) -> None:
147
147
  inner_kwargs = _inner_transport_kwargs(kwargs)
148
148
 
@@ -111,26 +111,27 @@ def _safe_record_failure(policy: Any, reason: str) -> None:
111
111
 
112
112
  class _AgentPayCore:
113
113
  def __init__(
114
- self,
115
- signer: ISigner,
116
- policy: IPolicyEngine,
117
- *,
118
- auto_retry_on_402: bool,
119
- raise_on_policy_rejection: bool,
120
- clock: Callable[[], int] | None,
121
- unmetered_credential_policy: CredentialMode,
122
- credential_headers: tuple[str, ...],
123
- credential_value_prefixes: tuple[str, ...],
124
- estimate_cost: Callable[[httpx.Request], int] | None,
125
- actual_cost: Callable[[httpx.Response], int | None] | None,
126
- credential_ttl_seconds: int,
127
- wallet_challenge_mode: bool,
114
+ self,
115
+ signer: ISigner,
116
+ policy: IPolicyEngine,
117
+ *,
118
+ auto_retry_on_402: bool,
119
+ raise_on_policy_rejection: bool,
120
+ clock: Callable[[], int] | None,
121
+ unmetered_credential_policy: CredentialMode,
122
+ credential_headers: tuple[str, ...],
123
+ credential_value_prefixes: tuple[str, ...],
124
+ estimate_cost: Callable[[httpx.Request], int] | None,
125
+ actual_cost: Callable[[httpx.Response], int | None] | None,
126
+ credential_ttl_seconds: int,
127
+ wallet_challenge_mode: bool,
128
128
  ) -> None:
129
129
  if unmetered_credential_policy not in ("block", "meter", "allow"):
130
130
  raise ValueError(
131
- f"unmetered_credential_policy must be block/meter/allow, got {unmetered_credential_policy!r}")
131
+ f"unmetered_credential_policy must be block/meter/allow, got {unmetered_credential_policy!r}"
132
+ )
132
133
  if unmetered_credential_policy == "meter" and (
133
- estimate_cost is None or not isinstance(policy, IMeteredPolicyEngine)
134
+ estimate_cost is None or not isinstance(policy, IMeteredPolicyEngine)
134
135
  ):
135
136
  raise ValueError("meter mode requires estimate_cost and a policy implementing IMeteredPolicyEngine")
136
137
 
@@ -182,9 +183,7 @@ class _AgentPayCore:
182
183
  try:
183
184
  estimate = self._estimate_cost(request)
184
185
  except Exception as exc: # noqa: BLE001
185
- raise PolicyViolationError(
186
- PolicyErrorCode.INVALID_AMOUNT_FORMAT, "estimate_cost callback failed"
187
- ) from exc
186
+ raise PolicyViolationError(PolicyErrorCode.INVALID_AMOUNT_FORMAT, "estimate_cost callback failed") from exc
188
187
 
189
188
  intent_id = f"cred_{uuid.uuid4().hex}"
190
189
  decision = self._policy.reserve_metered( # type: ignore[attr-defined]
@@ -225,11 +224,15 @@ class _AgentPayCore:
225
224
  if challenge.is_expired(self._clock()):
226
225
  return None
227
226
  if challenge.scheme not in ("EIP-3009", "agentpay-wallet"):
228
- raise PolicyViolationError(PolicyErrorCode.POLICY_SYSTEM_ERROR, f"unsupported payment scheme: {challenge.scheme}")
227
+ raise PolicyViolationError(
228
+ PolicyErrorCode.POLICY_SYSTEM_ERROR, f"unsupported payment scheme: {challenge.scheme}"
229
+ )
229
230
  if challenge.scheme == "agentpay-wallet":
230
231
  expected_binding = self._request_binding(request)
231
232
  if (challenge.extensions or {}).get("requestBinding") != expected_binding:
232
- raise PolicyViolationError(PolicyErrorCode.POLICY_SYSTEM_ERROR, "wallet challenge requestBinding mismatch")
233
+ raise PolicyViolationError(
234
+ PolicyErrorCode.POLICY_SYSTEM_ERROR, "wallet challenge requestBinding mismatch"
235
+ )
233
236
  if not (challenge.extensions or {}).get("routeId"):
234
237
  raise PolicyViolationError(PolicyErrorCode.POLICY_SYSTEM_ERROR, "wallet challenge missing routeId")
235
238
  raw_path, _, _ = request.url.raw_path.partition(b"?")
@@ -272,12 +275,18 @@ class _AgentPayCore:
272
275
  if challenge.scheme == "agentpay-wallet":
273
276
  # SECURITY-REVIEW: the challenge-bound reservation is the buyer-side approval gate.
274
277
  if reservation.intent_id != challenge.challenge_id or reservation.amount != challenge.amount_base_units:
275
- raise PolicyViolationError(PolicyErrorCode.POLICY_SYSTEM_ERROR, "wallet reservation does not match challenge")
278
+ raise PolicyViolationError(
279
+ PolicyErrorCode.POLICY_SYSTEM_ERROR, "wallet reservation does not match challenge"
280
+ )
276
281
  if reservation.expires_at < challenge.valid_before:
277
- raise PolicyViolationError(PolicyErrorCode.POLICY_SYSTEM_ERROR, "wallet reservation expires before challenge")
282
+ raise PolicyViolationError(
283
+ PolicyErrorCode.POLICY_SYSTEM_ERROR, "wallet reservation expires before challenge"
284
+ )
278
285
  request_binding = (challenge.extensions or {}).get("requestBinding")
279
286
  if not request_binding:
280
- raise PolicyViolationError(PolicyErrorCode.POLICY_SYSTEM_ERROR, "wallet challenge missing requestBinding")
287
+ raise PolicyViolationError(
288
+ PolicyErrorCode.POLICY_SYSTEM_ERROR, "wallet challenge missing requestBinding"
289
+ )
281
290
  wallet_auth = WalletAuthorization(
282
291
  challengeId=challenge.challenge_id,
283
292
  nonce="0x" + secrets.token_bytes(32).hex(),
@@ -291,8 +300,11 @@ class _AgentPayCore:
291
300
  headers["PAYMENT-SIGNATURE"] = encode_wallet_authorization(wallet_auth)
292
301
  content = request.read()
293
302
  return httpx.Request(
294
- method=request.method, url=request.url, headers=headers,
295
- content=content, extensions=dict(request.extensions),
303
+ method=request.method,
304
+ url=request.url,
305
+ headers=headers,
306
+ content=content,
307
+ extensions=dict(request.extensions),
296
308
  )
297
309
  authorization = self._signer.sign_payment_authorization(challenge, reservation)
298
310
  return _clone_request_with_authorization(request, authorization)
@@ -328,21 +340,21 @@ class AgentPayTransport(_AgentPayCore, httpx.BaseTransport):
328
340
  """
329
341
 
330
342
  def __init__(
331
- self,
332
- inner_transport: httpx.BaseTransport,
333
- signer: ISigner,
334
- policy: IPolicyEngine,
335
- *,
336
- auto_retry_on_402: bool = True,
337
- raise_on_policy_rejection: bool = False,
338
- clock: Callable[[], int] | None = None,
339
- unmetered_credential_policy: CredentialMode = "block",
340
- credential_headers: tuple[str, ...] = DEFAULT_CREDENTIAL_HEADERS,
341
- credential_value_prefixes: tuple[str, ...] = DEFAULT_CREDENTIAL_VALUE_PREFIXES,
342
- estimate_cost: Callable[[httpx.Request], int] | None = None,
343
- actual_cost: Callable[[httpx.Response], int | None] | None = None,
344
- credential_ttl_seconds: int = 60,
345
- wallet_challenge_mode: bool = False,
343
+ self,
344
+ inner_transport: httpx.BaseTransport,
345
+ signer: ISigner,
346
+ policy: IPolicyEngine,
347
+ *,
348
+ auto_retry_on_402: bool = True,
349
+ raise_on_policy_rejection: bool = False,
350
+ clock: Callable[[], int] | None = None,
351
+ unmetered_credential_policy: CredentialMode = "block",
352
+ credential_headers: tuple[str, ...] = DEFAULT_CREDENTIAL_HEADERS,
353
+ credential_value_prefixes: tuple[str, ...] = DEFAULT_CREDENTIAL_VALUE_PREFIXES,
354
+ estimate_cost: Callable[[httpx.Request], int] | None = None,
355
+ actual_cost: Callable[[httpx.Response], int | None] | None = None,
356
+ credential_ttl_seconds: int = 60,
357
+ wallet_challenge_mode: bool = False,
346
358
  ) -> None:
347
359
  httpx.BaseTransport.__init__(self)
348
360
  _AgentPayCore.__init__(
@@ -415,21 +427,21 @@ class AsyncAgentPayTransport(_AgentPayCore, httpx.AsyncBaseTransport):
415
427
  """
416
428
 
417
429
  def __init__(
418
- self,
419
- inner_transport: httpx.AsyncBaseTransport,
420
- signer: ISigner,
421
- policy: IPolicyEngine,
422
- *,
423
- auto_retry_on_402: bool = True,
424
- raise_on_policy_rejection: bool = False,
425
- clock: Callable[[], int] | None = None,
426
- unmetered_credential_policy: CredentialMode = "block",
427
- credential_headers: tuple[str, ...] = DEFAULT_CREDENTIAL_HEADERS,
428
- credential_value_prefixes: tuple[str, ...] = DEFAULT_CREDENTIAL_VALUE_PREFIXES,
429
- estimate_cost: Callable[[httpx.Request], int] | None = None,
430
- actual_cost: Callable[[httpx.Response], int | None] | None = None,
431
- credential_ttl_seconds: int = 60,
432
- wallet_challenge_mode: bool = False,
430
+ self,
431
+ inner_transport: httpx.AsyncBaseTransport,
432
+ signer: ISigner,
433
+ policy: IPolicyEngine,
434
+ *,
435
+ auto_retry_on_402: bool = True,
436
+ raise_on_policy_rejection: bool = False,
437
+ clock: Callable[[], int] | None = None,
438
+ unmetered_credential_policy: CredentialMode = "block",
439
+ credential_headers: tuple[str, ...] = DEFAULT_CREDENTIAL_HEADERS,
440
+ credential_value_prefixes: tuple[str, ...] = DEFAULT_CREDENTIAL_VALUE_PREFIXES,
441
+ estimate_cost: Callable[[httpx.Request], int] | None = None,
442
+ actual_cost: Callable[[httpx.Response], int | None] | None = None,
443
+ credential_ttl_seconds: int = 60,
444
+ wallet_challenge_mode: bool = False,
433
445
  ) -> None:
434
446
  httpx.AsyncBaseTransport.__init__(self)
435
447
  _AgentPayCore.__init__(