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.

1418 lines
57 KiB

9 years ago
/******************************************************************************
9 years ago
* Copyright © 2014-2016 The SuperNET Developers. *
9 years ago
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#include "iguana777.h"
9 years ago
#include "../includes/tweetnacl.h"
#include "../crypto777/OS_portable.h"
#include "../includes/libgfshare.h"
#include "../includes/utlist.h"
#include "../includes/uthash.h"
#include "../includes/curve25519.h"
#include "../includes/cJSON.h"
9 years ago
9 years ago
cJSON *SuperNET_argjson(cJSON *json)
{
cJSON *argjson = jduplicate(json);
jdelete(argjson,"agent");
jdelete(argjson,"method");
jdelete(argjson,"categoryhash");
jdelete(argjson,"subhash");
jdelete(argjson,"mypub");
jdelete(argjson,"hexmsg");
jdelete(argjson,"plaintext");
jdelete(argjson,"broadcast");
jdelete(argjson,"ov");
jdelete(argjson,"check");
jdelete(argjson,"yourip");
jdelete(argjson,"myip");
9 years ago
jdelete(argjson,"myipaddr");
9 years ago
return(argjson);
}
9 years ago
bits256 SuperNET_sharedseed(bits256 privkey,bits256 otherpub)
9 years ago
{
9 years ago
bits256 seed2,seed;
9 years ago
seed = curve25519_shared(privkey,otherpub);
9 years ago
vcalc_sha256(0,seed2.bytes,seed.bytes,sizeof(bits256));
9 years ago
return(seed2);
}
9 years ago
int32_t SuperNET_delaymillis(struct supernet_info *myinfo,int32_t maxdelay)
{
maxdelay += myinfo->maxdelay;
if ( maxdelay > SUPERNET_MAXDELAY )
maxdelay = SUPERNET_MAXDELAY;
9 years ago
if ( maxdelay == 0 )
return(0);
9 years ago
return(rand() % maxdelay);
}
void SuperNET_remotepeer(struct supernet_info *myinfo,struct iguana_info *coin,char *symbol,char *ipaddr,int32_t supernetflag)
{
uint64_t ipbits; struct iguana_peer *addr;
9 years ago
ipbits = calc_ipbits(ipaddr);
9 years ago
printf("got %s remotepeer.(%s) supernet.%d\n",symbol,ipaddr,supernetflag);
9 years ago
if ( supernetflag != 0 && (uint32_t)myinfo->myaddr.selfipbits != (uint32_t)ipbits )
9 years ago
{
9 years ago
if ( (addr= iguana_peerslot(coin,ipbits,0)) != 0 )
9 years ago
{
printf("launch startconnection to supernet peer.(%s)\n",ipaddr);
iguana_launch(coin,"connection",iguana_startconnection,addr,IGUANA_CONNTHREAD);
return;
}
}
iguana_possible_peer(coin,ipaddr);
}
int32_t SuperNET_confirmip(struct supernet_info *myinfo,uint32_t ipbits)
{
int32_t i,j,total = 0; uint32_t x;
for (i=0; i<IGUANA_MAXCOINS; i++)
{
if ( Coins[i] != 0 )
{
for (j=0; j<IGUANA_MAXPEERS; j++)
{
if ( (x= Coins[i]->peers.active[j].myipbits) != 0 )
{
if ( x == ipbits )
total++;
else total--;
}
}
}
}
return(total);
}
9 years ago
void SuperNET_checkipaddr(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr,char *myipaddr,char *remoteaddr)
9 years ago
{
uint32_t myipbits = (uint32_t)calc_ipbits(myipaddr);
if ( addr->myipbits == 0 )
addr->myipbits = myipbits;
else if ( addr->myipbits != myipbits )
{
printf("%s: myipaddr conflict %x != %x?\n",addr->ipaddr,addr->myipbits,myipbits);
addr->myipbits = 0;
}
if ( addr->myipbits != 0 && myinfo->myaddr.myipbits == 0 )
myinfo->myaddr.myipbits = addr->myipbits;
if ( addr->myipbits == myinfo->myaddr.myipbits )
myinfo->myaddr.confirmed++;
else myinfo->myaddr.confirmed--;
9 years ago
if ( (myinfo->myaddr.totalconfirmed= SuperNET_confirmip(myinfo,addr->myipbits)) >= coin->peers.numranked )
myinfo->myaddr.selfipbits = addr->myipbits;
9 years ago
if ( myinfo->myaddr.selfipbits == myinfo->myaddr.myipbits )
{
expand_ipbits(myinfo->ipaddr,myinfo->myaddr.selfipbits);
vcalc_sha256(0,myinfo->myaddr.iphash.bytes,(uint8_t *)&myinfo->myaddr.selfipbits,sizeof(myinfo->myaddr.selfipbits));
}
9 years ago
if ( myinfo->ipaddr[0] == 0 || strcmp(myinfo->ipaddr,"127.0.0.1") == 0 )
9 years ago
{
strcpy(myinfo->ipaddr,myipaddr);
}
9 years ago
//printf("myipaddr.%s self.%x your.%x\n",myinfo->ipaddr,myinfo->myaddr.selfipbits,myinfo->myaddr.myipbits);
9 years ago
}
9 years ago
int32_t _SuperNET_cipher(uint8_t nonce[crypto_box_NONCEBYTES],uint8_t *cipher,uint8_t *message,int32_t len,bits256 destpub,bits256 srcpriv,uint8_t *buf)
{
memset(cipher,0,len+crypto_box_ZEROBYTES);
memset(buf,0,crypto_box_ZEROBYTES);
memcpy(buf+crypto_box_ZEROBYTES,message,len);
crypto_box(cipher,buf,len+crypto_box_ZEROBYTES,nonce,destpub.bytes,srcpriv.bytes);
return(len + crypto_box_ZEROBYTES);
}
uint8_t *_SuperNET_decipher(uint8_t nonce[crypto_box_NONCEBYTES],uint8_t *cipher,uint8_t *message,int32_t len,bits256 srcpub,bits256 mypriv)
{
int32_t err;
if ( (err= crypto_box_open(message,cipher,len,nonce,srcpub.bytes,mypriv.bytes)) == 0 )
{
message += crypto_box_ZEROBYTES;
len -= crypto_box_ZEROBYTES;
return(message);
}
return(0);
}
9 years ago
void *SuperNET_deciphercalc(void **ptrp,int32_t *msglenp,bits256 privkey,bits256 srcpubkey,uint8_t *cipher,int32_t cipherlen,uint8_t *buf,int32_t bufsize)
9 years ago
{
9 years ago
uint8_t *origptr,*nonce,*message; void *retptr;
9 years ago
if ( bits256_nonz(privkey) == 0 )
privkey = GENESIS_PRIVKEY;
9 years ago
*ptrp = 0;
9 years ago
if ( cipherlen > bufsize )
9 years ago
{
9 years ago
message = calloc(1,cipherlen);
9 years ago
*ptrp = (void *)message;
}
9 years ago
else message = buf;
origptr = cipher;
if ( bits256_nonz(srcpubkey) == 0 )
{
memcpy(srcpubkey.bytes,cipher,sizeof(srcpubkey));
//char str[65]; printf("use attached pubkey.(%s)\n",bits256_str(str,srcpubkey));
cipher += sizeof(srcpubkey);
cipherlen -= sizeof(srcpubkey);
}
nonce = cipher;
cipher += crypto_box_NONCEBYTES, cipherlen -= crypto_box_NONCEBYTES;
*msglenp = cipherlen - crypto_box_ZEROBYTES;
9 years ago
if ( (retptr= _SuperNET_decipher(nonce,cipher,message,cipherlen,srcpubkey,privkey)) == 0 )
{
*msglenp = -1;
free(*ptrp);
}
return(retptr);
9 years ago
}
9 years ago
uint8_t *SuperNET_ciphercalc(void **ptrp,int32_t *cipherlenp,bits256 *privkeyp,bits256 *destpubkeyp,uint8_t *data,int32_t datalen,uint8_t *space2,int32_t space2size)
9 years ago
{
bits256 mypubkey; uint8_t *buf,*nonce,*cipher,*origptr,space[8192]; int32_t onetimeflag=0,allocsize;
9 years ago
*ptrp = 0;
9 years ago
allocsize = (datalen + crypto_box_NONCEBYTES + crypto_box_ZEROBYTES);
if ( bits256_nonz(*destpubkeyp) == 0 || memcmp(destpubkeyp->bytes,GENESIS_PUBKEY.bytes,sizeof(*destpubkeyp)) == 0 )
9 years ago
{
*destpubkeyp = GENESIS_PUBKEY;
onetimeflag = 2; // prevent any possible leakage of privkey by encrypting to known destpub
9 years ago
}
if ( bits256_nonz(*privkeyp) == 0 )
onetimeflag = 1;
if ( onetimeflag != 0 )
{
crypto_box_keypair(mypubkey.bytes,privkeyp->bytes);
allocsize += sizeof(bits256);
}
if ( allocsize > sizeof(space) )
buf = calloc(1,allocsize);
else buf = space;
9 years ago
if ( allocsize+sizeof(struct iguana_msghdr) > space2size )
{
cipher = calloc(1,allocsize + sizeof(struct iguana_msghdr));
*ptrp = (void *)cipher;
} else cipher = space2;
cipher = &cipher[sizeof(struct iguana_msghdr)];
9 years ago
origptr = nonce = cipher;
if ( onetimeflag != 0 )
{
memcpy(cipher,mypubkey.bytes,sizeof(mypubkey));
nonce = &cipher[sizeof(mypubkey)];
}
OS_randombytes(nonce,crypto_box_NONCEBYTES);
cipher = &nonce[crypto_box_NONCEBYTES];
_SuperNET_cipher(nonce,cipher,(void *)data,datalen,*destpubkeyp,*privkeyp,buf);
if ( buf != space )
free(buf);
*cipherlenp = allocsize;
return(origptr);
}
9 years ago
int32_t SuperNET_copybits(int32_t reverse,uint8_t *dest,uint8_t *src,int32_t len)
{
int32_t i; uint8_t *tmp;
if ( reverse != 0 )
{
tmp = dest;
dest = src;
src = tmp;
}
//printf("src.%p dest.%p len.%d\n",src,dest,len);
//for (i=0; i<len; i++)
// dest[i] = 0;
memset(dest,0,len);
len <<= 3;
for (i=0; i<len; i++)
if ( GETBIT(src,i) != 0 )
SETBIT(dest,i);
return(len >> 3);
}
9 years ago
uint16_t SuperNET_checkc(bits256 privkey,bits256 otherpub,void *num,int32_t len)
9 years ago
{
uint8_t buf[40]; bits256 check,seed,seed2;
seed = curve25519_shared(privkey,otherpub);
9 years ago
vcalc_sha256(0,seed2.bytes,seed.bytes,sizeof(seed));
memcpy(buf,seed2.bytes,sizeof(seed));
9 years ago
iguana_rwnum(1,&buf[sizeof(seed)],len,num);
9 years ago
vcalc_sha256(0,check.bytes,buf,sizeof(buf));
return(check.ushorts[0]);
}
9 years ago
int32_t SuperNET_json2bits(uint8_t *serialized,int32_t maxsize,cJSON *json,bits256 mypub,uint16_t checkc,uint32_t myipbits,uint32_t destipbits,int32_t _othervalid)
9 years ago
{
9 years ago
uint16_t apinum; bits256 categoryhash,subhash; uint32_t tmp,crc,timestamp;
char *agent,*method; //uint64_t tag;
9 years ago
char *hexmsg; uint8_t broadcastflag; int8_t othervalid; int32_t n,len = sizeof(uint32_t);
9 years ago
if ( _othervalid > 100 )
othervalid = 100;
else if ( _othervalid < -100 )
othervalid = -100;
else othervalid = _othervalid;
tmp = juint(json,"broadcast");
9 years ago
if ( tmp > SUPERNET_MAXHOPS )
broadcastflag = SUPERNET_MAXHOPS;
9 years ago
else broadcastflag = tmp;
categoryhash = jbits256(json,"categoryhash");
subhash = jbits256(json,"subhash");
9 years ago
timestamp = juint(json,"timestamp");
9 years ago
if ( bits256_nonz(categoryhash) > 0 && memcmp(categoryhash.bytes,GENESIS_PUBKEY.bytes,sizeof(categoryhash)) != 0 )
{
9 years ago
broadcastflag |= 0x40;
9 years ago
if ( bits256_nonz(subhash) > 0 && memcmp(subhash.bytes,GENESIS_PUBKEY.bytes,sizeof(subhash)) != 0 )
broadcastflag |= 0x20;
9 years ago
else subhash = GENESIS_PUBKEY;
if ( broadcastflag == 0 )
broadcastflag = 1;
}
else
{
categoryhash = subhash = GENESIS_PUBKEY;
if ( broadcastflag == 0 )
broadcastflag = 1;
}
9 years ago
if ( juint(json,"plaintext") != 0 )
broadcastflag |= 0x80;
9 years ago
//if ( (tag= j64bits(json,"tag")) == 0 )
// OS_randombytes((uint8_t *)&tag,sizeof(tag));
9 years ago
agent = jstr(json,"agent"), method = jstr(json,"method");
9 years ago
if ( agent != 0 && method != 0 && strcmp(agent,"SuperNET") == 0 && strcmp(method,"json2bits") == 0 )
{
9 years ago
agent = jstr(json,"destagent");
method = jstr(json,"destmethod");
}
if ( (apinum= SuperNET_API2num(agent,method)) == 0xffff )
{
printf("agent.(%s) method.(%s) is not found\n",agent,method);
return(-1);
}
9 years ago
len += iguana_rwnum(1,&serialized[len],sizeof(uint32_t),&timestamp);
9 years ago
len += iguana_rwnum(1,&serialized[len],sizeof(uint32_t),&destipbits);
9 years ago
len += iguana_rwnum(1,&serialized[len],sizeof(uint32_t),&myipbits);
//printf("myipbits.%x destipbits.%x\n",myipbits,destipbits);
9 years ago
len += iguana_rwnum(1,&serialized[len],sizeof(checkc),&checkc);
len += iguana_rwnum(1,&serialized[len],sizeof(apinum),&apinum);
9 years ago
//len += iguana_rwnum(1,&serialized[len],sizeof(tag),&tag);
9 years ago
len += iguana_rwbignum(1,&serialized[len],sizeof(mypub),mypub.bytes);
9 years ago
len += iguana_rwnum(1,&serialized[len],sizeof(othervalid),&othervalid);
9 years ago
len += iguana_rwnum(1,&serialized[len],sizeof(broadcastflag),&broadcastflag);
9 years ago
if ( (broadcastflag & 0x40) != 0 )
{
len += iguana_rwbignum(1,&serialized[len],sizeof(bits256),categoryhash.bytes);
if ( (broadcastflag & 0x20) != 0 )
len += iguana_rwbignum(1,&serialized[len],sizeof(bits256),subhash.bytes);
}
9 years ago
//printf("broadcastflag.%x\n",broadcastflag);
9 years ago
if ( (hexmsg= jstr(json,"hexmsg")) != 0 )
9 years ago
{
n = (int32_t)strlen(hexmsg);
if ( (n & 1) == 0 && is_hexstr(hexmsg,n) > 0 )
{
n >>= 1;
decode_hex(&serialized[len],n,hexmsg);
len += n;
9 years ago
} else return(-1);
}
9 years ago
crc = calc_crc32(0,&serialized[sizeof(crc)],len - sizeof(crc));
9 years ago
// char str[65]; printf("crc.%u ip.(%s %s) tag.%llx checkc.%x apinum.%d >>>>>>>>>>>>>>>> mypub.%s\n",crc,destip,myipaddr,(long long)tag,checkc,apinum,bits256_str(str,mypubkey));
9 years ago
iguana_rwnum(1,serialized,sizeof(crc),&crc);
9 years ago
//int32_t i; for (i=0; i<len; i++)
// printf("%02x ",serialized[i]);
//printf("SEND[%d]\n",len);
9 years ago
return(len);
}
9 years ago
cJSON *SuperNET_bits2json(uint8_t *serialized,int32_t datalen)
9 years ago
{
9 years ago
char destip[64],method[64],checkstr[5],agent[64],myipaddr[64],str[65],*hexmsg; //uint64_t tag;
9 years ago
uint16_t apinum,checkc; int8_t othervalid; uint32_t destipbits,myipbits,timestamp;
bits256 categoryhash,subhash,senderpub; cJSON *json = cJSON_CreateObject();
9 years ago
int32_t len = 0; uint32_t crc; uint8_t broadcastflag,plaintext;
9 years ago
len += iguana_rwnum(0,&serialized[len],sizeof(uint32_t),&crc);
9 years ago
len += iguana_rwnum(0,&serialized[len],sizeof(uint32_t),&timestamp);
9 years ago
len += iguana_rwnum(0,&serialized[len],sizeof(uint32_t),&destipbits);
len += iguana_rwnum(0,&serialized[len],sizeof(uint32_t),&myipbits);
9 years ago
len += iguana_rwnum(0,&serialized[len],sizeof(checkc),&checkc);
len += iguana_rwnum(0,&serialized[len],sizeof(apinum),&apinum);
9 years ago
//len += iguana_rwnum(0,&serialized[len],sizeof(tag),&tag);
9 years ago
len += iguana_rwbignum(0,&serialized[len],sizeof(bits256),senderpub.bytes);
9 years ago
len += iguana_rwnum(0,&serialized[len],sizeof(othervalid),&othervalid);
9 years ago
len += iguana_rwnum(0,&serialized[len],sizeof(broadcastflag),&broadcastflag);
9 years ago
categoryhash = subhash = GENESIS_PUBKEY;
9 years ago
if ( (broadcastflag & 0x40) != 0 )
{
len += iguana_rwbignum(0,&serialized[len],sizeof(bits256),categoryhash.bytes);
if ( (broadcastflag & 0x20) != 0 )
len += iguana_rwbignum(0,&serialized[len],sizeof(bits256),subhash.bytes);
}
9 years ago
//char str2[65]; printf("set cat.(%s) sub.(%s)\n",bits256_str(str,categoryhash),bits256_str(str2,subhash));
9 years ago
plaintext = (broadcastflag & 0x80) != 0;
9 years ago
broadcastflag &= 0x3f;
if ( broadcastflag > SUPERNET_MAXHOPS )
broadcastflag = SUPERNET_MAXHOPS;
9 years ago
//printf("<<<<<<<<<<<<<<<< crc.%u ipbits.(%x %x) tag.%llx checkc.%x apinum.%d valid.%d other.%d broadcast.%d plaintext.%d\n",crc,destipbits,myipbits,(long long)tag,checkc,apinum,addr->validpub,othervalid,broadcastflag,plaintext);
if ( SuperNET_num2API(agent,method,apinum) >= 0 )
9 years ago
{
jaddstr(json,"agent",agent);
jaddstr(json,"method",method);
9 years ago
if ( timestamp != 0 )
jaddnum(json,"timestamp",timestamp);
9 years ago
if ( bits256_nonz(categoryhash) > 0 && memcmp(GENESIS_PUBKEY.bytes,categoryhash.bytes,sizeof(categoryhash)) != 0 )
9 years ago
jaddbits256(json,"categoryhash",categoryhash);
9 years ago
if ( bits256_nonz(categoryhash) > 0 && memcmp(GENESIS_PUBKEY.bytes,subhash.bytes,sizeof(subhash)) != 0 )
9 years ago
jaddbits256(json,"subhash",subhash);
expand_ipbits(destip,destipbits), jaddstr(json,"yourip",destip);
expand_ipbits(myipaddr,myipbits), jaddstr(json,"myip",myipaddr);
jaddstr(json,"mypub",bits256_str(str,senderpub));
categoryhash = subhash = GENESIS_PUBKEY;
if ( (broadcastflag & 0x40) != 0 )
{
jaddbits256(json,"categoryhash",categoryhash);
if ( (broadcastflag & 0x20) != 0 )
jaddbits256(json,"subhash",subhash);
}
9 years ago
//jadd64bits(json,"tag",tag);
9 years ago
init_hexbytes_noT(checkstr,(void *)&checkc,sizeof(checkc));
jaddstr(json,"check",checkstr);
9 years ago
jaddnum(json,"ov",othervalid);
9 years ago
if ( plaintext != 0 )
9 years ago
jaddnum(json,"plaintext",plaintext!=0);
9 years ago
if ( broadcastflag != 0 )
jaddnum(json,"broadcast",broadcastflag%SUPERNET_MAXHOPS);
if ( len < datalen )
{
9 years ago
//printf("len %d vs %d datalen\n",len,datalen);
hexmsg = malloc(((datalen - len)<<1) + 1);
init_hexbytes_noT(hexmsg,&serialized[len],datalen - len);
9 years ago
//printf("hex.(%s)\n",hexmsg);
9 years ago
jaddstr(json,"hexmsg",hexmsg);
free(hexmsg);
}
9 years ago
//printf("bits2json.(%s)\n",jprint(json,0));
return(json);
9 years ago
} else printf("cant decode apinum.%d (%d.%d)\n",apinum,apinum>>5,apinum%0x1f);
return(0);
9 years ago
}
9 years ago
char *SuperNET_hexconv(char *hexmsg)
{
cJSON *json; char *myip,*yourip,*retstr = hexmsg; uint32_t myipbits=0,destipbits=0;
9 years ago
uint8_t *bits; int32_t n,len = (int32_t)strlen(hexmsg);
9 years ago
//if ( hexmsg == 0 || is_hexstr(hexmsg,len) == 0 )
9 years ago
return(hexmsg);
len >>= 1;
9 years ago
if ( (bits= calloc(1,len)) != 0 )
9 years ago
{
9 years ago
decode_hex(bits,len,hexmsg);
if ( (json= cJSON_Parse((char *)bits)) != 0 )
{
9 years ago
printf("parsed hexmsg.(%s)\n",(char *)bits);
9 years ago
if ( (myip= jstr(json,"myip")) != 0 )
myipbits = (uint32_t)calc_ipbits(myip);
if ( (yourip= jstr(json,"yourip")) != 0 )
destipbits = (uint32_t)calc_ipbits(yourip);
n = SuperNET_json2bits(bits,len,json,jbits256(json,"mypub"),juint(json,"checkc"),myipbits,destipbits,(int32_t)jdouble(json,"ov"));
cJSON *json2 = SuperNET_bits2json(bits,n); printf("hexconv.(%s) -> (%s)\n",jprint(json,0),jprint(json2,1));
if ( (retstr= calloc(1,n*2+1)) != 0 )
init_hexbytes_noT(retstr,bits,n);
else retstr = hexmsg;
9 years ago
free_json(json);
9 years ago
} //else printf("SuperNET_hexconv cant parse.(%s)\n",hexmsg);
9 years ago
free(bits);
9 years ago
}
9 years ago
return(retstr);
}
9 years ago
void iguana_setkeys(struct supernet_info *myinfo,struct iguana_peer *addr,bits256 *myprivp,bits256 *mypubp,bits256 *destpubp,bits256 *nextprivp,bits256 *nextpubp,bits256 *nextdestpubp)
{
9 years ago
*nextprivp = myinfo->privkey;
*nextpubp = myinfo->myaddr.pubkey;
*nextdestpubp = addr->pubkey;
9 years ago
if ( 1 || addr->validpub < 3 || addr->othervalid < 3 )
9 years ago
*myprivp = GENESIS_PRIVKEY, *destpubp = *mypubp = GENESIS_PUBKEY;
else *myprivp = *nextprivp, *mypubp = *nextpubp, *destpubp = *nextdestpubp;
9 years ago
//char str[65]; printf("(priv.%llx pub.%llx) -> destpub.%s\n",(long long)myprivp->txid,(long long)mypubp->txid,bits256_str(str,*destpubp));
}
9 years ago
bits256 iguana_actualpubkey(int32_t *offsetp,uint8_t *cipher,int32_t cipherlen,bits256 destpubkey)
{
int32_t i;
9 years ago
*offsetp = 0;
if ( cipherlen < 56+16 )
return(destpubkey);
for (i=56; i<56+16; i++)
if ( cipher[i] != 0 )
break;
if ( i == 56+16 )
9 years ago
{
*offsetp = sizeof(destpubkey);
memcpy(destpubkey.bytes,cipher,sizeof(destpubkey));
9 years ago
//char str[65]; printf("extracted destpubkey.(%s)\n",bits256_str(str,destpubkey));
9 years ago
}
return(destpubkey);
}
9 years ago
int32_t iguana_send_supernet(struct iguana_info *coin,struct iguana_peer *addr,char *jsonstr,int32_t delaymillis)
{
9 years ago
int32_t datalen,cipherlen,qlen = -1; uint8_t *serialized,space2[32768],*cipher; cJSON *json;
9 years ago
struct supernet_info *myinfo; uint16_t checkc;
bits256 destpub,privkey,pubkey,nextprivkey,nextpubkey,nextdestpub; void *ptr = 0;
9 years ago
myinfo = SuperNET_MYINFO(0);
9 years ago
if ( (json= cJSON_Parse(jsonstr)) != 0 )
{
9 years ago
iguana_setkeys(myinfo,addr,&privkey,&pubkey,&destpub,&nextprivkey,&nextpubkey,&nextdestpub);
9 years ago
if ( juint(json,"plaintext") == 0 && juint(json,"broadcast") == 0 && memcmp(destpub.bytes,GENESIS_PUBKEY.bytes,sizeof(pubkey)) == 0 )
9 years ago
{
9 years ago
printf("reject broadcasting non-plaintext! (%s)\n",jsonstr); getchar();
9 years ago
free_json(json);
return(-1);
}
9 years ago
serialized = malloc(sizeof(struct iguana_msghdr) + IGUANA_MAXPACKETSIZE);
9 years ago
checkc = SuperNET_checkc(nextprivkey,nextdestpub,&nextpubkey.txid,sizeof(nextpubkey.txid));
if ( (datalen= SuperNET_json2bits(&serialized[sizeof(struct iguana_msghdr)],IGUANA_MAXPACKETSIZE,json,nextpubkey,checkc,(uint32_t)calc_ipbits(myinfo->ipaddr),(uint32_t)calc_ipbits(addr->ipaddr),addr->othervalid)) > 0 )
9 years ago
{
9 years ago
if ( 0 && jstr(json,"method") != 0 && strcmp("getpeers",jstr(json,"method")) != 0 )
9 years ago
printf("SUPERSEND -> (%s) (%s) delaymillis.%d datalen.%d\n",jprint(SuperNET_bits2json(&serialized[sizeof(struct iguana_msghdr)],datalen),1),addr->ipaddr,delaymillis,datalen);
9 years ago
if ( 0 && memcmp(destpub.bytes,GENESIS_PUBKEY.bytes,sizeof(destpub)) == 0 )
9 years ago
qlen = iguana_queue_send(coin,addr,delaymillis,serialized,"SuperNET",datalen,0,0);
else
9 years ago
{
9 years ago
if ( (cipher= SuperNET_ciphercalc(&ptr,&cipherlen,&privkey,&destpub,&serialized[sizeof(struct iguana_msghdr)],datalen,space2,sizeof(space2))) != 0 )
9 years ago
{
9 years ago
void *msgbits; int32_t msglen,offset; bits256 testpriv; uint8_t space[65536]; void *ptr2;
9 years ago
destpub = iguana_actualpubkey(&offset,cipher,cipherlen,destpub);
9 years ago
if ( 0 && (msgbits= SuperNET_deciphercalc(&ptr2,&msglen,testpriv,destpub,&cipher[offset],cipherlen-offset,space,sizeof(space))) == 0 )
{
int32_t i; for (i=0; i<cipherlen; i++)
printf("%02x",cipher[i]);
printf(" cant decrypt cipherlen.%d otherpriv.%llx pub.%llx\n",cipherlen,(long long)testpriv.txid,(long long)pubkey.txid);
printf("encrypted mypriv.%llx destpub.%llx\n",(long long)privkey.txid,(long long)destpub.txid);
9 years ago
} //else printf("decrypted\n");
9 years ago
qlen = iguana_queue_send(coin,addr,delaymillis,&cipher[-sizeof(struct iguana_msghdr)],"SuperNETb",cipherlen,0,0);
9 years ago
if ( ptr != 0 )
free(ptr);
9 years ago
}
9 years ago
}
}
9 years ago
free(serialized);
9 years ago
} else printf("cant parse.(%s)\n",jsonstr);
9 years ago
return(qlen);
}
9 years ago
int32_t DHT_dist(bits256 desthash,bits256 hash)
{
int32_t i,dist = 0;
for (i=0; i<4; i++)
dist += bitweight(desthash.ulongs[i] ^ hash.ulongs[i]);
printf("(dist.%d) ",dist);
9 years ago
return(dist*0);
9 years ago
}
9 years ago
struct iguana_peer *iguana_peerfind(struct supernet_info *myinfo,struct iguana_info **coinp,uint64_t destipbits,bits256 category,bits256 subhash)
9 years ago
{
9 years ago
int32_t i,j; struct iguana_peer *addr; uint16_t port;
9 years ago
*coinp = 0;
9 years ago
port = (uint16_t)(destipbits >> 32);
9 years ago
for (i=0; i<IGUANA_MAXCOINS; i++)
{
if ( Coins[i] != 0 )
{
for (j=0; j<IGUANA_MAXPEERS; j++)
{
addr = &Coins[i]->peers.active[j];
if ( addr->usock >= 0 )
{
if ( destipbits == addr->ipbits || category_peer(myinfo,addr,category,subhash) >= 0 )
9 years ago
{
9 years ago
if ( port == 0 || addr->A.port == port )
{
*coinp = Coins[i];
return(addr);
}
9 years ago
}
}
}
}
}
return(0);
}
9 years ago
char *SuperNET_DHTsend(struct supernet_info *myinfo,uint64_t destipbits,bits256 categoryhash,bits256 subhash,char *hexmsg,int32_t maxdelay,int32_t broadcastflag,int32_t plaintext)
9 years ago
{
9 years ago
int32_t i,j; char *convstr,*jsonstr=0; struct iguana_peer *addr; cJSON *json; struct iguana_info *coin;
9 years ago
if ( myinfo == 0 )
return(clonestr("{\"error\":\"no supernet_info\"}"));
json = cJSON_CreateObject();
9 years ago
jaddstr(json,"agent","SuperNET");
jaddstr(json,"method","DHT");
9 years ago
convstr = SuperNET_hexconv(hexmsg);
jaddstr(json,"hexmsg",convstr);
if ( convstr != hexmsg )
free(convstr);
9 years ago
if ( broadcastflag > 0 )
9 years ago
jaddnum(json,"broadcast",broadcastflag-1);
9 years ago
if ( plaintext != 0 )
jaddnum(json,"plaintext",plaintext!=0);
9 years ago
if ( bits256_nonz(categoryhash) > 0 && memcmp(categoryhash.bytes,GENESIS_PUBKEY.bytes,sizeof(bits256)) != 0 )
jaddbits256(json,"categoryhash",categoryhash);
if ( bits256_nonz(subhash) > 0 && memcmp(subhash.bytes,GENESIS_PUBKEY.bytes,sizeof(bits256)) != 0 )
jaddbits256(json,"subhash",subhash);
if ( SuperNET_hexmsgfind(myinfo,categoryhash,subhash,hexmsg,1) >= 0 )
9 years ago
{
9 years ago
char str[65]; printf("duplicate hex.(%s) for %s\n",hexmsg,bits256_str(str,categoryhash));
9 years ago
return(clonestr("{\"error\":\"duplicate packet rejected\"}"));
9 years ago
} else SuperNET_hexmsgadd(myinfo,categoryhash,subhash,hexmsg,tai_now(),0);
9 years ago
jsonstr = jprint(json,1);
9 years ago
if ( broadcastflag != 0 || destipbits == 0 )
9 years ago
{
for (i=0; i<IGUANA_MAXCOINS; i++)
{
if ( Coins[i] != 0 )
{
for (j=0; j<IGUANA_MAXPEERS; j++)
{
addr = &Coins[i]->peers.active[j];
9 years ago
if ( addr->usock >= 0 && addr->supernet != 0 && (broadcastflag != 0 || category_peer(myinfo,addr,categoryhash,subhash) >= 0) )
9 years ago
{
9 years ago
char str[65]; printf("BROADCAST[%d] crc.%x %s SEND.(%ld) to %s\n",j,calc_crc32(0,jsonstr,(int32_t)strlen(jsonstr)),bits256_str(str,categoryhash),strlen(jsonstr),addr->ipaddr);
iguana_send_supernet(Coins[i],addr,jsonstr,maxdelay==0?0:(rand()%maxdelay));
9 years ago
}
9 years ago
}
}
}
9 years ago
return(clonestr("{\"result\":\"packet sent to all peers\"}"));
9 years ago
}
9 years ago
if ( (addr= iguana_peerfind(myinfo,&coin,destipbits,categoryhash,subhash)) == 0 )
9 years ago
return(clonestr("{\"error\":\"no route found\"}"));
9 years ago
if ( SuperNET_hexmsgfind(myinfo,categoryhash,subhash,hexmsg,1) >= 0 )
9 years ago
{
printf("SEND.(%s) to %s\n",jsonstr,addr->ipaddr);
iguana_send_supernet(coin,addr,jsonstr,maxdelay==0?0:(rand()%maxdelay));
return(clonestr("{\"result\":\"packet sent directly\"}"));
}
return(clonestr("{\"result\":\"no appropriate peers to send to\"}"));
9 years ago
}
9 years ago
char *SuperNET_DHTencode(struct supernet_info *myinfo,char *destip,bits256 categoryhash,bits256 subhash,char *hexmsg,int32_t maxdelay,int32_t broadcastflag,int32_t plaintext)
9 years ago
{
9 years ago
uint32_t destipbits; char *retstr;
destipbits = (uint32_t)calc_ipbits(destip);
9 years ago
if ( (retstr = SuperNET_DHTsend(myinfo,destipbits,categoryhash,subhash,hexmsg,maxdelay,broadcastflag,plaintext)) != 0 )
9 years ago
free(retstr);
return(clonestr("{\"result\":\"DHT sent\"}"));
9 years ago
}
9 years ago
char *SuperNET_forward(struct supernet_info *myinfo,char *hexmsg,uint32_t destipbits,bits256 categoryhash,bits256 subhash,int32_t maxdelay,int32_t broadcastflag,int32_t plaintext)
9 years ago
{
9 years ago
return(SuperNET_DHTsend(myinfo,destipbits,categoryhash,subhash,hexmsg,maxdelay,broadcastflag,plaintext));
9 years ago
}
int32_t SuperNET_destination(struct supernet_info *myinfo,uint32_t *destipbitsp,bits256 *categoryp,bits256 *subhashp,int32_t *maxdelayp,cJSON *json,char *remoteaddr)
9 years ago
{
9 years ago
char *destip; int32_t destflag = 0;
9 years ago
if ( (destip= jstr(json,"destip")) != 0 )
*destipbitsp = (uint32_t)calc_ipbits(destip);
9 years ago
else *destipbitsp = 0;
9 years ago
*maxdelayp = juint(json,"delay");
*categoryp = jbits256(json,"categoryhash");
*subhashp = jbits256(json,"subhash");
9 years ago
if ( *destipbitsp != 0 )
{
if ( *destipbitsp == myinfo->myaddr.selfipbits )
destflag |= SUPERNET_ISMINE;
else destflag |= SUPERNET_FORWARD;
}
else if ( bits256_nonz(*categoryp) > 0 )
9 years ago
{
if ( category_peer(myinfo,0,*categoryp,*subhashp) > 0 )
9 years ago
destflag |= SUPERNET_ISMINE;
9 years ago
if ( juint(json,"broadcast") > 0 )
destflag |= SUPERNET_FORWARD;
9 years ago
}
9 years ago
if ( remoteaddr == 0 || remoteaddr[0] == 0 || strcmp(remoteaddr,"127.0.0.1") == 0 )
9 years ago
destflag |= SUPERNET_ISMINE;
9 years ago
return(destflag);
}
9 years ago
char *SuperNET_JSON(struct supernet_info *myinfo,cJSON *json,char *remoteaddr,uint16_t port)
9 years ago
{
char hexbuf[8192]; bits256 category,subhash;
9 years ago
int32_t hexlen,destflag,maxdelay,flag=0,newflag=0; uint32_t destipbits,timestamp; cJSON *retjson;
9 years ago
char *forwardstr=0,*retstr=0,*agent=0,*method=0,*message,*hexmsg=0,*jsonstr=0; uint64_t tag;
9 years ago
//printf("SuperNET_JSON.(%s)\n",jprint(json,0));
9 years ago
if ( remoteaddr != 0 && strcmp(remoteaddr,"127.0.0.1") == 0 )
remoteaddr = 0;
if ( (agent = jstr(json,"agent")) == 0 )
agent = "bitcoinrpc";
9 years ago
method = jstr(json,"method");
9 years ago
if ( agent != 0 && strcmp(agent,"pangea") == 0 && jobj(json,"categoryhash") == 0 )
{
jaddbits256(json,"categoryhash",calc_categoryhashes(0,"pangea",0));
9 years ago
if ( jobj(json,"subhash") == 0 )
jaddbits256(json,"subhash",GENESIS_PUBKEY);
9 years ago
}
9 years ago
if ( remoteaddr == 0 )
9 years ago
{
9 years ago
if ( jobj(json,"timestamp") != 0 )
jdelete(json,"timestamp");
timestamp = (uint32_t)time(NULL);
jaddnum(json,"timestamp",timestamp);
9 years ago
}
9 years ago
if ( (tag= j64bits(json,"tag")) == 0 )
{
OS_randombytes((uint8_t *)&tag,sizeof(tag));
jadd64bits(json,"tag",tag);
}
9 years ago
//printf("SuperNET_JSON.(%s) remote.(%s)\n",jprint(json,0),remoteaddr!=0?remoteaddr:"");
destflag = SuperNET_destination(myinfo,&destipbits,&category,&subhash,&maxdelay,json,remoteaddr);
9 years ago
//printf("destflag.%d\n",destflag);
9 years ago
if ( (hexmsg= jstr(json,"hexmsg")) == 0 && (message= jstr(json,"message")) == 0 )
{
jsonstr = jprint(json,0);
hexlen = (int32_t)strlen(jsonstr);
if ( hexlen*2+1 > sizeof(hexbuf) )
hexmsg = malloc(hexlen*2+1), flag = 1;
else hexmsg = hexbuf;
9 years ago
init_hexbytes_noT(hexmsg,(uint8_t *)jsonstr,(int32_t)strlen(jsonstr)+1);
}
9 years ago
if ( (destflag & SUPERNET_FORWARD) != 0 )
{
9 years ago
if ( hexmsg != 0 )
{
if ( SuperNET_hexmsgfind(myinfo,category,subhash,hexmsg,0) < 0 )
9 years ago
{
9 years ago
//printf("add.(%s)\n",hexmsg);
newflag = 1;
9 years ago
SuperNET_hexmsgadd(myinfo,category,subhash,hexmsg,tai_now(),remoteaddr);
forwardstr = SuperNET_forward(myinfo,hexmsg,destipbits,category,subhash,maxdelay,juint(json,"broadcast"),juint(json,"plaintext")!=0);
9 years ago
}
9 years ago
}
}
9 years ago
if ( (destflag & SUPERNET_ISMINE) != 0 && agent != 0 && method != 0 )
9 years ago
{
9 years ago
if ( newflag == 0 && hexmsg != 0 && SuperNET_hexmsgfind(myinfo,category,subhash,hexmsg,0) < 0 )
9 years ago
SuperNET_hexmsgadd(myinfo,category,subhash,hexmsg,tai_now(),remoteaddr);
9 years ago
if ( (retstr= SuperNET_processJSON(myinfo,json,remoteaddr,port)) != 0 )
9 years ago
{
//printf("retstr.(%s)\n",retstr);
if ( remoteaddr != 0 && (retjson= cJSON_Parse(retstr)) != 0 )
{
if ( jobj(retjson,"result") != 0 || jobj(retjson,"error") != 0 || jobj(retjson,"method") == 0 )
{
//printf("it is a result, dont return\n");
free(retstr);
retstr = 0;
}
free_json(retjson);
}
} else printf("null retstr from SuperNET_JSON\n");
}
if ( flag != 0 && hexmsg != 0 && hexmsg != hexbuf )
9 years ago
free(hexmsg);
9 years ago
if ( retstr == 0 )
retstr = forwardstr, forwardstr = 0;
if ( forwardstr != 0 )
free(forwardstr);
if ( jsonstr != 0 )
free(jsonstr);
return(retstr);
}
char *SuperNET_p2p(struct iguana_info *coin,struct iguana_peer *addr,int32_t *delaymillisp,char *ipaddr,uint8_t *data,int32_t datalen,int32_t compressed)
9 years ago
{
9 years ago
struct supernet_info *myinfo;char *myipaddr,*method,*retstr,*checkstr; void *ptr=0;
bits256 senderpub,privkey,pubkey,nextprivkey,nextpubkey,nextdestpub;
uint16_t checkc,othercheckc; cJSON *json,*retjson; int32_t offset,maxdelay,msglen = datalen;
uint8_t space[8192],*msgbits = 0;
9 years ago
myinfo = SuperNET_MYINFO(0);
9 years ago
retstr = 0;
9 years ago
*delaymillisp = 0;
if ( compressed != 0 )
9 years ago
{
9 years ago
//int32_t i; for (i=0; i<datalen; i++)
// printf("%02x ",data[i]);
//printf("DECRYPT %d\n",datalen);
iguana_setkeys(myinfo,addr,&privkey,&pubkey,&senderpub,&nextprivkey,&nextpubkey,&nextdestpub);
9 years ago
senderpub = iguana_actualpubkey(&offset,data,datalen,senderpub);
if ( (msgbits= SuperNET_deciphercalc(&ptr,&msglen,privkey,senderpub,data+offset,datalen-offset,space,sizeof(space))) == 0 )
9 years ago
{
9 years ago
if ( (msgbits= SuperNET_deciphercalc(&ptr,&msglen,GENESIS_PRIVKEY,GENESIS_PUBKEY,data+offset,datalen-offset,space,sizeof(space))) == 0 )
9 years ago
{
9 years ago
if ( (msgbits= SuperNET_deciphercalc(&ptr,&msglen,GENESIS_PRIVKEY,senderpub,data+offset,datalen-offset,space,sizeof(space))) == 0 )
{
int32_t i; for (i=0; i<datalen; i++)
printf("%02x ",data[i]);
printf("error decrypting %d from %s\n",datalen,addr->ipaddr);
addr->validpub = 0;
return(0);
} else { char str[65]; printf("GENESIS recv %s\n",bits256_str(str,senderpub)); }
} else printf("GENESIS recv GENESIS\n");
9 years ago
} //else printf("decrypted mypriv.%llx senderpub.%llx\n",(long long)privkey.txid,(long long)senderpub.txid);
9 years ago
//for (i=0; i<msglen; i++)
// printf("%02x ",msgbits[i]);
//printf("DECRYPTED %d\n",msglen);
9 years ago
} else msgbits = data;
9 years ago
if ( (json= SuperNET_bits2json(msgbits,msglen)) != 0 )
9 years ago
{
9 years ago
senderpub = jbits256(json,"mypub");
9 years ago
if ( (checkstr= jstr(json,"check")) != 0 )
9 years ago
{
decode_hex((uint8_t *)&othercheckc,sizeof(othercheckc),checkstr);
9 years ago
checkc = SuperNET_checkc(myinfo->privkey,senderpub,&senderpub.txid,sizeof(senderpub.txid));
9 years ago
if ( checkc == othercheckc )
9 years ago
addr->validpub++;
else if ( addr->validpub > 0 )
addr->validpub >>= 1;
9 years ago
else addr->validpub--;
9 years ago
//printf("validpub.%d: %x vs %x shared.%llx\n",addr->validpub,checkc,othercheckc,(long long)addr->sharedseed.txid);
9 years ago
}
9 years ago
maxdelay = juint(json,"maxdelay");
9 years ago
if ( 0 && jstr(json,"method") != 0 && strcmp(jstr(json,"method"),"getpeers") != 0 )
9 years ago
printf("GOT >>>>>>>> SUPERNET P2P.(%s) from.%s %s valid.%d:%d\n",jprint(json,0),coin->symbol,addr->ipaddr,addr->validpub,addr->othervalid);
9 years ago
if ( (myipaddr= jstr(json,"yourip")) != 0 )
9 years ago
SuperNET_checkipaddr(SuperNET_MYINFO(0),coin,addr,myipaddr,ipaddr);
9 years ago
jaddstr(json,"fromp2p",coin->symbol);
method = jstr(json,"method");
if ( method != 0 && strcmp(method,"stop") == 0 )
{
addr->dead = (uint32_t)time(NULL);
9 years ago
addr->rank = 0;
9 years ago
free_json(json);
9 years ago
if ( ptr != 0 )
free(ptr);
9 years ago
//return(clonestr("{\"result\":\"peer marked as dead\"}"));
return(0);
9 years ago
}
9 years ago
retstr = SuperNET_JSON(myinfo,json,ipaddr,addr->A.port);
9 years ago
//printf("p2pret.(%s)\n",retstr);
9 years ago
*delaymillisp = SuperNET_delaymillis(myinfo,maxdelay);
senderpub = jbits256(json,"mypub");
9 years ago
addr->othervalid = (int32_t)jdouble(json,"ov");
9 years ago
addr->pubkey = senderpub;
9 years ago
free_json(json);
9 years ago
if ( (retjson= cJSON_Parse(retstr)) != 0 )
{
if ( jstr(retjson,"error") != 0 || (jstr(retjson,"result") != 0 && jstr(retjson,"method") == 0) )
{
9 years ago
//printf("filter.(%s) no need to send back\n",retstr);
9 years ago
free(retstr);
retstr = 0;
}
free_json(retjson);
}
}
9 years ago
if ( ptr != 0 )
free(ptr);
9 years ago
return(retstr);
}
9 years ago
cJSON *SuperNET_peerarray(struct iguana_info *coin,int32_t max,int32_t supernetflag)
{
int32_t i,r,j,n = 0; struct iguana_peer *addr; cJSON *array = cJSON_CreateArray();
r = rand();
for (j=0; j<IGUANA_MAXPEERS; j++)
{
i = (r + j) % IGUANA_MAXPEERS;
addr = &coin->peers.active[i];
if ( addr->usock >= 0 && supernetflag == (addr->supernet != 0) )
{
jaddistr(array,addr->ipaddr);
if ( ++n >= max )
break;
}
}
if ( n == 0 )
{
free_json(array);
return(0);
}
return(array);
}
int32_t SuperNET_coinpeers(struct iguana_info *coin,cJSON *SNjson,cJSON *rawjson,int32_t max)
{
cJSON *array,*item;
if ( (array= SuperNET_peerarray(coin,max,1)) != 0 )
{
max -= cJSON_GetArraySize(array);
item = cJSON_CreateObject();
jaddstr(item,"coin",coin->symbol);
jadd(item,"peers",array);
jaddi(SNjson,item);
}
if ( max > 0 && (array= SuperNET_peerarray(coin,max,0)) != 0 )
{
max -= cJSON_GetArraySize(array);
item = cJSON_CreateObject();
jaddstr(item,"coin",coin->symbol);
jadd(item,"peers",array);
jaddi(rawjson,item);
}
return(max);
}
void SuperNET_parsepeers(struct supernet_info *myinfo,cJSON *array,int32_t n,int32_t supernetflag)
{
int32_t i,j,m; cJSON *coinarray,*item; char *symbol,*ipaddr; struct iguana_info *ptr;
if ( array != 0 && n > 0 )
{
for (i=0; i<n; i++)
{
if ( (item= jitem(array,i)) != 0 && (symbol= jstr(item,"coin")) != 0 )
{
ptr = iguana_coinfind(symbol);
if ( (coinarray= jarray(&m,item,"peers")) != 0 )
{
for (j=0; j<m; j++)
{
if ( (ipaddr= jstr(jitem(coinarray,j),0)) != 0 )
SuperNET_remotepeer(myinfo,ptr,symbol,ipaddr,supernetflag);
else printf("no ipaddr[%d] of %d\n",j,m);
}
}
printf("parsed.%d %s.peers supernet.%d\n",m,symbol,supernetflag);
}
}
}
}
many changes blockexplorer tab: needs to allow to input height, blockhash or txid. also please display images/BTC_blocks.jpg below the text as a w800 x h400 bitmap, which is active using the mouse api for coin management, below the active coins have a form that arbitrary json can be input with an add button to the right that will call &#34;addcoin&#34; API. this way I can test adding new coins dynamically. dont worry if it doesnt work, just as long as it submits the json to the C code. I am pretty sure I need to do some debugging of this peers management is not working for me at all. maybe it is due to bad internet. On initialization you need to read in the confs/BTCD_peers.txt from the native filesystem and save it into the chrome app filesystem. same thing for confs/BTCD_hdrs.txt. But this is only to be done if there isnt already such a file inside chrome. if there is, only do it upon a button invoked by the user. the reason is that the pexe is updating this file with the latest. Maybe it is nice to have an &#34;extract&#34; button that will copy out from the chrome storage into the native filesystem. There is also the manifest issue about localstorage vs chrome.localstorage. not sure what is needed to be done, but certainly a priority to get it so everything works as a chrome app. I know before it was making ramchain files inside the chrome filesystem, so it is probably things the GUI is doing. maybe in the settings tab, which has obsolete stuff that can be removed. anyway, the issue about files existing in the native filesystem -&gt; chrome and optionally extracting them is an issue for the confs files and .html template files used to autogenerate the port7778, maybe other files are affected. i think we need a way to have a list of hardcoded files that are just copied into chrome on startup if they dont exist already (or if possible copy over if the native version is bigger?) and buttons to extract them for debug tab: THREE_STRINGS(SuperNET,encryptjson,passphrase,permanentfile,anything); TWO_STRINGS(SuperNET,decryptjson,passphrase,permanentfile); at the top of page a way to put in passphrase and optional permanentfile along with arbitrary json. The standard form template has no easy way to describe to pass in everything as it is oriented to specific fields. but the encryptjson API saves all the fields, so the arbitrary json from the form needs to be combined at the same level as the &#34;agent&#34;, &#34;method&#34;, etc. I know, not the best, but internally it makes it easier. so {&#34;agent&#34;:&#34;SuperNET&#34;,&#34;method&#34;:&#34;encryptjson&#34;,&#34;passphrase&#34;:&#34;&lt;passphrase&gt;&#34;,&#34; permanentfile&#34;:&#34;&lt;filename&gt;&#34;,&#34;fromform&#34;:&#34;valuefromform&#34;,&#34;fromform2&#34;:&#34;valu efromform2&#34;,...rest of form at top level} then this will save it into a file with crazy number (it is a hash like txid) but given the same passphrase and filename, it will regenerate this hash so you dont actually have to store it, but it helps during debugging. for the filename, we must warn quite strongly to the user that if the file is ever lost or even changed in any way that the data will not be recoverable. also best to not allow the user to specify a file that does not exist. I think at this point chrome app version gets a bit tricky. we could simply push the native file into the chrome storage, but then an attacker who gets access to the computer could just get a list of these files and it really wont be much protection. So that means if a filename is specified, it needs to be copied into the chrome space, then immediately deleted... ok, this seems like not a good approach. let us make it so that the permanentfile option is not available from the chrome app, but only if the native version is running. that way we sidestep the issue of the pexe not having access to the specified file. Speaking of native vs pexe, on the startup page we should have a radio button that allows the user to select which the GUI will talk to. It should default based on a self test to the more likely value, but it is possible that the user wants to use the native version, even if the pexe is running. another thing to have on the startup page is a simple login: THREE_STRINGS(SuperNET,login,passphrase,permanentfile,handle); ZERO_ARGS(SuperNET,logout); ZERO_ARGS(SuperNET,activehandle); the handle is a human readable name that is associated with the passphrase/permanentfile. There can only be one active account (though it will be possible to associate different accounts with tradebots). use the activehandle API to find out who is logged in and the associated addresses and pubkeys The above is not yet tested so if it doesnt work, dont fret, just let me know. Once set the handle can be displayed in various places to let the user know which account is logged in. The standard 12 dictionary word passphrases should be used, but any string can be sent in as the password for Pangea: INT_AND_ARRAY(pangea,host,minplayers,params); ZERO_ARGS(pangea,lobby); HASH_AND_STRING(pangea,join,tablehash,handle); HASH_AND_INT(pangea,buyin,tablehash,numchips); HASH_ARG(pangea,start,tablehash); // by host only HASH_ARG(pangea,status,tablehash); HASH_ARG(pangea,call,tablehash); HASH_ARG(pangea,check,tablehash); HASH_AND_INT(pangea,raise,tablehash,numchips); HASH_AND_INT(pangea,bet,tablehash,numchips); HASH_ARG(pangea,fold,tablehash); HASH_AND_STRING(pangea,mode,tablehash,modestr); HASH_ARG(pangea,history,tablehash); HASH_AND_INT(pangea,handhistory,tablehash,hand); The first thing that is done is a &#34;host&#34; by any node. the &#34;params&#34; should be an arbitrary json (like encryptjson) as it needs to be at the top level and it has quite a few different parameters still subject to change. The lobby API will just display all the hosted tables. once a table exists, players can join and then buyin. the buyin is denominated in chips, each chip&#39;s value is determined by the host&#39;s initial parameters. once there are enough players joined with adequate buyin&#39;s verified, the host will be able to do a start. if done before it will (eventually) give an error. for now it will just proceed. The host and players that have joined a tablehash, need to do regular status calls to see if the game has started. Probably just once per 5 or even 10 seconds is fine before the start. Once the game starts (the status will have this info) then once per second polling is needed. Then when it is your turn (as indicated by status) you need to do one of the 5 actions (fold, call, check, raise, bet). do not worry if you dont understand what all these do, just allow the user to do any of these. I guess it is possible to submit it ahead of time. I will support internally remembering the most recent action done prior to it being your turn. once it is your turn and an action is sent to the table, it is too late to change. The last API calls are for getting handhistory where hand is 0 to N-1, being the numbering of the hands played at that table. if just history, all the history for all hands at the table is coming back, so it could be quite big. probably I will make it a summary, but for the GUI just display the returned values. the mode is to change some poker specific modes, so just allow there to be a string entered. do not worry about understanding the pokerness of the API, just the overall flow: host -&gt; creates, join/buyin -&gt; fills up player slots, start -&gt; starts the game status -&gt; to determine when the game starts (or if it is cancelled) and once started actions -&gt; game specific but basically just (button + arg) that is the user input results are via status for current game and history for past ones please try to do the above logic in a generic way so it can be reused for other games. The basic flow should be the same for almost all multiplayer turn based games and even for multiplayer realtime games For InstantDEX: on the apikeypair/userid there needs to be two modes. one for when there is no stored apikey and the current form is fine, just need to make it wider as most apikeys are quite long. Now once there is an apikey saved all that is needed is the passphrase to unlock it. So here is where the encrptjson/decryptjson is used. When saving the apikey for the first time, it can be: a) not saved -&gt; nothing extra to do b) saved without password -&gt; you can just save to a file and use it to load it back in. use confs dir confs/instantdex.exchange.api or something like that c) saved with password (optional filename for native) -&gt; probably best to save in the confs dir to indicate that there is an encrypted file for this, so just that and not the actual passphrase in the file with the above, when the exchange is selected, you can see if the confs file exists and if it has the plaintext, just populate the field, if not, then indicate that a passphrase is needed. if the user provides the passphrase, then decryptjson and populate the fields and autosubmit. A special case is to encrypt the apikeys with the passphrase used when logging in. This is only available if the checkbox to &#34;remember passphrase during session&#34; is set on the main iguana login screen. (i forgot to mention that checkbox!) So the login passphrase is stored in memory, then the GUI simply uses that + encryptjson for storing/decrypting. I would imagine that storing in the confs file that it is encrypted using &#34;handle&#34;&#39;s account login might be a good way to differentiate between this mode of password usage. OK, so we now have the insecure plaintext, the decent using handle&#39;s passphrase and paranoid different passphrase for each exchange (with additional permanentfile for native versions) &#34;SUPPORT&#34; -&gt; &#34;SUPPORTS&#34; just a typo and &#34;allpairs&#34; API is missing from the selection Might as well add a &#34;tradebots&#34; tab: THREE_STRINGS_AND_DOUBLE(tradebot,monitor,exchange,base,rel,commission); STRING_AND_DOUBLE(tradebot,monitorall,exchange,commission); THREE_STRINGS(tradebot,unmonitor,exchange,base,rel); THREE_STRINGS_AND_THREE_DOUBLES(tradebot,accumulate,exchange,base,rel,pr ice,volume,duration); THREE_STRINGS_AND_THREE_DOUBLES(tradebot,divest,exchange,base,rel,price, volume,duration); STRING_ARG(tradebot,activebots,exchange); TWO_STRINGS(tradebot,status,exchange,botid); TWO_STRINGS(tradebot,pause,exchange,botid); TWO_STRINGS(tradebot,stop,exchange,botid); TWO_STRINGS(tradebot,resume,exchange,botid); the above are API for exchange specific bots, most should be self-explanatory. bots are created via &#34;accumulate&#34; or &#34;divest&#34; API call. it returns botid. once created, you can do status, pause, stop, resume to a botid. and an activebots API call lists all the active bots for an exchange. duration is in seconds the &#34;monitor&#34; API starts background monitoring of a specific base/rel, &#34;unmonitor&#34; stops this. &#34;monitorall&#34; just does a monitor to the entire list of &#34;allpairs&#34; for that exchange. Keep in mind that doing a monitorall will not add load to an exchange as the request to each exchange is governed by pollgap, but if you have 3 things monitored, it will take 3*pollgap + time each one takes to execute. and if N are monitored it is N*pollgap + time of each, with the &#34;time of each&#34; possibly taking a very long time. And one final request for today: Bitmap tab. It should be an active bitmap using mouse api. either a dropdown to select the bitmap or a form entry. then the rest of the page (resize the bitmap to the page size) being the active bitmap. So on a small screen the bitmap is smaller x/y dimensions and larger on larger screens. plz make sure the proper dimensions are communicated to the pexe via API if it ever is changed. @vineet.bhargav86: I changed the &#34;passphrase&#34; fieldname to &#34;password&#34; for the encryptjson/decryptjson related API. The reason is that the password is like a wallet password and is only local, so it doesnt need to be as high entropy as passphrase. I also added a field to the login API as I realized that the 12 word &#34;passphrase&#34; is the payload and usually wont be sent in: FOUR_STRINGS(SuperNET,login,handle,password,permanentfile,passphrase); using &#34;abiglongpassword&#34; for the passphrase -&gt; {&#34;pubkey&#34;:&#34;6c469ba10b40b3eb9d1dba569d7f929d55a29d8f97cd5425907ef2f38f906 209&#34;,&#34;RS&#34;:&#34;NXT-KGV9-DXX8-TM86-DXR96&#34;,&#34;NXT&#34;:&#34;12834974574569896807&#34;,&#34;btcpu bkey&#34;:&#34;024e7641dc947b211bc30fe3339765258902794687b227121fc217284f9d8503c 8&#34;,&#34;rmd160&#34;:&#34;33453c24914db7b77069b7ea24df44f6be145938&#34;,&#34;BTC&#34;:&#34;15g6QK2dSd iW9ZTQEnnJxKrSph6uP7uU23&#34;,&#34;BTCD&#34;:&#34;RDxHUpuv3TX5DZpbhxmS3rBeaxZW1fvYvC&#34;,&#34;r esult&#34;:&#34;success&#34;,&#34;handle&#34;:&#34;test&#34;,&#34;tag&#34;:&#34;14805226009240621255&#34;} and if you use that to log into NXT, it gives the same address. The BTC and BTCD addresses are all derived from the same privkey so they are all interchangeable with the NXT address. The user can therefore select which coin&#39;s addressing they are most comfortable with I also added an &#34;allin&#34; action API for pangea. all the action API will autocalculate the number of chips if passed in 0 for numchips ***************** security issue ******** please dont use the GET URL method when dealing with passphrase!!! Those URL&#39;s tend to get logged and available in browser histories. so anything dealing with the actual passphrase needs to use the postCall form or POST
9 years ago
cJSON *SuperNET_rosettajson(bits256 privkey,int32_t showprivs)
{
uint8_t rmd160[20],pub[33],flag = 0; uint64_t nxt64bits; bits256 pubkey;
char str2[41],wifbuf[64],addr[64],str[128]; cJSON *retjson;
pubkey = acct777_pubkey(privkey);
nxt64bits = acct777_nxt64bits(pubkey);
retjson = cJSON_CreateObject();
jaddbits256(retjson,"pubkey",pubkey);
RS_encode(str,nxt64bits);
jaddstr(retjson,"RS",str);
jadd64bits(retjson,"NXT",nxt64bits);
btc_priv2pub(pub,privkey.bytes);
init_hexbytes_noT(str,pub,33);
jaddstr(retjson,"btcpubkey",str);
calc_OP_HASH160(str2,rmd160,str);
jaddstr(retjson,"rmd160",str2);
if ( btc_coinaddr(addr,0,str) == 0 )
{
jaddstr(retjson,"BTC",addr);
if ( flag != 0 )
{
btc_priv2wif(wifbuf,privkey.bytes,0x80);
jaddstr(retjson,"BTCwif",wifbuf);
}
}
if ( btc_coinaddr(addr,60,str) == 0 )
{
jaddstr(retjson,"BTCD",addr);
if ( flag != 0 )
{
btc_priv2wif(wifbuf,privkey.bytes,0xbc);
jaddstr(retjson,"BTCDwif",wifbuf);
}
}
if ( flag != 0 )
jaddbits256(retjson,"privkey",privkey);
return(retjson);
}
9 years ago
#include "../includes/iguana_apidefs.h"
9 years ago
STRING_ARG(SuperNET,addr2rmd160,address)
{
uint8_t addrtype,rmd160[20]; char rmdstr[41]; cJSON *retjson;
bitcoin_addr2rmd160(&addrtype,rmd160,address);
init_hexbytes_noT(rmdstr,rmd160,sizeof(rmd160));
retjson = cJSON_CreateObject();
jaddstr(retjson,"result",rmdstr);
jaddnum(retjson,"addrtype",addrtype);
jaddstr(retjson,"address",address);
return(jprint(retjson,1));
}
9 years ago
HASH_AND_INT(SuperNET,priv2pub,privkey,addrtype)
9 years ago
{
9 years ago
cJSON *retjson; bits256 pub; uint8_t pubkey[33]; char coinaddr[64];
many changes blockexplorer tab: needs to allow to input height, blockhash or txid. also please display images/BTC_blocks.jpg below the text as a w800 x h400 bitmap, which is active using the mouse api for coin management, below the active coins have a form that arbitrary json can be input with an add button to the right that will call &#34;addcoin&#34; API. this way I can test adding new coins dynamically. dont worry if it doesnt work, just as long as it submits the json to the C code. I am pretty sure I need to do some debugging of this peers management is not working for me at all. maybe it is due to bad internet. On initialization you need to read in the confs/BTCD_peers.txt from the native filesystem and save it into the chrome app filesystem. same thing for confs/BTCD_hdrs.txt. But this is only to be done if there isnt already such a file inside chrome. if there is, only do it upon a button invoked by the user. the reason is that the pexe is updating this file with the latest. Maybe it is nice to have an &#34;extract&#34; button that will copy out from the chrome storage into the native filesystem. There is also the manifest issue about localstorage vs chrome.localstorage. not sure what is needed to be done, but certainly a priority to get it so everything works as a chrome app. I know before it was making ramchain files inside the chrome filesystem, so it is probably things the GUI is doing. maybe in the settings tab, which has obsolete stuff that can be removed. anyway, the issue about files existing in the native filesystem -&gt; chrome and optionally extracting them is an issue for the confs files and .html template files used to autogenerate the port7778, maybe other files are affected. i think we need a way to have a list of hardcoded files that are just copied into chrome on startup if they dont exist already (or if possible copy over if the native version is bigger?) and buttons to extract them for debug tab: THREE_STRINGS(SuperNET,encryptjson,passphrase,permanentfile,anything); TWO_STRINGS(SuperNET,decryptjson,passphrase,permanentfile); at the top of page a way to put in passphrase and optional permanentfile along with arbitrary json. The standard form template has no easy way to describe to pass in everything as it is oriented to specific fields. but the encryptjson API saves all the fields, so the arbitrary json from the form needs to be combined at the same level as the &#34;agent&#34;, &#34;method&#34;, etc. I know, not the best, but internally it makes it easier. so {&#34;agent&#34;:&#34;SuperNET&#34;,&#34;method&#34;:&#34;encryptjson&#34;,&#34;passphrase&#34;:&#34;&lt;passphrase&gt;&#34;,&#34; permanentfile&#34;:&#34;&lt;filename&gt;&#34;,&#34;fromform&#34;:&#34;valuefromform&#34;,&#34;fromform2&#34;:&#34;valu efromform2&#34;,...rest of form at top level} then this will save it into a file with crazy number (it is a hash like txid) but given the same passphrase and filename, it will regenerate this hash so you dont actually have to store it, but it helps during debugging. for the filename, we must warn quite strongly to the user that if the file is ever lost or even changed in any way that the data will not be recoverable. also best to not allow the user to specify a file that does not exist. I think at this point chrome app version gets a bit tricky. we could simply push the native file into the chrome storage, but then an attacker who gets access to the computer could just get a list of these files and it really wont be much protection. So that means if a filename is specified, it needs to be copied into the chrome space, then immediately deleted... ok, this seems like not a good approach. let us make it so that the permanentfile option is not available from the chrome app, but only if the native version is running. that way we sidestep the issue of the pexe not having access to the specified file. Speaking of native vs pexe, on the startup page we should have a radio button that allows the user to select which the GUI will talk to. It should default based on a self test to the more likely value, but it is possible that the user wants to use the native version, even if the pexe is running. another thing to have on the startup page is a simple login: THREE_STRINGS(SuperNET,login,passphrase,permanentfile,handle); ZERO_ARGS(SuperNET,logout); ZERO_ARGS(SuperNET,activehandle); the handle is a human readable name that is associated with the passphrase/permanentfile. There can only be one active account (though it will be possible to associate different accounts with tradebots). use the activehandle API to find out who is logged in and the associated addresses and pubkeys The above is not yet tested so if it doesnt work, dont fret, just let me know. Once set the handle can be displayed in various places to let the user know which account is logged in. The standard 12 dictionary word passphrases should be used, but any string can be sent in as the password for Pangea: INT_AND_ARRAY(pangea,host,minplayers,params); ZERO_ARGS(pangea,lobby); HASH_AND_STRING(pangea,join,tablehash,handle); HASH_AND_INT(pangea,buyin,tablehash,numchips); HASH_ARG(pangea,start,tablehash); // by host only HASH_ARG(pangea,status,tablehash); HASH_ARG(pangea,call,tablehash); HASH_ARG(pangea,check,tablehash); HASH_AND_INT(pangea,raise,tablehash,numchips); HASH_AND_INT(pangea,bet,tablehash,numchips); HASH_ARG(pangea,fold,tablehash); HASH_AND_STRING(pangea,mode,tablehash,modestr); HASH_ARG(pangea,history,tablehash); HASH_AND_INT(pangea,handhistory,tablehash,hand); The first thing that is done is a &#34;host&#34; by any node. the &#34;params&#34; should be an arbitrary json (like encryptjson) as it needs to be at the top level and it has quite a few different parameters still subject to change. The lobby API will just display all the hosted tables. once a table exists, players can join and then buyin. the buyin is denominated in chips, each chip&#39;s value is determined by the host&#39;s initial parameters. once there are enough players joined with adequate buyin&#39;s verified, the host will be able to do a start. if done before it will (eventually) give an error. for now it will just proceed. The host and players that have joined a tablehash, need to do regular status calls to see if the game has started. Probably just once per 5 or even 10 seconds is fine before the start. Once the game starts (the status will have this info) then once per second polling is needed. Then when it is your turn (as indicated by status) you need to do one of the 5 actions (fold, call, check, raise, bet). do not worry if you dont understand what all these do, just allow the user to do any of these. I guess it is possible to submit it ahead of time. I will support internally remembering the most recent action done prior to it being your turn. once it is your turn and an action is sent to the table, it is too late to change. The last API calls are for getting handhistory where hand is 0 to N-1, being the numbering of the hands played at that table. if just history, all the history for all hands at the table is coming back, so it could be quite big. probably I will make it a summary, but for the GUI just display the returned values. the mode is to change some poker specific modes, so just allow there to be a string entered. do not worry about understanding the pokerness of the API, just the overall flow: host -&gt; creates, join/buyin -&gt; fills up player slots, start -&gt; starts the game status -&gt; to determine when the game starts (or if it is cancelled) and once started actions -&gt; game specific but basically just (button + arg) that is the user input results are via status for current game and history for past ones please try to do the above logic in a generic way so it can be reused for other games. The basic flow should be the same for almost all multiplayer turn based games and even for multiplayer realtime games For InstantDEX: on the apikeypair/userid there needs to be two modes. one for when there is no stored apikey and the current form is fine, just need to make it wider as most apikeys are quite long. Now once there is an apikey saved all that is needed is the passphrase to unlock it. So here is where the encrptjson/decryptjson is used. When saving the apikey for the first time, it can be: a) not saved -&gt; nothing extra to do b) saved without password -&gt; you can just save to a file and use it to load it back in. use confs dir confs/instantdex.exchange.api or something like that c) saved with password (optional filename for native) -&gt; probably best to save in the confs dir to indicate that there is an encrypted file for this, so just that and not the actual passphrase in the file with the above, when the exchange is selected, you can see if the confs file exists and if it has the plaintext, just populate the field, if not, then indicate that a passphrase is needed. if the user provides the passphrase, then decryptjson and populate the fields and autosubmit. A special case is to encrypt the apikeys with the passphrase used when logging in. This is only available if the checkbox to &#34;remember passphrase during session&#34; is set on the main iguana login screen. (i forgot to mention that checkbox!) So the login passphrase is stored in memory, then the GUI simply uses that + encryptjson for storing/decrypting. I would imagine that storing in the confs file that it is encrypted using &#34;handle&#34;&#39;s account login might be a good way to differentiate between this mode of password usage. OK, so we now have the insecure plaintext, the decent using handle&#39;s passphrase and paranoid different passphrase for each exchange (with additional permanentfile for native versions) &#34;SUPPORT&#34; -&gt; &#34;SUPPORTS&#34; just a typo and &#34;allpairs&#34; API is missing from the selection Might as well add a &#34;tradebots&#34; tab: THREE_STRINGS_AND_DOUBLE(tradebot,monitor,exchange,base,rel,commission); STRING_AND_DOUBLE(tradebot,monitorall,exchange,commission); THREE_STRINGS(tradebot,unmonitor,exchange,base,rel); THREE_STRINGS_AND_THREE_DOUBLES(tradebot,accumulate,exchange,base,rel,pr ice,volume,duration); THREE_STRINGS_AND_THREE_DOUBLES(tradebot,divest,exchange,base,rel,price, volume,duration); STRING_ARG(tradebot,activebots,exchange); TWO_STRINGS(tradebot,status,exchange,botid); TWO_STRINGS(tradebot,pause,exchange,botid); TWO_STRINGS(tradebot,stop,exchange,botid); TWO_STRINGS(tradebot,resume,exchange,botid); the above are API for exchange specific bots, most should be self-explanatory. bots are created via &#34;accumulate&#34; or &#34;divest&#34; API call. it returns botid. once created, you can do status, pause, stop, resume to a botid. and an activebots API call lists all the active bots for an exchange. duration is in seconds the &#34;monitor&#34; API starts background monitoring of a specific base/rel, &#34;unmonitor&#34; stops this. &#34;monitorall&#34; just does a monitor to the entire list of &#34;allpairs&#34; for that exchange. Keep in mind that doing a monitorall will not add load to an exchange as the request to each exchange is governed by pollgap, but if you have 3 things monitored, it will take 3*pollgap + time each one takes to execute. and if N are monitored it is N*pollgap + time of each, with the &#34;time of each&#34; possibly taking a very long time. And one final request for today: Bitmap tab. It should be an active bitmap using mouse api. either a dropdown to select the bitmap or a form entry. then the rest of the page (resize the bitmap to the page size) being the active bitmap. So on a small screen the bitmap is smaller x/y dimensions and larger on larger screens. plz make sure the proper dimensions are communicated to the pexe via API if it ever is changed. @vineet.bhargav86: I changed the &#34;passphrase&#34; fieldname to &#34;password&#34; for the encryptjson/decryptjson related API. The reason is that the password is like a wallet password and is only local, so it doesnt need to be as high entropy as passphrase. I also added a field to the login API as I realized that the 12 word &#34;passphrase&#34; is the payload and usually wont be sent in: FOUR_STRINGS(SuperNET,login,handle,password,permanentfile,passphrase); using &#34;abiglongpassword&#34; for the passphrase -&gt; {&#34;pubkey&#34;:&#34;6c469ba10b40b3eb9d1dba569d7f929d55a29d8f97cd5425907ef2f38f906 209&#34;,&#34;RS&#34;:&#34;NXT-KGV9-DXX8-TM86-DXR96&#34;,&#34;NXT&#34;:&#34;12834974574569896807&#34;,&#34;btcpu bkey&#34;:&#34;024e7641dc947b211bc30fe3339765258902794687b227121fc217284f9d8503c 8&#34;,&#34;rmd160&#34;:&#34;33453c24914db7b77069b7ea24df44f6be145938&#34;,&#34;BTC&#34;:&#34;15g6QK2dSd iW9ZTQEnnJxKrSph6uP7uU23&#34;,&#34;BTCD&#34;:&#34;RDxHUpuv3TX5DZpbhxmS3rBeaxZW1fvYvC&#34;,&#34;r esult&#34;:&#34;success&#34;,&#34;handle&#34;:&#34;test&#34;,&#34;tag&#34;:&#34;14805226009240621255&#34;} and if you use that to log into NXT, it gives the same address. The BTC and BTCD addresses are all derived from the same privkey so they are all interchangeable with the NXT address. The user can therefore select which coin&#39;s addressing they are most comfortable with I also added an &#34;allin&#34; action API for pangea. all the action API will autocalculate the number of chips if passed in 0 for numchips ***************** security issue ******** please dont use the GET URL method when dealing with passphrase!!! Those URL&#39;s tend to get logged and available in browser histories. so anything dealing with the actual passphrase needs to use the postCall form or POST
9 years ago
if ( remoteaddr != 0 )
return(clonestr("{\"error\":\"no remote\"}"));
retjson = cJSON_CreateObject();
9 years ago
crypto_box_priv2pub(pub.bytes,privkey.bytes);
jaddbits256(retjson,"curve25519",pub);
pub = bitcoin_pubkey33(pubkey,privkey);
jaddbits256(retjson,"secp256k1",pub);
bitcoin_address(coinaddr,addrtype,pubkey,33);
jaddstr(retjson,"result",coinaddr);
9 years ago
return(jprint(retjson,1));
}
ZERO_ARGS(SuperNET,keypair)
{
many changes blockexplorer tab: needs to allow to input height, blockhash or txid. also please display images/BTC_blocks.jpg below the text as a w800 x h400 bitmap, which is active using the mouse api for coin management, below the active coins have a form that arbitrary json can be input with an add button to the right that will call &#34;addcoin&#34; API. this way I can test adding new coins dynamically. dont worry if it doesnt work, just as long as it submits the json to the C code. I am pretty sure I need to do some debugging of this peers management is not working for me at all. maybe it is due to bad internet. On initialization you need to read in the confs/BTCD_peers.txt from the native filesystem and save it into the chrome app filesystem. same thing for confs/BTCD_hdrs.txt. But this is only to be done if there isnt already such a file inside chrome. if there is, only do it upon a button invoked by the user. the reason is that the pexe is updating this file with the latest. Maybe it is nice to have an &#34;extract&#34; button that will copy out from the chrome storage into the native filesystem. There is also the manifest issue about localstorage vs chrome.localstorage. not sure what is needed to be done, but certainly a priority to get it so everything works as a chrome app. I know before it was making ramchain files inside the chrome filesystem, so it is probably things the GUI is doing. maybe in the settings tab, which has obsolete stuff that can be removed. anyway, the issue about files existing in the native filesystem -&gt; chrome and optionally extracting them is an issue for the confs files and .html template files used to autogenerate the port7778, maybe other files are affected. i think we need a way to have a list of hardcoded files that are just copied into chrome on startup if they dont exist already (or if possible copy over if the native version is bigger?) and buttons to extract them for debug tab: THREE_STRINGS(SuperNET,encryptjson,passphrase,permanentfile,anything); TWO_STRINGS(SuperNET,decryptjson,passphrase,permanentfile); at the top of page a way to put in passphrase and optional permanentfile along with arbitrary json. The standard form template has no easy way to describe to pass in everything as it is oriented to specific fields. but the encryptjson API saves all the fields, so the arbitrary json from the form needs to be combined at the same level as the &#34;agent&#34;, &#34;method&#34;, etc. I know, not the best, but internally it makes it easier. so {&#34;agent&#34;:&#34;SuperNET&#34;,&#34;method&#34;:&#34;encryptjson&#34;,&#34;passphrase&#34;:&#34;&lt;passphrase&gt;&#34;,&#34; permanentfile&#34;:&#34;&lt;filename&gt;&#34;,&#34;fromform&#34;:&#34;valuefromform&#34;,&#34;fromform2&#34;:&#34;valu efromform2&#34;,...rest of form at top level} then this will save it into a file with crazy number (it is a hash like txid) but given the same passphrase and filename, it will regenerate this hash so you dont actually have to store it, but it helps during debugging. for the filename, we must warn quite strongly to the user that if the file is ever lost or even changed in any way that the data will not be recoverable. also best to not allow the user to specify a file that does not exist. I think at this point chrome app version gets a bit tricky. we could simply push the native file into the chrome storage, but then an attacker who gets access to the computer could just get a list of these files and it really wont be much protection. So that means if a filename is specified, it needs to be copied into the chrome space, then immediately deleted... ok, this seems like not a good approach. let us make it so that the permanentfile option is not available from the chrome app, but only if the native version is running. that way we sidestep the issue of the pexe not having access to the specified file. Speaking of native vs pexe, on the startup page we should have a radio button that allows the user to select which the GUI will talk to. It should default based on a self test to the more likely value, but it is possible that the user wants to use the native version, even if the pexe is running. another thing to have on the startup page is a simple login: THREE_STRINGS(SuperNET,login,passphrase,permanentfile,handle); ZERO_ARGS(SuperNET,logout); ZERO_ARGS(SuperNET,activehandle); the handle is a human readable name that is associated with the passphrase/permanentfile. There can only be one active account (though it will be possible to associate different accounts with tradebots). use the activehandle API to find out who is logged in and the associated addresses and pubkeys The above is not yet tested so if it doesnt work, dont fret, just let me know. Once set the handle can be displayed in various places to let the user know which account is logged in. The standard 12 dictionary word passphrases should be used, but any string can be sent in as the password for Pangea: INT_AND_ARRAY(pangea,host,minplayers,params); ZERO_ARGS(pangea,lobby); HASH_AND_STRING(pangea,join,tablehash,handle); HASH_AND_INT(pangea,buyin,tablehash,numchips); HASH_ARG(pangea,start,tablehash); // by host only HASH_ARG(pangea,status,tablehash); HASH_ARG(pangea,call,tablehash); HASH_ARG(pangea,check,tablehash); HASH_AND_INT(pangea,raise,tablehash,numchips); HASH_AND_INT(pangea,bet,tablehash,numchips); HASH_ARG(pangea,fold,tablehash); HASH_AND_STRING(pangea,mode,tablehash,modestr); HASH_ARG(pangea,history,tablehash); HASH_AND_INT(pangea,handhistory,tablehash,hand); The first thing that is done is a &#34;host&#34; by any node. the &#34;params&#34; should be an arbitrary json (like encryptjson) as it needs to be at the top level and it has quite a few different parameters still subject to change. The lobby API will just display all the hosted tables. once a table exists, players can join and then buyin. the buyin is denominated in chips, each chip&#39;s value is determined by the host&#39;s initial parameters. once there are enough players joined with adequate buyin&#39;s verified, the host will be able to do a start. if done before it will (eventually) give an error. for now it will just proceed. The host and players that have joined a tablehash, need to do regular status calls to see if the game has started. Probably just once per 5 or even 10 seconds is fine before the start. Once the game starts (the status will have this info) then once per second polling is needed. Then when it is your turn (as indicated by status) you need to do one of the 5 actions (fold, call, check, raise, bet). do not worry if you dont understand what all these do, just allow the user to do any of these. I guess it is possible to submit it ahead of time. I will support internally remembering the most recent action done prior to it being your turn. once it is your turn and an action is sent to the table, it is too late to change. The last API calls are for getting handhistory where hand is 0 to N-1, being the numbering of the hands played at that table. if just history, all the history for all hands at the table is coming back, so it could be quite big. probably I will make it a summary, but for the GUI just display the returned values. the mode is to change some poker specific modes, so just allow there to be a string entered. do not worry about understanding the pokerness of the API, just the overall flow: host -&gt; creates, join/buyin -&gt; fills up player slots, start -&gt; starts the game status -&gt; to determine when the game starts (or if it is cancelled) and once started actions -&gt; game specific but basically just (button + arg) that is the user input results are via status for current game and history for past ones please try to do the above logic in a generic way so it can be reused for other games. The basic flow should be the same for almost all multiplayer turn based games and even for multiplayer realtime games For InstantDEX: on the apikeypair/userid there needs to be two modes. one for when there is no stored apikey and the current form is fine, just need to make it wider as most apikeys are quite long. Now once there is an apikey saved all that is needed is the passphrase to unlock it. So here is where the encrptjson/decryptjson is used. When saving the apikey for the first time, it can be: a) not saved -&gt; nothing extra to do b) saved without password -&gt; you can just save to a file and use it to load it back in. use confs dir confs/instantdex.exchange.api or something like that c) saved with password (optional filename for native) -&gt; probably best to save in the confs dir to indicate that there is an encrypted file for this, so just that and not the actual passphrase in the file with the above, when the exchange is selected, you can see if the confs file exists and if it has the plaintext, just populate the field, if not, then indicate that a passphrase is needed. if the user provides the passphrase, then decryptjson and populate the fields and autosubmit. A special case is to encrypt the apikeys with the passphrase used when logging in. This is only available if the checkbox to &#34;remember passphrase during session&#34; is set on the main iguana login screen. (i forgot to mention that checkbox!) So the login passphrase is stored in memory, then the GUI simply uses that + encryptjson for storing/decrypting. I would imagine that storing in the confs file that it is encrypted using &#34;handle&#34;&#39;s account login might be a good way to differentiate between this mode of password usage. OK, so we now have the insecure plaintext, the decent using handle&#39;s passphrase and paranoid different passphrase for each exchange (with additional permanentfile for native versions) &#34;SUPPORT&#34; -&gt; &#34;SUPPORTS&#34; just a typo and &#34;allpairs&#34; API is missing from the selection Might as well add a &#34;tradebots&#34; tab: THREE_STRINGS_AND_DOUBLE(tradebot,monitor,exchange,base,rel,commission); STRING_AND_DOUBLE(tradebot,monitorall,exchange,commission); THREE_STRINGS(tradebot,unmonitor,exchange,base,rel); THREE_STRINGS_AND_THREE_DOUBLES(tradebot,accumulate,exchange,base,rel,pr ice,volume,duration); THREE_STRINGS_AND_THREE_DOUBLES(tradebot,divest,exchange,base,rel,price, volume,duration); STRING_ARG(tradebot,activebots,exchange); TWO_STRINGS(tradebot,status,exchange,botid); TWO_STRINGS(tradebot,pause,exchange,botid); TWO_STRINGS(tradebot,stop,exchange,botid); TWO_STRINGS(tradebot,resume,exchange,botid); the above are API for exchange specific bots, most should be self-explanatory. bots are created via &#34;accumulate&#34; or &#34;divest&#34; API call. it returns botid. once created, you can do status, pause, stop, resume to a botid. and an activebots API call lists all the active bots for an exchange. duration is in seconds the &#34;monitor&#34; API starts background monitoring of a specific base/rel, &#34;unmonitor&#34; stops this. &#34;monitorall&#34; just does a monitor to the entire list of &#34;allpairs&#34; for that exchange. Keep in mind that doing a monitorall will not add load to an exchange as the request to each exchange is governed by pollgap, but if you have 3 things monitored, it will take 3*pollgap + time each one takes to execute. and if N are monitored it is N*pollgap + time of each, with the &#34;time of each&#34; possibly taking a very long time. And one final request for today: Bitmap tab. It should be an active bitmap using mouse api. either a dropdown to select the bitmap or a form entry. then the rest of the page (resize the bitmap to the page size) being the active bitmap. So on a small screen the bitmap is smaller x/y dimensions and larger on larger screens. plz make sure the proper dimensions are communicated to the pexe via API if it ever is changed. @vineet.bhargav86: I changed the &#34;passphrase&#34; fieldname to &#34;password&#34; for the encryptjson/decryptjson related API. The reason is that the password is like a wallet password and is only local, so it doesnt need to be as high entropy as passphrase. I also added a field to the login API as I realized that the 12 word &#34;passphrase&#34; is the payload and usually wont be sent in: FOUR_STRINGS(SuperNET,login,handle,password,permanentfile,passphrase); using &#34;abiglongpassword&#34; for the passphrase -&gt; {&#34;pubkey&#34;:&#34;6c469ba10b40b3eb9d1dba569d7f929d55a29d8f97cd5425907ef2f38f906 209&#34;,&#34;RS&#34;:&#34;NXT-KGV9-DXX8-TM86-DXR96&#34;,&#34;NXT&#34;:&#34;12834974574569896807&#34;,&#34;btcpu bkey&#34;:&#34;024e7641dc947b211bc30fe3339765258902794687b227121fc217284f9d8503c 8&#34;,&#34;rmd160&#34;:&#34;33453c24914db7b77069b7ea24df44f6be145938&#34;,&#34;BTC&#34;:&#34;15g6QK2dSd iW9ZTQEnnJxKrSph6uP7uU23&#34;,&#34;BTCD&#34;:&#34;RDxHUpuv3TX5DZpbhxmS3rBeaxZW1fvYvC&#34;,&#34;r esult&#34;:&#34;success&#34;,&#34;handle&#34;:&#34;test&#34;,&#34;tag&#34;:&#34;14805226009240621255&#34;} and if you use that to log into NXT, it gives the same address. The BTC and BTCD addresses are all derived from the same privkey so they are all interchangeable with the NXT address. The user can therefore select which coin&#39;s addressing they are most comfortable with I also added an &#34;allin&#34; action API for pangea. all the action API will autocalculate the number of chips if passed in 0 for numchips ***************** security issue ******** please dont use the GET URL method when dealing with passphrase!!! Those URL&#39;s tend to get logged and available in browser histories. so anything dealing with the actual passphrase needs to use the postCall form or POST
9 years ago
cJSON *retjson; bits256 pubkey,privkey;
if ( remoteaddr != 0 )
return(clonestr("{\"error\":\"no remote\"}"));
retjson = cJSON_CreateObject();
9 years ago
crypto_box_keypair(pubkey.bytes,privkey.bytes);
jaddstr(retjson,"result","generated keypair");
jaddbits256(retjson,"privkey",privkey);
jaddbits256(retjson,"pubkey",pubkey);
return(jprint(retjson,1));
}
TWOHASHES_AND_STRING(SuperNET,decipher,privkey,srcpubkey,cipherstr)
{
int32_t cipherlen=0,msglen; char *retstr; cJSON *retjson; void *ptr = 0; uint8_t *cipher,*message,space[8192];
many changes blockexplorer tab: needs to allow to input height, blockhash or txid. also please display images/BTC_blocks.jpg below the text as a w800 x h400 bitmap, which is active using the mouse api for coin management, below the active coins have a form that arbitrary json can be input with an add button to the right that will call &#34;addcoin&#34; API. this way I can test adding new coins dynamically. dont worry if it doesnt work, just as long as it submits the json to the C code. I am pretty sure I need to do some debugging of this peers management is not working for me at all. maybe it is due to bad internet. On initialization you need to read in the confs/BTCD_peers.txt from the native filesystem and save it into the chrome app filesystem. same thing for confs/BTCD_hdrs.txt. But this is only to be done if there isnt already such a file inside chrome. if there is, only do it upon a button invoked by the user. the reason is that the pexe is updating this file with the latest. Maybe it is nice to have an &#34;extract&#34; button that will copy out from the chrome storage into the native filesystem. There is also the manifest issue about localstorage vs chrome.localstorage. not sure what is needed to be done, but certainly a priority to get it so everything works as a chrome app. I know before it was making ramchain files inside the chrome filesystem, so it is probably things the GUI is doing. maybe in the settings tab, which has obsolete stuff that can be removed. anyway, the issue about files existing in the native filesystem -&gt; chrome and optionally extracting them is an issue for the confs files and .html template files used to autogenerate the port7778, maybe other files are affected. i think we need a way to have a list of hardcoded files that are just copied into chrome on startup if they dont exist already (or if possible copy over if the native version is bigger?) and buttons to extract them for debug tab: THREE_STRINGS(SuperNET,encryptjson,passphrase,permanentfile,anything); TWO_STRINGS(SuperNET,decryptjson,passphrase,permanentfile); at the top of page a way to put in passphrase and optional permanentfile along with arbitrary json. The standard form template has no easy way to describe to pass in everything as it is oriented to specific fields. but the encryptjson API saves all the fields, so the arbitrary json from the form needs to be combined at the same level as the &#34;agent&#34;, &#34;method&#34;, etc. I know, not the best, but internally it makes it easier. so {&#34;agent&#34;:&#34;SuperNET&#34;,&#34;method&#34;:&#34;encryptjson&#34;,&#34;passphrase&#34;:&#34;&lt;passphrase&gt;&#34;,&#34; permanentfile&#34;:&#34;&lt;filename&gt;&#34;,&#34;fromform&#34;:&#34;valuefromform&#34;,&#34;fromform2&#34;:&#34;valu efromform2&#34;,...rest of form at top level} then this will save it into a file with crazy number (it is a hash like txid) but given the same passphrase and filename, it will regenerate this hash so you dont actually have to store it, but it helps during debugging. for the filename, we must warn quite strongly to the user that if the file is ever lost or even changed in any way that the data will not be recoverable. also best to not allow the user to specify a file that does not exist. I think at this point chrome app version gets a bit tricky. we could simply push the native file into the chrome storage, but then an attacker who gets access to the computer could just get a list of these files and it really wont be much protection. So that means if a filename is specified, it needs to be copied into the chrome space, then immediately deleted... ok, this seems like not a good approach. let us make it so that the permanentfile option is not available from the chrome app, but only if the native version is running. that way we sidestep the issue of the pexe not having access to the specified file. Speaking of native vs pexe, on the startup page we should have a radio button that allows the user to select which the GUI will talk to. It should default based on a self test to the more likely value, but it is possible that the user wants to use the native version, even if the pexe is running. another thing to have on the startup page is a simple login: THREE_STRINGS(SuperNET,login,passphrase,permanentfile,handle); ZERO_ARGS(SuperNET,logout); ZERO_ARGS(SuperNET,activehandle); the handle is a human readable name that is associated with the passphrase/permanentfile. There can only be one active account (though it will be possible to associate different accounts with tradebots). use the activehandle API to find out who is logged in and the associated addresses and pubkeys The above is not yet tested so if it doesnt work, dont fret, just let me know. Once set the handle can be displayed in various places to let the user know which account is logged in. The standard 12 dictionary word passphrases should be used, but any string can be sent in as the password for Pangea: INT_AND_ARRAY(pangea,host,minplayers,params); ZERO_ARGS(pangea,lobby); HASH_AND_STRING(pangea,join,tablehash,handle); HASH_AND_INT(pangea,buyin,tablehash,numchips); HASH_ARG(pangea,start,tablehash); // by host only HASH_ARG(pangea,status,tablehash); HASH_ARG(pangea,call,tablehash); HASH_ARG(pangea,check,tablehash); HASH_AND_INT(pangea,raise,tablehash,numchips); HASH_AND_INT(pangea,bet,tablehash,numchips); HASH_ARG(pangea,fold,tablehash); HASH_AND_STRING(pangea,mode,tablehash,modestr); HASH_ARG(pangea,history,tablehash); HASH_AND_INT(pangea,handhistory,tablehash,hand); The first thing that is done is a &#34;host&#34; by any node. the &#34;params&#34; should be an arbitrary json (like encryptjson) as it needs to be at the top level and it has quite a few different parameters still subject to change. The lobby API will just display all the hosted tables. once a table exists, players can join and then buyin. the buyin is denominated in chips, each chip&#39;s value is determined by the host&#39;s initial parameters. once there are enough players joined with adequate buyin&#39;s verified, the host will be able to do a start. if done before it will (eventually) give an error. for now it will just proceed. The host and players that have joined a tablehash, need to do regular status calls to see if the game has started. Probably just once per 5 or even 10 seconds is fine before the start. Once the game starts (the status will have this info) then once per second polling is needed. Then when it is your turn (as indicated by status) you need to do one of the 5 actions (fold, call, check, raise, bet). do not worry if you dont understand what all these do, just allow the user to do any of these. I guess it is possible to submit it ahead of time. I will support internally remembering the most recent action done prior to it being your turn. once it is your turn and an action is sent to the table, it is too late to change. The last API calls are for getting handhistory where hand is 0 to N-1, being the numbering of the hands played at that table. if just history, all the history for all hands at the table is coming back, so it could be quite big. probably I will make it a summary, but for the GUI just display the returned values. the mode is to change some poker specific modes, so just allow there to be a string entered. do not worry about understanding the pokerness of the API, just the overall flow: host -&gt; creates, join/buyin -&gt; fills up player slots, start -&gt; starts the game status -&gt; to determine when the game starts (or if it is cancelled) and once started actions -&gt; game specific but basically just (button + arg) that is the user input results are via status for current game and history for past ones please try to do the above logic in a generic way so it can be reused for other games. The basic flow should be the same for almost all multiplayer turn based games and even for multiplayer realtime games For InstantDEX: on the apikeypair/userid there needs to be two modes. one for when there is no stored apikey and the current form is fine, just need to make it wider as most apikeys are quite long. Now once there is an apikey saved all that is needed is the passphrase to unlock it. So here is where the encrptjson/decryptjson is used. When saving the apikey for the first time, it can be: a) not saved -&gt; nothing extra to do b) saved without password -&gt; you can just save to a file and use it to load it back in. use confs dir confs/instantdex.exchange.api or something like that c) saved with password (optional filename for native) -&gt; probably best to save in the confs dir to indicate that there is an encrypted file for this, so just that and not the actual passphrase in the file with the above, when the exchange is selected, you can see if the confs file exists and if it has the plaintext, just populate the field, if not, then indicate that a passphrase is needed. if the user provides the passphrase, then decryptjson and populate the fields and autosubmit. A special case is to encrypt the apikeys with the passphrase used when logging in. This is only available if the checkbox to &#34;remember passphrase during session&#34; is set on the main iguana login screen. (i forgot to mention that checkbox!) So the login passphrase is stored in memory, then the GUI simply uses that + encryptjson for storing/decrypting. I would imagine that storing in the confs file that it is encrypted using &#34;handle&#34;&#39;s account login might be a good way to differentiate between this mode of password usage. OK, so we now have the insecure plaintext, the decent using handle&#39;s passphrase and paranoid different passphrase for each exchange (with additional permanentfile for native versions) &#34;SUPPORT&#34; -&gt; &#34;SUPPORTS&#34; just a typo and &#34;allpairs&#34; API is missing from the selection Might as well add a &#34;tradebots&#34; tab: THREE_STRINGS_AND_DOUBLE(tradebot,monitor,exchange,base,rel,commission); STRING_AND_DOUBLE(tradebot,monitorall,exchange,commission); THREE_STRINGS(tradebot,unmonitor,exchange,base,rel); THREE_STRINGS_AND_THREE_DOUBLES(tradebot,accumulate,exchange,base,rel,pr ice,volume,duration); THREE_STRINGS_AND_THREE_DOUBLES(tradebot,divest,exchange,base,rel,price, volume,duration); STRING_ARG(tradebot,activebots,exchange); TWO_STRINGS(tradebot,status,exchange,botid); TWO_STRINGS(tradebot,pause,exchange,botid); TWO_STRINGS(tradebot,stop,exchange,botid); TWO_STRINGS(tradebot,resume,exchange,botid); the above are API for exchange specific bots, most should be self-explanatory. bots are created via &#34;accumulate&#34; or &#34;divest&#34; API call. it returns botid. once created, you can do status, pause, stop, resume to a botid. and an activebots API call lists all the active bots for an exchange. duration is in seconds the &#34;monitor&#34; API starts background monitoring of a specific base/rel, &#34;unmonitor&#34; stops this. &#34;monitorall&#34; just does a monitor to the entire list of &#34;allpairs&#34; for that exchange. Keep in mind that doing a monitorall will not add load to an exchange as the request to each exchange is governed by pollgap, but if you have 3 things monitored, it will take 3*pollgap + time each one takes to execute. and if N are monitored it is N*pollgap + time of each, with the &#34;time of each&#34; possibly taking a very long time. And one final request for today: Bitmap tab. It should be an active bitmap using mouse api. either a dropdown to select the bitmap or a form entry. then the rest of the page (resize the bitmap to the page size) being the active bitmap. So on a small screen the bitmap is smaller x/y dimensions and larger on larger screens. plz make sure the proper dimensions are communicated to the pexe via API if it ever is changed. @vineet.bhargav86: I changed the &#34;passphrase&#34; fieldname to &#34;password&#34; for the encryptjson/decryptjson related API. The reason is that the password is like a wallet password and is only local, so it doesnt need to be as high entropy as passphrase. I also added a field to the login API as I realized that the 12 word &#34;passphrase&#34; is the payload and usually wont be sent in: FOUR_STRINGS(SuperNET,login,handle,password,permanentfile,passphrase); using &#34;abiglongpassword&#34; for the passphrase -&gt; {&#34;pubkey&#34;:&#34;6c469ba10b40b3eb9d1dba569d7f929d55a29d8f97cd5425907ef2f38f906 209&#34;,&#34;RS&#34;:&#34;NXT-KGV9-DXX8-TM86-DXR96&#34;,&#34;NXT&#34;:&#34;12834974574569896807&#34;,&#34;btcpu bkey&#34;:&#34;024e7641dc947b211bc30fe3339765258902794687b227121fc217284f9d8503c 8&#34;,&#34;rmd160&#34;:&#34;33453c24914db7b77069b7ea24df44f6be145938&#34;,&#34;BTC&#34;:&#34;15g6QK2dSd iW9ZTQEnnJxKrSph6uP7uU23&#34;,&#34;BTCD&#34;:&#34;RDxHUpuv3TX5DZpbhxmS3rBeaxZW1fvYvC&#34;,&#34;r esult&#34;:&#34;success&#34;,&#34;handle&#34;:&#34;test&#34;,&#34;tag&#34;:&#34;14805226009240621255&#34;} and if you use that to log into NXT, it gives the same address. The BTC and BTCD addresses are all derived from the same privkey so they are all interchangeable with the NXT address. The user can therefore select which coin&#39;s addressing they are most comfortable with I also added an &#34;allin&#34; action API for pangea. all the action API will autocalculate the number of chips if passed in 0 for numchips ***************** security issue ******** please dont use the GET URL method when dealing with passphrase!!! Those URL&#39;s tend to get logged and available in browser histories. so anything dealing with the actual passphrase needs to use the postCall form or POST
9 years ago
if ( remoteaddr != 0 )
return(clonestr("{\"error\":\"no remote\"}"));
if ( cipherstr != 0 )
cipherlen = (int32_t)strlen(cipherstr) >> 1;
9 years ago
if ( cipherlen < crypto_box_NONCEBYTES )
9 years ago
return(clonestr("{\"error\":\"cipher is too short\"}"));
9 years ago
cipher = calloc(1,cipherlen);
decode_hex(cipher,cipherlen,cipherstr);
9 years ago
if ( (message= SuperNET_deciphercalc(&ptr,&msglen,privkey,srcpubkey,cipher,cipherlen,space,sizeof(space))) != 0 )
9 years ago
{
9 years ago
message[msglen] = 0;
9 years ago
retjson = cJSON_CreateObject();
jaddstr(retjson,"result","deciphered message");
9 years ago
jaddstr(retjson,"message",(char *)message);
9 years ago
retstr = jprint(retjson,1);
9 years ago
if ( ptr != 0 )
free(ptr);
9 years ago
} else retstr = clonestr("{\"error\":\"couldnt decipher message\"}");
return(retstr);
}
TWOHASHES_AND_STRING(SuperNET,cipher,privkey,destpubkey,message)
{
9 years ago
cJSON *retjson; char *retstr,*hexstr,space[8129]; uint8_t space2[8129];
9 years ago
uint8_t *cipher; int32_t cipherlen,onetimeflag; bits256 origprivkey; void *ptr = 0;
many changes blockexplorer tab: needs to allow to input height, blockhash or txid. also please display images/BTC_blocks.jpg below the text as a w800 x h400 bitmap, which is active using the mouse api for coin management, below the active coins have a form that arbitrary json can be input with an add button to the right that will call &#34;addcoin&#34; API. this way I can test adding new coins dynamically. dont worry if it doesnt work, just as long as it submits the json to the C code. I am pretty sure I need to do some debugging of this peers management is not working for me at all. maybe it is due to bad internet. On initialization you need to read in the confs/BTCD_peers.txt from the native filesystem and save it into the chrome app filesystem. same thing for confs/BTCD_hdrs.txt. But this is only to be done if there isnt already such a file inside chrome. if there is, only do it upon a button invoked by the user. the reason is that the pexe is updating this file with the latest. Maybe it is nice to have an &#34;extract&#34; button that will copy out from the chrome storage into the native filesystem. There is also the manifest issue about localstorage vs chrome.localstorage. not sure what is needed to be done, but certainly a priority to get it so everything works as a chrome app. I know before it was making ramchain files inside the chrome filesystem, so it is probably things the GUI is doing. maybe in the settings tab, which has obsolete stuff that can be removed. anyway, the issue about files existing in the native filesystem -&gt; chrome and optionally extracting them is an issue for the confs files and .html template files used to autogenerate the port7778, maybe other files are affected. i think we need a way to have a list of hardcoded files that are just copied into chrome on startup if they dont exist already (or if possible copy over if the native version is bigger?) and buttons to extract them for debug tab: THREE_STRINGS(SuperNET,encryptjson,passphrase,permanentfile,anything); TWO_STRINGS(SuperNET,decryptjson,passphrase,permanentfile); at the top of page a way to put in passphrase and optional permanentfile along with arbitrary json. The standard form template has no easy way to describe to pass in everything as it is oriented to specific fields. but the encryptjson API saves all the fields, so the arbitrary json from the form needs to be combined at the same level as the &#34;agent&#34;, &#34;method&#34;, etc. I know, not the best, but internally it makes it easier. so {&#34;agent&#34;:&#34;SuperNET&#34;,&#34;method&#34;:&#34;encryptjson&#34;,&#34;passphrase&#34;:&#34;&lt;passphrase&gt;&#34;,&#34; permanentfile&#34;:&#34;&lt;filename&gt;&#34;,&#34;fromform&#34;:&#34;valuefromform&#34;,&#34;fromform2&#34;:&#34;valu efromform2&#34;,...rest of form at top level} then this will save it into a file with crazy number (it is a hash like txid) but given the same passphrase and filename, it will regenerate this hash so you dont actually have to store it, but it helps during debugging. for the filename, we must warn quite strongly to the user that if the file is ever lost or even changed in any way that the data will not be recoverable. also best to not allow the user to specify a file that does not exist. I think at this point chrome app version gets a bit tricky. we could simply push the native file into the chrome storage, but then an attacker who gets access to the computer could just get a list of these files and it really wont be much protection. So that means if a filename is specified, it needs to be copied into the chrome space, then immediately deleted... ok, this seems like not a good approach. let us make it so that the permanentfile option is not available from the chrome app, but only if the native version is running. that way we sidestep the issue of the pexe not having access to the specified file. Speaking of native vs pexe, on the startup page we should have a radio button that allows the user to select which the GUI will talk to. It should default based on a self test to the more likely value, but it is possible that the user wants to use the native version, even if the pexe is running. another thing to have on the startup page is a simple login: THREE_STRINGS(SuperNET,login,passphrase,permanentfile,handle); ZERO_ARGS(SuperNET,logout); ZERO_ARGS(SuperNET,activehandle); the handle is a human readable name that is associated with the passphrase/permanentfile. There can only be one active account (though it will be possible to associate different accounts with tradebots). use the activehandle API to find out who is logged in and the associated addresses and pubkeys The above is not yet tested so if it doesnt work, dont fret, just let me know. Once set the handle can be displayed in various places to let the user know which account is logged in. The standard 12 dictionary word passphrases should be used, but any string can be sent in as the password for Pangea: INT_AND_ARRAY(pangea,host,minplayers,params); ZERO_ARGS(pangea,lobby); HASH_AND_STRING(pangea,join,tablehash,handle); HASH_AND_INT(pangea,buyin,tablehash,numchips); HASH_ARG(pangea,start,tablehash); // by host only HASH_ARG(pangea,status,tablehash); HASH_ARG(pangea,call,tablehash); HASH_ARG(pangea,check,tablehash); HASH_AND_INT(pangea,raise,tablehash,numchips); HASH_AND_INT(pangea,bet,tablehash,numchips); HASH_ARG(pangea,fold,tablehash); HASH_AND_STRING(pangea,mode,tablehash,modestr); HASH_ARG(pangea,history,tablehash); HASH_AND_INT(pangea,handhistory,tablehash,hand); The first thing that is done is a &#34;host&#34; by any node. the &#34;params&#34; should be an arbitrary json (like encryptjson) as it needs to be at the top level and it has quite a few different parameters still subject to change. The lobby API will just display all the hosted tables. once a table exists, players can join and then buyin. the buyin is denominated in chips, each chip&#39;s value is determined by the host&#39;s initial parameters. once there are enough players joined with adequate buyin&#39;s verified, the host will be able to do a start. if done before it will (eventually) give an error. for now it will just proceed. The host and players that have joined a tablehash, need to do regular status calls to see if the game has started. Probably just once per 5 or even 10 seconds is fine before the start. Once the game starts (the status will have this info) then once per second polling is needed. Then when it is your turn (as indicated by status) you need to do one of the 5 actions (fold, call, check, raise, bet). do not worry if you dont understand what all these do, just allow the user to do any of these. I guess it is possible to submit it ahead of time. I will support internally remembering the most recent action done prior to it being your turn. once it is your turn and an action is sent to the table, it is too late to change. The last API calls are for getting handhistory where hand is 0 to N-1, being the numbering of the hands played at that table. if just history, all the history for all hands at the table is coming back, so it could be quite big. probably I will make it a summary, but for the GUI just display the returned values. the mode is to change some poker specific modes, so just allow there to be a string entered. do not worry about understanding the pokerness of the API, just the overall flow: host -&gt; creates, join/buyin -&gt; fills up player slots, start -&gt; starts the game status -&gt; to determine when the game starts (or if it is cancelled) and once started actions -&gt; game specific but basically just (button + arg) that is the user input results are via status for current game and history for past ones please try to do the above logic in a generic way so it can be reused for other games. The basic flow should be the same for almost all multiplayer turn based games and even for multiplayer realtime games For InstantDEX: on the apikeypair/userid there needs to be two modes. one for when there is no stored apikey and the current form is fine, just need to make it wider as most apikeys are quite long. Now once there is an apikey saved all that is needed is the passphrase to unlock it. So here is where the encrptjson/decryptjson is used. When saving the apikey for the first time, it can be: a) not saved -&gt; nothing extra to do b) saved without password -&gt; you can just save to a file and use it to load it back in. use confs dir confs/instantdex.exchange.api or something like that c) saved with password (optional filename for native) -&gt; probably best to save in the confs dir to indicate that there is an encrypted file for this, so just that and not the actual passphrase in the file with the above, when the exchange is selected, you can see if the confs file exists and if it has the plaintext, just populate the field, if not, then indicate that a passphrase is needed. if the user provides the passphrase, then decryptjson and populate the fields and autosubmit. A special case is to encrypt the apikeys with the passphrase used when logging in. This is only available if the checkbox to &#34;remember passphrase during session&#34; is set on the main iguana login screen. (i forgot to mention that checkbox!) So the login passphrase is stored in memory, then the GUI simply uses that + encryptjson for storing/decrypting. I would imagine that storing in the confs file that it is encrypted using &#34;handle&#34;&#39;s account login might be a good way to differentiate between this mode of password usage. OK, so we now have the insecure plaintext, the decent using handle&#39;s passphrase and paranoid different passphrase for each exchange (with additional permanentfile for native versions) &#34;SUPPORT&#34; -&gt; &#34;SUPPORTS&#34; just a typo and &#34;allpairs&#34; API is missing from the selection Might as well add a &#34;tradebots&#34; tab: THREE_STRINGS_AND_DOUBLE(tradebot,monitor,exchange,base,rel,commission); STRING_AND_DOUBLE(tradebot,monitorall,exchange,commission); THREE_STRINGS(tradebot,unmonitor,exchange,base,rel); THREE_STRINGS_AND_THREE_DOUBLES(tradebot,accumulate,exchange,base,rel,pr ice,volume,duration); THREE_STRINGS_AND_THREE_DOUBLES(tradebot,divest,exchange,base,rel,price, volume,duration); STRING_ARG(tradebot,activebots,exchange); TWO_STRINGS(tradebot,status,exchange,botid); TWO_STRINGS(tradebot,pause,exchange,botid); TWO_STRINGS(tradebot,stop,exchange,botid); TWO_STRINGS(tradebot,resume,exchange,botid); the above are API for exchange specific bots, most should be self-explanatory. bots are created via &#34;accumulate&#34; or &#34;divest&#34; API call. it returns botid. once created, you can do status, pause, stop, resume to a botid. and an activebots API call lists all the active bots for an exchange. duration is in seconds the &#34;monitor&#34; API starts background monitoring of a specific base/rel, &#34;unmonitor&#34; stops this. &#34;monitorall&#34; just does a monitor to the entire list of &#34;allpairs&#34; for that exchange. Keep in mind that doing a monitorall will not add load to an exchange as the request to each exchange is governed by pollgap, but if you have 3 things monitored, it will take 3*pollgap + time each one takes to execute. and if N are monitored it is N*pollgap + time of each, with the &#34;time of each&#34; possibly taking a very long time. And one final request for today: Bitmap tab. It should be an active bitmap using mouse api. either a dropdown to select the bitmap or a form entry. then the rest of the page (resize the bitmap to the page size) being the active bitmap. So on a small screen the bitmap is smaller x/y dimensions and larger on larger screens. plz make sure the proper dimensions are communicated to the pexe via API if it ever is changed. @vineet.bhargav86: I changed the &#34;passphrase&#34; fieldname to &#34;password&#34; for the encryptjson/decryptjson related API. The reason is that the password is like a wallet password and is only local, so it doesnt need to be as high entropy as passphrase. I also added a field to the login API as I realized that the 12 word &#34;passphrase&#34; is the payload and usually wont be sent in: FOUR_STRINGS(SuperNET,login,handle,password,permanentfile,passphrase); using &#34;abiglongpassword&#34; for the passphrase -&gt; {&#34;pubkey&#34;:&#34;6c469ba10b40b3eb9d1dba569d7f929d55a29d8f97cd5425907ef2f38f906 209&#34;,&#34;RS&#34;:&#34;NXT-KGV9-DXX8-TM86-DXR96&#34;,&#34;NXT&#34;:&#34;12834974574569896807&#34;,&#34;btcpu bkey&#34;:&#34;024e7641dc947b211bc30fe3339765258902794687b227121fc217284f9d8503c 8&#34;,&#34;rmd160&#34;:&#34;33453c24914db7b77069b7ea24df44f6be145938&#34;,&#34;BTC&#34;:&#34;15g6QK2dSd iW9ZTQEnnJxKrSph6uP7uU23&#34;,&#34;BTCD&#34;:&#34;RDxHUpuv3TX5DZpbhxmS3rBeaxZW1fvYvC&#34;,&#34;r esult&#34;:&#34;success&#34;,&#34;handle&#34;:&#34;test&#34;,&#34;tag&#34;:&#34;14805226009240621255&#34;} and if you use that to log into NXT, it gives the same address. The BTC and BTCD addresses are all derived from the same privkey so they are all interchangeable with the NXT address. The user can therefore select which coin&#39;s addressing they are most comfortable with I also added an &#34;allin&#34; action API for pangea. all the action API will autocalculate the number of chips if passed in 0 for numchips ***************** security issue ******** please dont use the GET URL method when dealing with passphrase!!! Those URL&#39;s tend to get logged and available in browser histories. so anything dealing with the actual passphrase needs to use the postCall form or POST
9 years ago
if ( remoteaddr != 0 )
return(clonestr("{\"error\":\"no remote\"}"));
9 years ago
if ( (cipher= SuperNET_ciphercalc(&ptr,&cipherlen,&privkey,&destpubkey,(uint8_t *)message,(int32_t)strlen(message)+1,space2,sizeof(space2))) != 0 )
9 years ago
{
9 years ago
if ( cipherlen > sizeof(space)/2 )
hexstr = calloc(1,(cipherlen<<1)+1);
else hexstr = (void *)space;
init_hexbytes_noT(hexstr,cipher,cipherlen);
retjson = cJSON_CreateObject();
jaddstr(retjson,"result",hexstr);
onetimeflag = memcmp(origprivkey.bytes,privkey.bytes,sizeof(privkey));
if ( onetimeflag != 0 )
{
//jaddbits256(retjson,"onetime_privkey",privkey);
9 years ago
jaddbits256(retjson,"onetime_pubkey",destpubkey);
if ( onetimeflag == 2 )
jaddstr(retjson,"warning","onetime keypair was used to broadcast");
}
retstr = jprint(retjson,1);
if ( hexstr != (void *)space )
free(hexstr);
9 years ago
if ( ptr != 0 )
free(ptr);
9 years ago
return(retstr);
9 years ago
}
printf("error encrypting message.(%s)\n",message);
return(clonestr("{\"error\":\"cant encrypt message\"}"));
9 years ago
}
bits256 SuperNET_pindecipher(IGUANA_ARGS,char *pin,char *privcipher)
{
cJSON *testjson; char *mstr,*cstr; bits256 privkey,pinpriv,pinpub;
conv_NXTpassword(pinpriv.bytes,pinpub.bytes,(uint8_t *)pin,(int32_t)strlen(pin));
9 years ago
privkey = GENESIS_PRIVKEY;
9 years ago
if ( (cstr= SuperNET_decipher(IGUANA_CALLARGS,pinpriv,pinpub,privcipher)) != 0 )
{
if ( (testjson= cJSON_Parse(cstr)) != 0 )
{
if ( (mstr= jstr(testjson,"message")) != 0 && strlen(mstr) == sizeof(bits256)*2 )
{
decode_hex(privkey.bytes,sizeof(privkey),mstr);
9 years ago
} else printf("error cant find message privcipher\n");
9 years ago
free_json(testjson);
9 years ago
} else printf("Error decipher.(%s)\n",cstr);
9 years ago
free(cstr);
9 years ago
} else printf("null return from deciphering privcipher\n");
9 years ago
return(privkey);
}
THREE_STRINGS(SuperNET,rosetta,passphrase,pin,showprivkey)
{
many changes blockexplorer tab: needs to allow to input height, blockhash or txid. also please display images/BTC_blocks.jpg below the text as a w800 x h400 bitmap, which is active using the mouse api for coin management, below the active coins have a form that arbitrary json can be input with an add button to the right that will call &#34;addcoin&#34; API. this way I can test adding new coins dynamically. dont worry if it doesnt work, just as long as it submits the json to the C code. I am pretty sure I need to do some debugging of this peers management is not working for me at all. maybe it is due to bad internet. On initialization you need to read in the confs/BTCD_peers.txt from the native filesystem and save it into the chrome app filesystem. same thing for confs/BTCD_hdrs.txt. But this is only to be done if there isnt already such a file inside chrome. if there is, only do it upon a button invoked by the user. the reason is that the pexe is updating this file with the latest. Maybe it is nice to have an &#34;extract&#34; button that will copy out from the chrome storage into the native filesystem. There is also the manifest issue about localstorage vs chrome.localstorage. not sure what is needed to be done, but certainly a priority to get it so everything works as a chrome app. I know before it was making ramchain files inside the chrome filesystem, so it is probably things the GUI is doing. maybe in the settings tab, which has obsolete stuff that can be removed. anyway, the issue about files existing in the native filesystem -&gt; chrome and optionally extracting them is an issue for the confs files and .html template files used to autogenerate the port7778, maybe other files are affected. i think we need a way to have a list of hardcoded files that are just copied into chrome on startup if they dont exist already (or if possible copy over if the native version is bigger?) and buttons to extract them for debug tab: THREE_STRINGS(SuperNET,encryptjson,passphrase,permanentfile,anything); TWO_STRINGS(SuperNET,decryptjson,passphrase,permanentfile); at the top of page a way to put in passphrase and optional permanentfile along with arbitrary json. The standard form template has no easy way to describe to pass in everything as it is oriented to specific fields. but the encryptjson API saves all the fields, so the arbitrary json from the form needs to be combined at the same level as the &#34;agent&#34;, &#34;method&#34;, etc. I know, not the best, but internally it makes it easier. so {&#34;agent&#34;:&#34;SuperNET&#34;,&#34;method&#34;:&#34;encryptjson&#34;,&#34;passphrase&#34;:&#34;&lt;passphrase&gt;&#34;,&#34; permanentfile&#34;:&#34;&lt;filename&gt;&#34;,&#34;fromform&#34;:&#34;valuefromform&#34;,&#34;fromform2&#34;:&#34;valu efromform2&#34;,...rest of form at top level} then this will save it into a file with crazy number (it is a hash like txid) but given the same passphrase and filename, it will regenerate this hash so you dont actually have to store it, but it helps during debugging. for the filename, we must warn quite strongly to the user that if the file is ever lost or even changed in any way that the data will not be recoverable. also best to not allow the user to specify a file that does not exist. I think at this point chrome app version gets a bit tricky. we could simply push the native file into the chrome storage, but then an attacker who gets access to the computer could just get a list of these files and it really wont be much protection. So that means if a filename is specified, it needs to be copied into the chrome space, then immediately deleted... ok, this seems like not a good approach. let us make it so that the permanentfile option is not available from the chrome app, but only if the native version is running. that way we sidestep the issue of the pexe not having access to the specified file. Speaking of native vs pexe, on the startup page we should have a radio button that allows the user to select which the GUI will talk to. It should default based on a self test to the more likely value, but it is possible that the user wants to use the native version, even if the pexe is running. another thing to have on the startup page is a simple login: THREE_STRINGS(SuperNET,login,passphrase,permanentfile,handle); ZERO_ARGS(SuperNET,logout); ZERO_ARGS(SuperNET,activehandle); the handle is a human readable name that is associated with the passphrase/permanentfile. There can only be one active account (though it will be possible to associate different accounts with tradebots). use the activehandle API to find out who is logged in and the associated addresses and pubkeys The above is not yet tested so if it doesnt work, dont fret, just let me know. Once set the handle can be displayed in various places to let the user know which account is logged in. The standard 12 dictionary word passphrases should be used, but any string can be sent in as the password for Pangea: INT_AND_ARRAY(pangea,host,minplayers,params); ZERO_ARGS(pangea,lobby); HASH_AND_STRING(pangea,join,tablehash,handle); HASH_AND_INT(pangea,buyin,tablehash,numchips); HASH_ARG(pangea,start,tablehash); // by host only HASH_ARG(pangea,status,tablehash); HASH_ARG(pangea,call,tablehash); HASH_ARG(pangea,check,tablehash); HASH_AND_INT(pangea,raise,tablehash,numchips); HASH_AND_INT(pangea,bet,tablehash,numchips); HASH_ARG(pangea,fold,tablehash); HASH_AND_STRING(pangea,mode,tablehash,modestr); HASH_ARG(pangea,history,tablehash); HASH_AND_INT(pangea,handhistory,tablehash,hand); The first thing that is done is a &#34;host&#34; by any node. the &#34;params&#34; should be an arbitrary json (like encryptjson) as it needs to be at the top level and it has quite a few different parameters still subject to change. The lobby API will just display all the hosted tables. once a table exists, players can join and then buyin. the buyin is denominated in chips, each chip&#39;s value is determined by the host&#39;s initial parameters. once there are enough players joined with adequate buyin&#39;s verified, the host will be able to do a start. if done before it will (eventually) give an error. for now it will just proceed. The host and players that have joined a tablehash, need to do regular status calls to see if the game has started. Probably just once per 5 or even 10 seconds is fine before the start. Once the game starts (the status will have this info) then once per second polling is needed. Then when it is your turn (as indicated by status) you need to do one of the 5 actions (fold, call, check, raise, bet). do not worry if you dont understand what all these do, just allow the user to do any of these. I guess it is possible to submit it ahead of time. I will support internally remembering the most recent action done prior to it being your turn. once it is your turn and an action is sent to the table, it is too late to change. The last API calls are for getting handhistory where hand is 0 to N-1, being the numbering of the hands played at that table. if just history, all the history for all hands at the table is coming back, so it could be quite big. probably I will make it a summary, but for the GUI just display the returned values. the mode is to change some poker specific modes, so just allow there to be a string entered. do not worry about understanding the pokerness of the API, just the overall flow: host -&gt; creates, join/buyin -&gt; fills up player slots, start -&gt; starts the game status -&gt; to determine when the game starts (or if it is cancelled) and once started actions -&gt; game specific but basically just (button + arg) that is the user input results are via status for current game and history for past ones please try to do the above logic in a generic way so it can be reused for other games. The basic flow should be the same for almost all multiplayer turn based games and even for multiplayer realtime games For InstantDEX: on the apikeypair/userid there needs to be two modes. one for when there is no stored apikey and the current form is fine, just need to make it wider as most apikeys are quite long. Now once there is an apikey saved all that is needed is the passphrase to unlock it. So here is where the encrptjson/decryptjson is used. When saving the apikey for the first time, it can be: a) not saved -&gt; nothing extra to do b) saved without password -&gt; you can just save to a file and use it to load it back in. use confs dir confs/instantdex.exchange.api or something like that c) saved with password (optional filename for native) -&gt; probably best to save in the confs dir to indicate that there is an encrypted file for this, so just that and not the actual passphrase in the file with the above, when the exchange is selected, you can see if the confs file exists and if it has the plaintext, just populate the field, if not, then indicate that a passphrase is needed. if the user provides the passphrase, then decryptjson and populate the fields and autosubmit. A special case is to encrypt the apikeys with the passphrase used when logging in. This is only available if the checkbox to &#34;remember passphrase during session&#34; is set on the main iguana login screen. (i forgot to mention that checkbox!) So the login passphrase is stored in memory, then the GUI simply uses that + encryptjson for storing/decrypting. I would imagine that storing in the confs file that it is encrypted using &#34;handle&#34;&#39;s account login might be a good way to differentiate between this mode of password usage. OK, so we now have the insecure plaintext, the decent using handle&#39;s passphrase and paranoid different passphrase for each exchange (with additional permanentfile for native versions) &#34;SUPPORT&#34; -&gt; &#34;SUPPORTS&#34; just a typo and &#34;allpairs&#34; API is missing from the selection Might as well add a &#34;tradebots&#34; tab: THREE_STRINGS_AND_DOUBLE(tradebot,monitor,exchange,base,rel,commission); STRING_AND_DOUBLE(tradebot,monitorall,exchange,commission); THREE_STRINGS(tradebot,unmonitor,exchange,base,rel); THREE_STRINGS_AND_THREE_DOUBLES(tradebot,accumulate,exchange,base,rel,pr ice,volume,duration); THREE_STRINGS_AND_THREE_DOUBLES(tradebot,divest,exchange,base,rel,price, volume,duration); STRING_ARG(tradebot,activebots,exchange); TWO_STRINGS(tradebot,status,exchange,botid); TWO_STRINGS(tradebot,pause,exchange,botid); TWO_STRINGS(tradebot,stop,exchange,botid); TWO_STRINGS(tradebot,resume,exchange,botid); the above are API for exchange specific bots, most should be self-explanatory. bots are created via &#34;accumulate&#34; or &#34;divest&#34; API call. it returns botid. once created, you can do status, pause, stop, resume to a botid. and an activebots API call lists all the active bots for an exchange. duration is in seconds the &#34;monitor&#34; API starts background monitoring of a specific base/rel, &#34;unmonitor&#34; stops this. &#34;monitorall&#34; just does a monitor to the entire list of &#34;allpairs&#34; for that exchange. Keep in mind that doing a monitorall will not add load to an exchange as the request to each exchange is governed by pollgap, but if you have 3 things monitored, it will take 3*pollgap + time each one takes to execute. and if N are monitored it is N*pollgap + time of each, with the &#34;time of each&#34; possibly taking a very long time. And one final request for today: Bitmap tab. It should be an active bitmap using mouse api. either a dropdown to select the bitmap or a form entry. then the rest of the page (resize the bitmap to the page size) being the active bitmap. So on a small screen the bitmap is smaller x/y dimensions and larger on larger screens. plz make sure the proper dimensions are communicated to the pexe via API if it ever is changed. @vineet.bhargav86: I changed the &#34;passphrase&#34; fieldname to &#34;password&#34; for the encryptjson/decryptjson related API. The reason is that the password is like a wallet password and is only local, so it doesnt need to be as high entropy as passphrase. I also added a field to the login API as I realized that the 12 word &#34;passphrase&#34; is the payload and usually wont be sent in: FOUR_STRINGS(SuperNET,login,handle,password,permanentfile,passphrase); using &#34;abiglongpassword&#34; for the passphrase -&gt; {&#34;pubkey&#34;:&#34;6c469ba10b40b3eb9d1dba569d7f929d55a29d8f97cd5425907ef2f38f906 209&#34;,&#34;RS&#34;:&#34;NXT-KGV9-DXX8-TM86-DXR96&#34;,&#34;NXT&#34;:&#34;12834974574569896807&#34;,&#34;btcpu bkey&#34;:&#34;024e7641dc947b211bc30fe3339765258902794687b227121fc217284f9d8503c 8&#34;,&#34;rmd160&#34;:&#34;33453c24914db7b77069b7ea24df44f6be145938&#34;,&#34;BTC&#34;:&#34;15g6QK2dSd iW9ZTQEnnJxKrSph6uP7uU23&#34;,&#34;BTCD&#34;:&#34;RDxHUpuv3TX5DZpbhxmS3rBeaxZW1fvYvC&#34;,&#34;r esult&#34;:&#34;success&#34;,&#34;handle&#34;:&#34;test&#34;,&#34;tag&#34;:&#34;14805226009240621255&#34;} and if you use that to log into NXT, it gives the same address. The BTC and BTCD addresses are all derived from the same privkey so they are all interchangeable with the NXT address. The user can therefore select which coin&#39;s addressing they are most comfortable with I also added an &#34;allin&#34; action API for pangea. all the action API will autocalculate the number of chips if passed in 0 for numchips ***************** security issue ******** please dont use the GET URL method when dealing with passphrase!!! Those URL&#39;s tend to get logged and available in browser histories. so anything dealing with the actual passphrase needs to use the postCall form or POST
9 years ago
uint8_t flag = 0; uint64_t nxt64bits; bits256 check,privkey,pubkey,pinpriv,pinpub;
char str[128],privcipher[512],*privcipherstr,*cstr; cJSON *retjson;
if ( remoteaddr != 0 )
return(clonestr("{\"error\":\"no remote\"}"));
9 years ago
nxt64bits = conv_NXTpassword(privkey.bytes,pubkey.bytes,(uint8_t *)passphrase,(int32_t)strlen(passphrase));
if ( showprivkey != 0 && strcmp(showprivkey,"yes") == 0 )
flag = 1;
privcipher[0] = 0;
conv_NXTpassword(pinpriv.bytes,pinpub.bytes,(uint8_t *)pin,(int32_t)strlen(pin));
if ( (cstr= SuperNET_cipher(IGUANA_CALLARGS,pinpriv,pinpub,bits256_str(str,privkey))) != 0 )
{
if ( (retjson= cJSON_Parse(cstr)) != 0 )
{
9 years ago
if ( (privcipherstr= jstr(retjson,"result")) != 0 )
9 years ago
strcpy(privcipher,privcipherstr);
free_json(retjson);
9 years ago
} else printf("error parsing cipher retstr.(%s)\n",cstr);
9 years ago
free(cstr);
9 years ago
} else printf("error SuperNET_cipher null return\n");
many changes blockexplorer tab: needs to allow to input height, blockhash or txid. also please display images/BTC_blocks.jpg below the text as a w800 x h400 bitmap, which is active using the mouse api for coin management, below the active coins have a form that arbitrary json can be input with an add button to the right that will call &#34;addcoin&#34; API. this way I can test adding new coins dynamically. dont worry if it doesnt work, just as long as it submits the json to the C code. I am pretty sure I need to do some debugging of this peers management is not working for me at all. maybe it is due to bad internet. On initialization you need to read in the confs/BTCD_peers.txt from the native filesystem and save it into the chrome app filesystem. same thing for confs/BTCD_hdrs.txt. But this is only to be done if there isnt already such a file inside chrome. if there is, only do it upon a button invoked by the user. the reason is that the pexe is updating this file with the latest. Maybe it is nice to have an &#34;extract&#34; button that will copy out from the chrome storage into the native filesystem. There is also the manifest issue about localstorage vs chrome.localstorage. not sure what is needed to be done, but certainly a priority to get it so everything works as a chrome app. I know before it was making ramchain files inside the chrome filesystem, so it is probably things the GUI is doing. maybe in the settings tab, which has obsolete stuff that can be removed. anyway, the issue about files existing in the native filesystem -&gt; chrome and optionally extracting them is an issue for the confs files and .html template files used to autogenerate the port7778, maybe other files are affected. i think we need a way to have a list of hardcoded files that are just copied into chrome on startup if they dont exist already (or if possible copy over if the native version is bigger?) and buttons to extract them for debug tab: THREE_STRINGS(SuperNET,encryptjson,passphrase,permanentfile,anything); TWO_STRINGS(SuperNET,decryptjson,passphrase,permanentfile); at the top of page a way to put in passphrase and optional permanentfile along with arbitrary json. The standard form template has no easy way to describe to pass in everything as it is oriented to specific fields. but the encryptjson API saves all the fields, so the arbitrary json from the form needs to be combined at the same level as the &#34;agent&#34;, &#34;method&#34;, etc. I know, not the best, but internally it makes it easier. so {&#34;agent&#34;:&#34;SuperNET&#34;,&#34;method&#34;:&#34;encryptjson&#34;,&#34;passphrase&#34;:&#34;&lt;passphrase&gt;&#34;,&#34; permanentfile&#34;:&#34;&lt;filename&gt;&#34;,&#34;fromform&#34;:&#34;valuefromform&#34;,&#34;fromform2&#34;:&#34;valu efromform2&#34;,...rest of form at top level} then this will save it into a file with crazy number (it is a hash like txid) but given the same passphrase and filename, it will regenerate this hash so you dont actually have to store it, but it helps during debugging. for the filename, we must warn quite strongly to the user that if the file is ever lost or even changed in any way that the data will not be recoverable. also best to not allow the user to specify a file that does not exist. I think at this point chrome app version gets a bit tricky. we could simply push the native file into the chrome storage, but then an attacker who gets access to the computer could just get a list of these files and it really wont be much protection. So that means if a filename is specified, it needs to be copied into the chrome space, then immediately deleted... ok, this seems like not a good approach. let us make it so that the permanentfile option is not available from the chrome app, but only if the native version is running. that way we sidestep the issue of the pexe not having access to the specified file. Speaking of native vs pexe, on the startup page we should have a radio button that allows the user to select which the GUI will talk to. It should default based on a self test to the more likely value, but it is possible that the user wants to use the native version, even if the pexe is running. another thing to have on the startup page is a simple login: THREE_STRINGS(SuperNET,login,passphrase,permanentfile,handle); ZERO_ARGS(SuperNET,logout); ZERO_ARGS(SuperNET,activehandle); the handle is a human readable name that is associated with the passphrase/permanentfile. There can only be one active account (though it will be possible to associate different accounts with tradebots). use the activehandle API to find out who is logged in and the associated addresses and pubkeys The above is not yet tested so if it doesnt work, dont fret, just let me know. Once set the handle can be displayed in various places to let the user know which account is logged in. The standard 12 dictionary word passphrases should be used, but any string can be sent in as the password for Pangea: INT_AND_ARRAY(pangea,host,minplayers,params); ZERO_ARGS(pangea,lobby); HASH_AND_STRING(pangea,join,tablehash,handle); HASH_AND_INT(pangea,buyin,tablehash,numchips); HASH_ARG(pangea,start,tablehash); // by host only HASH_ARG(pangea,status,tablehash); HASH_ARG(pangea,call,tablehash); HASH_ARG(pangea,check,tablehash); HASH_AND_INT(pangea,raise,tablehash,numchips); HASH_AND_INT(pangea,bet,tablehash,numchips); HASH_ARG(pangea,fold,tablehash); HASH_AND_STRING(pangea,mode,tablehash,modestr); HASH_ARG(pangea,history,tablehash); HASH_AND_INT(pangea,handhistory,tablehash,hand); The first thing that is done is a &#34;host&#34; by any node. the &#34;params&#34; should be an arbitrary json (like encryptjson) as it needs to be at the top level and it has quite a few different parameters still subject to change. The lobby API will just display all the hosted tables. once a table exists, players can join and then buyin. the buyin is denominated in chips, each chip&#39;s value is determined by the host&#39;s initial parameters. once there are enough players joined with adequate buyin&#39;s verified, the host will be able to do a start. if done before it will (eventually) give an error. for now it will just proceed. The host and players that have joined a tablehash, need to do regular status calls to see if the game has started. Probably just once per 5 or even 10 seconds is fine before the start. Once the game starts (the status will have this info) then once per second polling is needed. Then when it is your turn (as indicated by status) you need to do one of the 5 actions (fold, call, check, raise, bet). do not worry if you dont understand what all these do, just allow the user to do any of these. I guess it is possible to submit it ahead of time. I will support internally remembering the most recent action done prior to it being your turn. once it is your turn and an action is sent to the table, it is too late to change. The last API calls are for getting handhistory where hand is 0 to N-1, being the numbering of the hands played at that table. if just history, all the history for all hands at the table is coming back, so it could be quite big. probably I will make it a summary, but for the GUI just display the returned values. the mode is to change some poker specific modes, so just allow there to be a string entered. do not worry about understanding the pokerness of the API, just the overall flow: host -&gt; creates, join/buyin -&gt; fills up player slots, start -&gt; starts the game status -&gt; to determine when the game starts (or if it is cancelled) and once started actions -&gt; game specific but basically just (button + arg) that is the user input results are via status for current game and history for past ones please try to do the above logic in a generic way so it can be reused for other games. The basic flow should be the same for almost all multiplayer turn based games and even for multiplayer realtime games For InstantDEX: on the apikeypair/userid there needs to be two modes. one for when there is no stored apikey and the current form is fine, just need to make it wider as most apikeys are quite long. Now once there is an apikey saved all that is needed is the passphrase to unlock it. So here is where the encrptjson/decryptjson is used. When saving the apikey for the first time, it can be: a) not saved -&gt; nothing extra to do b) saved without password -&gt; you can just save to a file and use it to load it back in. use confs dir confs/instantdex.exchange.api or something like that c) saved with password (optional filename for native) -&gt; probably best to save in the confs dir to indicate that there is an encrypted file for this, so just that and not the actual passphrase in the file with the above, when the exchange is selected, you can see if the confs file exists and if it has the plaintext, just populate the field, if not, then indicate that a passphrase is needed. if the user provides the passphrase, then decryptjson and populate the fields and autosubmit. A special case is to encrypt the apikeys with the passphrase used when logging in. This is only available if the checkbox to &#34;remember passphrase during session&#34; is set on the main iguana login screen. (i forgot to mention that checkbox!) So the login passphrase is stored in memory, then the GUI simply uses that + encryptjson for storing/decrypting. I would imagine that storing in the confs file that it is encrypted using &#34;handle&#34;&#39;s account login might be a good way to differentiate between this mode of password usage. OK, so we now have the insecure plaintext, the decent using handle&#39;s passphrase and paranoid different passphrase for each exchange (with additional permanentfile for native versions) &#34;SUPPORT&#34; -&gt; &#34;SUPPORTS&#34; just a typo and &#34;allpairs&#34; API is missing from the selection Might as well add a &#34;tradebots&#34; tab: THREE_STRINGS_AND_DOUBLE(tradebot,monitor,exchange,base,rel,commission); STRING_AND_DOUBLE(tradebot,monitorall,exchange,commission); THREE_STRINGS(tradebot,unmonitor,exchange,base,rel); THREE_STRINGS_AND_THREE_DOUBLES(tradebot,accumulate,exchange,base,rel,pr ice,volume,duration); THREE_STRINGS_AND_THREE_DOUBLES(tradebot,divest,exchange,base,rel,price, volume,duration); STRING_ARG(tradebot,activebots,exchange); TWO_STRINGS(tradebot,status,exchange,botid); TWO_STRINGS(tradebot,pause,exchange,botid); TWO_STRINGS(tradebot,stop,exchange,botid); TWO_STRINGS(tradebot,resume,exchange,botid); the above are API for exchange specific bots, most should be self-explanatory. bots are created via &#34;accumulate&#34; or &#34;divest&#34; API call. it returns botid. once created, you can do status, pause, stop, resume to a botid. and an activebots API call lists all the active bots for an exchange. duration is in seconds the &#34;monitor&#34; API starts background monitoring of a specific base/rel, &#34;unmonitor&#34; stops this. &#34;monitorall&#34; just does a monitor to the entire list of &#34;allpairs&#34; for that exchange. Keep in mind that doing a monitorall will not add load to an exchange as the request to each exchange is governed by pollgap, but if you have 3 things monitored, it will take 3*pollgap + time each one takes to execute. and if N are monitored it is N*pollgap + time of each, with the &#34;time of each&#34; possibly taking a very long time. And one final request for today: Bitmap tab. It should be an active bitmap using mouse api. either a dropdown to select the bitmap or a form entry. then the rest of the page (resize the bitmap to the page size) being the active bitmap. So on a small screen the bitmap is smaller x/y dimensions and larger on larger screens. plz make sure the proper dimensions are communicated to the pexe via API if it ever is changed. @vineet.bhargav86: I changed the &#34;passphrase&#34; fieldname to &#34;password&#34; for the encryptjson/decryptjson related API. The reason is that the password is like a wallet password and is only local, so it doesnt need to be as high entropy as passphrase. I also added a field to the login API as I realized that the 12 word &#34;passphrase&#34; is the payload and usually wont be sent in: FOUR_STRINGS(SuperNET,login,handle,password,permanentfile,passphrase); using &#34;abiglongpassword&#34; for the passphrase -&gt; {&#34;pubkey&#34;:&#34;6c469ba10b40b3eb9d1dba569d7f929d55a29d8f97cd5425907ef2f38f906 209&#34;,&#34;RS&#34;:&#34;NXT-KGV9-DXX8-TM86-DXR96&#34;,&#34;NXT&#34;:&#34;12834974574569896807&#34;,&#34;btcpu bkey&#34;:&#34;024e7641dc947b211bc30fe3339765258902794687b227121fc217284f9d8503c 8&#34;,&#34;rmd160&#34;:&#34;33453c24914db7b77069b7ea24df44f6be145938&#34;,&#34;BTC&#34;:&#34;15g6QK2dSd iW9ZTQEnnJxKrSph6uP7uU23&#34;,&#34;BTCD&#34;:&#34;RDxHUpuv3TX5DZpbhxmS3rBeaxZW1fvYvC&#34;,&#34;r esult&#34;:&#34;success&#34;,&#34;handle&#34;:&#34;test&#34;,&#34;tag&#34;:&#34;14805226009240621255&#34;} and if you use that to log into NXT, it gives the same address. The BTC and BTCD addresses are all derived from the same privkey so they are all interchangeable with the NXT address. The user can therefore select which coin&#39;s addressing they are most comfortable with I also added an &#34;allin&#34; action API for pangea. all the action API will autocalculate the number of chips if passed in 0 for numchips ***************** security issue ******** please dont use the GET URL method when dealing with passphrase!!! Those URL&#39;s tend to get logged and available in browser histories. so anything dealing with the actual passphrase needs to use the postCall form or POST
9 years ago
retjson = SuperNET_rosettajson(privkey,flag);
9 years ago
jaddstr(retjson,"privcipher",privcipher);
check = SuperNET_pindecipher(IGUANA_CALLARGS,pin,privcipher);
if ( memcmp(check.bytes,privkey.bytes,sizeof(check)) != 0 )
{
jaddbits256(retjson,"deciphered",check);
jaddstr(retjson,"error","cant recreate privkey from (pin + privcipher)");
}
else if ( flag != 0 )
jaddbits256(retjson,"deciphered",check);
if ( jobj(retjson,"error") == 0 )
jaddstr(retjson,"result","use pin and privcipher to access wallet");
return(jprint(retjson,1));
}
STRING_ARG(SuperNET,broadcastcipher,message)
{
bits256 zero;
many changes blockexplorer tab: needs to allow to input height, blockhash or txid. also please display images/BTC_blocks.jpg below the text as a w800 x h400 bitmap, which is active using the mouse api for coin management, below the active coins have a form that arbitrary json can be input with an add button to the right that will call &#34;addcoin&#34; API. this way I can test adding new coins dynamically. dont worry if it doesnt work, just as long as it submits the json to the C code. I am pretty sure I need to do some debugging of this peers management is not working for me at all. maybe it is due to bad internet. On initialization you need to read in the confs/BTCD_peers.txt from the native filesystem and save it into the chrome app filesystem. same thing for confs/BTCD_hdrs.txt. But this is only to be done if there isnt already such a file inside chrome. if there is, only do it upon a button invoked by the user. the reason is that the pexe is updating this file with the latest. Maybe it is nice to have an &#34;extract&#34; button that will copy out from the chrome storage into the native filesystem. There is also the manifest issue about localstorage vs chrome.localstorage. not sure what is needed to be done, but certainly a priority to get it so everything works as a chrome app. I know before it was making ramchain files inside the chrome filesystem, so it is probably things the GUI is doing. maybe in the settings tab, which has obsolete stuff that can be removed. anyway, the issue about files existing in the native filesystem -&gt; chrome and optionally extracting them is an issue for the confs files and .html template files used to autogenerate the port7778, maybe other files are affected. i think we need a way to have a list of hardcoded files that are just copied into chrome on startup if they dont exist already (or if possible copy over if the native version is bigger?) and buttons to extract them for debug tab: THREE_STRINGS(SuperNET,encryptjson,passphrase,permanentfile,anything); TWO_STRINGS(SuperNET,decryptjson,passphrase,permanentfile); at the top of page a way to put in passphrase and optional permanentfile along with arbitrary json. The standard form template has no easy way to describe to pass in everything as it is oriented to specific fields. but the encryptjson API saves all the fields, so the arbitrary json from the form needs to be combined at the same level as the &#34;agent&#34;, &#34;method&#34;, etc. I know, not the best, but internally it makes it easier. so {&#34;agent&#34;:&#34;SuperNET&#34;,&#34;method&#34;:&#34;encryptjson&#34;,&#34;passphrase&#34;:&#34;&lt;passphrase&gt;&#34;,&#34; permanentfile&#34;:&#34;&lt;filename&gt;&#34;,&#34;fromform&#34;:&#34;valuefromform&#34;,&#34;fromform2&#34;:&#34;valu efromform2&#34;,...rest of form at top level} then this will save it into a file with crazy number (it is a hash like txid) but given the same passphrase and filename, it will regenerate this hash so you dont actually have to store it, but it helps during debugging. for the filename, we must warn quite strongly to the user that if the file is ever lost or even changed in any way that the data will not be recoverable. also best to not allow the user to specify a file that does not exist. I think at this point chrome app version gets a bit tricky. we could simply push the native file into the chrome storage, but then an attacker who gets access to the computer could just get a list of these files and it really wont be much protection. So that means if a filename is specified, it needs to be copied into the chrome space, then immediately deleted... ok, this seems like not a good approach. let us make it so that the permanentfile option is not available from the chrome app, but only if the native version is running. that way we sidestep the issue of the pexe not having access to the specified file. Speaking of native vs pexe, on the startup page we should have a radio button that allows the user to select which the GUI will talk to. It should default based on a self test to the more likely value, but it is possible that the user wants to use the native version, even if the pexe is running. another thing to have on the startup page is a simple login: THREE_STRINGS(SuperNET,login,passphrase,permanentfile,handle); ZERO_ARGS(SuperNET,logout); ZERO_ARGS(SuperNET,activehandle); the handle is a human readable name that is associated with the passphrase/permanentfile. There can only be one active account (though it will be possible to associate different accounts with tradebots). use the activehandle API to find out who is logged in and the associated addresses and pubkeys The above is not yet tested so if it doesnt work, dont fret, just let me know. Once set the handle can be displayed in various places to let the user know which account is logged in. The standard 12 dictionary word passphrases should be used, but any string can be sent in as the password for Pangea: INT_AND_ARRAY(pangea,host,minplayers,params); ZERO_ARGS(pangea,lobby); HASH_AND_STRING(pangea,join,tablehash,handle); HASH_AND_INT(pangea,buyin,tablehash,numchips); HASH_ARG(pangea,start,tablehash); // by host only HASH_ARG(pangea,status,tablehash); HASH_ARG(pangea,call,tablehash); HASH_ARG(pangea,check,tablehash); HASH_AND_INT(pangea,raise,tablehash,numchips); HASH_AND_INT(pangea,bet,tablehash,numchips); HASH_ARG(pangea,fold,tablehash); HASH_AND_STRING(pangea,mode,tablehash,modestr); HASH_ARG(pangea,history,tablehash); HASH_AND_INT(pangea,handhistory,tablehash,hand); The first thing that is done is a &#34;host&#34; by any node. the &#34;params&#34; should be an arbitrary json (like encryptjson) as it needs to be at the top level and it has quite a few different parameters still subject to change. The lobby API will just display all the hosted tables. once a table exists, players can join and then buyin. the buyin is denominated in chips, each chip&#39;s value is determined by the host&#39;s initial parameters. once there are enough players joined with adequate buyin&#39;s verified, the host will be able to do a start. if done before it will (eventually) give an error. for now it will just proceed. The host and players that have joined a tablehash, need to do regular status calls to see if the game has started. Probably just once per 5 or even 10 seconds is fine before the start. Once the game starts (the status will have this info) then once per second polling is needed. Then when it is your turn (as indicated by status) you need to do one of the 5 actions (fold, call, check, raise, bet). do not worry if you dont understand what all these do, just allow the user to do any of these. I guess it is possible to submit it ahead of time. I will support internally remembering the most recent action done prior to it being your turn. once it is your turn and an action is sent to the table, it is too late to change. The last API calls are for getting handhistory where hand is 0 to N-1, being the numbering of the hands played at that table. if just history, all the history for all hands at the table is coming back, so it could be quite big. probably I will make it a summary, but for the GUI just display the returned values. the mode is to change some poker specific modes, so just allow there to be a string entered. do not worry about understanding the pokerness of the API, just the overall flow: host -&gt; creates, join/buyin -&gt; fills up player slots, start -&gt; starts the game status -&gt; to determine when the game starts (or if it is cancelled) and once started actions -&gt; game specific but basically just (button + arg) that is the user input results are via status for current game and history for past ones please try to do the above logic in a generic way so it can be reused for other games. The basic flow should be the same for almost all multiplayer turn based games and even for multiplayer realtime games For InstantDEX: on the apikeypair/userid there needs to be two modes. one for when there is no stored apikey and the current form is fine, just need to make it wider as most apikeys are quite long. Now once there is an apikey saved all that is needed is the passphrase to unlock it. So here is where the encrptjson/decryptjson is used. When saving the apikey for the first time, it can be: a) not saved -&gt; nothing extra to do b) saved without password -&gt; you can just save to a file and use it to load it back in. use confs dir confs/instantdex.exchange.api or something like that c) saved with password (optional filename for native) -&gt; probably best to save in the confs dir to indicate that there is an encrypted file for this, so just that and not the actual passphrase in the file with the above, when the exchange is selected, you can see if the confs file exists and if it has the plaintext, just populate the field, if not, then indicate that a passphrase is needed. if the user provides the passphrase, then decryptjson and populate the fields and autosubmit. A special case is to encrypt the apikeys with the passphrase used when logging in. This is only available if the checkbox to &#34;remember passphrase during session&#34; is set on the main iguana login screen. (i forgot to mention that checkbox!) So the login passphrase is stored in memory, then the GUI simply uses that + encryptjson for storing/decrypting. I would imagine that storing in the confs file that it is encrypted using &#34;handle&#34;&#39;s account login might be a good way to differentiate between this mode of password usage. OK, so we now have the insecure plaintext, the decent using handle&#39;s passphrase and paranoid different passphrase for each exchange (with additional permanentfile for native versions) &#34;SUPPORT&#34; -&gt; &#34;SUPPORTS&#34; just a typo and &#34;allpairs&#34; API is missing from the selection Might as well add a &#34;tradebots&#34; tab: THREE_STRINGS_AND_DOUBLE(tradebot,monitor,exchange,base,rel,commission); STRING_AND_DOUBLE(tradebot,monitorall,exchange,commission); THREE_STRINGS(tradebot,unmonitor,exchange,base,rel); THREE_STRINGS_AND_THREE_DOUBLES(tradebot,accumulate,exchange,base,rel,pr ice,volume,duration); THREE_STRINGS_AND_THREE_DOUBLES(tradebot,divest,exchange,base,rel,price, volume,duration); STRING_ARG(tradebot,activebots,exchange); TWO_STRINGS(tradebot,status,exchange,botid); TWO_STRINGS(tradebot,pause,exchange,botid); TWO_STRINGS(tradebot,stop,exchange,botid); TWO_STRINGS(tradebot,resume,exchange,botid); the above are API for exchange specific bots, most should be self-explanatory. bots are created via &#34;accumulate&#34; or &#34;divest&#34; API call. it returns botid. once created, you can do status, pause, stop, resume to a botid. and an activebots API call lists all the active bots for an exchange. duration is in seconds the &#34;monitor&#34; API starts background monitoring of a specific base/rel, &#34;unmonitor&#34; stops this. &#34;monitorall&#34; just does a monitor to the entire list of &#34;allpairs&#34; for that exchange. Keep in mind that doing a monitorall will not add load to an exchange as the request to each exchange is governed by pollgap, but if you have 3 things monitored, it will take 3*pollgap + time each one takes to execute. and if N are monitored it is N*pollgap + time of each, with the &#34;time of each&#34; possibly taking a very long time. And one final request for today: Bitmap tab. It should be an active bitmap using mouse api. either a dropdown to select the bitmap or a form entry. then the rest of the page (resize the bitmap to the page size) being the active bitmap. So on a small screen the bitmap is smaller x/y dimensions and larger on larger screens. plz make sure the proper dimensions are communicated to the pexe via API if it ever is changed. @vineet.bhargav86: I changed the &#34;passphrase&#34; fieldname to &#34;password&#34; for the encryptjson/decryptjson related API. The reason is that the password is like a wallet password and is only local, so it doesnt need to be as high entropy as passphrase. I also added a field to the login API as I realized that the 12 word &#34;passphrase&#34; is the payload and usually wont be sent in: FOUR_STRINGS(SuperNET,login,handle,password,permanentfile,passphrase); using &#34;abiglongpassword&#34; for the passphrase -&gt; {&#34;pubkey&#34;:&#34;6c469ba10b40b3eb9d1dba569d7f929d55a29d8f97cd5425907ef2f38f906 209&#34;,&#34;RS&#34;:&#34;NXT-KGV9-DXX8-TM86-DXR96&#34;,&#34;NXT&#34;:&#34;12834974574569896807&#34;,&#34;btcpu bkey&#34;:&#34;024e7641dc947b211bc30fe3339765258902794687b227121fc217284f9d8503c 8&#34;,&#34;rmd160&#34;:&#34;33453c24914db7b77069b7ea24df44f6be145938&#34;,&#34;BTC&#34;:&#34;15g6QK2dSd iW9ZTQEnnJxKrSph6uP7uU23&#34;,&#34;BTCD&#34;:&#34;RDxHUpuv3TX5DZpbhxmS3rBeaxZW1fvYvC&#34;,&#34;r esult&#34;:&#34;success&#34;,&#34;handle&#34;:&#34;test&#34;,&#34;tag&#34;:&#34;14805226009240621255&#34;} and if you use that to log into NXT, it gives the same address. The BTC and BTCD addresses are all derived from the same privkey so they are all interchangeable with the NXT address. The user can therefore select which coin&#39;s addressing they are most comfortable with I also added an &#34;allin&#34; action API for pangea. all the action API will autocalculate the number of chips if passed in 0 for numchips ***************** security issue ******** please dont use the GET URL method when dealing with passphrase!!! Those URL&#39;s tend to get logged and available in browser histories. so anything dealing with the actual passphrase needs to use the postCall form or POST
9 years ago
if ( remoteaddr != 0 )
return(clonestr("{\"error\":\"no remote\"}"));
9 years ago
memset(zero.bytes,0,sizeof(zero));
return(SuperNET_cipher(IGUANA_CALLARGS,zero,zero,message));
}
STRING_ARG(SuperNET,broadcastdecipher,message)
{
bits256 zero;
many changes blockexplorer tab: needs to allow to input height, blockhash or txid. also please display images/BTC_blocks.jpg below the text as a w800 x h400 bitmap, which is active using the mouse api for coin management, below the active coins have a form that arbitrary json can be input with an add button to the right that will call &#34;addcoin&#34; API. this way I can test adding new coins dynamically. dont worry if it doesnt work, just as long as it submits the json to the C code. I am pretty sure I need to do some debugging of this peers management is not working for me at all. maybe it is due to bad internet. On initialization you need to read in the confs/BTCD_peers.txt from the native filesystem and save it into the chrome app filesystem. same thing for confs/BTCD_hdrs.txt. But this is only to be done if there isnt already such a file inside chrome. if there is, only do it upon a button invoked by the user. the reason is that the pexe is updating this file with the latest. Maybe it is nice to have an &#34;extract&#34; button that will copy out from the chrome storage into the native filesystem. There is also the manifest issue about localstorage vs chrome.localstorage. not sure what is needed to be done, but certainly a priority to get it so everything works as a chrome app. I know before it was making ramchain files inside the chrome filesystem, so it is probably things the GUI is doing. maybe in the settings tab, which has obsolete stuff that can be removed. anyway, the issue about files existing in the native filesystem -&gt; chrome and optionally extracting them is an issue for the confs files and .html template files used to autogenerate the port7778, maybe other files are affected. i think we need a way to have a list of hardcoded files that are just copied into chrome on startup if they dont exist already (or if possible copy over if the native version is bigger?) and buttons to extract them for debug tab: THREE_STRINGS(SuperNET,encryptjson,passphrase,permanentfile,anything); TWO_STRINGS(SuperNET,decryptjson,passphrase,permanentfile); at the top of page a way to put in passphrase and optional permanentfile along with arbitrary json. The standard form template has no easy way to describe to pass in everything as it is oriented to specific fields. but the encryptjson API saves all the fields, so the arbitrary json from the form needs to be combined at the same level as the &#34;agent&#34;, &#34;method&#34;, etc. I know, not the best, but internally it makes it easier. so {&#34;agent&#34;:&#34;SuperNET&#34;,&#34;method&#34;:&#34;encryptjson&#34;,&#34;passphrase&#34;:&#34;&lt;passphrase&gt;&#34;,&#34; permanentfile&#34;:&#34;&lt;filename&gt;&#34;,&#34;fromform&#34;:&#34;valuefromform&#34;,&#34;fromform2&#34;:&#34;valu efromform2&#34;,...rest of form at top level} then this will save it into a file with crazy number (it is a hash like txid) but given the same passphrase and filename, it will regenerate this hash so you dont actually have to store it, but it helps during debugging. for the filename, we must warn quite strongly to the user that if the file is ever lost or even changed in any way that the data will not be recoverable. also best to not allow the user to specify a file that does not exist. I think at this point chrome app version gets a bit tricky. we could simply push the native file into the chrome storage, but then an attacker who gets access to the computer could just get a list of these files and it really wont be much protection. So that means if a filename is specified, it needs to be copied into the chrome space, then immediately deleted... ok, this seems like not a good approach. let us make it so that the permanentfile option is not available from the chrome app, but only if the native version is running. that way we sidestep the issue of the pexe not having access to the specified file. Speaking of native vs pexe, on the startup page we should have a radio button that allows the user to select which the GUI will talk to. It should default based on a self test to the more likely value, but it is possible that the user wants to use the native version, even if the pexe is running. another thing to have on the startup page is a simple login: THREE_STRINGS(SuperNET,login,passphrase,permanentfile,handle); ZERO_ARGS(SuperNET,logout); ZERO_ARGS(SuperNET,activehandle); the handle is a human readable name that is associated with the passphrase/permanentfile. There can only be one active account (though it will be possible to associate different accounts with tradebots). use the activehandle API to find out who is logged in and the associated addresses and pubkeys The above is not yet tested so if it doesnt work, dont fret, just let me know. Once set the handle can be displayed in various places to let the user know which account is logged in. The standard 12 dictionary word passphrases should be used, but any string can be sent in as the password for Pangea: INT_AND_ARRAY(pangea,host,minplayers,params); ZERO_ARGS(pangea,lobby); HASH_AND_STRING(pangea,join,tablehash,handle); HASH_AND_INT(pangea,buyin,tablehash,numchips); HASH_ARG(pangea,start,tablehash); // by host only HASH_ARG(pangea,status,tablehash); HASH_ARG(pangea,call,tablehash); HASH_ARG(pangea,check,tablehash); HASH_AND_INT(pangea,raise,tablehash,numchips); HASH_AND_INT(pangea,bet,tablehash,numchips); HASH_ARG(pangea,fold,tablehash); HASH_AND_STRING(pangea,mode,tablehash,modestr); HASH_ARG(pangea,history,tablehash); HASH_AND_INT(pangea,handhistory,tablehash,hand); The first thing that is done is a &#34;host&#34; by any node. the &#34;params&#34; should be an arbitrary json (like encryptjson) as it needs to be at the top level and it has quite a few different parameters still subject to change. The lobby API will just display all the hosted tables. once a table exists, players can join and then buyin. the buyin is denominated in chips, each chip&#39;s value is determined by the host&#39;s initial parameters. once there are enough players joined with adequate buyin&#39;s verified, the host will be able to do a start. if done before it will (eventually) give an error. for now it will just proceed. The host and players that have joined a tablehash, need to do regular status calls to see if the game has started. Probably just once per 5 or even 10 seconds is fine before the start. Once the game starts (the status will have this info) then once per second polling is needed. Then when it is your turn (as indicated by status) you need to do one of the 5 actions (fold, call, check, raise, bet). do not worry if you dont understand what all these do, just allow the user to do any of these. I guess it is possible to submit it ahead of time. I will support internally remembering the most recent action done prior to it being your turn. once it is your turn and an action is sent to the table, it is too late to change. The last API calls are for getting handhistory where hand is 0 to N-1, being the numbering of the hands played at that table. if just history, all the history for all hands at the table is coming back, so it could be quite big. probably I will make it a summary, but for the GUI just display the returned values. the mode is to change some poker specific modes, so just allow there to be a string entered. do not worry about understanding the pokerness of the API, just the overall flow: host -&gt; creates, join/buyin -&gt; fills up player slots, start -&gt; starts the game status -&gt; to determine when the game starts (or if it is cancelled) and once started actions -&gt; game specific but basically just (button + arg) that is the user input results are via status for current game and history for past ones please try to do the above logic in a generic way so it can be reused for other games. The basic flow should be the same for almost all multiplayer turn based games and even for multiplayer realtime games For InstantDEX: on the apikeypair/userid there needs to be two modes. one for when there is no stored apikey and the current form is fine, just need to make it wider as most apikeys are quite long. Now once there is an apikey saved all that is needed is the passphrase to unlock it. So here is where the encrptjson/decryptjson is used. When saving the apikey for the first time, it can be: a) not saved -&gt; nothing extra to do b) saved without password -&gt; you can just save to a file and use it to load it back in. use confs dir confs/instantdex.exchange.api or something like that c) saved with password (optional filename for native) -&gt; probably best to save in the confs dir to indicate that there is an encrypted file for this, so just that and not the actual passphrase in the file with the above, when the exchange is selected, you can see if the confs file exists and if it has the plaintext, just populate the field, if not, then indicate that a passphrase is needed. if the user provides the passphrase, then decryptjson and populate the fields and autosubmit. A special case is to encrypt the apikeys with the passphrase used when logging in. This is only available if the checkbox to &#34;remember passphrase during session&#34; is set on the main iguana login screen. (i forgot to mention that checkbox!) So the login passphrase is stored in memory, then the GUI simply uses that + encryptjson for storing/decrypting. I would imagine that storing in the confs file that it is encrypted using &#34;handle&#34;&#39;s account login might be a good way to differentiate between this mode of password usage. OK, so we now have the insecure plaintext, the decent using handle&#39;s passphrase and paranoid different passphrase for each exchange (with additional permanentfile for native versions) &#34;SUPPORT&#34; -&gt; &#34;SUPPORTS&#34; just a typo and &#34;allpairs&#34; API is missing from the selection Might as well add a &#34;tradebots&#34; tab: THREE_STRINGS_AND_DOUBLE(tradebot,monitor,exchange,base,rel,commission); STRING_AND_DOUBLE(tradebot,monitorall,exchange,commission); THREE_STRINGS(tradebot,unmonitor,exchange,base,rel); THREE_STRINGS_AND_THREE_DOUBLES(tradebot,accumulate,exchange,base,rel,pr ice,volume,duration); THREE_STRINGS_AND_THREE_DOUBLES(tradebot,divest,exchange,base,rel,price, volume,duration); STRING_ARG(tradebot,activebots,exchange); TWO_STRINGS(tradebot,status,exchange,botid); TWO_STRINGS(tradebot,pause,exchange,botid); TWO_STRINGS(tradebot,stop,exchange,botid); TWO_STRINGS(tradebot,resume,exchange,botid); the above are API for exchange specific bots, most should be self-explanatory. bots are created via &#34;accumulate&#34; or &#34;divest&#34; API call. it returns botid. once created, you can do status, pause, stop, resume to a botid. and an activebots API call lists all the active bots for an exchange. duration is in seconds the &#34;monitor&#34; API starts background monitoring of a specific base/rel, &#34;unmonitor&#34; stops this. &#34;monitorall&#34; just does a monitor to the entire list of &#34;allpairs&#34; for that exchange. Keep in mind that doing a monitorall will not add load to an exchange as the request to each exchange is governed by pollgap, but if you have 3 things monitored, it will take 3*pollgap + time each one takes to execute. and if N are monitored it is N*pollgap + time of each, with the &#34;time of each&#34; possibly taking a very long time. And one final request for today: Bitmap tab. It should be an active bitmap using mouse api. either a dropdown to select the bitmap or a form entry. then the rest of the page (resize the bitmap to the page size) being the active bitmap. So on a small screen the bitmap is smaller x/y dimensions and larger on larger screens. plz make sure the proper dimensions are communicated to the pexe via API if it ever is changed. @vineet.bhargav86: I changed the &#34;passphrase&#34; fieldname to &#34;password&#34; for the encryptjson/decryptjson related API. The reason is that the password is like a wallet password and is only local, so it doesnt need to be as high entropy as passphrase. I also added a field to the login API as I realized that the 12 word &#34;passphrase&#34; is the payload and usually wont be sent in: FOUR_STRINGS(SuperNET,login,handle,password,permanentfile,passphrase); using &#34;abiglongpassword&#34; for the passphrase -&gt; {&#34;pubkey&#34;:&#34;6c469ba10b40b3eb9d1dba569d7f929d55a29d8f97cd5425907ef2f38f906 209&#34;,&#34;RS&#34;:&#34;NXT-KGV9-DXX8-TM86-DXR96&#34;,&#34;NXT&#34;:&#34;12834974574569896807&#34;,&#34;btcpu bkey&#34;:&#34;024e7641dc947b211bc30fe3339765258902794687b227121fc217284f9d8503c 8&#34;,&#34;rmd160&#34;:&#34;33453c24914db7b77069b7ea24df44f6be145938&#34;,&#34;BTC&#34;:&#34;15g6QK2dSd iW9ZTQEnnJxKrSph6uP7uU23&#34;,&#34;BTCD&#34;:&#34;RDxHUpuv3TX5DZpbhxmS3rBeaxZW1fvYvC&#34;,&#34;r esult&#34;:&#34;success&#34;,&#34;handle&#34;:&#34;test&#34;,&#34;tag&#34;:&#34;14805226009240621255&#34;} and if you use that to log into NXT, it gives the same address. The BTC and BTCD addresses are all derived from the same privkey so they are all interchangeable with the NXT address. The user can therefore select which coin&#39;s addressing they are most comfortable with I also added an &#34;allin&#34; action API for pangea. all the action API will autocalculate the number of chips if passed in 0 for numchips ***************** security issue ******** please dont use the GET URL method when dealing with passphrase!!! Those URL&#39;s tend to get logged and available in browser histories. so anything dealing with the actual passphrase needs to use the postCall form or POST
9 years ago
if ( remoteaddr != 0 )
return(clonestr("{\"error\":\"no remote\"}"));
9 years ago
memset(zero.bytes,0,sizeof(zero));
return(SuperNET_decipher(IGUANA_CALLARGS,zero,zero,message));
}
HASH_AND_STRING(SuperNET,multicastcipher,pubkey,message)
{
bits256 zero;
many changes blockexplorer tab: needs to allow to input height, blockhash or txid. also please display images/BTC_blocks.jpg below the text as a w800 x h400 bitmap, which is active using the mouse api for coin management, below the active coins have a form that arbitrary json can be input with an add button to the right that will call &#34;addcoin&#34; API. this way I can test adding new coins dynamically. dont worry if it doesnt work, just as long as it submits the json to the C code. I am pretty sure I need to do some debugging of this peers management is not working for me at all. maybe it is due to bad internet. On initialization you need to read in the confs/BTCD_peers.txt from the native filesystem and save it into the chrome app filesystem. same thing for confs/BTCD_hdrs.txt. But this is only to be done if there isnt already such a file inside chrome. if there is, only do it upon a button invoked by the user. the reason is that the pexe is updating this file with the latest. Maybe it is nice to have an &#34;extract&#34; button that will copy out from the chrome storage into the native filesystem. There is also the manifest issue about localstorage vs chrome.localstorage. not sure what is needed to be done, but certainly a priority to get it so everything works as a chrome app. I know before it was making ramchain files inside the chrome filesystem, so it is probably things the GUI is doing. maybe in the settings tab, which has obsolete stuff that can be removed. anyway, the issue about files existing in the native filesystem -&gt; chrome and optionally extracting them is an issue for the confs files and .html template files used to autogenerate the port7778, maybe other files are affected. i think we need a way to have a list of hardcoded files that are just copied into chrome on startup if they dont exist already (or if possible copy over if the native version is bigger?) and buttons to extract them for debug tab: THREE_STRINGS(SuperNET,encryptjson,passphrase,permanentfile,anything); TWO_STRINGS(SuperNET,decryptjson,passphrase,permanentfile); at the top of page a way to put in passphrase and optional permanentfile along with arbitrary json. The standard form template has no easy way to describe to pass in everything as it is oriented to specific fields. but the encryptjson API saves all the fields, so the arbitrary json from the form needs to be combined at the same level as the &#34;agent&#34;, &#34;method&#34;, etc. I know, not the best, but internally it makes it easier. so {&#34;agent&#34;:&#34;SuperNET&#34;,&#34;method&#34;:&#34;encryptjson&#34;,&#34;passphrase&#34;:&#34;&lt;passphrase&gt;&#34;,&#34; permanentfile&#34;:&#34;&lt;filename&gt;&#34;,&#34;fromform&#34;:&#34;valuefromform&#34;,&#34;fromform2&#34;:&#34;valu efromform2&#34;,...rest of form at top level} then this will save it into a file with crazy number (it is a hash like txid) but given the same passphrase and filename, it will regenerate this hash so you dont actually have to store it, but it helps during debugging. for the filename, we must warn quite strongly to the user that if the file is ever lost or even changed in any way that the data will not be recoverable. also best to not allow the user to specify a file that does not exist. I think at this point chrome app version gets a bit tricky. we could simply push the native file into the chrome storage, but then an attacker who gets access to the computer could just get a list of these files and it really wont be much protection. So that means if a filename is specified, it needs to be copied into the chrome space, then immediately deleted... ok, this seems like not a good approach. let us make it so that the permanentfile option is not available from the chrome app, but only if the native version is running. that way we sidestep the issue of the pexe not having access to the specified file. Speaking of native vs pexe, on the startup page we should have a radio button that allows the user to select which the GUI will talk to. It should default based on a self test to the more likely value, but it is possible that the user wants to use the native version, even if the pexe is running. another thing to have on the startup page is a simple login: THREE_STRINGS(SuperNET,login,passphrase,permanentfile,handle); ZERO_ARGS(SuperNET,logout); ZERO_ARGS(SuperNET,activehandle); the handle is a human readable name that is associated with the passphrase/permanentfile. There can only be one active account (though it will be possible to associate different accounts with tradebots). use the activehandle API to find out who is logged in and the associated addresses and pubkeys The above is not yet tested so if it doesnt work, dont fret, just let me know. Once set the handle can be displayed in various places to let the user know which account is logged in. The standard 12 dictionary word passphrases should be used, but any string can be sent in as the password for Pangea: INT_AND_ARRAY(pangea,host,minplayers,params); ZERO_ARGS(pangea,lobby); HASH_AND_STRING(pangea,join,tablehash,handle); HASH_AND_INT(pangea,buyin,tablehash,numchips); HASH_ARG(pangea,start,tablehash); // by host only HASH_ARG(pangea,status,tablehash); HASH_ARG(pangea,call,tablehash); HASH_ARG(pangea,check,tablehash); HASH_AND_INT(pangea,raise,tablehash,numchips); HASH_AND_INT(pangea,bet,tablehash,numchips); HASH_ARG(pangea,fold,tablehash); HASH_AND_STRING(pangea,mode,tablehash,modestr); HASH_ARG(pangea,history,tablehash); HASH_AND_INT(pangea,handhistory,tablehash,hand); The first thing that is done is a &#34;host&#34; by any node. the &#34;params&#34; should be an arbitrary json (like encryptjson) as it needs to be at the top level and it has quite a few different parameters still subject to change. The lobby API will just display all the hosted tables. once a table exists, players can join and then buyin. the buyin is denominated in chips, each chip&#39;s value is determined by the host&#39;s initial parameters. once there are enough players joined with adequate buyin&#39;s verified, the host will be able to do a start. if done before it will (eventually) give an error. for now it will just proceed. The host and players that have joined a tablehash, need to do regular status calls to see if the game has started. Probably just once per 5 or even 10 seconds is fine before the start. Once the game starts (the status will have this info) then once per second polling is needed. Then when it is your turn (as indicated by status) you need to do one of the 5 actions (fold, call, check, raise, bet). do not worry if you dont understand what all these do, just allow the user to do any of these. I guess it is possible to submit it ahead of time. I will support internally remembering the most recent action done prior to it being your turn. once it is your turn and an action is sent to the table, it is too late to change. The last API calls are for getting handhistory where hand is 0 to N-1, being the numbering of the hands played at that table. if just history, all the history for all hands at the table is coming back, so it could be quite big. probably I will make it a summary, but for the GUI just display the returned values. the mode is to change some poker specific modes, so just allow there to be a string entered. do not worry about understanding the pokerness of the API, just the overall flow: host -&gt; creates, join/buyin -&gt; fills up player slots, start -&gt; starts the game status -&gt; to determine when the game starts (or if it is cancelled) and once started actions -&gt; game specific but basically just (button + arg) that is the user input results are via status for current game and history for past ones please try to do the above logic in a generic way so it can be reused for other games. The basic flow should be the same for almost all multiplayer turn based games and even for multiplayer realtime games For InstantDEX: on the apikeypair/userid there needs to be two modes. one for when there is no stored apikey and the current form is fine, just need to make it wider as most apikeys are quite long. Now once there is an apikey saved all that is needed is the passphrase to unlock it. So here is where the encrptjson/decryptjson is used. When saving the apikey for the first time, it can be: a) not saved -&gt; nothing extra to do b) saved without password -&gt; you can just save to a file and use it to load it back in. use confs dir confs/instantdex.exchange.api or something like that c) saved with password (optional filename for native) -&gt; probably best to save in the confs dir to indicate that there is an encrypted file for this, so just that and not the actual passphrase in the file with the above, when the exchange is selected, you can see if the confs file exists and if it has the plaintext, just populate the field, if not, then indicate that a passphrase is needed. if the user provides the passphrase, then decryptjson and populate the fields and autosubmit. A special case is to encrypt the apikeys with the passphrase used when logging in. This is only available if the checkbox to &#34;remember passphrase during session&#34; is set on the main iguana login screen. (i forgot to mention that checkbox!) So the login passphrase is stored in memory, then the GUI simply uses that + encryptjson for storing/decrypting. I would imagine that storing in the confs file that it is encrypted using &#34;handle&#34;&#39;s account login might be a good way to differentiate between this mode of password usage. OK, so we now have the insecure plaintext, the decent using handle&#39;s passphrase and paranoid different passphrase for each exchange (with additional permanentfile for native versions) &#34;SUPPORT&#34; -&gt; &#34;SUPPORTS&#34; just a typo and &#34;allpairs&#34; API is missing from the selection Might as well add a &#34;tradebots&#34; tab: THREE_STRINGS_AND_DOUBLE(tradebot,monitor,exchange,base,rel,commission); STRING_AND_DOUBLE(tradebot,monitorall,exchange,commission); THREE_STRINGS(tradebot,unmonitor,exchange,base,rel); THREE_STRINGS_AND_THREE_DOUBLES(tradebot,accumulate,exchange,base,rel,pr ice,volume,duration); THREE_STRINGS_AND_THREE_DOUBLES(tradebot,divest,exchange,base,rel,price, volume,duration); STRING_ARG(tradebot,activebots,exchange); TWO_STRINGS(tradebot,status,exchange,botid); TWO_STRINGS(tradebot,pause,exchange,botid); TWO_STRINGS(tradebot,stop,exchange,botid); TWO_STRINGS(tradebot,resume,exchange,botid); the above are API for exchange specific bots, most should be self-explanatory. bots are created via &#34;accumulate&#34; or &#34;divest&#34; API call. it returns botid. once created, you can do status, pause, stop, resume to a botid. and an activebots API call lists all the active bots for an exchange. duration is in seconds the &#34;monitor&#34; API starts background monitoring of a specific base/rel, &#34;unmonitor&#34; stops this. &#34;monitorall&#34; just does a monitor to the entire list of &#34;allpairs&#34; for that exchange. Keep in mind that doing a monitorall will not add load to an exchange as the request to each exchange is governed by pollgap, but if you have 3 things monitored, it will take 3*pollgap + time each one takes to execute. and if N are monitored it is N*pollgap + time of each, with the &#34;time of each&#34; possibly taking a very long time. And one final request for today: Bitmap tab. It should be an active bitmap using mouse api. either a dropdown to select the bitmap or a form entry. then the rest of the page (resize the bitmap to the page size) being the active bitmap. So on a small screen the bitmap is smaller x/y dimensions and larger on larger screens. plz make sure the proper dimensions are communicated to the pexe via API if it ever is changed. @vineet.bhargav86: I changed the &#34;passphrase&#34; fieldname to &#34;password&#34; for the encryptjson/decryptjson related API. The reason is that the password is like a wallet password and is only local, so it doesnt need to be as high entropy as passphrase. I also added a field to the login API as I realized that the 12 word &#34;passphrase&#34; is the payload and usually wont be sent in: FOUR_STRINGS(SuperNET,login,handle,password,permanentfile,passphrase); using &#34;abiglongpassword&#34; for the passphrase -&gt; {&#34;pubkey&#34;:&#34;6c469ba10b40b3eb9d1dba569d7f929d55a29d8f97cd5425907ef2f38f906 209&#34;,&#34;RS&#34;:&#34;NXT-KGV9-DXX8-TM86-DXR96&#34;,&#34;NXT&#34;:&#34;12834974574569896807&#34;,&#34;btcpu bkey&#34;:&#34;024e7641dc947b211bc30fe3339765258902794687b227121fc217284f9d8503c 8&#34;,&#34;rmd160&#34;:&#34;33453c24914db7b77069b7ea24df44f6be145938&#34;,&#34;BTC&#34;:&#34;15g6QK2dSd iW9ZTQEnnJxKrSph6uP7uU23&#34;,&#34;BTCD&#34;:&#34;RDxHUpuv3TX5DZpbhxmS3rBeaxZW1fvYvC&#34;,&#34;r esult&#34;:&#34;success&#34;,&#34;handle&#34;:&#34;test&#34;,&#34;tag&#34;:&#34;14805226009240621255&#34;} and if you use that to log into NXT, it gives the same address. The BTC and BTCD addresses are all derived from the same privkey so they are all interchangeable with the NXT address. The user can therefore select which coin&#39;s addressing they are most comfortable with I also added an &#34;allin&#34; action API for pangea. all the action API will autocalculate the number of chips if passed in 0 for numchips ***************** security issue ******** please dont use the GET URL method when dealing with passphrase!!! Those URL&#39;s tend to get logged and available in browser histories. so anything dealing with the actual passphrase needs to use the postCall form or POST
9 years ago
if ( remoteaddr != 0 )
return(clonestr("{\"error\":\"no remote\"}"));
9 years ago
memset(zero.bytes,0,sizeof(zero));
return(SuperNET_cipher(IGUANA_CALLARGS,zero,pubkey,message));
}
HASH_AND_STRING(SuperNET,multicastdecipher,privkey,cipherstr)
{
bits256 zero;
many changes blockexplorer tab: needs to allow to input height, blockhash or txid. also please display images/BTC_blocks.jpg below the text as a w800 x h400 bitmap, which is active using the mouse api for coin management, below the active coins have a form that arbitrary json can be input with an add button to the right that will call &#34;addcoin&#34; API. this way I can test adding new coins dynamically. dont worry if it doesnt work, just as long as it submits the json to the C code. I am pretty sure I need to do some debugging of this peers management is not working for me at all. maybe it is due to bad internet. On initialization you need to read in the confs/BTCD_peers.txt from the native filesystem and save it into the chrome app filesystem. same thing for confs/BTCD_hdrs.txt. But this is only to be done if there isnt already such a file inside chrome. if there is, only do it upon a button invoked by the user. the reason is that the pexe is updating this file with the latest. Maybe it is nice to have an &#34;extract&#34; button that will copy out from the chrome storage into the native filesystem. There is also the manifest issue about localstorage vs chrome.localstorage. not sure what is needed to be done, but certainly a priority to get it so everything works as a chrome app. I know before it was making ramchain files inside the chrome filesystem, so it is probably things the GUI is doing. maybe in the settings tab, which has obsolete stuff that can be removed. anyway, the issue about files existing in the native filesystem -&gt; chrome and optionally extracting them is an issue for the confs files and .html template files used to autogenerate the port7778, maybe other files are affected. i think we need a way to have a list of hardcoded files that are just copied into chrome on startup if they dont exist already (or if possible copy over if the native version is bigger?) and buttons to extract them for debug tab: THREE_STRINGS(SuperNET,encryptjson,passphrase,permanentfile,anything); TWO_STRINGS(SuperNET,decryptjson,passphrase,permanentfile); at the top of page a way to put in passphrase and optional permanentfile along with arbitrary json. The standard form template has no easy way to describe to pass in everything as it is oriented to specific fields. but the encryptjson API saves all the fields, so the arbitrary json from the form needs to be combined at the same level as the &#34;agent&#34;, &#34;method&#34;, etc. I know, not the best, but internally it makes it easier. so {&#34;agent&#34;:&#34;SuperNET&#34;,&#34;method&#34;:&#34;encryptjson&#34;,&#34;passphrase&#34;:&#34;&lt;passphrase&gt;&#34;,&#34; permanentfile&#34;:&#34;&lt;filename&gt;&#34;,&#34;fromform&#34;:&#34;valuefromform&#34;,&#34;fromform2&#34;:&#34;valu efromform2&#34;,...rest of form at top level} then this will save it into a file with crazy number (it is a hash like txid) but given the same passphrase and filename, it will regenerate this hash so you dont actually have to store it, but it helps during debugging. for the filename, we must warn quite strongly to the user that if the file is ever lost or even changed in any way that the data will not be recoverable. also best to not allow the user to specify a file that does not exist. I think at this point chrome app version gets a bit tricky. we could simply push the native file into the chrome storage, but then an attacker who gets access to the computer could just get a list of these files and it really wont be much protection. So that means if a filename is specified, it needs to be copied into the chrome space, then immediately deleted... ok, this seems like not a good approach. let us make it so that the permanentfile option is not available from the chrome app, but only if the native version is running. that way we sidestep the issue of the pexe not having access to the specified file. Speaking of native vs pexe, on the startup page we should have a radio button that allows the user to select which the GUI will talk to. It should default based on a self test to the more likely value, but it is possible that the user wants to use the native version, even if the pexe is running. another thing to have on the startup page is a simple login: THREE_STRINGS(SuperNET,login,passphrase,permanentfile,handle); ZERO_ARGS(SuperNET,logout); ZERO_ARGS(SuperNET,activehandle); the handle is a human readable name that is associated with the passphrase/permanentfile. There can only be one active account (though it will be possible to associate different accounts with tradebots). use the activehandle API to find out who is logged in and the associated addresses and pubkeys The above is not yet tested so if it doesnt work, dont fret, just let me know. Once set the handle can be displayed in various places to let the user know which account is logged in. The standard 12 dictionary word passphrases should be used, but any string can be sent in as the password for Pangea: INT_AND_ARRAY(pangea,host,minplayers,params); ZERO_ARGS(pangea,lobby); HASH_AND_STRING(pangea,join,tablehash,handle); HASH_AND_INT(pangea,buyin,tablehash,numchips); HASH_ARG(pangea,start,tablehash); // by host only HASH_ARG(pangea,status,tablehash); HASH_ARG(pangea,call,tablehash); HASH_ARG(pangea,check,tablehash); HASH_AND_INT(pangea,raise,tablehash,numchips); HASH_AND_INT(pangea,bet,tablehash,numchips); HASH_ARG(pangea,fold,tablehash); HASH_AND_STRING(pangea,mode,tablehash,modestr); HASH_ARG(pangea,history,tablehash); HASH_AND_INT(pangea,handhistory,tablehash,hand); The first thing that is done is a &#34;host&#34; by any node. the &#34;params&#34; should be an arbitrary json (like encryptjson) as it needs to be at the top level and it has quite a few different parameters still subject to change. The lobby API will just display all the hosted tables. once a table exists, players can join and then buyin. the buyin is denominated in chips, each chip&#39;s value is determined by the host&#39;s initial parameters. once there are enough players joined with adequate buyin&#39;s verified, the host will be able to do a start. if done before it will (eventually) give an error. for now it will just proceed. The host and players that have joined a tablehash, need to do regular status calls to see if the game has started. Probably just once per 5 or even 10 seconds is fine before the start. Once the game starts (the status will have this info) then once per second polling is needed. Then when it is your turn (as indicated by status) you need to do one of the 5 actions (fold, call, check, raise, bet). do not worry if you dont understand what all these do, just allow the user to do any of these. I guess it is possible to submit it ahead of time. I will support internally remembering the most recent action done prior to it being your turn. once it is your turn and an action is sent to the table, it is too late to change. The last API calls are for getting handhistory where hand is 0 to N-1, being the numbering of the hands played at that table. if just history, all the history for all hands at the table is coming back, so it could be quite big. probably I will make it a summary, but for the GUI just display the returned values. the mode is to change some poker specific modes, so just allow there to be a string entered. do not worry about understanding the pokerness of the API, just the overall flow: host -&gt; creates, join/buyin -&gt; fills up player slots, start -&gt; starts the game status -&gt; to determine when the game starts (or if it is cancelled) and once started actions -&gt; game specific but basically just (button + arg) that is the user input results are via status for current game and history for past ones please try to do the above logic in a generic way so it can be reused for other games. The basic flow should be the same for almost all multiplayer turn based games and even for multiplayer realtime games For InstantDEX: on the apikeypair/userid there needs to be two modes. one for when there is no stored apikey and the current form is fine, just need to make it wider as most apikeys are quite long. Now once there is an apikey saved all that is needed is the passphrase to unlock it. So here is where the encrptjson/decryptjson is used. When saving the apikey for the first time, it can be: a) not saved -&gt; nothing extra to do b) saved without password -&gt; you can just save to a file and use it to load it back in. use confs dir confs/instantdex.exchange.api or something like that c) saved with password (optional filename for native) -&gt; probably best to save in the confs dir to indicate that there is an encrypted file for this, so just that and not the actual passphrase in the file with the above, when the exchange is selected, you can see if the confs file exists and if it has the plaintext, just populate the field, if not, then indicate that a passphrase is needed. if the user provides the passphrase, then decryptjson and populate the fields and autosubmit. A special case is to encrypt the apikeys with the passphrase used when logging in. This is only available if the checkbox to &#34;remember passphrase during session&#34; is set on the main iguana login screen. (i forgot to mention that checkbox!) So the login passphrase is stored in memory, then the GUI simply uses that + encryptjson for storing/decrypting. I would imagine that storing in the confs file that it is encrypted using &#34;handle&#34;&#39;s account login might be a good way to differentiate between this mode of password usage. OK, so we now have the insecure plaintext, the decent using handle&#39;s passphrase and paranoid different passphrase for each exchange (with additional permanentfile for native versions) &#34;SUPPORT&#34; -&gt; &#34;SUPPORTS&#34; just a typo and &#34;allpairs&#34; API is missing from the selection Might as well add a &#34;tradebots&#34; tab: THREE_STRINGS_AND_DOUBLE(tradebot,monitor,exchange,base,rel,commission); STRING_AND_DOUBLE(tradebot,monitorall,exchange,commission); THREE_STRINGS(tradebot,unmonitor,exchange,base,rel); THREE_STRINGS_AND_THREE_DOUBLES(tradebot,accumulate,exchange,base,rel,pr ice,volume,duration); THREE_STRINGS_AND_THREE_DOUBLES(tradebot,divest,exchange,base,rel,price, volume,duration); STRING_ARG(tradebot,activebots,exchange); TWO_STRINGS(tradebot,status,exchange,botid); TWO_STRINGS(tradebot,pause,exchange,botid); TWO_STRINGS(tradebot,stop,exchange,botid); TWO_STRINGS(tradebot,resume,exchange,botid); the above are API for exchange specific bots, most should be self-explanatory. bots are created via &#34;accumulate&#34; or &#34;divest&#34; API call. it returns botid. once created, you can do status, pause, stop, resume to a botid. and an activebots API call lists all the active bots for an exchange. duration is in seconds the &#34;monitor&#34; API starts background monitoring of a specific base/rel, &#34;unmonitor&#34; stops this. &#34;monitorall&#34; just does a monitor to the entire list of &#34;allpairs&#34; for that exchange. Keep in mind that doing a monitorall will not add load to an exchange as the request to each exchange is governed by pollgap, but if you have 3 things monitored, it will take 3*pollgap + time each one takes to execute. and if N are monitored it is N*pollgap + time of each, with the &#34;time of each&#34; possibly taking a very long time. And one final request for today: Bitmap tab. It should be an active bitmap using mouse api. either a dropdown to select the bitmap or a form entry. then the rest of the page (resize the bitmap to the page size) being the active bitmap. So on a small screen the bitmap is smaller x/y dimensions and larger on larger screens. plz make sure the proper dimensions are communicated to the pexe via API if it ever is changed. @vineet.bhargav86: I changed the &#34;passphrase&#34; fieldname to &#34;password&#34; for the encryptjson/decryptjson related API. The reason is that the password is like a wallet password and is only local, so it doesnt need to be as high entropy as passphrase. I also added a field to the login API as I realized that the 12 word &#34;passphrase&#34; is the payload and usually wont be sent in: FOUR_STRINGS(SuperNET,login,handle,password,permanentfile,passphrase); using &#34;abiglongpassword&#34; for the passphrase -&gt; {&#34;pubkey&#34;:&#34;6c469ba10b40b3eb9d1dba569d7f929d55a29d8f97cd5425907ef2f38f906 209&#34;,&#34;RS&#34;:&#34;NXT-KGV9-DXX8-TM86-DXR96&#34;,&#34;NXT&#34;:&#34;12834974574569896807&#34;,&#34;btcpu bkey&#34;:&#34;024e7641dc947b211bc30fe3339765258902794687b227121fc217284f9d8503c 8&#34;,&#34;rmd160&#34;:&#34;33453c24914db7b77069b7ea24df44f6be145938&#34;,&#34;BTC&#34;:&#34;15g6QK2dSd iW9ZTQEnnJxKrSph6uP7uU23&#34;,&#34;BTCD&#34;:&#34;RDxHUpuv3TX5DZpbhxmS3rBeaxZW1fvYvC&#34;,&#34;r esult&#34;:&#34;success&#34;,&#34;handle&#34;:&#34;test&#34;,&#34;tag&#34;:&#34;14805226009240621255&#34;} and if you use that to log into NXT, it gives the same address. The BTC and BTCD addresses are all derived from the same privkey so they are all interchangeable with the NXT address. The user can therefore select which coin&#39;s addressing they are most comfortable with I also added an &#34;allin&#34; action API for pangea. all the action API will autocalculate the number of chips if passed in 0 for numchips ***************** security issue ******** please dont use the GET URL method when dealing with passphrase!!! Those URL&#39;s tend to get logged and available in browser histories. so anything dealing with the actual passphrase needs to use the postCall form or POST
9 years ago
if ( remoteaddr != 0 )
return(clonestr("{\"error\":\"no remote\"}"));
9 years ago
memset(zero.bytes,0,sizeof(zero));
return(SuperNET_decipher(IGUANA_CALLARGS,privkey,zero,cipherstr));
}
ZERO_ARGS(SuperNET,stop)
{
if ( remoteaddr == 0 || strncmp(remoteaddr,"127.0.0.1",strlen("127.0.0.1")) == 0 )
{
iguana_exit();
return(clonestr("{\"result\":\"exit started\"}"));
} else return(clonestr("{\"error\":\"cant do a remote stop of this node\"}"));
}
TWO_ARRAYS(SuperNET,mypeers,supernet,rawpeers)
{
SuperNET_parsepeers(myinfo,supernet,cJSON_GetArraySize(supernet),1);
SuperNET_parsepeers(myinfo,rawpeers,cJSON_GetArraySize(rawpeers),0);
return(clonestr("{\"result\":\"peers parsed\"}"));
}
STRING_ARG(SuperNET,getpeers,activecoin)
{
int32_t i,max = 64;
cJSON *SNjson,*rawjson,*retjson = cJSON_CreateObject();
SNjson = cJSON_CreateArray();
rawjson = cJSON_CreateArray();
if ( coin != 0 )
max = SuperNET_coinpeers(coin,SNjson,rawjson,max);
else
{
for (i=0; i<IGUANA_MAXCOINS&&max>0; i++)
if ( Coins[i] != 0 )
max = SuperNET_coinpeers(Coins[i],SNjson,rawjson,max);
}
if ( max != 64 )
{
jaddstr(retjson,"agent","SuperNET");
jaddstr(retjson,"method","mypeers");
jadd(retjson,"supernet",SNjson);
jadd(retjson,"rawpeers",rawjson);
}
else
{
jaddstr(retjson,"error","no peers");
free_json(SNjson);
free_json(rawjson);
}
return(jprint(retjson,1));
}
TWOSTRINGS_AND_TWOHASHES_AND_TWOINTS(SuperNET,DHT,hexmsg,destip,categoryhash,subhash,maxdelay,broadcast)
9 years ago
{
if ( remoteaddr != 0 )
return(clonestr("{\"error\":\"cant remote DHT\"}"));
9 years ago
else if ( hexmsg == 0 || is_hexstr(hexmsg,(int32_t)strlen(hexmsg)) <= 0 )
return(clonestr("{\"error\":\"hexmsg missing or not in hex\"}"));
return(SuperNET_DHTencode(myinfo,destip,categoryhash,subhash,hexmsg,maxdelay,broadcast,juint(json,"plaintext")!=0));
9 years ago
}
HASH_AND_STRING(SuperNET,saveconf,wallethash,confjsonstr)
{
many changes blockexplorer tab: needs to allow to input height, blockhash or txid. also please display images/BTC_blocks.jpg below the text as a w800 x h400 bitmap, which is active using the mouse api for coin management, below the active coins have a form that arbitrary json can be input with an add button to the right that will call &#34;addcoin&#34; API. this way I can test adding new coins dynamically. dont worry if it doesnt work, just as long as it submits the json to the C code. I am pretty sure I need to do some debugging of this peers management is not working for me at all. maybe it is due to bad internet. On initialization you need to read in the confs/BTCD_peers.txt from the native filesystem and save it into the chrome app filesystem. same thing for confs/BTCD_hdrs.txt. But this is only to be done if there isnt already such a file inside chrome. if there is, only do it upon a button invoked by the user. the reason is that the pexe is updating this file with the latest. Maybe it is nice to have an &#34;extract&#34; button that will copy out from the chrome storage into the native filesystem. There is also the manifest issue about localstorage vs chrome.localstorage. not sure what is needed to be done, but certainly a priority to get it so everything works as a chrome app. I know before it was making ramchain files inside the chrome filesystem, so it is probably things the GUI is doing. maybe in the settings tab, which has obsolete stuff that can be removed. anyway, the issue about files existing in the native filesystem -&gt; chrome and optionally extracting them is an issue for the confs files and .html template files used to autogenerate the port7778, maybe other files are affected. i think we need a way to have a list of hardcoded files that are just copied into chrome on startup if they dont exist already (or if possible copy over if the native version is bigger?) and buttons to extract them for debug tab: THREE_STRINGS(SuperNET,encryptjson,passphrase,permanentfile,anything); TWO_STRINGS(SuperNET,decryptjson,passphrase,permanentfile); at the top of page a way to put in passphrase and optional permanentfile along with arbitrary json. The standard form template has no easy way to describe to pass in everything as it is oriented to specific fields. but the encryptjson API saves all the fields, so the arbitrary json from the form needs to be combined at the same level as the &#34;agent&#34;, &#34;method&#34;, etc. I know, not the best, but internally it makes it easier. so {&#34;agent&#34;:&#34;SuperNET&#34;,&#34;method&#34;:&#34;encryptjson&#34;,&#34;passphrase&#34;:&#34;&lt;passphrase&gt;&#34;,&#34; permanentfile&#34;:&#34;&lt;filename&gt;&#34;,&#34;fromform&#34;:&#34;valuefromform&#34;,&#34;fromform2&#34;:&#34;valu efromform2&#34;,...rest of form at top level} then this will save it into a file with crazy number (it is a hash like txid) but given the same passphrase and filename, it will regenerate this hash so you dont actually have to store it, but it helps during debugging. for the filename, we must warn quite strongly to the user that if the file is ever lost or even changed in any way that the data will not be recoverable. also best to not allow the user to specify a file that does not exist. I think at this point chrome app version gets a bit tricky. we could simply push the native file into the chrome storage, but then an attacker who gets access to the computer could just get a list of these files and it really wont be much protection. So that means if a filename is specified, it needs to be copied into the chrome space, then immediately deleted... ok, this seems like not a good approach. let us make it so that the permanentfile option is not available from the chrome app, but only if the native version is running. that way we sidestep the issue of the pexe not having access to the specified file. Speaking of native vs pexe, on the startup page we should have a radio button that allows the user to select which the GUI will talk to. It should default based on a self test to the more likely value, but it is possible that the user wants to use the native version, even if the pexe is running. another thing to have on the startup page is a simple login: THREE_STRINGS(SuperNET,login,passphrase,permanentfile,handle); ZERO_ARGS(SuperNET,logout); ZERO_ARGS(SuperNET,activehandle); the handle is a human readable name that is associated with the passphrase/permanentfile. There can only be one active account (though it will be possible to associate different accounts with tradebots). use the activehandle API to find out who is logged in and the associated addresses and pubkeys The above is not yet tested so if it doesnt work, dont fret, just let me know. Once set the handle can be displayed in various places to let the user know which account is logged in. The standard 12 dictionary word passphrases should be used, but any string can be sent in as the password for Pangea: INT_AND_ARRAY(pangea,host,minplayers,params); ZERO_ARGS(pangea,lobby); HASH_AND_STRING(pangea,join,tablehash,handle); HASH_AND_INT(pangea,buyin,tablehash,numchips); HASH_ARG(pangea,start,tablehash); // by host only HASH_ARG(pangea,status,tablehash); HASH_ARG(pangea,call,tablehash); HASH_ARG(pangea,check,tablehash); HASH_AND_INT(pangea,raise,tablehash,numchips); HASH_AND_INT(pangea,bet,tablehash,numchips); HASH_ARG(pangea,fold,tablehash); HASH_AND_STRING(pangea,mode,tablehash,modestr); HASH_ARG(pangea,history,tablehash); HASH_AND_INT(pangea,handhistory,tablehash,hand); The first thing that is done is a &#34;host&#34; by any node. the &#34;params&#34; should be an arbitrary json (like encryptjson) as it needs to be at the top level and it has quite a few different parameters still subject to change. The lobby API will just display all the hosted tables. once a table exists, players can join and then buyin. the buyin is denominated in chips, each chip&#39;s value is determined by the host&#39;s initial parameters. once there are enough players joined with adequate buyin&#39;s verified, the host will be able to do a start. if done before it will (eventually) give an error. for now it will just proceed. The host and players that have joined a tablehash, need to do regular status calls to see if the game has started. Probably just once per 5 or even 10 seconds is fine before the start. Once the game starts (the status will have this info) then once per second polling is needed. Then when it is your turn (as indicated by status) you need to do one of the 5 actions (fold, call, check, raise, bet). do not worry if you dont understand what all these do, just allow the user to do any of these. I guess it is possible to submit it ahead of time. I will support internally remembering the most recent action done prior to it being your turn. once it is your turn and an action is sent to the table, it is too late to change. The last API calls are for getting handhistory where hand is 0 to N-1, being the numbering of the hands played at that table. if just history, all the history for all hands at the table is coming back, so it could be quite big. probably I will make it a summary, but for the GUI just display the returned values. the mode is to change some poker specific modes, so just allow there to be a string entered. do not worry about understanding the pokerness of the API, just the overall flow: host -&gt; creates, join/buyin -&gt; fills up player slots, start -&gt; starts the game status -&gt; to determine when the game starts (or if it is cancelled) and once started actions -&gt; game specific but basically just (button + arg) that is the user input results are via status for current game and history for past ones please try to do the above logic in a generic way so it can be reused for other games. The basic flow should be the same for almost all multiplayer turn based games and even for multiplayer realtime games For InstantDEX: on the apikeypair/userid there needs to be two modes. one for when there is no stored apikey and the current form is fine, just need to make it wider as most apikeys are quite long. Now once there is an apikey saved all that is needed is the passphrase to unlock it. So here is where the encrptjson/decryptjson is used. When saving the apikey for the first time, it can be: a) not saved -&gt; nothing extra to do b) saved without password -&gt; you can just save to a file and use it to load it back in. use confs dir confs/instantdex.exchange.api or something like that c) saved with password (optional filename for native) -&gt; probably best to save in the confs dir to indicate that there is an encrypted file for this, so just that and not the actual passphrase in the file with the above, when the exchange is selected, you can see if the confs file exists and if it has the plaintext, just populate the field, if not, then indicate that a passphrase is needed. if the user provides the passphrase, then decryptjson and populate the fields and autosubmit. A special case is to encrypt the apikeys with the passphrase used when logging in. This is only available if the checkbox to &#34;remember passphrase during session&#34; is set on the main iguana login screen. (i forgot to mention that checkbox!) So the login passphrase is stored in memory, then the GUI simply uses that + encryptjson for storing/decrypting. I would imagine that storing in the confs file that it is encrypted using &#34;handle&#34;&#39;s account login might be a good way to differentiate between this mode of password usage. OK, so we now have the insecure plaintext, the decent using handle&#39;s passphrase and paranoid different passphrase for each exchange (with additional permanentfile for native versions) &#34;SUPPORT&#34; -&gt; &#34;SUPPORTS&#34; just a typo and &#34;allpairs&#34; API is missing from the selection Might as well add a &#34;tradebots&#34; tab: THREE_STRINGS_AND_DOUBLE(tradebot,monitor,exchange,base,rel,commission); STRING_AND_DOUBLE(tradebot,monitorall,exchange,commission); THREE_STRINGS(tradebot,unmonitor,exchange,base,rel); THREE_STRINGS_AND_THREE_DOUBLES(tradebot,accumulate,exchange,base,rel,pr ice,volume,duration); THREE_STRINGS_AND_THREE_DOUBLES(tradebot,divest,exchange,base,rel,price, volume,duration); STRING_ARG(tradebot,activebots,exchange); TWO_STRINGS(tradebot,status,exchange,botid); TWO_STRINGS(tradebot,pause,exchange,botid); TWO_STRINGS(tradebot,stop,exchange,botid); TWO_STRINGS(tradebot,resume,exchange,botid); the above are API for exchange specific bots, most should be self-explanatory. bots are created via &#34;accumulate&#34; or &#34;divest&#34; API call. it returns botid. once created, you can do status, pause, stop, resume to a botid. and an activebots API call lists all the active bots for an exchange. duration is in seconds the &#34;monitor&#34; API starts background monitoring of a specific base/rel, &#34;unmonitor&#34; stops this. &#34;monitorall&#34; just does a monitor to the entire list of &#34;allpairs&#34; for that exchange. Keep in mind that doing a monitorall will not add load to an exchange as the request to each exchange is governed by pollgap, but if you have 3 things monitored, it will take 3*pollgap + time each one takes to execute. and if N are monitored it is N*pollgap + time of each, with the &#34;time of each&#34; possibly taking a very long time. And one final request for today: Bitmap tab. It should be an active bitmap using mouse api. either a dropdown to select the bitmap or a form entry. then the rest of the page (resize the bitmap to the page size) being the active bitmap. So on a small screen the bitmap is smaller x/y dimensions and larger on larger screens. plz make sure the proper dimensions are communicated to the pexe via API if it ever is changed. @vineet.bhargav86: I changed the &#34;passphrase&#34; fieldname to &#34;password&#34; for the encryptjson/decryptjson related API. The reason is that the password is like a wallet password and is only local, so it doesnt need to be as high entropy as passphrase. I also added a field to the login API as I realized that the 12 word &#34;passphrase&#34; is the payload and usually wont be sent in: FOUR_STRINGS(SuperNET,login,handle,password,permanentfile,passphrase); using &#34;abiglongpassword&#34; for the passphrase -&gt; {&#34;pubkey&#34;:&#34;6c469ba10b40b3eb9d1dba569d7f929d55a29d8f97cd5425907ef2f38f906 209&#34;,&#34;RS&#34;:&#34;NXT-KGV9-DXX8-TM86-DXR96&#34;,&#34;NXT&#34;:&#34;12834974574569896807&#34;,&#34;btcpu bkey&#34;:&#34;024e7641dc947b211bc30fe3339765258902794687b227121fc217284f9d8503c 8&#34;,&#34;rmd160&#34;:&#34;33453c24914db7b77069b7ea24df44f6be145938&#34;,&#34;BTC&#34;:&#34;15g6QK2dSd iW9ZTQEnnJxKrSph6uP7uU23&#34;,&#34;BTCD&#34;:&#34;RDxHUpuv3TX5DZpbhxmS3rBeaxZW1fvYvC&#34;,&#34;r esult&#34;:&#34;success&#34;,&#34;handle&#34;:&#34;test&#34;,&#34;tag&#34;:&#34;14805226009240621255&#34;} and if you use that to log into NXT, it gives the same address. The BTC and BTCD addresses are all derived from the same privkey so they are all interchangeable with the NXT address. The user can therefore select which coin&#39;s addressing they are most comfortable with I also added an &#34;allin&#34; action API for pangea. all the action API will autocalculate the number of chips if passed in 0 for numchips ***************** security issue ******** please dont use the GET URL method when dealing with passphrase!!! Those URL&#39;s tend to get logged and available in browser histories. so anything dealing with the actual passphrase needs to use the postCall form or POST
9 years ago
if ( remoteaddr != 0 )
return(clonestr("{\"error\":\"no remote\"}"));
9 years ago
return(clonestr("{\"result\":\"saveconf here\"}"));
}
HASH_ARRAY_STRING(SuperNET,layer,mypriv,otherpubs,str)
{
many changes blockexplorer tab: needs to allow to input height, blockhash or txid. also please display images/BTC_blocks.jpg below the text as a w800 x h400 bitmap, which is active using the mouse api for coin management, below the active coins have a form that arbitrary json can be input with an add button to the right that will call &#34;addcoin&#34; API. this way I can test adding new coins dynamically. dont worry if it doesnt work, just as long as it submits the json to the C code. I am pretty sure I need to do some debugging of this peers management is not working for me at all. maybe it is due to bad internet. On initialization you need to read in the confs/BTCD_peers.txt from the native filesystem and save it into the chrome app filesystem. same thing for confs/BTCD_hdrs.txt. But this is only to be done if there isnt already such a file inside chrome. if there is, only do it upon a button invoked by the user. the reason is that the pexe is updating this file with the latest. Maybe it is nice to have an &#34;extract&#34; button that will copy out from the chrome storage into the native filesystem. There is also the manifest issue about localstorage vs chrome.localstorage. not sure what is needed to be done, but certainly a priority to get it so everything works as a chrome app. I know before it was making ramchain files inside the chrome filesystem, so it is probably things the GUI is doing. maybe in the settings tab, which has obsolete stuff that can be removed. anyway, the issue about files existing in the native filesystem -&gt; chrome and optionally extracting them is an issue for the confs files and .html template files used to autogenerate the port7778, maybe other files are affected. i think we need a way to have a list of hardcoded files that are just copied into chrome on startup if they dont exist already (or if possible copy over if the native version is bigger?) and buttons to extract them for debug tab: THREE_STRINGS(SuperNET,encryptjson,passphrase,permanentfile,anything); TWO_STRINGS(SuperNET,decryptjson,passphrase,permanentfile); at the top of page a way to put in passphrase and optional permanentfile along with arbitrary json. The standard form template has no easy way to describe to pass in everything as it is oriented to specific fields. but the encryptjson API saves all the fields, so the arbitrary json from the form needs to be combined at the same level as the &#34;agent&#34;, &#34;method&#34;, etc. I know, not the best, but internally it makes it easier. so {&#34;agent&#34;:&#34;SuperNET&#34;,&#34;method&#34;:&#34;encryptjson&#34;,&#34;passphrase&#34;:&#34;&lt;passphrase&gt;&#34;,&#34; permanentfile&#34;:&#34;&lt;filename&gt;&#34;,&#34;fromform&#34;:&#34;valuefromform&#34;,&#34;fromform2&#34;:&#34;valu efromform2&#34;,...rest of form at top level} then this will save it into a file with crazy number (it is a hash like txid) but given the same passphrase and filename, it will regenerate this hash so you dont actually have to store it, but it helps during debugging. for the filename, we must warn quite strongly to the user that if the file is ever lost or even changed in any way that the data will not be recoverable. also best to not allow the user to specify a file that does not exist. I think at this point chrome app version gets a bit tricky. we could simply push the native file into the chrome storage, but then an attacker who gets access to the computer could just get a list of these files and it really wont be much protection. So that means if a filename is specified, it needs to be copied into the chrome space, then immediately deleted... ok, this seems like not a good approach. let us make it so that the permanentfile option is not available from the chrome app, but only if the native version is running. that way we sidestep the issue of the pexe not having access to the specified file. Speaking of native vs pexe, on the startup page we should have a radio button that allows the user to select which the GUI will talk to. It should default based on a self test to the more likely value, but it is possible that the user wants to use the native version, even if the pexe is running. another thing to have on the startup page is a simple login: THREE_STRINGS(SuperNET,login,passphrase,permanentfile,handle); ZERO_ARGS(SuperNET,logout); ZERO_ARGS(SuperNET,activehandle); the handle is a human readable name that is associated with the passphrase/permanentfile. There can only be one active account (though it will be possible to associate different accounts with tradebots). use the activehandle API to find out who is logged in and the associated addresses and pubkeys The above is not yet tested so if it doesnt work, dont fret, just let me know. Once set the handle can be displayed in various places to let the user know which account is logged in. The standard 12 dictionary word passphrases should be used, but any string can be sent in as the password for Pangea: INT_AND_ARRAY(pangea,host,minplayers,params); ZERO_ARGS(pangea,lobby); HASH_AND_STRING(pangea,join,tablehash,handle); HASH_AND_INT(pangea,buyin,tablehash,numchips); HASH_ARG(pangea,start,tablehash); // by host only HASH_ARG(pangea,status,tablehash); HASH_ARG(pangea,call,tablehash); HASH_ARG(pangea,check,tablehash); HASH_AND_INT(pangea,raise,tablehash,numchips); HASH_AND_INT(pangea,bet,tablehash,numchips); HASH_ARG(pangea,fold,tablehash); HASH_AND_STRING(pangea,mode,tablehash,modestr); HASH_ARG(pangea,history,tablehash); HASH_AND_INT(pangea,handhistory,tablehash,hand); The first thing that is done is a &#34;host&#34; by any node. the &#34;params&#34; should be an arbitrary json (like encryptjson) as it needs to be at the top level and it has quite a few different parameters still subject to change. The lobby API will just display all the hosted tables. once a table exists, players can join and then buyin. the buyin is denominated in chips, each chip&#39;s value is determined by the host&#39;s initial parameters. once there are enough players joined with adequate buyin&#39;s verified, the host will be able to do a start. if done before it will (eventually) give an error. for now it will just proceed. The host and players that have joined a tablehash, need to do regular status calls to see if the game has started. Probably just once per 5 or even 10 seconds is fine before the start. Once the game starts (the status will have this info) then once per second polling is needed. Then when it is your turn (as indicated by status) you need to do one of the 5 actions (fold, call, check, raise, bet). do not worry if you dont understand what all these do, just allow the user to do any of these. I guess it is possible to submit it ahead of time. I will support internally remembering the most recent action done prior to it being your turn. once it is your turn and an action is sent to the table, it is too late to change. The last API calls are for getting handhistory where hand is 0 to N-1, being the numbering of the hands played at that table. if just history, all the history for all hands at the table is coming back, so it could be quite big. probably I will make it a summary, but for the GUI just display the returned values. the mode is to change some poker specific modes, so just allow there to be a string entered. do not worry about understanding the pokerness of the API, just the overall flow: host -&gt; creates, join/buyin -&gt; fills up player slots, start -&gt; starts the game status -&gt; to determine when the game starts (or if it is cancelled) and once started actions -&gt; game specific but basically just (button + arg) that is the user input results are via status for current game and history for past ones please try to do the above logic in a generic way so it can be reused for other games. The basic flow should be the same for almost all multiplayer turn based games and even for multiplayer realtime games For InstantDEX: on the apikeypair/userid there needs to be two modes. one for when there is no stored apikey and the current form is fine, just need to make it wider as most apikeys are quite long. Now once there is an apikey saved all that is needed is the passphrase to unlock it. So here is where the encrptjson/decryptjson is used. When saving the apikey for the first time, it can be: a) not saved -&gt; nothing extra to do b) saved without password -&gt; you can just save to a file and use it to load it back in. use confs dir confs/instantdex.exchange.api or something like that c) saved with password (optional filename for native) -&gt; probably best to save in the confs dir to indicate that there is an encrypted file for this, so just that and not the actual passphrase in the file with the above, when the exchange is selected, you can see if the confs file exists and if it has the plaintext, just populate the field, if not, then indicate that a passphrase is needed. if the user provides the passphrase, then decryptjson and populate the fields and autosubmit. A special case is to encrypt the apikeys with the passphrase used when logging in. This is only available if the checkbox to &#34;remember passphrase during session&#34; is set on the main iguana login screen. (i forgot to mention that checkbox!) So the login passphrase is stored in memory, then the GUI simply uses that + encryptjson for storing/decrypting. I would imagine that storing in the confs file that it is encrypted using &#34;handle&#34;&#39;s account login might be a good way to differentiate between this mode of password usage. OK, so we now have the insecure plaintext, the decent using handle&#39;s passphrase and paranoid different passphrase for each exchange (with additional permanentfile for native versions) &#34;SUPPORT&#34; -&gt; &#34;SUPPORTS&#34; just a typo and &#34;allpairs&#34; API is missing from the selection Might as well add a &#34;tradebots&#34; tab: THREE_STRINGS_AND_DOUBLE(tradebot,monitor,exchange,base,rel,commission); STRING_AND_DOUBLE(tradebot,monitorall,exchange,commission); THREE_STRINGS(tradebot,unmonitor,exchange,base,rel); THREE_STRINGS_AND_THREE_DOUBLES(tradebot,accumulate,exchange,base,rel,pr ice,volume,duration); THREE_STRINGS_AND_THREE_DOUBLES(tradebot,divest,exchange,base,rel,price, volume,duration); STRING_ARG(tradebot,activebots,exchange); TWO_STRINGS(tradebot,status,exchange,botid); TWO_STRINGS(tradebot,pause,exchange,botid); TWO_STRINGS(tradebot,stop,exchange,botid); TWO_STRINGS(tradebot,resume,exchange,botid); the above are API for exchange specific bots, most should be self-explanatory. bots are created via &#34;accumulate&#34; or &#34;divest&#34; API call. it returns botid. once created, you can do status, pause, stop, resume to a botid. and an activebots API call lists all the active bots for an exchange. duration is in seconds the &#34;monitor&#34; API starts background monitoring of a specific base/rel, &#34;unmonitor&#34; stops this. &#34;monitorall&#34; just does a monitor to the entire list of &#34;allpairs&#34; for that exchange. Keep in mind that doing a monitorall will not add load to an exchange as the request to each exchange is governed by pollgap, but if you have 3 things monitored, it will take 3*pollgap + time each one takes to execute. and if N are monitored it is N*pollgap + time of each, with the &#34;time of each&#34; possibly taking a very long time. And one final request for today: Bitmap tab. It should be an active bitmap using mouse api. either a dropdown to select the bitmap or a form entry. then the rest of the page (resize the bitmap to the page size) being the active bitmap. So on a small screen the bitmap is smaller x/y dimensions and larger on larger screens. plz make sure the proper dimensions are communicated to the pexe via API if it ever is changed. @vineet.bhargav86: I changed the &#34;passphrase&#34; fieldname to &#34;password&#34; for the encryptjson/decryptjson related API. The reason is that the password is like a wallet password and is only local, so it doesnt need to be as high entropy as passphrase. I also added a field to the login API as I realized that the 12 word &#34;passphrase&#34; is the payload and usually wont be sent in: FOUR_STRINGS(SuperNET,login,handle,password,permanentfile,passphrase); using &#34;abiglongpassword&#34; for the passphrase -&gt; {&#34;pubkey&#34;:&#34;6c469ba10b40b3eb9d1dba569d7f929d55a29d8f97cd5425907ef2f38f906 209&#34;,&#34;RS&#34;:&#34;NXT-KGV9-DXX8-TM86-DXR96&#34;,&#34;NXT&#34;:&#34;12834974574569896807&#34;,&#34;btcpu bkey&#34;:&#34;024e7641dc947b211bc30fe3339765258902794687b227121fc217284f9d8503c 8&#34;,&#34;rmd160&#34;:&#34;33453c24914db7b77069b7ea24df44f6be145938&#34;,&#34;BTC&#34;:&#34;15g6QK2dSd iW9ZTQEnnJxKrSph6uP7uU23&#34;,&#34;BTCD&#34;:&#34;RDxHUpuv3TX5DZpbhxmS3rBeaxZW1fvYvC&#34;,&#34;r esult&#34;:&#34;success&#34;,&#34;handle&#34;:&#34;test&#34;,&#34;tag&#34;:&#34;14805226009240621255&#34;} and if you use that to log into NXT, it gives the same address. The BTC and BTCD addresses are all derived from the same privkey so they are all interchangeable with the NXT address. The user can therefore select which coin&#39;s addressing they are most comfortable with I also added an &#34;allin&#34; action API for pangea. all the action API will autocalculate the number of chips if passed in 0 for numchips ***************** security issue ******** please dont use the GET URL method when dealing with passphrase!!! Those URL&#39;s tend to get logged and available in browser histories. so anything dealing with the actual passphrase needs to use the postCall form or POST
9 years ago
if ( remoteaddr != 0 )
return(clonestr("{\"error\":\"no remote\"}"));
9 years ago
return(clonestr("{\"result\":\"layer encrypt here\"}"));
}
9 years ago
TWO_STRINGS(SuperNET,categoryhashes,category,subcategory)
9 years ago
{
9 years ago
bits256 categoryhash,subhash; cJSON *retjson = cJSON_CreateObject();
many changes blockexplorer tab: needs to allow to input height, blockhash or txid. also please display images/BTC_blocks.jpg below the text as a w800 x h400 bitmap, which is active using the mouse api for coin management, below the active coins have a form that arbitrary json can be input with an add button to the right that will call &#34;addcoin&#34; API. this way I can test adding new coins dynamically. dont worry if it doesnt work, just as long as it submits the json to the C code. I am pretty sure I need to do some debugging of this peers management is not working for me at all. maybe it is due to bad internet. On initialization you need to read in the confs/BTCD_peers.txt from the native filesystem and save it into the chrome app filesystem. same thing for confs/BTCD_hdrs.txt. But this is only to be done if there isnt already such a file inside chrome. if there is, only do it upon a button invoked by the user. the reason is that the pexe is updating this file with the latest. Maybe it is nice to have an &#34;extract&#34; button that will copy out from the chrome storage into the native filesystem. There is also the manifest issue about localstorage vs chrome.localstorage. not sure what is needed to be done, but certainly a priority to get it so everything works as a chrome app. I know before it was making ramchain files inside the chrome filesystem, so it is probably things the GUI is doing. maybe in the settings tab, which has obsolete stuff that can be removed. anyway, the issue about files existing in the native filesystem -&gt; chrome and optionally extracting them is an issue for the confs files and .html template files used to autogenerate the port7778, maybe other files are affected. i think we need a way to have a list of hardcoded files that are just copied into chrome on startup if they dont exist already (or if possible copy over if the native version is bigger?) and buttons to extract them for debug tab: THREE_STRINGS(SuperNET,encryptjson,passphrase,permanentfile,anything); TWO_STRINGS(SuperNET,decryptjson,passphrase,permanentfile); at the top of page a way to put in passphrase and optional permanentfile along with arbitrary json. The standard form template has no easy way to describe to pass in everything as it is oriented to specific fields. but the encryptjson API saves all the fields, so the arbitrary json from the form needs to be combined at the same level as the &#34;agent&#34;, &#34;method&#34;, etc. I know, not the best, but internally it makes it easier. so {&#34;agent&#34;:&#34;SuperNET&#34;,&#34;method&#34;:&#34;encryptjson&#34;,&#34;passphrase&#34;:&#34;&lt;passphrase&gt;&#34;,&#34; permanentfile&#34;:&#34;&lt;filename&gt;&#34;,&#34;fromform&#34;:&#34;valuefromform&#34;,&#34;fromform2&#34;:&#34;valu efromform2&#34;,...rest of form at top level} then this will save it into a file with crazy number (it is a hash like txid) but given the same passphrase and filename, it will regenerate this hash so you dont actually have to store it, but it helps during debugging. for the filename, we must warn quite strongly to the user that if the file is ever lost or even changed in any way that the data will not be recoverable. also best to not allow the user to specify a file that does not exist. I think at this point chrome app version gets a bit tricky. we could simply push the native file into the chrome storage, but then an attacker who gets access to the computer could just get a list of these files and it really wont be much protection. So that means if a filename is specified, it needs to be copied into the chrome space, then immediately deleted... ok, this seems like not a good approach. let us make it so that the permanentfile option is not available from the chrome app, but only if the native version is running. that way we sidestep the issue of the pexe not having access to the specified file. Speaking of native vs pexe, on the startup page we should have a radio button that allows the user to select which the GUI will talk to. It should default based on a self test to the more likely value, but it is possible that the user wants to use the native version, even if the pexe is running. another thing to have on the startup page is a simple login: THREE_STRINGS(SuperNET,login,passphrase,permanentfile,handle); ZERO_ARGS(SuperNET,logout); ZERO_ARGS(SuperNET,activehandle); the handle is a human readable name that is associated with the passphrase/permanentfile. There can only be one active account (though it will be possible to associate different accounts with tradebots). use the activehandle API to find out who is logged in and the associated addresses and pubkeys The above is not yet tested so if it doesnt work, dont fret, just let me know. Once set the handle can be displayed in various places to let the user know which account is logged in. The standard 12 dictionary word passphrases should be used, but any string can be sent in as the password for Pangea: INT_AND_ARRAY(pangea,host,minplayers,params); ZERO_ARGS(pangea,lobby); HASH_AND_STRING(pangea,join,tablehash,handle); HASH_AND_INT(pangea,buyin,tablehash,numchips); HASH_ARG(pangea,start,tablehash); // by host only HASH_ARG(pangea,status,tablehash); HASH_ARG(pangea,call,tablehash); HASH_ARG(pangea,check,tablehash); HASH_AND_INT(pangea,raise,tablehash,numchips); HASH_AND_INT(pangea,bet,tablehash,numchips); HASH_ARG(pangea,fold,tablehash); HASH_AND_STRING(pangea,mode,tablehash,modestr); HASH_ARG(pangea,history,tablehash); HASH_AND_INT(pangea,handhistory,tablehash,hand); The first thing that is done is a &#34;host&#34; by any node. the &#34;params&#34; should be an arbitrary json (like encryptjson) as it needs to be at the top level and it has quite a few different parameters still subject to change. The lobby API will just display all the hosted tables. once a table exists, players can join and then buyin. the buyin is denominated in chips, each chip&#39;s value is determined by the host&#39;s initial parameters. once there are enough players joined with adequate buyin&#39;s verified, the host will be able to do a start. if done before it will (eventually) give an error. for now it will just proceed. The host and players that have joined a tablehash, need to do regular status calls to see if the game has started. Probably just once per 5 or even 10 seconds is fine before the start. Once the game starts (the status will have this info) then once per second polling is needed. Then when it is your turn (as indicated by status) you need to do one of the 5 actions (fold, call, check, raise, bet). do not worry if you dont understand what all these do, just allow the user to do any of these. I guess it is possible to submit it ahead of time. I will support internally remembering the most recent action done prior to it being your turn. once it is your turn and an action is sent to the table, it is too late to change. The last API calls are for getting handhistory where hand is 0 to N-1, being the numbering of the hands played at that table. if just history, all the history for all hands at the table is coming back, so it could be quite big. probably I will make it a summary, but for the GUI just display the returned values. the mode is to change some poker specific modes, so just allow there to be a string entered. do not worry about understanding the pokerness of the API, just the overall flow: host -&gt; creates, join/buyin -&gt; fills up player slots, start -&gt; starts the game status -&gt; to determine when the game starts (or if it is cancelled) and once started actions -&gt; game specific but basically just (button + arg) that is the user input results are via status for current game and history for past ones please try to do the above logic in a generic way so it can be reused for other games. The basic flow should be the same for almost all multiplayer turn based games and even for multiplayer realtime games For InstantDEX: on the apikeypair/userid there needs to be two modes. one for when there is no stored apikey and the current form is fine, just need to make it wider as most apikeys are quite long. Now once there is an apikey saved all that is needed is the passphrase to unlock it. So here is where the encrptjson/decryptjson is used. When saving the apikey for the first time, it can be: a) not saved -&gt; nothing extra to do b) saved without password -&gt; you can just save to a file and use it to load it back in. use confs dir confs/instantdex.exchange.api or something like that c) saved with password (optional filename for native) -&gt; probably best to save in the confs dir to indicate that there is an encrypted file for this, so just that and not the actual passphrase in the file with the above, when the exchange is selected, you can see if the confs file exists and if it has the plaintext, just populate the field, if not, then indicate that a passphrase is needed. if the user provides the passphrase, then decryptjson and populate the fields and autosubmit. A special case is to encrypt the apikeys with the passphrase used when logging in. This is only available if the checkbox to &#34;remember passphrase during session&#34; is set on the main iguana login screen. (i forgot to mention that checkbox!) So the login passphrase is stored in memory, then the GUI simply uses that + encryptjson for storing/decrypting. I would imagine that storing in the confs file that it is encrypted using &#34;handle&#34;&#39;s account login might be a good way to differentiate between this mode of password usage. OK, so we now have the insecure plaintext, the decent using handle&#39;s passphrase and paranoid different passphrase for each exchange (with additional permanentfile for native versions) &#34;SUPPORT&#34; -&gt; &#34;SUPPORTS&#34; just a typo and &#34;allpairs&#34; API is missing from the selection Might as well add a &#34;tradebots&#34; tab: THREE_STRINGS_AND_DOUBLE(tradebot,monitor,exchange,base,rel,commission); STRING_AND_DOUBLE(tradebot,monitorall,exchange,commission); THREE_STRINGS(tradebot,unmonitor,exchange,base,rel); THREE_STRINGS_AND_THREE_DOUBLES(tradebot,accumulate,exchange,base,rel,pr ice,volume,duration); THREE_STRINGS_AND_THREE_DOUBLES(tradebot,divest,exchange,base,rel,price, volume,duration); STRING_ARG(tradebot,activebots,exchange); TWO_STRINGS(tradebot,status,exchange,botid); TWO_STRINGS(tradebot,pause,exchange,botid); TWO_STRINGS(tradebot,stop,exchange,botid); TWO_STRINGS(tradebot,resume,exchange,botid); the above are API for exchange specific bots, most should be self-explanatory. bots are created via &#34;accumulate&#34; or &#34;divest&#34; API call. it returns botid. once created, you can do status, pause, stop, resume to a botid. and an activebots API call lists all the active bots for an exchange. duration is in seconds the &#34;monitor&#34; API starts background monitoring of a specific base/rel, &#34;unmonitor&#34; stops this. &#34;monitorall&#34; just does a monitor to the entire list of &#34;allpairs&#34; for that exchange. Keep in mind that doing a monitorall will not add load to an exchange as the request to each exchange is governed by pollgap, but if you have 3 things monitored, it will take 3*pollgap + time each one takes to execute. and if N are monitored it is N*pollgap + time of each, with the &#34;time of each&#34; possibly taking a very long time. And one final request for today: Bitmap tab. It should be an active bitmap using mouse api. either a dropdown to select the bitmap or a form entry. then the rest of the page (resize the bitmap to the page size) being the active bitmap. So on a small screen the bitmap is smaller x/y dimensions and larger on larger screens. plz make sure the proper dimensions are communicated to the pexe via API if it ever is changed. @vineet.bhargav86: I changed the &#34;passphrase&#34; fieldname to &#34;password&#34; for the encryptjson/decryptjson related API. The reason is that the password is like a wallet password and is only local, so it doesnt need to be as high entropy as passphrase. I also added a field to the login API as I realized that the 12 word &#34;passphrase&#34; is the payload and usually wont be sent in: FOUR_STRINGS(SuperNET,login,handle,password,permanentfile,passphrase); using &#34;abiglongpassword&#34; for the passphrase -&gt; {&#34;pubkey&#34;:&#34;6c469ba10b40b3eb9d1dba569d7f929d55a29d8f97cd5425907ef2f38f906 209&#34;,&#34;RS&#34;:&#34;NXT-KGV9-DXX8-TM86-DXR96&#34;,&#34;NXT&#34;:&#34;12834974574569896807&#34;,&#34;btcpu bkey&#34;:&#34;024e7641dc947b211bc30fe3339765258902794687b227121fc217284f9d8503c 8&#34;,&#34;rmd160&#34;:&#34;33453c24914db7b77069b7ea24df44f6be145938&#34;,&#34;BTC&#34;:&#34;15g6QK2dSd iW9ZTQEnnJxKrSph6uP7uU23&#34;,&#34;BTCD&#34;:&#34;RDxHUpuv3TX5DZpbhxmS3rBeaxZW1fvYvC&#34;,&#34;r esult&#34;:&#34;success&#34;,&#34;handle&#34;:&#34;test&#34;,&#34;tag&#34;:&#34;14805226009240621255&#34;} and if you use that to log into NXT, it gives the same address. The BTC and BTCD addresses are all derived from the same privkey so they are all interchangeable with the NXT address. The user can therefore select which coin&#39;s addressing they are most comfortable with I also added an &#34;allin&#34; action API for pangea. all the action API will autocalculate the number of chips if passed in 0 for numchips ***************** security issue ******** please dont use the GET URL method when dealing with passphrase!!! Those URL&#39;s tend to get logged and available in browser histories. so anything dealing with the actual passphrase needs to use the postCall form or POST
9 years ago
if ( remoteaddr != 0 )
return(clonestr("{\"error\":\"no remote\"}"));
9 years ago
categoryhash = calc_categoryhashes(&subhash,category,subcategory);
jaddstr(retjson,"result","category hashes calculated");
jaddbits256(retjson,"categoryhash",categoryhash);
jaddbits256(retjson,"subhash",subhash);
return(jprint(retjson,1));
9 years ago
}
TWO_STRINGS(SuperNET,subscribe,category,subcategory)
{
bits256 categoryhash,subhash;
many changes blockexplorer tab: needs to allow to input height, blockhash or txid. also please display images/BTC_blocks.jpg below the text as a w800 x h400 bitmap, which is active using the mouse api for coin management, below the active coins have a form that arbitrary json can be input with an add button to the right that will call &#34;addcoin&#34; API. this way I can test adding new coins dynamically. dont worry if it doesnt work, just as long as it submits the json to the C code. I am pretty sure I need to do some debugging of this peers management is not working for me at all. maybe it is due to bad internet. On initialization you need to read in the confs/BTCD_peers.txt from the native filesystem and save it into the chrome app filesystem. same thing for confs/BTCD_hdrs.txt. But this is only to be done if there isnt already such a file inside chrome. if there is, only do it upon a button invoked by the user. the reason is that the pexe is updating this file with the latest. Maybe it is nice to have an &#34;extract&#34; button that will copy out from the chrome storage into the native filesystem. There is also the manifest issue about localstorage vs chrome.localstorage. not sure what is needed to be done, but certainly a priority to get it so everything works as a chrome app. I know before it was making ramchain files inside the chrome filesystem, so it is probably things the GUI is doing. maybe in the settings tab, which has obsolete stuff that can be removed. anyway, the issue about files existing in the native filesystem -&gt; chrome and optionally extracting them is an issue for the confs files and .html template files used to autogenerate the port7778, maybe other files are affected. i think we need a way to have a list of hardcoded files that are just copied into chrome on startup if they dont exist already (or if possible copy over if the native version is bigger?) and buttons to extract them for debug tab: THREE_STRINGS(SuperNET,encryptjson,passphrase,permanentfile,anything); TWO_STRINGS(SuperNET,decryptjson,passphrase,permanentfile); at the top of page a way to put in passphrase and optional permanentfile along with arbitrary json. The standard form template has no easy way to describe to pass in everything as it is oriented to specific fields. but the encryptjson API saves all the fields, so the arbitrary json from the form needs to be combined at the same level as the &#34;agent&#34;, &#34;method&#34;, etc. I know, not the best, but internally it makes it easier. so {&#34;agent&#34;:&#34;SuperNET&#34;,&#34;method&#34;:&#34;encryptjson&#34;,&#34;passphrase&#34;:&#34;&lt;passphrase&gt;&#34;,&#34; permanentfile&#34;:&#34;&lt;filename&gt;&#34;,&#34;fromform&#34;:&#34;valuefromform&#34;,&#34;fromform2&#34;:&#34;valu efromform2&#34;,...rest of form at top level} then this will save it into a file with crazy number (it is a hash like txid) but given the same passphrase and filename, it will regenerate this hash so you dont actually have to store it, but it helps during debugging. for the filename, we must warn quite strongly to the user that if the file is ever lost or even changed in any way that the data will not be recoverable. also best to not allow the user to specify a file that does not exist. I think at this point chrome app version gets a bit tricky. we could simply push the native file into the chrome storage, but then an attacker who gets access to the computer could just get a list of these files and it really wont be much protection. So that means if a filename is specified, it needs to be copied into the chrome space, then immediately deleted... ok, this seems like not a good approach. let us make it so that the permanentfile option is not available from the chrome app, but only if the native version is running. that way we sidestep the issue of the pexe not having access to the specified file. Speaking of native vs pexe, on the startup page we should have a radio button that allows the user to select which the GUI will talk to. It should default based on a self test to the more likely value, but it is possible that the user wants to use the native version, even if the pexe is running. another thing to have on the startup page is a simple login: THREE_STRINGS(SuperNET,login,passphrase,permanentfile,handle); ZERO_ARGS(SuperNET,logout); ZERO_ARGS(SuperNET,activehandle); the handle is a human readable name that is associated with the passphrase/permanentfile. There can only be one active account (though it will be possible to associate different accounts with tradebots). use the activehandle API to find out who is logged in and the associated addresses and pubkeys The above is not yet tested so if it doesnt work, dont fret, just let me know. Once set the handle can be displayed in various places to let the user know which account is logged in. The standard 12 dictionary word passphrases should be used, but any string can be sent in as the password for Pangea: INT_AND_ARRAY(pangea,host,minplayers,params); ZERO_ARGS(pangea,lobby); HASH_AND_STRING(pangea,join,tablehash,handle); HASH_AND_INT(pangea,buyin,tablehash,numchips); HASH_ARG(pangea,start,tablehash); // by host only HASH_ARG(pangea,status,tablehash); HASH_ARG(pangea,call,tablehash); HASH_ARG(pangea,check,tablehash); HASH_AND_INT(pangea,raise,tablehash,numchips); HASH_AND_INT(pangea,bet,tablehash,numchips); HASH_ARG(pangea,fold,tablehash); HASH_AND_STRING(pangea,mode,tablehash,modestr); HASH_ARG(pangea,history,tablehash); HASH_AND_INT(pangea,handhistory,tablehash,hand); The first thing that is done is a &#34;host&#34; by any node. the &#34;params&#34; should be an arbitrary json (like encryptjson) as it needs to be at the top level and it has quite a few different parameters still subject to change. The lobby API will just display all the hosted tables. once a table exists, players can join and then buyin. the buyin is denominated in chips, each chip&#39;s value is determined by the host&#39;s initial parameters. once there are enough players joined with adequate buyin&#39;s verified, the host will be able to do a start. if done before it will (eventually) give an error. for now it will just proceed. The host and players that have joined a tablehash, need to do regular status calls to see if the game has started. Probably just once per 5 or even 10 seconds is fine before the start. Once the game starts (the status will have this info) then once per second polling is needed. Then when it is your turn (as indicated by status) you need to do one of the 5 actions (fold, call, check, raise, bet). do not worry if you dont understand what all these do, just allow the user to do any of these. I guess it is possible to submit it ahead of time. I will support internally remembering the most recent action done prior to it being your turn. once it is your turn and an action is sent to the table, it is too late to change. The last API calls are for getting handhistory where hand is 0 to N-1, being the numbering of the hands played at that table. if just history, all the history for all hands at the table is coming back, so it could be quite big. probably I will make it a summary, but for the GUI just display the returned values. the mode is to change some poker specific modes, so just allow there to be a string entered. do not worry about understanding the pokerness of the API, just the overall flow: host -&gt; creates, join/buyin -&gt; fills up player slots, start -&gt; starts the game status -&gt; to determine when the game starts (or if it is cancelled) and once started actions -&gt; game specific but basically just (button + arg) that is the user input results are via status for current game and history for past ones please try to do the above logic in a generic way so it can be reused for other games. The basic flow should be the same for almost all multiplayer turn based games and even for multiplayer realtime games For InstantDEX: on the apikeypair/userid there needs to be two modes. one for when there is no stored apikey and the current form is fine, just need to make it wider as most apikeys are quite long. Now once there is an apikey saved all that is needed is the passphrase to unlock it. So here is where the encrptjson/decryptjson is used. When saving the apikey for the first time, it can be: a) not saved -&gt; nothing extra to do b) saved without password -&gt; you can just save to a file and use it to load it back in. use confs dir confs/instantdex.exchange.api or something like that c) saved with password (optional filename for native) -&gt; probably best to save in the confs dir to indicate that there is an encrypted file for this, so just that and not the actual passphrase in the file with the above, when the exchange is selected, you can see if the confs file exists and if it has the plaintext, just populate the field, if not, then indicate that a passphrase is needed. if the user provides the passphrase, then decryptjson and populate the fields and autosubmit. A special case is to encrypt the apikeys with the passphrase used when logging in. This is only available if the checkbox to &#34;remember passphrase during session&#34; is set on the main iguana login screen. (i forgot to mention that checkbox!) So the login passphrase is stored in memory, then the GUI simply uses that + encryptjson for storing/decrypting. I would imagine that storing in the confs file that it is encrypted using &#34;handle&#34;&#39;s account login might be a good way to differentiate between this mode of password usage. OK, so we now have the insecure plaintext, the decent using handle&#39;s passphrase and paranoid different passphrase for each exchange (with additional permanentfile for native versions) &#34;SUPPORT&#34; -&gt; &#34;SUPPORTS&#34; just a typo and &#34;allpairs&#34; API is missing from the selection Might as well add a &#34;tradebots&#34; tab: THREE_STRINGS_AND_DOUBLE(tradebot,monitor,exchange,base,rel,commission); STRING_AND_DOUBLE(tradebot,monitorall,exchange,commission); THREE_STRINGS(tradebot,unmonitor,exchange,base,rel); THREE_STRINGS_AND_THREE_DOUBLES(tradebot,accumulate,exchange,base,rel,pr ice,volume,duration); THREE_STRINGS_AND_THREE_DOUBLES(tradebot,divest,exchange,base,rel,price, volume,duration); STRING_ARG(tradebot,activebots,exchange); TWO_STRINGS(tradebot,status,exchange,botid); TWO_STRINGS(tradebot,pause,exchange,botid); TWO_STRINGS(tradebot,stop,exchange,botid); TWO_STRINGS(tradebot,resume,exchange,botid); the above are API for exchange specific bots, most should be self-explanatory. bots are created via &#34;accumulate&#34; or &#34;divest&#34; API call. it returns botid. once created, you can do status, pause, stop, resume to a botid. and an activebots API call lists all the active bots for an exchange. duration is in seconds the &#34;monitor&#34; API starts background monitoring of a specific base/rel, &#34;unmonitor&#34; stops this. &#34;monitorall&#34; just does a monitor to the entire list of &#34;allpairs&#34; for that exchange. Keep in mind that doing a monitorall will not add load to an exchange as the request to each exchange is governed by pollgap, but if you have 3 things monitored, it will take 3*pollgap + time each one takes to execute. and if N are monitored it is N*pollgap + time of each, with the &#34;time of each&#34; possibly taking a very long time. And one final request for today: Bitmap tab. It should be an active bitmap using mouse api. either a dropdown to select the bitmap or a form entry. then the rest of the page (resize the bitmap to the page size) being the active bitmap. So on a small screen the bitmap is smaller x/y dimensions and larger on larger screens. plz make sure the proper dimensions are communicated to the pexe via API if it ever is changed. @vineet.bhargav86: I changed the &#34;passphrase&#34; fieldname to &#34;password&#34; for the encryptjson/decryptjson related API. The reason is that the password is like a wallet password and is only local, so it doesnt need to be as high entropy as passphrase. I also added a field to the login API as I realized that the 12 word &#34;passphrase&#34; is the payload and usually wont be sent in: FOUR_STRINGS(SuperNET,login,handle,password,permanentfile,passphrase); using &#34;abiglongpassword&#34; for the passphrase -&gt; {&#34;pubkey&#34;:&#34;6c469ba10b40b3eb9d1dba569d7f929d55a29d8f97cd5425907ef2f38f906 209&#34;,&#34;RS&#34;:&#34;NXT-KGV9-DXX8-TM86-DXR96&#34;,&#34;NXT&#34;:&#34;12834974574569896807&#34;,&#34;btcpu bkey&#34;:&#34;024e7641dc947b211bc30fe3339765258902794687b227121fc217284f9d8503c 8&#34;,&#34;rmd160&#34;:&#34;33453c24914db7b77069b7ea24df44f6be145938&#34;,&#34;BTC&#34;:&#34;15g6QK2dSd iW9ZTQEnnJxKrSph6uP7uU23&#34;,&#34;BTCD&#34;:&#34;RDxHUpuv3TX5DZpbhxmS3rBeaxZW1fvYvC&#34;,&#34;r esult&#34;:&#34;success&#34;,&#34;handle&#34;:&#34;test&#34;,&#34;tag&#34;:&#34;14805226009240621255&#34;} and if you use that to log into NXT, it gives the same address. The BTC and BTCD addresses are all derived from the same privkey so they are all interchangeable with the NXT address. The user can therefore select which coin&#39;s addressing they are most comfortable with I also added an &#34;allin&#34; action API for pangea. all the action API will autocalculate the number of chips if passed in 0 for numchips ***************** security issue ******** please dont use the GET URL method when dealing with passphrase!!! Those URL&#39;s tend to get logged and available in browser histories. so anything dealing with the actual passphrase needs to use the postCall form or POST
9 years ago
if ( remoteaddr != 0 )
return(clonestr("{\"error\":\"no remote\"}"));
9 years ago
categoryhash = calc_categoryhashes(&subhash,category,subcategory);
9 years ago
if ( category_subscribe(myinfo,categoryhash,subhash) != 0 )
9 years ago
return(clonestr("{\"result\":\"subscribed\"}"));
else return(clonestr("{\"error\":\"couldnt subscribe\"}"));
}
TWO_STRINGS(SuperNET,gethexmsg,category,subcategory)
{
9 years ago
bits256 categoryhash,subhash; struct category_msg *m; char *hexstr; cJSON *retjson; struct category_info *cat;
many changes blockexplorer tab: needs to allow to input height, blockhash or txid. also please display images/BTC_blocks.jpg below the text as a w800 x h400 bitmap, which is active using the mouse api for coin management, below the active coins have a form that arbitrary json can be input with an add button to the right that will call &#34;addcoin&#34; API. this way I can test adding new coins dynamically. dont worry if it doesnt work, just as long as it submits the json to the C code. I am pretty sure I need to do some debugging of this peers management is not working for me at all. maybe it is due to bad internet. On initialization you need to read in the confs/BTCD_peers.txt from the native filesystem and save it into the chrome app filesystem. same thing for confs/BTCD_hdrs.txt. But this is only to be done if there isnt already such a file inside chrome. if there is, only do it upon a button invoked by the user. the reason is that the pexe is updating this file with the latest. Maybe it is nice to have an &#34;extract&#34; button that will copy out from the chrome storage into the native filesystem. There is also the manifest issue about localstorage vs chrome.localstorage. not sure what is needed to be done, but certainly a priority to get it so everything works as a chrome app. I know before it was making ramchain files inside the chrome filesystem, so it is probably things the GUI is doing. maybe in the settings tab, which has obsolete stuff that can be removed. anyway, the issue about files existing in the native filesystem -&gt; chrome and optionally extracting them is an issue for the confs files and .html template files used to autogenerate the port7778, maybe other files are affected. i think we need a way to have a list of hardcoded files that are just copied into chrome on startup if they dont exist already (or if possible copy over if the native version is bigger?) and buttons to extract them for debug tab: THREE_STRINGS(SuperNET,encryptjson,passphrase,permanentfile,anything); TWO_STRINGS(SuperNET,decryptjson,passphrase,permanentfile); at the top of page a way to put in passphrase and optional permanentfile along with arbitrary json. The standard form template has no easy way to describe to pass in everything as it is oriented to specific fields. but the encryptjson API saves all the fields, so the arbitrary json from the form needs to be combined at the same level as the &#34;agent&#34;, &#34;method&#34;, etc. I know, not the best, but internally it makes it easier. so {&#34;agent&#34;:&#34;SuperNET&#34;,&#34;method&#34;:&#34;encryptjson&#34;,&#34;passphrase&#34;:&#34;&lt;passphrase&gt;&#34;,&#34; permanentfile&#34;:&#34;&lt;filename&gt;&#34;,&#34;fromform&#34;:&#34;valuefromform&#34;,&#34;fromform2&#34;:&#34;valu efromform2&#34;,...rest of form at top level} then this will save it into a file with crazy number (it is a hash like txid) but given the same passphrase and filename, it will regenerate this hash so you dont actually have to store it, but it helps during debugging. for the filename, we must warn quite strongly to the user that if the file is ever lost or even changed in any way that the data will not be recoverable. also best to not allow the user to specify a file that does not exist. I think at this point chrome app version gets a bit tricky. we could simply push the native file into the chrome storage, but then an attacker who gets access to the computer could just get a list of these files and it really wont be much protection. So that means if a filename is specified, it needs to be copied into the chrome space, then immediately deleted... ok, this seems like not a good approach. let us make it so that the permanentfile option is not available from the chrome app, but only if the native version is running. that way we sidestep the issue of the pexe not having access to the specified file. Speaking of native vs pexe, on the startup page we should have a radio button that allows the user to select which the GUI will talk to. It should default based on a self test to the more likely value, but it is possible that the user wants to use the native version, even if the pexe is running. another thing to have on the startup page is a simple login: THREE_STRINGS(SuperNET,login,passphrase,permanentfile,handle); ZERO_ARGS(SuperNET,logout); ZERO_ARGS(SuperNET,activehandle); the handle is a human readable name that is associated with the passphrase/permanentfile. There can only be one active account (though it will be possible to associate different accounts with tradebots). use the activehandle API to find out who is logged in and the associated addresses and pubkeys The above is not yet tested so if it doesnt work, dont fret, just let me know. Once set the handle can be displayed in various places to let the user know which account is logged in. The standard 12 dictionary word passphrases should be used, but any string can be sent in as the password for Pangea: INT_AND_ARRAY(pangea,host,minplayers,params); ZERO_ARGS(pangea,lobby); HASH_AND_STRING(pangea,join,tablehash,handle); HASH_AND_INT(pangea,buyin,tablehash,numchips); HASH_ARG(pangea,start,tablehash); // by host only HASH_ARG(pangea,status,tablehash); HASH_ARG(pangea,call,tablehash); HASH_ARG(pangea,check,tablehash); HASH_AND_INT(pangea,raise,tablehash,numchips); HASH_AND_INT(pangea,bet,tablehash,numchips); HASH_ARG(pangea,fold,tablehash); HASH_AND_STRING(pangea,mode,tablehash,modestr); HASH_ARG(pangea,history,tablehash); HASH_AND_INT(pangea,handhistory,tablehash,hand); The first thing that is done is a &#34;host&#34; by any node. the &#34;params&#34; should be an arbitrary json (like encryptjson) as it needs to be at the top level and it has quite a few different parameters still subject to change. The lobby API will just display all the hosted tables. once a table exists, players can join and then buyin. the buyin is denominated in chips, each chip&#39;s value is determined by the host&#39;s initial parameters. once there are enough players joined with adequate buyin&#39;s verified, the host will be able to do a start. if done before it will (eventually) give an error. for now it will just proceed. The host and players that have joined a tablehash, need to do regular status calls to see if the game has started. Probably just once per 5 or even 10 seconds is fine before the start. Once the game starts (the status will have this info) then once per second polling is needed. Then when it is your turn (as indicated by status) you need to do one of the 5 actions (fold, call, check, raise, bet). do not worry if you dont understand what all these do, just allow the user to do any of these. I guess it is possible to submit it ahead of time. I will support internally remembering the most recent action done prior to it being your turn. once it is your turn and an action is sent to the table, it is too late to change. The last API calls are for getting handhistory where hand is 0 to N-1, being the numbering of the hands played at that table. if just history, all the history for all hands at the table is coming back, so it could be quite big. probably I will make it a summary, but for the GUI just display the returned values. the mode is to change some poker specific modes, so just allow there to be a string entered. do not worry about understanding the pokerness of the API, just the overall flow: host -&gt; creates, join/buyin -&gt; fills up player slots, start -&gt; starts the game status -&gt; to determine when the game starts (or if it is cancelled) and once started actions -&gt; game specific but basically just (button + arg) that is the user input results are via status for current game and history for past ones please try to do the above logic in a generic way so it can be reused for other games. The basic flow should be the same for almost all multiplayer turn based games and even for multiplayer realtime games For InstantDEX: on the apikeypair/userid there needs to be two modes. one for when there is no stored apikey and the current form is fine, just need to make it wider as most apikeys are quite long. Now once there is an apikey saved all that is needed is the passphrase to unlock it. So here is where the encrptjson/decryptjson is used. When saving the apikey for the first time, it can be: a) not saved -&gt; nothing extra to do b) saved without password -&gt; you can just save to a file and use it to load it back in. use confs dir confs/instantdex.exchange.api or something like that c) saved with password (optional filename for native) -&gt; probably best to save in the confs dir to indicate that there is an encrypted file for this, so just that and not the actual passphrase in the file with the above, when the exchange is selected, you can see if the confs file exists and if it has the plaintext, just populate the field, if not, then indicate that a passphrase is needed. if the user provides the passphrase, then decryptjson and populate the fields and autosubmit. A special case is to encrypt the apikeys with the passphrase used when logging in. This is only available if the checkbox to &#34;remember passphrase during session&#34; is set on the main iguana login screen. (i forgot to mention that checkbox!) So the login passphrase is stored in memory, then the GUI simply uses that + encryptjson for storing/decrypting. I would imagine that storing in the confs file that it is encrypted using &#34;handle&#34;&#39;s account login might be a good way to differentiate between this mode of password usage. OK, so we now have the insecure plaintext, the decent using handle&#39;s passphrase and paranoid different passphrase for each exchange (with additional permanentfile for native versions) &#34;SUPPORT&#34; -&gt; &#34;SUPPORTS&#34; just a typo and &#34;allpairs&#34; API is missing from the selection Might as well add a &#34;tradebots&#34; tab: THREE_STRINGS_AND_DOUBLE(tradebot,monitor,exchange,base,rel,commission); STRING_AND_DOUBLE(tradebot,monitorall,exchange,commission); THREE_STRINGS(tradebot,unmonitor,exchange,base,rel); THREE_STRINGS_AND_THREE_DOUBLES(tradebot,accumulate,exchange,base,rel,pr ice,volume,duration); THREE_STRINGS_AND_THREE_DOUBLES(tradebot,divest,exchange,base,rel,price, volume,duration); STRING_ARG(tradebot,activebots,exchange); TWO_STRINGS(tradebot,status,exchange,botid); TWO_STRINGS(tradebot,pause,exchange,botid); TWO_STRINGS(tradebot,stop,exchange,botid); TWO_STRINGS(tradebot,resume,exchange,botid); the above are API for exchange specific bots, most should be self-explanatory. bots are created via &#34;accumulate&#34; or &#34;divest&#34; API call. it returns botid. once created, you can do status, pause, stop, resume to a botid. and an activebots API call lists all the active bots for an exchange. duration is in seconds the &#34;monitor&#34; API starts background monitoring of a specific base/rel, &#34;unmonitor&#34; stops this. &#34;monitorall&#34; just does a monitor to the entire list of &#34;allpairs&#34; for that exchange. Keep in mind that doing a monitorall will not add load to an exchange as the request to each exchange is governed by pollgap, but if you have 3 things monitored, it will take 3*pollgap + time each one takes to execute. and if N are monitored it is N*pollgap + time of each, with the &#34;time of each&#34; possibly taking a very long time. And one final request for today: Bitmap tab. It should be an active bitmap using mouse api. either a dropdown to select the bitmap or a form entry. then the rest of the page (resize the bitmap to the page size) being the active bitmap. So on a small screen the bitmap is smaller x/y dimensions and larger on larger screens. plz make sure the proper dimensions are communicated to the pexe via API if it ever is changed. @vineet.bhargav86: I changed the &#34;passphrase&#34; fieldname to &#34;password&#34; for the encryptjson/decryptjson related API. The reason is that the password is like a wallet password and is only local, so it doesnt need to be as high entropy as passphrase. I also added a field to the login API as I realized that the 12 word &#34;passphrase&#34; is the payload and usually wont be sent in: FOUR_STRINGS(SuperNET,login,handle,password,permanentfile,passphrase); using &#34;abiglongpassword&#34; for the passphrase -&gt; {&#34;pubkey&#34;:&#34;6c469ba10b40b3eb9d1dba569d7f929d55a29d8f97cd5425907ef2f38f906 209&#34;,&#34;RS&#34;:&#34;NXT-KGV9-DXX8-TM86-DXR96&#34;,&#34;NXT&#34;:&#34;12834974574569896807&#34;,&#34;btcpu bkey&#34;:&#34;024e7641dc947b211bc30fe3339765258902794687b227121fc217284f9d8503c 8&#34;,&#34;rmd160&#34;:&#34;33453c24914db7b77069b7ea24df44f6be145938&#34;,&#34;BTC&#34;:&#34;15g6QK2dSd iW9ZTQEnnJxKrSph6uP7uU23&#34;,&#34;BTCD&#34;:&#34;RDxHUpuv3TX5DZpbhxmS3rBeaxZW1fvYvC&#34;,&#34;r esult&#34;:&#34;success&#34;,&#34;handle&#34;:&#34;test&#34;,&#34;tag&#34;:&#34;14805226009240621255&#34;} and if you use that to log into NXT, it gives the same address. The BTC and BTCD addresses are all derived from the same privkey so they are all interchangeable with the NXT address. The user can therefore select which coin&#39;s addressing they are most comfortable with I also added an &#34;allin&#34; action API for pangea. all the action API will autocalculate the number of chips if passed in 0 for numchips ***************** security issue ******** please dont use the GET URL method when dealing with passphrase!!! Those URL&#39;s tend to get logged and available in browser histories. so anything dealing with the actual passphrase needs to use the postCall form or POST
9 years ago
if ( remoteaddr != 0 )
return(clonestr("{\"error\":\"no remote\"}"));
9 years ago
categoryhash = calc_categoryhashes(&subhash,category,subcategory);
9 years ago
if ( (m= category_gethexmsg(myinfo,&cat,categoryhash,subhash)) != 0 )
9 years ago
{
hexstr = calloc(1,m->len*2+1);
init_hexbytes_noT(hexstr,m->msg,m->len);
retjson = cJSON_CreateObject();
jaddstr(retjson,"result",hexstr);
free(hexstr);
return(jprint(retjson,1));
} else return(clonestr("{\"result\":\"no message\"}"));
}
THREE_STRINGS(SuperNET,posthexmsg,category,subcategory,hexmsg)
{
bits256 categoryhash,subhash;
many changes blockexplorer tab: needs to allow to input height, blockhash or txid. also please display images/BTC_blocks.jpg below the text as a w800 x h400 bitmap, which is active using the mouse api for coin management, below the active coins have a form that arbitrary json can be input with an add button to the right that will call &#34;addcoin&#34; API. this way I can test adding new coins dynamically. dont worry if it doesnt work, just as long as it submits the json to the C code. I am pretty sure I need to do some debugging of this peers management is not working for me at all. maybe it is due to bad internet. On initialization you need to read in the confs/BTCD_peers.txt from the native filesystem and save it into the chrome app filesystem. same thing for confs/BTCD_hdrs.txt. But this is only to be done if there isnt already such a file inside chrome. if there is, only do it upon a button invoked by the user. the reason is that the pexe is updating this file with the latest. Maybe it is nice to have an &#34;extract&#34; button that will copy out from the chrome storage into the native filesystem. There is also the manifest issue about localstorage vs chrome.localstorage. not sure what is needed to be done, but certainly a priority to get it so everything works as a chrome app. I know before it was making ramchain files inside the chrome filesystem, so it is probably things the GUI is doing. maybe in the settings tab, which has obsolete stuff that can be removed. anyway, the issue about files existing in the native filesystem -&gt; chrome and optionally extracting them is an issue for the confs files and .html template files used to autogenerate the port7778, maybe other files are affected. i think we need a way to have a list of hardcoded files that are just copied into chrome on startup if they dont exist already (or if possible copy over if the native version is bigger?) and buttons to extract them for debug tab: THREE_STRINGS(SuperNET,encryptjson,passphrase,permanentfile,anything); TWO_STRINGS(SuperNET,decryptjson,passphrase,permanentfile); at the top of page a way to put in passphrase and optional permanentfile along with arbitrary json. The standard form template has no easy way to describe to pass in everything as it is oriented to specific fields. but the encryptjson API saves all the fields, so the arbitrary json from the form needs to be combined at the same level as the &#34;agent&#34;, &#34;method&#34;, etc. I know, not the best, but internally it makes it easier. so {&#34;agent&#34;:&#34;SuperNET&#34;,&#34;method&#34;:&#34;encryptjson&#34;,&#34;passphrase&#34;:&#34;&lt;passphrase&gt;&#34;,&#34; permanentfile&#34;:&#34;&lt;filename&gt;&#34;,&#34;fromform&#34;:&#34;valuefromform&#34;,&#34;fromform2&#34;:&#34;valu efromform2&#34;,...rest of form at top level} then this will save it into a file with crazy number (it is a hash like txid) but given the same passphrase and filename, it will regenerate this hash so you dont actually have to store it, but it helps during debugging. for the filename, we must warn quite strongly to the user that if the file is ever lost or even changed in any way that the data will not be recoverable. also best to not allow the user to specify a file that does not exist. I think at this point chrome app version gets a bit tricky. we could simply push the native file into the chrome storage, but then an attacker who gets access to the computer could just get a list of these files and it really wont be much protection. So that means if a filename is specified, it needs to be copied into the chrome space, then immediately deleted... ok, this seems like not a good approach. let us make it so that the permanentfile option is not available from the chrome app, but only if the native version is running. that way we sidestep the issue of the pexe not having access to the specified file. Speaking of native vs pexe, on the startup page we should have a radio button that allows the user to select which the GUI will talk to. It should default based on a self test to the more likely value, but it is possible that the user wants to use the native version, even if the pexe is running. another thing to have on the startup page is a simple login: THREE_STRINGS(SuperNET,login,passphrase,permanentfile,handle); ZERO_ARGS(SuperNET,logout); ZERO_ARGS(SuperNET,activehandle); the handle is a human readable name that is associated with the passphrase/permanentfile. There can only be one active account (though it will be possible to associate different accounts with tradebots). use the activehandle API to find out who is logged in and the associated addresses and pubkeys The above is not yet tested so if it doesnt work, dont fret, just let me know. Once set the handle can be displayed in various places to let the user know which account is logged in. The standard 12 dictionary word passphrases should be used, but any string can be sent in as the password for Pangea: INT_AND_ARRAY(pangea,host,minplayers,params); ZERO_ARGS(pangea,lobby); HASH_AND_STRING(pangea,join,tablehash,handle); HASH_AND_INT(pangea,buyin,tablehash,numchips); HASH_ARG(pangea,start,tablehash); // by host only HASH_ARG(pangea,status,tablehash); HASH_ARG(pangea,call,tablehash); HASH_ARG(pangea,check,tablehash); HASH_AND_INT(pangea,raise,tablehash,numchips); HASH_AND_INT(pangea,bet,tablehash,numchips); HASH_ARG(pangea,fold,tablehash); HASH_AND_STRING(pangea,mode,tablehash,modestr); HASH_ARG(pangea,history,tablehash); HASH_AND_INT(pangea,handhistory,tablehash,hand); The first thing that is done is a &#34;host&#34; by any node. the &#34;params&#34; should be an arbitrary json (like encryptjson) as it needs to be at the top level and it has quite a few different parameters still subject to change. The lobby API will just display all the hosted tables. once a table exists, players can join and then buyin. the buyin is denominated in chips, each chip&#39;s value is determined by the host&#39;s initial parameters. once there are enough players joined with adequate buyin&#39;s verified, the host will be able to do a start. if done before it will (eventually) give an error. for now it will just proceed. The host and players that have joined a tablehash, need to do regular status calls to see if the game has started. Probably just once per 5 or even 10 seconds is fine before the start. Once the game starts (the status will have this info) then once per second polling is needed. Then when it is your turn (as indicated by status) you need to do one of the 5 actions (fold, call, check, raise, bet). do not worry if you dont understand what all these do, just allow the user to do any of these. I guess it is possible to submit it ahead of time. I will support internally remembering the most recent action done prior to it being your turn. once it is your turn and an action is sent to the table, it is too late to change. The last API calls are for getting handhistory where hand is 0 to N-1, being the numbering of the hands played at that table. if just history, all the history for all hands at the table is coming back, so it could be quite big. probably I will make it a summary, but for the GUI just display the returned values. the mode is to change some poker specific modes, so just allow there to be a string entered. do not worry about understanding the pokerness of the API, just the overall flow: host -&gt; creates, join/buyin -&gt; fills up player slots, start -&gt; starts the game status -&gt; to determine when the game starts (or if it is cancelled) and once started actions -&gt; game specific but basically just (button + arg) that is the user input results are via status for current game and history for past ones please try to do the above logic in a generic way so it can be reused for other games. The basic flow should be the same for almost all multiplayer turn based games and even for multiplayer realtime games For InstantDEX: on the apikeypair/userid there needs to be two modes. one for when there is no stored apikey and the current form is fine, just need to make it wider as most apikeys are quite long. Now once there is an apikey saved all that is needed is the passphrase to unlock it. So here is where the encrptjson/decryptjson is used. When saving the apikey for the first time, it can be: a) not saved -&gt; nothing extra to do b) saved without password -&gt; you can just save to a file and use it to load it back in. use confs dir confs/instantdex.exchange.api or something like that c) saved with password (optional filename for native) -&gt; probably best to save in the confs dir to indicate that there is an encrypted file for this, so just that and not the actual passphrase in the file with the above, when the exchange is selected, you can see if the confs file exists and if it has the plaintext, just populate the field, if not, then indicate that a passphrase is needed. if the user provides the passphrase, then decryptjson and populate the fields and autosubmit. A special case is to encrypt the apikeys with the passphrase used when logging in. This is only available if the checkbox to &#34;remember passphrase during session&#34; is set on the main iguana login screen. (i forgot to mention that checkbox!) So the login passphrase is stored in memory, then the GUI simply uses that + encryptjson for storing/decrypting. I would imagine that storing in the confs file that it is encrypted using &#34;handle&#34;&#39;s account login might be a good way to differentiate between this mode of password usage. OK, so we now have the insecure plaintext, the decent using handle&#39;s passphrase and paranoid different passphrase for each exchange (with additional permanentfile for native versions) &#34;SUPPORT&#34; -&gt; &#34;SUPPORTS&#34; just a typo and &#34;allpairs&#34; API is missing from the selection Might as well add a &#34;tradebots&#34; tab: THREE_STRINGS_AND_DOUBLE(tradebot,monitor,exchange,base,rel,commission); STRING_AND_DOUBLE(tradebot,monitorall,exchange,commission); THREE_STRINGS(tradebot,unmonitor,exchange,base,rel); THREE_STRINGS_AND_THREE_DOUBLES(tradebot,accumulate,exchange,base,rel,pr ice,volume,duration); THREE_STRINGS_AND_THREE_DOUBLES(tradebot,divest,exchange,base,rel,price, volume,duration); STRING_ARG(tradebot,activebots,exchange); TWO_STRINGS(tradebot,status,exchange,botid); TWO_STRINGS(tradebot,pause,exchange,botid); TWO_STRINGS(tradebot,stop,exchange,botid); TWO_STRINGS(tradebot,resume,exchange,botid); the above are API for exchange specific bots, most should be self-explanatory. bots are created via &#34;accumulate&#34; or &#34;divest&#34; API call. it returns botid. once created, you can do status, pause, stop, resume to a botid. and an activebots API call lists all the active bots for an exchange. duration is in seconds the &#34;monitor&#34; API starts background monitoring of a specific base/rel, &#34;unmonitor&#34; stops this. &#34;monitorall&#34; just does a monitor to the entire list of &#34;allpairs&#34; for that exchange. Keep in mind that doing a monitorall will not add load to an exchange as the request to each exchange is governed by pollgap, but if you have 3 things monitored, it will take 3*pollgap + time each one takes to execute. and if N are monitored it is N*pollgap + time of each, with the &#34;time of each&#34; possibly taking a very long time. And one final request for today: Bitmap tab. It should be an active bitmap using mouse api. either a dropdown to select the bitmap or a form entry. then the rest of the page (resize the bitmap to the page size) being the active bitmap. So on a small screen the bitmap is smaller x/y dimensions and larger on larger screens. plz make sure the proper dimensions are communicated to the pexe via API if it ever is changed. @vineet.bhargav86: I changed the &#34;passphrase&#34; fieldname to &#34;password&#34; for the encryptjson/decryptjson related API. The reason is that the password is like a wallet password and is only local, so it doesnt need to be as high entropy as passphrase. I also added a field to the login API as I realized that the 12 word &#34;passphrase&#34; is the payload and usually wont be sent in: FOUR_STRINGS(SuperNET,login,handle,password,permanentfile,passphrase); using &#34;abiglongpassword&#34; for the passphrase -&gt; {&#34;pubkey&#34;:&#34;6c469ba10b40b3eb9d1dba569d7f929d55a29d8f97cd5425907ef2f38f906 209&#34;,&#34;RS&#34;:&#34;NXT-KGV9-DXX8-TM86-DXR96&#34;,&#34;NXT&#34;:&#34;12834974574569896807&#34;,&#34;btcpu bkey&#34;:&#34;024e7641dc947b211bc30fe3339765258902794687b227121fc217284f9d8503c 8&#34;,&#34;rmd160&#34;:&#34;33453c24914db7b77069b7ea24df44f6be145938&#34;,&#34;BTC&#34;:&#34;15g6QK2dSd iW9ZTQEnnJxKrSph6uP7uU23&#34;,&#34;BTCD&#34;:&#34;RDxHUpuv3TX5DZpbhxmS3rBeaxZW1fvYvC&#34;,&#34;r esult&#34;:&#34;success&#34;,&#34;handle&#34;:&#34;test&#34;,&#34;tag&#34;:&#34;14805226009240621255&#34;} and if you use that to log into NXT, it gives the same address. The BTC and BTCD addresses are all derived from the same privkey so they are all interchangeable with the NXT address. The user can therefore select which coin&#39;s addressing they are most comfortable with I also added an &#34;allin&#34; action API for pangea. all the action API will autocalculate the number of chips if passed in 0 for numchips ***************** security issue ******** please dont use the GET URL method when dealing with passphrase!!! Those URL&#39;s tend to get logged and available in browser histories. so anything dealing with the actual passphrase needs to use the postCall form or POST
9 years ago
if ( remoteaddr != 0 )
return(clonestr("{\"error\":\"no remote\"}"));
9 years ago
categoryhash = calc_categoryhashes(&subhash,category,subcategory);
9 years ago
category_posthexmsg(myinfo,categoryhash,subhash,hexmsg,tai_now(),remoteaddr);
9 years ago
return(clonestr("{\"result\":\"posted message\"}"));
}
9 years ago
THREE_STRINGS(SuperNET,announce,category,subcategory,message)
{
bits256 categoryhash,subhash;
many changes blockexplorer tab: needs to allow to input height, blockhash or txid. also please display images/BTC_blocks.jpg below the text as a w800 x h400 bitmap, which is active using the mouse api for coin management, below the active coins have a form that arbitrary json can be input with an add button to the right that will call &#34;addcoin&#34; API. this way I can test adding new coins dynamically. dont worry if it doesnt work, just as long as it submits the json to the C code. I am pretty sure I need to do some debugging of this peers management is not working for me at all. maybe it is due to bad internet. On initialization you need to read in the confs/BTCD_peers.txt from the native filesystem and save it into the chrome app filesystem. same thing for confs/BTCD_hdrs.txt. But this is only to be done if there isnt already such a file inside chrome. if there is, only do it upon a button invoked by the user. the reason is that the pexe is updating this file with the latest. Maybe it is nice to have an &#34;extract&#34; button that will copy out from the chrome storage into the native filesystem. There is also the manifest issue about localstorage vs chrome.localstorage. not sure what is needed to be done, but certainly a priority to get it so everything works as a chrome app. I know before it was making ramchain files inside the chrome filesystem, so it is probably things the GUI is doing. maybe in the settings tab, which has obsolete stuff that can be removed. anyway, the issue about files existing in the native filesystem -&gt; chrome and optionally extracting them is an issue for the confs files and .html template files used to autogenerate the port7778, maybe other files are affected. i think we need a way to have a list of hardcoded files that are just copied into chrome on startup if they dont exist already (or if possible copy over if the native version is bigger?) and buttons to extract them for debug tab: THREE_STRINGS(SuperNET,encryptjson,passphrase,permanentfile,anything); TWO_STRINGS(SuperNET,decryptjson,passphrase,permanentfile); at the top of page a way to put in passphrase and optional permanentfile along with arbitrary json. The standard form template has no easy way to describe to pass in everything as it is oriented to specific fields. but the encryptjson API saves all the fields, so the arbitrary json from the form needs to be combined at the same level as the &#34;agent&#34;, &#34;method&#34;, etc. I know, not the best, but internally it makes it easier. so {&#34;agent&#34;:&#34;SuperNET&#34;,&#34;method&#34;:&#34;encryptjson&#34;,&#34;passphrase&#34;:&#34;&lt;passphrase&gt;&#34;,&#34; permanentfile&#34;:&#34;&lt;filename&gt;&#34;,&#34;fromform&#34;:&#34;valuefromform&#34;,&#34;fromform2&#34;:&#34;valu efromform2&#34;,...rest of form at top level} then this will save it into a file with crazy number (it is a hash like txid) but given the same passphrase and filename, it will regenerate this hash so you dont actually have to store it, but it helps during debugging. for the filename, we must warn quite strongly to the user that if the file is ever lost or even changed in any way that the data will not be recoverable. also best to not allow the user to specify a file that does not exist. I think at this point chrome app version gets a bit tricky. we could simply push the native file into the chrome storage, but then an attacker who gets access to the computer could just get a list of these files and it really wont be much protection. So that means if a filename is specified, it needs to be copied into the chrome space, then immediately deleted... ok, this seems like not a good approach. let us make it so that the permanentfile option is not available from the chrome app, but only if the native version is running. that way we sidestep the issue of the pexe not having access to the specified file. Speaking of native vs pexe, on the startup page we should have a radio button that allows the user to select which the GUI will talk to. It should default based on a self test to the more likely value, but it is possible that the user wants to use the native version, even if the pexe is running. another thing to have on the startup page is a simple login: THREE_STRINGS(SuperNET,login,passphrase,permanentfile,handle); ZERO_ARGS(SuperNET,logout); ZERO_ARGS(SuperNET,activehandle); the handle is a human readable name that is associated with the passphrase/permanentfile. There can only be one active account (though it will be possible to associate different accounts with tradebots). use the activehandle API to find out who is logged in and the associated addresses and pubkeys The above is not yet tested so if it doesnt work, dont fret, just let me know. Once set the handle can be displayed in various places to let the user know which account is logged in. The standard 12 dictionary word passphrases should be used, but any string can be sent in as the password for Pangea: INT_AND_ARRAY(pangea,host,minplayers,params); ZERO_ARGS(pangea,lobby); HASH_AND_STRING(pangea,join,tablehash,handle); HASH_AND_INT(pangea,buyin,tablehash,numchips); HASH_ARG(pangea,start,tablehash); // by host only HASH_ARG(pangea,status,tablehash); HASH_ARG(pangea,call,tablehash); HASH_ARG(pangea,check,tablehash); HASH_AND_INT(pangea,raise,tablehash,numchips); HASH_AND_INT(pangea,bet,tablehash,numchips); HASH_ARG(pangea,fold,tablehash); HASH_AND_STRING(pangea,mode,tablehash,modestr); HASH_ARG(pangea,history,tablehash); HASH_AND_INT(pangea,handhistory,tablehash,hand); The first thing that is done is a &#34;host&#34; by any node. the &#34;params&#34; should be an arbitrary json (like encryptjson) as it needs to be at the top level and it has quite a few different parameters still subject to change. The lobby API will just display all the hosted tables. once a table exists, players can join and then buyin. the buyin is denominated in chips, each chip&#39;s value is determined by the host&#39;s initial parameters. once there are enough players joined with adequate buyin&#39;s verified, the host will be able to do a start. if done before it will (eventually) give an error. for now it will just proceed. The host and players that have joined a tablehash, need to do regular status calls to see if the game has started. Probably just once per 5 or even 10 seconds is fine before the start. Once the game starts (the status will have this info) then once per second polling is needed. Then when it is your turn (as indicated by status) you need to do one of the 5 actions (fold, call, check, raise, bet). do not worry if you dont understand what all these do, just allow the user to do any of these. I guess it is possible to submit it ahead of time. I will support internally remembering the most recent action done prior to it being your turn. once it is your turn and an action is sent to the table, it is too late to change. The last API calls are for getting handhistory where hand is 0 to N-1, being the numbering of the hands played at that table. if just history, all the history for all hands at the table is coming back, so it could be quite big. probably I will make it a summary, but for the GUI just display the returned values. the mode is to change some poker specific modes, so just allow there to be a string entered. do not worry about understanding the pokerness of the API, just the overall flow: host -&gt; creates, join/buyin -&gt; fills up player slots, start -&gt; starts the game status -&gt; to determine when the game starts (or if it is cancelled) and once started actions -&gt; game specific but basically just (button + arg) that is the user input results are via status for current game and history for past ones please try to do the above logic in a generic way so it can be reused for other games. The basic flow should be the same for almost all multiplayer turn based games and even for multiplayer realtime games For InstantDEX: on the apikeypair/userid there needs to be two modes. one for when there is no stored apikey and the current form is fine, just need to make it wider as most apikeys are quite long. Now once there is an apikey saved all that is needed is the passphrase to unlock it. So here is where the encrptjson/decryptjson is used. When saving the apikey for the first time, it can be: a) not saved -&gt; nothing extra to do b) saved without password -&gt; you can just save to a file and use it to load it back in. use confs dir confs/instantdex.exchange.api or something like that c) saved with password (optional filename for native) -&gt; probably best to save in the confs dir to indicate that there is an encrypted file for this, so just that and not the actual passphrase in the file with the above, when the exchange is selected, you can see if the confs file exists and if it has the plaintext, just populate the field, if not, then indicate that a passphrase is needed. if the user provides the passphrase, then decryptjson and populate the fields and autosubmit. A special case is to encrypt the apikeys with the passphrase used when logging in. This is only available if the checkbox to &#34;remember passphrase during session&#34; is set on the main iguana login screen. (i forgot to mention that checkbox!) So the login passphrase is stored in memory, then the GUI simply uses that + encryptjson for storing/decrypting. I would imagine that storing in the confs file that it is encrypted using &#34;handle&#34;&#39;s account login might be a good way to differentiate between this mode of password usage. OK, so we now have the insecure plaintext, the decent using handle&#39;s passphrase and paranoid different passphrase for each exchange (with additional permanentfile for native versions) &#34;SUPPORT&#34; -&gt; &#34;SUPPORTS&#34; just a typo and &#34;allpairs&#34; API is missing from the selection Might as well add a &#34;tradebots&#34; tab: THREE_STRINGS_AND_DOUBLE(tradebot,monitor,exchange,base,rel,commission); STRING_AND_DOUBLE(tradebot,monitorall,exchange,commission); THREE_STRINGS(tradebot,unmonitor,exchange,base,rel); THREE_STRINGS_AND_THREE_DOUBLES(tradebot,accumulate,exchange,base,rel,pr ice,volume,duration); THREE_STRINGS_AND_THREE_DOUBLES(tradebot,divest,exchange,base,rel,price, volume,duration); STRING_ARG(tradebot,activebots,exchange); TWO_STRINGS(tradebot,status,exchange,botid); TWO_STRINGS(tradebot,pause,exchange,botid); TWO_STRINGS(tradebot,stop,exchange,botid); TWO_STRINGS(tradebot,resume,exchange,botid); the above are API for exchange specific bots, most should be self-explanatory. bots are created via &#34;accumulate&#34; or &#34;divest&#34; API call. it returns botid. once created, you can do status, pause, stop, resume to a botid. and an activebots API call lists all the active bots for an exchange. duration is in seconds the &#34;monitor&#34; API starts background monitoring of a specific base/rel, &#34;unmonitor&#34; stops this. &#34;monitorall&#34; just does a monitor to the entire list of &#34;allpairs&#34; for that exchange. Keep in mind that doing a monitorall will not add load to an exchange as the request to each exchange is governed by pollgap, but if you have 3 things monitored, it will take 3*pollgap + time each one takes to execute. and if N are monitored it is N*pollgap + time of each, with the &#34;time of each&#34; possibly taking a very long time. And one final request for today: Bitmap tab. It should be an active bitmap using mouse api. either a dropdown to select the bitmap or a form entry. then the rest of the page (resize the bitmap to the page size) being the active bitmap. So on a small screen the bitmap is smaller x/y dimensions and larger on larger screens. plz make sure the proper dimensions are communicated to the pexe via API if it ever is changed. @vineet.bhargav86: I changed the &#34;passphrase&#34; fieldname to &#34;password&#34; for the encryptjson/decryptjson related API. The reason is that the password is like a wallet password and is only local, so it doesnt need to be as high entropy as passphrase. I also added a field to the login API as I realized that the 12 word &#34;passphrase&#34; is the payload and usually wont be sent in: FOUR_STRINGS(SuperNET,login,handle,password,permanentfile,passphrase); using &#34;abiglongpassword&#34; for the passphrase -&gt; {&#34;pubkey&#34;:&#34;6c469ba10b40b3eb9d1dba569d7f929d55a29d8f97cd5425907ef2f38f906 209&#34;,&#34;RS&#34;:&#34;NXT-KGV9-DXX8-TM86-DXR96&#34;,&#34;NXT&#34;:&#34;12834974574569896807&#34;,&#34;btcpu bkey&#34;:&#34;024e7641dc947b211bc30fe3339765258902794687b227121fc217284f9d8503c 8&#34;,&#34;rmd160&#34;:&#34;33453c24914db7b77069b7ea24df44f6be145938&#34;,&#34;BTC&#34;:&#34;15g6QK2dSd iW9ZTQEnnJxKrSph6uP7uU23&#34;,&#34;BTCD&#34;:&#34;RDxHUpuv3TX5DZpbhxmS3rBeaxZW1fvYvC&#34;,&#34;r esult&#34;:&#34;success&#34;,&#34;handle&#34;:&#34;test&#34;,&#34;tag&#34;:&#34;14805226009240621255&#34;} and if you use that to log into NXT, it gives the same address. The BTC and BTCD addresses are all derived from the same privkey so they are all interchangeable with the NXT address. The user can therefore select which coin&#39;s addressing they are most comfortable with I also added an &#34;allin&#34; action API for pangea. all the action API will autocalculate the number of chips if passed in 0 for numchips ***************** security issue ******** please dont use the GET URL method when dealing with passphrase!!! Those URL&#39;s tend to get logged and available in browser histories. so anything dealing with the actual passphrase needs to use the postCall form or POST
9 years ago
if ( remoteaddr != 0 )
return(clonestr("{\"error\":\"no remote\"}"));
9 years ago
categoryhash = calc_categoryhashes(&subhash,category,subcategory);
9 years ago
return(SuperNET_categorymulticast(myinfo,0,categoryhash,subhash,message,juint(json,"maxdelay"),juint(json,"broadcast"),juint(json,"plaintext"),json,remoteaddr));
9 years ago
}
9 years ago
THREE_STRINGS(SuperNET,survey,category,subcategory,message)
{
bits256 categoryhash,subhash;
many changes blockexplorer tab: needs to allow to input height, blockhash or txid. also please display images/BTC_blocks.jpg below the text as a w800 x h400 bitmap, which is active using the mouse api for coin management, below the active coins have a form that arbitrary json can be input with an add button to the right that will call &#34;addcoin&#34; API. this way I can test adding new coins dynamically. dont worry if it doesnt work, just as long as it submits the json to the C code. I am pretty sure I need to do some debugging of this peers management is not working for me at all. maybe it is due to bad internet. On initialization you need to read in the confs/BTCD_peers.txt from the native filesystem and save it into the chrome app filesystem. same thing for confs/BTCD_hdrs.txt. But this is only to be done if there isnt already such a file inside chrome. if there is, only do it upon a button invoked by the user. the reason is that the pexe is updating this file with the latest. Maybe it is nice to have an &#34;extract&#34; button that will copy out from the chrome storage into the native filesystem. There is also the manifest issue about localstorage vs chrome.localstorage. not sure what is needed to be done, but certainly a priority to get it so everything works as a chrome app. I know before it was making ramchain files inside the chrome filesystem, so it is probably things the GUI is doing. maybe in the settings tab, which has obsolete stuff that can be removed. anyway, the issue about files existing in the native filesystem -&gt; chrome and optionally extracting them is an issue for the confs files and .html template files used to autogenerate the port7778, maybe other files are affected. i think we need a way to have a list of hardcoded files that are just copied into chrome on startup if they dont exist already (or if possible copy over if the native version is bigger?) and buttons to extract them for debug tab: THREE_STRINGS(SuperNET,encryptjson,passphrase,permanentfile,anything); TWO_STRINGS(SuperNET,decryptjson,passphrase,permanentfile); at the top of page a way to put in passphrase and optional permanentfile along with arbitrary json. The standard form template has no easy way to describe to pass in everything as it is oriented to specific fields. but the encryptjson API saves all the fields, so the arbitrary json from the form needs to be combined at the same level as the &#34;agent&#34;, &#34;method&#34;, etc. I know, not the best, but internally it makes it easier. so {&#34;agent&#34;:&#34;SuperNET&#34;,&#34;method&#34;:&#34;encryptjson&#34;,&#34;passphrase&#34;:&#34;&lt;passphrase&gt;&#34;,&#34; permanentfile&#34;:&#34;&lt;filename&gt;&#34;,&#34;fromform&#34;:&#34;valuefromform&#34;,&#34;fromform2&#34;:&#34;valu efromform2&#34;,...rest of form at top level} then this will save it into a file with crazy number (it is a hash like txid) but given the same passphrase and filename, it will regenerate this hash so you dont actually have to store it, but it helps during debugging. for the filename, we must warn quite strongly to the user that if the file is ever lost or even changed in any way that the data will not be recoverable. also best to not allow the user to specify a file that does not exist. I think at this point chrome app version gets a bit tricky. we could simply push the native file into the chrome storage, but then an attacker who gets access to the computer could just get a list of these files and it really wont be much protection. So that means if a filename is specified, it needs to be copied into the chrome space, then immediately deleted... ok, this seems like not a good approach. let us make it so that the permanentfile option is not available from the chrome app, but only if the native version is running. that way we sidestep the issue of the pexe not having access to the specified file. Speaking of native vs pexe, on the startup page we should have a radio button that allows the user to select which the GUI will talk to. It should default based on a self test to the more likely value, but it is possible that the user wants to use the native version, even if the pexe is running. another thing to have on the startup page is a simple login: THREE_STRINGS(SuperNET,login,passphrase,permanentfile,handle); ZERO_ARGS(SuperNET,logout); ZERO_ARGS(SuperNET,activehandle); the handle is a human readable name that is associated with the passphrase/permanentfile. There can only be one active account (though it will be possible to associate different accounts with tradebots). use the activehandle API to find out who is logged in and the associated addresses and pubkeys The above is not yet tested so if it doesnt work, dont fret, just let me know. Once set the handle can be displayed in various places to let the user know which account is logged in. The standard 12 dictionary word passphrases should be used, but any string can be sent in as the password for Pangea: INT_AND_ARRAY(pangea,host,minplayers,params); ZERO_ARGS(pangea,lobby); HASH_AND_STRING(pangea,join,tablehash,handle); HASH_AND_INT(pangea,buyin,tablehash,numchips); HASH_ARG(pangea,start,tablehash); // by host only HASH_ARG(pangea,status,tablehash); HASH_ARG(pangea,call,tablehash); HASH_ARG(pangea,check,tablehash); HASH_AND_INT(pangea,raise,tablehash,numchips); HASH_AND_INT(pangea,bet,tablehash,numchips); HASH_ARG(pangea,fold,tablehash); HASH_AND_STRING(pangea,mode,tablehash,modestr); HASH_ARG(pangea,history,tablehash); HASH_AND_INT(pangea,handhistory,tablehash,hand); The first thing that is done is a &#34;host&#34; by any node. the &#34;params&#34; should be an arbitrary json (like encryptjson) as it needs to be at the top level and it has quite a few different parameters still subject to change. The lobby API will just display all the hosted tables. once a table exists, players can join and then buyin. the buyin is denominated in chips, each chip&#39;s value is determined by the host&#39;s initial parameters. once there are enough players joined with adequate buyin&#39;s verified, the host will be able to do a start. if done before it will (eventually) give an error. for now it will just proceed. The host and players that have joined a tablehash, need to do regular status calls to see if the game has started. Probably just once per 5 or even 10 seconds is fine before the start. Once the game starts (the status will have this info) then once per second polling is needed. Then when it is your turn (as indicated by status) you need to do one of the 5 actions (fold, call, check, raise, bet). do not worry if you dont understand what all these do, just allow the user to do any of these. I guess it is possible to submit it ahead of time. I will support internally remembering the most recent action done prior to it being your turn. once it is your turn and an action is sent to the table, it is too late to change. The last API calls are for getting handhistory where hand is 0 to N-1, being the numbering of the hands played at that table. if just history, all the history for all hands at the table is coming back, so it could be quite big. probably I will make it a summary, but for the GUI just display the returned values. the mode is to change some poker specific modes, so just allow there to be a string entered. do not worry about understanding the pokerness of the API, just the overall flow: host -&gt; creates, join/buyin -&gt; fills up player slots, start -&gt; starts the game status -&gt; to determine when the game starts (or if it is cancelled) and once started actions -&gt; game specific but basically just (button + arg) that is the user input results are via status for current game and history for past ones please try to do the above logic in a generic way so it can be reused for other games. The basic flow should be the same for almost all multiplayer turn based games and even for multiplayer realtime games For InstantDEX: on the apikeypair/userid there needs to be two modes. one for when there is no stored apikey and the current form is fine, just need to make it wider as most apikeys are quite long. Now once there is an apikey saved all that is needed is the passphrase to unlock it. So here is where the encrptjson/decryptjson is used. When saving the apikey for the first time, it can be: a) not saved -&gt; nothing extra to do b) saved without password -&gt; you can just save to a file and use it to load it back in. use confs dir confs/instantdex.exchange.api or something like that c) saved with password (optional filename for native) -&gt; probably best to save in the confs dir to indicate that there is an encrypted file for this, so just that and not the actual passphrase in the file with the above, when the exchange is selected, you can see if the confs file exists and if it has the plaintext, just populate the field, if not, then indicate that a passphrase is needed. if the user provides the passphrase, then decryptjson and populate the fields and autosubmit. A special case is to encrypt the apikeys with the passphrase used when logging in. This is only available if the checkbox to &#34;remember passphrase during session&#34; is set on the main iguana login screen. (i forgot to mention that checkbox!) So the login passphrase is stored in memory, then the GUI simply uses that + encryptjson for storing/decrypting. I would imagine that storing in the confs file that it is encrypted using &#34;handle&#34;&#39;s account login might be a good way to differentiate between this mode of password usage. OK, so we now have the insecure plaintext, the decent using handle&#39;s passphrase and paranoid different passphrase for each exchange (with additional permanentfile for native versions) &#34;SUPPORT&#34; -&gt; &#34;SUPPORTS&#34; just a typo and &#34;allpairs&#34; API is missing from the selection Might as well add a &#34;tradebots&#34; tab: THREE_STRINGS_AND_DOUBLE(tradebot,monitor,exchange,base,rel,commission); STRING_AND_DOUBLE(tradebot,monitorall,exchange,commission); THREE_STRINGS(tradebot,unmonitor,exchange,base,rel); THREE_STRINGS_AND_THREE_DOUBLES(tradebot,accumulate,exchange,base,rel,pr ice,volume,duration); THREE_STRINGS_AND_THREE_DOUBLES(tradebot,divest,exchange,base,rel,price, volume,duration); STRING_ARG(tradebot,activebots,exchange); TWO_STRINGS(tradebot,status,exchange,botid); TWO_STRINGS(tradebot,pause,exchange,botid); TWO_STRINGS(tradebot,stop,exchange,botid); TWO_STRINGS(tradebot,resume,exchange,botid); the above are API for exchange specific bots, most should be self-explanatory. bots are created via &#34;accumulate&#34; or &#34;divest&#34; API call. it returns botid. once created, you can do status, pause, stop, resume to a botid. and an activebots API call lists all the active bots for an exchange. duration is in seconds the &#34;monitor&#34; API starts background monitoring of a specific base/rel, &#34;unmonitor&#34; stops this. &#34;monitorall&#34; just does a monitor to the entire list of &#34;allpairs&#34; for that exchange. Keep in mind that doing a monitorall will not add load to an exchange as the request to each exchange is governed by pollgap, but if you have 3 things monitored, it will take 3*pollgap + time each one takes to execute. and if N are monitored it is N*pollgap + time of each, with the &#34;time of each&#34; possibly taking a very long time. And one final request for today: Bitmap tab. It should be an active bitmap using mouse api. either a dropdown to select the bitmap or a form entry. then the rest of the page (resize the bitmap to the page size) being the active bitmap. So on a small screen the bitmap is smaller x/y dimensions and larger on larger screens. plz make sure the proper dimensions are communicated to the pexe via API if it ever is changed. @vineet.bhargav86: I changed the &#34;passphrase&#34; fieldname to &#34;password&#34; for the encryptjson/decryptjson related API. The reason is that the password is like a wallet password and is only local, so it doesnt need to be as high entropy as passphrase. I also added a field to the login API as I realized that the 12 word &#34;passphrase&#34; is the payload and usually wont be sent in: FOUR_STRINGS(SuperNET,login,handle,password,permanentfile,passphrase); using &#34;abiglongpassword&#34; for the passphrase -&gt; {&#34;pubkey&#34;:&#34;6c469ba10b40b3eb9d1dba569d7f929d55a29d8f97cd5425907ef2f38f906 209&#34;,&#34;RS&#34;:&#34;NXT-KGV9-DXX8-TM86-DXR96&#34;,&#34;NXT&#34;:&#34;12834974574569896807&#34;,&#34;btcpu bkey&#34;:&#34;024e7641dc947b211bc30fe3339765258902794687b227121fc217284f9d8503c 8&#34;,&#34;rmd160&#34;:&#34;33453c24914db7b77069b7ea24df44f6be145938&#34;,&#34;BTC&#34;:&#34;15g6QK2dSd iW9ZTQEnnJxKrSph6uP7uU23&#34;,&#34;BTCD&#34;:&#34;RDxHUpuv3TX5DZpbhxmS3rBeaxZW1fvYvC&#34;,&#34;r esult&#34;:&#34;success&#34;,&#34;handle&#34;:&#34;test&#34;,&#34;tag&#34;:&#34;14805226009240621255&#34;} and if you use that to log into NXT, it gives the same address. The BTC and BTCD addresses are all derived from the same privkey so they are all interchangeable with the NXT address. The user can therefore select which coin&#39;s addressing they are most comfortable with I also added an &#34;allin&#34; action API for pangea. all the action API will autocalculate the number of chips if passed in 0 for numchips ***************** security issue ******** please dont use the GET URL method when dealing with passphrase!!! Those URL&#39;s tend to get logged and available in browser histories. so anything dealing with the actual passphrase needs to use the postCall form or POST
9 years ago
if ( remoteaddr != 0 )
return(clonestr("{\"error\":\"no remote\"}"));
9 years ago
categoryhash = calc_categoryhashes(&subhash,category,subcategory);
9 years ago
return(SuperNET_categorymulticast(myinfo,1,categoryhash,subhash,message,juint(json,"maxdelay"),juint(json,"broadcast"),juint(json,"plaintext"),json,remoteaddr));
9 years ago
}
9 years ago
STRING_ARG(SuperNET,wif2priv,wif)
{
bits256 privkey; char str[65]; uint8_t privkeytype; cJSON *retjson = cJSON_CreateObject();
if ( btc_wif2priv(&privkeytype,privkey.bytes,wif) == sizeof(privkey) )
{
jaddstr(retjson,"result","success");
jaddstr(retjson,"privkey",bits256_str(str,privkey));
jaddnum(retjson,"type",privkeytype);
} else jaddstr(retjson,"error","couldnt convert wif");
return(jprint(retjson,1));
}
9 years ago
ZERO_ARGS(SuperNET,myipaddr)
{
cJSON *retjson = cJSON_CreateObject();
jaddstr(retjson,"result",myinfo->ipaddr);
return(jprint(retjson,1));
}
STRING_ARG(SuperNET,setmyipaddr,ipaddr)
{
cJSON *retjson = cJSON_CreateObject();
if ( is_ipaddr(ipaddr) != 0 )
{
strcpy(myinfo->ipaddr,ipaddr);
jaddstr(retjson,"result",myinfo->ipaddr);
} else jaddstr(retjson,"error","illegal ipaddr");
return(jprint(retjson,1));
}
9 years ago
STRING_ARG(SuperNET,utime2utc,utime)
{
uint32_t utc = 0; cJSON *retjson = cJSON_CreateObject();
utc = OS_conv_utime(utime);
char str[65]; printf("utime.%s -> %u -> %s\n",utime,utc,utc_str(str,utc));
jaddnum(retjson,"result",utc);
return(jprint(retjson,1));
}
INT_ARG(SuperNET,utc2utime,utc)
{
char str[65]; cJSON *retjson = cJSON_CreateObject();
jaddstr(retjson,"result",utc_str(str,utc));
return(jprint(retjson,1));
}
many changes blockexplorer tab: needs to allow to input height, blockhash or txid. also please display images/BTC_blocks.jpg below the text as a w800 x h400 bitmap, which is active using the mouse api for coin management, below the active coins have a form that arbitrary json can be input with an add button to the right that will call &#34;addcoin&#34; API. this way I can test adding new coins dynamically. dont worry if it doesnt work, just as long as it submits the json to the C code. I am pretty sure I need to do some debugging of this peers management is not working for me at all. maybe it is due to bad internet. On initialization you need to read in the confs/BTCD_peers.txt from the native filesystem and save it into the chrome app filesystem. same thing for confs/BTCD_hdrs.txt. But this is only to be done if there isnt already such a file inside chrome. if there is, only do it upon a button invoked by the user. the reason is that the pexe is updating this file with the latest. Maybe it is nice to have an &#34;extract&#34; button that will copy out from the chrome storage into the native filesystem. There is also the manifest issue about localstorage vs chrome.localstorage. not sure what is needed to be done, but certainly a priority to get it so everything works as a chrome app. I know before it was making ramchain files inside the chrome filesystem, so it is probably things the GUI is doing. maybe in the settings tab, which has obsolete stuff that can be removed. anyway, the issue about files existing in the native filesystem -&gt; chrome and optionally extracting them is an issue for the confs files and .html template files used to autogenerate the port7778, maybe other files are affected. i think we need a way to have a list of hardcoded files that are just copied into chrome on startup if they dont exist already (or if possible copy over if the native version is bigger?) and buttons to extract them for debug tab: THREE_STRINGS(SuperNET,encryptjson,passphrase,permanentfile,anything); TWO_STRINGS(SuperNET,decryptjson,passphrase,permanentfile); at the top of page a way to put in passphrase and optional permanentfile along with arbitrary json. The standard form template has no easy way to describe to pass in everything as it is oriented to specific fields. but the encryptjson API saves all the fields, so the arbitrary json from the form needs to be combined at the same level as the &#34;agent&#34;, &#34;method&#34;, etc. I know, not the best, but internally it makes it easier. so {&#34;agent&#34;:&#34;SuperNET&#34;,&#34;method&#34;:&#34;encryptjson&#34;,&#34;passphrase&#34;:&#34;&lt;passphrase&gt;&#34;,&#34; permanentfile&#34;:&#34;&lt;filename&gt;&#34;,&#34;fromform&#34;:&#34;valuefromform&#34;,&#34;fromform2&#34;:&#34;valu efromform2&#34;,...rest of form at top level} then this will save it into a file with crazy number (it is a hash like txid) but given the same passphrase and filename, it will regenerate this hash so you dont actually have to store it, but it helps during debugging. for the filename, we must warn quite strongly to the user that if the file is ever lost or even changed in any way that the data will not be recoverable. also best to not allow the user to specify a file that does not exist. I think at this point chrome app version gets a bit tricky. we could simply push the native file into the chrome storage, but then an attacker who gets access to the computer could just get a list of these files and it really wont be much protection. So that means if a filename is specified, it needs to be copied into the chrome space, then immediately deleted... ok, this seems like not a good approach. let us make it so that the permanentfile option is not available from the chrome app, but only if the native version is running. that way we sidestep the issue of the pexe not having access to the specified file. Speaking of native vs pexe, on the startup page we should have a radio button that allows the user to select which the GUI will talk to. It should default based on a self test to the more likely value, but it is possible that the user wants to use the native version, even if the pexe is running. another thing to have on the startup page is a simple login: THREE_STRINGS(SuperNET,login,passphrase,permanentfile,handle); ZERO_ARGS(SuperNET,logout); ZERO_ARGS(SuperNET,activehandle); the handle is a human readable name that is associated with the passphrase/permanentfile. There can only be one active account (though it will be possible to associate different accounts with tradebots). use the activehandle API to find out who is logged in and the associated addresses and pubkeys The above is not yet tested so if it doesnt work, dont fret, just let me know. Once set the handle can be displayed in various places to let the user know which account is logged in. The standard 12 dictionary word passphrases should be used, but any string can be sent in as the password for Pangea: INT_AND_ARRAY(pangea,host,minplayers,params); ZERO_ARGS(pangea,lobby); HASH_AND_STRING(pangea,join,tablehash,handle); HASH_AND_INT(pangea,buyin,tablehash,numchips); HASH_ARG(pangea,start,tablehash); // by host only HASH_ARG(pangea,status,tablehash); HASH_ARG(pangea,call,tablehash); HASH_ARG(pangea,check,tablehash); HASH_AND_INT(pangea,raise,tablehash,numchips); HASH_AND_INT(pangea,bet,tablehash,numchips); HASH_ARG(pangea,fold,tablehash); HASH_AND_STRING(pangea,mode,tablehash,modestr); HASH_ARG(pangea,history,tablehash); HASH_AND_INT(pangea,handhistory,tablehash,hand); The first thing that is done is a &#34;host&#34; by any node. the &#34;params&#34; should be an arbitrary json (like encryptjson) as it needs to be at the top level and it has quite a few different parameters still subject to change. The lobby API will just display all the hosted tables. once a table exists, players can join and then buyin. the buyin is denominated in chips, each chip&#39;s value is determined by the host&#39;s initial parameters. once there are enough players joined with adequate buyin&#39;s verified, the host will be able to do a start. if done before it will (eventually) give an error. for now it will just proceed. The host and players that have joined a tablehash, need to do regular status calls to see if the game has started. Probably just once per 5 or even 10 seconds is fine before the start. Once the game starts (the status will have this info) then once per second polling is needed. Then when it is your turn (as indicated by status) you need to do one of the 5 actions (fold, call, check, raise, bet). do not worry if you dont understand what all these do, just allow the user to do any of these. I guess it is possible to submit it ahead of time. I will support internally remembering the most recent action done prior to it being your turn. once it is your turn and an action is sent to the table, it is too late to change. The last API calls are for getting handhistory where hand is 0 to N-1, being the numbering of the hands played at that table. if just history, all the history for all hands at the table is coming back, so it could be quite big. probably I will make it a summary, but for the GUI just display the returned values. the mode is to change some poker specific modes, so just allow there to be a string entered. do not worry about understanding the pokerness of the API, just the overall flow: host -&gt; creates, join/buyin -&gt; fills up player slots, start -&gt; starts the game status -&gt; to determine when the game starts (or if it is cancelled) and once started actions -&gt; game specific but basically just (button + arg) that is the user input results are via status for current game and history for past ones please try to do the above logic in a generic way so it can be reused for other games. The basic flow should be the same for almost all multiplayer turn based games and even for multiplayer realtime games For InstantDEX: on the apikeypair/userid there needs to be two modes. one for when there is no stored apikey and the current form is fine, just need to make it wider as most apikeys are quite long. Now once there is an apikey saved all that is needed is the passphrase to unlock it. So here is where the encrptjson/decryptjson is used. When saving the apikey for the first time, it can be: a) not saved -&gt; nothing extra to do b) saved without password -&gt; you can just save to a file and use it to load it back in. use confs dir confs/instantdex.exchange.api or something like that c) saved with password (optional filename for native) -&gt; probably best to save in the confs dir to indicate that there is an encrypted file for this, so just that and not the actual passphrase in the file with the above, when the exchange is selected, you can see if the confs file exists and if it has the plaintext, just populate the field, if not, then indicate that a passphrase is needed. if the user provides the passphrase, then decryptjson and populate the fields and autosubmit. A special case is to encrypt the apikeys with the passphrase used when logging in. This is only available if the checkbox to &#34;remember passphrase during session&#34; is set on the main iguana login screen. (i forgot to mention that checkbox!) So the login passphrase is stored in memory, then the GUI simply uses that + encryptjson for storing/decrypting. I would imagine that storing in the confs file that it is encrypted using &#34;handle&#34;&#39;s account login might be a good way to differentiate between this mode of password usage. OK, so we now have the insecure plaintext, the decent using handle&#39;s passphrase and paranoid different passphrase for each exchange (with additional permanentfile for native versions) &#34;SUPPORT&#34; -&gt; &#34;SUPPORTS&#34; just a typo and &#34;allpairs&#34; API is missing from the selection Might as well add a &#34;tradebots&#34; tab: THREE_STRINGS_AND_DOUBLE(tradebot,monitor,exchange,base,rel,commission); STRING_AND_DOUBLE(tradebot,monitorall,exchange,commission); THREE_STRINGS(tradebot,unmonitor,exchange,base,rel); THREE_STRINGS_AND_THREE_DOUBLES(tradebot,accumulate,exchange,base,rel,pr ice,volume,duration); THREE_STRINGS_AND_THREE_DOUBLES(tradebot,divest,exchange,base,rel,price, volume,duration); STRING_ARG(tradebot,activebots,exchange); TWO_STRINGS(tradebot,status,exchange,botid); TWO_STRINGS(tradebot,pause,exchange,botid); TWO_STRINGS(tradebot,stop,exchange,botid); TWO_STRINGS(tradebot,resume,exchange,botid); the above are API for exchange specific bots, most should be self-explanatory. bots are created via &#34;accumulate&#34; or &#34;divest&#34; API call. it returns botid. once created, you can do status, pause, stop, resume to a botid. and an activebots API call lists all the active bots for an exchange. duration is in seconds the &#34;monitor&#34; API starts background monitoring of a specific base/rel, &#34;unmonitor&#34; stops this. &#34;monitorall&#34; just does a monitor to the entire list of &#34;allpairs&#34; for that exchange. Keep in mind that doing a monitorall will not add load to an exchange as the request to each exchange is governed by pollgap, but if you have 3 things monitored, it will take 3*pollgap + time each one takes to execute. and if N are monitored it is N*pollgap + time of each, with the &#34;time of each&#34; possibly taking a very long time. And one final request for today: Bitmap tab. It should be an active bitmap using mouse api. either a dropdown to select the bitmap or a form entry. then the rest of the page (resize the bitmap to the page size) being the active bitmap. So on a small screen the bitmap is smaller x/y dimensions and larger on larger screens. plz make sure the proper dimensions are communicated to the pexe via API if it ever is changed. @vineet.bhargav86: I changed the &#34;passphrase&#34; fieldname to &#34;password&#34; for the encryptjson/decryptjson related API. The reason is that the password is like a wallet password and is only local, so it doesnt need to be as high entropy as passphrase. I also added a field to the login API as I realized that the 12 word &#34;passphrase&#34; is the payload and usually wont be sent in: FOUR_STRINGS(SuperNET,login,handle,password,permanentfile,passphrase); using &#34;abiglongpassword&#34; for the passphrase -&gt; {&#34;pubkey&#34;:&#34;6c469ba10b40b3eb9d1dba569d7f929d55a29d8f97cd5425907ef2f38f906 209&#34;,&#34;RS&#34;:&#34;NXT-KGV9-DXX8-TM86-DXR96&#34;,&#34;NXT&#34;:&#34;12834974574569896807&#34;,&#34;btcpu bkey&#34;:&#34;024e7641dc947b211bc30fe3339765258902794687b227121fc217284f9d8503c 8&#34;,&#34;rmd160&#34;:&#34;33453c24914db7b77069b7ea24df44f6be145938&#34;,&#34;BTC&#34;:&#34;15g6QK2dSd iW9ZTQEnnJxKrSph6uP7uU23&#34;,&#34;BTCD&#34;:&#34;RDxHUpuv3TX5DZpbhxmS3rBeaxZW1fvYvC&#34;,&#34;r esult&#34;:&#34;success&#34;,&#34;handle&#34;:&#34;test&#34;,&#34;tag&#34;:&#34;14805226009240621255&#34;} and if you use that to log into NXT, it gives the same address. The BTC and BTCD addresses are all derived from the same privkey so they are all interchangeable with the NXT address. The user can therefore select which coin&#39;s addressing they are most comfortable with I also added an &#34;allin&#34; action API for pangea. all the action API will autocalculate the number of chips if passed in 0 for numchips ***************** security issue ******** please dont use the GET URL method when dealing with passphrase!!! Those URL&#39;s tend to get logged and available in browser histories. so anything dealing with the actual passphrase needs to use the postCall form or POST
9 years ago
ZERO_ARGS(SuperNET,logout)
{
if ( remoteaddr != 0 )
return(clonestr("{\"error\":\"no remote\"}"));
memset(myinfo->persistent_priv.bytes,0,sizeof(myinfo->persistent_priv));
memset(myinfo->myaddr.persistent.bytes,0,sizeof(myinfo->myaddr.persistent));
memset(myinfo->handle,0,sizeof(myinfo->handle));
memset(myinfo->myaddr.NXTADDR,0,sizeof(myinfo->myaddr.NXTADDR));
myinfo->myaddr.nxt64bits = 0;
return(clonestr("{\"result\":\"logged out\"}"));
}
ZERO_ARGS(SuperNET,activehandle)
{
cJSON *retjson;
if ( remoteaddr != 0 )
return(clonestr("{\"error\":\"no remote\"}"));
retjson = SuperNET_rosettajson(myinfo->persistent_priv,0);
jaddstr(retjson,"result","success");
jaddstr(retjson,"handle",myinfo->handle);
9 years ago
jaddbits256(retjson,"persistent",myinfo->myaddr.persistent);
9 years ago
SuperNET_MYINFOadd(myinfo);
many changes blockexplorer tab: needs to allow to input height, blockhash or txid. also please display images/BTC_blocks.jpg below the text as a w800 x h400 bitmap, which is active using the mouse api for coin management, below the active coins have a form that arbitrary json can be input with an add button to the right that will call &#34;addcoin&#34; API. this way I can test adding new coins dynamically. dont worry if it doesnt work, just as long as it submits the json to the C code. I am pretty sure I need to do some debugging of this peers management is not working for me at all. maybe it is due to bad internet. On initialization you need to read in the confs/BTCD_peers.txt from the native filesystem and save it into the chrome app filesystem. same thing for confs/BTCD_hdrs.txt. But this is only to be done if there isnt already such a file inside chrome. if there is, only do it upon a button invoked by the user. the reason is that the pexe is updating this file with the latest. Maybe it is nice to have an &#34;extract&#34; button that will copy out from the chrome storage into the native filesystem. There is also the manifest issue about localstorage vs chrome.localstorage. not sure what is needed to be done, but certainly a priority to get it so everything works as a chrome app. I know before it was making ramchain files inside the chrome filesystem, so it is probably things the GUI is doing. maybe in the settings tab, which has obsolete stuff that can be removed. anyway, the issue about files existing in the native filesystem -&gt; chrome and optionally extracting them is an issue for the confs files and .html template files used to autogenerate the port7778, maybe other files are affected. i think we need a way to have a list of hardcoded files that are just copied into chrome on startup if they dont exist already (or if possible copy over if the native version is bigger?) and buttons to extract them for debug tab: THREE_STRINGS(SuperNET,encryptjson,passphrase,permanentfile,anything); TWO_STRINGS(SuperNET,decryptjson,passphrase,permanentfile); at the top of page a way to put in passphrase and optional permanentfile along with arbitrary json. The standard form template has no easy way to describe to pass in everything as it is oriented to specific fields. but the encryptjson API saves all the fields, so the arbitrary json from the form needs to be combined at the same level as the &#34;agent&#34;, &#34;method&#34;, etc. I know, not the best, but internally it makes it easier. so {&#34;agent&#34;:&#34;SuperNET&#34;,&#34;method&#34;:&#34;encryptjson&#34;,&#34;passphrase&#34;:&#34;&lt;passphrase&gt;&#34;,&#34; permanentfile&#34;:&#34;&lt;filename&gt;&#34;,&#34;fromform&#34;:&#34;valuefromform&#34;,&#34;fromform2&#34;:&#34;valu efromform2&#34;,...rest of form at top level} then this will save it into a file with crazy number (it is a hash like txid) but given the same passphrase and filename, it will regenerate this hash so you dont actually have to store it, but it helps during debugging. for the filename, we must warn quite strongly to the user that if the file is ever lost or even changed in any way that the data will not be recoverable. also best to not allow the user to specify a file that does not exist. I think at this point chrome app version gets a bit tricky. we could simply push the native file into the chrome storage, but then an attacker who gets access to the computer could just get a list of these files and it really wont be much protection. So that means if a filename is specified, it needs to be copied into the chrome space, then immediately deleted... ok, this seems like not a good approach. let us make it so that the permanentfile option is not available from the chrome app, but only if the native version is running. that way we sidestep the issue of the pexe not having access to the specified file. Speaking of native vs pexe, on the startup page we should have a radio button that allows the user to select which the GUI will talk to. It should default based on a self test to the more likely value, but it is possible that the user wants to use the native version, even if the pexe is running. another thing to have on the startup page is a simple login: THREE_STRINGS(SuperNET,login,passphrase,permanentfile,handle); ZERO_ARGS(SuperNET,logout); ZERO_ARGS(SuperNET,activehandle); the handle is a human readable name that is associated with the passphrase/permanentfile. There can only be one active account (though it will be possible to associate different accounts with tradebots). use the activehandle API to find out who is logged in and the associated addresses and pubkeys The above is not yet tested so if it doesnt work, dont fret, just let me know. Once set the handle can be displayed in various places to let the user know which account is logged in. The standard 12 dictionary word passphrases should be used, but any string can be sent in as the password for Pangea: INT_AND_ARRAY(pangea,host,minplayers,params); ZERO_ARGS(pangea,lobby); HASH_AND_STRING(pangea,join,tablehash,handle); HASH_AND_INT(pangea,buyin,tablehash,numchips); HASH_ARG(pangea,start,tablehash); // by host only HASH_ARG(pangea,status,tablehash); HASH_ARG(pangea,call,tablehash); HASH_ARG(pangea,check,tablehash); HASH_AND_INT(pangea,raise,tablehash,numchips); HASH_AND_INT(pangea,bet,tablehash,numchips); HASH_ARG(pangea,fold,tablehash); HASH_AND_STRING(pangea,mode,tablehash,modestr); HASH_ARG(pangea,history,tablehash); HASH_AND_INT(pangea,handhistory,tablehash,hand); The first thing that is done is a &#34;host&#34; by any node. the &#34;params&#34; should be an arbitrary json (like encryptjson) as it needs to be at the top level and it has quite a few different parameters still subject to change. The lobby API will just display all the hosted tables. once a table exists, players can join and then buyin. the buyin is denominated in chips, each chip&#39;s value is determined by the host&#39;s initial parameters. once there are enough players joined with adequate buyin&#39;s verified, the host will be able to do a start. if done before it will (eventually) give an error. for now it will just proceed. The host and players that have joined a tablehash, need to do regular status calls to see if the game has started. Probably just once per 5 or even 10 seconds is fine before the start. Once the game starts (the status will have this info) then once per second polling is needed. Then when it is your turn (as indicated by status) you need to do one of the 5 actions (fold, call, check, raise, bet). do not worry if you dont understand what all these do, just allow the user to do any of these. I guess it is possible to submit it ahead of time. I will support internally remembering the most recent action done prior to it being your turn. once it is your turn and an action is sent to the table, it is too late to change. The last API calls are for getting handhistory where hand is 0 to N-1, being the numbering of the hands played at that table. if just history, all the history for all hands at the table is coming back, so it could be quite big. probably I will make it a summary, but for the GUI just display the returned values. the mode is to change some poker specific modes, so just allow there to be a string entered. do not worry about understanding the pokerness of the API, just the overall flow: host -&gt; creates, join/buyin -&gt; fills up player slots, start -&gt; starts the game status -&gt; to determine when the game starts (or if it is cancelled) and once started actions -&gt; game specific but basically just (button + arg) that is the user input results are via status for current game and history for past ones please try to do the above logic in a generic way so it can be reused for other games. The basic flow should be the same for almost all multiplayer turn based games and even for multiplayer realtime games For InstantDEX: on the apikeypair/userid there needs to be two modes. one for when there is no stored apikey and the current form is fine, just need to make it wider as most apikeys are quite long. Now once there is an apikey saved all that is needed is the passphrase to unlock it. So here is where the encrptjson/decryptjson is used. When saving the apikey for the first time, it can be: a) not saved -&gt; nothing extra to do b) saved without password -&gt; you can just save to a file and use it to load it back in. use confs dir confs/instantdex.exchange.api or something like that c) saved with password (optional filename for native) -&gt; probably best to save in the confs dir to indicate that there is an encrypted file for this, so just that and not the actual passphrase in the file with the above, when the exchange is selected, you can see if the confs file exists and if it has the plaintext, just populate the field, if not, then indicate that a passphrase is needed. if the user provides the passphrase, then decryptjson and populate the fields and autosubmit. A special case is to encrypt the apikeys with the passphrase used when logging in. This is only available if the checkbox to &#34;remember passphrase during session&#34; is set on the main iguana login screen. (i forgot to mention that checkbox!) So the login passphrase is stored in memory, then the GUI simply uses that + encryptjson for storing/decrypting. I would imagine that storing in the confs file that it is encrypted using &#34;handle&#34;&#39;s account login might be a good way to differentiate between this mode of password usage. OK, so we now have the insecure plaintext, the decent using handle&#39;s passphrase and paranoid different passphrase for each exchange (with additional permanentfile for native versions) &#34;SUPPORT&#34; -&gt; &#34;SUPPORTS&#34; just a typo and &#34;allpairs&#34; API is missing from the selection Might as well add a &#34;tradebots&#34; tab: THREE_STRINGS_AND_DOUBLE(tradebot,monitor,exchange,base,rel,commission); STRING_AND_DOUBLE(tradebot,monitorall,exchange,commission); THREE_STRINGS(tradebot,unmonitor,exchange,base,rel); THREE_STRINGS_AND_THREE_DOUBLES(tradebot,accumulate,exchange,base,rel,pr ice,volume,duration); THREE_STRINGS_AND_THREE_DOUBLES(tradebot,divest,exchange,base,rel,price, volume,duration); STRING_ARG(tradebot,activebots,exchange); TWO_STRINGS(tradebot,status,exchange,botid); TWO_STRINGS(tradebot,pause,exchange,botid); TWO_STRINGS(tradebot,stop,exchange,botid); TWO_STRINGS(tradebot,resume,exchange,botid); the above are API for exchange specific bots, most should be self-explanatory. bots are created via &#34;accumulate&#34; or &#34;divest&#34; API call. it returns botid. once created, you can do status, pause, stop, resume to a botid. and an activebots API call lists all the active bots for an exchange. duration is in seconds the &#34;monitor&#34; API starts background monitoring of a specific base/rel, &#34;unmonitor&#34; stops this. &#34;monitorall&#34; just does a monitor to the entire list of &#34;allpairs&#34; for that exchange. Keep in mind that doing a monitorall will not add load to an exchange as the request to each exchange is governed by pollgap, but if you have 3 things monitored, it will take 3*pollgap + time each one takes to execute. and if N are monitored it is N*pollgap + time of each, with the &#34;time of each&#34; possibly taking a very long time. And one final request for today: Bitmap tab. It should be an active bitmap using mouse api. either a dropdown to select the bitmap or a form entry. then the rest of the page (resize the bitmap to the page size) being the active bitmap. So on a small screen the bitmap is smaller x/y dimensions and larger on larger screens. plz make sure the proper dimensions are communicated to the pexe via API if it ever is changed. @vineet.bhargav86: I changed the &#34;passphrase&#34; fieldname to &#34;password&#34; for the encryptjson/decryptjson related API. The reason is that the password is like a wallet password and is only local, so it doesnt need to be as high entropy as passphrase. I also added a field to the login API as I realized that the 12 word &#34;passphrase&#34; is the payload and usually wont be sent in: FOUR_STRINGS(SuperNET,login,handle,password,permanentfile,passphrase); using &#34;abiglongpassword&#34; for the passphrase -&gt; {&#34;pubkey&#34;:&#34;6c469ba10b40b3eb9d1dba569d7f929d55a29d8f97cd5425907ef2f38f906 209&#34;,&#34;RS&#34;:&#34;NXT-KGV9-DXX8-TM86-DXR96&#34;,&#34;NXT&#34;:&#34;12834974574569896807&#34;,&#34;btcpu bkey&#34;:&#34;024e7641dc947b211bc30fe3339765258902794687b227121fc217284f9d8503c 8&#34;,&#34;rmd160&#34;:&#34;33453c24914db7b77069b7ea24df44f6be145938&#34;,&#34;BTC&#34;:&#34;15g6QK2dSd iW9ZTQEnnJxKrSph6uP7uU23&#34;,&#34;BTCD&#34;:&#34;RDxHUpuv3TX5DZpbhxmS3rBeaxZW1fvYvC&#34;,&#34;r esult&#34;:&#34;success&#34;,&#34;handle&#34;:&#34;test&#34;,&#34;tag&#34;:&#34;14805226009240621255&#34;} and if you use that to log into NXT, it gives the same address. The BTC and BTCD addresses are all derived from the same privkey so they are all interchangeable with the NXT address. The user can therefore select which coin&#39;s addressing they are most comfortable with I also added an &#34;allin&#34; action API for pangea. all the action API will autocalculate the number of chips if passed in 0 for numchips ***************** security issue ******** please dont use the GET URL method when dealing with passphrase!!! Those URL&#39;s tend to get logged and available in browser histories. so anything dealing with the actual passphrase needs to use the postCall form or POST
9 years ago
return(jprint(retjson,1));
}
9 years ago
struct supernet_info *SuperNET_accountfind(cJSON *json)
{
int32_t num; char *decryptstr; struct supernet_info M,*myinfo; struct iguana_info *coin = 0;
char *password,*permanentfile,*passphrase,*remoteaddr,*perspriv;
myinfo = 0;
if ( (password= jstr(json,"password")) == 0 )
password = "";
if ( (permanentfile= jstr(json,"permanentfile")) == 0 )
permanentfile = "";
if ( (passphrase= jstr(json,"passphrase")) == 0 )
passphrase = "";
remoteaddr = jstr(json,"remoteaddr");
if ( (passphrase == 0 || passphrase[0] == 0) && (decryptstr= SuperNET_decryptjson(IGUANA_CALLARGS,password,permanentfile)) != 0 )
{
if ( (json= cJSON_Parse(decryptstr)) != 0 )
{
memset(&M,0,sizeof(M));
if ( (perspriv= jstr(json,"persistent_priv")) != 0 && strlen(perspriv) == sizeof(bits256)*2 )
{
M.persistent_priv = bits256_conv(perspriv);
SuperNET_setkeys(&M,0,0,0);
9 years ago
if ( (myinfo = SuperNET_MYINFOfind(&num,M.myaddr.persistent)) != 0 )
{
printf("found account.(%s) %s %llu\n",myinfo!=0?myinfo->handle:"",M.myaddr.NXTADDR,(long long)M.myaddr.nxt64bits);
return(myinfo);
}
9 years ago
}
else if ( (passphrase= jstr(json,"result")) != 0 || (passphrase= jstr(json,"passphrase")) != 0 )
{
SuperNET_setkeys(&M,passphrase,(int32_t)strlen(passphrase),1);
9 years ago
if ( (myinfo= SuperNET_MYINFOfind(&num,M.myaddr.persistent)) != 0 )
{
printf("found account.(%s) %s %llu\n",myinfo!=0?myinfo->handle:"",M.myaddr.NXTADDR,(long long)M.myaddr.nxt64bits);
return(myinfo);
}
9 years ago
} else printf("no passphrase in (%s)\n",jprint(json,0));
free_json(json);
} else printf("cant parse.(%s)\n",decryptstr);
free(decryptstr);
}
return(SuperNET_MYINFO(0));
}
many changes blockexplorer tab: needs to allow to input height, blockhash or txid. also please display images/BTC_blocks.jpg below the text as a w800 x h400 bitmap, which is active using the mouse api for coin management, below the active coins have a form that arbitrary json can be input with an add button to the right that will call &#34;addcoin&#34; API. this way I can test adding new coins dynamically. dont worry if it doesnt work, just as long as it submits the json to the C code. I am pretty sure I need to do some debugging of this peers management is not working for me at all. maybe it is due to bad internet. On initialization you need to read in the confs/BTCD_peers.txt from the native filesystem and save it into the chrome app filesystem. same thing for confs/BTCD_hdrs.txt. But this is only to be done if there isnt already such a file inside chrome. if there is, only do it upon a button invoked by the user. the reason is that the pexe is updating this file with the latest. Maybe it is nice to have an &#34;extract&#34; button that will copy out from the chrome storage into the native filesystem. There is also the manifest issue about localstorage vs chrome.localstorage. not sure what is needed to be done, but certainly a priority to get it so everything works as a chrome app. I know before it was making ramchain files inside the chrome filesystem, so it is probably things the GUI is doing. maybe in the settings tab, which has obsolete stuff that can be removed. anyway, the issue about files existing in the native filesystem -&gt; chrome and optionally extracting them is an issue for the confs files and .html template files used to autogenerate the port7778, maybe other files are affected. i think we need a way to have a list of hardcoded files that are just copied into chrome on startup if they dont exist already (or if possible copy over if the native version is bigger?) and buttons to extract them for debug tab: THREE_STRINGS(SuperNET,encryptjson,passphrase,permanentfile,anything); TWO_STRINGS(SuperNET,decryptjson,passphrase,permanentfile); at the top of page a way to put in passphrase and optional permanentfile along with arbitrary json. The standard form template has no easy way to describe to pass in everything as it is oriented to specific fields. but the encryptjson API saves all the fields, so the arbitrary json from the form needs to be combined at the same level as the &#34;agent&#34;, &#34;method&#34;, etc. I know, not the best, but internally it makes it easier. so {&#34;agent&#34;:&#34;SuperNET&#34;,&#34;method&#34;:&#34;encryptjson&#34;,&#34;passphrase&#34;:&#34;&lt;passphrase&gt;&#34;,&#34; permanentfile&#34;:&#34;&lt;filename&gt;&#34;,&#34;fromform&#34;:&#34;valuefromform&#34;,&#34;fromform2&#34;:&#34;valu efromform2&#34;,...rest of form at top level} then this will save it into a file with crazy number (it is a hash like txid) but given the same passphrase and filename, it will regenerate this hash so you dont actually have to store it, but it helps during debugging. for the filename, we must warn quite strongly to the user that if the file is ever lost or even changed in any way that the data will not be recoverable. also best to not allow the user to specify a file that does not exist. I think at this point chrome app version gets a bit tricky. we could simply push the native file into the chrome storage, but then an attacker who gets access to the computer could just get a list of these files and it really wont be much protection. So that means if a filename is specified, it needs to be copied into the chrome space, then immediately deleted... ok, this seems like not a good approach. let us make it so that the permanentfile option is not available from the chrome app, but only if the native version is running. that way we sidestep the issue of the pexe not having access to the specified file. Speaking of native vs pexe, on the startup page we should have a radio button that allows the user to select which the GUI will talk to. It should default based on a self test to the more likely value, but it is possible that the user wants to use the native version, even if the pexe is running. another thing to have on the startup page is a simple login: THREE_STRINGS(SuperNET,login,passphrase,permanentfile,handle); ZERO_ARGS(SuperNET,logout); ZERO_ARGS(SuperNET,activehandle); the handle is a human readable name that is associated with the passphrase/permanentfile. There can only be one active account (though it will be possible to associate different accounts with tradebots). use the activehandle API to find out who is logged in and the associated addresses and pubkeys The above is not yet tested so if it doesnt work, dont fret, just let me know. Once set the handle can be displayed in various places to let the user know which account is logged in. The standard 12 dictionary word passphrases should be used, but any string can be sent in as the password for Pangea: INT_AND_ARRAY(pangea,host,minplayers,params); ZERO_ARGS(pangea,lobby); HASH_AND_STRING(pangea,join,tablehash,handle); HASH_AND_INT(pangea,buyin,tablehash,numchips); HASH_ARG(pangea,start,tablehash); // by host only HASH_ARG(pangea,status,tablehash); HASH_ARG(pangea,call,tablehash); HASH_ARG(pangea,check,tablehash); HASH_AND_INT(pangea,raise,tablehash,numchips); HASH_AND_INT(pangea,bet,tablehash,numchips); HASH_ARG(pangea,fold,tablehash); HASH_AND_STRING(pangea,mode,tablehash,modestr); HASH_ARG(pangea,history,tablehash); HASH_AND_INT(pangea,handhistory,tablehash,hand); The first thing that is done is a &#34;host&#34; by any node. the &#34;params&#34; should be an arbitrary json (like encryptjson) as it needs to be at the top level and it has quite a few different parameters still subject to change. The lobby API will just display all the hosted tables. once a table exists, players can join and then buyin. the buyin is denominated in chips, each chip&#39;s value is determined by the host&#39;s initial parameters. once there are enough players joined with adequate buyin&#39;s verified, the host will be able to do a start. if done before it will (eventually) give an error. for now it will just proceed. The host and players that have joined a tablehash, need to do regular status calls to see if the game has started. Probably just once per 5 or even 10 seconds is fine before the start. Once the game starts (the status will have this info) then once per second polling is needed. Then when it is your turn (as indicated by status) you need to do one of the 5 actions (fold, call, check, raise, bet). do not worry if you dont understand what all these do, just allow the user to do any of these. I guess it is possible to submit it ahead of time. I will support internally remembering the most recent action done prior to it being your turn. once it is your turn and an action is sent to the table, it is too late to change. The last API calls are for getting handhistory where hand is 0 to N-1, being the numbering of the hands played at that table. if just history, all the history for all hands at the table is coming back, so it could be quite big. probably I will make it a summary, but for the GUI just display the returned values. the mode is to change some poker specific modes, so just allow there to be a string entered. do not worry about understanding the pokerness of the API, just the overall flow: host -&gt; creates, join/buyin -&gt; fills up player slots, start -&gt; starts the game status -&gt; to determine when the game starts (or if it is cancelled) and once started actions -&gt; game specific but basically just (button + arg) that is the user input results are via status for current game and history for past ones please try to do the above logic in a generic way so it can be reused for other games. The basic flow should be the same for almost all multiplayer turn based games and even for multiplayer realtime games For InstantDEX: on the apikeypair/userid there needs to be two modes. one for when there is no stored apikey and the current form is fine, just need to make it wider as most apikeys are quite long. Now once there is an apikey saved all that is needed is the passphrase to unlock it. So here is where the encrptjson/decryptjson is used. When saving the apikey for the first time, it can be: a) not saved -&gt; nothing extra to do b) saved without password -&gt; you can just save to a file and use it to load it back in. use confs dir confs/instantdex.exchange.api or something like that c) saved with password (optional filename for native) -&gt; probably best to save in the confs dir to indicate that there is an encrypted file for this, so just that and not the actual passphrase in the file with the above, when the exchange is selected, you can see if the confs file exists and if it has the plaintext, just populate the field, if not, then indicate that a passphrase is needed. if the user provides the passphrase, then decryptjson and populate the fields and autosubmit. A special case is to encrypt the apikeys with the passphrase used when logging in. This is only available if the checkbox to &#34;remember passphrase during session&#34; is set on the main iguana login screen. (i forgot to mention that checkbox!) So the login passphrase is stored in memory, then the GUI simply uses that + encryptjson for storing/decrypting. I would imagine that storing in the confs file that it is encrypted using &#34;handle&#34;&#39;s account login might be a good way to differentiate between this mode of password usage. OK, so we now have the insecure plaintext, the decent using handle&#39;s passphrase and paranoid different passphrase for each exchange (with additional permanentfile for native versions) &#34;SUPPORT&#34; -&gt; &#34;SUPPORTS&#34; just a typo and &#34;allpairs&#34; API is missing from the selection Might as well add a &#34;tradebots&#34; tab: THREE_STRINGS_AND_DOUBLE(tradebot,monitor,exchange,base,rel,commission); STRING_AND_DOUBLE(tradebot,monitorall,exchange,commission); THREE_STRINGS(tradebot,unmonitor,exchange,base,rel); THREE_STRINGS_AND_THREE_DOUBLES(tradebot,accumulate,exchange,base,rel,pr ice,volume,duration); THREE_STRINGS_AND_THREE_DOUBLES(tradebot,divest,exchange,base,rel,price, volume,duration); STRING_ARG(tradebot,activebots,exchange); TWO_STRINGS(tradebot,status,exchange,botid); TWO_STRINGS(tradebot,pause,exchange,botid); TWO_STRINGS(tradebot,stop,exchange,botid); TWO_STRINGS(tradebot,resume,exchange,botid); the above are API for exchange specific bots, most should be self-explanatory. bots are created via &#34;accumulate&#34; or &#34;divest&#34; API call. it returns botid. once created, you can do status, pause, stop, resume to a botid. and an activebots API call lists all the active bots for an exchange. duration is in seconds the &#34;monitor&#34; API starts background monitoring of a specific base/rel, &#34;unmonitor&#34; stops this. &#34;monitorall&#34; just does a monitor to the entire list of &#34;allpairs&#34; for that exchange. Keep in mind that doing a monitorall will not add load to an exchange as the request to each exchange is governed by pollgap, but if you have 3 things monitored, it will take 3*pollgap + time each one takes to execute. and if N are monitored it is N*pollgap + time of each, with the &#34;time of each&#34; possibly taking a very long time. And one final request for today: Bitmap tab. It should be an active bitmap using mouse api. either a dropdown to select the bitmap or a form entry. then the rest of the page (resize the bitmap to the page size) being the active bitmap. So on a small screen the bitmap is smaller x/y dimensions and larger on larger screens. plz make sure the proper dimensions are communicated to the pexe via API if it ever is changed. @vineet.bhargav86: I changed the &#34;passphrase&#34; fieldname to &#34;password&#34; for the encryptjson/decryptjson related API. The reason is that the password is like a wallet password and is only local, so it doesnt need to be as high entropy as passphrase. I also added a field to the login API as I realized that the 12 word &#34;passphrase&#34; is the payload and usually wont be sent in: FOUR_STRINGS(SuperNET,login,handle,password,permanentfile,passphrase); using &#34;abiglongpassword&#34; for the passphrase -&gt; {&#34;pubkey&#34;:&#34;6c469ba10b40b3eb9d1dba569d7f929d55a29d8f97cd5425907ef2f38f906 209&#34;,&#34;RS&#34;:&#34;NXT-KGV9-DXX8-TM86-DXR96&#34;,&#34;NXT&#34;:&#34;12834974574569896807&#34;,&#34;btcpu bkey&#34;:&#34;024e7641dc947b211bc30fe3339765258902794687b227121fc217284f9d8503c 8&#34;,&#34;rmd160&#34;:&#34;33453c24914db7b77069b7ea24df44f6be145938&#34;,&#34;BTC&#34;:&#34;15g6QK2dSd iW9ZTQEnnJxKrSph6uP7uU23&#34;,&#34;BTCD&#34;:&#34;RDxHUpuv3TX5DZpbhxmS3rBeaxZW1fvYvC&#34;,&#34;r esult&#34;:&#34;success&#34;,&#34;handle&#34;:&#34;test&#34;,&#34;tag&#34;:&#34;14805226009240621255&#34;} and if you use that to log into NXT, it gives the same address. The BTC and BTCD addresses are all derived from the same privkey so they are all interchangeable with the NXT address. The user can therefore select which coin&#39;s addressing they are most comfortable with I also added an &#34;allin&#34; action API for pangea. all the action API will autocalculate the number of chips if passed in 0 for numchips ***************** security issue ******** please dont use the GET URL method when dealing with passphrase!!! Those URL&#39;s tend to get logged and available in browser histories. so anything dealing with the actual passphrase needs to use the postCall form or POST
9 years ago
FOUR_STRINGS(SuperNET,login,handle,password,permanentfile,passphrase)
{
char *str,*decryptstr = 0; cJSON *argjson;
if ( remoteaddr != 0 )
return(clonestr("{\"error\":\"no remote\"}"));
if ( bits256_nonz(myinfo->persistent_priv) != 0 && (str= SuperNET_logout(IGUANA_CALLARGS)) != 0 )
free(str);
if ( handle != 0 )
safecopy(myinfo->handle,handle,sizeof(myinfo->handle));
if ( (passphrase == 0 || passphrase[0] == 0) && (decryptstr= SuperNET_decryptjson(IGUANA_CALLARGS,password,permanentfile)) != 0 )
{
if ( (argjson= cJSON_Parse(decryptstr)) != 0 )
{
printf("decrypted.(%s)\n",decryptstr);
free(decryptstr);
9 years ago
if ( (passphrase= jstr(argjson,"passphrase")) != 0 )
many changes blockexplorer tab: needs to allow to input height, blockhash or txid. also please display images/BTC_blocks.jpg below the text as a w800 x h400 bitmap, which is active using the mouse api for coin management, below the active coins have a form that arbitrary json can be input with an add button to the right that will call &#34;addcoin&#34; API. this way I can test adding new coins dynamically. dont worry if it doesnt work, just as long as it submits the json to the C code. I am pretty sure I need to do some debugging of this peers management is not working for me at all. maybe it is due to bad internet. On initialization you need to read in the confs/BTCD_peers.txt from the native filesystem and save it into the chrome app filesystem. same thing for confs/BTCD_hdrs.txt. But this is only to be done if there isnt already such a file inside chrome. if there is, only do it upon a button invoked by the user. the reason is that the pexe is updating this file with the latest. Maybe it is nice to have an &#34;extract&#34; button that will copy out from the chrome storage into the native filesystem. There is also the manifest issue about localstorage vs chrome.localstorage. not sure what is needed to be done, but certainly a priority to get it so everything works as a chrome app. I know before it was making ramchain files inside the chrome filesystem, so it is probably things the GUI is doing. maybe in the settings tab, which has obsolete stuff that can be removed. anyway, the issue about files existing in the native filesystem -&gt; chrome and optionally extracting them is an issue for the confs files and .html template files used to autogenerate the port7778, maybe other files are affected. i think we need a way to have a list of hardcoded files that are just copied into chrome on startup if they dont exist already (or if possible copy over if the native version is bigger?) and buttons to extract them for debug tab: THREE_STRINGS(SuperNET,encryptjson,passphrase,permanentfile,anything); TWO_STRINGS(SuperNET,decryptjson,passphrase,permanentfile); at the top of page a way to put in passphrase and optional permanentfile along with arbitrary json. The standard form template has no easy way to describe to pass in everything as it is oriented to specific fields. but the encryptjson API saves all the fields, so the arbitrary json from the form needs to be combined at the same level as the &#34;agent&#34;, &#34;method&#34;, etc. I know, not the best, but internally it makes it easier. so {&#34;agent&#34;:&#34;SuperNET&#34;,&#34;method&#34;:&#34;encryptjson&#34;,&#34;passphrase&#34;:&#34;&lt;passphrase&gt;&#34;,&#34; permanentfile&#34;:&#34;&lt;filename&gt;&#34;,&#34;fromform&#34;:&#34;valuefromform&#34;,&#34;fromform2&#34;:&#34;valu efromform2&#34;,...rest of form at top level} then this will save it into a file with crazy number (it is a hash like txid) but given the same passphrase and filename, it will regenerate this hash so you dont actually have to store it, but it helps during debugging. for the filename, we must warn quite strongly to the user that if the file is ever lost or even changed in any way that the data will not be recoverable. also best to not allow the user to specify a file that does not exist. I think at this point chrome app version gets a bit tricky. we could simply push the native file into the chrome storage, but then an attacker who gets access to the computer could just get a list of these files and it really wont be much protection. So that means if a filename is specified, it needs to be copied into the chrome space, then immediately deleted... ok, this seems like not a good approach. let us make it so that the permanentfile option is not available from the chrome app, but only if the native version is running. that way we sidestep the issue of the pexe not having access to the specified file. Speaking of native vs pexe, on the startup page we should have a radio button that allows the user to select which the GUI will talk to. It should default based on a self test to the more likely value, but it is possible that the user wants to use the native version, even if the pexe is running. another thing to have on the startup page is a simple login: THREE_STRINGS(SuperNET,login,passphrase,permanentfile,handle); ZERO_ARGS(SuperNET,logout); ZERO_ARGS(SuperNET,activehandle); the handle is a human readable name that is associated with the passphrase/permanentfile. There can only be one active account (though it will be possible to associate different accounts with tradebots). use the activehandle API to find out who is logged in and the associated addresses and pubkeys The above is not yet tested so if it doesnt work, dont fret, just let me know. Once set the handle can be displayed in various places to let the user know which account is logged in. The standard 12 dictionary word passphrases should be used, but any string can be sent in as the password for Pangea: INT_AND_ARRAY(pangea,host,minplayers,params); ZERO_ARGS(pangea,lobby); HASH_AND_STRING(pangea,join,tablehash,handle); HASH_AND_INT(pangea,buyin,tablehash,numchips); HASH_ARG(pangea,start,tablehash); // by host only HASH_ARG(pangea,status,tablehash); HASH_ARG(pangea,call,tablehash); HASH_ARG(pangea,check,tablehash); HASH_AND_INT(pangea,raise,tablehash,numchips); HASH_AND_INT(pangea,bet,tablehash,numchips); HASH_ARG(pangea,fold,tablehash); HASH_AND_STRING(pangea,mode,tablehash,modestr); HASH_ARG(pangea,history,tablehash); HASH_AND_INT(pangea,handhistory,tablehash,hand); The first thing that is done is a &#34;host&#34; by any node. the &#34;params&#34; should be an arbitrary json (like encryptjson) as it needs to be at the top level and it has quite a few different parameters still subject to change. The lobby API will just display all the hosted tables. once a table exists, players can join and then buyin. the buyin is denominated in chips, each chip&#39;s value is determined by the host&#39;s initial parameters. once there are enough players joined with adequate buyin&#39;s verified, the host will be able to do a start. if done before it will (eventually) give an error. for now it will just proceed. The host and players that have joined a tablehash, need to do regular status calls to see if the game has started. Probably just once per 5 or even 10 seconds is fine before the start. Once the game starts (the status will have this info) then once per second polling is needed. Then when it is your turn (as indicated by status) you need to do one of the 5 actions (fold, call, check, raise, bet). do not worry if you dont understand what all these do, just allow the user to do any of these. I guess it is possible to submit it ahead of time. I will support internally remembering the most recent action done prior to it being your turn. once it is your turn and an action is sent to the table, it is too late to change. The last API calls are for getting handhistory where hand is 0 to N-1, being the numbering of the hands played at that table. if just history, all the history for all hands at the table is coming back, so it could be quite big. probably I will make it a summary, but for the GUI just display the returned values. the mode is to change some poker specific modes, so just allow there to be a string entered. do not worry about understanding the pokerness of the API, just the overall flow: host -&gt; creates, join/buyin -&gt; fills up player slots, start -&gt; starts the game status -&gt; to determine when the game starts (or if it is cancelled) and once started actions -&gt; game specific but basically just (button + arg) that is the user input results are via status for current game and history for past ones please try to do the above logic in a generic way so it can be reused for other games. The basic flow should be the same for almost all multiplayer turn based games and even for multiplayer realtime games For InstantDEX: on the apikeypair/userid there needs to be two modes. one for when there is no stored apikey and the current form is fine, just need to make it wider as most apikeys are quite long. Now once there is an apikey saved all that is needed is the passphrase to unlock it. So here is where the encrptjson/decryptjson is used. When saving the apikey for the first time, it can be: a) not saved -&gt; nothing extra to do b) saved without password -&gt; you can just save to a file and use it to load it back in. use confs dir confs/instantdex.exchange.api or something like that c) saved with password (optional filename for native) -&gt; probably best to save in the confs dir to indicate that there is an encrypted file for this, so just that and not the actual passphrase in the file with the above, when the exchange is selected, you can see if the confs file exists and if it has the plaintext, just populate the field, if not, then indicate that a passphrase is needed. if the user provides the passphrase, then decryptjson and populate the fields and autosubmit. A special case is to encrypt the apikeys with the passphrase used when logging in. This is only available if the checkbox to &#34;remember passphrase during session&#34; is set on the main iguana login screen. (i forgot to mention that checkbox!) So the login passphrase is stored in memory, then the GUI simply uses that + encryptjson for storing/decrypting. I would imagine that storing in the confs file that it is encrypted using &#34;handle&#34;&#39;s account login might be a good way to differentiate between this mode of password usage. OK, so we now have the insecure plaintext, the decent using handle&#39;s passphrase and paranoid different passphrase for each exchange (with additional permanentfile for native versions) &#34;SUPPORT&#34; -&gt; &#34;SUPPORTS&#34; just a typo and &#34;allpairs&#34; API is missing from the selection Might as well add a &#34;tradebots&#34; tab: THREE_STRINGS_AND_DOUBLE(tradebot,monitor,exchange,base,rel,commission); STRING_AND_DOUBLE(tradebot,monitorall,exchange,commission); THREE_STRINGS(tradebot,unmonitor,exchange,base,rel); THREE_STRINGS_AND_THREE_DOUBLES(tradebot,accumulate,exchange,base,rel,pr ice,volume,duration); THREE_STRINGS_AND_THREE_DOUBLES(tradebot,divest,exchange,base,rel,price, volume,duration); STRING_ARG(tradebot,activebots,exchange); TWO_STRINGS(tradebot,status,exchange,botid); TWO_STRINGS(tradebot,pause,exchange,botid); TWO_STRINGS(tradebot,stop,exchange,botid); TWO_STRINGS(tradebot,resume,exchange,botid); the above are API for exchange specific bots, most should be self-explanatory. bots are created via &#34;accumulate&#34; or &#34;divest&#34; API call. it returns botid. once created, you can do status, pause, stop, resume to a botid. and an activebots API call lists all the active bots for an exchange. duration is in seconds the &#34;monitor&#34; API starts background monitoring of a specific base/rel, &#34;unmonitor&#34; stops this. &#34;monitorall&#34; just does a monitor to the entire list of &#34;allpairs&#34; for that exchange. Keep in mind that doing a monitorall will not add load to an exchange as the request to each exchange is governed by pollgap, but if you have 3 things monitored, it will take 3*pollgap + time each one takes to execute. and if N are monitored it is N*pollgap + time of each, with the &#34;time of each&#34; possibly taking a very long time. And one final request for today: Bitmap tab. It should be an active bitmap using mouse api. either a dropdown to select the bitmap or a form entry. then the rest of the page (resize the bitmap to the page size) being the active bitmap. So on a small screen the bitmap is smaller x/y dimensions and larger on larger screens. plz make sure the proper dimensions are communicated to the pexe via API if it ever is changed. @vineet.bhargav86: I changed the &#34;passphrase&#34; fieldname to &#34;password&#34; for the encryptjson/decryptjson related API. The reason is that the password is like a wallet password and is only local, so it doesnt need to be as high entropy as passphrase. I also added a field to the login API as I realized that the 12 word &#34;passphrase&#34; is the payload and usually wont be sent in: FOUR_STRINGS(SuperNET,login,handle,password,permanentfile,passphrase); using &#34;abiglongpassword&#34; for the passphrase -&gt; {&#34;pubkey&#34;:&#34;6c469ba10b40b3eb9d1dba569d7f929d55a29d8f97cd5425907ef2f38f906 209&#34;,&#34;RS&#34;:&#34;NXT-KGV9-DXX8-TM86-DXR96&#34;,&#34;NXT&#34;:&#34;12834974574569896807&#34;,&#34;btcpu bkey&#34;:&#34;024e7641dc947b211bc30fe3339765258902794687b227121fc217284f9d8503c 8&#34;,&#34;rmd160&#34;:&#34;33453c24914db7b77069b7ea24df44f6be145938&#34;,&#34;BTC&#34;:&#34;15g6QK2dSd iW9ZTQEnnJxKrSph6uP7uU23&#34;,&#34;BTCD&#34;:&#34;RDxHUpuv3TX5DZpbhxmS3rBeaxZW1fvYvC&#34;,&#34;r esult&#34;:&#34;success&#34;,&#34;handle&#34;:&#34;test&#34;,&#34;tag&#34;:&#34;14805226009240621255&#34;} and if you use that to log into NXT, it gives the same address. The BTC and BTCD addresses are all derived from the same privkey so they are all interchangeable with the NXT address. The user can therefore select which coin&#39;s addressing they are most comfortable with I also added an &#34;allin&#34; action API for pangea. all the action API will autocalculate the number of chips if passed in 0 for numchips ***************** security issue ******** please dont use the GET URL method when dealing with passphrase!!! Those URL&#39;s tend to get logged and available in browser histories. so anything dealing with the actual passphrase needs to use the postCall form or POST
9 years ago
{
SuperNET_setkeys(myinfo,passphrase,(int32_t)strlen(passphrase),1);
free_json(argjson);
return(SuperNET_activehandle(IGUANA_CALLARGS));
}
else
{
free_json(argjson);
return(clonestr("{\"error\":\"cant find passphrase in decrypted json\"}"));
}
}
else
{
free(decryptstr);
return(clonestr("{\"error\":\"cant parse decrypted json\"}"));
}
}
if ( passphrase != 0 && passphrase[0] != 0 )
{
SuperNET_setkeys(myinfo,passphrase,(int32_t)strlen(passphrase),1);
if ( (str= SuperNET_encryptjson(IGUANA_CALLARGS,password,permanentfile,passphrase)) != 0 )
free(str);
return(SuperNET_activehandle(IGUANA_CALLARGS));
}
else return(clonestr("{\"error\":\"need passphrase\"}"));
printf("logged into (%s) %s %s\n",myinfo->myaddr.NXTADDR,myinfo->myaddr.BTC,myinfo->myaddr.BTCD);
return(SuperNET_activehandle(IGUANA_CALLARGS));
}
9 years ago
#include "../includes/iguana_apiundefs.h"