diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h
index a83393913..d1a85727e 100644
--- a/iguana/exchanges/LP_include.h
+++ b/iguana/exchanges/LP_include.h
@@ -172,7 +172,8 @@ struct LP_outpoint { bits256 spendtxid; uint64_t value,interest; int32_t spendvi
 struct LP_transaction
 {
     UT_hash_handle hh;
-    bits256 txid; int32_t height,numvouts,numvins; //uint32_t timestamp;
+    bits256 txid; int32_t height,numvouts,numvins,len; //uint32_t timestamp;
+    uint8_t *serialized;
     struct LP_outpoint outpoints[];
 };
 
@@ -303,6 +304,8 @@ struct LP_address *_LP_addressfind(struct iguana_info *coin,char *coinaddr);
 struct LP_address *_LP_addressadd(struct iguana_info *coin,char *coinaddr);
 int32_t iguana_signrawtransaction(void *ctx,char *symbol,uint8_t wiftaddr,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,struct iguana_msgtx *msgtx,char **signedtxp,bits256 *signedtxidp,struct vin_info *V,int32_t numinputs,char *rawtx,cJSON *vins,cJSON *privkeysjson);
 //void LP_butxo_swapfields_set(struct LP_utxoinfo *butxo);
+struct LP_address_utxo *LP_address_utxofind(struct iguana_info *coin,char *coinaddr,bits256 txid,int32_t vout);
+int32_t LP_destaddr(char *destaddr,cJSON *item);
 int32_t LP_waitmempool(char *symbol,char *coinaddr,bits256 txid,int32_t vout,int32_t duration);
 struct LP_transaction *LP_transactionfind(struct iguana_info *coin,bits256 txid);
 cJSON *LP_transactioninit(struct iguana_info *coin,bits256 txid,int32_t iter,cJSON *txobj);
@@ -310,10 +313,11 @@ int32_t LP_mempoolscan(char *symbol,bits256 searchtxid);
 int32_t LP_txheight(struct iguana_info *coin,bits256 txid);
 int32_t LP_address_utxoadd(struct iguana_info *coin,char *coinaddr,bits256 txid,int32_t vout,uint64_t value,int32_t height,int32_t spendheight);
 cJSON *LP_address_utxos(struct iguana_info *coin,char *coinaddr,int32_t electrumret);
-cJSON *LP_gettxout(char *symbol,bits256 txid,int32_t vout);
+cJSON *LP_gettxout(char *symbol,char *coinaddr,bits256 txid,int32_t vout);
 void LP_postutxos(char *symbol,char *coinaddr);
 int32_t LP_listunspent_both(char *symbol,char *coinaddr);
 uint16_t LP_randpeer(char *destip);
+cJSON *bitcoin_data2json(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,bits256 *txidp,struct iguana_msgtx *msgtx,uint8_t *extraspace,int32_t extralen,uint8_t *serialized,int32_t len,cJSON *vins,int32_t suppress_pubkeys);
 //int32_t LP_butxo_findeither(bits256 txid,int32_t vout);
 cJSON *LP_listunspent(char *symbol,char *coinaddr);
 int32_t LP_gettx_presence(char *symbol,bits256 expectedtxid);
diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c
index 93733a9b0..b7c9e04b0 100644
--- a/iguana/exchanges/LP_prices.c
+++ b/iguana/exchanges/LP_prices.c
@@ -394,10 +394,10 @@ double LP_pricecache(struct LP_quoteinfo *qp,char *base,char *rel,bits256 txid,i
                 ptr->price = 0.;
             printf("LP_pricecache: set %s/%s ptr->price %.8f\n",base,rel,ptr->price);
         }
-        printf("found %s/%s %.8f\n",base,rel,ptr->price);
+        printf(">>>>>>>>>> found %s/%s %.8f\n",base,rel,ptr->price);
         return(ptr->price);
     }
-    char str[65]; printf("cachemiss %s/%s %s/v%d\n",base,rel,bits256_str(str,txid),vout);
+    //char str[65]; printf("cachemiss %s/%s %s/v%d\n",base,rel,bits256_str(str,txid),vout);
     return(0.);
 }
 
diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c
index 3a632d6c1..deffe3bf6 100644
--- a/iguana/exchanges/LP_rpc.c
+++ b/iguana/exchanges/LP_rpc.c
@@ -243,7 +243,7 @@ cJSON *LP_paxprice(char *fiat)
 
 cJSON *LP_gettx(char *symbol,bits256 txid)
 {
-    char buf[128],str[65],*hexstr; int32_t len; bits256 checktxid; cJSON *retjson; struct iguana_info *coin; struct iguana_msgtx msgtx; uint8_t *extraspace,*serialized;
+    struct iguana_info *coin; char buf[512],str[65]; cJSON *retjson;
     if ( symbol == 0 || symbol[0] == 0 )
         return(cJSON_Parse("{\"error\":\"null symbol\"}"));
     coin = LP_coinfind(symbol);
@@ -258,49 +258,38 @@ cJSON *LP_gettx(char *symbol,bits256 txid)
     }
     else
     {
-        sprintf(buf,"[\"%s\"]",bits256_str(str,txid));
         if ( (retjson= electrum_transaction(symbol,coin->electrum,&retjson,txid)) != 0 )
-        {
-            hexstr = jprint(retjson,1);
-            if ( strlen(hexstr) > 20000 )
-            {
-                static uint32_t counter;
-                if ( counter++ < 3 )
-                    printf("rawtransaction too big %d\n",(int32_t)strlen(hexstr));
-                free(hexstr);
-                return(cJSON_Parse("{\"error\":\"transaction too big\"}"));
-            }
-            if ( hexstr[0] == '"' && hexstr[strlen(hexstr)-1] == '"' )
-                hexstr[strlen(hexstr)-1] = 0;
-            if ( (len= is_hexstr(hexstr+1,0)) > 2 )
-            {
-                memset(&msgtx,0,sizeof(msgtx));
-                len = (int32_t)strlen(hexstr+1) >> 1;
-                serialized = malloc(len);
-                decode_hex(serialized,len,hexstr+1);
-                free(hexstr);
-                //printf("DATA.(%s)\n",hexstr+1);
-                extraspace = calloc(1,1000000);
-                retjson = bitcoin_data2json(coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->height,&checktxid,&msgtx,extraspace,1000000,serialized,len,0,0);
-                free(serialized);
-                free(extraspace);
-                //printf("TX.(%s) match.%d\n",jprint(retjson,0),bits256_cmp(txid,checktxid));
-                return(retjson);
-            } else printf("non-hex tx.(%s)\n",hexstr);
-            free(hexstr);
-            return(cJSON_Parse("{\"error\":\"non hex transaction\"}"));
-        } else printf("failed blockchain.transaction.get %s %s\n",coin->symbol,buf);
+            return(retjson);
+        else printf("failed blockchain.transaction.get %s %s\n",coin->symbol,buf);
         return(cJSON_Parse("{\"error\":\"no transaction bytes\"}"));
     }
 }
 
-cJSON *LP_gettxout(char *symbol,bits256 txid,int32_t vout)
+cJSON *LP_gettxout_json(bits256 txid,int32_t vout,int32_t height,char *coinaddr,uint64_t value)
+{
+    cJSON *retjson,*addresses,*sobj;
+    retjson = cJSON_CreateObject();
+    jaddnum(retjson,"value",dstr(value));
+    jaddnum(retjson,"height",height);
+    jaddbits256(retjson,"txid",txid);
+    jaddnum(retjson,"vout",vout);
+    addresses = cJSON_CreateArray();
+    jaddistr(addresses,coinaddr);
+    sobj = cJSON_CreateObject();
+    jaddnum(sobj,"reqSigs",1);
+    jaddstr(sobj,"type","pubkey");
+    jadd(sobj,"addresses",addresses);
+    jadd(retjson,"scriptPubKey",sobj);
+    printf("GETTXOUT.(%s)\n",jprint(retjson,0));
+    return(retjson);
+}
+
+cJSON *LP_gettxout(char *symbol,char *coinaddr,bits256 txid,int32_t vout)
 {
-    char buf[128],str[65],coinaddr[64],*hexstr; uint64_t value; uint8_t *serialized; cJSON *sobj,*addresses,*item,*array,*hexobj,*retjson=0; int32_t i,n,v,len; bits256 t; struct iguana_info *coin;
+    char buf[128],str[65]; cJSON *item,*array,*vouts,*txobj,*retjson=0; int32_t i,v,n; bits256 t; struct iguana_info *coin; struct LP_transaction *tx; struct LP_address_utxo *up;
     if ( symbol == 0 || symbol[0] == 0 )
         return(cJSON_Parse("{\"error\":\"null symbol\"}"));
-    coin = LP_coinfind(symbol);
-    if ( coin == 0 )
+    if ( (coin= LP_coinfind(symbol)) == 0 )
         return(cJSON_Parse("{\"error\":\"no coin\"}"));
     if ( bits256_nonz(txid) == 0 )
         return(cJSON_Parse("{\"error\":\"null txid\"}"));
@@ -311,84 +300,52 @@ cJSON *LP_gettxout(char *symbol,bits256 txid,int32_t vout)
     }
     else
     {
-        printf("gettxout v%d\n",vout);
-        sprintf(buf,"[\"%s\"]",bits256_str(str,txid));
-        if ( (hexobj= electrum_transaction(symbol,coin->electrum,&hexobj,txid)) != 0 )
+        if ( (tx= LP_transactionfind(coin,txid)) != 0 && vout < tx->numvouts )
+        {
+            if ( tx->outpoints[vout].spendheight > 0 )
+                return(0);
+            return(LP_gettxout_json(txid,vout,tx->height,tx->outpoints[vout].coinaddr,tx->outpoints[vout].value));
+        }
+        if ( coinaddr[0] == 0 )
+        {
+            if ( (txobj= electrum_transaction(symbol,coin->electrum,&txobj,txid)) != 0 )
+            {
+                if ( (vouts= jarray(&n,txobj,"vout")) != 0 && n > 0 )
+                    LP_destaddr(coinaddr,jitem(vouts,vout));
+                free_json(txobj);
+            }
+        }
+        if ( coinaddr[0] != 0 )
         {
-            hexstr = jprint(hexobj,1);
-            if ( strlen(hexstr) > 20000 )
+            if ( (up= LP_address_utxofind(coin,coinaddr,txid,vout)) != 0 )
             {
-                static uint32_t counter;
-                if ( counter++ < 3 )
-                    printf("rawtransaction too big %d\n",(int32_t)strlen(hexstr));
-                free(hexstr);
-                return(cJSON_Parse("{\"error\":\"transaction too big\"}"));
+                if ( up->spendheight > 0 )
+                    return(0);
+                return(LP_gettxout_json(txid,vout,up->U.height,coinaddr,up->U.value));
             }
-            if ( hexstr[0] == '"' && hexstr[strlen(hexstr)-1] == '"' )
-                hexstr[strlen(hexstr)-1] = 0;
-            if ( (len= is_hexstr(hexstr+1,0)) > 2 )
+            if ( (array= electrum_address_listunspent(coin->symbol,0,&array,coinaddr)) != 0 )
             {
-                len = (int32_t)strlen(hexstr+1) >> 1;
-                serialized = malloc(len);
-                decode_hex(serialized,len,hexstr+1);
-                LP_swap_coinaddr(coin,coinaddr,&value,serialized,len,vout);
-                //printf("HEX.(%s) len.%d %s %.8f\n",hexstr+1,len,coinaddr,dstr(value));
-                free(hexstr);
-                if ( (array= electrum_address_listunspent(coin->symbol,0,&array,coinaddr)) != 0 )
+                //printf("array.(%s)\n",jprint(array,0));
+                if ( array != 0 && (n= cJSON_GetArraySize(array)) > 0 )
                 {
-                    //printf("array.(%s)\n",jprint(array,0));
-                    if ( array != 0 && (n= cJSON_GetArraySize(array)) > 0 )
+                    for (i=0; i<n; i++)
                     {
-                        for (i=0; i<n; i++)
+                        item = jitem(array,i);
+                        t = jbits256(item,"tx_hash");
+                        v = jint(item,"tx_pos");
+                        if ( v == vout && bits256_cmp(t,txid) == 0 )
                         {
-                            item = jitem(array,i);
-                            t = jbits256(item,"tx_hash");
-                            v = jint(item,"tx_pos");
-                            if ( v == vout && bits256_cmp(t,txid) == 0 )
-                            {
-                                retjson = cJSON_CreateObject();
-                                /*{
-                                    "bestblock": "002f7bbe3973b735f535d472501962e86ce8dbc76c73ac5a310a905931b907fa",
-                                    "confirmations": 7,
-                                    "value": 2013.10431750,
-                                    "scriptPubKey": {
-                                        "asm": "03b7621b44118017a16043f19b30cc8a4cfe068ac4e42417bae16ba460c80f3828 OP_CHECKSIG",
-                                        "hex": "2103b7621b44118017a16043f19b30cc8a4cfe068ac4e42417bae16ba460c80f3828ac",
-                                        "reqSigs": 1,
-                                        "type": "pubkey",
-                                        "addresses": [
-                                                      "RNJmgYaFF5DbnrNUX6pMYz9rcnDKC2tuAc"
-                                                      ]
-                                    },
-                                    "version": 1,
-                                    "coinbase": false
-                                }*/
-                                if ( value != j64bits(item,"value") )
-                                    printf("LP_gettxout: value %llu != %llu\n",(long long)value,(long long)j64bits(item,"value"));
-                                jaddnum(retjson,"value",dstr(value));
-                                jaddbits256(retjson,"txid",t);
-                                jaddnum(retjson,"vout",v);
-                                addresses = cJSON_CreateArray();
-                                jaddistr(addresses,coinaddr);
-                                sobj = cJSON_CreateObject();
-                                jaddnum(sobj,"reqSigs",1);
-                                jaddstr(sobj,"type","pubkey");
-                                jadd(sobj,"addresses",addresses);
-                                jadd(retjson,"scriptPubKey",sobj);
-                                printf("GETTXOUT.(%s)\n",jprint(retjson,0));
-                                break;
-                            }
+                            retjson = LP_gettxout_json(txid,vout,jint(item,"height"),coinaddr,j64bits(item,"value"));
+                            break;
                         }
                     }
-                    free_json(array);
                 }
-            } else free(hexstr);
-            if ( retjson == 0 )
-            {
-                
+                free_json(array);
+                if ( retjson != 0 )
+                    return(retjson);
             }
-            return(retjson);
         }
+        printf("couldnt find %s/v%d\n",bits256_str(str,txid),vout);
         return(cJSON_Parse("{\"error\":\"couldnt get tx\"}"));
     }
 }
diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c
index f4809d1f1..1a953c9af 100644
--- a/iguana/exchanges/LP_socket.c
+++ b/iguana/exchanges/LP_socket.c
@@ -310,7 +310,7 @@ int32_t electrum_process_array(struct iguana_info *coin,struct electrum_info *ep
                 v = jint(item,"vout");
                 value = LP_value_extract(item,0);
                 ht = LP_txheight(coin,txid);
-                if ( (retjson= LP_gettxout(coin->symbol,txid,v)) != 0 )
+                if ( (retjson= LP_gettxout(coin->symbol,coinaddr,txid,v)) != 0 )
                     free_json(retjson);
                 else
                 {
@@ -527,12 +527,79 @@ cJSON *electrum_estimatefee(char *symbol,struct electrum_info *ep,cJSON **retjso
 cJSON *electrum_getheader(char *symbol,struct electrum_info *ep,cJSON **retjsonp,int32_t n) { return(electrum_intarg(symbol,ep,retjsonp,"blockchain.block.get_header",n,ELECTRUM_TIMEOUT)); }
 cJSON *electrum_getchunk(char *symbol,struct electrum_info *ep,cJSON **retjsonp,int32_t n) { return(electrum_intarg(symbol,ep,retjsonp,"blockchain.block.get_chunk",n,ELECTRUM_TIMEOUT)); }
 
+cJSON *LP_transaction_fromdata(struct iguana_info *coin,bits256 txid,uint8_t *serialized,int32_t len)
+{
+    uint8_t *extraspace; cJSON *txobj; char str[65],str2[65]; struct iguana_msgtx msgtx; bits256 checktxid;
+    extraspace = calloc(1,1000000);
+    memset(&msgtx,0,sizeof(msgtx));
+    txobj = bitcoin_data2json(coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->height,&checktxid,&msgtx,extraspace,1000000,serialized,len,0,0);
+    //printf("TX.(%s) match.%d\n",jprint(retjson,0),bits256_cmp(txid,checktxid));
+    free(extraspace);
+    if ( bits256_cmp(txid,checktxid) != 0 )
+    {
+        printf("LP_transaction_fromdata mismatched txid %s vs %s\n",bits256_str(str,txid),bits256_str(str2,checktxid));
+        free_json(txobj);
+        txobj = 0;
+    }
+    return(txobj);
+}
+
 cJSON *electrum_transaction(char *symbol,struct electrum_info *ep,cJSON **retjsonp,bits256 txid)
 {
-    char str[65]; printf("%s add cache here -> TRANSACTION.(%s)\n",symbol,bits256_str(str,txid));
-    if ( bits256_nonz(txid) != 0 )
-        return(electrum_hasharg(symbol,ep,retjsonp,"blockchain.transaction.get",txid,ELECTRUM_TIMEOUT));
-    else return(cJSON_Parse("{\"error\":\"null txid\"}"));
+    char *hexstr,str[65]; int32_t len; cJSON *hexjson,*txobj=0; struct iguana_info *coin; uint8_t *serialized; struct LP_transaction *tx;
+    if ( bits256_nonz(txid) != 0 && (coin= LP_coinfind(symbol)) != 0 )
+    {
+        if ( (tx= LP_transactionfind(coin,txid)) != 0 && tx->serialized != 0 )
+        {
+            char str[65]; printf("%s cache hit -> TRANSACTION.(%s)\n",symbol,bits256_str(str,txid));
+            if ( (txobj= LP_transaction_fromdata(coin,txid,tx->serialized,tx->len)) != 0 )
+            {
+                *retjsonp = txobj;
+                return(txobj);
+            }
+        }
+        hexjson = electrum_hasharg(symbol,ep,&hexjson,"blockchain.transaction.get",txid,ELECTRUM_TIMEOUT);
+        hexstr = jprint(hexjson,1);
+        if ( strlen(hexstr) > 60000 )
+        {
+            static uint32_t counter;
+            if ( counter++ < 3 )
+                printf("rawtransaction too big %d\n",(int32_t)strlen(hexstr));
+            free(hexstr);
+            *retjsonp = cJSON_Parse("{\"error\":\"transaction too big\"}");
+            return(*retjsonp);
+        }
+        if ( hexstr[0] == '"' && hexstr[strlen(hexstr)-1] == '"' )
+            hexstr[strlen(hexstr)-1] = 0;
+        if ( (len= is_hexstr(hexstr+1,0)) > 2 )
+        {
+            len = (int32_t)strlen(hexstr+1) >> 1;
+            serialized = malloc(len);
+            decode_hex(serialized,len,hexstr+1);
+            free(hexstr);
+            //printf("DATA.(%s)\n",hexstr+1);
+            if ( (tx= LP_transactionfind(coin,txid)) == 0 || tx->serialized == 0 )
+            {
+                txobj = LP_transactioninit(coin,txid,0,0);
+                LP_transactioninit(coin,txid,1,txobj);
+                if ( (tx= LP_transactionfind(coin,txid)) != 0 )
+                {
+                    tx->serialized = serialized;
+                    tx->len = len;
+                }
+                else
+                {
+                    printf("unexpected couldnt find tx %s %s\n",coin->symbol,bits256_str(str,txid));
+                    free(serialized);
+                }
+            }
+            *retjsonp = txobj;
+            return(*retjsonp);
+        } else printf("non-hex tx.(%s)\n",hexstr);
+        free(hexstr);
+    }
+    *retjsonp = cJSON_Parse("{\"error\":\"null txid\"}");
+    return(*retjsonp);
 }
 
 cJSON *electrum_getmerkle(char *symbol,struct electrum_info *ep,cJSON **retjsonp,bits256 txid,int32_t height)
diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c
index b109e3130..202af4e49 100644
--- a/iguana/exchanges/LP_utxo.c
+++ b/iguana/exchanges/LP_utxo.c
@@ -332,7 +332,7 @@ int32_t LP_unspents_array(struct iguana_info *coin,char *coinaddr,cJSON *array)
         val = j64bits(item,"value");
         //if ( strcmp(coin->symbol,"LBC") == 0 )
         //    printf("(%s)\n",jprint(item,0));
-        if ( coin->electrum == 0 && (txobj= LP_gettxout(coin->symbol,txid,v)) != 0 )
+        if ( coin->electrum == 0 && (txobj= LP_gettxout(coin->symbol,coinaddr,txid,v)) != 0 )
         {
             value = LP_value_extract(txobj,0);
             if ( value != 0 && value != val )
@@ -475,7 +475,7 @@ uint64_t LP_txinterestvalue(uint64_t *interestp,char *destaddr,struct iguana_inf
     uint64_t interest,value = 0; cJSON *txobj;
     *interestp = 0;
     destaddr[0] = 0;
-    if ( (txobj= LP_gettxout(coin->symbol,txid,vout)) != 0 )
+    if ( (txobj= LP_gettxout(coin->symbol,destaddr,txid,vout)) != 0 )
     {
         if ( (value= LP_value_extract(txobj,0)) == 0 )
         {
@@ -591,7 +591,7 @@ int32_t LP_numconfirms(char *symbol,char *coinaddr,bits256 txid,int32_t vout,int
     if ( coin->electrum == 0 )
     {
         numconfirms = -1;
-        if ( (txobj= LP_gettxout(symbol,txid,vout)) != 0 )
+        if ( (txobj= LP_gettxout(symbol,coinaddr,txid,vout)) != 0 )
         {
             numconfirms = jint(txobj,"confirmations");
             free_json(txobj);
@@ -663,7 +663,7 @@ uint64_t LP_txvalue(char *coinaddr,char *symbol,bits256 txid,int32_t vout)
     }
     else
     {
-        if ( (txobj= LP_gettxout(coin->symbol,txid,vout)) != 0 )
+        if ( (txobj= LP_gettxout(coin->symbol,coinaddr,txid,vout)) != 0 )
         {
             value = LP_value_extract(txobj,0);//SATOSHIDEN * (jdouble(txobj,"value") + jdouble(txobj,"interest"));
             if ( coinaddr == 0 )