diff --git a/basilisk/basilisk.c b/basilisk/basilisk.c index 47c997c14..b6ca2cf51 100755 --- a/basilisk/basilisk.c +++ b/basilisk/basilisk.c @@ -954,6 +954,319 @@ void basilisks_init(struct supernet_info *myinfo) #include "../includes/iguana_apidefs.h" #include "../includes/iguana_apideclares.h" +HASH_ARRAY_STRING(basilisk,getmessage,hash,vals,hexstr) +{ + uint32_t msgid,width,channel; char *retstr; + if ( bits256_cmp(GENESIS_PUBKEY,jbits256(vals,"srchash")) == 0 ) + jaddbits256(vals,"srchash",hash); + if ( bits256_cmp(GENESIS_PUBKEY,jbits256(vals,"desthash")) == 0 ) + jaddbits256(vals,"desthash",myinfo->myaddr.persistent); + if ( (msgid= juint(vals,"msgid")) == 0 ) + { + msgid = (uint32_t)time(NULL); + jdelete(vals,"msgid"); + jaddnum(vals,"msgid",msgid); + } + if ( myinfo->NOTARY.RELAYID >= 0 || myinfo->dexsock >= 0 || myinfo->subsock >= 0 ) + { + channel = juint(vals,"channel"); + width = juint(vals,"width"); + retstr = basilisk_iterate_MSG(myinfo,channel,msgid,jbits256(vals,"srchash"),jbits256(vals,"desthash"),width); + //printf("getmessage.(%s)\n",retstr); + return(retstr); + } + //printf("getmessage not relay.%d dexsock.%d subsock.%d\n",myinfo->NOTARY.RELAYID,myinfo->dexsock,myinfo->subsock); + return(basilisk_standardservice("MSG",myinfo,0,jbits256(vals,"desthash"),vals,hexstr,1)); +} + +HASH_ARRAY_STRING(basilisk,sendmessage,hash,vals,hexstr) +{ + int32_t keylen,datalen,allocsize = 65536; uint8_t key[BASILISK_KEYSIZE],*space,*space2,*data,*ptr = 0; char *retstr=0; + space = calloc(1,allocsize); + space2 = calloc(1,allocsize); + data = get_dataptr(BASILISK_HDROFFSET,&ptr,&datalen,&space[BASILISK_KEYSIZE],allocsize-BASILISK_KEYSIZE,hexstr); + if ( myinfo->subsock >= 0 || myinfo->dexsock >= 0 || (myinfo->IAMNOTARY != 0 && myinfo->NOTARY.RELAYID >= 0) ) + { + keylen = basilisk_messagekey(key,juint(vals,"channel"),juint(vals,"msgid"),jbits256(vals,"srchash"),jbits256(vals,"desthash")); + if ( data != 0 ) + { + retstr = basilisk_respond_addmessage(myinfo,key,keylen,data,datalen,0,juint(vals,"duration")); + } else printf("no get_dataptr\n"); + if ( retstr != 0 ) + free(retstr); + } //else printf("not notary.%d relayid.%d\n",myinfo->IAMNOTARY,myinfo->NOTARY.RELAYID); + if ( vals != 0 && juint(vals,"fanout") == 0 ) + jaddnum(vals,"fanout",MAX(8,(int32_t)sqrt(myinfo->NOTARY.NUMRELAYS)+2)); + if ( BASILISK_KEYSIZE+datalen < allocsize ) + { + memcpy(space2,key,BASILISK_KEYSIZE); + if ( data != 0 && datalen != 0 ) + memcpy(&space2[BASILISK_KEYSIZE],data,datalen); + dex_reqsend(myinfo,"DEX",space2,datalen+BASILISK_KEYSIZE,1,""); + } else printf("sendmessage space too small error for %d\n",datalen); + free(space); + free(space2); + if ( ptr != 0 ) + free(ptr); + return(basilisk_standardservice("OUT",myinfo,0,jbits256(vals,"desthash"),vals,hexstr,0)); +} + +HASH_ARRAY_STRING(basilisk,value,hash,vals,hexstr) +{ + char *retstr=0,*symbol,*coinaddr,*infostr; cJSON *retjson,*sobj,*info,*addrs,*txoutjson,*txjson,*array; uint32_t basilisktag,blocktime; bits256 txid,blockhash; struct basilisk_item *ptr,Lptr; uint64_t value; int32_t timeoutmillis,vout,height,n,m; + if ( vals == 0 ) + return(clonestr("{\"error\":\"null valsobj\"}")); + //if ( myinfo->IAMNOTARY != 0 || myinfo->NOTARY.RELAYID >= 0 ) + // return(clonestr("{\"error\":\"special relays only do OUT and MSG\"}")); + //if ( coin == 0 ) + { + if ( (symbol= jstr(vals,"symbol")) != 0 || (symbol= jstr(vals,"coin")) != 0 ) + coin = iguana_coinfind(symbol); + } + if ( jobj(vals,"fanout") == 0 ) + jaddnum(vals,"fanout",MAX(5,(int32_t)sqrt(myinfo->NOTARY.NUMRELAYS)+1)); + txid = jbits256(vals,"txid"); + vout = jint(vals,"vout"); + if ( coin != 0 ) + { + if ( coin->FULLNODE < 0 ) + { + if ( (txoutjson= dpow_gettxout(myinfo,coin,txid,vout)) != 0 ) + { + if ( (coinaddr= jstr(txoutjson,"address")) != 0 && (value= SATOSHIDEN*jdouble(txoutjson,"value")) != 0 ) + { + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result","success"); + jaddstr(retjson,"address",coinaddr); + jadd64bits(retjson,"satoshis",value); + jaddnum(retjson,"value",dstr(value)); + jaddnum(retjson,"amount",dstr(value)); + height = dpow_getchaintip(myinfo,&blockhash,&blocktime,0,0,coin); + jaddnum(retjson,"height",height); + jaddnum(retjson,"numconfirms",jint(txoutjson,"confirmations")); + jaddbits256(retjson,"txid",txid); + jaddnum(retjson,"vout",vout); + jaddstr(retjson,"coin",coin->symbol); + } + else + { + free_json(txoutjson); + return(clonestr("{\"error\":\"return from gettxout missing fields\"}")); + } + free_json(txoutjson); + return(jprint(retjson,1)); + } else return(clonestr("{\"error\":\"null return from gettxout\"}")); + } + if ( (basilisktag= juint(vals,"basilisktag")) == 0 ) + basilisktag = rand(); + if ( (timeoutmillis= juint(vals,"timeout")) <= 0 ) + timeoutmillis = BASILISK_TIMEOUT; + if ( coin->FULLNODE > 0 && (ptr= basilisk_bitcoinvalue(&Lptr,myinfo,coin,remoteaddr,basilisktag,timeoutmillis,vals)) != 0 ) + { + retstr = ptr->retstr, ptr->retstr = 0; + ptr->finished = OS_milliseconds() + 10000; + return(retstr); + } + } + if ( myinfo->reqsock >= 0 ) + { + if ( (retstr= _dex_getrawtransaction(myinfo,symbol,txid)) != 0 ) + { + if ( (txoutjson= cJSON_Parse(retstr)) != 0 ) + { + //printf("TX.(%s)\n",jprint(txoutjson,0)); + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result","success"); + jaddnum(retjson,"numconfirms",jint(txoutjson,"confirmations")); + if ( (array= jarray(&n,txoutjson,"vout")) != 0 && vout < n && (txjson= jitem(array,vout)) != 0 ) + { + //printf("txjson.(%s)\n",jprint(txjson,0)); + if ( (value= jdouble(txjson,"value") * SATOSHIDEN) != 0 ) + { + if ( (sobj= jobj(txjson,"scriptPubKey")) != 0 && (addrs= jarray(&m,sobj,"addresses")) != 0 && (coinaddr= jstri(addrs,0)) != 0 ) + jaddstr(retjson,"address",coinaddr); + jadd64bits(retjson,"satoshis",value); + jaddnum(retjson,"value",dstr(value)); + if ( (infostr= _dex_getinfo(myinfo,symbol)) != 0 ) + { + if ( (info= cJSON_Parse(infostr)) != 0 ) + { + if ( (height= jint(info,"blocks")) > 0 ) + { + height -= jint(txoutjson,"confirmations"); + jaddnum(retjson,"height",height); + } + free_json(info); + } + free(infostr); + } + jaddbits256(retjson,"txid",txid); + jaddnum(retjson,"vout",vout); + jaddstr(retjson,"coin",symbol); + free(retstr); + free_json(txoutjson); + return(jprint(retjson,1)); + } + } + free_json(txoutjson); + return(jprint(retjson,1)); + } + return(retstr); + } + } + return(basilisk_standardservice("VAL",myinfo,0,hash,vals,hexstr,1)); +} + +HASH_ARRAY_STRING(basilisk,rawtx,hash,vals,hexstr) +{ + char *retstr=0,*symbol; uint32_t basilisktag; int32_t timeoutmillis,i,retval = -1; uint64_t amount,txfee; cJSON *retarray; + if ( vals == 0 ) + return(clonestr("{\"error\":\"null valsobj\"}")); + //if ( coin == 0 ) + { + if ( (symbol= jstr(vals,"symbol")) != 0 || (symbol= jstr(vals,"coin")) != 0 ) + coin = iguana_coinfind(symbol); + } + if ( jobj(vals,"numrequired") == 0 ) + jaddnum(vals,"numrequired",MIN(3,(int32_t)sqrt(myinfo->NOTARY.NUMRELAYS)+1)); + if ( jobj(vals,"fanout") == 0 ) + jaddnum(vals,"fanout",MAX(3,(int32_t)sqrt(myinfo->NOTARY.NUMRELAYS)+1)); + if ( coin != 0 ) + { + //if ( juint(vals,"burn") == 0 ) + // jaddnum(vals,"burn",0.0001); + if ( (basilisktag= juint(vals,"basilisktag")) == 0 ) + basilisktag = rand(); + if ( (timeoutmillis= juint(vals,"timeout")) <= 0 ) + timeoutmillis = BASILISK_TIMEOUT; + if ( (retstr= basilisk_bitcoinrawtx(myinfo,coin,remoteaddr,basilisktag,timeoutmillis,vals,0)) != 0 ) + { + printf("rawtx.(%s)\n",retstr); + if ( (amount= j64bits(vals,"satoshis")) == 0 ) + amount = jdouble(vals,"value") * SATOSHIDEN; + if ( (txfee= j64bits(vals,"txfee")) == 0 ) + txfee = coin->chain->txfee; + if ( txfee == 0 ) + txfee = 10000; + retval = -1; + if ( (retarray= cJSON_Parse(retstr)) != 0 ) + { + if ( is_cJSON_Array(retarray) != 0 ) + { + for (i=0; iFULLNODE >= 0 ) + return(clonestr("{\"error\":\"no passphrase or no native komodod\"}")); + else + { + safecopy(myinfo->jumblr_passphrase,passphrase,sizeof(myinfo->jumblr_passphrase)); + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result","success"); + privkey = jumblr_privkey(myinfo,BTCaddr,KMDaddr,JUMBLR_DEPOSITPREFIX); + smartaddress_add(myinfo,privkey,BTCaddr,KMDaddr); + myinfo->jumblr_depositkey = curve25519(privkey,curve25519_basepoint9()); + bitcoin_priv2wif(wifstr,privkey,coin->chain->wiftype); + if ( coin->FULLNODE < 0 ) + jumblr_importprivkey(myinfo,coin,wifstr); + jaddstr(retjson,"KMDdeposit",KMDaddr); + jaddstr(retjson,"BTCdeposit",BTCaddr); + if ( (coinbtc= iguana_coinfind("BTC")) != 0 ) + { + bitcoin_priv2wif(wifstr,privkey,coinbtc->chain->wiftype); + if ( coinbtc->FULLNODE < 0 ) + jumblr_importprivkey(myinfo,coinbtc,wifstr); + jaddnum(retjson,"BTCdeposits",dstr(jumblr_balance(myinfo,coinbtc,BTCaddr))); + } + privkey = jumblr_privkey(myinfo,BTCaddr,KMDaddr,""); + smartaddress_add(myinfo,privkey,BTCaddr,KMDaddr); + myinfo->jumblr_pubkey = curve25519(privkey,curve25519_basepoint9()); + jaddstr(retjson,"KMDjumblr",KMDaddr); + jaddstr(retjson,"BTCjumblr",BTCaddr); + if ( coinbtc != 0 ) + jaddnum(retjson,"BTCjumbled",dstr(jumblr_balance(myinfo,coinbtc,BTCaddr))); + return(jprint(retjson,1)); + } +} + +ZERO_ARGS(jumblr,status) +{ + cJSON *retjson; char KMDaddr[64],BTCaddr[64]; struct jumblr_item *ptr,*tmp; struct iguana_info *coinbtc; int64_t received,deposited,jumblred,step_t2z,step_z2z,step_z2t,finished,pending,maxval,minval; + if ( strcmp(coin->symbol,"KMD") == 0 && coin->FULLNODE < 0 && myinfo->jumblr_passphrase[0] != 0 ) + { + jumblr_opidsupdate(myinfo,coin); + retjson = cJSON_CreateObject(); + step_t2z = step_z2z = step_z2t = deposited = finished = pending = 0; + jumblr_privkey(myinfo,BTCaddr,KMDaddr,JUMBLR_DEPOSITPREFIX); + jaddstr(retjson,"KMDdeposit",KMDaddr); + jaddstr(retjson,"BTCdeposit",BTCaddr); + if ( (coinbtc= iguana_coinfind("BTC")) != 0 ) + jaddnum(retjson,"BTCdeposits",dstr(jumblr_balance(myinfo,coinbtc,BTCaddr))); + received = jumblr_receivedby(myinfo,coin,KMDaddr); + deposited = jumblr_balance(myinfo,coin,KMDaddr); + jumblr_privkey(myinfo,BTCaddr,KMDaddr,""); + jaddstr(retjson,"KMDjumblr",KMDaddr); + jaddstr(retjson,"BTCjumblr",BTCaddr); + if ( coinbtc != 0 ) + jaddnum(retjson,"BTCjumbled",dstr(jumblr_balance(myinfo,coinbtc,BTCaddr))); + finished = jumblr_receivedby(myinfo,coin,KMDaddr); + jumblred = jumblr_balance(myinfo,coin,KMDaddr); + HASH_ITER(hh,myinfo->jumblrs,ptr,tmp) + { + if ( strlen(ptr->src) >= 40 ) + { + if ( strlen(ptr->dest) >= 40 ) + step_z2z += ptr->amount; + else step_z2t += ptr->amount; + } else step_t2z += ptr->amount; + } + jaddstr(retjson,"result","success"); + jaddnum(retjson,"deposits",dstr(deposited)); + jaddnum(retjson,"t_to_z",dstr(step_t2z)); + jaddnum(retjson,"z_to_z",dstr(step_z2z)); + jaddnum(retjson,"z_to_t",dstr(step_z2t)); + maxval = MAX(step_t2z,MAX(step_z2z,step_z2t)); + minval = MIN(step_t2z,MIN(step_z2z,step_z2t)); + if ( maxval > minval ) + { + pending = (maxval - minval); + if ( pending < finished*.1 ) + pending = 0; + } + jaddnum(retjson,"pending",dstr(pending)); + jaddnum(retjson,"jumbled",dstr(jumblred)); + jaddnum(retjson,"received",dstr(received)); + jaddnum(retjson,"finished",dstr(finished)); + return(jprint(retjson,1)); + } + else + { + printf("(%s) (%s) %d\n",coin->symbol,myinfo->jumblr_passphrase,coin->FULLNODE); + return(clonestr("{\"error\":\"jumblr status no passphrase or no native komodod\"}")); + } +} + HASH_ARRAY_STRING(basilisk,balances,hash,vals,hexstr) { char *retstr=0,*symbol; uint32_t basilisktag; struct basilisk_item *ptr,Lptr; int32_t timeoutmillis; @@ -1189,5 +1502,242 @@ STRING_ARRAY_OBJ_STRING(basilisk,utxorawtx,symbol,utxos,vals,ignore) //int64_t iguana_verifytimelock(struct supernet_info *myinfo,struct iguana_info *coin,uint32_t timelocked,char *destaddr,bits256 txid,int32_t vout) +THREE_STRINGS_AND_DOUBLE(tradebot,aveprice,comment,base,rel,basevolume) +{ + double retvals[4],aveprice; cJSON *retjson = cJSON_CreateObject(); + aveprice = instantdex_avehbla(myinfo,retvals,base,rel,basevolume); + jaddstr(retjson,"result","success"); + jaddnum(retjson,"aveprice",aveprice); + jaddnum(retjson,"avebid",retvals[0]); + jaddnum(retjson,"bidvol",retvals[1]); + jaddnum(retjson,"aveask",retvals[2]); + jaddnum(retjson,"askvol",retvals[3]); + return(jprint(retjson,1)); +} + +ZERO_ARGS(InstantDEX,allcoins) +{ + struct iguana_info *tmp; cJSON *native,*notarychains,*basilisk,*virtual,*full,*retjson = cJSON_CreateObject(); + full = cJSON_CreateArray(); + native = cJSON_CreateArray(); + basilisk = cJSON_CreateArray(); + virtual = cJSON_CreateArray(); + notarychains = cJSON_CreateArray(); + HASH_ITER(hh,myinfo->allcoins,coin,tmp) + { + if ( coin->FULLNODE < 0 ) + jaddistr(native,coin->symbol); + //else if ( coin->virtualchain != 0 ) + // jaddistr(virtual,coin->symbol); + else if ( coin->FULLNODE > 0 )//|| coin->VALIDATENODE > 0 ) + jaddistr(full,coin->symbol); + //else if ( coin->notarychain >= 0 ) + // jaddistr(notarychains,coin->symbol); + else jaddistr(basilisk,coin->symbol); + } + jadd(retjson,"native",native); + jadd(retjson,"basilisk",basilisk); + jadd(retjson,"full",full); + //jadd(retjson,"virtual",virtual); + //jadd(retjson,"notarychains",notarychains); + return(jprint(retjson,1)); +} + +STRING_ARG(InstantDEX,available,source) +{ + uint64_t total = 0; int32_t i,n=0; char coinaddr[64]; cJSON *item,*unspents,*retjson = 0; + if ( source != 0 && source[0] != 0 && (coin= iguana_coinfind(source)) != 0 ) + { + if ( myinfo->expiration != 0 ) + { + bitcoin_address(coinaddr,coin->chain->pubtype,myinfo->persistent_pubkey33,33); + if ( (unspents= basilisk_unspents(myinfo,coin,coinaddr)) != 0 ) + { + //printf("available.(%s)\n",jprint(unspents,0)); + if ( (n= cJSON_GetArraySize(unspents)) > 0 ) + { + for (i=0; i %.8f\n",jprint(item,0),dstr(total)); + } + } + free_json(unspents); + } + retjson = cJSON_CreateObject(); + jaddnum(retjson,"result",dstr(total)); + printf(" n.%d total %.8f (%s)\n",n,dstr(total),jprint(retjson,0)); + return(jprint(retjson,1)); + } + printf("InstantDEX_available: need to unlock wallet\n"); + return(clonestr("{\"error\":\"need to unlock wallet\"}")); + } + printf("InstantDEX_available: %s is not active\n",source!=0?source:""); + return(clonestr("{\"error\":\"specified coin is not active\"}")); +} + +HASH_ARRAY_STRING(InstantDEX,request,hash,vals,hexstr) +{ + uint8_t serialized[512]; bits256 privkey; char buf[512],BTCaddr[64],KMDaddr[64]; struct basilisk_request R; int32_t jumblr,iambob,optionhours; cJSON *reqjson; uint32_t datalen=0,DEX_channel; struct iguana_info *bobcoin,*alicecoin; + myinfo->DEXactive = (uint32_t)time(NULL) + 3*BASILISK_TIMEOUT + 60; + jadd64bits(vals,"minamount",jdouble(vals,"minprice") * jdouble(vals,"amount") * SATOSHIDEN * SATOSHIDEN); + if ( jobj(vals,"desthash") == 0 ) + jaddbits256(vals,"desthash",hash); + jadd64bits(vals,"satoshis",jdouble(vals,"amount") * SATOSHIDEN); + jadd64bits(vals,"destsatoshis",jdouble(vals,"destamount") * SATOSHIDEN); + jaddnum(vals,"timestamp",time(NULL)); + if ( (jumblr= jint(vals,"usejumblr")) != 0 ) + privkey = jumblr_privkey(myinfo,BTCaddr,KMDaddr,jumblr == 1 ? JUMBLR_DEPOSITPREFIX : ""); + else privkey = myinfo->persistent_priv; + hash = curve25519(privkey,curve25519_basepoint9()); + if ( jobj(vals,"srchash") == 0 ) + jaddbits256(vals,"srchash",hash); + printf("service.(%s)\n",jprint(vals,0)); + memset(&R,0,sizeof(R)); + if ( basilisk_request_create(&R,vals,hash,juint(vals,"timestamp")) == 0 ) + { + iambob = bitcoin_coinptrs(hash,&bobcoin,&alicecoin,R.src,R.dest,privkey,GENESIS_PUBKEY); + if ( (optionhours= jint(vals,"optionhours")) != 0 ) + { + printf("iambob.%d optionhours.%d R.requestid.%u vs calc %u, q.%u\n",iambob,R.optionhours,R.requestid,basilisk_requestid(&R),R.quoteid); + if ( iambob != 0 && optionhours > 0 ) + { + sprintf(buf,"{\"error\":\"illegal call option request hours.%d when iambob.%d\"}",optionhours,iambob); + printf("ERROR.(%s)\n",buf); + return(clonestr(buf)); + } + else if ( iambob == 0 && optionhours < 0 ) + { + sprintf(buf,"{\"error\":\"illegal put option request hours.%d when iambob.%d\"}",optionhours,iambob); + printf("ERROR.(%s)\n",buf); + return(clonestr(buf)); + } + } + //if ( myinfo->IAMNOTARY != 0 || myinfo->NOTARY.RELAYID >= 0 ) + // R.relaybits = myinfo->myaddr.myipbits; + if ( (reqjson= basilisk_requestjson(&R)) != 0 ) + free_json(reqjson); + datalen = basilisk_rwDEXquote(1,serialized,&R); + //int32_t i; for (i=0; i 0 ) + { + uint32_t msgid;//,crc=0,crcs[2],numiters = 0; uint8_t buf[4096]; + memset(hash.bytes,0,sizeof(hash)); + msgid = (uint32_t)time(NULL); + DEX_channel = 'D' + ((uint32_t)'E' << 8) + ((uint32_t)'X' << 16); + basilisk_channelsend(myinfo,hash,hash,DEX_channel,msgid,serialized,datalen,60); + sleep(3); + /*while ( numiters < 10 && (crc= basilisk_crcsend(myinfo,0,buf,sizeof(buf),hash,myinfo->myaddr.persistent,DEX_channel,msgid,serialized,datalen,crcs)) == 0 ) + { + //printf("didnt get back what was sent\n"); + sleep(3); + basilisk_channelsend(myinfo,myinfo->myaddr.persistent,hash,DEX_channel,msgid,serialized,datalen,60); + numiters++; + }*/ + //if ( crc != 0 )//basilisk_channelsend(myinfo,R.srchash,R.desthash,DEX_channel,(uint32_t)time(NULL),serialized,datalen,30) == 0 ) + return(clonestr("{\"result\":\"DEX message sent\"}")); + //else return(clonestr("{\"error\":\"DEX message couldnt be sent\"}")); + } + return(clonestr("{\"error\":\"DEX message not sent\"}")); +} + +INT_ARG(InstantDEX,automatched,requestid) +{ + // return quoteid + myinfo->DEXactive = (uint32_t)time(NULL) + INSTANTDEX_LOCKTIME; + return(clonestr("{\"result\":\"automatched not yet\"}")); +} + +int32_t InstantDEX_incoming_func(struct supernet_info *myinfo,void *ptr,uint8_t *data,int32_t datalen) +{ + //int32_t i; + //for (i=0; iDEXpoll) + 2*drift; + if ( width < (drift+1) ) + width = 2*drift+1; + else if ( width > 64 ) + width = 64; + myinfo->DEXpoll = now; + retjson = cJSON_CreateObject(); + DEX_channel = 'D' + ((uint32_t)'E' << 8) + ((uint32_t)'X' << 16); + msgid = (uint32_t)time(NULL) + drift; + if ( (retarray= basilisk_channelget(myinfo,zero,myinfo->myaddr.persistent,DEX_channel,msgid,width)) != 0 ) + { + //printf("GOT.(%s)\n",jprint(retarray,0)); + if ( (retval= basilisk_process_retarray(myinfo,0,InstantDEX_process_channelget,data,sizeof(data),DEX_channel,msgid,retarray,InstantDEX_incoming_func)) > 0 ) + { + jaddstr(retjson,"result","success"); + } else jaddstr(retjson,"error","cant process InstantDEX retarray"); + jadd(retjson,"responses",retarray); + } + else + { + jaddstr(retjson,"error","cant do InstantDEX channelget"); + printf("error channelget\n"); + } + return(jprint(retjson,1)); +} + +/*TWO_INTS(InstantDEX,swapstatus,requestid,quoteid) + { + cJSON *vals; char *retstr; + myinfo->DEXactive = (uint32_t)time(NULL) + INSTANTDEX_LOCKTIME; + //if ( myinfo->IAMLP != 0 ) + // return(basilisk_respond_swapstatus(myinfo,myinfo->myaddr.persistent,requestid,quoteid)); + //else + { + vals = cJSON_CreateObject(); + jaddnum(vals,"requestid",(uint32_t)requestid); + jaddnum(vals,"quoteid",(uint32_t)quoteid); + jaddbits256(vals,"hash",myinfo->myaddr.persistent); + retstr = basilisk_standardservice("SWP",myinfo,0,myinfo->myaddr.persistent,vals,"",1); + free_json(vals); + return(retstr); + } + }*/ + +TWO_INTS(InstantDEX,accept,requestid,quoteid) +{ + cJSON *vals; char *retstr; + myinfo->DEXactive = (uint32_t)time(NULL) + INSTANTDEX_LOCKTIME; + if ( myinfo->IAMLP != 0 || myinfo->dexsock >= 0 || myinfo->subsock >= 0 ) + return(basilisk_respond_accept(myinfo,myinfo->persistent_priv,requestid,quoteid,&myinfo->DEXaccept)); + else + { + vals = cJSON_CreateObject(); + jaddnum(vals,"quoteid",(uint32_t)quoteid); + jaddnum(vals,"requestid",(uint32_t)requestid); + retstr = basilisk_standardservice("ACC",myinfo,0,myinfo->myaddr.persistent,vals,"",1); + free_json(vals); + return(retstr); + } +} + +ZERO_ARGS(InstantDEX,init) +{ + basilisk_swaps_init(myinfo); + return(clonestr("{\"result\":\"success\"}")); +} #include "../includes/iguana_apiundefs.h" diff --git a/basilisk/basilisk_DEX.c b/basilisk/basilisk_DEX.c index 3e3aaf8ea..5ec6fcaed 100755 --- a/basilisk/basilisk_DEX.c +++ b/basilisk/basilisk_DEX.c @@ -471,51 +471,6 @@ char *basilisk_respond_accept(struct supernet_info *myinfo,bits256 privkey,uint3 retstr = clonestr("{\"error\":\"couldnt find to requestid to choose\"}"); return(retstr); } - -#include "../includes/iguana_apidefs.h" -#include "../includes/iguana_apideclares.h" - -THREE_STRINGS_AND_DOUBLE(tradebot,aveprice,comment,base,rel,basevolume) -{ - double retvals[4],aveprice; cJSON *retjson = cJSON_CreateObject(); - aveprice = instantdex_avehbla(myinfo,retvals,base,rel,basevolume); - jaddstr(retjson,"result","success"); - jaddnum(retjson,"aveprice",aveprice); - jaddnum(retjson,"avebid",retvals[0]); - jaddnum(retjson,"bidvol",retvals[1]); - jaddnum(retjson,"aveask",retvals[2]); - jaddnum(retjson,"askvol",retvals[3]); - return(jprint(retjson,1)); -} - -ZERO_ARGS(InstantDEX,allcoins) -{ - struct iguana_info *tmp; cJSON *native,*notarychains,*basilisk,*virtual,*full,*retjson = cJSON_CreateObject(); - full = cJSON_CreateArray(); - native = cJSON_CreateArray(); - basilisk = cJSON_CreateArray(); - virtual = cJSON_CreateArray(); - notarychains = cJSON_CreateArray(); - HASH_ITER(hh,myinfo->allcoins,coin,tmp) - { - if ( coin->FULLNODE < 0 ) - jaddistr(native,coin->symbol); - //else if ( coin->virtualchain != 0 ) - // jaddistr(virtual,coin->symbol); - else if ( coin->FULLNODE > 0 )//|| coin->VALIDATENODE > 0 ) - jaddistr(full,coin->symbol); - //else if ( coin->notarychain >= 0 ) - // jaddistr(notarychains,coin->symbol); - else jaddistr(basilisk,coin->symbol); - } - jadd(retjson,"native",native); - jadd(retjson,"basilisk",basilisk); - jadd(retjson,"full",full); - //jadd(retjson,"virtual",virtual); - //jadd(retjson,"notarychains",notarychains); - return(jprint(retjson,1)); -} - cJSON *basilisk_unspents(struct supernet_info *myinfo,struct iguana_info *coin,char *coinaddr) { cJSON *unspents=0,*array=0; char *retstr; @@ -558,201 +513,3 @@ char *basilisk_sendrawtransaction(struct supernet_info *myinfo,struct iguana_inf return(retstr); } -STRING_ARG(InstantDEX,available,source) -{ - uint64_t total = 0; int32_t i,n=0; char coinaddr[64]; cJSON *item,*unspents,*retjson = 0; - if ( source != 0 && source[0] != 0 && (coin= iguana_coinfind(source)) != 0 ) - { - if ( myinfo->expiration != 0 ) - { - bitcoin_address(coinaddr,coin->chain->pubtype,myinfo->persistent_pubkey33,33); - if ( (unspents= basilisk_unspents(myinfo,coin,coinaddr)) != 0 ) - { - //printf("available.(%s)\n",jprint(unspents,0)); - if ( (n= cJSON_GetArraySize(unspents)) > 0 ) - { - for (i=0; i %.8f\n",jprint(item,0),dstr(total)); - } - } - free_json(unspents); - } - retjson = cJSON_CreateObject(); - jaddnum(retjson,"result",dstr(total)); - printf(" n.%d total %.8f (%s)\n",n,dstr(total),jprint(retjson,0)); - return(jprint(retjson,1)); - } - printf("InstantDEX_available: need to unlock wallet\n"); - return(clonestr("{\"error\":\"need to unlock wallet\"}")); - } - printf("InstantDEX_available: %s is not active\n",source!=0?source:""); - return(clonestr("{\"error\":\"specified coin is not active\"}")); -} - -HASH_ARRAY_STRING(InstantDEX,request,hash,vals,hexstr) -{ - uint8_t serialized[512]; bits256 privkey; char buf[512],BTCaddr[64],KMDaddr[64]; struct basilisk_request R; int32_t jumblr,iambob,optionhours; cJSON *reqjson; uint32_t datalen=0,DEX_channel; struct iguana_info *bobcoin,*alicecoin; - myinfo->DEXactive = (uint32_t)time(NULL) + 3*BASILISK_TIMEOUT + 60; - jadd64bits(vals,"minamount",jdouble(vals,"minprice") * jdouble(vals,"amount") * SATOSHIDEN * SATOSHIDEN); - if ( jobj(vals,"desthash") == 0 ) - jaddbits256(vals,"desthash",hash); - jadd64bits(vals,"satoshis",jdouble(vals,"amount") * SATOSHIDEN); - jadd64bits(vals,"destsatoshis",jdouble(vals,"destamount") * SATOSHIDEN); - jaddnum(vals,"timestamp",time(NULL)); - if ( (jumblr= jint(vals,"usejumblr")) != 0 ) - privkey = jumblr_privkey(myinfo,BTCaddr,KMDaddr,jumblr == 1 ? JUMBLR_DEPOSITPREFIX : ""); - else privkey = myinfo->persistent_priv; - hash = curve25519(privkey,curve25519_basepoint9()); - if ( jobj(vals,"srchash") == 0 ) - jaddbits256(vals,"srchash",hash); - printf("service.(%s)\n",jprint(vals,0)); - memset(&R,0,sizeof(R)); - if ( basilisk_request_create(&R,vals,hash,juint(vals,"timestamp")) == 0 ) - { - iambob = bitcoin_coinptrs(hash,&bobcoin,&alicecoin,R.src,R.dest,privkey,GENESIS_PUBKEY); - if ( (optionhours= jint(vals,"optionhours")) != 0 ) - { - printf("iambob.%d optionhours.%d R.requestid.%u vs calc %u, q.%u\n",iambob,R.optionhours,R.requestid,basilisk_requestid(&R),R.quoteid); - if ( iambob != 0 && optionhours > 0 ) - { - sprintf(buf,"{\"error\":\"illegal call option request hours.%d when iambob.%d\"}",optionhours,iambob); - printf("ERROR.(%s)\n",buf); - return(clonestr(buf)); - } - else if ( iambob == 0 && optionhours < 0 ) - { - sprintf(buf,"{\"error\":\"illegal put option request hours.%d when iambob.%d\"}",optionhours,iambob); - printf("ERROR.(%s)\n",buf); - return(clonestr(buf)); - } - } - //if ( myinfo->IAMNOTARY != 0 || myinfo->NOTARY.RELAYID >= 0 ) - // R.relaybits = myinfo->myaddr.myipbits; - if ( (reqjson= basilisk_requestjson(&R)) != 0 ) - free_json(reqjson); - datalen = basilisk_rwDEXquote(1,serialized,&R); - //int32_t i; for (i=0; i 0 ) - { - uint32_t msgid;//,crc=0,crcs[2],numiters = 0; uint8_t buf[4096]; - memset(hash.bytes,0,sizeof(hash)); - msgid = (uint32_t)time(NULL); - DEX_channel = 'D' + ((uint32_t)'E' << 8) + ((uint32_t)'X' << 16); - basilisk_channelsend(myinfo,hash,hash,DEX_channel,msgid,serialized,datalen,60); - sleep(3); - /*while ( numiters < 10 && (crc= basilisk_crcsend(myinfo,0,buf,sizeof(buf),hash,myinfo->myaddr.persistent,DEX_channel,msgid,serialized,datalen,crcs)) == 0 ) - { - //printf("didnt get back what was sent\n"); - sleep(3); - basilisk_channelsend(myinfo,myinfo->myaddr.persistent,hash,DEX_channel,msgid,serialized,datalen,60); - numiters++; - }*/ - //if ( crc != 0 )//basilisk_channelsend(myinfo,R.srchash,R.desthash,DEX_channel,(uint32_t)time(NULL),serialized,datalen,30) == 0 ) - return(clonestr("{\"result\":\"DEX message sent\"}")); - //else return(clonestr("{\"error\":\"DEX message couldnt be sent\"}")); - } - return(clonestr("{\"error\":\"DEX message not sent\"}")); -} - -INT_ARG(InstantDEX,automatched,requestid) -{ - // return quoteid - myinfo->DEXactive = (uint32_t)time(NULL) + INSTANTDEX_LOCKTIME; - return(clonestr("{\"result\":\"automatched not yet\"}")); -} - -int32_t InstantDEX_incoming_func(struct supernet_info *myinfo,void *ptr,uint8_t *data,int32_t datalen) -{ - //int32_t i; - //for (i=0; iDEXpoll) + 2*drift; - if ( width < (drift+1) ) - width = 2*drift+1; - else if ( width > 64 ) - width = 64; - myinfo->DEXpoll = now; - retjson = cJSON_CreateObject(); - DEX_channel = 'D' + ((uint32_t)'E' << 8) + ((uint32_t)'X' << 16); - msgid = (uint32_t)time(NULL) + drift; - if ( (retarray= basilisk_channelget(myinfo,zero,myinfo->myaddr.persistent,DEX_channel,msgid,width)) != 0 ) - { - //printf("GOT.(%s)\n",jprint(retarray,0)); - if ( (retval= basilisk_process_retarray(myinfo,0,InstantDEX_process_channelget,data,sizeof(data),DEX_channel,msgid,retarray,InstantDEX_incoming_func)) > 0 ) - { - jaddstr(retjson,"result","success"); - } else jaddstr(retjson,"error","cant process InstantDEX retarray"); - jadd(retjson,"responses",retarray); - } - else - { - jaddstr(retjson,"error","cant do InstantDEX channelget"); - printf("error channelget\n"); - } - return(jprint(retjson,1)); -} - -/*TWO_INTS(InstantDEX,swapstatus,requestid,quoteid) -{ - cJSON *vals; char *retstr; - myinfo->DEXactive = (uint32_t)time(NULL) + INSTANTDEX_LOCKTIME; - //if ( myinfo->IAMLP != 0 ) - // return(basilisk_respond_swapstatus(myinfo,myinfo->myaddr.persistent,requestid,quoteid)); - //else - { - vals = cJSON_CreateObject(); - jaddnum(vals,"requestid",(uint32_t)requestid); - jaddnum(vals,"quoteid",(uint32_t)quoteid); - jaddbits256(vals,"hash",myinfo->myaddr.persistent); - retstr = basilisk_standardservice("SWP",myinfo,0,myinfo->myaddr.persistent,vals,"",1); - free_json(vals); - return(retstr); - } -}*/ - -TWO_INTS(InstantDEX,accept,requestid,quoteid) -{ - cJSON *vals; char *retstr; - myinfo->DEXactive = (uint32_t)time(NULL) + INSTANTDEX_LOCKTIME; - if ( myinfo->IAMLP != 0 || myinfo->dexsock >= 0 || myinfo->subsock >= 0 ) - return(basilisk_respond_accept(myinfo,myinfo->persistent_priv,requestid,quoteid,&myinfo->DEXaccept)); - else - { - vals = cJSON_CreateObject(); - jaddnum(vals,"quoteid",(uint32_t)quoteid); - jaddnum(vals,"requestid",(uint32_t)requestid); - retstr = basilisk_standardservice("ACC",myinfo,0,myinfo->myaddr.persistent,vals,"",1); - free_json(vals); - return(retstr); - } -} - -ZERO_ARGS(InstantDEX,init) -{ - basilisk_swaps_init(myinfo); - return(clonestr("{\"result\":\"success\"}")); -} - -#include "../includes/iguana_apiundefs.h" diff --git a/basilisk/basilisk_MSG.c b/basilisk/basilisk_MSG.c index 3af06c656..6619c4db0 100755 --- a/basilisk/basilisk_MSG.c +++ b/basilisk/basilisk_MSG.c @@ -319,67 +319,6 @@ cJSON *dpow_addmessage(struct supernet_info *myinfo,char *jsonstr) return(retjson); } -#include "../includes/iguana_apidefs.h" -#include "../includes/iguana_apideclares.h" - -HASH_ARRAY_STRING(basilisk,getmessage,hash,vals,hexstr) -{ - uint32_t msgid,width,channel; char *retstr; - if ( bits256_cmp(GENESIS_PUBKEY,jbits256(vals,"srchash")) == 0 ) - jaddbits256(vals,"srchash",hash); - if ( bits256_cmp(GENESIS_PUBKEY,jbits256(vals,"desthash")) == 0 ) - jaddbits256(vals,"desthash",myinfo->myaddr.persistent); - if ( (msgid= juint(vals,"msgid")) == 0 ) - { - msgid = (uint32_t)time(NULL); - jdelete(vals,"msgid"); - jaddnum(vals,"msgid",msgid); - } - if ( myinfo->NOTARY.RELAYID >= 0 || myinfo->dexsock >= 0 || myinfo->subsock >= 0 ) - { - channel = juint(vals,"channel"); - width = juint(vals,"width"); - retstr = basilisk_iterate_MSG(myinfo,channel,msgid,jbits256(vals,"srchash"),jbits256(vals,"desthash"),width); - //printf("getmessage.(%s)\n",retstr); - return(retstr); - } - //printf("getmessage not relay.%d dexsock.%d subsock.%d\n",myinfo->NOTARY.RELAYID,myinfo->dexsock,myinfo->subsock); - return(basilisk_standardservice("MSG",myinfo,0,jbits256(vals,"desthash"),vals,hexstr,1)); -} - -HASH_ARRAY_STRING(basilisk,sendmessage,hash,vals,hexstr) -{ - int32_t keylen,datalen,allocsize = 65536; uint8_t key[BASILISK_KEYSIZE],*space,*space2,*data,*ptr = 0; char *retstr=0; - space = calloc(1,allocsize); - space2 = calloc(1,allocsize); - data = get_dataptr(BASILISK_HDROFFSET,&ptr,&datalen,&space[BASILISK_KEYSIZE],allocsize-BASILISK_KEYSIZE,hexstr); - if ( myinfo->subsock >= 0 || myinfo->dexsock >= 0 || (myinfo->IAMNOTARY != 0 && myinfo->NOTARY.RELAYID >= 0) ) - { - keylen = basilisk_messagekey(key,juint(vals,"channel"),juint(vals,"msgid"),jbits256(vals,"srchash"),jbits256(vals,"desthash")); - if ( data != 0 ) - { - retstr = basilisk_respond_addmessage(myinfo,key,keylen,data,datalen,0,juint(vals,"duration")); - } else printf("no get_dataptr\n"); - if ( retstr != 0 ) - free(retstr); - } //else printf("not notary.%d relayid.%d\n",myinfo->IAMNOTARY,myinfo->NOTARY.RELAYID); - if ( vals != 0 && juint(vals,"fanout") == 0 ) - jaddnum(vals,"fanout",MAX(8,(int32_t)sqrt(myinfo->NOTARY.NUMRELAYS)+2)); - if ( BASILISK_KEYSIZE+datalen < allocsize ) - { - memcpy(space2,key,BASILISK_KEYSIZE); - if ( data != 0 && datalen != 0 ) - memcpy(&space2[BASILISK_KEYSIZE],data,datalen); - dex_reqsend(myinfo,"DEX",space2,datalen+BASILISK_KEYSIZE,1,""); - } else printf("sendmessage space too small error for %d\n",datalen); - free(space); - free(space2); - if ( ptr != 0 ) - free(ptr); - return(basilisk_standardservice("OUT",myinfo,0,jbits256(vals,"desthash"),vals,hexstr,0)); -} -#include "../includes/iguana_apiundefs.h" - int32_t basilisk_channelsend(struct supernet_info *myinfo,bits256 srchash,bits256 desthash,uint32_t channel,uint32_t msgid,uint8_t *data,int32_t datalen,uint32_t duration) { char *retstr,*hexstr,strbuf[4096],*ptr = 0; int32_t retval = -1; cJSON *valsobj; diff --git a/basilisk/basilisk_bitcoin.c b/basilisk/basilisk_bitcoin.c index e601c1e64..3e5aae41b 100755 --- a/basilisk/basilisk_bitcoin.c +++ b/basilisk/basilisk_bitcoin.c @@ -1049,175 +1049,6 @@ cJSON *BTC_makeclaimfunc(struct supernet_info *myinfo,struct exchange_info *exch } #endif - -#include "../includes/iguana_apidefs.h" -#include "../includes/iguana_apideclares.h" - -HASH_ARRAY_STRING(basilisk,value,hash,vals,hexstr) -{ - char *retstr=0,*symbol,*coinaddr,*infostr; cJSON *retjson,*sobj,*info,*addrs,*txoutjson,*txjson,*array; uint32_t basilisktag,blocktime; bits256 txid,blockhash; struct basilisk_item *ptr,Lptr; uint64_t value; int32_t timeoutmillis,vout,height,n,m; - if ( vals == 0 ) - return(clonestr("{\"error\":\"null valsobj\"}")); - //if ( myinfo->IAMNOTARY != 0 || myinfo->NOTARY.RELAYID >= 0 ) - // return(clonestr("{\"error\":\"special relays only do OUT and MSG\"}")); - //if ( coin == 0 ) - { - if ( (symbol= jstr(vals,"symbol")) != 0 || (symbol= jstr(vals,"coin")) != 0 ) - coin = iguana_coinfind(symbol); - } - if ( jobj(vals,"fanout") == 0 ) - jaddnum(vals,"fanout",MAX(5,(int32_t)sqrt(myinfo->NOTARY.NUMRELAYS)+1)); - txid = jbits256(vals,"txid"); - vout = jint(vals,"vout"); - if ( coin != 0 ) - { - if ( coin->FULLNODE < 0 ) - { - if ( (txoutjson= dpow_gettxout(myinfo,coin,txid,vout)) != 0 ) - { - if ( (coinaddr= jstr(txoutjson,"address")) != 0 && (value= SATOSHIDEN*jdouble(txoutjson,"value")) != 0 ) - { - retjson = cJSON_CreateObject(); - jaddstr(retjson,"result","success"); - jaddstr(retjson,"address",coinaddr); - jadd64bits(retjson,"satoshis",value); - jaddnum(retjson,"value",dstr(value)); - jaddnum(retjson,"amount",dstr(value)); - height = dpow_getchaintip(myinfo,&blockhash,&blocktime,0,0,coin); - jaddnum(retjson,"height",height); - jaddnum(retjson,"numconfirms",jint(txoutjson,"confirmations")); - jaddbits256(retjson,"txid",txid); - jaddnum(retjson,"vout",vout); - jaddstr(retjson,"coin",coin->symbol); - } - else - { - free_json(txoutjson); - return(clonestr("{\"error\":\"return from gettxout missing fields\"}")); - } - free_json(txoutjson); - return(jprint(retjson,1)); - } else return(clonestr("{\"error\":\"null return from gettxout\"}")); - } - if ( (basilisktag= juint(vals,"basilisktag")) == 0 ) - basilisktag = rand(); - if ( (timeoutmillis= juint(vals,"timeout")) <= 0 ) - timeoutmillis = BASILISK_TIMEOUT; - if ( coin->FULLNODE > 0 && (ptr= basilisk_bitcoinvalue(&Lptr,myinfo,coin,remoteaddr,basilisktag,timeoutmillis,vals)) != 0 ) - { - retstr = ptr->retstr, ptr->retstr = 0; - ptr->finished = OS_milliseconds() + 10000; - return(retstr); - } - } - if ( myinfo->reqsock >= 0 ) - { - if ( (retstr= _dex_getrawtransaction(myinfo,symbol,txid)) != 0 ) - { - if ( (txoutjson= cJSON_Parse(retstr)) != 0 ) - { - //printf("TX.(%s)\n",jprint(txoutjson,0)); - retjson = cJSON_CreateObject(); - jaddstr(retjson,"result","success"); - jaddnum(retjson,"numconfirms",jint(txoutjson,"confirmations")); - if ( (array= jarray(&n,txoutjson,"vout")) != 0 && vout < n && (txjson= jitem(array,vout)) != 0 ) - { - //printf("txjson.(%s)\n",jprint(txjson,0)); - if ( (value= jdouble(txjson,"value") * SATOSHIDEN) != 0 ) - { - if ( (sobj= jobj(txjson,"scriptPubKey")) != 0 && (addrs= jarray(&m,sobj,"addresses")) != 0 && (coinaddr= jstri(addrs,0)) != 0 ) - jaddstr(retjson,"address",coinaddr); - jadd64bits(retjson,"satoshis",value); - jaddnum(retjson,"value",dstr(value)); - if ( (infostr= _dex_getinfo(myinfo,symbol)) != 0 ) - { - if ( (info= cJSON_Parse(infostr)) != 0 ) - { - if ( (height= jint(info,"blocks")) > 0 ) - { - height -= jint(txoutjson,"confirmations"); - jaddnum(retjson,"height",height); - } - free_json(info); - } - free(infostr); - } - jaddbits256(retjson,"txid",txid); - jaddnum(retjson,"vout",vout); - jaddstr(retjson,"coin",symbol); - free(retstr); - free_json(txoutjson); - return(jprint(retjson,1)); - } - } - free_json(txoutjson); - return(jprint(retjson,1)); - } - return(retstr); - } - } - return(basilisk_standardservice("VAL",myinfo,0,hash,vals,hexstr,1)); -} - -HASH_ARRAY_STRING(basilisk,rawtx,hash,vals,hexstr) -{ - char *retstr=0,*symbol; uint32_t basilisktag; int32_t timeoutmillis,i,retval = -1; uint64_t amount,txfee; cJSON *retarray; - if ( vals == 0 ) - return(clonestr("{\"error\":\"null valsobj\"}")); - //if ( coin == 0 ) - { - if ( (symbol= jstr(vals,"symbol")) != 0 || (symbol= jstr(vals,"coin")) != 0 ) - coin = iguana_coinfind(symbol); - } - if ( jobj(vals,"numrequired") == 0 ) - jaddnum(vals,"numrequired",MIN(3,(int32_t)sqrt(myinfo->NOTARY.NUMRELAYS)+1)); - if ( jobj(vals,"fanout") == 0 ) - jaddnum(vals,"fanout",MAX(3,(int32_t)sqrt(myinfo->NOTARY.NUMRELAYS)+1)); - if ( coin != 0 ) - { - //if ( juint(vals,"burn") == 0 ) - // jaddnum(vals,"burn",0.0001); - if ( (basilisktag= juint(vals,"basilisktag")) == 0 ) - basilisktag = rand(); - if ( (timeoutmillis= juint(vals,"timeout")) <= 0 ) - timeoutmillis = BASILISK_TIMEOUT; - if ( (retstr= basilisk_bitcoinrawtx(myinfo,coin,remoteaddr,basilisktag,timeoutmillis,vals,0)) != 0 ) - { - printf("rawtx.(%s)\n",retstr); - if ( (amount= j64bits(vals,"satoshis")) == 0 ) - amount = jdouble(vals,"value") * SATOSHIDEN; - if ( (txfee= j64bits(vals,"txfee")) == 0 ) - txfee = coin->chain->txfee; - if ( txfee == 0 ) - txfee = 10000; - retval = -1; - if ( (retarray= cJSON_Parse(retstr)) != 0 ) - { - if ( is_cJSON_Array(retarray) != 0 ) - { - for (i=0; iFULLNODE >= 0 ) - return(clonestr("{\"error\":\"no passphrase or no native komodod\"}")); - else - { - safecopy(myinfo->jumblr_passphrase,passphrase,sizeof(myinfo->jumblr_passphrase)); - retjson = cJSON_CreateObject(); - jaddstr(retjson,"result","success"); - privkey = jumblr_privkey(myinfo,BTCaddr,KMDaddr,JUMBLR_DEPOSITPREFIX); - smartaddress_add(myinfo,privkey,BTCaddr,KMDaddr); - myinfo->jumblr_depositkey = curve25519(privkey,curve25519_basepoint9()); - bitcoin_priv2wif(wifstr,privkey,coin->chain->wiftype); - if ( coin->FULLNODE < 0 ) - jumblr_importprivkey(myinfo,coin,wifstr); - jaddstr(retjson,"KMDdeposit",KMDaddr); - jaddstr(retjson,"BTCdeposit",BTCaddr); - if ( (coinbtc= iguana_coinfind("BTC")) != 0 ) - { - bitcoin_priv2wif(wifstr,privkey,coinbtc->chain->wiftype); - if ( coinbtc->FULLNODE < 0 ) - jumblr_importprivkey(myinfo,coinbtc,wifstr); - jaddnum(retjson,"BTCdeposits",dstr(jumblr_balance(myinfo,coinbtc,BTCaddr))); - } - privkey = jumblr_privkey(myinfo,BTCaddr,KMDaddr,""); - smartaddress_add(myinfo,privkey,BTCaddr,KMDaddr); - myinfo->jumblr_pubkey = curve25519(privkey,curve25519_basepoint9()); - jaddstr(retjson,"KMDjumblr",KMDaddr); - jaddstr(retjson,"BTCjumblr",BTCaddr); - if ( coinbtc != 0 ) - jaddnum(retjson,"BTCjumbled",dstr(jumblr_balance(myinfo,coinbtc,BTCaddr))); - return(jprint(retjson,1)); - } -} - -ZERO_ARGS(jumblr,status) -{ - cJSON *retjson; char KMDaddr[64],BTCaddr[64]; struct jumblr_item *ptr,*tmp; struct iguana_info *coinbtc; int64_t received,deposited,jumblred,step_t2z,step_z2z,step_z2t,finished,pending,maxval,minval; - if ( strcmp(coin->symbol,"KMD") == 0 && coin->FULLNODE < 0 && myinfo->jumblr_passphrase[0] != 0 ) - { - jumblr_opidsupdate(myinfo,coin); - retjson = cJSON_CreateObject(); - step_t2z = step_z2z = step_z2t = deposited = finished = pending = 0; - jumblr_privkey(myinfo,BTCaddr,KMDaddr,JUMBLR_DEPOSITPREFIX); - jaddstr(retjson,"KMDdeposit",KMDaddr); - jaddstr(retjson,"BTCdeposit",BTCaddr); - if ( (coinbtc= iguana_coinfind("BTC")) != 0 ) - jaddnum(retjson,"BTCdeposits",dstr(jumblr_balance(myinfo,coinbtc,BTCaddr))); - received = jumblr_receivedby(myinfo,coin,KMDaddr); - deposited = jumblr_balance(myinfo,coin,KMDaddr); - jumblr_privkey(myinfo,BTCaddr,KMDaddr,""); - jaddstr(retjson,"KMDjumblr",KMDaddr); - jaddstr(retjson,"BTCjumblr",BTCaddr); - if ( coinbtc != 0 ) - jaddnum(retjson,"BTCjumbled",dstr(jumblr_balance(myinfo,coinbtc,BTCaddr))); - finished = jumblr_receivedby(myinfo,coin,KMDaddr); - jumblred = jumblr_balance(myinfo,coin,KMDaddr); - HASH_ITER(hh,myinfo->jumblrs,ptr,tmp) - { - if ( strlen(ptr->src) >= 40 ) - { - if ( strlen(ptr->dest) >= 40 ) - step_z2z += ptr->amount; - else step_z2t += ptr->amount; - } else step_t2z += ptr->amount; - } - jaddstr(retjson,"result","success"); - jaddnum(retjson,"deposits",dstr(deposited)); - jaddnum(retjson,"t_to_z",dstr(step_t2z)); - jaddnum(retjson,"z_to_z",dstr(step_z2z)); - jaddnum(retjson,"z_to_t",dstr(step_z2t)); - maxval = MAX(step_t2z,MAX(step_z2z,step_z2t)); - minval = MIN(step_t2z,MIN(step_z2z,step_z2t)); - if ( maxval > minval ) - { - pending = (maxval - minval); - if ( pending < finished*.1 ) - pending = 0; - } - jaddnum(retjson,"pending",dstr(pending)); - jaddnum(retjson,"jumbled",dstr(jumblred)); - jaddnum(retjson,"received",dstr(received)); - jaddnum(retjson,"finished",dstr(finished)); - return(jprint(retjson,1)); - } - else - { - printf("(%s) (%s) %d\n",coin->symbol,myinfo->jumblr_passphrase,coin->FULLNODE); - return(clonestr("{\"error\":\"jumblr status no passphrase or no native komodod\"}")); - } -} - -#include "../includes/iguana_apiundefs.h" diff --git a/basilisk/smartaddress.c b/basilisk/smartaddress.c index 95b15c6e9..ff9707b0c 100755 --- a/basilisk/smartaddress.c +++ b/basilisk/smartaddress.c @@ -88,8 +88,3 @@ int32_t smartaddress_pubkey33(struct supernet_info *myinfo,bits256 *privkeyp,uin return(0); } -#include "../includes/iguana_apidefs.h" -#include "../includes/iguana_apideclares.h" - - -#include "../includes/iguana_apiundefs.h" diff --git a/basilisk/tradebots_liquidity.c b/basilisk/tradebots_liquidity.c index c87cea550..9ce61549b 100755 --- a/basilisk/tradebots_liquidity.c +++ b/basilisk/tradebots_liquidity.c @@ -1238,4 +1238,94 @@ ZERO_ARGS(tradebot,openliquidity) return(jprint(array,1)); } +ZERO_ARGS(tradebot,allbalances) +{ + int32_t i,n; double value,pending; char *base; cJSON *item,*balances = cJSON_CreateObject(); + if ( myinfo->liquidity_currencies == 0 ) + myinfo->liquidity_currencies = cJSON_Parse("[\"KMD\", \"BTC\"]"); + if ( myinfo->liquidity_currencies != 0 && (n= cJSON_GetArraySize(myinfo->liquidity_currencies)) > 0 ) + { + for (i=0; iliquidity_currencies,i); + value = tradebot_balance(myinfo,base); + pending = tradebot_pending(myinfo,base); + item = cJSON_CreateObject(); + jaddnum(item,"value",value); + jaddnum(item,"pending",pending); + jadd(balances,base,item); + } + } + return(jprint(balances,1)); +} + +ZERO_ARGS(tradebot,anchor) +{ + FILE *fp; char *anchorstr,fname[512]; cJSON *anchor; int32_t retval = -1; + if ( (anchorstr= tradebot_allbalances(myinfo,0,0,0)) != 0 ) + { + if ( (anchor= cJSON_Parse(anchorstr)) != 0 ) + { + if ( jobj(anchor,"error") == 0 ) + { + sprintf(fname,"%s/anchor",GLOBAL_DBDIR), OS_compatible_path(fname); + if ( (fp= fopen(fname,"wb")) != 0 ) + { + if ( fwrite(anchorstr,1,strlen(anchorstr)+1,fp) == strlen(anchorstr)+1 ) + retval = 0; + fclose(fp); + } + } + } + free(anchorstr); + } + if ( retval == 0 ) + return(clonestr("{\"result\":\"success\"}")); + else return(clonestr("{\"error\":\"couldnt make anchor file\"}")); +} + +ZERO_ARGS(tradebot,portfolio) +{ + char *currentstr,*anchorstr,fname[512]; long fsize; cJSON *current,*anchor=0,*portfolio=0; + if ( (currentstr= tradebot_allbalances(myinfo,0,0,0)) != 0 ) + { + if ( (current= cJSON_Parse(currentstr)) != 0 ) + { + sprintf(fname,"%s/anchor",GLOBAL_DBDIR), OS_compatible_path(fname); + if ( (anchorstr= OS_filestr(&fsize,fname)) != 0 ) + { + anchor = cJSON_Parse(anchorstr); + free(anchorstr); + } + if ( anchor == 0 ) + anchor = cJSON_Parse("{}"); + portfolio = tradebot_balancesdiff(myinfo,current,anchor); + free_json(current); + } + free(currentstr); + } + if ( portfolio == 0 ) + return(clonestr("{\"result\":\"success\"}")); + else return(jprint(portfolio,1)); +} + +ARRAY_OBJ_INT(tradebot,goals,currencies,vals,targettime) +{ + static bits256 zero; char *targetcoin; int32_t i,n; + if ( currencies != 0 && vals != 0 ) + { + // init things so automatically updates refli.bid and refli.ask + // volume range with margin + // currency percentage value in BTC? target distribution, max percentage, min percentage` + // min price to sell, max price to buy, max volume + n = cJSON_GetArraySize(currencies); + for (i=0; iliquidity_currencies == 0 ) - myinfo->liquidity_currencies = cJSON_Parse("[\"KMD\", \"BTC\"]"); - if ( myinfo->liquidity_currencies != 0 && (n= cJSON_GetArraySize(myinfo->liquidity_currencies)) > 0 ) - { - for (i=0; iliquidity_currencies,i); - value = tradebot_balance(myinfo,base); - pending = tradebot_pending(myinfo,base); - item = cJSON_CreateObject(); - jaddnum(item,"value",value); - jaddnum(item,"pending",pending); - jadd(balances,base,item); - } - } - return(jprint(balances,1)); -} - -ZERO_ARGS(tradebot,anchor) -{ - FILE *fp; char *anchorstr,fname[512]; cJSON *anchor; int32_t retval = -1; - if ( (anchorstr= tradebot_allbalances(myinfo,0,0,0)) != 0 ) - { - if ( (anchor= cJSON_Parse(anchorstr)) != 0 ) - { - if ( jobj(anchor,"error") == 0 ) - { - sprintf(fname,"%s/anchor",GLOBAL_DBDIR), OS_compatible_path(fname); - if ( (fp= fopen(fname,"wb")) != 0 ) - { - if ( fwrite(anchorstr,1,strlen(anchorstr)+1,fp) == strlen(anchorstr)+1 ) - retval = 0; - fclose(fp); - } - } - } - free(anchorstr); - } - if ( retval == 0 ) - return(clonestr("{\"result\":\"success\"}")); - else return(clonestr("{\"error\":\"couldnt make anchor file\"}")); -} - -ZERO_ARGS(tradebot,portfolio) -{ - char *currentstr,*anchorstr,fname[512]; long fsize; cJSON *current,*anchor=0,*portfolio=0; - if ( (currentstr= tradebot_allbalances(myinfo,0,0,0)) != 0 ) - { - if ( (current= cJSON_Parse(currentstr)) != 0 ) - { - sprintf(fname,"%s/anchor",GLOBAL_DBDIR), OS_compatible_path(fname); - if ( (anchorstr= OS_filestr(&fsize,fname)) != 0 ) - { - anchor = cJSON_Parse(anchorstr); - free(anchorstr); - } - if ( anchor == 0 ) - anchor = cJSON_Parse("{}"); - portfolio = tradebot_balancesdiff(myinfo,current,anchor); - free_json(current); - } - free(currentstr); - } - if ( portfolio == 0 ) - return(clonestr("{\"result\":\"success\"}")); - else return(jprint(portfolio,1)); -} - -ARRAY_OBJ_INT(tradebot,goals,currencies,vals,targettime) -{ - static bits256 zero; char *targetcoin; int32_t i,n; - if ( currencies != 0 && vals != 0 ) - { - // init things so automatically updates refli.bid and refli.ask - // volume range with margin - // currency percentage value in BTC? target distribution, max percentage, min percentage` - // min price to sell, max price to buy, max volume - n = cJSON_GetArraySize(currencies); - for (i=0; iinternaladdr,remoteaddr,0,vals,0,0,hash,0)); - } else return(clonestr("{\"error\":\"geckoget needs virtualchain\"}")); - } - return(clonestr("{\"error\":\"geckoget needs BTCD\"}")); -} - -#include "../includes/iguana_apiundefs.h" diff --git a/iguana/SuperNET_keys.c b/iguana/SuperNET_keys.c index 7ecab7989..31cbe6869 100755 --- a/iguana/SuperNET_keys.c +++ b/iguana/SuperNET_keys.c @@ -420,52 +420,4 @@ char *SuperNET_keysinit(struct supernet_info *myinfo,char *argjsonstr) return(coinargs); } -#include "../includes/iguana_apidefs.h" -#include "../includes/iguana_apideclares.h" - -TWO_STRINGS(SuperNET,decryptjson,password,permanentfile) -{ - char pass[8192],fname2[1023],destfname[1024]; cJSON *retjson; bits256 wallethash,wallet2priv; - safecopy(pass,password,sizeof(pass)); - safecopy(fname2,permanentfile,sizeof(fname2)); - wallethash = wallet2priv = GENESIS_PRIVKEY; - if ( strlen(pass) == sizeof(wallethash)*2 && is_hexstr(pass,(int32_t)sizeof(bits256)*2) > 0 ) - wallethash = bits256_conv(pass); - if ( strlen(fname2) == sizeof(wallet2priv)*2 && is_hexstr(fname2,(int32_t)sizeof(bits256)*2) > 0 ) - wallet2priv = bits256_conv(fname2); - if ( (retjson= SuperNET_decryptedjson(destfname,pass,sizeof(pass),wallethash,fname2,sizeof(fname2),wallet2priv)) != 0 ) - { - //printf("decrypt pass.(%s) fname2.(%s) -> destfname.(%s)\n",pass,fname2,destfname); - //obj = jduplicate(jobj(retjson,"payload")); - //jdelete(retjson,"payload"); - //jadd(retjson,"result",obj); - return(jprint(retjson,1)); - } else return(clonestr("{\"error\":\"couldnt decrypt json file\"}")); -} - -THREE_STRINGS(SuperNET,encryptjson,password,permanentfile,payload) -{ - char destfname[4096],pass[8192],fname2[1023]; cJSON *argjson,*retjson = cJSON_CreateObject(); - safecopy(pass,password,sizeof(pass)); - safecopy(fname2,permanentfile,sizeof(fname2)); - argjson = jduplicate(json); - //printf("argjson.(%s)\n",jprint(argjson,0)); - jdelete(argjson,"agent"); - jdelete(argjson,"method"); - jdelete(argjson,"password"); - jdelete(argjson,"permanentfile"); - jdelete(argjson,"timestamp"); - jdelete(argjson,"tag"); - if ( _SuperNET_encryptjson(myinfo,destfname,pass,sizeof(pass),fname2,sizeof(fname2),argjson) == 0 ) - { - jaddstr(retjson,"result","success"); - jaddstr(retjson,"filename",destfname); - } else jaddstr(retjson,"error","couldnt encrypt json file"); - free_json(argjson); - return(jprint(retjson,1)); -} - - -#include "../includes/iguana_apiundefs.h" - diff --git a/iguana/iguana_bitmap.c b/iguana/iguana_bitmap.c index ec1ce5484..89effe210 100755 --- a/iguana/iguana_bitmap.c +++ b/iguana/iguana_bitmap.c @@ -1162,42 +1162,3 @@ void iguana_bitmap(char *space,int32_t max,char *name) } } -#include "../includes/iguana_apidefs.h" -#include "../includes/iguana_apideclares.h" - -STRING_AND_TWOINTS(mouse,change,name,x,y) -{ - printf("mouse (%s) x.%d y.%d\n",name,x,y); - return(clonestr("{\"result\":\"changed\"}")); -} - -STRING_ARG(mouse,leave,name) -{ - printf("mouse (%s) leave\n",name); - return(clonestr("{\"result\":\"left\"}")); -} - -STRING_AND_TWOINTS(mouse,click,name,x,y) -{ - printf("mouse (%s) x.%d y.%d click\n",name,x,y); - return(clonestr("{\"result\":\"click\"}")); -} - -STRING_AND_INT(keyboard,key,name,c) -{ - printf(" KEY.(%s) c.%d (%c)\n",name,c,c); - return(clonestr("{\"result\":\"key\"}")); -} - -STRING_AND_TWOINTS(mouse,image,name,x,y) -{ - printf("mouse CREATE (%s) x.%d y.%d\n",name,x,y); - return(clonestr("{\"result\":\"opened\"}")); -} - -STRING_ARG(mouse,close,name) -{ - printf("mouse CLOSE (%s)\n",name); - return(clonestr("{\"result\":\"closed\"}")); -} -#include "../includes/iguana_apiundefs.h" diff --git a/iguana/iguana_payments.c b/iguana/iguana_payments.c index 5286d37ef..8e7aacf20 100755 --- a/iguana/iguana_payments.c +++ b/iguana/iguana_payments.c @@ -1685,4 +1685,99 @@ THREE_INTS(iguana,splitfunds,satoshis,duplicates,sendflag) return(jprint(retjson,1)); } +P2SH_SPENDAPI(iguana,spendmsig,activecoin,vintxid,vinvout,destaddress,destamount,destaddress2,destamount2,M,N,pubA,wifA,pubB,wifB,pubC,wifC) +{ + struct vin_info V; uint8_t p2sh_rmd160[20],serialized[2096],spendscript[32],pubkeys[3][65],*pubkeyptrs[3]; int32_t spendlen,height = 0; + char msigaddr[64],*retstr; cJSON *retjson,*txobj; struct iguana_info *active; + bits256 signedtxid; char *signedtx; + struct iguana_msgtx msgtx; + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + if ( myinfo->expiration == 0 ) + return(clonestr("{\"error\":\"need to unlock wallet\"}")); + if ( (active= iguana_coinfind(activecoin)) == 0 ) + return(clonestr("{\"error\":\"activecoin isnt active\"}")); + if ( M > N || N > 3 ) + return(clonestr("{\"error\":\"illegal M or N\"}")); + memset(&V,0,sizeof(V)); + txobj = bitcoin_txcreate(active->symbol,active->chain->isPoS,0,coin->chain->normal_txversion,0); + if ( destaddress[0] != 0 && destamount > 0. ) + bitcoin_txaddspend(active,txobj,destaddress,destamount * SATOSHIDEN); + if ( destaddress2[0] != 0 && destamount2 > 0. ) + bitcoin_txaddspend(active,txobj,destaddress2,destamount2 * SATOSHIDEN); + if ( pubA[0] != 0 && (retstr= _setVsigner(active,&V,0,pubA,wifA)) != 0 ) + return(retstr); + if ( N >= 2 && pubB[0] != 0 && (retstr= _setVsigner(active,&V,1,pubB,wifB)) != 0 ) + return(retstr); + if ( N == 3 && pubC[0] != 0 && (retstr= _setVsigner(active,&V,2,pubC,wifC)) != 0 ) + return(retstr); + V.M = M, V.N = N, V.type = IGUANA_SCRIPT_P2SH; + V.p2shlen = bitcoin_MofNspendscript(p2sh_rmd160,V.p2shscript,0,&V); + spendlen = bitcoin_p2shspend(spendscript,0,p2sh_rmd160); + if ( pubA[0] != 0 ) + { + decode_hex(pubkeys[0],(int32_t)strlen(pubA)>>1,pubA); + pubkeyptrs[0] = pubkeys[0]; + } + if ( pubB[0] != 0 ) + { + decode_hex(pubkeys[1],(int32_t)strlen(pubB)>>1,pubB); + pubkeyptrs[1] = pubkeys[1]; + } + if ( pubC[0] != 0 ) + { + decode_hex(pubkeys[2],(int32_t)strlen(pubC)>>1,pubC); + pubkeyptrs[2] = pubkeys[2]; + } + bitcoin_txinput(active,txobj,vintxid,vinvout,0xffffffff,spendscript,spendlen,V.p2shscript,V.p2shlen,pubkeyptrs,N,0,0); + bitcoin_address(msigaddr,active->chain->p2shtype,V.p2shscript,V.p2shlen); + retjson = cJSON_CreateObject(); + if ( bitcoin_verifyvins(active,height,&signedtxid,&signedtx,&msgtx,serialized,sizeof(serialized),&V,SIGHASH_ALL,1,V.suppress_pubkeys) == 0 ) + { + jaddstr(retjson,"result","msigtx"); + if ( signedtx != 0 ) + jaddstr(retjson,"signedtx",signedtx), free(signedtx); + jaddbits256(retjson,"txid",signedtxid); + } else jaddstr(retjson,"error","couldnt sign tx"); + jaddstr(retjson,"msigaddr",msigaddr); + return(jprint(retjson,1)); +} + +STRING_ARRAY_OBJ_STRING(bitcoinrpc,signrawtransaction,rawtx,vins,privkeys,sighash) +{ + char *signedtx = 0; struct vin_info *V; bits256 signedtxid; int32_t complete,numinputs = 1; struct iguana_msgtx msgtx; cJSON *retjson; int uselessbitcoin_error = 0; + retjson = cJSON_CreateObject(); + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + if ( myinfo->expiration == 0 ) + return(clonestr("{\"error\":\"need to unlock wallet\"}")); + //printf("rawtx.(%s) vins.(%s) privkeys.(%s) sighash.(%s)\n",rawtx,jprint(vins,0),jprint(privkeys,0),sighash); + if ( sighash == 0 || sighash[0] == 0 ) + sighash = "ALL"; + if ( strcmp(sighash,"ALL") != 0 ) + jaddstr(retjson,"error","only sighash all (ALL) supported for now"); + if ( (numinputs= cJSON_GetArraySize(vins)) > 0 ) + { + V = calloc(numinputs,sizeof(*V)); + memset(&msgtx,0,sizeof(msgtx)); + if ( (complete= iguana_signrawtransaction(myinfo,coin,coin->blocks.hwmchain.height,&msgtx,&signedtx,&signedtxid,V,numinputs,rawtx,vins,privkeys)) >= 0 ) + { + if ( signedtx != 0 ) + { + jaddstr(retjson,"result",signedtx); + jadd(retjson,"complete",complete!=0?jtrue():jfalse()); + free(signedtx); + } else jaddstr(retjson,"error",uselessbitcoin_error != 0 ? "-22" : "no transaction from verifyvins"); + } + else if ( complete == -2 ) + jaddstr(retjson,"error",uselessbitcoin_error != 0 ? "-22" : "hex2json -> json2hex error"); + else if ( complete == -1 ) + jaddstr(retjson,"error",uselessbitcoin_error != 0 ? "-22" : "couldnt load serialized tx or mismatched numinputs"); + free(V); + //for (i=0; iexpiration == 0 ) - return(clonestr("{\"error\":\"need to unlock wallet\"}")); - if ( (active= iguana_coinfind(activecoin)) == 0 ) - return(clonestr("{\"error\":\"activecoin isnt active\"}")); - if ( M > N || N > 3 ) - return(clonestr("{\"error\":\"illegal M or N\"}")); - memset(&V,0,sizeof(V)); - txobj = bitcoin_txcreate(active->symbol,active->chain->isPoS,0,coin->chain->normal_txversion,0); - if ( destaddress[0] != 0 && destamount > 0. ) - bitcoin_txaddspend(active,txobj,destaddress,destamount * SATOSHIDEN); - if ( destaddress2[0] != 0 && destamount2 > 0. ) - bitcoin_txaddspend(active,txobj,destaddress2,destamount2 * SATOSHIDEN); - if ( pubA[0] != 0 && (retstr= _setVsigner(active,&V,0,pubA,wifA)) != 0 ) - return(retstr); - if ( N >= 2 && pubB[0] != 0 && (retstr= _setVsigner(active,&V,1,pubB,wifB)) != 0 ) - return(retstr); - if ( N == 3 && pubC[0] != 0 && (retstr= _setVsigner(active,&V,2,pubC,wifC)) != 0 ) - return(retstr); - V.M = M, V.N = N, V.type = IGUANA_SCRIPT_P2SH; - V.p2shlen = bitcoin_MofNspendscript(p2sh_rmd160,V.p2shscript,0,&V); - spendlen = bitcoin_p2shspend(spendscript,0,p2sh_rmd160); - if ( pubA[0] != 0 ) - { - decode_hex(pubkeys[0],(int32_t)strlen(pubA)>>1,pubA); - pubkeyptrs[0] = pubkeys[0]; - } - if ( pubB[0] != 0 ) - { - decode_hex(pubkeys[1],(int32_t)strlen(pubB)>>1,pubB); - pubkeyptrs[1] = pubkeys[1]; - } - if ( pubC[0] != 0 ) - { - decode_hex(pubkeys[2],(int32_t)strlen(pubC)>>1,pubC); - pubkeyptrs[2] = pubkeys[2]; - } - bitcoin_txinput(active,txobj,vintxid,vinvout,0xffffffff,spendscript,spendlen,V.p2shscript,V.p2shlen,pubkeyptrs,N,0,0); - bitcoin_address(msigaddr,active->chain->p2shtype,V.p2shscript,V.p2shlen); - retjson = cJSON_CreateObject(); - if ( bitcoin_verifyvins(active,height,&signedtxid,&signedtx,&msgtx,serialized,sizeof(serialized),&V,SIGHASH_ALL,1,V.suppress_pubkeys) == 0 ) - { - jaddstr(retjson,"result","msigtx"); - if ( signedtx != 0 ) - jaddstr(retjson,"signedtx",signedtx), free(signedtx); - jaddbits256(retjson,"txid",signedtxid); - } else jaddstr(retjson,"error","couldnt sign tx"); - jaddstr(retjson,"msigaddr",msigaddr); - return(jprint(retjson,1)); -} - int32_t iguana_signrawtransaction(struct supernet_info *myinfo,struct iguana_info *coin,int32_t height,struct iguana_msgtx *msgtx,char **signedtxp,bits256 *signedtxidp,struct vin_info *V,int32_t numinputs,char *rawtx,cJSON *vins,cJSON *privkeysjson) { uint8_t *serialized,*serialized2,*serialized3,*serialized4,*extraspace,pubkeys[64][33]; int32_t finalized,i,len,n,z,plen,maxsize,complete = 0,extralen = 65536; char *privkeystr,*signedtx = 0; bits256 privkeys[64],privkey,txid; cJSON *item; cJSON *txobj = 0; @@ -1535,43 +1473,4 @@ int32_t iguana_signrawtransaction(struct supernet_info *myinfo,struct iguana_inf return(complete); } -STRING_ARRAY_OBJ_STRING(bitcoinrpc,signrawtransaction,rawtx,vins,privkeys,sighash) -{ - char *signedtx = 0; struct vin_info *V; bits256 signedtxid; int32_t complete,numinputs = 1; struct iguana_msgtx msgtx; cJSON *retjson; int uselessbitcoin_error = 0; - retjson = cJSON_CreateObject(); - if ( remoteaddr != 0 ) - return(clonestr("{\"error\":\"no remote\"}")); - if ( myinfo->expiration == 0 ) - return(clonestr("{\"error\":\"need to unlock wallet\"}")); - //printf("rawtx.(%s) vins.(%s) privkeys.(%s) sighash.(%s)\n",rawtx,jprint(vins,0),jprint(privkeys,0),sighash); - if ( sighash == 0 || sighash[0] == 0 ) - sighash = "ALL"; - if ( strcmp(sighash,"ALL") != 0 ) - jaddstr(retjson,"error","only sighash all (ALL) supported for now"); - if ( (numinputs= cJSON_GetArraySize(vins)) > 0 ) - { - V = calloc(numinputs,sizeof(*V)); - memset(&msgtx,0,sizeof(msgtx)); - if ( (complete= iguana_signrawtransaction(myinfo,coin,coin->blocks.hwmchain.height,&msgtx,&signedtx,&signedtxid,V,numinputs,rawtx,vins,privkeys)) >= 0 ) - { - if ( signedtx != 0 ) - { - jaddstr(retjson,"result",signedtx); - jadd(retjson,"complete",complete!=0?jtrue():jfalse()); - free(signedtx); - } else jaddstr(retjson,"error",uselessbitcoin_error != 0 ? "-22" : "no transaction from verifyvins"); - } - else if ( complete == -2 ) - jaddstr(retjson,"error",uselessbitcoin_error != 0 ? "-22" : "hex2json -> json2hex error"); - else if ( complete == -1 ) - jaddstr(retjson,"error",uselessbitcoin_error != 0 ? "-22" : "couldnt load serialized tx or mismatched numinputs"); - free(V); - //for (i=0; iinternaladdr,remoteaddr,0,vals,0,0,hash,0)); + } else return(clonestr("{\"error\":\"geckoget needs virtualchain\"}")); + } + return(clonestr("{\"error\":\"geckoget needs BTCD\"}")); +} + +TWO_STRINGS(SuperNET,decryptjson,password,permanentfile) +{ + char pass[8192],fname2[1023],destfname[1024]; cJSON *retjson; bits256 wallethash,wallet2priv; + safecopy(pass,password,sizeof(pass)); + safecopy(fname2,permanentfile,sizeof(fname2)); + wallethash = wallet2priv = GENESIS_PRIVKEY; + if ( strlen(pass) == sizeof(wallethash)*2 && is_hexstr(pass,(int32_t)sizeof(bits256)*2) > 0 ) + wallethash = bits256_conv(pass); + if ( strlen(fname2) == sizeof(wallet2priv)*2 && is_hexstr(fname2,(int32_t)sizeof(bits256)*2) > 0 ) + wallet2priv = bits256_conv(fname2); + if ( (retjson= SuperNET_decryptedjson(destfname,pass,sizeof(pass),wallethash,fname2,sizeof(fname2),wallet2priv)) != 0 ) + { + //printf("decrypt pass.(%s) fname2.(%s) -> destfname.(%s)\n",pass,fname2,destfname); + //obj = jduplicate(jobj(retjson,"payload")); + //jdelete(retjson,"payload"); + //jadd(retjson,"result",obj); + return(jprint(retjson,1)); + } else return(clonestr("{\"error\":\"couldnt decrypt json file\"}")); +} + +THREE_STRINGS(SuperNET,encryptjson,password,permanentfile,payload) +{ + char destfname[4096],pass[8192],fname2[1023]; cJSON *argjson,*retjson = cJSON_CreateObject(); + safecopy(pass,password,sizeof(pass)); + safecopy(fname2,permanentfile,sizeof(fname2)); + argjson = jduplicate(json); + //printf("argjson.(%s)\n",jprint(argjson,0)); + jdelete(argjson,"agent"); + jdelete(argjson,"method"); + jdelete(argjson,"password"); + jdelete(argjson,"permanentfile"); + jdelete(argjson,"timestamp"); + jdelete(argjson,"tag"); + if ( _SuperNET_encryptjson(myinfo,destfname,pass,sizeof(pass),fname2,sizeof(fname2),argjson) == 0 ) + { + jaddstr(retjson,"result","success"); + jaddstr(retjson,"filename",destfname); + } else jaddstr(retjson,"error","couldnt encrypt json file"); + free_json(argjson); + return(jprint(retjson,1)); +} + STRING_ARG(SuperNET,addr2rmd160,address) { diff --git a/includes/iguana_funcs.h b/includes/iguana_funcs.h index f36ea10e4..0dec6a079 100755 --- a/includes/iguana_funcs.h +++ b/includes/iguana_funcs.h @@ -15,6 +15,8 @@ #ifndef H_IGUANAFUNCS_H #define H_IGUANAFUNCS_H +#define SIGHASH_ALL 1 + // peers int32_t iguana_verifypeer(struct iguana_info *coin,void *key,void *value,int32_t itemind,int32_t itemsize); int32_t iguana_peermetrics(struct supernet_info *myinfo,struct iguana_info *coin); @@ -316,6 +318,10 @@ int32_t bitcoin_changescript(struct iguana_info *coin,uint8_t *changescript,int3 //cJSON *bitcoin_addinput(struct iguana_info *coin,cJSON *txobj,bits256 txid,int32_t vout,uint32_t sequenceid,uint8_t *spendscript,int32_t spendlen,uint8_t *redeemscript,int32_t p2shlen,uint8_t *pubkeys[],int32_t numpubkeys); int32_t bitcoin_verifytx(struct iguana_info *coin,bits256 *signedtxidp,char **signedtx,char *rawtxstr,struct vin_info *V,int32_t numinputs); int32_t bitcoin_verify(void *ctx,uint8_t *sig,int32_t siglen,bits256 txhash2,uint8_t *pubkey,int32_t plen); +cJSON *SuperNET_decryptedjson(char *destfname,char *passphrase,int32_t passsize,bits256 wallethash,char *fname2fa,int32_t fnamesize,bits256 wallet2priv); +int32_t bitcoin_txaddspend(struct iguana_info *coin,cJSON *txobj,char *destaddress,uint64_t satoshis); +char *_setVsigner(struct iguana_info *coin,struct vin_info *V,int32_t ind,char *pubstr,char *wifstr); + char *bitcoin_json2hex(struct supernet_info *myinfo,struct iguana_info *coin,bits256 *txidp,cJSON *txjson,struct vin_info *V); int32_t bitcoin_addr2rmd160(uint8_t *addrtypep,uint8_t rmd160[20],char *coinaddr); char *issue_startForging(struct supernet_info *myinfo,char *secret);