From cc72856aa377d25fa794f5d71d4fe9da9f07b3f8 Mon Sep 17 00:00:00 2001 From: Peter Date: Mon, 2 Oct 2023 07:51:38 -0600 Subject: [PATCH 1/3] msg confirm sends back error if user rejects tx --- jrx/pages/msg_confirm.html | 6 +++--- jrx/src/b_lib.ts | 30 ++++++++++++++++++++++-------- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/jrx/pages/msg_confirm.html b/jrx/pages/msg_confirm.html index c275d69..3a689c4 100644 --- a/jrx/pages/msg_confirm.html +++ b/jrx/pages/msg_confirm.html @@ -5,14 +5,14 @@ Is this message good or bad? -

Is this message good or bad?

+

Do you want to sign this message?


 
 
- +
- + diff --git a/jrx/src/b_lib.ts b/jrx/src/b_lib.ts index 08779fd..bbcc716 100644 --- a/jrx/src/b_lib.ts +++ b/jrx/src/b_lib.ts @@ -321,17 +321,27 @@ bi_msg_handler_content let msg_str : string = msg.data.params.message; // TODO: need to break here on whether the msg signature was good // (signed) or bad (not) - let resultt = await msg_sign(msg_str, secret_key) - return w2a_ok(resultt); + let resultt = await msg_sign(msg_str, secret_key); + if (resultt.result === 'good') { + return w2a_ok({signature: resultt.signature}); + } + else { + return w2a_err(awcp.ERROR_CODE_RpcRejectedByUserError, "you're not pretty enough"); + } // right now just sign tx case "transaction.sign": console.log('jr bg content message handler transaction sign'); let tx_str : string = msg.data.params.tx; console.log('transaction: ', tx_str); - let result = await tx_sign(tx_str, secret_key) - console.log('signed transaction: ', result.signedTransaction); - return w2a_ok(result); + let result = await tx_sign(tx_str, secret_key) + return w2a_ok({signedTransaction: result.signedTransaction}); + //if (result.result === 'good') { + // return w2a_ok({signedTransaction: result.signedTransaction}); + //} + //else { + // return w2a_err(awcp.ERROR_CODE_RpcRejectedByUserError, "you will never be pretty enough"); + //} // default is NYI default: @@ -354,7 +364,10 @@ async function msg_sign (msg_str : string, secret_key : Uint8Array) - : Promise<{signature : string}> + : Promise< {result : 'good', + signature : string} + | {result : 'bad'} + > { // does the user want to sign the message let confirm_window = await browser.windows.create({url : '../pages/msg_confirm.html', @@ -387,10 +400,11 @@ msg_sign // @ts-ignore yes nacl is stupid let signature : Uint8Array = nacl.sign.detached(hashed_salted_msg, secret_key); let signature_str : string = vdk_binary.bytes_to_hex_str(signature); - return {signature: signature_str}; + return {result : 'good', + signature : signature_str}; } else { - return { + return {result : 'bad'}; } } From 7d87fd626f856661873f159f7fe9c25eba9a0f5c Mon Sep 17 00:00:00 2001 From: Peter Date: Mon, 2 Oct 2023 08:20:45 -0600 Subject: [PATCH 2/3] start on confirm sign tx thing --- jrx/pages/tx_confirm.html | 25 +++++++++++ jrx/src/tx_confirm.ts | 89 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 114 insertions(+) create mode 100644 jrx/pages/tx_confirm.html create mode 100644 jrx/src/tx_confirm.ts diff --git a/jrx/pages/tx_confirm.html b/jrx/pages/tx_confirm.html new file mode 100644 index 0000000..26f9ec5 --- /dev/null +++ b/jrx/pages/tx_confirm.html @@ -0,0 +1,25 @@ + + + + + Do you want to sign this transaction? + + +

Do you want to sign this transaction?

+ +

Tx Base64

+

+
+
+

Tx Decomposed info

+

+
+
+ +
+ + + + + + diff --git a/jrx/src/tx_confirm.ts b/jrx/src/tx_confirm.ts new file mode 100644 index 0000000..d5723d3 --- /dev/null +++ b/jrx/src/tx_confirm.ts @@ -0,0 +1,89 @@ +/** + * Page script for "confirm sign message" popup window + */ + + +main(); + + +async function +main + () + : Promise +{ + console.log('msg_confirm main'); + + let result : '' | 'good' | 'bad' + = ''; + + document.getElementById('good')!.onclick + = function() { + console.log('click good'); + result = 'good'; + }; + document.getElementById('bad')!.onclick + = function() { + console.log('click bad'); + result = 'bad'; + }; + + + type bg_msg + = {msg_str : string}; + + async function listener + (msg : bg_msg, + _sender : any, + _sendResponse : any) + : Promise<'good' | 'bad'> + { + console.log('listener triggered', msg); + console.log('msg_str:', msg.msg_str); + document.getElementById('message')!.innerHTML = msg.msg_str; + + // every 5 ms check + // timeout of 10 minutes = 10*60 secs * 20 iterations = + // number of iters in a full second + let ITERS = 1; + let SEC = 200*ITERS; + let MIN = 60*SEC; + //let n_max = 10*MIN; + let n = 1; + let n_max = 30*SEC; + + while + (result === '') { + // if haven't timed out yet + if (n <= n_max) { + await sleep(5); + n = n + 1; + } + // if timed out + else { + result = 'bad'; + // this break is implied but you're not smart enough to figure + // that out yourself + break; + } + } + + // send result back + return result; + } + + // add listener + browser.runtime.onMessage.addListener(listener); +} + + + +/** + * Hack from stack overflow somewhere to sleep for the given number of ms + */ +async function +sleep + (ms: number) + : Promise +{ + return new Promise(resolve => setTimeout(resolve, ms)); +} From 16a4bcebbabe5adb8d2fb0e7672ba8ffe3e031db Mon Sep 17 00:00:00 2001 From: Peter Harpending Date: Mon, 2 Oct 2023 16:56:12 -0600 Subject: [PATCH 3/3] [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