private async Task <GetDepositAddressResponse> GetBitgoDepositAddressAsync(GetDepositAddressRequest request) { try { var(bitgoCoin, bitgoWalletId) = _assetMapper.AssetToBitgoCoinAndWallet(request.BrokerId, request.AssetSymbol); if (string.IsNullOrEmpty(bitgoWalletId) || string.IsNullOrEmpty(bitgoCoin)) { _logger.LogError( "Cannot process GetDepositAddress. Asset do not mapped to bitgo. Request: {jsonText}", JsonConvert.SerializeObject(request)); return(new GetDepositAddressResponse { Error = GetDepositAddressResponse.ErrorCode.AssetDoNotSupported }); } Error error = null; var label = _walletMapper.WalletToBitgoLabel(new JetWalletIdentity { BrokerId = request.BrokerId, ClientId = request.ClientId, WalletId = request.WalletId }); await using var ctx = DatabaseContext.Create(_dbContextOptionsBuilder); var addressEntity = await ctx.Addresses.Where(t => t.BrokerId == request.BrokerId && t.ClientId == request.ClientId && t.WalletId == request.WalletId && t.Blockchain == request.Blockchain && t.AssetSymbol == request.AssetSymbol).FirstOrDefaultAsync(); var address = addressEntity?.Address; if (string.IsNullOrEmpty(address)) { (address, error) = await _depositAddressGeneratorService.GetAddressAsync(bitgoCoin, bitgoWalletId, label); } if (string.IsNullOrEmpty(address)) { var preGeneratedAddresses = (await _generatedAddressDataWriter.GetAsync( GeneratedDepositAddressEntity.GeneratePartitionKey(request.BrokerId, bitgoCoin, bitgoWalletId, request.Blockchain))) .ToList(); if (preGeneratedAddresses.Count > 0) { var preGeneratedAddress = preGeneratedAddresses.First(); (address, error) = await _depositAddressGeneratorService.UpdateAddressLabelAsync(bitgoCoin, bitgoWalletId, preGeneratedAddress.Address.BitGoAddressId, label); if (error == null) { await _generatedAddressDataWriter.DeleteAsync(preGeneratedAddress.PartitionKey, preGeneratedAddress.RowKey); } } else { (address, error) = await _depositAddressGeneratorService.GenerateAddressAsync(bitgoCoin, bitgoWalletId, label); } } if (string.IsNullOrEmpty(address) || error != null) { _logger.LogError( "Cannot process GetDepositAddress. Unable to generate address. Request: {jsonText}. Error: {error}", JsonConvert.SerializeObject(request), error); return(new GetDepositAddressResponse { Error = GetDepositAddressResponse.ErrorCode.AddressNotGenerated }); } if (addressEntity == null) { await ctx.InsertAsync(new DepositAddressSqlEntity { BrokerId = request.BrokerId, ClientId = request.ClientId, WalletId = request.WalletId, Integration = "BitGo", AssetSymbol = request.AssetSymbol, Blockchain = request.Blockchain, Address = address, CreatedDate = DateTime.Now }); } await _addressDataWriter.InsertOrReplaceAsync(DepositAddressEntity.Create(request.WalletId, request.AssetSymbol, request.Blockchain, address)); await _addressDataWriter.CleanAndKeepMaxPartitions(Program.Settings.MaxClientInCache); _logger.LogInformation("Handle GetDepositAddress, request: {jsonText}, address: {address}", JsonConvert.SerializeObject(request), address); return(new GetDepositAddressResponse { Address = address, Error = GetDepositAddressResponse.ErrorCode.Ok }); } catch (Exception ex) { _logger.LogError(ex, "Exception on GetDepositAddress with request: {jsonText}", JsonConvert.SerializeObject(request)); throw; } }
public async Task <GetBitGoWalletLimitsResponse> GetSpendingLimitsAsync(GetBitGoWalletLimitsRequest request) { try { var(coin, wallet) = _assetMapper.AssetToBitgoCoinAndWallet(request.BrokerId, request.AssetId); var client = _bitGoClientService.GetByUser(request.BrokerId, BitGoUserNoSqlEntity.TechSignerId, coin); if (client == null) { return(new GetBitGoWalletLimitsResponse { Success = false, Error = $"Tech account is not configured, id = {BitGoUserNoSqlEntity.TechSignerId}, coin = {coin}" }); } var result = await client.GetSpendingLimitsForWalletAsync(coin, wallet); if (!result.Success) { _logger.LogInformation( $"Unable to get spending limits: {JsonConvert.SerializeObject(result.Error)}"); return(new GetBitGoWalletLimitsResponse { Success = false, Error = result.Error.Message }); } var limit = new SpendingLimit { AssetId = request.AssetId, BitgoCoin = coin }; foreach (var spendingLimit in result.Data.Limits) { if (spendingLimit.Coin == coin) { switch (spendingLimit.TimeWindow) { case "0": limit.TransactionLimit = _assetMapper.ConvertAmountFromBitgo(coin, decimal.Parse(spendingLimit.LimitAmountString)); break; case "3600": limit.HourlyLimit = _assetMapper.ConvertAmountFromBitgo(coin, decimal.Parse(spendingLimit.LimitAmountString)); limit.HourlySpent = _assetMapper.ConvertAmountFromBitgo(coin, decimal.Parse(spendingLimit.AmountSpentString)); break; case "86400": limit.DailyLimit = _assetMapper.ConvertAmountFromBitgo(coin, decimal.Parse(spendingLimit.LimitAmountString)); limit.DailySpent = _assetMapper.ConvertAmountFromBitgo(coin, decimal.Parse(spendingLimit.AmountSpentString)); break; } } } return(new GetBitGoWalletLimitsResponse { Success = true, Limit = limit }); } catch (Exception ex) { _logger.LogError(ex, "GetSpendingLimitsAsync request error: {message}", ex.Message); throw; } }