Files
managing-apps/src/Managing.Infrastructure.Web3/Subgraphs/Gbc.cs
Oda 56b4f14eb3 Price reminder and init approval
* Start price reminder grain

* Add config and init grain at startup

* Save init wallet when already init
2025-09-13 02:29:14 +07:00

107 lines
3.3 KiB
C#

using GraphQL;
using GraphQL.Client.Abstractions;
using Managing.Core;
using Managing.Domain.Candles;
using Managing.Infrastructure.Evm.Abstractions;
using Managing.Infrastructure.Evm.Services;
using Managing.Infrastructure.Evm.Subgraphs.Models;
using NBitcoin;
using static Managing.Common.Enums;
namespace Managing.Infrastructure.Evm.Subgraphs;
public class Gbc : ISubgraphPrices
{
private readonly IGraphQLClient _graphQLClient;
public SubgraphProvider GetProvider() => SubgraphProvider.Gbc;
public Gbc(IGraphQLClient graphQLHttpClient)
{
_graphQLClient = graphQLHttpClient ?? throw new ArgumentNullException(nameof(graphQLHttpClient));
}
public async Task<IEnumerable<Candle>> GetPrices(Ticker ticker, DateTime startDate, Timeframe timeframe)
{
var batchSize = 1000;
var batchMax = 6;
var priceRounds = new List<GbcPrice>();
var tickerContract = TokenService.GetContractAddress(ticker);
var unixTimeframe = timeframe.GetUnixInterval();
var start = startDate.ToUnixTimestamp();
var end = DateTime.UtcNow.ToUnixTimestamp();
var feedCondition =
$@"{{ tokenAddress: ""_{tickerContract}"", interval: ""_{unixTimeframe}"", timestamp_gte: {start}, timestamp_lte: {end} }}";
// Fetching prices from graphql ticker
for (int i = 0; i < batchMax; i++)
{
var query =
$"{{ pricefeeds(first: {batchSize}, skip: {i * batchSize}, orderBy: timestamp, orderDirection: desc, where: {feedCondition} ) {{ timestamp,o,h,l,c}} }}";
var graphQuery = new GraphQLRequest
{
Query = query
};
var response = await _graphQLClient.SendQueryAsync<GbcPrices>(graphQuery);
priceRounds.AddRange(response.Data.PriceFeeds);
}
priceRounds.Sort((timeA, timeB) => timeA.Timestamp - timeB.Timestamp);
var candles = new List<Candle>();
var firstRound = priceRounds.FirstOrDefault();
if (firstRound == null)
return candles;
var previousCandle = BuildCandle(firstRound, ticker, timeframe);
// Format response
foreach (var price in priceRounds.Skip(1))
{
var candle = BuildCandle(price, ticker, timeframe);
candle.OpenTime = previousCandle.Date;
candles.Add(candle);
}
return candles;
}
private Candle BuildCandle(GbcPrice ohlc, Ticker ticker, Timeframe timeframe)
{
return new Candle()
{
Date = DateHelpers.GetFromUnixTimestamp(ohlc.Timestamp),
Open = FormatPrice(ohlc.O),
High = FormatPrice(ohlc.H),
Low = FormatPrice(ohlc.L),
Close = FormatPrice(ohlc.C),
Exchange = TradingExchanges.Evm,
Ticker = ticker,
Timeframe = timeframe
};
}
private static decimal FormatPrice(string price)
{
return (decimal)(double.Parse(price) / 1e30);
}
public Task<decimal> GetVolume(Ticker ticker)
{
throw new NotImplementedException();
}
public Task<IEnumerable<Ticker>> GetTickers()
{
var tickers = new List<Ticker>()
{
Ticker.BTC,
Ticker.LINK,
Ticker.ETH,
Ticker.UNI
};
return Task.FromResult(tickers.AsEnumerable());
}
}