open-agentpay 0.1.0__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.
- open_agentpay-0.1.0/.gitignore +116 -0
- open_agentpay-0.1.0/PKG-INFO +101 -0
- open_agentpay-0.1.0/README.md +67 -0
- open_agentpay-0.1.0/pyproject.toml +52 -0
- open_agentpay-0.1.0/src/agentpay/__init__.py +45 -0
- open_agentpay-0.1.0/src/agentpay/budget/__init__.py +37 -0
- open_agentpay-0.1.0/src/agentpay/client/__init__.py +41 -0
- open_agentpay-0.1.0/src/agentpay/client/client.py +109 -0
- open_agentpay-0.1.0/src/agentpay/client/errors.py +28 -0
- open_agentpay-0.1.0/src/agentpay/client/interfaces.py +53 -0
- open_agentpay-0.1.0/src/agentpay/client/signer.py +340 -0
- open_agentpay-0.1.0/src/agentpay/client/transport.py +223 -0
- open_agentpay-0.1.0/src/agentpay/core/__init__.py +73 -0
- open_agentpay-0.1.0/src/agentpay/core/codecs.py +237 -0
- open_agentpay-0.1.0/src/agentpay/core/errors.py +70 -0
- open_agentpay-0.1.0/src/agentpay/core/interop.py +69 -0
- open_agentpay-0.1.0/src/agentpay/core/models.py +462 -0
- open_agentpay-0.1.0/src/agentpay/core/state.py +161 -0
- open_agentpay-0.1.0/src/agentpay/evm/__init__.py +79 -0
- open_agentpay-0.1.0/src/agentpay/evm/constants.py +118 -0
- open_agentpay-0.1.0/src/agentpay/evm/eip3009.py +194 -0
- open_agentpay-0.1.0/src/agentpay/evm/rpc.py +291 -0
- open_agentpay-0.1.0/src/agentpay/integrations/__init__.py +10 -0
- open_agentpay-0.1.0/src/agentpay/integrations/langchain/__init__.py +20 -0
- open_agentpay-0.1.0/src/agentpay/integrations/langchain/http.py +174 -0
- open_agentpay-0.1.0/src/agentpay/integrations/langchain/tool.py +210 -0
- open_agentpay-0.1.0/src/agentpay/policy/__init__.py +39 -0
- open_agentpay-0.1.0/src/agentpay/policy/config.py +118 -0
- open_agentpay-0.1.0/src/agentpay/policy/db.py +128 -0
- open_agentpay-0.1.0/src/agentpay/policy/errors.py +65 -0
- open_agentpay-0.1.0/src/agentpay/policy/evaluator.py +114 -0
- open_agentpay-0.1.0/src/agentpay/policy/interfaces.py +109 -0
- open_agentpay-0.1.0/src/agentpay/policy/models.py +343 -0
- open_agentpay-0.1.0/src/agentpay/policy/sqlite_engine.py +622 -0
- open_agentpay-0.1.0/src/agentpay/protocol/__init__.py +73 -0
- open_agentpay-0.1.0/src/agentpay/protocol/codecs.py +237 -0
- open_agentpay-0.1.0/src/agentpay/protocol/errors.py +70 -0
- open_agentpay-0.1.0/src/agentpay/protocol/interop.py +69 -0
- open_agentpay-0.1.0/src/agentpay/protocol/models.py +462 -0
- open_agentpay-0.1.0/src/agentpay/protocol/state.py +161 -0
- open_agentpay-0.1.0/src/agentpay/signer/__init__.py +39 -0
- open_agentpay-0.1.0/src/agentpay/state/__init__.py +65 -0
- open_agentpay-0.1.0/src/agentpay/state/buyer_coordinator.py +537 -0
- open_agentpay-0.1.0/src/agentpay/state/errors.py +104 -0
- open_agentpay-0.1.0/src/agentpay/state/guards.py +344 -0
- open_agentpay-0.1.0/src/agentpay/state/reconciliation.py +422 -0
- open_agentpay-0.1.0/src/agentpay/testing/__init__.py +17 -0
- open_agentpay-0.1.0/src/agentpay/testing/mock_seller.py +296 -0
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# Operating System Files
|
|
2
|
+
.DS_Store
|
|
3
|
+
.DS_Store?
|
|
4
|
+
._*
|
|
5
|
+
.Spotlight-V100
|
|
6
|
+
.Trashes
|
|
7
|
+
ehthumbs.db
|
|
8
|
+
Thumbs.db
|
|
9
|
+
|
|
10
|
+
# Environment & Secrets
|
|
11
|
+
.env
|
|
12
|
+
.env.local
|
|
13
|
+
.env.*.local
|
|
14
|
+
*.pem
|
|
15
|
+
*.key
|
|
16
|
+
*.p12
|
|
17
|
+
*.keystore
|
|
18
|
+
|
|
19
|
+
# Node.js & pnpm
|
|
20
|
+
node_modules/
|
|
21
|
+
npm-debug.log*
|
|
22
|
+
yarn-debug.log*
|
|
23
|
+
yarn-error.log*
|
|
24
|
+
pnpm-debug.log*
|
|
25
|
+
lerna-debug.log*
|
|
26
|
+
.pnpm-store/
|
|
27
|
+
.pnpm-debug.log*
|
|
28
|
+
|
|
29
|
+
# Build outputs (TypeScript / JavaScript)
|
|
30
|
+
dist/
|
|
31
|
+
build/
|
|
32
|
+
out/
|
|
33
|
+
.turbo/
|
|
34
|
+
*.tsbuildinfo
|
|
35
|
+
.eslintcache
|
|
36
|
+
|
|
37
|
+
# Python
|
|
38
|
+
__pycache__/
|
|
39
|
+
*.py[cod]
|
|
40
|
+
*$py.class
|
|
41
|
+
*.so
|
|
42
|
+
.Python
|
|
43
|
+
env/
|
|
44
|
+
venv/
|
|
45
|
+
.venv/
|
|
46
|
+
ENV/
|
|
47
|
+
*.egg-info/
|
|
48
|
+
.eggs/
|
|
49
|
+
*.egg
|
|
50
|
+
.pytest_cache/
|
|
51
|
+
.mypy_cache/
|
|
52
|
+
.ruff_cache/
|
|
53
|
+
|
|
54
|
+
# Java & Gradle
|
|
55
|
+
.gradle/
|
|
56
|
+
build/
|
|
57
|
+
!src/**/build/
|
|
58
|
+
bin/
|
|
59
|
+
*.class
|
|
60
|
+
*.jar
|
|
61
|
+
*.war
|
|
62
|
+
*.ear
|
|
63
|
+
*.nar
|
|
64
|
+
.gradletasknamecache
|
|
65
|
+
|
|
66
|
+
# Maven
|
|
67
|
+
target/
|
|
68
|
+
pom.xml.tag
|
|
69
|
+
pom.xml.releaseBackup
|
|
70
|
+
pom.xml.versionsBackup
|
|
71
|
+
pom.xml.next
|
|
72
|
+
release.properties
|
|
73
|
+
|
|
74
|
+
# IDE & Editors
|
|
75
|
+
# IntelliJ IDEA
|
|
76
|
+
.idea/
|
|
77
|
+
*.iml
|
|
78
|
+
*.ipr
|
|
79
|
+
*.iws
|
|
80
|
+
out/
|
|
81
|
+
|
|
82
|
+
# Visual Studio Code
|
|
83
|
+
.vscode/*
|
|
84
|
+
!.vscode/settings.json
|
|
85
|
+
!.vscode/tasks.json
|
|
86
|
+
!.vscode/launch.json
|
|
87
|
+
!.vscode/extensions.json
|
|
88
|
+
*.code-workspace
|
|
89
|
+
|
|
90
|
+
# Eclipse
|
|
91
|
+
.apt_generated
|
|
92
|
+
.classpath
|
|
93
|
+
.factorypath
|
|
94
|
+
.project
|
|
95
|
+
.settings/
|
|
96
|
+
.springBeans
|
|
97
|
+
|
|
98
|
+
# Testing & Coverage
|
|
99
|
+
coverage/
|
|
100
|
+
.nyc_output/
|
|
101
|
+
*.lcov
|
|
102
|
+
test-results/
|
|
103
|
+
reports/
|
|
104
|
+
|
|
105
|
+
# Database & Local Infrastructure
|
|
106
|
+
postgres-data/
|
|
107
|
+
*.db
|
|
108
|
+
*.sqlite
|
|
109
|
+
*.sqlite3
|
|
110
|
+
|
|
111
|
+
# Logs
|
|
112
|
+
logs/
|
|
113
|
+
*.log
|
|
114
|
+
|
|
115
|
+
# Internal docs, design, and roadmap (local only)
|
|
116
|
+
docs/
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: open-agentpay
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: The Open-Source Payment Infrastructure & Financial Firewall for Autonomous AI Agents
|
|
5
|
+
Project-URL: Homepage, https://github.com/july-whj/AgentPay
|
|
6
|
+
Project-URL: Documentation, https://github.com/july-whj/AgentPay#readme
|
|
7
|
+
Project-URL: Repository, https://github.com/july-whj/AgentPay
|
|
8
|
+
Author: AgentPay Contributors
|
|
9
|
+
License-Expression: Apache-2.0
|
|
10
|
+
Keywords: agent,ai,arbitrum,eip-712,financial-firewall,langchain,llm,usdc,x402
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
19
|
+
Classifier: Topic :: Security
|
|
20
|
+
Requires-Python: >=3.10
|
|
21
|
+
Requires-Dist: eth-account>=0.11.0
|
|
22
|
+
Requires-Dist: httpx>=0.27.0
|
|
23
|
+
Requires-Dist: pydantic-settings>=2.2.0
|
|
24
|
+
Requires-Dist: pydantic>=2.6.0
|
|
25
|
+
Requires-Dist: web3>=6.15.0
|
|
26
|
+
Provides-Extra: dev
|
|
27
|
+
Requires-Dist: mypy>=1.9.0; extra == 'dev'
|
|
28
|
+
Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
|
|
29
|
+
Requires-Dist: pytest>=8.0.0; extra == 'dev'
|
|
30
|
+
Requires-Dist: ruff>=0.3.0; extra == 'dev'
|
|
31
|
+
Provides-Extra: langchain
|
|
32
|
+
Requires-Dist: langchain-core>=0.1.0; extra == 'langchain'
|
|
33
|
+
Description-Content-Type: text/markdown
|
|
34
|
+
|
|
35
|
+
# Open AgentPay (`open-agentpay`)
|
|
36
|
+
|
|
37
|
+
[](https://pypi.org/project/open-agentpay/)
|
|
38
|
+
[](https://opensource.org/licenses/Apache-2.0)
|
|
39
|
+
[](https://www.python.org/downloads/)
|
|
40
|
+
|
|
41
|
+
**The Open-Source Payment Infrastructure & Financial Firewall for Autonomous AI Agents.**
|
|
42
|
+
|
|
43
|
+
AgentPay equips autonomous AI agents with gasless micro-payments (Circle USDC on Arbitrum Sepolia & Base) governed by an in-process, non-custodial **Financial Firewall**.
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## ⚡ Quickstart
|
|
48
|
+
|
|
49
|
+
### Installation
|
|
50
|
+
```bash
|
|
51
|
+
pip install open-agentpay
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Basic Usage: Transparent 402 Negotiation & Policy Guard
|
|
55
|
+
```python
|
|
56
|
+
from agentpay.client import AgentPayClient, LocalSigner
|
|
57
|
+
from agentpay.policy import SQLitePolicyEngine, PolicyConfig
|
|
58
|
+
|
|
59
|
+
# 1. Initialize local signer (non-custodial private key)
|
|
60
|
+
signer = LocalSigner("0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80")
|
|
61
|
+
|
|
62
|
+
# 2. Configure local financial firewall
|
|
63
|
+
policy = SQLitePolicyEngine.create_in_memory(
|
|
64
|
+
PolicyConfig(
|
|
65
|
+
id="agent_firewall",
|
|
66
|
+
wallet_address=signer.address,
|
|
67
|
+
max_per_tx_base_units=100_000, # Max $0.10 per call
|
|
68
|
+
rolling_budget_24h_base_units=1_000_000, # Daily limit $1.00
|
|
69
|
+
circuit_max_rpm=5, # Tripped if > 5 requests/min
|
|
70
|
+
)
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
# 3. Create client with automatic x402 challenge negotiation
|
|
74
|
+
client = AgentPayClient(signer=signer, policy=policy)
|
|
75
|
+
|
|
76
|
+
# 4. Transparent call (auto-pays 402 challenge via EIP-712 off-chain signature)
|
|
77
|
+
response = client.get("https://api.seller.com/v1/market-data?ticker=NVDA")
|
|
78
|
+
print(response.json())
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### LangChain Paid Tool Integration
|
|
82
|
+
```python
|
|
83
|
+
from agentpay.integrations.langchain import PaidTool
|
|
84
|
+
|
|
85
|
+
market_tool = PaidTool(
|
|
86
|
+
name="get_stock_quote",
|
|
87
|
+
description="Fetch real-time stock price (costs $0.05 USDC per query)",
|
|
88
|
+
endpoint="https://api.seller.com/v1/market-data",
|
|
89
|
+
method="GET",
|
|
90
|
+
client=client,
|
|
91
|
+
)
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## 🔒 Security Guarantees
|
|
97
|
+
- **Non-Custodial**: Private keys never leave the agent's local trust domain.
|
|
98
|
+
- **Fail-Closed**: Any policy violation, budget exhaustion, or circuit trip aborts immediately with zero funds spent.
|
|
99
|
+
- **Gasless for Agents**: AI Agents hold only USDC; execution gas is sponsored via EIP-3009 by the seller or facilitator.
|
|
100
|
+
|
|
101
|
+
For complete documentation, visit [AgentPay GitHub](https://github.com/july-whj/AgentPay).
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# Open AgentPay (`open-agentpay`)
|
|
2
|
+
|
|
3
|
+
[](https://pypi.org/project/open-agentpay/)
|
|
4
|
+
[](https://opensource.org/licenses/Apache-2.0)
|
|
5
|
+
[](https://www.python.org/downloads/)
|
|
6
|
+
|
|
7
|
+
**The Open-Source Payment Infrastructure & Financial Firewall for Autonomous AI Agents.**
|
|
8
|
+
|
|
9
|
+
AgentPay equips autonomous AI agents with gasless micro-payments (Circle USDC on Arbitrum Sepolia & Base) governed by an in-process, non-custodial **Financial Firewall**.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## ⚡ Quickstart
|
|
14
|
+
|
|
15
|
+
### Installation
|
|
16
|
+
```bash
|
|
17
|
+
pip install open-agentpay
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
### Basic Usage: Transparent 402 Negotiation & Policy Guard
|
|
21
|
+
```python
|
|
22
|
+
from agentpay.client import AgentPayClient, LocalSigner
|
|
23
|
+
from agentpay.policy import SQLitePolicyEngine, PolicyConfig
|
|
24
|
+
|
|
25
|
+
# 1. Initialize local signer (non-custodial private key)
|
|
26
|
+
signer = LocalSigner("0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80")
|
|
27
|
+
|
|
28
|
+
# 2. Configure local financial firewall
|
|
29
|
+
policy = SQLitePolicyEngine.create_in_memory(
|
|
30
|
+
PolicyConfig(
|
|
31
|
+
id="agent_firewall",
|
|
32
|
+
wallet_address=signer.address,
|
|
33
|
+
max_per_tx_base_units=100_000, # Max $0.10 per call
|
|
34
|
+
rolling_budget_24h_base_units=1_000_000, # Daily limit $1.00
|
|
35
|
+
circuit_max_rpm=5, # Tripped if > 5 requests/min
|
|
36
|
+
)
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
# 3. Create client with automatic x402 challenge negotiation
|
|
40
|
+
client = AgentPayClient(signer=signer, policy=policy)
|
|
41
|
+
|
|
42
|
+
# 4. Transparent call (auto-pays 402 challenge via EIP-712 off-chain signature)
|
|
43
|
+
response = client.get("https://api.seller.com/v1/market-data?ticker=NVDA")
|
|
44
|
+
print(response.json())
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### LangChain Paid Tool Integration
|
|
48
|
+
```python
|
|
49
|
+
from agentpay.integrations.langchain import PaidTool
|
|
50
|
+
|
|
51
|
+
market_tool = PaidTool(
|
|
52
|
+
name="get_stock_quote",
|
|
53
|
+
description="Fetch real-time stock price (costs $0.05 USDC per query)",
|
|
54
|
+
endpoint="https://api.seller.com/v1/market-data",
|
|
55
|
+
method="GET",
|
|
56
|
+
client=client,
|
|
57
|
+
)
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## 🔒 Security Guarantees
|
|
63
|
+
- **Non-Custodial**: Private keys never leave the agent's local trust domain.
|
|
64
|
+
- **Fail-Closed**: Any policy violation, budget exhaustion, or circuit trip aborts immediately with zero funds spent.
|
|
65
|
+
- **Gasless for Agents**: AI Agents hold only USDC; execution gas is sponsored via EIP-3009 by the seller or facilitator.
|
|
66
|
+
|
|
67
|
+
For complete documentation, visit [AgentPay GitHub](https://github.com/july-whj/AgentPay).
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "open-agentpay"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "The Open-Source Payment Infrastructure & Financial Firewall for Autonomous AI Agents"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = "Apache-2.0"
|
|
11
|
+
authors = [
|
|
12
|
+
{ name = "AgentPay Contributors" }
|
|
13
|
+
]
|
|
14
|
+
requires-python = ">=3.10"
|
|
15
|
+
keywords = ["agent", "ai", "llm", "x402", "usdc", "eip-712", "financial-firewall", "arbitrum", "langchain"]
|
|
16
|
+
classifiers = [
|
|
17
|
+
"Development Status :: 4 - Beta",
|
|
18
|
+
"Intended Audience :: Developers",
|
|
19
|
+
"License :: OSI Approved :: Apache Software License",
|
|
20
|
+
"Programming Language :: Python :: 3",
|
|
21
|
+
"Programming Language :: Python :: 3.10",
|
|
22
|
+
"Programming Language :: Python :: 3.11",
|
|
23
|
+
"Programming Language :: Python :: 3.12",
|
|
24
|
+
"Topic :: Scientific/Engineering :: Artificial Intelligence",
|
|
25
|
+
"Topic :: Security",
|
|
26
|
+
]
|
|
27
|
+
dependencies = [
|
|
28
|
+
"eth-account>=0.11.0",
|
|
29
|
+
"web3>=6.15.0",
|
|
30
|
+
"httpx>=0.27.0",
|
|
31
|
+
"pydantic>=2.6.0",
|
|
32
|
+
"pydantic-settings>=2.2.0"
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
[project.optional-dependencies]
|
|
36
|
+
langchain = [
|
|
37
|
+
"langchain-core>=0.1.0"
|
|
38
|
+
]
|
|
39
|
+
dev = [
|
|
40
|
+
"pytest>=8.0.0",
|
|
41
|
+
"pytest-asyncio>=0.23.0",
|
|
42
|
+
"ruff>=0.3.0",
|
|
43
|
+
"mypy>=1.9.0"
|
|
44
|
+
]
|
|
45
|
+
|
|
46
|
+
[project.urls]
|
|
47
|
+
Homepage = "https://github.com/july-whj/AgentPay"
|
|
48
|
+
Documentation = "https://github.com/july-whj/AgentPay#readme"
|
|
49
|
+
Repository = "https://github.com/july-whj/AgentPay"
|
|
50
|
+
|
|
51
|
+
[tool.hatch.build.targets.wheel]
|
|
52
|
+
packages = ["src/agentpay"]
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"""
|
|
2
|
+
AgentPay Python SDK
|
|
3
|
+
The Open-Source Payment Infrastructure & Financial Firewall for Autonomous AI Agents.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
__version__ = "0.1.0"
|
|
7
|
+
|
|
8
|
+
from agentpay.client import (
|
|
9
|
+
AgentPayClient,
|
|
10
|
+
AgentPayTransport,
|
|
11
|
+
AsyncAgentPayClient,
|
|
12
|
+
AsyncAgentPayTransport,
|
|
13
|
+
ISigner,
|
|
14
|
+
LocalSigner,
|
|
15
|
+
)
|
|
16
|
+
from agentpay.core import (
|
|
17
|
+
HEADER_PAYMENT_REQUIRED,
|
|
18
|
+
HEADER_PAYMENT_SIGNATURE,
|
|
19
|
+
PaymentAuthorization,
|
|
20
|
+
PaymentChallenge,
|
|
21
|
+
SignatureData,
|
|
22
|
+
decode_authorization,
|
|
23
|
+
decode_challenge,
|
|
24
|
+
encode_authorization,
|
|
25
|
+
encode_challenge,
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
__all__ = [
|
|
29
|
+
"HEADER_PAYMENT_REQUIRED",
|
|
30
|
+
"HEADER_PAYMENT_SIGNATURE",
|
|
31
|
+
"AgentPayClient",
|
|
32
|
+
"AgentPayTransport",
|
|
33
|
+
"AsyncAgentPayClient",
|
|
34
|
+
"AsyncAgentPayTransport",
|
|
35
|
+
"ISigner",
|
|
36
|
+
"LocalSigner",
|
|
37
|
+
"PaymentAuthorization",
|
|
38
|
+
"PaymentChallenge",
|
|
39
|
+
"SignatureData",
|
|
40
|
+
"__version__",
|
|
41
|
+
"decode_authorization",
|
|
42
|
+
"decode_challenge",
|
|
43
|
+
"encode_authorization",
|
|
44
|
+
"encode_challenge",
|
|
45
|
+
]
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"""
|
|
2
|
+
AgentPay Budget sub-package.
|
|
3
|
+
|
|
4
|
+
Exposes budget models, ledger records, and reservation tokens for buyer spending limits.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from agentpay.core.state import BudgetLedgerState
|
|
10
|
+
from agentpay.policy.models import (
|
|
11
|
+
BreakerState,
|
|
12
|
+
LedgerEntryState,
|
|
13
|
+
PaymentRequest,
|
|
14
|
+
PolicyConfig,
|
|
15
|
+
PolicyDecision,
|
|
16
|
+
ReservationToken,
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
# Backward compatibility / convenient domain aliases
|
|
20
|
+
BudgetReservation = ReservationToken
|
|
21
|
+
LedgerEntry = LedgerEntryState
|
|
22
|
+
PolicyEvaluationResult = PolicyDecision
|
|
23
|
+
PolicyStatus = BreakerState
|
|
24
|
+
|
|
25
|
+
__all__ = [
|
|
26
|
+
"BreakerState",
|
|
27
|
+
"BudgetLedgerState",
|
|
28
|
+
"BudgetReservation",
|
|
29
|
+
"LedgerEntry",
|
|
30
|
+
"LedgerEntryState",
|
|
31
|
+
"PaymentRequest",
|
|
32
|
+
"PolicyConfig",
|
|
33
|
+
"PolicyDecision",
|
|
34
|
+
"PolicyEvaluationResult",
|
|
35
|
+
"PolicyStatus",
|
|
36
|
+
"ReservationToken",
|
|
37
|
+
]
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"""
|
|
2
|
+
AgentPay Client SDK and Signers.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
from agentpay.client.client import AgentPayClient, AsyncAgentPayClient
|
|
8
|
+
from agentpay.client.errors import (
|
|
9
|
+
ClientError,
|
|
10
|
+
InvalidPrivateKeyError,
|
|
11
|
+
ReservationMismatchError,
|
|
12
|
+
SignerError,
|
|
13
|
+
UnsupportedNetworkError,
|
|
14
|
+
)
|
|
15
|
+
from agentpay.client.interfaces import ISigner
|
|
16
|
+
from agentpay.client.signer import (
|
|
17
|
+
DEFAULT_TOKEN_NAMES,
|
|
18
|
+
EIP3009_MESSAGE_TYPES,
|
|
19
|
+
LocalSigner,
|
|
20
|
+
generate_nonce,
|
|
21
|
+
parse_caip2_chain_id,
|
|
22
|
+
)
|
|
23
|
+
from agentpay.client.transport import AgentPayTransport, AsyncAgentPayTransport
|
|
24
|
+
|
|
25
|
+
__all__ = [
|
|
26
|
+
"DEFAULT_TOKEN_NAMES",
|
|
27
|
+
"EIP3009_MESSAGE_TYPES",
|
|
28
|
+
"AgentPayClient",
|
|
29
|
+
"AgentPayTransport",
|
|
30
|
+
"AsyncAgentPayClient",
|
|
31
|
+
"AsyncAgentPayTransport",
|
|
32
|
+
"ClientError",
|
|
33
|
+
"ISigner",
|
|
34
|
+
"InvalidPrivateKeyError",
|
|
35
|
+
"LocalSigner",
|
|
36
|
+
"ReservationMismatchError",
|
|
37
|
+
"SignerError",
|
|
38
|
+
"UnsupportedNetworkError",
|
|
39
|
+
"generate_nonce",
|
|
40
|
+
"parse_caip2_chain_id",
|
|
41
|
+
]
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
"""
|
|
2
|
+
AgentPayClient: Drop-in httpx.Client with automatic 402 payment negotiation.
|
|
3
|
+
|
|
4
|
+
Wraps the financial firewall and EIP-712 cryptographic signer to automatically
|
|
5
|
+
satisfy HTTP 402 Payment Required challenges.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from collections.abc import Callable
|
|
11
|
+
from typing import Any
|
|
12
|
+
|
|
13
|
+
import httpx
|
|
14
|
+
|
|
15
|
+
from agentpay.client.interfaces import ISigner
|
|
16
|
+
from agentpay.client.transport import AgentPayTransport, AsyncAgentPayTransport
|
|
17
|
+
from agentpay.policy.interfaces import IPolicyEngine
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class AgentPayClient(httpx.Client):
|
|
21
|
+
"""
|
|
22
|
+
HTTP client for autonomous AI agents with integrated financial firewall.
|
|
23
|
+
|
|
24
|
+
Inherits from httpx.Client: fully compatible with LangChain, LlamaIndex,
|
|
25
|
+
and standard Python HTTP toolchains.
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
def __init__(
|
|
29
|
+
self,
|
|
30
|
+
signer: ISigner,
|
|
31
|
+
policy: IPolicyEngine,
|
|
32
|
+
*,
|
|
33
|
+
transport: httpx.BaseTransport | None = None,
|
|
34
|
+
auto_retry_on_402: bool = True,
|
|
35
|
+
raise_on_policy_rejection: bool = False,
|
|
36
|
+
clock: Callable[[], int] | None = None,
|
|
37
|
+
**kwargs: Any,
|
|
38
|
+
) -> None:
|
|
39
|
+
self.signer = signer
|
|
40
|
+
self.policy = policy
|
|
41
|
+
self.auto_retry_on_402 = auto_retry_on_402
|
|
42
|
+
self.raise_on_policy_rejection = raise_on_policy_rejection
|
|
43
|
+
self._clock = clock
|
|
44
|
+
|
|
45
|
+
inner = transport or httpx.HTTPTransport()
|
|
46
|
+
agent_transport = AgentPayTransport(
|
|
47
|
+
inner_transport=inner,
|
|
48
|
+
signer=signer,
|
|
49
|
+
policy=policy,
|
|
50
|
+
auto_retry_on_402=auto_retry_on_402,
|
|
51
|
+
raise_on_policy_rejection=raise_on_policy_rejection,
|
|
52
|
+
clock=clock,
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
super().__init__(transport=agent_transport, **kwargs)
|
|
56
|
+
|
|
57
|
+
def async_client(
|
|
58
|
+
self,
|
|
59
|
+
*,
|
|
60
|
+
transport: httpx.AsyncBaseTransport | None = None,
|
|
61
|
+
**kwargs: Any,
|
|
62
|
+
) -> AsyncAgentPayClient:
|
|
63
|
+
"""Create an asynchronous AsyncAgentPayClient sharing the same signer and policy."""
|
|
64
|
+
return AsyncAgentPayClient(
|
|
65
|
+
signer=self.signer,
|
|
66
|
+
policy=self.policy,
|
|
67
|
+
transport=transport,
|
|
68
|
+
auto_retry_on_402=self.auto_retry_on_402,
|
|
69
|
+
raise_on_policy_rejection=self.raise_on_policy_rejection,
|
|
70
|
+
clock=self._clock,
|
|
71
|
+
**kwargs,
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
class AsyncAgentPayClient(httpx.AsyncClient):
|
|
76
|
+
"""
|
|
77
|
+
Asynchronous HTTP client for autonomous AI agents with integrated financial firewall.
|
|
78
|
+
|
|
79
|
+
Inherits from httpx.AsyncClient.
|
|
80
|
+
"""
|
|
81
|
+
|
|
82
|
+
def __init__(
|
|
83
|
+
self,
|
|
84
|
+
signer: ISigner,
|
|
85
|
+
policy: IPolicyEngine,
|
|
86
|
+
*,
|
|
87
|
+
transport: httpx.AsyncBaseTransport | None = None,
|
|
88
|
+
auto_retry_on_402: bool = True,
|
|
89
|
+
raise_on_policy_rejection: bool = False,
|
|
90
|
+
clock: Callable[[], int] | None = None,
|
|
91
|
+
**kwargs: Any,
|
|
92
|
+
) -> None:
|
|
93
|
+
self.signer = signer
|
|
94
|
+
self.policy = policy
|
|
95
|
+
self.auto_retry_on_402 = auto_retry_on_402
|
|
96
|
+
self.raise_on_policy_rejection = raise_on_policy_rejection
|
|
97
|
+
self._clock = clock
|
|
98
|
+
|
|
99
|
+
inner = transport or httpx.AsyncHTTPTransport()
|
|
100
|
+
agent_transport = AsyncAgentPayTransport(
|
|
101
|
+
inner_transport=inner,
|
|
102
|
+
signer=signer,
|
|
103
|
+
policy=policy,
|
|
104
|
+
auto_retry_on_402=auto_retry_on_402,
|
|
105
|
+
raise_on_policy_rejection=raise_on_policy_rejection,
|
|
106
|
+
clock=clock,
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
super().__init__(transport=agent_transport, **kwargs)
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Signer and Client Exceptions for AgentPay.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class ClientError(Exception):
|
|
9
|
+
"""Base exception for all AgentPay client and signer operations."""
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class SignerError(ClientError):
|
|
13
|
+
"""Base exception for cryptographic signing errors."""
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class InvalidPrivateKeyError(SignerError):
|
|
17
|
+
"""Raised when an invalid EVM private key is provided."""
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class UnsupportedNetworkError(SignerError):
|
|
21
|
+
"""Raised when a challenge specifies a network unsupported by the signer (e.g. non-EIP155)."""
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class ReservationMismatchError(SignerError):
|
|
25
|
+
"""
|
|
26
|
+
Raised when an approved ReservationToken does not match the PaymentChallenge.
|
|
27
|
+
Critical financial firewall guardrail violation.
|
|
28
|
+
"""
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Signer interface protocols for AgentPay.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
from typing import Protocol, runtime_checkable
|
|
8
|
+
|
|
9
|
+
from agentpay.core.models import PaymentAuthorization, PaymentChallenge
|
|
10
|
+
from agentpay.policy.models import ReservationToken
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@runtime_checkable
|
|
14
|
+
class ISigner(Protocol):
|
|
15
|
+
"""
|
|
16
|
+
Protocol for signing agents and cryptographic keystores.
|
|
17
|
+
Enforces firewall reservation binding before signing.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
@property
|
|
21
|
+
def address(self) -> str:
|
|
22
|
+
"""The canonical lowercase EVM address of the signing wallet."""
|
|
23
|
+
...
|
|
24
|
+
|
|
25
|
+
def sign_payment_authorization(
|
|
26
|
+
self,
|
|
27
|
+
challenge: PaymentChallenge,
|
|
28
|
+
reservation: ReservationToken,
|
|
29
|
+
*,
|
|
30
|
+
nonce: str | None = None,
|
|
31
|
+
token_name: str | None = None,
|
|
32
|
+
token_version: str = "2",
|
|
33
|
+
) -> PaymentAuthorization:
|
|
34
|
+
"""
|
|
35
|
+
Sign an EIP-712/3009 transfer authorization for the given challenge.
|
|
36
|
+
|
|
37
|
+
MUST verify that the reservation matches the challenge before signing.
|
|
38
|
+
|
|
39
|
+
Args:
|
|
40
|
+
challenge: The PaymentChallenge from the 402 PAYMENT-REQUIRED header.
|
|
41
|
+
reservation: The Approved ReservationToken from the policy engine.
|
|
42
|
+
nonce: Optional 32-byte hex nonce. If omitted, a random nonce is generated.
|
|
43
|
+
token_name: Optional EIP-712 domain token name (e.g. 'USD Coin').
|
|
44
|
+
token_version: EIP-712 domain version (default '2').
|
|
45
|
+
|
|
46
|
+
Returns:
|
|
47
|
+
PaymentAuthorization populated with cryptographic signature.
|
|
48
|
+
|
|
49
|
+
Raises:
|
|
50
|
+
ReservationMismatchError: If the reservation does not match the challenge.
|
|
51
|
+
SignerError: If cryptographic signing fails.
|
|
52
|
+
"""
|
|
53
|
+
...
|