mirror of
https://github.com/JKorf/CryptoExchange.Net
synced 2025-06-08 00:16:27 +00:00
Updated some interfaces, made time syncing methods nullable for apis not using it, added optional retry checking, removed private key from api credentials, added better support for api credentials subclasses
This commit is contained in:
parent
a222bb3f02
commit
11650f7c1a
@ -37,8 +37,8 @@ namespace CryptoExchange.Net.UnitTests
|
|||||||
|
|
||||||
public CallResult<T> Deserialize<T>(string data) => Deserialize<T>(data, null, null);
|
public CallResult<T> Deserialize<T>(string data) => Deserialize<T>(data, null, null);
|
||||||
|
|
||||||
public override TimeSpan GetTimeOffset() => throw new NotImplementedException();
|
public override TimeSpan? GetTimeOffset() => null;
|
||||||
public override TimeSyncInfo GetTimeSyncInfo() => throw new NotImplementedException();
|
public override TimeSyncInfo GetTimeSyncInfo() => null;
|
||||||
protected override AuthenticationProvider CreateAuthenticationProvider(ApiCredentials credentials) => throw new NotImplementedException();
|
protected override AuthenticationProvider CreateAuthenticationProvider(ApiCredentials credentials) => throw new NotImplementedException();
|
||||||
protected override Task<WebCallResult<DateTime>> GetServerTimestampAsync() => throw new NotImplementedException();
|
protected override Task<WebCallResult<DateTime>> GetServerTimestampAsync() => throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
@ -142,7 +142,7 @@ namespace CryptoExchange.Net.UnitTests.TestImplementations
|
|||||||
ParameterPositions[method] = position;
|
ParameterPositions[method] = position;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override TimeSpan GetTimeOffset()
|
public override TimeSpan? GetTimeOffset()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
@ -178,7 +178,7 @@ namespace CryptoExchange.Net.UnitTests.TestImplementations
|
|||||||
return new ServerError((int)error["errorCode"], (string)error["errorMessage"]);
|
return new ServerError((int)error["errorCode"], (string)error["errorMessage"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override TimeSpan GetTimeOffset()
|
public override TimeSpan? GetTimeOffset()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
@ -21,20 +21,6 @@ namespace CryptoExchange.Net.Authentication
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public SecureString? Secret { get; }
|
public SecureString? Secret { get; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The private key to authenticate requests
|
|
||||||
/// </summary>
|
|
||||||
public PrivateKey? PrivateKey { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Create Api credentials providing a private key for authentication
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="privateKey">The private key used for signing</param>
|
|
||||||
public ApiCredentials(PrivateKey privateKey)
|
|
||||||
{
|
|
||||||
PrivateKey = privateKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create Api credentials providing an api key and secret for authentication
|
/// Create Api credentials providing an api key and secret for authentication
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -69,11 +55,8 @@ namespace CryptoExchange.Net.Authentication
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public virtual ApiCredentials Copy()
|
public virtual ApiCredentials Copy()
|
||||||
{
|
{
|
||||||
if (PrivateKey == null)
|
|
||||||
// Use .GetString() to create a copy of the SecureString
|
// Use .GetString() to create a copy of the SecureString
|
||||||
return new ApiCredentials(Key!.GetString(), Secret!.GetString());
|
return new ApiCredentials(Key!.GetString(), Secret!.GetString());
|
||||||
else
|
|
||||||
return new ApiCredentials(PrivateKey!.Copy());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -123,7 +106,6 @@ namespace CryptoExchange.Net.Authentication
|
|||||||
{
|
{
|
||||||
Key?.Dispose();
|
Key?.Dispose();
|
||||||
Secret?.Dispose();
|
Secret?.Dispose();
|
||||||
PrivateKey?.Dispose();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -223,7 +223,7 @@ namespace CryptoExchange.Net.Authentication
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
protected static DateTime GetTimestamp(RestApiClient apiClient)
|
protected static DateTime GetTimestamp(RestApiClient apiClient)
|
||||||
{
|
{
|
||||||
return DateTime.UtcNow.Add(apiClient?.GetTimeOffset() ?? TimeSpan.Zero)!;
|
return DateTime.UtcNow.Add(apiClient.GetTimeOffset() ?? TimeSpan.Zero)!;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -1,110 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Security;
|
|
||||||
|
|
||||||
namespace CryptoExchange.Net.Authentication
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Private key info
|
|
||||||
/// </summary>
|
|
||||||
public class PrivateKey : IDisposable
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The private key
|
|
||||||
/// </summary>
|
|
||||||
public SecureString Key { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The private key's pass phrase
|
|
||||||
/// </summary>
|
|
||||||
public SecureString? Passphrase { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Indicates if the private key is encrypted or not
|
|
||||||
/// </summary>
|
|
||||||
public bool IsEncrypted { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Create a private key providing an encrypted key information
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="key">The private key used for signing</param>
|
|
||||||
/// <param name="passphrase">The private key's passphrase</param>
|
|
||||||
public PrivateKey(SecureString key, SecureString passphrase)
|
|
||||||
{
|
|
||||||
Key = key;
|
|
||||||
Passphrase = passphrase;
|
|
||||||
|
|
||||||
IsEncrypted = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Create a private key providing an encrypted key information
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="key">The private key used for signing</param>
|
|
||||||
/// <param name="passphrase">The private key's passphrase</param>
|
|
||||||
public PrivateKey(string key, string passphrase)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(key) || string.IsNullOrEmpty(passphrase))
|
|
||||||
throw new ArgumentException("Key and passphrase can't be null/empty");
|
|
||||||
|
|
||||||
var secureKey = new SecureString();
|
|
||||||
foreach (var c in key)
|
|
||||||
secureKey.AppendChar(c);
|
|
||||||
secureKey.MakeReadOnly();
|
|
||||||
Key = secureKey;
|
|
||||||
|
|
||||||
var securePassphrase = new SecureString();
|
|
||||||
foreach (var c in passphrase)
|
|
||||||
securePassphrase.AppendChar(c);
|
|
||||||
securePassphrase.MakeReadOnly();
|
|
||||||
Passphrase = securePassphrase;
|
|
||||||
|
|
||||||
IsEncrypted = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Create a private key providing an unencrypted key information
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="key">The private key used for signing</param>
|
|
||||||
public PrivateKey(SecureString key)
|
|
||||||
{
|
|
||||||
Key = key;
|
|
||||||
|
|
||||||
IsEncrypted = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Create a private key providing an encrypted key information
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="key">The private key used for signing</param>
|
|
||||||
public PrivateKey(string key)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(key))
|
|
||||||
throw new ArgumentException("Key can't be null/empty");
|
|
||||||
|
|
||||||
Key = key.ToSecureString();
|
|
||||||
|
|
||||||
IsEncrypted = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Copy the private key
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
public PrivateKey Copy()
|
|
||||||
{
|
|
||||||
if (Passphrase == null)
|
|
||||||
return new PrivateKey(Key.GetString());
|
|
||||||
else
|
|
||||||
return new PrivateKey(Key.GetString(), Passphrase.GetString());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Dispose
|
|
||||||
/// </summary>
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
Key?.Dispose();
|
|
||||||
Passphrase?.Dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -6,6 +6,7 @@ using System.Net.Http;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using CryptoExchange.Net.Authentication;
|
using CryptoExchange.Net.Authentication;
|
||||||
|
using CryptoExchange.Net.Interfaces;
|
||||||
using CryptoExchange.Net.Logging;
|
using CryptoExchange.Net.Logging;
|
||||||
using CryptoExchange.Net.Objects;
|
using CryptoExchange.Net.Objects;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
@ -17,7 +18,7 @@ namespace CryptoExchange.Net
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Base API for all API clients
|
/// Base API for all API clients
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class BaseApiClient: IDisposable
|
public abstract class BaseApiClient : IDisposable, IBaseApiClient
|
||||||
{
|
{
|
||||||
private ApiCredentials? _apiCredentials;
|
private ApiCredentials? _apiCredentials;
|
||||||
private AuthenticationProvider? _authenticationProvider;
|
private AuthenticationProvider? _authenticationProvider;
|
||||||
@ -131,7 +132,7 @@ namespace CryptoExchange.Net
|
|||||||
protected abstract AuthenticationProvider CreateAuthenticationProvider(ApiCredentials credentials);
|
protected abstract AuthenticationProvider CreateAuthenticationProvider(ApiCredentials credentials);
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void SetApiCredentials(ApiCredentials credentials)
|
public void SetApiCredentials<T>(T credentials) where T : ApiCredentials
|
||||||
{
|
{
|
||||||
_apiCredentials = credentials?.Copy();
|
_apiCredentials = credentials?.Copy();
|
||||||
_created = false;
|
_created = false;
|
||||||
|
@ -53,7 +53,7 @@ namespace CryptoExchange.Net
|
|||||||
/// Set the API credentials for this client. All Api clients in this client will use the new credentials, regardless of earlier set options.
|
/// Set the API credentials for this client. All Api clients in this client will use the new credentials, regardless of earlier set options.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="credentials">The credentials to set</param>
|
/// <param name="credentials">The credentials to set</param>
|
||||||
public void SetApiCredentials(ApiCredentials credentials)
|
protected virtual void SetApiCredentials<T>(T credentials) where T : ApiCredentials
|
||||||
{
|
{
|
||||||
foreach (var apiClient in ApiClients)
|
foreach (var apiClient in ApiClients)
|
||||||
apiClient.SetApiCredentials(credentials);
|
apiClient.SetApiCredentials(credentials);
|
||||||
|
@ -20,35 +20,24 @@ namespace CryptoExchange.Net
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Base rest API client for interacting with a REST API
|
/// Base rest API client for interacting with a REST API
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class RestApiClient: BaseApiClient
|
public abstract class RestApiClient : BaseApiClient, IRestApiClient
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <inheritdoc />
|
||||||
/// The factory for creating requests. Used for unit testing
|
|
||||||
/// </summary>
|
|
||||||
public IRequestFactory RequestFactory { get; set; } = new RequestFactory();
|
public IRequestFactory RequestFactory { get; set; } = new RequestFactory();
|
||||||
|
/// <inheritdoc />
|
||||||
|
public abstract TimeSyncInfo? GetTimeSyncInfo();
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public abstract TimeSpan? GetTimeOffset();
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public int TotalRequestsMade { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Request headers to be sent with each request
|
/// Request headers to be sent with each request
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected Dictionary<string, string>? StandardRequestHeaders { get; set; }
|
protected Dictionary<string, string>? StandardRequestHeaders { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get time sync info for an API client
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
public abstract TimeSyncInfo GetTimeSyncInfo();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get time offset for an API client
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
public abstract TimeSpan GetTimeOffset();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Total amount of requests made with this API client
|
|
||||||
/// </summary>
|
|
||||||
public int TotalRequestsMade { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Options for this client
|
/// Options for this client
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -110,13 +99,21 @@ namespace CryptoExchange.Net
|
|||||||
Dictionary<string, string>? additionalHeaders = null,
|
Dictionary<string, string>? additionalHeaders = null,
|
||||||
bool ignoreRatelimit = false)
|
bool ignoreRatelimit = false)
|
||||||
{
|
{
|
||||||
|
int currentTry = 0;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
currentTry++;
|
||||||
var request = await PrepareRequestAsync(uri, method, cancellationToken, parameters, signed, parameterPosition, arraySerialization, requestWeight, deserializer, additionalHeaders, ignoreRatelimit).ConfigureAwait(false);
|
var request = await PrepareRequestAsync(uri, method, cancellationToken, parameters, signed, parameterPosition, arraySerialization, requestWeight, deserializer, additionalHeaders, ignoreRatelimit).ConfigureAwait(false);
|
||||||
if (!request)
|
if (!request)
|
||||||
return new WebCallResult(request.Error!);
|
return new WebCallResult(request.Error!);
|
||||||
|
|
||||||
var result = await GetResponseAsync<object>(request.Data, deserializer, cancellationToken, true).ConfigureAwait(false);
|
var result = await GetResponseAsync<object>(request.Data, deserializer, cancellationToken, true).ConfigureAwait(false);
|
||||||
|
if (await ShouldRetryRequestAsync(result, currentTry).ConfigureAwait(false))
|
||||||
|
continue;
|
||||||
|
|
||||||
return result.AsDataless();
|
return result.AsDataless();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Execute a request to the uri and deserialize the response into the provided type parameter
|
/// Execute a request to the uri and deserialize the response into the provided type parameter
|
||||||
@ -149,11 +146,20 @@ namespace CryptoExchange.Net
|
|||||||
bool ignoreRatelimit = false
|
bool ignoreRatelimit = false
|
||||||
) where T : class
|
) where T : class
|
||||||
{
|
{
|
||||||
|
int currentTry = 0;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
currentTry++;
|
||||||
var request = await PrepareRequestAsync(uri, method, cancellationToken, parameters, signed, parameterPosition, arraySerialization, requestWeight, deserializer, additionalHeaders, ignoreRatelimit).ConfigureAwait(false);
|
var request = await PrepareRequestAsync(uri, method, cancellationToken, parameters, signed, parameterPosition, arraySerialization, requestWeight, deserializer, additionalHeaders, ignoreRatelimit).ConfigureAwait(false);
|
||||||
if (!request)
|
if (!request)
|
||||||
return new WebCallResult<T>(request.Error!);
|
return new WebCallResult<T>(request.Error!);
|
||||||
|
|
||||||
return await GetResponseAsync<T>(request.Data, deserializer, cancellationToken, false).ConfigureAwait(false);
|
var result = await GetResponseAsync<T>(request.Data, deserializer, cancellationToken, false).ConfigureAwait(false);
|
||||||
|
if (await ShouldRetryRequestAsync(result, currentTry).ConfigureAwait(false))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -190,7 +196,8 @@ namespace CryptoExchange.Net
|
|||||||
{
|
{
|
||||||
var syncTask = SyncTimeAsync();
|
var syncTask = SyncTimeAsync();
|
||||||
var timeSyncInfo = GetTimeSyncInfo();
|
var timeSyncInfo = GetTimeSyncInfo();
|
||||||
if (timeSyncInfo.TimeSyncState.LastSyncTime == default)
|
|
||||||
|
if (timeSyncInfo != null && timeSyncInfo.TimeSyncState.LastSyncTime == default)
|
||||||
{
|
{
|
||||||
// Initially with first request we'll need to wait for the time syncing, if it's not the first request we can just continue
|
// Initially with first request we'll need to wait for the time syncing, if it's not the first request we can just continue
|
||||||
var syncTimeResult = await syncTask.ConfigureAwait(false);
|
var syncTimeResult = await syncTask.ConfigureAwait(false);
|
||||||
@ -235,8 +242,6 @@ namespace CryptoExchange.Net
|
|||||||
return new CallResult<IRequest>(request);
|
return new CallResult<IRequest>(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Executes the request and returns the result deserialized into the type parameter class
|
/// Executes the request and returns the result deserialized into the type parameter class
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -376,6 +381,16 @@ namespace CryptoExchange.Net
|
|||||||
return Task.FromResult<ServerError?>(null);
|
return Task.FromResult<ServerError?>(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Can be used to indicate that a request should be retried. Defaults to false. Make sure to retry a max number of times (based on the the tries parameter) or the request will retry forever.
|
||||||
|
/// Note that this is always called; even when the request might be successful
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">WebCallResult type parameter</typeparam>
|
||||||
|
/// <param name="callResult">The result of the call</param>
|
||||||
|
/// <param name="tries">The current try number</param>
|
||||||
|
/// <returns>True if call should retry, false if the call should return</returns>
|
||||||
|
protected virtual Task<bool> ShouldRetryRequestAsync<T>(WebCallResult<T> callResult, int tries) => Task.FromResult(false);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a request object
|
/// Creates a request object
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -521,11 +536,14 @@ namespace CryptoExchange.Net
|
|||||||
/// Retrieve the server time for the purpose of syncing time between client and server to prevent authentication issues
|
/// Retrieve the server time for the purpose of syncing time between client and server to prevent authentication issues
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>Server time</returns>
|
/// <returns>Server time</returns>
|
||||||
protected abstract Task<WebCallResult<DateTime>> GetServerTimestampAsync();
|
protected virtual Task<WebCallResult<DateTime>> GetServerTimestampAsync() => throw new NotImplementedException();
|
||||||
|
|
||||||
internal async Task<WebCallResult<bool>> SyncTimeAsync()
|
internal async Task<WebCallResult<bool>> SyncTimeAsync()
|
||||||
{
|
{
|
||||||
var timeSyncParams = GetTimeSyncInfo();
|
var timeSyncParams = GetTimeSyncInfo();
|
||||||
|
if (timeSyncParams == null)
|
||||||
|
return new WebCallResult<bool>(null, null, null, null, null, null, null, null, true, null);
|
||||||
|
|
||||||
if (await timeSyncParams.TimeSyncState.Semaphore.WaitAsync(0).ConfigureAwait(false))
|
if (await timeSyncParams.TimeSyncState.Semaphore.WaitAsync(0).ConfigureAwait(false))
|
||||||
{
|
{
|
||||||
if (!timeSyncParams.SyncTime || (DateTime.UtcNow - timeSyncParams.TimeSyncState.LastSyncTime < timeSyncParams.RecalculationInterval))
|
if (!timeSyncParams.SyncTime || (DateTime.UtcNow - timeSyncParams.TimeSyncState.LastSyncTime < timeSyncParams.RecalculationInterval))
|
||||||
|
@ -18,13 +18,10 @@ namespace CryptoExchange.Net
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Base socket API client for interaction with a websocket API
|
/// Base socket API client for interaction with a websocket API
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class SocketApiClient : BaseApiClient
|
public abstract class SocketApiClient : BaseApiClient, ISocketApiClient
|
||||||
{
|
{
|
||||||
#region Fields
|
#region Fields
|
||||||
|
/// <inheritdoc/>
|
||||||
/// <summary>
|
|
||||||
/// The factory for creating sockets. Used for unit testing
|
|
||||||
/// </summary>
|
|
||||||
public IWebsocketFactory SocketFactory { get; set; } = new WebsocketFactory();
|
public IWebsocketFactory SocketFactory { get; set; } = new WebsocketFactory();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
17
CryptoExchange.Net/Interfaces/IBaseApiClient.cs
Normal file
17
CryptoExchange.Net/Interfaces/IBaseApiClient.cs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
using CryptoExchange.Net.Authentication;
|
||||||
|
|
||||||
|
namespace CryptoExchange.Net.Interfaces
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Base api client
|
||||||
|
/// </summary>
|
||||||
|
public interface IBaseApiClient
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Set the API credentials for this API client
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T"></typeparam>
|
||||||
|
/// <param name="credentials"></param>
|
||||||
|
void SetApiCredentials<T>(T credentials) where T : ApiCredentials;
|
||||||
|
}
|
||||||
|
}
|
33
CryptoExchange.Net/Interfaces/IRestApiClient.cs
Normal file
33
CryptoExchange.Net/Interfaces/IRestApiClient.cs
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
using CryptoExchange.Net.Objects;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace CryptoExchange.Net.Interfaces
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Base rest API client
|
||||||
|
/// </summary>
|
||||||
|
public interface IRestApiClient : IBaseApiClient
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The factory for creating requests. Used for unit testing
|
||||||
|
/// </summary>
|
||||||
|
IRequestFactory RequestFactory { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Total amount of requests made with this API client
|
||||||
|
/// </summary>
|
||||||
|
int TotalRequestsMade { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get time offset for an API client. Return null if time syncing shouldnt/cant be done
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
TimeSpan? GetTimeOffset();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get time sync info for an API client. Return null if time syncing shouldnt/cant be done
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
TimeSyncInfo? GetTimeSyncInfo();
|
||||||
|
}
|
||||||
|
}
|
@ -18,11 +18,5 @@ namespace CryptoExchange.Net.Interfaces
|
|||||||
/// The total amount of requests made with this client
|
/// The total amount of requests made with this client
|
||||||
/// </summary>
|
/// </summary>
|
||||||
int TotalRequestsMade { get; }
|
int TotalRequestsMade { get; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Set the API credentials for this client. All Api clients in this client will use the new credentials, regardless of earlier set options.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="credentials">The credentials to set</param>
|
|
||||||
void SetApiCredentials(ApiCredentials credentials);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
81
CryptoExchange.Net/Interfaces/ISocketApiClient.cs
Normal file
81
CryptoExchange.Net/Interfaces/ISocketApiClient.cs
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
using CryptoExchange.Net.Objects;
|
||||||
|
using CryptoExchange.Net.Sockets;
|
||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CryptoExchange.Net.Interfaces
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Socket API client
|
||||||
|
/// </summary>
|
||||||
|
public interface ISocketApiClient: IBaseApiClient
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The current amount of socket connections on the API client
|
||||||
|
/// </summary>
|
||||||
|
int CurrentConnections { get; }
|
||||||
|
/// <summary>
|
||||||
|
/// The current amount of subscriptions over all connections
|
||||||
|
/// </summary>
|
||||||
|
int CurrentSubscriptions { get; }
|
||||||
|
/// <summary>
|
||||||
|
/// Incoming data kpbs
|
||||||
|
/// </summary>
|
||||||
|
double IncomingKbps { get; }
|
||||||
|
/// <summary>
|
||||||
|
/// Client options
|
||||||
|
/// </summary>
|
||||||
|
SocketApiClientOptions Options { get; }
|
||||||
|
/// <summary>
|
||||||
|
/// The factory for creating sockets. Used for unit testing
|
||||||
|
/// </summary>
|
||||||
|
IWebsocketFactory SocketFactory { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the url to reconnect to after losing a connection
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="connection"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<Uri?> GetReconnectUriAsync(SocketConnection connection);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Log the current state of connections and subscriptions
|
||||||
|
/// </summary>
|
||||||
|
string GetSubscriptionsState();
|
||||||
|
/// <summary>
|
||||||
|
/// Reconnect all connections
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task ReconnectAsync();
|
||||||
|
/// <summary>
|
||||||
|
/// Update the original request to send when the connection is restored after disconnecting. Can be used to update an authentication token for example.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="request">The original request</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<CallResult<object>> RevitalizeRequestAsync(object request);
|
||||||
|
/// <summary>
|
||||||
|
/// Periodically sends data over a socket connection
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="identifier">Identifier for the periodic send</param>
|
||||||
|
/// <param name="interval">How often</param>
|
||||||
|
/// <param name="objGetter">Method returning the object to send</param>
|
||||||
|
void SendPeriodic(string identifier, TimeSpan interval, Func<SocketConnection, object> objGetter);
|
||||||
|
/// <summary>
|
||||||
|
/// Unsubscribe all subscriptions
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task UnsubscribeAllAsync();
|
||||||
|
/// <summary>
|
||||||
|
/// Unsubscribe an update subscription
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="subscriptionId">The id of the subscription to unsubscribe</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<bool> UnsubscribeAsync(int subscriptionId);
|
||||||
|
/// <summary>
|
||||||
|
/// Unsubscribe an update subscription
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="subscription">The subscription to unsubscribe</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task UnsubscribeAsync(UpdateSubscription subscription);
|
||||||
|
}
|
||||||
|
}
|
@ -16,12 +16,6 @@ namespace CryptoExchange.Net.Interfaces
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
ClientOptions ClientOptions { get; }
|
ClientOptions ClientOptions { get; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Set the API credentials for this client. All Api clients in this client will use the new credentials, regardless of earlier set options.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="credentials">The credentials to set</param>
|
|
||||||
void SetApiCredentials(ApiCredentials credentials);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Incoming kilobytes per second of data
|
/// Incoming kilobytes per second of data
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user