/******************************************************************************
* Copyright © 2014 - 2016 The SuperNET Developers . *
* *
* See the AUTHORS , DEVELOPER - AGREEMENT and LICENSE files at *
* the top - level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing . *
* *
* Unless otherwise agreed in a custom licensing agreement , no part of the *
* SuperNET software , including this file may be copied , modified , propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited . *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# define EXCHANGE_NAME "lakebtc"
# define UPDATE lakebtc ## _price
# define SUPPORTS lakebtc ## _supports
# define SIGNPOST lakebtc ## _signpost
# define TRADE lakebtc ## _trade
# define ORDERSTATUS lakebtc ## _orderstatus
# define CANCELORDER lakebtc ## _cancelorder
# define OPENORDERS lakebtc ## _openorders
# define TRADEHISTORY lakebtc ## _tradehistory
# define BALANCES lakebtc ## _balances
# define PARSEBALANCE lakebtc ## _parsebalance
# define WITHDRAW lakebtc ## _withdraw
# define CHECKBALANCE lakebtc ## _checkbalance
# define ALLPAIRS lakebtc ## _allpairs
# define FUNCS lakebtc ## _funcs
# define BASERELS lakebtc ## _baserels
static char * BASERELS [ ] [ 2 ] = { { " btc " , " usd " } , { " btc " , " cny " } } ;
# include "exchange_supports.h"
double UPDATE ( struct exchange_info * exchange , char * base , char * rel , struct exchange_quote * quotes , int32_t maxdepth , double commission , cJSON * argjson , int32_t invert )
{
char url [ 1024 ] ;
if ( strcmp ( rel , " USD " ) = = 0 )
sprintf ( url , " https://www.LakeBTC.com/api_v1/bcorderbook " ) ;
else if ( strcmp ( rel , " CNY " ) = = 0 )
sprintf ( url , " https://www.LakeBTC.com/api_v1/bcorderbook_cny " ) ;
else printf ( " illegal lakebtc pair.(%s/%s) \ n " ,base,rel) ;
return ( exchanges777_standardprices ( exchange , commission , base , rel , url , quotes , 0 , 0 , maxdepth , 0 , invert ) ) ;
}
cJSON * SIGNPOST ( void * * cHandlep , int32_t dotrade , char * * retstrp , struct exchange_info * exchange , char * payload , char * hdr1 , uint64_t tonce )
{
char hdr2 [ 512 ] , cmdbuf [ 1024 ] , buf64 [ 1024 ] , hdr3 [ 512 ] , dest [ 1025 ] , hdr4 [ 512 ] , * sig , * data = 0 ; cJSON * json ;
hdr2 [ 0 ] = hdr3 [ 0 ] = hdr4 [ 0 ] = 0 ;
json = 0 ;
if ( ( sig = hmac_sha1_str ( dest , exchange - > apisecret , ( int32_t ) strlen ( exchange - > apisecret ) , hdr1 ) ) ! = 0 )
{
sprintf ( cmdbuf , " %s:%s " , exchange - > userid , sig ) ;
nn_base64_encode ( ( void * ) cmdbuf , strlen ( cmdbuf ) , buf64 , sizeof ( buf64 ) ) ;
sprintf ( hdr1 , " Authorization:Basic %s " , buf64 ) ;
sprintf ( hdr2 , " Json-Rpc-Tonce: %llu " , ( long long ) tonce ) ;
if ( dotrade = = 0 )
data = exchange_would_submit ( payload , hdr1 , hdr2 , hdr3 , hdr4 ) ;
else if ( ( data = curl_post ( & exchange - > cHandle , " https://www.LakeBTC.com/api_v1 " , 0 , payload , hdr1 , hdr2 , hdr3 , hdr4 ) ) ! = 0 )
json = cJSON_Parse ( data ) ;
}
if ( retstrp ! = 0 )
* retstrp = data ;
else if ( data ! = 0 )
free ( data ) ;
return ( json ) ;
}
/* LakeBTC provides trading JSON-RPC API interface. HMAC (Hash-based Message Authentication Code) is employed as our authentication mechanisms. You need at 0.1 BTC in your account to retrieve your private key.
Besides your private key , the client needs to prepare the following attributes
tonce ( timestamp in microseconds , i . e . , unixtime × 1000000 , make sure your clock is correctly adjusted )
accesskey ( your registered email address at LakeBTC )
requestmethod ( post )
id ( JSON - RPC request id , an integer )
method ( JSON - RPC method )
params ( JSON - RPC parameters )
Concatenate the above parameters with & , in that order . Parameters can be blank . For example , $ signature =
tonce = 1389067414466757 & accesskey = foo @ bar . com & requestmethod = post & id = 123 & method = ticker & params =
Create HMAC signature with your private key by using SHA1 . $ hash =
hash_hmac ( ' sha1 ' , $ signature , $ privatetkey ) # php
Join your email and the hash signature with colon ( : ) , and sign with Base64 . $ b64 =
base64_encode ( " foo@bar.com:<hash> " ) # php YXRjQHF3amlhbi5jb206ZmEzM2UzYzg5MDZjg5MzdiYzFiYw = =
Set HTTP Header . Note tonce is the same as that in Step 2.
Json - Rpc - Tonce : 1389067414466757 # HTTP HEADER
Authorization : Basic YXRjQHF3amlhbi5jb206ZmEzM2UzYzg5MDZjg5MzdiYzFiYw = = # HTTP HEADER
POST params data in JSON format to this url :
https : //www.LakeBTC.com/api_v1
API Methods
getAccountInfo
method = getAccountInfo
params = ( i . e . , blank )
static CURL * cHandle ;
char * data , * method , buf64 [ 4096 ] , paramstr [ 128 ] , jsonbuf [ 1024 ] , base [ 64 ] , rel [ 64 ] , pairstr [ 64 ] , params [ 1024 ] , dest [ 512 ] , url [ 1024 ] , cmdbuf [ 8192 ] , * sig , hdr1 [ 4096 ] , hdr2 [ 4096 ] , buf [ 4096 ] ; cJSON * json ; uint64_t tonce , nonce , txid = 0 ;
* retstrp = 0 ;
params [ 0 ] = 0 ;
nonce = exchange_nonce ( exchange ) ;
tonce = ( nonce * 1000000 + ( ( uint64_t ) milliseconds ( ) % 1000 ) * 1000 ) ;
if ( dir = = 0 )
{
method = " getAccountInfo " ;
sprintf ( buf , " tonce=%llu&accesskey=%s&requestmethod=post&id=1&method=%s¶ms= " , ( long long ) tonce , exchange - > userid , method ) ;
sprintf ( jsonbuf , " { \" method \" : \" %s \" , \" params \" :[ \" %s \" ], \" id \" :1} " , method , params ) ;
}
else
{
if ( ( dir = flipstr_for_exchange ( exchange , pairstr , " %s_%s " , dir , & price , & volume , base , rel ) ) = = 0 )
{
printf ( " cant find baserel (%s/%s) \n " , base , rel ) ;
return ( 0 ) ;
}
method = ( dir > 0 ) ? " buyOrder " : " sellOrder " ;
touppercase ( rel ) ;
sprintf ( paramstr , " %.2f,%.4f,%s " , price , volume , rel ) ;
sprintf ( buf , " tonce=%llu&accesskey=%s&requestmethod=post&id=1&method=%s¶ms=%s " , ( long long ) tonce , exchange - > userid , method , paramstr ) ;
sprintf ( jsonbuf , " { \" method \" : \" %s \" , \" params \" :[ \" %s \" ], \" id \" :1} " , method , paramstr ) ;
}
if ( ( sig = hmac_sha1_str ( dest , exchange - > apisecret , ( int32_t ) strlen ( exchange - > apisecret ) , buf ) ) ! = 0 )
{
sprintf ( cmdbuf , " %s:%s " , exchange - > userid , sig ) ;
nn_base64_encode ( ( void * ) cmdbuf , strlen ( cmdbuf ) , buf64 , sizeof ( buf64 ) ) ;
sprintf ( url , " https://www.lakebtc.com/api_v1 " ) ;
sprintf ( hdr1 , " Authorization:Basic %s " , buf64 ) ;
sprintf ( hdr2 , " Json-Rpc-Tonce: %llu " , ( long long ) tonce ) ;
if ( ( data = curl_post ( & cHandle , url , 0 , jsonbuf , hdr1 , hdr2 , 0 , 0 ) ) ! = 0 )
{
//printf("submit cmd.(%s) [%s]\n",jsonbuf,data);
if ( ( json = cJSON_Parse ( data ) ) ! = 0 )
{
txid = j64bits ( json , " order_id " ) ;
free_json ( json ) ;
}
} else fprintf ( stderr , " submit err cmd.(%s) \n " , cmdbuf ) ;
if ( retstrp ! = 0 )
* retstrp = data ;
else if ( data ! = 0 )
free ( data ) ;
}
*/
char * PARSEBALANCE ( struct exchange_info * exchange , double * balancep , char * coinstr , cJSON * argjson )
{
char field [ 128 ] , * str , * itemstr = 0 ; cJSON * obj = 0 , * item = 0 , * prof = 0 ; double locked = 0 ;
* balancep = 0. ;
strcpy ( field , coinstr ) ;
touppercase ( field ) ;
if ( argjson ! = 0 & & ( obj = jobj ( argjson , " balance " ) ) ! = 0 & & ( item = jobj ( argjson , " locked " ) ) ! = 0 & & ( prof = jobj ( argjson , " profile " ) ) ! = 0 )
{
* balancep = jdouble ( obj , field ) ;
locked = jdouble ( item , field ) ;
obj = cJSON_CreateObject ( ) ;
jaddstr ( obj , " base " , field ) ;
jaddnum ( obj , " balance " , * balancep ) ;
jaddnum ( obj , " locked " , locked ) ;
if ( ( str = jstr ( prof , " btc_deposit_addres " ) ) ! = 0 )
jaddstr ( obj , " deposit_address " , str ) ;
itemstr = jprint ( obj , 1 ) ;
}
if ( itemstr = = 0 )
return ( clonestr ( " { \" error \" : \" cant find coin balance \" } " ) ) ;
return ( itemstr ) ;
}
cJSON * BALANCES ( struct exchange_info * exchange , cJSON * argjson )
{
char payload [ 1024 ] , jsonbuf [ 1024 ] , * method ; uint64_t tonce ;
method = " getAccountInfo " ;
tonce = ( exchange_nonce ( exchange ) * 1000000 + ( ( uint64_t ) OS_milliseconds ( ) % 1000 ) * 1000 ) ;
sprintf ( payload , " tonce=%llu&accesskey=%s&requestmethod=post&id=1&method=%s¶ms= " , ( long long ) tonce , exchange - > userid , method ) ;
sprintf ( jsonbuf , " { \" method \" : \" %s \" , \" params \" :[ \" %s \" ], \" id \" :1} " , method , " " ) ;
return ( SIGNPOST ( & exchange - > cHandle , 1 , 0 , exchange , jsonbuf , payload , tonce ) ) ;
}
# include "checkbalance.c"
uint64_t TRADE ( int32_t dotrade , char * * retstrp , struct exchange_info * exchange , char * base , char * rel , int32_t dir , double price , double volume , cJSON * argjson )
{
char payload [ 1024 ] , jsonbuf [ 1024 ] , pairstr [ 64 ] , paramstr [ 512 ] , * extra , * method ;
cJSON * json ; uint64_t tonce , txid = 0 ;
if ( ( extra = * retstrp ) ! = 0 )
* retstrp = 0 ;
tonce = ( exchange_nonce ( exchange ) * 1000000 + ( ( uint64_t ) OS_milliseconds ( ) % 1000 ) * 1000 ) ;
if ( ( dir = flipstr_for_exchange ( exchange , pairstr , " %s_%s " , dir , & price , & volume , base , rel , argjson ) ) = = 0 )
{
printf ( " cant find baserel (%s/%s) \n " , base , rel ) ;
return ( 0 ) ;
}
method = ( dir > 0 ) ? " buyOrder " : " sellOrder " ;
touppercase ( rel ) ;
sprintf ( paramstr , " %.2f,%.4f,%s " , price , volume , rel ) ;
sprintf ( payload , " tonce=%llu&accesskey=%s&requestmethod=post&id=1&method=%s¶ms=%s " , ( long long ) tonce , exchange - > userid , method , paramstr ) ;
sprintf ( jsonbuf , " { \" method \" : \" %s \" , \" params \" :[ \" %s \" ], \" id \" :1} " , method , paramstr ) ;
if ( CHECKBALANCE ( retstrp , dotrade , exchange , dir , base , rel , price , volume , argjson ) = = 0 & & ( json = SIGNPOST ( & exchange - > cHandle , dotrade , retstrp , exchange , jsonbuf , payload , tonce ) ) ! = 0 )
{
txid = j64bits ( json , " order_id " ) ;
free_json ( json ) ;
}
return ( txid ) ;
}
char * CANCELORDER ( struct exchange_info * exchange , uint64_t quoteid , cJSON * argjson )
{
char payload [ 1024 ] , jsonbuf [ 1024 ] , * method , * retstr = 0 ; cJSON * json ; uint64_t tonce ;
method = " cancelOrder " ;
tonce = ( exchange_nonce ( exchange ) * 1000000 + ( ( uint64_t ) OS_milliseconds ( ) % 1000 ) * 1000 ) ;
sprintf ( jsonbuf , " { \" method \" : \" %s \" , \" params \" :[ \" %llu \" ], \" id \" :1} " , method , ( long long ) quoteid ) ;
if ( ( json = SIGNPOST ( & exchange - > cHandle , 1 , & retstr , exchange , payload , jsonbuf , tonce ) ) ! = 0 )
{
free_json ( json ) ;
}
return ( retstr ) ; // return standardized cancelorder
}
char * OPENORDERS ( struct exchange_info * exchange , cJSON * argjson )
{
char payload [ 1024 ] , jsonbuf [ 1024 ] , * method , * retstr = 0 ; cJSON * json ; uint64_t tonce ;
method = " getOrders " ;
tonce = ( exchange_nonce ( exchange ) * 1000000 + ( ( uint64_t ) OS_milliseconds ( ) % 1000 ) * 1000 ) ;
sprintf ( jsonbuf , " { \" method \" : \" %s \" , \" params \" :[ \" %s \" ], \" id \" :1} " , method , " " ) ;
if ( ( json = SIGNPOST ( & exchange - > cHandle , 1 , & retstr , exchange , payload , jsonbuf , tonce ) ) ! = 0 )
{
free_json ( json ) ;
}
return ( retstr ) ; // return standardized open orders
}
char * TRADEHISTORY ( struct exchange_info * exchange , cJSON * argjson )
{
char payload [ 1024 ] , jsonbuf [ 1024 ] , timestr [ 64 ] , * method , * retstr = 0 ;
cJSON * json ; uint64_t tonce ; uint32_t starttime ;
method = " getTrades " ;
if ( ( starttime = juint ( argjson , " start " ) ) ! = 0 )
sprintf ( timestr , " %u " , starttime ) ;
else timestr [ 0 ] = 0 ;
tonce = ( exchange_nonce ( exchange ) * 1000000 + ( ( uint64_t ) OS_milliseconds ( ) % 1000 ) * 1000 ) ;
sprintf ( jsonbuf , " { \" method \" : \" %s \" , \" params \" :[%s], \" id \" :1} " , method , timestr ) ;
if ( ( json = SIGNPOST ( & exchange - > cHandle , 1 , & retstr , exchange , payload , jsonbuf , tonce ) ) ! = 0 )
{
free_json ( json ) ;
}
return ( retstr ) ; // return standardized tradehistory
}
char * ORDERSTATUS ( struct exchange_info * exchange , uint64_t quoteid , cJSON * argjson )
{
char * status , * retstr ;
status = OPENORDERS ( exchange , argjson ) ;
if ( ( retstr = exchange_extractorderid ( 0 , status , quoteid , " id " ) ) ! = 0 )
{
free ( status ) ;
return ( retstr ) ;
}
free ( status ) ;
return ( clonestr ( " { \" error \" : \" cant find quoteid \" } " ) ) ;
}
char * WITHDRAW ( struct exchange_info * exchange , char * base , double amount , char * destaddr , cJSON * argjson )
{
return ( clonestr ( " { \" error \" : \" lakebtc doesnt seem to have withdraw api! \" } " ) ) ;
}
struct exchange_funcs lakebtc_funcs = EXCHANGE_FUNCS ( lakebtc , EXCHANGE_NAME ) ;
# include "exchange_undefs.h"