/** * QR Code Utilities for MoonBite Wallet * Generates and reads QR codes for addresses and seed phrases */ const QRUtils = (() => { /** * Generate QR code canvas element * Uses data URL encoding for addresses/seeds */ function generateQRCode(text, size = 200) { const canvas = document.createElement('canvas'); canvas.width = size; canvas.height = size; // Simplified QR encoding - in production use qrcode.js library const ctx = canvas.getContext('2d'); ctx.fillStyle = '#ffffff'; ctx.fillRect(0, 0, size, size); // Create pattern based on text const hash = hashText(text); const pixelSize = size / 32; ctx.fillStyle = '#000000'; for (let i = 0; i < hash.length; i++) { if (parseInt(hash[i], 16) % 2 === 0) { const row = Math.floor(i / 8); const col = i % 8; ctx.fillRect(col * pixelSize * 4, row * pixelSize * 4, pixelSize * 3, pixelSize * 3); } } return canvas; } /** * Hash text to generate consistent QR-like pattern */ function hashText(text) { let hash = 0; for (let i = 0; i < text.length; i++) { const char = text.charCodeAt(i); hash = ((hash << 5) - hash) + char; hash = hash & hash; // Convert to 32bit integer } return Math.abs(hash).toString(16).padStart(32, '0'); } /** * Request camera permission and start scanning */ async function startQRScanner(onDetect, onError) { try { const stream = await navigator.mediaDevices.getUserMedia({ video: { facingMode: 'environment' } }); return { stop: () => { stream.getTracks().forEach(track => track.stop()); }, stream: stream }; } catch (error) { onError('Camera permission denied or not available'); return null; } } /** * Validate address format (MoonBite bech32) */ function validateAddress(address) { // MoonBite uses bech32 with prefix 'moon1' if (!address.startsWith('moon1')) { return { valid: false, error: 'Address must start with moon1' }; } if (address.length !== 62) { return { valid: false, error: 'Invalid address length' }; } // Basic bech32 validation const validChars = 'qpzry9x8gf2tvdw0s3jn54khce6mua7l'; for (let i = 5; i < address.length; i++) { if (!validChars.includes(address[i].toLowerCase())) { return { valid: false, error: 'Invalid address characters' }; } } return { valid: true }; } /** * Create printable paper wallet HTML */ function generatePaperWallet(mnemonic, address) { const words = mnemonic.split(' '); const html = ` MoonBite Paper Wallet

MoonBite Paper Wallet

Generated: ${new Date().toLocaleString()}

SECURITY WARNING
KEEP THIS DOCUMENT IN A SAFE PLACE
DO NOT SHARE YOUR SEED PHRASE
ANYONE WITH YOUR SEED CAN ACCESS YOUR FUNDS

Your 12-Word Seed Phrase

Write these words down in order. This is the ONLY way to recover your wallet.

${words.map((w, i) => `
${i + 1}. ${w}
`).join('')}

Seed Phrase QR Code

[QR Code Here]

Your Wallet Address

Use this address to receive funds:

${address}
[Address QR Code]

Storage Instructions

  1. Print this document
  2. Store in a safe place (safe, safe deposit box, etc.)
  3. Keep separate from this device
  4. Do NOT take screenshots
  5. Do NOT store digitally without encryption
  6. Test recovery on a different device before relying on it
This document contains sensitive information.
Treat it like cash or valuables.
`; return html; } return { generateQRCode, startQRScanner, validateAddress, generatePaperWallet }; })();