From 8310974067b37e1be982e4e68898093b1e556af4 Mon Sep 17 00:00:00 2001 From: Jkorf Date: Fri, 13 Mar 2026 16:32:41 +0100 Subject: [PATCH 1/9] wip --- CoinGecko.Net.UnitTests/RestRequestTests.cs | 2 +- CoinGecko.Net/Clients/CoinGeckoRestClient.cs | 8 +---- .../Clients/CoinGeckoRestClientApi.cs | 5 +-- CoinGecko.Net/CoinGecko.Net.csproj | 4 ++- .../CoinGeckoAuthenticationProvider.cs | 12 +++---- CoinGecko.Net/CoinGeckoCredentials.cs | 35 +++++++++++++++++++ .../Interfaces/ICoinGeckoRestClient.cs | 11 ++---- .../Interfaces/ICoinGeckoRestClientApi.cs | 2 +- .../Objects/CoinGeckoApiCredentials.cs | 34 ------------------ .../Objects/Options/CoinGeckoRestOptions.cs | 4 +-- 10 files changed, 55 insertions(+), 62 deletions(-) create mode 100644 CoinGecko.Net/CoinGeckoCredentials.cs delete mode 100644 CoinGecko.Net/Objects/CoinGeckoApiCredentials.cs diff --git a/CoinGecko.Net.UnitTests/RestRequestTests.cs b/CoinGecko.Net.UnitTests/RestRequestTests.cs index 8419bd4..e6c5d10 100644 --- a/CoinGecko.Net.UnitTests/RestRequestTests.cs +++ b/CoinGecko.Net.UnitTests/RestRequestTests.cs @@ -19,7 +19,7 @@ public async Task ValidateAuthCalls() var client = new CoinGeckoRestClient(opts => { opts.AutoTimestamp = false; - opts.ApiCredentials = new Objects.CoinGeckoApiCredentials("123"); + opts.ApiCredentials = new CoinGeckoCredentials("123"); }); var tester = new RestRequestValidator(client, "Endpoints", "https://pro-api.coingecko.com", IsAuthenticated); await tester.ValidateAsync(client => client.Api.GetApiUsageAsync(), "GetApiUsage"); diff --git a/CoinGecko.Net/Clients/CoinGeckoRestClient.cs b/CoinGecko.Net/Clients/CoinGeckoRestClient.cs index 3692f1b..6916b1d 100644 --- a/CoinGecko.Net/Clients/CoinGeckoRestClient.cs +++ b/CoinGecko.Net/Clients/CoinGeckoRestClient.cs @@ -10,7 +10,7 @@ namespace CoinGecko.Net.Clients { /// - public class CoinGeckoRestClient: BaseRestClient, ICoinGeckoRestClient + public class CoinGeckoRestClient: BaseRestClient, ICoinGeckoRestClient { /// public ICoinGeckoRestClientApi Api { get; } @@ -40,12 +40,6 @@ public CoinGeckoRestClient(HttpClient? httpClient, ILoggerFactory? loggerFactory } #endregion - /// - public void SetOptions(UpdateOptions options) - { - Api.SetOptions(options); - } - /// /// Set the default options to be used when creating new clients /// diff --git a/CoinGecko.Net/Clients/CoinGeckoRestClientApi.cs b/CoinGecko.Net/Clients/CoinGeckoRestClientApi.cs index c6e554c..dfb519b 100644 --- a/CoinGecko.Net/Clients/CoinGeckoRestClientApi.cs +++ b/CoinGecko.Net/Clients/CoinGeckoRestClientApi.cs @@ -24,7 +24,7 @@ namespace CoinGecko.Net.Clients { /// - internal class CoinGeckoRestClientApi : RestApiClient, ICoinGeckoRestClientApi + internal class CoinGeckoRestClientApi : RestApiClient, ICoinGeckoRestClientApi { private static readonly RequestDefinitionCache _definitions = new RequestDefinitionCache(); private readonly CoinGeckoRestOptions _options; @@ -676,6 +676,7 @@ private string GetBaseAddress() } /// - protected override AuthenticationProvider CreateAuthenticationProvider(ApiCredentials credentials) => new CoinGeckoAuthenticationProvider((CoinGeckoApiCredentials)credentials); + protected override CoinGeckoAuthenticationProvider CreateAuthenticationProvider(CoinGeckoCredentials credentials) + => new CoinGeckoAuthenticationProvider(credentials); } } diff --git a/CoinGecko.Net/CoinGecko.Net.csproj b/CoinGecko.Net/CoinGecko.Net.csproj index 0ea3246..66185d2 100644 --- a/CoinGecko.Net/CoinGecko.Net.csproj +++ b/CoinGecko.Net/CoinGecko.Net.csproj @@ -52,10 +52,12 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - all runtime; build; native; contentfiles; analyzers; buildtransitive + + + \ No newline at end of file diff --git a/CoinGecko.Net/CoinGeckoAuthenticationProvider.cs b/CoinGecko.Net/CoinGeckoAuthenticationProvider.cs index 147e828..ed22667 100644 --- a/CoinGecko.Net/CoinGeckoAuthenticationProvider.cs +++ b/CoinGecko.Net/CoinGeckoAuthenticationProvider.cs @@ -6,16 +6,16 @@ namespace CoinGecko.Net { - internal class CoinGeckoAuthenticationProvider : AuthenticationProvider + internal class CoinGeckoAuthenticationProvider : AuthenticationProvider { /// /// Whether or not a demo key is configured /// - public bool IsDemo => _credentials.DemoKey; + public bool IsDemo => ApiCredentials.DemoKey; public override ApiCredentialsType[] SupportedCredentialTypes => [ApiCredentialsType.Hmac]; - public CoinGeckoAuthenticationProvider(CoinGeckoApiCredentials credentials) : base(credentials) + public CoinGeckoAuthenticationProvider(CoinGeckoCredentials credentials) : base(credentials) { } @@ -23,10 +23,10 @@ public override void ProcessRequest(RestApiClient apiClient, RestRequestConfigur { request.QueryParameters ??= new Dictionary(); - if (_credentials.DemoKey) - request.QueryParameters.Add("x_cg_demo_api_key", _credentials.Key); + if (IsDemo) + request.QueryParameters.Add("x_cg_demo_api_key", Credential.PublicKey); else - request.QueryParameters.Add("x_cg_pro_api_key", _credentials.Key); + request.QueryParameters.Add("x_cg_pro_api_key", Credential.PublicKey); } } } diff --git a/CoinGecko.Net/CoinGeckoCredentials.cs b/CoinGecko.Net/CoinGeckoCredentials.cs new file mode 100644 index 0000000..a98ed8a --- /dev/null +++ b/CoinGecko.Net/CoinGeckoCredentials.cs @@ -0,0 +1,35 @@ +using CryptoExchange.Net.Authentication; + +namespace CoinGecko.Net +{ + /// + /// CoinGecko credentials + /// + public class CoinGeckoCredentials : ApiCredentials + { + /// + /// Whether using a demo key + /// + public bool DemoKey { get; } + + /// + /// ctor + /// + /// The API key + /// Whether or not this is a demo key + public CoinGeckoCredentials(string apiKey, bool demoKey = false) : this(new ApiKeyCredential(apiKey)) + { + DemoKey = demoKey; + } + + /// + /// ctor + /// + /// The API key credentials + /// Whether or not this is a demo key + public CoinGeckoCredentials(ApiKeyCredential credential, bool demoKey = false) : base(credential) { } + + /// + public override ApiCredentials Copy() => new CoinGeckoCredentials(ApiKey!, DemoKey); + } +} diff --git a/CoinGecko.Net/Interfaces/ICoinGeckoRestClient.cs b/CoinGecko.Net/Interfaces/ICoinGeckoRestClient.cs index f3b3bfc..a47ec22 100644 --- a/CoinGecko.Net/Interfaces/ICoinGeckoRestClient.cs +++ b/CoinGecko.Net/Interfaces/ICoinGeckoRestClient.cs @@ -1,22 +1,17 @@ -using CryptoExchange.Net.Objects.Options; +using CryptoExchange.Net.Interfaces.Clients; +using CryptoExchange.Net.Objects.Options; namespace CoinGecko.Net.Interfaces { /// /// Client for accessing the CoinGecko Rest API. /// - public interface ICoinGeckoRestClient + public interface ICoinGeckoRestClient : IRestClient { /// /// Api endpoints /// /// ICoinGeckoRestClientApi Api { get; } - - /// - /// Update specific options - /// - /// Options to update. Only specific options are changeable after the client has been created - void SetOptions(UpdateOptions options); } } diff --git a/CoinGecko.Net/Interfaces/ICoinGeckoRestClientApi.cs b/CoinGecko.Net/Interfaces/ICoinGeckoRestClientApi.cs index 6d79ffd..753cf1d 100644 --- a/CoinGecko.Net/Interfaces/ICoinGeckoRestClientApi.cs +++ b/CoinGecko.Net/Interfaces/ICoinGeckoRestClientApi.cs @@ -13,7 +13,7 @@ namespace CoinGecko.Net.Interfaces /// /// CoinGecko API endpoints /// - public interface ICoinGeckoRestClientApi: IRestApiClient + public interface ICoinGeckoRestClientApi: IRestApiClient { /// /// Get asset categories diff --git a/CoinGecko.Net/Objects/CoinGeckoApiCredentials.cs b/CoinGecko.Net/Objects/CoinGeckoApiCredentials.cs deleted file mode 100644 index 97162f1..0000000 --- a/CoinGecko.Net/Objects/CoinGeckoApiCredentials.cs +++ /dev/null @@ -1,34 +0,0 @@ -using CryptoExchange.Net.Authentication; - -namespace CoinGecko.Net.Objects -{ - /// - /// CoinGecko API credentials - /// - public class CoinGeckoApiCredentials : ApiCredentials - { - /// - /// Wheter using a demo key - /// - public bool DemoKey { get; } - - /// - /// ctor - /// - /// The API key - /// Whether or not this is a demo key - public CoinGeckoApiCredentials(string key, bool demoKey = false) : base(key, "-") - { - DemoKey = demoKey; - } - - /// - /// Copy - /// - /// - public override ApiCredentials Copy() - { - return new CoinGeckoApiCredentials(Key, DemoKey); - } - } -} diff --git a/CoinGecko.Net/Objects/Options/CoinGeckoRestOptions.cs b/CoinGecko.Net/Objects/Options/CoinGeckoRestOptions.cs index 4eefb7b..4f038c2 100644 --- a/CoinGecko.Net/Objects/Options/CoinGeckoRestOptions.cs +++ b/CoinGecko.Net/Objects/Options/CoinGeckoRestOptions.cs @@ -5,7 +5,7 @@ namespace CoinGecko.Net.Objects.Options /// /// CoinGecko Rest API options /// - public class CoinGeckoRestOptions : RestExchangeOptions + public class CoinGeckoRestOptions : RestExchangeOptions { /// /// Default options for the CoinGecko client @@ -26,7 +26,7 @@ public CoinGeckoRestOptions() /// /// Api options /// - public RestApiOptions ApiOptions { get; private set; } = new RestApiOptions(); + public RestApiOptions ApiOptions { get; private set; } = new RestApiOptions(); internal CoinGeckoRestOptions Set(CoinGeckoRestOptions targetOptions) { From 922f60da6d9a5b8317bc77bbbe89fcd4341f7356 Mon Sep 17 00:00:00 2001 From: JKorf Date: Sun, 15 Mar 2026 21:50:45 +0100 Subject: [PATCH 2/9] wip --- CoinGecko.Net/CoinGeckoAuthenticationProvider.cs | 4 ++-- CoinGecko.Net/CoinGeckoCredentials.cs | 10 +++++++++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/CoinGecko.Net/CoinGeckoAuthenticationProvider.cs b/CoinGecko.Net/CoinGeckoAuthenticationProvider.cs index ed22667..63a129e 100644 --- a/CoinGecko.Net/CoinGeckoAuthenticationProvider.cs +++ b/CoinGecko.Net/CoinGeckoAuthenticationProvider.cs @@ -24,9 +24,9 @@ public override void ProcessRequest(RestApiClient apiClient, RestRequestConfigur request.QueryParameters ??= new Dictionary(); if (IsDemo) - request.QueryParameters.Add("x_cg_demo_api_key", Credential.PublicKey); + request.QueryParameters.Add("x_cg_demo_api_key", Credential.Key); else - request.QueryParameters.Add("x_cg_pro_api_key", Credential.PublicKey); + request.QueryParameters.Add("x_cg_pro_api_key", Credential.Key); } } } diff --git a/CoinGecko.Net/CoinGeckoCredentials.cs b/CoinGecko.Net/CoinGeckoCredentials.cs index a98ed8a..07e370a 100644 --- a/CoinGecko.Net/CoinGeckoCredentials.cs +++ b/CoinGecko.Net/CoinGeckoCredentials.cs @@ -1,4 +1,5 @@ using CryptoExchange.Net.Authentication; +using System; namespace CoinGecko.Net { @@ -12,6 +13,11 @@ public class CoinGeckoCredentials : ApiCredentials /// public bool DemoKey { get; } + /// + /// + [Obsolete("Parameterless constructor is only for deserialization purposes and should not be used directly. Use parameterized constructor instead.")] + public CoinGeckoCredentials() { } + /// /// ctor /// @@ -30,6 +36,8 @@ public CoinGeckoCredentials(string apiKey, bool demoKey = false) : this(new ApiK public CoinGeckoCredentials(ApiKeyCredential credential, bool demoKey = false) : base(credential) { } /// - public override ApiCredentials Copy() => new CoinGeckoCredentials(ApiKey!, DemoKey); +#pragma warning disable CS0618 // Type or member is obsolete + public override ApiCredentials Copy() => new CoinGeckoCredentials { CredentialPairs = CredentialPairs }; +#pragma warning restore CS0618 // Type or member is obsolete } } From ec38ad942ddbff3738064ad9ddcf85644703f016 Mon Sep 17 00:00:00 2001 From: Jkorf Date: Mon, 16 Mar 2026 13:58:25 +0100 Subject: [PATCH 3/9] wip --- CoinGecko.Net/CoinGecko.Net.csproj | 1 + .../ExtensionMethods/ServiceCollectionExtensions.cs | 12 +++++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/CoinGecko.Net/CoinGecko.Net.csproj b/CoinGecko.Net/CoinGecko.Net.csproj index 66185d2..b5bf697 100644 --- a/CoinGecko.Net/CoinGecko.Net.csproj +++ b/CoinGecko.Net/CoinGecko.Net.csproj @@ -23,6 +23,7 @@ true true https://github.com/JKorf/CoinGecko.Net?tab=readme-ov-file#release-notes + $(NoWarn);SYSLIB1100;SYSLIB1101 true diff --git a/CoinGecko.Net/ExtensionMethods/ServiceCollectionExtensions.cs b/CoinGecko.Net/ExtensionMethods/ServiceCollectionExtensions.cs index b7c227e..0114673 100644 --- a/CoinGecko.Net/ExtensionMethods/ServiceCollectionExtensions.cs +++ b/CoinGecko.Net/ExtensionMethods/ServiceCollectionExtensions.cs @@ -30,7 +30,17 @@ public static IServiceCollection AddCoinGecko( IConfiguration configuration) { var options = new CoinGeckoRestOptions(); - configuration.Bind(options); + + try + { + configuration.Bind(options); + } + catch (InvalidOperationException ex) + { + throw new InvalidOperationException("Invalid configuration provided", ex); + } + + LibraryHelpers.ValidateCredentials(options.ApiCredentials); var restEnvName = options.Environment?.Name ?? options.Environment?.Name ?? CoinGeckoEnvironment.Live.Name; options.Environment = CoinGeckoEnvironment.GetEnvironmentByName(restEnvName) ?? options.Environment!; From 69feb17c4652fb0ebcb644dfeb3c4dafaeef0487 Mon Sep 17 00:00:00 2001 From: JKorf Date: Mon, 16 Mar 2026 22:02:06 +0100 Subject: [PATCH 4/9] wip --- CoinGecko.Net/CoinGeckoAuthenticationProvider.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CoinGecko.Net/CoinGeckoAuthenticationProvider.cs b/CoinGecko.Net/CoinGeckoAuthenticationProvider.cs index 63a129e..23069f0 100644 --- a/CoinGecko.Net/CoinGeckoAuthenticationProvider.cs +++ b/CoinGecko.Net/CoinGeckoAuthenticationProvider.cs @@ -13,7 +13,7 @@ internal class CoinGeckoAuthenticationProvider : AuthenticationProvider public bool IsDemo => ApiCredentials.DemoKey; - public override ApiCredentialsType[] SupportedCredentialTypes => [ApiCredentialsType.Hmac]; + public override ApiCredentialsType[] SupportedCredentialTypes => [ApiCredentialsType.HMAC]; public CoinGeckoAuthenticationProvider(CoinGeckoCredentials credentials) : base(credentials) { From 2f60d8b6e5aab345e01b3ab219ca53fcdf943e85 Mon Sep 17 00:00:00 2001 From: Jkorf Date: Wed, 18 Mar 2026 16:17:24 +0100 Subject: [PATCH 5/9] wip --- .../CoinGeckoAuthenticationProvider.cs | 4 +- CoinGecko.Net/CoinGeckoCredentials.cs | 51 ++++++++++++------- .../Objects/Options/CoinGeckoRestOptions.cs | 2 +- 3 files changed, 34 insertions(+), 23 deletions(-) diff --git a/CoinGecko.Net/CoinGeckoAuthenticationProvider.cs b/CoinGecko.Net/CoinGeckoAuthenticationProvider.cs index 23069f0..dbeba15 100644 --- a/CoinGecko.Net/CoinGeckoAuthenticationProvider.cs +++ b/CoinGecko.Net/CoinGeckoAuthenticationProvider.cs @@ -13,9 +13,7 @@ internal class CoinGeckoAuthenticationProvider : AuthenticationProvider public bool IsDemo => ApiCredentials.DemoKey; - public override ApiCredentialsType[] SupportedCredentialTypes => [ApiCredentialsType.HMAC]; - - public CoinGeckoAuthenticationProvider(CoinGeckoCredentials credentials) : base(credentials) + public CoinGeckoAuthenticationProvider(CoinGeckoCredentials credentials) : base(credentials, credentials.Credential) { } diff --git a/CoinGecko.Net/CoinGeckoCredentials.cs b/CoinGecko.Net/CoinGeckoCredentials.cs index 07e370a..8a10567 100644 --- a/CoinGecko.Net/CoinGeckoCredentials.cs +++ b/CoinGecko.Net/CoinGeckoCredentials.cs @@ -13,31 +13,44 @@ public class CoinGeckoCredentials : ApiCredentials /// public bool DemoKey { get; } - /// - /// - [Obsolete("Parameterless constructor is only for deserialization purposes and should not be used directly. Use parameterized constructor instead.")] + internal ApiKeyCredential Credential { get; set; } + public CoinGeckoCredentials() { } - /// - /// ctor - /// - /// The API key - /// Whether or not this is a demo key - public CoinGeckoCredentials(string apiKey, bool demoKey = false) : this(new ApiKeyCredential(apiKey)) + public CoinGeckoCredentials(string apiKey, bool demoKey = false) { + Credential = new ApiKeyCredential(apiKey); DemoKey = demoKey; } - /// - /// ctor - /// - /// The API key credentials - /// Whether or not this is a demo key - public CoinGeckoCredentials(ApiKeyCredential credential, bool demoKey = false) : base(credential) { } - /// -#pragma warning disable CS0618 // Type or member is obsolete - public override ApiCredentials Copy() => new CoinGeckoCredentials { CredentialPairs = CredentialPairs }; -#pragma warning restore CS0618 // Type or member is obsolete + public override ApiCredentials Copy() => new CoinGeckoCredentials { Credential = Credential }; + + // /// + // /// + // [Obsolete("Parameterless constructor is only for deserialization purposes and should not be used directly. Use parameterized constructor instead.")] + // public CoinGeckoCredentials() { } + + // /// + // /// ctor + // /// + // /// The API key + // /// Whether or not this is a demo key + // public CoinGeckoCredentials(string apiKey, bool demoKey = false) : this(new ApiKeyCredential(apiKey)) + // { + // DemoKey = demoKey; + // } + + // /// + // /// ctor + // /// + // /// The API key credentials + // /// Whether or not this is a demo key + // public CoinGeckoCredentials(ApiKeyCredential credential, bool demoKey = false) : base(credential) { } + + // /// + //#pragma warning disable CS0618 // Type or member is obsolete + // public override ApiCredentials Copy() => new CoinGeckoCredentials { CredentialPairs = CredentialPairs }; + //#pragma warning restore CS0618 // Type or member is obsolete } } diff --git a/CoinGecko.Net/Objects/Options/CoinGeckoRestOptions.cs b/CoinGecko.Net/Objects/Options/CoinGeckoRestOptions.cs index 4f038c2..e251e5f 100644 --- a/CoinGecko.Net/Objects/Options/CoinGeckoRestOptions.cs +++ b/CoinGecko.Net/Objects/Options/CoinGeckoRestOptions.cs @@ -26,7 +26,7 @@ public CoinGeckoRestOptions() /// /// Api options /// - public RestApiOptions ApiOptions { get; private set; } = new RestApiOptions(); + public RestApiOptions ApiOptions { get; private set; } = new RestApiOptions(); internal CoinGeckoRestOptions Set(CoinGeckoRestOptions targetOptions) { From 2bf2ea2a4dfab7e064ec72462118c62f7b58f78f Mon Sep 17 00:00:00 2001 From: Jkorf Date: Thu, 19 Mar 2026 16:35:50 +0100 Subject: [PATCH 6/9] wip --- CoinGecko.Net/CoinGeckoCredentials.cs | 78 ++++++++++++------- .../ServiceCollectionExtensions.cs | 2 - 2 files changed, 48 insertions(+), 32 deletions(-) diff --git a/CoinGecko.Net/CoinGeckoCredentials.cs b/CoinGecko.Net/CoinGeckoCredentials.cs index 8a10567..6b9dfa6 100644 --- a/CoinGecko.Net/CoinGeckoCredentials.cs +++ b/CoinGecko.Net/CoinGeckoCredentials.cs @@ -11,46 +11,64 @@ public class CoinGeckoCredentials : ApiCredentials /// /// Whether using a demo key /// - public bool DemoKey { get; } + public bool DemoKey { get; set; } - internal ApiKeyCredential Credential { get; set; } + /// + /// API key credential + /// + public ApiKeyCredential Credential { get; set; } + /// + /// Create new credentials + /// +#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring as nullable. public CoinGeckoCredentials() { } +#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring as nullable. + + /// + /// Create new credentials providing Api key credentials + /// + /// Api key credentials + public CoinGeckoCredentials(ApiKeyCredential credential) + { + Credential = credential; + } + + /// + /// Create new credentials providing Api key credentials + /// + /// The API key + /// Whether this is a demo key + public CoinGeckoCredentials(string key, bool demoKey = false) + { + Credential = new ApiKeyCredential(key); + DemoKey = demoKey; + } - public CoinGeckoCredentials(string apiKey, bool demoKey = false) + /// + /// Specify the ApiKey + /// + /// The API key + /// Whether this is a demo key + public CoinGeckoCredentials WithApiKey(string key, bool demoKey = false) { - Credential = new ApiKeyCredential(apiKey); + if (Credential != null) throw new InvalidOperationException("Credentials already set"); + DemoKey = demoKey; + Credential = new ApiKeyCredential(key); + return this; } /// public override ApiCredentials Copy() => new CoinGeckoCredentials { Credential = Credential }; - // /// - // /// - // [Obsolete("Parameterless constructor is only for deserialization purposes and should not be used directly. Use parameterized constructor instead.")] - // public CoinGeckoCredentials() { } - - // /// - // /// ctor - // /// - // /// The API key - // /// Whether or not this is a demo key - // public CoinGeckoCredentials(string apiKey, bool demoKey = false) : this(new ApiKeyCredential(apiKey)) - // { - // DemoKey = demoKey; - // } - - // /// - // /// ctor - // /// - // /// The API key credentials - // /// Whether or not this is a demo key - // public CoinGeckoCredentials(ApiKeyCredential credential, bool demoKey = false) : base(credential) { } - - // /// - //#pragma warning disable CS0618 // Type or member is obsolete - // public override ApiCredentials Copy() => new CoinGeckoCredentials { CredentialPairs = CredentialPairs }; - //#pragma warning restore CS0618 // Type or member is obsolete + /// + public override void Validate() + { + if (Credential == null) + throw new ArgumentException("Credential not set"); + + Credential.Validate(); + } } } diff --git a/CoinGecko.Net/ExtensionMethods/ServiceCollectionExtensions.cs b/CoinGecko.Net/ExtensionMethods/ServiceCollectionExtensions.cs index 0114673..8b19f40 100644 --- a/CoinGecko.Net/ExtensionMethods/ServiceCollectionExtensions.cs +++ b/CoinGecko.Net/ExtensionMethods/ServiceCollectionExtensions.cs @@ -40,8 +40,6 @@ public static IServiceCollection AddCoinGecko( throw new InvalidOperationException("Invalid configuration provided", ex); } - LibraryHelpers.ValidateCredentials(options.ApiCredentials); - var restEnvName = options.Environment?.Name ?? options.Environment?.Name ?? CoinGeckoEnvironment.Live.Name; options.Environment = CoinGeckoEnvironment.GetEnvironmentByName(restEnvName) ?? options.Environment!; options.ApiCredentials = options.ApiCredentials ?? options.ApiCredentials; From 478a5d95f1317cd256208de44f29c246d22df719 Mon Sep 17 00:00:00 2001 From: Jkorf Date: Fri, 20 Mar 2026 13:56:32 +0100 Subject: [PATCH 7/9] wip --- .../ServiceCollectionExtensions.cs | 1 + Examples/example-config.json | 25 +++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 Examples/example-config.json diff --git a/CoinGecko.Net/ExtensionMethods/ServiceCollectionExtensions.cs b/CoinGecko.Net/ExtensionMethods/ServiceCollectionExtensions.cs index 8b19f40..77881ed 100644 --- a/CoinGecko.Net/ExtensionMethods/ServiceCollectionExtensions.cs +++ b/CoinGecko.Net/ExtensionMethods/ServiceCollectionExtensions.cs @@ -21,6 +21,7 @@ public static class ServiceCollectionExtensions { /// /// Add services such as the ICoinGeckoRestClient. Configures the services based on the provided configuration. + /// See for an example of how to set up the configuration. /// /// The service collection /// The configuration(section) containing the options diff --git a/Examples/example-config.json b/Examples/example-config.json new file mode 100644 index 0000000..02bf49f --- /dev/null +++ b/Examples/example-config.json @@ -0,0 +1,25 @@ +{ + // Options section, select this section during DI registration using Configuration.GetSection("CoinGecko") + "CoinGecko": { + // API credentials for both REST and Websocket client + "ApiCredentials": { + "DemoKey": false, + "Credential": { + "Key": "APIKEY" + } + }, + // Set the environment by name + "Environment": { + "name": "live" + }, + "RequestTimeout": "00:00:20", + "CachingEnabled": true, + "OutputOriginalData": true, + "Proxy": { + "Host": "https://127.0.0.1", + "Port": 8080, + "Login": "User", + "Password": "Pass" + } + } +} \ No newline at end of file From bd86335494f53c4499e415748f6ad81fd45663c1 Mon Sep 17 00:00:00 2001 From: JKorf Date: Sun, 22 Mar 2026 22:06:16 +0100 Subject: [PATCH 8/9] wip --- CoinGecko.Net/CoinGeckoCredentials.cs | 2 +- CoinGecko.Net/CryptoClientExtensions.cs | 20 ------------------- .../CryptoClientExtensions.cs | 19 ------------------ .../ServiceCollectionExtensions.cs | 1 - 4 files changed, 1 insertion(+), 41 deletions(-) delete mode 100644 CoinGecko.Net/CryptoClientExtensions.cs delete mode 100644 CoinGecko.Net/ExtensionMethods/CryptoClientExtensions.cs diff --git a/CoinGecko.Net/CoinGeckoCredentials.cs b/CoinGecko.Net/CoinGeckoCredentials.cs index 6b9dfa6..41c437f 100644 --- a/CoinGecko.Net/CoinGeckoCredentials.cs +++ b/CoinGecko.Net/CoinGeckoCredentials.cs @@ -66,7 +66,7 @@ public CoinGeckoCredentials WithApiKey(string key, bool demoKey = false) public override void Validate() { if (Credential == null) - throw new ArgumentException("Credential not set"); + throw new ArgumentException($"No credentials provided on {GetType().Name}"); Credential.Validate(); } diff --git a/CoinGecko.Net/CryptoClientExtensions.cs b/CoinGecko.Net/CryptoClientExtensions.cs deleted file mode 100644 index acd6da6..0000000 --- a/CoinGecko.Net/CryptoClientExtensions.cs +++ /dev/null @@ -1,20 +0,0 @@ -using CoinGecko.Net.Clients; -using CoinGecko.Net.Interfaces; -using CryptoExchange.Net.Interfaces; -using CryptoExchange.Net.Interfaces.Clients; - -namespace CryptoExchange.Net.Clients -{ - /// - /// Extensions for the ICryptoRestClient and ICryptoSocketClient interfaces - /// - public static class CryptoClientExtensions - { - /// - /// Get the CoinGecko REST Api client - /// - /// - /// - public static ICoinGeckoRestClient CoinGecko(this ICryptoRestClient baseClient) => baseClient.TryGet(() => new CoinGeckoRestClient()); - } -} diff --git a/CoinGecko.Net/ExtensionMethods/CryptoClientExtensions.cs b/CoinGecko.Net/ExtensionMethods/CryptoClientExtensions.cs deleted file mode 100644 index 363db9b..0000000 --- a/CoinGecko.Net/ExtensionMethods/CryptoClientExtensions.cs +++ /dev/null @@ -1,19 +0,0 @@ -using CoinGecko.Net.Clients; -using CoinGecko.Net.Interfaces; -using CryptoExchange.Net.Interfaces.Clients; - -namespace CryptoExchange.Net.Interfaces -{ - /// - /// Extensions for the ICryptoRestClient and ICryptoSocketClient interfaces - /// - public static class CryptoClientExtensions - { - /// - /// Get the CoinGecko REST Api client - /// - /// - /// - public static ICoinGeckoRestClient CoinGecko(this ICryptoRestClient baseClient) => baseClient.TryGet(() => new CoinGeckoRestClient()); - } -} diff --git a/CoinGecko.Net/ExtensionMethods/ServiceCollectionExtensions.cs b/CoinGecko.Net/ExtensionMethods/ServiceCollectionExtensions.cs index 77881ed..c4958fc 100644 --- a/CoinGecko.Net/ExtensionMethods/ServiceCollectionExtensions.cs +++ b/CoinGecko.Net/ExtensionMethods/ServiceCollectionExtensions.cs @@ -78,7 +78,6 @@ private static IServiceCollection AddCoinGeckoCore( return LibraryHelpers.CreateHttpClientMessageHandler(options); }).SetHandlerLifetime(Timeout.InfiniteTimeSpan); - services.AddTransient(); return services; } } From f573d920af30f2b238eac47ee3e411fa0cd3ca5e Mon Sep 17 00:00:00 2001 From: Jkorf Date: Mon, 23 Mar 2026 15:01:14 +0100 Subject: [PATCH 9/9] wip --- CoinGecko.Net/CoinGecko.Net.csproj | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/CoinGecko.Net/CoinGecko.Net.csproj b/CoinGecko.Net/CoinGecko.Net.csproj index b5bf697..302efa1 100644 --- a/CoinGecko.Net/CoinGecko.Net.csproj +++ b/CoinGecko.Net/CoinGecko.Net.csproj @@ -53,12 +53,10 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - \ No newline at end of file