struct basilisk_request *basilisk_parsejson(struct basilisk_request *rp,cJSON *reqjson) { uint32_t requestid,quoteid; memset(rp,0,sizeof(*rp)); rp->hash = jbits256(reqjson,"hash"); rp->desthash = jbits256(reqjson,"desthash"); rp->srcamount = j64bits(reqjson,"srcamount"); rp->minamount = j64bits(reqjson,"minamount"); rp->destamount = j64bits(reqjson,"destamount"); requestid = juint(reqjson,"requestid"); quoteid = juint(reqjson,"quoteid"); if ( jstr(reqjson,"relay") != 0 ) rp->relaybits = (uint32_t)calc_ipbits(jstr(reqjson,"relay")); rp->timestamp = juint(reqjson,"timestamp"); rp->quotetime = juint(reqjson,"quotetime"); safecopy(rp->src,jstr(reqjson,"src"),sizeof(rp->src)); safecopy(rp->dest,jstr(reqjson,"dest"),sizeof(rp->dest)); if ( quoteid != 0 ) { rp->quoteid = basilisk_quoteid(rp); if ( quoteid != rp->quoteid ) printf("basilisk_parsejson quoteid.%u != %u error\n",quoteid,rp->quoteid); } rp->requestid = basilisk_requestid(rp); if ( requestid != rp->requestid ) printf("basilisk_parsejson requestid.%u != %u error\n",requestid,rp->requestid); return(rp); }
uint64_t TRADE(char **retstrp,struct exchange_info *exchange,char *base,char *rel,int32_t dir,double price,double volume) { char payload[1024],pairstr[64],pricestr[64],*extra,*method; cJSON *json; int32_t type; uint64_t txid = 0; if ( (extra= *retstrp) != 0 ) *retstrp = 0; 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); } if ( extra != 0 && strcmp(extra,"market") == 0 ) method = (dir > 0) ? "buy_market" : "sell_market"; else method = (dir > 0) ? "buy" : "sell", sprintf(pricestr,"&price=%.2f",price); if ( strcmp(pairstr,"btccny") == 0 ) type = 1; else if ( strcmp(pairstr,"ltccny") == 0 ) type = 2; else { printf("cant find baserel (%s/%s)\n",base,rel); return(0); } sprintf(payload,"&amount=%.4f&coin_type=%d%s",volume,type,pricestr); if ( (json= huobi_issue_auth(exchange,method,payload)) != 0 ) { txid = j64bits(json,"order_id"); free_json(json); } return(txid); }
uint64_t TRADE(char **retstrp,struct exchange_info *exchange,char *base,char *rel,int32_t dir,double price,double volume) { char payload[1024],pairstr[512],*typestr,*method,*extra; cJSON *json; uint64_t txid = 0; if ( (extra= *retstrp) != 0 ) *retstrp = 0; 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 = "order/new"; //Either "market" / "limit" / "stop" / "trailing-stop" / "fill-or-kill" / "exchange market" / "exchange limit" / "exchange stop" / "exchange trailing-stop" / "exchange fill-or-kill". (type starting by "exchange " are exchange orders, others are margin trading orders) if ( (typestr= extra) == 0 ) typestr = "exchange limit"; sprintf(payload,"{\"request\":\"/v1/%s\",\"nonce\":\"%llu\",\"exchange\":\"bitfinex\",\"side\":\"%s\",\"type\":\"%s\",\"price\":\"%.8f\",\"amount\":\"%.8f\",\"symbol\":\"%s\"}",method,(long long)exchange_nonce(exchange),dir>0?"buy":"sell",typestr,price,volume,pairstr); if ( (json= SIGNPOST(retstrp,exchange,payload,method)) != 0 ) { if ( (txid= j64bits(json,"order_id")) == 0 ) { if ( dir != 0 ) printf("bitfinex: no txid error\n"); } free_json(json); } return(txid); }
uint64_t TRADE(void **cHandlep,int32_t dotrade,char **retstrp,struct exchange_info *exchange,char *base,char *rel,int32_t dir,double price,double volume) { char payload[1024],buf[1024],url[1024],digest[512],pairstr[512],pricestr[64],*extra,*typestr; cJSON *json; uint64_t txid = 0; if ( (extra= *retstrp) != 0 ) *retstrp = 0; 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); } if ( extra != 0 && strcmp(extra,"market") == 0 ) typestr = (dir > 0) ? "buy_market" : "sell_market", sprintf(pricestr,"&price=%.2f",price); // docs say market orders put volume in price else typestr = (dir > 0) ? "buy" : "sell"; sprintf(pricestr,"&price=%.2f",price); sprintf(buf,"amount=%.4f&api_key=%s%ssymbol=%s&type=%s&secret_key=%s",volume,exchange->apikey,pricestr,pairstr,typestr,exchange->apisecret); calc_md5(digest,buf,(int32_t)strlen(buf)); touppercase(digest); sprintf(payload,"amount=%.4f&api_key=%s%s&symbol=%s&type=%s&sign=%s",volume,exchange->apikey,pricestr,pairstr,typestr,digest); sprintf(url,"%s/%s",EXCHANGE_AUTHURL,"trade.do"); if ( CHECKBALANCE(retstrp,dotrade,exchange,dir,base,rel,price,volume) == 0 && (json= SIGNPOST(cHandlep,dotrade,retstrp,exchange,url,payload)) != 0 ) { txid = j64bits(json,"order_id"); free_json(json); } return(txid); }
cJSON *gecko_paymentsobj(struct supernet_info *myinfo,cJSON *txjson,cJSON *valsobj,int32_t reusedaddrs) { cJSON *item,*array; char *coinaddr; uint64_t satoshis; uint8_t addrtype,pubkey33[33],rmd160[20],outputscript[512]; int32_t i,n,scriptlen; uint32_t locktime,txversion; struct iguana_waddress *waddr; struct iguana_waccount *wacct; locktime = jint(valsobj,"locktime"); if ( (txversion= juint(valsobj,"txversion")) == 0 ) txversion = (locktime == 0) ? IGUANA_NORMAL_TXVERSION : IGUANA_LOCKTIME_TXVERSION; if ( txjson == 0 ) txjson = bitcoin_txcreate(1,locktime,txversion); if ( (array= jarray(&n,valsobj,"payments")) != 0 && n > 0 ) { for (i=0; i<n; i++) { item = jitem(array,i); if ( (coinaddr= jfieldname(item)) != 0 && (satoshis= j64bits(item,coinaddr)) > 0 ) { printf("payment.%s <- %.8f\n",coinaddr,dstr(satoshis)); bitcoin_addr2rmd160(&addrtype,rmd160,coinaddr); scriptlen = 0; if ( reusedaddrs == 0 ) { if ( (waddr= iguana_waddresssearch(myinfo,&wacct,coinaddr)) != 0 ) { if ( bitcoin_pubkeylen(waddr->pubkey) > 0 ) scriptlen = bitcoin_pubkeyspend(outputscript,0,pubkey33); } } if ( scriptlen == 0 ) scriptlen = bitcoin_standardspend(outputscript,0,rmd160); bitcoin_txoutput(txjson,outputscript,scriptlen,satoshis); } } } return(txjson); }
uint64_t TRADE(void **cHandlep,int32_t dotrade,char **retstrp,struct exchange_info *exchange,char *base,char *rel,int32_t dir,double price,double volume) { char payload[1024],market[16],coinname[16],fmtstr[512],*pricefmt,*extra,*volfmt = "%.3f"; cJSON *json,*resultobj; uint64_t txid = 0; if ( (extra= *retstrp) != 0 ) *retstrp = 0; if ( (dir= cny_flip(market,coinname,base,rel,dir,&price,&volume)) == 0 ) { fprintf(stderr,"btc38_trade illegal base.(%s) or rel.(%s)\n",base,rel); return(0); } if ( strcmp(market,"cny") == 0 ) pricefmt = "%.5f"; else pricefmt = "%.6f"; //sprintf(fmtstr,"key=%%s&time=%%llu&md5=%%s&type=%%s&mk_type=%%s&coinname=%%s&price=%s&amount=%s",pricefmt,volfmt); //sprintf(payload,fmtstr,exchange->apikey,(long long)nonce,digest,dir>0?"1":"2",market,coinname,price,volume); sprintf(fmtstr,"&type=%%s&mk_type=%%s&coinname=%%s&price=%s&amount=%s",pricefmt,volfmt); sprintf(payload,fmtstr,dir>0?"1":"2",market,coinname,price,volume); if ( CHECKBALANCE(retstrp,dotrade,exchange,dir,base,rel,price,volume) == 0 && (json= SIGNPOST(cHandlep,dotrade,retstrp,exchange,payload,"submitOrder.php")) != 0 ) { if ( juint(json,"success") > 0 && (resultobj= jobj(json,"return")) != 0 ) { if ( (txid= j64bits(resultobj,"order_id")) == 0 ) { if ( j64bits(resultobj,"remains") == 0 ) txid = _crc32(0,payload,strlen(payload)); } } free_json(json); if ( retstrp != 0 && *retstrp != 0 ) { if ( (json= cJSON_Parse(*retstrp)) == 0 ) { json = cJSON_CreateObject(); jaddstr(json,"result",*retstrp); free(*retstrp); *retstrp = jprint(json,1); } else free_json(json); } } return(txid); }
char *bidask_func(int32_t localaccess,int32_t valid,char *sender,cJSON *json,char *origargstr) { struct destbuf gui,exchangestr,name,base,rel,offerNXT; struct InstantDEX_quote iQ; copy_cJSON(&offerNXT,jobj(json,"offerNXT")); //printf("got (%s)\n",origargstr); if ( strcmp(SUPERNET.NXTADDR,offerNXT.buf) != 0 ) { if ( bidask_parse(&exchangestr,&name,&base,&rel,&gui,&iQ,json) == 0 ) return(InstantDEX_placebidask(sender,j64bits(json,"orderid"),exchangestr.buf,name.buf,base.buf,rel.buf,&iQ,jstr(json,"extra"),jstr(json,"secret"),jstr(json,"activenxt"),json)); else printf("error with incoming bidask\n"); } else fprintf(stderr,"got my bidask from network (%s)\n",origargstr); return(clonestr("{\"result\":\"got loopback bidask\"}")); }
char *SuperNET_processJSON(struct supernet_info *myinfo,cJSON *json,char *remoteaddr) { cJSON *retjson; uint64_t tag; uint32_t timeout; char *jsonstr,*method,*retjsonstr,*retstr = 0; //char str[65]; printf("processJSON %p %s\n",&myinfo->privkey,bits256_str(str,myinfo->privkey)); if ( json != 0 ) { if ( (tag= j64bits(json,"tag")) == 0 ) { OS_randombytes((uint8_t *)&tag,sizeof(tag)); jadd64bits(json,"tag",tag); } if ( (timeout= juint(json,"timeout")) == 0 ) timeout = IGUANA_JSONTIMEOUT; if ( (method= jstr(json,"method")) != 0 && strcmp(method,"DHT") == 0 && remoteaddr != 0 ) { SuperNET_hexmsgprocess(myinfo,0,json,jstr(json,"hexmsg"),remoteaddr); return(clonestr("{\"result\":\"processed remote DHT\"}")); } jsonstr = jprint(json,0); if ( remoteaddr == 0 || jstr(json,"immediate") != 0 ) retjsonstr = SuperNET_jsonstr(myinfo,jsonstr,remoteaddr); else retjsonstr = iguana_blockingjsonstr(myinfo,jsonstr,tag,timeout,remoteaddr); if ( retjsonstr != 0 ) { if ( (retjson= cJSON_Parse(retjsonstr)) != 0 ) { jdelete(retjson,"tag"); jadd64bits(retjson,"tag",tag); retstr = jprint(retjson,1); //printf("retstr.(%s) retjsonstr.%p retjson.%p\n",retstr,retjsonstr,retjson); free(retjsonstr);//,strlen(retjsonstr)+1); } else retstr = retjsonstr; } free(jsonstr); } else retstr = clonestr("{\"error\":\"cant parse JSON\"}"); if ( retstr == 0 ) retstr = clonestr("{\"error\":\"null return\"}"); return(retstr); }
cJSON *LP_NXT_redeems() { char url[1024],*retstr,*recv,*method,*msgstr,assetname[128]; uint64_t totals[2][sizeof(assetids)/sizeof(*assetids)],mult,txnum,assetid,qty; int32_t i,ind,numtx=0,past_marker=0; cJSON *item,*attach,*decjson,*array,*msgjson,*encjson,*retjson=0; //sleep 1; fiat/supernet sendtoaddress RNZZuQYu8xJLZHuekhd96hYfoQuiCMz99T 1001.44150000 # txnum.8537615468620726612 //sleep 1; fiat/pangea sendtoaddress RWMdRaUmMZqKkEibwEhY6XS3RLCXJDWHTi 22.10910000 # txnum.2649622877615958504 uint64_t txnum_marker = calc_nxt64bits("8537615468620726612"); // 2649622877615958504"); // set to most recent processed uint64_t txnum_marker2 = calc_nxt64bits("7256847492742571143"); // dont change, end marker char *passphrase = ""; char *account = "NXT-MRBN-8DFH-PFMK-A4DBM"; memset(totals,0,sizeof(totals)); sprintf(url,"http://127.0.0.1:7876/nxt?requestType=getBlockchainTransactions&account=%s",account); //printf("calling (%s)\n",url); if ( (retstr= issue_curlt(url,LP_HTTP_TIMEOUT)) != 0 ) { //printf("got.(%s)\n",retstr); if ( (retjson= cJSON_Parse(retstr)) != 0 ) { if ( (array= jarray(&numtx,retjson,"transactions")) != 0 ) { for (i=0; i<numtx; i++) { msgjson = encjson = decjson = 0; txnum = assetid = qty = 0; item = jitem(array,i); msgstr = jstr(item,"message"); txnum = j64bits(item,"transaction"); if ( txnum == txnum_marker ) past_marker = 1; //printf("%d: %s\n",i,jprint(item,0)); if ( (recv= jstr(item,"recipientRS")) != 0 && strcmp(recv,"NXT-MRBN-8DFH-PFMK-A4DBM") == 0 ) { if ( (attach= jobj(item,"attachment")) != 0 && jint(attach,"version.AssetTransfer") == 1 ) { assetid = j64bits(attach,"asset"); qty = j64bits(attach,"quantityQNT"); //printf("txnum.%llu (%s)\n",(long long)txnum,jprint(attach,0)); if ( (msgstr == 0 || msgstr[0] == 0) && jint(attach,"version.PrunablePlainMessage") == 1 ) { method = "getPrunableMessage"; if ( (msgjson= LP_NXT_message(method,txnum,"test")) != 0 ) { msgstr = jstr(msgjson,"message"); //printf("%d method.(%s) (%s)\n",i,method,msgstr); } } if ( msgstr == 0 || msgstr[0] == 0 ) msgstr = jstr(attach,"message"); if ( msgstr == 0 || msgstr[0] == 0 ) { if ( (encjson= jobj(attach,"encryptedMessage")) != 0 ) { msgstr = "encryptedMessage";//jstr(encjson,"data"); if ( (decjson= LP_NXT_decrypt(txnum,account,jstr(encjson,"data"),jstr(encjson,"nonce"),passphrase)) != 0 ) { //printf("%s\n",jprint(decjson,0)); if ( jstr(decjson,"decryptedMessage") != 0 ) msgstr = jstr(decjson,"decryptedMessage"); } } } } mult = LP_assetid_mult(&ind,assetname,assetid); if ( ind >= 0 ) totals[past_marker][ind] += qty * mult; if ( msgstr != 0 && assetname[0] != 0 && qty != 0 ) { char validaddress[64]; int32_t z,n; n = (int32_t)strlen(msgstr); for (z=0; z<n; z++) { if ( msgstr[z] == 'R' ) break; } memset(validaddress,0,sizeof(validaddress)); if ( n-z >= 34 ) strncpy(validaddress,&msgstr[z],34); if ( txnum == calc_nxt64bits("4545341872872347590") ) strcpy(validaddress,"RKuwq4oi4mqQ2V4r54mPEthn3TBrEwu2Ni"); if ( past_marker == 0 ) { if ( strlen(validaddress) == 34 || strlen(validaddress) == 33 ) { //printf("%-4d: (%34s) <- %13.5f %10s tx.%llu past_marker.%d\n",i,validaddress,dstr(qty * mult),assetname,(long long)txnum,past_marker); LP_sendtoaddress_line(validaddress,assetname,(qty * mult),txnum); } else printf("%-4d: (%34s) <- %13.5f %10s tx.%llu\n",i,msgstr!=0?msgstr:jprint(item,0),dstr(qty * mult),assetname,(long long)txnum); } } if ( msgjson != 0 ) free_json(msgjson); if ( decjson != 0 ) free_json(decjson); } if ( txnum == txnum_marker2 ) break; } } //free_json(retjson); } free(retstr); } else printf("null return from NXT api call\n"); printf("\nTotal redeemed.%d\n",numtx); for (past_marker=0; past_marker<2; past_marker++) { for (i=0; i<sizeof(totals[0])/sizeof(*totals[0]); i++) { if ( totals[past_marker][i] != 0 ) printf("%-10s %13.5f past_marker.%d\n",assetids[i][1],dstr(totals[past_marker][i]),past_marker); } printf("\n>>>>>>>>>> already processed:\n"); } return(retjson); }
void NXTventure_liquidation() { /*{"quantityQNT":"607438148","unconfirmedQuantityQNT":"607438148","decimals":4,"name":"ARDR","asset":""}, {"quantityQNT":"451991779","unconfirmedQuantityQNT":"451991779","decimals":4,"name":"SuperNET","asset":"12071612744977229797"}, {"quantityQNT":"146960000","unconfirmedQuantityQNT":"146960000","decimals":4,"name":"Privatebet","asset":"17083334802666450484"}, {"quantityQNT":"79500188","unconfirmedQuantityQNT":"79500188","decimals":3,"name":"crypto777","asset":"13476425053110940554"}, {"quantityQNT":"1495473","unconfirmedQuantityQNT":"1495473","decimals":0,"name":"jl777hodl","asset":"6932037131189568014"}, {"quantityQNT":"7250","unconfirmedQuantityQNT":"7250","decimals":0,"name":"InstantDEX","asset":"15344649963748848799"},*/ char *assetids[][4] = { { "12422608354438203866", "607438148", "ARDR", "10000" }, { "12071612744977229797", "451991779", "SuperNET", "10000" }, { "17083334802666450484", "146960000", "Privatebet", "10000" }, { "13476425053110940554", "79500188", "crypto777", "1000" }, { "6932037131189568014", "1495473", "jl777hodl", "1" }, { "15344649963748848799", "7250", "InstantDEX", "1" }, }; void *cHandle=0; char *retstr,*retstr2,url[1024],*account; uint64_t txid,qty,qtyA,assetid,sum; double ratio; cJSON *array,*retjson2,*item,*retjson; int32_t i,j,decimals,numassetids=(int32_t)(sizeof(assetids)/sizeof(*assetids)),n=0; char *passphrase = ""; sprintf(url,"http://127.0.0.1:7876/nxt?requestType=getAssetAccounts&asset=16212446818542881180"); if ( (retstr= issue_curlt(url,LP_HTTP_TIMEOUT)) != 0 ) { if ( (retjson= cJSON_Parse(retstr)) != 0 ) { if ( (array= jarray(&n,retjson,"accountAssets")) != 0 ) { for (j=0; j<numassetids; j++) { assetid = calc_nxt64bits(assetids[j][0]); qtyA = calc_nxt64bits(assetids[j][1]); decimals = (int32_t)calc_nxt64bits(assetids[j][3]); printf("distribute %llu QNT of %s assetid %llu %.8f\n",(long long)qtyA,assetids[j][2],(long long)assetid,(double)qtyA / decimals); sum = 0; for (i=0; i<n; i++) { item = jitem(array,i); qty = j64bits(item,"quantityQNT"); ratio = (double)qty / (1000000. - 13000.); if ( (account= jstr(item,"accountRS")) != 0 && qtyA*ratio >= 1 ) { if ( strcmp(account,"NXT-XRK4-5HYK-5965-9FH4Z") != 0 ) { sum += (long long)(qtyA * ratio); sprintf(url,"requestType=transferAsset&secretPhrase=%s&recipient=%s&asset=%llu&quantityQNT=%llu&feeNQT=100000000&deadline=60",passphrase,account,(long long)assetid,(long long)(qtyA * ratio)); if ( (retstr2= curl_post(&cHandle,"http://127.0.0.1:7876/nxt","",url,"","","","")) != 0 ) { if ( (retjson2= cJSON_Parse(retstr2)) != 0 ) { txid = j64bits(retjson2,"transaction"); printf("%s %.6f %8llu QNT %s -> %llu %.8f txid %llu\n",account,ratio,(long long)qtyA,assetids[j][2],(long long)(qtyA * ratio),((double)(long long)(qtyA * ratio))/decimals,(long long)txid); free_json(retjson2); } free(retstr2); } usleep(250000); } } } printf("%s distribution total %llu QNT %.8f\n",assetids[j][2],(long long)sum,(double)sum/decimals); } } free_json(retjson); } printf("NXTventure assethodlers.%d\n",n); free(retstr); } }
char *InstantDEX(char *jsonstr,char *remoteaddr,int32_t localaccess) { char *prices777_allorderbooks(); char *InstantDEX_openorders(); char *InstantDEX_tradehistory(int32_t firsti,int32_t endi); char *InstantDEX_cancelorder(char *activenxt,char *secret,uint64_t sequenceid,uint64_t quoteid); struct destbuf exchangestr,method,gui,name,base,rel; double balance; char *retstr = 0,key[512],retbuf[1024],*activenxt,*secret,*coinstr; struct InstantDEX_quote iQ; struct exchange_info *exchange; cJSON *json; uint64_t assetbits,sequenceid; uint32_t maxdepth; int32_t invert=0,keysize,allfields; struct prices777 *prices; //printf("INSTANTDEX.(%s)\n",jsonstr); if ( INSTANTDEX.readyflag == 0 ) return(0); if ( jsonstr != 0 && (json= cJSON_Parse(jsonstr)) != 0 ) { // test: asset/asset, asset/external, external/external, autofill and automatch // peggy integration bidask_parse(&exchangestr,&name,&base,&rel,&gui,&iQ,json); if ( iQ.s.offerNXT == 0 ) iQ.s.offerNXT = SUPERNET.my64bits; //printf("isask.%d base.(%s) rel.(%s)\n",iQ.s.isask,base.buf,rel.buf); copy_cJSON(&method,jobj(json,"method")); if ( (sequenceid= j64bits(json,"orderid")) == 0 ) sequenceid = j64bits(json,"sequenceid"); allfields = juint(json,"allfields"); if ( (maxdepth= juint(json,"maxdepth")) <= 0 ) maxdepth = MAX_DEPTH; if ( exchangestr.buf[0] == 0 ) { if ( iQ.s.baseid != 0 && iQ.s.relid != 0 ) strcpy(exchangestr.buf,"nxtae"); else strcpy(exchangestr.buf,"basket"); } assetbits = InstantDEX_name(key,&keysize,exchangestr.buf,name.buf,base.buf,&iQ.s.baseid,rel.buf,&iQ.s.relid); //printf("2nd isask.%d base.(%s) rel.(%s)\n",iQ.s.isask,base.buf,rel.buf); exchange = exchange_find(exchangestr.buf); secret = jstr(json,"secret"), activenxt = jstr(json,"activenxt"); if ( secret == 0 ) { secret = SUPERNET.NXTACCTSECRET; activenxt = SUPERNET.NXTADDR; } if ( strcmp(method.buf,"allorderbooks") == 0 ) retstr = prices777_allorderbooks(); /*else if ( strcmp(method.buf,"coinshuffle") == 0 ) { if ( strcmp(exchangestr.buf,"shuffle") == 0 ) retstr = InstantDEX_coinshuffle(base.buf,&iQ,json); else retstr = clonestr("{\"error\":\"coinshuffle must use shuffle exchange\"}"); }*/ else if ( strcmp(method.buf,"openorders") == 0 ) retstr = InstantDEX_openorders(SUPERNET.NXTADDR,juint(json,"allorders")); else if ( strcmp(method.buf,"allexchanges") == 0 ) retstr = jprint(exchanges_json(),1); else if ( strcmp(method.buf,"cancelorder") == 0 ) retstr = InstantDEX_cancelorder(jstr(json,"activenxt"),jstr(json,"secret"),sequenceid,iQ.s.quoteid); else if ( strcmp(method.buf,"orderstatus") == 0 ) retstr = InstantDEX_orderstatus(sequenceid,iQ.s.quoteid); else if ( strcmp(method.buf,"tradehistory") == 0 ) retstr = InstantDEX_tradehistory(juint(json,"firsti"),juint(json,"endi")); else if ( strcmp(method.buf,"lottostats") == 0 ) retstr = jprint(InstantDEX_lottostats(),1); else if ( strcmp(method.buf,"balance") == 0 ) { if ( exchange != 0 && exchange->trade != 0 ) { if ( (coinstr= jstr(json,"base")) != 0 ) { if ( exchange->coinbalance != 0 ) { if ( exchange->balancejson == 0 ) { (*exchange->trade)(&retstr,exchange,0,0,0,0,0); if ( retstr != 0 ) { exchange->balancejson = cJSON_Parse(retstr); free(retstr); } } return((*exchange->coinbalance)(exchange,&balance,coinstr)); } else retstr = clonestr("{\"error\":\"coinbalance missing\"}"); } else (*exchange->trade)(&retstr,exchange,0,0,0,0,0); } else retstr = clonestr("{\"error\":\"cant find exchange\"}"); printf("%s ptr%.p trade.%p\n",exchangestr.buf,exchange,exchange!=0?exchange->trade:0); } else if ( strcmp(method.buf,"tradesequence") == 0 ) { //printf("call tradesequence.(%s)\n",jsonstr); retstr = InstantDEX_tradesequence(activenxt,secret,json); } else if ( strcmp(method.buf,"makebasket") == 0 ) { if ( (prices= prices777_makebasket(0,json,1,"basket",0,0)) != 0 ) retstr = clonestr("{\"result\":\"basket made\"}"); else retstr = clonestr("{\"error\":\"couldnt make basket\"}"); } else if ( strcmp(method.buf,"peggyrates") == 0 ) { if ( SUPERNET.peggy != 0 ) retstr = peggyrates(juint(json,"timestamp")); else retstr = clonestr("{\"error\":\"peggy disabled\"}"); } else if ( strcmp(method.buf,"LSUM") == 0 ) { sprintf(retbuf,"{\"result\":\"%s\",\"amount\":%d}",(rand() & 1) ? "BUY" : "SELL",(rand() % 100) * 100000); retstr = clonestr(retbuf); } else if ( strcmp(method.buf,"placebid") == 0 || strcmp(method.buf,"placeask") == 0 ) return(InstantDEX_placebidask(0,sequenceid,exchangestr.buf,name.buf,base.buf,rel.buf,&iQ,jstr(json,"extra"),secret,activenxt,json)); else if ( strcmp(exchangestr.buf,"active") == 0 && strcmp(method.buf,"orderbook") == 0 ) retstr = prices777_activebooks(name.buf,base.buf,rel.buf,iQ.s.baseid,iQ.s.relid,maxdepth,allfields,strcmp(exchangestr.buf,"active") == 0 || juint(json,"tradeable")); else if ( (prices= prices777_find(&invert,iQ.s.baseid,iQ.s.relid,exchangestr.buf)) == 0 ) { if ( (prices= prices777_poll(exchangestr.buf,name.buf,base.buf,iQ.s.baseid,rel.buf,iQ.s.relid)) != 0 ) { if ( prices777_equiv(prices->baseid) == prices777_equiv(iQ.s.baseid) && prices777_equiv(prices->relid) == prices777_equiv(iQ.s.relid) ) invert = 0; else if ( prices777_equiv(prices->baseid) == prices777_equiv(iQ.s.relid) && prices777_equiv(prices->relid) == prices777_equiv(iQ.s.baseid) ) invert = 1; else invert = 0, printf("baserel not matching (%s %s) %llu %llu vs (%s %s) %llu %llu\n",prices->base,prices->rel,(long long)prices->baseid,(long long)prices->relid,base.buf,rel.buf,(long long)iQ.s.baseid,(long long)iQ.s.relid); } } if ( retstr == 0 && prices != 0 ) { if ( strcmp(method.buf,"disable") == 0 ) { if ( prices != 0 ) { if ( strcmp(prices->exchange,"unconf") == 0 ) return(clonestr("{\"error\":\"cannot disable unconf\"}")); prices->disabled = 1; return(clonestr("{\"result\":\"success\"}")); } else return(clonestr("{\"error\":\"no prices to disable\"}")); } else if ( strcmp(method.buf,"enable") == 0 ) { if ( prices != 0 ) { prices->disabled = 0; return(clonestr("{\"result\":\"success\"}")); } else return(clonestr("{\"error\":\"no prices to enable\"}")); } else if ( strcmp(method.buf,"orderbook") == 0 ) { if ( maxdepth < MAX_DEPTH ) return(prices777_orderbook_jsonstr(invert,SUPERNET.my64bits,prices,&prices->O,maxdepth,allfields)); else if ( (retstr= prices->orderbook_jsonstrs[invert][allfields]) == 0 ) { retstr = prices777_orderbook_jsonstr(invert,SUPERNET.my64bits,prices,&prices->O,MAX_DEPTH,allfields); portable_mutex_lock(&prices->mutex); if ( prices->orderbook_jsonstrs[invert][allfields] != 0 ) free(prices->orderbook_jsonstrs[invert][allfields]); prices->orderbook_jsonstrs[invert][allfields] = retstr; portable_mutex_unlock(&prices->mutex); if ( retstr == 0 ) retstr = clonestr("{}"); } if ( retstr != 0 ) retstr = clonestr(retstr); } } //if ( Debuglevel > 2 ) printf("(%s) %p exchange.(%s) base.(%s) %llu rel.(%s) %llu | name.(%s) %llu\n",retstr!=0?retstr:"",prices,exchangestr.buf,base.buf,(long long)iQ.s.baseid,rel.buf,(long long)iQ.s.relid,name.buf,(long long)assetbits); } return(retstr); }
int32_t bidask_parse(struct destbuf *exchangestr,struct destbuf *name,struct destbuf *base,struct destbuf *rel,struct destbuf *gui,struct InstantDEX_quote *iQ,cJSON *json) { uint64_t basemult,relmult,baseamount,relamount; double price,volume; int32_t exchangeid,keysize,flag; char key[1024],buf[64],*methodstr; memset(iQ,0,sizeof(*iQ)); iQ->s.baseid = j64bits(json,"baseid"); iQ->s.relid = j64bits(json,"relid"); iQ->s.baseamount = j64bits(json,"baseamount"), iQ->s.relamount = j64bits(json,"relamount"); iQ->s.vol = jdouble(json,"volume"); iQ->s.price = jdouble(json,"price"); copy_cJSON(exchangestr,jobj(json,"exchange")); if ( exchangestr->buf[0] == 0 || find_exchange(&exchangeid,exchangestr->buf) == 0 ) exchangeid = -1; iQ->exchangeid = exchangeid; copy_cJSON(base,jobj(json,"base")); copy_cJSON(rel,jobj(json,"rel")); copy_cJSON(name,jobj(json,"name")); methodstr = jstr(json,"method"); if ( methodstr != 0 && (strcmp(methodstr,"placeask") == 0 || strcmp(methodstr,"ask") == 0) ) iQ->s.isask = 1; if ( strcmp(exchangestr->buf,"wallet") == 0 && (iQ->s.baseid == NXT_ASSETID || strcmp(base->buf,"NXT") == 0) ) { flag = 1; if ( strcmp(methodstr,"placeask") == 0 ) methodstr = "placebid"; else if ( strcmp(methodstr,"placebid") == 0 ) methodstr = "placeask"; else if ( strcmp(methodstr,"ask") == 0 ) methodstr = "bid"; else if ( strcmp(methodstr,"bid") == 0 ) methodstr = "ask"; else flag = 0; if ( flag != 0 ) { iQ->s.baseid = iQ->s.relid, iQ->s.relid = NXT_ASSETID; strcpy(base->buf,rel->buf), strcpy(rel->buf,"NXT"); baseamount = iQ->s.baseamount; iQ->s.baseamount = iQ->s.relamount, iQ->s.relamount = baseamount; name->buf[0] = 0; if ( iQ->s.vol > SMALLVAL && iQ->s.price > SMALLVAL ) { iQ->s.vol *= iQ->s.price; iQ->s.price = 1. / iQ->s.price; } iQ->s.isask ^= 1; printf("INVERT\n"); } } if ( (iQ->s.timestamp= juint(json,"timestamp")) == 0 ) iQ->s.timestamp = (uint32_t)time(NULL); copy_cJSON(gui,jobj(json,"gui")), strncpy(iQ->gui,gui->buf,sizeof(iQ->gui)-1); iQ->s.automatch = juint(json,"automatch"); iQ->s.minperc = juint(json,"minperc"); if ( (iQ->s.duration= juint(json,"duration")) == 0 || iQ->s.duration > ORDERBOOK_EXPIRATION ) iQ->s.duration = ORDERBOOK_EXPIRATION; InstantDEX_name(key,&keysize,exchangestr->buf,name->buf,base->buf,&iQ->s.baseid,rel->buf,&iQ->s.relid); //printf(">>>>>>>>>>>> BASE.(%s) REL.(%s)\n",base->buf,rel->buf); iQ->s.basebits = stringbits(base->buf); iQ->s.relbits = stringbits(rel->buf); iQ->s.offerNXT = j64bits(json,"offerNXT"); iQ->s.quoteid = j64bits(json,"quoteid"); if ( strcmp(exchangestr->buf,"shuffle") == 0 ) { if ( iQ->s.price == 0. ) iQ->s.price = 1.; if ( iQ->s.vol == 0. ) iQ->s.vol = 1.; if ( iQ->s.baseamount == 0 ) iQ->s.baseamount = iQ->s.price * SATOSHIDEN; } else { if ( iQ->s.baseamount == 0 || iQ->s.relamount == 0 ) { if ( iQ->s.price <= SMALLVAL || iQ->s.vol <= SMALLVAL ) return(-1); set_best_amounts(&iQ->s.baseamount,&iQ->s.relamount,iQ->s.price,iQ->s.vol); } } if ( iQ->s.quoteid == 0 ) iQ->s.quoteid = calc_quoteid(iQ); else if ( iQ->s.quoteid != calc_quoteid(iQ) ) { printf("bidask_parse quoteid.%llu != calc.%llu\n",(long long)iQ->s.quoteid,(long long)calc_quoteid(iQ)); return(-1); } if ( iQ->s.price > SMALLVAL && iQ->s.vol > SMALLVAL && iQ->s.baseid != 0 && iQ->s.relid != 0 ) { buf[0] = 0, _set_assetname(&basemult,buf,0,iQ->s.baseid); //printf("baseid.%llu -> %s mult.%llu\n",(long long)iQ->baseid,buf,(long long)basemult); buf[0] = 0, _set_assetname(&relmult,buf,0,iQ->s.relid); //printf("relid.%llu -> %s mult.%llu\n",(long long)iQ->relid,buf,(long long)relmult); //basemult = get_assetmult(iQ->baseid), relmult = get_assetmult(iQ->relid); baseamount = (iQ->s.baseamount + basemult/2) / basemult, baseamount *= basemult; relamount = (iQ->s.relamount + relmult/2) / relmult, relamount *= relmult; if ( iQ->s.price != 0. && iQ->s.vol != 0 ) { price = prices777_price_volume(&volume,baseamount,relamount); if ( fabs(iQ->s.price - price)/price > 0.001 ) { printf("cant create accurate price ref.(%f %f) -> (%f %f)\n",iQ->s.price,iQ->s.vol,price,volume); return(-1); } } } return(0); }