import { WalletsApiClient, LeagueWalletDTO, WithdrawRequestDTO, WithdrawResponseDTO } from '@/lib/api/wallets/WalletsApiClient'; import { LeagueWalletViewModel } from '@/lib/view-models/LeagueWalletViewModel'; import { WalletTransactionViewModel } from '@/lib/view-models/WalletTransactionViewModel'; import { SubmitBlocker, ThrottleBlocker } from '@/lib/blockers'; /** * League Wallet Service * * Orchestrates league wallet operations by coordinating API calls and view model creation. * All dependencies are injected via constructor. */ export class LeagueWalletService { private readonly submitBlocker = new SubmitBlocker(); private readonly throttle = new ThrottleBlocker(500); constructor( private readonly apiClient: WalletsApiClient ) {} /** * Get wallet for a league */ async getWalletForLeague(leagueId: string): Promise { const dto = await this.apiClient.getLeagueWallet(leagueId); const transactions = dto.transactions.map(t => new WalletTransactionViewModel({ id: t.id, type: t.type, description: t.description, amount: t.amount, fee: t.fee, netAmount: t.netAmount, date: new Date(t.date), status: t.status, reference: t.reference, })); return new LeagueWalletViewModel({ balance: dto.balance, currency: dto.currency, totalRevenue: dto.totalRevenue, totalFees: dto.totalFees, totalWithdrawals: dto.totalWithdrawals, pendingPayouts: dto.pendingPayouts, transactions, canWithdraw: dto.canWithdraw, withdrawalBlockReason: dto.withdrawalBlockReason, }); } /** * Withdraw from league wallet */ async withdraw(leagueId: string, amount: number, currency: string, seasonId: string, destinationAccount: string): Promise { if (!this.submitBlocker.canExecute() || !this.throttle.canExecute()) { throw new Error('Request blocked due to rate limiting'); } this.submitBlocker.block(); this.throttle.block(); try { const request: WithdrawRequestDTO = { amount, currency, seasonId, destinationAccount, }; return await this.apiClient.withdrawFromLeagueWallet(leagueId, request); } finally { this.submitBlocker.release(); } } }