using Managing.Application.Abstractions.Repositories; using Managing.Application.Abstractions.Services; using Managing.Common; using Managing.Domain.Accounts; using Managing.Domain.Users; using Microsoft.Extensions.Logging; namespace Managing.Application.Users; public class UserService : IUserService { private readonly IEvmManager _evmManager; private readonly IUserRepository _userRepository; private readonly IAccountService _accountService; private readonly ILogger _logger; private string[] authorizedAddresses = [ "0x6781920674dA695aa5120d95D80c4B1788046806", // Macbook "0xA2B43AFF0992a47838DF2e6099A8439981f0B717", // Phone "0xAD4bcf258852e9d47E580798d312E1a52D59E721", // Razil "0xAd6D6c80910096b40e45690506a9f1052e072dCB", // Teru "0x309b9235edbe1C6f840816771c6C21aDa6c275EE", // Cowchain "0x23AA99254cfaA2c374bE2bA5B55C68018cCdFCb3", // Local optiflex "0x932167388dD9aad41149b3cA23eBD489E2E2DD78", // Embedded wallet "0x66CB57Fe3f53cE57376421106dFDa2D39186cBd0", // Embedded wallet optiflex "0x7baBf95621f22bEf2DB67E500D022Ca110722FaD", // DevCowchain "0xc8bC497534d0A43bAb2BBA9BA94d46D9Ddfaea6B" // DevCowchain2 ]; public UserService( IEvmManager evmManager, IUserRepository userRepository, IAccountService accountService, ILogger logger) { _evmManager = evmManager; _userRepository = userRepository; _accountService = accountService; _logger = logger; } public async Task Authenticate(string name, string address, string message, string signature) { var recoveredAddress = _evmManager.VerifySignature(signature, message); // Verify message if (!message.Equals("KaigenTeamXCowchain")) { _logger.LogWarning($"Message {message} not starting with KaigenTeamXCowchain"); throw new Exception( $"Message not good : {message} - Address : {address} - User : {name} - Signature : {signature}"); } // if (!authorizedAddresses.Contains(recoveredAddress)) // { // _logger.LogWarning($"Address {recoveredAddress} not authorized"); // throw new Exception("Address not authorized"); // } if (recoveredAddress == null || !recoveredAddress.Equals(address)) { _logger.LogWarning($"Address {recoveredAddress} not corresponding"); throw new Exception("Address not corresponding"); } // Check if account exist var user = await _userRepository.GetUserByNameAsync(name); if (user != null) { if (!user.Name.Equals(name)) throw new Exception("Name not corresponding"); // User and account found user.Accounts = _accountService.GetAccountsByUser(user).ToList(); // Check if recoverred address owns the account var account = user.Accounts.FirstOrDefault(a => a.Key.Equals(recoveredAddress)); if (account == null) { throw new Exception("Account not found"); } return user; } else { // First login user = new User { Name = name }; await _userRepository.InsertUserAsync(user); // Create embedded account to authenticate user var account = await _accountService.CreateAccount(user, new Account { Name = $"{name}-embedded", Key = recoveredAddress, Exchange = Enums.TradingExchanges.Evm, Type = Enums.AccountType.Privy }); user.Accounts = new List() { account }; // Update user with the new account await _userRepository.UpdateUser(user); } return user; } public User GetUser(string name) { return _userRepository.GetUserByNameAsync(name).Result; } 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; } public async Task UpdateAgentName(User user, string agentName) { // Check if agent name is already used var existingUser = await _userRepository.GetUserByAgentNameAsync(agentName); if (existingUser != null) { throw new Exception("Agent name already used"); } user.AgentName = agentName; await _userRepository.UpdateUser(user); return user; } }