Beispiel #1
0
        public async Task TransferAllAssetsToAddress(string clientId, string srcAddress, string srcPrivateKey, string destAddress)
        {
            var transactionId = Guid.NewGuid().ToString("N");
            var transfer      =
                await
                _transferEventsRepository.RegisterAsync(TransferEvent.CreateNewTransferAll(clientId, transactionId, srcAddress));

            var contextData = TransferContextData.Create(new TransferContextData.TransferModel
            {
                ClientId    = clientId,
                OperationId = transfer.Id
            });

            await _bitCoinTransactionsRepository.CreateAsync(transactionId, null, contextData);

            if (_baseSettings.UsePushPrivateKeyService)
            {
                await _srvBlockchainHelper.PushPrivateKey(srcPrivateKey);

                srcPrivateKey = null;
            }

            var  assets = (await _assetsDict.Values()).ToArray();
            bool needToTransferAssets = (await _srvBlockchainReader.GetBalancesForAdress(srcAddress, assets)).Any(x => x.Balance > 0);

            if (needToTransferAssets)
            {
                var queueMsg = await _bitCoinCommandProducer.TransferAllAssetsToAddress(transactionId, srcAddress, srcPrivateKey, destAddress);

                await _bitCoinTransactionsRepository.UpdateRequestAsync(transactionId, queueMsg);
            }
        }
        public async Task <CommandHandlingResult> Handle(Commands.SaveTransferOperationStateCommand command, IEventPublisher eventPublisher)
        {
            var message       = command.QueueMessage;
            var transactionId = message.Id;

            var transaction = await _transactionsRepository.FindByTransactionIdAsync(transactionId);

            if (transaction == null)
            {
                _log.Error(nameof(Commands.SaveManualOperationStateCommand), new Exception($"unknown transaction {transactionId}"), context: command);
                return(CommandHandlingResult.Ok());
            }

            var amountNoFee = await _feeCalculationService.GetAmountNoFeeAsync(message);

            var context = await _transactionService.GetTransactionContext <TransferContextData>(transactionId) ??
                          TransferContextData.Create(
                message.FromClientId,
                new TransferContextData.TransferModel
            {
                ClientId = message.ToClientid
            },
                new TransferContextData.TransferModel
            {
                ClientId = message.FromClientId
            });

            context.Transfers[0].OperationId = Guid.NewGuid().ToString();
            context.Transfers[1].OperationId = Guid.NewGuid().ToString();

            var destWallet = await _walletCredentialsRepository.GetAsync(message.ToClientid);

            var sourceWallet = await _walletCredentialsRepository.GetAsync(message.FromClientId);

            var contextJson = context.ToJson();
            var cmd         = new TransferCommand
            {
                Amount             = amountNoFee,
                AssetId            = message.AssetId,
                Context            = contextJson,
                SourceAddress      = sourceWallet?.MultiSig,
                DestinationAddress = destWallet?.MultiSig,
                TransactionId      = Guid.Parse(transactionId)
            };

            await SaveState(cmd, context);

            eventPublisher.PublishEvent(new TransferOperationStateSavedEvent {
                TransactionId = transactionId, QueueMessage = message, AmountNoFee = (double)amountNoFee
            });

            return(CommandHandlingResult.Ok());
        }
Beispiel #3
0
        public async Task GenerateTransferFromOrdinaryWallet(string clientId, string sourceAddress, string sourceKey, double amount, string assetId,
                                                             TransferContextData.AdditionalActions additionalActionsDest = null)
        {
            var asset = await _assetsRepository.GetAssetAsync(assetId);

            if (asset == null)
            {
                return;
            }

            amount = Math.Abs(amount);

            var transactionId = Guid.NewGuid().ToString("N");

            var clientCreds = await _walletCredentialsRepository.GetAsync(clientId);

            var transfer =
                await
                _transferEventsRepository.RegisterAsync(TransferEvent.CreateNew(clientId, clientCreds.MultiSig, null, assetId, amount, transactionId,
                                                                                sourceAddress, clientCreds.MultiSig));

            var contextData = TransferContextData.Create(new TransferContextData.TransferModel
            {
                ClientId    = clientId,
                OperationId = transfer.Id,
                Actions     = additionalActionsDest
            });

            if (_baseSettings.UsePushPrivateKeyService)
            {
                await _srvBlockchainHelper.PushPrivateKey(sourceKey, true);

                sourceKey = null;
            }

            var queueMsg = await
                           _bitCoinCommandProducer.ProduceGenerateTransferAsync(transactionId, sourceAddress, sourceKey,
                                                                                clientCreds.MultiSig, amount, asset.BlockChainId);

            await _bitCoinTransactionsRepository.CreateAsync(transactionId, queueMsg, contextData);
        }
Beispiel #4
0
        public async Task <string> GenerateTransfer(string destClientId, string sourceClientId, double amount, string assetId,
                                                    bool fromBtcConvWallet = false,
                                                    TransferContextData.AdditionalActions additionalActionsDest = null,
                                                    TransferContextData.AdditionalActions additionalActionsSrc  = null)
        {
            var asset = await _assetsRepository.GetAssetAsync(assetId);

            if (asset == null)
            {
                throw new ArgumentNullException(nameof(assetId));
            }

            amount = Math.Abs(amount);

            var transactionId = Guid.NewGuid().ToString("N");

            var destClientCredentials = await _walletCredentialsRepository.GetAsync(destClientId);

            var sourceWalletCred = await _walletCredentialsRepository.GetAsync(sourceClientId);

            var destTransfer =
                await
                _transferEventsRepository.RegisterAsync(TransferEvent.CreateNew(destClientId, destClientCredentials.MultiSig, null, assetId, amount, transactionId,
                                                                                destClientCredentials.Address, destClientCredentials.MultiSig));

            var sourceTransfer =
                await
                _transferEventsRepository.RegisterAsync(TransferEvent.CreateNew(sourceClientId,
                                                                                fromBtcConvWallet ? sourceWalletCred.BtcConvertionWalletAddress : sourceWalletCred.MultiSig,
                                                                                null, assetId, -amount, transactionId,
                                                                                sourceWalletCred.Address, sourceWalletCred.MultiSig));

            var contextData = TransferContextData.Create(new TransferContextData.TransferModel
            {
                ClientId    = destClientId,
                OperationId = destTransfer.Id,
                Actions     = additionalActionsDest
            }, new TransferContextData.TransferModel
            {
                ClientId    = sourceClientId,
                OperationId = sourceTransfer.Id,
                Actions     = additionalActionsSrc
            });


            var pk = fromBtcConvWallet
                ? sourceWalletCred.BtcConvertionWalletPrivateKey
                : sourceWalletCred.PrivateKey;

            if (_baseSettings.UsePushPrivateKeyService)
            {
                await _srvBlockchainHelper.PushPrivateKey(pk, fromBtcConvWallet);
            }

            var queueMsg = await
                           _bitCoinCommandProducer.ProduceGenerateTransferAsync(transactionId,
                                                                                fromBtcConvWallet?sourceWalletCred.BtcConvertionWalletAddress : sourceWalletCred.MultiSig,
                                                                                _baseSettings.UsePushPrivateKeyService?null : pk, destClientCredentials.MultiSig, amount, asset.BlockChainId);

            await _bitCoinTransactionsRepository.CreateAsync(transactionId, queueMsg, contextData);

            return(destTransfer.Id);
        }
Beispiel #5
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);
        }