Pages:
Author

Topic: MtGox API version 2: Unofficial Documentation - page 10. (Read 62534 times)

sr. member
Activity: 406
Merit: 250
Before you exit, `print $result->content` - when I did Perl complained to me about SSL, but the warning could be disabled by inserting the following line:

the code I pasted was working - I was just showing others who were having problems :]  thanks though.
sr. member
Activity: 406
Merit: 250
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.
sr. member
Activity: 246
Merit: 250
Thank you, I made some progress in the meantime (current code -> http://pastebin.com/RXQadJPA) :

I changed the method to print the HTTP request with something similar to your code (

Code:
   if (connection.getResponseCode() != 200) {
System.err.println("Failed : HTTP error code : "
+ connection.getResponseCode());
}           
           
            BufferedReader br = new BufferedReader(new InputStreamReader((connection.getInputStream())));
           
            String output;
            System.out.println("HTTP response \n");
while ((output = br.readLine()) != null) {
System.out.println(output);
                        answer+=output;
}
            connection.disconnect();

Now the ticker response works like a charm and gets printed, while I get a 403 when trying to access my informations .

Code:
Failed : HTTP error code : 403
Apr 15, 2013 4:09:58 PM io.botcoin.api.MtGox query
java.io.IOException: Server returned HTTP response code: 403 for URL: https://data.mtgox.com/api/2/BTCUSD/money/info

This is weird: with the old method to read the answer, the beginning seems to be "response:success " ...

meh... Should I try to sign the request with the private key you indicated and provide it to you so we can verify if it is correctly generated?

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

There are quite a few things that can cause it, but from what you've told me it seems pretty clear that your api key and secret are correct, and your nonce is always increasing. Your API key doesn't even need any rights to get a successful response (but it won't give you any information if you don't give it the rights).
sr. member
Activity: 246
Merit: 250
here is what I get using this as secret key : SGVsbG8gV29ybGQh

Code:
post_data_mac : BTCUSD/money/infononce=1366035867142
signature: ZprNub9nISb5NdCig1LMXI9VYCdlbV/3/klZ78EJXHsTASg12xvWEZyrUTaVw5MUcJQtDMf1LrbguKka6BDlMA==

Ok, your hmac code is definitely working properly Smiley
sr. member
Activity: 246
Merit: 250
I have two additional un-related questions :

is there a method to request withdrawal like in the v1 of the API (https://en.bitcoin.it/wiki/MtGox/API/HTTP/v1#Withdraw_bitcoins)? I can't see it in your doku but I've found in the official pdf :

Quote
4.4 send simple
URL: https://mtgox.com/api/2/money/bitcoin/send_simple
Calling this method requires to be identified with an API key with the
withdraw right.
List of parameters address Target bitcoin address
7

amount int Amount of bitcoins to withdraw
fee int Fee amount to be added to transaction (optional), maximum 0.01
BTC
no instant Setting this parameter to 1 will prevent transaction from being processed internally, and force usage of the bitcoin blockchain even if receipient is also on the system
green Setting this parameter to 1 will cause the TX to use MtGox’s green address
Send bitcoins to a given address
This API allows sending a given number of bitcoins to any bitcoin address. Transfers to bitcoin address on the same system are processed instantly, unless the no instant flag is set.
On success, this method will return the transaction id (in offser trx ) which will contain either the bitcoin transaction id as hexadecimal or a UUID value in case of internal transfer.

In the  Wiki they wrote :
Quote
BTCUSD/money/ticker_fast
Solves the problem of ticker lag. (supposedly)
Did you try it? Is not in your doku ... How come it solves the lag problem?


PS: who is the software architect that returns the balance in EUR in a function that is called from "BTCUSD/money/info" ? :\

Yes there are quite a few methods I haven't got round to documenting yet as they can take up quite a bit of time. As I'm not affiliated with MtGox I don't have access to their protocols, so I have to do detective work Smiley I should probably contact MagicalTux to get the official information. I don't have too much spare time at the moment though, exams and such, so I probably won't be able to make too much progress on the rest of the documentation (but if there's a specific method you need out of those I'm aware of - https://bitbucket.org/nitrous/mtgox-api/overview#markdown-header-other-methods - then I'll have a look).

I was not aware of ticker_fast though, must be new in response to recent events, I'll try to add that to the documentation ASAP, the ticker methods are quite simple anyway, they don't seem to accept any arguments so it shouldn't take me too long. I imagine it supersedes the current ticker and connects the same way the websocket does, which is claimed to be realtime. I'll compare the two if I notice MtGox's lag increasing substantially again.

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.
sr. member
Activity: 246
Merit: 250
I went through this recently in perl, hopefully you can make sense of it.

Code:
$ticker_ref = __request('BTCUSD/money/ticker'); 

sub __request {
my ($method, $args) = @_;

$args = "" unless defined $args;

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);

unless ( $result->is_success ) {
__msg "failed $method";
exit 1;
};

return $json->decode( $result->content );

};

Before you exit, `print $result->content` - when I did Perl complained to me about SSL, but the warning could be disabled by inserting the following line:
Code:
$ENV{'PERL_LWP_SSL_VERIFY_HOSTNAME'} = 0;
(This is only temporary however, if you get an SSL warning you should install the certificate for data.mtgox.com to be safe)

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;

It didn't matter in this case but it might solve some problems later on. The rest of your code seems fine - I was able to get a response. Make sure you're using all the modules you need, I needed the following to get your code to work:
Code:
use Time::HiRes qw(gettimeofday);
use Digest::SHA qw( hmac_sha512 );
use HTTP::Request::Common qw(POST GET);
use MIME::Base64;
use LWP::UserAgent;

And if it still doesn't work, send me the result of printing $result->content and your $post_data
sr. member
Activity: 267
Merit: 250
Woodwallets.io
here is what I get using this as secret key : SGVsbG8gV29ybGQh

Code:
post_data_mac : BTCUSD/money/infononce=1366035867142
signature: ZprNub9nISb5NdCig1LMXI9VYCdlbV/3/klZ78EJXHsTASg12xvWEZyrUTaVw5MUcJQtDMf1LrbguKka6BDlMA==
sr. member
Activity: 267
Merit: 250
Woodwallets.io
Thank you, I made some progress in the meantime (current code -> http://pastebin.com/RXQadJPA) :

I changed the method to print the HTTP request with something similar to your code (

Code:
   if (connection.getResponseCode() != 200) {
System.err.println("Failed : HTTP error code : "
+ connection.getResponseCode());
}           
           
            BufferedReader br = new BufferedReader(new InputStreamReader((connection.getInputStream())));
           
            String output;
            System.out.println("HTTP response \n");
while ((output = br.readLine()) != null) {
System.out.println(output);
                        answer+=output;
}
            connection.disconnect();

Now the ticker response works like a charm and gets printed, while I get a 403 when trying to access my informations .

Code:
Failed : HTTP error code : 403
Apr 15, 2013 4:09:58 PM io.botcoin.api.MtGox query
java.io.IOException: Server returned HTTP response code: 403 for URL: https://data.mtgox.com/api/2/BTCUSD/money/info

This is weird: with the old method to read the answer, the beginning seems to be "response:success " ...

meh... Should I try to sign the request with the private key you indicated and provide it to you so we can verify if it is correctly generated?



sr. member
Activity: 246
Merit: 250
I generated a new pair of keys and it works. Weird, I'm using the other pair with the v1 api and another node.js bot.

Now I have another problem related with reading the http answer : It only gets printed the first line

Code:
{"result":"success","data": 
 
and then it stops .


This is the code I'm currently using, taken from the wiki example of the v1:

Code:
// write post
            connection.getOutputStream().write(post_data.getBytes());
            // read info
            byte buffer[] = new byte[16384];
            int len = connection.getInputStream().read(buffer, 0, 16384);
            System.out.print(new String(buffer, 0, len, "UTF-8"));

Quote
MtGox has changed their API so that you are required to use a key and secret for every method.
For every method? I'm not sure about the actual meaning of this. Should I generate a pair of keys for each method? one for orders, one for getinfo, one for withdraw .... ?  And how I do the association keypair <---> method ?


Sounds crazy ! ;|

Thank you a lot for the help, I feel like we are getting closer. I will write a Trading Class for the v2 and make it open asap!


Sorry about that misunderstanding, no you don't need individual API keys for each method! You can use the same API key, it just seems that some methods complain or display undefined behaviour when issued with an invalid/empty API key, whereas they used to be more lenient (e.g. money/ticker).

As for the short response, that's strange as the response is usually all on one line anyway, so there shouldn't be a problem. Perhaps the server simply hasn't had time to send the entire JSON response yet, as the read() method doesn't necessarily wait for EOF, try using something along these lines instead:
Code:
byte current;
byte buffer[] = new byte[16384];
int len = 0;
InputStream s = connection.getInputStream();
while (true) {
    current = s.read();
    if (current == -1) break;
    buffer[len] = current;
    len++;
}
System.out.print(new String(buffer, 0, len, "UTF-8"));

Note - I haven't tested the above code, so it might not work as written, but the essence is to keep trying to read from the connection (in this case, byte by byte, although I'm sure you could adapt it to read larger chunks at a time), until EOF is reached. Note also that some methods, e.g. money/depth/full, request more than 16384 bytes (full depth can be as large as 1mb, maybe even bigger), so you will need to watch out for that and maybe extend the buffer if necessary.
sr. member
Activity: 246
Merit: 250
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
sr. member
Activity: 267
Merit: 250
Woodwallets.io
I have two additional un-related questions :

is there a method to request withdrawal like in the v1 of the API (https://en.bitcoin.it/wiki/MtGox/API/HTTP/v1#Withdraw_bitcoins)? I can't see it in your doku but I've found in the official pdf :

Quote
4.4 send simple
URL: https://mtgox.com/api/2/money/bitcoin/send_simple
Calling this method requires to be identified with an API key with the
withdraw right.
List of parameters address Target bitcoin address
7

amount int Amount of bitcoins to withdraw
fee int Fee amount to be added to transaction (optional), maximum 0.01
BTC
no instant Setting this parameter to 1 will prevent transaction from being processed internally, and force usage of the bitcoin blockchain even if receipient is also on the system
green Setting this parameter to 1 will cause the TX to use MtGox’s green address
Send bitcoins to a given address
This API allows sending a given number of bitcoins to any bitcoin address. Transfers to bitcoin address on the same system are processed instantly, unless the no instant flag is set.
On success, this method will return the transaction id (in offser trx ) which will contain either the bitcoin transaction id as hexadecimal or a UUID value in case of internal transfer.

In the  Wiki they wrote :
Quote
BTCUSD/money/ticker_fast
Solves the problem of ticker lag. (supposedly)
Did you try it? Is not in your doku ... How come it solves the lag problem?


PS: who is the software architect that returns the balance in EUR in a function that is called from "BTCUSD/money/info" ? :\
sr. member
Activity: 406
Merit: 250
I went through this recently in perl, hopefully you can make sense of it.

$ticker_ref = __request('BTCUSD/money/ticker');

sub __request {
   my ($method, $args) = @_;

   $args = "" unless defined $args;

   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);

   unless ( $result->is_success ) {
       __msg "failed $method";
      exit 1;
   };

   return $json->decode( $result->content );

};
sr. member
Activity: 267
Merit: 250
Woodwallets.io
I generated a new pair of keys and it works. Weird, I'm using the other pair with the v1 api and another node.js bot.

Now I have another problem related with reading the http answer : It only gets printed the first line

Code:
{"result":"success","data": 
 
and then it stops .


This is the code I'm currently using, taken from the wiki example of the v1:

Code:
// write post
            connection.getOutputStream().write(post_data.getBytes());
            // read info
            byte buffer[] = new byte[16384];
            int len = connection.getInputStream().read(buffer, 0, 16384);
            System.out.print(new String(buffer, 0, len, "UTF-8"));

Quote
MtGox has changed their API so that you are required to use a key and secret for every method.
For every method? I'm not sure about the actual meaning of this. Should I generate a pair of keys for each method? one for orders, one for getinfo, one for withdraw .... ?  And how I do the association keypair <---> method ?


Sounds crazy ! ;|

Thank you a lot for the help, I feel like we are getting closer. I will write a Trading Class for the v2 and make it open asap!



member
Activity: 83
Merit: 10
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.


Code:
 
function mtgox_query($path, array $req = array()) {
// API settings
$key 'my valid key';
$secret 'my secret code';
 
// generate a nonce as microtime, with as-string handling to avoid problems with 32bits systems
$mt explode(' 'microtime());
$req['nonce'] = $mt[1].substr($mt[0], 26);
 
// generate the POST data string
$post_data http_build_query($req'''&');
 
$prefix '';
if (substr($path02) == '2/') {
$prefix substr($path2)."\0";
}
 
// generate the extra headers
$headers = array(
'Rest-Key: '.$key,
'Rest-Sign: '.base64_encode(hash_hmac('sha512'$prefix.$post_database64_decode($secret), true)),
);
 
// our curl handle (initialize if required)
static $ch null;
if (is_null($ch)) {
$ch curl_init();
curl_setopt($chCURLOPT_RETURNTRANSFERtrue);
curl_setopt($chCURLOPT_USERAGENT'Mozilla/4.0 (compatible; MtGox PHP client; '.php_uname('s').'; PHP/'.phpversion().')');
}
curl_setopt($chCURLOPT_URL'https://data.mtgox.com/api/2/'.$path); //Base URL
curl_setopt($chCURLOPT_POSTFIELDS$post_data);
curl_setopt($chCURLOPT_HTTPHEADER$headers);
curl_setopt($chCURLOPT_SSL_VERIFYPEERFALSE);
 
// run the query
$res curl_exec($ch);
if ($res === false) throw new Exception('Could not get reply: '.curl_error($ch));
$dec json_decode($restrue);
if (!$dec) throw new Exception('Invalid data received, please make sure connection is working and requested API exists');
return $dec;
}
 
// example 1: get infos about the account, plus the list of rights we have access to
var_dump(mtgox_query('BTCUSD/money/ticker'));// PATH
 
// old api (get funds)
//var_dump(mtgox_query('0/getFunds.php'));
 
// trade example
// var_dump(mtgox_query('0/buyBTC.php', array('amount' => 1, 'price' => 15)));
sr. member
Activity: 246
Merit: 250
Ah yes, that must be it, I just checked and mtgox.com is signed by VeriSign, whereas data.mtgox.com is signed by StartCom - two different certificates unfortunately. Go to https://data.mtgox.com and you should be able to get the correct certificate, it might be useful adding it to the same keystore as well, just in case it ever needs both. Hopefully this will finally fix it Smiley

Getting there !  SSL works!

I added the two certificate to the same file with

Code:
keytool -import -alias mtgox-data -file data.mtgox.com.cer -keystore mtgox.jks
keytool -import -alias mtgox-com -file mtgox.com.cer -keystore mtgox.jks

Then set the system property (trust store)

Code:
System.setProperty("javax.net.ssl.trustStore",settings.KEYSTORE_PATH);
System.setProperty("javax.net.ssl.trustStorePassword",settings.KEYSTORE_PWD);

Now it ... works! Well, kind of. I got a 403 instead... Sad

Code:
java.io.IOException: Server returned HTTP response code: 403 for URL: https://data.mtgox.com/api/2/BTCUSD/money/info


      

MtGox has changed their API so that you are required to use a key and secret for every method. Also, if you are still having errors, your nonce could not be working properly, so do try generating a new api key/secret.
sr. member
Activity: 406
Merit: 250
Hmm, ironic that 10 days ago listentobitcoin was switched from socket.io to websocket! I looked at their github repo, and I think this edit https://github.com/MaxLaumeister/Listen-To-Bitcoin/blob/778273ae2a91a89f230bd88302fa69fdee61a7da/socket.js might have what you're looking for.

nice, that works thanks.. I wonder why he switched.
sr. member
Activity: 246
Merit: 250
Ah yes, that must be it, I just checked and mtgox.com is signed by VeriSign, whereas data.mtgox.com is signed by StartCom - two different certificates unfortunately. Go to https://data.mtgox.com and you should be able to get the correct certificate, it might be useful adding it to the same keystore as well, just in case it ever needs both. Hopefully this will finally fix it Smiley

Getting there !  SSL works!

I added the two certificate to the same file with

Code:
keytool -import -alias mtgox-data -file data.mtgox.com.cer -keystore mtgox.jks
keytool -import -alias mtgox-com -file mtgox.com.cer -keystore mtgox.jks

Then set the system property (trust store)

Code:
System.setProperty("javax.net.ssl.trustStore",settings.KEYSTORE_PATH);
System.setProperty("javax.net.ssl.trustStorePassword",settings.KEYSTORE_PWD);

Now it ... works! Well, kind of. I got a 403 instead... Sad

Code:
java.io.IOException: Server returned HTTP response code: 403 for URL: https://data.mtgox.com/api/2/BTCUSD/money/info

Ah good, it's connecting properly now Smiley The reason it gives a 403 error is likely that the HMAC is wrong  or not being sent, try setting the path to 'BTCUSD/money/ticker' - this doesn't care about the authentication and should work, just to check that it can actually get a valid response, then:
  • Set your secret to "SGVsbG8gV29ybGQh", then send me your post_data_mac and signature results so that I can check your HMAC is working correctly, although it seems like your code is correct.
  • Are both your API key and secret valid? Consider generating a new pair, and making sure all the rights are selected.
sr. member
Activity: 267
Merit: 250
Woodwallets.io
Ah yes, that must be it, I just checked and mtgox.com is signed by VeriSign, whereas data.mtgox.com is signed by StartCom - two different certificates unfortunately. Go to https://data.mtgox.com and you should be able to get the correct certificate, it might be useful adding it to the same keystore as well, just in case it ever needs both. Hopefully this will finally fix it Smiley

Getting there !  SSL works!

I added the two certificate to the same file with

Code:
keytool -import -alias mtgox-data -file data.mtgox.com.cer -keystore mtgox.jks
keytool -import -alias mtgox-com -file mtgox.com.cer -keystore mtgox.jks

Then set the system property (trust store)

Code:
System.setProperty("javax.net.ssl.trustStore",settings.KEYSTORE_PATH);
System.setProperty("javax.net.ssl.trustStorePassword",settings.KEYSTORE_PWD);

Now it ... works! Well, kind of. I got a 403 instead... Sad

Code:
java.io.IOException: Server returned HTTP response code: 403 for URL: https://data.mtgox.com/api/2/BTCUSD/money/info


     
sr. member
Activity: 246
Merit: 250
edit:  never mind just spotted this:

websocket is officially deprecated now?
shockdiode: yep, replaced by socket.io server


Hmm, ironic that 10 days ago listentobitcoin was switched from socket.io to websocket! I looked at their github repo, and I think this edit https://github.com/MaxLaumeister/Listen-To-Bitcoin/blob/778273ae2a91a89f230bd88302fa69fdee61a7da/socket.js might have what you're looking for.
sr. member
Activity: 406
Merit: 250
yea I downloaded the source to listentobitcoins too, it only shows transactions from blockchain for me, can't get it to show trades for some reason, it connects but nothing comes through.

I was thinking of using it as a starting point for another little project but don't really want to convert it to socket.io just cos mtgox websocket maybe temporarily dodgy.


---
edit:  never mind just spotted this:

websocket is officially deprecated now?
shockdiode: yep, replaced by socket.io server
Pages:
Jump to: