-
+
-
+
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/b_lib.ts b/jrx/src/b_lib.ts
index 5795904..a4b8b3d 100644
--- a/jrx/src/b_lib.ts
+++ b/jrx/src/b_lib.ts
@@ -321,17 +321,33 @@ 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)
+ 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});
+ //}
+ //else {
+ // return w2a_err(awcp.ERROR_CODE_RpcRejectedByUserError, "you will never be pretty enough");
+ //}
// default is NYI
default:
@@ -354,7 +370,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,11 +406,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 {
- // @ts-ignore i just want things to compile FIXME
- return 'go please yourself';
+ return {result : 'bad'};
}
}
@@ -411,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
new file mode 100644
index 0000000..7f712a5
--- /dev/null
+++ b/jrx/src/tx_confirm.ts
@@ -0,0 +1,98 @@
+/**
+ * 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
+ = {tx_str : string,
+ tx_data : object};
+
+ async function listener
+ (msg : bg_msg,
+ _sender : any,
+ _sendResponse : any)
+ : Promise<'good' | 'bad'>
+ {
+ console.log('listener triggered', msg);
+ 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 =
+ // 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;
+
+ // 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
+ 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));
+}