from __future__ import annotations from dataclasses import dataclass from datetime import datetime,timezone from decimal import Decimal,ROUND_UP from src.application.contracts import ICache,ILogger from src.application.domain.exceptions import ServiceUnavailableException from src.infrastructure.config import settings @dataclass(slots=True) class PaymentQuote: usdt_amount: Decimal usdt_exchange_rate: Decimal gas_fee: Decimal service_fee: Decimal total_price: Decimal service_fee_rate: Decimal created_at: datetime class PaymentQuoteService: def __init__(self, *, remote_cache: ICache, logger: ILogger): self._remote_cache = remote_cache self._logger = logger async def get_quote(self, usdt_amount: Decimal) -> PaymentQuote: rate_raw = await self._remote_cache.hget('tradex:rub:rate','value') gas_raw = await self._remote_cache.hget('gwei:eth:last','normal_rub') self._logger.info(f'Actual market values: rate={rate_raw}, gas={gas_raw}') if rate_raw is None: self._logger.error('Exchange rate unavailable') raise ServiceUnavailableException(message='Exchange rate unavailable') if gas_raw is None: self._logger.error('Exchange gas unavailable') raise ServiceUnavailableException(message='Exchange gas unavailable') gas_fee = Decimal(gas_raw).quantize(Decimal('0.00'), rounding=ROUND_UP) usdt_exchange_rate = Decimal(rate_raw).quantize(Decimal('0.00'), rounding=ROUND_UP) service_fee = (usdt_amount * usdt_exchange_rate * settings.PAYMENT_SERVICE_FEE_RATE).quantize(Decimal('0.01')) total_price = (usdt_amount * usdt_exchange_rate + service_fee + gas_fee).quantize(Decimal('0.01')) return PaymentQuote( usdt_amount=usdt_amount, usdt_exchange_rate=usdt_exchange_rate, gas_fee=gas_fee, service_fee=service_fee, total_price=total_price, service_fee_rate=settings.PAYMENT_SERVICE_FEE_RATE, created_at=datetime.now(timezone.utc), )