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

680 lines
30 KiB

/******************************************************************************
* Copyright © 2014-2017 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. *
* *
******************************************************************************/
// included from basilisk.c
// deposit address <coin> -> corresponding KMD address, if KMD deposit starts JUMBLR
// jumblr address <coin> is the destination of JUMBLR and JUMBLR BTC (would need tracking to map back to non-BTC)
// <symbol> address <coin> is DEX'ed for <SYMBOL>
// return value convention: -1 error, 0 partial match, >= 1 exact match
int32_t smartaddress_type(char *typestr)
{
char upper[64];
if ( strcmp(typestr,"deposit") != 0 && strcmp(typestr,"jumblr") != 0 && strcmp(typestr,"dividend") != 0 && strcmp(typestr,"pangea") != 0 )
{
upper[sizeof(upper)-1] = 0;
strncpy(upper,typestr,sizeof(upper)-1);
touppercase(upper);
if ( iguana_coinfind(upper) != 0 )
return(0);
else return(-1);
}
return(1);
}
bits256 jumblr_privkey(struct supernet_info *myinfo,char *coinaddr,uint8_t pubtype,char *KMDaddr,char *prefix)
{
bits256 privkey,pubkey; uint8_t pubkey33[33]; char passphrase[sizeof(myinfo->jumblr_passphrase) + 64];
sprintf(passphrase,"%s%s",prefix,myinfo->jumblr_passphrase);
if ( myinfo->jumblr_passphrase[0] == 0 )
strcpy(myinfo->jumblr_passphrase,"password");
conv_NXTpassword(privkey.bytes,pubkey.bytes,(uint8_t *)passphrase,(int32_t)strlen(passphrase));
bitcoin_pubkey33(myinfo->ctx,pubkey33,privkey);
bitcoin_address(coinaddr,pubtype,pubkey33,33);
bitcoin_address(KMDaddr,60,pubkey33,33);
//printf("(%s) -> (%s %s)\n",passphrase,coinaddr,KMDaddr);
return(privkey);
}
cJSON *smartaddress_extrajson(struct smartaddress *ap)
{
cJSON *retjson = cJSON_CreateObject();
if ( strcmp(ap->typestr,"dividend") == 0 )
{
}
return(retjson);
}
cJSON *smartaddress_json(struct smartaddress *ap)
{
char coinaddr[64],symbol[64]; uint8_t desttype,tmp,rmd160[20]; int32_t j,n; struct iguana_info *coin,*dest; cJSON *array,*item,*retjson; double amount;
retjson = cJSON_CreateObject();
jaddstr(retjson,"type",ap->typestr);
strcpy(symbol,ap->typestr), touppercase(symbol);
if ( (dest= iguana_coinfind(symbol)) != 0 )
desttype = dest->chain->pubtype;
else desttype = 60;
if ( (n= ap->numsymbols) > 0 )
{
array = cJSON_CreateArray();
for (j=0; j<n; j++)
{
if ( (coin= iguana_coinfind(ap->symbols[j].symbol)) != 0 )
{
bitcoin_address(coinaddr,coin->chain->pubtype,ap->pubkey33,33);
item = cJSON_CreateObject();
jaddstr(item,"coin",coin->symbol);
jaddstr(item,"address",coinaddr);
if ( (amount= ap->symbols[j].srcavail) != 0 )
jaddnum(item,"sourceamount",amount);
if ( dest != 0 )
{
bitcoin_addr2rmd160(&tmp,rmd160,coinaddr);
bitcoin_address(coinaddr,desttype,rmd160,20);
jaddstr(item,"dest",coinaddr);
if ( (amount= ap->symbols[j].destamount) != 0 )
jaddnum(item,"destamount",amount);
if ( coin->DEXinfo.depositaddr[0] != 0 )
{
jaddstr(item,"jumblr_deposit",coin->DEXinfo.depositaddr);
jaddnum(item,"deposit_avail",coin->DEXinfo.avail);
}
if ( coin->DEXinfo.jumblraddr[0] != 0 )
{
jaddstr(item,"jumblr",coin->DEXinfo.jumblraddr);
jaddnum(item,"jumblr_avail",coin->DEXinfo.jumblravail);
}
if ( ap->symbols[j].maxbid != 0. )
jaddnum(item,"maxbid",ap->symbols[j].maxbid);
if ( ap->symbols[j].minask != 0. )
jaddnum(item,"minask",ap->symbols[j].minask);
}
jadd(item,"extra",smartaddress_extrajson(ap));
jaddi(array,item);
}
}
jadd(retjson,"coins",array);
}
return(retjson);
}
void smartaddress_symboladd(struct smartaddress *ap,char *symbol,double maxbid,double minask)
{
char tmp[64]; struct smartaddress_symbol *sp;
strcpy(tmp,ap->typestr), touppercase(tmp);
if ( strcmp(tmp,symbol) != 0 )
{
ap->symbols = realloc(ap->symbols,(ap->numsymbols+1) * sizeof(*ap->symbols));
sp = &ap->symbols[ap->numsymbols++];
memset(sp,0,sizeof(*sp));
safecopy(sp->symbol,symbol,sizeof(sp->symbol));
sp->maxbid = maxbid;
sp->minask = minask;
printf("symboladd.%d (%s) <- (%s %f %f)\n",ap->numsymbols,ap->typestr,symbol,maxbid,minask);
}
}
struct smartaddress *smartaddressptr(struct smartaddress_symbol **ptrp,struct supernet_info *myinfo,char *_type,char *_symbol)
{
char type[64],symbol[64]; int32_t i,j,n; struct smartaddress *ap;
if ( ptrp != 0 )
*ptrp = 0;
strcpy(type,_type), tolowercase(type);
strcpy(symbol,_symbol), touppercase(symbol);
for (i=0; i<myinfo->numsmartaddrs; i++)
{
ap = &myinfo->smartaddrs[i];
if ( strcmp(type,ap->typestr) == 0 )
{
n = ap->numsymbols;
for (j=0; j<n; j++)
{
if ( strcmp(ap->symbols[j].symbol,symbol) == 0 )
{
if ( ptrp != 0 )
*ptrp = &ap->symbols[j];
return(ap);
}
}
}
}
return(0);
}
void smartaddress_minmaxupdate(struct supernet_info *myinfo,char *_type,char *_symbol,double maxbid,double minask)
{
struct smartaddress *ap; struct smartaddress_symbol *sp;
if ( (ap= smartaddressptr(&sp,myinfo,_type,_symbol)) != 0 && sp != 0 )
{
dxblend(&sp->maxbid,maxbid,0.5);
dxblend(&sp->minask,minask,0.5);
}
}
void smartaddress_availupdate(struct supernet_info *myinfo,char *_type,char *_symbol,double srcavail,double destamount)
{
struct smartaddress *ap; struct smartaddress_symbol *sp;
if ( (ap= smartaddressptr(&sp,myinfo,_type,_symbol)) != 0 && sp != 0 )
{
if ( srcavail > SMALLVAL )
sp->srcavail = srcavail;
if ( destamount > SMALLVAL )
sp->destamount = destamount;
}
}
int32_t _smartaddress_add(struct supernet_info *myinfo,bits256 privkey,char *type,char *symbol,double maxbid,double minask)
{
char coinaddr[64]; uint8_t addrtype,rmd160[20]; struct smartaddress *ap; int32_t i,j,n;
if ( myinfo->numsmartaddrs < sizeof(myinfo->smartaddrs)/sizeof(*myinfo->smartaddrs) )
{
for (i=0; i<myinfo->numsmartaddrs; i++)
{
ap = &myinfo->smartaddrs[i];
if ( strcmp(type,ap->typestr) == 0 && bits256_cmp(ap->privkey,privkey) == 0 )
{
n = ap->numsymbols;
for (j=0; j<n; j++)
{
if ( strcmp(ap->symbols[j].symbol,symbol) == 0 )
{
ap->symbols[j].maxbid = maxbid;
ap->symbols[j].minask = minask;
if ( maxbid > SMALLVAL && minask > SMALLVAL && smartaddress_type(type) == 0 )
smartaddress_minmaxupdate(myinfo,symbol,type,1./minask,1./maxbid);
return(0);
}
}
smartaddress_symboladd(ap,symbol,maxbid,minask);
return(i+1);
}
}
ap = &myinfo->smartaddrs[myinfo->numsmartaddrs];
if ( smartaddress_type(symbol) < 0 )
return(-1);
strcpy(ap->typestr,type);
smartaddress_symboladd(ap,"KMD",0.,0.);
smartaddress_symboladd(ap,"BTC",0.,0.);
ap->privkey = privkey;
bitcoin_pubkey33(myinfo->ctx,ap->pubkey33,privkey);
calc_rmd160_sha256(ap->rmd160,ap->pubkey33,33);
ap->pubkey = curve25519(privkey,curve25519_basepoint9());
char str[65]; printf("pubkey.(%s) ",bits256_str(str,ap->pubkey));
bitcoin_address(coinaddr,0,ap->pubkey33,33);
for (i=0; i<20; i++)
printf("%02x",ap->rmd160[i]);
bitcoin_addr2rmd160(&addrtype,rmd160,coinaddr);
printf(", ");
for (i=0; i<20; i++)
printf("%02x",rmd160[i]);
printf (" <- rmd160 for %d %s\n",myinfo->numsmartaddrs,coinaddr);
return(++myinfo->numsmartaddrs + 1);
}
printf("too many smartaddresses %d vs %d\n",myinfo->numsmartaddrs,(int32_t)(sizeof(myinfo->smartaddrs)/sizeof(*myinfo->smartaddrs)));
return(-1);
}
int32_t smartaddress_add(struct supernet_info *myinfo,bits256 privkey,char *type,char *symbol,double maxbid,double minask)
{
int32_t retval;
portable_mutex_lock(&myinfo->smart_mutex);
retval = _smartaddress_add(myinfo,privkey,type,symbol,maxbid,minask);
portable_mutex_unlock(&myinfo->smart_mutex);
return(retval);
}
int32_t smartaddress_symbolmatch(char *typestr,double *bidaskp,struct smartaddress *ap,char *symbol)
{
int32_t j,n;
strcpy(typestr,ap->typestr);
if ( (n= ap->numsymbols) > 0 )
{
for (j=0; j<n; j++)
{
if ( strcmp(ap->symbols[j].symbol,symbol) == 0 )
{
bidaskp[0] = ap->symbols[j].maxbid;
bidaskp[1] = ap->symbols[j].minask;
return(j);
}
}
}
return(-1);
}
int32_t smartaddress(struct supernet_info *myinfo,char *typestr,double *bidaskp,bits256 *privkeyp,char *symbol,char *coinaddr)
{
int32_t i,j,retval = -1; uint8_t addrtype,rmd160[20]; struct smartaddress *ap;
memset(privkeyp,0,sizeof(*privkeyp));
memset(bidaskp,0,sizeof(*bidaskp) * 2);
bitcoin_addr2rmd160(&addrtype,rmd160,coinaddr);
portable_mutex_lock(&myinfo->smart_mutex);
for (i=0; i<myinfo->numsmartaddrs; i++)
if ( memcmp(myinfo->smartaddrs[i].rmd160,rmd160,20) == 0 )
{
ap = &myinfo->smartaddrs[i];
*privkeyp = ap->privkey;
if ( (j= smartaddress_symbolmatch(typestr,bidaskp,ap,symbol)) >= 0 )
retval = 0;
else retval = (i+1);
break;
}
portable_mutex_unlock(&myinfo->smart_mutex);
for (i=0; i<20; i++)
printf("%02x",rmd160[i]);
printf(" <- rmd160 smartaddress cant find (%s) of %d\n",coinaddr,myinfo->numsmartaddrs);
return(retval);
}
int32_t smartaddress_pubkey(struct supernet_info *myinfo,char *typestr,double *bidaskp,bits256 *privkeyp,char *symbol,bits256 pubkey)
{
int32_t i,j,retval = -1; struct smartaddress *ap;
memset(privkeyp,0,sizeof(*privkeyp));
memset(bidaskp,0,sizeof(*bidaskp) * 2);
portable_mutex_lock(&myinfo->smart_mutex);
for (i=0; i<myinfo->numsmartaddrs; i++)
if ( bits256_cmp(myinfo->smartaddrs[i].pubkey,pubkey) == 0 )
{
ap = &myinfo->smartaddrs[i];
*privkeyp = ap->privkey;
if ( (j= smartaddress_symbolmatch(typestr,bidaskp,ap,symbol)) >= 0 )
retval = 0;
else retval = (i+1);
break;
}
portable_mutex_unlock(&myinfo->smart_mutex);
char str[65]; if ( retval < 0 )
printf("smartaddress_pubkey no match for %s\n",bits256_str(str,pubkey));
return(retval);
}
int32_t smartaddress_pubkey33(struct supernet_info *myinfo,char *typestr,double *bidaskp,bits256 *privkeyp,char *symbol,uint8_t *pubkey33)
{
int32_t i,j,retval = -1; struct smartaddress *ap;
memset(privkeyp,0,sizeof(*privkeyp));
memset(bidaskp,0,sizeof(*bidaskp) * 2);
portable_mutex_lock(&myinfo->smart_mutex);
for (i=0; i<myinfo->numsmartaddrs; i++)
if ( memcmp(myinfo->smartaddrs[i].pubkey33,pubkey33,33) == 0 )
{
ap = &myinfo->smartaddrs[i];
*privkeyp = ap->privkey;
if ( (j= smartaddress_symbolmatch(typestr,bidaskp,ap,symbol)) >= 0 )
retval = 0;
else retval = (i+1);
break;
}
portable_mutex_unlock(&myinfo->smart_mutex);
return(retval);
}
void smartaddress_CMCname(char *CMCname,char *symbol)
{
if ( strcmp(symbol,"KMD") == 0 )
strcpy(CMCname,"komodo");
else if ( strcmp(symbol,"BTC") == 0 )
strcpy(CMCname,"bitcoin");
}
void smartaddress_coinupdate(struct supernet_info *myinfo,char *symbol,double BTC2KMD,double KMDavail,double KMD2USD)
{
int32_t r; double avebid,aveask,highbid,lowask,CMC_average,changes[3]; struct iguana_info *coin; struct DEXcoin_info *ptr;
if ( (coin= iguana_coinfind(symbol)) != 0 )
{
ptr = &coin->DEXinfo;
ptr->coin = coin;
if ( coin->CMCname[0] == 0 )
smartaddress_CMCname(coin->CMCname,symbol);
r = (((symbol[0]^symbol[1]^symbol[2])&0x7f) % 15) - 7; // 53 to 67 seconds
if ( time(NULL) > (ptr->lasttime + 60 + r) )
{
if ( strcmp(symbol,ptr->symbol) != 0 )
{
safecopy(ptr->symbol,symbol,sizeof(ptr->symbol));
safecopy(ptr->CMCname,coin->CMCname,sizeof(ptr->CMCname));
}
ptr->deposit_privkey = jumblr_privkey(myinfo,ptr->depositaddr,coin->chain->pubtype,ptr->KMDdepositaddr,JUMBLR_DEPOSITPREFIX);
ptr->jumblr_privkey = jumblr_privkey(myinfo,ptr->jumblraddr,coin->chain->pubtype,ptr->KMDjumblraddr,"");
ptr->avail = dstr(jumblr_balance(myinfo,coin,ptr->depositaddr));
ptr->jumblravail = dstr(jumblr_balance(myinfo,ptr->coin,ptr->jumblraddr));
if ( strcmp(symbol,"USD") == 0 )
{
if ( KMD2USD > SMALLVAL )
{
ptr->kmdprice = 1./ KMD2USD;
if ( (ptr->BTC2KMD= BTC2KMD) > SMALLVAL )
ptr->btcprice = ptr->kmdprice * BTC2KMD;
}
printf("USD btcprice %.8f kmdprice %.8f\n",ptr->btcprice,ptr->kmdprice);
}
else
{
if ( strcmp(symbol,"BTC") == 0 )
ptr->btcprice = 1.;
else if ( coin->CMCname[0] != 0 && (ptr->btcprice == 0. || (ptr->counter++ % 10) == 0) )
ptr->btcprice = get_theoretical(&avebid,&aveask,&highbid,&lowask,&CMC_average,changes,coin->CMCname,symbol,"BTC",&ptr->USD_average);
if ( strcmp("KMD",symbol) == 0 )
ptr->kmdprice = 1.;
else if ( (ptr->BTC2KMD= BTC2KMD) > SMALLVAL )
ptr->kmdprice = ptr->btcprice / BTC2KMD;
}
ptr->lasttime = (uint32_t)time(NULL);
printf("%s avail %.8f KMDavail %.8f btcprice %.8f deposit.(%s %s) -> jumblr.(%s %s)\n",symbol,ptr->avail,KMDavail,ptr->btcprice,ptr->depositaddr,ptr->KMDdepositaddr,ptr->jumblraddr,ptr->KMDjumblraddr);
}
} // else printf("skip\n");
}
void smartaddress_dex(struct supernet_info *myinfo,char *type,int32_t selector,struct iguana_info *basecoin,char *coinaddr,double maxavail,struct iguana_info *relcoin,double maxbid,double minask,cJSON *extraobj,double maxvol)
{
double minamount,minbtc,price,avail,vol,btc2kmd,basebtc,relbtc,baseusd,relusd; char *retstr; cJSON *vals; bits256 hash; struct smartaddress *ap;
basebtc = basecoin->DEXinfo.btcprice;
relbtc = relcoin->DEXinfo.btcprice;
baseusd = basecoin->DEXinfo.USD_average;
relusd = relcoin->DEXinfo.USD_average;
if ( (btc2kmd= basecoin->DEXinfo.BTC2KMD) < SMALLVAL && (btc2kmd= relcoin->DEXinfo.BTC2KMD) < SMALLVAL )
return;
minamount = price = 0.;
if ( basebtc < SMALLVAL && relbtc < SMALLVAL )
return;
if ( myinfo->DEXratio < .95 || myinfo->DEXratio > 1.01 )
myinfo->DEXratio = 0.995;
if ( basebtc < SMALLVAL || relbtc < SMALLVAL )
{
if ( (price= maxbid) > SMALLVAL )
{
if ( basebtc < SMALLVAL )
basebtc = price * relbtc, printf("calculated basebtc %.8f from (%.8f * %.8f)\n",basebtc,price,relbtc);
else if ( relbtc < SMALLVAL )
relbtc = basebtc / price, printf("calculated relbtc %.8f from (%.8f / %.8f)\n",relbtc,basebtc,price); // price * relbtc == basebtc
}
} else price = myinfo->DEXratio * (basebtc / relbtc);
minbtc = btc2kmd * (JUMBLR_INCR + 3*(JUMBLR_INCR * JUMBLR_FEE + JUMBLR_TXFEE));
if ( minamount == 0. && basebtc > SMALLVAL )
minamount = (minbtc / basebtc);
printf("DEX %s/%s maxavail %.8f minbtc %.8f btcprice %.8f -> minamount %.8f price %.8f vs maxbid %.8f DEXratio %.5f DEXpending %.8f\n",basecoin->symbol,relcoin->symbol,maxavail,minbtc,basecoin->DEXinfo.btcprice,minamount,price,maxbid,myinfo->DEXratio,basecoin->DEXinfo.DEXpending);
if ( minamount > SMALLVAL && maxavail > minamount + basecoin->DEXinfo.DEXpending && (maxbid == 0. || price <= maxbid) )
{
avail = (maxavail - basecoin->DEXinfo.DEXpending);
/*if ( avail >= (100. * minamount) )
vol = (100. * minamount);
else if ( avail >= (10. * minamount) )
vol = (10. * minamount);
else*/ if ( avail >= minamount )
vol = minamount;
else vol = 0.;
if ( vol > 0. )
{
vals = cJSON_CreateObject();
jaddstr(vals,"source",basecoin->symbol);
jaddstr(vals,"dest",relcoin->symbol);
jaddnum(vals,"amount",vol);
jaddnum(vals,"minprice",price);
if ( (ap= smartaddressptr(0,myinfo,type,basecoin->symbol)) != 0 )
jaddbits256(vals,"srchash",ap->pubkey);
if ( selector != 0 )
{
jaddnum(vals,"usejumblr",selector);
jaddnum(vals,"DEXselector",selector);
}
memset(hash.bytes,0,sizeof(hash));
basecoin->DEXinfo.DEXpending += vol;
if ( (retstr= InstantDEX_request(myinfo,basecoin,0,0,hash,vals,"")) != 0 )
{
printf("request.(%s) -> (%s)\n",jprint(vals,0),retstr);
free(retstr);
}
free_json(vals);
} else printf("avail %.8f < minamount %.8f\n",avail,minamount);
} //else printf("failed if check %d %d %d %d\n",minamount > SMALLVAL,maxavail > minamount + basecoin->DEXinfo.DEXpending,maxbid == 0,price <= maxbid);
/*
minbtc = (basecoin->DEXinfo.btcprice * 1.2) * (JUMBLR_INCR + 3*(JUMBLR_INCR * JUMBLR_FEE + JUMBLR_TXFEE));
btcavail = dstr(jumblr_balance(myinfo,coinbtc,kmdcoin->DEXinfo.depositaddr));
avail = (btcavail - coinbtc->DEXinfo.DEXpending);
printf("BTC.%d deposits %.8f, min %.8f avail %.8f pending %.8f\n",toKMD,btcavail,minbtc,avail,coinbtc->DEXinfo.DEXpending);
if ( toKMD == 0 && coinbtc != 0 && btcavail > (minbtc + coinbtc->DEXinfo.DEXpending) )
{
if ( vol > 0. )
{
vals = cJSON_CreateObject();
jaddstr(vals,"source","BTC");
jaddstr(vals,"dest","KMD");
jaddnum(vals,"amount",vol);
jaddnum(vals,"minprice",0.985/kmdcoin->DEXinfo.btcprice);
jaddnum(vals,"usejumblr",1);
jaddnum(vals,"DEXselector",1);
memset(hash.bytes,0,sizeof(hash));
coinbtc->DEXinfo.DEXpending += vol;
if ( (retstr= InstantDEX_request(myinfo,coinbtc,0,0,hash,vals,"")) != 0 )
{
printf("request.(%s) -> (%s)\n",jprint(vals,0),retstr);
free(retstr);
}
free_json(vals);
// curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"InstantDEX\",\"method\":\"request\",\"vals\":{\"source\":\"KMD\",\"amount\":20,\"dest\":\"USD\",\"minprice\":0.08}}"
}
} //else printf("btcavail %.8f pending %.8f\n",btcavail,pending);
minkmd = 100.;
avail = (kmdcoin->DEXinfo.KMDavail - kmdcoin->DEXinfo.DEXpending);
printf("KMD.%d deposits %.8f, min %.8f, avail %.8f pending %.8f\n",toKMD,kmdcoin->DEXinfo.KMDavail,minkmd,avail,kmdcoin->DEXinfo.DEXpending);
if ( toKMD != 0 && coinbtc != 0 && kmdcoin->DEXinfo.KMDavail > (minkmd + kmdcoin->DEXinfo.DEXpending) )
{
if ( avail > 100.*JUMBLR_INCR )
vol = 100.*JUMBLR_INCR;
else if ( avail > 10.*JUMBLR_INCR )
vol = 10.*JUMBLR_INCR;
else if ( avail >= JUMBLR_INCR )
vol = JUMBLR_INCR;
else vol = 0.;
if ( vol > 0. )
{
vals = cJSON_CreateObject();
jaddstr(vals,"source","KMD");
jaddstr(vals,"dest","BTC");
jaddnum(vals,"amount",vol);
//jaddnum(vals,"destamount",JUMBLR_INCR*kmdcoin->DEXinfo.btcprice);
jaddnum(vals,"minprice",0.985 * kmdcoin->DEXinfo.btcprice);
jaddnum(vals,"usejumblr",2);
memset(hash.bytes,0,sizeof(hash));
kmdcoin->DEXinfo.DEXpending += vol;
jaddnum(vals,"DEXselector",2);
if ( (retstr= InstantDEX_request(myinfo,coinbtc,0,0,hash,vals,"")) != 0 )
{
printf("request.(%s) -> (%s)\n",jprint(vals,0),retstr);
free(retstr);
}
free_json(vals);
}
} else printf("kmdavail %.8f pending %.8f\n",kmdcoin->DEXinfo.avail,kmdcoin->DEXinfo.DEXpending);*/
}
void smartaddress_depositjumblr(struct supernet_info *myinfo,char *symbol,char *coinaddr,double maxbid,double minask,cJSON *extraobj)
{
struct iguana_info *basecoin,*relcoin;
if ( (basecoin= iguana_coinfind(symbol)) != 0 && (relcoin= iguana_coinfind("KMD")) != 0 )
{
if ( strcmp(coinaddr,basecoin->DEXinfo.depositaddr) == 0 )
smartaddress_dex(myinfo,"deposit",1,basecoin,coinaddr,basecoin->DEXinfo.avail,relcoin,maxbid,minask,extraobj,0.);
else printf("smartaddress_jumblr.%s: mismatch deposit address (%s) vs (%s)\n",symbol,coinaddr,basecoin->DEXinfo.depositaddr);
}
}
double smartaddress_jumblrcredit(struct supernet_info *myinfo,char *symbol)
{
return(0.); // default to BTC conversion for now
}
void smartaddress_jumblr(struct supernet_info *myinfo,char *symbol,char *coinaddr,double maxbid,double minask,cJSON *extraobj)
{
struct iguana_info *basecoin,*relcoin; double credits = 0.;
if ( strcmp("BTC",symbol) != 0 )
{
if ( (credits= smartaddress_jumblrcredit(myinfo,symbol)) <= 0. )
return;
}
if ( (basecoin= iguana_coinfind("KMD")) != 0 && (relcoin= iguana_coinfind(symbol)) != 0 )
{
if ( strcmp(coinaddr,basecoin->DEXinfo.jumblraddr) == 0 )
smartaddress_dex(myinfo,"jumblr",2,basecoin,coinaddr,basecoin->DEXinfo.jumblravail,relcoin,maxbid,minask,extraobj,credits);
else printf("smartaddress_jumblr.%s: mismatch jumblr address (%s) vs (%s)\n",symbol,coinaddr,basecoin->DEXinfo.jumblraddr);
}
}
void smartaddress_dividend(struct supernet_info *myinfo,char *symbol,char *coinaddr,double maxbid,double minask,cJSON *extraobj)
{
// support list of weighted addresses, including snapshots
}
void smartaddress_pangea(struct supernet_info *myinfo,char *symbol,char *coinaddr,double maxbid,double minask,cJSON *extraobj)
{
// table deposit
}
void smartaddress_action(struct supernet_info *myinfo,int32_t selector,char *typestr,char *symbol,char *coinaddr,double maxbid,double minask,cJSON *extraobj)
{
char rel[64]; struct iguana_info *basecoin,*relcoin; double avail;
if ( strcmp(typestr,"deposit") == 0 && selector == 0 )
smartaddress_depositjumblr(myinfo,symbol,coinaddr,maxbid,minask,extraobj);
else if ( strcmp(typestr,"jumblr") == 0 && selector == 0 )
smartaddress_jumblr(myinfo,symbol,coinaddr,maxbid,minask,extraobj);
else if ( strcmp(typestr,"dividend") == 0 && selector == 0 )
smartaddress_dividend(myinfo,symbol,coinaddr,maxbid,minask,extraobj);
else if ( strcmp(typestr,"pangea") == 0 && selector == 0 )
smartaddress_pangea(myinfo,symbol,coinaddr,maxbid,minask,extraobj);
else
{
safecopy(rel,typestr,sizeof(rel));
touppercase(rel);
if ( (relcoin= iguana_coinfind(rel)) != 0 && (basecoin= iguana_coinfind(symbol)) != 0 )
{
if ( myinfo->numswaps == 0 )//|| (basecoin->FULLNODE < 0 && relcoin->FULLNODE < 0) )
{
if ( (avail= dstr(jumblr_balance(myinfo,basecoin,coinaddr))) > SMALLVAL )
{
smartaddress_availupdate(myinfo,typestr,symbol,avail,SMALLVAL*0.99);
smartaddress_dex(myinfo,typestr,0,basecoin,coinaddr,avail,relcoin,maxbid,minask,extraobj,0.);
}
}
}
}
}
void smartaddress_update(struct supernet_info *myinfo,int32_t selector)
{
double maxbid,minask; uint8_t addrtype,rmd160[20]; char *smartstr,*typestr,*symbol,*address,coinaddr[64]; cJSON *smartarray,*extraobj,*item,*array,*coinitem; int32_t iter,i,n,j,m; struct iguana_info *kmdcoin,*coinbtc = 0;
//printf("smartaddress_update numswaps.%d notary.%d IAMLP.%d %p %p %f\n",myinfo->numswaps,myinfo->IAMNOTARY,myinfo->IAMLP,kmdcoin,coinbtc,kmdcoin->DEXinfo.btcprice);
if ( myinfo->IAMNOTARY != 0 || myinfo->IAMLP != 0 || myinfo->secret[0] == 0 )
return;
kmdcoin = iguana_coinfind("KMD");
coinbtc = iguana_coinfind("BTC");
if ( kmdcoin == 0 || coinbtc == 0 )
return;
smartaddress_coinupdate(myinfo,"KMD",0.,0.,0.); // must be first
if ( kmdcoin->DEXinfo.btcprice > SMALLVAL )
{
if ( (smartstr= InstantDEX_smartaddresses(myinfo,0,0,0)) != 0 )
{
if ( (smartarray= cJSON_Parse(smartstr)) != 0 )
{
if ( (n= cJSON_GetArraySize(smartarray)) > 0 )
{
for (iter=0; iter<2; iter++)
{
for (i=0; i<n; i++)
{
item = jitem(smartarray,i);
if ( (typestr= jstr(item,"type")) != 0 && (array= jarray(&m,item,"coins")) != 0 )
{
for (j=0; j<m; j++)
{
coinitem = jitem(array,j);
if ( (symbol= jstr(coinitem,"coin")) == 0 )
continue;
if ( iter == 0 )
smartaddress_coinupdate(myinfo,symbol,kmdcoin->DEXinfo.btcprice,kmdcoin->DEXinfo.avail,kmdcoin->DEXinfo.USD_average);
else
{
printf("Action.%s (%s)\n",typestr,jprint(coinitem,0));
if ( (address= jstr(coinitem,"address")) != 0 )
{
if ( strcmp(typestr,"jumblr") == 0 )
{
bitcoin_addr2rmd160(&addrtype,rmd160,address);
bitcoin_address(coinaddr,kmdcoin->chain->pubtype,rmd160,20);
} else strcpy(coinaddr,address);
maxbid = jdouble(coinitem,"maxbid");
minask = jdouble(coinitem,"minask");
extraobj = jobj(coinitem,"extra");
smartaddress_action(myinfo,selector,typestr,symbol,coinaddr,maxbid,minask,extraobj);
}
}
}
}
}
}
}
free_json(smartarray);
}
free(smartstr);
}
}
}
#include "../includes/iguana_apidefs.h"
#include "../includes/iguana_apideclares.h"
#include "../includes/iguana_apideclares2.h"
ZERO_ARGS(InstantDEX,smartaddresses)
{
int32_t i; cJSON *retjson = cJSON_CreateArray();
portable_mutex_lock(&myinfo->smart_mutex);
for (i=0; i<myinfo->numsmartaddrs; i++)
jaddi(retjson,smartaddress_json(&myinfo->smartaddrs[i]));
portable_mutex_unlock(&myinfo->smart_mutex);
return(jprint(retjson,1));
}
TWO_STRINGS_AND_TWO_DOUBLES(InstantDEX,smartaddress,type,symbol,maxbid,minask)
{
char prefix[64],coinaddr[64],KMDaddr[64],typestr[64]; double bidask[2]; uint8_t pubkey33[33]; bits256 privkey;
if ( smartaddress_type(type) < 0 )
return(clonestr("{\"error\":\"non-supported smartaddress type\"}"));
if ( iguana_coinfind(symbol) == 0 )
return(clonestr("{\"error\":\"non-supported smartaddress symbol\"}"));
if ( strcmp(type,"deposit") == 0 || strcmp(type,"jumblr") == 0 )
{
if ( smartaddress_pubkey(myinfo,typestr,bidask,&privkey,symbol,strcmp(type,"deposit") == 0 ? myinfo->jumblr_depositkey : myinfo->jumblr_pubkey) < 0 )
return(clonestr("{\"error\":\"unexpected missing smartaddress deposit/jumblr\"}"));
}
else
{
strcpy(prefix,type);
tolowercase(prefix);
if ( strcmp(prefix,"btc") == 0 || strcmp(prefix,"kmd") == 0 )
return(clonestr("{\"success\":\"no need add BTC or KMD to smartaddress\"}"));
strcat(prefix," ");
privkey = jumblr_privkey(myinfo,coinaddr,0,KMDaddr,prefix);
}
if ( (coin= iguana_coinfind(symbol)) == 0 )
return(clonestr("{\"error\":\"non-supported smartaddress symbol\"}"));
bitcoin_pubkey33(myinfo->ctx,pubkey33,privkey);
bitcoin_address(coinaddr,coin->chain->pubtype,pubkey33,33);
smartaddress_add(myinfo,privkey,type,symbol,maxbid,minask);
return(InstantDEX_smartaddresses(myinfo,0,0,0));
}
#include "../includes/iguana_apiundefs.h"