API обмена crypto.com практически не имеет доступной документации, по крайней мере, для C#. Я пытаюсь получить хотя бы сводку по счету, но терплю неудачу. Можем ли мы попытаться создать здесь правильные функции, которыми смогут пользоваться все?
Вот ссылка на документ
В основном только 2 функции, как показано ниже, классы удалены для упрощения:
using Newtonsoft.Json;
using RestSharp;
using System.Security.Cryptography;
using System.Text;
namespace Crypto.Account
{
internal class AccountSummary
{
private readonly string apiKey = "xxxxxx";
private readonly string apiSecret = "xxxxx";
private readonly string apiUrl = "https://api.crypto.com/v2/private/get-account-summary";
public AccountResponse GetAccountSummary()
{
var client = new RestClient();
var request = new RestRequest(apiUrl, Method.Post);
long timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
string sign = GetSignature(timestamp);
var requestBody = new
{
id = 1,
method = "private/get-account-summary",
@params = new { },
nonce = timestamp,
api_key = apiKey,
sig = sign
};
request.AddJsonBody(requestBody);
var response = client.Execute(request);
if (response.IsSuccessful)
{
//return JsonConvert.DeserializeObject<AccountResponse>(response.Content);
return "hooray";
}
else
{
throw new Exception($"Error: {response.StatusCode}, {response.Content}");
}
}
private string GetSignature(long timestamp)
{
string sigPayload = $"{apiKey}{timestamp}private/get-account-summary";
using (var hmacsha256 = new HMACSHA256(Encoding.UTF8.GetBytes(apiSecret)))
{
var hash = hmacsha256.ComputeHash(Encoding.UTF8.GetBytes(sigPayload));
return BitConverter.ToString(hash).Replace("-", "").ToLower();
}
}
}
}
Я получаю либо это:
10002 401 НЕ АВТОРИЗИРОВАНО Не аутентифицировано или ключ/подпись неверны.
или это
10003 401 IP_ILLEGAL IP-адрес не внесен в белый список
Что необходимо исправить? Какие-либо предложения?
Я проголосовал за два комментария, потому что вы нашли время ответить. Однако ни один из них не был полезен.
Вот базовый код для получения сводной информации о вашей учетной записи из API обмена Crypto.com. Это служит основой для расширения функциональных возможностей и должно помочь начать работу.
Сорт:
using Newtonsoft.Json;
using RestSharp;
using System.Security.Cryptography;
using System.Text;
namespace Crypto.Account
{
internal class AccountSummary
{
private const string apiKey = "yourAPIkey";
private const string apiSecret = "yourAPIsecret";
private readonly string apiUrl = "https://api.crypto.com/v2/private/get-account-summary";
public class AccountResponse
{
public int Id { get; set; }
public string Method { get; set; } = string.Empty;
public int Code { get; set; }
public AccountResult? Result { get; set; }
}
public class AccountResult
{
public List<AccountBalance>? Accounts { get; set; }
}
public class AccountBalance
{
public decimal Available { get; set; }
public decimal TotalBalance { get; set; }
public string Currency { get; set; } = string.Empty;
}
public AccountResponse GetAccountSummary()
{
var client = new RestClient();
var request = new RestRequest(apiUrl, Method.Post);
long timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
int id = 1;
var requestBody = new
{
id,
method = "private/get-account-summary",
@params = new { },
nonce = timestamp,
api_key = apiKey
};
string sign = GetSign(requestBody.method, id, timestamp);
request.AddJsonBody(new
{
requestBody.id,
requestBody.method,
requestBody.@params,
requestBody.nonce,
requestBody.api_key,
sig = sign
});
var response = client.Execute(request);
if (response.IsSuccessful)
{
var accountResponse = JsonConvert.DeserializeObject<AccountResponse>(response.Content);
if (accountResponse != null && accountResponse.Code == 0)
{
return accountResponse;
}
else
{
throw new Exception(accountResponse?.Method ?? "Unknown error occurred.");
}
}
else
{
throw new Exception($"Error: {response.StatusCode}, {response.Content}");
}
}
private string GetSign(string method, int id, long nonce)
{
string sigPayload = $"{method}{id}{apiKey}{nonce}";
using (var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(apiSecret)))
{
var hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(sigPayload));
return BitConverter.ToString(hash).Replace("-", "").ToLower();
}
}
}
}
Главное окно:
<Window x:Class = "Crypto.MainWindow"
xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d = "http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local = "clr-namespace:Crypto"
mc:Ignorable = "d"
Title = "MainWindow" Height = "450" Width = "800">
<Grid>
<TextBlock x:Name = "totalAssetTextBlock" HorizontalAlignment = "Left" Margin = "10,10,0,0" VerticalAlignment = "Top" FontSize = "16"/>
<DataGrid x:Name = "balancesDataGrid" AutoGenerateColumns = "False" HorizontalAlignment = "Left" Margin = "10,50,0,0" VerticalAlignment = "Top" Height = "500" Width = "600">
<DataGrid.Columns>
<DataGridTextColumn Header = "Currency" Binding = "{Binding Currency}" Width = "*"/>
<DataGridTextColumn Header = "Available" Binding = "{Binding Available}" Width = "*"/>
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>
Код позади:
using Crypto.Account;
using System.Windows;
namespace Crypto
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
LoadAccountSummaryAsync();
}
private async void LoadAccountSummaryAsync()
{
try
{
AccountSummary accountSummary = new AccountSummary();
var summary = await Task.Run(() => accountSummary.GetAccountSummary());
if (summary != null && summary.Result != null)
{
balancesDataGrid.ItemsSource = summary.Result.Accounts;
}
else
{
MessageBox.Show("No data returned from the API.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
}
}
Не стесняйтесь добавлять любые улучшения.
Ошибка «IP-адрес не внесен в белый список» похоже на проблему с конфигурацией учетной записи, а не на проблему с кодом.