xproof 0.2.0__tar.gz → 0.2.2__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.
- xproof-0.2.2/PKG-INFO +281 -0
- xproof-0.2.2/README.md +240 -0
- {xproof-0.2.0 → xproof-0.2.2}/pyproject.toml +1 -1
- {xproof-0.2.0 → xproof-0.2.2}/xproof/__init__.py +1 -1
- {xproof-0.2.0 → xproof-0.2.2}/xproof/client.py +97 -0
- xproof-0.2.2/xproof.egg-info/PKG-INFO +281 -0
- xproof-0.2.0/PKG-INFO +0 -235
- xproof-0.2.0/README.md +0 -194
- xproof-0.2.0/xproof.egg-info/PKG-INFO +0 -235
- {xproof-0.2.0 → xproof-0.2.2}/LICENSE +0 -0
- {xproof-0.2.0 → xproof-0.2.2}/setup.cfg +0 -0
- {xproof-0.2.0 → xproof-0.2.2}/tests/test_client.py +0 -0
- {xproof-0.2.0 → xproof-0.2.2}/tests/test_integration.py +0 -0
- {xproof-0.2.0 → xproof-0.2.2}/xproof/exceptions.py +0 -0
- {xproof-0.2.0 → xproof-0.2.2}/xproof/integrations/__init__.py +0 -0
- {xproof-0.2.0 → xproof-0.2.2}/xproof/integrations/autogen.py +0 -0
- {xproof-0.2.0 → xproof-0.2.2}/xproof/integrations/crewai.py +0 -0
- {xproof-0.2.0 → xproof-0.2.2}/xproof/integrations/deerflow.py +0 -0
- {xproof-0.2.0 → xproof-0.2.2}/xproof/integrations/langchain.py +0 -0
- {xproof-0.2.0 → xproof-0.2.2}/xproof/integrations/llamaindex.py +0 -0
- {xproof-0.2.0 → xproof-0.2.2}/xproof/integrations/openai_agents.py +0 -0
- {xproof-0.2.0 → xproof-0.2.2}/xproof/models.py +0 -0
- {xproof-0.2.0 → xproof-0.2.2}/xproof/py.typed +0 -0
- {xproof-0.2.0 → xproof-0.2.2}/xproof/utils.py +0 -0
- {xproof-0.2.0 → xproof-0.2.2}/xproof.egg-info/SOURCES.txt +0 -0
- {xproof-0.2.0 → xproof-0.2.2}/xproof.egg-info/dependency_links.txt +0 -0
- {xproof-0.2.0 → xproof-0.2.2}/xproof.egg-info/requires.txt +0 -0
- {xproof-0.2.0 → xproof-0.2.2}/xproof.egg-info/top_level.txt +0 -0
xproof-0.2.2/PKG-INFO
ADDED
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: xproof
|
|
3
|
+
Version: 0.2.2
|
|
4
|
+
Summary: Python SDK for xProof — blockchain-anchored proof-of-existence for AI agents on MultiversX
|
|
5
|
+
Author-email: xProof <contact@xproof.app>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://xproof.app
|
|
8
|
+
Project-URL: Repository, https://github.com/jasonxkensei/xproof
|
|
9
|
+
Project-URL: Documentation, https://xproof.app/docs
|
|
10
|
+
Project-URL: Issues, https://github.com/jasonxkensei/xproof/issues
|
|
11
|
+
Project-URL: Changelog, https://github.com/jasonxkensei/xproof/releases
|
|
12
|
+
Keywords: blockchain,multiversx,proof-of-existence,certification,sha256,ai-agents,accountability,audit-trail,web3
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
23
|
+
Classifier: Topic :: Security :: Cryptography
|
|
24
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
25
|
+
Classifier: Typing :: Typed
|
|
26
|
+
Requires-Python: >=3.8
|
|
27
|
+
Description-Content-Type: text/markdown
|
|
28
|
+
License-File: LICENSE
|
|
29
|
+
Requires-Dist: requests>=2.25.0
|
|
30
|
+
Provides-Extra: dev
|
|
31
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
32
|
+
Requires-Dist: responses>=0.20.0; extra == "dev"
|
|
33
|
+
Provides-Extra: llamaindex
|
|
34
|
+
Requires-Dist: llama-index-core>=0.13.0; extra == "llamaindex"
|
|
35
|
+
Provides-Extra: autogen
|
|
36
|
+
Requires-Dist: pyautogen>=0.2.0; extra == "autogen"
|
|
37
|
+
Provides-Extra: openai-agents
|
|
38
|
+
Requires-Dist: openai-agents>=0.0.3; extra == "openai-agents"
|
|
39
|
+
Provides-Extra: deerflow
|
|
40
|
+
Dynamic: license-file
|
|
41
|
+
|
|
42
|
+
# xproof
|
|
43
|
+
|
|
44
|
+
On-chain decision provenance for autonomous agents. **WHY before acting. WHAT after.** Timestamps written by the chain, not your agent.
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
pip install xproof
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## 3 steps. 30 seconds.
|
|
53
|
+
|
|
54
|
+
### Step 1 — Register (no wallet, no payment)
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
curl -X POST https://xproof.app/api/agent/register \
|
|
58
|
+
-H "Content-Type: application/json" \
|
|
59
|
+
-d '{"agent_name": "my-agent"}'
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
```json
|
|
63
|
+
{ "api_key": "pm_...", "trial": { "remaining": 10 } }
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Step 2 — Anchor WHY before acting
|
|
67
|
+
|
|
68
|
+
Hash your reasoning and certify it *before* your agent executes.
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
curl -X POST https://xproof.app/api/proof \
|
|
72
|
+
-H "Authorization: Bearer pm_..." \
|
|
73
|
+
-H "Content-Type: application/json" \
|
|
74
|
+
-d '{
|
|
75
|
+
"file_hash": "<sha256_of_reasoning>",
|
|
76
|
+
"file_name": "reasoning.json",
|
|
77
|
+
"author": "my-agent",
|
|
78
|
+
"metadata": { "action_type": "decision" }
|
|
79
|
+
}'
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
```json
|
|
83
|
+
{ "id": "why-proof-uuid", "transaction_hash": "0x..." }
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Step 3 — Anchor WHAT after acting
|
|
87
|
+
|
|
88
|
+
Hash your output and link it to the WHY proof.
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
curl -X POST https://xproof.app/api/proof \
|
|
92
|
+
-H "Authorization: Bearer pm_..." \
|
|
93
|
+
-H "Content-Type: application/json" \
|
|
94
|
+
-d '{
|
|
95
|
+
"file_hash": "<sha256_of_output>",
|
|
96
|
+
"file_name": "output.json",
|
|
97
|
+
"author": "my-agent",
|
|
98
|
+
"metadata": { "action_type": "execution", "why_proof_id": "why-proof-uuid" }
|
|
99
|
+
}'
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
```json
|
|
103
|
+
{ "id": "what-proof-uuid", "transaction_hash": "0x..." }
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
When something goes wrong, you don't guess. You verify.
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## Python SDK
|
|
111
|
+
|
|
112
|
+
```python
|
|
113
|
+
from xproof import XProofClient, hash_string
|
|
114
|
+
|
|
115
|
+
# Register — zero-friction, no wallet, no payment
|
|
116
|
+
client = XProofClient.register("my-agent")
|
|
117
|
+
# 10 free certs, API key stored automatically
|
|
118
|
+
|
|
119
|
+
# Step 2: Anchor WHY before acting
|
|
120
|
+
why = client.certify_hash(
|
|
121
|
+
file_hash=hash_string('{"action": "summarize", "model": "gpt-4"}'),
|
|
122
|
+
file_name="reasoning.json",
|
|
123
|
+
author="my-agent",
|
|
124
|
+
metadata={"action_type": "decision"},
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
# Step 3: Anchor WHAT after acting
|
|
128
|
+
what = client.certify_hash(
|
|
129
|
+
file_hash=hash_string(execution_output),
|
|
130
|
+
file_name="output.json",
|
|
131
|
+
author="my-agent",
|
|
132
|
+
metadata={"action_type": "execution", "why_proof_id": why.id},
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
print(what.transaction_url) # MultiversX explorer link
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Or use an existing API key:
|
|
139
|
+
|
|
140
|
+
```python
|
|
141
|
+
client = XProofClient(api_key="pm_your_api_key")
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## Framework Integrations
|
|
147
|
+
|
|
148
|
+
### LangChain
|
|
149
|
+
|
|
150
|
+
```python
|
|
151
|
+
from xproof.integrations.langchain import XProofCallbackHandler
|
|
152
|
+
|
|
153
|
+
handler = XProofCallbackHandler(api_key="pm_...")
|
|
154
|
+
llm = ChatOpenAI(callbacks=[handler])
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### CrewAI
|
|
158
|
+
|
|
159
|
+
```python
|
|
160
|
+
from xproof.integrations.crewai import XProofListener
|
|
161
|
+
|
|
162
|
+
listener = XProofListener(api_key="pm_...")
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### AutoGen
|
|
166
|
+
|
|
167
|
+
```python
|
|
168
|
+
from xproof.integrations.autogen import XProofHook
|
|
169
|
+
|
|
170
|
+
hook = XProofHook(api_key="pm_...")
|
|
171
|
+
agent.register_hook("process_last_received_message", hook.on_message)
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### LlamaIndex
|
|
175
|
+
|
|
176
|
+
```python
|
|
177
|
+
from xproof.integrations.llamaindex import XProofCallbackHandler
|
|
178
|
+
from llama_index.core import Settings
|
|
179
|
+
from llama_index.core.callbacks import CallbackManager
|
|
180
|
+
|
|
181
|
+
Settings.callback_manager = CallbackManager([XProofCallbackHandler(api_key="pm_...")])
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
## 4W Framework (WHO / WHAT / WHEN / WHY)
|
|
187
|
+
|
|
188
|
+
Full accountability metadata on every certification:
|
|
189
|
+
|
|
190
|
+
```python
|
|
191
|
+
from xproof import XProofClient, hash_bytes
|
|
192
|
+
|
|
193
|
+
client = XProofClient(api_key="pm_your_key")
|
|
194
|
+
|
|
195
|
+
action_data = b'{"action": "generate_report", "model": "gpt-4"}'
|
|
196
|
+
action_hash = hash_bytes(action_data)
|
|
197
|
+
|
|
198
|
+
cert = client.certify_hash(
|
|
199
|
+
file_hash=action_hash,
|
|
200
|
+
file_name="agent-action.json",
|
|
201
|
+
author="research-agent",
|
|
202
|
+
who="erd1abc...or-agent-id",
|
|
203
|
+
what=action_hash,
|
|
204
|
+
when="2026-03-20T12:00:00Z",
|
|
205
|
+
why=hash_bytes(b"Summarize Q1 earnings report"),
|
|
206
|
+
metadata={"model": "gpt-4", "session_id": "sess-123"},
|
|
207
|
+
)
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
## Batch Certification
|
|
211
|
+
|
|
212
|
+
Certify up to 50 files in a single API call:
|
|
213
|
+
|
|
214
|
+
```python
|
|
215
|
+
results = client.batch_certify([
|
|
216
|
+
{"file_hash": "abc123...", "file_name": "file1.pdf", "author": "my-agent"},
|
|
217
|
+
{"file_hash": "def456...", "file_name": "file2.pdf"},
|
|
218
|
+
])
|
|
219
|
+
|
|
220
|
+
print(results.summary.total) # 2
|
|
221
|
+
print(results.summary.created) # 2
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
## Certify a Local File
|
|
225
|
+
|
|
226
|
+
```python
|
|
227
|
+
# Auto-hashes with SHA-256
|
|
228
|
+
cert = client.certify("path/to/report.pdf", author="my-agent")
|
|
229
|
+
print(cert.id)
|
|
230
|
+
print(cert.transaction_url)
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
## Verify a Proof
|
|
234
|
+
|
|
235
|
+
```python
|
|
236
|
+
# By proof ID
|
|
237
|
+
proof = client.verify("certification-uuid")
|
|
238
|
+
print(proof.file_name, proof.blockchain_status)
|
|
239
|
+
|
|
240
|
+
# By file hash
|
|
241
|
+
proof = client.verify_hash("e3b0c442...")
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
## Pricing
|
|
245
|
+
|
|
246
|
+
```python
|
|
247
|
+
pricing = client.get_pricing()
|
|
248
|
+
print(pricing.price_usd) # e.g. 0.05
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
## API Reference
|
|
252
|
+
|
|
253
|
+
### `XProofClient(api_key=None, base_url="https://xproof.app", timeout=30)`
|
|
254
|
+
|
|
255
|
+
| Parameter | Type | Default |
|
|
256
|
+
|------------|-------|------------------------|
|
|
257
|
+
| `api_key` | `str` | `None` |
|
|
258
|
+
| `base_url` | `str` | `"https://xproof.app"` |
|
|
259
|
+
| `timeout` | `int` | `30` (seconds) |
|
|
260
|
+
|
|
261
|
+
### Methods
|
|
262
|
+
|
|
263
|
+
| Method | Description |
|
|
264
|
+
|--------|-------------|
|
|
265
|
+
| `XProofClient.register(agent_name)` | Register agent, get trial key |
|
|
266
|
+
| `certify(path, author, file_name?, **fourW)` | Certify file (hashes locally) |
|
|
267
|
+
| `certify_hash(file_hash, file_name, author, **fourW)` | Certify by pre-computed hash |
|
|
268
|
+
| `batch_certify(files)` | Batch certify (up to 50) |
|
|
269
|
+
| `verify(proof_id)` | Look up by proof ID |
|
|
270
|
+
| `verify_hash(file_hash)` | Look up by file hash |
|
|
271
|
+
| `get_pricing()` | Get current pricing |
|
|
272
|
+
|
|
273
|
+
## Links
|
|
274
|
+
|
|
275
|
+
- [xproof.app](https://xproof.app) — dashboard & docs
|
|
276
|
+
- [npm SDK](https://www.npmjs.com/package/@xproof/xproof) — `npm install @xproof/xproof`
|
|
277
|
+
- [Examples](https://github.com/jasonxkensei/xproof-examples) — LangChain, CrewAI, AutoGen, LlamaIndex
|
|
278
|
+
|
|
279
|
+
## License
|
|
280
|
+
|
|
281
|
+
MIT
|
xproof-0.2.2/README.md
ADDED
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
# xproof
|
|
2
|
+
|
|
3
|
+
On-chain decision provenance for autonomous agents. **WHY before acting. WHAT after.** Timestamps written by the chain, not your agent.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
pip install xproof
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## 3 steps. 30 seconds.
|
|
12
|
+
|
|
13
|
+
### Step 1 — Register (no wallet, no payment)
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
curl -X POST https://xproof.app/api/agent/register \
|
|
17
|
+
-H "Content-Type: application/json" \
|
|
18
|
+
-d '{"agent_name": "my-agent"}'
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
```json
|
|
22
|
+
{ "api_key": "pm_...", "trial": { "remaining": 10 } }
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### Step 2 — Anchor WHY before acting
|
|
26
|
+
|
|
27
|
+
Hash your reasoning and certify it *before* your agent executes.
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
curl -X POST https://xproof.app/api/proof \
|
|
31
|
+
-H "Authorization: Bearer pm_..." \
|
|
32
|
+
-H "Content-Type: application/json" \
|
|
33
|
+
-d '{
|
|
34
|
+
"file_hash": "<sha256_of_reasoning>",
|
|
35
|
+
"file_name": "reasoning.json",
|
|
36
|
+
"author": "my-agent",
|
|
37
|
+
"metadata": { "action_type": "decision" }
|
|
38
|
+
}'
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
```json
|
|
42
|
+
{ "id": "why-proof-uuid", "transaction_hash": "0x..." }
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Step 3 — Anchor WHAT after acting
|
|
46
|
+
|
|
47
|
+
Hash your output and link it to the WHY proof.
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
curl -X POST https://xproof.app/api/proof \
|
|
51
|
+
-H "Authorization: Bearer pm_..." \
|
|
52
|
+
-H "Content-Type: application/json" \
|
|
53
|
+
-d '{
|
|
54
|
+
"file_hash": "<sha256_of_output>",
|
|
55
|
+
"file_name": "output.json",
|
|
56
|
+
"author": "my-agent",
|
|
57
|
+
"metadata": { "action_type": "execution", "why_proof_id": "why-proof-uuid" }
|
|
58
|
+
}'
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
```json
|
|
62
|
+
{ "id": "what-proof-uuid", "transaction_hash": "0x..." }
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
When something goes wrong, you don't guess. You verify.
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## Python SDK
|
|
70
|
+
|
|
71
|
+
```python
|
|
72
|
+
from xproof import XProofClient, hash_string
|
|
73
|
+
|
|
74
|
+
# Register — zero-friction, no wallet, no payment
|
|
75
|
+
client = XProofClient.register("my-agent")
|
|
76
|
+
# 10 free certs, API key stored automatically
|
|
77
|
+
|
|
78
|
+
# Step 2: Anchor WHY before acting
|
|
79
|
+
why = client.certify_hash(
|
|
80
|
+
file_hash=hash_string('{"action": "summarize", "model": "gpt-4"}'),
|
|
81
|
+
file_name="reasoning.json",
|
|
82
|
+
author="my-agent",
|
|
83
|
+
metadata={"action_type": "decision"},
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
# Step 3: Anchor WHAT after acting
|
|
87
|
+
what = client.certify_hash(
|
|
88
|
+
file_hash=hash_string(execution_output),
|
|
89
|
+
file_name="output.json",
|
|
90
|
+
author="my-agent",
|
|
91
|
+
metadata={"action_type": "execution", "why_proof_id": why.id},
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
print(what.transaction_url) # MultiversX explorer link
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Or use an existing API key:
|
|
98
|
+
|
|
99
|
+
```python
|
|
100
|
+
client = XProofClient(api_key="pm_your_api_key")
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## Framework Integrations
|
|
106
|
+
|
|
107
|
+
### LangChain
|
|
108
|
+
|
|
109
|
+
```python
|
|
110
|
+
from xproof.integrations.langchain import XProofCallbackHandler
|
|
111
|
+
|
|
112
|
+
handler = XProofCallbackHandler(api_key="pm_...")
|
|
113
|
+
llm = ChatOpenAI(callbacks=[handler])
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### CrewAI
|
|
117
|
+
|
|
118
|
+
```python
|
|
119
|
+
from xproof.integrations.crewai import XProofListener
|
|
120
|
+
|
|
121
|
+
listener = XProofListener(api_key="pm_...")
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### AutoGen
|
|
125
|
+
|
|
126
|
+
```python
|
|
127
|
+
from xproof.integrations.autogen import XProofHook
|
|
128
|
+
|
|
129
|
+
hook = XProofHook(api_key="pm_...")
|
|
130
|
+
agent.register_hook("process_last_received_message", hook.on_message)
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### LlamaIndex
|
|
134
|
+
|
|
135
|
+
```python
|
|
136
|
+
from xproof.integrations.llamaindex import XProofCallbackHandler
|
|
137
|
+
from llama_index.core import Settings
|
|
138
|
+
from llama_index.core.callbacks import CallbackManager
|
|
139
|
+
|
|
140
|
+
Settings.callback_manager = CallbackManager([XProofCallbackHandler(api_key="pm_...")])
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## 4W Framework (WHO / WHAT / WHEN / WHY)
|
|
146
|
+
|
|
147
|
+
Full accountability metadata on every certification:
|
|
148
|
+
|
|
149
|
+
```python
|
|
150
|
+
from xproof import XProofClient, hash_bytes
|
|
151
|
+
|
|
152
|
+
client = XProofClient(api_key="pm_your_key")
|
|
153
|
+
|
|
154
|
+
action_data = b'{"action": "generate_report", "model": "gpt-4"}'
|
|
155
|
+
action_hash = hash_bytes(action_data)
|
|
156
|
+
|
|
157
|
+
cert = client.certify_hash(
|
|
158
|
+
file_hash=action_hash,
|
|
159
|
+
file_name="agent-action.json",
|
|
160
|
+
author="research-agent",
|
|
161
|
+
who="erd1abc...or-agent-id",
|
|
162
|
+
what=action_hash,
|
|
163
|
+
when="2026-03-20T12:00:00Z",
|
|
164
|
+
why=hash_bytes(b"Summarize Q1 earnings report"),
|
|
165
|
+
metadata={"model": "gpt-4", "session_id": "sess-123"},
|
|
166
|
+
)
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
## Batch Certification
|
|
170
|
+
|
|
171
|
+
Certify up to 50 files in a single API call:
|
|
172
|
+
|
|
173
|
+
```python
|
|
174
|
+
results = client.batch_certify([
|
|
175
|
+
{"file_hash": "abc123...", "file_name": "file1.pdf", "author": "my-agent"},
|
|
176
|
+
{"file_hash": "def456...", "file_name": "file2.pdf"},
|
|
177
|
+
])
|
|
178
|
+
|
|
179
|
+
print(results.summary.total) # 2
|
|
180
|
+
print(results.summary.created) # 2
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
## Certify a Local File
|
|
184
|
+
|
|
185
|
+
```python
|
|
186
|
+
# Auto-hashes with SHA-256
|
|
187
|
+
cert = client.certify("path/to/report.pdf", author="my-agent")
|
|
188
|
+
print(cert.id)
|
|
189
|
+
print(cert.transaction_url)
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
## Verify a Proof
|
|
193
|
+
|
|
194
|
+
```python
|
|
195
|
+
# By proof ID
|
|
196
|
+
proof = client.verify("certification-uuid")
|
|
197
|
+
print(proof.file_name, proof.blockchain_status)
|
|
198
|
+
|
|
199
|
+
# By file hash
|
|
200
|
+
proof = client.verify_hash("e3b0c442...")
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
## Pricing
|
|
204
|
+
|
|
205
|
+
```python
|
|
206
|
+
pricing = client.get_pricing()
|
|
207
|
+
print(pricing.price_usd) # e.g. 0.05
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
## API Reference
|
|
211
|
+
|
|
212
|
+
### `XProofClient(api_key=None, base_url="https://xproof.app", timeout=30)`
|
|
213
|
+
|
|
214
|
+
| Parameter | Type | Default |
|
|
215
|
+
|------------|-------|------------------------|
|
|
216
|
+
| `api_key` | `str` | `None` |
|
|
217
|
+
| `base_url` | `str` | `"https://xproof.app"` |
|
|
218
|
+
| `timeout` | `int` | `30` (seconds) |
|
|
219
|
+
|
|
220
|
+
### Methods
|
|
221
|
+
|
|
222
|
+
| Method | Description |
|
|
223
|
+
|--------|-------------|
|
|
224
|
+
| `XProofClient.register(agent_name)` | Register agent, get trial key |
|
|
225
|
+
| `certify(path, author, file_name?, **fourW)` | Certify file (hashes locally) |
|
|
226
|
+
| `certify_hash(file_hash, file_name, author, **fourW)` | Certify by pre-computed hash |
|
|
227
|
+
| `batch_certify(files)` | Batch certify (up to 50) |
|
|
228
|
+
| `verify(proof_id)` | Look up by proof ID |
|
|
229
|
+
| `verify_hash(file_hash)` | Look up by file hash |
|
|
230
|
+
| `get_pricing()` | Get current pricing |
|
|
231
|
+
|
|
232
|
+
## Links
|
|
233
|
+
|
|
234
|
+
- [xproof.app](https://xproof.app) — dashboard & docs
|
|
235
|
+
- [npm SDK](https://www.npmjs.com/package/@xproof/xproof) — `npm install @xproof/xproof`
|
|
236
|
+
- [Examples](https://github.com/jasonxkensei/xproof-examples) — LangChain, CrewAI, AutoGen, LlamaIndex
|
|
237
|
+
|
|
238
|
+
## License
|
|
239
|
+
|
|
240
|
+
MIT
|
|
@@ -281,6 +281,103 @@ class XProofClient:
|
|
|
281
281
|
data = self._request("POST", "/api/proof", json=payload)
|
|
282
282
|
return Certification.from_dict(data)
|
|
283
283
|
|
|
284
|
+
VALID_THRESHOLD_STAGES = ("initial", "partial", "pre-commitment", "final")
|
|
285
|
+
|
|
286
|
+
def certify_with_confidence(
|
|
287
|
+
self,
|
|
288
|
+
file_hash: str,
|
|
289
|
+
file_name: str,
|
|
290
|
+
author: str,
|
|
291
|
+
confidence_level: float,
|
|
292
|
+
threshold_stage: str,
|
|
293
|
+
decision_id: str,
|
|
294
|
+
*,
|
|
295
|
+
who: Optional[str] = None,
|
|
296
|
+
what: Optional[str] = None,
|
|
297
|
+
when: Optional[str] = None,
|
|
298
|
+
why: Optional[str] = None,
|
|
299
|
+
metadata: Optional[Dict[str, Any]] = None,
|
|
300
|
+
) -> Certification:
|
|
301
|
+
"""Certify a file hash with confidence-level anchoring.
|
|
302
|
+
|
|
303
|
+
Creates a forensic trail by anchoring proofs at different confidence
|
|
304
|
+
thresholds, linked by a shared ``decision_id``. An agent trading at
|
|
305
|
+
60%, 80%, then final creates an immutable trail that distinguishes
|
|
306
|
+
real reasoning from post-hoc reconstruction.
|
|
307
|
+
|
|
308
|
+
Args:
|
|
309
|
+
file_hash: 64-character lowercase hex SHA-256 digest.
|
|
310
|
+
file_name: Original file name.
|
|
311
|
+
author: Author / owner name.
|
|
312
|
+
confidence_level: Confidence between 0.0 and 1.0.
|
|
313
|
+
threshold_stage: One of ``initial``, ``partial``,
|
|
314
|
+
``pre-commitment``, ``final``.
|
|
315
|
+
decision_id: Shared identifier linking all proofs in the
|
|
316
|
+
same decision chain.
|
|
317
|
+
who: 4W -- agent identity.
|
|
318
|
+
what: 4W -- action hash or description.
|
|
319
|
+
when: 4W -- ISO-8601 timestamp.
|
|
320
|
+
why: 4W -- instruction or reason.
|
|
321
|
+
metadata: Extra key-value metadata stored alongside the proof.
|
|
322
|
+
|
|
323
|
+
Returns:
|
|
324
|
+
A :class:`Certification` with the on-chain proof details.
|
|
325
|
+
|
|
326
|
+
Raises:
|
|
327
|
+
ValueError: If confidence_level or threshold_stage is invalid.
|
|
328
|
+
"""
|
|
329
|
+
if not self.api_key:
|
|
330
|
+
raise ValueError("api_key is required — call register() or pass an api_key")
|
|
331
|
+
if not 0.0 <= confidence_level <= 1.0:
|
|
332
|
+
raise ValueError("confidence_level must be between 0.0 and 1.0")
|
|
333
|
+
if threshold_stage not in self.VALID_THRESHOLD_STAGES:
|
|
334
|
+
raise ValueError(
|
|
335
|
+
f"threshold_stage must be one of: {', '.join(self.VALID_THRESHOLD_STAGES)}"
|
|
336
|
+
)
|
|
337
|
+
if not decision_id or not decision_id.strip():
|
|
338
|
+
raise ValueError("decision_id is required")
|
|
339
|
+
|
|
340
|
+
proof_metadata: Dict[str, Any] = dict(metadata) if metadata else {}
|
|
341
|
+
proof_metadata["confidence_level"] = confidence_level
|
|
342
|
+
proof_metadata["threshold_stage"] = threshold_stage
|
|
343
|
+
proof_metadata["decision_id"] = decision_id
|
|
344
|
+
if who is not None:
|
|
345
|
+
proof_metadata["who"] = who
|
|
346
|
+
if what is not None:
|
|
347
|
+
proof_metadata["what"] = what
|
|
348
|
+
if when is not None:
|
|
349
|
+
proof_metadata["when"] = when
|
|
350
|
+
if why is not None:
|
|
351
|
+
proof_metadata["why"] = why
|
|
352
|
+
|
|
353
|
+
payload: Dict[str, Any] = {
|
|
354
|
+
"filename": file_name,
|
|
355
|
+
"file_hash": file_hash,
|
|
356
|
+
"author_name": author,
|
|
357
|
+
"metadata": proof_metadata,
|
|
358
|
+
}
|
|
359
|
+
data = self._request("POST", "/api/proof", json=payload)
|
|
360
|
+
return Certification.from_dict(data)
|
|
361
|
+
|
|
362
|
+
def get_confidence_trail(self, decision_id: str) -> Dict[str, Any]:
|
|
363
|
+
"""Retrieve the full confidence trail for a decision chain.
|
|
364
|
+
|
|
365
|
+
Args:
|
|
366
|
+
decision_id: The shared identifier linking proofs in the chain.
|
|
367
|
+
|
|
368
|
+
Returns:
|
|
369
|
+
A dictionary with ``decision_id``, ``total_anchors``,
|
|
370
|
+
``current_confidence``, ``current_stage``, ``is_finalized``,
|
|
371
|
+
and ``stages`` (list of anchor details sorted by confidence).
|
|
372
|
+
"""
|
|
373
|
+
from urllib.parse import quote
|
|
374
|
+
data = self._request(
|
|
375
|
+
"GET",
|
|
376
|
+
f"/api/confidence-trail/{quote(decision_id, safe='')}",
|
|
377
|
+
auth_required=False,
|
|
378
|
+
)
|
|
379
|
+
return data
|
|
380
|
+
|
|
284
381
|
def batch_certify(
|
|
285
382
|
self,
|
|
286
383
|
files: List[Dict[str, Any]],
|