Files
managing-apps/src/Managing.Infrastructure.Web3/Subgraphs/Chainlink.cs
2024-05-03 16:39:25 +05:00

123 lines
3.8 KiB
C#

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<IEnumerable<Candle>> GetPrices(Ticker ticker, DateTime startDate, Timeframe timeframe)
{
var path = ticker.ToString() + _baseToken;
var batchSize = 1000;
var batchMax = 6;
var priceRounds = new List<ChainlinkPrice>();
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<ChainlinkPrices>(graphQuery);
priceRounds.AddRange(response.Data.Prices);
}
var rounds = new List<Round>();
// 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<decimal> GetVolume(Ticker ticker)
{
//var query = $"{{ assetPairs() {{ id }} }}";
//var graphQuery = new GraphQLRequest
//{
// Query = query
//};
//var response = await _graphQLClient.SendQueryAsync<AssetPairs>(graphQuery);
throw new NotImplementedException();
}
public async Task<IEnumerable<Ticker>> GetTickers()
{
var batchSize = 100;
var batchMax = 10;
var tickers = new List<Ticker>();
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<ChainlinkAssetPairs>(graphQuery);
if (response.Data?.AssetPairs != null)
{
tickers.AddRange(ParseTickers(response.Data.AssetPairs));
}
}
return tickers;
}
private List<Ticker> ParseTickers(List<AssetPair> pairs)
{
var tickers = new List<Ticker>();
foreach (var pair in pairs)
{
var items = pair.Id.Split('/');
if (items.Length == 2 && items[1] == Constants.Stablecoins.Usd)
{
try
{
var ticker = MiscExtensions.ParseEnum<Ticker>(items[0]);
tickers.Add(ticker);
}
catch (Exception ex) { }
}
}
return tickers;
}
}