diff --git a/index.html b/index.html index e207d78..0047af4 100644 --- a/index.html +++ b/index.html @@ -13,7 +13,12 @@ th { border: 1px solid black; } + + .unconfirmed-tx { + color: darkred; + } + @@ -44,7 +49,7 @@ send-tx - + @@ -127,10 +132,15 @@ } else if (tx.type === "in") { row.insertCell().innerHTML = '↙'; row.insertCell().textContent = tx.sender; + } else if (tx.type === "self") { + row.insertCell().innerHTML = '⟲'; + row.insertCell().textContent = tx.address; } row.insertCell().textContent = tx.amount; row.insertCell().textContent = tx.time; row.insertCell().textContent = tx.txid; + if (tx.block === null) + row.className = 'unconfirmed-tx'; }); }).catch(error => console.error(error)) } @@ -145,17 +155,32 @@ details.txs = data.txs.map(tx => { let d = { txid: tx.txid, - time: tx.time + time: tx.time, + block: tx.block_no } - //TODO: handle when both in and out (change to same) - if (tx.incoming) { - d.type = "in"; - d.amount = tx.incoming.value; - d.sender = tx.incoming.inputs.map(i => i.address) - } else if (tx.outgoing) { + if (tx.outgoing) { d.type = "out"; - d.amount = tx.outgoing.value; - d.receiver = tx.outgoing.outputs.map(i => i.address) + d.amount = 0; + d.receiver = []; + let change = 0; + tx.outgoing.outputs.forEach(o => { + if (o.address !== address) { + d.receiver.push(o.address) + d.amount += parseFloat(o.value) + } else + change += parseFloat(o.value) + }); + d.fee = parseFloat((tx.outgoing.value - (d.amount + change)).toFixed(8)) + if (!d.amount && change > 0) { + d.type = "self"; + d.amount = change + delete d.receiver; + d.address = address; + } + } else if (tx.incoming) { + d.type = "in"; + d.amount = parseFloat(tx.incoming.value); + d.sender = tx.incoming.inputs.map(i => i.address) } return d; }) diff --git a/lib_btc.js b/lib_btc.js index 2fa91ca..add5e19 100644 --- a/lib_btc.js +++ b/lib_btc.js @@ -2549,19 +2549,15 @@ })(); })(typeof global !== "undefined" ? global : window); -(function(EXPORTS) { //btc_api v1.0.1 +(function(EXPORTS) { //btc_api v1.0.2 const btc_api = EXPORTS; const URL = "https://chain.so/api/v2/"; - const fetch_api = btc_api.fetch = function(api, post = null) { + const fetch_api = btc_api.fetch = function(api) { return new Promise((resolve, reject) => { - let uri = URL + api; - console.debug(uri, post); - (post === null ? fetch(uri) : fetch(uri, { - method: "POST", - body: JSON.stringify(post) - })).then(response => { + console.debug(URL + api); + fetch(URL + api).then(response => { response.json() .then(result => result.status === "success" ? resolve(result) : reject(result)) .catch(error => reject(error)) @@ -2569,6 +2565,19 @@ }) }; + const broadcast = btc_api.broadcast = rawtx => new Promise((resolve, reject) => { + $.ajax({ + type: "POST", + url: URL + "send_tx/BTC/", + data: { + "tx_hex": rawtx + }, + dataType: "json", + error: e => reject(e.responseJSON), + success: r => r.status === "success" ? resolve(r) : reject(r) + }) + }); + Object.defineProperties(btc_api, { newKeys: { get: () => { @@ -2602,8 +2611,8 @@ btc_api.sendTx = function(senderID, senderPrivKey, receiverID, amount, fee) { return new Promise((resolve, reject) => { - //if(btc_api.address(senderPrivKey) !== senderID) - // return reject("Invalid privateKey") + if (coinjs.wif2address(senderPrivKey).address !== senderID) + return reject("Invalid privateKey"); getBalance(senderID).then(balance => { if (balance < amount + fee) return reject("Insufficient Balance"); @@ -2626,11 +2635,9 @@ console.debug("Unsigned:", r.serialize()); r.sign(senderPrivKey, 1 /*sighashtype*/ ); //Sign the tx using private key WIF console.debug("Signed:", r.serialize()); - return resolve(r); - debugger; - fetch_api('send_tx/BTC', { - tx_hex: r.serialize() - }).then(result => resolve(result)).catch(error => reject(error)) + broadcast(r.serialize()) + .then(result => resolve(result)) + .catch(error => reject(error)); }).catch(error => reject(error)) }).catch(error => reject(error)) })