Ejemplo n.º 1
0
        public async Task <bool> Execute(string address, BlockchainType blockchain)
        {
            if (!SupportedNetworks.Contains(blockchain))
            {
                throw new BlockchainTypeNotSupported(blockchain);
            }

            IBlockchainApiClient blockchainClient = _blockchainClientProvider.Get(blockchain);

            try
            {
                return(await blockchainClient.ValidateAddressAsync(address));
            }
            catch (WalletAddressValidationException e)
            {
                _log.ErrorWithDetails(e, new
                {
                    Blockchain = e.Blockchain.ToString(),
                    e.Address
                });

                throw;
            }
            catch (UnrecognizedApiResponse e)
            {
                _log.ErrorWithDetails(e, new { e.ResponseType });

                throw;
            }
        }
 public BroadcastTransactionCommandHandler(IBlockchainApiClient client,
                                           ILogFactory logFactory,
                                           IChaosKitty chaosKitty)
 {
     _client     = client;
     _chaosKitty = chaosKitty;
     _log        = logFactory.CreateLog(this);
 }
Ejemplo n.º 3
0
 public WaitForTransactionEndingCommandHandler(RetryDelayProvider retryDelayProvider,
                                               IBlockchainApiClient client,
                                               ILogFactory logFactory,
                                               IChaosKitty chaosKitty)
 {
     _retryDelayProvider = retryDelayProvider;
     _client             = client;
     _log        = logFactory.CreateLog(this);
     _chaosKitty = chaosKitty;
 }
Ejemplo n.º 4
0
 public BlockchainController(Blockchain blockchain, IBlockchainApiClient apiClient)
 {
     if (blockchain == null)
     {
         throw new ArgumentNullException("Blockchain must not be null");
     }
     if (apiClient == null)
     {
         throw new ArgumentNullException("ApiClient must not be null");
     }
     this.blockchain = blockchain;
     this.apiClient  = apiClient;
 }
Ejemplo n.º 5
0
        public async Task <IMerchantWallet> CreateAsync(CreateMerchantWalletCommand cmd)
        {
            IBlockchainApiClient blockchainClient = _blockchainClientProvider.Get(cmd.Network);

            string walletAddress = await blockchainClient.CreateAddressAsync();

            return(await _merchantWalletRespository.CreateAsync(new MerchantWallet
            {
                MerchantId = cmd.MerchantId,
                Network = cmd.Network,
                WalletAddress = walletAddress,
                CreatedOn = DateTime.UtcNow,
                DisplayName = cmd.DisplayName,
                IncomingPaymentDefaults = Enumerable.Empty <string>().ToList(),
                OutgoingPaymentDefaults = Enumerable.Empty <string>().ToList()
            }));
        }
Ejemplo n.º 6
0
        public async Task <TransferResult> ExecuteAsync(TransferCommand transferCommand)
        {
            BlockchainType blockchainType = transferCommand.AssetId.GetBlockchainType();

            IBlockchainApiClient blockchainClient = _blockchainClientProvider.Get(blockchainType);

            BlockchainTransferResult blockchainTransferResult =
                await blockchainClient.TransferAsync(transferCommand.ToBlockchainTransfer());

            ITransfer transfer = await _transferRepository.AddAsync(new Transfer
            {
                AssetId      = transferCommand.AssetId,
                Blockchain   = blockchainTransferResult.Blockchain,
                CreatedOn    = DateTime.UtcNow,
                Amounts      = transferCommand.Amounts,
                Transactions = Mapper.Map <IEnumerable <TransferTransaction> >(blockchainTransferResult.Transactions)
            });

            return(Mapper.Map <TransferResult>(transfer));
        }
Ejemplo n.º 7
0
        public BalanceProcessor(
            string blockchainType,
            ILogFactory logFactory,
            IHotWalletsProvider hotWalletsProvider,
            IBlockchainApiClient blockchainApiClient,
            ICqrsEngine cqrsEngine,
            IEnrolledBalanceRepository enrolledBalanceRepository,
            IReadOnlyDictionary <string, Asset> assets,
            IReadOnlyDictionary <string, BlockchainAsset> blockchainAssets)
        {
            _blockchainType            = blockchainType;
            _log                       = logFactory.CreateLog(this);
            _hotWalletAddress          = hotWalletsProvider.GetHotWalletAddress(blockchainType);
            _blockchainApiClient       = blockchainApiClient;
            _cqrsEngine                = cqrsEngine;
            _enrolledBalanceRepository = enrolledBalanceRepository;
            _assets                    = assets;
            _blockchainAssets          = blockchainAssets;

            _warningAssets = new HashSet <string>();
        }
Ejemplo n.º 8
0
        public async Task <IReadOnlyList <MerchantWalletBalanceLine> > GetBalancesAsync(string merchantId)
        {
            var balances = new List <MerchantWalletBalanceLine>();

            IReadOnlyList <IMerchantWallet> wallets = await _merchantWalletRespository.GetByMerchantAsync(merchantId);

            foreach (IMerchantWallet merchantWallet in wallets)
            {
                IBlockchainApiClient blockchainClient = _blockchainClientProvider.Get(merchantWallet.Network);

                IReadOnlyList <BlockchainBalanceResult> walletBalance =
                    await blockchainClient.GetBalancesAsync(merchantWallet.WalletAddress);

                balances.AddRange(walletBalance.Select(x => new MerchantWalletBalanceLine
                {
                    Id      = merchantWallet.Id,
                    AssetId = x.AssetId,
                    Balance = x.Balance
                }));
            }

            return(balances);
        }
 public UpdateAddressesBackgroundTask(ILogger <UpdateAddressesBackgroundTask> logger,
                                      IBlockchainApiClient blockchainApiClient)
 {
     _logger = logger;
     _blockchainApiClient = blockchainApiClient;
 }
 public BlockchainDataController(IBlockchainApiClient blockchainApiClient,
                                 IMtGoxAddressesFetcher mtGoxAddressesFetcher)
 {
     _blockchainApiClient   = blockchainApiClient;
     _mtGoxAddressesFetcher = mtGoxAddressesFetcher;
 }
        /// <summary>
        ///
        /// </summary>
        /// <param name="cashoutModel"></param>
        /// <returns>
        /// ValidationError - client error
        /// ArgumentValidationException - developer error
        /// </returns>
        public async Task <IReadOnlyCollection <ValidationError> > ValidateAsync(CashoutModel cashoutModel)
        {
            var errors = new List <ValidationError>(1);

            if (cashoutModel == null)
            {
                return(FieldNotValidResult("cashoutModel can't be null"));
            }

            if (string.IsNullOrEmpty(cashoutModel.AssetId))
            {
                return(FieldNotValidResult("cashoutModel.AssetId can't be null or empty"));
            }

            Asset asset;

            try
            {
                asset = await _assetsService.TryGetAssetAsync(cashoutModel.AssetId);
            }
            catch (Exception)
            {
                throw new ArgumentValidationException($"Asset with Id-{cashoutModel.AssetId} does not exists",
                                                      "assetId");
            }

            if (asset.IsDisabled)
            {
                errors.Add(ValidationError.Create(ValidationErrorType.None, $"Asset {asset.Id} is disabled"));
            }

            if (asset == null)
            {
                throw new ArgumentValidationException($"Asset with Id-{cashoutModel.AssetId} does not exists",
                                                      "assetId");
            }

            var isAddressValid = true;
            IBlockchainApiClient blockchainClient = null;

            if (asset.Id != LykkeConstants.SolarAssetId)
            {
                if (string.IsNullOrEmpty(asset.BlockchainIntegrationLayerId))
                {
                    throw new ArgumentValidationException(
                              $"Given asset Id-{cashoutModel.AssetId} is not a part of Blockchain Integration Layer",
                              "assetId");
                }

                blockchainClient = _blockchainApiClientProvider.Get(asset.BlockchainIntegrationLayerId);
            }

            if (string.IsNullOrEmpty(cashoutModel.DestinationAddress) ||
                !cashoutModel.DestinationAddress.IsValidPartitionOrRowKey() ||
                asset.Id != LykkeConstants.SolarAssetId && blockchainClient != null &&
                !await blockchainClient.IsAddressValidAsync(cashoutModel.DestinationAddress) ||
                asset.Id == LykkeConstants.SolarAssetId &&
                !SolarCoinValidation.ValidateAddress(cashoutModel.DestinationAddress)
                )
            {
                isAddressValid = false;
                errors.Add(ValidationError.Create(ValidationErrorType.AddressIsNotValid, "Address is not valid"));
            }

            if (isAddressValid)
            {
                if (asset.Id != LykkeConstants.SolarAssetId)
                {
                    var isBlocked = await _blackListService.IsBlockedWithoutAddressValidationAsync
                                    (
                        asset.BlockchainIntegrationLayerId,
                        cashoutModel.DestinationAddress
                                    );

                    if (isBlocked)
                    {
                        errors.Add(ValidationError.Create(ValidationErrorType.BlackListedAddress, "Address is in the black list"));
                    }
                }

                if (cashoutModel.Volume.HasValue && Math.Abs(cashoutModel.Volume.Value) < (decimal)asset.CashoutMinimalAmount)
                {
                    var minimalAmount = asset.CashoutMinimalAmount.GetFixedAsString(asset.Accuracy).TrimEnd('0');

                    errors.Add(ValidationError.Create(ValidationErrorType.LessThanMinCashout,
                                                      $"Please enter an amount greater than {minimalAmount}"));
                }

                if (asset.Id != LykkeConstants.SolarAssetId)
                {
                    var blockchainSettings = _blockchainSettingsProvider.Get(asset.BlockchainIntegrationLayerId);

                    if (cashoutModel.DestinationAddress == blockchainSettings.HotWalletAddress)
                    {
                        errors.Add(ValidationError.Create(ValidationErrorType.HotwalletTargetProhibited,
                                                          "Hot wallet as destitnation address prohibited"));
                    }

                    var isPublicExtensionRequired =
                        _blockchainWalletsCacheService.IsPublicExtensionRequired(asset.BlockchainIntegrationLayerId);
                    if (isPublicExtensionRequired)
                    {
                        var hotWalletParseResult = await _blockchainWalletsClient.ParseAddressAsync(
                            asset.BlockchainIntegrationLayerId,
                            blockchainSettings.HotWalletAddress);

                        var destAddressParseResult = await _blockchainWalletsClient.ParseAddressAsync(
                            asset.BlockchainIntegrationLayerId,
                            cashoutModel.DestinationAddress);

                        if (hotWalletParseResult.BaseAddress == destAddressParseResult.BaseAddress)
                        {
                            var existedClientIdAsDestination = await _blockchainWalletsClient.TryGetClientIdAsync(
                                asset.BlockchainIntegrationLayerId,
                                cashoutModel.DestinationAddress);

                            if (existedClientIdAsDestination == null)
                            {
                                errors.Add(ValidationError.Create(ValidationErrorType.DepositAddressNotFound,
                                                                  $"Deposit address {cashoutModel.DestinationAddress} not found"));
                            }
                        }

                        var forbiddenCharacterErrors = await ValidateForForbiddenCharsAsync(
                            destAddressParseResult.BaseAddress,
                            destAddressParseResult.AddressExtension,
                            asset.BlockchainIntegrationLayerId);

                        if (forbiddenCharacterErrors != null)
                        {
                            errors.AddRange(forbiddenCharacterErrors);
                        }

                        if (!string.IsNullOrEmpty(destAddressParseResult.BaseAddress))
                        {
                            if (!cashoutModel.DestinationAddress.Contains(destAddressParseResult.BaseAddress))
                            {
                                errors.Add(ValidationError.Create(ValidationErrorType.FieldIsNotValid,
                                                                  "Base Address should be part of destination address"));
                            }

                            // full address is already checked by integration,
                            // we don't need to validate it again,
                            // just ensure that base address is not black-listed
                            var isBlockedBase = await _blackListService.IsBlockedWithoutAddressValidationAsync(
                                asset.BlockchainIntegrationLayerId,
                                destAddressParseResult.BaseAddress);

                            if (isBlockedBase)
                            {
                                errors.Add(ValidationError.Create(ValidationErrorType.BlackListedAddress,
                                                                  "Base Address is in the black list"));
                            }
                        }
                    }
                }

                if (cashoutModel.ClientId.HasValue)
                {
                    var destinationClientId = await _blockchainWalletsClient.TryGetClientIdAsync
                                              (
                        asset.BlockchainIntegrationLayerId,
                        cashoutModel.DestinationAddress
                                              );

                    if (destinationClientId.HasValue && destinationClientId == cashoutModel.ClientId.Value)
                    {
                        var error = ValidationError.Create
                                    (
                            ValidationErrorType.CashoutToSelfAddress,
                            "Withdrawals to the deposit wallet owned by the customer himself prohibited"
                                    );

                        errors.Add(error);
                    }
                }
            }

            return(errors);
        }