jr: multiple keypairs and they have names, one is active

This commit is contained in:
2024-03-19 01:58:39 -06:00
parent 5e8d24b793
commit f479a770c3
3 changed files with 272 additions and 52 deletions
+16 -2
View File
@@ -27,7 +27,7 @@
<tr>
<td><img src="../art/keypair.svg" style="width: 32px; height: 32px;"></td>
<td style="justify-content: center; font-size: 28px; text-align: center; font-weight: bold">
KEYPAIRS
ACCOUNTS
</td>
</tr>
</table>
@@ -42,12 +42,25 @@
<!-- keypairs added dynamically from page script -->
<ul id="keypairs"></ul>
</div>
<!-- generate new keypair -->
<div style="margin-top: 5px; width: 95%; background: #d6ffd9; border: 1px solid #6c5d96; border-radius: 5px; padding: 5px;">
<table >
<tr>
<td><img src="../art/keypair.svg" style="width: 32px; height: 32px;"></td>
<td style="justify-content: center; font-size: 28px; text-align: center; font-weight: bold">
GENERATE NEW KEYPAIR
</td>
</tr>
</table>
<form>
<label for="generate-name">Name:</label>
<input id="generate-name" value="default1"></input>
<br>
<button id="generate-btn">Generate New Keypair</button>
</form>
</div>
<!-- faert recovery -->
<div style="margin-top: 5px; width: 95%; background: #ffd6d9; border: 1px solid #6c5d96; border-radius: 5px; padding: 5px;">
<table >
@@ -62,6 +75,7 @@
<form>
<label for="faert-input">GajuPhrase:</label>
<input id="faert-input"></input>
<br>
<button id="faert-btn">Recover Keypair from GajuPhrase</button>
</form>
<!-- recover from seed phrase
+213 -38
View File
@@ -60,7 +60,8 @@ import * as vdk_binary from './jex_include/local-vdk_binary-0.1.0/dist/vdk_bina
export type {
// global types
// popup script call/return data
p_data
p_data,
p_rich_pubkey
};
@@ -98,8 +99,14 @@ let TX_SIGN_TIMEOUT = 30*GB_MIN;
/**
* data that is displayed in the popup window
*/
type p_data =
{pubkey_ak_strs : Array<string>};
type p_data
= {rich_pubkeys: Array<p_rich_pubkey>};
type p_rich_pubkey
= {akstr : string,
active : boolean,
name : string};
//=============================================================================
@@ -132,16 +139,17 @@ p_get_data
*/
async function
p_generate_keypair
()
(name : string)
: Promise<void>
{
console.log('b_lib p_generate_keypair');
return await browser.runtime.sendMessage({frum: 'popup',
data: {method : 'p_generate_keypair',
args : {}}}) as void;
args : {name: name}}}) as void;
}
//=============================================================================
//=============================================================================
// API: BACKGROUND SCRIPT
@@ -214,13 +222,19 @@ type bi_nacl_keypair
type bi_rich_keypair
= {nacl_keypair : bi_nacl_keypair,
name : string,
active : boolean};
/**
* JR state used internally
*
* @internal
*/
type bi_state
= {keypairs: Array<bi_nacl_keypair>};
= {rich_keypairs: Array<bi_rich_keypair>};
@@ -233,9 +247,14 @@ type bi_state
* @internal
*/
type bis_state
= {jr_state: {keypairs: Array<bis_nacl_keypair>}};
= {jr_state: {rich_keypairs: Array<bis_rich_keypair>}};
type bis_rich_keypair
= {nacl_keypair : bis_nacl_keypair,
name : string,
active : boolean};
/**
* How keypairs are stored
@@ -345,8 +364,15 @@ bi_msg_handler_content
console.log('jr bg content message handler method:', msg.data.method);
let public_key : Uint8Array = i_state.keypairs[0].publicKey;
let secret_key : Uint8Array = i_state.keypairs[0].secretKey;
// if no keypairs, throw error
if (bi_no_keypairs(i_state))
return w2a_err(421, 'user has no keys');
// from now on can assume there is a keypair and it is active
// @ts-ignore am assuming impossible things didn't happen
let public_key : Uint8Array = bi_active_pubkey(i_state).result;
// @ts-ignore am assuming impossible things didn't happen
let secret_key : Uint8Array = bi_active_privkey(i_state).result;
switch (msg.data.method) {
// right now just give connect info back
@@ -405,6 +431,108 @@ bi_msg_handler_content
}
}
type Safe<t>
= Ok<t>
| Err;
type Ok<t>
= {ok : true,
result : t};
type Err
= {ok : false,
error : string};
function
ok
<t>
(x: t)
: Ok<t>
{
return {ok: true, result: x};
}
function
err
(msg: string)
: Err
{
return {ok: false, error: msg};
}
function
bi_active_pubkey
(i_state : bi_state)
: Safe<Uint8Array>
{
if (bi_no_keypairs(i_state))
return err('no keypairs');
else
{
// type bi_nacl_keypair
// = {secretKey : Uint8Array,
// publicKey : Uint8Array};
// type bi_rich_keypair
// = {nacl_keypair : bi_nacl_keypair,
// name : string,
// active : boolean};
// type bi_state
// = {keypairs: Array<bi_rich_keypair>};
let rich_keypairs : Array<bi_rich_keypair> = i_state.rich_keypairs;
for (let rkp of rich_keypairs) {
// if this keypair is active, return it
if (rkp.active)
return ok(rkp.nacl_keypair.publicKey);
}
// if no keypairs were active, error
return err("impossible state: no active keypair");
}
}
function
bi_active_privkey
(i_state : bi_state)
: Safe<Uint8Array>
{
if (bi_no_keypairs(i_state))
return err('no keypairs');
else
{
// type bi_nacl_keypair
// = {secretKey : Uint8Array,
// publicKey : Uint8Array};
// type bi_rich_keypair
// = {nacl_keypair : bi_nacl_keypair,
// name : string,
// active : boolean};
// type bi_state
// = {keypairs: Array<bi_rich_keypair>};
let rich_keypairs : Array<bi_rich_keypair> = i_state.rich_keypairs;
for (let rkp of rich_keypairs) {
// if this keypair is active, return it
if (rkp.active)
return ok(rkp.nacl_keypair.secretKey);
}
// if no keypairs were active, error
return err("impossible state: no active keypair");
}
}
/**
* Return true if there is no keypairs
*/
function
bi_no_keypairs
(i_state : bi_state)
: boolean
{
return (0 === i_state.rich_keypairs.length);
}
type gb = 'good' | 'bad';
@@ -760,7 +888,7 @@ type bi_pc_p_get_data =
type bi_pc_p_generate_keypair =
{method : 'p_generate_keypair',
args : {}};
args : {name: string}};
type bi_popup_return_data
= p_data
@@ -799,32 +927,45 @@ bi_p_get_data
: Promise<p_data>
{
console.log('b_lib bi_p_get_data');
// type bi_state
// = {keypairs: Array<bi_nacl_keypair>};
// type p_data
// = {rich_pubkeys: Array<p_rich_pubkey>};
// type p_rich_pubkey
// = {akstr : string,
// active : boolean,
// name : string};
// type bi_nacl_keypair
// = {secretKey : Uint8Array,
// publicKey : Uint8Array};
// type bi_rich_keypair
// = {nacl_keypair : bi_nacl_keypair,
// name : string,
// active : boolean};
// type bi_state
// = {rich_keypairs: Array<bi_rich_keypair>};
let jr_state : bi_state = await bi_get_state();
// accumulator
let akstrs : Array<string> = [];
let p_rkps : Array<p_rich_pubkey> = [];
for (let this_keypair of jr_state.keypairs) {
let this_pubkey : Uint8Array = this_keypair.publicKey;
let this_ak_str : string = await vdk_aeser.pubkey2ak_str(this_pubkey);
akstrs.push(this_ak_str);
for (let i_rkp of jr_state.rich_keypairs) {
let this_pubkey : Uint8Array = i_rkp.nacl_keypair.publicKey;
let this_akstr : string = await vdk_aeser.pubkey2ak_str(this_pubkey);
let this_active : boolean = i_rkp.active;
let this_name : string = i_rkp.name;
p_rkps.push({akstr : this_akstr,
active : this_active,
name : this_name});
}
// type p_data =
// {pubkey_ak_strs : Array<string>};
return {pubkey_ak_strs: akstrs};
return {rich_pubkeys: p_rkps};
}
async function
bi_p_generate_keypair
(args: {})
(args: {name: string})
: Promise<void>
{
console.log('b_lib bi_p_generate_keypair');
@@ -832,14 +973,24 @@ bi_p_generate_keypair
// get state
let state : bi_state = await bi_get_state();
// type bi_state
// = {keypairs: Array<bi_nacl_keypair>};
// type bi_nacl_keypair
// = {secretKey : Uint8Array,
// publicKey : Uint8Array};
// @ts-ignore fuck off typescript
let new_keypair : bi_nacl_keypair = nacl.sign.keyPair() as bi_nacl_keypair;
state.keypairs.push(new_keypair);
// type bi_rich_keypair
// = {nacl_keypair : bi_nacl_keypair,
// name : string,
// active : boolean};
// type bi_state
// = {rich_keypairs: Array<bi_rich_keypair>};
// @ts-ignore nacl sucks i know
let new_keypair : bi_nacl_keypair = nacl.sign.keyPair() as bi_nacl_keypair;
// if there are no keypairs, the first one is active
let active : boolean = bi_no_keypairs(state);
// update state
state.rich_keypairs.push({nacl_keypair : new_keypair,
active : active,
name : args.name});
// set new state
await bi_set_state(state);
@@ -948,14 +1099,28 @@ bi_set_state
*/
function
bi_i2s
(internal_state : bi_state)
(i_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);
// accumulator
let srkps : Array<bis_rich_keypair> = [];
return {jr_state : {keypairs: s_keypairs}};
// convert internal rich keypairs to storage rich keypairs
for (let this_irkp of i_state.rich_keypairs)
{
// nacl keypair
let this_inkp : bi_nacl_keypair = this_irkp.nacl_keypair;
let this_snkp : bis_nacl_keypair = bi_i2s_keypair(this_inkp);
// this storage rich keypair
let this_srkp : bis_rich_keypair = {nacl_keypair : this_snkp,
active : this_irkp.active,
name : this_irkp.name};
srkps.push(this_srkp);
}
return {jr_state : {rich_keypairs: srkps}};
}
@@ -1023,9 +1188,7 @@ bi_state_default
// let init_keypair : bi_nacl_keypair = nacl.sign.keyPair() as bi_nacl_keypair;
// let default_state : bi_state = { keypairs: [init_keypair] };
// if no key, generate one
// @ts-ignore ts doesn't like that nacl is dumb. i don't like it either
let default_state : bi_state = { keypairs: [] };
let default_state : bi_state = { rich_keypairs: [] };
console.log('jr_state_default default_state', default_state);
return default_state;
}
@@ -1046,8 +1209,6 @@ bi_s2i
(s_state : bis_state)
: bi_state
{
// for now bis_state is just keypairs
let s_keypairs : Array<bis_nacl_keypair> = s_state.jr_state.keypairs;
// convert numbers to byte array
function nums2bytes(nums: Array<number>): Uint8Array {
@@ -1065,9 +1226,23 @@ bi_s2i
}
// convert each keypair
let i_keypairs : Array<bi_nacl_keypair> = s_keypairs.map(keypair_s2i);
// accumulator
let irkps : Array<bi_rich_keypair> = [];
return {keypairs: i_keypairs};
// for now bis_state is just keypairs
// storage rich keypairs
let srkps : Array<bis_rich_keypair> = s_state.jr_state.rich_keypairs;
for (let this_srkp of srkps)
{
let this_inkp : bi_nacl_keypair = keypair_s2i(this_srkp.nacl_keypair);
irkps.push({nacl_keypair : this_inkp,
active : this_srkp.active,
name : this_srkp.name});
}
return {rich_keypairs: irkps};
}
+43 -12
View File
@@ -38,7 +38,9 @@ p_main
let onclick_generate =
async function () {
console.log('popup p_main onclick_generate');
await b_lib.p_generate_keypair();
// @ts-ignore fuck off
let name : string = document.getElementById('generate-name')!.value;
await b_lib.p_generate_keypair(name);
pi_repop();
};
document
@@ -58,8 +60,6 @@ pi_repop
console.log('popup pi_repop');
let popup_data: b_lib.p_data = await b_lib.p_get_data();
// type p_data =
// {pubkey_ak_strs : Array<string>};
// show keypairs
// step 1: delete the existing list of keypairs
@@ -81,28 +81,59 @@ pi_repop
// keypair function so this is prophylaxis
kill_all_children(pubkeys_ul);
// type p_data
// = {rich_pubkeys: Array<p_rich_pubkey>};
// type p_rich_pubkey
// = {akstr : string,
// active : boolean,
// name : string};
// keypairs
let akstrs : Array<string> = popup_data.pubkey_ak_strs;
let akstrs_empty : boolean = (0 === akstrs.length);
let rkps : Array<b_lib.p_rich_pubkey> = popup_data.rich_pubkeys;
let no_keypairs : boolean = (0 === rkps.length);
// if the keypairs are empty unhide the "no keypairs" paragraph
if (akstrs_empty)
if (no_keypairs)
document.getElementById('no-keypairs')!.hidden = false;
// if the keypairs are not empty
else
{
// hide the "no keypairs" paragraph
document.getElementById('no-keypairs')!.hidden = true;
// for each keypair
// for each rich keypair
// each one of these is an ak_... string
for (let this_akstr of akstrs)
for (let this_rkp of rkps)
{
// make an li
let this_li = document.createElement('li');
// shorten akstr
let this_shakstr = pi_shakstr(this_akstr);
// make inner text the key
this_li.innerHTML = this_shakstr;
// make a ul
let rkp_ul = document.createElement('ul');
// make a li for the name
let name_li = document.createElement('li');
name_li.innerHTML = 'Name: ' + this_rkp.name;
// make li for address
let addr_li = document.createElement('li');
addr_li.innerHTML = 'Addr: ';
let addr_span = document.createElement('span');
addr_span.style.fontSize = 'xx-small';
addr_span.innerHTML = this_rkp.akstr;
// add everything inside-out
addr_li.appendChild(addr_span);
rkp_ul.appendChild(addr_li);
rkp_ul.appendChild(name_li);
this_li.appendChild(rkp_ul);
// if active, make background green
if (this_rkp.active)
this_li.style.background = 'green';
else
this_li.style.background = 'red';
// // balance
// // add a br