Esempio n. 1
0
        public Dictionary <string, CryptoData> GetCryptoData(BTCPayNetworkProvider networkProvider, bool alwaysIncludeBTC = false)
        {
            Dictionary <string, CryptoData> rates = new Dictionary <string, CryptoData>();
            var        serializer = new Serializer(Dummy);
            CryptoData phantom    = null;

#pragma warning disable CS0618
            // Legacy
            if (alwaysIncludeBTC)
            {
                var btcNetwork = networkProvider?.GetNetwork("BTC");
                phantom = new CryptoData()
                {
                    ParentEntity = this, IsPhantomBTC = true, Rate = Rate, CryptoCode = "BTC", TxFee = TxFee, FeeRate = new FeeRate(TxFee, 100), DepositAddress = DepositAddress, Network = btcNetwork
                };
                rates.Add("BTC", phantom);
            }
            if (CryptoData != null)
            {
                foreach (var prop in CryptoData.Properties())
                {
                    if (prop.Name == "BTC" && phantom != null)
                    {
                        rates.Remove("BTC");
                    }
                    var r = serializer.ToObject <CryptoData>(prop.Value.ToString());
                    r.CryptoCode   = prop.Name;
                    r.ParentEntity = this;
                    r.Network      = networkProvider?.GetNetwork(r.CryptoCode);
                    rates.Add(r.CryptoCode, r);
                }
            }
#pragma warning restore CS0618
            return(rates);
        }
Esempio n. 2
0
        public void Start()
        {
            if (Directory.Exists(_Directory))
            {
                Utils.DeleteDirectory(_Directory);
            }
            if (!Directory.Exists(_Directory))
            {
                Directory.CreateDirectory(_Directory);
            }


            NetworkProvider = new BTCPayNetworkProvider(ChainType.Regtest);
            ExplorerNode    = new RPCClient(RPCCredentialString.Parse(GetEnvironment("TESTS_BTCRPCCONNECTION", "server=http://127.0.0.1:43782;ceiwHEbqWI83:DwubwWsoo3")), NetworkProvider.GetNetwork("BTC").NBitcoinNetwork);
            LTCExplorerNode = new RPCClient(RPCCredentialString.Parse(GetEnvironment("TESTS_LTCRPCCONNECTION", "server=http://127.0.0.1:43783;ceiwHEbqWI83:DwubwWsoo3")), NetworkProvider.GetNetwork("LTC").NBitcoinNetwork);

            ExplorerClient    = new ExplorerClient(NetworkProvider.GetNetwork("BTC").NBXplorerNetwork, new Uri(GetEnvironment("TESTS_BTCNBXPLORERURL", "http://127.0.0.1:32838/")));
            LTCExplorerClient = new ExplorerClient(NetworkProvider.GetNetwork("LTC").NBXplorerNetwork, new Uri(GetEnvironment("TESTS_LTCNBXPLORERURL", "http://127.0.0.1:32838/")));

            PayTester = new BTCPayServerTester(Path.Combine(_Directory, "pay"))
            {
                NBXplorerUri    = ExplorerClient.Address,
                LTCNBXplorerUri = LTCExplorerClient.Address,
                Postgres        = GetEnvironment("TESTS_POSTGRES", "User ID=postgres;Host=127.0.0.1;Port=39372;Database=btcpayserver")
            };
            PayTester.Port     = int.Parse(GetEnvironment("TESTS_PORT", Utils.FreeTcpPort().ToString(CultureInfo.InvariantCulture)), CultureInfo.InvariantCulture);
            PayTester.HostName = GetEnvironment("TESTS_HOSTNAME", "127.0.0.1");
            PayTester.Start();

            var btc = NetworkProvider.GetNetwork("BTC").NBitcoinNetwork;

            CustomerEclair = new EclairTester(this, "TEST_ECLAIR", "http://*****:*****@127.0.0.1:30992/", "eclair", btc);
            MerchantCharge = new ChargeTester(this, "TEST_CHARGE", "http://*****:*****@127.0.0.1:54938/", "lightning-charged", btc);
        }
Esempio n. 3
0
        public override void PreparePaymentModel(PaymentModel model, InvoiceResponse invoiceResponse,
                                                 StoreBlob storeBlob, IPaymentMethod paymentMethod)
        {
            var paymentMethodId = paymentMethod.GetId();

            var cryptoInfo = invoiceResponse.CryptoInfo.First(o => o.GetpaymentMethodId() == paymentMethodId);
            var network    = _networkProvider.GetNetwork <BTCPayNetwork>(model.CryptoCode);

            model.PaymentMethodName   = GetPaymentMethodName(network);
            model.InvoiceBitcoinUrl   = cryptoInfo.PaymentUrls?.BOLT11;
            model.InvoiceBitcoinUrlQR = $"lightning:{cryptoInfo.PaymentUrls?.BOLT11?.ToUpperInvariant()?.Substring("LIGHTNING:".Length)}";

            model.PeerInfo = ((LightningLikePaymentMethodDetails)paymentMethod.GetPaymentMethodDetails()).NodeInfo;
            if (storeBlob.LightningAmountInSatoshi && model.CryptoCode == "BTC")
            {
                var satoshiCulture = new CultureInfo(CultureInfo.InvariantCulture.Name);
                satoshiCulture.NumberFormat.NumberGroupSeparator = " ";
                model.CryptoCode  = "Sats";
                model.BtcDue      = Money.Parse(model.BtcDue).ToUnit(MoneyUnit.Satoshi).ToString("N0", satoshiCulture);
                model.BtcPaid     = Money.Parse(model.BtcPaid).ToUnit(MoneyUnit.Satoshi).ToString("N0", satoshiCulture);
                model.OrderAmount = Money.Parse(model.OrderAmount).ToUnit(MoneyUnit.Satoshi).ToString("N0", satoshiCulture);
                model.NetworkFee  = new Money(model.NetworkFee, MoneyUnit.BTC).ToUnit(MoneyUnit.Satoshi);
                model.Rate        = _currencyNameTable.DisplayFormatCurrency(paymentMethod.Rate / 100_000_000, model.InvoiceCurrency);
            }
        }
Esempio n. 4
0
        public IActionResult GetStoreEthereumLikePaymentMethod(string cryptoCode)
        {
            var eth = StoreData.GetSupportedPaymentMethods(_btcPayNetworkProvider)
                      .OfType <EthereumSupportedPaymentMethod>();

            var network = _btcPayNetworkProvider.GetNetwork <EthereumBTCPayNetwork>(cryptoCode);

            if (network is null)
            {
                return(NotFound());
            }

            var excludeFilters       = StoreData.GetStoreBlob().GetExcludedPaymentMethods();
            var paymentMethodId      = new PaymentMethodId(network.CryptoCode, EthereumPaymentType.Instance);
            var matchedPaymentMethod = eth.SingleOrDefault(method =>
                                                           method.PaymentId == paymentMethodId);

            return(View(new EditEthereumPaymentMethodViewModel()
            {
                Enabled = !excludeFilters.Match(paymentMethodId),
                XPub = matchedPaymentMethod?.XPub,
                Index = matchedPaymentMethod?.CurrentIndex ?? 0,
                Passphrase = matchedPaymentMethod?.Password,
                Seed = matchedPaymentMethod?.Seed,
                StoreSeed = !string.IsNullOrEmpty(matchedPaymentMethod?.Seed),
                OriginalIndex = matchedPaymentMethod?.CurrentIndex ?? 0,
                KeyPath = string.IsNullOrEmpty(matchedPaymentMethod?.KeyPath)
                    ? network.GetDefaultKeyPath()
                    : matchedPaymentMethod?.KeyPath
            }));
        }
Esempio n. 5
0
        public void Start()
        {
            if (Directory.Exists(_Directory))
            {
                Utils.DeleteDirectory(_Directory);
            }
            if (!Directory.Exists(_Directory))
            {
                Directory.CreateDirectory(_Directory);
            }


            NetworkProvider = new BTCPayNetworkProvider(ChainType.Regtest);
            ExplorerNode    = new RPCClient(RPCCredentialString.Parse(GetEnvironment("TESTS_BTCRPCCONNECTION", "server=http://127.0.0.1:43782;ceiwHEbqWI83:DwubwWsoo3")), NetworkProvider.GetNetwork("BTC").NBitcoinNetwork);
            LTCExplorerNode = new RPCClient(RPCCredentialString.Parse(GetEnvironment("TESTS_LTCRPCCONNECTION", "server=http://127.0.0.1:43783;ceiwHEbqWI83:DwubwWsoo3")), NetworkProvider.GetNetwork("LTC").NBitcoinNetwork);

            ExplorerClient    = new ExplorerClient(NetworkProvider.GetNetwork("BTC").NBXplorerNetwork, new Uri(GetEnvironment("TESTS_BTCNBXPLORERURL", "http://127.0.0.1:32838/")));
            LTCExplorerClient = new ExplorerClient(NetworkProvider.GetNetwork("LTC").NBXplorerNetwork, new Uri(GetEnvironment("TESTS_LTCNBXPLORERURL", "http://127.0.0.1:32838/")));

            PayTester = new BTCPayServerTester(Path.Combine(_Directory, "pay"))
            {
                NBXplorerUri    = ExplorerClient.Address,
                LTCNBXplorerUri = LTCExplorerClient.Address,
                Postgres        = GetEnvironment("TESTS_POSTGRES", "User ID=postgres;Host=127.0.0.1;Port=39372;Database=btcpayserver")
            };
            PayTester.Port     = int.Parse(GetEnvironment("TESTS_PORT", Utils.FreeTcpPort().ToString()));
            PayTester.HostName = GetEnvironment("TESTS_HOSTNAME", "127.0.0.1");
            PayTester.Start();

            MerchantEclair = new EclairTester(this, "TEST_ECLAIR1", "http://127.0.0.1:30992/", "eclair1");
            CustomerEclair = new EclairTester(this, "TEST_ECLAIR2", "http://127.0.0.1:30993/", "eclair2");
        }
Esempio n. 6
0
        public override void PreparePaymentModel(PaymentModel model, InvoiceResponse invoiceResponse,
                                                 StoreBlob storeBlob, IPaymentMethod paymentMethod)
        {
            var paymentMethodId = paymentMethod.GetId();
            var network         = _networkProvider.GetNetwork <ZcashLikeSpecificBtcPayNetwork>(model.CryptoCode);

            model.PaymentMethodName = GetPaymentMethodName(network);
            model.CryptoImage       = GetCryptoImage(network);
            if (model.Activated)
            {
                var cryptoInfo = invoiceResponse.CryptoInfo.First(o => o.GetpaymentMethodId() == paymentMethodId);
                model.InvoiceBitcoinUrl = ZcashPaymentType.Instance.GetPaymentLink(network,
                                                                                   new ZcashLikeOnChainPaymentMethodDetails()
                {
                    DepositAddress = cryptoInfo.Address
                }, cryptoInfo.Due,
                                                                                   null);
                model.InvoiceBitcoinUrlQR = model.InvoiceBitcoinUrl;
            }
            else
            {
                model.InvoiceBitcoinUrl   = "";
                model.InvoiceBitcoinUrlQR = "";
            }
        }
        public override void PreparePaymentModel(PaymentModel model, InvoiceResponse invoiceResponse,
                                                 StoreBlob storeBlob)
        {
            var paymentMethodId = new PaymentMethodId(model.CryptoCode, PaymentTypes.LightningLike);

            var cryptoInfo = invoiceResponse.CryptoInfo.First(o => o.GetpaymentMethodId() == paymentMethodId);
            var network    = _networkProvider.GetNetwork <BTCPayNetwork>(model.CryptoCode);

            model.IsLightning              = true;
            model.PaymentMethodName        = GetPaymentMethodName(network);
            model.InvoiceBitcoinUrl        = cryptoInfo.PaymentUrls.BOLT11;
            model.InvoiceBitcoinUrlQR      = $"lightning:{cryptoInfo.PaymentUrls.BOLT11.ToUpperInvariant().Substring("LIGHTNING:".Length)}";
            model.LightningAmountInSatoshi = storeBlob.LightningAmountInSatoshi;
            if (storeBlob.LightningAmountInSatoshi && model.CryptoCode == "BTC")
            {
                var satoshiCulture = new CultureInfo(CultureInfo.InvariantCulture.Name);
                satoshiCulture.NumberFormat.NumberGroupSeparator = " ";

                model.CryptoCode  = "Sats";
                model.BtcDue      = Money.Parse(model.BtcDue).ToUnit(MoneyUnit.Satoshi).ToString("N0", satoshiCulture);
                model.BtcPaid     = Money.Parse(model.BtcPaid).ToUnit(MoneyUnit.Satoshi).ToString("N0", satoshiCulture);
                model.OrderAmount = Money.Parse(model.OrderAmount).ToUnit(MoneyUnit.Satoshi).ToString("N0", satoshiCulture);

                model.NetworkFee = new Money(model.NetworkFee, MoneyUnit.BTC).ToUnit(MoneyUnit.Satoshi);
            }
        }
        public override void PreparePaymentModel(PaymentModel model, InvoiceResponse invoiceResponse,
                                                 StoreBlob storeBlob, IPaymentMethod paymentMethod)
        {
            var paymentMethodId = paymentMethod.GetId();
            var cryptoInfo      = invoiceResponse.CryptoInfo.First(o => o.GetpaymentMethodId() == paymentMethodId);
            var network         = _networkProvider.GetNetwork <EthereumBTCPayNetwork>(model.CryptoCode);

            model.PaymentMethodName   = GetPaymentMethodName(network);
            model.CryptoImage         = GetCryptoImage(network);
            model.InvoiceBitcoinUrl   = "";
            model.InvoiceBitcoinUrlQR = cryptoInfo.Address ?? "";
        }
        public override void PreparePaymentModel(PaymentModel model, InvoiceResponse invoiceResponse)
        {
            var paymentMethodId = new PaymentMethodId(model.CryptoCode, PaymentTypes.BTCLike);

            var cryptoInfo = invoiceResponse.CryptoInfo.First(o => o.GetpaymentMethodId() == paymentMethodId);
            var network    = _networkProvider.GetNetwork <BTCPayNetwork>(model.CryptoCode);

            model.IsLightning         = false;
            model.PaymentMethodName   = GetPaymentMethodName(network);
            model.InvoiceBitcoinUrl   = cryptoInfo.PaymentUrls.BIP21;
            model.InvoiceBitcoinUrlQR = cryptoInfo.PaymentUrls.BIP21;
        }
Esempio n. 10
0
        public async Task <IActionResult> ViewPullPayment(string pullPaymentId)
        {
            using var ctx = _dbContextFactory.CreateContext();
            var pp = await ctx.PullPayments.FindAsync(pullPaymentId);

            if (pp is null)
            {
                return(NotFound());
            }

            var blob    = pp.GetBlob();
            var payouts = (await ctx.Payouts.GetPayoutInPeriod(pp)
                           .OrderByDescending(o => o.Date)
                           .ToListAsync())
                          .Select(o => new
            {
                Entity        = o,
                Blob          = o.GetBlob(_serializerSettings),
                TransactionId = o.GetProofBlob(_serializerSettings)?.TransactionId?.ToString()
            });
            var cd        = _currencyNameTable.GetCurrencyData(blob.Currency, false);
            var totalPaid = payouts.Where(p => p.Entity.State != PayoutState.Cancelled).Select(p => p.Blob.Amount).Sum();
            var amountDue = blob.Limit - totalPaid;

            ViewPullPaymentModel vm = new ViewPullPaymentModel(pp, DateTimeOffset.UtcNow)
            {
                AmountFormatted          = _currencyNameTable.FormatCurrency(blob.Limit, blob.Currency),
                AmountCollected          = totalPaid,
                AmountCollectedFormatted = _currencyNameTable.FormatCurrency(totalPaid, blob.Currency),
                AmountDue          = amountDue,
                ClaimedAmount      = amountDue,
                AmountDueFormatted = _currencyNameTable.FormatCurrency(amountDue, blob.Currency),
                CurrencyData       = cd,
                StartDate          = pp.StartDate,
                LastRefreshed      = DateTime.Now,
                Payouts            = payouts
                                     .Select(entity => new ViewPullPaymentModel.PayoutLine
                {
                    Id              = entity.Entity.Id,
                    Amount          = entity.Blob.Amount,
                    AmountFormatted = _currencyNameTable.FormatCurrency(entity.Blob.Amount, blob.Currency),
                    Currency        = blob.Currency,
                    Status          = entity.Entity.State.GetStateString(),
                    Destination     = entity.Blob.Destination.Address.ToString(),
                    Link            = GetTransactionLink(_networkProvider.GetNetwork <BTCPayNetwork>(entity.Entity.GetPaymentMethodId().CryptoCode), entity.TransactionId),
                    TransactionId   = entity.TransactionId
                }).ToList()
            };

            vm.IsPending &= vm.AmountDue > 0.0m;
            return(View(nameof(ViewPullPayment), vm));
        }
Esempio n. 11
0
        public override async Task <IPaymentMethodDetails> CreatePaymentMethodDetails(
            InvoiceLogs logs,
            LNURLPaySupportedPaymentMethod supportedPaymentMethod, PaymentMethod paymentMethod, Data.StoreData store,
            BTCPayNetwork network, object preparePaymentObject, IEnumerable <PaymentMethodId> invoicePaymentMethods)
        {
            var lnPmi = new PaymentMethodId(supportedPaymentMethod.CryptoCode, PaymentTypes.LightningLike);

            if (!supportedPaymentMethod.EnableForStandardInvoices &&
                paymentMethod.ParentEntity.Type == InvoiceType.Standard &&
                invoicePaymentMethods.Contains(lnPmi))
            {
                throw new PaymentMethodUnavailableException("LNURL is not enabled for standard invoices");
            }
            if (string.IsNullOrEmpty(paymentMethod.ParentEntity.Id))
            {
                var lnSupported = store.GetSupportedPaymentMethods(_networkProvider)
                                  .OfType <LightningSupportedPaymentMethod>().SingleOrDefault(method =>
                                                                                              method.PaymentId.CryptoCode == supportedPaymentMethod.CryptoCode &&
                                                                                              method.PaymentId.PaymentType == LightningPaymentType.Instance);

                if (lnSupported is null)
                {
                    throw new PaymentMethodUnavailableException("LNURL requires a lightning node to be configured for the store.");
                }

                return(new LNURLPayPaymentMethodDetails()
                {
                    Activated = false,
                    LightningSupportedPaymentMethod = lnSupported
                });
            }


            var lnLightningSupportedPaymentMethod =
                ((LNURLPayPaymentMethodDetails)paymentMethod.GetPaymentMethodDetails()).LightningSupportedPaymentMethod;

            NodeInfo?nodeInfo = null;

            if (lnLightningSupportedPaymentMethod != null)
            {
                nodeInfo = (await _lightningLikePaymentHandler.GetNodeInfo(lnLightningSupportedPaymentMethod, _networkProvider.GetNetwork <BTCPayNetwork>(supportedPaymentMethod.CryptoCode), logs, paymentMethod.PreferOnion)).FirstOrDefault();
            }

            return(new LNURLPayPaymentMethodDetails
            {
                Activated = true,
                LightningSupportedPaymentMethod = lnLightningSupportedPaymentMethod,
                BTCPayInvoiceId = paymentMethod.ParentEntity.Id,
                Bech32Mode = supportedPaymentMethod.UseBech32Scheme,
                NodeInfo = nodeInfo?.ToString()
            });
        }
        public override void PreparePaymentModel(PaymentModel model, InvoiceResponse invoiceResponse,
                                                 StoreBlob storeBlob, IPaymentMethod paymentMethod)
        {
            var paymentMethodId = paymentMethod.GetId();
            var cryptoInfo      = invoiceResponse.CryptoInfo.First(o => o.GetpaymentMethodId() == paymentMethodId);
            var network         = _networkProvider.GetNetwork <BTCPayNetwork>(model.CryptoCode);

            model.ShowRecommendedFee = storeBlob.ShowRecommendedFee;
            model.FeeRate            = ((BitcoinLikeOnChainPaymentMethod)paymentMethod.GetPaymentMethodDetails()).GetFeeRate();
            model.PaymentMethodName  = GetPaymentMethodName(network);

            var lightningFallback = "";

            if (model.Activated && network.SupportLightning && storeBlob.OnChainWithLnInvoiceFallback)
            {
                var lightningInfo = invoiceResponse.CryptoInfo.FirstOrDefault(a =>
                                                                              a.GetpaymentMethodId() == new PaymentMethodId(model.CryptoCode, PaymentTypes.LightningLike));
                if (!string.IsNullOrEmpty(lightningInfo?.PaymentUrls?.BOLT11))
                {
                    lightningFallback = "&" + lightningInfo.PaymentUrls.BOLT11
                                        .Replace("lightning:", "lightning=", StringComparison.OrdinalIgnoreCase)
                                        .ToUpperInvariant();
                }
            }

            if (model.Activated)
            {
                model.InvoiceBitcoinUrl   = (cryptoInfo.PaymentUrls?.BIP21 ?? "") + lightningFallback;
                model.InvoiceBitcoinUrlQR = (cryptoInfo.PaymentUrls?.BIP21 ?? "") + lightningFallback
                                            .Replace("LIGHTNING=", "lightning=", StringComparison.OrdinalIgnoreCase);
            }
            else
            {
                model.InvoiceBitcoinUrl   = "";
                model.InvoiceBitcoinUrlQR = "";
            }

            // Most wallets still don't support GROESTLCOIN: schema, so we're leaving this for better days
            // Ref: https://github.com/btcpayserver/btcpayserver/pull/2060#issuecomment-723828348
            //model.InvoiceBitcoinUrlQR = cryptoInfo.PaymentUrls.BIP21
            //    .Replace("groestlcoin:", "GROESTLCOIN:", StringComparison.OrdinalIgnoreCase)

            // We're leading the way in Bitcoin community with adding UPPERCASE Bech32 addresses in QR Code
            if (network.CryptoCode.Equals("BTC", StringComparison.InvariantCultureIgnoreCase) && _bech32Prefix.TryGetValue(model.CryptoCode, out var prefix) && model.BtcAddress.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
            {
                model.InvoiceBitcoinUrlQR = model.InvoiceBitcoinUrlQR.Replace(
                    $"{network.NBitcoinNetwork.UriScheme}:{model.BtcAddress}", $"{network.NBitcoinNetwork.UriScheme}:{model.BtcAddress.ToUpperInvariant()}",
                    StringComparison.OrdinalIgnoreCase
                    );
            }
        }
Esempio n. 13
0
        public bool TaprootActivated(string crytoCode)
        {
            var network = (BTCPayNetwork)_NetworkProvider.GetNetwork(crytoCode);

#pragma warning disable CS0618
            if (!(network.IsBTC && network.NBitcoinNetwork.ChainName == ChainName.Mainnet))
            {
                // Consider it activated for everything that is not mainnet bitcoin
                return(true);
            }
#pragma warning restore CS0618
            var status = _Dashboard.Get(crytoCode).Status;
            return(status.ChainHeight >= 709632);
        }
        public override void PreparePaymentModel(PaymentModel model, InvoiceResponse invoiceResponse, StoreBlob storeBlob)
        {
            var paymentMethodId = new PaymentMethodId(model.CryptoCode, PaymentType);
            var cryptoInfo      = invoiceResponse.CryptoInfo.First(o => o.GetpaymentMethodId() == paymentMethodId);
            var network         = _networkProvider.GetNetwork <MoneroLikeSpecificBtcPayNetwork>(model.CryptoCode);

            model.IsLightning       = false;
            model.PaymentMethodName = GetPaymentMethodName(network);
            model.CryptoImage       = GetCryptoImage(network);
            model.InvoiceBitcoinUrl = MoneroPaymentType.Instance.GetPaymentLink(network, new MoneroLikeOnChainPaymentMethodDetails()
            {
                DepositAddress = cryptoInfo.Address
            }, cryptoInfo.Due, null);
            model.InvoiceBitcoinUrlQR = model.InvoiceBitcoinUrl;
        }
Esempio n. 15
0
        public IActionResult CheckoutAppearance()
        {
            var storeBlob = CurrentStore.GetStoreBlob();
            var vm        = new CheckoutAppearanceViewModel();

            SetCryptoCurrencies(vm, CurrentStore);
            vm.PaymentMethodCriteria = CurrentStore.GetSupportedPaymentMethods(_NetworkProvider)
                                       .Where(s => !storeBlob.GetExcludedPaymentMethods().Match(s.PaymentId))
                                       .Where(s => _NetworkProvider.GetNetwork(s.PaymentId.CryptoCode) != null)
                                       .Where(s => s.PaymentId.PaymentType != PaymentTypes.LNURLPay)
                                       .Select(method =>
            {
                var existing =
                    storeBlob.PaymentMethodCriteria.SingleOrDefault(criteria =>
                                                                    criteria.PaymentMethod == method.PaymentId);
                if (existing is null)
                {
                    return(new PaymentMethodCriteriaViewModel()
                    {
                        PaymentMethod = method.PaymentId.ToString(),
                        Value = ""
                    });
                }
                else
                {
                    return(new PaymentMethodCriteriaViewModel()
                    {
                        PaymentMethod = existing.PaymentMethod.ToString(),
                        Type = existing.Above
                            ? PaymentMethodCriteriaViewModel.CriteriaType.GreaterThan
                            : PaymentMethodCriteriaViewModel.CriteriaType.LessThan,
                        Value = existing.Value?.ToString() ?? ""
                    });
                }
            }).ToList();

            vm.RequiresRefundEmail   = storeBlob.RequiresRefundEmail;
            vm.LazyPaymentMethods    = storeBlob.LazyPaymentMethods;
            vm.RedirectAutomatically = storeBlob.RedirectAutomatically;
            vm.CustomCSS             = storeBlob.CustomCSS;
            vm.CustomLogo            = storeBlob.CustomLogo;
            vm.HtmlTitle             = storeBlob.HtmlTitle;
            vm.ReceiptOptions        = CheckoutAppearanceViewModel.ReceiptOptionsViewModel.Create(storeBlob.ReceiptOptions);
            vm.AutoDetectLanguage    = storeBlob.AutoDetectLanguage;
            vm.SetLanguages(_LangService, storeBlob.DefaultLang);

            return(View(vm));
        }
        protected override Task <ILightningClient> GetLightningClient(string cryptoCode,
                                                                      bool doingAdminThings)
        {
            _btcPayServerOptions.InternalLightningByCryptoCode.TryGetValue(cryptoCode,
                                                                           out var internalLightningNode);
            var network = _btcPayNetworkProvider.GetNetwork <BTCPayNetwork>(cryptoCode);

            var store = HttpContext.GetStoreData();

            if (network == null || store == null)
            {
                return(null);
            }

            var id       = new PaymentMethodId(cryptoCode, PaymentTypes.LightningLike);
            var existing = store.GetSupportedPaymentMethods(_btcPayNetworkProvider)
                           .OfType <LightningSupportedPaymentMethod>()
                           .FirstOrDefault(d => d.PaymentId == id);

            if (existing == null || (existing.GetLightningUrl().IsInternalNode(internalLightningNode) &&
                                     !CanUseInternalLightning(doingAdminThings)))
            {
                return(null);
            }

            return(Task.FromResult(_lightningClientFactory.Create(existing.GetLightningUrl(), network)));
        }
Esempio n. 17
0
        public IEnumerable <DerivationStrategy> GetDerivationStrategies(BTCPayNetworkProvider networks)
        {
#pragma warning disable CS0618
            bool btcReturned = false;
            if (!string.IsNullOrEmpty(DerivationStrategies))
            {
                JObject strategies = JObject.Parse(DerivationStrategies);
                foreach (var strat in strategies.Properties())
                {
                    var network = networks.GetNetwork(strat.Name);
                    if (network != null)
                    {
                        if (network == networks.BTC && btcReturned)
                        {
                            btcReturned = true;
                        }
                        yield return(BTCPayServer.DerivationStrategy.Parse(strat.Value.Value <string>(), network));
                    }
                }
            }

            if (!btcReturned && !string.IsNullOrEmpty(DerivationStrategy))
            {
                if (networks.BTC != null)
                {
                    yield return(BTCPayServer.DerivationStrategy.Parse(DerivationStrategy, networks.BTC));
                }
            }
#pragma warning restore CS0618
        }
        protected override async Task <ILightningClient> GetLightningClient(string cryptoCode,
                                                                            bool doingAdminThings)
        {
            var network = _btcPayNetworkProvider.GetNetwork <BTCPayNetwork>(cryptoCode);

            var store = HttpContext.GetStoreData();

            if (network == null || store == null)
            {
                return(null);
            }

            var id       = new PaymentMethodId(cryptoCode, PaymentTypes.LightningLike);
            var existing = store.GetSupportedPaymentMethods(_btcPayNetworkProvider)
                           .OfType <LightningSupportedPaymentMethod>()
                           .FirstOrDefault(d => d.PaymentId == id);

            if (existing == null)
            {
                return(null);
            }
            if (existing.GetExternalLightningUrl() is LightningConnectionString connectionString)
            {
                return(_lightningClientFactory.Create(connectionString, network));
            }
            else if (
                await CanUseInternalLightning(doingAdminThings) &&
                _lightningNetworkOptions.Value.InternalLightningByCryptoCode.TryGetValue(network.CryptoCode,
                                                                                         out var internalLightningNode))
            {
                return(_lightningClientFactory.Create(internalLightningNode, network));
            }
            return(null);
        }
Esempio n. 19
0
        private void AddPaymentMethods(StoreData store, StoreBlob storeBlob, StoreViewModel vm)
        {
            var excludeFilters         = storeBlob.GetExcludedPaymentMethods();
            var derivationByCryptoCode =
                store
                .GetSupportedPaymentMethods(_NetworkProvider)
                .OfType <DerivationSchemeSettings>()
                .ToDictionary(c => c.Network.CryptoCode.ToUpperInvariant());

            var lightningByCryptoCode = store
                                        .GetSupportedPaymentMethods(_NetworkProvider)
                                        .OfType <LightningSupportedPaymentMethod>()
                                        .ToDictionary(c => c.CryptoCode.ToUpperInvariant());

            foreach (var paymentMethodId in _paymentMethodHandlerDictionary.Distinct().SelectMany(handler => handler.GetSupportedPaymentMethods()))
            {
                switch (paymentMethodId.PaymentType)
                {
                case BitcoinPaymentType _:
                    var strategy = derivationByCryptoCode.TryGet(paymentMethodId.CryptoCode);
                    var network  = _NetworkProvider.GetNetwork <BTCPayNetwork>(paymentMethodId.CryptoCode);
                    var value    = strategy?.ToPrettyString() ?? string.Empty;

                    vm.DerivationSchemes.Add(new StoreViewModel.DerivationScheme()
                    {
                        Crypto          = paymentMethodId.CryptoCode,
                        WalletSupported = network.WalletSupported,
                        Value           = value,
                        WalletId        = new WalletId(store.Id, paymentMethodId.CryptoCode),
                        Enabled         = !excludeFilters.Match(paymentMethodId) && strategy != null,
#if ALTCOINS
                        Collapsed = network is ElementsBTCPayNetwork elementsBTCPayNetwork && elementsBTCPayNetwork.NetworkCryptoCode != elementsBTCPayNetwork.CryptoCode && string.IsNullOrEmpty(value)
#endif
                    });
                    break;
Esempio n. 20
0
        public static IEnumerable <ISupportedPaymentMethod> GetSupportedPaymentMethods(this StoreData storeData, BTCPayNetworkProvider networks)
        {
            ArgumentNullException.ThrowIfNull(storeData);
#pragma warning disable CS0618
            bool btcReturned = false;

            if (!string.IsNullOrEmpty(storeData.DerivationStrategies))
            {
                JObject strategies = JObject.Parse(storeData.DerivationStrategies);
                foreach (var strat in strategies.Properties())
                {
                    if (!PaymentMethodId.TryParse(strat.Name, out var paymentMethodId))
                    {
                        continue;
                    }
                    var network = networks.GetNetwork <BTCPayNetworkBase>(paymentMethodId.CryptoCode);
                    if (network != null)
                    {
                        if (network == networks.BTC && paymentMethodId.PaymentType == PaymentTypes.BTCLike && btcReturned)
                        {
                            continue;
                        }
                        if (strat.Value.Type == JTokenType.Null)
                        {
                            continue;
                        }
                        yield return
                            (paymentMethodId.PaymentType.DeserializeSupportedPaymentMethod(network, strat.Value));
                    }
                }
            }
#pragma warning restore CS0618
        }
        public async Task <IActionResult> ShowLightningNodeInfo(string storeId, string cryptoCode)
        {
            var store = await _StoreRepository.FindStore(storeId);

            if (store == null)
            {
                return(NotFound());
            }

            try
            {
                var paymentMethodDetails = GetExistingLightningSupportedPaymentMethod(cryptoCode, store);
                var network  = _BtcPayNetworkProvider.GetNetwork <BTCPayNetwork>(cryptoCode);
                var nodeInfo =
                    await _LightningLikePaymentHandler.GetNodeInfo(paymentMethodDetails, network, new InvoiceLogs());

                return(View(new ShowLightningNodeInfoViewModel
                {
                    Available = nodeInfo.Any(),
                    NodeInfo = nodeInfo.Select(n => new ShowLightningNodeInfoViewModel.NodeData(n)).ToArray(),
                    CryptoCode = cryptoCode,
                    CryptoImage = GetImage(paymentMethodDetails.PaymentId, network),
                    StoreName = store.StoreName
                }));
            }
            catch (Exception)
            {
                return(View(new ShowLightningNodeInfoViewModel
                {
                    Available = false,
                    CryptoCode = cryptoCode,
                    StoreName = store.StoreName
                }));
            }
        }
Esempio n. 22
0
        public PaymentMethodDictionary GetPaymentMethods(BTCPayNetworkProvider networkProvider)
        {
            PaymentMethodDictionary paymentMethods = new PaymentMethodDictionary();
            var serializer = new Serializer(Dummy);

#pragma warning disable CS0618
            if (PaymentMethod != null)
            {
                foreach (var prop in PaymentMethod.Properties())
                {
                    var r = serializer.ToObject <PaymentMethod>(prop.Value.ToString());
                    var paymentMethodId = PaymentMethodId.Parse(prop.Name);
                    r.CryptoCode   = paymentMethodId.CryptoCode;
                    r.PaymentType  = paymentMethodId.PaymentType.ToString();
                    r.ParentEntity = this;
                    r.Network      = networkProvider?.GetNetwork(r.CryptoCode);
                    if (r.Network != null || networkProvider == null)
                    {
                        paymentMethods.Add(r);
                    }
                }
            }
#pragma warning restore CS0618
            return(paymentMethods);
        }
Esempio n. 23
0
        public virtual async Task <IActionResult> PayInvoice(string cryptoCode, PayLightningInvoiceRequest lightningInvoice, CancellationToken cancellationToken = default)
        {
            var lightningClient = await GetLightningClient(cryptoCode, true);

            var network = _btcPayNetworkProvider.GetNetwork <BTCPayNetwork>(cryptoCode);

            if (lightningInvoice?.BOLT11 is null ||
                !BOLT11PaymentRequest.TryParse(lightningInvoice.BOLT11, out _, network.NBitcoinNetwork))
            {
                ModelState.AddModelError(nameof(lightningInvoice.BOLT11), "The BOLT11 invoice was invalid.");
            }

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

            var param = lightningInvoice?.MaxFeeFlat != null || lightningInvoice?.MaxFeePercent != null
                ? new PayInvoiceParams {
                MaxFeePercent = lightningInvoice.MaxFeePercent, MaxFeeFlat = lightningInvoice.MaxFeeFlat
            }
                : null;
            var result = await lightningClient.Pay(lightningInvoice.BOLT11, param, cancellationToken);

            return(result.Result switch
            {
                PayResult.CouldNotFindRoute => this.CreateAPIError("could-not-find-route", "Impossible to find a route to the peer"),
                PayResult.Error => this.CreateAPIError("generic-error", result.ErrorDetail),
                PayResult.Ok => Ok(new LightningPaymentData
                {
                    TotalAmount = result.Details?.TotalAmount,
                    FeeAmount = result.Details?.FeeAmount
                }),
                _ => throw new NotSupportedException("Unsupported Payresult")
            });
        private bool GetCryptoCodeWallet(string cryptoCode, out BTCPayNetwork network, out BTCPayWallet wallet)
        {
            network = _btcPayNetworkProvider.GetNetwork <BTCPayNetwork>(cryptoCode);
            wallet  = network != null?_walletProvider.GetWallet(network) : null;

            return(wallet != null);
        }
Esempio n. 25
0
        public IEnumerable <ISupportedPaymentMethod> GetSupportedPaymentMethod(BTCPayNetworkProvider networks)
        {
#pragma warning disable CS0618
            bool btcReturned = false;
            if (!string.IsNullOrEmpty(DerivationStrategies))
            {
                JObject strategies = JObject.Parse(DerivationStrategies);
                foreach (var strat in strategies.Properties())
                {
                    var paymentMethodId = PaymentMethodId.Parse(strat.Name);
                    var network         = networks.GetNetwork(paymentMethodId.CryptoCode);
                    if (network != null)
                    {
                        if (network == networks.BTC && paymentMethodId.PaymentType == PaymentTypes.BTCLike)
                        {
                            btcReturned = true;
                        }
                        yield return(PaymentMethodExtensions.Deserialize(paymentMethodId, strat.Value, network));
                    }
                }
            }

            if (!btcReturned && !string.IsNullOrEmpty(DerivationStrategy))
            {
                if (networks.BTC != null)
                {
                    yield return(BTCPayServer.DerivationStrategy.Parse(DerivationStrategy, networks.BTC));
                }
            }
#pragma warning restore CS0618
        }
        private string GetDisplayName(PaymentMethodId paymentMethodId)
        {
            var display = _NetworkProvider.GetNetwork(paymentMethodId.CryptoCode)?.DisplayName ?? paymentMethodId.CryptoCode;

            return(paymentMethodId.PaymentType == PaymentTypes.BTCLike ?
                   display : $"{display} (Lightning)");
        }
Esempio n. 27
0
        public async Task <IActionResult> ShowLightningNodeInfo(string storeId, string cryptoCode)
        {
            var store = await _StoreRepository.FindStore(storeId);

            if (store == null)
            {
                return(NotFound());
            }

            try
            {
                var paymentMethodDetails = GetExistingLightningSupportedPaymentMethod(cryptoCode, store);
                var network  = _BtcPayNetworkProvider.GetNetwork <BTCPayNetwork>(cryptoCode);
                var nodeInfo =
                    await _LightningLikePaymentHandler.GetNodeInfo(this.Request.IsOnion(), paymentMethodDetails,
                                                                   network);

                return(View(new ShowLightningNodeInfoViewModel()
                {
                    Available = true,
                    NodeInfo = nodeInfo.ToString(),
                    CryptoCode = cryptoCode,
                    CryptoImage = GetImage(paymentMethodDetails.PaymentId, network)
                }));
            }
            catch (Exception)
            {
                return(View(new ShowLightningNodeInfoViewModel()
                {
                    Available = false, CryptoCode = cryptoCode
                }));
            }
        }
Esempio n. 28
0
        public ServerTester(string scope)
        {
            _Directory = scope;
            if (Directory.Exists(_Directory))
            {
                Utils.DeleteDirectory(_Directory);
            }
            if (!Directory.Exists(_Directory))
            {
                Directory.CreateDirectory(_Directory);
            }

            NetworkProvider = new BTCPayNetworkProvider(NetworkType.Regtest);
            ExplorerNode    = new RPCClient(RPCCredentialString.Parse(GetEnvironment("TESTS_BTCRPCCONNECTION", "server=http://127.0.0.1:43782;ceiwHEbqWI83:DwubwWsoo3")), NetworkProvider.GetNetwork <BTCPayNetwork>("BTC").NBitcoinNetwork);
            ExplorerNode.ScanRPCCapabilities();

            ExplorerClient = new ExplorerClient(NetworkProvider.GetNetwork <BTCPayNetwork>("BTC").NBXplorerNetwork, new Uri(GetEnvironment("TESTS_BTCNBXPLORERURL", "http://127.0.0.1:32838/")));

            PayTester = new BTCPayServerTester(Path.Combine(_Directory, "pay"))
            {
                NBXplorerUri = ExplorerClient.Address,
                TestDatabase = Enum.Parse <TestDatabases>(GetEnvironment("TESTS_DB", TestDatabases.Postgres.ToString()), true),
                Postgres     = GetEnvironment("TESTS_POSTGRES", "User ID=postgres;Host=127.0.0.1;Port=39372;Database=btcpayserver"),
                MySQL        = GetEnvironment("TESTS_MYSQL", "User ID=root;Host=127.0.0.1;Port=33036;Database=btcpayserver")
            };
            PayTester.Port        = int.Parse(GetEnvironment("TESTS_PORT", Utils.FreeTcpPort().ToString(CultureInfo.InvariantCulture)), CultureInfo.InvariantCulture);
            PayTester.HostName    = GetEnvironment("TESTS_HOSTNAME", "127.0.0.1");
            PayTester.InContainer = bool.Parse(GetEnvironment("TESTS_INCONTAINER", "false"));

            PayTester.SSHPassword   = GetEnvironment("TESTS_SSHPASSWORD", "opD3i2282D");
            PayTester.SSHKeyFile    = GetEnvironment("TESTS_SSHKEYFILE", "");
            PayTester.SSHConnection = GetEnvironment("TESTS_SSHCONNECTION", "[email protected]:21622");
        }
        public virtual async Task <IActionResult> PayInvoice(string cryptoCode, PayLightningInvoiceRequest lightningInvoice)
        {
            var lightningClient = await GetLightningClient(cryptoCode, true);

            var network = _btcPayNetworkProvider.GetNetwork <BTCPayNetwork>(cryptoCode);

            if (lightningInvoice?.BOLT11 is null ||
                !BOLT11PaymentRequest.TryParse(lightningInvoice.BOLT11, out _, network.NBitcoinNetwork))
            {
                ModelState.AddModelError(nameof(lightningInvoice.BOLT11), "The BOLT11 invoice was invalid.");
            }

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

            var result = await lightningClient.Pay(lightningInvoice.BOLT11);

            switch (result.Result)
            {
            case PayResult.CouldNotFindRoute:
                return(this.CreateAPIError("could-not-find-route", "Impossible to find a route to the peer"));

            case PayResult.Error:
                return(this.CreateAPIError("generic-error", result.ErrorDetail));

            case PayResult.Ok:
                return(Ok());

            default:
                throw new NotSupportedException("Unsupported Payresult");
            }
        }
Esempio n. 30
0
        public ServerTester(string scope)
        {
            _Directory = scope;
            if (Directory.Exists(_Directory))
            {
                Utils.DeleteDirectory(_Directory);
            }
            if (!Directory.Exists(_Directory))
            {
                Directory.CreateDirectory(_Directory);
            }

            NetworkProvider = new BTCPayNetworkProvider(NetworkType.Regtest);
            ExplorerNode    = new RPCClient(RPCCredentialString.Parse(GetEnvironment("TESTS_BTCRPCCONNECTION", "server=http://127.0.0.1:43782;ceiwHEbqWI83:DwubwWsoo3")), NetworkProvider.GetNetwork <BTCPayNetwork>("BTC").NBitcoinNetwork);
            ExplorerNode.ScanRPCCapabilities();
            LTCExplorerNode = new RPCClient(RPCCredentialString.Parse(GetEnvironment("TESTS_LTCRPCCONNECTION", "server=http://127.0.0.1:43783;ceiwHEbqWI83:DwubwWsoo3")), NetworkProvider.GetNetwork <BTCPayNetwork>("LTC").NBitcoinNetwork);

            ExplorerClient    = new ExplorerClient(NetworkProvider.GetNetwork <BTCPayNetwork>("BTC").NBXplorerNetwork, new Uri(GetEnvironment("TESTS_BTCNBXPLORERURL", "http://127.0.0.1:32838/")));
            LTCExplorerClient = new ExplorerClient(NetworkProvider.GetNetwork <BTCPayNetwork>("LTC").NBXplorerNetwork, new Uri(GetEnvironment("TESTS_LTCNBXPLORERURL", "http://127.0.0.1:32838/")));

            var btc = NetworkProvider.GetNetwork <BTCPayNetwork>("BTC").NBitcoinNetwork;

            CustomerLightningD = LightningClientFactory.CreateClient(GetEnvironment("TEST_CUSTOMERLIGHTNINGD", "type=clightning;server=tcp://127.0.0.1:30992/"), btc);
            MerchantLightningD = LightningClientFactory.CreateClient(GetEnvironment("TEST_MERCHANTLIGHTNINGD", "type=clightning;server=tcp://127.0.0.1:30993/"), btc);

            MerchantCharge = new ChargeTester(this, "TEST_MERCHANTCHARGE", "type=charge;server=http://127.0.0.1:54938/;api-token=foiewnccewuify", "merchant_lightningd", btc);

            MerchantLnd = new LndMockTester(this, "TEST_MERCHANTLND", "https://*****:*****@127.0.0.1:53280/", "merchant_lnd", btc);

            PayTester = new BTCPayServerTester(Path.Combine(_Directory, "pay"))
            {
                NBXplorerUri        = ExplorerClient.Address,
                LTCNBXplorerUri     = LTCExplorerClient.Address,
                TestDatabase        = Enum.Parse <TestDatabases>(GetEnvironment("TESTS_DB", TestDatabases.Postgres.ToString()), true),
                Postgres            = GetEnvironment("TESTS_POSTGRES", "User ID=postgres;Host=127.0.0.1;Port=39372;Database=btcpayserver"),
                MySQL               = GetEnvironment("TESTS_MYSQL", "User ID=root;Host=127.0.0.1;Port=33036;Database=btcpayserver"),
                IntegratedLightning = MerchantCharge.Client.Uri
            };
            PayTester.Port        = int.Parse(GetEnvironment("TESTS_PORT", Utils.FreeTcpPort().ToString(CultureInfo.InvariantCulture)), CultureInfo.InvariantCulture);
            PayTester.HostName    = GetEnvironment("TESTS_HOSTNAME", "127.0.0.1");
            PayTester.InContainer = bool.Parse(GetEnvironment("TESTS_INCONTAINER", "false"));

            PayTester.SSHPassword   = GetEnvironment("TESTS_SSHPASSWORD", "opD3i2282D");
            PayTester.SSHKeyFile    = GetEnvironment("TESTS_SSHKEYFILE", "");
            PayTester.SSHConnection = GetEnvironment("TESTS_SSHCONNECTION", "[email protected]:21622");
        }