diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 585e68745..be3c73466 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -164,6 +164,7 @@ calcaddress(passphrase)\n\ instantdex_deposit(weeks, amount, broadcast=1)\n\ instantdex_claim()\n\ timelock(coin, duration, destaddr=(tradeaddr), amount)\n\ +unlockedspend(coin, txid)\n\ jpg(srcfile, destfile, power2=7, password, data="", required, ind=0)\n\ \"}")); //sell(base, rel, price, basevolume, timeout=10, duration=3600)\n\ @@ -516,6 +517,10 @@ jpg(srcfile, destfile, power2=7, password, data="", required, ind=0)\n\ { return(LP_timelock(coin,juint(argjson,"duration"),jstr(argjson,"destaddr"),jdouble(argjson,"amount")*SATOSHIDEN)); } + else if ( strcmp(method,"unlockedspend") == 0 ) + { + return(LP_unlockedspend(ctx,coin,jbits256(argjson,"txid"))); + } else if ( strcmp(method,"getrawtransaction") == 0 ) { return(jprint(LP_gettx(coin,jbits256(argjson,"txid"),0),1)); diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index 019e5e644..9552ab367 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -164,35 +164,6 @@ int32_t LP_deposit_addr(char *symbol,char *p2shaddr,uint8_t *script,uint8_t tadd return(n); } -char *LP_timelock(char *symbol,uint32_t duration,char *destaddr,uint64_t satoshis) -{ - struct iguana_info *coin; uint32_t expiration; char *retstr,p2shaddr[64],redeemscript[256]; cJSON *argjson,*array,*item; int32_t n=0; uint8_t addrtype,rmd160[20],p2sh160[20],script[40]; - if ( (coin= LP_coinfind(symbol)) != 0 ) - { - expiration = (uint32_t)time(NULL) + duration; - if ( destaddr == 0 ) - destaddr = coin->smartaddr; - bitcoin_addr2rmd160(symbol,coin->taddr,&addrtype,rmd160,destaddr); - n = bitcoin_timelockspend(script,0,rmd160,expiration); - init_hexbytes_noT(redeemscript,script,n); - calc_rmd160_sha256(p2sh160,script,n); - bitcoin_address(symbol,p2shaddr,coin->taddr,coin->p2shtype,p2sh160,20); - argjson = cJSON_CreateObject(); - array = cJSON_CreateArray(); - item = cJSON_CreateObject(); - jaddnum(item,p2shaddr,dstr(satoshis)); - jaddi(array,item); - jadd(argjson,"outputs",array); - jaddstr(argjson,"opreturn",redeemscript); - //printf("deposit.(%s)\n",jprint(argjson,0)); - if ( (retstr= LP_withdraw(coin,argjson)) != 0 ) - { - printf("timelock.(%s)\n",retstr); - return(retstr); - } else return(clonestr("{\"error\":\"null return from LP_withdraw\"}")); - } else return(clonestr("{\"error\":\"cant find coin\"}")); -} - char *LP_instantdex_deposit(struct iguana_info *coin,int32_t weeks,double amount,int32_t broadcast) { char p2shaddr[64],*retstr,*hexstr; uint8_t script[512]; int32_t weeki,scriptlen; cJSON *argjson,*retjson,*array,*item,*obj; uint32_t timestamp; bits256 txid,sendtxid; uint64_t amount64; @@ -314,6 +285,112 @@ int64_t LP_claimtx(void *ctx,struct iguana_info *coin,bits256 *claimtxidp,bits25 return(sum); } +uint32_t LP_claimtime(struct iguana_info *coin,uint32_t expiration) +{ + uint32_t heighttime,now = (uint32_t)time(NULL); + heighttime = LP_heighttime(coin->symbol,coin->height); + printf("claimtime: now %u height.%d heighttime.%u expiration.%u\n",now,coin->height,heighttime,expiration); + if ( heighttime >= expiration ) + return(heighttime + 1); + return(0); +} + +char *LP_unlockedspend(void *ctx,char *symbol,bits256 utxotxid) +{ + cJSON *txjson,*vouts,*vout0,*opret,*sobj,*retjson; uint16_t utxovout; char *signedtx,*opretstr,vinaddr[64],destaddr[64]; uint32_t expiration,claimtime; uint8_t redeemscript[128]; bits256 signedtxid,sendtxid; int32_t numvouts,redeemlen; int64_t satoshis,destamount; struct iguana_info *coin; + if ( (coin= LP_coinfind(symbol)) == 0 ) + return(clonestr("{\"error\":\"cant find coin\"}")); + retjson = cJSON_CreateObject(); + utxovout = 0; + memset(&sendtxid,0,sizeof(sendtxid)); + if ( (txjson= LP_gettx(coin->symbol,utxotxid,1)) != 0 ) + { + if ( (vouts= jarray(&numvouts,txjson,"vout")) != 0 && numvouts >= 2 ) + { + vout0 = jitem(vouts,0); + LP_destaddr(vinaddr,vout0); + satoshis = LP_value_extract(vout0,0); + opret = jitem(vouts,numvouts - 1); + jaddstr(retjson,"result","success"); + jaddbits256(retjson,"lockedtxid",utxotxid); + jaddnum(retjson,"amount",dstr(satoshis)); + if ( (sobj= jobj(opret,"scriptPubKey")) != 0 ) + { + if ( (opretstr= jstr(sobj,"hex")) != 0 ) + { + jaddstr(retjson,"opreturn",opretstr); + redeemlen = (int32_t)strlen(opretstr) >> 1; + if ( redeemlen == 34 ) + { + decode_hex(redeemscript,redeemlen,opretstr); + if ( redeemscript[0] == SCRIPT_OP_RETURN && redeemscript[1] == 32 && redeemscript[2] == 4 && redeemscript[7] == 0xb1 && redeemscript[8] == 0x75 && redeemscript[9] == 0x76 && redeemscript[10] == 0xa9 && redeemscript[11] == 0x14 && redeemscript[32] == 0x88 && redeemscript[33] == 0xac ) + { + expiration = 0; + expiration = (expiration << 8) | redeemscript[3]; + expiration = (expiration << 8) | redeemscript[4]; + expiration = (expiration << 8) | redeemscript[5]; + expiration = (expiration << 8) | redeemscript[6]; + bitcoin_address(symbol,destaddr,coin->taddr,coin->pubtype,&redeemscript[12],20); + jaddstr(retjson,"address",destaddr); + jaddnum(retjson,"expiration",expiration); + claimtime = LP_claimtime(coin,expiration); + jaddnum(retjson,"claimtime",claimtime); + if ( claimtime != 0 && strcmp(destaddr,coin->smartaddr) == 0 && time(NULL) > expiration ) + { + char str[65]; printf("LP_timespend satoshis %.8f %s/v%d\n",dstr(satoshis - coin->txfee),bits256_str(str,utxotxid),utxovout); + if ( (signedtx= basilisk_swap_bobtxspend(&signedtxid,coin->txfee,"timespend",coin->symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,ctx,G.LP_privkey,0,redeemscript+2,redeemlen-2,0,0,utxotxid,utxovout,coin->smartaddr,G.LP_pubsecp,0,claimtime,&destamount,0,0,vinaddr,0,coin->zcash)) != 0 ) + { + //sendtxid = LP_broadcast("timespend",symbol,signedtx,signedtxid); + jaddstr(retjson,"signedtx",signedtx); + jaddbits256(retjson,"txid",signedtxid); + if ( bits256_cmp(sendtxid,signedtxid) == 0 ) + jaddbits256(retjson,"sendtxid",sendtxid); + else printf("error sending %s\n",bits256_str(str,signedtxid)); + free(signedtx); + } + else + { + printf("error doing timespend %s/v%d %.8f\n",bits256_str(str,utxotxid),utxovout,dstr(satoshis)); + jaddstr(retjson,"error","couldnt sign timespend"); + } + } + } else jaddstr(retjson,"error","mismatched redeemscript"); + } + } + } + } + free_json(txjson); + } + return(jprint(retjson,1)); +} + +char *LP_timelock(char *symbol,uint32_t duration,char *destaddr,uint64_t satoshis) +{ + struct iguana_info *coin; uint32_t expiration; char *retstr,p2shaddr[64],redeemscript[256]; cJSON *argjson,*array,*item; int32_t n=0; uint8_t addrtype,rmd160[20],p2sh160[20],script[40]; + if ( (coin= LP_coinfind(symbol)) != 0 ) + { + expiration = (uint32_t)time(NULL) + duration; + if ( destaddr == 0 ) + destaddr = coin->smartaddr; + bitcoin_addr2rmd160(symbol,coin->taddr,&addrtype,rmd160,destaddr); + n = bitcoin_timelockspend(script,0,rmd160,expiration); + init_hexbytes_noT(redeemscript,script,n); + calc_rmd160_sha256(p2sh160,script,n); + bitcoin_address(symbol,p2shaddr,coin->taddr,coin->p2shtype,p2sh160,20); + argjson = cJSON_CreateObject(); + array = cJSON_CreateArray(); + item = cJSON_CreateObject(); + jaddnum(item,p2shaddr,dstr(satoshis + coin->txfee)); + jaddi(array,item); + jadd(argjson,"outputs",array); + jaddstr(argjson,"opreturn",redeemscript); + //printf("deposit.(%s)\n",jprint(argjson,0)); + if ( (retstr= LP_withdraw(coin,argjson)) != 0 ) + return(retstr); + else return(clonestr("{\"error\":\"timelock got null return from LP_withdraw\"}")); + } else return(clonestr("{\"error\":\"cant find coin\"}")); +} + int32_t LP_claim_submit(void *ctx,cJSON *txids,int64_t *sump,struct iguana_info *coin,bits256 utxotxid) { uint8_t redeemscript[512]; bits256 claimtxid; cJSON *txjson,*vout0,*vout1,*vout2,*vouts,*item; int32_t numvouts; char str[65],vinaddr[64],destaddr[64],checkaddr[64]; int32_t j,utxovout,flagi = 0,redeemlen,weeki,iter; int64_t weeksatoshis,satoshis; uint32_t expiration,claimtime; diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 715e027f1..9b9372cf9 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -498,11 +498,15 @@ int32_t LP_connectstartbob(void *ctx,int32_t pubsock,char *base,char *rel,double if ( (kmdcoin= LP_coinfind("KMD")) != 0 ) jadd(reqjson,"proof",LP_instantdex_txids(0,kmdcoin->smartaddr)); //char str[65]; printf("BOB pubsock.%d binds to %d (%s)\n",pubsock,pair,bits256_str(str,qp->desthash)); + LP_importaddress(qp->destcoin,qp->destaddr); + LP_otheraddress(qp->srccoin,otheraddr,qp->destcoin,qp->destaddr); + LP_importaddress(qp->srccoin,otheraddr); bits256 zero; memset(zero.bytes,0,sizeof(zero)); - for (i=0; i<3; i++) + for (i=0; i<1; i++) { LP_reserved_msg(1,qp->srccoin,qp->destcoin,qp->desthash,jprint(reqjson,0)); + break; sleep(10); if ( swap->received != 0 ) { @@ -513,9 +517,6 @@ int32_t LP_connectstartbob(void *ctx,int32_t pubsock,char *base,char *rel,double LP_reserved_msg(1,qp->srccoin,qp->destcoin,zero,jprint(reqjson,0)); } free_json(reqjson); - LP_importaddress(qp->destcoin,qp->destaddr); - LP_otheraddress(qp->srccoin,otheraddr,qp->destcoin,qp->destaddr); - LP_importaddress(qp->srccoin,otheraddr); retval = 0; } else printf("error launching swaploop\n"); } else printf("couldnt bind to any port %s\n",pairstr); diff --git a/iguana/exchanges/unlockedspend b/iguana/exchanges/unlockedspend new file mode 100755 index 000000000..f6f40c191 --- /dev/null +++ b/iguana/exchanges/unlockedspend @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"unlockedspend\",\"coin\":\"KMD\",\"txid\":\"e858e382a816b4cab22e3fd3e29901c7ef497cd1fdad7683314cc9187eca34fd\"}"