Example #1
0
        public async Task <bool> SendTransaction(string transactionHex)
        {
            var result = false;
            var sendTransactionRequest = new SendTransactionRequest()
            {
                hex = transactionHex
            };

            var client            = new RestClient(ApiUrl);
            var request           = new RestRequest("/api/Wallet/send-transaction", Method.Post);
            var transactionToSend = JsonConvert.SerializeObject(sendTransactionRequest);

            request.AddParameter("application/json; charset=utf-8", transactionToSend, ParameterType.RequestBody);
            request.RequestFormat = DataFormat.Json;

            var response = await client.ExecuteAsync <BuildTransactionResult>(request);

            if (response.StatusCode == HttpStatusCode.OK)
            {
                result = true;
            }
            return(result);
        }
Example #2
0
        /// <summary>
        ///     Sends a transaction that has already been built.
        ///     Use the /api/Wallet/build-transaction call to create transactions.
        /// </summary>
        /// <param name="request">An object containing the necessary parameters used to a send transaction request.</param>
        /// <returns>A JSON object containing information about the sent transaction.</returns>
        public async Task <WalletSendTransactionModel> SendTransaction(string rawHex)
        {
            try
            {
                Guard.Null(rawHex, nameof(rawHex), "Unable to send transaction, Provided rawHex Is NULL/Empty!");

                SendTransactionRequest decodeTxRequest = new SendTransactionRequest
                {
                    Hex = rawHex
                };

                WalletSendTransactionModel response = await base.SendPostJSON <WalletSendTransactionModel>("/api/Wallet/send-transaction", decodeTxRequest);

                Guard.Null(response, nameof(response), "'api/Wallet/send-transaction' API Response Was Null!");

                return(response);
            }
            catch (Exception ex)
            {
                logger.LogCritical($"An Error '{ex.Message}' Occured When Getting raw transaction For '{rawHex}'!", ex);
                throw;
            }
        }
        private async Task <string> PayoutAsync(Balance balance)
        {
            // send transaction
            logger.Info(() => $"[{LogCategory}] Sending {FormatAmount(balance.Amount)} to {balance.Address}");

            var amount = (BigInteger)Math.Floor(balance.Amount * EthereumConstants.Wei);

            var request = new SendTransactionRequest
            {
                From  = poolConfig.Address,
                To    = balance.Address,
                Value = writeHex(amount),
            };

            var response = await daemon.ExecuteCmdSingleAsync <string>(logger, EC.SendTx, new[] { request });

            if (response.Error != null)
            {
                throw new Exception($"{EC.SendTx} returned error: {response.Error.Message} code {response.Error.Code}");
            }

            if (string.IsNullOrEmpty(response.Response) || EthereumConstants.ZeroHashPattern.IsMatch(response.Response))
            {
                throw new Exception($"{EC.SendTx} did not return a valid transaction hash");
            }

            var txHash = response.Response;

            logger.Info(() => $"[{LogCategory}] Payout transaction id: {txHash}");

            // update db
            await PersistPaymentsAsync(new[] { balance }, txHash);

            // done
            return(txHash);
        }
        public IActionResult SendTransaction([FromBody] SendTransactionRequest request)
        {
            // checks the request is valid
            if (!this.ModelState.IsValid)
            {
                var errors = this.ModelState.Values.SelectMany(e => e.Errors.Select(m => m.ErrorMessage));
                return(ErrorHelpers.BuildErrorResponse(HttpStatusCode.BadRequest, "Formatting error", string.Join(Environment.NewLine, errors)));
            }

            try
            {
                var result = this.walletManager.SendTransaction(request.Hex);
                if (result)
                {
                    return(this.Ok());
                }

                return(this.StatusCode((int)HttpStatusCode.BadRequest));
            }
            catch (Exception e)
            {
                return(ErrorHelpers.BuildErrorResponse(HttpStatusCode.BadRequest, e.Message, e.ToString()));
            }
        }
 public async Task <IActionResult> SendTransaction([FromBody] SendTransactionRequest request,
                                                   CancellationToken cancellationToken = default(CancellationToken))
 {
     return(await this.walletController.SendTransaction(request, cancellationToken).ConfigureAwait(false));
 }
        public async Task <SendTransactionResponse> SignAndSendTransactionAsync(SendTransactionRequest request)
        {
            _logger.LogInformation("Transfer Request: {jsonText}", JsonConvert.SerializeObject(request));

            try
            {
                var client = _bitGoClientService.GetByUser(request.BrokerId, BitGoUserNoSqlEntity.TechSignerId, request.BitgoCoin);
                if (client == null)
                {
                    throw new Exception($"Tech account is not configured, id = {BitGoUserNoSqlEntity.TechSignerId}, coin = {request.BitgoCoin}");
                }

                var wallet = _myNoSqlServerWalletDataReader.Get(
                    BitGoWalletNoSqlEntity.GeneratePartitionKey(request.BrokerId),
                    BitGoWalletNoSqlEntity.GenerateRowKey(request.BitgoWalletId));

                if (string.IsNullOrEmpty(wallet?.Wallet?.ApiKey))
                {
                    _logger.LogError("Cannot find pass phase for wallet {bitgoWalletIdText}", request.BitgoWalletId);
                    throw new Exception($"Cannot find pass phase for wallet {request.BitgoWalletId}");
                }

                var walletPass = _encryptionService.Decrypt(wallet.Wallet.ApiKey);

                var result = await client.SendCoinsAsync(request.BitgoCoin, request.BitgoWalletId,
                                                         walletPass, request.SequenceId,
                                                         request.Amount, request.Address);

                if (!result.Success)
                {
                    switch (result.Error.Code)
                    {
                    case "DuplicateSequenceIdError":
                    {
                        var transaction = await client.GetTransferBySequenceIdAsync(request.BitgoCoin,
                                                                                    request.BitgoWalletId, request.SequenceId);

                        if (!transaction.Success || transaction.Data == null)
                        {
                            _logger.LogError("Transfer is Duplicate, but cannot found transaction: {jsonText}",
                                             JsonConvert.SerializeObject(transaction.Error));

                            return(new SendTransactionResponse()
                                {
                                    Error = result.Error
                                });
                        }

                        _logger.LogInformation("Transfer is Duplicate, Result: {jsonText}",
                                               JsonConvert.SerializeObject(transaction.Data));

                        return(new SendTransactionResponse()
                            {
                                DuplicateTransaction = transaction.Data
                            });
                    }

                    case "needs unlock":
                        await _sessionPublisher.PublishAsync(new SignalBitGoSessionStateUpdate()
                        {
                            State = BitGoSessionState.Locked
                        });

                        return(new SendTransactionResponse()
                        {
                            Error =
                            {
                                Code         = "needs unlock",
                                ErrorMessage = "Session is locked"
                            }
                        });
                    }
                }

                if (!result.Success)
                {
                    _logger.LogError("Transfer Result: {jsonText}", JsonConvert.SerializeObject(result.Error));
                    return(new SendTransactionResponse()
                    {
                        Error = result.Error
                    });
                }

                await AddVolumeToApiKey(request.BrokerId, _encryptionService.GetSha256Hash(wallet.Wallet.ApiKey),
                                        request.BitgoCoin,
                                        _assetMapper.ConvertAmountFromBitgo(request.BitgoCoin, long.Parse(request.Amount)));

                _logger.LogInformation("Transfer Result: {jsonText}", JsonConvert.SerializeObject(result.Data));
                return(new SendTransactionResponse()
                {
                    Result = result.Data
                });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Transfer Request ERROR: {jsonText}. Error: {message}",
                                 JsonConvert.SerializeObject(request), ex.Message);
                throw;
            }
        }
Example #7
0
 public Task <SendTransactionResponse> SendAsync(SendTransactionRequest Request)
 => PutSimpleJsonAsync <SendTransactionResponse, SendTransactionRequest>(Request, Api.PutAddTransaction);
Example #8
0
 public SendTransactionResponse Send(SendTransactionRequest Request)
 => SendAsync(Request).GetAwaiter().GetResult();
Example #9
0
        public static async Task <WalletBuildTransactionModel> SendTransactionOnSidechain(int apiPortForSidechain,
                                                                                          SendTransactionRequest sendTransactionRequest)
        {
            using (var client = new HttpClient())
            {
                client.DefaultRequestHeaders.Accept.Clear();
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

                var uri = new Uri(
                    $"http://localhost:{apiPortForSidechain}/api/SidechainRuntime/send-transaction");
                var request             = new JsonContent(sendTransactionRequest);
                var httpResponseMessage = await client.PostAsync(uri, request);

                string json = await httpResponseMessage.Content.ReadAsStringAsync();

                return(JsonConvert.DeserializeObject <WalletBuildTransactionModel>(json));
            }
        }
 public async Task <IActionResult> SendTransaction([FromBody] SendTransactionRequest request,
                                                   CancellationToken cancellationToken = default(CancellationToken))
 {
     return(await this.Execute(request, cancellationToken,
                               async (req, token) => Json(await this.walletService.SendTransaction(req, token))));
 }
        public SendTransactionResponse ProcessTransactionold(SendTransactionRequest request)
        {
            var dataStoreType = "Backup";

            Account account = null;

            if (dataStoreType == "Backup")
            {
                var transactionStore = new BackupTransactionRepository();
                account = transactionStore.GetAccount(request.DebtorAccountNumber);
            }
            else
            {
                var transactionStore = new TransactionRepository();
                account = transactionStore.GetAccount(request.DebtorAccountNumber);
            }

            var result = new SendTransactionResponse();

            if (request.PaymentScheme == PaymentScheme.Bacs)
            {
                if (account == null)
                {
                    result.Success = false;
                }
                else if (account.AllowedPaymentSchemes != AllowedPaymentSchemes.Bacs)
                {
                    result.Success = false;
                }
            }
            else if (request.PaymentScheme == PaymentScheme.FasterPayments)
            {
                if (account == null)
                {
                    result.Success = false;
                }
                else if (account.AllowedPaymentSchemes != AllowedPaymentSchemes.FasterPayments)
                {
                    result.Success = false;
                }
                else if (account.Balance < request.Amount)
                {
                    result.Success = false;
                }
            }
            else if (request.PaymentScheme == PaymentScheme.Chaps)
            {
                if (account == null)
                {
                    result.Success = false;
                }
                else if (account.AllowedPaymentSchemes != AllowedPaymentSchemes.Chaps)
                {
                    result.Success = false;
                }
                else if (account.Status != AccountStatus.Live)
                {
                    result.Success = false;
                }
            }

            if (result.Success)
            {
                account.Balance -= request.Amount;

                if (dataStoreType == "Backup")
                {
                    var transactionStore = new BackupTransactionRepository();
                    transactionStore.UpdateAccount(account);
                }
                else
                {
                    var transactionStore = new TransactionRepository();
                    transactionStore.UpdateAccount(account);
                }
            }

            return(result);
        }
Example #12
0
        public async Task <IActionResult> SendTransactionAsync([FromBody] SendTransactionRequest request)
        {
            Guard.NotNull(request, nameof(request));

            // checks the request is valid
            if (!this.ModelState.IsValid)
            {
                return(BuildErrorResponse(this.ModelState));
            }

            try
            {
                var transaction = new Transaction(request.Hex);

                WalletSendTransactionModel model = new WalletSendTransactionModel
                {
                    TransactionId = transaction.GetHash(),
                    Outputs       = new List <TransactionOutputModel>()
                };

                foreach (var output in transaction.Outputs)
                {
                    model.Outputs.Add(new TransactionOutputModel
                    {
                        Address = output.ScriptPubKey.GetDestinationAddress(this.network).ToString(),
                        Amount  = output.Value,
                    });
                }

                var result = await this.broadcasterManager.TryBroadcastAsync(transaction).ConfigureAwait(false);

                if (result == Bitcoin.Broadcasting.Success.Yes)
                {
                    return(this.Json(model));
                }

                if (result == Bitcoin.Broadcasting.Success.DontKnow)
                {
                    // wait for propagation
                    var waited = TimeSpan.Zero;
                    var period = TimeSpan.FromSeconds(1);
                    while (TimeSpan.FromSeconds(21) > waited)
                    {
                        // if broadcasts doesn't contain then success
                        var transactionEntry = this.broadcasterManager.GetTransaction(transaction.GetHash());
                        if (transactionEntry != null && transactionEntry.State == Bitcoin.Broadcasting.State.Propagated)
                        {
                            return(this.Json(model));
                        }
                        await Task.Delay(period).ConfigureAwait(false);

                        waited += period;
                    }
                }

                throw new TimeoutException("Transaction propagation has timed out. Lost connection?");
            }
            catch (Exception e)
            {
                this.logger.LogError("Exception occurred: {0}", e.ToString());
                return(ErrorHelpers.BuildErrorResponse(HttpStatusCode.BadRequest, e.Message, e.ToString()));
            }
        }