MtGox/API/HTTP: Difference between revisions

From Bitcoin Wiki
Jump to navigation Jump to search
PaulGWebster (talk | contribs)
m Updated to reflect API updated 0->1
Vbmithr (talk | contribs)
Line 156: Line 156:


=== Python ===
=== Python ===
Python version here: https://bitcointalk.org/index.php?topic=49789.msg592388#msg592388
<source lang="python">
from urllib import urlencode
import urllib2
import time
from hashlib import sha512
from hmac import HMAC
import base64
import json
def get_nonce():
    return int(time.time()*100000)
 
def sign_data(secret, data):
    return base64.b64encode(str(HMAC(secret, data, sha512).digest()))
     
class requester:
    def __init__(self, auth_key, auth_secret):
        self.auth_key = auth_key
        self.auth_secret = base64.b64decode(auth_secret)
       
    def build_query(self, req={}):
        req["nonce"] = get_nonce()
        post_data = urlencode(req)
        headers = {}
        headers["User-Agent"] = "GoxApi"
        headers["Rest-Key"] = self.auth_key
        headers["Rest-Sign"] = sign_data(self.auth_secret, post_data)
        return (post_data, headers)
       
    def perform(self, path, args):
        data, headers = self.build_query(args)
        req = urllib2.Request("https://mtgox.com/api/0/"+path, data, headers)
        res = urllib2.urlopen(req, data)
        return json.load(res)
</source>


=== Node.js ===
=== Node.js ===

Revision as of 12:26, 20 October 2012

Two versions of the HTTP API are currently available, see the following pages for details on the methods available for each:

Summary

All HTTP API requests are sent to URLs beginning with https://mtgox.com/api/*. It allows placing orders, performing withdrawls, deposits, and other things. All responses are in JSON format.

There is a Ruby gem, guten-mtgox and a Perl module available for interacting with the HTTP API.

Cache

All API methods are cached for 10 seconds. Do not request results more often than that, you might be blocked by the anti-DDoS filters.

Currency Symbols

List of the currency symbols available with the API:

USD, AUD, CAD, CHF, CNY, DKK, EUR, GBP, HKD, JPY, NZD, PLN, RUB, SEK, SGD, THB

Authentication

Authentication is performed by signing each request using HMAC-SHA512. The request must contain an extra value "nonce" which must be an always incrementing numeric value. A reference implementation is provided here:

basically the base64 string should contain:
  • the binary representation of the api key id
  • binary hmac-sha512 signature
  • json data

api key looks like that: 12345678-abcd-1234-abcd-50286e649d5c

it's actually hexadecimal, it should be converted to binary

hash should then be appended (binary too) and then encode everything in base64

Warning : the API is no more accepting authentication by login/pass ( since 2012 march 1 ) , you _need_ to use an API key.

perl

IMPORTANT! This is a simplified perl module simply returning user info not a full API, it is shown simply for illustrative purposes for those wishing to developing there own modules from scratch.. or bots.. or other

IMPORTANT! This requires you compiled perl libwww with https support

#!/usr/bin/perl

use strict;
use warnings;

use Time::HiRes qw(gettimeofday);
use MIME::Base64;
use Digest::SHA qw(hmac_sha512);

use JSON;
use LWP::UserAgent;

use Data::Dumper;

my $lwp = LWP::UserAgent->new;
$lwp->agent("perl $]");

my $json = JSON->new->allow_nonref;

my $secret = '_MTGOX API SECRET GET YOURS AT https://classic.mtgox.com/support/tradeAPI';
my $key = '_MTGOX API KEY GET YOURS AT https://classic.mtgox.com/support/tradeAPI';

## user code


my $request = genReq('/1/generic/private/info');
my $res = $lwp->request($request);

# Check the outcome of the response
if ($res->is_success) {
        print Dumper($json->decode( $res->content ))."\n";
}
else { print $res->status_line, "\n"; }

exit 0;


## sub routines and helpers

sub genReq {
        my ($uri) = shift;

        my $req = HTTP::Request->new(POST => 'https://mtgox.com/api/'.$uri);
        $req->content_type('application/x-www-form-urlencoded');
        $req->content("nonce=".microtime());
        $req->header('Rest-Key' => $key);
        $req->header('Rest-Sign' => signReq($req->content(),$secret));

        return $req;
};

sub signReq {
        my ($content,$secret) = @_;
        return encode_base64(hmac_sha512($content,decode_base64($secret)));
}

sub microtime { return sprintf "%d%06d", gettimeofday; }

PHP

<?php

function mtgox_query($path, array $req = array()) {
	// API settings
	$key = '';
	$secret = '';

	// 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], 2, 6);

	// generate the POST data string
	$post_data = http_build_query($req, '', '&');

	// generate the extra headers
	$headers = array(
		'Rest-Key: '.$key,
		'Rest-Sign: '.base64_encode(hash_hmac('sha512', $post_data, base64_decode($secret), true)),
	);

	// our curl handle (initialize if required)
	static $ch = null;
	if (is_null($ch)) {
		$ch = curl_init();
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
		curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MtGox PHP client; '.php_uname('s').'; PHP/'.phpversion().')');
	}
	curl_setopt($ch, CURLOPT_URL, 'https://mtgox.com/api/'.$path);
	curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
	curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
	curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);

	// run the query
	$res = curl_exec($ch);
	if ($res === false) throw new Exception('Could not get reply: '.curl_error($ch));
	$dec = json_decode($res, true);
	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('0/info.php'));

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

Python

from urllib import urlencode
import urllib2
import time
from hashlib import sha512
from hmac import HMAC
import base64
import json
def get_nonce():
    return int(time.time()*100000)

def sign_data(secret, data):
    return base64.b64encode(str(HMAC(secret, data, sha512).digest()))
      
class requester:
    def __init__(self, auth_key, auth_secret):
        self.auth_key = auth_key
        self.auth_secret = base64.b64decode(auth_secret)
        
    def build_query(self, req={}):
        req["nonce"] = get_nonce()
        post_data = urlencode(req)
        headers = {}
        headers["User-Agent"] = "GoxApi"
        headers["Rest-Key"] = self.auth_key
        headers["Rest-Sign"] = sign_data(self.auth_secret, post_data)
        return (post_data, headers)
        
    def perform(self, path, args):
        data, headers = self.build_query(args)
        req = urllib2.Request("https://mtgox.com/api/0/"+path, data, headers)
        res = urllib2.urlopen(req, data)
        return json.load(res)

Node.js

Generic Node.js Example trading library (supports MtGox and Bitfloor): https://github.com/bitfloor/trader.nodejs

Java

basic Java Example on https://gist.github.com/2396722 hoping for many java forks and pull requests on github

XChange API : https://github.com/timmolter/XChange

Javascript Firefox addon

  • [1] firefox ticker addon

See Also