atp-protocol 1.0.1__py3-none-any.whl → 1.2.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.
- {atp_protocol-1.0.1.dist-info → atp_protocol-1.2.0.dist-info}/METADATA +87 -176
- {atp_protocol-1.0.1.dist-info → atp_protocol-1.2.0.dist-info}/RECORD +4 -4
- {atp_protocol-1.0.1.dist-info → atp_protocol-1.2.0.dist-info}/LICENSE +0 -0
- {atp_protocol-1.0.1.dist-info → atp_protocol-1.2.0.dist-info}/WHEEL +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: atp-protocol
|
|
3
|
-
Version: 1.0
|
|
3
|
+
Version: 1.2.0
|
|
4
4
|
Summary: ATP Protocol - Agentic Trade Protocol. The easiest way to enable agent-to-agent payments powered by Solana.
|
|
5
5
|
License: MIT
|
|
6
6
|
Keywords: atp,atp-protocol,solana,blockchain,cryptocurrency,payment-gated,agent-to-agent,agent payments,agent execution,payment settlement,solana payments,usdc,sol,fastapi,agent api,payment gateway,settlement service,agent marketplace,decentralized payments,web3,crypto payments,agent infrastructure,payment middleware,automated settlement
|
|
@@ -23,8 +23,6 @@ Requires-Dist: loguru
|
|
|
23
23
|
Requires-Dist: pydantic
|
|
24
24
|
Requires-Dist: python-dotenv
|
|
25
25
|
Requires-Dist: setuptools
|
|
26
|
-
Requires-Dist: solana
|
|
27
|
-
Requires-Dist: solders
|
|
28
26
|
Requires-Dist: starlette
|
|
29
27
|
Requires-Dist: swarms
|
|
30
28
|
Project-URL: Documentation, https://github.com/The-Swarm-Corporation/ATP-Protocol
|
|
@@ -257,33 +255,46 @@ stateDiagram-v2
|
|
|
257
255
|
|
|
258
256
|
## ATP Settlement Middleware
|
|
259
257
|
|
|
260
|
-
The ATP
|
|
258
|
+
The ATP Settlement Middleware enables **automatic payment processing** for any FastAPI endpoint. Unlike the main ATP Gateway (which uses a 402 challenge), the middleware handles payment **automatically after** your endpoint executes—perfect for APIs that want seamless billing.
|
|
261
259
|
|
|
262
|
-
### How
|
|
260
|
+
### How It Works
|
|
263
261
|
|
|
264
|
-
The
|
|
262
|
+
The middleware intercepts requests, executes your endpoint, then automatically processes payment:
|
|
265
263
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
264
|
+
```mermaid
|
|
265
|
+
sequenceDiagram
|
|
266
|
+
autonumber
|
|
267
|
+
participant C as Client
|
|
268
|
+
participant M as Middleware
|
|
269
|
+
participant E as Endpoint
|
|
270
|
+
participant SS as Settlement Service
|
|
271
|
+
participant S as Solana
|
|
273
272
|
|
|
274
|
-
|
|
273
|
+
C->>M: POST /v1/chat<br/>(x-wallet-private-key header)
|
|
274
|
+
M->>E: Forward request
|
|
275
|
+
E-->>M: Response + usage data
|
|
276
|
+
M->>M: Extract token usage<br/>(auto-detects format)
|
|
277
|
+
M->>SS: Calculate payment<br/>(usage → USD → SOL/USDC)
|
|
278
|
+
SS->>SS: Split payment<br/>(95% recipient, 5% treasury)
|
|
279
|
+
SS->>S: Send payment transaction
|
|
280
|
+
S-->>SS: Transaction signature
|
|
281
|
+
SS-->>M: Settlement details
|
|
282
|
+
M->>M: Add settlement info<br/>to response
|
|
283
|
+
M-->>C: Response + atp_settlement
|
|
284
|
+
```
|
|
275
285
|
|
|
276
|
-
|
|
277
|
-
|---------|-----------------|------------|
|
|
278
|
-
| **Payment Flow** | Two-step: 402 challenge → settle | Automatic: single request |
|
|
279
|
-
| **Response** | Returns 402 with payment challenge | Returns normal response + settlement info |
|
|
280
|
-
| **Integration** | Requires two API calls | Single API call with wallet header |
|
|
281
|
-
| **Use Case** | Pay-to-unlock results | Automatic per-request billing |
|
|
282
|
-
| **Wallet Key** | Provided during settlement | Provided in request header |
|
|
286
|
+
**Step-by-step:**
|
|
283
287
|
|
|
284
|
-
|
|
288
|
+
1. **Client sends request** with wallet private key in header (`x-wallet-private-key`)
|
|
289
|
+
2. **Middleware forwards** request to your endpoint
|
|
290
|
+
3. **Endpoint executes** and returns response with usage data
|
|
291
|
+
4. **Middleware extracts** token counts (supports OpenAI, Anthropic, Google, etc.)
|
|
292
|
+
5. **Settlement service calculates** cost: `(input_tokens × input_rate + output_tokens × output_rate) / 1M`
|
|
293
|
+
6. **Settlement service splits** payment: 95% to recipient, 5% to Swarms Treasury
|
|
294
|
+
7. **Settlement service sends** Solana transaction
|
|
295
|
+
8. **Middleware adds** settlement info to response and returns to client
|
|
285
296
|
|
|
286
|
-
|
|
297
|
+
### Quick Start
|
|
287
298
|
|
|
288
299
|
```python
|
|
289
300
|
from fastapi import FastAPI
|
|
@@ -294,197 +305,97 @@ app = FastAPI()
|
|
|
294
305
|
|
|
295
306
|
app.add_middleware(
|
|
296
307
|
ATPSettlementMiddleware,
|
|
297
|
-
allowed_endpoints=[
|
|
298
|
-
|
|
299
|
-
"/v1/completions",
|
|
300
|
-
"/v1/agent/execute",
|
|
301
|
-
],
|
|
302
|
-
input_cost_per_million_usd=10.0, # $10 per million input tokens
|
|
308
|
+
allowed_endpoints=["/v1/chat", "/v1/completions"],
|
|
309
|
+
input_cost_per_million_usd=10.0, # $10 per million input tokens
|
|
303
310
|
output_cost_per_million_usd=30.0, # $30 per million output tokens
|
|
304
|
-
|
|
305
|
-
payment_token=PaymentToken.SOL,
|
|
306
|
-
recipient_pubkey="YourPublicKeyHere", # Required: endpoint host receives payment
|
|
307
|
-
skip_preflight=False, # Skip Solana transaction preflight simulation
|
|
308
|
-
commitment="confirmed", # Solana commitment level
|
|
309
|
-
require_wallet=True, # Require wallet key (if False, skips settlement when missing)
|
|
311
|
+
recipient_pubkey="YourPublicKeyHere", # Your wallet receives 95%
|
|
312
|
+
payment_token=PaymentToken.SOL,
|
|
310
313
|
)
|
|
311
314
|
```
|
|
312
315
|
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
- **`allowed_endpoints`** (required): List of endpoint paths to apply settlement to (exact matches only)
|
|
316
|
-
- **`input_cost_per_million_usd`** (required): Cost per million input tokens in USD
|
|
317
|
-
- **`output_cost_per_million_usd`** (required): Cost per million output tokens in USD
|
|
318
|
-
- **`wallet_private_key_header`** (default: `"x-wallet-private-key"`): HTTP header name containing the wallet private key
|
|
319
|
-
- **`payment_token`** (default: `PaymentToken.SOL`): Token to use for payment (SOL or USDC)
|
|
320
|
-
- **`recipient_pubkey`** (required): Solana public key of the recipient wallet (endpoint host receives main payment)
|
|
321
|
-
- **`skip_preflight`** (default: `False`): Whether to skip preflight simulation for Solana transactions
|
|
322
|
-
- **`commitment`** (default: `"confirmed"`): Solana commitment level (`processed`|`confirmed`|`finalized`)
|
|
323
|
-
- **`require_wallet`** (default: `True`): Whether to require wallet private key (if False, skips settlement when missing)
|
|
324
|
-
|
|
325
|
-
### Usage Example
|
|
326
|
-
|
|
327
|
-
**Client Request:**
|
|
316
|
+
**Client request:**
|
|
328
317
|
```bash
|
|
329
318
|
curl -X POST http://localhost:8000/v1/chat \
|
|
330
|
-
-H "Content-Type: application/json" \
|
|
331
319
|
-H "x-wallet-private-key: [1,2,3,...]" \
|
|
332
|
-
-d '{"message": "Hello
|
|
320
|
+
-d '{"message": "Hello!"}'
|
|
333
321
|
```
|
|
334
322
|
|
|
335
|
-
**
|
|
323
|
+
**Your endpoint:**
|
|
336
324
|
```python
|
|
337
325
|
@app.post("/v1/chat")
|
|
338
|
-
async def
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
"output": "Hello! This is a response from the chat endpoint.",
|
|
326
|
+
async def chat(request: dict):
|
|
327
|
+
return {
|
|
328
|
+
"output": "Response here",
|
|
342
329
|
"usage": {
|
|
343
|
-
"input_tokens": 150,
|
|
344
|
-
"output_tokens": 50,
|
|
345
|
-
|
|
346
|
-
},
|
|
330
|
+
"input_tokens": 150,
|
|
331
|
+
"output_tokens": 50,
|
|
332
|
+
}
|
|
347
333
|
}
|
|
348
|
-
return JSONResponse(content=response_data)
|
|
349
334
|
```
|
|
350
335
|
|
|
351
|
-
**Response
|
|
336
|
+
**Response includes settlement:**
|
|
352
337
|
```json
|
|
353
338
|
{
|
|
354
|
-
"output": "
|
|
355
|
-
"usage": {
|
|
356
|
-
"input_tokens": 150,
|
|
357
|
-
"output_tokens": 50,
|
|
358
|
-
"total_tokens": 200
|
|
359
|
-
},
|
|
360
|
-
"atp_usage": {
|
|
361
|
-
"input_tokens": 150,
|
|
362
|
-
"output_tokens": 50,
|
|
363
|
-
"total_tokens": 200
|
|
364
|
-
},
|
|
339
|
+
"output": "Response here",
|
|
340
|
+
"usage": {"input_tokens": 150, "output_tokens": 50},
|
|
365
341
|
"atp_settlement": {
|
|
366
342
|
"status": "paid",
|
|
367
343
|
"transaction_signature": "5j7s8K9...",
|
|
368
|
-
"pricing": {
|
|
369
|
-
"usd_cost": 0.003,
|
|
370
|
-
"source": "middleware_rates",
|
|
371
|
-
"input_tokens": 150,
|
|
372
|
-
"output_tokens": 50,
|
|
373
|
-
"total_tokens": 200,
|
|
374
|
-
"input_cost_per_million_usd": 10.0,
|
|
375
|
-
"output_cost_per_million_usd": 30.0,
|
|
376
|
-
"input_cost_usd": 0.0015,
|
|
377
|
-
"output_cost_usd": 0.0015
|
|
378
|
-
},
|
|
379
344
|
"payment": {
|
|
380
|
-
"total_amount_lamports": 300000,
|
|
381
345
|
"total_amount_sol": 0.0003,
|
|
382
|
-
"
|
|
383
|
-
"treasury": {
|
|
384
|
-
"pubkey": "7MaX4muAn8ZQREJxnupm8sgokwFHujgrGfH9Qn81BuEV",
|
|
385
|
-
"amount_lamports": 15000,
|
|
386
|
-
"amount_sol": 0.000015,
|
|
387
|
-
"amount_usd": 0.00015
|
|
388
|
-
},
|
|
389
|
-
"recipient": {
|
|
390
|
-
"pubkey": "YourPublicKeyHere",
|
|
391
|
-
"amount_lamports": 285000,
|
|
392
|
-
"amount_sol": 0.000285,
|
|
393
|
-
"amount_usd": 0.00285
|
|
394
|
-
}
|
|
346
|
+
"recipient": {"amount_sol": 0.000285},
|
|
347
|
+
"treasury": {"amount_sol": 0.000015}
|
|
395
348
|
}
|
|
396
349
|
}
|
|
397
350
|
}
|
|
398
351
|
```
|
|
399
352
|
|
|
400
|
-
###
|
|
353
|
+
### Configuration
|
|
401
354
|
|
|
402
|
-
|
|
355
|
+
| Parameter | Required | Description |
|
|
356
|
+
|-----------|----------|-------------|
|
|
357
|
+
| `allowed_endpoints` | ✅ | List of paths to apply settlement (e.g., `["/v1/chat"]`) |
|
|
358
|
+
| `input_cost_per_million_usd` | ✅ | Cost per million input tokens |
|
|
359
|
+
| `output_cost_per_million_usd` | ✅ | Cost per million output tokens |
|
|
360
|
+
| `recipient_pubkey` | ✅ | Your Solana wallet (receives 95% of payment) |
|
|
361
|
+
| `wallet_private_key_header` | ❌ | Header name for wallet key (default: `x-wallet-private-key`) |
|
|
362
|
+
| `payment_token` | ❌ | `PaymentToken.SOL` or `PaymentToken.USDC` (default: SOL) |
|
|
363
|
+
| `require_wallet` | ❌ | Require wallet key or skip settlement (default: `True`) |
|
|
364
|
+
| `settlement_service_url` | ❌ | Settlement service URL (default: from `ATP_SETTLEMENT_URL` env) |
|
|
403
365
|
|
|
404
|
-
|
|
405
|
-
- **Anthropic**: `input_tokens`, `output_tokens`, `total_tokens`
|
|
406
|
-
- **Google/Gemini**: `promptTokenCount`, `candidatesTokenCount`, `totalTokenCount`
|
|
407
|
-
- **Cohere**: `tokens` (total), or `input_tokens`/`output_tokens` separately
|
|
408
|
-
- **Generic**: `input_tokens`, `output_tokens`, `total_tokens`
|
|
409
|
-
- **Nested**: `usage.prompt_tokens`, `meta.usage`, `statistics`, etc.
|
|
366
|
+
### Payment Calculation
|
|
410
367
|
|
|
411
|
-
The middleware
|
|
412
|
-
1. Checking if the entire response contains usage-like keys at the top level
|
|
413
|
-
2. Searching nested structures with common usage key names (`usage`, `token_usage`, `meta`, `statistics`, etc.)
|
|
368
|
+
The middleware uses your configured rates to calculate cost:
|
|
414
369
|
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
sequenceDiagram
|
|
419
|
-
autonumber
|
|
420
|
-
participant C as Client
|
|
421
|
-
participant M as Middleware
|
|
422
|
-
participant E as Endpoint
|
|
423
|
-
participant S as Solana
|
|
424
|
-
|
|
425
|
-
C->>M: POST /v1/chat<br/>(x-wallet-private-key header)
|
|
426
|
-
M->>E: Forward request
|
|
427
|
-
E-->>M: Response + usage data
|
|
428
|
-
M->>M: Extract usage tokens<br/>(normalize format)
|
|
429
|
-
M->>M: Calculate USD cost<br/>(from token counts)
|
|
430
|
-
M->>M: Fetch token price<br/>(SOL/USDC)
|
|
431
|
-
M->>M: Calculate payment amounts<br/>(with 5% fee split)
|
|
432
|
-
M->>S: Send split payment tx<br/>(recipient + treasury)
|
|
433
|
-
S-->>M: Transaction signature
|
|
434
|
-
M->>M: Add settlement info<br/>to response
|
|
435
|
-
M-->>C: Response + atp_settlement
|
|
370
|
+
```
|
|
371
|
+
usd_cost = (input_tokens / 1,000,000 × input_rate) + (output_tokens / 1,000,000 × output_rate)
|
|
372
|
+
token_amount = usd_cost / token_price_usd
|
|
436
373
|
```
|
|
437
374
|
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
- **Total Payment**: `usd_cost / token_price_usd`
|
|
443
|
-
- **Swarms Treasury Fee**: `5%` of total (from `config.SETTLEMENT_FEE_PERCENT`)
|
|
444
|
-
- **Recipient Amount**: `95%` of total (endpoint host receives this)
|
|
445
|
-
|
|
446
|
-
The fee is **taken from the total** (not added on top), so the recipient receives the net amount after fees.
|
|
447
|
-
|
|
448
|
-
### Error Handling
|
|
449
|
-
|
|
450
|
-
- **Missing wallet key**: Returns `401 Unauthorized` if `require_wallet=True` (default)
|
|
451
|
-
- **Missing usage data**: Logs warning and returns original response (no settlement)
|
|
452
|
-
- **Payment failure**: Returns `500 Internal Server Error` with error details
|
|
453
|
-
- **Invalid private key**: Returns `500 Internal Server Error` with parsing error
|
|
454
|
-
|
|
455
|
-
### Custom API Key Integration
|
|
375
|
+
Payment is split automatically:
|
|
376
|
+
- **95%** → `recipient_pubkey` (your wallet)
|
|
377
|
+
- **5%** → Swarms Treasury (processing fee)
|
|
456
378
|
|
|
457
|
-
|
|
379
|
+
The fee is **deducted from the total** (not added on top).
|
|
458
380
|
|
|
459
|
-
|
|
460
|
-
# Simple in-memory mapping (replace with database in production)
|
|
461
|
-
API_KEY_TO_WALLET = {
|
|
462
|
-
"user_api_key_123": "[1,2,3,...]", # Solana private key
|
|
463
|
-
}
|
|
381
|
+
### Supported Usage Formats
|
|
464
382
|
|
|
465
|
-
|
|
466
|
-
"""Custom dependency to map API keys to wallet private keys."""
|
|
467
|
-
if api_key not in API_KEY_TO_WALLET:
|
|
468
|
-
raise HTTPException(status_code=401, detail="Invalid API key")
|
|
469
|
-
return API_KEY_TO_WALLET[api_key]
|
|
383
|
+
The middleware auto-detects usage from common API formats:
|
|
470
384
|
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
385
|
+
- **OpenAI**: `prompt_tokens`, `completion_tokens`
|
|
386
|
+
- **Anthropic**: `input_tokens`, `output_tokens`
|
|
387
|
+
- **Google/Gemini**: `promptTokenCount`, `candidatesTokenCount`
|
|
388
|
+
- **Generic**: `input_tokens`, `output_tokens`, `total_tokens`
|
|
389
|
+
- **Nested**: `usage.*`, `meta.usage`, `statistics.*`
|
|
476
390
|
|
|
477
|
-
|
|
478
|
-
- You want automatic, per-request billing
|
|
479
|
-
- Your API already returns usage data
|
|
480
|
-
- You want a single-request flow (no 402 challenge)
|
|
481
|
-
- You're building a service that charges per API call
|
|
391
|
+
### Middleware vs. Main Protocol
|
|
482
392
|
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
-
|
|
486
|
-
|
|
487
|
-
|
|
393
|
+
| Feature | Main Gateway | Middleware |
|
|
394
|
+
|---------|--------------|------------|
|
|
395
|
+
| **Flow** | Two-step: 402 challenge → settle | Automatic: single request |
|
|
396
|
+
| **Use Case** | Pay-to-unlock results | Per-request billing |
|
|
397
|
+
| **Integration** | Two API calls | One API call |
|
|
488
398
|
|
|
489
|
-
|
|
399
|
+
**Use middleware for:** Automatic billing on every request
|
|
400
|
+
**Use main protocol for:** Explicit payment approval before results
|
|
490
401
|
|
|
@@ -3,7 +3,7 @@ atp/config.py,sha256=lYERbrySRTuyS_jeaAnLHYuBEQNLqaKLQTy_nEFP7lY,2041
|
|
|
3
3
|
atp/middleware.py,sha256=GlRBXEba_hlGMPi69LAGUJSQsKfmwSnAENKZQ9QcXhU,13185
|
|
4
4
|
atp/schemas.py,sha256=iASVBPpAhrO-LDXs2UC9ABtfV1oDYsu4kZcz3dVeJNA,6220
|
|
5
5
|
atp/settlement_client.py,sha256=jfvhxDqp2kDISWG7tjX5s88goAPxp-lMXvuJtpMyOys,6742
|
|
6
|
-
atp_protocol-1.0.
|
|
7
|
-
atp_protocol-1.0.
|
|
8
|
-
atp_protocol-1.0.
|
|
9
|
-
atp_protocol-1.0.
|
|
6
|
+
atp_protocol-1.2.0.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
7
|
+
atp_protocol-1.2.0.dist-info/METADATA,sha256=r-Q1CFshMWPS-jftoGwI7OuPcj8B609IRGcBe00VX0E,14295
|
|
8
|
+
atp_protocol-1.2.0.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
|
9
|
+
atp_protocol-1.2.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|