Exemplo n.º 1
0
        private async Task ProcessCashOut(CashOutCommand cmd)
        {
            var request = new TransferData
            {
                SourceAddress      = cmd.SourceAddress,
                DestinationAddress = cmd.DestinationAddress,
                Amount             = cmd.Amount,
                AssetId            = cmd.AssetId,
                TransactionId      = cmd.TransactionId
            };

            var response = await _bitcoinApiClient.TransferAsync(request);

            var reqMsg = $"{BitCoinCommands.CashOut}:{request.ToJson()}";

            await ProcessBitcoinApiResponse(reqMsg, BitCoinCommands.CashOut, response, cmd.Context);
        }
Exemplo n.º 2
0
        public async Task <IActionResult> RedeemAsync(CancellationToken token)
        {
            try
            {
                var command = new CashOutCommand(_userManager.GetLongUserId(User) /*, model.Amount*/);
                await _commandBus.DispatchAsync(command, token);

                return(Ok());
            }
            catch (InvalidOperationException e)
            {
                _logger.Exception(e, new Dictionary <string, string>()
                {
                    ["user"] = _userManager.GetUserId(User)
                });
                return(BadRequest());
            }
        }
        private async Task <bool> ProcessCashOut(IBitcoinTransaction transaction, CashInOutQueueMessage msg)
        {
            //Get client wallet
            var walletCredentials = await _walletCredentialsRepository
                                    .GetAsync(msg.ClientId);

            var amount  = msg.Amount.ParseAnyDouble();
            var context = await _bitcoinTransactionService.GetTransactionContext <CashOutContextData>(transaction.TransactionId);

            var asset = await _assetsService.TryGetAssetAsync(msg.AssetId);

            var isOffchainClient = await _clientSettingsRepository.IsOffchainClient(msg.ClientId);

            var isBtcOffchainClient = isOffchainClient && asset.Blockchain == Blockchain.Bitcoin;

            bool isForwardWithdawal = context.AddData?.ForwardWithdrawal != null;

            if (isForwardWithdawal)
            {
                var baseAsset = await _assetsService.TryGetAssetAsync(asset.ForwardBaseAsset);

                var forwardCashInId = await _cashOperationsRepository
                                      .RegisterAsync(new CashInOutOperation
                {
                    Id            = Guid.NewGuid().ToString(),
                    ClientId      = msg.ClientId,
                    Multisig      = walletCredentials.MultiSig,
                    AssetId       = baseAsset.Id,
                    Amount        = Math.Abs(amount),
                    DateTime      = DateTime.UtcNow.AddDays(asset.ForwardFrozenDays),
                    AddressFrom   = walletCredentials.MultiSig,
                    AddressTo     = context.Address,
                    TransactionId = msg.Id,
                    Type          = CashOperationType.ForwardCashIn,
                    State         = isBtcOffchainClient ?
                                    TransactionStates.InProcessOffchain : TransactionStates.InProcessOnchain
                });

                await _forwardWithdrawalRepository.SetLinkedCashInOperationId(msg.ClientId, context.AddData.ForwardWithdrawal.Id,
                                                                              forwardCashInId);
            }

            //Register cash operation
            var cashOperationId = await _cashOperationsRepository
                                  .RegisterAsync(new CashInOutOperation
            {
                Id             = Guid.NewGuid().ToString(),
                ClientId       = msg.ClientId,
                Multisig       = walletCredentials.MultiSig,
                AssetId        = msg.AssetId,
                Amount         = -Math.Abs(amount),
                DateTime       = DateTime.UtcNow,
                AddressFrom    = walletCredentials.MultiSig,
                AddressTo      = context.Address,
                TransactionId  = msg.Id,
                Type           = isForwardWithdawal ? CashOperationType.ForwardCashOut : CashOperationType.None,
                BlockChainHash = asset.IssueAllowed && isBtcOffchainClient ? string.Empty : transaction.BlockchainHash,
                State          = GetState(transaction, isBtcOffchainClient)
            });

            //Update context data
            context.CashOperationId = cashOperationId;
            var contextJson = context.ToJson();
            var cmd         = new CashOutCommand
            {
                Amount             = Math.Abs(amount),
                AssetId            = msg.AssetId,
                Context            = contextJson,
                SourceAddress      = walletCredentials.MultiSig,
                DestinationAddress = context.Address,
                TransactionId      = Guid.Parse(transaction.TransactionId)
            };

            await _bitcoinTransactionsRepository.UpdateAsync(transaction.TransactionId, cmd.ToJson(), null, "");

            await _bitcoinTransactionService.SetTransactionContext(transaction.TransactionId, context);

            if (!isOffchainClient && asset.Blockchain == Blockchain.Bitcoin)
            {
                await _bitcoinCommandSender.SendCommand(cmd);
            }

            if (asset.Blockchain == Blockchain.Ethereum)
            {
                string errMsg = string.Empty;

                try
                {
                    var address = await _bcnClientCredentialsRepository.GetClientAddress(msg.ClientId);

                    var txRequest =
                        await _ethereumTransactionRequestRepository.GetAsync(Guid.Parse(transaction.TransactionId));

                    txRequest.OperationIds = new[] { cashOperationId };
                    await _ethereumTransactionRequestRepository.UpdateAsync(txRequest);

                    var response = await _srvEthereumHelper.SendCashOutAsync(txRequest.Id,
                                                                             txRequest.SignedTransfer.Sign,
                                                                             asset, address, txRequest.AddressTo,
                                                                             txRequest.Volume);

                    if (response.HasError)
                    {
                        errMsg = response.Error.ToJson();
                    }
                }
                catch (Exception e)
                {
                    errMsg = $"{e.GetType()}\n{e.Message}";
                }

                if (!string.IsNullOrEmpty(errMsg))
                {
                    await _ethClientEventLogs.WriteEvent(msg.ClientId, Event.Error,
                                                         new { Request = transaction.TransactionId, Error = errMsg }.ToJson());
                }
            }

            return(true);
        }