public ExternalConnectionString Clone()
 {
     return(new ExternalConnectionString()
     {
         MacaroonFilePath = MacaroonFilePath,
         CertificateThumbprint = CertificateThumbprint,
         Macaroon = Macaroon,
         MacaroonDirectoryPath = MacaroonDirectoryPath,
         Server = Server,
         APIToken = APIToken,
         CookieFilePath = CookieFilePath,
         AccessKey = AccessKey,
         Macaroons = Macaroons?.Clone()
     });
 }
        /// <summary>
        /// Return a connectionString which does not depends on external resources or information like relative path or file path
        /// </summary>
        /// <returns></returns>
        public async Task <ExternalConnectionString> Expand(Uri absoluteUrlBase, ExternalServiceTypes serviceType)
        {
            var connectionString = this.Clone();
            // Transform relative URI into absolute URI
            var serviceUri = connectionString.Server.IsAbsoluteUri ? connectionString.Server : ToRelative(absoluteUrlBase, connectionString.Server.ToString());

            if (!serviceUri.Scheme.Equals("https", StringComparison.OrdinalIgnoreCase) &&
                !serviceUri.DnsSafeHost.EndsWith(".onion", StringComparison.OrdinalIgnoreCase))
            {
                throw new System.Security.SecurityException($"Insecure transport protocol to access this service, please use HTTPS or TOR");
            }
            connectionString.Server = serviceUri;

            if (serviceType == ExternalServiceTypes.LNDGRPC || serviceType == ExternalServiceTypes.LNDRest)
            {
                // Read the MacaroonDirectory
                if (connectionString.MacaroonDirectoryPath != null)
                {
                    try
                    {
                        connectionString.Macaroons = await Macaroons.GetFromDirectoryAsync(connectionString.MacaroonDirectoryPath);

                        connectionString.MacaroonDirectoryPath = null;
                    }
                    catch (Exception ex)
                    {
                        throw new System.IO.DirectoryNotFoundException("Macaroon directory path not found", ex);
                    }
                }

                // Read the MacaroonFilePath
                if (connectionString.MacaroonFilePath != null)
                {
                    try
                    {
                        connectionString.Macaroon = await System.IO.File.ReadAllBytesAsync(connectionString.MacaroonFilePath);

                        connectionString.MacaroonFilePath = null;
                    }
                    catch (Exception ex)
                    {
                        throw new System.IO.FileNotFoundException("Macaroon not found", ex);
                    }
                }
            }

            if (serviceType == ExternalServiceTypes.Charge || serviceType == ExternalServiceTypes.RTL || serviceType == ExternalServiceTypes.Spark)
            {
                // Read access key from cookie file
                if (connectionString.CookieFilePath != null)
                {
                    string cookieFileContent = null;
                    bool   isFake            = false;
                    try
                    {
                        cookieFileContent = await System.IO.File.ReadAllTextAsync(connectionString.CookieFilePath);

                        isFake = connectionString.CookieFilePath == "fake";
                        connectionString.CookieFilePath = null;
                    }
                    catch (Exception ex)
                    {
                        throw new System.IO.FileNotFoundException("Cookie file path not found", ex);
                    }
                    if (serviceType == ExternalServiceTypes.RTL)
                    {
                        connectionString.AccessKey = cookieFileContent;
                    }
                    else if (serviceType == ExternalServiceTypes.Spark)
                    {
                        var cookie = (isFake ? "fake:fake:fake" // Hacks for testing
                                    : cookieFileContent).Split(':');
                        if (cookie.Length >= 3)
                        {
                            connectionString.AccessKey = cookie[2];
                        }
                        else
                        {
                            throw new FormatException("Invalid cookiefile format");
                        }
                    }
                    else if (serviceType == ExternalServiceTypes.Charge)
                    {
                        connectionString.APIToken = isFake ? "fake" : cookieFileContent;
                    }
                }
            }
            return(connectionString);
        }