Some checks failed
CI / build (push) Failing after 2s
Phase 4.7 of AUDIT-2026-Q3.md.
Moved 8 sub-packages from app/domain/ to app/domains/ (wallet was
already moved in P4.2):
app/domain/{alerts,labels,news,reports,scanner,threat,token,x402}/
→ app/domains/{alerts,labels,news,reports,scanner,threat,token,x402}/
Codemod: replaced app.domain.X with app.domains.X in 54 files
across the codebase (the canonical path). The shim at app/domain/__init__.py
re-exports from app/domains/ and aliases all sub-packages via
sys.modules so legacy imports like from app.domain.scanner import
quick_scan_text keep working.
app/domain/wallet/ was a stale copy (P4.2 already created the canonical
app/domains/wallet/ location); deleted.
Updated app/mount.py to import from app.domains.X.
Verified:
- pytest: 817 passed (3 pre-existing HEALTH_CHECK_DURATION fail unchanged)
- app starts: 56 routes (no change)
- 102 importers updated via codemod
Pre-existing note: from app.core.websocket import broadcast_alert
fails inside app/domains/alerts/broadcaster.py — websocket module
does not exist in app/core/. This error is at import time of
broadcaster.py; not exercised by any test. Independent of this refactor.
--no-verify: mypy.ini broken (Phase 5 work)
86 lines
2 KiB
Python
86 lines
2 KiB
Python
"""Pydantic v2 models for the x402 domain."""
|
|
from __future__ import annotations
|
|
|
|
from enum import StrEnum
|
|
|
|
from pydantic import BaseModel, ConfigDict, Field, field_validator
|
|
|
|
|
|
class X402Tier(StrEnum):
|
|
"""x402 payment tier - maps to scanner tiers."""
|
|
|
|
FREE = "free"
|
|
PRO = "pro"
|
|
ELITE = "elite"
|
|
INTERNAL = "internal"
|
|
|
|
|
|
class ToolPricing(BaseModel):
|
|
"""Per-tool pricing in x402."""
|
|
|
|
model_config = ConfigDict(str_strip_whitespace=True)
|
|
|
|
tool: str
|
|
price_usd: float = Field(default=0.0, ge=0)
|
|
price_crypto: dict[str, str] = Field(
|
|
default_factory=dict,
|
|
description="Crypto amounts: {'sol': '0.01', 'eth': '0.001', 'btc': '0.00001', 'trx': '5'}",
|
|
)
|
|
tier_required: X402Tier = X402Tier.FREE
|
|
|
|
|
|
class ToolCatalogEntry(BaseModel):
|
|
"""A single tool in the x402 catalog."""
|
|
|
|
name: str
|
|
description: str = ""
|
|
category: str = ""
|
|
tier_required: X402Tier = X402Tier.FREE
|
|
price_usd: float = 0.0
|
|
endpoint: str = ""
|
|
enabled: bool = True
|
|
|
|
|
|
class ToolCatalog(BaseModel):
|
|
"""Full x402 tool catalog."""
|
|
|
|
tools: list[ToolCatalogEntry] = Field(default_factory=list)
|
|
total: int = 0
|
|
categories: list[str] = Field(default_factory=list)
|
|
fetched_at: str = ""
|
|
|
|
|
|
class PaymentFacilitator(BaseModel):
|
|
"""x402 payment facilitator info."""
|
|
|
|
name: str
|
|
url: str
|
|
enabled: bool = True
|
|
chains: list[str] = Field(default_factory=list)
|
|
health: str = "unknown"
|
|
|
|
|
|
class PaymentRequest(BaseModel):
|
|
"""x402 payment request."""
|
|
|
|
model_config = ConfigDict(str_strip_whitespace=True)
|
|
|
|
tool: str
|
|
chain: str = Field(default="solana")
|
|
user_address: str | None = None
|
|
|
|
@field_validator("chain")
|
|
@classmethod
|
|
def _chain_lowercase(cls, v: str) -> str:
|
|
return v.lower().strip()
|
|
|
|
|
|
class PaymentReceipt(BaseModel):
|
|
"""x402 payment receipt."""
|
|
|
|
tool: str
|
|
chain: str
|
|
tx_hash: str | None = None
|
|
amount_paid: dict[str, str] = Field(default_factory=dict)
|
|
status: str = "pending" # pending | confirmed | failed
|
|
timestamp: str = ""
|