diff --git a/CryptoExchange.Net/Authentication/ApiCredentials.cs b/CryptoExchange.Net/Authentication/ApiCredentials.cs
index 2c6d65d..53c00f4 100644
--- a/CryptoExchange.Net/Authentication/ApiCredentials.cs
+++ b/CryptoExchange.Net/Authentication/ApiCredentials.cs
@@ -1,5 +1,8 @@
using System;
+using System.IO;
using System.Security;
+using System.Text;
+using Newtonsoft.Json.Linq;
namespace CryptoExchange.Net.Authentication
{
@@ -8,12 +11,12 @@ namespace CryptoExchange.Net.Authentication
///
/// The api key to authenticate requests
///
- public SecureString Key { get; }
+ public SecureString Key { get; private set; }
///
/// The api secret to authenticate requests
///
- public SecureString Secret { get; }
+ public SecureString Secret { get; private set; }
///
/// The private key to authenticate requests
@@ -50,17 +53,49 @@ namespace CryptoExchange.Net.Authentication
if (string.IsNullOrEmpty(key) || string.IsNullOrEmpty(secret))
throw new ArgumentException("Key and secret can't be null/empty");
- var secureApiKey = new SecureString();
- foreach (var c in key)
- secureApiKey.AppendChar(c);
- secureApiKey.MakeReadOnly();
- Key = secureApiKey;
+ Key = CreateSecureString(key);
+ Secret = CreateSecureString(secret);
+ }
- var secureApiSecret = new SecureString();
- foreach (var c in secret)
- secureApiSecret.AppendChar(c);
- secureApiSecret.MakeReadOnly();
- Secret = secureApiSecret;
+ ///
+ /// Create Api credentials providing a stream containing json data. The json data should include two values: apiKey and apiSecret
+ ///
+ /// The stream containing the json data
+ /// A key to identify the credentials for the API. For example, when set to `binanceKey` the json data should contain a value for the property `binanceKey`. Defaults to 'apiKey'.
+ /// A key to identify the credentials for the API. For example, when set to `binanceSecret` the json data should contain a value for the property `binanceSecret`. Defaults to 'apiSecret'.
+ public ApiCredentials(Stream inputStream, string identifierKey = null, string identifierSecret = null)
+ {
+ using (var reader = new StreamReader(inputStream, Encoding.ASCII, false, 512, true))
+ {
+ var stringData = reader.ReadToEnd();
+ var jsonData = JToken.Parse(stringData);
+ var key = TryGetValue(jsonData, identifierKey ?? "apiKey");
+ var secret = TryGetValue(jsonData, identifierSecret ?? "apiSecret");
+
+ if (key == null || secret == null)
+ throw new ArgumentException("apiKey or apiSecret value not found in Json credential file");
+
+ Key = CreateSecureString(key);
+ Secret = CreateSecureString(secret);
+ }
+
+ inputStream.Seek(0, SeekOrigin.Begin);
+ }
+
+ protected string TryGetValue(JToken data, string key)
+ {
+ if (data[key] == null)
+ return null;
+ return (string) data[key];
+ }
+
+ protected SecureString CreateSecureString(string source)
+ {
+ var secureString = new SecureString();
+ foreach (var c in source)
+ secureString.AppendChar(c);
+ secureString.MakeReadOnly();
+ return secureString;
}
public void Dispose()