Skip to content

Instantly share code, notes, and snippets.

@christopherobin
Last active October 3, 2015 05:08
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 10 You must be signed in to fork a gist
  • Save christopherobin/2396722 to your computer and use it in GitHub Desktop.
Save christopherobin/2396722 to your computer and use it in GitHub Desktop.
Functionnal MtGox client written in Java (Updated for v2 and data.mtgox.com)
package com.mtgox.api;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.HashMap;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
public class Client {
protected final int BUFFER_SIZE = 8192;
protected String key;
protected String secret;
public Client(String key, String secret) {
this.key = key;
this.secret = secret;
}
public String query(String path, HashMap<String, String> args) throws Exception {
// small sanity check
if (args == null) {
args = new HashMap<>();
}
// build URL, actually we may want to fallback to mtgox.com directly for
// private calls, but that should be fine for now
URL queryUrl = new URL("https://data.mtgox.com/api/" + path);
// create connection
HttpURLConnection connection = (HttpURLConnection)queryUrl.openConnection();
// set user agent
connection.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; Java Test client)");
if (this.secret != null && this.key != null) {
// add nonce and build arg list, nonce is now converted to nanoseconds
// as some implementations uses that, allowing you to use the same value
// across languages. If you use any other library to call the API, make
// sure that you are using the same kind of nonce, or you will encounter
// issues
args.put("nonce", String.valueOf(System.currentTimeMillis() * 1000000));
String sign_data = this.buildQueryString(args);
// api v2 now adds the path followed by a 0 byte in the signature
if (path.startsWith("2/")) {
sign_data = path.substring(2) + "\0" + sign_data;
}
// args signature
Mac mac = Mac.getInstance("HmacSHA512");
SecretKeySpec secret_spec = new SecretKeySpec((new BASE64Decoder()).decodeBuffer(this.secret), "HmacSHA512");
mac.init(secret_spec);
String signature = (new BASE64Encoder()).encode(mac.doFinal(sign_data.getBytes()));
// add signature headers
connection.setRequestProperty("Rest-Key", this.key);
connection.setRequestProperty("Rest-Sign", signature.replaceAll("\n", ""));
}
// write post
if (!args.isEmpty()) {
connection.setDoOutput(true);
connection.getOutputStream().write(this.buildQueryString(args).getBytes());
}
// read info
String result = new String();
byte buffer[] = new byte[this.BUFFER_SIZE];
int len = 0;
// read until eof, no need to increment buffer size too much as the answer will
// most likely arrive in smaller chunks
while ((len = connection.getInputStream().read(buffer, 0, this.BUFFER_SIZE)) > 0) {
result += new String(buffer, 0, len, "UTF-8");
}
return result;
}
protected String buildQueryString(HashMap<String, String> args) throws Exception {
String result = new String();
for (String hashkey : args.keySet()) {
if (result.length() > 0) result += '&';
result += URLEncoder.encode(hashkey, "UTF-8") + "="
+ URLEncoder.encode(args.get(hashkey), "UTF-8");
}
return result;
}
}
@christopherobin
Copy link
Author

Hopefully this new version should work better.
Changes are fairly simple:

  • Key and secret can be left null when creating the Client for calling public APIs
  • Support for API v2
  • Support for data.mtgox.com
  • Exceptions are now bubbled all the way to the top and are the user's responsability

@panipsilos
Copy link

Hi,

guys I am trying to run the new version mtgox-api-v2-java (UsageExample.java) , but again I am getting the following error:

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
jun 06, 2013 8:32:33 PM com.mtgox.api.MtGox getBalance
SEVERE: null
Unexpected token END OF FILE at position 0.
at org.json.simple.parser.JSONParser.parse(JSONParser.java:257)
at org.json.simple.parser.JSONParser.parse(JSONParser.java:81)
at org.json.simple.parser.JSONParser.parse(JSONParser.java:75)
at com.mtgox.api.MtGox.getBalance(MtGox.java:254)
at com.mtgox.examples.UsageExample.main(UsageExample.java:43)

After investigating on the issue, I found out that I may need to download the certificate. So I downloaded and ran the InstallCert java program. But then I didnt know exactly what URL and port to use as argument so I just used the mtgox.com. However I bump into the same exception.

Anybody could help me out please??

@gubatron
Copy link

gubatron commented Nov 9, 2013

does this API allow posting orders?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment