Files
nym/nym-browser-extension/storage/internal-dev/index.js
T
Tommy Verrall 3e8451f292 updated browser extension piece
- keep all the internal-dev wasm pieces as future examples
- everything previously was going to be removed
- shows functioning wasm interaction with the js
2025-06-11 17:15:20 +02:00

303 lines
9.6 KiB
JavaScript

/**
* Nym Extension Storage - Internal Development Example
*
* This file demonstrates how to use the ExtensionStorage WASM module
* for securely storing and managing BIP39 mnemonics in browser extensions.
*
* To run this example:
* 1. Build the WASM module: `cd .. && make wasm-pack`
* 2. Serve this directory: `python3 -m http.server 8000`
* 3. Open http://localhost:8000 in your browser
* 4. Open the browser's developer console to see the output
*/
import init, {
ExtensionStorage,
set_panic_hook
} from "./wasm/extension_storage.js"
/**
* Test mnemonics for demonstration
* Note: These are for testing only - never use these in production!
*/
const TEST_MNEMONICS = {
valid: {
wallet1: "figure aspect pill salute review sponsor army city muffin engine army kid rival chunk unit insect blouse paddle velvet shallow box crawl grace never",
wallet2: "salmon picture danger pill tomato hour hand chaos tray bargain frequent fuel scheme coil divert season lucky ginger mom stem mistake blanket lake suffer",
wallet3: "cat quiz circle letter trade unhappy quarter garlic sting gravity zone stock scatter merge account barrel forward fame club chest camp under crop connect",
wallet4: "mammal fashion rice two marble high brain achieve first harsh infant timber flush cloud hunt address brand immune tip identify aspect call beyond once"
},
invalid: "this is not a valid mnemonic phrase"
};
const STORAGE_PASSWORD = "my-super-secure-password-123";
/**
* Helper function to log results with better formatting
*/
function logResult(operation, result, error = null) {
const timestamp = new Date().toISOString();
console.group(`🔍 [${timestamp}] ${operation}`);
if (error) {
console.error("❌ Error:", error);
} else {
console.log("✅ Result:", result);
}
console.groupEnd();
}
/**
* Test basic storage operations
*/
async function testBasicOperations(storage) {
console.log("\n📦 Testing Basic Storage Operations");
console.log("=" .repeat(50));
// Test storing a valid mnemonic
try {
await storage.store_mnemonic("test-wallet", TEST_MNEMONICS.valid.wallet1);
logResult("Store valid mnemonic", "Successfully stored");
} catch (error) {
logResult("Store valid mnemonic", null, error);
}
// Test reading the stored mnemonic
try {
const result = await storage.read_mnemonic("test-wallet");
logResult("Read stored mnemonic", result);
} catch (error) {
logResult("Read stored mnemonic", null, error);
}
// Test reading a non-existent mnemonic
try {
const result = await storage.read_mnemonic("non-existent");
logResult("Read non-existent mnemonic", result);
} catch (error) {
logResult("Read non-existent mnemonic", null, error);
}
// Test storing an invalid mnemonic
try {
await storage.store_mnemonic("invalid-wallet", TEST_MNEMONICS.invalid);
logResult("Store invalid mnemonic", "Should not reach here");
} catch (error) {
logResult("Store invalid mnemonic", null, error.toString());
}
// Clean up
try {
await storage.remove_mnemonic("test-wallet");
logResult("Remove test wallet", "Successfully removed");
} catch (error) {
logResult("Remove test wallet", null, error);
}
}
/**
* Test multiple wallet management
*/
async function testMultipleWallets(storage) {
console.log("\n👥 Testing Multiple Wallet Management");
console.log("=" .repeat(50));
// Store multiple wallets
const walletNames = Object.keys(TEST_MNEMONICS.valid);
const walletMnemonics = Object.values(TEST_MNEMONICS.valid);
for (let i = 0; i < walletNames.length; i++) {
try {
await storage.store_mnemonic(walletNames[i], walletMnemonics[i]);
logResult(`Store wallet: ${walletNames[i]}`, "Success");
} catch (error) {
logResult(`Store wallet: ${walletNames[i]}`, null, error);
}
}
// Get all wallet keys
try {
const allKeys = await storage.get_all_mnemonic_keys();
logResult("Get all wallet keys", allKeys);
} catch (error) {
logResult("Get all wallet keys", null, error);
}
// Check if specific wallets exist
for (const walletName of walletNames) {
try {
const exists = await storage.has_mnemonic(walletName);
logResult(`Check wallet exists: ${walletName}`, exists);
} catch (error) {
logResult(`Check wallet exists: ${walletName}`, null, error);
}
}
// Read each wallet
for (const walletName of walletNames) {
try {
const mnemonic = await storage.read_mnemonic(walletName);
logResult(`Read wallet: ${walletName}`, `${mnemonic.substring(0, 20)}...`);
} catch (error) {
logResult(`Read wallet: ${walletName}`, null, error);
}
}
}
/**
* Test wallet removal and cleanup
*/
async function testWalletRemoval(storage) {
console.log("\n🗑️ Testing Wallet Removal");
console.log("=" .repeat(50));
const walletNames = Object.keys(TEST_MNEMONICS.valid);
// Remove wallets one by one
for (const walletName of walletNames) {
try {
await storage.remove_mnemonic(walletName);
logResult(`Remove wallet: ${walletName}`, "Success");
} catch (error) {
logResult(`Remove wallet: ${walletName}`, null, error);
}
// Verify removal
try {
const exists = await storage.has_mnemonic(walletName);
logResult(`Verify removal: ${walletName}`, `Exists: ${exists}`);
} catch (error) {
logResult(`Verify removal: ${walletName}`, null, error);
}
}
// Check final state
try {
const allKeys = await storage.get_all_mnemonic_keys();
logResult("Final wallet count", `${allKeys.length} wallets remaining`);
} catch (error) {
logResult("Final wallet count", null, error);
}
}
/**
* Test storage existence check
*/
async function testStorageExistence() {
console.log("\n💾 Testing Storage Existence");
console.log("=" .repeat(50));
try {
const exists = await ExtensionStorage.exists();
logResult("Storage database exists", exists);
} catch (error) {
logResult("Storage database exists", null, error);
}
}
/**
* Main demonstration function
*/
async function runDemo() {
console.log("🚀 Nym Extension Storage Demo");
console.log("=" .repeat(60));
console.log("This demo shows how to use the ExtensionStorage WASM module");
console.log("Check the browser console for detailed output\n");
try {
// Initialize the WASM module
console.log("🔧 Initializing WASM module...");
await init();
console.log("✅ WASM module initialized successfully\n");
// Set up better stack traces for Rust panics
set_panic_hook();
} catch (error) {
console.error("💥 Failed to initialize WASM module:", error);
return;
}
// Test storage existence before creating instance
await testStorageExistence();
try {
// Create storage instance with password
console.log("🔐 Creating storage instance with password...");
const storage = await new ExtensionStorage(STORAGE_PASSWORD);
console.log("✅ Storage instance created successfully\n");
// Run all tests
await testBasicOperations(storage);
await testMultipleWallets(storage);
await testWalletRemoval(storage);
// Test storage existence after operations
await testStorageExistence();
console.log("\n🎉 Demo completed successfully!");
console.log("Check the IndexedDB in your browser's developer tools to see the stored data.");
} catch (error) {
console.error("💥 Fatal error during demo:", error);
}
}
/**
* Additional utility functions for interactive testing
*/
window.nymStorageDemo = {
/**
* Create a new storage instance for manual testing
*/
async createStorage(password = STORAGE_PASSWORD) {
try {
await init();
set_panic_hook();
return await new ExtensionStorage(password);
} catch (error) {
console.error("Failed to initialize WASM or create storage:", error);
throw error;
}
},
/**
* Quick test with a storage instance
*/
async quickTest(storage, name = "test", mnemonic = TEST_MNEMONICS.valid.wallet1) {
console.log(`Testing with wallet: ${name}`);
await storage.store_mnemonic(name, mnemonic);
console.log("✅ Stored");
const retrieved = await storage.read_mnemonic(name);
console.log("✅ Retrieved:", retrieved);
const exists = await storage.has_mnemonic(name);
console.log("✅ Exists:", exists);
await storage.remove_mnemonic(name);
console.log("✅ Removed");
return "Test completed";
},
/**
* Available test mnemonics
*/
mnemonics: TEST_MNEMONICS
};
// Start the demo when the page loads
document.addEventListener('DOMContentLoaded', () => {
console.log("📚 Interactive Demo Functions Available:");
console.log("- window.nymStorageDemo.createStorage() - Create storage instance");
console.log("- window.nymStorageDemo.quickTest(storage) - Run quick test");
console.log("- window.nymStorageDemo.mnemonics - Test mnemonic phrases");
console.log("\nStarting automated demo...\n");
runDemo();
});
// Export for module usage
export { runDemo, TEST_MNEMONICS, STORAGE_PASSWORD };