using Managing.Application.Abstractions.Repositories; using Managing.Application.Abstractions.Services; using Managing.Domain.Accounts; using Managing.Domain.Users; namespace Managing.Application.Users; public class UserService : IUserService { private readonly IEvmManager _evmManager; private readonly IUserRepository _userRepository; private readonly IAccountService _accountService; private string[] authorizedAddresses = ["0x6781920674dA695aa5120d95D80c4B1788046806", "0xA2B43AFF0992a47838DF2e6099A8439981f0B717", "0xAD4bcf258852e9d47E580798d312E1a52D59E721", "0xAd6D6c80910096b40e45690506a9f1052e072dCB"]; public UserService( IEvmManager evmManager, IUserRepository userRepository, IAccountService accountService) { _evmManager = evmManager; _userRepository = userRepository; _accountService = accountService; } public async Task Authenticate(string name, string address, string message, string signature) { var recoveredAddress = _evmManager.VerifySignature(signature, message); if (!authorizedAddresses.Contains(recoveredAddress)) throw new Exception("Address not authorized"); if (recoveredAddress == null || !recoveredAddress.Equals(address)) throw new Exception("Address not corresponding"); // Check if account exist var account = await _accountService.GetAccountByKey(recoveredAddress, true, false); var user = await _userRepository.GetUserByNameAsync(name); if (account != null && user != null) { // User and account found user.Accounts = _accountService.GetAccountsByUser(user).ToList(); if (!user.Name.Equals(name)) throw new Exception("Name not corresponding"); return user; } else { // No account and no account = new Account { Name = $"Auth-{new Random().Next(1, 99)}", Key = recoveredAddress, Secret = "", Exchange = Common.Enums.TradingExchanges.Evm, Type = Common.Enums.AccountType.Auth, }; if (user != null) { _ = await _accountService.CreateAccount(user, account); user.Accounts = _accountService.GetAccountsByUser(user).ToList(); return user; } else { // No user found, we create one // Create user if not existing user = new User() { Name = name, Accounts = new List { account }, }; _ = await _accountService.CreateAccount(user, account); await _userRepository.InsertUserAsync(user); } } return user; } public async Task GetUserByAddressAsync(string address) { var account = await _accountService.GetAccountByKey(address, true, false); var user = await _userRepository.GetUserByNameAsync(account.User.Name); user.Accounts = _accountService.GetAccountsByUser(user).ToList(); return user; } }