You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

266 lines
12 KiB

/******************************************************************************
* 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&params=",(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&params=%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&params=",(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&params=%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"