public async Task <IActionResult> BuildAndSendCreateSmartContractTransactionAsync([FromBody] BuildCreateContractTransactionRequest request)
        {
            if (!this.ModelState.IsValid)
            {
                return(ModelStateErrors.BuildErrorResponse(this.ModelState));
            }

            // Ignore this check if the node is running dev mode.
            if (this.nodeSettings.DevMode == null && !this.connectionManager.ConnectedPeers.Any())
            {
                this.logger.LogTrace("(-)[NO_CONNECTED_PEERS]");
                return(ErrorHelpers.BuildErrorResponse(HttpStatusCode.Forbidden, "Can't send transaction as the node requires at least one connection.", string.Empty));
            }

            BuildCreateContractTransactionResponse response = this.smartContractTransactionService.BuildCreateTx(request);

            if (!response.Success)
            {
                return(ErrorHelpers.BuildErrorResponse(HttpStatusCode.BadRequest, response.Message, string.Empty));
            }

            Transaction transaction = this.network.CreateTransaction(response.Hex);

            await this.broadcasterManager.BroadcastTransactionAsync(transaction);

            // Check if transaction was actually added to a mempool.
            TransactionBroadcastEntry transactionBroadCastEntry = this.broadcasterManager.GetTransaction(transaction.GetHash());

            if (transactionBroadCastEntry?.TransactionBroadcastState == Features.Wallet.Broadcasting.TransactionBroadcastState.CantBroadcast)
            {
                this.logger.LogError("Exception occurred: {0}", transactionBroadCastEntry.ErrorMessage);
                return(ErrorHelpers.BuildErrorResponse(HttpStatusCode.BadRequest, transactionBroadCastEntry.ErrorMessage, "Transaction Exception"));
            }

            response.Message = "Your CREATE contract transaction was successfully built and sent. Check the receipt using the transaction ID once it has been included in a new block.";

            return(this.Json(response));
        }
Пример #2
0
        public IActionResult GetXServerStats()
        {
            if (!this.ModelState.IsValid)
            {
                return(ModelStateErrors.BuildErrorResponse(this.ModelState));
            }

            try
            {
                var serverStats = new GetXServerStatsResult()
                {
                    Connected = this.xServerManager.ConnectedSeeds.Count,
                    Nodes     = this.xServerManager.ConnectedSeeds
                };

                return(this.Json(serverStats));
            }
            catch (Exception e)
            {
                this.logger.LogError("Exception occurred: {0}", e.ToString());
                return(ErrorHelpers.BuildErrorResponse(HttpStatusCode.BadRequest, e.Message, e.ToString()));
            }
        }
Пример #3
0
        public IActionResult GetBalance([FromQuery] WalletBalanceRequest request)
        {
            Guard.NotNull(request, nameof(request));

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

            try
            {
                var model = new WalletBalanceModel();

                IEnumerable <AccountBalance> balances = this.walletManager.GetBalances(request.WalletName, request.AccountName);

                foreach (AccountBalance balance in balances)
                {
                    HdAccount account = balance.Account;
                    model.AccountsBalances.Add(new AccountBalanceModel
                    {
                        CoinType          = this.coinType,
                        Name              = account.Name,
                        HdPath            = account.HdPath,
                        AmountConfirmed   = balance.AmountConfirmed,
                        AmountUnconfirmed = balance.AmountUnconfirmed
                    });
                }

                return(this.Json(model));
            }
            catch (Exception e)
            {
                this.logger.LogError("Exception occurred: {0}", e.ToString());
                return(ErrorHelpers.BuildErrorResponse(HttpStatusCode.BadRequest, e.Message, e.ToString()));
            }
        }
        public IActionResult ColdStakingWithdrawal([FromBody] ColdStakingWithdrawalRequest request)
        {
            Guard.NotNull(request, nameof(request));

            this.logger.LogTrace("({0}:'{1}')", nameof(request), request);

            // Checks the request is valid.
            if (!this.ModelState.IsValid)
            {
                this.logger.LogTrace("(-)[MODEL_STATE_INVALID]");
                return(ModelStateErrors.BuildErrorResponse(this.ModelState));
            }

            try
            {
                Money amount    = Money.Parse(request.Amount);
                Money feeAmount = Money.Parse(request.Fees);

                Transaction transaction = this.ColdStakingManager.GetColdStakingWithdrawalTransaction(this.walletTransactionHandler,
                                                                                                      request.ReceivingAddress, request.WalletName, request.WalletPassword, amount, feeAmount);

                var model = new ColdStakingWithdrawalResponse
                {
                    TransactionHex = transaction.ToHex()
                };

                this.logger.LogTrace("(-):'{0}'", model);

                return(this.Json(model));
            }
            catch (Exception e)
            {
                this.logger.LogError("Exception occurred: {0}", e.ToString());
                this.logger.LogTrace("(-)[ERROR]");
                return(ErrorHelpers.BuildErrorResponse(HttpStatusCode.BadRequest, e.Message, e.ToString()));
            }
        }
Пример #5
0
        public IActionResult GetColdStakingAddress([FromQuery] GetColdStakingAddressRequest request)
        {
            Guard.NotNull(request, nameof(request));

            // Checks that the request is valid.
            if (!this.ModelState.IsValid)
            {
                this.logger.LogTrace("(-)[MODEL_STATE_INVALID]");
                return(ModelStateErrors.BuildErrorResponse(this.ModelState));
            }

            try
            {
                var address =
                    this.ColdStakingManager.GetFirstUnusedColdStakingAddress(request.WalletName,
                                                                             request.IsColdWalletAddress);

                var model = new GetColdStakingAddressResponse
                {
                    Address = request.Segwit ? address?.Bech32Address : address?.Address
                };

                if (model.Address == null)
                {
                    throw new WalletException("The cold staking account does not exist.");
                }

                this.logger.LogTrace("(-):'{0}'", model);
                return(Json(model));
            }
            catch (Exception e)
            {
                this.logger.LogError("Exception occurred: {0}", e.ToString());
                this.logger.LogTrace("(-)[ERROR]");
                return(ErrorHelpers.BuildErrorResponse(HttpStatusCode.BadRequest, e.Message, e.ToString()));
            }
        }
        public IActionResult EstimateOfflineColdStakingSetupFee([FromBody] SetupOfflineColdStakingRequest request)
        {
            Guard.NotNull(request, nameof(request));

            // Checks the request is valid.
            if (!this.ModelState.IsValid)
            {
                this.logger.LogTrace("(-)[MODEL_STATE_INVALID]");
                return(ModelStateErrors.BuildErrorResponse(this.ModelState));
            }

            try
            {
                Money amount = Money.Parse(request.Amount);

                Money estimatedFee = this.ColdStakingManager.EstimateSetupTransactionFee(
                    this.walletTransactionHandler,
                    request.ColdWalletAddress,
                    request.HotWalletAddress,
                    request.WalletName,
                    request.WalletAccount,
                    null,
                    amount,
                    request.SubtractFeeFromAmount,
                    true,
                    request.SegwitChangeAddress);

                this.logger.LogTrace("(-):'{0}'", estimatedFee);
                return(this.Json(estimatedFee));
            }
            catch (Exception e)
            {
                this.logger.LogError("Exception occurred: {0}", e.ToString());
                this.logger.LogTrace("(-)[ERROR]");
                return(ErrorHelpers.BuildErrorResponse(HttpStatusCode.BadRequest, e.Message, e.ToString()));
            }
        }
        //PurchaseRequests/Create
        public ActionResult Create([FromBody] PurchaseRequest purchaseRequest)
        {
            if (purchaseRequest.Description == null)
            {
                return(new EmptyResult());
            }
            purchaseRequest.DateCreated = DateTime.Now;

            if (!ModelState.IsValid)
            {
                var errorMessages = ModelStateErrors.GetModelStateErrors(ModelState);
                return(new JsonNetResult {
                    Data = new Msg {
                        Result = "Failed", Message = "ModelState invalid.", Data = errorMessages
                    }
                });
            }


            db.PurchaseRequests.Add(purchaseRequest);

            try
            {
                db.SaveChanges();
            }
            catch (Exception ex)
            {
                return(new JsonNetResult {
                    Data = new JsonMessage("Failure", ex.Message)
                });
            }
            return(new JsonNetResult {
                Data = new Msg {
                    Result = "Success", Message = "Purchase Request was created the new id is:" + purchaseRequest.Id, Data = purchaseRequest
                }
            });                                                                                                                                                                       //This  will add user id to this string
        }
Пример #8
0
 // Create
 public ActionResult Create([System.Web.Http.FromBody] PurchaseRequest purchaserequest)
 {
     if (!ModelState.IsValid)
     {
         var errorMessages = ModelStateErrors.GetModelStateErrors(ModelState);
         return(new JsonNetResult {
             Data = new Msg {
                 Result = "Failed", Message = "ModelState invalid.", Data = errorMessages
             }
         });
     }
     purchaserequest.DateCreated = DateTime.Now;
     if (!ModelState.IsValid)
     {
         return(new JsonNetResult {
             Data = new JsonMessage("Failure", "Model State is not valid")
         });
         //return Json(new JsonMessage("Failure", "Model State is not valid"), JsonRequestBehavior.AllowGet);
     }
     db.PurchaseRequests.Add(purchaserequest);
     try
     {
         db.SaveChanges();
     }
     catch (Exception ex)
     {
         return(new JsonNetResult {
             Data = new JsonMessage("Failure", ex.Message)
         });
         //return Json(new JsonMessage("Failure", ex.Message), JsonRequestBehavior.AllowGet);
     }
     return(new JsonNetResult {
         Data = new JsonMessage("Success", "Purchase request was created")
     });
     //return Json(new JsonMessage("Success", "Purchase Request was created,"));
 }
Пример #9
0
        public IActionResult GetStorage([FromQuery] GetStorageRequest request)
        {
            if (!this.ModelState.IsValid)
            {
                this.logger.LogTrace("(-)[MODELSTATE_INVALID]");
                return(ModelStateErrors.BuildErrorResponse(this.ModelState));
            }

            var height = request.BlockHeight.HasValue ? request.BlockHeight.Value : (ulong)this.chainIndexer.Height;

            ChainedHeader chainedHeader = this.chainIndexer.GetHeader((int)height);

            var scHeader = chainedHeader?.Header as ISmartContractBlockHeader;

            IStateRepositoryRoot stateAtHeight = this.stateRoot.GetSnapshotTo(scHeader.HashStateRoot.ToBytes());

            uint160 addressNumeric = request.ContractAddress.ToUint160(this.network);

            byte[] storageValue = stateAtHeight.GetStorageValue(addressNumeric, Encoding.UTF8.GetBytes(request.StorageKey));

            if (storageValue == null)
            {
                return(this.NotFound(new
                {
                    Message = string.Format("No data at storage with key {0}", request.StorageKey)
                }));
            }

            // Interpret the storage bytes as an object of the given type
            object interpretedStorageValue = this.InterpretStorageValue(request.DataType, storageValue);

            // Use MethodParamStringSerializer to serialize the interpreted object to a string
            string serialized = MethodParameterStringSerializer.Serialize(interpretedStorageValue, this.network);

            return(this.Json(serialized));
        }
Пример #10
0
        public IActionResult Recover([FromBody] WalletRecoveryRequest request)
        {
            Guard.NotNull(request, nameof(request));

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

            try
            {
                Wallet wallet = this.walletManager.RecoverWallet(request.Password, request.Name, request.Mnemonic, request.CreationDate, passphrase: request.Passphrase);

                this.SyncFromBestHeightForRecoveredWallets(request.CreationDate);

                return(this.Ok());
            }
            catch (WalletException e)
            {
                // indicates that this wallet already exists
                this.logger.LogError("Exception occurred: {0}", e.ToString());
                return(ErrorHelpers.BuildErrorResponse(HttpStatusCode.Conflict, e.Message, e.ToString()));
            }
            catch (FileNotFoundException e)
            {
                // indicates that this wallet does not exist
                this.logger.LogError("Exception occurred: {0}", e.ToString());
                return(ErrorHelpers.BuildErrorResponse(HttpStatusCode.NotFound, "Wallet not found.", e.ToString()));
            }
            catch (Exception e)
            {
                this.logger.LogError("Exception occurred: {0}", e.ToString());
                return(ErrorHelpers.BuildErrorResponse(HttpStatusCode.BadRequest, e.Message, e.ToString()));
            }
        }
Пример #11
0
        public IActionResult SetupColdStaking([FromBody] SetupColdStakingRequest request)
        {
            Guard.NotNull(request, nameof(request));

            // Checks the request is valid.
            if (!this.ModelState.IsValid)
            {
                this.logger.LogTrace("(-)[MODEL_STATE_INVALID]");
                return(ModelStateErrors.BuildErrorResponse(this.ModelState));
            }

            try
            {
                var amount    = Money.Parse(request.Amount);
                var feeAmount = Money.Parse(request.Fees);

                var transaction = this.ColdStakingManager.GetColdStakingSetupTransaction(
                    this.walletTransactionHandler, request.ColdWalletAddress, request.HotWalletAddress,
                    request.WalletName, request.WalletAccount, request.WalletPassword, amount, feeAmount,
                    request.SegwitChangeAddress, request.PayToScript);

                var model = new SetupColdStakingResponse
                {
                    TransactionHex = transaction.ToHex()
                };

                this.logger.LogTrace("(-):'{0}'", model);
                return(Json(model));
            }
            catch (Exception e)
            {
                this.logger.LogError("Exception occurred: {0}", e.ToString());
                this.logger.LogTrace("(-)[ERROR]");
                return(ErrorHelpers.BuildErrorResponse(HttpStatusCode.BadRequest, e.Message, e.ToString()));
            }
        }
Пример #12
0
        protected async Task <IActionResult> Execute <TRequest>(TRequest request, CancellationToken token, Func <TRequest, CancellationToken, Task <IActionResult> > action, bool checkModelState = true)
        {
            if (checkModelState && !this.ModelState.IsValid)
            {
                Guard.NotNull(request, nameof(request));
                this.Logger.LogTrace($"{nameof(request)}(-)[MODEL_STATE_INVALID]");
                return(ModelStateErrors.BuildErrorResponse(this.ModelState));
            }

            try
            {
                return(await action(request, token));
            }
            catch (FeatureException e)
            {
                this.Logger.LogError("Exception occurred: {0}", e.ToString());
                return(e.MapToErrorResponse());
            }
            catch (Exception e)
            {
                this.Logger.LogError("Exception occurred: {0}", e.ToString());
                return(ErrorHelpers.BuildErrorResponse(HttpStatusCode.BadRequest, e.Message, e.ToString()));
            }
        }
        public async Task <IActionResult> GetTransactionAsync(string id)
        {
            if (!this.ModelState.IsValid)
            {
                return(ModelStateErrors.BuildErrorResponse(this.ModelState));
            }

            if (string.IsNullOrWhiteSpace(id))
            {
                throw new ArgumentNullException("id", "id must be specified");
            }

            try
            {
                Transaction trx   = this.blockRepository.GetTransactionById(new uint256(id));
                var         model = new TransactionVerboseModel(trx, this.network);
                return(Json(model));
            }
            catch (Exception e)
            {
                this.logger.LogError("Exception occurred: {0}", e.ToString());
                return(ErrorHelpers.BuildErrorResponse(HttpStatusCode.BadRequest, e.Message, e.ToString()));
            }
        }
        public IActionResult ReplaceFederationMemberIp([FromBody] ReplaceFederationMemberIpModel model)
        {
            if (!this.ModelState.IsValid)
            {
                return(ModelStateErrors.BuildErrorResponse(this.ModelState));
            }

            try
            {
                IPEndPoint endPointToReplace = model.EndPoint.ToIPEndPoint(this.fullNode.Network.DefaultPort);
                IPEndPoint endPointToUse     = model.EndPointToUse.ToIPEndPoint(this.fullNode.Network.DefaultPort);

                if (!this.federatedPegSettings.FederationNodeIpEndPoints.Contains(endPointToReplace))
                {
                    return(this.Json($"{endPointToReplace} does not exist in the federation."));
                }

                this.federatedPegSettings.FederationNodeIpEndPoints.Remove(endPointToReplace);
                this.federatedPegSettings.FederationNodeIpAddresses.Remove(endPointToReplace.Address);

                if (this.federatedPegSettings.FederationNodeIpEndPoints.Contains(endPointToUse))
                {
                    return(this.Json($"{endPointToUse} already exists in the federation."));
                }

                this.federatedPegSettings.FederationNodeIpEndPoints.Add(endPointToUse);
                this.federatedPegSettings.FederationNodeIpAddresses.Add(endPointToUse.Address);

                return(this.Json($"{endPointToReplace} has been replaced with {endPointToUse}."));
            }
            catch (Exception e)
            {
                this.logger.Error("Exception thrown calling /api/FederationGateway/{0}: {1}.", FederationGatewayRouteEndPoint.FederationMemberIpReplace, e.Message);
                return(ErrorHelpers.BuildErrorResponse(HttpStatusCode.BadRequest, e.Message, e.ToString()));
            }
        }
Пример #15
0
        //[ProducesResponseType(typeof(void), 401)]
        public IActionResult GetBlockAsync(string id, [FromQuery] BlockQueryRequest query)
        {
            if (!this.ModelState.IsValid)
            {
                return(ModelStateErrors.BuildErrorResponse(this.ModelState));
            }

            ChainedHeader chainHeader = null;


            if (string.IsNullOrWhiteSpace(id))
            {
                throw new ArgumentNullException("id", "id must be block hash or block height");
            }

            // If the id is more than 50 characters, it is likely hash and not height.
            if (id.Length < 50)
            {
                chainHeader = this.chain.GetHeader(int.Parse(id));
            }
            else
            {
                chainHeader = this.chain.GetHeader(new uint256(id));
            }

            if (chainHeader == null)
            {
                return(new NotFoundObjectResult("Block not found"));
            }

            try
            {
                Block block = this.blockStoreCache.GetBlock(chainHeader.Header.GetHash());

                if (block == null)
                {
                    return(new NotFoundObjectResult("Block not found"));
                }

                PosBlockModel blockModel = new PosBlockModel(block, this.chain);

                if (this.stakeChain != null)
                {
                    BlockStake blockStake = this.stakeChain.Get(chainHeader.HashBlock);

                    if (blockStake != null)
                    {
                        blockModel.StakeTime       = blockStake.StakeTime;
                        blockModel.StakeModifierV2 = blockStake.StakeModifierV2;
                        blockModel.HashProof       = blockStake.HashProof;
                    }
                }

                return(Json(blockModel));
            }
            catch (Exception e)
            {
                this.logger.LogError("Exception occurred: {0}", e.ToString());
                return(ErrorHelpers.BuildErrorResponse(HttpStatusCode.BadRequest, e.Message, e.ToString()));
            }
        }
        public HttpResponseMessage Post([FromBody] CreateChamadaViewModel ViewModel)
        {
            try
            {
                if (ViewModel == null)
                {
                    return(Request.CreateResponse(HttpStatusCode.NotAcceptable, "Campos Inválidos", "text/plain"));
                }
                if (ModelState.IsValid)
                {
                    #region Binance
                    var    userId         = int.Parse(Helper.GetJWTPayloadValue(Request, "id"));
                    var    user           = _UserRepo.GetById(userId);
                    var    chamada        = _ChamadasRepo.GetWith_Symbol_and_Filter(ViewModel.id);
                    var    ordemType      = BinanceHelper.getEntradaOrderType(chamada);
                    string BinanceOrderID = "";
                    if (!BinanceHelper.ValidateFilterPrice(chamada.Symbol.filters.Where(x => x.filterType == "PRICE_FILTER").FirstOrDefault(), ViewModel.qtd))
                    {
                        return(Request.CreateResponse(HttpStatusCode.BadRequest, new BinanceErrors {
                            code = 0, motivo = "Quantidade Inválida"
                        }));
                    }

                    do
                    {
                        BinanceOrderID = Helper.GenerateRandomOcoOrderID(10);
                    } while (_OrdemRepo.IsValidOrderID(BinanceOrderID));

                    HttpResponseMessage BinanceResult = BinanceRestApi.SendOrdemEntrada(user.BinanceAPIKey, user.BinanceAPISecret, ordemType, chamada.Symbol.symbol, ViewModel.qtd, chamada.PrecoEntrada, chamada.RangeEntrada, BinanceOrderID);
                    #endregion
                    if (BinanceResult.IsSuccessStatusCode)
                    {
                        var ordem = new Ordem()
                        {
                            DataCadastro     = DateTime.UtcNow,
                            DataExecucao     = null,
                            Quantidade       = (decimal)ViewModel.qtd,
                            Chamada_Id       = ViewModel.id,
                            Usuario_Id       = user.Id,
                            OrdemStatus_Id   = 1,
                            TipoOrdem_Id     = 1,
                            BinanceStatus_Id = 1,
                            OrderID          = BinanceOrderID
                        };
                        Logs.LogOrdem(user.Id + " (" + user.Email + ") => " + DateTime.UtcNow + " => Type (Aceitar Chamada Sucesso) ChamadaID => " + chamada.Id);
                        _OrdemRepo.Add(ordem);
                        var objanonimo = new
                        {
                            Id           = ordem.Id,
                            TipoOrdem    = 1,
                            Status_id    = ordem.OrdemStatus_Id,
                            DataCadastro = ordem.DataCadastro,
                            Quantidade   = ordem.Quantidade.ToString("N8"),
                            Chamada_Id   = ordem.Chamada_Id,
                            Symbol       = chamada.Symbol.symbol,
                            Descricao    = "Aguardando Entrada",
                            PrecoEntrada = chamada.PrecoEntrada.ToString("N8"),
                            PrecoGain    = chamada.PrecoGain.ToString("N8"),
                            PrecoLoss    = chamada.PrecoLoss.ToString("N8"),
                            RangeEntrada = chamada.RangeEntrada.ToString("N8"),
                            observacao   = chamada.Observacao
                        };
                        //necessario porque o kra pode estar logado no app e na web ao mesmo tempo e tentar enviar nos dois
                        _signalContext.Clients.User(userId.ToString()).RemoverChamada(chamada.Id);
                        _signalContext.Clients.User("admin").AddPosicionado(chamada.Id);
                        return(Request.CreateResponse(HttpStatusCode.OK, objanonimo));
                    }
                    else
                    {
                        var BinanceerrorObj = Helper.GetBinanceErrorObj(BinanceResult);
                        Logs.LogOrdem(user.Id + " (" + user.Email + ") => Type (Aceitar Chamada Erro) ChamadaID => " + chamada.Id + " code => " + BinanceerrorObj.code + " motivo => " + BinanceerrorObj.msg);
                        return(Request.CreateResponse(HttpStatusCode.BadRequest, BinanceerrorObj));
                    }
                }
                var modelstateError = ModelStateErrors.DisplayModelStateError(ModelState);
                return(Request.CreateResponse(HttpStatusCode.NotAcceptable, modelstateError, "text/plain"));
            }
            catch (Exception ex)
            {
                return(Request.CreateResponse(HttpStatusCode.InternalServerError, ex.Message));
            }
        }
Пример #17
0
        public IActionResult UploadWantedSystemMessageAsync([FromBody] UploadWantedSystemMessageRequest request)
        {
            Guard.NotNull(request, nameof(request));

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

            try
            {
                Transaction transaction = this.network.CreateTransaction(request.TransactionHex);

                var wantedMessageOuts = transaction.Outputs.Where(txOut => WantedSystemMessageTemplate.Instance.CheckScriptPubKey(txOut.ScriptPubKey));

                if (wantedMessageOuts.Count() == 0)
                {
                    throw new Exception("The transaction you provided doesn't contain any Wanted System Messages.");
                }

                var wm = this.walletManager as WalletManager;

                WantedSystemMessageModel wsmm = null;

                // let's make sure that the transaction is put into the message store
                wsmm = wm.AddWantedSystemMessageToMessageStore(transaction);

                // add the partially signed transaction to the message store
                // TODO: do not limit this check to the first input
                if (transaction.Inputs[0].ScriptSig.Length > 0)
                {
                    wsmm = wm.AddPartiallySignedTxToMessageStore(transaction);
                }


                // get the reviewer's address details
                var reviewerAddress = wm.ReviewerAddresses[request.ReviewerAddress];
                if (reviewerAddress == null)
                {
                    throw new Exception($"The reviewer '{request.ReviewerAddress}' was not found in the address book.");
                }
                var multiSigParams = PayToMultiSigTemplate.Instance.ExtractScriptPubKeyParameters(reviewerAddress.ScriptPubKey);

                // try to combine the partially signed signatures
                TransactionBuilder tb = new TransactionBuilder(this.network);
                tb.AddCoins((this.walletTransactionHandler as WalletTransactionHandler).GetCoinsForReviewersAddress(reviewerAddress));

                var fullySignedTx = tb.CombineSignatures(wsmm.PartiallySignedTransactions.Select(stx => this.network.CreateTransaction(stx.TransactionHex)).ToArray());
                if (fullySignedTx != null)
                {
                    var checkResults = fullySignedTx.Check();

                    // TODO: do not limit this check to the first input
                    string[] signatures     = fullySignedTx.Inputs[0].ScriptSig.ToString().Split(' ');
                    int      signatureCount = signatures.Count(s => s != "0");

                    if ((checkResults != TransactionCheckResult.Success) || (signatureCount < multiSigParams.SignatureCount))
                    {
                        fullySignedTx = null;
                    }
                }

                // return the fully signed transaction if available
                UploadWantedSystemMessageModel model = new UploadWantedSystemMessageModel
                {
                    WantedSystemMessage       = wsmm,
                    FullySignedTransactionHex = fullySignedTx == null ? "" : fullySignedTx.ToHex()
                };

                return(this.Json(model));
            }
            catch (Exception e)
            {
                this.logger.LogError("Exception occurred: {0}", e.ToString());
                return(ErrorHelpers.BuildErrorResponse(HttpStatusCode.BadRequest, e.Message, e.ToString()));
            }
        }
Пример #18
0
        public IActionResult ListSpendableTransactionOuts([FromBody] ListSpendableTransactionOutsRequest request)
        {
            Guard.NotNull(request, nameof(request));

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

            try
            {
                string requestWalletName  = null;
                string requestAccountName = null;

                if (String.IsNullOrWhiteSpace(request.WalletName) || String.IsNullOrWhiteSpace(request.AccountName))
                {
                    // let's find the proper wallet and account first
                    foreach (var walletName in this.walletManager.GetWalletsNames())
                    {
                        HdAddress address = null;
                        foreach (var hdAccount in this.walletManager.GetWallet(walletName).GetAccountsByCoinType(this.coinType))
                        {
                            address = hdAccount.ExternalAddresses.FirstOrDefault(hdAddress => hdAddress.Address.ToString() == request.Address);
                            if (address == null)
                            {
                                address = hdAccount.InternalAddresses.FirstOrDefault(hdAddress => hdAddress.Address.ToString() == request.Address);
                            }

                            if (address != null)
                            {
                                requestAccountName = hdAccount.Name;
                                break;
                            }
                        }

                        if (requestAccountName != null)
                        {
                            requestWalletName = walletName;
                            break;
                        }
                    }

                    if ((requestWalletName == null) || (requestAccountName == null))
                    {
                        throw new Exception("The address you requested is not in this wallet.");
                    }
                }
                else
                {
                    requestWalletName  = request.WalletName;
                    requestAccountName = request.AccountName;
                }

                WalletAccountReference account = new WalletAccountReference(requestWalletName, requestAccountName);

                List <DetailedSpendableTransactionModel> transactionList = new List <DetailedSpendableTransactionModel>();
                foreach (var spendableOutput in this.walletManager.GetSpendableTransactionsInAccount(account, request.MinConfirmations).OrderByDescending(a => a.Transaction.Amount))
                {
                    if (spendableOutput.Transaction.Amount == 0)
                    {
                        continue;
                    }

                    if (!String.IsNullOrWhiteSpace(request.Address) && (spendableOutput.Address.Address.ToString() != request.Address))
                    {
                        continue;
                    }

                    transactionList.Add(new DetailedSpendableTransactionModel()
                    {
                        Address         = spendableOutput.Address.Address.ToString(),
                        TransactionHash = spendableOutput.Transaction.Id,
                        Index           = spendableOutput.Transaction.Index,
                        Amount          = spendableOutput.Transaction.Amount.Satoshi,
                        ScriptPubKey    = spendableOutput.Transaction.ScriptPubKey.ToHex()
                    });
                }

                ListSpendableTransactionsModel model = new ListSpendableTransactionsModel
                {
                    Network               = this.network.ToString(),
                    WalletName            = account.WalletName,
                    AccountName           = account.AccountName,
                    SpendableTransactions = transactionList
                };

                return(this.Json(model));
            }
            catch (Exception e)
            {
                this.logger.LogError("Exception occurred: {0}", e.ToString());
                return(ErrorHelpers.BuildErrorResponse(HttpStatusCode.BadRequest, e.Message, e.ToString()));
            }
        }
Пример #19
0
        public IActionResult SignWantedSystemMessageAsync([FromBody] SignWantedSystemMessageRequest request)
        {
            Guard.NotNull(request, nameof(request));

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

            try
            {
                // parse the transaction
                Transaction tx = this.network.CreateTransaction(request.TransactionHex);

                // check if we have the message transaction in our message store
                WalletManager wm = this.walletManager as WalletManager;
                if (!wm.WantedSystemMessages.Any(t => t.Key == tx.GetHash()))
                {
                    throw new Exception($"The transcation with hash '{tx.GetHash()}' is not in the message store. You must upload it first by using the upload-wanted-system-message API.");
                }
                //WantedSystemMessageModel wantedMessage = wm.WantedSystemMessages.First(t => t.Key == tx.GetHash()).Value;

                // get the signing keys
                List <BitcoinExtKey> privateKeys = new List <BitcoinExtKey>();
                if (!String.IsNullOrWhiteSpace(request.SigningKey))
                {
                    // parse request.SigningKey into a Bitcoin Private Key
                    try
                    {
                        privateKeys.Add(new BitcoinExtKey(request.SigningKey));
                    }
                    catch
                    {
                        throw new Exception($"The signing key you provided is not in a valid format.");
                    }
                }
                else
                {
                    throw new Exception($"You must provide a signing key in order to sign the message.");

                    // TODO: add our own private keys
                }

                // sign the transaction with the key
                var reviewerAddress = wm.ReviewerAddresses[request.ReviewerAddress];
                if (reviewerAddress == null)
                {
                    throw new Exception($"The reviewer '{request.ReviewerAddress}' was not found in the address book.");
                }

                TransactionBuilder tb = new TransactionBuilder(this.network);
                tb.AddCoins((this.walletTransactionHandler as WalletTransactionHandler).GetCoinsForReviewersAddress(reviewerAddress));
                tb.AddCoins(tx);
                Transaction signedTx = tb.AddKeys(privateKeys.ToArray()).SignTransaction(tx);

                if (signedTx.GetHash() == tx.GetHash())
                {
                    throw new Exception($"The signing key you provided is not associated with the message or it is already signed with that key.");
                }

                // return the (partially) signed transaction
                SignWantedSystemMessageModel model = new SignWantedSystemMessageModel
                {
                    TransactionHex = signedTx.ToHex(),
                    WasSigned      = request.TransactionHex != signedTx.ToHex()
                };

                return(this.Json(model));
            }
            catch (Exception e)
            {
                this.logger.LogError("Exception occurred: {0}", e.ToString());
                return(ErrorHelpers.BuildErrorResponse(HttpStatusCode.BadRequest, e.Message, e.ToString()));
            }
        }
Пример #20
0
        public HttpResponseMessage VenderMercado(int id)
        {
            try
            {
                if (ModelState.IsValid)
                {
                    var userId = int.Parse(Helper.GetJWTPayloadValue(Request, "id"));
                    var user   = _UserRepo.GetById(userId);
                    //alterar pra receber como parametro chamada id
                    var OriginalOrder = _OrdemRepo.GetById(id);
                    var ordem         = _OrdemRepo.GetOcoOrder(userId, OriginalOrder.Chamada_Id);
                    ordem.MotivoCancelamento_ID = 2;
                    _OrdemRepo.Update(ordem);


                    //caso tenha cancelado e tenha dado erro pra criar venda a mercado
                    if (ordem.OrdemStatus_Id == 4 && ordem.BinanceStatus_Id == 4 && ordem.MotivoCancelamento_ID == 2)
                    {
                        string BinanceOrderID;
                        do
                        {
                            BinanceOrderID = Helper.GenerateRandomOcoOrderID(10);
                        } while (_OrdemRepo.IsValidOrderID(BinanceOrderID));
                        var     listAssets      = _OrdemComissionRepo.GetOrderComissions(id);
                        decimal SaldoQuantidade = Helper.ArredondarQuantidadeVenda(listAssets, OriginalOrder);
                        var     resMarket       = BinanceRestApi.VenderMercado(user.BinanceAPIKey, user.BinanceAPISecret, ordem.Chamada.Symbol.symbol, SaldoQuantidade, BinanceOrderID);
                        if (resMarket.IsSuccessStatusCode)
                        {
                            var BinanceContent = resMarket.Content.ReadAsStringAsync().Result;
                            var BinanceResult  = JsonConvert.DeserializeObject <NewOrder>(BinanceContent);
                            var newOrder       = new Ordem
                            {
                                BinanceStatus_Id  = 3,
                                OrdemStatus_Id    = 2,
                                OrderID           = BinanceOrderID,
                                Chamada_Id        = OriginalOrder.Chamada_Id,
                                DataCadastro      = DateTime.UtcNow,
                                TipoOrdem_Id      = 3,
                                Quantidade        = ordem.Quantidade,
                                Usuario_Id        = userId,
                                MainOrderID       = OriginalOrder.Id,
                                PrecoVendaMercado = BinanceResult.fills.FirstOrDefault().price
                            };
                            _OrdemRepo.Add(newOrder);
                            Logs.LogOrdem(user.Id + " (" + user.Email + ") => " + DateTime.UtcNow + " => Type (Vender a Mercado Sucesso) MainOrderId =>  " + OriginalOrder.Id);
                            OriginalOrder.OrdemStatus_Id    = 2;
                            OriginalOrder.BinanceStatus_Id  = 3;
                            OriginalOrder.PrecoVendaMercado = BinanceResult.fills.FirstOrDefault().price;
                            _OrdemRepo.Update(OriginalOrder);
                            return(Request.CreateResponse(HttpStatusCode.OK, OriginalOrder));
                        }
                        else
                        {
                            var BinanceerrorObj = Helper.GetBinanceErrorObj(resMarket);
                            Logs.LogOrdem(user.Id + " (" + user.Email + ") => " + DateTime.UtcNow + " => Type (Vender a Mercado Erro) MainOrderId => " + OriginalOrder.Id + " code => " + BinanceerrorObj.code + " motivo => " + BinanceerrorObj.msg);
                            return(Request.CreateResponse(HttpStatusCode.BadRequest, BinanceerrorObj));
                        }
                    }

                    var res = BinanceRestApi.CancelarOco(user.BinanceAPIKey, user.BinanceAPISecret, ordem.Chamada.Symbol.symbol, ordem.OcoOrderListId);
                    if (res.IsSuccessStatusCode)
                    {
                        ordem.BinanceStatus_Id = 4;
                        ordem.OrdemStatus_Id   = 4;
                        ordem.DataCancelamento = DateTime.UtcNow;
                        _OrdemRepo.Update(ordem);

                        string BinanceOrderID;
                        do
                        {
                            BinanceOrderID = Helper.GenerateRandomOcoOrderID(10);
                        } while (_OrdemRepo.IsValidOrderID(BinanceOrderID));
                        var     listAssets      = _OrdemComissionRepo.GetOrderComissions(id);
                        decimal SaldoQuantidade = Helper.ArredondarQuantidadeVenda(listAssets, OriginalOrder);
                        var     resMarket       = BinanceRestApi.VenderMercado(user.BinanceAPIKey, user.BinanceAPISecret, ordem.Chamada.Symbol.symbol, SaldoQuantidade, BinanceOrderID);
                        if (resMarket.IsSuccessStatusCode)
                        {
                            var BinanceContent = resMarket.Content.ReadAsStringAsync().Result;
                            var BinanceResult  = JsonConvert.DeserializeObject <NewOrder>(BinanceContent);
                            var newOrder       = new Ordem
                            {
                                BinanceStatus_Id  = 3,
                                OrdemStatus_Id    = 2,
                                OrderID           = BinanceOrderID,
                                Chamada_Id        = OriginalOrder.Chamada_Id,
                                DataCadastro      = DateTime.UtcNow,
                                TipoOrdem_Id      = 3,
                                Quantidade        = ordem.Quantidade,
                                Usuario_Id        = userId,
                                MainOrderID       = OriginalOrder.Id,
                                PrecoVendaMercado = BinanceResult.fills.FirstOrDefault().price
                            };
                            _OrdemRepo.Add(newOrder);
                            Logs.LogOrdem(user.Id + " (" + user.Email + ") => " + DateTime.UtcNow + " => Type (Vender a Mercado Sucesso) MainOrderId =>  " + OriginalOrder.Id);
                            OriginalOrder.OrdemStatus_Id    = 2;
                            OriginalOrder.BinanceStatus_Id  = 3;
                            OriginalOrder.PrecoVendaMercado = BinanceResult.fills.FirstOrDefault().price;
                            _OrdemRepo.Update(OriginalOrder);
                            return(Request.CreateResponse(HttpStatusCode.OK, OriginalOrder));
                        }
                        else
                        {
                            var BinanceerrorObj = Helper.GetBinanceErrorObj(resMarket);
                            Logs.LogOrdem(user.Id + " (" + user.Email + ") => " + DateTime.UtcNow + " => Type (Vender a Mercado Erro) MainOrderId => " + OriginalOrder.Id + " code => " + BinanceerrorObj.code + " motivo => " + BinanceerrorObj.msg);
                            return(Request.CreateResponse(HttpStatusCode.BadRequest, BinanceerrorObj));
                        }
                    }
                    else
                    {
                        var BinanceErrorObj = Helper.GetBinanceErrorObj(res);
                        Logs.LogOrdem(user.Id + " (" + user.Email + ") => " + DateTime.UtcNow + " => Type (Erro ao Cancelar Ordem Oco Para Venda a Mercado) OcoOrderListID => " + ordem.OcoOrderListId + " code => " + BinanceErrorObj.code + " motivo => " + BinanceErrorObj.msg);
                        return(Request.CreateResponse(HttpStatusCode.BadRequest, BinanceErrorObj));
                    }
                }
                var modelstateError = ModelStateErrors.DisplayModelStateError(ModelState);
                return(Request.CreateResponse(HttpStatusCode.NotAcceptable, modelstateError, "text/plain"));
            }
            catch (Exception ex)
            {
                return(Request.CreateResponse(HttpStatusCode.InternalServerError, ex.Message));
            }
        }
        public IActionResult SetupOfflineColdStaking([FromBody] SetupOfflineColdStakingRequest request)
        {
            Guard.NotNull(request, nameof(request));

            // Checks the request is valid.
            if (!this.ModelState.IsValid)
            {
                this.logger.LogTrace("(-)[MODEL_STATE_INVALID]");
                return(ModelStateErrors.BuildErrorResponse(this.ModelState));
            }

            try
            {
                Money amount    = Money.Parse(request.Amount);
                Money feeAmount = Money.Parse(request.Fees);

                (Transaction transaction, TransactionBuildContext context) = this.ColdStakingManager.GetColdStakingSetupTransaction(
                    this.walletTransactionHandler,
                    request.ColdWalletAddress,
                    request.HotWalletAddress,
                    request.WalletName,
                    request.WalletAccount,
                    null,
                    amount,
                    feeAmount,
                    request.SubtractFeeFromAmount,
                    true,
                    request.SplitCount,
                    request.SegwitChangeAddress);

                // TODO: We use the same code in the regular wallet for offline signing request construction, perhaps it should be moved to a common method
                // Need to be able to look up the keypath for the UTXOs that were used.
                IEnumerable <UnspentOutputReference> spendableTransactions = this.ColdStakingManager.GetSpendableTransactionsInAccount(
                    new WalletAccountReference(request.WalletName, request.WalletAccount)).ToList();

                var utxos     = new List <UtxoDescriptor>();
                var addresses = new List <AddressDescriptor>();
                foreach (ICoin coin in context.TransactionBuilder.FindSpentCoins(transaction))
                {
                    utxos.Add(new UtxoDescriptor()
                    {
                        Amount        = coin.TxOut.Value.ToUnit(MoneyUnit.BTC).ToString(),
                        TransactionId = coin.Outpoint.Hash.ToString(),
                        Index         = coin.Outpoint.N.ToString(),
                        ScriptPubKey  = coin.TxOut.ScriptPubKey.ToHex()
                    });

                    UnspentOutputReference outputReference = spendableTransactions.FirstOrDefault(u => u.Transaction.Id == coin.Outpoint.Hash && u.Transaction.Index == coin.Outpoint.N);

                    if (outputReference != null)
                    {
                        bool segwit = outputReference.Transaction.ScriptPubKey.IsScriptType(ScriptType.P2WPKH);
                        addresses.Add(new AddressDescriptor()
                        {
                            Address = segwit ? outputReference.Address.Bech32Address : outputReference.Address.Address, AddressType = segwit ? "p2wpkh" : "p2pkh", KeyPath = outputReference.Address.HdPath
                        });
                    }
                }

                // Return transaction hex, UTXO list, address list. The offline signer will infer from the transaction structure that a cold staking setup is being made.
                var model = new BuildOfflineSignResponse()
                {
                    WalletName          = request.WalletName,
                    WalletAccount       = request.WalletAccount,
                    Fee                 = context.TransactionFee.ToUnit(MoneyUnit.BTC).ToString(),
                    UnsignedTransaction = transaction.ToHex(),
                    Utxos               = utxos,
                    Addresses           = addresses
                };

                this.logger.LogTrace("(-):'{0}'", model);
                return(this.Json(model));
            }
            catch (Exception e)
            {
                this.logger.LogError("Exception occurred: {0}", e.ToString());
                this.logger.LogTrace("(-)[ERROR]");
                return(ErrorHelpers.BuildErrorResponse(HttpStatusCode.BadRequest, e.Message, e.ToString()));
            }
        }
        public HttpResponseMessage aceitar([FromBody] AceitarEdicaoViewModel model)
        {
            try
            {
                if (model == null)
                {
                    return(Request.CreateResponse(HttpStatusCode.NotAcceptable, "Campos Inválidos", "text/plain"));
                }
                if (ModelState.IsValid)
                {
                    var userId         = int.Parse(Helper.GetJWTPayloadValue(Request, "id"));
                    var chamadaEditada = _ChamadaEditadaRepo.GetById(model.EdicaoId);
                    var user           = _UserRepo.GetById(userId);
                    var ordem          = _OrdemRepo.GetOcoOrder(userId, model.ChamadaId);
                    ordem.MotivoCancelamento_ID = 3;
                    _OrdemRepo.Update(ordem);

                    //caso tenha cancelado e dado erro pra criar outra oco
                    if (ordem.OrdemStatus_Id == 4 && ordem.BinanceStatus_Id == 4 && ordem.MotivoCancelamento_ID == 3)
                    {
                        string LimitOrderID, StopOrderID;
                        do
                        {
                            LimitOrderID = Helper.GenerateRandomOcoOrderID(10);
                        } while (_OrdemRepo.IsValidOrderID(LimitOrderID));
                        do
                        {
                            StopOrderID = Helper.GenerateRandomOcoOrderID(10);
                        } while (_OrdemRepo.IsValidOrderID(StopOrderID));
                        var limitLoss = Helper.OcoStopLimitWithPercent(ordem.Chamada.Symbol_id, chamadaEditada.NewLoss, 0.5m);
                        //cria uma nova ordem
                        var ocoReturn = BinanceRestApi.SendSaidaOco(user.BinanceAPIKey, user.BinanceAPISecret, ordem.Chamada.Symbol.symbol, ordem.Quantidade, chamadaEditada.NewGain, chamadaEditada.NewLoss, limitLoss, LimitOrderID, StopOrderID);
                        if (ocoReturn.IsSuccessStatusCode)
                        {
                            var edicaoAceita = new EdicaoAceita
                            {
                                Usuario_Id        = userId,
                                TipoEdicao_ID     = 1,
                                DataCadastro      = DateTime.UtcNow,
                                ChamadaEditada_ID = model.EdicaoId,
                                Chamada_ID        = model.ChamadaId
                            };
                            _EdicaoAceitaRepo.Add(edicaoAceita);

                            var ocoRes   = ocoReturn.Content.ReadAsStringAsync().Result;
                            var ocoObj   = JsonConvert.DeserializeObject <dynamic>(ocoRes);
                            var OcoOrder = new Ordem
                            {
                                DataCadastro     = DateTime.UtcNow,
                                DataExecucao     = null,
                                Quantidade       = ordem.Quantidade,
                                Chamada_Id       = ordem.Chamada_Id,
                                Usuario_Id       = user.Id,
                                OrdemStatus_Id   = 3,
                                TipoOrdem_Id     = 2,
                                BinanceStatus_Id = 1,
                                StopOrder_ID     = StopOrderID,
                                LimitOrder_ID    = LimitOrderID,
                                OcoOrderListId   = (string)ocoObj.listClientOrderId,
                                MainOrderID      = ordem.MainOrderID
                            };
                            _OrdemRepo.Add(OcoOrder);

                            var retunrobj = new { PrecoEntrada = ordem.Chamada.PrecoEntrada, NewGain = chamadaEditada.NewGain, NewLoss = chamadaEditada.NewLoss, chamadaId = chamadaEditada.Chamada_Id };
                            Logs.LogOrdem(user.Id + " (" + user.Email + ") => Type (Criar Ordem Editada Sucesso) MainOrderID => " + OcoOrder.MainOrderID);
                            return(Request.CreateResponse(HttpStatusCode.OK, retunrobj));
                        }
                        else
                        {
                            var BinanceErrorObj = Helper.GetBinanceErrorObj(ocoReturn);
                            Logs.LogOrdem(user.Id + " (" + user.Email + ") => Type (Erro ao Criar Ordem Editada) OcoOrderListID => " + ordem.OcoOrderListId + " code => " + BinanceErrorObj.code + " motivo => " + BinanceErrorObj.msg);
                            return(Request.CreateResponse(HttpStatusCode.BadRequest, BinanceErrorObj));
                        }
                    }

                    var res = BinanceRestApi.CancelarOco(user.BinanceAPIKey, user.BinanceAPISecret, ordem.Chamada.Symbol.symbol, ordem.OcoOrderListId);
                    if (res.IsSuccessStatusCode)
                    {
                        ordem.OrdemStatus_Id   = 4;
                        ordem.BinanceStatus_Id = 4;
                        ordem.DataCancelamento = DateTime.UtcNow;
                        _OrdemRepo.Update(ordem);
                        string LimitOrderID, StopOrderID;
                        do
                        {
                            LimitOrderID = Helper.GenerateRandomOcoOrderID(10);
                        } while (_OrdemRepo.IsValidOrderID(LimitOrderID));
                        do
                        {
                            StopOrderID = Helper.GenerateRandomOcoOrderID(10);
                        } while (_OrdemRepo.IsValidOrderID(StopOrderID));
                        var limitLoss = Helper.OcoStopLimitWithPercent(ordem.Chamada.Symbol_id, chamadaEditada.NewLoss, 0.5m);
                        //cria uma nova ordem
                        var ocoReturn = BinanceRestApi.SendSaidaOco(user.BinanceAPIKey, user.BinanceAPISecret, ordem.Chamada.Symbol.symbol, ordem.Quantidade, chamadaEditada.NewGain, chamadaEditada.NewLoss, limitLoss, LimitOrderID, StopOrderID);
                        if (ocoReturn.IsSuccessStatusCode)
                        {
                            var edicaoAceita = new EdicaoAceita
                            {
                                Usuario_Id        = userId,
                                TipoEdicao_ID     = 1,
                                DataCadastro      = DateTime.UtcNow,
                                ChamadaEditada_ID = model.EdicaoId,
                                Chamada_ID        = model.ChamadaId
                            };
                            _EdicaoAceitaRepo.Add(edicaoAceita);

                            var ocoRes   = ocoReturn.Content.ReadAsStringAsync().Result;
                            var ocoObj   = JsonConvert.DeserializeObject <dynamic>(ocoRes);
                            var OcoOrder = new Ordem
                            {
                                DataCadastro     = DateTime.UtcNow,
                                DataExecucao     = null,
                                Quantidade       = ordem.Quantidade,
                                Chamada_Id       = ordem.Chamada_Id,
                                Usuario_Id       = user.Id,
                                OrdemStatus_Id   = 3,
                                TipoOrdem_Id     = 2,
                                BinanceStatus_Id = 1,
                                StopOrder_ID     = StopOrderID,
                                LimitOrder_ID    = LimitOrderID,
                                OcoOrderListId   = (string)ocoObj.listClientOrderId,
                                MainOrderID      = ordem.MainOrderID
                            };
                            _OrdemRepo.Add(OcoOrder);

                            var retunrobj = new { PrecoEntrada = ordem.Chamada.PrecoEntrada, NewGain = chamadaEditada.NewGain, NewLoss = chamadaEditada.NewLoss, chamadaId = chamadaEditada.Chamada_Id };
                            Logs.LogOrdem(user.Id + " (" + user.Email + ") => Type (Criar Ordem Editada Sucesso) => OrderId => " + OcoOrder.Id + " =>  MainOrderID => " + OcoOrder.MainOrderID);
                            return(Request.CreateResponse(HttpStatusCode.OK, retunrobj));
                        }
                        else
                        {
                            var BinanceErrorObj = Helper.GetBinanceErrorObj(ocoReturn);
                            Logs.LogOrdem(user.Id + " (" + user.Email + ") => Type (Erro ao Criar Ordem Editada) OcoOrderListID => " + ordem.OcoOrderListId + " code => " + BinanceErrorObj.code + " motivo => " + BinanceErrorObj.msg);
                            return(Request.CreateResponse(HttpStatusCode.BadRequest, BinanceErrorObj));
                        }
                    }
                    else
                    {
                        var BinanceErrorObj = Helper.GetBinanceErrorObj(res);
                        Logs.LogOrdem(user.Id + " (" + user.Email + ") => Type (Erro ao Cancelar Ordem Para Aceitar Edição) OcoOrderListID => " + ordem.OcoOrderListId + " code => " + BinanceErrorObj.code + " motivo => " + BinanceErrorObj.msg);
                        return(Request.CreateResponse(HttpStatusCode.BadRequest, BinanceErrorObj));
                    }
                }
                var modelstateError = ModelStateErrors.DisplayModelStateError(ModelState);
                return(Request.CreateResponse(HttpStatusCode.NotAcceptable, modelstateError, "text/plain"));
            }
            catch (Exception ex)
            {
                return(Request.CreateResponse(HttpStatusCode.InternalServerError, ex.Message));
            }
        }
Пример #23
0
 /// <summary>
 ///     Add a list of errors to model state
 /// </summary>
 /// <param name="error"></param>
 public void AddModelStateError(string error)
 {
     ModelStateErrors.Add(error);
 }
Пример #24
0
        public IActionResult GetBlock([FromQuery] SearchByHashRequest query)
        {
            if (!this.ModelState.IsValid)
            {
                return(ModelStateErrors.BuildErrorResponse(this.ModelState));
            }

            try
            {
                uint256 blockId = uint256.Parse(query.Hash);

                ChainedHeader chainedHeader = this.chainIndexer.GetHeader(blockId);

                if (chainedHeader == null)
                {
                    return(this.Ok("Block not found"));
                }

                Block block = chainedHeader.Block ?? this.blockStore.GetBlock(blockId);

                // In rare occasions a block that is found in the
                // indexer may not have been pushed to the store yet.
                if (block == null)
                {
                    return(this.Ok("Block not found"));
                }

                if (!query.OutputJson)
                {
                    return(this.Json(block));
                }

                BlockModel blockModel = query.ShowTransactionDetails
                    ? new BlockTransactionDetailsModel(block, chainedHeader, this.chainIndexer.Tip, this.network)
                    : new BlockModel(block, chainedHeader, this.chainIndexer.Tip, this.network);

                if (this.network.Consensus.IsProofOfStake)
                {
                    var posBlock = block as PosBlock;

                    blockModel.PosBlockSignature = posBlock.BlockSignature.ToHex(this.network.Consensus.ConsensusFactory);
                    blockModel.PosBlockTrust     = new Target(chainedHeader.GetBlockTarget()).ToUInt256().ToString();
                    blockModel.PosChainTrust     = chainedHeader.ChainWork.ToString(); // this should be similar to ChainWork

                    if (this.stakeChain != null)
                    {
                        BlockStake blockStake = this.stakeChain.Get(blockId);

                        blockModel.PosModifierv2 = blockStake?.StakeModifierV2.ToString();
                        blockModel.PosFlags      = blockStake?.Flags == BlockFlag.BLOCK_PROOF_OF_STAKE ? "proof-of-stake" : "proof-of-work";
                        blockModel.PosHashProof  = blockStake?.HashProof.ToString();
                    }
                }

                return(this.Json(blockModel));
            }
            catch (Exception e)
            {
                this.logger.LogError("Exception occurred: {0}", e.ToString());
                return(ErrorHelpers.BuildErrorResponse(HttpStatusCode.BadRequest, e.Message, e.ToString()));
            }
        }
Пример #25
0
        public IActionResult SendWantedSystemMessageAsync([FromBody] SendWantedSystemMessageRequest request)
        {
            Guard.NotNull(request, nameof(request));

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

            if (!this.connectionManager.ConnectedPeers.Any())
            {
                throw new WalletException("Can't send transaction: sending transaction requires at least one connection!");
            }

            try
            {
                Transaction transaction = this.network.CreateTransaction(request.Hex);

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

                foreach (var output in transaction.Outputs)
                {
                    if (WantedSystemMessageTemplate.Instance.CheckScriptPubKey(output.ScriptPubKey))
                    {
                        model.Outputs.Add(new TransactionOutputModel
                        {
                            Address = $"N/A (Wanted System Message)",
                            Amount  = output.Value
                        });
                    }
                    else
                    {
                        model.Outputs.Add(new TransactionOutputModel
                        {
                            Address = output.ScriptPubKey.GetDestinationAddress(this.network).ToString(),
                            Amount  = output.Value
                        });
                    }
                }

                if (transaction.Inputs.All(tri => String.IsNullOrEmpty(tri.ScriptSig.ToString())))
                {
                    throw new Exception("This transcation is not signed. In order to publish a transaction on the network, it must be fully signed first.");
                }

                if (transaction.Inputs.Any(tri => String.IsNullOrEmpty(tri.ScriptSig.ToString())))
                {
                    throw new Exception("This transcation is only partially signed. In order to publish a transaction on the network, it must be fully signed first.");
                }

                this.walletManager.ProcessTransaction(transaction, null, null, false);

                this.broadcasterManager.BroadcastTransactionAsync(transaction).GetAwaiter().GetResult();

                return(this.Json(model));
            }
            catch (Exception e)
            {
                this.logger.LogError("Exception occurred: {0}", e.ToString());
                return(ErrorHelpers.BuildErrorResponse(HttpStatusCode.BadRequest, e.Message, e.ToString()));
            }
        }
Пример #26
0
        public IActionResult GetHistory([FromQuery] WalletHistoryRequest request)
        {
            Guard.NotNull(request, nameof(request));

            if (!this.ModelState.IsValid)
            {
                return(ModelStateErrors.BuildErrorResponse(this.ModelState));
            }

            try
            {
                var model = new WalletHistoryModel();

                // Get a list of all the transactions found in an account (or in a wallet if no account is specified), with the addresses associated with them.
                IEnumerable <AccountHistory> accountsHistory = this.walletManager.GetHistory(request.WalletName, request.AccountName);

                foreach (AccountHistory accountHistory in accountsHistory)
                {
                    var transactionItems = new List <TransactionItemModel>();

                    List <FlatHistory> items = accountHistory.History.OrderByDescending(o => o.Transaction.CreationTime).Take(200).ToList();

                    // Represents a sublist containing only the transactions that have already been spent.
                    List <FlatHistory> spendingDetails = items.Where(t => t.Transaction.SpendingDetails != null).ToList();

                    // Represents a sublist of transactions associated with receive addresses + a sublist of already spent transactions associated with change addresses.
                    // In effect, we filter out 'change' transactions that are not spent, as we don't want to show these in the history.
                    List <FlatHistory> history = items.Where(t => !t.Address.IsChangeAddress() || (t.Address.IsChangeAddress() && !t.Transaction.IsSpendable())).ToList();

                    // Represents a sublist of 'change' transactions.
                    List <FlatHistory> allchange = items.Where(t => t.Address.IsChangeAddress()).ToList();

                    foreach (FlatHistory item in history)
                    {
                        TransactionData transaction = item.Transaction;
                        HdAddress       address     = item.Address;

                        // We don't show in history transactions that are outputs of staking transactions.
                        if (transaction.IsCoinStake != null && transaction.IsCoinStake.Value && transaction.SpendingDetails == null)
                        {
                            continue;
                        }

                        // First we look for staking transaction as they require special attention.
                        // A staking transaction spends one of our inputs into 2 outputs, paid to the same address.
                        if (transaction.SpendingDetails?.IsCoinStake != null && transaction.SpendingDetails.IsCoinStake.Value)
                        {
                            // We look for the 2 outputs related to our spending input.
                            List <FlatHistory> relatedOutputs = items.Where(h => h.Transaction.Id == transaction.SpendingDetails.TransactionId && h.Transaction.IsCoinStake != null && h.Transaction.IsCoinStake.Value).ToList();
                            if (relatedOutputs.Any())
                            {
                                // Add staking transaction details.
                                // The staked amount is calculated as the difference between the sum of the outputs and the input and should normally be equal to 1.
                                var stakingItem = new TransactionItemModel
                                {
                                    Type             = TransactionItemType.Staked,
                                    ToAddress        = address.Address,
                                    Amount           = relatedOutputs.Sum(o => o.Transaction.Amount) - transaction.Amount,
                                    Id               = transaction.SpendingDetails.TransactionId,
                                    Timestamp        = transaction.SpendingDetails.CreationTime,
                                    ConfirmedInBlock = transaction.SpendingDetails.BlockHeight
                                };

                                transactionItems.Add(stakingItem);
                            }

                            // No need for further processing if the transaction itself is the output of a staking transaction.
                            if (transaction.IsCoinStake != null)
                            {
                                continue;
                            }
                        }

                        // Create a record for a 'receive' transaction.
                        if (!address.IsChangeAddress())
                        {
                            // Add incoming fund transaction details.
                            var receivedItem = new TransactionItemModel
                            {
                                Type             = TransactionItemType.Received,
                                ToAddress        = address.Address,
                                Amount           = transaction.Amount,
                                Id               = transaction.Id,
                                Timestamp        = transaction.CreationTime,
                                ConfirmedInBlock = transaction.BlockHeight
                            };

                            transactionItems.Add(receivedItem);
                        }

                        // If this is a normal transaction (not staking) that has been spent, add outgoing fund transaction details.
                        if (transaction.SpendingDetails != null && transaction.SpendingDetails.IsCoinStake == null)
                        {
                            // Create a record for a 'send' transaction.
                            uint256 spendingTransactionId = transaction.SpendingDetails.TransactionId;
                            var     sentItem = new TransactionItemModel
                            {
                                Type             = TransactionItemType.Send,
                                Id               = spendingTransactionId,
                                Timestamp        = transaction.SpendingDetails.CreationTime,
                                ConfirmedInBlock = transaction.SpendingDetails.BlockHeight,
                                Amount           = Money.Zero
                            };

                            // If this 'send' transaction has made some external payments, i.e the funds were not sent to another address in the wallet.
                            if (transaction.SpendingDetails.Payments != null)
                            {
                                sentItem.Payments = new List <PaymentDetailModel>();
                                foreach (PaymentDetails payment in transaction.SpendingDetails.Payments)
                                {
                                    sentItem.Payments.Add(new PaymentDetailModel
                                    {
                                        DestinationAddress = payment.DestinationAddress,
                                        Amount             = payment.Amount
                                    });

                                    sentItem.Amount += payment.Amount;
                                }
                            }

                            // Get the change address for this spending transaction.
                            FlatHistory changeAddress = allchange.FirstOrDefault(a => a.Transaction.Id == spendingTransactionId);

                            // Find all the spending details containing the spending transaction id and aggregate the sums.
                            // This is our best shot at finding the total value of inputs for this transaction.
                            var inputsAmount = new Money(spendingDetails.Where(t => t.Transaction.SpendingDetails.TransactionId == spendingTransactionId).Sum(t => t.Transaction.Amount));

                            // The fee is calculated as follows: funds in utxo - amount spent - amount sent as change.
                            sentItem.Fee = inputsAmount - sentItem.Amount - (changeAddress == null ? 0 : changeAddress.Transaction.Amount);

                            // Mined/staked coins add more coins to the total out.
                            // That makes the fee negative. If that's the case ignore the fee.
                            if (sentItem.Fee < 0)
                            {
                                sentItem.Fee = 0;
                            }

                            if (!transactionItems.Contains(sentItem, new SentTransactionItemModelComparer()))
                            {
                                transactionItems.Add(sentItem);
                            }
                        }
                    }

                    model.AccountsHistoryModel.Add(new AccountHistoryModel
                    {
                        TransactionsHistory = transactionItems.OrderByDescending(t => t.Timestamp).ToList(),
                        Name     = accountHistory.Account.Name,
                        CoinType = this.coinType,
                        HdPath   = accountHistory.Account.HdPath
                    });
                }

                return(this.Json(model));
            }
            catch (Exception e)
            {
                this.logger.LogError("Exception occurred: {0}", e.ToString());
                return(ErrorHelpers.BuildErrorResponse(HttpStatusCode.BadRequest, e.Message, e.ToString()));
            }
        }
Пример #27
0
        public IActionResult CreateReviewerAddressAsync([FromBody] CreateReviewerAddressRequest request)
        {
            Guard.NotNull(request, nameof(request));

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

            try
            {
                // calculate the Manager password hash
                byte[] binaryPassword = System.Text.Encoding.ASCII.GetBytes(request.RsaPassword);

                Org.BouncyCastle.Crypto.Digests.Sha512Digest sha = new Org.BouncyCastle.Crypto.Digests.Sha512Digest();
                sha.BlockUpdate(binaryPassword, 0, binaryPassword.Length);

                byte[] shaOutput = new byte[512 / 8];
                sha.DoFinal(shaOutput, 0);

                NBitcoin.DataEncoders.HexEncoder he = new NBitcoin.DataEncoders.HexEncoder();
                string rsaPasswordHashHex           = he.EncodeData(shaOutput);

                // create the multisig address
                PubKey[] groupMemberKeys = request.SignaturePubKeys.Select(pubKeyHex => new PubKey(pubKeyHex)).ToArray();

                var scriptPubKey = PayToMultiSigTemplate
                                   .Instance
                                   .GenerateScriptPubKey(request.RequeiredSignatureCount, groupMemberKeys);

                PublicReviewerAddressModel model = new PublicReviewerAddressModel
                {
                    PublicApiUrl = request.PublicApiUrl
                };

                // check if the API is reachable and the address can be added to the watch list
                Uri apiRequestUri = new Uri(new Uri(model.PublicApiUrl), $"/api/WatchOnlyWallet/watch?address={scriptPubKey.Hash.GetAddress(this.network).ToString()}");
                try
                {
                    HttpWebRequest apiRequest = (HttpWebRequest)WebRequest.Create(apiRequestUri);

                    ASCIIEncoding encoding = new ASCIIEncoding();
                    string        postData = "";
                    byte[]        data     = encoding.GetBytes(postData);

                    apiRequest.Method        = "POST";
                    apiRequest.ContentType   = "application/x-www-form-urlencoded";
                    apiRequest.ContentLength = data.Length;

                    using (Stream stream = apiRequest.GetRequestStream())
                    {
                        stream.Write(data, 0, data.Length);
                    }

                    HttpWebResponse apiResponse = (HttpWebResponse)apiRequest.GetResponse();

                    string responseString = new StreamReader(apiResponse.GetResponseStream()).ReadToEnd();

                    if (apiResponse.StatusCode != HttpStatusCode.OK)
                    {
                        throw new Exception($"The API request '{apiRequestUri.ToString()}' returned the status code '{apiResponse.StatusCode}'.");
                    }
                }
                catch (Exception e)
                {
                    throw new Exception($"The API request '{apiRequestUri.ToString()}' returned an error '{e.Message}'.");
                }


                // generate the RSA keypair for the address
                AsymmetricCipherKeyPair rsaKeyPair = GetRSAKeyPairFromSeed(request.RsaPassword + scriptPubKey.Hash.GetAddress(this.network).ToString());

                RsaKeyParameters rsaPublicKey = rsaKeyPair.Public as RsaKeyParameters;
                RsaPublicKey     pbk          = new RsaPublicKey()
                {
                    Exponent = rsaPublicKey.Exponent.ToByteArrayUnsigned(),
                    Modulus  = rsaPublicKey.Modulus.ToByteArrayUnsigned()
                };

                RsaPrivateCrtKeyParameters rsaPrivateKey = rsaKeyPair.Private as RsaPrivateCrtKeyParameters;
                RsaPrivateKey prk = new RsaPrivateKey()
                {
                    DP             = rsaPrivateKey.DP.ToByteArrayUnsigned(),
                    DQ             = rsaPrivateKey.DQ.ToByteArrayUnsigned(),
                    Exponent       = rsaPrivateKey.Exponent.ToByteArrayUnsigned(),
                    Modulus        = rsaPrivateKey.Modulus.ToByteArrayUnsigned(),
                    P              = rsaPrivateKey.P.ToByteArrayUnsigned(),
                    PublicExponent = rsaPrivateKey.PublicExponent.ToByteArrayUnsigned(),
                    Q              = rsaPrivateKey.Q.ToByteArrayUnsigned(),
                    QInv           = rsaPrivateKey.QInv.ToByteArrayUnsigned()
                };

                // return all the information we have
                model = new PublicReviewerAddressModel
                {
                    Network            = this.network.ToString(),
                    Address            = scriptPubKey.Hash.GetAddress(this.network).ToString(),
                    PublicName         = request.PublicName,
                    GroupName          = request.GroupName,
                    ValidFrom          = request.ValidFrom.ToString("o"),
                    ValidUntil         = request.ValidUntil.ToString("o"),
                    ScriptPubKeyHex    = scriptPubKey.ToHex(),
                    RsaPublicKeyHex    = pbk.ToHex(),
                    RsaPrivateKeyHex   = prk.ToHex(),
                    RsaPasswordHashHex = rsaPasswordHashHex,
                    PublicApiUrl       = request.PublicApiUrl
                };

                ((WalletManager)this.walletManager).AddReviewerAddressToReviewerStore(model);

                return(this.Json(model));
            }
            catch (Exception e)
            {
                this.logger.LogError("Exception occurred: {0}", e.ToString());
                return(ErrorHelpers.BuildErrorResponse(HttpStatusCode.BadRequest, e.Message, e.ToString()));
            }
        }