protected static void CheckPermissions(DecryptedRequest decryptedRequest, SecureApiSettings secureApiSettings)
        {
            if (decryptedRequest == null)
            {
                throw new ArgumentNullException(nameof(decryptedRequest));
            }

            if (!secureApiSettings.IsSecureApiEnabled)
            {
                throw new X1WalletException(HttpStatusCode.Unauthorized,
                                            "SecureApi is disabled by configuration/arguments", null);
            }

            if (string.IsNullOrWhiteSpace(secureApiSettings.SecureApiUser) || string.IsNullOrWhiteSpace(secureApiSettings.SecureApiPassword))
            {
                return;
            }

            var user     = secureApiSettings.SecureApiUser.Trim();
            var password = secureApiSettings.SecureApiPassword.Trim();

            if (user != decryptedRequest.User || password != decryptedRequest.Password)
            {
                throw new X1WalletException(HttpStatusCode.Unauthorized,
                                            "Invalid credentials.", null);
            }
        }
        protected static DecryptedRequest DecryptRequest(RequestObject request, WalletController walletController)
        {
            byte[] decrypted = VCL.Decrypt(request.CipherV2Bytes.FromBase64(), request.CurrentPublicKey.FromBase64(), VCL.ECKeyPair.PrivateKey, AuthKey.PrivateKey);
            if (decrypted == null)
            {
                throw new X1WalletException((HttpStatusCode)427, "Public key changed - please reload", null);
            }
            string           json             = decrypted.FromUTF8Bytes();
            DecryptedRequest decryptedRequest = JsonConvert.DeserializeObject <DecryptedRequest>(json);

            if (((IList)CommandsWithoutWalletNameCheck).Contains(decryptedRequest.Command))
            {
                return(decryptedRequest);
            }
            if (decryptedRequest.Target == null)
            {
                throw new X1WalletException(HttpStatusCode.BadRequest, "No wallet name was supplied.");
            }
            walletController.SetWalletName(decryptedRequest.Target.Replace($".{walletController.CoinTicker}{X1WalletFile.FileExtension}", ""));
            return(decryptedRequest);
        }
        public async Task <ECCModel> ExecuteAsync([FromBody] RequestObject request)
        {
            if (AuthKey == null)
            {
                this.Response.StatusCode = 403;
                return(null);
            }

            try
            {
                if (IsRequestForPublicKey(request))
                {
                    return(CreatePublicKey());
                }

                DecryptedRequest decryptedRequest = DecryptRequest(request, this.walletController);
                CheckPermissions(decryptedRequest, this.secureApiSettings);

                switch (decryptedRequest.Command)
                {
                case "createWallet":
                {
                    WalletCreateRequest walletCreateRequest = Deserialize <WalletCreateRequest>(decryptedRequest.Payload);
                    this.walletController.CreateWallet(walletCreateRequest);
                    return(CreateOk(request));
                }

                case "loadWallet":
                {
                    LoadWalletResponse loadWalletResponse = this.walletController.LoadWallet();
                    return(CreateOk(loadWalletResponse, request));
                }

                case "daemonInfo":     // one-time information about the running daemon, includes list of wallet files
                {
                    DaemonInfo daemonStatus = this.walletController.GetDaemonInfo();
                    return(CreateOk(daemonStatus, request));
                }

                case "walletInfo":     // does not depend on weather a wallet is loaded, but if a wallet is loaded, it includes all wallet info, including balance and staking info when enabled
                {
                    WalletInfo walletInfo = this.walletController.GetWalletInfo();
                    return(CreateOk(walletInfo, request));
                }

                case "historyInfo":
                {
                    var         historyRequest = Deserialize <HistoryRequest>(decryptedRequest.Payload);
                    HistoryInfo historyInfo    = this.walletController.GetHistoryInfo(historyRequest);
                    return(CreateOk(historyInfo, request));
                }

                case "getReceiveAddresses":
                {
                    var getAddressesRequest = Deserialize <GetAddressesRequest>(decryptedRequest.Payload);
                    GetAddressesResponse getAddressesResponse = this.walletController.GetUsedReceiveAddresses(getAddressesRequest);
                    return(CreateOk(getAddressesResponse, request));
                }

                case "createReceiveAddress":
                {
                    var createReceiveAddressRequest             = Deserialize <CreateReceiveAddressRequest>(decryptedRequest.Payload);
                    CreateReceiveAddressResponse addressesModel = this.walletController.CreateReceiveAddress(createReceiveAddressRequest);
                    return(CreateOk(addressesModel, request));
                }

                case "estimateFee":
                {
                    var  txFeeEstimateRequest = Deserialize <TransactionRequest>(decryptedRequest.Payload);
                    long fee = this.walletController.EstimateFee(txFeeEstimateRequest);
                    return(CreateOk(fee, request));
                }

                case "buildTransaction":
                {
                    var buildTransactionRequest             = Deserialize <TransactionRequest>(decryptedRequest.Payload);
                    TransactionResponse transactionResponse = this.walletController.BuildTransaction(buildTransactionRequest);
                    return(CreateOk(transactionResponse, request));
                }

                case "repair":
                {
                    var walletSyncFromDateRequest = Deserialize <RepairRequest>(decryptedRequest.Payload);
                    this.walletController.Repair(walletSyncFromDateRequest);
                    return(CreateOk(request));
                }

                case "importKeys":
                {
                    var importKeysRequest  = Deserialize <ImportKeysRequest>(decryptedRequest.Payload);
                    var importKeysResponse = this.walletController.ImportKeys(importKeysRequest);
                    return(CreateOk(importKeysResponse, request));
                }

                case "exportKeys":
                {
                    var exportKeysRequest  = Deserialize <ExportKeysRequest>(decryptedRequest.Payload);
                    var exportKeysResponse = this.walletController.ExportKeys(exportKeysRequest);
                    return(CreateOk(exportKeysResponse, request));
                }

                case "startStaking":
                {
                    var startStakingRequest = Deserialize <StartStakingRequest>(decryptedRequest.Payload);
                    this.walletController.StartStaking(startStakingRequest);
                    return(CreateOk(request));
                }

                case "stopStaking":
                {
                    this.walletController.StopStaking();
                    return(CreateOk(request));
                }

                default:
                    throw new NotSupportedException($"The command '{decryptedRequest.Command}' is not supported.");
                }
            }
            catch (Exception e)
            {
                return(CreateError(e, request));
            }
        }