Example #1
0
        UpdateStoreLightningNetworkPaymentMethodToInternalNode(string storeId,
                                                               string cryptoCode, LightningNetworkPaymentMethodData paymentMethod,
                                                               CancellationToken token = default)
        {
            var response = await _httpClient.SendAsync(
                CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/LightningNetwork/{cryptoCode}/internal",
                                  method : HttpMethod.Put), token);

            return(await HandleResponse <LightningNetworkPaymentMethodData>(response));
        }
Example #2
0
        public virtual async Task <LightningNetworkPaymentMethodData> UpdateStoreLightningNetworkPaymentMethod(
            string storeId,
            string cryptoCode, LightningNetworkPaymentMethodData paymentMethod,
            CancellationToken token = default)
        {
            var response = await _httpClient.SendAsync(
                CreateHttpRequest($"api/v1/stores/{storeId}/payment-methods/LightningNetwork/{cryptoCode}",
                                  bodyPayload : paymentMethod, method : HttpMethod.Put), token);

            return(await HandleResponse <LightningNetworkPaymentMethodData>(response));
        }
Example #3
0
        public async Task <IActionResult> UpdateLightningNetworkPaymentMethod(string cryptoCode,
                                                                              [FromBody] LightningNetworkPaymentMethodData paymentMethodData)
        {
            var id = new PaymentMethodId(cryptoCode, PaymentTypes.LightningLike);

            if (!GetNetwork(cryptoCode, out var network))
            {
                return(NotFound());
            }

            var internalLightning = GetInternalLightningNode(network.CryptoCode);

            if (string.IsNullOrEmpty(paymentMethodData?.ConnectionString))
            {
                ModelState.AddModelError(nameof(LightningNetworkPaymentMethodData.ConnectionString),
                                         "Missing connectionString");
            }

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


            PaymentMethodId paymentMethodId = new PaymentMethodId(network.CryptoCode, PaymentTypes.LightningLike);

            Payments.Lightning.LightningSupportedPaymentMethod paymentMethod = null;
            if (!string.IsNullOrEmpty(paymentMethodData.ConnectionString))
            {
                if (!LightningConnectionString.TryParse(paymentMethodData.ConnectionString, false,
                                                        out var connectionString, out var error))
                {
                    ModelState.AddModelError(nameof(paymentMethodData.ConnectionString), $"Invalid URL ({error})");
                    return(this.CreateValidationError(ModelState));
                }

                if (connectionString.ConnectionType == LightningConnectionType.LndGRPC)
                {
                    ModelState.AddModelError(nameof(paymentMethodData.ConnectionString),
                                             $"BTCPay does not support gRPC connections");
                    return(this.CreateValidationError(ModelState));
                }

                bool isInternalNode = connectionString.IsInternalNode(internalLightning);

                if (connectionString.BaseUri.Scheme == "http")
                {
                    if (!isInternalNode && !connectionString.AllowInsecure)
                    {
                        ModelState.AddModelError(nameof(paymentMethodData.ConnectionString), "The url must be HTTPS");
                        return(this.CreateValidationError(ModelState));
                    }
                }

                if (connectionString.MacaroonFilePath != null)
                {
                    if (!CanUseInternalLightning())
                    {
                        ModelState.AddModelError(nameof(paymentMethodData.ConnectionString),
                                                 "You are not authorized to use macaroonfilepath");
                        return(this.CreateValidationError(ModelState));
                    }

                    if (!System.IO.File.Exists(connectionString.MacaroonFilePath))
                    {
                        ModelState.AddModelError(nameof(paymentMethodData.ConnectionString),
                                                 "The macaroonfilepath file does not exist");
                        return(this.CreateValidationError(ModelState));
                    }

                    if (!System.IO.Path.IsPathRooted(connectionString.MacaroonFilePath))
                    {
                        ModelState.AddModelError(nameof(paymentMethodData.ConnectionString),
                                                 "The macaroonfilepath should be fully rooted");
                        return(this.CreateValidationError(ModelState));
                    }
                }

                if (isInternalNode && !CanUseInternalLightning())
                {
                    ModelState.AddModelError(nameof(paymentMethodData.ConnectionString), "Unauthorized url");
                    return(this.CreateValidationError(ModelState));
                }

                paymentMethod = new Payments.Lightning.LightningSupportedPaymentMethod()
                {
                    CryptoCode = paymentMethodId.CryptoCode
                };
                paymentMethod.SetLightningUrl(connectionString);
            }

            var store     = Store;
            var storeBlob = store.GetStoreBlob();

            store.SetSupportedPaymentMethod(id, paymentMethod);
            storeBlob.SetExcluded(id, !paymentMethodData.Enabled);
            store.SetStoreBlob(storeBlob);
            await _storeRepository.UpdateStore(store);

            return(Ok(GetExistingLightningLikePaymentMethod(cryptoCode, store)));
        }
Example #4
0
        public async Task <IActionResult> UpdateLightningNetworkPaymentMethod(string storeId, string cryptoCode,
                                                                              [FromBody] LightningNetworkPaymentMethodData paymentMethodData)
        {
            var paymentMethodId = new PaymentMethodId(cryptoCode, PaymentTypes.LightningLike);

            if (!GetNetwork(cryptoCode, out var network))
            {
                return(NotFound());
            }

            if (string.IsNullOrEmpty(paymentMethodData.ConnectionString))
            {
                ModelState.AddModelError(nameof(LightningNetworkPaymentMethodData.ConnectionString),
                                         "Missing connectionString");
            }

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

            LightningSupportedPaymentMethod?paymentMethod = null;

            if (!string.IsNullOrEmpty(paymentMethodData !.ConnectionString))
            {
                if (paymentMethodData.ConnectionString == LightningSupportedPaymentMethod.InternalNode)
                {
                    if (!await CanUseInternalLightning())
                    {
                        ModelState.AddModelError(nameof(paymentMethodData.ConnectionString),
                                                 $"You are not authorized to use the internal lightning node");
                        return(this.CreateValidationError(ModelState));
                    }

                    paymentMethod = new Payments.Lightning.LightningSupportedPaymentMethod()
                    {
                        CryptoCode = paymentMethodId.CryptoCode
                    };
                    paymentMethod.SetInternalNode();
                }
                else
                {
                    if (!LightningConnectionString.TryParse(paymentMethodData.ConnectionString, false,
                                                            out var connectionString, out var error))
                    {
                        ModelState.AddModelError(nameof(paymentMethodData.ConnectionString), $"Invalid URL ({error})");
                        return(this.CreateValidationError(ModelState));
                    }

                    if (connectionString.ConnectionType == LightningConnectionType.LndGRPC)
                    {
                        ModelState.AddModelError(nameof(paymentMethodData.ConnectionString),
                                                 $"BTCPay does not support gRPC connections");
                        return(this.CreateValidationError(ModelState));
                    }

                    if (!await CanManageServer() && !connectionString.IsSafe())
                    {
                        ModelState.AddModelError(nameof(paymentMethodData.ConnectionString),
                                                 $"You do not have 'btcpay.server.canmodifyserversettings' rights, so the connection string should not contain 'cookiefilepath', 'macaroondirectorypath', 'macaroonfilepath', and should not point to a local ip or to a dns name ending with '.internal', '.local', '.lan' or '.'.");
                        return(this.CreateValidationError(ModelState));
                    }

                    paymentMethod = new Payments.Lightning.LightningSupportedPaymentMethod()
                    {
                        CryptoCode = paymentMethodId.CryptoCode
                    };
                    paymentMethod.SetLightningUrl(connectionString);
                }
            }

            var store     = Store;
            var storeBlob = store.GetStoreBlob();

            store.SetSupportedPaymentMethod(paymentMethodId, paymentMethod);
            storeBlob.SetExcluded(paymentMethodId, !paymentMethodData.Enabled);
            store.SetStoreBlob(storeBlob);
            await _storeRepository.UpdateStore(store);

            return(Ok(GetExistingLightningLikePaymentMethod(cryptoCode, store)));
        }