Ejemplo n.º 1
0
        public async Task SetEarnProgramByWalletAsync(SetEarnProgramByWalletRequest request)
        {
            using var activity = MyTelemetry.StartActivity("SetEarnProgramByWalletAsync");
            request.AddToActivityAsJsonTag("request");

            _logger.LogWarning("Change EnableEarnProgram. Wallet: {walletId}, EnableEarnProgram: {flag}", request.WalletId, request.EnableEarnProgram);

            await using var ctx = new DatabaseContext(_dbContextOptionsBuilder.Options);

            var walletEntity = ctx.ClientWallet.FirstOrDefault(e => e.WalletId == request.WalletId);

            if (walletEntity != null)
            {
                var oldWallet = (ClientWallet)walletEntity.Clone();

                walletEntity.EnableEarnProgram = request.EnableEarnProgram;
                await ctx.SaveChangesAsync();


                await UpdateCache(
                    walletEntity.ClientId,
                    walletEntity.BrokerId,
                    new List <ClientWalletEntity> {
                    walletEntity
                });

                await _publisher.PublishAsync(new ClientWalletUpdateMessage()
                {
                    OldWallet = ClientWallet.Create(oldWallet),
                    NewWallet = ClientWallet.Create(walletEntity)
                });
            }
        }
Ejemplo n.º 2
0
        public async Task <ClientWalletList> GetWalletsByClient(JetClientIdentity clientId)
        {
            _logger.LogInformation("Request wallets for Broker/Brand/Client: {brokerId}/{clientId}",
                                   clientId.BrokerId, clientId.ClientId);

            clientId.BrokerId.AddToActivityAsTag("brokerId");
            clientId.ClientId.AddToActivityAsTag("clientId");

            _logger.LogInformation("Request to get wallets. clientId: {clientText}", JsonSerializer.Serialize(clientId));

            using var activity  = MyTelemetry.StartActivity($"Use DB context {DatabaseContext.Schema}")?.AddTag("db-schema", DatabaseContext.Schema);
            await using var ctx = new DatabaseContext(_dbContextOptionsBuilder.Options);

            var list = await ctx.ClientWallet.Where(e => e.BrokerId == clientId.BrokerId && e.ClientId == clientId.ClientId)
                       .ToListAsync();

            if (!list.Any())
            {
                using var _ = MyTelemetry.StartActivity($"Create a new wallet");
                var wallet = new ClientWallet()
                {
                    IsDefault         = true,
                    IsInternal        = false,
                    EnableEarnProgram = true,
                    Name             = "spot",
                    WalletId         = GenerateDefaultWalletId(clientId.ClientId),
                    CreatedAt        = DateTime.UtcNow,
                    BaseAsset        = Program.Settings.BaseAssetSymbol,
                    EnableUseTestNet = Program.Settings.EnableUseTestNetByDefault
                };

                wallet.WalletId.AddToActivityAsTag("walletId");

                var entity = new ClientWalletEntity(clientId.BrokerId, clientId.ClientId, wallet);

                await ctx.UpsetAsync(new [] { entity });

                list.Add(entity);

                _logger.LogInformation("Created default wallet. Wallet: {walletJson}", JsonSerializer.Serialize(entity));
            }

            foreach (var clientWalletEntity in list.Where(e => string.IsNullOrWhiteSpace(e.BaseAsset)))
            {
                clientWalletEntity.BaseAsset = Program.Settings.BaseAssetSymbol;
            }

            await UpdateCache(clientId.ClientId, clientId.BrokerId, list);

            return(new ClientWalletList()
            {
                Wallets = list.Select(e => new ClientWallet()
                {
                    IsDefault = e.IsDefault, Name = e.Name,
                    WalletId = e.WalletId, CreatedAt = e.CreatedAt, BaseAsset = e.BaseAsset,
                    EnableUseTestNet = e.EnableUseTestNet, IsInternal = e.IsInternal, EnableEarnProgram = e.EnableEarnProgram
                }).ToList()
            });
        }
Ejemplo n.º 3
0
        public async Task <SetBaseAssetResponse> SetBaseAssetAsync(SetBaseAssetRequest request)
        {
            using var activity = MyTelemetry.StartActivity($"Set base asset request");
            request.AddToActivityAsJsonTag("request");
            request.ClientId.ClientId.AddToActivityAsTag("clientId");
            request.ClientId.BrokerId.AddToActivityAsTag("brokerId");
            request.WalletId.AddToActivityAsTag("WalletId");

            if (string.IsNullOrEmpty(request.ClientId?.ClientId) ||
                string.IsNullOrEmpty(request.ClientId?.BrokerId) ||
                string.IsNullOrEmpty(request.WalletId) ||
                string.IsNullOrWhiteSpace(request.BaseAsset))
            {
                var message = "Cannot set base asset. BadRequest.";
                _logger.LogError(message);
                return(new SetBaseAssetResponse()
                {
                    Success = false,
                    ErrorMessage = message
                });
            }
            await using var ctx = new DatabaseContext(_dbContextOptionsBuilder.Options);
            var walletEntity = ctx.ClientWallet.FirstOrDefault(e => e.WalletId == request.WalletId);

            if (walletEntity == null)
            {
                var message = $"Wallet not found. WalletId: {request.WalletId}";
                _logger.LogError(message);
                return(new SetBaseAssetResponse()
                {
                    Success = false,
                    ErrorMessage = message
                });
            }

            var oldWallet = (ClientWallet)walletEntity.Clone();

            walletEntity.BaseAsset = request.BaseAsset;
            await ctx.SaveChangesAsync();

            await UpdateCache(request.ClientId.ClientId, request.ClientId.BrokerId, new List <ClientWalletEntity> {
                walletEntity
            });

            await _publisher.PublishAsync(new ClientWalletUpdateMessage()
            {
                OldWallet = ClientWallet.Create(oldWallet),
                NewWallet = ClientWallet.Create(walletEntity)
            });

            return(new SetBaseAssetResponse()
            {
                Success = true
            });
        }
Ejemplo n.º 4
0
        public ClientWalletEntity(string brokerId, string clientId, ClientWallet wallet)
        {
            BrokerId = brokerId;
            ClientId = clientId;

            WalletId          = wallet.WalletId;
            IsDefault         = wallet.IsDefault;
            Name              = wallet.Name;
            CreatedAt         = wallet.CreatedAt;
            BaseAsset         = wallet.BaseAsset;
            EnableUseTestNet  = wallet.EnableUseTestNet;
            EnableEarnProgram = wallet.EnableEarnProgram;
        }
Ejemplo n.º 5
0
        public async Task <CreateWalletResponse> CreateWalletAsync(CreateWalletRequest request)
        {
            using var _ = MyTelemetry.StartActivity($"Create a new wallet");
            request.Name.AddToActivityAsTag("wallet-name");
            request.ClientId.ClientId.AddToActivityAsTag("clientId");
            request.ClientId.BrokerId.AddToActivityAsTag("brokerId");

            _logger.LogInformation("Request to create wallet. Request: {requestText}", JsonSerializer.Serialize(request));

            if (string.IsNullOrEmpty(request.ClientId?.ClientId) ||
                string.IsNullOrEmpty(request.ClientId?.BrokerId) ||
                string.IsNullOrEmpty(request.Name) ||
                string.IsNullOrWhiteSpace(request.BaseAsset))
            {
                _logger.LogError("Cannot create wallet. BadRequest.");
                return(new CreateWalletResponse()
                {
                    Success = false,
                    ErrorMessage = "Bad request"
                });
            }

            var index = DateTimeOffset.UtcNow.ToUnixTimeSeconds();

            var wallet = new ClientWallet()
            {
                IsDefault         = false,
                IsInternal        = false,
                EnableEarnProgram = true,
                Name             = request.Name,
                WalletId         = $"{Program.Settings.WalletPrefix}{request.ClientId.ClientId}-{index}",
                CreatedAt        = DateTime.UtcNow,
                BaseAsset        = request.BaseAsset,
                EnableUseTestNet = Program.Settings.EnableUseTestNetByDefault
            };

            wallet.WalletId.AddToActivityAsTag("walletId");

            var entity = new ClientWalletEntity(request.ClientId.BrokerId, request.ClientId.ClientId, wallet);

            await using var ctx = new DatabaseContext(_dbContextOptionsBuilder.Options);
            await ctx.ClientWallet.AddAsync(entity);

            await ctx.SaveChangesAsync();

            var list = await ctx.ClientWallet
                       .Where(e => e.ClientId == request.ClientId.ClientId && e.BrokerId == request.ClientId.BrokerId)
                       .ToListAsync();

            await UpdateCache(request.ClientId.ClientId, request.ClientId.BrokerId, list);

            _logger.LogInformation("Wallet created. Wallet: {walletJson}", JsonSerializer.Serialize(entity));

            return(new CreateWalletResponse()
            {
                Success = true,
                Name = request.Name,
                WalletId = wallet.WalletId,
                CreatedAt = wallet.CreatedAt
            });
        }
        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
            });
        }