public async Task <CreateInvitation> CreateInvitationAsync([FromBody] CreateInvitationRequest request)
        {
            var(auth, tenantId, adminId, adminEmail) = Authorize();

            if (!auth)
            {
                return(new CreateInvitation());
            }

            var invite = ValidatorLinkEntity.Generate(tenantId, Guid.NewGuid().ToString("N"));

            invite.InvitationToken     = Guid.NewGuid().ToString("N") + Guid.NewGuid().ToString("N") + Guid.NewGuid().ToString("N");
            invite.Name                = request.Name;
            invite.Position            = request.Position;
            invite.Description         = request.Description;
            invite.CreatedAt           = DateTime.UtcNow;
            invite.CreatedByAdminId    = adminId;
            invite.CreatedByAdminEmail = adminEmail;
            await _validationWriter.InsertOrReplaceAsync(invite);


            _logger.LogInformation("Invitation Created. TenantId: {TenantId}; AdminId: {AdminId}", tenantId, adminId);

            var resp = new CreateInvitation()
            {
                TenantId        = invite.TenantId,
                InvitationToken = invite.InvitationToken,
                Name            = invite.Name,
                Position        = invite.Position,
                Description     = invite.Description
            };

            return(resp);
        }
示例#2
0
        public async Task InsertOrReplaceCountry(CountryModel country)
        {
            await using var context = new DatabaseContext(_dbContextOptionsBuilder.Options);
            await context.UpsertAsync(new[] { country });

            await _cache.InsertOrReplaceAsync(KycCountryNoSqlEntity.Create(country));
        }
        public async Task SetBaseAssetToClientProfile(string tenantId, long clientId, string baseAssetId)
        {
            var profile = await GetClientProfile(tenantId, clientId);

            profile.BaseAssetId = baseAssetId;

            await _clientProfileDataWriter.InsertOrReplaceAsync(profile);
        }
示例#4
0
        public async Task <(SessionEntity, string)> CreateVerifiedSessionAsync(string tenantId, long clientId, string publicKey = null)
        {
            var(session, token) = SessionEntity.Generate(_sessionConfig.ExpirationTimeInMins);
            session.Verified    = true;
            session.Sms         = true;
            session.Pin         = true;
            session.PublicKey   = publicKey;

            session.ClientId = clientId;
            session.TenantId = tenantId;

            await _sessionsWriter.InsertOrReplaceAsync(session);

            return(session, token);
        }
示例#5
0
        private async Task ProcessQuoteAsync(QuoteMessage quote)
        {
            var entity = await _priceWriter.GetAsync(Price.GetPk(), quote.AssetPair);

            var writerTask = Task.CompletedTask;

            if (entity != null)
            {
                if (quote.IsBuy)
                {
                    entity.Bid = (decimal)quote.Price;
                }
                else
                {
                    entity.Ask = (decimal)quote.Price;
                }

                entity.UpdatedDt = quote.Timestamp;

                writerTask = _priceWriter.InsertOrReplaceAsync(entity);
            }

            await Task.WhenAll(
                _database.HashSetAsync(RedisService.GetMarketDataKey(quote.AssetPair),
                                       quote.IsBuy ? nameof(MarketSlice.Bid) : nameof(MarketSlice.Ask),
                                       quote.Price.ToString(CultureInfo.InvariantCulture)),
                writerTask);
        }
        private async Task DoProcess()
        {
            List <BidAsk> buffer;

            lock (_gate)
            {
                if (!_buffer.Any())
                {
                    return;
                }

                buffer  = _buffer;
                _buffer = new List <BidAsk>(128);
            }

            var taskList = new List <Task>();

            foreach (var group in buffer.GroupBy(e => e.Id))
            {
                var last = @group.OrderByDescending(e => e.DateTime).First();
                var task = _writer.InsertOrReplaceAsync(BidAskNoSql.Create(last));
                taskList.Add(task.AsTask());

                _logger.LogInformation("Quote: {brokerId}:{symbol} {bid} | {ask} | {timestampText}", last.LiquidityProvider, last.Id, last.Bid, last.Ask, last.DateTime.ToString("O"));
            }

            if (taskList.Any())
            {
                await Task.WhenAll(taskList);
            }
        }
示例#7
0
        public override async Task <CreateApprovalRequestResponse> CreateApprovalRequest(CreateApprovalRequestRequest request, ServerCallContext context)
        {
            var tenantId = request.TenantId;
            var vaultId  = context.GetVaultId();

            foreach (var validatorRequest in request.ValidatorRequests)
            {
                var entity = ApprovalRequestMyNoSqlEntity.Generate(validatorRequest.ValidatorId, request.TransferSigningRequestId);
                entity.TenantId   = tenantId;
                entity.MessageEnc = validatorRequest.TransactionDetailsEncBase64;
                entity.SecretEnc  = validatorRequest.SecretEncBase64;
                entity.IvNonce    = validatorRequest.IvNonce;
                entity.IsOpen     = true;
                entity.VaultId    = vaultId;

                await _dataWriter.InsertOrReplaceAsync(entity);

                await _pushNotificator.SendPushNotifications(entity);

                _logger.LogInformation("CreateApprovalRequest processed. TransferSigningRequestId={TransferSigningRequestId}; TenantId={TenantId}; VaultId={VaultId}; ValidatorId={ValidatorId}", request.TransferSigningRequestId, tenantId, vaultId, validatorRequest.ValidatorId);
            }

            //await _dataWriter.BulkInsertOrReplaceAsync(list, DataSynchronizationPeriod.Immediately);

            var resp = new CreateApprovalRequestResponse();

            return(resp);
        }
        public async Task UpdateBitGoWallet(BitGoWallet wallet)
        {
            using var action = MyTelemetry.StartActivity("Update BitGo wallet");
            wallet.ApiKey    = _encryptionService.Encrypt(wallet.ApiKey);
            try
            {
                _logger.LogInformation("Update BitGoWallet: {jsonText}",
                                       JsonConvert.SerializeObject(wallet, new ApiKeyHiddenJsonConverter(typeof(BitGoWallet))));

                wallet.UpdatedDate = DateTime.Now;
                ValidateWallet(wallet);

                var entity = BitGoWalletNoSqlEntity.Create(wallet);

                var existingItem = await _writer.GetAsync(entity.PartitionKey, entity.RowKey);

                if (existingItem == null)
                {
                    throw new Exception("Cannot update BitGo wallet. Do not exist");
                }

                await _writer.InsertOrReplaceAsync(entity);

                _logger.LogInformation("Updated BitGo wallet: {jsonText}",
                                       JsonConvert.SerializeObject(wallet, new ApiKeyHiddenJsonConverter(typeof(BitGoWallet))));
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Cannot update BitGo wallet: {requestJson}",
                                 JsonConvert.SerializeObject(wallet, new ApiKeyHiddenJsonConverter(typeof(BitGoWallet))));
                ex.FailActivity();
                throw;
            }
        }
示例#9
0
        public async Task UpdateSpotInstrumentFeesSettings(SpotInstrumentFees settings)
        {
            using var action = MyTelemetry.StartActivity("Update Spot Instrument Fees Settings");
            settings.AddToActivityAsJsonTag("settings");
            try
            {
                _logger.LogInformation("Update Spot Instrument Fees Setting: {jsonText}",
                                       JsonConvert.SerializeObject(settings));

                ValidateSettings(settings);

                var entity = SpotInstrumentFeesNoSqlEntity.Create(settings);

                var existingItem = await _writer.GetAsync(entity.PartitionKey, entity.RowKey);

                if (existingItem == null)
                {
                    throw new Exception("Cannot update Spot Instrument Fees Settings. Do not exist");
                }

                await _writer.InsertOrReplaceAsync(entity);

                _logger.LogInformation("Updated Spot Instrument Fees Setting: {jsonText}",
                                       JsonConvert.SerializeObject(settings));
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Cannot update ExternalMarketSettings: {requestJson}",
                                 JsonConvert.SerializeObject(settings));
                ex.FailActivity();
                throw;
            }
        }
示例#10
0
        private async Task ProcessMessageAsync(OrderbookMessage orderbookMessage)
        {
            OrderbookEntity orderbook = null;

            try
            {
                orderbook = await _orderbookWriter.GetAsync(OrderbookEntity.GetPk(), orderbookMessage.AssetPair);
            }
            catch (Exception ex)
            {
                _log.Warning($"Can't get orderbook from mynosql for assetPair = {orderbookMessage.AssetPair}", ex);
            }

            var entity = orderbook ?? new OrderbookEntity(orderbookMessage.AssetPair)
            {
                CreatedAt = orderbookMessage.Timestamp
            };

            entity.CreatedAt = orderbookMessage.Timestamp;
            var prices = orderbookMessage.IsBuy ? entity.Bids : entity.Asks;

            prices.Clear();

            foreach (var price in orderbookMessage.Prices)
            {
                prices.Add(new VolumePriceEntity((decimal)price.Volume, (decimal)price.Price));
            }

            await _orderbookWriter.InsertOrReplaceAsync(entity);
        }
        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 ValueTask <bool> UpdateBitgoCoinEntityAsync(string coin, int accuracy, int requiredConfirmations, bool isMainNet)
        {
            if (string.IsNullOrEmpty(coin))
            {
                throw new Exception("Cannot update coin. Coin cannot be empty");
            }
            if (accuracy < 0)
            {
                throw new Exception("Cannot update coin. Accuracy can't be less then 0");
            }
            if (requiredConfirmations < 0)
            {
                throw new Exception("Cannot update coin. RequiredConfirmations can't be less then 0");
            }

            var entity = BitgoCoinEntity.Create(coin, accuracy, requiredConfirmations, isMainNet);

            var existingItem = await _bitgoCoins.GetAsync(entity.PartitionKey, entity.RowKey);

            if (existingItem == null)
            {
                throw new Exception("Cannot update coin. Coin not found");
            }

            await _bitgoCoins.InsertOrReplaceAsync(entity);

            return(true);
        }
示例#13
0
    public async Task AddOrUpdateAsync(string ruleId, DateTime expires)
    {
        var nosqlModel = NotificationNoSql.Create(ruleId, expires);
        await _myNoSqlServerDataWriter.InsertOrReplaceAsync(nosqlModel);

        await _myNoSqlServerDataWriter.CleanAndKeepMaxRecords(NotificationNoSql.GeneratePartitionKey(), 3500);
    }
        public async Task RegisterNewSessionAsync(AuthorizationToken token, RefreshToken refreshToken, string userAgent, string ip, string description, PlatformTypes platformType, LoginApplication application)
        {
            if (!token.RootSessionId.HasValue)
            {
                throw new Exception("Cannot RegisterNewSession without RootSessionId");
            }

            var pkBase64 = token.PublicKey != null?Convert.ToBase64String(token.PublicKey) : "";

            var session = RootSessionNoSqlEntity.Generate(token.RootSessionId.Value, token.TraderId(), token.BrandId, userAgent, ip, pkBase64,
                                                          token.Passed2FA, token.EmailVerified, description, platformType, application);

            session.Expires = refreshToken.Expires;

            var task1 = _sessionWriter.InsertOrReplaceAsync(session).AsTask();

            var shortSession = ShortRootSessionNoSqlEntity.Create(session);

            shortSession.Expires = refreshToken.Expires;
            var task2 = _rootSessionWriter.InsertOrReplaceAsync(shortSession).AsTask();

            var task3 = _rootSessionWriter.GetCountAsync(
                ShortRootSessionNoSqlEntity.GeneratePartitionKey(token.TraderId())).AsTask();
            await Task.WhenAll(task1, task2, task3);

            if (task3.Result > _maxSessionsCount)
            {
                var sessions = await _sessionWriter.GetAsync(
                    ShortRootSessionNoSqlEntity.GeneratePartitionKey(token.TraderId()));

                var oldestSession = sessions.OrderBy(s => s.CreateTime).First();
                await Logout(token.TraderId(), oldestSession.RootSessionId);
            }
        }
        private async Task AddVolumeToApiKey(string brokerId, string apiKey, string asset, double amount)
        {
            try
            {
                var existingEntity = await _myNoSqlServerApiKeyDataWriter.GetAsync(
                    ApiKeyVolumeNoSqlEntity.GeneratePartitionKey(brokerId),
                    ApiKeyVolumeNoSqlEntity.GenerateRowKey(apiKey, asset));

                if (existingEntity == null)
                {
                    existingEntity = ApiKeyVolumeNoSqlEntity.Create(new ApiKeyVolume
                    {
                        BrokerId       = brokerId,
                        ApiKeyHash     = apiKey,
                        Asset          = asset,
                        Volume         = amount,
                        LastUpdateTime = DateTime.Now
                    });
                }
                else
                {
                    existingEntity.Volume.Volume        += amount;
                    existingEntity.Volume.LastUpdateTime = DateTime.Now;
                }

                await _myNoSqlServerApiKeyDataWriter.InsertOrReplaceAsync(existingEntity);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex,
                                 "Unable to update accumulated volume for api key {apiKey}, asset {asset}, amount {amount}", apiKey,
                                 asset, amount);
            }
        }
        private async Task SaveMarketDataAsync(List <MarketSlice> marketData, Dictionary <string, IList <Candle> > prices)
        {
            var tasks = new List <Task>();

            List <string> assetPairIds      = prices.Keys.ToList();
            var           pricesValue       = new Dictionary <string, SortedSetEntry[]>();
            var           baseVolumesValue  = new Dictionary <string, SortedSetEntry[]>();
            var           quoteVolumesValue = new Dictionary <string, SortedSetEntry[]>();

            tasks.Add(_database.SortedSetAddAsync(RedisService.GetAssetPairsKey(),
                                                  marketData.Select(x => new SortedSetEntry(x.AssetPairId, 0)).ToArray()));

            foreach (var assetPairId in assetPairIds)
            {
                pricesValue.Add(assetPairId,
                                prices[assetPairId].Select(x =>
                                                           new SortedSetEntry(RedisExtensions.SerializeWithTimestamp((decimal)x.Open, x.DateTime),
                                                                              x.DateTime.ToUnixTime())).ToArray());

                baseVolumesValue.Add(assetPairId,
                                     prices[assetPairId].Select(x =>
                                                                new SortedSetEntry(RedisExtensions.SerializeWithTimestamp((decimal)x.TradingVolume, x.DateTime),
                                                                                   x.DateTime.ToUnixTime())).ToArray());

                quoteVolumesValue.Add(assetPairId,
                                      prices[assetPairId].Select(x =>
                                                                 new SortedSetEntry(RedisExtensions.SerializeWithTimestamp((decimal)x.TradingOppositeVolume, x.DateTime),
                                                                                    x.DateTime.ToUnixTime())).ToArray());
            }

            foreach (MarketSlice marketSlice in marketData)
            {
                tasks.Add(_database.HashSetAsync(RedisService.GetMarketDataKey(marketSlice.AssetPairId),
                                                 marketSlice.ToMarketSliceHash()));
            }

            await Task.WhenAll(tasks);

            tasks = new List <Task>();

            foreach (MarketSlice marketSlice in marketData)
            {
                tasks.Add(_priceWriter.InsertOrReplaceAsync(marketSlice.ToPrice()));
                tasks.Add(_tickerWriter.InsertOrReplaceAsync(marketSlice.ToTicker()));
            }

            await Task.WhenAll(tasks);

            tasks = new List <Task>();

            foreach (var assetPairId in assetPairIds)
            {
                tasks.Add(_database.SortedSetAddAsync(RedisService.GetMarketDataPriceKey(assetPairId), pricesValue[assetPairId]));
                tasks.Add(_database.SortedSetAddAsync(RedisService.GetMarketDataBaseVolumeKey(assetPairId), baseVolumesValue[assetPairId]));
                tasks.Add(_database.SortedSetAddAsync(RedisService.GetMarketDataQuoteVolumeKey(assetPairId), quoteVolumesValue[assetPairId]));
            }

            await Task.WhenAll(tasks);
        }
        public async Task UpdateLiquidityConverterSettingsAsync(LiquidityConverterSettings settings)
        {
            await _settingsDataWriter.InsertOrReplaceAsync(SettingsLiquidityConverterNoSql.Create(settings));

            await ReloadSettings();

            _logger.LogInformation("Updated LiquidityConverterSettings Settings: {jsonText}",
                                   JsonConvert.SerializeObject(settings));
        }
        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);
        }
示例#19
0
        public async Task <string> CreateVerifiedSessionAsync(string token, string publicKey = null)
        {
            string sessionId = SessionEntity.GenerateSessionId();
            var    session   = SessionEntity.Generate(_expirationTimeInMins, sessionId);

            session.Token     = token;
            session.Verified  = true;
            session.Sms       = true;
            session.Pin       = true;
            session.PublicKey = publicKey;

            var lykkeSession = await _clientSessionsClient.GetAsync(token);

            session.ClientId       = lykkeSession.ClientId;
            session.PartnerId      = lykkeSession.PartnerId;
            session.LykkeSessionId = lykkeSession.AuthId.ToString();

            await _sessionsWriter.InsertOrReplaceAsync(session);

            return(sessionId);
        }
        public void Update(string brokerId, OrderBook orderBook)
        {
            var symbol = orderBook.Symbol;

            _orderBooks.Update(brokerId, symbol, orderBook);

            var entity = OrderBookEntity.GenerateEntity(brokerId, orderBook.Symbol);

            entity.OrderBook = orderBook;

            _dataWriter.InsertOrReplaceAsync(entity).GetAwaiter().GetResult();
        }
        public async Task UpdateProfile(KycProfile profile, string operation, string agent, string comment)
        {
            await using var context = new DatabaseContext(_dbContextOptionsBuilder.Options);
            await context.UpsertAsync(new[] { profile });

            await _cache.InsertOrReplaceAsync(KycProfileNoSqlEntity.Create(profile));

            await _cache.CleanAndKeepMaxRecords(KycProfileNoSqlEntity.GeneratePartitionKey(), 10000);

            context.AuditLogs.Add(KycAuditLog.Create(profile, operation, agent, comment));
            await context.SaveChangesAsync();
        }
        public async Task AddWalletAsync(LpWallet wallet)
        {
            var entity = LpWalletNoSql.Create(wallet);

            await _noSqlDataWriter.InsertOrReplaceAsync(entity);

            lock (_sync)
            {
                _data[wallet.Name] = wallet;
            }

            _logger.LogInformation("Added Wallet {name}: {jsonText}", wallet.Name, JsonConvert.SerializeObject(wallet));
        }
示例#23
0
        public async Task <ProfilesResponse> GetAllProfiles()
        {
            var groups = await _profileWriter.GetAsync(FeeProfilesNoSqlEntity.GeneratePartitionKey(), FeeProfilesNoSqlEntity.GenerateRowKey());

            if (groups.DepositProfiles == null || !groups.DepositProfiles.Any())
            {
                var list = new List <string>()
                {
                    FeeProfileConsts.DefaultProfile
                };
                await _profileWriter.InsertOrReplaceAsync(FeeProfilesNoSqlEntity.Create(groups.Profiles, list));
            }

            return(new ProfilesResponse()
            {
                WithdrawalProfiles = groups?.Profiles ?? new List <string>(),
                DepositProfiles = groups?.DepositProfiles ?? new List <string>()
                {
                    FeeProfileConsts.DefaultProfile
                }
            });
        }
        public async Task AddOrUpdateRouteAsync(ProviderRoute newRoute)
        {
            if (string.IsNullOrEmpty(newRoute.Id))
            {
                newRoute.Id = Guid.NewGuid().ToString("N");
            }

            var entity = ProviderRouteMyNoSqlEntity.Create(newRoute);

            await _routeWriter.InsertOrReplaceAsync(entity);

            _logger.LogInformation("Added/updated provider route {routeJson}", JsonConvert.SerializeObject(newRoute));
        }
示例#25
0
        public async Task <bool> TryInsertOrReplaceAsync(TEntity entity)
        {
            try
            {
                await _writer.InsertOrReplaceAsync(entity);

                return(true);
            }
            catch (Exception e)
            {
                _log.Error(e, $"Cannot execute InsertOrReplaceAsync to MyNoSql with entity {typeof(TEntity).Name}", $"data: {entity.ToJson()}");
                return(false);
            }
        }
        public async Task PingValidatorAsync([FromBody] PingValidatorRequest request)
        {
            var(auth, tenantId, adminId, adminEmail) = Authorize();

            if (!auth)
            {
                return;
            }

            var entity = _validationReader.Get(ValidatorLinkEntity.GeneratePartitionKey(tenantId),
                                               ValidatorLinkEntity.GenerateRowKey(request.ApiKeyId));

            if (entity == null)
            {
                _logger.LogInformation("Cannot send ping. ValidatorLinkEntity not found by API key: {ApiKeyId}", request.ApiKeyId);
                HttpContext.Response.StatusCode = (int)HttpStatusCode.BadRequest;
                return;
            }

            if (!entity.IsAccepted)
            {
                _logger.LogInformation("Cannot send ping. ValidatorLinkEntity is not accepted: {ApiKeyId}", request.ApiKeyId);
                HttpContext.Response.StatusCode = (int)HttpStatusCode.BadRequest;
                return;
            }

            if (string.IsNullOrEmpty(request.Message))
            {
                _logger.LogInformation("Cannot send ping. Message cannot be empty: {ApiKeyId}", request.ApiKeyId);
                HttpContext.Response.StatusCode = (int)HttpStatusCode.BadRequest;
                return;
            }

            if (Encoding.UTF8.GetBytes(request.Message).Length > 100)
            {
                _logger.LogInformation("Cannot send ping. Message length in bytes more that 100: {ApiKeyId}; Message: {Message}", request.ApiKeyId, request.Message);
                HttpContext.Response.StatusCode = (int)HttpStatusCode.BadRequest;
                return;
            }

            var message = PingMessageMyNoSqlEntity.Generate(entity.ValidatorId, request.Message);

            await _pingMessageWriter.InsertOrReplaceAsync(message);

            _logger.LogInformation("Ping message are created. API key: {ApiKeyId}; ValidatorId: {ValidatorId}; TenantId: {TenantId}; Name: {Name}; AdminId: {AdminId}", request.ApiKeyId, entity.ValidatorId, entity.TenantId, entity.Name, adminId);
        }
示例#27
0
        public async ValueTask <bool> UpdateBitgoAssetMapEntityAsync(string brokerId, string assetSymbol,
                                                                     string bitgoWalletId, string enabledBitgoWalletIds, string bitgoCoin, double minBalance, string tagSeparator)
        {
            if (string.IsNullOrEmpty(brokerId))
            {
                throw new Exception("Cannot update asset map. BrokerId cannot be empty");
            }
            if (string.IsNullOrEmpty(assetSymbol))
            {
                throw new Exception("Cannot update asset map. AssetSymbol cannot be empty");
            }
            if (string.IsNullOrEmpty(bitgoWalletId))
            {
                throw new Exception("Cannot update asset map. BitgoWalletId cannot be empty");
            }
            if (string.IsNullOrEmpty(bitgoCoin))
            {
                throw new Exception("Cannot update asset map. BitgoCoin cannot be empty");
            }

            var coin = await _bitgoCoins.GetAsync(BitgoCoinEntity.GeneratePartitionKey(),
                                                  BitgoCoinEntity.GenerateRowKey(bitgoCoin));

            if (coin == null)
            {
                throw new Exception("Cannot update asset map. Unknown BitgoCoin.");
            }

            var entity = BitgoAssetMapEntity.Create(brokerId, assetSymbol, bitgoWalletId,
                                                    enabledBitgoWalletIds, bitgoCoin, minBalance, tagSeparator);

            var existingEntity = await _assetMap.GetAsync(entity.PartitionKey, entity.RowKey);

            if (existingEntity == null)
            {
                throw new Exception("Cannot update asset map. Asset map not found");
            }

            await _assetMap.InsertOrReplaceAsync(entity);

            return(true);
        }
        private async Task ProcessMessageAsync(OrderbookMessage orderbookMessage)
        {
            var entity = await _orderbookWriter.GetAsync(OrderbookEntity.GetPk(), orderbookMessage.AssetPair)
                         ?? new OrderbookEntity(orderbookMessage.AssetPair)
            {
                CreatedAt = orderbookMessage.Timestamp,
            };

            entity.CreatedAt = orderbookMessage.Timestamp;
            var prices = orderbookMessage.IsBuy ? entity.Bids : entity.Asks;

            prices.Clear();

            foreach (var price in orderbookMessage.Prices)
            {
                prices.Add(new VolumePriceEntity((decimal)price.Volume, (decimal)price.Price));
            }

            await _orderbookWriter.InsertOrReplaceAsync(entity);
        }
示例#29
0
        public async Task <SnapshotEntity> GetSnapshot(string walletId, string assetId)
        {
            var snapshot = await _writer.GetAsync(SnapshotNoSqlEntity.GeneratePartitionKey(walletId),
                                                  SnapshotNoSqlEntity.GenerateRowKey(assetId));

            if (snapshot != null)
            {
                return(snapshot.Entity);
            }

            await using var ctx = DatabaseContext.Create(_dbContextOptionsBuilder);
            var snapshotEntity = await ctx.AvgSnapshots.FirstOrDefaultAsync(t => t.AssetId == assetId && t.WalletId == walletId);

            if (snapshotEntity != null)
            {
                await _writer.InsertOrReplaceAsync(SnapshotNoSqlEntity.Create(snapshotEntity));

                await _writer.CleanAndKeepMaxPartitions(Program.Settings.MaxCachedSnapshots);
            }

            return(snapshotEntity);
        }
示例#30
0
        private async Task UpdateCache(string clientId, string brokerId, List <ClientWalletEntity> list)
        {
            if (string.IsNullOrWhiteSpace(brokerId) ||
                string.IsNullOrWhiteSpace(clientId))
            {
                throw new Exception($"Client and broker cannot be null. Client: {JsonConvert.SerializeObject(clientId)}");
            }

            var noSqlEntity = new ClientWalletNoSqlEntity()
            {
                BrokerId     = brokerId,
                ClientId     = clientId,
                PartitionKey = ClientWalletNoSqlEntity.GeneratePartitionKey(brokerId),
                RowKey       = ClientWalletNoSqlEntity.GenerateRowKey(clientId),
                Wallets      = list.Select(e => new ClientWallet()
                {
                    Name              = e.Name,
                    IsDefault         = e.IsDefault,
                    WalletId          = e.WalletId,
                    CreatedAt         = e.CreatedAt,
                    BaseAsset         = e.BaseAsset,
                    EnableUseTestNet  = e.EnableUseTestNet,
                    IsInternal        = e.IsInternal,
                    EnableEarnProgram = e.EnableEarnProgram
                }).ToList()
            };

            try
            {
                await _writer.InsertOrReplaceAsync(noSqlEntity);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Cannot update cache. Entity: {json}", JsonConvert.SerializeObject(noSqlEntity));
            }
        }