agentguard-python-sdk 0.1.0__py3-none-any.whl
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.
- agentguard/__init__.py +3 -0
- agentguard/client.py +126 -0
- agentguard/consent.py +58 -0
- agentguard/types.py +25 -0
- agentguard_python_sdk-0.1.0.dist-info/METADATA +65 -0
- agentguard_python_sdk-0.1.0.dist-info/RECORD +8 -0
- agentguard_python_sdk-0.1.0.dist-info/WHEEL +5 -0
- agentguard_python_sdk-0.1.0.dist-info/top_level.txt +1 -0
agentguard/__init__.py
ADDED
agentguard/client.py
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import httpx
|
|
2
|
+
import uuid
|
|
3
|
+
import logging
|
|
4
|
+
from typing import Optional, Dict, Any
|
|
5
|
+
from .consent import generate_consent_proof
|
|
6
|
+
from .types import AgentGuardReceipt, AuditProof
|
|
7
|
+
|
|
8
|
+
logger = logging.getLogger("agentguard-sdk")
|
|
9
|
+
|
|
10
|
+
class AgentGuardClient:
|
|
11
|
+
def __init__(self, wallet_address: str, base_url: str = "https://agentguard-backend.onrender.com"):
|
|
12
|
+
"""
|
|
13
|
+
Initialize the AgentGuard production client.
|
|
14
|
+
|
|
15
|
+
Args:
|
|
16
|
+
wallet_address: The user's wallet address (Principal ID).
|
|
17
|
+
base_url: The URL of the AgentGuard Backend.
|
|
18
|
+
"""
|
|
19
|
+
self.wallet_address = wallet_address
|
|
20
|
+
self.base_url = base_url.rstrip("/")
|
|
21
|
+
self.async_client = httpx.AsyncClient(timeout=30.0)
|
|
22
|
+
|
|
23
|
+
async def pay_and_fetch(
|
|
24
|
+
self,
|
|
25
|
+
resource_url: str,
|
|
26
|
+
amount_algo: float,
|
|
27
|
+
purpose: str
|
|
28
|
+
) -> AgentGuardReceipt:
|
|
29
|
+
"""
|
|
30
|
+
Asynchronously perform an on-chain payment and return a typed receipt.
|
|
31
|
+
|
|
32
|
+
Args:
|
|
33
|
+
resource_url: The URL/ID of the resource being accessed.
|
|
34
|
+
amount_algo: The amount to pay in ALGO.
|
|
35
|
+
purpose: The purpose of the data processing.
|
|
36
|
+
|
|
37
|
+
Returns:
|
|
38
|
+
AgentGuardReceipt: A structured receipt with transaction details.
|
|
39
|
+
"""
|
|
40
|
+
# 1. Generate Nonce for replay protection
|
|
41
|
+
nonce = str(uuid.uuid4())
|
|
42
|
+
|
|
43
|
+
# 2. Generate Consent Proof (SHA256 of metadata)
|
|
44
|
+
consent_hash, timestamp = generate_consent_proof(
|
|
45
|
+
principal_id=self.wallet_address,
|
|
46
|
+
resource_url=resource_url,
|
|
47
|
+
purpose=purpose,
|
|
48
|
+
nonce=nonce
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
# 3. Request Payment via Backend Proxy
|
|
52
|
+
payload = {
|
|
53
|
+
"resource_url": resource_url,
|
|
54
|
+
"amount_algo": amount_algo,
|
|
55
|
+
"purpose": purpose,
|
|
56
|
+
"principal_id": self.wallet_address,
|
|
57
|
+
"consent_hash": consent_hash,
|
|
58
|
+
"nonce": nonce,
|
|
59
|
+
"timestamp": timestamp
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
try:
|
|
63
|
+
response = await self.async_client.post(f"{self.base_url}/pay", json=payload)
|
|
64
|
+
response.raise_for_status()
|
|
65
|
+
res_data = response.json()
|
|
66
|
+
|
|
67
|
+
return AgentGuardReceipt(
|
|
68
|
+
tx_id=res_data["tx_id"],
|
|
69
|
+
consent_hash=res_data["consent_hash"],
|
|
70
|
+
audit_url=res_data["audit_url"],
|
|
71
|
+
data=res_data.get("data", {})
|
|
72
|
+
)
|
|
73
|
+
except httpx.HTTPStatusError as e:
|
|
74
|
+
logger.error(f"Payment failed: {e.response.text}")
|
|
75
|
+
raise Exception(f"Payment failed: {e.response.text}")
|
|
76
|
+
except Exception as e:
|
|
77
|
+
logger.error(f"Connection failed: {e}")
|
|
78
|
+
raise Exception(f"Could not connect to AgentGuard Backend: {e}")
|
|
79
|
+
|
|
80
|
+
async def verify(self, tx_id: str) -> AuditProof:
|
|
81
|
+
"""
|
|
82
|
+
Asynchronously verify a transaction against the blockchain audit trail.
|
|
83
|
+
"""
|
|
84
|
+
try:
|
|
85
|
+
response = await self.async_client.get(f"{self.base_url}/verify/{tx_id}")
|
|
86
|
+
response.raise_for_status()
|
|
87
|
+
res_data = response.json()
|
|
88
|
+
|
|
89
|
+
return AuditProof(
|
|
90
|
+
verified=res_data["verified"],
|
|
91
|
+
tx_id=res_data["tx_id"],
|
|
92
|
+
principal_id=res_data["principal_id"],
|
|
93
|
+
consent_hash=res_data["consent_hash"],
|
|
94
|
+
on_chain_hash=res_data["on_chain_hash"],
|
|
95
|
+
explorer_url=res_data["explorer_url"],
|
|
96
|
+
message=res_data["message"]
|
|
97
|
+
)
|
|
98
|
+
except Exception as e:
|
|
99
|
+
logger.error(f"Verification failed: {e}")
|
|
100
|
+
raise Exception(f"Verification failed: {e}")
|
|
101
|
+
|
|
102
|
+
async def register_budget(self, limit_algo: float) -> Dict[str, Any]:
|
|
103
|
+
"""
|
|
104
|
+
Convenience method to register/update the user's budget.
|
|
105
|
+
"""
|
|
106
|
+
payload = {
|
|
107
|
+
"wallet_address": self.wallet_address,
|
|
108
|
+
"budget_algo": limit_algo
|
|
109
|
+
}
|
|
110
|
+
try:
|
|
111
|
+
response = await self.async_client.post(f"{self.base_url}/user/register", json=payload)
|
|
112
|
+
response.raise_for_status()
|
|
113
|
+
return response.json()
|
|
114
|
+
except Exception as e:
|
|
115
|
+
logger.error(f"Budget registration failed: {e}")
|
|
116
|
+
raise Exception(f"Budget registration failed: {e}")
|
|
117
|
+
|
|
118
|
+
async def close(self):
|
|
119
|
+
"""Close the underlying HTTP client."""
|
|
120
|
+
await self.async_client.aclose()
|
|
121
|
+
|
|
122
|
+
async def __aenter__(self):
|
|
123
|
+
return self
|
|
124
|
+
|
|
125
|
+
async def __aexit__(self, exc_type, exc_val, exc_tb):
|
|
126
|
+
await self.close()
|
agentguard/consent.py
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import time
|
|
2
|
+
import json
|
|
3
|
+
import hashlib
|
|
4
|
+
import logging
|
|
5
|
+
from typing import Dict, Any
|
|
6
|
+
|
|
7
|
+
# Configure logging
|
|
8
|
+
logger = logging.getLogger("agentguard-sdk")
|
|
9
|
+
|
|
10
|
+
def generate_consent(principal_id: str, purpose: str, item: str, nonce: str, data_fiduciary: str = "AgentGuard Platform") -> Dict[str, Any]:
|
|
11
|
+
"""
|
|
12
|
+
Creates a user consent object dictionary containing DPDP compliant fields.
|
|
13
|
+
"""
|
|
14
|
+
timestamp = int(time.time())
|
|
15
|
+
|
|
16
|
+
consent_obj = {
|
|
17
|
+
"principal_id": principal_id,
|
|
18
|
+
"data_fiduciary": data_fiduciary,
|
|
19
|
+
"purpose": purpose,
|
|
20
|
+
"item": item,
|
|
21
|
+
"timestamp": timestamp,
|
|
22
|
+
"nonce": nonce
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
logger.info(f"Generated DPDP consent for principal={principal_id} at {timestamp}")
|
|
26
|
+
return consent_obj
|
|
27
|
+
|
|
28
|
+
def hash_consent(consent: Dict[str, Any]) -> str:
|
|
29
|
+
"""
|
|
30
|
+
Converts a consent dictionary into a sorted JSON string
|
|
31
|
+
and generates a SHA256 hash of it for on-chain logging.
|
|
32
|
+
|
|
33
|
+
Args:
|
|
34
|
+
consent: The consent dictionary.
|
|
35
|
+
|
|
36
|
+
Returns:
|
|
37
|
+
str: SHA256 hash string.
|
|
38
|
+
"""
|
|
39
|
+
# Convert consent dict to JSON string with sorted keys to ensure determinism
|
|
40
|
+
consent_json = json.dumps(consent, sort_keys=True)
|
|
41
|
+
|
|
42
|
+
# Generate SHA256 hash
|
|
43
|
+
consent_hash = hashlib.sha256(consent_json.encode("utf-8")).hexdigest()
|
|
44
|
+
|
|
45
|
+
logger.info(f"Consent hash generated: {consent_hash}")
|
|
46
|
+
return consent_hash
|
|
47
|
+
|
|
48
|
+
def generate_consent_proof(principal_id: str, resource_url: str, purpose: str, nonce: str) -> tuple[str, int]:
|
|
49
|
+
"""
|
|
50
|
+
High-level helper to generate a consent hash and return the timestamp used.
|
|
51
|
+
"""
|
|
52
|
+
consent = generate_consent(
|
|
53
|
+
principal_id=principal_id,
|
|
54
|
+
purpose=purpose,
|
|
55
|
+
item=resource_url,
|
|
56
|
+
nonce=nonce
|
|
57
|
+
)
|
|
58
|
+
return hash_consent(consent), consent["timestamp"]
|
agentguard/types.py
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
from dataclasses import dataclass, field
|
|
2
|
+
from typing import Dict, Any
|
|
3
|
+
|
|
4
|
+
@dataclass
|
|
5
|
+
class AgentGuardReceipt:
|
|
6
|
+
"""
|
|
7
|
+
Structured response for a successful AgentGuard payment.
|
|
8
|
+
"""
|
|
9
|
+
tx_id: str
|
|
10
|
+
consent_hash: str
|
|
11
|
+
audit_url: str
|
|
12
|
+
data: Dict[str, Any] = field(default_factory=dict)
|
|
13
|
+
|
|
14
|
+
@dataclass
|
|
15
|
+
class AuditProof:
|
|
16
|
+
"""
|
|
17
|
+
Structured response for a DPDP compliance audit.
|
|
18
|
+
"""
|
|
19
|
+
verified: bool
|
|
20
|
+
tx_id: str
|
|
21
|
+
principal_id: str
|
|
22
|
+
consent_hash: str
|
|
23
|
+
on_chain_hash: str
|
|
24
|
+
explorer_url: str
|
|
25
|
+
message: str
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: agentguard-python-sdk
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A production-grade middleware for AI agents to perform on-chain payments and verifiable consent.
|
|
5
|
+
Author: AgentGuard Team
|
|
6
|
+
License: MIT
|
|
7
|
+
Requires-Python: >=3.9
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
Requires-Dist: httpx>=0.27.0
|
|
10
|
+
Requires-Dist: pydantic>=2.0.0
|
|
11
|
+
|
|
12
|
+
# AgentGuard SDK
|
|
13
|
+
|
|
14
|
+
AgentGuard is a production-grade middleware that enables AI agents to perform on-chain payments and generate verifiable consent proofs in compliance with DPDP (Digital Personal Data Protection) standards.
|
|
15
|
+
|
|
16
|
+
By isolating private keys in a hardened **MCP Server (Vault)** and using the **AgentGuard Backend (Dispatcher)** as a secure proxy, the SDK allows developers to add monetization and compliance to their agents with zero blockchain complexity.
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
pip install agentguard
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Quick Start (3-Line Usage)
|
|
25
|
+
|
|
26
|
+
```python
|
|
27
|
+
import asyncio
|
|
28
|
+
from agentguard import AgentGuardClient
|
|
29
|
+
|
|
30
|
+
async def main():
|
|
31
|
+
# 1. Initialize the client
|
|
32
|
+
async with AgentGuardClient(wallet_address="YOUR_WALLET_ADDRESS") as client:
|
|
33
|
+
|
|
34
|
+
# 2. Perform a secure payment (includes automatic DPDP consent hashing)
|
|
35
|
+
receipt = await client.pay_and_fetch(
|
|
36
|
+
resource_url="https://api.stock.com/reliance",
|
|
37
|
+
amount_algo=0.05,
|
|
38
|
+
purpose="Financial Analysis"
|
|
39
|
+
)
|
|
40
|
+
print(f"Payment Successful! TX ID: {receipt.tx_id}")
|
|
41
|
+
|
|
42
|
+
# 3. Verify compliance audit trail
|
|
43
|
+
proof = await client.verify(receipt.tx_id)
|
|
44
|
+
print(f"On-Chain Verified: {proof.verified}")
|
|
45
|
+
|
|
46
|
+
if __name__ == "__main__":
|
|
47
|
+
asyncio.run(main())
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Architecture
|
|
51
|
+
|
|
52
|
+
1. **SDK**: Generates UUID nonces and SHA256 consent hashes.
|
|
53
|
+
2. **Backend**: Proxies requests to the internal vault and maintains audit records.
|
|
54
|
+
3. **MCP Server (Vault)**: A hardened, isolated environment that signs transactions using Algorand.
|
|
55
|
+
4. **Algorand Blockchain**: Provides the irrefutable proof-of-consent and payment settlement.
|
|
56
|
+
|
|
57
|
+
## Features
|
|
58
|
+
|
|
59
|
+
- **Async First**: Built on `httpx` for high-performance agentic loops.
|
|
60
|
+
- **Zero-Trust**: Private keys never leave the vault.
|
|
61
|
+
- **DPDP Compliant**: Automatic cryptographic logging of purpose-bound consent.
|
|
62
|
+
- **Simple Audit**: Direct links to blockchain explorers for every transaction.
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
© 2026 AgentGuard Team. Built for the Algorand Ecosystem.
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
agentguard/__init__.py,sha256=P8UrlV5qCw8DCFwGmAunbItyBncuDH7UK7HzsqYMxBk,69
|
|
2
|
+
agentguard/client.py,sha256=8rvSOzfrtjKNy5PibBbikX9Sm-_-OnW4OXxrFWUGRUM,4550
|
|
3
|
+
agentguard/consent.py,sha256=RDefJwimc9MM14fbRrM9740yMHate7IIyJElkDoPPHE,1846
|
|
4
|
+
agentguard/types.py,sha256=lJCLHl-DYYV6wDETIhj7NbE548YviUXgMp6svH5nM60,534
|
|
5
|
+
agentguard_python_sdk-0.1.0.dist-info/METADATA,sha256=I67rw1MY1cM2EjF3eO48ij2lu6GVmmi8y2TEkXov2j4,2410
|
|
6
|
+
agentguard_python_sdk-0.1.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
7
|
+
agentguard_python_sdk-0.1.0.dist-info/top_level.txt,sha256=rEW5sAnjxXRs63ja2psmsMRMJJfi_3EAxf7crl1nHyw,11
|
|
8
|
+
agentguard_python_sdk-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
agentguard
|