private async Task <bool> ProcessDestroy(IBitcoinTransaction transaction, CashInOutQueueMessage msg)
        {
            var amount = msg.Amount.ParseAnyDouble();
            //Get uncolor context data
            var context = await _bitcoinTransactionService.GetTransactionContext <UncolorContextData>(transaction.TransactionId);

            //Register cash operation
            var cashOperationId = await _cashOperationsRepository
                                  .RegisterAsync(new CashInOutOperation
            {
                Id            = Guid.NewGuid().ToString("N"),
                ClientId      = msg.ClientId,
                Multisig      = context.AddressFrom,
                AssetId       = msg.AssetId,
                Amount        = -Math.Abs(amount),
                DateTime      = DateTime.UtcNow,
                AddressFrom   = context.AddressFrom,
                AddressTo     = context.AddressTo,
                TransactionId = msg.Id
            });

            //Update context data
            context.CashOperationId = cashOperationId;
            var contextJson = context.ToJson();
            var cmd         = new DestroyCommand
            {
                Context       = contextJson,
                Amount        = Math.Abs(amount),
                AssetId       = msg.AssetId,
                Address       = context.AddressFrom,
                TransactionId = Guid.Parse(msg.Id)
            };

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

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

            //Send to bitcoin
            await _bitcoinCommandSender.SendCommand(cmd);

            return(true);
        }
        private async Task <IClientTrade[]> SaveTransactionAndContext(IClientTrade[] trades, List <AggregatedTransfer> operations, LimitQueueItem.LimitOrderWithTrades limitOrderWithTrades)
        {
            var contextData = await _bitcoinTransactionService.GetTransactionContext <SwapOffchainContextData>(limitOrderWithTrades.Order.Id) ?? new SwapOffchainContextData();

            foreach (var operation in operations.Where(x => x.ClientId == limitOrderWithTrades.Order.ClientId))
            {
                var trade = trades.FirstOrDefault(x => x.ClientId == operation.ClientId && x.AssetId == operation.AssetId && Math.Abs(x.Amount - (double)operation.Amount) < 0.00000001);

                contextData.Operations.Add(new SwapOffchainContextData.Operation()
                {
                    TransactionId = operation.TransferId,
                    Amount        = operation.Amount,
                    ClientId      = operation.ClientId,
                    AssetId       = operation.AssetId,
                    ClientTradeId = trade?.Id
                });
            }

            await _bitcoinTransactionService.CreateOrUpdateAsync(limitOrderWithTrades.Order.Id);

            await _bitcoinTransactionService.SetTransactionContext(limitOrderWithTrades.Order.Id, contextData);

            return(trades);
        }
示例#3
0
        public async Task <bool> ProcessMessage(TransferQueueMessage queueMessage)
        {
            var amount = queueMessage.Amount.ParseAnyDouble();

            //Get client wallets
            var toWallet = await _walletCredentialsRepository.GetAsync(queueMessage.ToClientid);

            var fromWallet = await _walletCredentialsRepository.GetAsync(queueMessage.FromClientId);

            //Register transfer events
            var destTransfer =
                await
                _transferEventsRepository.RegisterAsync(
                    TransferEvent.CreateNew(queueMessage.ToClientid,
                                            toWallet.MultiSig, null,
                                            queueMessage.AssetId, amount, queueMessage.Id,
                                            toWallet.Address, toWallet.MultiSig, state: TransactionStates.SettledOffchain));

            var sourceTransfer =
                await
                _transferEventsRepository.RegisterAsync(
                    TransferEvent.CreateNew(queueMessage.FromClientId,
                                            fromWallet.MultiSig, null,
                                            queueMessage.AssetId, -amount, queueMessage.Id,
                                            fromWallet.Address, fromWallet.MultiSig, state: TransactionStates.SettledOffchain));

            //Craete or Update transfer context
            var transaction = await _bitCoinTransactionsRepository.FindByTransactionIdAsync(queueMessage.Id);

            if (transaction == null)
            {
                await _log.WriteWarningAsync(nameof(TransferQueue), nameof(ProcessMessage), queueMessage.ToJson(), "unkown transaction");

                return(false);
            }

            var contextData = await _bitcoinTransactionService.GetTransactionContext <TransferContextData>(transaction.TransactionId);

            if (contextData == null)
            {
                contextData = TransferContextData
                              .Create(queueMessage.FromClientId, new TransferContextData.TransferModel
                {
                    ClientId = queueMessage.ToClientid
                }, new TransferContextData.TransferModel
                {
                    ClientId = queueMessage.FromClientId
                });
            }

            contextData.Transfers[0].OperationId = destTransfer.Id;
            contextData.Transfers[1].OperationId = sourceTransfer.Id;

            var contextJson = contextData.ToJson();
            var cmd         = new TransferCommand
            {
                Amount             = amount,
                AssetId            = queueMessage.AssetId,
                Context            = contextJson,
                SourceAddress      = fromWallet.MultiSig,
                DestinationAddress = toWallet.MultiSig,
                TransactionId      = Guid.Parse(queueMessage.Id)
            };

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

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

            if (await _clientSettingsRepository.IsOffchainClient(queueMessage.ToClientid))
            {
                if (!await _clientAccountsRepository.IsTrusted(queueMessage.ToClientid))
                {
                    try
                    {
                        await _offchainRequestService.CreateOffchainRequestAndNotify(transaction.TransactionId, queueMessage.ToClientid, queueMessage.AssetId, (decimal)amount, null, OffchainTransferType.CashinToClient);
                    }
                    catch (Exception)
                    {
                        await _log.WriteWarningAsync(nameof(TransferQueue), nameof(ProcessMessage), "", $"Transfer already exists {transaction.TransactionId}");
                    }
                }
            }
            else
            {
                await _bitcoinCommandSender.SendCommand(cmd);
            }



            return(true);
        }
        private async Task FinalizeIssue(IBitcoinTransaction transaction)
        {
            var contextData = await _bitcoinTransactionService.GetTransactionContext <IssueContextData>(transaction.TransactionId);

            await _cashOperationsRepository.SetIsSettledAsync(contextData.ClientId, contextData.CashOperationId, true);
        }