private async Task <GetDepositAddressResponse> GeCircleDepositAddressAsync(GetDepositAddressRequest request) { try { var asset = _circleAssetMapper.AssetToCircleAsset(request.BrokerId, request.AssetSymbol); if (asset == null || string.IsNullOrEmpty(asset.CircleAsset)) { _logger.LogError( "Cannot process GetDepositAddress. Asset do not mapped to circle. Request: {jsonText}", JsonConvert.SerializeObject(request)); return(new GetDepositAddressResponse { Error = GetDepositAddressResponse.ErrorCode.AssetDoNotSupported }); } 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; string error = null; if (string.IsNullOrEmpty(address)) { var preGeneratedAddresses = (await _generatedAddressDataWriter.GetAsync( GeneratedDepositAddressEntity.GeneratePartitionKey(request.BrokerId, asset.CircleAsset, asset.CircleWalletId, request.Blockchain))) .ToList(); if (preGeneratedAddresses.Count > 0) { var preGeneratedAddress = preGeneratedAddresses.First(); address = preGeneratedAddress.Address.Address; await _generatedAddressDataWriter.DeleteAsync(preGeneratedAddress.PartitionKey, preGeneratedAddress.RowKey); } else { var id = Guid.NewGuid().ToString(); var response = await _circleDepositAddressService.GenerateDepositAddress( new CreateCircleDepositAddressRequest { RequestGuid = id, BrokerId = asset.BrokerId, Asset = request.AssetSymbol, Blockchain = request.Blockchain }); if (!response.IsSuccess) { _logger.LogError( "Unable to pre-generate address for broker {broker}, asset {asset}, wallet id {walletId}, blockchain {blockchain}: {error}", asset.BrokerId, request.AssetSymbol, asset.CircleWalletId, request.Blockchain, response.ErrorMessage); } address = response.Data?.Address; error = response.ErrorMessage; } } 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 = "Circle", 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; } }
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; } }
private async Task DoTime() { var maxCount = Program.ReloadedSettings(e => e.PreGeneratedAddressesCount).Invoke(); var wallets = await _bitGoAssetMapSettingsService.GetAllAssetMapsAsync(); foreach (var wallet in wallets) { var assetIdentity = new AssetIdentity { BrokerId = wallet.BrokerId, Symbol = wallet.AssetSymbol }; var paymentSettings = _assetPaymentSettingsClient.GetAssetById(assetIdentity); if (paymentSettings?.BitGoCrypto?.IsEnabledDeposit != true) { continue; } var asset = _assetsDictionaryClient.GetAssetById(assetIdentity); if (asset == null || !asset.IsEnabled) { continue; } var blockchain = asset.DepositBlockchains.FirstOrDefault(); if (string.IsNullOrEmpty(blockchain)) { continue; } var entitiesCount = await _dataWriter.GetCountAsync( GeneratedDepositAddressEntity.GeneratePartitionKey(wallet.BrokerId, wallet.BitgoCoin, wallet.BitgoWalletId, blockchain)); if (entitiesCount < maxCount) { for (var i = 1; i <= maxCount - entitiesCount; i++) { try { var id = Guid.NewGuid().ToString(); var label = $"PreGenerated-{id}"; var(addressId, address, error) = await _depositAddressGeneratorService.GenerateOrGetAddressIdAsync(wallet.BitgoCoin, wallet.BitgoWalletId, label); if (string.IsNullOrEmpty(addressId) || error != null) { _logger.LogError( "Unable to pre-generate address for broker {broker}, asset {asset}, wallet id {walletId}: {error}", wallet.BrokerId, wallet.BitgoCoin, wallet.BitgoWalletId, error); continue; } await _dataWriter.InsertAsync(GeneratedDepositAddressEntity.Create( new GeneratedDepositAddress { BrokerId = wallet.BrokerId, Asset = wallet.BitgoCoin, WalletId = wallet.BitgoWalletId, PreGeneratedWalletId = id, AddressLabel = label, Address = address, BitGoAddressId = addressId, Blockchain = blockchain })); } catch (Exception ex) { _logger.LogError(ex, "Unable to pre-generate address for broker {broker}, asset {asset}, wallet id {walletId}, blockchain {blockchain}", wallet.BrokerId, wallet.BitgoCoin, wallet.BitgoWalletId, blockchain); } } _logger.LogInformation( "Pre-generated {count} addresses for broker {broker}, asset {asset}, wallet id {walletId}, blockchain {blockchain}", maxCount - entitiesCount, wallet.BrokerId, wallet.BitgoCoin, wallet.BitgoWalletId, blockchain); } } }