Bitcoin Forum
November 15, 2024, 08:35:31 AM *
News: Check out the artwork 1Dq created to commemorate this forum's 15th anniversary
 
   Home   Help Search Login Register More  
Pages: « 1 2 [3] 4 5 6 7 8 9 10 11 »  All
  Print  
Author Topic: MtGox API version 2: Unofficial Documentation  (Read 62513 times)
advanced
Sr. Member
****
Offline Offline

Activity: 267
Merit: 250


Woodwallets.io


View Profile WWW
April 15, 2013, 03:52:03 PM
 #41

Thanks, as always!

I've found out about that method by reading through the pdfs @ https://github.com/MtGox/mtgox-doc/tree/master/api , it seems quite useful.

Quote
BTCUSD/money/info isn't technically the method, the actual method is money/info, but it can be accessed with a currency context as well. money/info gives your account details, including all the currency wallets you have, so if you have an EUR wallet, it will show up, as well as your BTC wallet, and any other currencies

Are you sure? I tried removing the BTCUSD from the ticker ending with (money/ticker) and I get a http 500.


Quote
Do you know what the response is that comes with the 403 error? Your function should still generate and return the answer, right?

Actually I'm afraid that I can't get the answer as the instruction to read the http inputstream throws the IOException... I'll try to go back to the buffer example to be able to read the answer from there

Bitmessage : BM-NAx31aEiqeq5zKUtxhKscXQ7Dwn1jJfR
nitrous (OP)
Sr. Member
****
Offline Offline

Activity: 246
Merit: 250


View Profile
April 15, 2013, 03:57:46 PM
 #42

I also recommend making sure you join your arguments to your nonce properly using the following, and updating it wherever necessay:
Code:
my $post_data = $nonce . ($args == '' ? '' : '&' . $args);
my $hash_data = $method . chr(0) . $post_data;

I think it's ok as it is - the ? doesn't seem to be required in post data and I'm supplying the args in full:

print Dumper __request('BTCUSD/money/order/add', "&type=$type&amount_int=$amount");

I've created and cancelled orders with it anyway so seems fine.


Oh sorry, yeah if you pass it with a leading ampersand it's most definitely fine, yeah that works great then  Smiley

403 probably means failed authentication - I don't think the post data should contain the method should it? (as shown above)

mine works with just nonce + any other arguments.


The API can return 403 for quite a few different reasons (wrong API key, bad nonce, etc), but it usually hints in the JSON the specific reason for the error.
post_data_mac is the equivalent of your $hash_data

Donations: 1Q2EN7TzJ6z82xvmQrRoQoMf3Tf4rMCyvL
MtGox API v2 Unofficial Documentation: https://bitbucket.org/nitrous/mtgox-api/overview
MtGox API v2 Unofficial Documentation Forum Thread: https://bitcointalk.org/index.php?topic=164404.0
nitrous (OP)
Sr. Member
****
Offline Offline

Activity: 246
Merit: 250


View Profile
April 15, 2013, 04:03:49 PM
 #43

Thanks, as always!

I've found out about that method by reading through the pdfs @ https://github.com/MtGox/mtgox-doc/tree/master/api , it seems quite useful.

Quote
BTCUSD/money/info isn't technically the method, the actual method is money/info, but it can be accessed with a currency context as well. money/info gives your account details, including all the currency wallets you have, so if you have an EUR wallet, it will show up, as well as your BTC wallet, and any other currencies

Are you sure? I tried removing the BTCUSD from the ticker ending with (money/ticker) and I get a http 500.


Quote
Do you know what the response is that comes with the 403 error? Your function should still generate and return the answer, right?

Actually I'm afraid that I can't get the answer as the instruction to read the http inputstream throws the IOException... I'll try to go back to the buffer example to be able to read the answer from there

With money/ticker, a currency context is required as it returns information specific to a given currency, but money/info does not require a context as it is independent of the currency - it just returns an informative overview of your entire account (all wallets inclusive), so you can call BTCUSD/money/info if you want, but it's really just redirecting to money/info.

Could you catch the exception or is the response data completely blocked from you? The JSON response should contain an error key pointing to the problem, although it can be somewhat cryptic.

Donations: 1Q2EN7TzJ6z82xvmQrRoQoMf3Tf4rMCyvL
MtGox API v2 Unofficial Documentation: https://bitbucket.org/nitrous/mtgox-api/overview
MtGox API v2 Unofficial Documentation Forum Thread: https://bitcointalk.org/index.php?topic=164404.0
advanced
Sr. Member
****
Offline Offline

Activity: 267
Merit: 250


Woodwallets.io


View Profile WWW
April 15, 2013, 04:24:06 PM
 #44

All right, I'll try to get that JSON right away. In the meantime another question: is it correct that the HTTP requests are GETs, right?

Bitmessage : BM-NAx31aEiqeq5zKUtxhKscXQ7Dwn1jJfR
nitrous (OP)
Sr. Member
****
Offline Offline

Activity: 246
Merit: 250


View Profile
April 15, 2013, 04:27:51 PM
 #45

All right, I'll try to get that JSON right away. In the meantime another question: is it correct that the HTTP requests are GETs, right?

I should have spotted that! No, it's POST. I'm surprised you managed to get money/ticker working without POST but yes, you need to send the post_data by POST during the connection.

Donations: 1Q2EN7TzJ6z82xvmQrRoQoMf3Tf4rMCyvL
MtGox API v2 Unofficial Documentation: https://bitbucket.org/nitrous/mtgox-api/overview
MtGox API v2 Unofficial Documentation Forum Thread: https://bitcointalk.org/index.php?topic=164404.0
advanced
Sr. Member
****
Offline Offline

Activity: 267
Merit: 250


Woodwallets.io


View Profile WWW
April 15, 2013, 04:42:00 PM
 #46

ah, really? :\  Huh Writing this client is driving me nuts.


This is the behaviour at the moment :
Doing nothing or specifing the request method with this line :
Code:
connection.setRequestMethod("GET");
allows me to read the ticker and gives me the 403 on my info.

Using post, on the other hand, stars giving me a HTTP 500 on the ticker! (and still 403 on the info)
Code:
connection.setRequestMethod("POST");
/code]



This is everything I was able to get so far... unfortunately not any JSON.



Code:
Failed : HTTP error code : 403 -
Server returned HTTP response code: 403 for URL: https://data.mtgox.com/api/2/money/info
Forbidden("java.net.SocketPermission" "data.mtgox.com:80" "connect,resolve")
Apr 15, 2013 6:39:36 PM io.botcoin.api.MtGox query

Bitmessage : BM-NAx31aEiqeq5zKUtxhKscXQ7Dwn1jJfR
MikeH
Sr. Member
****
Offline Offline

Activity: 406
Merit: 250


View Profile
April 15, 2013, 05:06:30 PM
 #47

if only the world would settle on 1 language.  Smiley
bittencoin
Member
**
Offline Offline

Activity: 83
Merit: 10


View Profile
April 15, 2013, 05:30:52 PM
Last edit: April 15, 2013, 05:56:36 PM by bittencoin
 #48

Hi Nitrous,

I tried to read and follow your guide to try to pull up some data, but I am getting errors in the response when I just try to get the ticker info.  

array(3) { ["result"]=> string(5) "error" ["error"]=> string(20) "Chosen API not found" ["token"]=> string(13) "unknown_error" }

Basically, all I did was taking the example php template and put in my api key and secret (not shown here), and changed the base URL to
Code:
https://data.mtgox.com/api/2/
and changed the path to
Code:
BTCUSD/money/ticker
but the var dump says Chosen API not found.  I tested with many new api key/secret codes, but that appears not to be the source of the problem.  Any insight is appreciated.  Thank you.



Hi bittencoin,

You are correct that the API code and secret are not the problem, the problem is with this part of your code:

Code:
	$prefix = '';
if (substr($path, 0, 2) == '2/') {
$prefix = substr($path, 2)."\0";
}
 
// generate the extra headers
$headers = array(
'Rest-Key: '.$key,
'Rest-Sign: '.base64_encode(hash_hmac('sha512', $prefix.$post_data, base64_decode($secret), true)),
);
 

Your prefix is empty in a normal scenario, instead, you should change this code to the following:
Code:
	$prefix = $path;
if (substr($path, 0, 2) == '2/') {
$prefix = substr($path, 2);
}
 
// generate the extra headers
$headers = array(
'Rest-Key: '.$key,
'Rest-Sign: '.base64_encode(hash_hmac('sha512', $prefix."\0".$post_data, base64_decode($secret), true)),
);

I have made sure your prefix variable contains the path, and I've moved the null character into the rest-sign to make sure it's always included. This code worked for me after doing those fixes Smiley

Thank you Nitrous.  I will test it out and report back.  But by looking at the original template code from mtgox, I can see why it does not work now.  

This block of code is suppose to check if the "path" is api version 2
Code:
$prefix = '';
if (substr($path, 0, 2) == '2/') {
$prefix = substr($path, 2)."\0";
}

the check is supposed to look for the "2/" at end of the string, but in this case the $path variable is "BTCUSD/money/ticker" and does not contain the "2/".  If I am correct, the original code tried to look for the "2/" in the wrong string, it should be looking for the version in the base url
Code:
https://data.mtgox.com/api/2/
using the code
Code:
substr($path, -2, 2) == '2/'
.  So if that is fixed, then you don't need to hard code the null character into the REST sign.  

UPDATE:

Here is my fix of that block of code

Code:
$prefix = '';
$baseurl = 'https://data.mtgox.com/api/2/';
if (substr($baseurl, -2, 2) == '2/') {
$prefix = $path."\0";

}
nitrous (OP)
Sr. Member
****
Offline Offline

Activity: 246
Merit: 250


View Profile
April 15, 2013, 06:22:56 PM
 #49


Thank you Nitrous.  I will test it out and report back.  But by looking at the original template code from mtgox, I can see why it does not work now.  

This block of code is suppose to check if the "path" is api version 2
Code:
$prefix = '';
if (substr($path, 0, 2) == '2/') {
$prefix = substr($path, 2)."\0";
}

the check is supposed to look for the "2/" at end of the string, but in this case the $path variable is "BTCUSD/money/ticker" and does not contain the "2/".  If I am correct, the original code tried to look for the "2/" in the wrong string, it should be looking for the version in the base url
Code:
https://data.mtgox.com/api/2/
using the code
Code:
substr($path, -2, 2) == '2/'
.  So if that is fixed, then you don't need to hard code the null character into the REST sign.  

UPDATE:

Here is my fix of that block of code

Code:
$prefix = '';
$baseurl = 'https://data.mtgox.com/api/2/';
if (substr($baseurl, -2, 2) == '2/') {
$prefix = $path."\0";

}

Ok, let me know how it goes, your code is very close to working, the error you received was simply not signing the request properly, which the above should fix Smiley

Donations: 1Q2EN7TzJ6z82xvmQrRoQoMf3Tf4rMCyvL
MtGox API v2 Unofficial Documentation: https://bitbucket.org/nitrous/mtgox-api/overview
MtGox API v2 Unofficial Documentation Forum Thread: https://bitcointalk.org/index.php?topic=164404.0
nitrous (OP)
Sr. Member
****
Offline Offline

Activity: 246
Merit: 250


View Profile
April 15, 2013, 06:31:52 PM
 #50

ah, really? :\  Huh Writing this client is driving me nuts.


This is the behaviour at the moment :
Doing nothing or specifing the request method with this line :
Code:
connection.setRequestMethod("GET");
allows me to read the ticker and gives me the 403 on my info.

Using post, on the other hand, stars giving me a HTTP 500 on the ticker! (and still 403 on the info)
Code:
connection.setRequestMethod("POST");
/code]



This is everything I was able to get so far... unfortunately not any JSON.



Code:
Failed : HTTP error code : 403 -
Server returned HTTP response code: 403 for URL: https://data.mtgox.com/api/2/money/info
Forbidden("java.net.SocketPermission" "data.mtgox.com:80" "connect,resolve")
Apr 15, 2013 6:39:36 PM io.botcoin.api.MtGox query

Your code is so close to working, which makes it that much more frustrating. It must be some small, easy to miss, error. Anyway, I quickly wrote this using my own basic API as a reference: http://pastebin.com/SmrxuJQj

I was able to get it to work, so if you compare each line hopefully you'll finally find whatever's causing the problem Smiley Also, I found a way to get the JSON even with the IOException: declare the query function as throwing java.io.Exception, then you can check the response code of the connection - if it is >= 400, use getErrorStream instead of getInputStream, hopefully this will help you debug.

Note: I added "000" to the nonce because my api uses miroseconds, and otherwise I would be rejected by the server, feel free to remove them as your nonces are milliseconds.

Donations: 1Q2EN7TzJ6z82xvmQrRoQoMf3Tf4rMCyvL
MtGox API v2 Unofficial Documentation: https://bitbucket.org/nitrous/mtgox-api/overview
MtGox API v2 Unofficial Documentation Forum Thread: https://bitcointalk.org/index.php?topic=164404.0
MikeH
Sr. Member
****
Offline Offline

Activity: 406
Merit: 250


View Profile
April 15, 2013, 06:47:53 PM
 #51

not sure if it's an issue with v2 but others have had probs with their nonce not being long enough, something to keep in mind - but remember if you fiddle with it, you can't make it shorter again Smiley

don't know the requirement but mine's working at 16 chars.
nitrous (OP)
Sr. Member
****
Offline Offline

Activity: 246
Merit: 250


View Profile
April 15, 2013, 07:13:13 PM
 #52

not sure if it's an issue with v2 but others have had probs with their nonce not being long enough, something to keep in mind - but remember if you fiddle with it, you can't make it shorter again Smiley

don't know the requirement but mine's working at 16 chars.


Yeah I noticed that recently, but testing today with a separate API key I found 13 also seems to work, so millisecond time should also be ok. I'll put it on my todo list to find the minimum length at some point Smiley

Donations: 1Q2EN7TzJ6z82xvmQrRoQoMf3Tf4rMCyvL
MtGox API v2 Unofficial Documentation: https://bitbucket.org/nitrous/mtgox-api/overview
MtGox API v2 Unofficial Documentation Forum Thread: https://bitcointalk.org/index.php?topic=164404.0
advanced
Sr. Member
****
Offline Offline

Activity: 267
Merit: 250


Woodwallets.io


View Profile WWW
April 16, 2013, 09:58:28 AM
 #53

Thanks! My today's resolution is : don't go to sleep unless it works.

So, lets try to capture exceptions and errors:

Code:
            if (connection.getResponseCode() != 200) {
                 BufferedReader errBr = new BufferedReader(new InputStreamReader((connection.getErrorStream())));
               
System.err.println("Failed : HTTP error code : "
+ connection.getResponseCode() + " \n Response message:"
                                        + connection.getResponseMessage() + " \n Permission :"
                                        + connection.getPermission());
                         String output;
                         System.out.println("Error Stream: : \n"); //TODO Remove
                         while ((output = errBr.readLine()) != null) {
                            System.err.println(output);

                    }                                         
}           
             

And here we go baby :

Code:
Failed : HTTP error code : 403 
Response message:Forbidden
Permission :("java.net.SocketPermission" "data.mtgox.com:80" "connect,resolve")
Error Stream: {"result":"error","error":"Identification required to access private API","token":"login_error_missing_nonce"}



missing nonce?


Bitmessage : BM-NAx31aEiqeq5zKUtxhKscXQ7Dwn1jJfR
advanced
Sr. Member
****
Offline Offline

Activity: 267
Merit: 250


Woodwallets.io


View Profile WWW
April 16, 2013, 10:09:34 AM
 #54

update : the call to the ticker works only via GET

Bitmessage : BM-NAx31aEiqeq5zKUtxhKscXQ7Dwn1jJfR
MikeH
Sr. Member
****
Offline Offline

Activity: 406
Merit: 250


View Profile
April 16, 2013, 10:14:00 AM
 #55

works via POST for me - should paste the rest of the code in question.
advanced
Sr. Member
****
Offline Offline

Activity: 267
Merit: 250


Woodwallets.io


View Profile WWW
April 16, 2013, 10:23:32 AM
Last edit: April 16, 2013, 10:36:35 AM by advanced
 #56

Spotted new difference between your code

Code:
HttpsURLConnection c = (HttpsURLConnection)query.openConnection();

and my code

Code:
HttpURLConnection connection = (HttpURLConnection)query.openConnection();


still missing_nonce_error.


Plus, I don't understand howcome it works for you without specifying the keystore file .... :\ To make your code work I had to add the keystore to it! (And yes, it works with the same api keys I'm try to use)

Bitmessage : BM-NAx31aEiqeq5zKUtxhKscXQ7Dwn1jJfR
advanced
Sr. Member
****
Offline Offline

Activity: 267
Merit: 250


Woodwallets.io


View Profile WWW
April 16, 2013, 10:25:14 AM
 #57

works via POST for me - should paste the rest of the code in question.


I receive this error when "POSTing" it : {"result":"error","error":"Invalid request method for this API","token":"invalid_request_method"}

Bitmessage : BM-NAx31aEiqeq5zKUtxhKscXQ7Dwn1jJfR
MikeH
Sr. Member
****
Offline Offline

Activity: 406
Merit: 250


View Profile
April 16, 2013, 10:50:53 AM
 #58

I've only posted perl code.. is that what you ran?

paste your java equivalent of the following:


my $nonce = 'nonce=' . sprintf "%d", gettimeofday * 1e6;
my $hash_data = $method . chr(0) . $nonce . $args;

my $req = HTTP::Request->new(POST => 'https://data.mtgox.com/api/2/' . $method );
$req->content_type('application/x-www-form-urlencoded');
$req->content($nonce . $args);
$req->header('Rest-Key' => $key);
$req->header('Rest-Sign' => encode_base64( hmac_sha512( $hash_data, decode_base64($secret) ) ));

my $result = $lwp->request($req);
advanced
Sr. Member
****
Offline Offline

Activity: 267
Merit: 250


Woodwallets.io


View Profile WWW
April 16, 2013, 10:52:30 AM
 #59

I've only posted perl code.. is that what you ran?

paste your java equivalent of the following:


my $nonce = 'nonce=' . sprintf "%d", gettimeofday * 1e6;
my $hash_data = $method . chr(0) . $nonce . $args;

my $req = HTTP::Request->new(POST => 'https://data.mtgox.com/api/2/' . $method );
$req->content_type('application/x-www-form-urlencoded');
$req->content($nonce . $args);
$req->header('Rest-Key' => $key);
$req->header('Rest-Sign' => encode_base64( hmac_sha512( $hash_data, decode_base64($secret) ) ));

my $result = $lwp->request($req);


Hi Mike, thanks for your support. However, if you go back in this conversation you can follow the track of the java discussion .

Bitmessage : BM-NAx31aEiqeq5zKUtxhKscXQ7Dwn1jJfR
advanced
Sr. Member
****
Offline Offline

Activity: 267
Merit: 250


Woodwallets.io


View Profile WWW
April 16, 2013, 11:02:57 AM
Last edit: April 16, 2013, 11:32:16 AM by advanced
 #60

I ran your code, inspected it line by line, tried to go back to deprecated Base64 functions, but nothing.

The only difference I was able to spot is the way you (don't) encode the post data arguments. I'm trying to use this function to add the arguments, which maybe does something weird to the request . I don't see how anyway :


Here is how I call the query and add the argument :


Code:
        String urlPath = "money/info";
        HashMap<String, String> query_args = new HashMap<>();  
        String queryResult = query(urlPath, query_args);

Code:
 public String query(String path, HashMap<String, String> args) {
.//here args should be empty
.
.
  args.put("nonce", nonce);        
//here the nonce is added to the args
  String hash_data = path + "\0" + this.buildQueryString(args);
//here the nonce should be added to hash_data: indeed if I print I have money/info◙nonce=1366110562837
.
.
.
}


And below is the function buildQueryString


Code:
   //Build the query string given a set of query parameters
     protected String buildQueryString(HashMap<String, String> args) {
        String result = new String();
        for (String hashkey : args.keySet()) {
            if (result.length() > 0) result += '&';
            try {
                result += URLEncoder.encode(hashkey, "UTF-8") + "="
                        + URLEncoder.encode(args.get(hashkey), "UTF-8");
            } catch (Exception ex) {
                Logger.getLogger(MtGox.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        return result;
    }


I wonder if is something related to the ◙  symbol, but I see it in your hash_data as well!


EDIT: nope, I tried to build the string manually and I get the same damn 'missing nonce' error.

Bitmessage : BM-NAx31aEiqeq5zKUtxhKscXQ7Dwn1jJfR
Pages: « 1 2 [3] 4 5 6 7 8 9 10 11 »  All
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!