Browse Source

instantdex API

release/v0.1
jl777 9 years ago
parent
commit
4e0a0026be
  1. 6
      iguana/SuperNET.h
  2. 4
      iguana/SuperNET_category.c
  3. 7
      iguana/SuperNET_hexmsg.c
  4. 4
      iguana/exchanges/bitfinex.c
  5. 4
      iguana/exchanges/bitstamp.c
  6. 4
      iguana/exchanges/bittrex.c
  7. 4
      iguana/exchanges/btc38.c
  8. 4
      iguana/exchanges/btce.c
  9. 4
      iguana/exchanges/coinbase.c
  10. 4
      iguana/exchanges/huobi.c
  11. 4
      iguana/exchanges/lakebtc.c
  12. 4
      iguana/exchanges/okcoin.c
  13. 4
      iguana/exchanges/poloniex.c
  14. 4
      iguana/exchanges/quadriga.c
  15. 19
      iguana/exchanges777.h
  16. 2
      iguana/iguana.sources
  17. 232
      iguana/iguana_exchanges.c
  18. 271
      iguana/iguana_instantdex.c
  19. 60
      iguana/iguana_tradebots.c
  20. 9
      iguana/pangea_api.c
  21. 12
      iguana/pnacl/Release/iguana.nmf
  22. BIN
      iguana/pnacl/Release/iguana.pexe
  23. 12
      includes/iguana_apideclares.h

6
iguana/SuperNET.h

@ -109,7 +109,7 @@ struct category_chain
struct category_info
{
UT_hash_handle hh; queue_t Q;
int32_t (*process_func)(struct supernet_info *myinfo,void *data,int32_t datalen,char *remoteaddr);
char *(*processfunc)(struct supernet_info *myinfo,void *data,int32_t datalen,char *remoteaddr);
struct category_chain *cchain;
bits256 hash; void *info; struct category_info *sub;
};
@ -139,8 +139,8 @@ void *category_info(bits256 categoryhash,bits256 subhash);
void *category_infoset(bits256 categoryhash,bits256 subhash,void *info);
struct category_info *category_find(bits256 categoryhash,bits256 subhash);
void SuperNET_hexmsgprocess(struct supernet_info *myinfo,cJSON *json,char *hexmsg,char *remoteaddr);
struct category_info *category_processfunc(bits256 categoryhash,int32_t (*process_func)(struct supernet_info *myinfo,void *data,int32_t datalen,char *remoteaddr));
int32_t pangea_hexmsg(struct supernet_info *myinfo,void *data,int32_t len,char *remoteaddr);
struct category_info *category_processfunc(bits256 categoryhash,char *(*process_func)(struct supernet_info *myinfo,void *data,int32_t datalen,char *remoteaddr));
char *pangea_hexmsg(struct supernet_info *myinfo,void *data,int32_t len,char *remoteaddr);
void pangea_queues(struct supernet_info *myinfo);
int32_t SuperNET_str2hex(uint8_t *hex,char *str);

4
iguana/SuperNET_category.c

@ -74,12 +74,12 @@ void *category_infoset(bits256 categoryhash,bits256 subhash,void *info)
return(0);
}
struct category_info *category_processfunc(bits256 categoryhash,int32_t (*process_func)(struct supernet_info *myinfo,void *data,int32_t datalen,char *remoteaddr))
struct category_info *category_processfunc(bits256 categoryhash,char *(*process_func)(struct supernet_info *myinfo,void *data,int32_t datalen,char *remoteaddr))
{
struct category_info *cat;
if ( (cat= category_find(categoryhash,GENESIS_PUBKEY)) != 0 )
{
cat->process_func = process_func;
cat->processfunc = process_func;
return(cat);
}
return(0);

7
iguana/SuperNET_hexmsg.c

@ -75,7 +75,7 @@ void SuperNET_hexmsgadd(struct supernet_info *myinfo,bits256 categoryhash,bits25
void SuperNET_hexmsgprocess(struct supernet_info *myinfo,cJSON *json,char *hexmsg,char *remoteaddr)
{
int32_t len,flag=0; uint8_t _buf[8192],*buf = _buf; bits256 categoryhash; struct category_info *cat;
int32_t len,flag=0; char *str; uint8_t _buf[8192],*buf = _buf; bits256 categoryhash; struct category_info *cat;
if ( hexmsg != 0 )
{
len = (int32_t)strlen(hexmsg);
@ -88,9 +88,10 @@ void SuperNET_hexmsgprocess(struct supernet_info *myinfo,cJSON *json,char *hexms
categoryhash = jbits256(json,"categoryhash");
if ( (cat= category_find(categoryhash,GENESIS_PUBKEY)) != 0 )
{
if ( cat->process_func != 0 )
if ( cat->processfunc != 0 )
{
(*cat->process_func)(myinfo,buf,len,remoteaddr);
if ( (str= (*cat->processfunc)(myinfo,buf,len,remoteaddr)) != 0 )
free(str);
flag = 1;
//printf("PROCESSFUNC\n");
}

4
iguana/exchanges/bitfinex.c

@ -27,11 +27,11 @@
#define WITHDRAW bitfinex ## _withdraw
#define CHECKBALANCE bitfinex ## _checkbalance
double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *quotes,int32_t maxdepth,cJSON *argjson)
double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *quotes,int32_t maxdepth,double commission,cJSON *argjson)
{
char url[1024];
sprintf(url,"https://api.bitfinex.com/v1/book/%s%s",base,rel);
return(exchanges777_standardprices(exchange,base,rel,url,quotes,"price","amount",maxdepth,0));
return(exchanges777_standardprices(exchange,commission,base,rel,url,quotes,"price","amount",maxdepth,0));
}
int32_t SUPPORTS(struct exchange_info *exchange,char *base,char *rel,cJSON *argjson)

4
iguana/exchanges/bitstamp.c

@ -28,11 +28,11 @@
#define EXCHANGE_AUTHURL "https://www.bitstamp.net/api"
#define CHECKBALANCE bitstamp ## _checkbalance
double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *quotes,int32_t maxdepth,cJSON *argjson)
double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *quotes,int32_t maxdepth,double commission,cJSON *argjson)
{
char url[1024];
sprintf(url,"https://www.bitstamp.net/api/order_book/");
return(exchanges777_standardprices(exchange,base,rel,url,quotes,0,0,maxdepth,0));
return(exchanges777_standardprices(exchange,commission,base,rel,url,quotes,0,0,maxdepth,0));
}
int32_t SUPPORTS(struct exchange_info *exchange,char *base,char *rel,cJSON *argjson)

4
iguana/exchanges/bittrex.c

@ -27,7 +27,7 @@
#define WITHDRAW bittrex ## _withdraw
#define CHECKBALANCE bittrex ## _checkbalance
double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *quotes,int32_t maxdepth,cJSON *argjson)
double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *quotes,int32_t maxdepth,double commission,cJSON *argjson)
{
cJSON *json,*obj; char *jsonstr,market[128],url[1024]; double hbla = 0.;
sprintf(market,"%s-%s",rel,base);
@ -38,7 +38,7 @@ double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchang
if ( (json = cJSON_Parse(jsonstr)) != 0 )
{
if ( (obj= cJSON_GetObjectItem(json,"success")) != 0 && is_cJSON_True(obj) != 0 )
hbla = exchanges777_json_orderbook(exchange,base,rel,quotes,maxdepth,json,"result","buy","sell","Rate","Quantity");
hbla = exchanges777_json_orderbook(exchange,commission,base,rel,quotes,maxdepth,json,"result","buy","sell","Rate","Quantity");
free_json(json);
}
free(jsonstr);

4
iguana/exchanges/btc38.c

@ -28,7 +28,7 @@
#define EXCHANGE_AUTHURL "http://www.btc38.com/trade/t_api"
#define CHECKBALANCE btc38 ## _checkbalance
double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *quotes,int32_t maxdepth,cJSON *argjson)
double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *quotes,int32_t maxdepth,double commission,cJSON *argjson)
{
char url[1024],lrel[16],lbase[16];
strcpy(lrel,rel), strcpy(lbase,base);
@ -36,7 +36,7 @@ double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchang
if ( strcmp(lbase,"cny") == 0 && strcmp(lrel,"btc") == 0 )
sprintf(url,"http://api.btc38.com/v1/depth.php?c=%s&mk_type=%s","btc","cny");
else sprintf(url,"http://api.btc38.com/v1/depth.php?c=%s&mk_type=%s",lbase,lrel);
return(exchanges777_standardprices(exchange,base,rel,url,quotes,0,0,maxdepth,0));
return(exchanges777_standardprices(exchange,commission,base,rel,url,quotes,0,0,maxdepth,0));
}
int32_t SUPPORTS(struct exchange_info *exchange,char *_base,char *_rel,cJSON *argjson)

4
iguana/exchanges/btce.c

@ -28,14 +28,14 @@
#define EXCHANGE_AUTHURL "https://btc-e.com/tapi"
#define CHECKBALANCE btce ## _checkbalance
double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *quotes,int32_t maxdepth,cJSON *argjson)
double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *quotes,int32_t maxdepth,double commission,cJSON *argjson)
{
char field[64],url[1024],lbase[16],lrel[16];
strcpy(lrel,rel), strcpy(lbase,base);
tolowercase(lrel), tolowercase(lbase);
sprintf(field,"%s_%s",lbase,lrel);
sprintf(url,"https://btc-e.com/api/3/depth/%s",field);
return(exchanges777_standardprices(exchange,base,rel,url,quotes,0,0,maxdepth,field));
return(exchanges777_standardprices(exchange,commission,base,rel,url,quotes,0,0,maxdepth,field));
}
int32_t SUPPORTS(struct exchange_info *exchange,char *base,char *rel,cJSON *argjson)

4
iguana/exchanges/coinbase.c

@ -28,11 +28,11 @@
#define EXCHANGE_AUTHURL "https://api.exchange.coinbase.com"
#define CHECKBALANCE coinbase ## _checkbalance
double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *quotes,int32_t maxdepth,cJSON *argjson)
double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *quotes,int32_t maxdepth,double commission,cJSON *argjson)
{
char url[1024];
sprintf(url,"https://api.exchange.coinbase.com/products/%s-%s/book?level=2",base,rel);
return(exchanges777_standardprices(exchange,base,rel,url,quotes,0,0,maxdepth,0));
return(exchanges777_standardprices(exchange,commission,base,rel,url,quotes,0,0,maxdepth,0));
}
int32_t SUPPORTS(struct exchange_info *exchange,char *base,char *rel,cJSON *argjson)

4
iguana/exchanges/huobi.c

@ -27,12 +27,12 @@
#define WITHDRAW huobi ## _withdraw
#define CHECKBALANCE huobi ## _checkbalance
double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *quotes,int32_t maxdepth,cJSON *argjson)
double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *quotes,int32_t maxdepth,double commission,cJSON *argjson)
{
char url[1024],lbase[16];
strcpy(lbase,base), tolowercase(lbase);
sprintf(url,"http://api.huobi.com/staticmarket/depth_%s_json.js ",lbase);
return(exchanges777_standardprices(exchange,base,rel,url,quotes,0,0,maxdepth,0));
return(exchanges777_standardprices(exchange,commission,base,rel,url,quotes,0,0,maxdepth,0));
}
int32_t SUPPORTS(struct exchange_info *exchange,char *base,char *rel,cJSON *argjson)

4
iguana/exchanges/lakebtc.c

@ -27,7 +27,7 @@
#define WITHDRAW lakebtc ## _withdraw
#define CHECKBALANCE lakebtc ## _checkbalance
double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *quotes,int32_t maxdepth,cJSON *argjson)
double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *quotes,int32_t maxdepth,double commission,cJSON *argjson)
{
char url[1024];
if ( strcmp(rel,"USD") == 0 )
@ -35,7 +35,7 @@ double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchang
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,base,rel,url,quotes,0,0,maxdepth,0));
return(exchanges777_standardprices(exchange,commission,base,rel,url,quotes,0,0,maxdepth,0));
}
int32_t SUPPORTS(struct exchange_info *exchange,char *base,char *rel,cJSON *argjson)

4
iguana/exchanges/okcoin.c

@ -28,7 +28,7 @@
#define EXCHANGE_AUTHURL "https://www.okcoin.com/api/v1"
#define CHECKBALANCE okcoin ## _checkbalance
double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *quotes,int32_t maxdepth,cJSON *argjson)
double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *quotes,int32_t maxdepth,double commission,cJSON *argjson)
{
char url[1024],lrel[16],lbase[16];
strcpy(lrel,rel), strcpy(lbase,base);
@ -41,7 +41,7 @@ double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchang
exit(-1);
return(0);
}
return(exchanges777_standardprices(exchange,base,rel,url,quotes,0,0,maxdepth,0));
return(exchanges777_standardprices(exchange,commission,base,rel,url,quotes,0,0,maxdepth,0));
}
int32_t SUPPORTS(struct exchange_info *exchange,char *base,char *rel,cJSON *argjson)

4
iguana/exchanges/poloniex.c

@ -28,12 +28,12 @@
#define EXCHANGE_AUTHURL "https://poloniex.com/tradingApi"
#define CHECKBALANCE poloniex ## _checkbalance
double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *quotes,int32_t maxdepth,cJSON *argjson)
double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *quotes,int32_t maxdepth,double commission,cJSON *argjson)
{
char market[128],url[1024];
sprintf(market,"%s_%s",rel,base);
sprintf(url,"https://poloniex.com/public?command=returnOrderBook&currencyPair=%s&depth=%d",market,maxdepth);
return(exchanges777_standardprices(exchange,base,rel,url,quotes,0,0,maxdepth,0));
return(exchanges777_standardprices(exchange,commission,base,rel,url,quotes,0,0,maxdepth,0));
}
int32_t SUPPORTS(struct exchange_info *exchange,char *base,char *rel,cJSON *argjson)

4
iguana/exchanges/quadriga.c

@ -27,13 +27,13 @@
#define WITHDRAW quadriga ## _withdraw
#define CHECKBALANCE quadriga ## _checkbalance
double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *quotes,int32_t maxdepth,cJSON *argjson)
double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *quotes,int32_t maxdepth,double commission,cJSON *argjson)
{
char url[1024],lrel[16],lbase[16];
strcpy(lrel,rel), strcpy(lbase,base);
tolowercase(lrel), tolowercase(lbase);
sprintf(url,"https://api.quadrigacx.com/v2/order_book?book=%s_%s",lbase,lrel);
return(exchanges777_standardprices(exchange,base,rel,url,quotes,0,0,maxdepth,0));
return(exchanges777_standardprices(exchange,commission,base,rel,url,quotes,0,0,maxdepth,0));
}
int32_t SUPPORTS(struct exchange_info *exchange,char *base,char *rel,cJSON *argjson)

19
iguana/exchanges777.h

@ -20,27 +20,17 @@
#include <curl/curl.h>
#include <curl/easy.h>
#define EXCHANGES777_MINPOLLGAP 3
#define EXCHANGES777_MAXDEPTH 200
#define EXCHANGES777_DEFAULT_TIMEOUT 30
struct exchange_info;
struct exchange_quote { double price,volume; uint64_t orderid,offerNXT; uint32_t timestamp; };
struct exchange_request
{
struct queueitem DL;
cJSON *argjson; char **retstrp;
double price,volume,hbla,lastbid,lastask;
uint64_t orderid;
int32_t dir,depth,func,numbids,numasks;
char base[16],rel[16],destaddr[64],invert,allflag,dotrade;
struct exchange_quote bidasks[];
};
struct exchange_funcs
{
char name[32];
double (*price)(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *quotes,int32_t maxdepth,cJSON *argjson);
double (*price)(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *quotes,int32_t maxdepth,double commission,cJSON *argjson);
int32_t (*supports)(struct exchange_info *exchange,char *base,char *rel,cJSON *argjson);
char *(*parsebalance)(struct exchange_info *exchange,double *balancep,char *coinstr,cJSON *argjson);
cJSON *(*balances)(struct exchange_info *exchange,cJSON *argjson);
@ -63,6 +53,11 @@ struct exchange_info
};
void *curl_post(void **cHandlep,char *url,char *userpass,char *postfields,char *hdr0,char *hdr1,char *hdr2,char *hdr3);
char *InstantDEX_hexmsg(struct supernet_info *myinfo,void *data,int32_t len,char *remoteaddr);
char *instantdex_sendcmd(struct supernet_info *myinfo,cJSON *argjson,char *cmdstr,char *ipaddr,int32_t hops);
char *exchanges777_Qprices(struct exchange_info *exchange,char *base,char *rel,int32_t maxseconds,int32_t allfields,int32_t depth,cJSON *argjson,int32_t monitor,double commission);
struct exchange_info *exchanges777_info(char *exchangestr,int32_t sleepflag,cJSON *json,char *remoteaddr);
char *exchanges777_unmonitor(struct exchange_info *exchange,char *base,char *rel);
void prices777_processprice(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *bidasks,int32_t maxdepth);
#endif

2
iguana/iguana.sources

@ -1,3 +1,3 @@
#iguana_html.c
SOURCES := SuperNET.c SuperNET_category.c SuperNET_hexmsg.c pangea_api.c pangea_bets.c cards777.c pangea_summary.c pangea_json.c pangea_hand.c poker.c ramchain_api.c iguana_tx.c iguana_wallet.c iguana_pubkeys.c iguana_recv.c iguana_bundles.c iguana_msg.c iguana_rpc.c iguana777.c iguana_chains.c iguana_peers.c iguana_accept.c iguana_bitmap.c iguana_init.c iguana_ramchain.c iguana_blocks.c iguana_json.c main.c
SOURCES := SuperNET.c SuperNET_category.c SuperNET_hexmsg.c iguana_exchanges.c iguana_tradebots.c iguana_instantdex.c pangea_api.c pangea_bets.c cards777.c pangea_summary.c pangea_json.c pangea_hand.c poker.c ramchain_api.c iguana_tx.c iguana_wallet.c iguana_pubkeys.c iguana_recv.c iguana_bundles.c iguana_msg.c iguana_rpc.c iguana777.c iguana_chains.c iguana_peers.c iguana_accept.c iguana_bitmap.c iguana_init.c iguana_ramchain.c iguana_blocks.c iguana_json.c main.c

232
iguana/iguana_exchanges.c

@ -19,6 +19,17 @@
#define EXCHANGE777_ISPENDING 2
#define EXCHANGE777_REQUEUE 3
struct exchange_request
{
struct queueitem DL;
cJSON *argjson; char **retstrp;
double price,volume,hbla,lastbid,lastask,commission;
uint64_t orderid; uint32_t timedout;
int32_t dir,depth,func,numbids,numasks;
char base[32],rel[32],destaddr[64],invert,allflag,dotrade;
struct exchange_quote bidasks[];
};
char *Exchange_names[] = { "bitfinex", "btc38", "bitstamp", "btce", "poloniex", "bittrex", "huobi", "coinbase", "okcoin", "lakebtc", "quadriga", "truefx", "ecb", "instaforex", "fxcm", "yahoo" };
struct exchange_info *Exchanges[sizeof(Exchange_names)/sizeof(*Exchange_names)];
@ -27,15 +38,20 @@ void prices777_processprice(struct exchange_info *exchange,char *base,char *rel,
}
cJSON *exchanges777_quotejson(struct exchange_quote *quote,int32_t allflag)
cJSON *exchanges777_quotejson(struct exchange_quote *quote,int32_t allflag,double pricesum,double totalvol)
{
cJSON *json; char str[65];
if ( allflag != 0 )
{
json = cJSON_CreateObject();
if ( totalvol > SMALLVAL )
pricesum /= totalvol;
jaddnum(json,"price",quote->price);
jaddnum(json,"volume",quote->volume);
jaddstr(json,"time",utc_str(str,quote->timestamp));
jaddnum(json,"aveprice",pricesum);
jaddnum(json,"cumulative",totalvol);
if ( quote->timestamp != 0 )
jaddstr(json,"time",utc_str(str,quote->timestamp));
if ( quote->orderid > 0 )
jadd64bits(json,"orderid",quote->orderid);
if ( quote->offerNXT > 0 )
@ -46,7 +62,9 @@ cJSON *exchanges777_quotejson(struct exchange_quote *quote,int32_t allflag)
char *exchanges777_orderbook_jsonstr(struct exchange_info *exchange,char *_base,char *_rel,struct exchange_quote *bidasks,int32_t maxdepth,int32_t invert,int32_t allflag)
{
struct exchange_quote *bid,*ask; cJSON *json,*bids,*asks; double highbid,lowask; uint32_t timestamp;
struct exchange_quote *bid,*ask,A,B; cJSON *json,*bids,*asks;
double highbid,lowask,price,volume,bidsum,asksum,bidvol,askvol;
uint32_t timestamp;
int32_t slot,numbids,numasks,enda,endb; char baserel[64],base[64],rel[64],str[65];
if ( invert == 0 )
{
@ -60,20 +78,54 @@ char *exchanges777_orderbook_jsonstr(struct exchange_info *exchange,char *_base,
}
json = cJSON_CreateObject(), bids = cJSON_CreateArray(), asks = cJSON_CreateArray();
highbid = lowask = 0.;
for (slot=numbids=numasks=enda=endb=0; slot<maxdepth; slot++)
bidsum = asksum = bidvol = askvol = 0.;
for (slot=numbids=numasks=enda=endb=0; slot<maxdepth && enda+endb!=2; slot++)
{
bid = &bidasks[slot << 1], ask = &bidasks[(slot << 1) + 1];
if ( endb == 0 && bid->price > SMALLVAL )
if ( endb == 0 && (price= bid->price) > SMALLVAL )
{
jaddi(bids,exchanges777_quotejson(bid,allflag));
if ( numbids++ == 0 )
highbid = bid->price;
volume = bid->volume;
if ( invert == 0 )
{
bidsum += (price * volume), bidvol += volume;
//printf("bid %f %f vol %f, cumulative %f %f\n",bid->price,price,volume,bidsum/bidvol,bidvol);
jaddi(bids,exchanges777_quotejson(bid,allflag,bidsum,bidvol));
if ( numbids++ == 0 )
highbid = price;
}
else
{
volume *= price;
price = 1. / price;
A = *bid;
A.price = price, A.volume = volume;
asksum += (price * volume), askvol += volume;
jaddi(asks,exchanges777_quotejson(&A,allflag,asksum,askvol));
if ( numasks++ == 0 )
lowask = price;
}
} else endb = 1;
if ( enda == 0 && ask->price > SMALLVAL )
if ( enda == 0 && (price= ask->price) > SMALLVAL )
{
jaddi(asks,exchanges777_quotejson(ask,allflag));
if ( numasks++ == 0 )
lowask = ask->price;
volume = ask->volume;
if ( invert == 0 )
{
asksum += (price * volume), askvol += volume;
jaddi(asks,exchanges777_quotejson(ask,allflag,asksum,askvol));
if ( numasks++ == 0 )
lowask = price;
}
else
{
volume *= price;
price = 1. / price;
B = *ask;
B.price = price, B.volume = volume;
bidsum += (price * volume), bidvol += volume;
jaddi(bids,exchanges777_quotejson(&B,allflag,bidsum,bidvol));
if ( numbids++ == 0 )
highbid = price;
}
} else enda = 1;
}
jaddstr(json,"exchange",exchange->name);
@ -108,7 +160,7 @@ char *exchanges777_orderbook_jsonstr(struct exchange_info *exchange,char *_base,
return(jprint(json,1));
}
void exchanges777_json_quotes(struct exchange_info *exchange,char *base,char *rel,double *lastbidp,double *lastaskp,double *hblap,struct exchange_quote *bidasks,cJSON *bids,cJSON *asks,int32_t maxdepth,char *pricefield,char *volfield,uint32_t reftimestamp)
void exchanges777_json_quotes(struct exchange_info *exchange,double commission,char *base,char *rel,double *lastbidp,double *lastaskp,double *hblap,struct exchange_quote *bidasks,cJSON *bids,cJSON *asks,int32_t maxdepth,char *pricefield,char *volfield,uint32_t reftimestamp)
{
int32_t i,slot,n=0,m=0,dir,bidask,slot_ba,numitems,numbids,numasks; uint64_t orderid,offerNXT;
cJSON *item; struct exchange_quote *quote; uint32_t timestamp; double price,volume,hbla = 0.;
@ -128,7 +180,7 @@ void exchanges777_json_quotes(struct exchange_info *exchange,char *base,char *re
if ( maxdepth != 0 && m > maxdepth )
m = maxdepth;
}
for (i=0; i<n||i<m; i++)
for (i=0; i<n || i<m; i++)
{
for (bidask=0; bidask<2; bidask++)
{
@ -157,15 +209,15 @@ void exchanges777_json_quotes(struct exchange_info *exchange,char *base,char *re
else continue;
if ( price > SMALLVAL && volume > SMALLVAL )
{
if ( exchange->commission != 0. )
if ( commission != 0. )
{
//printf("price %f fee %f -> ",price,prices->commission * price);
if ( bidask == 0 )
price -= exchange->commission * price;
else price += exchange->commission * price;
price -= commission * price;
else price += commission * price;
//printf("%f\n",price);
}
quote = (bidask == 0) ? &bidasks[numbids<<1] : &bidasks[(numbids<<1) + 1];
quote = (bidask == 0) ? &bidasks[numbids<<1] : &bidasks[(numasks<<1) + 1];
quote->price = price, quote->volume = volume, quote->timestamp = timestamp, quote->orderid = orderid, quote->offerNXT = offerNXT;
if ( bidask == 0 )
slot_ba = (numbids++ << 1);
@ -179,7 +231,7 @@ void exchanges777_json_quotes(struct exchange_info *exchange,char *base,char *re
hbla = price;
else hbla = 0.5 * (hbla + price);
}
printf("%d,%d: %-8s %s %5s/%-5s %13.8f vol %13.8f | invert %13.8f vol %13.8f | timestamp.%u\n",numbids,numasks,exchange->name,dir>0?"bid":"ask",base,rel,price,volume,1./price,volume*price,timestamp);
printf("%d,%d: %-8s %s %5s/%-5s %13.8f vol %13.8f | i %13.8f vol %13.8f | t.%u\n",numbids,numasks,exchange->name,dir>0?"bid":"ask",base,rel,price,volume,1./price,volume*price,timestamp);
}
}
}
@ -187,7 +239,7 @@ void exchanges777_json_quotes(struct exchange_info *exchange,char *base,char *re
*hblap = hbla;
}
double exchanges777_json_orderbook(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *bidasks,int32_t maxdepth,cJSON *json,char *resultfield,char *bidfield,char *askfield,char *pricefield,char *volfield)
double exchanges777_json_orderbook(struct exchange_info *exchange,double commission,char *base,char *rel,struct exchange_quote *bidasks,int32_t maxdepth,cJSON *json,char *resultfield,char *bidfield,char *askfield,char *pricefield,char *volfield)
{
cJSON *obj = 0,*bidobj=0,*askobj=0; double lastbid,lastask,hbla = 0.; int32_t numasks=0,numbids=0;
if ( resultfield == 0 )
@ -200,13 +252,13 @@ double exchanges777_json_orderbook(struct exchange_info *exchange,char *base,cha
askobj = jarray(&numasks,obj,askfield);
if ( bidobj != 0 || askobj != 0 )
{
exchanges777_json_quotes(exchange,base,rel,&lastbid,&lastask,&hbla,bidasks,bidobj,askobj,maxdepth,pricefield,volfield,0);
exchanges777_json_quotes(exchange,commission,base,rel,&lastbid,&lastask,&hbla,bidasks,bidobj,askobj,maxdepth,pricefield,volfield,0);
}
}
return(hbla);
}
double exchanges777_standardprices(struct exchange_info *exchange,char *base,char *rel,char *url,struct exchange_quote *quotes,char *price,char *volume,int32_t maxdepth,char *field)
double exchanges777_standardprices(struct exchange_info *exchange,double commission,char *base,char *rel,char *url,struct exchange_quote *quotes,char *price,char *volume,int32_t maxdepth,char *field)
{
char *jsonstr; cJSON *json; double hbla = 0.;
if ( (jsonstr= issue_curl(url)) != 0 )
@ -215,7 +267,7 @@ double exchanges777_standardprices(struct exchange_info *exchange,char *base,cha
printf("(%s) -> (%s)\n",url,jsonstr);
if ( (json= cJSON_Parse(jsonstr)) != 0 )
{
hbla = exchanges777_json_orderbook(exchange,base,rel,quotes,maxdepth,json,field,"bids","asks",price,volume);
hbla = exchanges777_json_orderbook(exchange,commission,base,rel,quotes,maxdepth,json,field,"bids","asks",price,volume);
free_json(json);
}
free(jsonstr);
@ -288,7 +340,7 @@ int32_t flipstr_for_exchange(struct exchange_info *exchange,char *pairstr,char *
int32_t cny_flip(char *market,char *coinname,char *base,char *rel,int32_t dir,double *pricep,double *volumep)
{
char pairstr[512],lbase[16],lrel[16],*refstr=0;
char pairstr[512],lbase[32],lrel[32],*refstr=0;
strcpy(lbase,base), tolowercase(lbase), strcpy(lrel,rel), tolowercase(lrel);
if ( strcmp(lbase,"cny") == 0 || strcmp(lrel,"cny") == 0 )
{
@ -339,7 +391,7 @@ char *exchange_extractorderid(int32_t historyflag,char *status,uint64_t quoteid,
int32_t baserel_polarity(char *pairs[][2],int32_t n,char *_base,char *_rel)
{
int32_t i; char base[16],rel[16];
int32_t i; char base[32],rel[32];
strcpy(base,_base), tolowercase(base);
strcpy(rel,_rel), tolowercase(rel);
for (i=0; i<n; i++)
@ -374,7 +426,7 @@ char *exchanges777_process(struct exchange_info *exchange,int32_t *retvalp,struc
{
case 'Q':
memset(req->bidasks,0,req->depth * sizeof(*req->bidasks) * 2);
(*exchange->issue.price)(exchange,req->base,req->rel,req->bidasks,req->depth,req->argjson);
(*exchange->issue.price)(exchange,req->base,req->rel,req->bidasks,req->depth,req->commission,req->argjson);
retstr = exchanges777_orderbook_jsonstr(exchange,req->base,req->rel,req->bidasks,req->depth,req->invert,req->allflag);
break;
case 'S':
@ -429,15 +481,17 @@ void exchanges777_loop(void *ptr)
retstr = 0;
if ( (req= queue_dequeue(&exchange->requestQ,0)) != 0 )
{
printf("dequeued %s.%c\n",exchange->name,req->func);
//printf("dequeued %s.%c\n",exchange->name,req->func);
retstr = exchanges777_process(exchange,&retval,req);
if ( retval == EXCHANGE777_DONE )
{
if ( retstr != 0 )
{
if ( req->retstrp != 0 )
if ( req->retstrp != 0 && req->timedout == 0 )
*req->retstrp = retstr;
else free(retstr);
if ( req->timedout != 0 )
printf("timedout.%u req finally finished at %u\n",req->timedout,(uint32_t)time(NULL));
}
free(req);
flag++;
@ -459,12 +513,15 @@ void exchanges777_loop(void *ptr)
}
if ( flag == 0 && time(NULL) > exchange->lastpoll+exchange->pollgap )
{
printf("check %s pricesQ\n",exchange->name);
if ( (req= queue_dequeue(&exchange->pricesQ,0)) != 0 )
{
exchange->lastpoll = (uint32_t)time(NULL);
req->hbla = (*exchange->issue.price)(exchange,req->base,req->rel,req->bidasks,req->depth,req->argjson);
prices777_processprice(exchange,req->base,req->rel,req->bidasks,req->depth);
if ( req->base[0] != 0 )
{
//printf("check %s pricesQ (%s %s)\n",exchange->name,req->base,req->rel);
exchange->lastpoll = (uint32_t)time(NULL);
req->hbla = (*exchange->issue.price)(exchange,req->base,req->rel,req->bidasks,req->depth,req->commission,req->argjson);
prices777_processprice(exchange,req->base,req->rel,req->bidasks,req->depth);
}
queue_enqueue("pricesQ",&exchange->pricesQ,&req->DL,0);
}
}
@ -473,6 +530,25 @@ void exchanges777_loop(void *ptr)
}
}
char *exchanges777_unmonitor(struct exchange_info *exchange,char *base,char *rel)
{
struct exchange_request PAD,*req; char *retstr = 0;
memset(&PAD,0,sizeof(PAD));
queue_enqueue("pricesQ",&exchange->pricesQ,&PAD.DL,0);
while ( (req= queue_dequeue(&exchange->pricesQ,0)) != 0 && req != &PAD )
{
if ( strcmp(base,req->base) == 0 || strcmp(rel,req->rel) == 0 )
{
printf("unmonitor.%s (%s %s)\n",exchange->name,base,rel);
free(req);
retstr = clonestr("{\"result\":\"unmonitored\"}");
} else queue_enqueue("pricesQ",&exchange->pricesQ,&req->DL,0);
}
if ( retstr == 0 )
retstr = clonestr("{\"error\":\"cant find base/rel pair to unmonitor\"}");
return(retstr);
}
char *exchanges777_submit(struct exchange_info *exchange,char **retstrp,struct exchange_request *req,int32_t func,int32_t maxseconds)
{
int32_t i;
@ -481,36 +557,54 @@ char *exchanges777_submit(struct exchange_info *exchange,char **retstrp,struct e
maxseconds = EXCHANGES777_DEFAULT_TIMEOUT;
queue_enqueue("exchangeQ",&exchange->requestQ,&req->DL,0);
for (i=0; i<maxseconds; i++)
{
if ( *retstrp != 0 )
return(*retstrp);
sleep(1);
}
req->timedout = (uint32_t)time(NULL);
return(clonestr("{\"error\":\"request timed out\"}"));
}
char *exchanges777_Qtrade(struct exchange_info *exchange,char *base,char *rel,int32_t maxseconds,int32_t dotrade,int32_t dir,double price,double volume,cJSON *argjson)
{
struct exchange_request *req; char *retstr = 0;
if ( base[0] == 0 || rel[0] == 0 )
struct exchange_request *req; int32_t polarity; char *retstr = 0;
if ( base[0] == 0 || rel[0] == 0 || (polarity= (*exchange->issue.supports)(exchange,base,rel,argjson)) == 0 || price < SMALLVAL || volume < SMALLVAL )
return(clonestr("{\"error\":\"invalid base or rel\"}"));
req = calloc(1,sizeof(*req));
req->argjson = argjson; req->retstrp = &retstr;
safecopy(req->base,base,sizeof(req->base));
safecopy(req->rel,rel,sizeof(req->rel));
req->price = price, req->volume = volume;
req->dir = dir, req->dotrade = dotrade;
if ( polarity < 0 )
dir *= -1, volume *= price, price = 1. / price;
req->price = price, req->volume = volume, req->dir = dir;
req->dotrade = dotrade;
return(exchanges777_submit(exchange,&retstr,req,'T',maxseconds));
}
char *exchanges777_Qprices(struct exchange_info *exchange,char *base,char *rel,int32_t maxseconds,int32_t allfields,int32_t invert,int32_t depth,cJSON *argjson)
char *exchanges777_Qprices(struct exchange_info *exchange,char *base,char *rel,int32_t maxseconds,int32_t allfields,int32_t depth,cJSON *argjson,int32_t monitor,double commission)
{
struct exchange_request *req; char *retstr = 0;
if ( base[0] == 0 || rel[0] == 0 )
struct exchange_request *req; char *retstr = 0; int32_t polarity;
if ( base[0] == 0 || rel[0] == 0 || (polarity= (*exchange->issue.supports)(exchange,base,rel,argjson)) == 0 )
return(clonestr("{\"error\":\"invalid base or rel\"}"));
if ( depth <= 0 )
depth = 1;
req = calloc(1,sizeof(*req) + sizeof(*req->bidasks)*depth*2);
req->argjson = argjson; req->retstrp = &retstr;
safecopy(req->base,base,sizeof(req->base));
safecopy(req->rel,rel,sizeof(req->rel));
req->depth = depth, req->allflag = allfields, req->invert = invert;
return(exchanges777_submit(exchange,&retstr,req,'Q',maxseconds));
req->depth = depth, req->allflag = allfields;
req->invert = (polarity < 0);
if ( (req->commission= commission) == 0. )
req->commission = exchange->commission;
if ( monitor == 0 )
return(exchanges777_submit(exchange,&retstr,req,'Q',maxseconds));
else
{
req->func = 'Q';
queue_enqueue("pricesQ",&exchange->pricesQ,&req->DL,0);
return(clonestr("{\"result\":\"start monitoring\"}"));
}
}
char *exchanges777_Qrequest(struct exchange_info *exchange,int32_t func,char *base,char *rel,int32_t maxseconds,uint64_t orderid,char *destaddr,double amount,cJSON *argjson)
@ -578,7 +672,8 @@ struct exchange_info *exchange_create(char *exchangestr,cJSON *argjson)
iguana_initQ(&exchange->pendingQ[1],"pending1");
exchange->exchangeid = exchangeid;
safecopy(exchange->name,exchangestr,sizeof(exchange->name));
exchange->pollgap = juint(argjson,"pollgap");
if ( (exchange->pollgap= juint(argjson,"pollgap")) < EXCHANGES777_MINPOLLGAP )
exchange->pollgap = EXCHANGES777_MINPOLLGAP;
if ( (key= jstr(argjson,"apikey")) != 0 || (key= jstr(argjson,"key")) != 0 )
safecopy(exchange->apikey,key,sizeof(exchange->apikey));
if ( (secret= jstr(argjson,"apisecret")) != 0 || (secret= jstr(argjson,"secret")) != 0 )
@ -594,9 +689,11 @@ struct exchange_info *exchange_create(char *exchangestr,cJSON *argjson)
return(exchange);
}
struct exchange_info *exchanges777_info(char *exchangestr,int32_t sleepflag,cJSON *json)
struct exchange_info *exchanges777_info(char *exchangestr,int32_t sleepflag,cJSON *json,char *remoteaddr)
{
struct exchange_info *exchange;
if ( remoteaddr != 0 )
return(0);
if ( (exchange= exchanges777_find(exchangestr)) == 0 )
{
if ( (exchange= exchange_create(exchangestr,json)) != 0 )
@ -611,9 +708,17 @@ struct exchange_info *exchanges777_info(char *exchangestr,int32_t sleepflag,cJSO
void exchanges777_init(int32_t sleepflag)
{
int32_t i; cJSON *argjson = cJSON_CreateObject();
for (i=0; i<sizeof(Exchange_names)/sizeof(*Exchange_names); i++)
exchanges777_info(Exchange_names[i],sleepflag,argjson);
int32_t i; cJSON *argjson; bits256 instantdexhash;
if ( 0 )
{
argjson = cJSON_CreateObject();
for (i=0; i<sizeof(Exchange_names)/sizeof(*Exchange_names); i++)
exchanges777_info(Exchange_names[i],sleepflag,argjson,0);
free_json(argjson);
}
instantdexhash = calc_categoryhashes(0,"InstantDEX",0);
category_subscribe(SuperNET_MYINFO(0),instantdexhash,GENESIS_PUBKEY);
category_processfunc(instantdexhash,InstantDEX_hexmsg);
}
#include "../includes/iguana_apidefs.h"
@ -621,15 +726,15 @@ void exchanges777_init(int32_t sleepflag)
THREE_STRINGS_AND_THREE_INTS(InstantDEX,orderbook,exchange,base,rel,depth,allfields,invert)
{
struct exchange_info *ptr;
if ( (ptr= exchanges777_info(exchange,1,json)) != 0 )
return(exchanges777_Qprices(ptr,base,rel,juint(json,"maxseconds"),allfields,invert,depth,json));
if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 )
return(exchanges777_Qprices(ptr,base,rel,juint(json,"maxseconds"),allfields,depth,json,0,ptr->commission));
else return(clonestr("{\"error\":\"cant find or create exchange\"}"));
}
THREE_STRINGS_AND_THREE_DOUBLES(InstantDEX,buy,exchange,base,rel,price,volume,dotrade)
{
struct exchange_info *ptr;
if ( (ptr= exchanges777_info(exchange,1,json)) != 0 )
if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 )
return(exchanges777_Qtrade(ptr,base,rel,juint(json,"maxseconds"),dotrade,1,price,volume,json));
else return(clonestr("{\"error\":\"cant find or create exchange\"}"));
}
@ -637,7 +742,7 @@ THREE_STRINGS_AND_THREE_DOUBLES(InstantDEX,buy,exchange,base,rel,price,volume,do
THREE_STRINGS_AND_THREE_DOUBLES(InstantDEX,sell,exchange,base,rel,price,volume,dotrade)
{
struct exchange_info *ptr;
if ( (ptr= exchanges777_info(exchange,1,json)) != 0 )
if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 )
return(exchanges777_Qtrade(ptr,base,rel,juint(json,"maxseconds"),dotrade,-1,price,volume,json));
else return(clonestr("{\"error\":\"cant find or create exchange\"}"));
}
@ -645,7 +750,7 @@ THREE_STRINGS_AND_THREE_DOUBLES(InstantDEX,sell,exchange,base,rel,price,volume,d
THREE_STRINGS_AND_DOUBLE(InstantDEX,withdraw,exchange,base,destaddr,amount)
{
struct exchange_info *ptr;
if ( (ptr= exchanges777_info(exchange,1,json)) != 0 )
if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 )
return(exchanges777_Qrequest(ptr,'W',base,0,juint(json,"maxseconds"),0,destaddr,amount,json));
else return(clonestr("{\"error\":\"cant find or create exchange\"}"));
}
@ -653,7 +758,7 @@ THREE_STRINGS_AND_DOUBLE(InstantDEX,withdraw,exchange,base,destaddr,amount)
THREE_STRINGS(InstantDEX,supports,exchange,base,rel)
{
struct exchange_info *ptr;
if ( (ptr= exchanges777_info(exchange,1,json)) != 0 )
if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 )
return(exchanges777_Qrequest(ptr,'S',base,rel,juint(json,"maxseconds"),0,0,0,json));
else return(clonestr("{\"error\":\"cant find or create exchange\"}"));
}
@ -661,7 +766,7 @@ THREE_STRINGS(InstantDEX,supports,exchange,base,rel)
TWO_STRINGS(InstantDEX,balance,exchange,base)
{
struct exchange_info *ptr;
if ( (ptr= exchanges777_info(exchange,1,json)) != 0 )
if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 )
return(exchanges777_Qrequest(ptr,'B',base,0,juint(json,"maxseconds"),0,0,0,json));
else return(clonestr("{\"error\":\"cant find or create exchange\"}"));
}
@ -669,7 +774,7 @@ TWO_STRINGS(InstantDEX,balance,exchange,base)
TWO_STRINGS(InstantDEX,orderstatus,exchange,orderid)
{
struct exchange_info *ptr;
if ( (ptr= exchanges777_info(exchange,1,json)) != 0 )
if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 )
return(exchanges777_Qrequest(ptr,'P',0,0,juint(json,"maxseconds"),calc_nxt64bits(orderid),0,0,json));
else return(clonestr("{\"error\":\"cant find or create exchange\"}"));
}
@ -677,7 +782,7 @@ TWO_STRINGS(InstantDEX,orderstatus,exchange,orderid)
TWO_STRINGS(InstantDEX,cancelorder,exchange,orderid)
{
struct exchange_info *ptr;
if ( (ptr= exchanges777_info(exchange,1,json)) != 0 )
if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 )
return(exchanges777_Qrequest(ptr,'C',0,0,juint(json,"maxseconds"),calc_nxt64bits(orderid),0,0,json));
else return(clonestr("{\"error\":\"cant find or create exchange\"}"));
}
@ -685,7 +790,7 @@ TWO_STRINGS(InstantDEX,cancelorder,exchange,orderid)
STRING_ARG(InstantDEX,openorders,exchange)
{
struct exchange_info *ptr;
if ( (ptr= exchanges777_info(exchange,1,json)) != 0 )
if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 )
return(exchanges777_Qrequest(ptr,'O',0,0,juint(json,"maxseconds"),0,0,0,json));
else return(clonestr("{\"error\":\"cant find or create exchange\"}"));
}
@ -693,7 +798,7 @@ STRING_ARG(InstantDEX,openorders,exchange)
STRING_ARG(InstantDEX,tradehistory,exchange)
{
struct exchange_info *ptr;
if ( (ptr= exchanges777_info(exchange,1,json)) != 0 )
if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 )
return(exchanges777_Qrequest(ptr,'H',0,0,juint(json,"maxseconds"),0,0,0,json));
else return(clonestr("{\"error\":\"cant find or create exchange\"}"));
}
@ -701,7 +806,7 @@ STRING_ARG(InstantDEX,tradehistory,exchange)
THREE_STRINGS(InstantDEX,apikeypair,exchange,apikey,apisecret)
{
struct exchange_info *ptr;
if ( (ptr= exchanges777_info(exchange,1,json)) != 0 )
if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 )
{
if ( apikey != 0 && apikey[0] != 0 && apisecret != 0 && apisecret[0] != 0 )
{
@ -715,7 +820,7 @@ THREE_STRINGS(InstantDEX,apikeypair,exchange,apikey,apisecret)
THREE_STRINGS(InstantDEX,setuserid,exchange,userid,tradepassword)
{
struct exchange_info *ptr;
if ( (ptr= exchanges777_info(exchange,1,json)) != 0 )
if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 )
{
safecopy(ptr->userid,userid,sizeof(ptr->userid));
safecopy(ptr->tradepassword,tradepassword,sizeof(ptr->tradepassword));
@ -723,4 +828,13 @@ THREE_STRINGS(InstantDEX,setuserid,exchange,userid,tradepassword)
} else return(clonestr("{\"error\":\"cant find or create exchange\"}"));
}
STRING_AND_INT(InstantDEX,pollgap,exchange,pollgap)
{
struct exchange_info *ptr;
if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 )
{
ptr->pollgap = pollgap;
return(clonestr("{\"result\":\"set pollgap\"}"));
} else return(clonestr("{\"error\":\"cant find or create exchange\"}"));
}
#include "../includes/iguana_apiundefs.h"

271
iguana/iguana_instantdex.c

@ -0,0 +1,271 @@
/******************************************************************************
* 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. *
* *
******************************************************************************/
#include "exchanges777.h"
struct instantdex_msghdr
{
struct acct777_sig sig __attribute__((packed));
char cmd[8];
uint8_t serialized[];
} __attribute__((packed));
int32_t instantdex_rwdata(int32_t rwflag,uint64_t cmdbits,uint8_t *data,int32_t datalen)
{
// need to inplace serialize/deserialize here
return(datalen);
}
struct instantdex_msghdr *instantdex_msgcreate(struct supernet_info *myinfo,struct instantdex_msghdr *msg,int32_t datalen)
{
bits256 otherpubkey; uint64_t signerbits; uint32_t timestamp; uint8_t buf[sizeof(msg->sig)],*data;
memset(&msg->sig,0,sizeof(msg->sig));
datalen += (int32_t)(sizeof(*msg) - sizeof(msg->sig));
data = (void *)((long)msg + sizeof(msg->sig));
otherpubkey = acct777_msgpubkey(data,datalen);
timestamp = (uint32_t)time(NULL);
acct777_sign(&msg->sig,myinfo->privkey,otherpubkey,timestamp,data,datalen);
if ( (signerbits= acct777_validate(&msg->sig,acct777_msgprivkey(data,datalen),msg->sig.pubkey)) != 0 )
{
int32_t i; char str[65],str2[65];
for (i=0; i<datalen; i++)
printf("%02x",data[i]);
printf(">>>>>>>>>>>>>>>> validated [%ld] len.%d (%s + %s)\n",(long)data-(long)msg,datalen,bits256_str(str,acct777_msgprivkey(data,datalen)),bits256_str(str2,msg->sig.pubkey));
memset(buf,0,sizeof(buf));
acct777_rwsig(1,buf,&msg->sig);
memcpy(&msg->sig,buf,sizeof(buf));
return(msg);
} else printf("error validating instantdex msg\n");
return(0);
}
char *instantdex_sendcmd(struct supernet_info *myinfo,cJSON *argjson,char *cmdstr,char *ipaddr,int32_t hops)
{
char *reqstr,hexstr[8192]; uint8_t _msg[4096]; uint64_t nxt64bits; int32_t datalen;
bits256 instantdexhash; struct instantdex_msghdr *msg;
msg = (struct instantdex_msghdr *)_msg;
memset(msg,0,sizeof(*msg));
instantdexhash = calc_categoryhashes(0,"InstantDEX",0);
category_subscribe(myinfo,instantdexhash,GENESIS_PUBKEY);
if ( ipaddr == 0 || ipaddr[0] == 0 || strncmp(ipaddr,"127.0.0.1",strlen("127.0.0.1")) == 0 )
return(clonestr("{\"error\":\"no ipaddr, need to send your ipaddr for now\"}"));
jaddstr(argjson,"cmd",cmdstr);
jaddstr(argjson,"agent","SuperNET");
jaddstr(argjson,"method","DHT");
jaddstr(argjson,"traderip",ipaddr);
jaddbits256(argjson,"categoryhash",instantdexhash);
jaddbits256(argjson,"traderpub",myinfo->myaddr.persistent);
nxt64bits = acct777_nxt64bits(myinfo->myaddr.persistent);
reqstr = jprint(argjson,1);
datalen = (int32_t)(strlen(reqstr) + 1);
memcpy(msg->serialized,reqstr,datalen);
free(reqstr);
if ( (datalen+sizeof(*msg))*2+1 < sizeof(hexstr) && instantdex_msgcreate(myinfo,msg,datalen) != 0 )
{
printf("instantdex send.(%s)\n",cmdstr);
init_hexbytes_noT(hexstr,(uint8_t *)msg,msg->sig.allocsize);
return(SuperNET_categorymulticast(myinfo,0,instantdexhash,GENESIS_PUBKEY,hexstr,0,hops,1));
}
else
{
printf("cant msgcreate\n");
return(clonestr("{\"error\":\"couldnt create instantdex message\"}"));
}
}
char *instantdex_reqprice(struct supernet_info *myinfo,struct instantdex_msghdr *msg,cJSON *argjson,char *remoteaddr,uint64_t signerbits,uint8_t *data,int32_t datalen)
{
if ( argjson != 0 )
{
return(clonestr("{\"result\":\"reqprice response not sent\"}"));
return(clonestr("{\"result\":\"reqprice response sent\"}"));
} else return(clonestr("{\"error\":\"reqprice needs argjson\"}"));
}
char *instantdex_proposal(struct supernet_info *myinfo,struct instantdex_msghdr *msg,cJSON *argjson,char *remoteaddr,uint64_t signerbits,uint8_t *data,int32_t datalen)
{
if ( argjson != 0 )
{
return(clonestr("{\"result\":\"proposal ignored\"}"));
return(clonestr("{\"result\":\"proposal accepted\"}"));
} else return(clonestr("{\"error\":\"response needs argjson\"}"));
}
char *instantdex_accepted(struct supernet_info *myinfo,struct instantdex_msghdr *msg,cJSON *argjson,char *remoteaddr,uint64_t signerbits,uint8_t *data,int32_t datalen)
{
if ( argjson != 0 )
{
return(clonestr("{\"result\":\"proposal was accepted, confirmation sent\"}"));
} else return(clonestr("{\"error\":\"response needs argjson\"}"));
}
char *instantdex_confirmed(struct supernet_info *myinfo,struct instantdex_msghdr *msg,cJSON *argjson,char *remoteaddr,uint64_t signerbits,uint8_t *data,int32_t datalen)
{
if ( argjson != 0 )
{
return(clonestr("{\"result\":\"proposal was confirmed\"}"));
} else return(clonestr("{\"error\":\"response needs argjson\"}"));
}
char *instantdex_parse(struct supernet_info *myinfo,struct instantdex_msghdr *msg,cJSON *argjson,char *remoteaddr,uint64_t signerbits,uint8_t *data,int32_t datalen)
{
static struct { char *cmdstr; char *(*func)(struct supernet_info *myinfo,struct instantdex_msghdr *msg,cJSON *argjson,char *remoteaddr,uint64_t signerbits,uint8_t *data,int32_t datalen); uint64_t cmdbits; } cmds[] =
{
{ "reqprice", instantdex_reqprice }, { "proposal", instantdex_proposal },
{ "accepted", instantdex_accepted }, { "confirmed", instantdex_confirmed },
};
char *retstr = 0; int32_t i; uint64_t cmdbits;
if ( cmds[0].cmdbits == 0 )
{
for (i=0; i<sizeof(cmds)/sizeof(*cmds); i++)
cmds[i].cmdbits = stringbits(cmds[i].cmdstr);
}
cmdbits = stringbits(msg->cmd);
for (i=0; i<sizeof(cmds)/sizeof(*cmds); i++)
{
if ( cmds[i].cmdbits == cmdbits )
{
retstr = (*cmds[i].func)(myinfo,msg,argjson,remoteaddr,signerbits,data,datalen);
break;
}
}
return(retstr);
}
char *InstantDEX_hexmsg(struct supernet_info *myinfo,void *ptr,int32_t len,char *remoteaddr)
{
struct instantdex_msghdr *msg = ptr; cJSON *argjson; int32_t n,datalen,newlen,flag = 0;
uint64_t signerbits; uint8_t *data; uint8_t tmp[sizeof(msg->sig)]; char *retstr = 0;
acct777_rwsig(0,(void *)&msg->sig,(void *)tmp);
memcpy(&msg->sig,tmp,sizeof(msg->sig));
datalen = len - (int32_t)sizeof(msg->sig);
data = (void *)((long)msg + sizeof(msg->sig));
if ( remoteaddr != 0 && remoteaddr[0] == 0 && strcmp("127.0.0.1",remoteaddr) == 0 && ((uint8_t *)msg)[len-1] == 0 && (argjson= cJSON_Parse((char *)msg)) != 0 )
{
printf("instantdex_hexmsg RESULT.(%s)\n",jprint(argjson,0));
retstr = instantdex_parse(myinfo,msg,argjson,0,myinfo->myaddr.nxt64bits,0,0);
free_json(argjson);
return(retstr);
}
//printf("msg.%p len.%d data.%p datalen.%d crc.%u %s\n",msg,len,data,datalen,calc_crc32(0,(void *)msg,len),bits256_str(str,msg->sig.pubkey));
//return(0);
else if ( (signerbits= acct777_validate(&msg->sig,acct777_msgprivkey(data,datalen),msg->sig.pubkey)) != 0 )
{
flag++;
printf("<<<<<<<<<<<<< sigsize.%ld VALIDATED [%ld] len.%d t%u allocsize.%d (%s) [%d]\n",sizeof(msg->sig),(long)data-(long)msg,datalen,msg->sig.timestamp,msg->sig.allocsize,(char *)msg->serialized,data[datalen-1]);
if ( data[datalen-1] == 0 && (argjson= cJSON_Parse((char *)msg->serialized)) != 0 )
retstr = instantdex_parse(myinfo,msg,argjson,remoteaddr,signerbits,data,datalen);
else
{
newlen = (int32_t)(msg->sig.allocsize - sizeof(*msg));
data = msg->serialized;
if ( msg->serialized[len - 1] == 0 )
{
if ( (argjson= cJSON_Parse((char *)msg->serialized)) != 0 )
{
n = (int32_t)(strlen((char *)msg->serialized) + 1);
newlen -= n;
if ( n >= 0 )
data = &msg->serialized[n];
else data = 0;
}
}
if ( data != 0 )
retstr = instantdex_parse(myinfo,msg,argjson,remoteaddr,signerbits,data,newlen);
}
}
if ( argjson != 0 )
free_json(argjson);
return(retstr);
}
#include "../includes/iguana_apidefs.h"
THREE_STRINGS_AND_DOUBLE(InstantDEX,request,reference,base,rel,volume)
{
int32_t hops = 3; cJSON *argjson;
if ( remoteaddr == 0 )
{
argjson = cJSON_CreateObject();
jaddstr(argjson,"ref",reference);
jaddstr(argjson,"base",base);
jaddstr(argjson,"rel",rel);
jaddnum(argjson,"volume",volume);
return(instantdex_sendcmd(myinfo,argjson,"request",myinfo->ipaddr,hops));
} else return(clonestr("{\"error\":\"InstantDEX API request only local usage!\"}"));
}
cJSON *InstantDEX_argjson(char *reference,char *message,bits256 basetxid,bits256 reltxid,int32_t iter,int32_t val,int32_t val2)
{
cJSON *argjson = cJSON_CreateObject();
jaddstr(argjson,"ref",reference);
if ( message != 0 && message[0] != 0 )
jaddstr(argjson,"message",message);
jaddbits256(argjson,"basetxid",basetxid);
jaddbits256(argjson,"reltxid",reltxid);
if ( iter != 3 )
{
jaddnum(argjson,"duration",val);
jaddnum(argjson,"flags",val2);
}
else
{
if ( val > 0 )
jaddnum(argjson,"baseheight",val);
if ( val2 > 0 )
jaddnum(argjson,"relheight",val2);
}
return(argjson);
}
TWOSTRINGS_AND_TWOHASHES_AND_TWOINTS(InstantDEX,proposal,reference,message,basetxid,reltxid,duration,flags)
{
int32_t hops = 3; cJSON *argjson; char *retstr;
if ( remoteaddr == 0 )
{
argjson = InstantDEX_argjson(reference,message,basetxid,reltxid,1,duration,flags);
retstr = instantdex_sendcmd(myinfo,argjson,"proposal",myinfo->ipaddr,hops);
free_json(argjson);
return(retstr);
} else return(clonestr("{\"error\":\"InstantDEX API proposal only local usage!\"}"));
}
TWOSTRINGS_AND_TWOHASHES_AND_TWOINTS(InstantDEX,accept,reference,message,basetxid,reltxid,duration,flags)
{
int32_t hops = 3; cJSON *argjson; char *retstr;
if ( remoteaddr == 0 )
{
argjson = InstantDEX_argjson(reference,message,basetxid,reltxid,2,duration,flags);
retstr = instantdex_sendcmd(myinfo,argjson,"accept",myinfo->ipaddr,hops);
free_json(argjson);
return(retstr);
} else return(clonestr("{\"error\":\"InstantDEX API accept only local usage!\"}"));
}
TWOSTRINGS_AND_TWOHASHES_AND_TWOINTS(InstantDEX,confirm,reference,message,basetxid,reltxid,baseheight,relheight)
{
int32_t hops = 3; cJSON *argjson; char *retstr;
if ( remoteaddr == 0 )
{
argjson = InstantDEX_argjson(reference,message,basetxid,reltxid,3,baseheight,relheight);
retstr = instantdex_sendcmd(myinfo,argjson,"confirm",myinfo->ipaddr,hops);
free_json(argjson);
return(retstr);
} else return(clonestr("{\"error\":\"InstantDEX API confirm only local usage!\"}"));
}
#include "../includes/iguana_apiundefs.h"

60
iguana/iguana_tradebots.c

@ -0,0 +1,60 @@
/******************************************************************************
* 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. *
* *
******************************************************************************/
#include "exchanges777.h"
#include "../includes/iguana_apidefs.h"
THREE_STRINGS_AND_DOUBLE(tradebot,monitor,exchange,base,rel,commission)
{
int32_t allfields = 1,depth = 50; struct exchange_info *ptr;
if ( remoteaddr == 0 )
{
if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 )
return(exchanges777_Qprices(ptr,base,rel,30,allfields,depth,json,1,commission * .01));
else return(clonestr("{\"error\":\"couldnt find/create exchange info\"}"));
} else return(clonestr("{\"error\":\"tradebots only local usage!\"}"));
}
THREE_STRINGS(tradebot,unmonitor,exchange,base,rel)
{
struct exchange_info *ptr;
if ( remoteaddr == 0 )
{
if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 )
return(exchanges777_unmonitor(ptr,base,rel));
else return(clonestr("{\"error\":\"couldnt find/create exchange info\"}"));
} else return(clonestr("{\"error\":\"tradebots only local usage!\"}"));
}
THREE_STRINGS_AND_THREE_DOUBLES(tradebot,accumulate,exchange,base,rel,price,volume,duration)
{
if ( remoteaddr == 0 )
{
return(clonestr("{\"result\":\"start accumulating\"}"));
} else return(clonestr("{\"error\":\"tradebots only local usage!\"}"));
}
THREE_STRINGS_AND_THREE_DOUBLES(tradebot,divest,exchange,base,rel,price,volume,duration)
{
if ( remoteaddr == 0 )
{
return(clonestr("{\"result\":\"start divesting\"}"));
} else return(clonestr("{\"error\":\"tradebots only local usage!\"}"));
}
#include "../includes/iguana_apiundefs.h"

9
iguana/pangea_api.c

@ -439,7 +439,7 @@ void pangea_parse(struct supernet_info *myinfo,struct pangea_msghdr *pm,cJSON *a
}
}
int32_t pangea_hexmsg(struct supernet_info *myinfo,void *data,int32_t len,char *remoteaddr)
char *pangea_hexmsg(struct supernet_info *myinfo,void *data,int32_t len,char *remoteaddr)
{
static struct { char *cmdstr; void (*func)(PANGEA_HANDARGS); uint64_t cmdbits; } tablecmds[] =
{
@ -455,7 +455,7 @@ int32_t pangea_hexmsg(struct supernet_info *myinfo,void *data,int32_t len,char *
{ "showdown", pangea_showdown }, { "summary", pangea_summary },
};
struct pangea_msghdr *pm = data; cJSON *argjson; bits256 tablehash;
uint64_t cmdbits; uint8_t *serialized; uint8_t tmp[sizeof(pm->sig)]; char str[65],str2[65];
uint64_t cmdbits; uint8_t *serialized; uint8_t tmp[sizeof(pm->sig)]; char *retstr=0,str[65],str2[65];
struct table_info *tp; int32_t i,allocsize,datalen,flag = 0;
if ( tablecmds[0].cmdbits == 0 )
{
@ -468,10 +468,11 @@ int32_t pangea_hexmsg(struct supernet_info *myinfo,void *data,int32_t len,char *
serialized = (void *)((long)pm + sizeof(pm->sig));
if ( remoteaddr != 0 && remoteaddr[0] == 0 && strcmp("127.0.0.1",remoteaddr) == 0 && ((uint8_t *)pm)[len-1] == 0 && (argjson= cJSON_Parse((char *)pm)) != 0 )
{
// ?? iguana_rwbignum(0,pm->tablehash.bytes,sizeof(bits256),tablehash.bytes);
printf("pangea_hexmsg RESULT.(%s)\n",jprint(argjson,0));
pangea_parse(myinfo,pm,argjson,remoteaddr);
free_json(argjson);
return(1);
return(retstr);
}
//printf("pm.%p len.%d serialized.%p datalen.%d crc.%u %s\n",pm,len,serialized,datalen,calc_crc32(0,(void *)pm,len),bits256_str(str,pm->sig.pubkey));
//return(0);
@ -520,7 +521,7 @@ int32_t pangea_hexmsg(struct supernet_info *myinfo,void *data,int32_t len,char *
printf("%02x",serialized[i]);
printf("<<<<<<<<<<<<< sigsize.%ld SIG ERROR [%ld] len.%d (%s + %s)\n",sizeof(pm->sig),(long)serialized-(long)pm,datalen,bits256_str(str,acct777_msgprivkey(serialized,datalen)),bits256_str(str2,pm->sig.pubkey));
}
return(flag);
return(retstr);
}
void pangea_update(struct supernet_info *myinfo)

12
iguana/pnacl/Release/iguana.nmf

@ -0,0 +1,12 @@
{
"program": {
"portable": {
"pnacl-translate": {
"url": "iguana.pexe"
},
"pnacl-debug": {
"url": "iguana_unstripped.bc"
}
}
}
}

BIN
iguana/pnacl/Release/iguana.pexe

Binary file not shown.

12
includes/iguana_apideclares.h

@ -32,6 +32,18 @@ TWO_STRINGS(InstantDEX,orderstatus,exchange,orderid);
TWO_STRINGS(InstantDEX,cancelorder,exchange,orderid);
STRING_ARG(InstantDEX,openorders,exchange);
STRING_ARG(InstantDEX,tradehistory,exchange);
STRING_AND_INT(InstantDEX,pollgap,exchange,pollgap);
THREE_STRINGS_AND_DOUBLE(InstantDEX,request,reference,base,rel,volume);
TWOSTRINGS_AND_TWOHASHES_AND_TWOINTS(InstantDEX,proposal,reference,message,basetxid,reltxid,duration,flags);
TWOSTRINGS_AND_TWOHASHES_AND_TWOINTS(InstantDEX,accept,reference,message,basetxid,reltxid,duration,flags);
TWOSTRINGS_AND_TWOHASHES_AND_TWOINTS(InstantDEX,confirm,reference,message,basetxid,reltxid,baseheight,relheight);
THREE_STRINGS_AND_DOUBLE(tradebot,monitor,exchange,base,rel,commission);
THREE_STRINGS(tradebot,unmonitor,exchange,base,rel);
THREE_STRINGS_AND_THREE_DOUBLES(tradebot,accumulate,exchange,base,rel,price,volume,duration);
THREE_STRINGS_AND_THREE_DOUBLES(tradebot,divest,exchange,base,rel,price,volume,duration);
/*HASH_AND_ARRAY(pangea,userturn,tablehash,params);
HASH_AND_ARRAY(pangea,status,tableid,params);

Loading…
Cancel
Save