github.com/piotrnar/gocoin@v0.0.0-20240512203912-faa0448c5e96/client/www/templates/send.html (about) 1 <script type="text/javascript" src="webui/crypto.js"></script> 2 <script type="text/javascript" src="webui/bech32.js"></script> 3 <div id="light" class="white_content"> 4 <table width="100%"><tr> 5 <td><h3><b class="mono" id="disp_txid"></b></h3> 6 <td align="right"><img title="Close this popup" src="webui/close.png" class="hand" onclick="closepopup_x(false)"> 7 </table> 8 <pre id="rawdiv" style="background-color:white"></pre> 9 </div><div id="fade" class="black_overlay"></div> 10 11 <style> 12 td.inpid { 13 text-align: left; 14 font-size: 90%; 15 font-family: monospace; 16 } 17 td.P2SH-P2WPKH { 18 color:brown; 19 font-style:italic; 20 } 21 td.P2WSH { 22 color:purple; 23 font-style:italic; 24 } 25 td.P2WPKH { 26 color:darkgreen; 27 font-style:italic; 28 } 29 td.P2TAP { 30 color:blue; 31 font-style:italic; 32 } 33 td.long_addr { 34 font-size:9px; 35 } 36 </style> 37 <script> 38 const addrbook_lab = "Address Book" 39 40 const AvgOutputSize = 34 41 42 var selected_value = 0 43 var ets_inputs = 0 44 var witness_size = 0 45 var non_segwit_cnt = 0 46 var first_input_addr = '' 47 var selected_cnt = 0 48 var total_to_pay = 0 49 var cur_but = null 50 51 var wallet = new Array() 52 var addrbook = new Array() 53 var basic_addrbook_len = 0 // without the wallets virgin addrs 54 var auto_transalte_to_segwit = false 55 var auto_transalte_to_segwit_p2sh = false 56 var auto_transalte_to_segwit_tap = false 57 58 const ADDR_LIST_SIZE = 15 59 60 function build_change_list() { 61 var virgincounter = 0 62 while (changeaddrsel.options.length>1) changeaddrsel.remove(1) 63 //changeaddrsel.options = [changeaddrsel.options[0]] 64 for (var i=0; i<wallet.length; i++) { 65 var wpkh = '' 66 var op = document.createElement("option") 67 if (wallet[i].virgin) { 68 op.text = "* " 69 } 70 71 wpkh = translate_address(wallet[i].addr) 72 73 if (wpkh != '') { 74 op.text += 'SW:' + wallet[i].label 75 op.text += " - " + wpkh 76 op.value = wpkh 77 } else { 78 op.text += wallet[i].label 79 op.text += " - " + wallet[i].addr 80 op.value = wallet[i].addr 81 } 82 83 if (wallet[i].virgin) { 84 virgincounter++ 85 changeaddrsel.add(op, changeaddrsel[virgincounter]) 86 } else { 87 changeaddrsel.add(op) 88 } 89 } 90 } 91 92 93 function show_input_tx() { 94 var aj = ajax() 95 var vout = parseInt(this["vout"]) 96 aj.onreadystatechange=function() { 97 if(aj.readyState==4) { 98 var sta = xval(aj.responseXML, "status") 99 if (sta!="OK") { 100 alert(sta) 101 return 102 } 103 disp_txid.innerHTML = xval(aj.responseXML, "id") 104 105 var s = '' 106 var tout = 0 107 108 s += 'Len: ' + xval(aj.responseXML, "size") + '\n' 109 s += "Total inputs: " + aj.responseXML.getElementsByTagName('input').length + "\n" 110 s += "\n" 111 112 var is = aj.responseXML.getElementsByTagName('output') 113 for (var i=0; i<is.length; i++) { 114 s += (i+1) + ") " 115 var val = parseInt(xval(is[i], "value")) 116 tout += val 117 s += (parseFloat(val)/1e8).toFixed(8) 118 s += " BTC => " + xval(is[i], "addr") 119 if (i==vout) s += " <-------------------------------" 120 s += "\n" 121 } 122 s += "Total output: " + (parseFloat(tout)/1e8).toFixed(8) + " BTC\n" 123 124 rawdiv.innerHTML = s 125 126 if (prvpos==null) { 127 fade.addEventListener('click', closepopup) 128 fade.style.cursor = 'pointer' 129 fade.title = 'Click here to close the popup' 130 } 131 prvpos = document.body.scrollTop 132 window.scrollTo(0,0) 133 134 light.style.display='block' 135 fade.style.display='block' 136 document.addEventListener("scroll", noscroll) 137 } 138 } 139 aj.open("GET","txs2s.xml?minedid="+this["txid"]+'&minedat='+this["block"]+'&sid='+sid, true); 140 aj.send(null); 141 } 142 143 function fetch_wallet_balance(name) { 144 var curr_wallet_raw = localStorage.getItem("gocoinWal_"+name) 145 auto_transalte_to_segwit = curr_wallet_raw.indexOf("SegWit") != -1 146 if (auto_transalte_to_segwit) { 147 auto_transalte_to_segwit_p2sh = curr_wallet_raw.indexOf("SegWit P2SH") != -1 148 if (!auto_transalte_to_segwit_p2sh) { 149 auto_transalte_to_segwit_tap = curr_wallet_raw.indexOf("SegWit Tap") != -1 150 } 151 } 152 153 wallet = parse_wallet(curr_wallet_raw) 154 var wallet_addr = new Array() 155 156 for (var i=0; i<wallet.length; i++) { 157 wallet_addr.push(wallet[i].addr) 158 } 159 160 while (unspent.rows.length>1) { 161 unspent.deleteRow(1) 162 } 163 164 var aj = ajax() 165 aj.onerror=function() { 166 console.log("onerror") 167 } 168 169 aj.onload=function() { 170 try { 171 var totbtc = 0 172 var totouts = 0 173 bal = JSON.parse(aj.responseText) 174 var outs = new Array() 175 var i, ii 176 for (i in wallet) { 177 var rec = bal[wallet[i].addr] 178 if (typeof(rec)=='undefined') continue 179 if (rec.Outs!=null) { 180 totouts += rec.Outs.length 181 for (ii in rec.Outs) { 182 var ty = rec.Outs[ii].AddrType 183 if (ty=='P2PKH') { 184 var ad = rec.Outs[ii].Addr 185 if (ad.substr(0,3)=="bc1" || ad.substr(0,3)=="tb1") { 186 ty = ad.length > 45 ? "P2WSH" : "P2WPKH" 187 } 188 } 189 outs.push({'block':rec.Outs[ii].Height, 'txid':rec.Outs[ii].TxId, 190 'vout':rec.Outs[ii].Vout, 'value':rec.Outs[ii].Value, 191 'addr':wallet[i].addr, 'label':wallet[i].label, 192 'addr2':rec.Outs[ii].Addr, 'msg':rec.Outs[ii].Message, 'type':ty}) 193 } 194 } 195 totbtc += rec.Value 196 } 197 outs.sort(function(a,b){ 198 if (a.block == b.block) return 0 199 return (a.block > b.block) ? 1 : -1; 200 }) 201 202 outcnt_val.value = outs.length 203 for (i in outs) { 204 var row_number = parseInt(i)+1 205 var inp, td, row = unspent.insertRow(-1) 206 row.className = "how" 207 row["addr"] = outs[i].addr2 208 row["value"] = outs[i].value 209 row["label"] = outs[i].label 210 211 inp = document.createElement('input') 212 inp.type = 'hidden' 213 inp.name = "txid"+row_number 214 inp.value = outs[i].txid 215 row.appendChild(inp) 216 217 inp = document.createElement('input') 218 inp.type = 'hidden' 219 inp.name = "txvout"+row_number 220 inp.value = outs[i].vout 221 row.appendChild(inp) 222 223 inp = document.createElement('input') 224 inp.type = 'hidden' 225 inp.id = "txsigsiz"+row_number 226 inp["segwit_size"] = 0 227 if (outs[i].type=="P2PKH") { 228 inp.value = 72 + 34 // pub_key + signature 229 } else if (outs[i].type=="P2WPSH") { 230 inp.value = 23 // P2SH script 231 inp["segwit_size"] = 1 + 72 + 34 // witness_ver + key + signature 232 } else if (outs[i].type=="P2WPKH") { 233 inp.value = 0 234 inp["segwit_size"] = 1 + 72 + 34 // witness_ver + key + signature 235 } else if (outs[i].type=="P2TAP") { 236 inp.value = 0 237 inp["segwit_size"] = 1 + 1 + 64 + 0 // wit_ver + scr_len + schnorr_signature [+ hash_type] 238 } else { 239 // default for P2SH and P2WSH (3 keys and 2 signatures) 240 inp.value = 2 + 3*34 + 2*73 241 } 242 row.appendChild(inp) 243 244 td = row.insertCell(-1) 245 td.align = 'right' 246 td.innerText = row_number 247 248 td = row.insertCell(-1) 249 td.align = 'right' 250 td.innerText = outs[i].block 251 252 td = row.insertCell(-1) 253 td.className = 'inpid hand' 254 td.innerText = outs[i].txid + ' - ' + outs[i].vout 255 td["txid"] = outs[i].txid 256 td["vout"] = outs[i].vout 257 td["block"] = outs[i].block 258 td.addEventListener('click', show_input_tx) 259 260 td = row.insertCell(-1) 261 td.align = 'right' 262 td.className = 'mono bold' 263 td.innerText = val2str_pad(outs[i].value,true) 264 265 td = row.insertCell(-1) 266 td.className = 'bold hand' 267 td["row_number"] = row_number 268 td.addEventListener('click', selectadr) 269 td.classList.add(outs[i].type) 270 td.innerText = outs[i].addr2 271 if (outs[i].addr2.length>45) { 272 td.classList.add("long_addr") 273 } 274 td.title = outs[i].addr 275 276 td = row.insertCell(-1) 277 td.className = 'hand' 278 td["row_number"] = row_number 279 td.addEventListener('click', selectlabel) 280 td.innerText = outs[i].label 281 282 td = row.insertCell(-1) 283 td.className = 'hand' 284 if (typeof(outs[i].msg)=='string' && outs[i].msg != '') { 285 var img = document.createElement("img") 286 img.src = 'webui/message.png' 287 img.title = outs[i].msg.substr(0,2)=='j0' ? ('*'+outs[i].msg.substr(2)) : outs[i].msg 288 td.appendChild(img) 289 } 290 291 td = row.insertCell(-1) 292 td.align = 'center' 293 var inp = document.createElement("input") 294 inp.id = "txout"+row_number 295 inp.type = "checkbox" 296 inp.name = "txout"+row_number 297 inp.onchange = recalc_inputs 298 td.appendChild(inp) 299 } 300 301 total_btc.innerText = val2str(totbtc) 302 outs_cnt.innerText = totouts 303 } catch (e) { 304 console.log(e) 305 } 306 } 307 308 aj.open("POST", "balance.json", true) 309 aj.send(JSON.stringify(wallet_addr)) 310 } 311 312 function recalc_inputs() { 313 selected_value = 0 314 selected_cnt = 0 315 ets_inputs = 0 316 witness_size = 0 317 non_segwit_cnt = 0 318 first_input_addr = '' 319 for (var i=1; i<unspent.rows.length; i++) { 320 if (document.getElementById('txout'+i).checked) { 321 if (first_input_addr=='') first_input_addr=unspent.rows[i].addr 322 selected_value += unspent.rows[i].value 323 selected_cnt++ 324 var el = document.getElementById('txsigsiz'+i) 325 ets_inputs += 36 + 1 + parseFloat(el.value) + 4 326 var sws = el["segwit_size"] 327 if (sws==0) non_segwit_cnt++ 328 else witness_size += sws 329 } 330 } 331 332 selval.innerText = (selected_value/1e8).toFixed(8) 333 selcnt.innerText = selected_cnt.toString() 334 335 paybut.disabled = (selected_cnt==0) 336 337 recalc_to_pay() 338 } 339 340 function addr2outsize(ad) { 341 if (ad.substr(0,3)=="bc1" || ad.substr(0,3)=="tb1") { 342 return 8 + ((ad.length>45) ? 35 : 23) 343 } 344 switch (ad[0]) { 345 case '1': 346 case 'm': 347 case 'n': 348 return 8+1+25 349 case '2': 350 case '3': 351 return 8+1+23 352 } 353 return AvgOutputSize 354 } 355 356 357 function recalc_to_pay() { 358 var el, v, fee, totsend=0 359 var butdisabled = false 360 var non_segwit_size = 10+ets_inputs // version + v_in + n_out + lock_time 361 362 fee = val2int(txfee.value) 363 364 for (var idx=1; idx<outtab.rows.length-3; idx++) { 365 el = document.getElementById('out'+idx) 366 v = val2int(el.value) 367 if (isNaN(v)) { 368 el.classList.add('err') 369 butdisabled = true 370 document.getElementById('mbtc_out'+idx).value = '' 371 } else { 372 el.classList.remove('err') 373 totsend += v 374 document.getElementById('mbtc_out'+idx).value = val2str(1000*v) 375 } 376 var ad = document.getElementById('inadr'+idx).value 377 non_segwit_size += addr2outsize(ad) 378 } 379 380 if (include_fee_output_in_size_calculation.checked) { 381 var ad = changeaddrsel.selectedIndex 382 if (ad!=0) { 383 ad = changeaddrsel.options[ad].value 384 non_segwit_size += addr2outsize(ad) 385 } else { 386 non_segwit_size += addr2outsize(first_input_addr) 387 } 388 } 389 390 var tx_size = non_segwit_size 391 if (witness_size>0) { 392 // segwit tx is 2 bytes longer, plus each non-segwit input uses one extra byte (0) in its segwit section 393 tx_size += 2+witness_size+non_segwit_cnt 394 } 395 var vsize = Math.floor((3*(non_segwit_size+1) + tx_size)/4) 396 397 ets.innerText = vsize 398 399 if (auto_adjust_fee.checked) { 400 var spb = parseFloat(spb_to_use.value) 401 if (isNaN(spb)) spb = 0 402 fee = Math.round(vsize*spb) 403 txfee.value = val2str(fee) 404 } 405 406 if (isNaN(fee)) { 407 txfee.classList.add('err') 408 butdisabled = true 409 txfee_mbtc.value = '' 410 } else { 411 txfee.classList.remove('err') 412 txfee_mbtc.value = val2str(1000*fee) 413 } 414 415 var chval = selected_value-totsend-fee 416 changeval.value = val2str(chval) 417 changeval_mbtc.value = val2str(1000*chval) 418 if (chval<0) { 419 changeval.style.color = 'red' 420 butdisabled = true 421 include_fee_out_checkbox.classList.remove('err') 422 } else if (chval>0) { 423 changeval.style.color = 'green' 424 if (!include_fee_output_in_size_calculation.checked) { 425 include_fee_out_checkbox.classList.add('err') 426 } else { 427 include_fee_out_checkbox.classList.remove('err') 428 } 429 } else { 430 changeval.style.color = '' 431 if (include_fee_output_in_size_calculation.checked) { 432 include_fee_out_checkbox.classList.add('err') 433 } else { 434 include_fee_out_checkbox.classList.remove('err') 435 } 436 } 437 438 paybut.disabled = butdisabled 439 440 if (vsize<1 || isNaN(fee)) { 441 feeperbyte.innerText = '???' 442 } else { 443 feeperbyte.innerText = (fee/vsize).toFixed(1) 444 } 445 } 446 447 448 function auto_adjust_fee_clicked() { 449 if (auto_adjust_fee.checked) { 450 recalc_to_pay() 451 } 452 } 453 454 function translate_address(t) { 455 var pkb = hex2array(t) 456 if (pkb!=null && typeof(pkb)=="object" && pkb.length==33 && (pkb[0]==2 || pkb[0]==3)) { 457 // public key 458 if (auto_transalte_to_segwit_tap) { 459 return sw_encode(testnet?"tb":"bc", 1, pkb.slice(1, 33)) 460 } 461 t = pubkey_to_p2kh(pkb) 462 // fallback to regulat addr transation 463 } 464 if (!auto_transalte_to_segwit) return t 465 if (auto_transalte_to_segwit_p2sh) return p2kh_to_witness_p2sh(t) 466 try { 467 var r = Base58.decode(t) 468 if (25!=r.length || 0!=r[0] && 111!=r[0]) return "" 469 return sw_encode(testnet?"tb":"bc", 0, r.slice(1,21)) 470 } catch (e) { 471 return "" 472 } 473 } 474 475 476 function open_address_book(idx) { 477 if (cur_but!=null) { 478 cur_but.click() 479 } 480 481 addrbook = parse_wallet(localStorage.getItem("gocoinAddressBook")) 482 basic_addrbook_len = addrbook.length 483 484 // append the curtrent wallet's virgin addresses 485 try { // in case if we had no wallets in the browser 486 var tmp = parse_wallet(localStorage.getItem("gocoinWal_"+qswal.options[qswal.selectedIndex].text)) 487 for (var i in tmp) { 488 if (tmp[i].virgin) addrbook.push(tmp[i]) 489 } 490 } catch (ex) {} 491 492 var c = outtab.rows[idx].cells[1] 493 var inadr = document.getElementById('inadr'+idx) 494 var div = document.createElement("div") 495 c.style.position="realitive" 496 div.style.position="absolute" 497 498 var sel = document.createElement("select") 499 sel.style.width = '100%' 500 sel.size = ADDR_LIST_SIZE 501 502 for (var i=0; i<addrbook.length; i++) { 503 var op = document.createElement("option") 504 var wpkh = '' 505 506 if (i >= basic_addrbook_len) { 507 wpkh = translate_address(addrbook[i].addr) 508 } 509 510 if (wpkh != '') { 511 var label = 'SW:' + addrbook[i].label 512 op = document.createElement("option") 513 op.text += label 514 op.text += " - " + wpkh 515 op.value = wpkh 516 op.selected = inadr.value==op.value 517 op["addr_label"] = label 518 } else { 519 op.text += addrbook[i].label 520 op.text += " - " + addrbook[i].addr 521 op.value = addrbook[i].addr 522 op.selected = inadr.value==op.value 523 op["addr_label"] = addrbook[i].label 524 } 525 sel.add(op) 526 } 527 528 div.appendChild(sel) 529 c.appendChild(div) 530 531 var but = document.getElementById("addrbook"+idx) 532 var prv_valu = but.value 533 var prv_oncl = but.onclick 534 but.value = "Close the list" 535 cur_but = but 536 but.onclick = sel.onchange = function() { 537 c.removeChild(div) 538 but.onclick = prv_oncl 539 if (sel.selectedIndex!=-1) { 540 inadr.value = sel.options[sel.selectedIndex].value 541 but.value = sel.options[sel.selectedIndex].addr_label 542 } else { 543 but.value = addrbook_lab 544 } 545 cur_but = null 546 recalc_to_pay() 547 } 548 } 549 550 551 function reslab(idx) { 552 var val = document.getElementById("inadr"+idx).value 553 var but = document.getElementById("addrbook"+idx) 554 for (var i=0; i<addrbook.length; i++) { 555 if (val==addrbook[i].addr) { 556 but.value = addrbook[i].label 557 return 558 } 559 } 560 for (var i=0; i<wallet.length; i++) { 561 if (val==wallet[i].addr) { 562 but.value = wallet[i].label 563 return 564 } 565 } 566 but.value = addrbook_lab 567 } 568 569 570 function del_last_output() { 571 if (outtab.rows.length<=5) { 572 alert('You cannot remove the only output') 573 return 574 } 575 if (confirm('Remove the last output?')) { 576 outtab.deleteRow(outtab.rows.length-4) 577 recalc_to_pay() 578 } 579 } 580 581 function add_new_output() { 582 var idx = outtab.rows.length-3 583 var val, c, r = outtab.insertRow(idx) 584 585 c = r.insertCell(-1) 586 c.innerHTML = 'Out#'+idx 587 if (idx>1) { 588 c.style.cursor = 'pointer' 589 c.title = 'Click to delete this output' 590 c.id = idx 591 c.onclick = function() {del_output(idx)} 592 } 593 594 c = r.insertCell(-1) 595 c.innerHTML = '<input id="inadr'+idx+'" name="adr'+idx+'" size="68" class="mono" onkeyup="reslab('+idx+')" onchange="reslab('+idx+')">' 596 c.innerHTML += ' <input type="button" style="width:100px;font-size:12px;padding:2px" value="'+ 597 addrbook_lab+'" id="addrbook'+idx+'" onclick="open_address_book('+idx+')" tabindex="-1">' 598 599 // amount BTC 600 c = r.insertCell(-1) 601 val = document.createElement('input') 602 val.type = 'text' 603 val.size = 13 604 val.id = 'out'+idx 605 val.name = 'btc'+idx 606 val.onchange = recalc_to_pay 607 val.onkeyup = recalc_to_pay 608 val.className = 'mono r' 609 val.setAttribute("autocomplete","off") 610 val.autoComplete = false 611 val.value = '' 612 c.appendChild(val) 613 614 // empty cell between BTC and mBTC 615 c = r.insertCell(-1) 616 617 // amount mBTC 618 c = r.insertCell(-1) 619 val = document.createElement('input') 620 val.type = 'text' 621 val.size = 13 622 val.id = 'mbtc_out'+idx 623 val.className = 'mono r dis' 624 val.readOnly = true 625 val.tabIndex = -1 626 c.appendChild(val) 627 628 recalc_to_pay() 629 } 630 631 function allchange(t) { 632 for (var i=1; i<unspent.rows.length; i++) { 633 document.getElementById('txout'+i).checked = t.checked 634 } 635 recalc_inputs() 636 } 637 638 function selectadr() { 639 var idx = this.row_number 640 var addr = unspent.rows[idx].addr 641 var chkd = document.getElementById('txout'+idx).checked 642 for (var i=1; i<unspent.rows.length; i++) { 643 if (unspent.rows[i].addr==addr) { 644 document.getElementById('txout'+i).checked = !chkd 645 } 646 } 647 recalc_inputs() 648 } 649 650 function selectlabel() { 651 var idx = this.row_number 652 var label = unspent.rows[idx].label 653 var chkd = document.getElementById('txout'+idx).checked 654 for (var i=1; i<unspent.rows.length; i++) { 655 if (unspent.rows[i].label==label) { 656 document.getElementById('txout'+i).checked = !chkd 657 } 658 } 659 recalc_inputs() 660 } 661 662 function final_clicked() { 663 if (final_checkbox.checked) { 664 tx_seq.value = -2 665 tx_seq.readOnly = true 666 tx_seq.style.backgroundColor = '#c0c0c0' 667 } else { 668 tx_seq.value = 0 669 tx_seq.readOnly = false 670 tx_seq.style.backgroundColor = '#ffffff' 671 } 672 } 673 674 document.addEventListener('DOMContentLoaded', function() { 675 add_new_output() 676 txfee.onchange = recalc_to_pay 677 txfee.onkeyup = recalc_to_pay 678 // use avg_fee_spb value, but randomly modyfied by up to +/- 10%, for user's privacy 679 spb_to_use.value = (Math.random()/5+0.9)*avg_fee_spb.toFixed(10).substr(0,7) 680 recalc_inputs() 681 var abc = localStorage.getItem("gocoinAddressBook") 682 if (typeof(abc)!="string") { 683 abc = "# Empty Address Book" 684 localStorage.setItem("gocoinAddressBook", abc) 685 } 686 address_book.value = abc 687 }) 688 689 function edit_address_book() { 690 addrr_book_div.style.display='block' 691 addrbook_button.value = "Save Address Book" 692 addrbook_button.onclick = function() {save_address_book()} 693 } 694 695 function save_address_book() { 696 localStorage.setItem("gocoinAddressBook", address_book.value) 697 addrr_book_div.style.display='none' 698 addrbook_button.value = "Edit Address Book" 699 addrbook_button.onclick = function() {edit_address_book()} 700 } 701 702 </script> 703 704 <form method="post" action="payment.zip"> 705 <input type="hidden" id="outcnt_val" name="outcnt" value=""> 706 <h2>Payment details 707 <input style="float:right;" id="addrbook_button" type="button" value="Edit Address Book" onclick="edit_address_book()"> 708 </h2> 709 710 <div id="addrr_book_div" style="display:none"> 711 <textarea id="address_book" style="width:100%" rows="15"></textarea> 712 <br><br> 713 </div> 714 715 Selected amount: <b id="selval">0.00000000</b> BTC in <b id="selcnt">0</b> outputs. 716 <table class="bord" vspace="10" id="outtab"> 717 <tr> 718 <th> 719 <th>Pay to address 720 <th>Amount BTC 721 <th> 722 <th><i>... mBTC</i> 723 </tr> 724 725 <tr> 726 <td colspan="2"> 727 <table width="100%"><tr> 728 <td><a href="javascript:add_new_output()" title="Add another output">+add output</a> 729 | 730 <a href="javascript:del_last_output()" title="Remove last output">-remove last</a> 731 <td align="center" title="Transaction sequence for RBF purpose">Sequence : <input name="tx_seq" id="tx_seq" class="mono r" size="2" value="0"> 732 • 733 <span onclick="final_checkbox.click()" class="hand"> 734 <input onchange="final_clicked()" type="checkbox" id="final_checkbox" onclick="event.stopPropagation()">Final 735 </span> 736 <td align="right">Transaction fee: 737 </table> 738 <td><input type="text" id="txfee" name="txfee" size="13" class="mono r" value="0.0001" onchange="recalc_to_pay" onkeyup="recalc_to_pay"> 739 <td style="font-size:10px" title="Fee per byte"><b id="feeperbyte"></b><br>SPB 740 <td><input type="text" id="txfee_mbtc" size="13" class="mono r dis" readonly="readonly" tabindex="-1"> 741 </tr> 742 743 <tr title="Transaction change"> 744 <td>Change 745 <td><select name="change" style="width:100%" id="changeaddrsel" onchange="recalc_to_pay()"> 746 <option value="">The first input's address</option> 747 </select> 748 <td class="r"> 749 <input type="text" class="mono r dis" id="changeval" size="13" readonly="readonly" onclick="this.select()"> 750 <td id="include_fee_out_checkbox"><input type="checkbox" id="include_fee_output_in_size_calculation" title="Include in size calculation" onchange="recalc_to_pay()"> 751 <td class="r"> 752 <input type="text" class="mono r dis" id="changeval_mbtc" size="13" readonly="readonly" tabindex="-1"> 753 </tr> 754 755 <tr> 756 <td colspan="5" align="left"> 757 <input type="checkbox" title="auto adjust the fee" id="auto_adjust_fee" checked="checked" onchange="auto_adjust_fee_clicked()"> 758 Auto-calc transaction fee using price of 759 <input type="text" id="spb_to_use" class="mono r" size="7" onchange="recalc_to_pay()"> Satoshis Per Byte. 760 761 Estimated virtual transaction size: <span id="ets" style="font-weight:bold"></span> bytes 762 <hr> 763 <input type="submit" id="paybut" disabled="disabled" value="Download payment.zip" style="width:100%"> 764 </td> 765 </tr> 766 </table> 767 <i><b>Note:</b> all the inputs selected below will be combined within one transaction, despite of the amounts entered above.</i> 768 769 <h2>Select Inputs</h2> 770 Wallet: <select id="qswal" onchange="quick_switch_wallet()"></select> 771 - 772 total balance of <b id="total_btc"></b> BTC in <b id="outs_cnt"></b> outputs. 773 <i id="wallet_min_warning" style="color:purple;float:right;display:none" title="Modify MinValue in gocoin.conf to change it"> 774 <img src="webui/warning.png" style="vertical-align:middle"> 775 Only accounting outputs with at least <b id="min_val_btc"></b> BTC</i> 776 <br><br> 777 <table id="unspent" width="100%"> 778 <tr> 779 <th width="20"># 780 <th width="40">Block 781 <th>TxID - VOut 782 <th width="80">BTC Value 783 <th colspan="2">Address 784 <th> 785 <th><input type="checkbox" onchange="allchange(this)"> 786 </tr> 787 <!--UTXOROW--> 788 </table> 789 790 </form> 791 <script> 792 793 if (typeof(localStorage.gocoinWallets)=="string") { 794 build_wallet_list() 795 } else { 796 localStorage.gocoinWallets = "" 797 } 798 799 800 var warning_set = false 801 blno.addEventListener("lastblock", function(e) { 802 if (!e.block.WalletON) { 803 location.reload() 804 return 805 } 806 if (!warning_set) { 807 warning_set = true 808 if (e.block.MinValue>0) { 809 min_val_btc.innerText = val2str(e.block.MinValue) 810 wallet_min_warning.style.display = 'block' 811 } 812 } 813 }) 814 qswal.addEventListener("loadwallet", function(e) { 815 fetch_wallet_balance(e.name) 816 build_change_list() 817 }) 818 document.addEventListener('DOMContentLoaded', function() { 819 quick_switch_wallet() // this is to force loading wallet after loading 820 addrbook = parse_wallet(localStorage.getItem("gocoinAddressBook")) 821 window.onkeyup = function (event) { 822 if(event.keyCode == 27) closepopup_x(false) 823 } 824 }) 825 </script>