chore: add wasm console demo

This commit is contained in:
Sameh Abouel-saad 2025-05-26 13:22:42 +03:00
parent 1e52c572d2
commit 44b4dfd6a7
14 changed files with 1138 additions and 14 deletions

View File

@ -27,6 +27,16 @@ build-wasm-app:
# Build everything: wasm, copy, then extension # Build everything: wasm, copy, then extension
build-extension-all: build-wasm-app build-extension-all: build-wasm-app
cp wasm_app/pkg/wasm_app.js extension/public/wasm/wasm_app.js
cp wasm_app/pkg/wasm_app_bg.wasm extension/public/wasm/wasm_app_bg.wasm
cd extension && npm run build cd extension && npm run build
# Build everything: wasm, copy, then extension
build-vault-browser-ext:
cd wasm_app && wasm-pack build --target web --out-dir ../vault_browser_ext/wasm_app/pkg
cp vault_browser_ext/wasm_app/pkg/wasm_app.js vault_browser_ext/public/wasm/
cp vault_browser_ext/wasm_app/pkg/wasm_app_bg.wasm vault_browser_ext/public/wasm/
cd vault_browser_ext && npm install && npm run build
cp vault_browser_ext/manifest.json vault_browser_ext/dist/
cp vault_browser_ext/*.png vault_browser_ext/dist/
mkdir -p vault_browser_ext/dist/src
cp vault_browser_ext/sandbox.html vault_browser_ext/dist/
cp vault_browser_ext/sandbox.js vault_browser_ext/dist/

View File

@ -7,6 +7,7 @@ edition = "2021"
path = "src/lib.rs" path = "src/lib.rs"
[dependencies] [dependencies]
instant = { version = "0.1", features = ["wasm-bindgen"] }
# Only universal/core dependencies here # Only universal/core dependencies here
tokio = { version = "1.37", features = ["rt", "macros"] } tokio = { version = "1.37", features = ["rt", "macros"] }

View File

@ -7,6 +7,7 @@ edition = "2021"
path = "src/lib.rs" path = "src/lib.rs"
[dependencies] [dependencies]
instant = { version = "0.1", features = ["wasm-bindgen"] }
tokio = { version = "1.37", features = ["rt", "macros"] } tokio = { version = "1.37", features = ["rt", "macros"] }
async-trait = "0.1" async-trait = "0.1"

View File

@ -7,6 +7,7 @@ edition = "2021"
path = "src/lib.rs" path = "src/lib.rs"
[dependencies] [dependencies]
instant = { version = "0.1", features = ["wasm-bindgen"] }
once_cell = "1.18" once_cell = "1.18"
tokio = { version = "1.37", features = ["rt", "macros"] } tokio = { version = "1.37", features = ["rt", "macros"] }
kvstore = { path = "../kvstore" } kvstore = { path = "../kvstore" }

View File

@ -9,6 +9,8 @@ use zeroize::Zeroize;
/// SessionManager: Ergonomic, stateful wrapper over the Vault stateless API. /// SessionManager: Ergonomic, stateful wrapper over the Vault stateless API.
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
pub struct SessionManager<S: KVStore + Send + Sync> { pub struct SessionManager<S: KVStore + Send + Sync> {
// ... existing fields
vault: Vault<S>, vault: Vault<S>,
unlocked_keyspace: Option<(String, Vec<u8>, KeyspaceData)>, // (name, password, data) unlocked_keyspace: Option<(String, Vec<u8>, KeyspaceData)>, // (name, password, data)
current_keypair: Option<String>, current_keypair: Option<String>,
@ -38,7 +40,12 @@ impl<S: KVStore + Send + Sync> SessionManager<S> {
} }
} }
pub async fn create_keyspace(&mut self, name: &str, password: &[u8], tags: Option<Vec<String>>) -> Result<(), VaultError> { pub async fn create_keyspace(
&mut self,
name: &str,
password: &[u8],
tags: Option<Vec<String>>,
) -> Result<(), VaultError> {
self.vault.create_keyspace(name, password, tags).await?; self.vault.create_keyspace(name, password, tags).await?;
self.unlock_keyspace(name, password).await self.unlock_keyspace(name, password).await
} }
@ -90,12 +97,34 @@ impl<S: KVStore + Send + Sync> SessionManager<S> {
self.unlocked_keyspace.as_ref().map(|(_, _, data)| data) self.unlocked_keyspace.as_ref().map(|(_, _, data)| data)
} }
/// Returns the name of the currently unlocked keyspace, if any.
pub fn current_keyspace_name(&self) -> Option<&str> {
self.unlocked_keyspace
.as_ref()
.map(|(name, _, _)| name.as_str())
}
pub fn current_keypair(&self) -> Option<&KeyEntry> { pub fn current_keypair(&self) -> Option<&KeyEntry> {
let keyspace = self.current_keyspace()?; let keyspace = self.current_keyspace()?;
let key_id = self.current_keypair.as_ref()?; let key_id = self.current_keypair.as_ref()?;
keyspace.keypairs.iter().find(|k| &k.id == key_id) keyspace.keypairs.iter().find(|k| &k.id == key_id)
} }
/// Returns the metadata of the current selected keypair, if any.
pub fn current_keypair_metadata(&self) -> Option<crate::KeyMetadata> {
self.current_keypair().and_then(|k| k.metadata.clone())
}
/// Returns the public key of the current selected keypair, if any.
pub fn current_keypair_public_key(&self) -> Option<Vec<u8>> {
self.current_keypair().map(|k| k.public_key.clone())
}
/// Returns true if a keyspace is currently unlocked.
pub fn is_unlocked(&self) -> bool {
self.unlocked_keyspace.is_some()
}
pub async fn sign(&self, message: &[u8]) -> Result<Vec<u8>, VaultError> { pub async fn sign(&self, message: &[u8]) -> Result<Vec<u8>, VaultError> {
let (name, password, _) = self let (name, password, _) = self
.unlocked_keyspace .unlocked_keyspace
@ -137,7 +166,12 @@ impl<S: KVStore> SessionManager<S> {
} }
} }
pub async fn create_keyspace(&mut self, name: &str, password: &[u8], tags: Option<Vec<String>>) -> Result<(), VaultError> { pub async fn create_keyspace(
&mut self,
name: &str,
password: &[u8],
tags: Option<Vec<String>>,
) -> Result<(), VaultError> {
self.vault.create_keyspace(name, password, tags).await?; self.vault.create_keyspace(name, password, tags).await?;
self.unlock_keyspace(name, password).await self.unlock_keyspace(name, password).await
} }
@ -189,12 +223,34 @@ impl<S: KVStore> SessionManager<S> {
self.unlocked_keyspace.as_ref().map(|(_, _, data)| data) self.unlocked_keyspace.as_ref().map(|(_, _, data)| data)
} }
/// Returns the name of the currently unlocked keyspace, if any.
pub fn current_keyspace_name(&self) -> Option<&str> {
self.unlocked_keyspace
.as_ref()
.map(|(name, _, _)| name.as_str())
}
pub fn current_keypair(&self) -> Option<&KeyEntry> { pub fn current_keypair(&self) -> Option<&KeyEntry> {
let keyspace = self.current_keyspace()?; let keyspace = self.current_keyspace()?;
let key_id = self.current_keypair.as_ref()?; let key_id = self.current_keypair.as_ref()?;
keyspace.keypairs.iter().find(|k| &k.id == key_id) keyspace.keypairs.iter().find(|k| &k.id == key_id)
} }
/// Returns the metadata of the current selected keypair, if any.
pub fn current_keypair_metadata(&self) -> Option<crate::KeyMetadata> {
self.current_keypair().and_then(|k| k.metadata.clone())
}
/// Returns the public key of the current selected keypair, if any.
pub fn current_keypair_public_key(&self) -> Option<Vec<u8>> {
self.current_keypair().map(|k| k.public_key.clone())
}
/// Returns true if a keyspace is currently unlocked.
pub fn is_unlocked(&self) -> bool {
self.unlocked_keyspace.is_some()
}
pub async fn sign(&self, message: &[u8]) -> Result<Vec<u8>, VaultError> { pub async fn sign(&self, message: &[u8]) -> Result<Vec<u8>, VaultError> {
let (name, password, _) = self let (name, password, _) = self
.unlocked_keyspace .unlocked_keyspace

View File

@ -7,7 +7,9 @@ edition = "2021"
crate-type = ["cdylib"] crate-type = ["cdylib"]
[dependencies] [dependencies]
instant = { version = "0.1", features = ["wasm-bindgen"] }
web-sys = { version = "0.3", features = ["console"] } web-sys = { version = "0.3", features = ["console"] }
js-sys = "0.3"
kvstore = { path = "../kvstore" } kvstore = { path = "../kvstore" }
hex = "0.4" hex = "0.4"
wasm-bindgen = { version = "0.2", features = ["serde-serialize"] } wasm-bindgen = { version = "0.2", features = ["serde-serialize"] }

View File

@ -9,6 +9,7 @@ use vault::rhai_bindings as vault_rhai_bindings;
use vault::session::SessionManager; use vault::session::SessionManager;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
use wasm_bindgen::JsValue; use wasm_bindgen::JsValue;
use js_sys::Uint8Array;
thread_local! { thread_local! {
static ENGINE: Lazy<RefCell<Engine>> = Lazy::new(|| RefCell::new(Engine::new())); static ENGINE: Lazy<RefCell<Engine>> = Lazy::new(|| RefCell::new(Engine::new()));
@ -21,6 +22,34 @@ pub use vault::session_singleton::SESSION_MANAGER;
// Session Lifecycle // Session Lifecycle
// ===================== // =====================
/// Create and unlock a new keyspace with the given name and password
#[wasm_bindgen]
pub async fn create_keyspace(keyspace: &str, password: &str) -> Result<(), JsValue> {
let keyspace = keyspace.to_string();
let password_vec = password.as_bytes().to_vec();
match WasmStore::open("vault").await {
Ok(store) => {
let vault = vault::Vault::new(store);
let mut manager = SessionManager::new(vault);
match manager.create_keyspace(&keyspace, &password_vec, None).await {
Ok(_) => {
SESSION_MANAGER.with(|cell| cell.replace(Some(manager)));
}
Err(e) => {
web_sys::console::error_1(&format!("Failed to create keyspace: {e}").into());
return Err(JsValue::from_str(&format!("Failed to create keyspace: {e}")));
}
}
}
Err(e) => {
web_sys::console::error_1(&format!("Failed to open WasmStore: {e}").into());
return Err(JsValue::from_str(&format!("Failed to open WasmStore: {e}")));
}
}
SESSION_PASSWORD.with(|cell| cell.replace(Some(password.as_bytes().to_vec())));
Ok(())
}
/// Initialize session with keyspace and password /// Initialize session with keyspace and password
#[wasm_bindgen] #[wasm_bindgen]
pub async fn init_session(keyspace: &str, password: &str) -> Result<(), JsValue> { pub async fn init_session(keyspace: &str, password: &str) -> Result<(), JsValue> {
@ -61,6 +90,36 @@ pub fn lock_session() {
// Keypair Management // Keypair Management
// ===================== // =====================
/// Get metadata of the currently selected keypair
#[wasm_bindgen]
pub fn current_keypair_metadata() -> Result<JsValue, JsValue> {
SESSION_MANAGER.with(|cell| {
cell.borrow().as_ref()
.and_then(|session| session.current_keypair_metadata())
.map(|meta| wasm_bindgen::JsValue::from_serde(&meta).unwrap())
.ok_or_else(|| JsValue::from_str("No keypair selected or no keyspace unlocked"))
})
}
/// Get public key of the currently selected keypair as Uint8Array
#[wasm_bindgen]
pub fn current_keypair_public_key() -> Result<JsValue, JsValue> {
SESSION_MANAGER.with(|cell| {
cell.borrow().as_ref()
.and_then(|session| session.current_keypair_public_key())
.map(|pk| js_sys::Uint8Array::from(pk.as_slice()).into())
.ok_or_else(|| JsValue::from_str("No keypair selected or no keyspace unlocked"))
})
}
/// Returns true if a keyspace is currently unlocked
#[wasm_bindgen]
pub fn is_unlocked() -> bool {
SESSION_MANAGER.with(|cell| {
cell.borrow().as_ref().map(|session| session.is_unlocked()).unwrap_or(false)
})
}
/// Get all keypairs from the current session /// Get all keypairs from the current session
/// Returns an array of keypair objects with id, type, and metadata /// Returns an array of keypair objects with id, type, and metadata
// #[wasm_bindgen] // #[wasm_bindgen]
@ -118,18 +177,12 @@ pub async fn add_keypair(
let password = SESSION_PASSWORD let password = SESSION_PASSWORD
.with(|pw| pw.borrow().clone()) .with(|pw| pw.borrow().clone())
.ok_or_else(|| JsValue::from_str("Session password not set"))?; .ok_or_else(|| JsValue::from_str("Session password not set"))?;
let (keyspace_name, session_exists) = SESSION_MANAGER.with(|cell| { let keyspace_name = SESSION_MANAGER.with(|cell| {
if let Some(ref session) = cell.borrow().as_ref() { cell.borrow().as_ref().and_then(|session| {
let keyspace_name = session.current_keyspace().map(|_| "".to_string()); // TODO: replace with actual keyspace name if available; session.current_keyspace_name().map(|name| name.to_string())
(keyspace_name, true) })
} else {
(None, false)
}
}); });
let keyspace_name = keyspace_name.ok_or_else(|| JsValue::from_str("No keyspace selected"))?; let keyspace_name = keyspace_name.ok_or_else(|| JsValue::from_str("No keyspace selected"))?;
if !session_exists {
return Err(JsValue::from_str("Session not initialized"));
}
let key_type = key_type let key_type = key_type
.as_deref() .as_deref()
.map(|s| match s { .map(|s| match s {
@ -153,6 +206,9 @@ pub async fn add_keypair(
.add_keypair(&keyspace_name, &password, Some(key_type), metadata) .add_keypair(&keyspace_name, &password, Some(key_type), metadata)
.await .await
.map_err(|e| JsValue::from_str(&format!("add_keypair error: {e}")))?; .map_err(|e| JsValue::from_str(&format!("add_keypair error: {e}")))?;
// Refresh in-memory keyspace data so list_keypairs reflects the new keypair immediately
session.unlock_keyspace(&keyspace_name, &password).await
.map_err(|e| JsValue::from_str(&format!("refresh keyspace after add_keypair error: {e}")))?;
// Put session back // Put session back
SESSION_MANAGER.with(|cell| *cell.borrow_mut() = Some(session_opt.take().unwrap())); SESSION_MANAGER.with(|cell| *cell.borrow_mut() = Some(session_opt.take().unwrap()));
Ok(JsValue::from_str(&key_id)) Ok(JsValue::from_str(&key_id))

View File

@ -0,0 +1,17 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>WASM App Demo</title>
</head>
<body>
<h1>WASM App Demo</h1>
<script type="module">
import init, * as wasm from './wasm_app.js';
window.wasm = wasm;
init().then(() => {
console.log("WASM module loaded! Try window.wasm in the console.");
});
</script>
</body>
</html>

13
wasm_console_demo/main.js Normal file
View File

@ -0,0 +1,13 @@
// Minimal loader for the vault WASM module for console interaction
// Adjust the module path if needed (this assumes the default wasm-pack output in the parent dir)
import init, * as vault from './wasm_app.js';
window.vault = null;
init().then(() => {
window.vault = vault;
console.log('Vault WASM module loaded. Use window.vault.<function>() in the console.');
});
// Optional: Helper to convert Uint8Array to hex
window.toHex = arr => Array.from(new Uint8Array(arr)).map(b => b.toString(16).padStart(2, '0')).join('');

View File

@ -0,0 +1,15 @@
{
"name": "wasm_app",
"type": "module",
"version": "0.1.0",
"files": [
"wasm_app_bg.wasm",
"wasm_app.js",
"wasm_app.d.ts"
],
"main": "wasm_app.js",
"types": "wasm_app.d.ts",
"sideEffects": [
"./snippets/*"
]
}

103
wasm_console_demo/wasm_app.d.ts vendored Normal file
View File

@ -0,0 +1,103 @@
/* tslint:disable */
/* eslint-disable */
/**
* Initialize the scripting environment (must be called before run_rhai)
*/
export function init_rhai_env(): void;
/**
* Securely run a Rhai script in the extension context (must be called only after user approval)
*/
export function run_rhai(script: string): any;
/**
* Create and unlock a new keyspace with the given name and password
*/
export function create_keyspace(keyspace: string, password: string): Promise<void>;
/**
* Initialize session with keyspace and password
*/
export function init_session(keyspace: string, password: string): Promise<void>;
/**
* Lock the session (zeroize password and session)
*/
export function lock_session(): void;
/**
* Get metadata of the currently selected keypair
*/
export function current_keypair_metadata(): any;
/**
* Get public key of the currently selected keypair as Uint8Array
*/
export function current_keypair_public_key(): any;
/**
* Returns true if a keyspace is currently unlocked
*/
export function is_unlocked(): boolean;
/**
* Get all keypairs from the current session
* Returns an array of keypair objects with id, type, and metadata
* Select keypair for the session
*/
export function select_keypair(key_id: string): void;
/**
* List keypairs in the current session's keyspace
*/
export function list_keypairs(): Promise<any>;
/**
* Add a keypair to the current keyspace
*/
export function add_keypair(key_type?: string | null, metadata?: string | null): Promise<any>;
/**
* Sign message with current session
*/
export function sign(message: Uint8Array): Promise<any>;
export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;
export interface InitOutput {
readonly memory: WebAssembly.Memory;
readonly init_rhai_env: () => void;
readonly run_rhai: (a: number, b: number) => [number, number, number];
readonly create_keyspace: (a: number, b: number, c: number, d: number) => any;
readonly init_session: (a: number, b: number, c: number, d: number) => any;
readonly lock_session: () => void;
readonly current_keypair_metadata: () => [number, number, number];
readonly current_keypair_public_key: () => [number, number, number];
readonly is_unlocked: () => number;
readonly select_keypair: (a: number, b: number) => [number, number];
readonly list_keypairs: () => any;
readonly add_keypair: (a: number, b: number, c: number, d: number) => any;
readonly sign: (a: number, b: number) => any;
readonly __wbindgen_exn_store: (a: number) => void;
readonly __externref_table_alloc: () => number;
readonly __wbindgen_export_2: WebAssembly.Table;
readonly __wbindgen_malloc: (a: number, b: number) => number;
readonly __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
readonly __wbindgen_export_5: WebAssembly.Table;
readonly __externref_table_dealloc: (a: number) => void;
readonly closure89_externref_shim: (a: number, b: number, c: any) => void;
readonly closure133_externref_shim: (a: number, b: number, c: any) => void;
readonly closure188_externref_shim: (a: number, b: number, c: any) => void;
readonly closure1847_externref_shim: (a: number, b: number, c: any, d: any) => void;
readonly __wbindgen_start: () => void;
}
export type SyncInitInput = BufferSource | WebAssembly.Module;
/**
* Instantiates the given `module`, which can either be bytes or
* a precompiled `WebAssembly.Module`.
*
* @param {{ module: SyncInitInput }} module - Passing `SyncInitInput` directly is deprecated.
*
* @returns {InitOutput}
*/
export function initSync(module: { module: SyncInitInput } | SyncInitInput): InitOutput;
/**
* If `module_or_path` is {RequestInfo} or {URL}, makes a request and
* for everything else, calls `WebAssembly.instantiate` directly.
*
* @param {{ module_or_path: InitInput | Promise<InitInput> }} module_or_path - Passing `InitInput` directly is deprecated.
*
* @returns {Promise<InitOutput>}
*/
export default function __wbg_init (module_or_path?: { module_or_path: InitInput | Promise<InitInput> } | InitInput | Promise<InitInput>): Promise<InitOutput>;

View File

@ -0,0 +1,822 @@
let wasm;
function addToExternrefTable0(obj) {
const idx = wasm.__externref_table_alloc();
wasm.__wbindgen_export_2.set(idx, obj);
return idx;
}
function handleError(f, args) {
try {
return f.apply(this, args);
} catch (e) {
const idx = addToExternrefTable0(e);
wasm.__wbindgen_exn_store(idx);
}
}
const cachedTextDecoder = (typeof TextDecoder !== 'undefined' ? new TextDecoder('utf-8', { ignoreBOM: true, fatal: true }) : { decode: () => { throw Error('TextDecoder not available') } } );
if (typeof TextDecoder !== 'undefined') { cachedTextDecoder.decode(); };
let cachedUint8ArrayMemory0 = null;
function getUint8ArrayMemory0() {
if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) {
cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer);
}
return cachedUint8ArrayMemory0;
}
function getStringFromWasm0(ptr, len) {
ptr = ptr >>> 0;
return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len));
}
function isLikeNone(x) {
return x === undefined || x === null;
}
function getArrayU8FromWasm0(ptr, len) {
ptr = ptr >>> 0;
return getUint8ArrayMemory0().subarray(ptr / 1, ptr / 1 + len);
}
let WASM_VECTOR_LEN = 0;
const cachedTextEncoder = (typeof TextEncoder !== 'undefined' ? new TextEncoder('utf-8') : { encode: () => { throw Error('TextEncoder not available') } } );
const encodeString = (typeof cachedTextEncoder.encodeInto === 'function'
? function (arg, view) {
return cachedTextEncoder.encodeInto(arg, view);
}
: function (arg, view) {
const buf = cachedTextEncoder.encode(arg);
view.set(buf);
return {
read: arg.length,
written: buf.length
};
});
function passStringToWasm0(arg, malloc, realloc) {
if (realloc === undefined) {
const buf = cachedTextEncoder.encode(arg);
const ptr = malloc(buf.length, 1) >>> 0;
getUint8ArrayMemory0().subarray(ptr, ptr + buf.length).set(buf);
WASM_VECTOR_LEN = buf.length;
return ptr;
}
let len = arg.length;
let ptr = malloc(len, 1) >>> 0;
const mem = getUint8ArrayMemory0();
let offset = 0;
for (; offset < len; offset++) {
const code = arg.charCodeAt(offset);
if (code > 0x7F) break;
mem[ptr + offset] = code;
}
if (offset !== len) {
if (offset !== 0) {
arg = arg.slice(offset);
}
ptr = realloc(ptr, len, len = offset + arg.length * 3, 1) >>> 0;
const view = getUint8ArrayMemory0().subarray(ptr + offset, ptr + len);
const ret = encodeString(arg, view);
offset += ret.written;
ptr = realloc(ptr, len, offset, 1) >>> 0;
}
WASM_VECTOR_LEN = offset;
return ptr;
}
let cachedDataViewMemory0 = null;
function getDataViewMemory0() {
if (cachedDataViewMemory0 === null || cachedDataViewMemory0.buffer.detached === true || (cachedDataViewMemory0.buffer.detached === undefined && cachedDataViewMemory0.buffer !== wasm.memory.buffer)) {
cachedDataViewMemory0 = new DataView(wasm.memory.buffer);
}
return cachedDataViewMemory0;
}
const CLOSURE_DTORS = (typeof FinalizationRegistry === 'undefined')
? { register: () => {}, unregister: () => {} }
: new FinalizationRegistry(state => {
wasm.__wbindgen_export_5.get(state.dtor)(state.a, state.b)
});
function makeMutClosure(arg0, arg1, dtor, f) {
const state = { a: arg0, b: arg1, cnt: 1, dtor };
const real = (...args) => {
// First up with a closure we increment the internal reference
// count. This ensures that the Rust closure environment won't
// be deallocated while we're invoking it.
state.cnt++;
const a = state.a;
state.a = 0;
try {
return f(a, state.b, ...args);
} finally {
if (--state.cnt === 0) {
wasm.__wbindgen_export_5.get(state.dtor)(a, state.b);
CLOSURE_DTORS.unregister(state);
} else {
state.a = a;
}
}
};
real.original = state;
CLOSURE_DTORS.register(real, state, state);
return real;
}
function debugString(val) {
// primitive types
const type = typeof val;
if (type == 'number' || type == 'boolean' || val == null) {
return `${val}`;
}
if (type == 'string') {
return `"${val}"`;
}
if (type == 'symbol') {
const description = val.description;
if (description == null) {
return 'Symbol';
} else {
return `Symbol(${description})`;
}
}
if (type == 'function') {
const name = val.name;
if (typeof name == 'string' && name.length > 0) {
return `Function(${name})`;
} else {
return 'Function';
}
}
// objects
if (Array.isArray(val)) {
const length = val.length;
let debug = '[';
if (length > 0) {
debug += debugString(val[0]);
}
for(let i = 1; i < length; i++) {
debug += ', ' + debugString(val[i]);
}
debug += ']';
return debug;
}
// Test for built-in
const builtInMatches = /\[object ([^\]]+)\]/.exec(toString.call(val));
let className;
if (builtInMatches && builtInMatches.length > 1) {
className = builtInMatches[1];
} else {
// Failed to match the standard '[object ClassName]'
return toString.call(val);
}
if (className == 'Object') {
// we're a user defined class or Object
// JSON.stringify avoids problems with cycles, and is generally much
// easier than looping through ownProperties of `val`.
try {
return 'Object(' + JSON.stringify(val) + ')';
} catch (_) {
return 'Object';
}
}
// errors
if (val instanceof Error) {
return `${val.name}: ${val.message}\n${val.stack}`;
}
// TODO we could test for more things here, like `Set`s and `Map`s.
return className;
}
/**
* Initialize the scripting environment (must be called before run_rhai)
*/
export function init_rhai_env() {
wasm.init_rhai_env();
}
function takeFromExternrefTable0(idx) {
const value = wasm.__wbindgen_export_2.get(idx);
wasm.__externref_table_dealloc(idx);
return value;
}
/**
* Securely run a Rhai script in the extension context (must be called only after user approval)
* @param {string} script
* @returns {any}
*/
export function run_rhai(script) {
const ptr0 = passStringToWasm0(script, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len0 = WASM_VECTOR_LEN;
const ret = wasm.run_rhai(ptr0, len0);
if (ret[2]) {
throw takeFromExternrefTable0(ret[1]);
}
return takeFromExternrefTable0(ret[0]);
}
/**
* Create and unlock a new keyspace with the given name and password
* @param {string} keyspace
* @param {string} password
* @returns {Promise<void>}
*/
export function create_keyspace(keyspace, password) {
const ptr0 = passStringToWasm0(keyspace, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len0 = WASM_VECTOR_LEN;
const ptr1 = passStringToWasm0(password, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
const ret = wasm.create_keyspace(ptr0, len0, ptr1, len1);
return ret;
}
/**
* Initialize session with keyspace and password
* @param {string} keyspace
* @param {string} password
* @returns {Promise<void>}
*/
export function init_session(keyspace, password) {
const ptr0 = passStringToWasm0(keyspace, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len0 = WASM_VECTOR_LEN;
const ptr1 = passStringToWasm0(password, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
const ret = wasm.init_session(ptr0, len0, ptr1, len1);
return ret;
}
/**
* Lock the session (zeroize password and session)
*/
export function lock_session() {
wasm.lock_session();
}
/**
* Get metadata of the currently selected keypair
* @returns {any}
*/
export function current_keypair_metadata() {
const ret = wasm.current_keypair_metadata();
if (ret[2]) {
throw takeFromExternrefTable0(ret[1]);
}
return takeFromExternrefTable0(ret[0]);
}
/**
* Get public key of the currently selected keypair as Uint8Array
* @returns {any}
*/
export function current_keypair_public_key() {
const ret = wasm.current_keypair_public_key();
if (ret[2]) {
throw takeFromExternrefTable0(ret[1]);
}
return takeFromExternrefTable0(ret[0]);
}
/**
* Returns true if a keyspace is currently unlocked
* @returns {boolean}
*/
export function is_unlocked() {
const ret = wasm.is_unlocked();
return ret !== 0;
}
/**
* Get all keypairs from the current session
* Returns an array of keypair objects with id, type, and metadata
* Select keypair for the session
* @param {string} key_id
*/
export function select_keypair(key_id) {
const ptr0 = passStringToWasm0(key_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len0 = WASM_VECTOR_LEN;
const ret = wasm.select_keypair(ptr0, len0);
if (ret[1]) {
throw takeFromExternrefTable0(ret[0]);
}
}
/**
* List keypairs in the current session's keyspace
* @returns {Promise<any>}
*/
export function list_keypairs() {
const ret = wasm.list_keypairs();
return ret;
}
/**
* Add a keypair to the current keyspace
* @param {string | null} [key_type]
* @param {string | null} [metadata]
* @returns {Promise<any>}
*/
export function add_keypair(key_type, metadata) {
var ptr0 = isLikeNone(key_type) ? 0 : passStringToWasm0(key_type, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
var len0 = WASM_VECTOR_LEN;
var ptr1 = isLikeNone(metadata) ? 0 : passStringToWasm0(metadata, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
var len1 = WASM_VECTOR_LEN;
const ret = wasm.add_keypair(ptr0, len0, ptr1, len1);
return ret;
}
function passArray8ToWasm0(arg, malloc) {
const ptr = malloc(arg.length * 1, 1) >>> 0;
getUint8ArrayMemory0().set(arg, ptr / 1);
WASM_VECTOR_LEN = arg.length;
return ptr;
}
/**
* Sign message with current session
* @param {Uint8Array} message
* @returns {Promise<any>}
*/
export function sign(message) {
const ptr0 = passArray8ToWasm0(message, wasm.__wbindgen_malloc);
const len0 = WASM_VECTOR_LEN;
const ret = wasm.sign(ptr0, len0);
return ret;
}
function __wbg_adapter_32(arg0, arg1, arg2) {
wasm.closure89_externref_shim(arg0, arg1, arg2);
}
function __wbg_adapter_35(arg0, arg1, arg2) {
wasm.closure133_externref_shim(arg0, arg1, arg2);
}
function __wbg_adapter_38(arg0, arg1, arg2) {
wasm.closure188_externref_shim(arg0, arg1, arg2);
}
function __wbg_adapter_135(arg0, arg1, arg2, arg3) {
wasm.closure1847_externref_shim(arg0, arg1, arg2, arg3);
}
const __wbindgen_enum_IdbTransactionMode = ["readonly", "readwrite", "versionchange", "readwriteflush", "cleanup"];
async function __wbg_load(module, imports) {
if (typeof Response === 'function' && module instanceof Response) {
if (typeof WebAssembly.instantiateStreaming === 'function') {
try {
return await WebAssembly.instantiateStreaming(module, imports);
} catch (e) {
if (module.headers.get('Content-Type') != 'application/wasm') {
console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve Wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n", e);
} else {
throw e;
}
}
}
const bytes = await module.arrayBuffer();
return await WebAssembly.instantiate(bytes, imports);
} else {
const instance = await WebAssembly.instantiate(module, imports);
if (instance instanceof WebAssembly.Instance) {
return { instance, module };
} else {
return instance;
}
}
}
function __wbg_get_imports() {
const imports = {};
imports.wbg = {};
imports.wbg.__wbg_buffer_609cc3eee51ed158 = function(arg0) {
const ret = arg0.buffer;
return ret;
};
imports.wbg.__wbg_call_672a4d21634d4a24 = function() { return handleError(function (arg0, arg1) {
const ret = arg0.call(arg1);
return ret;
}, arguments) };
imports.wbg.__wbg_call_7cccdd69e0791ae2 = function() { return handleError(function (arg0, arg1, arg2) {
const ret = arg0.call(arg1, arg2);
return ret;
}, arguments) };
imports.wbg.__wbg_createObjectStore_d2f9e1016f4d81b9 = function() { return handleError(function (arg0, arg1, arg2, arg3) {
const ret = arg0.createObjectStore(getStringFromWasm0(arg1, arg2), arg3);
return ret;
}, arguments) };
imports.wbg.__wbg_crypto_574e78ad8b13b65f = function(arg0) {
const ret = arg0.crypto;
return ret;
};
imports.wbg.__wbg_error_524f506f44df1645 = function(arg0) {
console.error(arg0);
};
imports.wbg.__wbg_error_ff4ddaabdfc5dbb3 = function() { return handleError(function (arg0) {
const ret = arg0.error;
return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
}, arguments) };
imports.wbg.__wbg_getRandomValues_3c9c0d586e575a16 = function() { return handleError(function (arg0, arg1) {
globalThis.crypto.getRandomValues(getArrayU8FromWasm0(arg0, arg1));
}, arguments) };
imports.wbg.__wbg_getRandomValues_b8f5dbd5f3995a9e = function() { return handleError(function (arg0, arg1) {
arg0.getRandomValues(arg1);
}, arguments) };
imports.wbg.__wbg_getTime_46267b1c24877e30 = function(arg0) {
const ret = arg0.getTime();
return ret;
};
imports.wbg.__wbg_get_4f73335ab78445db = function(arg0, arg1, arg2) {
const ret = arg1[arg2 >>> 0];
var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
var len1 = WASM_VECTOR_LEN;
getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
};
imports.wbg.__wbg_get_67b2ba62fc30de12 = function() { return handleError(function (arg0, arg1) {
const ret = Reflect.get(arg0, arg1);
return ret;
}, arguments) };
imports.wbg.__wbg_get_8da03f81f6a1111e = function() { return handleError(function (arg0, arg1) {
const ret = arg0.get(arg1);
return ret;
}, arguments) };
imports.wbg.__wbg_instanceof_IdbDatabase_a3ef009ca00059f9 = function(arg0) {
let result;
try {
result = arg0 instanceof IDBDatabase;
} catch (_) {
result = false;
}
const ret = result;
return ret;
};
imports.wbg.__wbg_instanceof_IdbFactory_12eaba3366f4302f = function(arg0) {
let result;
try {
result = arg0 instanceof IDBFactory;
} catch (_) {
result = false;
}
const ret = result;
return ret;
};
imports.wbg.__wbg_instanceof_IdbOpenDbRequest_a3416e156c9db893 = function(arg0) {
let result;
try {
result = arg0 instanceof IDBOpenDBRequest;
} catch (_) {
result = false;
}
const ret = result;
return ret;
};
imports.wbg.__wbg_instanceof_IdbRequest_4813c3f207666aa4 = function(arg0) {
let result;
try {
result = arg0 instanceof IDBRequest;
} catch (_) {
result = false;
}
const ret = result;
return ret;
};
imports.wbg.__wbg_length_52b6c4580c5ec934 = function(arg0) {
const ret = arg0.length;
return ret;
};
imports.wbg.__wbg_msCrypto_a61aeb35a24c1329 = function(arg0) {
const ret = arg0.msCrypto;
return ret;
};
imports.wbg.__wbg_new0_f788a2397c7ca929 = function() {
const ret = new Date();
return ret;
};
imports.wbg.__wbg_new_23a2665fac83c611 = function(arg0, arg1) {
try {
var state0 = {a: arg0, b: arg1};
var cb0 = (arg0, arg1) => {
const a = state0.a;
state0.a = 0;
try {
return __wbg_adapter_135(a, state0.b, arg0, arg1);
} finally {
state0.a = a;
}
};
const ret = new Promise(cb0);
return ret;
} finally {
state0.a = state0.b = 0;
}
};
imports.wbg.__wbg_new_405e22f390576ce2 = function() {
const ret = new Object();
return ret;
};
imports.wbg.__wbg_new_78feb108b6472713 = function() {
const ret = new Array();
return ret;
};
imports.wbg.__wbg_new_a12002a7f91c75be = function(arg0) {
const ret = new Uint8Array(arg0);
return ret;
};
imports.wbg.__wbg_newnoargs_105ed471475aaf50 = function(arg0, arg1) {
const ret = new Function(getStringFromWasm0(arg0, arg1));
return ret;
};
imports.wbg.__wbg_newwithbyteoffsetandlength_d97e637ebe145a9a = function(arg0, arg1, arg2) {
const ret = new Uint8Array(arg0, arg1 >>> 0, arg2 >>> 0);
return ret;
};
imports.wbg.__wbg_newwithlength_a381634e90c276d4 = function(arg0) {
const ret = new Uint8Array(arg0 >>> 0);
return ret;
};
imports.wbg.__wbg_node_905d3e251edff8a2 = function(arg0) {
const ret = arg0.node;
return ret;
};
imports.wbg.__wbg_now_d18023d54d4e5500 = function(arg0) {
const ret = arg0.now();
return ret;
};
imports.wbg.__wbg_objectStoreNames_9bb1ab04a7012aaf = function(arg0) {
const ret = arg0.objectStoreNames;
return ret;
};
imports.wbg.__wbg_objectStore_21878d46d25b64b6 = function() { return handleError(function (arg0, arg1, arg2) {
const ret = arg0.objectStore(getStringFromWasm0(arg1, arg2));
return ret;
}, arguments) };
imports.wbg.__wbg_open_88b1390d99a7c691 = function() { return handleError(function (arg0, arg1, arg2) {
const ret = arg0.open(getStringFromWasm0(arg1, arg2));
return ret;
}, arguments) };
imports.wbg.__wbg_open_e0c0b2993eb596e1 = function() { return handleError(function (arg0, arg1, arg2, arg3) {
const ret = arg0.open(getStringFromWasm0(arg1, arg2), arg3 >>> 0);
return ret;
}, arguments) };
imports.wbg.__wbg_process_dc0fbacc7c1c06f7 = function(arg0) {
const ret = arg0.process;
return ret;
};
imports.wbg.__wbg_push_737cfc8c1432c2c6 = function(arg0, arg1) {
const ret = arg0.push(arg1);
return ret;
};
imports.wbg.__wbg_put_066faa31a6a88f5b = function() { return handleError(function (arg0, arg1, arg2) {
const ret = arg0.put(arg1, arg2);
return ret;
}, arguments) };
imports.wbg.__wbg_put_9ef5363941008835 = function() { return handleError(function (arg0, arg1) {
const ret = arg0.put(arg1);
return ret;
}, arguments) };
imports.wbg.__wbg_queueMicrotask_97d92b4fcc8a61c5 = function(arg0) {
queueMicrotask(arg0);
};
imports.wbg.__wbg_queueMicrotask_d3219def82552485 = function(arg0) {
const ret = arg0.queueMicrotask;
return ret;
};
imports.wbg.__wbg_randomFillSync_ac0988aba3254290 = function() { return handleError(function (arg0, arg1) {
arg0.randomFillSync(arg1);
}, arguments) };
imports.wbg.__wbg_require_60cc747a6bc5215a = function() { return handleError(function () {
const ret = module.require;
return ret;
}, arguments) };
imports.wbg.__wbg_resolve_4851785c9c5f573d = function(arg0) {
const ret = Promise.resolve(arg0);
return ret;
};
imports.wbg.__wbg_result_f29afabdf2c05826 = function() { return handleError(function (arg0) {
const ret = arg0.result;
return ret;
}, arguments) };
imports.wbg.__wbg_set_65595bdd868b3009 = function(arg0, arg1, arg2) {
arg0.set(arg1, arg2 >>> 0);
};
imports.wbg.__wbg_setonerror_d7e3056cc6e56085 = function(arg0, arg1) {
arg0.onerror = arg1;
};
imports.wbg.__wbg_setonsuccess_afa464ee777a396d = function(arg0, arg1) {
arg0.onsuccess = arg1;
};
imports.wbg.__wbg_setonupgradeneeded_fcf7ce4f2eb0cb5f = function(arg0, arg1) {
arg0.onupgradeneeded = arg1;
};
imports.wbg.__wbg_static_accessor_GLOBAL_88a902d13a557d07 = function() {
const ret = typeof global === 'undefined' ? null : global;
return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
};
imports.wbg.__wbg_static_accessor_GLOBAL_THIS_56578be7e9f832b0 = function() {
const ret = typeof globalThis === 'undefined' ? null : globalThis;
return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
};
imports.wbg.__wbg_static_accessor_SELF_37c5d418e4bf5819 = function() {
const ret = typeof self === 'undefined' ? null : self;
return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
};
imports.wbg.__wbg_static_accessor_WINDOW_5de37043a91a9c40 = function() {
const ret = typeof window === 'undefined' ? null : window;
return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
};
imports.wbg.__wbg_subarray_aa9065fa9dc5df96 = function(arg0, arg1, arg2) {
const ret = arg0.subarray(arg1 >>> 0, arg2 >>> 0);
return ret;
};
imports.wbg.__wbg_target_0a62d9d79a2a1ede = function(arg0) {
const ret = arg0.target;
return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
};
imports.wbg.__wbg_then_44b73946d2fb3e7d = function(arg0, arg1) {
const ret = arg0.then(arg1);
return ret;
};
imports.wbg.__wbg_transaction_d6d07c3c9963c49e = function() { return handleError(function (arg0, arg1, arg2) {
const ret = arg0.transaction(arg1, __wbindgen_enum_IdbTransactionMode[arg2]);
return ret;
}, arguments) };
imports.wbg.__wbg_versions_c01dfd4722a88165 = function(arg0) {
const ret = arg0.versions;
return ret;
};
imports.wbg.__wbindgen_cb_drop = function(arg0) {
const obj = arg0.original;
if (obj.cnt-- == 1) {
obj.a = 0;
return true;
}
const ret = false;
return ret;
};
imports.wbg.__wbindgen_closure_wrapper288 = function(arg0, arg1, arg2) {
const ret = makeMutClosure(arg0, arg1, 90, __wbg_adapter_32);
return ret;
};
imports.wbg.__wbindgen_closure_wrapper518 = function(arg0, arg1, arg2) {
const ret = makeMutClosure(arg0, arg1, 134, __wbg_adapter_35);
return ret;
};
imports.wbg.__wbindgen_closure_wrapper776 = function(arg0, arg1, arg2) {
const ret = makeMutClosure(arg0, arg1, 189, __wbg_adapter_38);
return ret;
};
imports.wbg.__wbindgen_debug_string = function(arg0, arg1) {
const ret = debugString(arg1);
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
};
imports.wbg.__wbindgen_init_externref_table = function() {
const table = wasm.__wbindgen_export_2;
const offset = table.grow(4);
table.set(0, undefined);
table.set(offset + 0, undefined);
table.set(offset + 1, null);
table.set(offset + 2, true);
table.set(offset + 3, false);
;
};
imports.wbg.__wbindgen_is_function = function(arg0) {
const ret = typeof(arg0) === 'function';
return ret;
};
imports.wbg.__wbindgen_is_null = function(arg0) {
const ret = arg0 === null;
return ret;
};
imports.wbg.__wbindgen_is_object = function(arg0) {
const val = arg0;
const ret = typeof(val) === 'object' && val !== null;
return ret;
};
imports.wbg.__wbindgen_is_string = function(arg0) {
const ret = typeof(arg0) === 'string';
return ret;
};
imports.wbg.__wbindgen_is_undefined = function(arg0) {
const ret = arg0 === undefined;
return ret;
};
imports.wbg.__wbindgen_json_parse = function(arg0, arg1) {
const ret = JSON.parse(getStringFromWasm0(arg0, arg1));
return ret;
};
imports.wbg.__wbindgen_json_serialize = function(arg0, arg1) {
const obj = arg1;
const ret = JSON.stringify(obj === undefined ? null : obj);
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
};
imports.wbg.__wbindgen_memory = function() {
const ret = wasm.memory;
return ret;
};
imports.wbg.__wbindgen_string_new = function(arg0, arg1) {
const ret = getStringFromWasm0(arg0, arg1);
return ret;
};
imports.wbg.__wbindgen_throw = function(arg0, arg1) {
throw new Error(getStringFromWasm0(arg0, arg1));
};
return imports;
}
function __wbg_init_memory(imports, memory) {
}
function __wbg_finalize_init(instance, module) {
wasm = instance.exports;
__wbg_init.__wbindgen_wasm_module = module;
cachedDataViewMemory0 = null;
cachedUint8ArrayMemory0 = null;
wasm.__wbindgen_start();
return wasm;
}
function initSync(module) {
if (wasm !== undefined) return wasm;
if (typeof module !== 'undefined') {
if (Object.getPrototypeOf(module) === Object.prototype) {
({module} = module)
} else {
console.warn('using deprecated parameters for `initSync()`; pass a single object instead')
}
}
const imports = __wbg_get_imports();
__wbg_init_memory(imports);
if (!(module instanceof WebAssembly.Module)) {
module = new WebAssembly.Module(module);
}
const instance = new WebAssembly.Instance(module, imports);
return __wbg_finalize_init(instance, module);
}
async function __wbg_init(module_or_path) {
if (wasm !== undefined) return wasm;
if (typeof module_or_path !== 'undefined') {
if (Object.getPrototypeOf(module_or_path) === Object.prototype) {
({module_or_path} = module_or_path)
} else {
console.warn('using deprecated parameters for the initialization function; pass a single object instead')
}
}
if (typeof module_or_path === 'undefined') {
module_or_path = new URL('wasm_app_bg.wasm', import.meta.url);
}
const imports = __wbg_get_imports();
if (typeof module_or_path === 'string' || (typeof Request === 'function' && module_or_path instanceof Request) || (typeof URL === 'function' && module_or_path instanceof URL)) {
module_or_path = fetch(module_or_path);
}
__wbg_init_memory(imports);
const { instance, module } = await __wbg_load(await module_or_path, imports);
return __wbg_finalize_init(instance, module);
}
export { initSync };
export default __wbg_init;

Binary file not shown.

27
wasm_console_demo/wasm_app_bg.wasm.d.ts vendored Normal file
View File

@ -0,0 +1,27 @@
/* tslint:disable */
/* eslint-disable */
export const memory: WebAssembly.Memory;
export const init_rhai_env: () => void;
export const run_rhai: (a: number, b: number) => [number, number, number];
export const create_keyspace: (a: number, b: number, c: number, d: number) => any;
export const init_session: (a: number, b: number, c: number, d: number) => any;
export const lock_session: () => void;
export const current_keypair_metadata: () => [number, number, number];
export const current_keypair_public_key: () => [number, number, number];
export const is_unlocked: () => number;
export const select_keypair: (a: number, b: number) => [number, number];
export const list_keypairs: () => any;
export const add_keypair: (a: number, b: number, c: number, d: number) => any;
export const sign: (a: number, b: number) => any;
export const __wbindgen_exn_store: (a: number) => void;
export const __externref_table_alloc: () => number;
export const __wbindgen_export_2: WebAssembly.Table;
export const __wbindgen_malloc: (a: number, b: number) => number;
export const __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
export const __wbindgen_export_5: WebAssembly.Table;
export const __externref_table_dealloc: (a: number) => void;
export const closure89_externref_shim: (a: number, b: number, c: any) => void;
export const closure133_externref_shim: (a: number, b: number, c: any) => void;
export const closure188_externref_shim: (a: number, b: number, c: any) => void;
export const closure1847_externref_shim: (a: number, b: number, c: any, d: any) => void;
export const __wbindgen_start: () => void;