feat: Implement payment processing with contract auditing, event loops, and web observability endpoints.
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
import os
|
||||
|
||||
from src.payments.contract_audit import analyze_checkout_contract
|
||||
|
||||
|
||||
def test_payment_contract_audit_detects_current_controls():
|
||||
report = analyze_checkout_contract(
|
||||
os.path.join("contracts", "PolyWeatherCheckout.sol")
|
||||
)
|
||||
|
||||
assert report["checks"]["has_only_owner_modifier"] is True
|
||||
assert report["checks"]["allowed_token_check"] is True
|
||||
assert report["checks"]["duplicate_order_check"] is True
|
||||
assert report["checks"]["paid_order_written_before_transfer"] is True
|
||||
assert report["checks"]["has_pause_switch"] is False
|
||||
assert report["checks"]["binds_plan_amount_onchain"] is False
|
||||
assert any(risk["id"] == "single_owner_admin" for risk in report["risks"])
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
from src.database.db_manager import DBManager
|
||||
from src.payments.contract_checkout import PaymentContractCheckoutService
|
||||
|
||||
|
||||
def test_payment_runtime_state_and_audit_event_roundtrip(tmp_path):
|
||||
db_path = tmp_path / "payments.db"
|
||||
db = DBManager(str(db_path))
|
||||
|
||||
db.set_payment_runtime_state("payment_event_loop", {"last_scanned_block": 123})
|
||||
db.append_payment_audit_event("event_loop_cycle", {"blocks": 10, "events": 2})
|
||||
|
||||
state = db.get_payment_runtime_state("payment_event_loop")
|
||||
events = db.list_payment_audit_events(limit=10)
|
||||
|
||||
assert state == {"last_scanned_block": 123}
|
||||
assert events
|
||||
assert events[0]["event_type"] == "event_loop_cycle"
|
||||
assert events[0]["payload"]["events"] == 2
|
||||
|
||||
|
||||
def test_payment_checkout_parses_multiple_rpc_urls(monkeypatch, tmp_path):
|
||||
monkeypatch.setenv("POLYWEATHER_PAYMENT_ENABLED", "true")
|
||||
monkeypatch.setenv("SUPABASE_URL", "https://example.supabase.co")
|
||||
monkeypatch.setenv("SUPABASE_SERVICE_ROLE_KEY", "service-role")
|
||||
monkeypatch.setenv(
|
||||
"POLYWEATHER_PAYMENT_RPC_URLS",
|
||||
"https://rpc-1.example,https://rpc-2.example",
|
||||
)
|
||||
monkeypatch.setenv(
|
||||
"POLYWEATHER_PAYMENT_ACCEPTED_TOKENS_JSON",
|
||||
'[{"code":"usdc_e","address":"0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174","decimals":6,"receiver_contract":"0xeD2f13Aa5fF033c58FB436E178451Cd07f693f32","is_default":true}]',
|
||||
)
|
||||
monkeypatch.setenv("POLYWEATHER_DB_PATH", str(tmp_path / "payments.db"))
|
||||
|
||||
service = PaymentContractCheckoutService()
|
||||
status = service.get_rpc_runtime_status()
|
||||
|
||||
assert service.rpc_urls == ["https://rpc-1.example", "https://rpc-2.example"]
|
||||
assert status["configured_rpc_count"] == 2
|
||||
assert status["all_rpc_urls"][0] == "https://rpc-1.example"
|
||||
@@ -35,3 +35,13 @@ def test_metrics_endpoint_returns_prometheus_payload():
|
||||
response = client.get('/metrics')
|
||||
assert response.status_code == 200
|
||||
assert 'polyweather_http_requests_total' in response.text
|
||||
|
||||
|
||||
def test_payment_runtime_endpoint_returns_shape():
|
||||
response = client.get('/api/payments/runtime')
|
||||
assert response.status_code == 200
|
||||
payload = response.json()
|
||||
assert 'checkout' in payload
|
||||
assert 'rpc' in payload
|
||||
assert 'event_loop_state' in payload
|
||||
assert 'recent_audit_events' in payload
|
||||
|
||||
Reference in New Issue
Block a user