-
Notifications
You must be signed in to change notification settings - Fork 9
Expand file tree
/
Copy pathserver.py
More file actions
83 lines (65 loc) · 2.38 KB
/
server.py
File metadata and controls
83 lines (65 loc) · 2.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
"""Payment-protected API server using FastAPI and the Machine Payments Protocol."""
import os
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
from mpp import Challenge, Credential, Receipt
from mpp.methods.tempo import ChargeIntent, TempoAccount, tempo
from mpp.methods.tempo._defaults import PATH_USD, TESTNET_CHAIN_ID
from mpp.server import Mpp
app = FastAPI(
title="Payment-Protected API",
description="Example API demonstrating Machine Payments Protocol payment protection",
)
DESTINATION = os.environ.get(
"PAYMENT_DESTINATION", "0x742d35Cc6634c0532925a3b844bC9e7595F8fE00"
)
# Optional: set FEE_PAYER_KEY to sponsor gas for clients.
# When set, the server co-signs 0x78 fee payer envelopes locally.
fee_payer_key = os.environ.get("FEE_PAYER_KEY")
fee_payer = TempoAccount.from_key(fee_payer_key) if fee_payer_key else None
server = Mpp.create(
method=tempo(
chain_id=TESTNET_CHAIN_ID,
currency=PATH_USD,
recipient=DESTINATION,
fee_payer=fee_payer,
intents={"charge": ChargeIntent()},
),
)
@app.get("/free")
async def free_endpoint():
"""A free endpoint that anyone can access."""
return {"message": "This content is free!"}
@app.get("/paid")
async def paid_endpoint(request: Request):
"""A paid endpoint that requires payment to access."""
result = await server.charge(
authorization=request.headers.get("Authorization"),
amount="0.001",
chain_id=TESTNET_CHAIN_ID,
fee_payer=fee_payer is not None,
)
if isinstance(result, Challenge):
return JSONResponse(
status_code=402,
content={"error": "Payment required"},
headers={"WWW-Authenticate": result.to_www_authenticate(server.realm)},
)
credential, receipt = result
return {
"message": "This is paid content!",
"payer": credential.source,
"tx": receipt.reference,
}
@app.get("/paid-decorator")
@server.pay(amount="0.001", chain_id=TESTNET_CHAIN_ID)
async def paid_decorator_endpoint(request: Request, credential: Credential, receipt: Receipt):
"""A paid endpoint using the server.pay() decorator."""
return {
"message": "This is paid content!",
"payer": credential.source,
"tx": receipt.reference,
}
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000)