1
0
mirror of https://github.com/JKorf/CryptoExchange.Net synced 2026-04-13 00:22:22 +00:00
This commit is contained in:
Jkorf 2026-03-18 16:18:58 +01:00
parent f977290878
commit eef8fc86df
12 changed files with 76 additions and 369 deletions

View File

@ -29,7 +29,7 @@ namespace CryptoExchange.Net.UnitTests
// act
// assert
Assert.Throws(typeof(ArgumentException),
() => new RestExchangeOptions<TestEnvironment, TestCredentials>() { ApiCredentials = new TestCredentials(key, secret) });
() => new RestExchangeOptions<TestEnvironment, HMACCredential>() { ApiCredentials = new HMACCredential(key, secret) });
}
[Test]
@ -38,94 +38,19 @@ namespace CryptoExchange.Net.UnitTests
// arrange, act
var options = new TestClientOptions
{
ApiCredentials = new TestCredentials("123", "456"),
ApiCredentials = new HMACCredential("123", "456"),
ReceiveWindow = TimeSpan.FromSeconds(10)
};
// assert
Assert.That(options.ReceiveWindow == TimeSpan.FromSeconds(10));
Assert.That(options.ApiCredentials.GetCredential<HMACCredential>().Key == "123");
Assert.That(options.ApiCredentials.GetCredential<HMACCredential>().Secret == "456");
Assert.That(options.ApiCredentials.Key == "123");
Assert.That(options.ApiCredentials.Secret == "456");
}
[Test]
public void TestApiOptionsAreSet()
{
// arrange, act
var options = new TestClientOptions();
options.Api1Options.ApiCredentials = new TestCredentials("123", "456");
options.Api2Options.ApiCredentials = new TestCredentials("789", "101");
// assert
Assert.That(options.Api1Options.ApiCredentials.GetCredential<HMACCredential>().Key == "123");
Assert.That(options.Api1Options.ApiCredentials.GetCredential<HMACCredential>().Secret == "456");
Assert.That(options.Api2Options.ApiCredentials.GetCredential<HMACCredential>().Key == "789");
Assert.That(options.Api2Options.ApiCredentials.GetCredential<HMACCredential>().Secret == "101");
}
[Test]
public void TestClientUsesCorrectOptions()
{
var client = new TestRestClient(options => {
options.Api1Options.ApiCredentials = new TestCredentials("111", "222");
options.ApiCredentials = new TestCredentials("333", "444");
});
var authProvider1 = (TestAuthProvider)client.Api1.AuthenticationProvider;
var authProvider2 = (TestAuthProvider)client.Api2.AuthenticationProvider;
Assert.That(authProvider1.GetKey() == "111");
Assert.That(authProvider1.GetSecret() == "222");
Assert.That(authProvider2.GetKey() == "333");
Assert.That(authProvider2.GetSecret() == "444");
}
[Test]
public void TestClientUsesCorrectOptionsWithDefault()
{
TestClientOptions.Default.ApiCredentials = new TestCredentials("123", "456");
TestClientOptions.Default.Api1Options.ApiCredentials = new TestCredentials("111", "222");
var client = new TestRestClient();
var authProvider1 = (TestAuthProvider)client.Api1.AuthenticationProvider;
var authProvider2 = (TestAuthProvider)client.Api2.AuthenticationProvider;
Assert.That(authProvider1.GetKey() == "111");
Assert.That(authProvider1.GetSecret() == "222");
Assert.That(authProvider2.GetKey() == "123");
Assert.That(authProvider2.GetSecret() == "456");
// Cleanup static values
TestClientOptions.Default.ApiCredentials = null;
TestClientOptions.Default.Api1Options.ApiCredentials = null;
}
[Test]
public void TestClientUsesCorrectOptionsWithOverridingDefault()
{
TestClientOptions.Default.ApiCredentials = new TestCredentials("123", "456");
TestClientOptions.Default.Api1Options.ApiCredentials = new TestCredentials("111", "222");
var client = new TestRestClient(options =>
{
options.Api1Options.ApiCredentials = new TestCredentials("333", "444");
options.Environment = new TestEnvironment("Test", "https://test.test");
});
var authProvider1 = client.Api1.AuthenticationProvider;
var authProvider2 = client.Api2.AuthenticationProvider;
Assert.That(authProvider1.GetKey() == "333");
Assert.That(authProvider1.GetSecret() == "444");
Assert.That(authProvider2.GetKey() == "123");
Assert.That(authProvider2.GetSecret() == "456");
Assert.That(client.Api2.BaseAddress == "https://localhost:123");
// Cleanup static values
TestClientOptions.Default.ApiCredentials = null;
TestClientOptions.Default.Api1Options.ApiCredentials = null;
}
}
public class TestClientOptions: RestExchangeOptions<TestEnvironment, TestCredentials>
public class TestClientOptions: RestExchangeOptions<TestEnvironment, HMACCredential>
{
/// <summary>
/// Default options for the futures client
@ -148,9 +73,9 @@ namespace CryptoExchange.Net.UnitTests
/// </summary>
public TimeSpan ReceiveWindow { get; set; } = TimeSpan.FromSeconds(5);
public RestApiOptions<TestCredentials> Api1Options { get; private set; } = new RestApiOptions<TestCredentials>();
public RestApiOptions Api1Options { get; private set; } = new RestApiOptions();
public RestApiOptions<TestCredentials> Api2Options { get; set; } = new RestApiOptions<TestCredentials>();
public RestApiOptions Api2Options { get; set; } = new RestApiOptions();
internal TestClientOptions Set(TestClientOptions targetOptions)
{

View File

@ -26,14 +26,14 @@ namespace CryptoExchange.Net.UnitTests
var options = new TestClientOptions();
_logger = NullLogger.Instance;
Initialize(options);
SubClient = AddApiClient(new TestSubClient(options, new RestApiOptions<TestCredentials>()));
SubClient = AddApiClient(new TestSubClient(options, new RestApiOptions()));
}
public TestBaseClient(TestClientOptions exchangeOptions) : base(null, "Test")
{
_logger = NullLogger.Instance;
Initialize(exchangeOptions);
SubClient = AddApiClient(new TestSubClient(exchangeOptions, new RestApiOptions<TestCredentials>()));
SubClient = AddApiClient(new TestSubClient(exchangeOptions, new RestApiOptions()));
}
public void Log(LogLevel verbosity, string data)
@ -42,11 +42,11 @@ namespace CryptoExchange.Net.UnitTests
}
}
public class TestSubClient : RestApiClient<TestEnvironment, TestAuthProvider, TestCredentials>
public class TestSubClient : RestApiClient<TestEnvironment, TestAuthProvider, HMACCredential>
{
protected override IRestMessageHandler MessageHandler => throw new NotImplementedException();
public TestSubClient(RestExchangeOptions<TestEnvironment, TestCredentials> options, RestApiOptions<TestCredentials> apiOptions) : base(new TraceLogger(), null, "https://localhost:123", options, apiOptions)
public TestSubClient(RestExchangeOptions<TestEnvironment, HMACCredential> options, RestApiOptions apiOptions) : base(new TraceLogger(), null, "https://localhost:123", options, apiOptions)
{
}
@ -58,15 +58,13 @@ namespace CryptoExchange.Net.UnitTests
/// <inheritdoc />
public override string FormatSymbol(string baseAsset, string quoteAsset, TradingMode futuresType, DateTime? deliverDate = null) => $"{baseAsset.ToUpperInvariant()}{quoteAsset.ToUpperInvariant()}";
protected override IMessageSerializer CreateSerializer() => new SystemTextJsonMessageSerializer(new System.Text.Json.JsonSerializerOptions());
protected override TestAuthProvider CreateAuthenticationProvider(TestCredentials credentials) => throw new NotImplementedException();
protected override TestAuthProvider CreateAuthenticationProvider(HMACCredential credentials) => throw new NotImplementedException();
protected override Task<WebCallResult<DateTime>> GetServerTimestampAsync() => throw new NotImplementedException();
}
public class TestAuthProvider : AuthenticationProvider<TestCredentials, HMACCredential>
public class TestAuthProvider : AuthenticationProvider<HMACCredential, HMACCredential>
{
public override ApiCredentialsType[] SupportedCredentialTypes => [ApiCredentialsType.HMAC];
public TestAuthProvider(TestCredentials credentials) : base(credentials)
public TestAuthProvider(HMACCredential credentials) : base(credentials, credentials)
{
}
@ -87,14 +85,4 @@ namespace CryptoExchange.Net.UnitTests
TestAddress = url;
}
}
public class TestCredentials : ApiCredentials
{
public TestCredentials(string apiKey, string secret) : this(new HMACCredential(apiKey, secret)) { }
public TestCredentials(HMACCredential credential) : base(credential) { }
/// <inheritdoc />
public override ApiCredentials Copy() => new TestCredentials(HMAC!);
}
}

View File

@ -130,7 +130,7 @@ namespace CryptoExchange.Net.UnitTests.TestImplementations
}
}
public class TestRestApi1Client : RestApiClient<TestEnvironment, TestAuthProvider, TestCredentials>
public class TestRestApi1Client : RestApiClient<TestEnvironment, TestAuthProvider, HMACCredential>
{
protected override IRestMessageHandler MessageHandler { get; } = new TestRestMessageHandler();
@ -159,7 +159,7 @@ namespace CryptoExchange.Net.UnitTests.TestImplementations
ParameterPositions[method] = position;
}
protected override TestAuthProvider CreateAuthenticationProvider(TestCredentials credentials)
protected override TestAuthProvider CreateAuthenticationProvider(HMACCredential credentials)
=> new TestAuthProvider(credentials);
protected override Task<WebCallResult<DateTime>> GetServerTimestampAsync()
@ -168,7 +168,7 @@ namespace CryptoExchange.Net.UnitTests.TestImplementations
}
}
public class TestRestApi2Client : RestApiClient<TestEnvironment, TestAuthProvider, TestCredentials>
public class TestRestApi2Client : RestApiClient<TestEnvironment, TestAuthProvider, HMACCredential>
{
protected override IRestMessageHandler MessageHandler { get; } = new TestRestMessageHandler();
@ -187,7 +187,7 @@ namespace CryptoExchange.Net.UnitTests.TestImplementations
return await SendAsync<T>("http://www.test.com", new RequestDefinition("/", HttpMethod.Get) { Weight = 0 }, null, ct);
}
protected override TestAuthProvider CreateAuthenticationProvider(TestCredentials credentials)
protected override TestAuthProvider CreateAuthenticationProvider(HMACCredential credentials)
=> new TestAuthProvider(credentials);
protected override Task<WebCallResult<DateTime>> GetServerTimestampAsync()

View File

@ -1,143 +1,10 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace CryptoExchange.Net.Authentication
namespace CryptoExchange.Net.Authentication
{
/// <summary>
/// Api credentials, used to sign requests accessing private endpoints
/// </summary>
public abstract class ApiCredentials
{
/// <summary>
/// The credential pairs contained in these API credentials. This can contain multiple credential pairs when the API requires different credentials for different endpoints.
/// </summary>
public CredentialPair[] CredentialPairs { get; protected set; } = Array.Empty<CredentialPair>();
/// <summary>
/// The public key/identifier for the provided credentials
/// </summary>
public string Key => CredentialPairs.First().Key;
/// <summary>
/// HMAC credentials
/// </summary>
public HMACCredential? HMAC
{
get => (HMACCredential?)CredentialPairs.SingleOrDefault(x => x.CredentialType == ApiCredentialsType.HMAC);
set => AddOrRemoveCredential(ApiCredentialsType.HMAC, value);
}
/// <summary>
/// RSA credentials
/// </summary>
public RSACredential? RSA
{
get => (RSACredential?)CredentialPairs.SingleOrDefault(x => x.CredentialType == ApiCredentialsType.RSA);
set => AddOrRemoveCredential(ApiCredentialsType.RSA, value);
}
/// <summary>
/// RSA credentials in XML format
/// </summary>
public RSAXmlCredential? RSAXml
{
get => (RSAXmlCredential?)CredentialPairs.SingleOrDefault(x => x.CredentialType == ApiCredentialsType.RSA);
set => AddOrRemoveCredential(ApiCredentialsType.RSA, value);
}
#if NETSTANDARD2_1_OR_GREATER || NET7_0_OR_GREATER
/// <summary>
/// RSA credentials in PEM/Base64 format
/// </summary>
public RSAPemCredential? RSAPem
{
get => (RSAPemCredential?)CredentialPairs.SingleOrDefault(x => x.CredentialType == ApiCredentialsType.RSA);
set => AddOrRemoveCredential(ApiCredentialsType.RSA, value);
}
#endif
#if NET8_0_OR_GREATER
/// <summary>
/// Ed25519 credentials
/// </summary>
public Ed25519Credential? Ed25519
{
get => (Ed25519Credential?)CredentialPairs.SingleOrDefault(x => x.CredentialType == ApiCredentialsType.Ed25519);
set => AddOrRemoveCredential(ApiCredentialsType.Ed25519, value);
}
#endif
/// <summary>
/// ECDsa credentials
/// </summary>
public ECDsaCredential? ECDsa
{
get => (ECDsaCredential?)CredentialPairs.SingleOrDefault(x => x.CredentialType == ApiCredentialsType.ECDsa);
set => AddOrRemoveCredential(ApiCredentialsType.ECDsa, value);
}
/// <summary>
/// API key credentials
/// </summary>
public ApiKeyCredential? ApiKey
{
get => (ApiKeyCredential?)CredentialPairs.SingleOrDefault(x => x.CredentialType == ApiCredentialsType.ApiKey);
set => AddOrRemoveCredential(ApiCredentialsType.ApiKey, value);
}
/// <summary>
/// If credential is null attempt to remove the credential of the type, else add it
/// </summary>
protected void AddOrRemoveCredential(ApiCredentialsType type, CredentialPair? credential)
{
if (credential is null)
{
var cred = CredentialPairs.SingleOrDefault(x => x.CredentialType == type);
if (cred != null)
{
var newList = CredentialPairs.ToList();
newList.Remove(cred);
CredentialPairs = newList.ToArray();
}
}
else
{
var newList = CredentialPairs.ToList();
newList.Add(credential);
CredentialPairs = newList.ToArray();
}
}
/// <summary>
/// DI constructor
/// </summary>
[Obsolete("Parameterless constructor is only for deserialization purposes and should not be used directly.")]
public ApiCredentials() { }
/// <summary>
/// Create API credentials using the provided credential pair
/// </summary>
public ApiCredentials(CredentialPair credential)
{
CredentialPairs = [credential];
}
/// <summary>
/// Create API credentials using the provided credential pairs
/// </summary>
public ApiCredentials(params IEnumerable<CredentialPair?> credentials)
{
CredentialPairs = credentials.Where(x => x != null).ToArray()!;
}
/// <summary>
/// Get credentials of a specific type
/// </summary>
public T? GetCredential<T>() where T : CredentialPair
{
return CredentialPairs.OfType<T>().SingleOrDefault();
}
/// <summary>
/// Copy the credentials
/// </summary>

View File

@ -1,33 +0,0 @@
namespace CryptoExchange.Net.Authentication
{
/// <summary>
/// Credentials type
/// </summary>
public enum ApiCredentialsType
{
/// <summary>
/// HMAC credentials
/// </summary>
HMAC,
/// <summary>
/// RSA credentials
/// </summary>
RSA,
/// <summary>
/// Ed25519 credentials
/// </summary>
Ed25519,
/// <summary>
/// ECDsa credentials
/// </summary>
ECDsa,
/// <summary>
/// API key credentials
/// </summary>
ApiKey,
/// <summary>
/// Custom / exchange specific
/// </summary>
Custom
}
}

View File

@ -29,11 +29,6 @@ namespace CryptoExchange.Net.Authentication
/// </summary>
public abstract string Key { get; }
/// <summary>
/// The supported credential types
/// </summary>
public abstract ApiCredentialsType[] SupportedCredentialTypes { get; }
/// <summary>
/// Authenticate a REST request
/// </summary>
@ -458,13 +453,14 @@ namespace CryptoExchange.Net.Authentication
/// <inheritdoc />
public abstract class AuthenticationProvider<TApiCredentials> : AuthenticationProvider
where TApiCredentials : ApiCredentials
{
/// <summary>
/// API credentials used for signing requests
/// </summary>
public TApiCredentials ApiCredentials { get; set; }
public CredentialPair? Credential { get; set; }
/// <summary>
/// ctor
/// </summary>
@ -472,17 +468,28 @@ namespace CryptoExchange.Net.Authentication
{
ApiCredentials = credentials;
}
/// <summary>
/// ctor
/// </summary>
protected AuthenticationProvider(TApiCredentials credentials, CredentialPair? credentialPair)
{
if (credentialPair == null)
throw new ArgumentNullException(nameof(credentialPair), $"Credential pair needed but not provided");
ApiCredentials = credentials;
Credential = credentialPair;
}
}
/// <inheritdoc />
public abstract class AuthenticationProvider<TApiCredentials, TCredentialType> : AuthenticationProvider<TApiCredentials>
where TApiCredentials : ApiCredentials
where TCredentialType : CredentialPair
{
/// <summary>
/// The specific credential type used for signing requests.
/// </summary>
public TCredentialType Credential { get; set; }
public new TCredentialType Credential => (TCredentialType)base.Credential!;
/// <inheritdoc />
public override string Key => Credential.Key;
@ -490,10 +497,8 @@ namespace CryptoExchange.Net.Authentication
/// <summary>
/// ctor
/// </summary>
protected AuthenticationProvider(TApiCredentials credentials) : base(credentials)
protected AuthenticationProvider(TApiCredentials credentials, TCredentialType? credential) : base(credentials, credential)
{
Credential = credentials.GetCredential<TCredentialType>()
?? throw new Exception($"Credential type {typeof(TCredentialType).Name} needed but not provided");
}
/// <summary>
@ -513,10 +518,10 @@ namespace CryptoExchange.Net.Authentication
/// <returns></returns>
protected string SignHMACSHA256(byte[] data, SignOutputType? outputType = null)
{
if (Credential.CredentialType != ApiCredentialsType.HMAC)
if (Credential is not HMACCredential hmacCredential)
throw new InvalidOperationException($"Invalid HMAC signing without HMAC credentials provided");
return SignHMACSHA256((Credential as HMACCredential)!, data, outputType);
return SignHMACSHA256(hmacCredential, data, outputType);
}
/// <summary>
@ -536,10 +541,10 @@ namespace CryptoExchange.Net.Authentication
/// <returns></returns>
protected string SignHMACSHA384(byte[] data, SignOutputType? outputType = null)
{
if (Credential.CredentialType != ApiCredentialsType.HMAC)
if (Credential is not HMACCredential hmacCredential)
throw new InvalidOperationException($"Invalid HMAC signing without HMAC credentials provided");
return SignHMACSHA384((Credential as HMACCredential)!, data, outputType);
return SignHMACSHA384(hmacCredential, data, outputType);
}
/// <summary>
@ -559,10 +564,10 @@ namespace CryptoExchange.Net.Authentication
/// <returns></returns>
protected string SignHMACSHA512(byte[] data, SignOutputType? outputType = null)
{
if (Credential.CredentialType != ApiCredentialsType.HMAC)
if (Credential is not HMACCredential hmacCredential)
throw new InvalidOperationException($"Invalid HMAC signing without HMAC credentials provided");
return SignHMACSHA512((Credential as HMACCredential)!, data, outputType);
return SignHMACSHA512(hmacCredential, data, outputType);
}
/// <summary>
@ -573,10 +578,10 @@ namespace CryptoExchange.Net.Authentication
/// <returns></returns>
protected string SignRSASHA256(byte[] data, SignOutputType? outputType = null)
{
if (Credential.CredentialType != ApiCredentialsType.RSA)
if (Credential is not RSACredential rsaCredential)
throw new InvalidOperationException($"Invalid RSA signing without RSA credentials provided");
return SignRSASHA256((Credential as RSACredential)!, data, outputType);
return SignRSASHA256(rsaCredential, data, outputType);
}
/// <summary>
@ -587,10 +592,10 @@ namespace CryptoExchange.Net.Authentication
/// <returns></returns>
protected string SignRSASHA384(byte[] data, SignOutputType? outputType = null)
{
if (Credential.CredentialType != ApiCredentialsType.RSA)
if (Credential is not RSACredential rsaCredential)
throw new InvalidOperationException($"Invalid RSA signing without RSA credentials provided");
return SignRSASHA384((Credential as RSACredential)!, data, outputType);
return SignRSASHA384(rsaCredential, data, outputType);
}
/// <summary>
@ -601,10 +606,10 @@ namespace CryptoExchange.Net.Authentication
/// <returns></returns>
protected string SignRSASHA512(byte[] data, SignOutputType? outputType = null)
{
if (Credential.CredentialType != ApiCredentialsType.RSA)
if (Credential is not RSACredential rsaCredential)
throw new InvalidOperationException($"Invalid RSA signing without RSA credentials provided");
return SignRSASHA512((Credential as RSACredential)!, data, outputType);
return SignRSASHA512(rsaCredential, data, outputType);
}
#if NET8_0_OR_GREATER
@ -619,10 +624,10 @@ namespace CryptoExchange.Net.Authentication
/// </summary>
public string SignEd25519(byte[] data, SignOutputType? outputType = null)
{
if (Credential.CredentialType != ApiCredentialsType.Ed25519)
if (Credential is not Ed25519Credential ed25519Credential)
throw new InvalidOperationException($"Invalid Ed25519 signing without Ed25519 credentials provided");
return SignEd25519((Credential as Ed25519Credential)!, data, outputType);
return SignEd25519(ed25519Credential, data, outputType);
}
#endif
}

View File

@ -7,16 +7,12 @@ namespace CryptoExchange.Net.Authentication
/// <summary>
/// Credential pair base class
/// </summary>
public abstract class CredentialPair
public abstract class CredentialPair : ApiCredentials
{
/// <summary>
/// The (public) key/identifier for this credential pair
/// </summary>
public string Key { get; set; }
/// <summary>
/// Type of credentials
/// </summary>
public abstract ApiCredentialsType CredentialType { get; }
/// <summary>
/// ctor
@ -32,9 +28,6 @@ namespace CryptoExchange.Net.Authentication
/// </summary>
public class ApiKeyCredential : CredentialPair
{
/// <inheritdoc />
public override ApiCredentialsType CredentialType => ApiCredentialsType.ApiKey;
/// <summary>
/// ctor
/// </summary>
@ -44,6 +37,9 @@ namespace CryptoExchange.Net.Authentication
if (string.IsNullOrEmpty(key))
throw new ArgumentException("Key can't be null/empty");
}
/// <inheritdoc />
public override ApiCredentials Copy() => new ApiKeyCredential(Key);
}
/// <summary>
@ -62,9 +58,6 @@ namespace CryptoExchange.Net.Authentication
/// </summary>
public string? Pass { get; set; }
/// <inheritdoc />
public override ApiCredentialsType CredentialType => ApiCredentialsType.HMAC;
/// <summary>
/// ctor
/// </summary>
@ -88,6 +81,9 @@ namespace CryptoExchange.Net.Authentication
{
return _sBytes ??= Encoding.UTF8.GetBytes(Secret);
}
/// <inheritdoc />
public override ApiCredentials Copy() => new HMACCredential(Key, Secret, Pass);
}
/// <summary>
@ -104,9 +100,6 @@ namespace CryptoExchange.Net.Authentication
/// </summary>
public string? Pass { get; set; }
/// <inheritdoc />
public override ApiCredentialsType CredentialType => ApiCredentialsType.RSA;
/// <summary>
/// ctor
/// </summary>
@ -161,6 +154,9 @@ namespace CryptoExchange.Net.Authentication
return rsa;
}
/// <inheritdoc />
public override ApiCredentials Copy() => new RSAPemCredential(Key, PrivateKey, Pass);
}
#endif
@ -188,6 +184,9 @@ namespace CryptoExchange.Net.Authentication
rsa.FromXmlString(PrivateKey);
return rsa;
}
/// <inheritdoc />
public override ApiCredentials Copy() => new RSAXmlCredential(Key, PrivateKey, Pass);
}
#if NET8_0_OR_GREATER
@ -207,9 +206,6 @@ namespace CryptoExchange.Net.Authentication
/// </summary>
public string? Pass { get; set; }
/// <inheritdoc />
public override ApiCredentialsType CredentialType => ApiCredentialsType.Ed25519;
/// <summary>
/// ctor
/// </summary>
@ -239,6 +235,9 @@ namespace CryptoExchange.Net.Authentication
_signKey = NSec.Cryptography.Key.Import(NSec.Cryptography.SignatureAlgorithm.Ed25519, keyBytes, NSec.Cryptography.KeyBlobFormat.PkixPrivateKey);
return _signKey;
}
/// <inheritdoc />
public override ApiCredentials Copy() => new Ed25519Credential(Key, PrivateKey, Pass);
}
#endif
@ -256,9 +255,6 @@ namespace CryptoExchange.Net.Authentication
/// </summary>
public string? Pass { get; set; }
/// <inheritdoc />
public override ApiCredentialsType CredentialType => ApiCredentialsType.ECDsa;
/// <summary>
/// ctor
/// </summary>
@ -270,5 +266,8 @@ namespace CryptoExchange.Net.Authentication
PrivateKey = privateKey;
Pass = pass;
}
/// <inheritdoc />
public override ApiCredentials Copy() => new ECDsaCredential(Key, PrivateKey, Pass);
}
}

View File

@ -852,9 +852,6 @@ namespace CryptoExchange.Net.Clients
/// <inheritdoc />
public new RestExchangeOptions<TEnvironment, TApiCredentials> ClientOptions => (RestExchangeOptions<TEnvironment, TApiCredentials>)base.ClientOptions;
/// <inheritdoc />
public new RestApiOptions<TApiCredentials> ApiOptions => (RestApiOptions<TApiCredentials>)base.ApiOptions;
/// <summary>
/// ctor
/// </summary>
@ -863,14 +860,14 @@ namespace CryptoExchange.Net.Clients
HttpClient? httpClient,
string baseAddress,
RestExchangeOptions<TEnvironment, TApiCredentials> options,
RestApiOptions<TApiCredentials> apiOptions) : base(
RestApiOptions apiOptions) : base(
logger,
httpClient,
baseAddress,
options,
apiOptions)
{
ApiCredentials = apiOptions.ApiCredentials ?? options.ApiCredentials;
ApiCredentials = options.ApiCredentials;
}
/// <inheritdoc />
@ -930,7 +927,7 @@ namespace CryptoExchange.Net.Clients
HttpClient? httpClient,
string baseAddress,
RestExchangeOptions<TEnvironment, TApiCredentials> options,
RestApiOptions<TApiCredentials> apiOptions) : base(
RestApiOptions apiOptions) : base(
logger,
httpClient,
baseAddress,

View File

@ -1066,9 +1066,6 @@ namespace CryptoExchange.Net.Clients
/// <inheritdoc />
public new SocketExchangeOptions<TEnvironment, TApiCredentials> ClientOptions => (SocketExchangeOptions<TEnvironment, TApiCredentials>)base.ClientOptions;
/// <inheritdoc />
public new SocketApiOptions<TApiCredentials> ApiOptions => (SocketApiOptions<TApiCredentials>)base.ApiOptions;
/// <summary>
/// ctor
/// </summary>
@ -1076,13 +1073,13 @@ namespace CryptoExchange.Net.Clients
ILogger logger,
string baseAddress,
SocketExchangeOptions<TEnvironment, TApiCredentials> options,
SocketApiOptions<TApiCredentials> apiOptions) : base(
SocketApiOptions apiOptions) : base(
logger,
baseAddress,
options,
apiOptions)
{
ApiCredentials = apiOptions.ApiCredentials ?? options.ApiCredentials;
ApiCredentials = options.ApiCredentials;
}
/// <inheritdoc />
@ -1154,7 +1151,7 @@ namespace CryptoExchange.Net.Clients
ILogger logger,
string baseAddress,
SocketExchangeOptions<TEnvironment, TApiCredentials> options,
SocketApiOptions<TApiCredentials> apiOptions) : base(
SocketApiOptions apiOptions) : base(
logger,
baseAddress,
options,

View File

@ -167,8 +167,8 @@ namespace CryptoExchange.Net
/// </summary>
public static void ValidateCredentials(ApiCredentials? credentials)
{
if (credentials != null && credentials.CredentialPairs.Length == 0)
throw new ArgumentException("ApiCredentials configuration invalid");
//if (credentials != null && credentials.CredentialPairs.Length == 0)
// throw new ArgumentException("ApiCredentials configuration invalid");
}
}
}

View File

@ -24,23 +24,4 @@ namespace CryptoExchange.Net.Objects.Options
return item;
}
}
/// <inheritdoc />
public class RestApiOptions<TApiCredentials> : RestApiOptions where TApiCredentials : ApiCredentials
{
/// <summary>
/// The api credentials used for signing requests to this API. Overrides API credentials provided in the client options
/// </summary>
public TApiCredentials? ApiCredentials { get; set; }
/// <summary>
/// Set the values of this options on the target options
/// </summary>
public new T Set<T>(T item) where T : RestApiOptions<TApiCredentials>, new()
{
base.Set(item);
item.ApiCredentials = (TApiCredentials?)ApiCredentials?.Copy();
return item;
}
}
}

View File

@ -31,23 +31,4 @@ namespace CryptoExchange.Net.Objects.Options
return item;
}
}
/// <inheritdoc />
public class SocketApiOptions<TApiCredentials> : SocketApiOptions where TApiCredentials : ApiCredentials
{
/// <summary>
/// The api credentials used for signing requests to this API. Overrides API credentials provided in the client options
/// </summary>
public TApiCredentials? ApiCredentials { get; set; }
/// <summary>
/// Set the values of this options on the target options
/// </summary>
public new T Set<T>(T item) where T : SocketApiOptions<TApiCredentials>, new()
{
base.Set(item);
item.ApiCredentials = (TApiCredentials?)ApiCredentials?.Copy();
return item;
}
}
}