public static string GetDefaultCacheFilename(string apiUrl)
        {
            var home = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData, Environment.SpecialFolderOption.Create);
            var hash = SHA256.Create().ComputeHash(Encoding.UTF8.GetBytes(apiUrl));
            var file = JsonWebSigner.Base64UrlEncoded(hash) + ".lets-encrypt.cache.json";

            return(Path.Combine(home, file));
        }
        public async Task Init(string email, CancellationToken token = default(CancellationToken))
        {
            _accountKey = new RSACryptoServiceProvider(4096);


            // retrieve the API directory
            (_directory, _) = await SendAsync <APIDirectory>(HttpMethod.Get, new Uri("directory", UriKind.Relative), null, token);

            // check for account
            if (File.Exists(_cachePath))
            {
                bool success;
                try
                {
                    RegistrationCache.SetInstance(RegistrationCache.LoadCacheFromFile(_cachePath));
                    _accountKey.ImportCspBlob(RegistrationCache.Instance.AccountKey);
                    _encryptor = new JsonWebSigner(_accountKey, RegistrationCache.Instance.Location.ToString());
                    success    = true;
                }
                catch
                {
                    success = false;
                }

                if (success)
                {
                    return;
                }
            }

            // no account found, create a new account
            _encryptor             = new JsonWebSigner(_accountKey, null);
            var(account, response) = await SendAsync <Account>(HttpMethod.Post, _directory.NewAccount, new Account
            {
                // we validate this in the UI before we get here, so that is fine
                TermsOfServiceAgreed = true,
                Contacts             = new[] { "mailto:" + email },
            }, token);

            _encryptor.SetKeyId(account);

            if (account.Status != "valid")
            {
                throw new InvalidOperationException("Account status is not valid, was: " + account.Status + Environment.NewLine + response);
            }

            RegistrationCache.SetInstance(new RegistrationCache
            {
                Location   = account.Location,
                AccountKey = _accountKey.ExportCspBlob(true),
                Id         = account.Id,
                Key        = account.Key
            });

            RegistrationCache.SaveInstance(_cachePath);
        }