public override async Task <GetDepositAddressResponse> GetDepositAddress(GetDepositAddressRequest request, ServerCallContext context)
        {
            try
            {
                var asset = await _siriusWalletsService.CheckDepositPreconditionsAsync(context.GetHttpContext().User.GetClientId(), request.AssetId);

                var depositWallet = await _siriusWalletsService.GetWalletAddressAsync(
                    context.GetHttpContext().User.GetClientId(),
                    context.GetHttpContext().User.GetWalletId(),
                    asset.SiriusAssetId);

                return(new GetDepositAddressResponse
                {
                    Payload = _mapper.Map <DepositAddress>(depositWallet)
                });
            }
            catch (HftApiException e)
            {
                return(new GetDepositAddressResponse
                {
                    Error = new Error
                    {
                        Code = _mapper.Map <ErrorCode>(e.ErrorCode),
                        Message = e.Message
                    }
                });
            }
        }
Beispiel #2
0
        public async Task <GetDepositAddressResponse> GetDepositAddressAsync(GetDepositAddressRequest request)
        {
            var entity = _depositAddressReader.Get(DepositAddressEntity.GeneratePartitionKey(request.WalletId),
                                                   DepositAddressEntity.GenerateRowKey(request.AssetSymbol, request.Blockchain));

            if (entity != null)
            {
                return(new GetDepositAddressResponse()
                {
                    Address = entity.Address,
                    Error = GetDepositAddressResponse.ErrorCode.Ok
                });
            }

            return(await _service.GetDepositAddressAsync(request));
        }
        public async Task <GetDepositAddressResponse> GetDepositAddressAsync(GetDepositAddressRequest request)
        {
            var assetIdentity = new AssetIdentity
            {
                BrokerId = request.BrokerId,
                Symbol   = request.AssetSymbol
            };

            var paymentSettings = _assetPaymentSettingsClient.GetAssetById(assetIdentity);

            if (paymentSettings?.BitGoCrypto?.IsEnabledDeposit == true)
            {
                return(await GetBitgoDepositAddressAsync(request));
            }
            if (paymentSettings?.Circle?.IsEnabledBlockchainDeposit == true)
            {
                return(await GeCircleDepositAddressAsync(request));
            }

            return(new GetDepositAddressResponse
            {
                Error = GetDepositAddressResponse.ErrorCode.AddressNotGenerated
            });
        }
        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 <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;
            }
        }