From 16a4bcebbabe5adb8d2fb0e7672ba8ffe3e031db Mon Sep 17 00:00:00 2001 From: Peter Harpending Date: Mon, 2 Oct 2023 16:56:12 -0600 Subject: [PATCH] [wip] somehow tx signature confirmation broke blakejs it's all just so tiresome --- jrx/src/b_lib.ts | 78 ++++++++++++++++++++++++++++++++---------- jrx/src/msg_confirm.ts | 27 ++++++++++++--- jrx/src/tx_confirm.ts | 15 ++++++-- 3 files changed, 93 insertions(+), 27 deletions(-) diff --git a/jrx/src/b_lib.ts b/jrx/src/b_lib.ts index bbcc716..04121af 100644 --- a/jrx/src/b_lib.ts +++ b/jrx/src/b_lib.ts @@ -335,7 +335,13 @@ bi_msg_handler_content let tx_str : string = msg.data.params.tx; console.log('transaction: ', tx_str); let result = await tx_sign(tx_str, secret_key) - return w2a_ok({signedTransaction: result.signedTransaction}); + if + ('good' === result.result) { + return w2a_ok({signedTransaction: result.signedTransaction}); + } + else { + return w2a_err(awcp.ERROR_CODE_RpcRejectedByUserError, "your not pretty enough"); + } //if (result.result === 'good') { // return w2a_ok({signedTransaction: result.signedTransaction}); //} @@ -424,32 +430,66 @@ async function tx_sign (tx_str : string, secret_key : Uint8Array) - : Promise<{signedTransaction : string}> + : Promise< {result : 'good', + signedTransaction : string} + | {result : 'bad'} + > { + // does the user want to sign the message + let confirm_window = await browser.windows.create({url : '../pages/tx_confirm.html', + type : 'popup'}); + + // @ts-ignore shut the fuck up + let tabid : number = confirm_window.tabs[0].id; + + // stupid hack because otherwise the message gets sent before the listener in the page script is created + await sleep(200); + // debug: show tx let mansplained_tx : object = await vdk_aeser.mansplain(tx_str); console.log('mansplained_tx,', mansplained_tx); + type browser_send_data = {tx_str : string, + tx_data : object}; - let tx_bytes : Uint8Array = (await vdk_aeser.unbaseNcheck(tx_str)).bytes; - // thank you ulf - // https://github.com/aeternity/protocol/tree/fd179822fc70241e79cbef7636625cf344a08109/consensus#transaction-signature - // we sign <> - // SerializedObject can either be the object or the hash of the object - // let's stick with hash for now - let network_id : Uint8Array = vdk_binary.encode_utf8('ae_uat'); - // let tx_hash_bytes : Uint8Array = hash(tx_bytes); - let sign_data : Uint8Array = vdk_binary.bytes_concat(network_id, tx_bytes); - // @ts-ignore yes nacl is stupid - let signature : Uint8Array = nacl.sign.detached(sign_data, secret_key); - let signed_tx_bytes : Uint8Array = vdk_aeser.signed_tx([signature], tx_bytes); - let signed_tx_str : string = await vdk_aeser.baseNcheck('tx', signed_tx_bytes); + let result: 'good' | 'bad' + = await browser.tabs.sendMessage(tabid, + {tx_str : tx_str, + tx_data : mansplained_tx}); + + + console.log('result', result); + + // close the popup + browser.tabs.remove(tabid); + // if we're supposed to sign the tx + if + ('good' === result) { + let tx_bytes : Uint8Array = (await vdk_aeser.unbaseNcheck(tx_str)).bytes; + // thank you ulf + // https://github.com/aeternity/protocol/tree/fd179822fc70241e79cbef7636625cf344a08109/consensus#transaction-signature + // we sign <> + // SerializedObject can either be the object or the hash of the object + // let's stick with hash for now + let network_id : Uint8Array = vdk_binary.encode_utf8('ae_uat'); + // let tx_hash_bytes : Uint8Array = hash(tx_bytes); + let sign_data : Uint8Array = vdk_binary.bytes_concat(network_id, tx_bytes); + // @ts-ignore yes nacl is stupid + let signature : Uint8Array = nacl.sign.detached(sign_data, secret_key); + let signed_tx_bytes : Uint8Array = vdk_aeser.signed_tx([signature], tx_bytes); + let signed_tx_str : string = await vdk_aeser.baseNcheck('tx', signed_tx_bytes); + // debugging + let mansplained_stx : object = await vdk_aeser.mansplain(signed_tx_str); + console.log('mansplained signed tx:', mansplained_stx); + return {result : 'good', + signedTransaction : signed_tx_str}; + } + // if user rejected the tx + else { + return {result : 'bad'}; + } - // debugging - let mansplained_stx : object = await vdk_aeser.mansplain(signed_tx_str); - console.log('mansplained signed tx:', mansplained_stx); - return {signedTransaction: signed_tx_str}; } /** diff --git a/jrx/src/msg_confirm.ts b/jrx/src/msg_confirm.ts index d5723d3..a517835 100644 --- a/jrx/src/msg_confirm.ts +++ b/jrx/src/msg_confirm.ts @@ -1,17 +1,34 @@ /** * Page script for "confirm sign message" popup window + * + * For some reason getting "duplicate function implementation" errors from TSC + * if I give these functions normal names + * + * Getting this error on both this file and tx_confirm.ts + * + * For some reason changing the names only in this file gets rid of the errors + * in both files. + * + * No idea what the fuck is going on and I can almost guarantee I don't want to + * know. + * + * Everything about this language is painful. You know I think a lot. I wonder + * why everything is stupid. In any individual case, you can understand the + * chain of incentives for why thing X is stupid. But the majority of things + * should not be stupid. The stupid should be the exception. Instead the world + * runs on the short bus tech stack. */ -main(); +maine(); async function -main +maine () : Promise { - console.log('msg_confirm main'); + console.log('msg_confirm maine'); let result : '' | 'good' | 'bad' = ''; @@ -55,7 +72,7 @@ main (result === '') { // if haven't timed out yet if (n <= n_max) { - await sleep(5); + await sleepy(5); n = n + 1; } // if timed out @@ -81,7 +98,7 @@ main * Hack from stack overflow somewhere to sleep for the given number of ms */ async function -sleep +sleepy (ms: number) : Promise { diff --git a/jrx/src/tx_confirm.ts b/jrx/src/tx_confirm.ts index d5723d3..7f712a5 100644 --- a/jrx/src/tx_confirm.ts +++ b/jrx/src/tx_confirm.ts @@ -29,7 +29,8 @@ main type bg_msg - = {msg_str : string}; + = {tx_str : string, + tx_data : object}; async function listener (msg : bg_msg, @@ -38,8 +39,10 @@ main : Promise<'good' | 'bad'> { console.log('listener triggered', msg); - console.log('msg_str:', msg.msg_str); - document.getElementById('message')!.innerHTML = msg.msg_str; + console.log('tx_str:', msg.tx_str); + console.log('tx_data:', msg.tx_data); + document.getElementById('tx-base64')!.innerHTML = msg.tx_str; + document.getElementById('tx-decomposed')!.innerHTML = JSON.stringify(msg.tx_data, undefined, 4); // every 5 ms check // timeout of 10 minutes = 10*60 secs * 20 iterations = @@ -51,6 +54,12 @@ main let n = 1; let n_max = 30*SEC; + // result starts as neutral + // if user clicks good, result will be updated to 'good' + // if user clicks bad, result will be updated to 'bad' + // if user doesn't click in 30 seconds, default to 'bad' + // this has the effect of sitting and waiting until the user clicks a button + // with a timeout as a backstop while (result === '') { // if haven't timed out yet