andre77 / bittrex-ws-java

Bittrex Websocket Java-Client
13 stars 2 forks source link

Issues with Authenticate #4

Closed sp33dy closed 6 years ago

sp33dy commented 6 years ago

Hi,

First of all, thank you for this library! It works really well for the Public callbacks.

However, I'm having a problem with the authenticate. I managed to sign the GetAuthContext and then call the Authenticate. This seems to work the very first time I try in a client, then it rarely works after that point.

What I have now just discovered is IF I create a new Java Main (i.e. new class name) and run, it connects EVERYTIME and then it continues to experience the same issue as the last.

Can you think of anything that might be at fault here?

I've raised an issue on the Bittrex github () , but I'm beginning to think that this is a bug somewhere in this library???

Any help would be really appreciated.

Kind regards

Sp33dy

sp33dy commented 6 years ago

To add, I'm running in Eclipse. Could that be holding something open that it shouldnt? In fact, I'll try exporting the code and run it on cmd line to see if it exhibits the same issue.

sp33dy commented 6 years ago

I continually see this error:

Verbose serverSentEvents - Trigger onData with data: {"I":"1","E":"There was an error invoking Hub method 'c2.Authenticate'."}

I just can't figure out why it returns this a LOT of the time.

sp33dy commented 6 years ago

Sample code (with rubbish debug in along side turning logging on). Is it me being stupid?

`import java.io.ByteArrayInputStream; import java.io.IOException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.SignatureException; import java.util.Arrays; import java.util.Base64; import java.util.Formatter; import java.util.concurrent.ExecutionException; import java.util.zip.Inflater; import java.util.zip.InflaterInputStream;

import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec;

import microsoft.aspnet.signalr.client.LogLevel; import microsoft.aspnet.signalr.client.Logger; import microsoft.aspnet.signalr.client.SignalRFuture; import microsoft.aspnet.signalr.client.hubs.HubConnection; import microsoft.aspnet.signalr.client.hubs.HubProxy; import microsoft.aspnet.signalr.client.transport.ServerSentEventsTransport;

public class AuthenticateSocket {

private static final String DEFAULT_SERVER_URL = "https://socket.bittrex.com/signalR";    
private static final String HMAC_SHA512 = "HmacSHA512";

private static final String API_KEY = "KEY";
private static final String API_SECRET = "SECRET";

private static final String HUB = "c2";

public static void main(String[] args) {
    try {
        Logger logger = (message, level) -> {
            if (level == LogLevel.Verbose) {
                System.out.println(level + " " + message);
            }
        };

        HubConnection connection = new HubConnection(DEFAULT_SERVER_URL, null, false, logger);
        final HubProxy proxy = connection.createHubProxy(HUB);

        proxy.subscribe(new Object() {
            @SuppressWarnings("unused")
            public Boolean Authenticate(String key, String signed) {
                System.out.println("Authenticate! ");
                return true;
            }
        });

        SignalRFuture<Void> start = connection.start(new ServerSentEventsTransport(logger));
        start.get();

        System.out.println("Getting Challenge!");
        SignalRFuture<String> challenge = proxy.invoke(String.class, "GetAuthContext", API_KEY);
        String signed = calculateHMAC(challenge.get(), API_SECRET);
        System.out.println("Signed: "+signed);
        SignalRFuture<Boolean> authenticated = proxy.invoke(Boolean.class, "Authenticate", API_KEY, signed);
        System.out.println(2222);
        authenticated.done(v -> System.out.println("Authenticated? "+v));
        System.out.println("DONE");

// System.out.println(authenticated.get()); // System.out.println("Authenticated? "+authenticated.get()); } catch (Exception e) { System.out.println("Some bad shit went down! "+e); } }

private static String toHexString(byte[] bytes) {
    Formatter formatter = new Formatter();
    for (byte b : bytes) {
        formatter.format("%02x", b);
    }
    return formatter.toString();
}

public static String calculateHMAC(String data, String key) throws SignatureException, NoSuchAlgorithmException, InvalidKeyException {
    System.out.println("calculateHMAC");
    SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), HMAC_SHA512);
    Mac mac = Mac.getInstance(HMAC_SHA512);
    mac.init(secretKeySpec);
    return toHexString(mac.doFinal(data.getBytes()));
}

public static String decompress(String gzip) throws IOException {
    byte[] compressed = Base64.getDecoder().decode(gzip);
    ByteArrayInputStream bais = new ByteArrayInputStream(compressed);
    InflaterInputStream iis = new InflaterInputStream(bais, new Inflater(true));

    String result = "";
    byte[] buf = new byte[5];
    int rlen = -1;
    while ((rlen = iis.read(buf)) != -1) {
        result += new String(Arrays.copyOf(buf, rlen));
    }
    return result;
}

} `

sp33dy commented 6 years ago

I believe adding the Authenticate method in the proxy's subscribe isn't needed; but I'm desperate and willing to try anything right now.

sp33dy commented 6 years ago

It's getting late, but I'm now getting a connection every time. I've now fixed it by removing the parameter from the start:

From:

SignalRFuture<Void> start = connection.start(new ServerSentEventsTransport(logger));

To:

SignalRFuture<Void> start = connection.start();

I'll look into this parameter in the morning, but at least I'm chuffed this is now working!

sp33dy commented 6 years ago

Completely happy now, thank you.