77import hashlib
88import hmac
99import subprocess
10+ import asyncio
1011
1112from mpp import (
1213 Challenge ,
@@ -148,9 +149,29 @@ def error(message: str, error_type: str = "unknown_error"):
148149 "base64url.encode" : "base64url-encode" ,
149150 "base64url.decode" : "base64url-decode" ,
150151 "challenge.id" : "generate-challenge-id" ,
152+ "tempo.receipt.verify" : "verify-tempo-receipt" ,
151153}
152154
153155
156+ class FakeRpcResponse :
157+ def __init__ (self , payload ):
158+ self ._payload = payload
159+
160+ def raise_for_status (self ):
161+ return None
162+
163+ def json (self ):
164+ return self ._payload
165+
166+
167+ class FakeRpcClient :
168+ def __init__ (self , receipt ):
169+ self ._receipt = receipt
170+
171+ async def post (self , * args , ** kwargs ):
172+ return FakeRpcResponse ({"jsonrpc" : "2.0" , "result" : self ._receipt , "id" : 1 })
173+
174+
154175def adapter_success (value ):
155176 return {"ok" : True , "value" : value }
156177
@@ -177,6 +198,40 @@ def response_value_for_operation(op: str, result):
177198 return result
178199
179200
201+ async def verify_tempo_receipt (input_value : dict ):
202+ from mpp .methods .tempo .intents import ChargeIntent
203+ from mpp .server .intent import VerificationError
204+
205+ credential_data = input_value ["credential" ]
206+ challenge_data = credential_data ["challenge" ]
207+ request_json = json .dumps (challenge_data ["request" ], separators = ("," , ":" ))
208+ request_b64 = base64url_encode (request_json )
209+
210+ credential = Credential (
211+ challenge = ChallengeEcho (
212+ id = challenge_data ["id" ],
213+ realm = challenge_data .get ("realm" , "" ),
214+ method = challenge_data ["method" ],
215+ intent = challenge_data ["intent" ],
216+ request = request_b64 ,
217+ expires = challenge_data .get ("expires" ),
218+ digest = challenge_data .get ("digest" ),
219+ ),
220+ payload = credential_data ["payload" ],
221+ source = credential_data .get ("source" ),
222+ )
223+
224+ intent = ChargeIntent (rpc_url = "https://rpc.test" )
225+ intent ._http_client = FakeRpcClient (input_value ["receipt" ])
226+
227+ try :
228+ receipt = await intent .verify (credential , challenge_data ["request" ])
229+ except VerificationError as exc :
230+ return error (str (exc ), "verification_error" )
231+
232+ return success ({"status" : receipt .status , "reference" : receipt .reference })
233+
234+
180235def run_legacy_subprocess (command : str , input_data : str = "" ):
181236 result = subprocess .run (
182237 [sys .executable , __file__ , command ],
@@ -296,6 +351,9 @@ def main():
296351 opaque = params .get ("opaque" ),
297352 )
298353 print (json .dumps (success (result )))
354+ elif command == "verify-tempo-receipt" :
355+ params = json .loads (input_data )
356+ print (json .dumps (asyncio .run (verify_tempo_receipt (params ))))
299357 else :
300358 print (json .dumps (error (f"Unknown command: { command } " )))
301359 except Exception as e :
@@ -307,6 +365,8 @@ def main():
307365 error_type = "encoding_error"
308366 elif command .startswith ("generate-" ):
309367 error_type = "generation_error"
368+ elif command .startswith ("verify-tempo-receipt" ):
369+ error_type = "verification_error"
310370 else :
311371 error_type = "unknown_error"
312372 print (json .dumps (error (str (e ), error_type )))
0 commit comments