[wip] jr: working on presenting address to user

This commit is contained in:
2023-08-11 12:15:56 -06:00
parent 1e80a53051
commit a73da72382
2 changed files with 269 additions and 86 deletions
+266 -83
View File
@@ -22,7 +22,10 @@
* # Naming Conventions * # Naming Conventions
* *
* - `b_...` -> background script API * - `b_...` -> background script API
* - `_...` -> internal * - `bi_...` -> background internal
* - `bis_...` -> background internal storage
* storage is in json types so we need a separate type layer
*
* - `p_...` -> popup script API * - `p_...` -> popup script API
* *
* @module * @module
@@ -45,24 +48,32 @@ export {
//=============================================================================
//============================================================================= //=============================================================================
// API: GLOBAL TYPES // API: GLOBAL TYPES
//============================================================================= //=============================================================================
//=============================================================================
//=============================================================================
//============================================================================= //=============================================================================
// API: POPUP TYPES // API: POPUP TYPES
//============================================================================= //=============================================================================
//=============================================================================
//=============================================================================
//============================================================================= //=============================================================================
// API: POPUP SCRIPT // API: POPUP SCRIPT
//============================================================================= //=============================================================================
//=============================================================================
//=============================================================================
//============================================================================= //=============================================================================
// API: BACKGROUND SCRIPT // API: BACKGROUND SCRIPT
//============================================================================= //=============================================================================
//=============================================================================
/** /**
* main function for background thread * main function for background thread
@@ -75,18 +86,20 @@ b_main
console.log('b_main'); console.log('b_main');
// get state // get state
let state: _state = await _get_state(); let state: bi_state = await bi_get_state();
console.log(state); console.log(state);
// handle messages from content or popup scripts // handle messages from content or popup scripts
browser.runtime.onMessage.addListener(_runtime_msg_handler); browser.runtime.onMessage.addListener(bi_runtime_msg_handler);
} }
//=============================================================================
//============================================================================= //=============================================================================
// INTERNALS: TYPES // INTERNALS: TYPES
//============================================================================= //=============================================================================
//=============================================================================
/** /**
* @example * @example
@@ -104,40 +117,72 @@ b_main
* *
* @internal * @internal
*/ */
type _a2w_calldata type bi_a2w_calldata
= awcp.EventData_A2W<awcp.RpcCall<string, any>>; = awcp.EventData_A2W<awcp.RpcCall<string, any>>;
// method params // method params
/** /**
* Return data * Return data for queries from a page script
*
* @internal
*/ */
type _w2a_return_data type bi_w2a_return_data
= awcp.EventData_W2A<awcp.RpcResp<string, any>>; = awcp.EventData_W2A<awcp.RpcResp<string, any>>;
/** /**
* Type from NaCL * Type copied from NaCL
*
* @internal
*/ */
type _nacl_keypair type bi_nacl_keypair
= {secretKey : Uint8Array, = {secretKey : Uint8Array,
publicKey : Uint8Array}; publicKey : Uint8Array};
/** /**
* JR state * JR state used internally
*
* @internal
*/ */
type _state = {keypairs: Array<_nacl_keypair>}; type bi_state
= {keypairs: Array<bi_nacl_keypair>};
/**
* JR storage state
*
* Storage is in JSON so we have to have a different type for storage and for
* what's actually used during ordinary data processing.
*
* @internal
*/
type bis_state
= {jr_state: {keypairs: Array<bis_nacl_keypair>}};
/**
* How keypairs are stored
*
* @internal
*/
type bis_nacl_keypair
= {secretKey : Array<number>,
publicKey : Array<number>};
//=============================================================================
//============================================================================= //=============================================================================
// INTERNALS: FUNCTIONS // INTERNALS: FUNCTIONS
//============================================================================= //=============================================================================
//=============================================================================
/** /**
@@ -149,39 +194,54 @@ type _state = {keypairs: Array<_nacl_keypair>};
* @internal * @internal
*/ */
async function async function
_runtime_msg_handler bi_runtime_msg_handler
(msg : {frum: 'content' | 'popup', (msg : {frum: 'content' | 'popup',
data: any}, data: any},
sender : any, sender : any,
sendResponse : any) sendResponse : any)
: Promise<_w2a_return_data | _popup_return_data> : Promise<bi_w2a_return_data | bi_popup_return_data>
{ {
//console.log('msg', msg); //console.log('msg', msg);
//console.log('sender', sender); //console.log('sender', sender);
//console.log('sendResponse', sendResponse); //console.log('sendResponse', sendResponse);
switch (msg.frum) { switch (msg.frum) {
// messages from the content script (i.e. from page scripts)
case 'content': case 'content':
return await _msg_handler_content(msg.data as _a2w_calldata, sender, sendResponse); return await bi_msg_handler_content(msg.data as bi_a2w_calldata, sender, sendResponse);
// messages from the popup window
case 'popup': case 'popup':
return await _msg_handler_popup(msg.data as _popup_calldata, sender, sendResponse); return await bi_msg_handler_popup(msg.data as bi_popup_calldata, sender, sendResponse);
} }
} }
//-----------------------------------------------------------------------------
// INTERNALS: CONTENT SCRIPT MESSAGE HANDLING
//-----------------------------------------------------------------------------
/** /**
* Handle messages from the content script * Handle messages from the content script
* *
* Note to self: `sendResponse` is fake. Doesn't work. Instead just return the * Note to self: `sendResponse` is fake. Doesn't work. Instead just return the
* response * response.
*
* Literally the way it works is that
*
* - IF this is a non-async function (i.e. does NOT return a `Promise`), THEN
* `sendResponse` is fake and the runtime sends back the return value of the
* function. This is our case.
* - ELSE `sendResponse` works. Presumably this is for backward compabitility.
*
* @internal
*/ */
async function async function
_msg_handler_content bi_msg_handler_content
(msg : _a2w_calldata, (msg : bi_a2w_calldata,
sender : any, sender : any,
sendResponse : any) sendResponse : any)
: Promise<_w2a_return_data> : Promise<bi_w2a_return_data>
{ {
//console.log('msg', msg); //console.log('msg', msg);
//console.log('sender', sender); //console.log('sender', sender);
@@ -191,7 +251,7 @@ _msg_handler_content
let msg_id : string | number = msg.data.id; let msg_id : string | number = msg.data.id;
function w2a_ok(result_for_content_script: any) { function w2a_ok(result_for_content_script: any) {
return mk_w2a_msg_ok(msg_method, msg_id, result_for_content_script); return bi_mk_w2a_msg_ok(msg_method, msg_id, result_for_content_script);
} }
switch (msg.data.method) { switch (msg.data.method) {
@@ -199,76 +259,38 @@ _msg_handler_content
return w2a_ok({id : "jr", return w2a_ok({id : "jr",
name : "JR", name : "JR",
networkId : "ae_uat", networkId : "ae_uat",
origin : "foobar", origin : browser.runtime.getURL('/'),
type : "extension"}); type : "extension"});
// TODO: factor this out into a function
case "address.subscribe": case "address.subscribe":
// get the state
let i_state : bi_state = await bi_get_state();
// get the keypairs
// for now only getting the first one
let address_bytes : Uint8Array = i_state.keypairs[0].publicKey;
// convert it to a string
let address_ak_str : string = vdk_aeser.pubkey2ak_str(address_bytes);
return w2a_ok({subscription : ["connected"], return w2a_ok({subscription : ["connected"],
address : {current : {"bobs": {}}, address : {current : {address_ak_str: {}},
connected : {}}}); connected : {}}});
} }
} }
/** /**
* fetch the state from local storage * Wrap up bs for w2a message
* *
* if there is no state make an initial state and store it * This really should go into the AWCP library but I'm lazy
*/ *
async function * @internal
_get_state
()
: Promise<_state>
{
console.log('jr bg _get_state');
// this may or may not have the keyword "jr_state"
let gotten_state : object = await browser.storage.local.get();
console.log('jr bg gotten_state', gotten_state);
// if there is such a state, get it
// @ts-ignore ts doesn't understand querying if a key exists
if (!!(gotten_state.jr_state)) {
// @ts-ignore ts doesn't understand that we have proved that the key exists
return gotten_state.jr_state;
}
// otherwise return default state
else {
return _state_default();
}
}
/**
* default state for JR
*/ */
function function
_state_default bi_mk_w2a_msg_ok
()
: _state
{
console.log('jr_state_default');
// if no key, generate one
// @ts-ignore ts doesn't like that nacl is dumb. i don't like it either
let init_keypair : nacl_keypair = nacl.sign.keyPair() as nacl_keypair;
let default_state = { keypairs: [init_keypair] };
console.log('jr_state_default default_state', default_state);
return default_state;
}
/**
* wrap up bs for w2a message
*/
function
mk_w2a_msg_ok
<result_t extends any> <result_t extends any>
(method : string, (method : string,
id : string | number, id : string | number,
@@ -284,28 +306,189 @@ mk_w2a_msg_ok
//----------------------------------------------------------------------------
// INTERNALS: POPUP WINDOW MESSAGE HANDLING
//----------------------------------------------------------------------------
type bi_popup_calldata
type _popup_calldata
= 'init'; = 'init';
type _popup_return_data type bi_popup_return_data
= 'die'; = 'die';
/** /**
* Handle messages from the popup * Handle messages from the popup
*
* @internal
*/ */
async function async function
_msg_handler_popup bi_msg_handler_popup
(msg : _popup_calldata, (msg : bi_popup_calldata,
sender : any, sender : any,
sendResponse : any) sendResponse : any)
: Promise<_popup_return_data> : Promise<bi_popup_return_data>
{ {
console.log('jr bg_msg_handler_popup msg', msg); console.log('jr bg_msg_handler_popup msg', msg);
return 'die'; return 'die';
} }
//=============================================================================
//=============================================================================
// INTERNALS: STORAGE API
//=============================================================================
//=============================================================================
/**
* Fetch the state from local storage
*
* if there is no state make an initial state and store it
*
* @internal
*/
async function
bi_get_state
()
: Promise<bi_state>
{
console.log('jr bg bi_get_state');
// this may or may not have the keyword "jr_state"
let gotten_state : {jr_state?: bi_state} = await browser.storage.local.get();
console.log('jr bg gotten_state', gotten_state);
// problem: browser storage is JSON basically
// so we need to convert our state to and from json
// if there is such a state, get it
// @ts-ignore ts doesn't understand querying if a key exists
if (!!(gotten_state.jr_state)) {
// @ts-ignore ts doesn't understand that we have proved that the key exists
return bi_s2i(gotten_state);
}
// otherwise return default state
else {
// set the state
let default_i_state : bi_state = bi_state_default();
await bi_set_state(default_i_state);
// return it
return default_i_state;
}
}
/**
* Set the state. Blocks until state is set, exception is thrown if there is an
* exception.
*
* @internal
*/
async function
bi_set_state
(i_state : bi_state)
: Promise<void>
{
console.log('jr bg bi_set_state internal state:', i_state);
// convert to storage state
let s_state : bis_state = bi_i2s(i_state);
console.log('jr bg bi_set_state storage state:', s_state);
// store
await browser.storage.local.set(s_state);
}
//-----------------------------------------------------------------------------
// INTERNALS: INTERNAL->STORAGE TYPE COERCION
//-----------------------------------------------------------------------------
/**
* Internal state to storage state converter
*
* @internal
*/
function
bi_i2s
(internal_state : bi_state)
: bis_state
{
// convert keypairs
let i_keypairs : Array<bi_nacl_keypair> = internal_state.keypairs;
let s_keypairs : Array<bis_nacl_keypair> = i_keypairs.map(bi_i2s_keypair);
}
/**
* JSONify a keypair
*
* basically turn each array into numbers
*
* @internal
*/
function
bi_i2s_keypair
(i_keypair : bi_nacl_keypair)
: bis_nacl_keypair
{
let i_secretKey : Uint8Array = i_keypair.secretKey;
let i_publicKey : Uint8Array = i_keypair.publicKey;
let s_secretKey : Array<number> = bi_i2s_bytes2nums(i_secretKey);
let s_publicKey : Array<number> = bi_i2s_bytes2nums(i_publicKey);
return {secretKey : s_secretKey,
publicKey : s_publicKey};
}
/**
* Convert a byte array to an array of numbers
*
* @internal
*/
function
bi_i2s_bytes2nums
(bytes: Uint8Array)
: Array<number>
{
let arr : Array<number> = [];
for (let this_byte of bytes) {
arr.push(this_byte);
}
return arr;
}
/**
* Default state for JR
*
* Note
* 1. This returns the *internal* state that lives in RAM, **NOT** what is
* stored in browser storage
* 2. This function is **NOT** deterministic. It randomly generates a keypair
*
* @internal
*/
function
bi_state_default
()
: bi_state
{
console.log('jr_state_default');
// if no key, generate one
// @ts-ignore ts doesn't like that nacl is dumb. i don't like it either
let init_keypair : bi_nacl_keypair = nacl.sign.keyPair() as bi_nacl_keypair;
let default_state : bi_state = { keypairs: [init_keypair] };
console.log('jr_state_default default_state', default_state);
return default_state;
}
+1 -1
View File
@@ -21,7 +21,7 @@ let detect_msg = {type : "to_aepp",
params : {id : "jr", params : {id : "jr",
name : "JR", name : "JR",
networkId : "ae_uat", networkId : "ae_uat",
origin : "foobar", origin : browser.runtime.getURL('/'),
type : "extension"}}}; type : "extension"}}};
/** /**