public async Task <IActionResult> Build([Required, FromBody] BuildSingleTransactionRequest request) { if (!ModelState.IsValid) { return(BadRequest(ModelState.ToErrorResponse())); } var fromAddress = _dynamicService.GetBitcoinAddress(request.FromAddress); if (fromAddress == null) { return(BadRequest(ErrorResponse.Create($"{nameof(request.FromAddress)} is not a valid"))); } var toAddress = _dynamicService.GetBitcoinAddress(request.ToAddress); if (toAddress == null) { return(BadRequest(ErrorResponse.Create($"{nameof(request.ToAddress)} is not a valid"))); } if (request.AssetId != Asset.Dynamic.Id) { return(BadRequest(ErrorResponse.Create($"{nameof(request.AssetId)} was not found"))); } var broadcast = await _dynamicService.GetBroadcastAsync(request.OperationId); if (broadcast != null) { return(new StatusCodeResult(StatusCodes.Status409Conflict)); } var build = await _buildRepository.GetAsync(request.OperationId); if (build != null) { return(Ok(new BuildTransactionResponse() { TransactionContext = build.TransactionContext })); } var amount = Conversions.CoinsFromContract(request.Amount, Asset.Dynamic.Accuracy); var fromAddressBalance = await _dynamicService.GetAddressBalance(request.FromAddress); var fee = _dynamicService.GetFee(); var requiredBalance = request.IncludeFee ? amount : amount + fee; if (amount < fee) { return(BadRequest(BlockchainErrorResponse.FromKnownError(BlockchainErrorCode.AmountIsTooSmall))); } if (requiredBalance > fromAddressBalance) { return(BadRequest(BlockchainErrorResponse.FromKnownError(BlockchainErrorCode.NotEnoughBalance))); } await _log.WriteInfoAsync(nameof(TransactionsController), nameof(Build), request.ToJson(), "Build transaction"); var transactionContext = await _dynamicService.BuildTransactionAsync(request.OperationId, fromAddress, toAddress, amount, request.IncludeFee); await _buildRepository.AddAsync(request.OperationId, transactionContext); return(Ok(new BuildTransactionResponse() { TransactionContext = transactionContext })); }