docker files fixes from liaqat

This commit is contained in:
alirehmani
2024-05-03 16:39:25 +05:00
commit 464a8730e8
587 changed files with 44288 additions and 0 deletions

View File

@@ -0,0 +1,122 @@
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;
}
}

View File

@@ -0,0 +1,92 @@
using GraphQL.Client.Abstractions;
using GraphQL;
using Managing.Core;
using Managing.Infrastructure.Evm.Abstractions;
using Managing.Infrastructure.Evm.Subgraphs.Models;
using Managing.Domain.Candles;
using Managing.Infrastructure.Evm.Extensions;
using static Managing.Common.Enums;
namespace Managing.Infrastructure.Evm.Subgraphs;
public class ChainlinkGmx : ISubgraphPrices
{
SubgraphProvider ISubgraphPrices.GetProvider() => SubgraphProvider.ChainlinkGmx;
private readonly IGraphQLClient _graphQLClient;
private readonly string _baseToken = "_USD";
private Dictionary<string, string> _feeds = new Dictionary<string, string>()
{
{"BTC_USD", "0xae74faa92cb67a95ebcab07358bc222e33a34da7" },
{"ETH_USD", "0x37bc7498f4ff12c19678ee8fe19d713b87f6a9e6" },
{"BNB_USD", "0xc45ebd0f901ba6b2b8c7e70b717778f055ef5e6d" },
{"LINK_USD", "0xdfd03bfc3465107ce570a0397b247f546a42d0fa" },
{"UNI_USD", "0x68577f915131087199fe48913d8b416b3984fd38" },
{"SUSHI_USD", "0x7213536a36094cd8a768a5e45203ec286cba2d74" },
{"AVAX_USD", "0x0fc3657899693648bba4dbd2d8b33b82e875105d" },
{"AAVE_USD", "0xe3f0dede4b499c07e12475087ab1a084b5f93bc0" },
{"YFI_USD", "0x8a4d74003870064d41d4f84940550911fbfccf04" },
{"SPELL_USD", "0x8640b23468815902e011948f3ab173e1e83f9879" },
};
public ChainlinkGmx(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 feed = _feeds.GetValueOrDefault(path);
var perChunk = 1000;
var totalChunk = 6;
var priceRounds = new List<Round>();
var feedCondition = $@"{{ feed: ""{feed}"" }}";
for (int i = 0; i < totalChunk; i++)
{
var query = $"{{ rounds(first: {perChunk}, skip: {i * perChunk}, orderBy: unixTimestamp, orderDirection: desc, where: {feedCondition} ) {{ unixTimestamp,value}} }}";
var graphQuery = new GraphQLRequest
{
Query = query
};
var response = await _graphQLClient.SendQueryAsync<PriceRoundsChainlinkGmx>(graphQuery);
priceRounds.AddRange(response.Data.Rounds);
}
var rounds = new List<Round>();
var uniqTs = new HashSet<int>();
foreach (var round in priceRounds)
{
if (uniqTs.Contains(round.UnixTimestamp))
{
continue;
}
uniqTs.Add(round.UnixTimestamp);
rounds.Add(new Round
{
UnixTimestamp = round.UnixTimestamp,
Value = (double.Parse(round.Value) / 1e8).ToString(),
Date = DateHelpers.GetFromUnixTimestamp(round.UnixTimestamp)
});
}
rounds.Sort((timeA, timeB) => timeA.UnixTimestamp - timeB.UnixTimestamp);
return rounds.ToArray().GetCandles(timeframe, ticker);
}
public Task<decimal> GetVolume(Ticker ticker)
{
throw new NotImplementedException();
}
public Task<IEnumerable<Ticker>> GetTickers()
{
throw new NotImplementedException();
}
}

View File

@@ -0,0 +1,104 @@
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.ToString(),
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());
}
}

View File

@@ -0,0 +1,15 @@
namespace Managing.Infrastructure.Evm.Subgraphs.Models;
public class GbcPrices
{
public List<GbcPrice> PriceFeeds { get; set; }
}
public class GbcPrice
{
public int Timestamp { get; set; }
public string O { get; set; }
public string H { get; set; }
public string L { get; set; }
public string C { get; set; }
}

View File

@@ -0,0 +1,11 @@
using Nethereum.Contracts.Standards.ERC20.TokenList;
namespace Managing.Infrastructure.Evm.Subgraphs.Models;
public class Pair
{
public string ReserveETH { get; set; }
public string ReserveUSD { get; set; }
public Token Token0 { get; set; }
public Token Token1 { get; set; }
}

View File

@@ -0,0 +1,6 @@
namespace Managing.Infrastructure.Evm.Subgraphs.Models;
public class Pools
{
public List<Pair> Pairs { get; set; }
}

View File

@@ -0,0 +1,17 @@
namespace Managing.Infrastructure.Evm.Subgraphs.Models;
public class ChainlinkPrice
{
public string Price { get; set; }
public string Timestamp { get; set; }
}
public class ChainlinkAssetPairs
{
public List<AssetPair> AssetPairs { get; set; }
}
public class AssetPair
{
public string Id { get; set; }
}

View File

@@ -0,0 +1,6 @@
namespace Managing.Infrastructure.Evm.Subgraphs.Models;
public class ChainlinkPrices
{
public List<ChainlinkPrice> Prices { get; set; }
}

View File

@@ -0,0 +1,8 @@
namespace Managing.Infrastructure.Evm.Subgraphs.Models;
public class Round
{
public int UnixTimestamp { get; set; }
public DateTime Date { get; set; }
public string Value { get; set; }
}

View File

@@ -0,0 +1,6 @@
namespace Managing.Infrastructure.Evm.Subgraphs.Models;
public class PriceRoundsChainlinkGmx
{
public List<Round> Rounds { get; set; }
}

View File

@@ -0,0 +1,20 @@
using Nethereum.Contracts.Standards.ERC20.TokenList;
using System.Text.Json.Serialization;
namespace Managing.Infrastructure.Evm.Subgraphs.Models;
public class TokenDetails : Token
{
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string TradeVolume { get; set; }
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string TradeVolumeUSD { get; set; }
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string TotalSupply { get; set; }
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string TotalLiquidity { get; set; }
}

View File

@@ -0,0 +1,6 @@
namespace Managing.Infrastructure.Evm.Subgraphs.Models;
public class TopTokens
{
public List<TokenDetails> Tokens { get; set; }
}

View File

@@ -0,0 +1,41 @@
using Managing.Infrastructure.Evm.Abstractions;
using Managing.Infrastructure.Evm.Services;
using Microsoft.Extensions.DependencyInjection;
using static Managing.Common.Enums;
namespace Managing.Infrastructure.Evm.Subgraphs;
public static class SubgraphExtensions
{
public static void AddUniswapV2(this IServiceCollection services)
{
services.AddSingleton<IUniswap>(ctx =>
{
return new Uniswap(SubgraphService.GetSubgraphClient(SubgraphProvider.UniswapV2));
});
}
public static void AddChainlink(this IServiceCollection services)
{
services.AddSingleton<ISubgraphPrices>(ctx =>
{
return new Chainlink(SubgraphService.GetSubgraphClient(SubgraphProvider.ChainlinkPrice));
});
}
public static void AddGbcFeed(this IServiceCollection services)
{
services.AddSingleton<ISubgraphPrices>(ctx =>
{
return new Gbc(SubgraphService.GetSubgraphClient(SubgraphProvider.Gbc));
});
}
public static void AddChainlinkGmx(this IServiceCollection services)
{
services.AddSingleton<ISubgraphPrices>(ctx =>
{
return new ChainlinkGmx(SubgraphService.GetSubgraphClient(SubgraphProvider.ChainlinkGmx));
});
}
}

View File

@@ -0,0 +1,85 @@
using GraphQL.Client.Abstractions;
using GraphQL;
using Managing.Infrastructure.Evm.Abstractions;
using Managing.Infrastructure.Evm.Subgraphs.Models;
using Managing.Domain.Candles;
using static Managing.Common.Enums;
namespace Managing.Infrastructure.Evm.Subgraphs;
public class Uniswap : IUniswap
{
SubgraphProvider ISubgraphPrices.GetProvider() => SubgraphProvider.UniswapV2;
private readonly IGraphQLClient _graphQLClient;
public Uniswap(IGraphQLClient graphQLHttpClient)
{
_graphQLClient = graphQLHttpClient ?? throw new ArgumentNullException(nameof(graphQLHttpClient));
}
/// <summary>
/// Get the first 150 most liquid market pairs ordered by desc
/// </summary>
/// <returns></returns>
public async Task<Pools> GetMostLiquidMarketPairs()
{
var query = new GraphQLRequest
{
Query = @"
{
pairs(first: 150, orderBy: reserveETH orderDirection: desc){
token0 {
symbol
}
token1 {
symbol
}
reserveETH
reserveUSD
}
}
"
};
GraphQLResponse<Pools> response = await _graphQLClient.SendQueryAsync<Pools>(query);
return response.Data;
}
public async Task<TopTokens> GetTopTokens()
{
var query = new GraphQLRequest
{
Query = @"
{
tokens (first: 150, orderBy: tradeVolumeUSD orderDirection: desc){
symbol
name
tradeVolume
tradeVolumeUSD
totalSupply
totalLiquidity
}
}
"
};
GraphQLResponse<TopTokens> response = await _graphQLClient.SendQueryAsync<TopTokens>(query);
return response.Data;
}
public Task<IEnumerable<Candle>> GetPrices(Ticker ticker, DateTime startDate, Timeframe timeframe)
{
throw new NotImplementedException();
}
public Task<decimal> GetVolume(Ticker ticker)
{
throw new NotImplementedException();
}
public Task<IEnumerable<Ticker>> GetTickers()
{
throw new NotImplementedException();
}
}