public async Task <ClientWalletList> GetWalletsByClient(JetClientIdentity clientId)
        {
            var entity = _reader.Get(ClientWalletNoSqlEntity.GeneratePartitionKey(clientId.BrokerId),
                                     ClientWalletNoSqlEntity.GenerateRowKey(clientId.ClientId));

            if (entity != null)
            {
                return new ClientWalletList()
                       {
                           Wallets = entity.Wallets
                       }
            }
            ;

            var wallets = await _grpcService.GetWalletsByClient(clientId);

            return(wallets);
        }
示例#2
0
        private async Task <ChangeBalanceGrpcResponse> ExecuteInternalTransferAsync(string transactionId,
                                                                                    string fromClientId, string fromWalletId, string toWalletId, decimal amount, string assetSymbol, string assetBrokerId)

        {
            var asset = _assetsDictionaryClient.GetAssetById(new AssetIdentity()
            {
                BrokerId = assetBrokerId,
                Symbol   = assetSymbol
            });

            //todo: убрать тут передачу бренда в принципе
            var wallets =
                await _clientWalletService.GetWalletsByClient(
                    new JetClientIdentity(assetBrokerId, "brand-to-remove", fromClientId));

            var wallet = wallets?.Wallets.FirstOrDefault(e => e.WalletId == fromWalletId);

            if (asset == null)
            {
                return(new ChangeBalanceGrpcResponse()
                {
                    TransactionId = transactionId,
                    Result = false,
                    ErrorMessage = "Cannot transfer funds, asset do not found",
                    ErrorCode = ChangeBalanceGrpcResponse.ErrorCodeEnum.AssetDoNotFound
                });
            }

            if (!asset.IsEnabled)
            {
                return(new ChangeBalanceGrpcResponse()
                {
                    TransactionId = transactionId,
                    Result = false,
                    ErrorMessage = "Cannot transfer funds, asset is Disabled.",
                    ErrorCode = ChangeBalanceGrpcResponse.ErrorCodeEnum.AssetIsDisabled
                });
            }

            if (wallet == null)
            {
                return(new ChangeBalanceGrpcResponse()
                {
                    TransactionId = transactionId,
                    Result = false,
                    ErrorMessage = "Cannot transfer funds, wallet do not found.",
                    ErrorCode = ChangeBalanceGrpcResponse.ErrorCodeEnum.WalletDoNotFound
                });
            }

            var balanceChangeRequest = new ExBalanceUpdateInstruction
            {
                OperationId = transactionId,
                EventType   = "Internal Transfer",
                Timestamp   = DateTime.UtcNow,
                Updates     = new List <ExBalanceUpdateInstruction.BalanceUpdate>
                {
                    new ExBalanceUpdateInstruction.BalanceUpdate
                    {
                        WalletId      = fromWalletId,
                        AssetId       = asset.Symbol,
                        Number        = 1,
                        Amount        = -(decimal)amount,
                        ReserveAmount = 0
                    },
                    new ExBalanceUpdateInstruction.BalanceUpdate
                    {
                        WalletId      = toWalletId,
                        AssetId       = asset.Symbol,
                        Number        = 2,
                        Amount        = (decimal)amount,
                        ReserveAmount = 0
                    }
                }
            };
            var balanceResponse = await _balanceOperationService.ProcessBalanceUpdate(balanceChangeRequest);

            _logger.LogInformation("BalanceService call. Request: {requestText}. Response: {responseText}",
                                   JsonConvert.SerializeObject(balanceChangeRequest), JsonConvert.SerializeObject(balanceResponse));

            if (balanceResponse.Result != ExBalanceUpdate.BalanceUpdateResult.Ok)
            {
                return(new ChangeBalanceGrpcResponse()
                {
                    TransactionId = transactionId,
                    Result = false,
                    ErrorMessage = $"Cannot transfer funds, error: {balanceResponse.Result}",
                    ErrorCode = balanceResponse.Result == ExBalanceUpdate.BalanceUpdateResult.LowBalance
                        ? ChangeBalanceGrpcResponse.ErrorCodeEnum.LowBalance
                        : ChangeBalanceGrpcResponse.ErrorCodeEnum.Error
                });
            }

            return(new ChangeBalanceGrpcResponse()
            {
                TransactionId = transactionId,
                Result = true,
                ErrorCode = ChangeBalanceGrpcResponse.ErrorCodeEnum.Ok
            });
        }
        public async Task <AuthorizationResponse> AuthorizationAsync(AuthorizationRequest request)
        {
            using var activity = MyTelemetry.StartActivity("Authorization base on session token");

            if (string.IsNullOrEmpty(request.Token) ||
                string.IsNullOrEmpty(request.BrandId) ||
                string.IsNullOrEmpty(request.BrokerId))
            {
                return(new AuthorizationResponse()
                {
                    Result = false
                });
            }

            var(result, baseToken) = TokensManager.ParseBase64Token <JetWalletToken>(request.Token, AuthConst.GetSessionEncodingKey(), DateTime.UtcNow);

            if (result != TokenParseResult.Ok)
            {
                activity.SetStatus(Status.Error);
                return(new AuthorizationResponse()
                {
                    Result = false
                });
            }

            if (!string.IsNullOrEmpty(baseToken.SessionRootId))
            {
                _logger.LogWarning("Cannot Authorization session base on token with existing RootSession: {rootIdText}", baseToken.SessionRootId);
                activity.SetStatus(Status.Error);
                return(new AuthorizationResponse()
                {
                    Result = false
                });
            }

            var token = new JetWalletToken()
            {
                Id            = baseToken.Id,
                Expires       = DateTime.UtcNow.AddMinutes(_settings.SessionLifeTimeMinutes),
                SessionRootId = Guid.NewGuid().ToString("N"),
                SessionId     = Guid.NewGuid().ToString("N"),
                BrandId       = request.BrandId,
                BrokerId      = request.BrokerId
            };

            token.Id.AddToActivityAsTag("clientId");
            token.BrokerId.AddToActivityAsTag("brokerId");
            token.BrandId.AddToActivityAsTag("brandId");

            token.SessionRootId.AddToActivityAsTag("sessionRootId");


            var clientIdentity = new JetClientIdentity(request.BrokerId, request.BrandId, baseToken.Id);
            var response       = await _clientRegistrationService.GetOrRegisterClientAsync(clientIdentity);

            if (response.Result != ClientRegistrationResponse.RegistrationResult.Ok)
            {
                _logger.LogError("Cannot register client. Client already register with another brand. BrokerId/BrandId/ClientId: {brokerId}/{brandId}/{clientId}",
                                 clientIdentity.BrokerId, clientIdentity.BrandId, clientIdentity.ClientId);

                activity.SetStatus(Status.Error);
                return(new AuthorizationResponse()
                {
                    Result = false
                });
            }

            ClientWallet wallet  = null;
            var          wallets = await _clientWalletService.GetWalletsByClient(clientIdentity);

            if (string.IsNullOrEmpty(request.WalletId))
            {
                wallet = wallets?.Wallets?.FirstOrDefault(w => w.IsDefault) ?? wallets?.Wallets?.FirstOrDefault();
            }
            else
            {
                wallet = wallets?.Wallets?.FirstOrDefault(w => w.WalletId == request.WalletId);
            }

            if (wallet == null)
            {
                request.WalletId.AddToActivityAsTag("walletId");
                _logger.LogWarning("Cannot Authorization session, wallet do not found. WalletId {walletId}. ClientId: {clientId}", request.WalletId, token.Id);
                activity.SetStatus(Status.Error);
                return(new AuthorizationResponse()
                {
                    Result = false
                });
            }

            token.WalletId = wallet.WalletId;
            token.WalletId.AddToActivityAsTag("walletId");

            var session = token.IssueTokenAsBase64String(AuthConst.GetSessionEncodingKey());

            var dueData   = DateTime.UtcNow.AddHours(_settings.RootSessionLifeTimeHours);
            var publicKey = MyRsa.ReadPublicKeyFromPem(request.PublicKeyPem);

            var entity = SpotSessionNoSql.Create(request.BrokerId, request.BrandId, baseToken.Id, dueData, publicKey, token.SessionRootId);
            await _writer.InsertOrReplaceAsync(entity);

            await _sessionAuditService.NewSessionAudit(baseToken, token, request.UserAgent, request.Ip);

            _logger.LogInformation("Session Authorization is success. RootSessionId: {rootIdText}. ClientId:{clientId}", token.SessionRootId, token.ClientId());

            return(new AuthorizationResponse()
            {
                Result = true,
                Token = session
            });
        }