public async ValueTask <NewCredentialsGrpcResponse> RegisterAsync(RegisterRequest request)
        {
            try
            {
                await using var ctx = DatabaseContext.Create(_dbContextOptionsBuilder);

                var disabledCountries = Program.Settings.DisabledCountries.Split("|");

                if (disabledCountries.Contains(request.PersonalData.CountryOfRegistration))
                {
                    return(NewCredentialsGrpcResponse.Create(null, ResponseStatuses.CountryRestricted));
                }

                if (request.ExternalData == null)
                {
                    request.ExternalData = new List <KeyValueModel>();
                }

                if (request.Utm == null)
                {
                    request.Utm = new List <KeyValueModel>();
                }

                var email = request.AuthCredentials.Email.ToLower();

                var authResponse = await _authService.GetIdByEmailAsync(new GetIdGrpcRequest()
                {
                    Brand = request.BrandId,
                    Email = email
                });

                string platformType = request.ExternalData?
                                      .FirstOrDefault(x => x.Key == "platformType")?.Value
                                      ?? MyJetWallet.Domain.PlatformType.Spot.ToString();

                if (authResponse.TraderId != null)
                {
                    if (request.ExternalData != null)
                    {
                        var processIdRequest = request.ExternalData
                                               .FirstOrDefault(x => x.Key == "processId");
                        if (processIdRequest != null)
                        {
                            var traderExternalDataProcessId =
                                await ctx.ExternalDataEntities.FirstOrDefaultAsync(t => t.TraderId == authResponse.TraderId && t.Key == "processId");

                            if (traderExternalDataProcessId != null && traderExternalDataProcessId.Value == processIdRequest.Value)
                            {
                                return new NewCredentialsGrpcResponse
                                       {
                                           TraderId = authResponse.TraderId,
                                           Status   = ResponseStatuses.Successful
                                       }
                            }
                            ;
                        }

                        await _failPublisher.PublishAsync(
                            new ClientRegisterFailAlreadyExistsMessage
                        {
                            TraderId     = authResponse.TraderId,
                            IpAddress    = request.PersonalData.IpOfRegistration,
                            UserAgent    = request.AdditionalData.UserAgent,
                            PlatformType = platformType
                        });

                        return(new NewCredentialsGrpcResponse
                        {
                            //todo: use local constant
                            TraderId = Guid.Empty.ToString("N"),
                            Status = ResponseStatuses.Successful
                        });
                    }

                    return(NewCredentialsGrpcResponse.Create(null, ResponseStatuses.ClientAlreadyExists));
                }

                var emailHash  = email.EncodeToSha1();
                var isInternal = Regex.IsMatch(email, Program.Settings.InternalAccountPatterns);

                var auth = AuthenticationCredentialsEntity.Create(
                    email,
                    request.AuthCredentials.Hash,
                    request.AuthCredentials.Salt,
                    Program.AuthEncodingKey,
                    Program.AuthEncodingInitVector,
                    request.BrandId
                    );

                var personalData = new PersonalDataGrpcModel()
                {
                    Id                    = auth.Id,
                    Email                 = email,
                    City                  = request.PersonalData.City,
                    Phone                 = request.PersonalData.Phone,
                    Sex                   = request.PersonalData.Sex,
                    FirstName             = request.PersonalData.FirstName,
                    LastName              = request.PersonalData.LastName,
                    PostalCode            = request.PersonalData.PostalCode,
                    CountryOfCitizenship  = request.PersonalData.CountryOfCitizenship,
                    CountryOfResidence    = request.PersonalData.CountryOfResidence,
                    DateOfBirth           = request.PersonalData.DateOfBirth,
                    KYC                   = PersonalDataKYCEnum.NotVerified,
                    Confirm               = request.PersonalData.Confirm,
                    Address               = request.PersonalData.Address,
                    USCitizen             = request.PersonalData.USCitizen,
                    IpOfRegistration      = request.PersonalData.IpOfRegistration,
                    CountryOfRegistration = request.PersonalData.CountryOfRegistration,
                    CreatedAt             = DateTime.UtcNow,
                    PhoneCode             = request.PersonalData.PhoneCode,
                    PhoneNumber           = request.PersonalData.PhoneNumber,
                    PhoneIso              = request.PersonalData.PhoneIso,
                    // EmailHash = emailHash,
                    // IsInternal = isInternal,
                    // EmailGroupId = emailGroup.Id,
                    BrandId      = request.BrandId,
                    PlatformType = platformType,
                    AuditLog     = new AuditLogGrpcContract
                    {
                        TraderId    = auth.Id,
                        Ip          = request.AuditLog.Ip,
                        ServiceName = "Service.Registration"
                    }
                };

                await _personalData.CreateRecordAsync(personalData);

                await _authService.RegisterCredentialsAsync(new AuthCredentialsGrpcModel
                {
                    EncodedEmail = auth.Email,
                    Hash         = auth.Hash,
                    Salt         = auth.Salt,
                    Brand        = auth.Brand,
                    Id           = auth.Id,
                });

                ctx.ExternalDataEntities.UpsertRange(request.ExternalData.Select(x =>
                                                                                 ExternalDataEntity.Create(auth.Id, x.Key, x.Value)));

                request.AuditLog.TraderId    = auth.Id;
                request.AuditLog.UpdatedData = JsonConvert.SerializeObject(personalData);
                request.AuditLog.After       = request.AuditLog.UpdatedData;

                await _auditLogService.RegisterEventAsync(request.AuditLog);

                await ctx.RegisterLogModelDbModels.AddAsync(request.CreateRegLogModel(auth.Id));

                await ctx.SaveChangesAsync();

                await _registerPublisher.PublishAsync(new ClientRegisterMessage
                {
                    TraderId  = auth.Id,
                    IpAddress = request?.PersonalData?.IpOfRegistration,
                    UserAgent = request?.AdditionalData?.UserAgent,
                });

                _logger.LogInformation("User with id {userId} and email {maskedEmail} completed registration", auth.Id, auth.Email);

                return(new NewCredentialsGrpcResponse
                {
                    TraderId = auth.Id,
                    Status = ResponseStatuses.Successful
                });
            }
            catch (Exception exception)
            {
                _logger.LogError(exception, exception.Message);
                return(NewCredentialsGrpcResponse.Create(null, ResponseStatuses.SystemError));
            }
        }