have transitioned jr to typescript
This commit is contained in:
Vendored
+72
@@ -0,0 +1,72 @@
|
|||||||
|
declare let detect_msg: {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
networkId: string;
|
||||||
|
origin: string;
|
||||||
|
type: string;
|
||||||
|
};
|
||||||
|
declare let detect_awcp_msg: {
|
||||||
|
type: string;
|
||||||
|
data: {
|
||||||
|
jsonrpc: string;
|
||||||
|
method: string;
|
||||||
|
params: {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
networkId: string;
|
||||||
|
origin: string;
|
||||||
|
type: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
declare function post_detect_msg(): void;
|
||||||
|
declare function mk_detectable(): Promise<void>;
|
||||||
|
declare function sleep(ms: number): Promise<unknown>;
|
||||||
|
/**
|
||||||
|
* This handles messages from *other parts of the extension*
|
||||||
|
*/
|
||||||
|
declare function handler(msg: any): void;
|
||||||
|
/**
|
||||||
|
* This handles messages from page scripts
|
||||||
|
*/
|
||||||
|
declare function window_message_handler(msg: {
|
||||||
|
data: any;
|
||||||
|
}): void;
|
||||||
|
/**
|
||||||
|
* window_message_handler handles all messages sent into the event bus,
|
||||||
|
* including messages that we sent (yay js). window_message_handler branches on
|
||||||
|
* whether the message is for us or not (is the science good or bad?). If the
|
||||||
|
* message is for us (the science is good), then this function is triggered.
|
||||||
|
*
|
||||||
|
* The bottom line is this is the function that *actually* handles messages
|
||||||
|
* from the window
|
||||||
|
*/
|
||||||
|
declare function the_science_is_good(awcp_rcp_data: {
|
||||||
|
id: string | number;
|
||||||
|
method: string;
|
||||||
|
params: object;
|
||||||
|
}): void;
|
||||||
|
/**
|
||||||
|
* Called in response to "connection.open" requests from page scripts
|
||||||
|
*
|
||||||
|
* FIXME: this should query the user to see if he wants to connect
|
||||||
|
*/
|
||||||
|
declare function post_connect_msg(msg_ident: string | number): void;
|
||||||
|
/**
|
||||||
|
* Called in response to "address.subscribe" requests from page scripts
|
||||||
|
*
|
||||||
|
* this is to get the wallet's address
|
||||||
|
*/
|
||||||
|
declare function bg_address_subscribe(msg_ident: string | number): void;
|
||||||
|
/**
|
||||||
|
* Called in response to "transaction.sign" requests from page scripts
|
||||||
|
*
|
||||||
|
* user wants us to sign a transaction
|
||||||
|
*/
|
||||||
|
declare function bg_tx_sign(msg_ident: string | number, params: object): void;
|
||||||
|
/**
|
||||||
|
* Called in response to "message.sign" requests from page scripts
|
||||||
|
*
|
||||||
|
* user wants us to sign a message
|
||||||
|
*/
|
||||||
|
declare function bg_msg_sign(msg_ident: string | number, params: object): void;
|
||||||
Vendored
+20
-39
@@ -1,44 +1,34 @@
|
|||||||
let detect_msg =
|
"use strict";
|
||||||
{id : "urmom",
|
let detect_msg = { id: "urmom",
|
||||||
name : "JR",
|
name: "JR",
|
||||||
networkId : "ae_uat",
|
networkId: "ae_uat",
|
||||||
origin : "ur dads balls",
|
origin: "ur dads balls",
|
||||||
type : "extension"};
|
type: "extension" };
|
||||||
|
let detect_awcp_msg = { type: "to_aepp",
|
||||||
let detect_awcp_msg =
|
data: { jsonrpc: "2.0",
|
||||||
{type: "to_aepp",
|
method: "connection.announcePresence",
|
||||||
data: {jsonrpc: "2.0",
|
params: detect_msg } };
|
||||||
method: "connection.announcePresence",
|
|
||||||
params: detect_msg}};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function post_detect_msg() {
|
function post_detect_msg() {
|
||||||
window.postMessage(detect_awcp_msg, '*');
|
window.postMessage(detect_awcp_msg, '*');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async function mk_detectable() {
|
async function mk_detectable() {
|
||||||
//while (true) {
|
//while (true) {
|
||||||
// 3 seconds times 40 is 2 minutes
|
// 3 seconds times 40 is 2 minutes
|
||||||
for (let i=1; i<=40; i++) {
|
for (let i = 1; i <= 40; i++) {
|
||||||
console.error('pee');
|
console.error('pee');
|
||||||
post_detect_msg();
|
post_detect_msg();
|
||||||
await sleep(3000);
|
await sleep(3000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function sleep(ms) {
|
function sleep(ms) {
|
||||||
return new Promise(resolve => setTimeout(resolve, ms));
|
return new Promise(resolve => setTimeout(resolve, ms));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This handles messages from *other parts of the extension*
|
* This handles messages from *other parts of the extension*
|
||||||
*/
|
*/
|
||||||
function handler(msg) {
|
function handler(msg) {
|
||||||
console.error('message: ', msg);
|
console.error('message: ', msg);
|
||||||
switch(msg) {
|
switch (msg) {
|
||||||
case 'mk-detectable':
|
case 'mk-detectable':
|
||||||
mk_detectable();
|
mk_detectable();
|
||||||
return;
|
return;
|
||||||
@@ -46,7 +36,6 @@ function handler(msg) {
|
|||||||
console.error('your mom is dead');
|
console.error('your mom is dead');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This handles messages from page scripts
|
* This handles messages from page scripts
|
||||||
*/
|
*/
|
||||||
@@ -76,7 +65,6 @@ function window_message_handler(msg) {
|
|||||||
console.error('the science is bad');
|
console.error('the science is bad');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* window_message_handler handles all messages sent into the event bus,
|
* window_message_handler handles all messages sent into the event bus,
|
||||||
* including messages that we sent (yay js). window_message_handler branches on
|
* including messages that we sent (yay js). window_message_handler branches on
|
||||||
@@ -96,7 +84,7 @@ function the_science_is_good(awcp_rcp_data) {
|
|||||||
// params : {name : "sidekick examples",
|
// params : {name : "sidekick examples",
|
||||||
// version : 1}}}
|
// version : 1}}}
|
||||||
// can assume it is a call
|
// can assume it is a call
|
||||||
let msg_ident = awcp_rcp_data.id;
|
let msg_ident = awcp_rcp_data.id;
|
||||||
let msg_method = awcp_rcp_data.method;
|
let msg_method = awcp_rcp_data.method;
|
||||||
// branch here on the "method" field
|
// branch here on the "method" field
|
||||||
switch (msg_method) {
|
switch (msg_method) {
|
||||||
@@ -117,7 +105,6 @@ function the_science_is_good(awcp_rcp_data) {
|
|||||||
console.error("we're going to have to put the science to sleep");
|
console.error("we're going to have to put the science to sleep");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called in response to "connection.open" requests from page scripts
|
* Called in response to "connection.open" requests from page scripts
|
||||||
*
|
*
|
||||||
@@ -126,16 +113,13 @@ function the_science_is_good(awcp_rcp_data) {
|
|||||||
function post_connect_msg(msg_ident) {
|
function post_connect_msg(msg_ident) {
|
||||||
// : EventData_W2A_connection_open
|
// : EventData_W2A_connection_open
|
||||||
// http://localhost:6969/local-awcp-0.2.1/types/EventData_W2A_connection_open.html
|
// http://localhost:6969/local-awcp-0.2.1/types/EventData_W2A_connection_open.html
|
||||||
let connect_response =
|
let connect_response = { type: "to_aepp",
|
||||||
{type: "to_aepp",
|
data: { jsonrpc: "2.0",
|
||||||
data: {jsonrpc: "2.0",
|
id: msg_ident,
|
||||||
id: msg_ident,
|
method: "connection.open",
|
||||||
method: "connection.open",
|
result: detect_msg } };
|
||||||
result: detect_msg}};
|
|
||||||
window.postMessage(connect_response, '*');
|
window.postMessage(connect_response, '*');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called in response to "address.subscribe" requests from page scripts
|
* Called in response to "address.subscribe" requests from page scripts
|
||||||
*
|
*
|
||||||
@@ -143,8 +127,6 @@ function post_connect_msg(msg_ident) {
|
|||||||
*/
|
*/
|
||||||
function bg_address_subscribe(msg_ident) {
|
function bg_address_subscribe(msg_ident) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called in response to "transaction.sign" requests from page scripts
|
* Called in response to "transaction.sign" requests from page scripts
|
||||||
*
|
*
|
||||||
@@ -152,7 +134,6 @@ function bg_address_subscribe(msg_ident) {
|
|||||||
*/
|
*/
|
||||||
function bg_tx_sign(msg_ident, params) {
|
function bg_tx_sign(msg_ident, params) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called in response to "message.sign" requests from page scripts
|
* Called in response to "message.sign" requests from page scripts
|
||||||
*
|
*
|
||||||
@@ -160,10 +141,10 @@ function bg_tx_sign(msg_ident, params) {
|
|||||||
*/
|
*/
|
||||||
function bg_msg_sign(msg_ident, params) {
|
function bg_msg_sign(msg_ident, params) {
|
||||||
}
|
}
|
||||||
|
// @ts-ignore browser
|
||||||
browser.runtime.onMessage.addListener(handler);
|
browser.runtime.onMessage.addListener(handler);
|
||||||
window.addEventListener('message', window_message_handler);
|
window.addEventListener('message', window_message_handler);
|
||||||
//window.addEventListener('message', function(evt) { console.error('BYYYYYYYYYYYYYYY', evt) });
|
//window.addEventListener('message', function(evt) { console.error('BYYYYYYYYYYYYYYY', evt) });
|
||||||
//window.addEventListener('click', function() { console.error('HERRRO'); });
|
//window.addEventListener('click', function() { console.error('HERRRO'); });
|
||||||
|
|
||||||
console.error('poop');
|
console.error('poop');
|
||||||
|
//# sourceMappingURL=content.js.map
|
||||||
Vendored
+1
@@ -0,0 +1 @@
|
|||||||
|
{"version":3,"file":"content.js","sourceRoot":"","sources":["../src/content.ts"],"names":[],"mappings":";AAAA,IAAI,UAAU,GACN,EAAC,EAAE,EAAU,OAAO;IACnB,IAAI,EAAQ,IAAI;IAChB,SAAS,EAAG,QAAQ;IACpB,MAAM,EAAM,eAAe;IAC3B,IAAI,EAAQ,WAAW,EAAC,CAAC;AAElC,IAAI,eAAe,GACX,EAAC,IAAI,EAAE,SAAS;IACf,IAAI,EAAE,EAAC,OAAO,EAAE,KAAK;QACd,MAAM,EAAE,6BAA6B;QACrC,MAAM,EAAE,UAAU,EAAC,EAAC,CAAC;AAIrC,SAAS,eAAe;IACpB,MAAM,CAAC,WAAW,CAAC,eAAe,EAAE,GAAG,CAAC,CAAC;AAC7C,CAAC;AAGD,KAAK,UAAU,aAAa;IACxB,gBAAgB;IAChB,kCAAkC;IAClC,KAAK,IAAI,CAAC,GAAC,CAAC,EAAE,CAAC,IAAE,EAAE,EAAE,CAAC,EAAE,EAAE;QACtB,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACrB,eAAe,EAAE,CAAC;QAClB,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC;KACrB;AACL,CAAC;AAED,SAAS,KAAK,CAAC,EAAU;IACrB,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AAC3D,CAAC;AAGD;;GAEG;AACH,SAAS,OAAO,CAAC,GAAQ;IACrB,OAAO,CAAC,KAAK,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;IAChC,QAAO,GAAG,EAAE;QACR,KAAK,eAAe;YAChB,aAAa,EAAE,CAAC;YAChB,OAAO;QACX;YACI,OAAO,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;KACzC;AACL,CAAC;AAED;;GAEG;AACH,SAAS,sBAAsB,CAAC,GAAgB;IAC5C,OAAO,CAAC,KAAK,CAAC,uBAAuB,EAAE,GAAG,CAAC,CAAC;IAC5C,mBAAmB;IACnB,IAAI;IACJ,0BAA0B;IAC1B,cAAc;IACd,wBAAwB;IACxB,6BAA6B;IAC7B,mCAAmC;IACnC,kBAAkB;IAClB,qCAAqC;IACrC,qBAAqB;IACrB,QAAQ;IACR,MAAM;IACN,IAAI;IACJ,IAAI,WAAW,GAAG,GAAG,CAAC,IAAI,CAAC;IAC3B,OAAO,CAAC,KAAK,CAAC,eAAe,EAAE,WAAW,CAAC,CAAC;IAC5C,OAAO,CAAC,KAAK,CAAC,6BAA6B,CAAC,CAAC;IAC7C,IAAI,WAAW,CAAC,IAAI,KAAK,YAAY,EAAE;QACnC,OAAO,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;QACrC,mBAAmB,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;KACzC;SACI;QACD,OAAO,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;KACvC;AACL,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,mBAAmB,CAAC,aAAkE;IAC3F,wBAAwB;IACxB,uBAAuB;IACvB,oBAAoB;IACpB,8BAA8B;IAC9B,gCAAgC;IAChC,iDAAiD;IACjD,6CAA6C;IAC7C,6BAA6B;IAC7B,0BAA0B;IAC1B,IAAI,SAAS,GAAI,aAAa,CAAC,EAAE,CAAC;IAClC,IAAI,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC;IACtC,oCAAoC;IACpC,QAAQ,UAAU,EAAE;QAChB,KAAK,iBAAiB;YAClB,gBAAgB,CAAC,SAAS,CAAC,CAAC;YAC5B,MAAM;QACV,KAAK,mBAAmB;YACpB,oBAAoB,CAAC,SAAS,CAAC,CAAC;YAChC,MAAM;QACV,KAAK,kBAAkB;YACnB,UAAU,CAAC,SAAS,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;YAC5C,MAAM;QACV,KAAK,cAAc;YACf,WAAW,CAAC,SAAS,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;YAC7C,MAAM;QACV;YACI,OAAO,CAAC,KAAK,CAAC,+CAA+C,CAAC,CAAC;YAC/D,OAAO,CAAC,KAAK,CAAC,iDAAiD,CAAC,CAAC;KACxE;AACL,CAAC;AAED;;;;GAIG;AACH,SAAS,gBAAgB,CAAC,SAAwB;IAC9C,kCAAkC;IAClC,kFAAkF;IAClF,IAAI,gBAAgB,GACZ,EAAC,IAAI,EAAE,SAAS;QACf,IAAI,EAAE,EAAC,OAAO,EAAE,KAAK;YACd,EAAE,EAAE,SAAS;YACb,MAAM,EAAE,iBAAiB;YACzB,MAAM,EAAE,UAAU,EAAC,EAAC,CAAC;IACrC,MAAM,CAAC,WAAW,CAAC,gBAAgB,EAAE,GAAG,CAAC,CAAC;AAC9C,CAAC;AAGD;;;;GAIG;AACH,SAAS,oBAAoB,CAAC,SAAwB;AACtD,CAAC;AAGD;;;;GAIG;AACH,SAAS,UAAU,CAAC,SAAwB,EAAE,MAAc;AAC5D,CAAC;AAED;;;;GAIG;AACH,SAAS,WAAW,CAAC,SAAwB,EAAE,MAAc;AAC7D,CAAC;AAED,qBAAqB;AACrB,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;AAC/C,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,sBAAsB,CAAC,CAAC;AAC3D,+FAA+F;AAC/F,4EAA4E;AAE5E,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC"}
|
||||||
Vendored
+193
@@ -0,0 +1,193 @@
|
|||||||
|
/**
|
||||||
|
* This is the script for the popup window
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* runs whenever the popup opens
|
||||||
|
*/
|
||||||
|
declare function main(): Promise<void>;
|
||||||
|
/**
|
||||||
|
* Tells the content script to spam the event bus with detection messages
|
||||||
|
*/
|
||||||
|
declare function detuctable(): Promise<void>;
|
||||||
|
/**
|
||||||
|
* gets the id of the current tab
|
||||||
|
*/
|
||||||
|
declare function active_tab_id(): Promise<number>;
|
||||||
|
/**
|
||||||
|
* clear the list of keypairs and relist
|
||||||
|
*
|
||||||
|
* clearing is so this can be a re-entry call
|
||||||
|
*/
|
||||||
|
declare function relist_keypairs(): Promise<void>;
|
||||||
|
/**
|
||||||
|
* kill all child nodes in the dom
|
||||||
|
*/
|
||||||
|
declare function pfizer(elt: HTMLElement): void;
|
||||||
|
/**
|
||||||
|
* This function is called in the init phase (after the user clicks the popup)
|
||||||
|
*
|
||||||
|
* If we have keypairs, put them in the keypairs element in the popup window
|
||||||
|
*
|
||||||
|
* Example call objects:
|
||||||
|
*
|
||||||
|
* Case of no keypairs:
|
||||||
|
*
|
||||||
|
* ```js
|
||||||
|
* obj = {}
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* Case of a named keypair
|
||||||
|
*
|
||||||
|
* ```js
|
||||||
|
* obj = {
|
||||||
|
* keypairs: [
|
||||||
|
* {
|
||||||
|
* name: string,
|
||||||
|
* publicKey: uint8array
|
||||||
|
* secretKey: uint8array
|
||||||
|
* },
|
||||||
|
* {
|
||||||
|
* name: string,
|
||||||
|
* publicKey: uint8array
|
||||||
|
* secretKey: uint8array
|
||||||
|
* }
|
||||||
|
* ]
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
declare function handle_keypairs(obj: {
|
||||||
|
keypairs?: Array<named_keypair>;
|
||||||
|
}): Promise<void>;
|
||||||
|
/**
|
||||||
|
* function called if there are no keypairs
|
||||||
|
*/
|
||||||
|
declare function no_keypairs(): void;
|
||||||
|
declare type keypair = {
|
||||||
|
publicKey: Uint8Array;
|
||||||
|
secretKey: Uint8Array;
|
||||||
|
};
|
||||||
|
declare type named_keypair = keypair & {
|
||||||
|
name: string;
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* This function is called when the user clicks the button to generate a keypair
|
||||||
|
*/
|
||||||
|
declare function generate_keypair(): Promise<void>;
|
||||||
|
/**
|
||||||
|
* This function is called in the case where there is at least one keypair, and
|
||||||
|
* it renders the list of keypairs
|
||||||
|
*/
|
||||||
|
declare function ls_keypairs(keypairs: Array<named_keypair>): Promise<void>;
|
||||||
|
/**
|
||||||
|
* This renders a single keypair item in the list of keypairs
|
||||||
|
*/
|
||||||
|
declare function render_keypair(parent_ul: HTMLElement, nk: named_keypair): Promise<void>;
|
||||||
|
/**
|
||||||
|
* take the publicKey bytes and output a string of the form ak_...
|
||||||
|
*/
|
||||||
|
declare function publicKey_bytes_to_str(publicKey_bytes: Uint8Array): Promise<string>;
|
||||||
|
/**
|
||||||
|
* take the first 4 bytes from sha256(sha256(inputBytes)) and concatenate it onto input, return that
|
||||||
|
*
|
||||||
|
* From https://github.com/aeternity/protocol/blob/c007deeac4a01e401238412801ac7084ac72d60e/node/api/api_encoding.md
|
||||||
|
*
|
||||||
|
* ```erlang
|
||||||
|
* add_check_bytes(Bin) when is_binary(Bin) ->
|
||||||
|
* <<Check:4/binary, _/binary>> = sha256(sha256(Bin)),
|
||||||
|
* <<Bin/binary, Check/binary>>.
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
declare function shasha4_concat(input_bytes: Uint8Array): Promise<Uint8Array>;
|
||||||
|
/**
|
||||||
|
* the first 4 bytes of the sha256 of the sha256 of the input
|
||||||
|
*
|
||||||
|
* returns a Uint8Array
|
||||||
|
*/
|
||||||
|
declare function shasha4(input_bytes: Uint8Array): Promise<Uint8Array>;
|
||||||
|
/**
|
||||||
|
* Console.log the message and put it in the log thing
|
||||||
|
*/
|
||||||
|
declare function logln(message: string): void;
|
||||||
|
/**
|
||||||
|
* Base58 encoding/decoding
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* Encode a Uint8Array into base58
|
||||||
|
*/
|
||||||
|
declare function encode(binary: Uint8Array): string;
|
||||||
|
/**
|
||||||
|
* count the number of leading zeros in a uint8array
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
declare function nlz(bytes: Uint8Array): number;
|
||||||
|
/**
|
||||||
|
* Generate a bunch of '1's for however many leading zeros there are
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
declare function encode_zeros(how_many: number): string;
|
||||||
|
/**
|
||||||
|
* Encode a Uint8Array that has no leading zeros
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
declare function encode_rest(bytes: Uint8Array): string;
|
||||||
|
/**
|
||||||
|
* Convert a bytestring to a bignum
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
declare function bytes_to_bigint(bytes: Uint8Array): bigint;
|
||||||
|
/**
|
||||||
|
* Convert a BigInt to Base58
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
declare function bignum_to_base58(q: bigint): string;
|
||||||
|
/**
|
||||||
|
* Decode a Base58 string into a Uint8Array
|
||||||
|
*/
|
||||||
|
declare function decode(base58: string): Uint8Array;
|
||||||
|
/**
|
||||||
|
* count the number of leading 1 characters in a uint8array
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
declare function nlo(base58: string): number;
|
||||||
|
/**
|
||||||
|
* Generate a bunch of '0's for however many leading ones there are
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
declare function decode_ones(how_many: number): Array<number>;
|
||||||
|
/**
|
||||||
|
* Decode a string that has no leading 1s
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
declare function decode_rest(base58: string): Array<number>;
|
||||||
|
/**
|
||||||
|
* Convert a base58 string to a bignum
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
declare function base58_to_bigint(base58: string): bigint;
|
||||||
|
/**
|
||||||
|
* convert a bignum into a byte array
|
||||||
|
*
|
||||||
|
* @end
|
||||||
|
*/
|
||||||
|
declare function bigint_to_base256(q: bigint): Array<number>;
|
||||||
|
/**
|
||||||
|
* Base58 integer -> character conversion table
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
declare function bigint_to_char(n: bigint): string;
|
||||||
|
/**
|
||||||
|
* Base58 character -> integer conversion table
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
declare function char_to_bigint(s: string): bigint;
|
||||||
Vendored
+539
@@ -0,0 +1,539 @@
|
|||||||
|
"use strict";
|
||||||
|
/**
|
||||||
|
* This is the script for the popup window
|
||||||
|
*/
|
||||||
|
//import {default as nacl} from './nacl.js';
|
||||||
|
main();
|
||||||
|
/**
|
||||||
|
* runs whenever the popup opens
|
||||||
|
*/
|
||||||
|
async function main() {
|
||||||
|
// detect button action
|
||||||
|
document.getElementById('mk-detectable').onclick = detuctable;
|
||||||
|
document.getElementById('generate').onclick = generate_keypair;
|
||||||
|
// delete keypairs
|
||||||
|
// browser.storage.local.clear();
|
||||||
|
await relist_keypairs();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Tells the content script to spam the event bus with detection messages
|
||||||
|
*/
|
||||||
|
async function detuctable() {
|
||||||
|
let ati = await active_tab_id();
|
||||||
|
// @ts-ignore browser api unknown
|
||||||
|
browser.tabs.sendMessage(ati, // active tab
|
||||||
|
'mk-detectable'); // message
|
||||||
|
// @ts-ignore disabled exists on this
|
||||||
|
document.getElementById('mk-detectable').disabled = true;
|
||||||
|
// FIXME: update button with detect info
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* gets the id of the current tab
|
||||||
|
*/
|
||||||
|
async function active_tab_id() {
|
||||||
|
// @ts-ignore browser api unkown
|
||||||
|
let active_tabs = await browser.tabs.query({ active: true, currentWindow: true });
|
||||||
|
return active_tabs[0].id;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* clear the list of keypairs and relist
|
||||||
|
*
|
||||||
|
* clearing is so this can be a re-entry call
|
||||||
|
*/
|
||||||
|
async function relist_keypairs() {
|
||||||
|
// delete all list items
|
||||||
|
pfizer(document.getElementById('keypairs'));
|
||||||
|
// look for keypairs then relist
|
||||||
|
// @ts-ignore browser api
|
||||||
|
let obj = await browser.storage.local.get('keypairs');
|
||||||
|
await handle_keypairs(obj);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* kill all child nodes in the dom
|
||||||
|
*/
|
||||||
|
function pfizer(elt) {
|
||||||
|
while (elt.firstChild) {
|
||||||
|
elt.removeChild(elt.firstChild);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* This function is called in the init phase (after the user clicks the popup)
|
||||||
|
*
|
||||||
|
* If we have keypairs, put them in the keypairs element in the popup window
|
||||||
|
*
|
||||||
|
* Example call objects:
|
||||||
|
*
|
||||||
|
* Case of no keypairs:
|
||||||
|
*
|
||||||
|
* ```js
|
||||||
|
* obj = {}
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* Case of a named keypair
|
||||||
|
*
|
||||||
|
* ```js
|
||||||
|
* obj = {
|
||||||
|
* keypairs: [
|
||||||
|
* {
|
||||||
|
* name: string,
|
||||||
|
* publicKey: uint8array
|
||||||
|
* secretKey: uint8array
|
||||||
|
* },
|
||||||
|
* {
|
||||||
|
* name: string,
|
||||||
|
* publicKey: uint8array
|
||||||
|
* secretKey: uint8array
|
||||||
|
* }
|
||||||
|
* ]
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
async function handle_keypairs(obj) {
|
||||||
|
logln('handle_keypairs');
|
||||||
|
// branch on if there are no keypairs
|
||||||
|
// no 'keypairs' key
|
||||||
|
if (!!!obj.keypairs) {
|
||||||
|
no_keypairs();
|
||||||
|
}
|
||||||
|
// 'keypairs' key but points to empty array
|
||||||
|
else if (0 === obj.keypairs.length) {
|
||||||
|
no_keypairs();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
await ls_keypairs(obj.keypairs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* function called if there are no keypairs
|
||||||
|
*/
|
||||||
|
function no_keypairs() {
|
||||||
|
logln('no keypairs!');
|
||||||
|
document.getElementById('no-keypairs').hidden = false;
|
||||||
|
}
|
||||||
|
// publicKey : Uint8Array,
|
||||||
|
// secretKey : Uint8Array};
|
||||||
|
/**
|
||||||
|
* This function is called when the user clicks the button to generate a keypair
|
||||||
|
*/
|
||||||
|
async function generate_keypair() {
|
||||||
|
logln('generating a keypair');
|
||||||
|
// @ts-ignore namespace nacl
|
||||||
|
let keypair = nacl.sign.keyPair();
|
||||||
|
// @ts-ignore changing type
|
||||||
|
keypair.name = "Untitled Keypair 1";
|
||||||
|
// fixme: ADD keypair (factor out into separate function)
|
||||||
|
// @ts-ignore cannot find namespace browser
|
||||||
|
browser.storage.local.set({ 'keypairs': [keypair] });
|
||||||
|
await relist_keypairs();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* This function is called in the case where there is at least one keypair, and
|
||||||
|
* it renders the list of keypairs
|
||||||
|
*/
|
||||||
|
async function ls_keypairs(keypairs) {
|
||||||
|
logln('keypairs!');
|
||||||
|
console.log('keypairs: ', keypairs);
|
||||||
|
// make keypair list visible
|
||||||
|
let keypairs_ul = document.getElementById('keypairs');
|
||||||
|
keypairs_ul.hidden = false;
|
||||||
|
// render each keypair
|
||||||
|
for (let kp of keypairs) {
|
||||||
|
console.log(kp);
|
||||||
|
await render_keypair(keypairs_ul, kp);
|
||||||
|
}
|
||||||
|
//let keypairs_json = JSON.stringify(keypairs, undefined, 4);
|
||||||
|
//document.getElementById('keypairs').innerHTML = keypairs_json;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* This renders a single keypair item in the list of keypairs
|
||||||
|
*/
|
||||||
|
async function render_keypair(parent_ul, nk) {
|
||||||
|
let name = nk.name;
|
||||||
|
let publicKey = nk.publicKey;
|
||||||
|
// create the element
|
||||||
|
// <li></li>
|
||||||
|
let li = document.createElement('li');
|
||||||
|
// <li></li> -> <li>{name}</li>
|
||||||
|
li.innerHTML += name;
|
||||||
|
// <li>{name}</li> -> <li>{name}<br></li>
|
||||||
|
li.appendChild(document.createElement('br'));
|
||||||
|
// <code></code>
|
||||||
|
let code = document.createElement('code');
|
||||||
|
let pubkey_str = await publicKey_bytes_to_str(publicKey);
|
||||||
|
// <code></code> -> <code>ak_...</code>
|
||||||
|
code.innerHTML += pubkey_str;
|
||||||
|
// <li>...</li> -> <li>...<code>...</code></li>
|
||||||
|
li.appendChild(code);
|
||||||
|
// <ul></ul> -> <ul><li>...</li></ul>
|
||||||
|
parent_ul.appendChild(li);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* take the publicKey bytes and output a string of the form ak_...
|
||||||
|
*/
|
||||||
|
async function publicKey_bytes_to_str(publicKey_bytes) {
|
||||||
|
// From https://github.com/aeternity/protocol/blob/c007deeac4a01e401238412801ac7084ac72d60e/node/api/api_encoding.md
|
||||||
|
//
|
||||||
|
// ```erlang
|
||||||
|
// add_check_bytes(Bin) when is_binary(Bin) ->
|
||||||
|
// <<Check:4/binary, _/binary>> = sha256(sha256(Bin)),
|
||||||
|
// <<Bin/binary, Check/binary>>.
|
||||||
|
// ```
|
||||||
|
let bytes_to_encode = await shasha4_concat(publicKey_bytes);
|
||||||
|
let b58_str = encode(bytes_to_encode);
|
||||||
|
return 'ak_' + b58_str;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* take the first 4 bytes from sha256(sha256(inputBytes)) and concatenate it onto input, return that
|
||||||
|
*
|
||||||
|
* From https://github.com/aeternity/protocol/blob/c007deeac4a01e401238412801ac7084ac72d60e/node/api/api_encoding.md
|
||||||
|
*
|
||||||
|
* ```erlang
|
||||||
|
* add_check_bytes(Bin) when is_binary(Bin) ->
|
||||||
|
* <<Check:4/binary, _/binary>> = sha256(sha256(Bin)),
|
||||||
|
* <<Bin/binary, Check/binary>>.
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
async function shasha4_concat(input_bytes) {
|
||||||
|
let shasha4_bytes = await shasha4(input_bytes);
|
||||||
|
let input_bytes_length = input_bytes.byteLength;
|
||||||
|
// this is so dumb
|
||||||
|
// make blank array
|
||||||
|
let return_bytes = new Uint8Array(input_bytes_length + 4);
|
||||||
|
// copy input bytes into it
|
||||||
|
for (let input_bytes_idx0 = 0; input_bytes_idx0 < input_bytes_length; input_bytes_idx0++) {
|
||||||
|
return_bytes[input_bytes_idx0] = input_bytes[input_bytes_idx0];
|
||||||
|
}
|
||||||
|
// copy sha bytes
|
||||||
|
for (let shasha4_bytes_idx0 = 0; shasha4_bytes_idx0 < 4; shasha4_bytes_idx0++) {
|
||||||
|
// if shasha4_bytes_idx0 = 0, then we want to start at input_bytes_length
|
||||||
|
let return_bytes_idx0 = input_bytes_length + shasha4_bytes_idx0;
|
||||||
|
return_bytes[return_bytes_idx0] = shasha4_bytes[shasha4_bytes_idx0];
|
||||||
|
}
|
||||||
|
return return_bytes;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* the first 4 bytes of the sha256 of the sha256 of the input
|
||||||
|
*
|
||||||
|
* returns a Uint8Array
|
||||||
|
*/
|
||||||
|
async function shasha4(input_bytes) {
|
||||||
|
let x = await crypto.subtle.digest('SHA-256', input_bytes);
|
||||||
|
let y = await crypto.subtle.digest('SHA-256', x);
|
||||||
|
let z = y.slice(0, 4);
|
||||||
|
return new Uint8Array(z);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Console.log the message and put it in the log thing
|
||||||
|
*/
|
||||||
|
function logln(message) {
|
||||||
|
console.log(message);
|
||||||
|
document.getElementById('log').innerHTML += message;
|
||||||
|
document.getElementById('log').innerHTML += '\n';
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Base58 encoding/decoding
|
||||||
|
*/
|
||||||
|
//=============================================================================
|
||||||
|
// ENCODING
|
||||||
|
//=============================================================================
|
||||||
|
/**
|
||||||
|
* Encode a Uint8Array into base58
|
||||||
|
*/
|
||||||
|
function encode(binary) {
|
||||||
|
let num_leading_zeros = nlz(binary);
|
||||||
|
let rest = binary.slice(num_leading_zeros);
|
||||||
|
let ones = encode_zeros(num_leading_zeros);
|
||||||
|
let rest_b58 = encode_rest(rest);
|
||||||
|
let result = ones + rest_b58;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* count the number of leading zeros in a uint8array
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
function nlz(bytes) {
|
||||||
|
let n = 0;
|
||||||
|
for (let this_byte of bytes) {
|
||||||
|
if (0 === this_byte) {
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Generate a bunch of '1's for however many leading zeros there are
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
function encode_zeros(how_many) {
|
||||||
|
let ones = '';
|
||||||
|
for (let i = 1; i <= how_many; i++) {
|
||||||
|
ones += '1';
|
||||||
|
}
|
||||||
|
return ones;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Encode a Uint8Array that has no leading zeros
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
function encode_rest(bytes) {
|
||||||
|
let bytes_bignum = bytes_to_bigint(bytes);
|
||||||
|
let result = bignum_to_base58(bytes_bignum);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Convert a bytestring to a bignum
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
function bytes_to_bigint(bytes) {
|
||||||
|
let acc_bigint = 0n;
|
||||||
|
for (let this_byte of bytes) {
|
||||||
|
acc_bigint <<= 8n;
|
||||||
|
acc_bigint += BigInt(this_byte);
|
||||||
|
}
|
||||||
|
return acc_bigint;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Convert a BigInt to Base58
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
function bignum_to_base58(q) {
|
||||||
|
let s = '';
|
||||||
|
while (q !== 0n) {
|
||||||
|
let this_n = q % 58n;
|
||||||
|
q /= 58n;
|
||||||
|
let this_b58_char = bigint_to_char(this_n);
|
||||||
|
s = this_b58_char + s;
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
//=============================================================================
|
||||||
|
// DECODING
|
||||||
|
//=============================================================================
|
||||||
|
/**
|
||||||
|
* Decode a Base58 string into a Uint8Array
|
||||||
|
*/
|
||||||
|
function decode(base58) {
|
||||||
|
let num_leading_ones = nlo(base58);
|
||||||
|
let rest = base58.slice(num_leading_ones);
|
||||||
|
let zeros = decode_ones(num_leading_ones);
|
||||||
|
let rest_arr = decode_rest(rest);
|
||||||
|
let pre_result = zeros.concat(rest_arr);
|
||||||
|
return new Uint8Array(pre_result);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* count the number of leading 1 characters in a uint8array
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
function nlo(base58) {
|
||||||
|
let n = 0;
|
||||||
|
for (let this_char of base58) {
|
||||||
|
if ('1' === this_char) {
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Generate a bunch of '0's for however many leading ones there are
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
function decode_ones(how_many) {
|
||||||
|
let zeros = [];
|
||||||
|
for (let i = 1; i <= how_many; i++) {
|
||||||
|
zeros.push(0);
|
||||||
|
}
|
||||||
|
return zeros;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Decode a string that has no leading 1s
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
function decode_rest(base58) {
|
||||||
|
let result_bignum = base58_to_bigint(base58);
|
||||||
|
let result = bigint_to_base256(result_bignum);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Convert a base58 string to a bignum
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
function base58_to_bigint(base58) {
|
||||||
|
let acc_bigint = 0n;
|
||||||
|
for (let this_char of base58) {
|
||||||
|
acc_bigint *= 58n;
|
||||||
|
acc_bigint += char_to_bigint(this_char);
|
||||||
|
}
|
||||||
|
return acc_bigint;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* convert a bignum into a byte array
|
||||||
|
*
|
||||||
|
* @end
|
||||||
|
*/
|
||||||
|
function bigint_to_base256(q) {
|
||||||
|
let arr_reverse = [];
|
||||||
|
while (q !== 0n) {
|
||||||
|
let r = Number(q % 256n);
|
||||||
|
q /= 256n;
|
||||||
|
arr_reverse.push(r);
|
||||||
|
}
|
||||||
|
arr_reverse.reverse();
|
||||||
|
return arr_reverse;
|
||||||
|
}
|
||||||
|
//=============================================================================
|
||||||
|
// TRANSLATION TABLES
|
||||||
|
//=============================================================================
|
||||||
|
/**
|
||||||
|
* Base58 integer -> character conversion table
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
function bigint_to_char(n) {
|
||||||
|
switch (n) {
|
||||||
|
case 0n: return '1';
|
||||||
|
case 1n: return '2';
|
||||||
|
case 2n: return '3';
|
||||||
|
case 3n: return '4';
|
||||||
|
case 4n: return '5';
|
||||||
|
case 5n: return '6';
|
||||||
|
case 6n: return '7';
|
||||||
|
case 7n: return '8';
|
||||||
|
case 8n: return '9';
|
||||||
|
case 9n: return 'A';
|
||||||
|
case 10n: return 'B';
|
||||||
|
case 11n: return 'C';
|
||||||
|
case 12n: return 'D';
|
||||||
|
case 13n: return 'E';
|
||||||
|
case 14n: return 'F';
|
||||||
|
case 15n: return 'G';
|
||||||
|
case 16n: return 'H';
|
||||||
|
case 17n: return 'J';
|
||||||
|
case 18n: return 'K';
|
||||||
|
case 19n: return 'L';
|
||||||
|
case 20n: return 'M';
|
||||||
|
case 21n: return 'N';
|
||||||
|
case 22n: return 'P';
|
||||||
|
case 23n: return 'Q';
|
||||||
|
case 24n: return 'R';
|
||||||
|
case 25n: return 'S';
|
||||||
|
case 26n: return 'T';
|
||||||
|
case 27n: return 'U';
|
||||||
|
case 28n: return 'V';
|
||||||
|
case 29n: return 'W';
|
||||||
|
case 30n: return 'X';
|
||||||
|
case 31n: return 'Y';
|
||||||
|
case 32n: return 'Z';
|
||||||
|
case 33n: return 'a';
|
||||||
|
case 34n: return 'b';
|
||||||
|
case 35n: return 'c';
|
||||||
|
case 36n: return 'd';
|
||||||
|
case 37n: return 'e';
|
||||||
|
case 38n: return 'f';
|
||||||
|
case 39n: return 'g';
|
||||||
|
case 40n: return 'h';
|
||||||
|
case 41n: return 'i';
|
||||||
|
case 42n: return 'j';
|
||||||
|
case 43n: return 'k';
|
||||||
|
case 44n: return 'm';
|
||||||
|
case 45n: return 'n';
|
||||||
|
case 46n: return 'o';
|
||||||
|
case 47n: return 'p';
|
||||||
|
case 48n: return 'q';
|
||||||
|
case 49n: return 'r';
|
||||||
|
case 50n: return 's';
|
||||||
|
case 51n: return 't';
|
||||||
|
case 52n: return 'u';
|
||||||
|
case 53n: return 'v';
|
||||||
|
case 54n: return 'w';
|
||||||
|
case 55n: return 'x';
|
||||||
|
case 56n: return 'y';
|
||||||
|
case 57n: return 'z';
|
||||||
|
default:
|
||||||
|
throw new Error('invalid base58 bigint: ' + n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Base58 character -> integer conversion table
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
function char_to_bigint(s) {
|
||||||
|
switch (s) {
|
||||||
|
case '1': return 0n;
|
||||||
|
case '2': return 1n;
|
||||||
|
case '3': return 2n;
|
||||||
|
case '4': return 3n;
|
||||||
|
case '5': return 4n;
|
||||||
|
case '6': return 5n;
|
||||||
|
case '7': return 6n;
|
||||||
|
case '8': return 7n;
|
||||||
|
case '9': return 8n;
|
||||||
|
case 'A': return 9n;
|
||||||
|
case 'B': return 10n;
|
||||||
|
case 'C': return 11n;
|
||||||
|
case 'D': return 12n;
|
||||||
|
case 'E': return 13n;
|
||||||
|
case 'F': return 14n;
|
||||||
|
case 'G': return 15n;
|
||||||
|
case 'H': return 16n;
|
||||||
|
case 'J': return 17n;
|
||||||
|
case 'K': return 18n;
|
||||||
|
case 'L': return 19n;
|
||||||
|
case 'M': return 20n;
|
||||||
|
case 'N': return 21n;
|
||||||
|
case 'P': return 22n;
|
||||||
|
case 'Q': return 23n;
|
||||||
|
case 'R': return 24n;
|
||||||
|
case 'S': return 25n;
|
||||||
|
case 'T': return 26n;
|
||||||
|
case 'U': return 27n;
|
||||||
|
case 'V': return 28n;
|
||||||
|
case 'W': return 29n;
|
||||||
|
case 'X': return 30n;
|
||||||
|
case 'Y': return 31n;
|
||||||
|
case 'Z': return 32n;
|
||||||
|
case 'a': return 33n;
|
||||||
|
case 'b': return 34n;
|
||||||
|
case 'c': return 35n;
|
||||||
|
case 'd': return 36n;
|
||||||
|
case 'e': return 37n;
|
||||||
|
case 'f': return 38n;
|
||||||
|
case 'g': return 39n;
|
||||||
|
case 'h': return 40n;
|
||||||
|
case 'i': return 41n;
|
||||||
|
case 'j': return 42n;
|
||||||
|
case 'k': return 43n;
|
||||||
|
case 'm': return 44n;
|
||||||
|
case 'n': return 45n;
|
||||||
|
case 'o': return 46n;
|
||||||
|
case 'p': return 47n;
|
||||||
|
case 'q': return 48n;
|
||||||
|
case 'r': return 49n;
|
||||||
|
case 's': return 50n;
|
||||||
|
case 't': return 51n;
|
||||||
|
case 'u': return 52n;
|
||||||
|
case 'v': return 53n;
|
||||||
|
case 'w': return 54n;
|
||||||
|
case 'x': return 55n;
|
||||||
|
case 'y': return 56n;
|
||||||
|
case 'z': return 57n;
|
||||||
|
default:
|
||||||
|
throw new Error('invalid base58 char: ' + s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//# sourceMappingURL=popup.js.map
|
||||||
Vendored
+1
File diff suppressed because one or more lines are too long
@@ -0,0 +1,5 @@
|
|||||||
|
{type, extension}.
|
||||||
|
{realm, local}.
|
||||||
|
{name, jrx}.
|
||||||
|
{version, "0.1.0"}.
|
||||||
|
{deps, []}.
|
||||||
+1
-1
@@ -5,7 +5,7 @@
|
|||||||
"icons" : {"48" : "icons/jrx-icon-48.png",
|
"icons" : {"48" : "icons/jrx-icon-48.png",
|
||||||
"96" : "icons/jrx-icon-96.png"},
|
"96" : "icons/jrx-icon-96.png"},
|
||||||
"content_scripts" : [{"matches" : ["*://*/*"],
|
"content_scripts" : [{"matches" : ["*://*/*"],
|
||||||
"js" : ["content.js"]}],
|
"js" : ["dist/content.js"]}],
|
||||||
"browser_action" : {"default_icon" : "icons/jrx-icon-32.png",
|
"browser_action" : {"default_icon" : "icons/jrx-icon-32.png",
|
||||||
"default_title" : "Jaeck Russell",
|
"default_title" : "Jaeck Russell",
|
||||||
"default_popup" : "popup.html"},
|
"default_popup" : "popup.html"},
|
||||||
|
|||||||
+1
-1
@@ -25,6 +25,6 @@
|
|||||||
<!-- including nacl here -->
|
<!-- including nacl here -->
|
||||||
<script src="nacl.js"></script>
|
<script src="nacl.js"></script>
|
||||||
|
|
||||||
<script type="module" src="popup.js"></script>
|
<script type="module" src="dist/popup.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
-205
@@ -1,205 +0,0 @@
|
|||||||
/**
|
|
||||||
* This is the script for the popup window
|
|
||||||
*/
|
|
||||||
|
|
||||||
//import {default as nacl} from './nacl.js';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* runs whenever the popup opens
|
|
||||||
*/
|
|
||||||
async function
|
|
||||||
main()
|
|
||||||
{
|
|
||||||
// detect button action
|
|
||||||
document.getElementById('mk-detectable').onclick = mk_detectable;
|
|
||||||
document.getElementById('generate').onclick = generate_keypair;
|
|
||||||
|
|
||||||
// delete keypairs
|
|
||||||
// browser.storage.local.clear();
|
|
||||||
relist_keypairs();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tells the content script to spam the event bus with detection messages
|
|
||||||
*/
|
|
||||||
async function
|
|
||||||
mk_detectable()
|
|
||||||
{
|
|
||||||
let ati = await active_tab_id();
|
|
||||||
browser.tabs.sendMessage(ati, // active tab
|
|
||||||
'mk-detectable'); // message
|
|
||||||
document.getElementById('mk-detectable').disabled = true;
|
|
||||||
// FIXME: update button with detect info
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* gets the id of the current tab
|
|
||||||
*/
|
|
||||||
async function
|
|
||||||
active_tab_id()
|
|
||||||
{
|
|
||||||
let active_tabs = await browser.tabs.query({active: true, currentWindow: true});
|
|
||||||
return active_tabs[0].id;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* clear the list of keypairs and relist
|
|
||||||
*
|
|
||||||
* clearing is so this can be a re-entry call
|
|
||||||
*/
|
|
||||||
function
|
|
||||||
relist_keypairs()
|
|
||||||
{
|
|
||||||
// delete all list items
|
|
||||||
pfizer(document.getElementById('keypairs'));
|
|
||||||
// look for keypairs then relist
|
|
||||||
browser.storage.local.get('keypairs').then(handle_keypairs, (err) => { console.error(err); } );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* kill all child nodes in the dom
|
|
||||||
*/
|
|
||||||
function
|
|
||||||
pfizer(elt)
|
|
||||||
{
|
|
||||||
while (elt.firstChild) {
|
|
||||||
elt.removeChild(elt.firstChild);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This function is called in the init phase (after the user clicks the popup)
|
|
||||||
*
|
|
||||||
* If we have keypairs, put them in the keypairs element in the popup window
|
|
||||||
*
|
|
||||||
* Example call objects:
|
|
||||||
*
|
|
||||||
* Case of no keypairs:
|
|
||||||
*
|
|
||||||
* ```js
|
|
||||||
* obj = {}
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* Case of a named keypair
|
|
||||||
*
|
|
||||||
* ```js
|
|
||||||
* obj = {
|
|
||||||
* keypairs: [
|
|
||||||
* {
|
|
||||||
* name: string,
|
|
||||||
* publicKey: uint8array
|
|
||||||
* secretKey: uint8array
|
|
||||||
* },
|
|
||||||
* {
|
|
||||||
* name: string,
|
|
||||||
* publicKey: uint8array
|
|
||||||
* secretKey: uint8array
|
|
||||||
* }
|
|
||||||
* ]
|
|
||||||
* }
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
function
|
|
||||||
handle_keypairs(obj)
|
|
||||||
{
|
|
||||||
logln('handle_keypairs');
|
|
||||||
// branch on if there are no keypairs
|
|
||||||
// no 'keypairs' key
|
|
||||||
if (!!!obj.keypairs) {
|
|
||||||
no_keypairs();
|
|
||||||
}
|
|
||||||
// 'keypairs' key but points to empty array
|
|
||||||
else if (0 === obj.keypairs.length) {
|
|
||||||
no_keypairs();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ls_keypairs(obj.keypairs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* function called if there are no keypairs
|
|
||||||
*/
|
|
||||||
function
|
|
||||||
no_keypairs()
|
|
||||||
{
|
|
||||||
logln('no keypairs!');
|
|
||||||
document.getElementById('no-keypairs').hidden = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This function is called when the user clicks the button to generate a keypair
|
|
||||||
*/
|
|
||||||
function
|
|
||||||
generate_keypair()
|
|
||||||
{
|
|
||||||
logln('generating a keypair');
|
|
||||||
let keypair = nacl.sign.keyPair();
|
|
||||||
keypair.name = "Untitled Keypair 1";
|
|
||||||
// fixme: ADD keypair (factor out into separate function)
|
|
||||||
browser.storage.local.set({'keypairs': [keypair]});
|
|
||||||
relist_keypairs();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This function is called in the case where there is at least one keypair, and
|
|
||||||
* it renders the list of keypairs
|
|
||||||
*/
|
|
||||||
function
|
|
||||||
ls_keypairs(keypairs)
|
|
||||||
{
|
|
||||||
logln('keypairs!');
|
|
||||||
console.log('keypairs: ', keypairs)
|
|
||||||
// make keypair list visible
|
|
||||||
let keypairs_ul = document.getElementById('keypairs');
|
|
||||||
keypairs_ul.hidden = false;
|
|
||||||
// render each keypair
|
|
||||||
for (let kp of keypairs) {
|
|
||||||
console.log(kp);
|
|
||||||
render_keypair(keypairs_ul, kp);
|
|
||||||
}
|
|
||||||
//let keypairs_json = JSON.stringify(keypairs, undefined, 4);
|
|
||||||
//document.getElementById('keypairs').innerHTML = keypairs_json;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This renders a single keypair item in the list of keypairs
|
|
||||||
*/
|
|
||||||
function
|
|
||||||
render_keypair(parent_ul, {name, publicKey})
|
|
||||||
{
|
|
||||||
// create the element
|
|
||||||
let li = document.createElement('li');
|
|
||||||
li.innerHTML += name;
|
|
||||||
parent_ul.appendChild(li);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Console.log the message and put it in the log thing
|
|
||||||
*/
|
|
||||||
function
|
|
||||||
logln(message)
|
|
||||||
{
|
|
||||||
console.log(message);
|
|
||||||
document.getElementById('log').innerHTML += message;
|
|
||||||
document.getElementById('log').innerHTML += '\n';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* send the given message to the tab
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
main();
|
|
||||||
@@ -0,0 +1,170 @@
|
|||||||
|
let detect_msg =
|
||||||
|
{id : "urmom",
|
||||||
|
name : "JR",
|
||||||
|
networkId : "ae_uat",
|
||||||
|
origin : "ur dads balls",
|
||||||
|
type : "extension"};
|
||||||
|
|
||||||
|
let detect_awcp_msg =
|
||||||
|
{type: "to_aepp",
|
||||||
|
data: {jsonrpc: "2.0",
|
||||||
|
method: "connection.announcePresence",
|
||||||
|
params: detect_msg}};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function post_detect_msg() {
|
||||||
|
window.postMessage(detect_awcp_msg, '*');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async function mk_detectable() {
|
||||||
|
//while (true) {
|
||||||
|
// 3 seconds times 40 is 2 minutes
|
||||||
|
for (let i=1; i<=40; i++) {
|
||||||
|
console.error('pee');
|
||||||
|
post_detect_msg();
|
||||||
|
await sleep(3000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function sleep(ms: number) {
|
||||||
|
return new Promise(resolve => setTimeout(resolve, ms));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This handles messages from *other parts of the extension*
|
||||||
|
*/
|
||||||
|
function handler(msg: any) {
|
||||||
|
console.error('message: ', msg);
|
||||||
|
switch(msg) {
|
||||||
|
case 'mk-detectable':
|
||||||
|
mk_detectable();
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
console.error('your mom is dead');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This handles messages from page scripts
|
||||||
|
*/
|
||||||
|
function window_message_handler(msg: {data: any}) {
|
||||||
|
console.error('the science is coming', msg);
|
||||||
|
// example science:
|
||||||
|
// {
|
||||||
|
// "type": "to_waellet",
|
||||||
|
// "data": {
|
||||||
|
// "jsonrpc": "2.0",
|
||||||
|
// "id": "ske-connect-1",
|
||||||
|
// "method": "connection.open",
|
||||||
|
// "params": {
|
||||||
|
// "name": "sidekick examples",
|
||||||
|
// "version": 1
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
let the_science = msg.data;
|
||||||
|
console.error('THE SCIENCE: ', the_science);
|
||||||
|
console.error('is the science good or bad?');
|
||||||
|
if (the_science.type === 'to_waellet') {
|
||||||
|
console.error('the science is good');
|
||||||
|
the_science_is_good(the_science.data);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
console.error('the science is bad');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* window_message_handler handles all messages sent into the event bus,
|
||||||
|
* including messages that we sent (yay js). window_message_handler branches on
|
||||||
|
* whether the message is for us or not (is the science good or bad?). If the
|
||||||
|
* message is for us (the science is good), then this function is triggered.
|
||||||
|
*
|
||||||
|
* The bottom line is this is the function that *actually* handles messages
|
||||||
|
* from the window
|
||||||
|
*/
|
||||||
|
function the_science_is_good(awcp_rcp_data: {id: string|number, method: string, params: object}) {
|
||||||
|
// example science data:
|
||||||
|
// // layer 3: json rpc
|
||||||
|
// {jsonrpc : "2.0",
|
||||||
|
// id : "ske-connect-1",
|
||||||
|
// method : "connection.open",
|
||||||
|
// // layer 4: AWCP-specific semantics
|
||||||
|
// params : {name : "sidekick examples",
|
||||||
|
// version : 1}}}
|
||||||
|
// can assume it is a call
|
||||||
|
let msg_ident = awcp_rcp_data.id;
|
||||||
|
let msg_method = awcp_rcp_data.method;
|
||||||
|
// branch here on the "method" field
|
||||||
|
switch (msg_method) {
|
||||||
|
case "connection.open":
|
||||||
|
post_connect_msg(msg_ident);
|
||||||
|
break;
|
||||||
|
case "address.subscribe":
|
||||||
|
bg_address_subscribe(msg_ident);
|
||||||
|
break;
|
||||||
|
case "transaction.sign":
|
||||||
|
bg_tx_sign(msg_ident, awcp_rcp_data.params);
|
||||||
|
break;
|
||||||
|
case "message.sign":
|
||||||
|
bg_msg_sign(msg_ident, awcp_rcp_data.params);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
console.error('the science is worse than i initially thought');
|
||||||
|
console.error("we're going to have to put the science to sleep");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called in response to "connection.open" requests from page scripts
|
||||||
|
*
|
||||||
|
* FIXME: this should query the user to see if he wants to connect
|
||||||
|
*/
|
||||||
|
function post_connect_msg(msg_ident: string|number) {
|
||||||
|
// : EventData_W2A_connection_open
|
||||||
|
// http://localhost:6969/local-awcp-0.2.1/types/EventData_W2A_connection_open.html
|
||||||
|
let connect_response =
|
||||||
|
{type: "to_aepp",
|
||||||
|
data: {jsonrpc: "2.0",
|
||||||
|
id: msg_ident,
|
||||||
|
method: "connection.open",
|
||||||
|
result: detect_msg}};
|
||||||
|
window.postMessage(connect_response, '*');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called in response to "address.subscribe" requests from page scripts
|
||||||
|
*
|
||||||
|
* this is to get the wallet's address
|
||||||
|
*/
|
||||||
|
function bg_address_subscribe(msg_ident: string|number) {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called in response to "transaction.sign" requests from page scripts
|
||||||
|
*
|
||||||
|
* user wants us to sign a transaction
|
||||||
|
*/
|
||||||
|
function bg_tx_sign(msg_ident: string|number, params: object) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called in response to "message.sign" requests from page scripts
|
||||||
|
*
|
||||||
|
* user wants us to sign a message
|
||||||
|
*/
|
||||||
|
function bg_msg_sign(msg_ident: string|number, params: object) {
|
||||||
|
}
|
||||||
|
|
||||||
|
// @ts-ignore browser
|
||||||
|
browser.runtime.onMessage.addListener(handler);
|
||||||
|
window.addEventListener('message', window_message_handler);
|
||||||
|
//window.addEventListener('message', function(evt) { console.error('BYYYYYYYYYYYYYYY', evt) });
|
||||||
|
//window.addEventListener('click', function() { console.error('HERRRO'); });
|
||||||
|
|
||||||
|
console.error('poop');
|
||||||
@@ -0,0 +1,751 @@
|
|||||||
|
/**
|
||||||
|
* This is the script for the popup window
|
||||||
|
*/
|
||||||
|
|
||||||
|
//import {default as nacl} from './nacl.js';
|
||||||
|
|
||||||
|
main();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* runs whenever the popup opens
|
||||||
|
*/
|
||||||
|
async function
|
||||||
|
main
|
||||||
|
()
|
||||||
|
: Promise<void>
|
||||||
|
{
|
||||||
|
// detect button action
|
||||||
|
document.getElementById('mk-detectable')!.onclick = detuctable;
|
||||||
|
document.getElementById('generate')!.onclick = generate_keypair;
|
||||||
|
|
||||||
|
// delete keypairs
|
||||||
|
// browser.storage.local.clear();
|
||||||
|
await relist_keypairs();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tells the content script to spam the event bus with detection messages
|
||||||
|
*/
|
||||||
|
async function
|
||||||
|
detuctable
|
||||||
|
()
|
||||||
|
: Promise<void>
|
||||||
|
{
|
||||||
|
let ati = await active_tab_id();
|
||||||
|
// @ts-ignore browser api unknown
|
||||||
|
browser.tabs.sendMessage(ati, // active tab
|
||||||
|
'mk-detectable'); // message
|
||||||
|
// @ts-ignore disabled exists on this
|
||||||
|
document.getElementById('mk-detectable').disabled = true;
|
||||||
|
// FIXME: update button with detect info
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gets the id of the current tab
|
||||||
|
*/
|
||||||
|
async function
|
||||||
|
active_tab_id
|
||||||
|
()
|
||||||
|
: Promise<number>
|
||||||
|
{
|
||||||
|
// @ts-ignore browser api unkown
|
||||||
|
let active_tabs = await browser.tabs.query({active: true, currentWindow: true});
|
||||||
|
return active_tabs[0].id;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clear the list of keypairs and relist
|
||||||
|
*
|
||||||
|
* clearing is so this can be a re-entry call
|
||||||
|
*/
|
||||||
|
async function
|
||||||
|
relist_keypairs
|
||||||
|
()
|
||||||
|
: Promise<void>
|
||||||
|
{
|
||||||
|
// delete all list items
|
||||||
|
pfizer(document.getElementById('keypairs')!);
|
||||||
|
// look for keypairs then relist
|
||||||
|
// @ts-ignore browser api
|
||||||
|
let obj = await browser.storage.local.get('keypairs');
|
||||||
|
await handle_keypairs(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* kill all child nodes in the dom
|
||||||
|
*/
|
||||||
|
function
|
||||||
|
pfizer
|
||||||
|
(elt : HTMLElement)
|
||||||
|
: void
|
||||||
|
{
|
||||||
|
while (elt.firstChild) {
|
||||||
|
elt.removeChild(elt.firstChild);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function is called in the init phase (after the user clicks the popup)
|
||||||
|
*
|
||||||
|
* If we have keypairs, put them in the keypairs element in the popup window
|
||||||
|
*
|
||||||
|
* Example call objects:
|
||||||
|
*
|
||||||
|
* Case of no keypairs:
|
||||||
|
*
|
||||||
|
* ```js
|
||||||
|
* obj = {}
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* Case of a named keypair
|
||||||
|
*
|
||||||
|
* ```js
|
||||||
|
* obj = {
|
||||||
|
* keypairs: [
|
||||||
|
* {
|
||||||
|
* name: string,
|
||||||
|
* publicKey: uint8array
|
||||||
|
* secretKey: uint8array
|
||||||
|
* },
|
||||||
|
* {
|
||||||
|
* name: string,
|
||||||
|
* publicKey: uint8array
|
||||||
|
* secretKey: uint8array
|
||||||
|
* }
|
||||||
|
* ]
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
async function
|
||||||
|
handle_keypairs
|
||||||
|
(obj : {keypairs? : Array<named_keypair>})
|
||||||
|
: Promise<void>
|
||||||
|
{
|
||||||
|
logln('handle_keypairs');
|
||||||
|
// branch on if there are no keypairs
|
||||||
|
// no 'keypairs' key
|
||||||
|
if (!!!obj.keypairs) {
|
||||||
|
no_keypairs();
|
||||||
|
}
|
||||||
|
// 'keypairs' key but points to empty array
|
||||||
|
else if (0 === obj.keypairs.length) {
|
||||||
|
no_keypairs();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
await ls_keypairs(obj.keypairs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* function called if there are no keypairs
|
||||||
|
*/
|
||||||
|
function
|
||||||
|
no_keypairs
|
||||||
|
()
|
||||||
|
: void
|
||||||
|
{
|
||||||
|
logln('no keypairs!');
|
||||||
|
document.getElementById('no-keypairs')!.hidden = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
type keypair
|
||||||
|
= {publicKey : Uint8Array,
|
||||||
|
secretKey : Uint8Array};
|
||||||
|
|
||||||
|
type named_keypair
|
||||||
|
= keypair & {name : string};
|
||||||
|
// publicKey : Uint8Array,
|
||||||
|
// secretKey : Uint8Array};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function is called when the user clicks the button to generate a keypair
|
||||||
|
*/
|
||||||
|
async function
|
||||||
|
generate_keypair
|
||||||
|
()
|
||||||
|
: Promise<void>
|
||||||
|
{
|
||||||
|
logln('generating a keypair');
|
||||||
|
// @ts-ignore namespace nacl
|
||||||
|
let keypair : keypair = nacl.sign.keyPair();
|
||||||
|
// @ts-ignore changing type
|
||||||
|
keypair.name = "Untitled Keypair 1";
|
||||||
|
// fixme: ADD keypair (factor out into separate function)
|
||||||
|
// @ts-ignore cannot find namespace browser
|
||||||
|
browser.storage.local.set({'keypairs': [keypair]});
|
||||||
|
await relist_keypairs();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function is called in the case where there is at least one keypair, and
|
||||||
|
* it renders the list of keypairs
|
||||||
|
*/
|
||||||
|
async function
|
||||||
|
ls_keypairs
|
||||||
|
(keypairs : Array<named_keypair>)
|
||||||
|
: Promise<void>
|
||||||
|
{
|
||||||
|
logln('keypairs!');
|
||||||
|
console.log('keypairs: ', keypairs)
|
||||||
|
// make keypair list visible
|
||||||
|
let keypairs_ul = document.getElementById('keypairs')!;
|
||||||
|
keypairs_ul.hidden = false;
|
||||||
|
// render each keypair
|
||||||
|
for (let kp of keypairs) {
|
||||||
|
console.log(kp);
|
||||||
|
await render_keypair(keypairs_ul, kp);
|
||||||
|
}
|
||||||
|
//let keypairs_json = JSON.stringify(keypairs, undefined, 4);
|
||||||
|
//document.getElementById('keypairs').innerHTML = keypairs_json;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This renders a single keypair item in the list of keypairs
|
||||||
|
*/
|
||||||
|
async function
|
||||||
|
render_keypair
|
||||||
|
(parent_ul : HTMLElement,
|
||||||
|
nk : named_keypair)
|
||||||
|
// {name : string,
|
||||||
|
// publicKey : Uint8Array} : named_keypair)
|
||||||
|
: Promise<void>
|
||||||
|
{
|
||||||
|
let name : string = nk.name;
|
||||||
|
let publicKey : Uint8Array = nk.publicKey;
|
||||||
|
// create the element
|
||||||
|
// <li></li>
|
||||||
|
let li = document.createElement('li');
|
||||||
|
// <li></li> -> <li>{name}</li>
|
||||||
|
li.innerHTML += name;
|
||||||
|
// <li>{name}</li> -> <li>{name}<br></li>
|
||||||
|
li.appendChild(document.createElement('br'));
|
||||||
|
|
||||||
|
// <code></code>
|
||||||
|
let code : HTMLElement = document.createElement('code');
|
||||||
|
let pubkey_str : string = await publicKey_bytes_to_str(publicKey);
|
||||||
|
// <code></code> -> <code>ak_...</code>
|
||||||
|
code.innerHTML += pubkey_str;
|
||||||
|
// <li>...</li> -> <li>...<code>...</code></li>
|
||||||
|
li.appendChild(code);
|
||||||
|
|
||||||
|
// <ul></ul> -> <ul><li>...</li></ul>
|
||||||
|
parent_ul.appendChild(li);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* take the publicKey bytes and output a string of the form ak_...
|
||||||
|
*/
|
||||||
|
async function
|
||||||
|
publicKey_bytes_to_str
|
||||||
|
(publicKey_bytes : Uint8Array)
|
||||||
|
: Promise<string>
|
||||||
|
{
|
||||||
|
// From https://github.com/aeternity/protocol/blob/c007deeac4a01e401238412801ac7084ac72d60e/node/api/api_encoding.md
|
||||||
|
//
|
||||||
|
// ```erlang
|
||||||
|
// add_check_bytes(Bin) when is_binary(Bin) ->
|
||||||
|
// <<Check:4/binary, _/binary>> = sha256(sha256(Bin)),
|
||||||
|
// <<Bin/binary, Check/binary>>.
|
||||||
|
// ```
|
||||||
|
let bytes_to_encode = await shasha4_concat(publicKey_bytes);
|
||||||
|
let b58_str = encode(bytes_to_encode);
|
||||||
|
return 'ak_' + b58_str;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* take the first 4 bytes from sha256(sha256(inputBytes)) and concatenate it onto input, return that
|
||||||
|
*
|
||||||
|
* From https://github.com/aeternity/protocol/blob/c007deeac4a01e401238412801ac7084ac72d60e/node/api/api_encoding.md
|
||||||
|
*
|
||||||
|
* ```erlang
|
||||||
|
* add_check_bytes(Bin) when is_binary(Bin) ->
|
||||||
|
* <<Check:4/binary, _/binary>> = sha256(sha256(Bin)),
|
||||||
|
* <<Bin/binary, Check/binary>>.
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
async function
|
||||||
|
shasha4_concat
|
||||||
|
(input_bytes: Uint8Array)
|
||||||
|
: Promise<Uint8Array>
|
||||||
|
{
|
||||||
|
let shasha4_bytes = await shasha4(input_bytes);
|
||||||
|
let input_bytes_length = input_bytes.byteLength;
|
||||||
|
// this is so dumb
|
||||||
|
// make blank array
|
||||||
|
let return_bytes = new Uint8Array(input_bytes_length + 4);
|
||||||
|
// copy input bytes into it
|
||||||
|
for (let input_bytes_idx0 = 0;
|
||||||
|
input_bytes_idx0 < input_bytes_length;
|
||||||
|
input_bytes_idx0++)
|
||||||
|
{
|
||||||
|
return_bytes[input_bytes_idx0] = input_bytes[input_bytes_idx0];
|
||||||
|
}
|
||||||
|
// copy sha bytes
|
||||||
|
for (let shasha4_bytes_idx0 = 0;
|
||||||
|
shasha4_bytes_idx0 < 4;
|
||||||
|
shasha4_bytes_idx0++)
|
||||||
|
{
|
||||||
|
// if shasha4_bytes_idx0 = 0, then we want to start at input_bytes_length
|
||||||
|
let return_bytes_idx0 = input_bytes_length + shasha4_bytes_idx0;
|
||||||
|
return_bytes[return_bytes_idx0] = shasha4_bytes[shasha4_bytes_idx0];
|
||||||
|
}
|
||||||
|
return return_bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the first 4 bytes of the sha256 of the sha256 of the input
|
||||||
|
*
|
||||||
|
* returns a Uint8Array
|
||||||
|
*/
|
||||||
|
async function
|
||||||
|
shasha4
|
||||||
|
(input_bytes : Uint8Array)
|
||||||
|
: Promise<Uint8Array>
|
||||||
|
{
|
||||||
|
let x = await crypto.subtle.digest('SHA-256', input_bytes);
|
||||||
|
let y = await crypto.subtle.digest('SHA-256', x);
|
||||||
|
let z = y.slice(0, 4);
|
||||||
|
return new Uint8Array(z);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Console.log the message and put it in the log thing
|
||||||
|
*/
|
||||||
|
function
|
||||||
|
logln
|
||||||
|
(message : string)
|
||||||
|
: void
|
||||||
|
{
|
||||||
|
console.log(message);
|
||||||
|
document.getElementById('log')!.innerHTML += message;
|
||||||
|
document.getElementById('log')!.innerHTML += '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base58 encoding/decoding
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
// ENCODING
|
||||||
|
//=============================================================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encode a Uint8Array into base58
|
||||||
|
*/
|
||||||
|
function
|
||||||
|
encode
|
||||||
|
(binary : Uint8Array)
|
||||||
|
: string
|
||||||
|
{
|
||||||
|
let num_leading_zeros : number = nlz(binary);
|
||||||
|
let rest : Uint8Array = binary.slice(num_leading_zeros);
|
||||||
|
let ones : string = encode_zeros(num_leading_zeros);
|
||||||
|
let rest_b58 : string = encode_rest(rest);
|
||||||
|
let result : string = ones + rest_b58;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* count the number of leading zeros in a uint8array
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
function
|
||||||
|
nlz
|
||||||
|
(bytes: Uint8Array)
|
||||||
|
: number
|
||||||
|
{
|
||||||
|
let n = 0;
|
||||||
|
for (let this_byte of bytes)
|
||||||
|
{
|
||||||
|
if (0 === this_byte) { n++; }
|
||||||
|
else { break; }
|
||||||
|
}
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a bunch of '1's for however many leading zeros there are
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
function
|
||||||
|
encode_zeros
|
||||||
|
(how_many : number)
|
||||||
|
: string
|
||||||
|
{
|
||||||
|
let ones : string = '';
|
||||||
|
for (let i = 1;
|
||||||
|
i <= how_many;
|
||||||
|
i++)
|
||||||
|
{
|
||||||
|
ones += '1';
|
||||||
|
}
|
||||||
|
|
||||||
|
return ones;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encode a Uint8Array that has no leading zeros
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
function
|
||||||
|
encode_rest
|
||||||
|
(bytes : Uint8Array)
|
||||||
|
: string
|
||||||
|
{
|
||||||
|
let bytes_bignum : bigint = bytes_to_bigint(bytes);
|
||||||
|
let result : string = bignum_to_base58(bytes_bignum);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a bytestring to a bignum
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
function
|
||||||
|
bytes_to_bigint
|
||||||
|
(bytes: Uint8Array)
|
||||||
|
: bigint
|
||||||
|
{
|
||||||
|
let acc_bigint : bigint = 0n;
|
||||||
|
for(let this_byte of bytes)
|
||||||
|
{
|
||||||
|
acc_bigint <<= 8n;
|
||||||
|
acc_bigint += BigInt(this_byte);
|
||||||
|
}
|
||||||
|
return acc_bigint;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a BigInt to Base58
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
function
|
||||||
|
bignum_to_base58
|
||||||
|
(q: bigint)
|
||||||
|
: string
|
||||||
|
{
|
||||||
|
let s = '';
|
||||||
|
while (q !== 0n)
|
||||||
|
{
|
||||||
|
let this_n : bigint = q % 58n;
|
||||||
|
q /= 58n;
|
||||||
|
|
||||||
|
let this_b58_char : string = bigint_to_char(this_n);
|
||||||
|
s = this_b58_char + s;
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
// DECODING
|
||||||
|
//=============================================================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decode a Base58 string into a Uint8Array
|
||||||
|
*/
|
||||||
|
function
|
||||||
|
decode
|
||||||
|
(base58: string)
|
||||||
|
: Uint8Array
|
||||||
|
{
|
||||||
|
let num_leading_ones : number = nlo(base58);
|
||||||
|
let rest : string = base58.slice(num_leading_ones);
|
||||||
|
let zeros : Array<number> = decode_ones(num_leading_ones);
|
||||||
|
let rest_arr : Array<number> = decode_rest(rest);
|
||||||
|
let pre_result : Array<number> = zeros.concat(rest_arr);
|
||||||
|
return new Uint8Array(pre_result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* count the number of leading 1 characters in a uint8array
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
function
|
||||||
|
nlo
|
||||||
|
(base58: string)
|
||||||
|
: number
|
||||||
|
{
|
||||||
|
let n = 0;
|
||||||
|
for (let this_char of base58)
|
||||||
|
{
|
||||||
|
if ('1' === this_char) { n++; }
|
||||||
|
else { break; }
|
||||||
|
}
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a bunch of '0's for however many leading ones there are
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
function
|
||||||
|
decode_ones
|
||||||
|
(how_many : number)
|
||||||
|
: Array<number>
|
||||||
|
{
|
||||||
|
let zeros : Array<number> = [];
|
||||||
|
for (let i = 1;
|
||||||
|
i <= how_many;
|
||||||
|
i++)
|
||||||
|
{
|
||||||
|
zeros.push(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return zeros;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decode a string that has no leading 1s
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
function
|
||||||
|
decode_rest
|
||||||
|
(base58: string)
|
||||||
|
: Array<number>
|
||||||
|
{
|
||||||
|
let result_bignum : bigint = base58_to_bigint(base58);
|
||||||
|
let result : Array<number> = bigint_to_base256(result_bignum);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a base58 string to a bignum
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
function
|
||||||
|
base58_to_bigint
|
||||||
|
(base58: string)
|
||||||
|
: bigint
|
||||||
|
{
|
||||||
|
let acc_bigint : bigint = 0n;
|
||||||
|
for(let this_char of base58)
|
||||||
|
{
|
||||||
|
acc_bigint *= 58n;
|
||||||
|
acc_bigint += char_to_bigint(this_char);
|
||||||
|
}
|
||||||
|
return acc_bigint;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* convert a bignum into a byte array
|
||||||
|
*
|
||||||
|
* @end
|
||||||
|
*/
|
||||||
|
function
|
||||||
|
bigint_to_base256
|
||||||
|
(q: bigint)
|
||||||
|
: Array<number>
|
||||||
|
{
|
||||||
|
let arr_reverse = [];
|
||||||
|
while(q !== 0n)
|
||||||
|
{
|
||||||
|
let r: number = Number(q % 256n);
|
||||||
|
q /= 256n;
|
||||||
|
arr_reverse.push(r);
|
||||||
|
}
|
||||||
|
arr_reverse.reverse();
|
||||||
|
return arr_reverse;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
// TRANSLATION TABLES
|
||||||
|
//=============================================================================
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base58 integer -> character conversion table
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
function
|
||||||
|
bigint_to_char
|
||||||
|
(n: bigint)
|
||||||
|
: string
|
||||||
|
{
|
||||||
|
switch(n) {
|
||||||
|
case 0n: return '1';
|
||||||
|
case 1n: return '2';
|
||||||
|
case 2n: return '3';
|
||||||
|
case 3n: return '4';
|
||||||
|
case 4n: return '5';
|
||||||
|
case 5n: return '6';
|
||||||
|
case 6n: return '7';
|
||||||
|
case 7n: return '8';
|
||||||
|
case 8n: return '9';
|
||||||
|
case 9n: return 'A';
|
||||||
|
case 10n: return 'B';
|
||||||
|
case 11n: return 'C';
|
||||||
|
case 12n: return 'D';
|
||||||
|
case 13n: return 'E';
|
||||||
|
case 14n: return 'F';
|
||||||
|
case 15n: return 'G';
|
||||||
|
case 16n: return 'H';
|
||||||
|
case 17n: return 'J';
|
||||||
|
case 18n: return 'K';
|
||||||
|
case 19n: return 'L';
|
||||||
|
case 20n: return 'M';
|
||||||
|
case 21n: return 'N';
|
||||||
|
case 22n: return 'P';
|
||||||
|
case 23n: return 'Q';
|
||||||
|
case 24n: return 'R';
|
||||||
|
case 25n: return 'S';
|
||||||
|
case 26n: return 'T';
|
||||||
|
case 27n: return 'U';
|
||||||
|
case 28n: return 'V';
|
||||||
|
case 29n: return 'W';
|
||||||
|
case 30n: return 'X';
|
||||||
|
case 31n: return 'Y';
|
||||||
|
case 32n: return 'Z';
|
||||||
|
case 33n: return 'a';
|
||||||
|
case 34n: return 'b';
|
||||||
|
case 35n: return 'c';
|
||||||
|
case 36n: return 'd';
|
||||||
|
case 37n: return 'e';
|
||||||
|
case 38n: return 'f';
|
||||||
|
case 39n: return 'g';
|
||||||
|
case 40n: return 'h';
|
||||||
|
case 41n: return 'i';
|
||||||
|
case 42n: return 'j';
|
||||||
|
case 43n: return 'k';
|
||||||
|
case 44n: return 'm';
|
||||||
|
case 45n: return 'n';
|
||||||
|
case 46n: return 'o';
|
||||||
|
case 47n: return 'p';
|
||||||
|
case 48n: return 'q';
|
||||||
|
case 49n: return 'r';
|
||||||
|
case 50n: return 's';
|
||||||
|
case 51n: return 't';
|
||||||
|
case 52n: return 'u';
|
||||||
|
case 53n: return 'v';
|
||||||
|
case 54n: return 'w';
|
||||||
|
case 55n: return 'x';
|
||||||
|
case 56n: return 'y';
|
||||||
|
case 57n: return 'z';
|
||||||
|
default:
|
||||||
|
throw new Error('invalid base58 bigint: ' + n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base58 character -> integer conversion table
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
function
|
||||||
|
char_to_bigint
|
||||||
|
(s: string)
|
||||||
|
: bigint
|
||||||
|
{
|
||||||
|
switch(s) {
|
||||||
|
case '1': return 0n;
|
||||||
|
case '2': return 1n;
|
||||||
|
case '3': return 2n;
|
||||||
|
case '4': return 3n;
|
||||||
|
case '5': return 4n;
|
||||||
|
case '6': return 5n;
|
||||||
|
case '7': return 6n;
|
||||||
|
case '8': return 7n;
|
||||||
|
case '9': return 8n;
|
||||||
|
case 'A': return 9n;
|
||||||
|
case 'B': return 10n;
|
||||||
|
case 'C': return 11n;
|
||||||
|
case 'D': return 12n;
|
||||||
|
case 'E': return 13n;
|
||||||
|
case 'F': return 14n;
|
||||||
|
case 'G': return 15n;
|
||||||
|
case 'H': return 16n;
|
||||||
|
case 'J': return 17n;
|
||||||
|
case 'K': return 18n;
|
||||||
|
case 'L': return 19n;
|
||||||
|
case 'M': return 20n;
|
||||||
|
case 'N': return 21n;
|
||||||
|
case 'P': return 22n;
|
||||||
|
case 'Q': return 23n;
|
||||||
|
case 'R': return 24n;
|
||||||
|
case 'S': return 25n;
|
||||||
|
case 'T': return 26n;
|
||||||
|
case 'U': return 27n;
|
||||||
|
case 'V': return 28n;
|
||||||
|
case 'W': return 29n;
|
||||||
|
case 'X': return 30n;
|
||||||
|
case 'Y': return 31n;
|
||||||
|
case 'Z': return 32n;
|
||||||
|
case 'a': return 33n;
|
||||||
|
case 'b': return 34n;
|
||||||
|
case 'c': return 35n;
|
||||||
|
case 'd': return 36n;
|
||||||
|
case 'e': return 37n;
|
||||||
|
case 'f': return 38n;
|
||||||
|
case 'g': return 39n;
|
||||||
|
case 'h': return 40n;
|
||||||
|
case 'i': return 41n;
|
||||||
|
case 'j': return 42n;
|
||||||
|
case 'k': return 43n;
|
||||||
|
case 'm': return 44n;
|
||||||
|
case 'n': return 45n;
|
||||||
|
case 'o': return 46n;
|
||||||
|
case 'p': return 47n;
|
||||||
|
case 'q': return 48n;
|
||||||
|
case 'r': return 49n;
|
||||||
|
case 's': return 50n;
|
||||||
|
case 't': return 51n;
|
||||||
|
case 'u': return 52n;
|
||||||
|
case 'v': return 53n;
|
||||||
|
case 'w': return 54n;
|
||||||
|
case 'x': return 55n;
|
||||||
|
case 'y': return 56n;
|
||||||
|
case 'z': return 57n;
|
||||||
|
default:
|
||||||
|
throw new Error('invalid base58 char: ' + s);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
{"compilerOptions" : {"target" : "es2022",
|
||||||
|
"strict" : true,
|
||||||
|
"esModuleInterop" : true,
|
||||||
|
"skipLibCheck" : true,
|
||||||
|
"forceConsistentCasingInFileNames" : true,
|
||||||
|
"noImplicitAny" : true,
|
||||||
|
"strictNullChecks" : true,
|
||||||
|
"strictPropertyInitialization" : true,
|
||||||
|
"sourceMap" : true,
|
||||||
|
"outDir" : "dist",
|
||||||
|
"declaration" : true},
|
||||||
|
"$schema" : "https://json.schemastore.org/tsconfig",
|
||||||
|
"display" : "Recommended",
|
||||||
|
"include" : ["src/**/*"],
|
||||||
|
"exclude" : ["src/jex_include"],
|
||||||
|
"composite" : true}
|
||||||
Reference in New Issue
Block a user