docker files fixes from liaqat
This commit is contained in:
620
src/Managing.Infrastructure.Web3/EvmManager.cs
Normal file
620
src/Managing.Infrastructure.Web3/EvmManager.cs
Normal file
@@ -0,0 +1,620 @@
|
||||
using Managing.Application.Abstractions.Repositories;
|
||||
using Managing.Domain.Evm;
|
||||
using NBitcoin;
|
||||
using Nethereum.Contracts;
|
||||
using Nethereum.Hex.HexTypes;
|
||||
using Nethereum.Signer;
|
||||
using Nethereum.Web3;
|
||||
using Nethereum.HdWallet;
|
||||
using System.Numerics;
|
||||
using System.Net.Http.Json;
|
||||
using Managing.Infrastructure.Evm.Services;
|
||||
using Managing.Domain.Candles;
|
||||
using Managing.Infrastructure.Evm.Abstractions;
|
||||
using Managing.Core;
|
||||
using static Managing.Common.Enums;
|
||||
using Managing.Infrastructure.Evm.Services.Gmx;
|
||||
using Nethereum.Contracts.Standards.ERC20.ContractDefinition;
|
||||
using Managing.Common;
|
||||
using Managing.Domain.Trades;
|
||||
using Managing.Domain.Accounts;
|
||||
using Managing.Infrastructure.Evm.Models.Gmx;
|
||||
using Managing.Infrastructure.Evm.Referentials;
|
||||
|
||||
namespace Managing.Infrastructure.Evm;
|
||||
|
||||
public class EvmManager : IEvmManager
|
||||
{
|
||||
private readonly Web3 _web3;
|
||||
private readonly HttpClient _httpClient;
|
||||
private readonly string _password = "!StrongPassword94";
|
||||
private readonly IEnumerable<ISubgraphPrices> _subgraphs;
|
||||
private Dictionary<string, Dictionary<string, decimal>> _geckoPrices;
|
||||
|
||||
public EvmManager(IEnumerable<ISubgraphPrices> subgraphs)
|
||||
{
|
||||
var defaultChain = ChainService.GetEthereum();
|
||||
_web3 = new Web3(defaultChain.RpcUrl);
|
||||
_httpClient = new HttpClient();
|
||||
_subgraphs = subgraphs;
|
||||
_geckoPrices = _geckoPrices != null && _geckoPrices.Any() ? _geckoPrices : new Dictionary<string, Dictionary<string, decimal>>();
|
||||
SetupPrices();
|
||||
}
|
||||
|
||||
public void SetupPrices()
|
||||
{
|
||||
try
|
||||
{
|
||||
var geckoIds = new List<string>();
|
||||
|
||||
foreach (var ticker in Enum.GetValues<Ticker>())
|
||||
{
|
||||
var geckoId = TokenService.GetGeckoToken(ticker.ToString())?.Id;
|
||||
if (geckoId != null)
|
||||
{
|
||||
geckoIds.Add(geckoId);
|
||||
}
|
||||
}
|
||||
|
||||
if (geckoIds != null && geckoIds.Count > 0 && !_geckoPrices.Any())
|
||||
{
|
||||
_geckoPrices = GetPrices(geckoIds).Result;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// TODO : Handle error
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<decimal> GetAddressBalance(string address)
|
||||
{
|
||||
var balance = await _web3.Eth.GetBalance.SendRequestAsync(address);
|
||||
var etherAmount = Web3.Convert.FromWei(balance.Value);
|
||||
return etherAmount;
|
||||
}
|
||||
|
||||
public async Task<List<Holder>> GetContractHolders(string contractAddress, DateTime since)
|
||||
{
|
||||
var holders = new List<Holder>();
|
||||
var contract = _web3.Eth.ERC721.GetContractService(contractAddress);
|
||||
|
||||
// Retrieve total supply to iterate over all token id generated within the contract
|
||||
var totalSupply = await contract.TotalSupplyQueryAsync();
|
||||
|
||||
for (int tokenId = 1; tokenId < 10; tokenId++)
|
||||
{
|
||||
// Retrieve the owner of the nft
|
||||
var tokenOwner = await contract.OwnerOfQueryAsync(tokenId);
|
||||
|
||||
// If holder already have an nft we get the holder
|
||||
// Otherwise we create a new holder
|
||||
var holder = holders.FirstOrDefault(h => h.HolderAddress == tokenOwner) ?? new Holder(tokenOwner);
|
||||
|
||||
// Retrieve all events related to the owner on the contract address
|
||||
var nfts = await GetNftEvent(contractAddress, tokenOwner);
|
||||
|
||||
// Get tokenId related event
|
||||
var nftEvent = nfts.FirstOrDefault(n => n.Event.TokenId == new BigInteger(tokenId));
|
||||
|
||||
if (nftEvent != null)
|
||||
{
|
||||
// Retrieve the date of the nft event that occur in the blocknumber
|
||||
var blockDate = await GetBlockDate(nftEvent.Log.BlockNumber);
|
||||
var nft = new Nft(contractAddress, tokenId, blockDate);
|
||||
|
||||
// Verify if the date of the holding is before the date passed from the parameters
|
||||
if (blockDate <= since)
|
||||
{
|
||||
holder.AddNft(nft);
|
||||
|
||||
// If holder do not exist in the list we add it
|
||||
if (!holders.Exists(h => h.HolderAddress == tokenOwner))
|
||||
{
|
||||
holders.Add(holder);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"TokenId #{tokenId} for owner {tokenOwner} date not in range ({blockDate:f})");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"Error when getting tokenId #{tokenId} for owner {tokenOwner}");
|
||||
}
|
||||
|
||||
UpdateLine(tokenId, (int)totalSupply, holders.Count);
|
||||
}
|
||||
|
||||
return holders;
|
||||
}
|
||||
|
||||
public async Task<List<EventLog<Nethereum.Contracts.Standards.ERC721.ContractDefinition.TransferEventDTO>>> GetNftEvent(string contractAddress, string tokenOwner)
|
||||
{
|
||||
return await NftService.GetNftEvent(_web3, tokenOwner, contractAddress);
|
||||
}
|
||||
|
||||
public async Task<DateTime> GetBlockDate(int blockNumber)
|
||||
{
|
||||
return await GetBlockDate(new HexBigInteger(blockNumber));
|
||||
}
|
||||
|
||||
public async Task<DateTime> GetBlockDate(HexBigInteger blockNumber)
|
||||
{
|
||||
var block = await _web3.Eth.Blocks.GetBlockWithTransactionsByNumber.SendRequestAsync(blockNumber);
|
||||
var date = DateHelpers.GetFromUnixTimestamp((int)block.Timestamp.Value);
|
||||
return date;
|
||||
}
|
||||
|
||||
private void UpdateLine(int count, int total, int holders)
|
||||
{
|
||||
Console.WriteLine($"{count}/{total} - {(((decimal)count * 100m) / (decimal)total)} % - Holders : {holders}");
|
||||
}
|
||||
|
||||
public string VerifySignature(string signature, string message)
|
||||
{
|
||||
var signer = new EthereumMessageSigner();
|
||||
var addressRecovered = signer.EncodeUTF8AndEcRecover(message, signature);
|
||||
return addressRecovered;
|
||||
}
|
||||
|
||||
public string SignMessage(string message, string privateKey)
|
||||
{
|
||||
var signer = new EthereumMessageSigner();
|
||||
var signature = signer.EncodeUTF8AndSign(message, new EthECKey(privateKey));
|
||||
return signature;
|
||||
}
|
||||
|
||||
public (string Key, string Secret) GenerateAddress()
|
||||
{
|
||||
var mnemo = new Mnemonic(Wordlist.English, WordCount.Twelve);
|
||||
var wallet = new Wallet(mnemo.ToString(), _password);
|
||||
var account = wallet.GetAccount(0);
|
||||
|
||||
return (account.Address, mnemo.ToString());
|
||||
}
|
||||
|
||||
public string GetAddressFromMnemo(string mnemo)
|
||||
{
|
||||
var wallet = new Wallet(mnemo, _password);
|
||||
return wallet.GetAccount(0).Address;
|
||||
}
|
||||
|
||||
public async Task<EvmBalance> GetEtherBalance(Domain.Evm.Chain chain, string account)
|
||||
{
|
||||
var web3 = new Web3(chain.RpcUrl);
|
||||
var etherBalance = Web3.Convert.FromWei(await web3.Eth.GetBalance.SendRequestAsync(account));
|
||||
var etherPrice = (await GetPrices(new List<string> { "ethereum"}))["ethereum"]["usd"];
|
||||
|
||||
return new EvmBalance() { Balance = etherBalance, Price = etherPrice, TokenName = "ETH", Value = etherBalance * etherPrice };
|
||||
}
|
||||
|
||||
public async Task<List<EvmBalance>> GetAllBalances(Domain.Evm.Chain chain, string publicAddress)
|
||||
{
|
||||
var balances = new List<EvmBalance>();
|
||||
|
||||
|
||||
var web3 = new Web3(chain.RpcUrl);
|
||||
SetupPrices();
|
||||
foreach (var ticker in Enum.GetValues<Ticker>())
|
||||
{
|
||||
try
|
||||
{
|
||||
var balance = await GetTokenBalance(chain.Name, ticker, publicAddress);
|
||||
if (balance != null && balance.Balance > 0)
|
||||
{
|
||||
balances.Add(balance);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// TODO : handle exception
|
||||
}
|
||||
}
|
||||
var etherBalance = await GetEtherBalance(chain, publicAddress);
|
||||
etherBalance.Chain = chain;
|
||||
balances.Add(etherBalance);
|
||||
//var pageSize = 50;
|
||||
//var tokenCount = TokenService.GetTokens().Count;
|
||||
//for (int i = 0; i < (tokenCount / pageSize); i++)
|
||||
//{
|
||||
// var pageBalances = await GetBalances(chain, i, pageSize, publicAddress).ConfigureAwait(false);
|
||||
// balances.AddRange(pageBalances);
|
||||
//}
|
||||
|
||||
return balances;
|
||||
}
|
||||
|
||||
public async Task<EvmBalance> GetTokenBalance(string chainName, Ticker ticker, string publicAddress)
|
||||
{
|
||||
var chain = ChainService.GetChain(chainName);
|
||||
var web3 = new Web3(chain.RpcUrl);
|
||||
var balanceOfMessage = new BalanceOfFunction() { Owner = publicAddress };
|
||||
|
||||
//Creating a new query handler
|
||||
var queryHandler = web3.Eth.GetContractQueryHandler<BalanceOfFunction>();
|
||||
|
||||
var contractAddress = TokenService.GetContractAddress(ticker);
|
||||
|
||||
if (contractAddress == Arbitrum.Address.Zero)
|
||||
return null;
|
||||
|
||||
var balance = await queryHandler
|
||||
.QueryAsync<BigInteger>(contractAddress, balanceOfMessage)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
var geckoId = TokenService.GetGeckoToken(ticker.ToString())?.Id;
|
||||
|
||||
if (geckoId == null)
|
||||
return null;
|
||||
|
||||
var tokenUsdPrice = _geckoPrices[geckoId][Constants.Stablecoins.Usd.ToLowerInvariant()];
|
||||
var tokenDecimal = TokenService.GetDecimal(ticker);
|
||||
var balanceFromWei = Web3.Convert.FromWei(balance, tokenDecimal);
|
||||
|
||||
var evmBalance = new EvmBalance
|
||||
{
|
||||
TokenName = ticker.ToString(),
|
||||
Balance = balanceFromWei,
|
||||
TokenAddress = contractAddress,
|
||||
Value = tokenUsdPrice * balanceFromWei,
|
||||
Price = tokenUsdPrice,
|
||||
Chain = chain
|
||||
};
|
||||
|
||||
return evmBalance;
|
||||
}
|
||||
|
||||
public async Task<List<EvmBalance>> GetBalances(Domain.Evm.Chain chain, int page, int pageSize, string publicAddress)
|
||||
{
|
||||
var callList = new List<IMulticallInputOutput>();
|
||||
var startItem = (page * pageSize);
|
||||
var tokens = TokenService.GetTokens();
|
||||
var totaItemsToFetch = startItem + pageSize <= tokens.Count ? startItem + pageSize : tokens.Count + startItem;
|
||||
|
||||
for (int i = startItem; i < totaItemsToFetch; i++)
|
||||
{
|
||||
var balanceOfMessage = new BalanceOfFunction() { Owner = publicAddress };
|
||||
var call = new MulticallInputOutput<BalanceOfFunction, BalanceOfOutputDTO>(balanceOfMessage,
|
||||
tokens[i].Address);
|
||||
callList.Add(call);
|
||||
}
|
||||
var evmTokens = new List<(EvmBalance Balance, GeckoToken GeckoToken)>();
|
||||
|
||||
try
|
||||
{
|
||||
var web3 = new Web3(chain.RpcUrl);
|
||||
var geckoTokens = TokenService.GetGeckoTokens();
|
||||
|
||||
await web3.Eth.GetMultiQueryHandler().MultiCallAsync(callList.ToArray());
|
||||
|
||||
for (int i = startItem; i < totaItemsToFetch; i++)
|
||||
{
|
||||
var balance = ((MulticallInputOutput<BalanceOfFunction, BalanceOfOutputDTO>)callList[i - startItem]).Output.Balance;
|
||||
if (balance > 0)
|
||||
{
|
||||
var tokenBalance = new EvmBalance()
|
||||
{
|
||||
Balance = Web3.Convert.FromWei(balance, tokens[i].Decimals),
|
||||
TokenName = tokens[i].Symbol,
|
||||
TokenAddress = tokens[i].Address,
|
||||
Chain = chain
|
||||
};
|
||||
|
||||
var geckoToken = geckoTokens.FirstOrDefault(x => string.Equals(x.Symbol, tokens[i].Symbol, StringComparison.InvariantCultureIgnoreCase));
|
||||
|
||||
evmTokens.Add((tokenBalance, geckoToken));
|
||||
}
|
||||
}
|
||||
|
||||
if (evmTokens.Count > 0)
|
||||
{
|
||||
var ids = evmTokens.Select(x => x.GeckoToken?.Id).Distinct().ToList();
|
||||
var prices = await GetPrices(ids).ConfigureAwait(false);
|
||||
|
||||
foreach (var balance in evmTokens)
|
||||
{
|
||||
if (balance.GeckoToken != null)
|
||||
{
|
||||
var price = prices[balance.GeckoToken.Id.ToLower()];
|
||||
balance.Balance.Price = price["usd"];
|
||||
balance.Balance.Value = balance.Balance.Price * balance.Balance.Balance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// TODO : Handle error
|
||||
// No enable to reach rpc
|
||||
}
|
||||
|
||||
return evmTokens.Select(e => e.Balance).ToList();
|
||||
}
|
||||
|
||||
public async Task<Dictionary<string, Dictionary<string, decimal>>> GetPrices(List<string> geckoIds)
|
||||
{
|
||||
var idsCombined = string.Join(",", geckoIds);
|
||||
return await _httpClient.GetFromJsonAsync<Dictionary<string, Dictionary<string, decimal>>>("https://api.coingecko.com/api/v3/simple/price?ids=" + idsCombined + "&vs_currencies=usd");
|
||||
}
|
||||
|
||||
public async Task<List<EvmBalance>> GetAllBalancesOnAllChain(string publicAddress)
|
||||
{
|
||||
var chainBalances = new List<EvmBalance>();
|
||||
var chains = ChainService.GetChains();
|
||||
|
||||
foreach (var chain in chains)
|
||||
{
|
||||
chainBalances.AddRange(await GetAllBalances(chain, publicAddress));
|
||||
}
|
||||
|
||||
return chainBalances;
|
||||
}
|
||||
|
||||
public async Task<List<Candle>> GetCandles(SubgraphProvider subgraphProvider, Ticker ticker, DateTime startDate, Timeframe timeframe)
|
||||
{
|
||||
|
||||
string gmxTimeframe = GmxHelpers.GeTimeframe(timeframe);
|
||||
var gmxPrices = await _httpClient.GetFromJsonAsync<GmxPrices>($"https://stats.gmx.io/api/candles/{ticker}?preferableChainId=42161&period={gmxTimeframe}&from={startDate.ToUnixTimestamp()}&preferableSource=fast");
|
||||
//var subgraph = _subgraphs.First(s => s.GetProvider() == subgraphProvider);
|
||||
//var prices = await subgraph.GetPrices(ticker, startDate, timeframe);
|
||||
|
||||
//if (prices == null)
|
||||
//{
|
||||
// foreach (var subgraphFallback in _subgraphs.Where(s => s.GetProvider() != subgraphProvider))
|
||||
// {
|
||||
// prices = await subgraphFallback.GetPrices(ticker, startDate, timeframe);
|
||||
|
||||
// if (prices != null)
|
||||
// break;
|
||||
// }
|
||||
//}
|
||||
|
||||
if (gmxPrices == null)
|
||||
return null;
|
||||
|
||||
gmxPrices.prices.RemoveAt(gmxPrices.prices.Count - 1);
|
||||
return gmxPrices.prices.Select(p => GmxMappers.Map(p, ticker, timeframe)).ToList();
|
||||
}
|
||||
|
||||
public decimal GetVolume(SubgraphProvider subgraphProvider, Ticker ticker)
|
||||
{
|
||||
var subgraph = GetSubgraph(subgraphProvider);
|
||||
var volume = subgraph.GetVolume(ticker).Result;
|
||||
return volume;
|
||||
}
|
||||
|
||||
private ISubgraphPrices GetSubgraph(SubgraphProvider subgraphProvider)
|
||||
{
|
||||
return _subgraphs.First(s => s.GetProvider() == subgraphProvider);
|
||||
}
|
||||
|
||||
public async Task<List<Ticker>> GetAvailableTicker()
|
||||
{
|
||||
var subgraph = GetSubgraph(SubgraphProvider.Gbc);
|
||||
var pairs = await subgraph.GetTickers();
|
||||
return pairs.ToList();
|
||||
}
|
||||
|
||||
public async Task<Candle> GetCandle(SubgraphProvider subgraphProvider, Ticker ticker)
|
||||
{
|
||||
var lastPrices = await GetCandles(subgraphProvider, ticker, DateTime.UtcNow.AddMinutes(-15), Timeframe.FiveMinutes);
|
||||
return lastPrices.Last();
|
||||
}
|
||||
|
||||
public async Task<bool> InitAddress(string chainName, string publicAddress, string privateKey)
|
||||
{
|
||||
try
|
||||
{
|
||||
var chain = ChainService.GetChain(chainName);
|
||||
var account = new Wallet(privateKey, _password).GetAccount(publicAddress);
|
||||
var web3 = new Web3(account, chain.RpcUrl);
|
||||
var tickers = await GetAvailableTicker();
|
||||
await GmxService.InitAccountForTrading(web3, publicAddress, tickers);
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<bool> ApproveTicker(string publicAddress, string privateKey, Ticker ticker)
|
||||
{
|
||||
try
|
||||
{
|
||||
var account = new Wallet(privateKey, _password).GetAccount(publicAddress);
|
||||
var contractAddress = TokenService.GetContractAddress(ticker);
|
||||
await GmxService.ApproveToken(_web3, publicAddress, contractAddress);
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<bool> Send(
|
||||
Domain.Evm.Chain chain,
|
||||
Ticker ticker,
|
||||
decimal amount,
|
||||
string publicAddress,
|
||||
string privateKey,
|
||||
string receiverAddress)
|
||||
{
|
||||
var account = new Wallet(privateKey, _password).GetAccount(publicAddress);
|
||||
var web3 = new Web3(account, chain.RpcUrl);
|
||||
|
||||
try
|
||||
{
|
||||
if (ticker == Ticker.ETH)
|
||||
{
|
||||
return await SendEth(amount, receiverAddress, web3);
|
||||
}
|
||||
else
|
||||
{
|
||||
return await SendToken(ticker, amount, publicAddress, receiverAddress, web3);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task<bool> SendEth(decimal amount, string receiverAddress, Web3 web3)
|
||||
{
|
||||
web3.TransactionManager.UseLegacyAsDefault = true;
|
||||
var ethService = web3.Eth.GetEtherTransferService();
|
||||
var gas = await ethService.EstimateGasAsync(receiverAddress, amount);
|
||||
var transaction = await ethService.TransferEtherAndWaitForReceiptAsync(receiverAddress, amount, gas: gas);
|
||||
|
||||
return transaction.Status.Value == 1;
|
||||
}
|
||||
|
||||
private static async Task<bool> SendToken(
|
||||
Ticker ticker,
|
||||
decimal amount,
|
||||
string senderAddress,
|
||||
string receiverAddress,
|
||||
Web3 web3)
|
||||
{
|
||||
|
||||
var contractAddress = TokenService.GetContractAddress(ticker);
|
||||
var transactionMessage = new TransferFunction
|
||||
{
|
||||
FromAddress = senderAddress,
|
||||
To = receiverAddress,
|
||||
Value = Web3.Convert.ToWei(amount)
|
||||
};
|
||||
|
||||
var transferHandler = web3.Eth.GetContractTransactionHandler<TransferFunction>();
|
||||
var transferReceipt =
|
||||
await transferHandler.SendRequestAndWaitForReceiptAsync(contractAddress, transactionMessage);
|
||||
|
||||
var transaction = await web3.Eth.Transactions.GetTransactionByHash.SendRequestAsync(transferReceipt.TransactionHash);
|
||||
return transaction != null;
|
||||
}
|
||||
|
||||
public async Task<bool> CancelOrders(Account account, Ticker ticker)
|
||||
{
|
||||
var wallet = new Wallet(account.Secret, _password).GetAccount(account.Key);
|
||||
var chain = ChainService.GetChain(Constants.Chains.Arbitrum);
|
||||
var web3 = new Web3(wallet, chain.RpcUrl);
|
||||
return await GmxService.CancelOrders(web3, account.Key, ticker);
|
||||
}
|
||||
|
||||
public async Task<Trade> IncreasePosition(
|
||||
Account account,
|
||||
Ticker ticker,
|
||||
TradeDirection direction,
|
||||
decimal price,
|
||||
decimal quantity,
|
||||
decimal? leverage)
|
||||
{
|
||||
var wallet = new Wallet(account.Secret, _password).GetAccount(account.Key);
|
||||
var chain = ChainService.GetChain(Constants.Chains.Arbitrum);
|
||||
var web3 = new Web3(wallet, chain.RpcUrl);
|
||||
|
||||
Trade trade = null;
|
||||
try
|
||||
{
|
||||
trade = await GmxService.IncreasePosition(web3, account.Key, ticker, direction, price, quantity, leverage);
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
|
||||
return trade;
|
||||
}
|
||||
|
||||
public async Task<Trade> DecreasePosition(
|
||||
Account account,
|
||||
Ticker ticker,
|
||||
TradeDirection direction,
|
||||
decimal price,
|
||||
decimal quantity,
|
||||
decimal? leverage)
|
||||
{
|
||||
var wallet = new Wallet(account.Secret, _password).GetAccount(account.Key);
|
||||
var chain = ChainService.GetChain(Constants.Chains.Arbitrum);
|
||||
var web3 = new Web3(wallet, chain.RpcUrl);
|
||||
|
||||
Trade trade = null;
|
||||
try
|
||||
{
|
||||
trade = await GmxService.DecreasePosition(web3, account.Key, ticker, direction, price, quantity, leverage);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
|
||||
return trade;
|
||||
}
|
||||
|
||||
public async Task<Trade> DecreaseOrder(Account account, TradeType tradeType, Ticker ticker, TradeDirection direction, decimal price, decimal quantity, decimal? leverage)
|
||||
{
|
||||
|
||||
var wallet = new Wallet(account.Secret, _password).GetAccount(account.Key);
|
||||
var chain = ChainService.GetChain(Constants.Chains.Arbitrum);
|
||||
var web3 = new Web3(wallet, chain.RpcUrl);
|
||||
|
||||
Trade trade = null;
|
||||
try
|
||||
{
|
||||
trade = await GmxService.DecreaseOrder(web3, tradeType, account.Key, ticker, direction, price, quantity, leverage);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
|
||||
return trade;
|
||||
}
|
||||
|
||||
public async Task<Trade> GetTrade(Account account, string chainName, Ticker ticker)
|
||||
{
|
||||
return await GetTrade(account.Key, chainName, ticker);
|
||||
}
|
||||
|
||||
|
||||
public async Task<Trade> GetTrade(string reference, string chainName, Ticker ticker)
|
||||
{
|
||||
var chain = ChainService.GetChain(chainName);
|
||||
var web3 = new Web3(chain.RpcUrl);
|
||||
return await GmxService.GetTrade(web3, reference, ticker);
|
||||
}
|
||||
|
||||
public async Task<decimal> QuantityInPosition(string chainName, string publicAddress, Ticker ticker)
|
||||
{
|
||||
var chain = ChainService.GetChain(chainName);
|
||||
var web3 = new Web3(chain.RpcUrl);
|
||||
var quantity = await GmxService.QuantityInPosition(web3, publicAddress, ticker);
|
||||
return quantity;
|
||||
}
|
||||
|
||||
public async Task<decimal> GetFee(string chainName)
|
||||
{
|
||||
var chain = ChainService.GetChain(chainName);
|
||||
var web3 = new Web3(chain.RpcUrl);
|
||||
var etherPrice = (await GetPrices(new List<string> { "ethereum" }))["ethereum"]["usd"];
|
||||
var fee = await GmxService.GetFee(web3, etherPrice);
|
||||
return fee;
|
||||
}
|
||||
|
||||
public async Task<List<Trade>> GetOrders(Account account, Ticker ticker)
|
||||
{
|
||||
var wallet = new Wallet(account.Secret, _password).GetAccount(account.Key);
|
||||
var chain = ChainService.GetChain(Constants.Chains.Arbitrum);
|
||||
var web3 = new Web3(wallet, chain.RpcUrl);
|
||||
var orders = await GmxService.GetOrders(web3, account.Key, ticker);
|
||||
|
||||
return GmxHelpers.Map(orders, ticker);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user