public async Task <ClientWalletEntity> RegisterOrGetDefaultWallets(ClientIdentity client)
        {
            var existWallet = await _walletsWriter.TryGetAsync(ClientWalletEntity.GetPartitionKey(client.TenantId), ClientWalletEntity.GetRowKey(client.ClientId));

            if (existWallet != null)
            {
                return(existWallet);
            }

            bool result;

            do
            {
                var walletId = GenerateWalletId();

                var entity = ClientWalletEntity.Generate(client.TenantId, client.ClientId);
                entity.WalletId = walletId;
                entity.Type     = TradingWalletType.Trading;
                entity.Client   = client;

                var indexById = ClientWalletIndexByIdEntity.Generate(entity.Client.TenantId, walletId, entity.Client.ClientId);
                result = await _walletsByIdWriter.TryInsertAsync(indexById);

                if (result)
                {
                    await _walletsWriter.InsertOrReplaceAsync(entity);

                    return(entity);
                }

                _logger.LogInformation("Cannot insert new wallet with id={WalletId}. ClientId={clientId}, TenantId={TenamtId}", entity.WalletId, entity.Client.TenantId, entity.Client.ClientId);
            } while (true);
        }
        public async Task <ClientIdentity> Login(string tenantId, string username, string password)
        {
            var data = await _dataWriter.TryGetAsync(AuthDataEntity.GeneratePartitionKey(), AuthDataEntity.GenerateRowKey(tenantId, username));

            if (data.PasswordHash == password.ToSha256().ToBase64())
            {
                var indexEntity = AuthDataIndexByIdEntity.Generate(data.TenantId, data.ClientId, data.Email);
                await _indexDataWriter.InsertOrReplaceAsync(indexEntity);

                return(new ClientIdentity()
                {
                    ClientId = data.ClientId,
                    TenantId = data.TenantId
                });
            }

            return(null);
        }
        public async Task <bool> CheckPin(string tenantId, long clientId, string pinHash)
        {
            var indexEntity = await _indexDataWriter.TryGetAsync(AuthDataIndexByIdEntity.GeneratePartitionKey(tenantId), AuthDataIndexByIdEntity.GenerateRowKey(clientId));

            if (indexEntity == null)
            {
                return(false);
            }

            var entity = await _dataWriter.TryGetAsync(AuthDataEntity.GeneratePartitionKey(), AuthDataEntity.GenerateRowKey(indexEntity.TenantId, indexEntity.Email));

            if (entity == null || entity.PinHash != pinHash)
            {
                return(false);
            }

            return(true);
        }
        private async Task <ClientProfileEntity> CreateClientProfile(string tenantId, long clientId)
        {
            var exist = await _clientProfileDataWriter.TryGetAsync(ClientProfileEntity.GeneratePartitionKey(tenantId), ClientProfileEntity.GenerateRowKey(clientId));

            if (exist != null)
            {
                return(exist);
            }

            var baseAsset = await _marketDataService.GetDefaultBaseAsset(tenantId);

            var profile = new ClientProfileEntity()
            {
                PartitionKey = ClientProfileEntity.GeneratePartitionKey(tenantId),
                RowKey       = ClientProfileEntity.GenerateRowKey(clientId),
                TenantId     = tenantId,
                ClientId     = clientId,
                BaseAssetId  = baseAsset.Symbol
            };

            await _clientProfileDataWriter.InsertOrReplaceAsync(profile);

            return(profile);
        }