using GraphQL.Client.Abstractions; using GraphQL; using Managing.Infrastructure.Evm.Abstractions; using Managing.Core; using Managing.Infrastructure.Evm.Subgraphs.Models; using Managing.Common; using Managing.Domain.Candles; using Managing.Infrastructure.Evm.Extensions; using static Managing.Common.Enums; namespace Managing.Infrastructure.Evm.Subgraphs; public class Chainlink : ISubgraphPrices { SubgraphProvider ISubgraphPrices.GetProvider() => SubgraphProvider.ChainlinkPrice; private readonly IGraphQLClient _graphQLClient; private readonly string _baseToken = "/USD"; public Chainlink(IGraphQLClient graphQLHttpClient) { _graphQLClient = graphQLHttpClient ?? throw new ArgumentNullException(nameof(graphQLHttpClient)); } public async Task> GetPrices(Ticker ticker, DateTime startDate, Timeframe timeframe) { var path = ticker.ToString() + _baseToken; var batchSize = 1000; var batchMax = 6; var priceRounds = new List(); var feedCondition = $@"{{ assetPair: ""{path}"" }}"; // Fetching prices from graphql ticker for (int i = 0; i < batchMax; i++) { var query = $"{{ prices(first: {batchSize}, skip: {i * batchSize}, orderBy: timestamp, orderDirection: desc, where: {feedCondition} ) {{ timestamp,price}} }}"; var graphQuery = new GraphQLRequest { Query = query }; var response = await _graphQLClient.SendQueryAsync(graphQuery); priceRounds.AddRange(response.Data.Prices); } var rounds = new List(); // Format response foreach (var round in priceRounds) { var timestamp = int.Parse(round.Timestamp); rounds.Add(new Round { UnixTimestamp = timestamp, Value = (double.Parse(round.Price) / 1e8).ToString(), Date = DateHelpers.GetFromUnixTimestamp(timestamp) }); } rounds.Sort((timeA, timeB) => timeA.UnixTimestamp - timeB.UnixTimestamp); return rounds.ToArray().GetCandles(timeframe, ticker); } public Task GetVolume(Ticker ticker) { //var query = $"{{ assetPairs() {{ id }} }}"; //var graphQuery = new GraphQLRequest //{ // Query = query //}; //var response = await _graphQLClient.SendQueryAsync(graphQuery); throw new NotImplementedException(); } public async Task> GetTickers() { var batchSize = 100; var batchMax = 10; var tickers = new List(); for (int i = 0; i < batchMax; i++) { var query = $"{{ assetPairs(first: {batchSize}, skip: {i * batchSize}) {{ id }} }}"; var graphQuery = new GraphQLRequest { Query = query }; var response = await _graphQLClient.SendQueryAsync(graphQuery); if (response.Data?.AssetPairs != null) { tickers.AddRange(ParseTickers(response.Data.AssetPairs)); } } return tickers; } private List ParseTickers(List pairs) { var tickers = new List(); foreach (var pair in pairs) { var items = pair.Id.Split('/'); if (items.Length == 2 && items[1] == Constants.Stablecoins.Usd) { try { var ticker = MiscExtensions.ParseEnum(items[0]); tickers.Add(ticker); } catch (Exception ex) { } } } return tickers; } }