private DerivationSchemeSettings ParseDerivationStrategy(string derivationScheme, Script hint, BTCPayNetwork network)
        {
            var parser = new DerivationSchemeParser(network);

            parser.HintScriptPubKey = hint;
            return(new DerivationSchemeSettings(parser.Parse(derivationScheme), network));
        }
예제 #2
0
        private DerivationStrategy ParseDerivationStrategy(string derivationScheme, Script hint, BTCPayNetwork network)
        {
            var parser = new DerivationSchemeParser(network.NBitcoinNetwork, network.DefaultSettings.ChainType);

            parser.HintScriptPubKey = hint;
            return(new DerivationStrategy(parser.Parse(derivationScheme), network));
        }
        public async Task <NBXplorerPublicWallet> ConstructClient()
        {
            var data = GetData();

            var explorerClient = _nbXplorerClientProvider.GetClient(data.CryptoCode);
            var factory        = explorerClient.Network.DerivationStrategyFactory;

            if (string.IsNullOrEmpty(data
                                     .DerivationStrategy))
            {
                return(await _nbXplorerPublicWalletProvider.Get(data.CryptoCode,
                                                                BitcoinAddress.Create(
                                                                    data.Address,
                                                                    explorerClient.Network.NBitcoinNetwork)));
            }
            else
            {
                return(await _nbXplorerPublicWalletProvider.Get(data.CryptoCode,
                                                                _derivationSchemeParser.Parse(factory,
                                                                                              data.DerivationStrategy)));
            }
        }
        public async Task <IActionResult> Create(CreatePaymentForwarderViewModel viewModel)
        {
            var services = await _externalServiceManager.GetExternalServicesData(new ExternalServicesDataQuery()
            {
                UserId = _userManager.GetUserId(User),
                Type   = new[] { NBXplorerWalletService.NBXplorerWalletServiceType }
            });

            if (services.Any())
            {
                var newServices = services.ToList();
                newServices.Insert(0, new ExternalServiceData()
                {
                    Id   = null,
                    Name = "None"
                });
                services = newServices;
            }

            viewModel.Services =
                new SelectList(services, nameof(ExternalServiceData.Id), nameof(ExternalServiceData.Name));
            viewModel.CryptoCodes = new SelectList(_nbXplorerOptions.Cryptos?.ToList() ?? new List <string>(),
                                                   viewModel.CryptoCode);
            viewModel.PaymentDestinations = viewModel.PaymentDestinations ??
                                            new List <CreatePaymentForwarderViewModel.PaymentDestination>();

            if (!string.IsNullOrEmpty(viewModel.Action))
            {
                if (viewModel.Action == "add-destination")
                {
                    viewModel.PaymentDestinations.Add(new CreatePaymentForwarderViewModel.PaymentDestination());
                    return(View(viewModel));
                }

                if (viewModel.Action.StartsWith("remove-destination", StringComparison.InvariantCultureIgnoreCase))
                {
                    var index = int.Parse(viewModel.Action.Substring(viewModel.Action.IndexOf(":") + 1));
                    viewModel.PaymentDestinations.RemoveAt(index);
                    return(View(viewModel));
                }
            }

            if ((string.IsNullOrEmpty(viewModel.SelectedSourceWalletExternalServiceId) &&
                 !viewModel.GenerateSourceWallet) ||
                !string.IsNullOrEmpty(viewModel.SelectedSourceWalletExternalServiceId) &&
                viewModel.GenerateSourceWallet)
            {
                if (viewModel.Services.Items.Any())
                {
                    ModelState.AddModelError(nameof(viewModel.SelectedSourceWalletExternalServiceId),
                                             "Please select a source nbxplorer wallet OR check the generate wallet checkbox");
                }

                ModelState.AddModelError(nameof(viewModel.GenerateSourceWallet),
                                         "Please select a source nbxplorer wallet OR check the generate wallet checkbox");
            }
            else if (!string.IsNullOrEmpty(viewModel.SelectedSourceWalletExternalServiceId))
            {
                var service = services.SingleOrDefault(data =>
                                                       data.Id == viewModel.SelectedSourceWalletExternalServiceId);
                if (service == null)
                {
                    viewModel.AddModelError(
                        nameof(viewModel.SelectedSourceWalletExternalServiceId),
                        "Wallet chosen is wrong... ヽ༼ ಠ益ಠ ༽ノ ", ModelState);
                }
                else
                {
                    var data = new NBXplorerWalletService(service, _nbXplorerPublicWalletProvider,
                                                          _derivationSchemeParser, _nbXplorerClientProvider).GetData();
                    if (data.CryptoCode != viewModel.CryptoCode)
                    {
                        viewModel.AddModelError(
                            nameof(viewModel.SelectedSourceWalletExternalServiceId),
                            "Wallet chosen not the same crypto", ModelState);
                    }
                    else if (!data.PrivateKeys.Any())
                    {
                        viewModel.AddModelError(
                            nameof(viewModel.SelectedSourceWalletExternalServiceId),
                            "Wallet chosen has so signing keys which would make forwarding txs impossible", ModelState);
                    }
                }
            }

            if (!viewModel.PaymentDestinations.Any())
            {
                ModelState.AddModelError(string.Empty,
                                         "Please add at least one transaction destination");
            }
            else
            {
                var totalSumIssue = viewModel.PaymentDestinations.Sum(output => output.AmountPercentage) > 100;


                var subtractFeesOutputs = viewModel.PaymentDestinations.Select((output, i) => (output, i))
                                          .Where(tuple => tuple.Item1.SubtractFeesFromOutput);

                if (subtractFeesOutputs.Count() > 1)
                {
                    foreach (var subtractFeesOutput in subtractFeesOutputs)
                    {
                        viewModel.AddModelError(
                            nameof(CreatePaymentForwarderViewModel.PaymentDestination.SubtractFeesFromOutput),
                            "You can only subtract fees from one destination", ModelState);
                    }
                }

                for (var index = 0; index < viewModel.PaymentDestinations.Count; index++)
                {
                    if (totalSumIssue)
                    {
                        viewModel.AddModelError(
                            nameof(CreatePaymentForwarderViewModel.PaymentDestination.AmountPercentage),
                            "Your total amounts across all outputs exceeds 100%. We're not a central bank and can't print more money than you own, sorry.",
                            ModelState);
                    }

                    var viewModelPaymentDestination = viewModel.PaymentDestinations[index];

                    var check =
                        (string.IsNullOrEmpty(viewModelPaymentDestination.DerivationStrategy) ? 0 : 1) +
                        (string.IsNullOrEmpty(viewModelPaymentDestination.DestinationAddress) ? 0 : 1) +
                        (string.IsNullOrEmpty(viewModelPaymentDestination.SelectedDestinationWalletExternalServiceId)
                            ? 0
                            : 1);
                    if (check != 1)
                    {
                        viewModel.AddModelError(
                            nameof(CreatePaymentForwarderViewModel.PaymentDestination.DestinationAddress),
                            "Please choose to track either an address OR a derivation scheme OR an existing NBXplorer Wallet External Service",
                            ModelState);
                        viewModel.AddModelError(
                            nameof(CreatePaymentForwarderViewModel.PaymentDestination.DerivationStrategy),
                            "Please choose to track either an address OR a derivation scheme OR an existing NBXplorer Wallet External Service",
                            ModelState);
                        viewModel.AddModelError(
                            nameof(CreatePaymentForwarderViewModel.PaymentDestination.SelectedDestinationWalletExternalServiceId),
                            "Please choose to track either an address OR a derivation scheme OR an existing NBXplorer Wallet External Service",
                            ModelState);
                    }

                    if (!string.IsNullOrEmpty(viewModelPaymentDestination.SelectedDestinationWalletExternalServiceId) &&
                        !string.IsNullOrEmpty(viewModel.CryptoCode))
                    {
                        var service = services.SingleOrDefault(data =>
                                                               data.Id == viewModelPaymentDestination.SelectedDestinationWalletExternalServiceId);
                        if (service == null)
                        {
                            viewModel.AddModelError(
                                nameof(CreatePaymentForwarderViewModel.PaymentDestination.SelectedDestinationWalletExternalServiceId),
                                "Wallet chosen is wrong... ヽ༼ ಠ益ಠ ༽ノ ", ModelState);
                        }
                        else if (
                            new NBXplorerWalletService(service, _nbXplorerPublicWalletProvider, _derivationSchemeParser, _nbXplorerClientProvider).GetData().CryptoCode !=
                            viewModel.CryptoCode)
                        {
                            viewModel.AddModelError(
                                nameof(CreatePaymentForwarderViewModel.PaymentDestination.SelectedDestinationWalletExternalServiceId),
                                "Wallet chosen not the same crypto", ModelState);
                        }
                    }

                    BitcoinAddress         address            = null;
                    DerivationStrategyBase derivationStrategy = null;
                    if (!string.IsNullOrEmpty(viewModelPaymentDestination.DestinationAddress) &&
                        !string.IsNullOrEmpty(viewModel.CryptoCode))
                    {
                        try
                        {
                            address = BitcoinAddress.Create(viewModelPaymentDestination.DestinationAddress,
                                                            _nbXplorerClientProvider.GetClient(viewModel.CryptoCode).Network.NBitcoinNetwork);
                        }
                        catch (Exception)
                        {
                            viewModel.AddModelError(
                                nameof(CreatePaymentForwarderViewModel.PaymentDestination.DestinationAddress),
                                "Invalid Address", ModelState);
                        }
                    }

                    if (!string.IsNullOrEmpty(viewModelPaymentDestination.DerivationStrategy) &&
                        !string.IsNullOrEmpty(viewModel.CryptoCode))
                    {
                        try
                        {
                            var factory = _nbXplorerClientProvider.GetClient(viewModel.CryptoCode).Network
                                          .DerivationStrategyFactory;

                            derivationStrategy = _derivationSchemeParser.Parse(factory,
                                                                               viewModelPaymentDestination.DerivationStrategy);
                        }
                        catch
                        {
                            viewModel.AddModelError(
                                nameof(CreatePaymentForwarderViewModel.PaymentDestination.DerivationStrategy),
                                "Invalid Derivation Scheme", ModelState);
                        }
                    }
                }
            }


            if (!ModelState.IsValid)
            {
                return(View(viewModel));
            }

            return(await SetItUp(viewModel));
        }
예제 #5
0
 private DerivationStrategy ParseDerivationStrategy(string derivationScheme, Script hint, BTCPayNetwork network)
 {
     var parser = new DerivationSchemeParser(network.NBitcoinNetwork);
     parser.HintScriptPubKey = hint;
     return new DerivationStrategy(parser.Parse(derivationScheme), network);
 }