From dc70e1934157e90440167d98f749bf5e07068bbb Mon Sep 17 00:00:00 2001 From: nils2525 Date: Thu, 9 Apr 2026 01:31:44 +0200 Subject: [PATCH 1/2] Added CoinGeckoRestClientDexApi --- CoinGecko.Net/Clients/CoinGeckoRestClient.cs | 6 +- .../Clients/CoinGeckoRestClientDexApi.cs | 93 ++++++++ .../CoinGeckoSourceGenerationContext.cs | 2 + .../Interfaces/ICoinGeckoRestClient.cs | 6 + .../Interfaces/ICoinGeckoRestClientDexApi.cs | 47 ++++ .../Objects/Models/CoinGeckoDexItem.cs | 49 ++++ .../Objects/Models/CoinGeckoDexNetwork.cs | 9 + .../Models/CoinGeckoDexNetworkDetail.cs | 23 ++ .../Models/CoinGeckoDexNetworksResponse.cs | 9 + .../Objects/Models/CoinGeckoDexPageLinks.cs | 35 +++ .../Objects/Models/CoinGeckoDexPool.cs | 9 + .../Objects/Models/CoinGeckoDexPoolDetails.cs | 219 ++++++++++++++++++ .../Models/CoinGeckoDexPoolRelationShip.cs | 43 ++++ .../Objects/Models/CoinGeckoDexResponse.cs | 70 ++++++ .../Models/CoinGeckoDexSearchPoolsResponse.cs | 9 + .../Objects/Models/CoinGeckoDexToken.cs | 9 + .../Objects/Models/CoinGeckoDexTokenDetail.cs | 47 ++++ 17 files changed, 684 insertions(+), 1 deletion(-) create mode 100644 CoinGecko.Net/Clients/CoinGeckoRestClientDexApi.cs create mode 100644 CoinGecko.Net/Interfaces/ICoinGeckoRestClientDexApi.cs create mode 100644 CoinGecko.Net/Objects/Models/CoinGeckoDexItem.cs create mode 100644 CoinGecko.Net/Objects/Models/CoinGeckoDexNetwork.cs create mode 100644 CoinGecko.Net/Objects/Models/CoinGeckoDexNetworkDetail.cs create mode 100644 CoinGecko.Net/Objects/Models/CoinGeckoDexNetworksResponse.cs create mode 100644 CoinGecko.Net/Objects/Models/CoinGeckoDexPageLinks.cs create mode 100644 CoinGecko.Net/Objects/Models/CoinGeckoDexPool.cs create mode 100644 CoinGecko.Net/Objects/Models/CoinGeckoDexPoolDetails.cs create mode 100644 CoinGecko.Net/Objects/Models/CoinGeckoDexPoolRelationShip.cs create mode 100644 CoinGecko.Net/Objects/Models/CoinGeckoDexResponse.cs create mode 100644 CoinGecko.Net/Objects/Models/CoinGeckoDexSearchPoolsResponse.cs create mode 100644 CoinGecko.Net/Objects/Models/CoinGeckoDexToken.cs create mode 100644 CoinGecko.Net/Objects/Models/CoinGeckoDexTokenDetail.cs diff --git a/CoinGecko.Net/Clients/CoinGeckoRestClient.cs b/CoinGecko.Net/Clients/CoinGeckoRestClient.cs index 6916b1d..aaee6b5 100644 --- a/CoinGecko.Net/Clients/CoinGeckoRestClient.cs +++ b/CoinGecko.Net/Clients/CoinGeckoRestClient.cs @@ -10,11 +10,14 @@ namespace CoinGecko.Net.Clients { /// - public class CoinGeckoRestClient: BaseRestClient, ICoinGeckoRestClient + public class CoinGeckoRestClient : BaseRestClient, ICoinGeckoRestClient { /// public ICoinGeckoRestClientApi Api { get; } + /// + public ICoinGeckoRestClientDexApi DexApi { get; } + #region constructor/destructor /// /// Create a new instance of the CoinGeckoClient using provided options @@ -37,6 +40,7 @@ public CoinGeckoRestClient(HttpClient? httpClient, ILoggerFactory? loggerFactory Initialize(options.Value); Api = AddApiClient(new CoinGeckoRestClientApi(this, _logger, httpClient, options.Value)); +DexApi = AddApiClient(new CoinGeckoRestClientDexApi(this, _logger, httpClient, options.Value)); } #endregion diff --git a/CoinGecko.Net/Clients/CoinGeckoRestClientDexApi.cs b/CoinGecko.Net/Clients/CoinGeckoRestClientDexApi.cs new file mode 100644 index 0000000..e1c895e --- /dev/null +++ b/CoinGecko.Net/Clients/CoinGeckoRestClientDexApi.cs @@ -0,0 +1,93 @@ +using System; +using System.Collections.Generic; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; +using CoinGecko.Net.Clients.MessageHandlers; +using CoinGecko.Net.Interfaces; +using CoinGecko.Net.Objects.Models; +using CoinGecko.Net.Objects.Options; +using CryptoExchange.Net.Clients; +using CryptoExchange.Net.Converters.MessageParsing.DynamicConverters; +using CryptoExchange.Net.Interfaces; +using CryptoExchange.Net.Objects; +using CryptoExchange.Net.Objects.Errors; +using CryptoExchange.Net.SharedApis; +using Microsoft.Extensions.Logging; + +namespace CoinGecko.Net.Clients +{ + /// + internal class CoinGeckoRestClientDexApi : RestApiClient, ICoinGeckoRestClientDexApi + { + private static readonly RequestDefinitionCache _definitions = new RequestDefinitionCache(); + private readonly CoinGeckoRestOptions _options; + + protected override IRestMessageHandler MessageHandler { get; } = new CoinGeckoRestMessageHandler(new ErrorMapping([])); + + internal CoinGeckoRestClientDexApi(CoinGeckoRestClient baseClient, ILogger logger, HttpClient? httpClient, CoinGeckoRestOptions options) + : base(logger, httpClient, options.Environment.RestApiAddressPublic, options, options.ApiOptions) + { + _options = options; + StandardRequestHeaders = new Dictionary + { + { "User-Agent", "CryptoExchange.Net/" + baseClient.CryptoExchangeLibVersion.ToString() } + }; + } + + /// + protected override IMessageSerializer CreateSerializer() => new SystemTextJsonMessageSerializer(SerializerOptions.WithConverters(CoinGeckoApi.SerializationContext)); + + /// + public override string FormatSymbol(string baseAsset, string quoteAsset, TradingMode tradingMode, DateTime? deliverTime = null) => throw new NotImplementedException(); + + #region Search Pools + + /// + public Task> SearchPoolsAsync(string query, string? network = null, IEnumerable? include = null, CancellationToken ct = default) + { + var parameters = new ParameterCollection(); + parameters.Add("query", query); + parameters.AddOptional("network", network); + parameters.AddOptionalCommaSeparated("include", include); + + var request = _definitions.GetOrCreate(HttpMethod.Get, "/api/v3/onchain/search/pools", CoinGeckoApi.RateLimiter.CoinGecko, 1, false); + return SendAsync(GetBaseAddress(), request, parameters, ct); + } + + #endregion + + #region Get Networks + + /// + public Task> GetDexNetworksAsync(int page = 1, CancellationToken ct = default) + { + var parameters = new ParameterCollection(); + parameters.Add("page", page); + + var request = _definitions.GetOrCreate(HttpMethod.Get, "/api/v3/onchain/networks", CoinGeckoApi.RateLimiter.CoinGecko, 1, false); + return SendAsync(GetBaseAddress(), request, parameters, ct); + } + + #endregion + + + + private string GetBaseAddress() + { + if (AuthenticationProvider != null) + { + if (((CoinGeckoAuthenticationProvider)AuthenticationProvider).IsDemo) + return _options.Environment.RestApiAddressPublic; + + return _options.Environment.RestApiAddressPro; + } + + return _options.Environment.RestApiAddressPublic; + } + + /// + protected override CoinGeckoAuthenticationProvider CreateAuthenticationProvider(CoinGeckoCredentials credentials) + => new CoinGeckoAuthenticationProvider(credentials); + } +} diff --git a/CoinGecko.Net/Converters/CoinGeckoSourceGenerationContext.cs b/CoinGecko.Net/Converters/CoinGeckoSourceGenerationContext.cs index 6863ac8..8e2c4cf 100644 --- a/CoinGecko.Net/Converters/CoinGeckoSourceGenerationContext.cs +++ b/CoinGecko.Net/Converters/CoinGeckoSourceGenerationContext.cs @@ -67,6 +67,8 @@ namespace CoinGecko.Net.Converters [JsonSerializable(typeof(CoinGeckoTrendingNftData[]))] [JsonSerializable(typeof(CoinGeckoTrendingCategory[]))] [JsonSerializable(typeof(CoinGeckoTrendingCategoryData[]))] + [JsonSerializable(typeof(CoinGeckoDexNetworksResponse))] + [JsonSerializable(typeof(CoinGeckoDexSearchPoolsResponse))] [JsonSerializable(typeof(string))] [JsonSerializable(typeof(int?))] [JsonSerializable(typeof(int))] diff --git a/CoinGecko.Net/Interfaces/ICoinGeckoRestClient.cs b/CoinGecko.Net/Interfaces/ICoinGeckoRestClient.cs index a47ec22..305715e 100644 --- a/CoinGecko.Net/Interfaces/ICoinGeckoRestClient.cs +++ b/CoinGecko.Net/Interfaces/ICoinGeckoRestClient.cs @@ -13,5 +13,11 @@ public interface ICoinGeckoRestClient : IRestClient /// /// ICoinGeckoRestClientApi Api { get; } + + /// + /// Dex Api endpoints + /// + /// + ICoinGeckoRestClientDexApi DexApi { get; } } } diff --git a/CoinGecko.Net/Interfaces/ICoinGeckoRestClientDexApi.cs b/CoinGecko.Net/Interfaces/ICoinGeckoRestClientDexApi.cs new file mode 100644 index 0000000..dea0eac --- /dev/null +++ b/CoinGecko.Net/Interfaces/ICoinGeckoRestClientDexApi.cs @@ -0,0 +1,47 @@ +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using CoinGecko.Net.Objects.Models; +using CryptoExchange.Net.Interfaces.Clients; +using CryptoExchange.Net.Objects; + +namespace CoinGecko.Net.Interfaces +{ + /// + /// CoinGecko API endpoints + /// + public interface ICoinGeckoRestClientDexApi : IRestApiClient + { + /// + /// Get dex networks + /// + /// Docs:
+ ///
+ /// Endpoint:
+ /// GET /api/v3/onchain/networks + ///
+ ///
+ /// Page number + /// Cancellation token + /// + Task> GetDexNetworksAsync(int page = 1, CancellationToken ct = default); + + /// + /// Search pools + /// + /// Docs:
+ ///

+ /// Endpoint:
+ /// GET /api/v3/onchain/search/pools + /// + ///
+ /// Search query, can be pool contract address, token name, token symbol, or token contract address + /// The network id + /// Attributes to include. Available values: base_token, quote_token, dex + /// Cancellation token + /// + Task> SearchPoolsAsync(string query, string? network = null, IEnumerable? include = null, CancellationToken ct = default); + + + } +} diff --git a/CoinGecko.Net/Objects/Models/CoinGeckoDexItem.cs b/CoinGecko.Net/Objects/Models/CoinGeckoDexItem.cs new file mode 100644 index 0000000..589c3c2 --- /dev/null +++ b/CoinGecko.Net/Objects/Models/CoinGeckoDexItem.cs @@ -0,0 +1,49 @@ +using System.Text.Json.Serialization; + +namespace CoinGecko.Net.Objects.Models +{ + /// + /// Dex item with attributes and relationships + /// + [SerializationModel] + public record CoinGeckoDexItem : CoinGeckoDexItem + { + /// + /// ["relationships"] Relationships + /// + [JsonPropertyName("relationships")] + public TRelationShip Details { get; set; } + } + + /// + /// Dex item with attributes + /// + [SerializationModel] + public record CoinGeckoDexItem : CoinGeckoDexItem + { + /// + /// ["attributes"] Attributes + /// + [JsonPropertyName("attributes")] + public T Details { get; set; } + } + + /// + /// Dex item + /// + [SerializationModel] + public record CoinGeckoDexItem + { + /// + /// ["id"] Id + /// + [JsonPropertyName("id")] + public string Id { get; set; } = string.Empty; + + /// + /// ["type"] Type + /// + [JsonPropertyName("type")] + public string Type { get; set; } = string.Empty; + } +} diff --git a/CoinGecko.Net/Objects/Models/CoinGeckoDexNetwork.cs b/CoinGecko.Net/Objects/Models/CoinGeckoDexNetwork.cs new file mode 100644 index 0000000..e75bd4c --- /dev/null +++ b/CoinGecko.Net/Objects/Models/CoinGeckoDexNetwork.cs @@ -0,0 +1,9 @@ +namespace CoinGecko.Net.Objects.Models +{ + /// + /// Dex network + /// + [SerializationModel] + public record CoinGeckoDexNetwork : CoinGeckoDexItem + { } +} diff --git a/CoinGecko.Net/Objects/Models/CoinGeckoDexNetworkDetail.cs b/CoinGecko.Net/Objects/Models/CoinGeckoDexNetworkDetail.cs new file mode 100644 index 0000000..d7bbdaa --- /dev/null +++ b/CoinGecko.Net/Objects/Models/CoinGeckoDexNetworkDetail.cs @@ -0,0 +1,23 @@ +using System.Text.Json.Serialization; + +namespace CoinGecko.Net.Objects.Models +{ + /// + /// Dex network details + /// + [SerializationModel] + public record CoinGeckoDexNetworkDetail + { + /// + /// ["name"] Name + /// + [JsonPropertyName("name")] + public string Name { get; set; } = string.Empty; + + /// + /// ["coingecko_asset_platform_id"] CoinGecko asset platform id + /// + [JsonPropertyName("coingecko_asset_platform_id")] + public string? CoinGeckoAssetPlatformId { get; set; } + } +} diff --git a/CoinGecko.Net/Objects/Models/CoinGeckoDexNetworksResponse.cs b/CoinGecko.Net/Objects/Models/CoinGeckoDexNetworksResponse.cs new file mode 100644 index 0000000..dde0d75 --- /dev/null +++ b/CoinGecko.Net/Objects/Models/CoinGeckoDexNetworksResponse.cs @@ -0,0 +1,9 @@ +namespace CoinGecko.Net.Objects.Models +{ + /// + /// Dex networks response + /// + [SerializationModel] + public record CoinGeckoDexNetworksResponse : CoinGeckoDexResponsePaged + { } +} diff --git a/CoinGecko.Net/Objects/Models/CoinGeckoDexPageLinks.cs b/CoinGecko.Net/Objects/Models/CoinGeckoDexPageLinks.cs new file mode 100644 index 0000000..7714fc2 --- /dev/null +++ b/CoinGecko.Net/Objects/Models/CoinGeckoDexPageLinks.cs @@ -0,0 +1,35 @@ +using System.Text.Json.Serialization; + +namespace CoinGecko.Net.Objects.Models +{ + /// + /// Dex pagination links + /// + [SerializationModel] + public record CoinGeckoDexPageLinks + { + /// + /// ["first"] First page link + /// + [JsonPropertyName("first")] + public string First { get; set; } = string.Empty; + + /// + /// ["last"] Last page link + /// + [JsonPropertyName("last")] + public string Last { get; set; } = string.Empty; + + /// + /// ["prev"] Previous page link + /// + [JsonPropertyName("prev")] + public string? Prev { get; set; } + + /// + /// ["next"] Next page link + /// + [JsonPropertyName("next")] + public string? Next { get; set; } + } +} diff --git a/CoinGecko.Net/Objects/Models/CoinGeckoDexPool.cs b/CoinGecko.Net/Objects/Models/CoinGeckoDexPool.cs new file mode 100644 index 0000000..754ffbb --- /dev/null +++ b/CoinGecko.Net/Objects/Models/CoinGeckoDexPool.cs @@ -0,0 +1,9 @@ +namespace CoinGecko.Net.Objects.Models +{ + /// + /// Dex pool + /// + [SerializationModel] + public record CoinGeckoDexPool : CoinGeckoDexItem + { } +} diff --git a/CoinGecko.Net/Objects/Models/CoinGeckoDexPoolDetails.cs b/CoinGecko.Net/Objects/Models/CoinGeckoDexPoolDetails.cs new file mode 100644 index 0000000..748d35f --- /dev/null +++ b/CoinGecko.Net/Objects/Models/CoinGeckoDexPoolDetails.cs @@ -0,0 +1,219 @@ +using System; +using System.Text.Json.Serialization; + +namespace CoinGecko.Net.Objects.Models +{ + /// + /// Dex pool details + /// + [SerializationModel] + public record CoinGeckoDexPoolDetails + { + /// + /// ["base_token_price_usd"] Base token price in USD + /// + [JsonPropertyName("base_token_price_usd")] + public decimal BaseTokenPriceUsd { get; set; } + + /// + /// ["base_token_price_native_currency"] Base token price in native currency + /// + [JsonPropertyName("base_token_price_native_currency"), JsonConverter(typeof(DecimalConverter))] + public decimal? BaseTokenPriceNativeCurrency { get; set; } + + /// + /// ["quote_token_price_usd"] Quote token price in USD + /// + [JsonPropertyName("quote_token_price_usd"), JsonConverter(typeof(DecimalConverter))] + public decimal? QuoteTokenPriceUsd { get; set; } + + /// + /// ["quote_token_price_native_currency"] Quote token price in native currency + /// + [JsonPropertyName("quote_token_price_native_currency"), JsonConverter(typeof(DecimalConverter))] + public decimal? QuoteTokenPriceNativeCurrency { get; set; } + + /// + /// ["base_token_price_quote_token"] Base token price in quote token + /// + [JsonPropertyName("base_token_price_quote_token"), JsonConverter(typeof(DecimalConverter))] + public decimal? BaseTokenPriceQuoteToken { get; set; } + + /// + /// ["quote_token_price_base_token"] Quote token price in base token + /// + [JsonPropertyName("quote_token_price_base_token"), JsonConverter(typeof(DecimalConverter))] + public decimal? QuoteTokenPriceBaseToken { get; set; } + + /// + /// ["address"] Pool address + /// + [JsonPropertyName("address")] + public string Address { get; set; } = string.Empty; + + /// + /// ["name"] Name + /// + [JsonPropertyName("name")] + public string Name { get; set; } = string.Empty; + + /// + /// ["pool_created_at"] Pool creation time + /// + [JsonPropertyName("pool_created_at")] + public DateTime PoolCreatedAt { get; set; } + + /// + /// ["fdv_usd"] Fully diluted valuation in USD + /// + [JsonPropertyName("fdv_usd")] + public decimal? FullyDilutedValuationUsd { get; set; } + + /// + /// ["market_cap_usd"] Market cap in USD + /// + [JsonPropertyName("market_cap_usd")] + public decimal? MarketCapUsd { get; set; } + + /// + /// ["price_change_percentage"] Price change percentage + /// + [JsonPropertyName("price_change_percentage")] + public CoinGeckoDexTimeValues PriceChangePercentage { get; set; } + + /// + /// ["transactions"] Transactions + /// + [JsonPropertyName("transactions")] + public CoinGeckoDexTransactions Transactions { get; set; } + + /// + /// ["volume_usd"] Volume in USD + /// + [JsonPropertyName("volume_usd")] + public CoinGeckoDexTimeValues VolumeUsd { get; set; } + + /// + /// ["reserve_in_usd"] Reserve in USD + /// + [JsonPropertyName("reserve_in_usd")] + public decimal? ReserveInUsd { get; set; } + } + + /// + /// Dex time interval values + /// + [SerializationModel] + public record CoinGeckoDexTimeValues + { + /// + /// ["m5"] Five minutes + /// + [JsonPropertyName("m5")] + public decimal FiveMinutes { get; set; } + + /// + /// ["m15"] Fifteen minutes + /// + [JsonPropertyName("m15")] + public decimal FifteenMinutes { get; set; } + + /// + /// ["m30"] Thirty minutes + /// + [JsonPropertyName("m30")] + public decimal ThirtyMinutes { get; set; } + + /// + /// ["h1"] One hour + /// + [JsonPropertyName("h1")] + public decimal OneHour { get; set; } + + /// + /// ["h6"] Six hours + /// + [JsonPropertyName("h6")] + public decimal SixHours { get; set; } + + /// + /// ["h24"] Twenty four hours + /// + [JsonPropertyName("h24")] + public decimal OneDay { get; set; } + } + + /// + /// Dex transaction counts per time interval + /// + [SerializationModel] + public record CoinGeckoDexTransactions + { + /// + /// ["m5"] Five minutes + /// + [JsonPropertyName("m5")] + public CoinGeckoDexTransactionCounts FiveMinutes { get; set; } + + /// + /// ["m15"] Fifteen minutes + /// + [JsonPropertyName("m15")] + public CoinGeckoDexTransactionCounts FifteenMinutes { get; set; } + + /// + /// ["m30"] Thirty minutes + /// + [JsonPropertyName("m30")] + public CoinGeckoDexTransactionCounts ThirtyMinutes { get; set; } + + /// + /// ["h1"] One hour + /// + [JsonPropertyName("h1")] + public CoinGeckoDexTransactionCounts OneHour { get; set; } + + /// + /// ["h6"] Six hours + /// + [JsonPropertyName("h6")] + public CoinGeckoDexTransactionCounts SixHours { get; set; } + + /// + /// ["h24"] Twenty four hours + /// + [JsonPropertyName("h24")] + public CoinGeckoDexTransactionCounts OneDay { get; set; } + } + + /// + /// Dex transaction counts + /// + [SerializationModel] + public record CoinGeckoDexTransactionCounts + { + /// + /// ["buys"] Number of buys + /// + [JsonPropertyName("buys")] + public int Buys { get; set; } + + /// + /// ["sells"] Number of sells + /// + [JsonPropertyName("sells")] + public int Sells { get; set; } + + /// + /// ["buyers"] Number of buyers + /// + [JsonPropertyName("buyers")] + public int? Buyers { get; set; } + + /// + /// ["sellers"] Number of sellers + /// + [JsonPropertyName("sellers")] + public int? Sellers { get; set; } + } +} diff --git a/CoinGecko.Net/Objects/Models/CoinGeckoDexPoolRelationShip.cs b/CoinGecko.Net/Objects/Models/CoinGeckoDexPoolRelationShip.cs new file mode 100644 index 0000000..e05b423 --- /dev/null +++ b/CoinGecko.Net/Objects/Models/CoinGeckoDexPoolRelationShip.cs @@ -0,0 +1,43 @@ +using System.Text.Json.Serialization; +using CoinGecko.Net.Objects.Models; + +namespace CoinGecko.Net.Objects +{ + /// + /// Dex pool relationships + /// + [SerializationModel] + public record CoinGeckoDexPoolRelationShip + { + /// + /// ["base_token"] Base token + /// + [JsonPropertyName("base_token")] + public CoinGeckoDexPoolRelationShipItem BaseToken { get; set; } + + /// + /// ["quote_token"] Quote token + /// + [JsonPropertyName("quote_token")] + public CoinGeckoDexPoolRelationShipItem QuoteToken { get; set; } + + /// + /// ["dex"] Dex + /// + [JsonPropertyName("dex")] + public CoinGeckoDexPoolRelationShipItem Dex { get; set; } + } + + /// + /// Dex pool relationship item + /// + [SerializationModel] + public record CoinGeckoDexPoolRelationShipItem + { + /// + /// ["data"] Data + /// + [JsonPropertyName("data")] + public CoinGeckoDexItem Data { get; set; } + } +} diff --git a/CoinGecko.Net/Objects/Models/CoinGeckoDexResponse.cs b/CoinGecko.Net/Objects/Models/CoinGeckoDexResponse.cs new file mode 100644 index 0000000..7afffdf --- /dev/null +++ b/CoinGecko.Net/Objects/Models/CoinGeckoDexResponse.cs @@ -0,0 +1,70 @@ +using System.Text.Json.Serialization; +using CoinGecko.Net.Objects.Models; + +namespace CoinGecko.Net.Objects +{ + /// + /// Dex response + /// + [SerializationModel] + public record CoinGeckoDexResponse + where TData : CoinGeckoDexItem + { + /// + /// ["data"] Data + /// + [JsonPropertyName("data")] + public TData[] Data { get; set; } + } + + + /// + /// Dex response with included items + /// + [SerializationModel] + public record CoinGeckoDexResponse : CoinGeckoDexResponse + where TData : CoinGeckoDexItem + where TInclude : CoinGeckoDexItem + { + /// + /// ["includes"] Data + /// + [JsonPropertyName("includes")] + public TData[] Data { get; set; } = []; + + /// + /// ["included"] Included items + /// + [JsonPropertyName("included")] + public TInclude[] Included { get; set; } = []; + } + + /// + /// Paged dex response + /// + [SerializationModel] + public record CoinGeckoDexResponsePaged : CoinGeckoDexResponse + where TData : CoinGeckoDexItem + { + /// + /// ["links"] Page links + /// + [JsonPropertyName("links")] + public CoinGeckoDexPageLinks PageLinks { get; set; } = new(); + } + + /// + /// Paged dex response with included items + /// + [SerializationModel] + public record CoinGeckoDexResponsePaged : CoinGeckoDexResponse + where TData : CoinGeckoDexItem + where TInclude : CoinGeckoDexItem + { + /// + /// ["links"] Page links + /// + [JsonPropertyName("links")] + public CoinGeckoDexPageLinks PageLinks { get; set; } = new(); + } +} diff --git a/CoinGecko.Net/Objects/Models/CoinGeckoDexSearchPoolsResponse.cs b/CoinGecko.Net/Objects/Models/CoinGeckoDexSearchPoolsResponse.cs new file mode 100644 index 0000000..9bf583a --- /dev/null +++ b/CoinGecko.Net/Objects/Models/CoinGeckoDexSearchPoolsResponse.cs @@ -0,0 +1,9 @@ +namespace CoinGecko.Net.Objects.Models +{ + /// + /// Dex search pools response + /// + [SerializationModel] + public record CoinGeckoDexSearchPoolsResponse : CoinGeckoDexResponse + { } +} diff --git a/CoinGecko.Net/Objects/Models/CoinGeckoDexToken.cs b/CoinGecko.Net/Objects/Models/CoinGeckoDexToken.cs new file mode 100644 index 0000000..3619b16 --- /dev/null +++ b/CoinGecko.Net/Objects/Models/CoinGeckoDexToken.cs @@ -0,0 +1,9 @@ +namespace CoinGecko.Net.Objects.Models +{ + /// + /// Dex token + /// + [SerializationModel] + public record CoinGeckoDexToken : CoinGeckoDexItem + { } +} diff --git a/CoinGecko.Net/Objects/Models/CoinGeckoDexTokenDetail.cs b/CoinGecko.Net/Objects/Models/CoinGeckoDexTokenDetail.cs new file mode 100644 index 0000000..d19b215 --- /dev/null +++ b/CoinGecko.Net/Objects/Models/CoinGeckoDexTokenDetail.cs @@ -0,0 +1,47 @@ +using System.Text.Json.Serialization; + +namespace CoinGecko.Net.Objects.Models +{ + /// + /// Dex token details + /// + [SerializationModel] + public record CoinGeckoDexTokenDetail + { + /// + /// ["address"] Address + /// + [JsonPropertyName("address")] + public string Address { get; set; } + + /// + /// ["name"] Name + /// + [JsonPropertyName("name")] + public string Name { get; set; } + + /// + /// ["symbol"] Symbol + /// + [JsonPropertyName("symbol")] + public string Symbol { get; set; } + + /// + /// ["icon_url"] Icon URL + /// + [JsonPropertyName("icon_url")] + public string? IconUrl { get; set; } + + /// + /// ["decimals"] Decimals + /// + [JsonPropertyName("decimals")] + public int Decimals { get; set; } + + /// + /// ["coingecko_coin_id"] CoinGecko coin id + /// + [JsonPropertyName("coingecko_coin_id")] + public string? CoinGeckoCoinId { get; set; } + } +} From 4d55bbfe3ae97442f8d6438ac3d341f8e52c8217 Mon Sep 17 00:00:00 2001 From: nils2525 Date: Tue, 28 Apr 2026 12:35:11 +0200 Subject: [PATCH 2/2] Updated Dex model structure; Fixed some compiler warnings --- .../Objects/Models/CoinGeckoDexItem.cs | 6 +++--- .../Objects/Models/CoinGeckoDexPoolDetails.cs | 18 +++++++++--------- .../Models/CoinGeckoDexPoolRelationShip.cs | 8 ++++---- .../Objects/Models/CoinGeckoDexResponse.cs | 8 +------- .../Objects/Models/CoinGeckoDexTokenDetail.cs | 6 +++--- 5 files changed, 20 insertions(+), 26 deletions(-) diff --git a/CoinGecko.Net/Objects/Models/CoinGeckoDexItem.cs b/CoinGecko.Net/Objects/Models/CoinGeckoDexItem.cs index 589c3c2..ae4cfb8 100644 --- a/CoinGecko.Net/Objects/Models/CoinGeckoDexItem.cs +++ b/CoinGecko.Net/Objects/Models/CoinGeckoDexItem.cs @@ -6,13 +6,13 @@ namespace CoinGecko.Net.Objects.Models /// Dex item with attributes and relationships /// [SerializationModel] - public record CoinGeckoDexItem : CoinGeckoDexItem + public record CoinGeckoDexItem : CoinGeckoDexItem { /// /// ["relationships"] Relationships /// [JsonPropertyName("relationships")] - public TRelationShip Details { get; set; } + public TRelationShip? Details { get; set; } } /// @@ -25,7 +25,7 @@ public record CoinGeckoDexItem : CoinGeckoDexItem /// ["attributes"] Attributes /// [JsonPropertyName("attributes")] - public T Details { get; set; } + public T? Details { get; set; } } /// diff --git a/CoinGecko.Net/Objects/Models/CoinGeckoDexPoolDetails.cs b/CoinGecko.Net/Objects/Models/CoinGeckoDexPoolDetails.cs index 748d35f..e4946f5 100644 --- a/CoinGecko.Net/Objects/Models/CoinGeckoDexPoolDetails.cs +++ b/CoinGecko.Net/Objects/Models/CoinGeckoDexPoolDetails.cs @@ -79,19 +79,19 @@ public record CoinGeckoDexPoolDetails /// ["price_change_percentage"] Price change percentage /// [JsonPropertyName("price_change_percentage")] - public CoinGeckoDexTimeValues PriceChangePercentage { get; set; } + public CoinGeckoDexTimeValues? PriceChangePercentage { get; set; } /// /// ["transactions"] Transactions /// [JsonPropertyName("transactions")] - public CoinGeckoDexTransactions Transactions { get; set; } + public CoinGeckoDexTransactions? Transactions { get; set; } /// /// ["volume_usd"] Volume in USD /// [JsonPropertyName("volume_usd")] - public CoinGeckoDexTimeValues VolumeUsd { get; set; } + public CoinGeckoDexTimeValues? VolumeUsd { get; set; } /// /// ["reserve_in_usd"] Reserve in USD @@ -153,37 +153,37 @@ public record CoinGeckoDexTransactions /// ["m5"] Five minutes /// [JsonPropertyName("m5")] - public CoinGeckoDexTransactionCounts FiveMinutes { get; set; } + public CoinGeckoDexTransactionCounts? FiveMinutes { get; set; } /// /// ["m15"] Fifteen minutes /// [JsonPropertyName("m15")] - public CoinGeckoDexTransactionCounts FifteenMinutes { get; set; } + public CoinGeckoDexTransactionCounts? FifteenMinutes { get; set; } /// /// ["m30"] Thirty minutes /// [JsonPropertyName("m30")] - public CoinGeckoDexTransactionCounts ThirtyMinutes { get; set; } + public CoinGeckoDexTransactionCounts? ThirtyMinutes { get; set; } /// /// ["h1"] One hour /// [JsonPropertyName("h1")] - public CoinGeckoDexTransactionCounts OneHour { get; set; } + public CoinGeckoDexTransactionCounts? OneHour { get; set; } /// /// ["h6"] Six hours /// [JsonPropertyName("h6")] - public CoinGeckoDexTransactionCounts SixHours { get; set; } + public CoinGeckoDexTransactionCounts? SixHours { get; set; } /// /// ["h24"] Twenty four hours /// [JsonPropertyName("h24")] - public CoinGeckoDexTransactionCounts OneDay { get; set; } + public CoinGeckoDexTransactionCounts? OneDay { get; set; } } /// diff --git a/CoinGecko.Net/Objects/Models/CoinGeckoDexPoolRelationShip.cs b/CoinGecko.Net/Objects/Models/CoinGeckoDexPoolRelationShip.cs index e05b423..aa084bd 100644 --- a/CoinGecko.Net/Objects/Models/CoinGeckoDexPoolRelationShip.cs +++ b/CoinGecko.Net/Objects/Models/CoinGeckoDexPoolRelationShip.cs @@ -13,19 +13,19 @@ public record CoinGeckoDexPoolRelationShip /// ["base_token"] Base token /// [JsonPropertyName("base_token")] - public CoinGeckoDexPoolRelationShipItem BaseToken { get; set; } + public CoinGeckoDexPoolRelationShipItem? BaseToken { get; set; } /// /// ["quote_token"] Quote token /// [JsonPropertyName("quote_token")] - public CoinGeckoDexPoolRelationShipItem QuoteToken { get; set; } + public CoinGeckoDexPoolRelationShipItem? QuoteToken { get; set; } /// /// ["dex"] Dex /// [JsonPropertyName("dex")] - public CoinGeckoDexPoolRelationShipItem Dex { get; set; } + public CoinGeckoDexPoolRelationShipItem? Dex { get; set; } } /// @@ -38,6 +38,6 @@ public record CoinGeckoDexPoolRelationShipItem /// ["data"] Data /// [JsonPropertyName("data")] - public CoinGeckoDexItem Data { get; set; } + public CoinGeckoDexItem? Data { get; set; } } } diff --git a/CoinGecko.Net/Objects/Models/CoinGeckoDexResponse.cs b/CoinGecko.Net/Objects/Models/CoinGeckoDexResponse.cs index 7afffdf..117dc2e 100644 --- a/CoinGecko.Net/Objects/Models/CoinGeckoDexResponse.cs +++ b/CoinGecko.Net/Objects/Models/CoinGeckoDexResponse.cs @@ -14,7 +14,7 @@ public record CoinGeckoDexResponse /// ["data"] Data /// [JsonPropertyName("data")] - public TData[] Data { get; set; } + public TData[] Data { get; set; } = []; } @@ -26,12 +26,6 @@ public record CoinGeckoDexResponse : CoinGeckoDexResponse - /// ["includes"] Data - /// - [JsonPropertyName("includes")] - public TData[] Data { get; set; } = []; - /// /// ["included"] Included items /// diff --git a/CoinGecko.Net/Objects/Models/CoinGeckoDexTokenDetail.cs b/CoinGecko.Net/Objects/Models/CoinGeckoDexTokenDetail.cs index d19b215..fb185c9 100644 --- a/CoinGecko.Net/Objects/Models/CoinGeckoDexTokenDetail.cs +++ b/CoinGecko.Net/Objects/Models/CoinGeckoDexTokenDetail.cs @@ -12,19 +12,19 @@ public record CoinGeckoDexTokenDetail /// ["address"] Address /// [JsonPropertyName("address")] - public string Address { get; set; } + public string Address { get; set; } = string.Empty; /// /// ["name"] Name /// [JsonPropertyName("name")] - public string Name { get; set; } + public string Name { get; set; } = string.Empty; /// /// ["symbol"] Symbol /// [JsonPropertyName("symbol")] - public string Symbol { get; set; } + public string Symbol { get; set; } = string.Empty; /// /// ["icon_url"] Icon URL