diff --git a/CH.CQRS/CH.CQRS.csproj b/CH.CQRS/CH.CQRS.csproj
index 11530f8..bff4ccf 100644
--- a/CH.CQRS/CH.CQRS.csproj
+++ b/CH.CQRS/CH.CQRS.csproj
@@ -16,6 +16,7 @@
+
diff --git a/CH.CQRS/Service/CryptoStats/CryptoService.cs b/CH.CQRS/Service/CryptoStats/CryptoService.cs
index 880a486..fc1a557 100644
--- a/CH.CQRS/Service/CryptoStats/CryptoService.cs
+++ b/CH.CQRS/Service/CryptoStats/CryptoService.cs
@@ -1,12 +1,13 @@
+using CH.CryptoStats.CoinGecko;
using CH.CryptoStats.CoinMarketCap;
namespace CH.CQRS.Service.CryptoStats;
-public class CryptoService(CoinMarketCapService coinMarketCap)
+public class CryptoService(CoinGeckoService coinGecko)
{
public async Task GetCryptoStatsAsync(CancellationToken cancellationToken)
{
- var crypto = await coinMarketCap.GetCryptoStatsAsync("bitcoin", "cad", cancellationToken);
+ var crypto = await coinGecko.GetCryptoStatsAsync("bitcoin", "cad", cancellationToken);
}
}
diff --git a/CH.CryptoStats.CoinGecko/CoinGecko.cs b/CH.CryptoStats.CoinGecko/CoinGecko.cs
deleted file mode 100644
index 11dfa4d..0000000
--- a/CH.CryptoStats.CoinGecko/CoinGecko.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Text.Json;
-using System.Threading.Tasks;
-using CH.CryptoStats.Abstractions;
-
-namespace CH.CryptoStats.CoinGecko;
-
-public class CoinGecko : ICryptoStats
-{
- //https://docs.coingecko.com/reference/coins-id
- public Task GetCryptoStatsAsync(string cryptoName, string currency, CancellationToken cancellationToken)
- {
- throw new NotImplementedException();
- }
-
- public Task ParseCryptoStats(JsonDocument jsonDocument, string currency, CancellationToken cancellationToken)
- {
- throw new NotImplementedException();
- }
-}
diff --git a/CH.CryptoStats.CoinGecko/CoinGeckoEntity.cs b/CH.CryptoStats.CoinGecko/CoinGeckoEntity.cs
new file mode 100644
index 0000000..bac0ff5
--- /dev/null
+++ b/CH.CryptoStats.CoinGecko/CoinGeckoEntity.cs
@@ -0,0 +1,24 @@
+using System.Text.Json.Serialization;
+namespace CH.CryptoStats.CoinGecko;
+public class CoinGeckoEntity
+ {
+ [JsonPropertyName("symbol")]
+ public required string Symbol { get; set; }
+ [JsonPropertyName("name")]
+ public required string Name { get; set; }
+ [JsonPropertyName("current_price")]
+ public decimal Price { get; set; }
+ [JsonPropertyName("market_cap")]
+ public decimal MarketCap { get; set; }
+ [JsonPropertyName("fully_diluted_valuation")]
+ public decimal FullyDilutedValuation { get; set; }
+ [JsonPropertyName("circulating_supply")]
+ public decimal CirculatingSupply { get; set; }
+ [JsonPropertyName("total_supply")]
+ public decimal TotalSupply { get; set; }
+ [JsonPropertyName("max_supply")]
+ public decimal MaxSupply { get; set; }
+
+ [JsonPropertyName("last_updated")]
+ public DateTime LastUpdated { get; set; }
+ }
\ No newline at end of file
diff --git a/CH.CryptoStats.CoinGecko/CoinGeckoModule.cs b/CH.CryptoStats.CoinGecko/CoinGeckoModule.cs
index 4f454a8..85cbc51 100644
--- a/CH.CryptoStats.CoinGecko/CoinGeckoModule.cs
+++ b/CH.CryptoStats.CoinGecko/CoinGeckoModule.cs
@@ -9,7 +9,7 @@ public class CoinGeckoModule : IModule
{
public IServiceCollection ConfigureServices(IServiceCollection services)
{
- services.AddScoped();
+ services.AddScoped();
return services;
}
}
diff --git a/CH.CryptoStats.CoinGecko/CoinGeckoService.cs b/CH.CryptoStats.CoinGecko/CoinGeckoService.cs
new file mode 100644
index 0000000..1daecdc
--- /dev/null
+++ b/CH.CryptoStats.CoinGecko/CoinGeckoService.cs
@@ -0,0 +1,38 @@
+using CH.CryptoStats.Abstractions;
+using Microsoft.Extensions.Configuration;
+using System.Net.Http.Json;
+using System.Text.Json;
+using CH.Energy.Abstractions.Enum;
+
+namespace CH.CryptoStats.CoinGecko;
+
+public class CoinGeckoService(IConfiguration configuration, HttpClient httpClient) : ICryptoStats
+{
+ public async Task GetCryptoStatsAsync(string cryptoName, string currency, CancellationToken cancellationToken)
+ {
+ var apiKey = configuration.GetValue("CoinGecko:ApiKey");
+ var apiUrl = configuration.GetValue("CoinGecko:ApiUrl");
+ var response = await httpClient.GetAsync($"{apiUrl}?ids={cryptoName}&vs_currency={currency}&x_cg_demo_api_key={apiKey}",cancellationToken);
+ var jsonResponse = await response.Content.ReadFromJsonAsync>(cancellationToken);
+ return ParseCryptoStats(jsonResponse.FirstOrDefault(), currency, cancellationToken).Result;
+ }
+
+ private Task ParseCryptoStats(CoinGeckoEntity coinGeckoEntity, string currency, CancellationToken cancellationToken)
+ {
+
+ var cryptoStats = new Abstractions.CryptoStats
+ {
+ Name = coinGeckoEntity.Name,
+ Symbol = coinGeckoEntity.Symbol,
+ MaxSupply = coinGeckoEntity.MaxSupply,
+ CirculatingSupply = coinGeckoEntity.CirculatingSupply,
+ TotalSupply = coinGeckoEntity.TotalSupply,
+ Currency = (Currency)System.Enum.Parse(typeof(Currency), currency.ToUpper()),
+ UpdatedAt = coinGeckoEntity.LastUpdated,
+ Price = coinGeckoEntity.Price,
+ MarketCap = coinGeckoEntity.MarketCap,
+ FullyDilutedMarketCap = coinGeckoEntity.FullyDilutedValuation
+ };
+ return Task.FromResult(cryptoStats);
+ }
+}
diff --git a/CH.CryptoStats.CoinMarketCap/CH.CryptoStats.CoinMarketCap.csproj b/CH.CryptoStats.CoinMarketCap/CH.CryptoStats.CoinMarketCap.csproj
index 359c8bb..06aa80e 100644
--- a/CH.CryptoStats.CoinMarketCap/CH.CryptoStats.CoinMarketCap.csproj
+++ b/CH.CryptoStats.CoinMarketCap/CH.CryptoStats.CoinMarketCap.csproj
@@ -14,5 +14,6 @@
+
diff --git a/CH.CryptoStats.CoinMarketCap/CoinMarketCapEntity.cs b/CH.CryptoStats.CoinMarketCap/CoinMarketCapEntity.cs
index 2752375..598ae5e 100644
--- a/CH.CryptoStats.CoinMarketCap/CoinMarketCapEntity.cs
+++ b/CH.CryptoStats.CoinMarketCap/CoinMarketCapEntity.cs
@@ -11,9 +11,9 @@ public class CoinMarketCapEntity
[JsonPropertyName("id")]
public int Id { get; set; }
[JsonPropertyName("name")]
- public string Name { get; set; }
+ public required string Name { get; set; }
[JsonPropertyName("symbol")]
- public string Symbol { get; set; }
+ public required string Symbol { get; set; }
[JsonPropertyName("max_supply")]
public int MaxSupply { get; set; }
[JsonPropertyName("circulating_supply")]
@@ -27,6 +27,7 @@ public class CoinMarketCapEntity
}
public class ApiResponse
{
+ [JsonPropertyName("data")]
public required Dictionary Data { get; set; }
}
@@ -43,9 +44,9 @@ public class CurrencyValue
[JsonPropertyName("price")]
public decimal Price { get; set; }
[JsonPropertyName("volume_24h")]
- public decimal Volume24h { get; set; }
+ public decimal Volume24H { get; set; }
[JsonPropertyName("volume_change_24h")]
- public decimal VolumeChange24h { get; set; }
+ public decimal VolumeChange24H { get; set; }
[JsonPropertyName("market_cap")]
public decimal MarketCap { get; set; }
[JsonPropertyName("market_cap_dominance")]
diff --git a/CH.CryptoStats.CoinMarketCap/CoinMarketCapService.cs b/CH.CryptoStats.CoinMarketCap/CoinMarketCapService.cs
index ab76ec6..fa1c7c2 100644
--- a/CH.CryptoStats.CoinMarketCap/CoinMarketCapService.cs
+++ b/CH.CryptoStats.CoinMarketCap/CoinMarketCapService.cs
@@ -2,6 +2,8 @@
using Microsoft.Extensions.Configuration;
using System.Net.Http.Json;
using System.Text.Json;
+using CH.Energy.Abstractions.Enum;
+
namespace CH.CryptoStats.CoinMarketCap;
public class CoinMarketCapService(HttpClient httpClient, IConfiguration configuration) : ICryptoStats
@@ -18,6 +20,7 @@ public class CoinMarketCapService(HttpClient httpClient, IConfiguration configur
private Task ParseCryptoStats(CoinMarketCapEntity coinMarketCapEntity, string currency, CancellationToken cancellationToken)
{
+ var quoteData = coinMarketCapEntity.Quote.CAD ?? coinMarketCapEntity.Quote.USD;
var cryptoStats = new Abstractions.CryptoStats
{
Name = coinMarketCapEntity.Name,
@@ -25,20 +28,14 @@ public class CoinMarketCapService(HttpClient httpClient, IConfiguration configur
MaxSupply = coinMarketCapEntity.MaxSupply,
CirculatingSupply = coinMarketCapEntity.CirculatingSupply,
TotalSupply = coinMarketCapEntity.TotalSupply,
- Currency = currency.ToUpper(),
+ Currency = (Currency)System.Enum.Parse(typeof(Currency), currency.ToUpper()),
UpdatedAt = DateTime.Parse(coinMarketCapEntity.LastUpdated),
- Price = coinMarketCapEntity.Quote.CAD == null ?
- coinMarketCapEntity.Quote.USD.Price : coinMarketCapEntity.Quote.CAD.Price,
- Volume24H = coinMarketCapEntity.Quote.CAD == null ?
- coinMarketCapEntity.Quote.USD.Volume24h : coinMarketCapEntity.Quote.CAD.Volume24h,
- VolumeChange24H = coinMarketCapEntity.Quote.CAD == null ?
- coinMarketCapEntity.Quote.USD.VolumeChange24h : coinMarketCapEntity.Quote.CAD.VolumeChange24h,
- MarketCap = coinMarketCapEntity.Quote.CAD == null ?
- coinMarketCapEntity.Quote.USD.MarketCap : coinMarketCapEntity.Quote.CAD.MarketCap,
- MarketCapDominance = coinMarketCapEntity.Quote.CAD == null ?
- coinMarketCapEntity.Quote.USD.MarketCapDominance : coinMarketCapEntity.Quote.CAD.MarketCapDominance,
- FullyDilutedMarketCap = coinMarketCapEntity.Quote.CAD == null ?
- coinMarketCapEntity.Quote.USD.FullyDilutedMarketCap : coinMarketCapEntity.Quote.CAD.FullyDilutedMarketCap
+ Price = quoteData.Price,
+ Volume24H = quoteData.Volume24H,
+ VolumeChange24H = quoteData.VolumeChange24H,
+ MarketCap = quoteData.MarketCap,
+ MarketCapDominance = quoteData.MarketCapDominance,
+ FullyDilutedMarketCap = quoteData.FullyDilutedMarketCap
};
return Task.FromResult(cryptoStats);
}
diff --git a/CH.CryptoStats/CH.CryptoStats.Abstractions.csproj b/CH.CryptoStats/CH.CryptoStats.Abstractions.csproj
index c9141d6..ba4fe7f 100644
--- a/CH.CryptoStats/CH.CryptoStats.Abstractions.csproj
+++ b/CH.CryptoStats/CH.CryptoStats.Abstractions.csproj
@@ -12,4 +12,7 @@
+
+
+
diff --git a/CH.CryptoStats/CryptoStats.cs b/CH.CryptoStats/CryptoStats.cs
index 5c985c9..f589b0f 100644
--- a/CH.CryptoStats/CryptoStats.cs
+++ b/CH.CryptoStats/CryptoStats.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
+using CH.Energy.Abstractions.Enum;
namespace CH.CryptoStats.Abstractions;
@@ -10,10 +11,10 @@ public class CryptoStats
{
public required string Name { get; set; }
public required string Symbol { get; set; }
- public long MaxSupply { get; set; }
- public long CirculatingSupply { get; set; }
- public long TotalSupply { get; set; }
- public required string Currency { get; set; }
+ public decimal MaxSupply { get; set; }
+ public decimal CirculatingSupply { get; set; }
+ public decimal TotalSupply { get; set; }
+ public required Currency Currency { get; set; }
public DateTime UpdatedAt { get; set; }
public decimal Price { get; set; }
public decimal Volume24H { get; set; }
diff --git a/CH.Enum/CH.Enum.csproj b/CH.Enum/CH.Enum.csproj
new file mode 100644
index 0000000..3a63532
--- /dev/null
+++ b/CH.Enum/CH.Enum.csproj
@@ -0,0 +1,9 @@
+
+
+
+ net8.0
+ enable
+ enable
+
+
+
diff --git a/CH.Enum/Currency.cs b/CH.Enum/Currency.cs
new file mode 100644
index 0000000..638c271
--- /dev/null
+++ b/CH.Enum/Currency.cs
@@ -0,0 +1,7 @@
+namespace CH.Energy.Abstractions.Enum;
+
+public enum Currency
+{
+ USD,
+ CAD,
+}
\ No newline at end of file
diff --git a/ConstellationHeating.sln b/ConstellationHeating.sln
index 0ef0fe0..fa03266 100644
--- a/ConstellationHeating.sln
+++ b/ConstellationHeating.sln
@@ -21,6 +21,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CH.Energy.Abstractions", "C
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CH.Energy.HydroQuebec", "CH.Energy.HydroQuebec\CH.Energy.HydroQuebec.csproj", "{91BB50CF-87B6-40A0-BB70-B42B7208167A}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CH.Enum", "CH.Enum\CH.Enum.csproj", "{45E17ADC-A1C9-4EE0-BA6E-A4B52F0621BD}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -63,6 +65,10 @@ Global
{91BB50CF-87B6-40A0-BB70-B42B7208167A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{91BB50CF-87B6-40A0-BB70-B42B7208167A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{91BB50CF-87B6-40A0-BB70-B42B7208167A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {45E17ADC-A1C9-4EE0-BA6E-A4B52F0621BD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {45E17ADC-A1C9-4EE0-BA6E-A4B52F0621BD}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {45E17ADC-A1C9-4EE0-BA6E-A4B52F0621BD}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {45E17ADC-A1C9-4EE0-BA6E-A4B52F0621BD}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE