예제 #1
0
        public override async Task <BalancesResponse> GetBalances(Empty request, ServerCallContext context)
        {
            var walletId = context.GetHttpContext().User.GetWalletId();
            var balances = await _balanceService.GetBalancesAsync(walletId);

            var res = new BalancesResponse();

            res.Payload.AddRange(_mapper.Map <List <Balance> >(balances));

            return(res);
        }
예제 #2
0
        public async Task <IActionResult> GetBalances()
        {
            var walletId = User.GetWalletId();
            var balances = await _balanceService.GetBalancesAsync(walletId);

            return(Ok(ResponseModel <IReadOnlyCollection <Balance> > .Ok(balances)));
        }
예제 #3
0
        public async Task ExecuteAsync()
        {
            _log.Info("Transfer started.");

            var balances = await _balanceService.GetBalancesAsync();

            _log.Info($"Got {balances.Length} balances to transfer.");

            await TransferAsync(balances);

            _log.Info("transfer completed.");
        }
예제 #4
0
        public async Task ExecuteAsync()
        {
            _log.Info("Copying started.");

            var balances = await _balanceService.GetBalancesAsync();

            _log.Info($"Got {balances.Length} balances to copy.");

            await CopyAsync(balances);

            _log.Info("Copying completed.");
        }
        public async Task <IActionResult> Get([Required, FromQuery] int take, [FromQuery] string continuation)
        {
            if (take < 1)
            {
                return(BadRequest(ErrorResponse.Create("Invalid parameter").AddModelError("take", "Must be positive non zero integer")));
            }
            if (!string.IsNullOrEmpty(continuation))
            {
                try
                {
                    JsonConvert.DeserializeObject <TableContinuationToken>(Utils.HexToString(continuation));
                }
                catch (JsonReaderException)
                {
                    return(BadRequest(ErrorResponse.Create("Invalid parameter").AddModelError("continuation", "Must be valid continuation token")));
                }
            }

            var balances = await _balanceService.GetBalancesAsync(take, continuation);

            var results = new List <WalletBalanceContract>();

            foreach (var b in balances.Wallets)
            {
                var result = new WalletBalanceContract
                {
                    Address = b.Address,
                    AssetId = b.AssetId,
                    Balance = b.Balance.ToString(),
                    Block   = b.Ledger
                };
                results.Add(result);
            }

            return(Ok(PaginationResponse.From(balances.ContinuationToken, results)));
        }
        public async Task <Guid> CreateWithdrawalAsync(
            string requestId,
            string clientId,
            string walletId,
            string assetId,
            decimal volume,
            string destinationAddress,
            string destinationAddressExtension)
        {
            var uniqueRequestId = $"{walletId}_{requestId}";

            var validationResult =
                await _validationService.ValidateWithdrawalRequestAsync(assetId, volume);

            if (validationResult != null)
            {
                throw HftApiException.Create(validationResult.Code, validationResult.Message).AddField(validationResult.FieldName);
            }

            var operationId = Guid.NewGuid();

            var payload = await _idempotencyService.CreateEntityOrGetPayload(uniqueRequestId, operationId.ToString());

            if (payload != null)
            {
                operationId = Guid.Parse(payload);
            }

            var asset = await _assetsService.GetAssetByIdAsync(assetId);

            if (asset.BlockchainIntegrationType != BlockchainIntegrationType.Sirius)
            {
                throw HftApiException.Create(HftApiErrorCode.ActionForbidden, "Asset unavailable");
            }

            var balances = await _balanceService.GetBalancesAsync(walletId);

            var cashoutSettings = await _clientAccountClient.ClientSettings.GetCashOutBlockSettingsAsync(clientId);

            var kycStatus = await _kycStatusService.GetKycStatusAsync(clientId);

            var cashoutCommand = new CreateCashoutCommand
            {
                OperationId                 = operationId,
                WalletId                    = walletId,
                DestinationAddress          = destinationAddress,
                DestinationAddressExtension = destinationAddressExtension,
                Volume = volume,
                Asset  = new AssetCashoutModel
                {
                    Id              = asset.AssetId,
                    DisplayId       = asset.Symbol,
                    MultiplierPower = asset.MultiplierPower,
                    AssetAddress    = asset.AssetAddress,
                    Accuracy        = asset.Accuracy,
                    BlockchainIntegrationLayerId = asset.BlockchainIntegrationLayerId,
                    Blockchain                = asset.Blockchain.ToString(),
                    Type                      = asset.Type?.ToString(),
                    IsTradable                = asset.IsTradable,
                    IsTrusted                 = asset.IsTrusted,
                    KycNeeded                 = asset.KycNeeded,
                    BlockchainWithdrawal      = asset.BlockchainWithdrawal,
                    CashoutMinimalAmount      = (decimal)asset.CashoutMinimalAmount,
                    LowVolumeAmount           = (decimal?)asset.LowVolumeAmount ?? 0,
                    LykkeEntityId             = asset.LykkeEntityId,
                    SiriusAssetId             = asset.SiriusAssetId,
                    BlockchainIntegrationType = Lykke.Service.Assets.Client.Models.BlockchainIntegrationType.Sirius
                },
                Client = new ClientCashoutModel
                {
                    Id             = new Guid(clientId),
                    Balance        = balances.SingleOrDefault(x => x.AssetId == assetId)?.Available ?? 0,
                    CashOutBlocked = cashoutSettings.CashOutBlocked,
                    KycStatus      = kycStatus.ToString()
                },
                GlobalSettings = new GlobalSettingsCashoutModel
                {
                    MaxConfirmationAttempts = -1,
                    TwoFactorEnabled        = false,
                    CashOutBlocked          = false, // TODO
                    FeeSettings             = new FeeSettingsCashoutModel
                    {
                        TargetClients = new Dictionary <string, string>
                        {
                            { "Cashout", _feeSettings.WithdrawalFeeDestinationClientId }
                        }
                    }
                }
            };

            _cqrsEngine.SendCommand(cashoutCommand, "hft-api", OperationsBoundedContext.Name);

            return(operationId);
        }
        public async Task <ValidationResult> ValidateLimitOrderAsync(string walletId, string assetPairId, OrderAction side, decimal price, decimal volume)
        {
            if (price <= 0)
            {
                return(new ValidationResult
                {
                    Code = HftApiErrorCode.InvalidField,
                    Message = HftApiErrorMessages.LessThanZero(nameof(price)),
                    FieldName = nameof(price)
                });
            }

            if (volume <= 0)
            {
                return(new ValidationResult
                {
                    Code = HftApiErrorCode.InvalidField,
                    Message = HftApiErrorMessages.LessThanZero(nameof(volume)),
                    FieldName = nameof(volume)
                });
            }

            var assetPair = await _assetsService.GetAssetPairByIdAsync(assetPairId);

            if (assetPair == null)
            {
                return(new ValidationResult
                {
                    Code = HftApiErrorCode.ItemNotFound,
                    Message = HftApiErrorMessages.AssetPairNotFound,
                    FieldName = nameof(assetPairId)
                });
            }

            if (volume < assetPair.MinVolume)
            {
                return(new ValidationResult
                {
                    Code = HftApiErrorCode.InvalidField,
                    Message = HftApiErrorMessages.MustBeGreaterThan(nameof(volume), assetPair.MinVolume.ToString(CultureInfo.InvariantCulture)),
                    FieldName = nameof(volume)
                });
            }

            decimal totalVolume;
            string  asset;

            if (side == OrderAction.Buy)
            {
                asset       = assetPair.QuoteAssetId;
                totalVolume = price * volume;
            }
            else
            {
                asset       = assetPair.BaseAssetId;
                totalVolume = volume;
            }

            var balances = await _balanceService.GetBalancesAsync(walletId);

            var assetBalance = balances.FirstOrDefault(x => x.AssetId == asset);

            if (assetBalance == null || assetBalance.Available - assetBalance.Reserved < totalVolume)
            {
                return(new ValidationResult
                {
                    Code = HftApiErrorCode.MeNotEnoughFunds,
                    Message = "Not enough funds",
                    FieldName = nameof(volume)
                });
            }

            return(null);
        }