public virtual async Task <IActionResult> CreateRecipe(CreateRecipeViewModel viewModel)
        {
            if (!ModelState.IsValid)
            {
                return(this.ViewOrBadRequest(viewModel));
            }

            var recipe = new Recipe()
            {
                Enabled     = false,
                Name        = viewModel.Name,
                Description = viewModel.Description,
                UserId      = GetUserId()
            };
            await _recipeManager.AddOrUpdateRecipe(recipe);

            if (string.IsNullOrEmpty(recipe.Id))
            {
                ModelState.AddModelError(string.Empty, "Could not save recipe");
                return(this.ViewOrBadRequest(viewModel));
            }

            if (this.IsApi())
            {
                return(await EditRecipe(recipe.Id, (string)null));
            }
            return(RedirectToAction("EditRecipe", new { id = recipe.Id, statusMessage = "Recipe created" }));
        }
Esempio n. 2
0
        private async Task <IActionResult> SetItUp(CreateDCAViewModel vm)
        {
            var presetName = $"Generated_DCA";

            var recipe = new Recipe()
            {
                Name        = presetName,
                Description = "Generated from a preset",
                UserId      = _userManager.GetUserId(User),
                Enabled     = false
            };
            await _recipeManager.AddOrUpdateRecipe(recipe);

            var recipeTrigger = new RecipeTrigger()
            {
                TriggerId = new TimerTrigger().Id,
                RecipeId  = recipe.Id
            };

            recipeTrigger.Set(new TimerTriggerParameters()
            {
                StartOn            = vm.StartOn,
                TriggerEvery       = vm.TriggerEvery,
                TriggerEveryAmount = vm.TriggerEveryAmount
            });
            await _recipeManager.AddOrUpdateRecipeTrigger(recipeTrigger);

            var recipeActionGroup = new RecipeActionGroup()
            {
                RecipeId = recipe.Id
            };

            await _recipeManager.AddRecipeActionGroup(recipeActionGroup);

            var tradeAction = new RecipeAction()
            {
                RecipeId            = recipe.Id,
                RecipeActionGroupId = recipeActionGroup.Id,
                ActionId            = new PlaceOrderDataActionHandler().ActionId,
                ExternalServiceId   = vm.SelectedExchangeServiceId,
                Order    = 0,
                DataJson = JsonConvert.SerializeObject(new PlaceOrderData()
                {
                    Amount       = vm.FiatAmount.ToString(CultureInfo.InvariantCulture),
                    IsBuy        = vm.IsBuy,
                    MarketSymbol = vm.MarketSymbol,
                    OrderType    = OrderType.Market
                })
            };

            await _recipeManager.AddOrUpdateRecipeAction(tradeAction);


            return(RedirectToAction("EditRecipe", "Recipes", new
            {
                id = recipe.Id,
                statusMessage =
                    "Preset generated. Recipe is currently disabled for now. Please verify details are correct before enabling!"
            }));
        }
        private async Task <IActionResult> SetItUp(CreatePaymentForwarderViewModel vm)
        {
            var client     = _nbXplorerClientProvider.GetClient(vm.CryptoCode);
            var presetName = $"Generated_PaymentForwarder_{vm.CryptoCode}";
            var sourceExternalServiceId = vm.SelectedSourceWalletExternalServiceId;

            if (vm.GenerateSourceWallet)
            {
                var genResponse = await client.GenerateWalletAsync(new GenerateWalletRequest()
                {
                    ScriptPubKeyType = client.Network.NBitcoinNetwork.Consensus.SupportSegwit
                        ? ScriptPubKeyType.SegwitP2SH
                        : ScriptPubKeyType.Legacy,
                });

                var data = new NBXplorerWalletExternalServiceData()
                {
                    CryptoCode         = vm.CryptoCode,
                    DerivationStrategy = genResponse.DerivationScheme.ToString(),
                    PrivateKeys        = new List <PrivateKeyDetails>()
                    {
                        new PrivateKeyDetails()
                        {
                            MnemonicSeed = genResponse.Mnemonic
                        }
                    }
                };

                var sourceWallet = new ExternalServiceData()
                {
                    Name     = presetName + "_Source_Wallet",
                    UserId   = _userManager.GetUserId(User),
                    Type     = NBXplorerWalletService.NBXplorerWalletServiceType,
                    DataJson = client.Serializer.ToString(data)
                };
                await _externalServiceManager.AddOrUpdateExternalServiceData(sourceWallet);

                sourceExternalServiceId = sourceWallet.Id;
            }

            var recipe = new Recipe()
            {
                Name        = presetName,
                Description = "Generated from a preset",
                UserId      = _userManager.GetUserId(User),
                Enabled     = false
            };
            await _recipeManager.AddOrUpdateRecipe(recipe);

            var recipeTrigger = new RecipeTrigger()
            {
                ExternalServiceId = sourceExternalServiceId,
                TriggerId         = NBXplorerBalanceTrigger.Id,
                RecipeId          = recipe.Id,
                DataJson          = client.Serializer.ToString(new NBXplorerBalanceTriggerParameters()
                {
                    BalanceValue    = vm.SendEntireBalance ? 0 : vm.SendBalanceValue,
                    BalanceComparer = vm.SendEntireBalance
                        ? BalanceComparer.GreaterThan
                        : BalanceComparer.GreaterThanOrEqual,
                    BalanceMoneyUnit = vm.SendBalanceMoneyUnit
                })
            };

            await _recipeManager.AddOrUpdateRecipeTrigger(recipeTrigger);

            var recipeActionGroup = new RecipeActionGroup()
            {
                RecipeId = recipe.Id
            };
            await _recipeManager.AddRecipeActionGroup(recipeActionGroup);

            var recipeActionGroupIndex = 0;
            var ouputs = new List <SendTransactionData.TransactionOutput>();

            foreach (var paymentDestination in vm.PaymentDestinations)
            {
                var destinationExternalServiceId        = paymentDestination.SelectedDestinationWalletExternalServiceId;
                NBXplorerWalletExternalServiceData data = null;

                if (string.IsNullOrEmpty(destinationExternalServiceId))
                {
                    data = new NBXplorerWalletExternalServiceData()
                    {
                        CryptoCode         = vm.CryptoCode,
                        Address            = paymentDestination.DestinationAddress,
                        DerivationStrategy = paymentDestination.DerivationStrategy,
                    };

                    var wallet = new ExternalServiceData()
                    {
                        Name     = presetName + $"_Dest_Wallet_{data.DerivationStrategy}",
                        UserId   = _userManager.GetUserId(User),
                        Type     = NBXplorerWalletService.NBXplorerWalletServiceType,
                        DataJson = client.Serializer.ToString(data)
                    };
                    await _externalServiceManager.AddOrUpdateExternalServiceData(wallet);

                    destinationExternalServiceId = wallet.Id;
                }
                else
                {
                    var service = vm.Services.Items.Cast <ExternalServiceData>()
                                  .Single(serviceData => serviceData.Id == destinationExternalServiceId);
                    data = new NBXplorerWalletService(service, _nbXplorerPublicWalletProvider, _derivationSchemeParser, _nbXplorerClientProvider).GetData();
                }

                var recipeAction = new RecipeAction()
                {
                    RecipeId            = recipe.Id,
                    RecipeActionGroupId = recipeActionGroup.Id,
                    ActionId            = new GenerateNextAddressDataActionHandler().ActionId,
                    ExternalServiceId   = destinationExternalServiceId,
                    Order    = recipeActionGroupIndex,
                    DataJson = JsonConvert.SerializeObject(new GenerateNextAddressData())
                };
                await _recipeManager.AddOrUpdateRecipeAction(recipeAction);

                var noDecimalParse = paymentDestination.AmountPercentage / 100;
                ouputs.Add(new SendTransactionData.TransactionOutput()
                {
                    DestinationAddress     = "{{ActionData" + recipeActionGroupIndex + "}}",
                    Amount                 = "{{TriggerData.Balance.ToDecimal(MoneyUnit.BTC) * " + noDecimalParse + "}}",
                    SubtractFeesFromOutput = paymentDestination.SubtractFeesFromOutput
                });

                recipeActionGroupIndex++;
            }

            var sweepRecipeAction = new RecipeAction()
            {
                RecipeId            = recipe.Id,
                RecipeActionGroupId = recipeActionGroup.Id,
                ActionId            = new SendTransactionDataActionHandler().ActionId,
                ExternalServiceId   = sourceExternalServiceId,
                Order    = recipeActionGroupIndex,
                DataJson = JsonConvert.SerializeObject(new SendTransactionData()
                {
                    Outputs = ouputs
                })
            };

            await _recipeManager.AddOrUpdateRecipeAction(sweepRecipeAction);

            return(RedirectToAction("EditRecipe", "Recipes", new
            {
                id = recipe.Id,
                statusMessage =
                    "Preset generated. Recipe is currently disabled for now. Please verify details are correct before enabling!"
            }));
        }
        private async Task <IActionResult> SetItUp(CreateFiatExchangeConversionViewModel vm)
        {
            var presetName = $"Generated_FiatExchangeConversion";

            var recipe = new Recipe()
            {
                Name        = presetName,
                Description = "Generated from a preset",
                UserId      = _userManager.GetUserId(User),
                Enabled     = false
            };
            await _recipeManager.AddOrUpdateRecipe(recipe);

            var recipeTrigger = new RecipeTrigger()
            {
                ExternalServiceId = vm.SelectedBTCPayExternalServiceId,
                TriggerId         = new InvoiceStatusChangedTrigger().Id,
                RecipeId          = recipe.Id
            };

            recipeTrigger.Set(new InvoiceStatusChangedTriggerParameters()
            {
                Conditions = new List <InvoiceStatusChangeCondition>()
                {
                    new InvoiceStatusChangeCondition()
                    {
                        Status            = vm.Status,
                        ExceptionStatuses = InvoiceStatusChangedController.AllowedExceptionStatus.Select(item => item.Value).ToList()
                    }
                }
            });
            await _recipeManager.AddOrUpdateRecipeTrigger(recipeTrigger);

            var recipeActionGroup = new RecipeActionGroup()
            {
                RecipeId = recipe.Id
            };

            foreach (var condition in vm.Conditions)
            {
                await _recipeManager.AddRecipeActionGroup(recipeActionGroup);

                var recipeActionGroupIndex = 0;
                var getPayments            = new RecipeAction()
                {
                    RecipeId            = recipe.Id,
                    RecipeActionGroupId = recipeActionGroup.Id,
                    ActionId            = new GetPaymentsFromInvoiceDataActionHandler().ActionId,
                    ExternalServiceId   = vm.SelectedBTCPayExternalServiceId,
                    Order    = recipeActionGroupIndex,
                    DataJson = JsonConvert.SerializeObject(new GetPaymentsFromInvoiceData()
                    {
                        CryptoCode  = condition.CryptoCode,
                        InvoiceId   = "{{TriggerData.Invoice.Id}}",
                        PaymentType = ""
                    })
                };
                recipeActionGroupIndex++;
                await _recipeManager.AddOrUpdateRecipeAction(getPayments);

                var tradeAction = new RecipeAction()
                {
                    RecipeId            = recipe.Id,
                    RecipeActionGroupId = recipeActionGroup.Id,
                    ActionId            = new PlaceOrderDataActionHandler().ActionId,
                    ExternalServiceId   = condition.ExchangeServiceId,
                    Order    = recipeActionGroupIndex,
                    DataJson = JsonConvert.SerializeObject(new PlaceOrderData()
                    {
                        Amount       = "{{PreviousAction.Sum(" + nameof(InvoicePaymentInfo.Value) + ")}}",
                        IsBuy        = condition.IsBuy,
                        MarketSymbol = condition.MarketSymbol,
                        OrderType    = OrderType.Market
                    })
                };

                recipeActionGroupIndex++;
                await _recipeManager.AddOrUpdateRecipeAction(tradeAction);
            }

            return(RedirectToAction("EditRecipe", "Recipes", new
            {
                id = recipe.Id,
                statusMessage =
                    "Preset generated. Recipe is currently disabled for now. Please verify details are correct before enabling!"
            }));
        }
        private async Task <IActionResult> SetItUp(CreateBTCPayEmailReceiptsViewModel vm)
        {
            var presetName = $"Generated_BTCPayEmailReceipts_{vm.Status}";

            var recipe = new Recipe()
            {
                Name        = presetName,
                Description = "Generated from a preset",
                UserId      = _userManager.GetUserId(User),
                Enabled     = false
            };
            await _recipeManager.AddOrUpdateRecipe(recipe);

            var recipeTrigger = new RecipeTrigger()
            {
                ExternalServiceId = vm.SelectedBTCPayExternalServiceId,
                TriggerId         = new InvoiceStatusChangedTrigger().Id,
                RecipeId          = recipe.Id
            };

            recipeTrigger.Set(new InvoiceStatusChangedTriggerParameters()
            {
                Conditions = new List <InvoiceStatusChangeCondition>()
                {
                    new InvoiceStatusChangeCondition()
                    {
                        Status            = vm.Status,
                        ExceptionStatuses = InvoiceStatusChangedController.AllowedExceptionStatus.Select(item => item.Value).ToList()
                    }
                }
            });
            await _recipeManager.AddOrUpdateRecipeTrigger(recipeTrigger);

            var recipeActionGroup = new RecipeActionGroup()
            {
                RecipeId = recipe.Id
            };
            await _recipeManager.AddRecipeActionGroup(recipeActionGroup);

            var recipeActionGroupIndex = 0;

            if (vm.SendToCustomer)
            {
                var sendEmailAction = new RecipeAction()
                {
                    RecipeId            = recipe.Id,
                    RecipeActionGroupId = recipeActionGroup.Id,
                    ActionId            = new SendEmailDataActionHandler().ActionId,
                    ExternalServiceId   = vm.SelectedSMTPExternalServiceId,
                    Order    = recipeActionGroupIndex,
                    DataJson = JsonConvert.SerializeObject(new SendEmailData()
                    {
                        IsHTML  = true,
                        Body    = vm.HTMLBody,
                        Subject = vm.Subject,
                        From    = vm.From,
                        To      = "{{TriggerData.Invoice.Buyer.email}}"
                    })
                };
                await _recipeManager.AddOrUpdateRecipeAction(sendEmailAction);

                recipeActionGroupIndex++;
            }
            if (!string.IsNullOrEmpty(vm.AlternateEmail))
            {
                var sendEmailAction = new RecipeAction()
                {
                    RecipeId            = recipe.Id,
                    RecipeActionGroupId = recipeActionGroup.Id,
                    ActionId            = new SendEmailDataActionHandler().ActionId,
                    ExternalServiceId   = vm.SelectedSMTPExternalServiceId,
                    Order    = recipeActionGroupIndex,
                    DataJson = JsonConvert.SerializeObject(new SendEmailData()
                    {
                        IsHTML  = true,
                        Body    = vm.HTMLBody,
                        Subject = vm.Subject,
                        From    = vm.From,
                        To      = vm.AlternateEmail
                    })
                };
                await _recipeManager.AddOrUpdateRecipeAction(sendEmailAction);

                recipeActionGroupIndex++;
            }


            return(RedirectToAction("EditRecipe", "Recipes", new
            {
                id = recipe.Id,
                statusMessage =
                    "Preset generated. Recipe is currently disabled for now. Please verify details are correct before enabling!"
            }));
        }