{"id":811395,"date":"2025-12-09T11:35:08","date_gmt":"2025-12-09T11:35:08","guid":{"rendered":"https:\/\/gridnet.org\/wpp\/?p=811395"},"modified":"2025-12-09T11:54:04","modified_gmt":"2025-12-09T11:54:04","slug":"one-link-to-launch-them-all-deep-linking-for-gridnet-os","status":"publish","type":"post","link":"https:\/\/gridnet.org\/wpp\/index.php\/2025\/12\/09\/one-link-to-launch-them-all-deep-linking-for-gridnet-os\/","title":{"rendered":"One Link to Launch Them All: Deep Linking for GRIDNET OS"},"content":{"rendered":"<style>\n\/* Mobile-responsive improvements *\/\n@media (max-width: 768px) {\n    \/* Make code blocks scrollable on mobile *\/\n    pre {\n        overflow-x: auto !important;\n        -webkit-overflow-scrolling: touch;\n        max-width: 100%;\n    }<\/p>\n<p>    \/* Adjust padding on mobile *\/\n    div[style*=\"padding: 60px 40px\"],\n    div[style*=\"padding: 50px 40px\"] {\n        padding: 50px 4px !important;\n    }<\/p>\n<p>    div[style*=\"padding: 30px\"],\n    div[style*=\"padding: 25px 30px\"],\n    div[style*=\"padding: 20px\"] {\n        padding-left: 15px !important;\n        padding-right: 15px !important;\n    }<\/p>\n<p>    \/* Make grid layouts single column on small screens *\/\n    div[style*=\"display: grid\"] {\n        grid-template-columns: 1fr !important;\n    }<\/p>\n<p>    \/* Ensure flex items wrap *\/\n    div[style*=\"display: flex\"] {\n        flex-wrap: wrap !important;\n    }<\/p>\n<p>    \/* Tables: make them scrollable *\/\n    table {\n        display: block;\n        overflow-x: auto;\n        -webkit-overflow-scrolling: touch;\n    }<\/p>\n<p>    \/* Reduce font sizes slightly for mobile *\/\n    h2 { font-size: 1.8em !important; }\n    h3 { font-size: 1.4em !important; }\n    h4 { font-size: 1.2em !important; }\n}<\/p>\n<p>\/* Ensure images and diagrams never overflow *\/\nimg, svg {\n    max-width: 100%;\n    height: auto;\n}<\/p>\n<p>\/* Box sizing for all elements *\/\n* {\n    box-sizing: border-box;\n}\n<\/style>\n<p><!-- Version Announcement Banner --><\/p>\n<div style=\"background: linear-gradient(90deg, #0a2e1a 0%, #1a3f2a 50%, #0a2e1a 100%); border: 2px solid #00ff00; padding: 20px 30px; margin-bottom: 30px; border-radius: 8px; display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 20px;\">\n<div style=\"display: flex; align-items: center; gap: 15px;\">\n<div style=\"background: #00ff00; color: #0a0e27; padding: 8px 16px; border-radius: 6px; font-weight: 700; font-size: 0.9em; white-space: nowrap;\">NOW LIVE<\/div>\n<div>\n<div style=\"color: #00ff00; font-weight: 600; font-size: 1.05em;\">GLinks are available in GRIDNET Core 1.9.4+<\/div>\n<div style=\"color: #88cc88; font-size: 0.9em; margin-top: 4px;\">Deep linking for decentralized applications<\/div>\n<\/p><\/div>\n<\/p><\/div>\n<div style=\"display: flex; flex-wrap: wrap; gap: 12px; align-items: center;\">\n        <a href=\"https:\/\/www.youtube.com\/@GRIDNETProject\" target=\"_blank\" style=\"background: linear-gradient(135deg, #FF0000 0%, #CC0000 100%); color: #ffffff; padding: 12px 24px; border-radius: 8px; text-decoration: none; font-weight: 600; display: inline-flex; align-items: center; gap: 10px; line-height: 1;\"><br \/>\n            <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"currentColor\" style=\"display: block; flex-shrink: 0;\"><path d=\"M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.545 15.568V8.432L15.818 12l-6.273 3.568z\"\/><\/svg><br \/>\n            <span style=\"line-height: 1;\">350TB+ LIVE Coding<\/span><br \/>\n        <\/a><br \/>\n        <a href=\"https:\/\/discord.com\/invite\/sN4uyfBSh6\" target=\"_blank\" style=\"background: linear-gradient(135deg, #5865F2 0%, #4752C4 100%); color: #ffffff; padding: 12px 24px; border-radius: 8px; text-decoration: none; font-weight: 600; display: inline-flex; align-items: center; gap: 10px; line-height: 1;\"><br \/>\n            <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"currentColor\" style=\"display: block; flex-shrink: 0;\"><path d=\"M20.317 4.37a19.791 19.791 0 0 0-4.885-1.515.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.27 18.27 0 0 0-5.487 0 12.64 12.64 0 0 0-.617-1.25.077.077 0 0 0-.079-.037A19.736 19.736 0 0 0 3.677 4.37a.07.07 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057a.082.082 0 0 0 .031.057 19.9 19.9 0 0 0 5.993 3.03.078.078 0 0 0 .084-.028 14.09 14.09 0 0 0 1.226-1.994.076.076 0 0 0-.041-.106 13.107 13.107 0 0 1-1.872-.892.077.077 0 0 1-.008-.128 10.2 10.2 0 0 0 .372-.292.074.074 0 0 1 .077-.01c3.928 1.793 8.18 1.793 12.062 0a.074.074 0 0 1 .078.01c.12.098.246.198.373.292a.077.077 0 0 1-.006.127 12.299 12.299 0 0 1-1.873.892.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.076.076 0 0 0 .084.028 19.839 19.839 0 0 0 6.002-3.03.077.077 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 0 0-.031-.03zM8.02 15.33c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.956-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.956 2.418-2.157 2.418zm7.975 0c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.955-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.946 2.418-2.157 2.418z\"\/><\/svg><br \/>\n            <span style=\"line-height: 1;\">Join Discord<\/span><br \/>\n        <\/a>\n    <\/div>\n<\/div>\n<p><!-- Hero Section --><\/p>\n<div style=\"background: linear-gradient(135deg, #1a1e3f 0%, #0a0e27 100%); border-left: 4px solid #00ffff; padding: 60px 40px; margin-bottom: 60px; border-radius: 8px; box-shadow: 0 10px 40px rgba(0, 255, 255, 0.1);\">\n<div style=\"color: #ff00ff; font-size: 1.4em; margin-bottom: 30px; font-weight: 300;\">One Click to Spawn a Decentralized Operating System<\/div>\n<p style=\"font-size: 1.2em; line-height: 1.6;\">Imagine clicking a single link and watching a complete decentralized operating system materialize in your browser\u2014pre-configured to show exactly the transaction, wallet address, or block you wanted to see. That&#8217;s what GLinks deliver: <strong style=\"color: #00ffff; font-weight: 600;\">deep linking for decentralized applications<\/strong>, with the power to encapsulate not just navigation state, but the complete context of what you&#8217;re trying to accomplish.<\/p>\n<p style=\"font-size: 1.1em; line-height: 1.6; margin-top: 15px; color: #c0c0c0;\">This isn&#8217;t a simple URL redirect. GLinks bootstrap an entire GRIDNET OS instance, authenticate the user (anonymously or otherwise), launch the target dApp, navigate to the specified view, and execute an action\u2014all from a single encoded URL parameter. It&#8217;s the kind of seamless experience we&#8217;ve come to expect from native apps, now available for the decentralized web.<\/p>\n<div style=\"color: #a0a0a0; font-style: italic; margin-top: 20px; padding-top: 20px; border-top: 1px solid #2a2e4f;\">Technical Deep Dive \u2022 GRIDNET OS Development Team \u2022 December 2025<\/div>\n<\/div>\n<p><!-- The GRIDNET OS Philosophy --><\/p>\n<div style=\"background: linear-gradient(135deg, #0a0e27 0%, #1a1e3f 100%); padding: 40px; border-radius: 12px; margin-bottom: 50px; border: 1px solid #2a2e4f;\">\n<h3 style=\"color: #ff00ff; font-size: 1.5em; margin-top: 0; margin-bottom: 25px;\">The Challenge: True Decentralization of the User Interface<\/h3>\n<p style=\"font-size: 1.1em; line-height: 1.7; color: #e0e0e0; margin-bottom: 20px;\">Most blockchain platforms today\u2014even the most respected ones like <strong style=\"color: #ffff00;\">AAVE<\/strong>, <strong style=\"color: #ffff00;\">Uniswap<\/strong>, and countless others\u2014rely on <strong style=\"color: #ff6666;\">traditional centralized web servers<\/strong> to deliver their user interfaces. The blockchain itself may be decentralized, but the moment you visit their website, you&#8217;re trusting a centralized server to serve you the correct, unmodified frontend code. This creates a single point of failure, censorship vulnerability, and trust assumption that undermines the very principles of decentralization.<\/p>\n<p style=\"font-size: 1.1em; line-height: 1.7; color: #e0e0e0; margin-bottom: 20px;\"><strong style=\"color: #00ffff;\">GRIDNET OS takes a fundamentally different approach.<\/strong> We deliver not just the backend, but the <em>entire user interface<\/em>\u2014every UI dApp, every component, every asset\u2014from a decentralized network. There is no central server to censor, compromise, or take down.<\/p>\n<div style=\"background: #0d1a2d; border-left: 4px solid #ffff00; padding: 20px 25px; border-radius: 4px; margin: 25px 0;\">\n<p style=\"font-size: 1em; line-height: 1.6; color: #e0e0e0; margin: 0;\"><strong style=\"color: #ffff00;\">A Note on the Bootloader:<\/strong> Even in our case, when accessing GRIDNET OS via <code style=\"color: #00ffff;\">https:\/\/ui.gridnet.org<\/code>, the initial bootloader itself must be delivered from one of our centralized servers. This stems from the inherently centralized nature of DNS entries\u2014someone has to resolve that domain name. However, as soon as the bootloader executes, it strives to deliver <em>all subsequent components<\/em>\u2014UI dApps, assets, scripts, and data\u2014from peers discovered through <strong style=\"color: #00ffff;\">Kademlia DHT<\/strong>. You can observe this in action: open Chrome DevTools and watch as nodes are discovered and reported during the boot sequence. The bootloader is the minimal trust anchor; everything else flows from the decentralized network.<\/p>\n<\/div>\n<div style=\"background: #0a0e27; border-radius: 8px; padding: 25px; margin: 25px 0; border: 1px solid #2a2e4f;\">\n<div style=\"color: #00ffff; font-weight: 600; font-size: 1.1em; margin-bottom: 15px;\">What This Enables:<\/div>\n<div style=\"display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 15px;\">\n<div style=\"display: flex; align-items: flex-start; gap: 10px;\">\n        <span style=\"color: #00ff00; font-size: 1.2em;\">\u2713<\/span><br \/>\n        <span style=\"color: #c0c0c0; font-size: 0.95em;\"><strong style=\"color: #e0e0e0;\">Multi-tasking &#038; Windowed Applications<\/strong> \u2014 Run multiple dApps simultaneously in separate windows<\/span>\n    <\/div>\n<div style=\"display: flex; align-items: flex-start; gap: 10px;\">\n        <span style=\"color: #00ff00; font-size: 1.2em;\">\u2713<\/span><br \/>\n        <span style=\"color: #c0c0c0; font-size: 0.95em;\"><strong style=\"color: #e0e0e0;\">Parallelism of Execution<\/strong> \u2014 True concurrent processing across dApps<\/span>\n    <\/div>\n<div style=\"display: flex; align-items: flex-start; gap: 10px;\">\n        <span style=\"color: #00ff00; font-size: 1.2em;\">\u2713<\/span><br \/>\n        <span style=\"color: #c0c0c0; font-size: 0.95em;\"><strong style=\"color: #e0e0e0;\">Cross-Process Communication<\/strong> \u2014 dApps can securely communicate with each other<\/span>\n    <\/div>\n<div style=\"display: flex; align-items: flex-start; gap: 10px;\">\n        <span style=\"color: #00ff00; font-size: 1.2em;\">\u2713<\/span><br \/>\n        <span style=\"color: #c0c0c0; font-size: 0.95em;\"><strong style=\"color: #e0e0e0;\">Decentralized File System<\/strong> \u2014 Store and retrieve files without central servers<\/span>\n    <\/div>\n<div style=\"display: flex; align-items: flex-start; gap: 10px;\">\n        <span style=\"color: #00ff00; font-size: 1.2em;\">\u2713<\/span><br \/>\n        <span style=\"color: #c0c0c0; font-size: 0.95em;\"><strong style=\"color: #e0e0e0;\">Process Compartmentation<\/strong> \u2014 Isolated execution environments for security<\/span>\n    <\/div>\n<div style=\"display: flex; align-items: flex-start; gap: 10px;\">\n        <span style=\"color: #00ff00; font-size: 1.2em;\">\u2713<\/span><br \/>\n        <span style=\"color: #c0c0c0; font-size: 0.95em;\"><strong style=\"color: #e0e0e0;\">Decentralized Processing Threads<\/strong> \u2014 Offload computation to the network<\/span>\n    <\/div>\n<div style=\"display: flex; align-items: flex-start; gap: 10px;\">\n        <span style=\"color: #00ff00; font-size: 1.2em;\">\u2713<\/span><br \/>\n        <span style=\"color: #c0c0c0; font-size: 0.95em;\"><strong style=\"color: #e0e0e0;\">Onion-Routed Communication<\/strong> \u2014 Privacy-preserving network layer<\/span>\n    <\/div>\n<div style=\"display: flex; align-items: flex-start; gap: 10px;\">\n        <span style=\"color: #00ff00; font-size: 1.2em;\">\u2713<\/span><br \/>\n        <span style=\"color: #c0c0c0; font-size: 0.95em;\"><strong style=\"color: #e0e0e0;\">Cross-Browser Data Exchange<\/strong> \u2014 Sync state across browser instances<\/span>\n    <\/div>\n<\/div>\n<\/div>\n<div style=\"background: #1a0a2e; border-left: 4px solid #ff00ff; padding: 20px 25px; border-radius: 4px; margin-top: 25px;\">\n<p style=\"font-size: 1.05em; line-height: 1.6; color: #e0e0e0; margin: 0;\"><strong style=\"color: #ff00ff;\">The Trade-off:<\/strong> All of this power comes with a technical requirement\u2014<strong style=\"color: #ffff00;\">the entire operating system must load and initialize before any individual UI dApp can launch<\/strong>. The Window Manager, Package Manager, VM Context, WebSocket connections to decentralized nodes, cryptographic authentication\u2014all of this must be ready before your Wallet or Explorer can open. This is fundamentally different from traditional web apps where a single HTTP request returns a ready-to-use page.<\/p>\n<\/div>\n<p style=\"font-size: 1.1em; line-height: 1.7; color: #e0e0e0; margin-top: 25px; margin-bottom: 0;\"><strong style=\"color: #00ffff;\">This is precisely why GLinks exist.<\/strong> They solve the challenge of deep linking into a system that must bootstrap itself first. GLinks carry the complete intent\u2014which dApp, which view, which action, which data\u2014and the GLink handler orchestrates the entire startup sequence, ensuring everything initializes in the correct order before finally delivering the user to their destination.<\/p>\n<\/div>\n<p><!-- Table of Contents --><\/p>\n<div style=\"background: #1a1e3f; padding: 30px; border-radius: 8px; margin: 40px 0; border: 1px solid #2a2e4f;\">\n<h3 style=\"margin-top: 0; color: #ff00ff; font-size: 1.6em;\">Table of Contents<\/h3>\n<ul style=\"margin: 20px 0; padding-left: 40px; color: #e0e0e0;\">\n<li style=\"margin-bottom: 12px; font-size: 1.05em;\"><a style=\"color: #00ffff; text-decoration: none;\" href=\"#why-glinks\">1. Why GLinks Matter: The Deep Linking Revolution<\/a><\/li>\n<li style=\"margin-bottom: 12px; font-size: 1.05em;\"><a style=\"color: #00ffff; text-decoration: none;\" href=\"#anatomy\">2. Anatomy of a GLink<\/a>\n<ul style=\"margin-top: 8px; padding-left: 25px;\">\n<li style=\"margin-bottom: 6px; font-size: 0.95em;\"><a style=\"color: #a0a0a0; text-decoration: none;\" href=\"#anatomy\">URL Structure<\/a><\/li>\n<li style=\"margin-bottom: 6px; font-size: 0.95em;\"><a style=\"color: #a0a0a0; text-decoration: none;\" href=\"#anatomy\">JSON Data Format<\/a><\/li>\n<li style=\"margin-bottom: 6px; font-size: 0.95em;\"><a style=\"color: #a0a0a0; text-decoration: none;\" href=\"#anatomy\">Base64 Encoding<\/a><\/li>\n<\/ul>\n<\/li>\n<li style=\"margin-bottom: 12px; font-size: 1.05em;\"><a style=\"color: #00ffff; text-decoration: none;\" href=\"#lifecycle\">3. The GLink Lifecycle<\/a><\/li>\n<li style=\"margin-bottom: 12px; font-size: 1.05em;\"><a style=\"color: #00ffff; text-decoration: none;\" href=\"#dapp-integration\">4. Implementing GLink Support in Your UI dApp<\/a><\/li>\n<li style=\"margin-bottom: 12px; font-size: 1.05em;\"><a style=\"color: #00ffff; text-decoration: none;\" href=\"#wallet-example\">5. Case Study: Wallet UI dApp<\/a><\/li>\n<li style=\"margin-bottom: 12px; font-size: 1.05em;\"><a style=\"color: #00ffff; text-decoration: none;\" href=\"#explorer-example\">6. Case Study: Blockchain Explorer UI dApp<\/a><\/li>\n<li style=\"margin-bottom: 12px; font-size: 1.05em;\"><a style=\"color: #00ffff; text-decoration: none;\" href=\"#creating-glinks\">7. Creating GLinks Programmatically<\/a><\/li>\n<li style=\"margin-bottom: 12px; font-size: 1.05em;\"><a style=\"color: #00ffff; text-decoration: none;\" href=\"#api-reference\">8. API Reference<\/a><\/li>\n<li style=\"margin-bottom: 12px; font-size: 1.05em;\"><a style=\"color: #00ffff; text-decoration: none;\" href=\"#best-practices\">9. Best Practices<\/a><\/li>\n<li style=\"margin-bottom: 12px; font-size: 1.05em;\"><a style=\"color: #00ffff; text-decoration: none;\" href=\"#encoding-flow\">10. The Encoding\/Decoding Flow<\/a><\/li>\n<li style=\"margin-bottom: 12px; font-size: 1.05em;\"><a style=\"color: #00ffff; text-decoration: none;\" href=\"#sequence\">11. Communication Sequence Diagram<\/a><\/li>\n<li style=\"margin-bottom: 12px; font-size: 1.05em;\"><a style=\"color: #00ffff; text-decoration: none;\" href=\"#use-cases\">12. Real-World Use Cases<\/a><\/li>\n<li style=\"margin-bottom: 12px; font-size: 1.05em;\"><a style=\"color: #00ffff; text-decoration: none;\" href=\"#troubleshooting\">13. Troubleshooting Guide<\/a><\/li>\n<li style=\"margin-bottom: 12px; font-size: 1.05em;\"><a style=\"color: #00ffff; text-decoration: none;\" href=\"#security\">14. Security Considerations<\/a><\/li>\n<\/ul>\n<\/div>\n<p><!-- Section 1: Why GLinks Matter --><\/p>\n<h2 id=\"why-glinks\" style=\"color: #ff00ff; font-size: 2.2em; margin-top: 60px; margin-bottom: 30px; padding-bottom: 15px; border-bottom: 2px solid #ff00ff; text-shadow: 0 0 15px rgba(255, 0, 255, 0.3);\">1. Why GLinks Matter: The Deep Linking Revolution<\/h2>\n<p style=\"margin-bottom: 20px; font-size: 1.1em; color: #e0e0e0;\">In traditional web applications, deep linking is straightforward\u2014you craft a URL with path segments and query parameters, and the server routes you to the right page. But GRIDNET OS isn&#8217;t a traditional web application. It&#8217;s a <strong style=\"color: #00ffff; font-weight: 600;\">complete operating system that runs in your browser<\/strong>, with multiple windowed applications, user sessions, blockchain connections, and cryptographic authentication.<\/p>\n<p style=\"margin-bottom: 20px; font-size: 1.1em; color: #e0e0e0;\">When someone shares a link to view a specific transaction, what actually needs to happen?<\/p>\n<div style=\"background: #1a1e3f; padding: 30px; border-radius: 8px; margin: 30px 0; border: 1px solid #2a2e4f;\">\n<ul style=\"margin: 0; padding-left: 40px; color: #e0e0e0;\">\n<li style=\"margin-bottom: 15px; font-size: 1.05em;\"><strong style=\"color: #00ffff; font-weight: 600;\">Bootstrap the OS:<\/strong> Load GRIDNET OS core, initialize the window manager, establish WebSocket connections to decentralized nodes<\/li>\n<li style=\"margin-bottom: 15px; font-size: 1.05em;\"><strong style=\"color: #00ffff; font-weight: 600;\">Authenticate:<\/strong> Create an anonymous session or prompt for login\u2014the blockchain doesn&#8217;t know &#8220;guest mode&#8221;<\/li>\n<li style=\"margin-bottom: 15px; font-size: 1.05em;\"><strong style=\"color: #00ffff; font-weight: 600;\">Launch the dApp:<\/strong> Find and instantiate the Blockchain Explorer application<\/li>\n<li style=\"margin-bottom: 15px; font-size: 1.05em;\"><strong style=\"color: #00ffff; font-weight: 600;\">Navigate to view:<\/strong> Switch to the Transactions tab<\/li>\n<li style=\"margin-bottom: 15px; font-size: 1.05em;\"><strong style=\"color: #00ffff; font-weight: 600;\">Execute action:<\/strong> Fetch and display the specific transaction details<\/li>\n<li style=\"margin-bottom: 0; font-size: 1.05em;\"><strong style=\"color: #00ffff; font-weight: 600;\">Report status:<\/strong> Confirm to the user that everything worked (or explain what went wrong)<\/li>\n<\/ul>\n<\/div>\n<p style=\"margin-bottom: 20px; font-size: 1.1em; color: #e0e0e0;\">GLinks encapsulate all of this in a single URL. One click, and the entire orchestration happens automatically.<\/p>\n<div style=\"background: #1a1e3f; border-left: 4px solid #00ff00; padding: 25px 30px; margin: 30px 0; border-radius: 4px;\">\n<h4 style=\"color: #00ff00; font-size: 1.3em; margin-top: 0; margin-bottom: 15px;\">The Breakthrough<\/h4>\n<p style=\"margin-bottom: 0; font-size: 1.1em; color: #e0e0e0;\">With GLinks, sharing blockchain data becomes as simple as sharing any other link. Post a transaction on social media, embed a payment request in an email, or create a QR code that opens someone&#8217;s wallet pre-filled with your address. <strong style=\"color: #00ffff; font-weight: 600;\">The decentralized web finally gets the user experience it deserves.<\/strong><\/p>\n<\/div>\n<p><!-- Section 2: Anatomy of a GLink --><\/p>\n<h2 id=\"anatomy\" style=\"color: #ff00ff; font-size: 2.2em; margin-top: 60px; margin-bottom: 30px; padding-bottom: 15px; border-bottom: 2px solid #ff00ff; text-shadow: 0 0 15px rgba(255, 0, 255, 0.3);\">2. Anatomy of a GLink<\/h2>\n<p style=\"margin-bottom: 20px; font-size: 1.1em; color: #e0e0e0;\">A GLink is a URL that carries encoded instructions for GRIDNET OS. Let&#8217;s dissect its structure:<\/p>\n<h3 style=\"color: #00ffff; font-size: 1.6em; margin-top: 40px; margin-bottom: 20px;\">URL Structure<\/h3>\n<p><!-- GLink URL Structure Diagram --><\/p>\n<div style=\"background: linear-gradient(135deg, #0a0e27 0%, #1a1e3f 100%); padding: 40px 30px; border-radius: 12px; margin: 30px 0; border: 1px solid #2a2e4f; box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);\">\n<p>    <!-- Header --><\/p>\n<div style=\"text-align: center; margin-bottom: 30px;\">\n<div style=\"display: inline-block; background: linear-gradient(90deg, #00ffff, #ff00ff); padding: 2px; border-radius: 8px;\">\n<div style=\"background: #0a0e27; padding: 12px 40px; border-radius: 6px;\">\n                <span style=\"font-size: 1.2em; font-weight: 700; background: linear-gradient(90deg, #00ffff, #ff00ff); -webkit-background-clip: text; -webkit-text-fill-color: transparent; letter-spacing: 2px;\">GLINK URL ANATOMY<\/span>\n            <\/div>\n<\/p><\/div>\n<\/p><\/div>\n<p>    <!-- URL Display --><\/p>\n<div style=\"background: #0a0e27; padding: 20px; border-radius: 8px; font-family: 'Courier New', monospace; overflow-x: auto; margin-bottom: 25px;\">\n<div style=\"display: flex; flex-wrap: wrap; align-items: center; gap: 0;\">\n            <span style=\"color: #00ff00; font-size: 1.1em;\">https:\/\/ui.gridnet.org\/<\/span><br \/>\n            <span style=\"color: #a0a0a0; font-size: 1.1em;\">?<\/span><br \/>\n            <span style=\"color: #ff00ff; font-size: 1.1em;\">glink<\/span><br \/>\n            <span style=\"color: #a0a0a0; font-size: 1.1em;\">=<\/span><br \/>\n            <span style=\"color: #ffff00; font-size: 1.1em;\">eyJhcHAiOiJvcmcuZ3JpZG5ldHByb2plY3QuVUlkQXBwcy53YWxsZXQiLCJ2aWV3Ijoic2VuZCIsImRhdGEiOnsiYWRkcmVzcyI6ImFsaWNlIn19<\/span>\n        <\/div>\n<\/p><\/div>\n<p>    <!-- Component Breakdown --><\/p>\n<div style=\"display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 15px;\">\n<div style=\"background: #1a1e3f; border-radius: 8px; padding: 15px; border-left: 3px solid #00ff00;\">\n<div style=\"color: #00ff00; font-weight: 600; margin-bottom: 8px;\">Base URL<\/div>\n<p>            <code style=\"color: #88ff88; font-size: 0.9em;\">https:\/\/ui.gridnet.org\/<\/code><\/p>\n<div style=\"color: #a0a0a0; font-size: 0.85em; margin-top: 8px;\">GRIDNET OS entry point<\/div>\n<\/p><\/div>\n<div style=\"background: #1a1e3f; border-radius: 8px; padding: 15px; border-left: 3px solid #ff00ff;\">\n<div style=\"color: #ff00ff; font-weight: 600; margin-bottom: 8px;\">Parameter Name<\/div>\n<p>            <code style=\"color: #ff88ff; font-size: 0.9em;\">glink<\/code><\/p>\n<div style=\"color: #a0a0a0; font-size: 0.85em; margin-top: 8px;\">Query parameter identifier<\/div>\n<\/p><\/div>\n<div style=\"background: #1a1e3f; border-radius: 8px; padding: 15px; border-left: 3px solid #ffff00;\">\n<div style=\"color: #ffff00; font-weight: 600; margin-bottom: 8px;\">Encoded Payload<\/div>\n<p>            <code style=\"color: #ffff88; font-size: 0.9em;\">Base64(JSON)<\/code><\/p>\n<div style=\"color: #a0a0a0; font-size: 0.85em; margin-top: 8px;\">URL-safe Base64 encoded JSON<\/div>\n<\/p><\/div>\n<\/p><\/div>\n<\/div>\n<h3 style=\"color: #00ffff; font-size: 1.6em; margin-top: 40px; margin-bottom: 20px;\">JSON Data Format<\/h3>\n<p style=\"margin-bottom: 20px; font-size: 1.1em; color: #e0e0e0;\">The encoded payload is a JSON object with the following structure:<\/p>\n<p><!-- JSON Structure Diagram --><\/p>\n<div style=\"background: linear-gradient(135deg, #0a0e27 0%, #1a1e3f 100%); padding: 35px 30px; border-radius: 12px; margin: 30px 0; border: 1px solid #2a2e4f;\">\n<div style=\"display: flex; align-items: center; gap: 15px; margin-bottom: 25px; padding-bottom: 20px; border-bottom: 1px solid #2a2e4f;\">\n<div style=\"background: linear-gradient(135deg, #00ffff 0%, #0088aa 100%); padding: 10px 15px; border-radius: 6px;\">\n            <span style=\"color: #ffffff; font-weight: 700; font-size: 0.85em; letter-spacing: 1px;\">JSON<\/span>\n        <\/div>\n<div>\n<div style=\"color: #00ffff; font-weight: 700; font-size: 1.2em;\">GLink Data Structure<\/div>\n<div style=\"color: #606080; font-size: 0.85em;\">All fields except &#8216;app&#8217; are optional<\/div>\n<\/p><\/div>\n<\/p><\/div>\n<p>    <code style=\"display: block; background: #0a0e27; padding: 25px; border-radius: 8px; overflow-x: auto; margin: 0; color: #e0e0e0; font-size: 1em; line-height: 1.6; white-space: pre;\">{<br \/>\n    <span style=\"color: #ff6666;\">\"app\"<\/span>: <span style=\"color: #98c379;\">\"org.gridnetproject.UIdApps.wallet\"<\/span>,    <span style=\"color: #5c6370;\">\/\/ Required: Package ID<\/span><br \/>\n    <span style=\"color: #ff6666;\">\"view\"<\/span>: <span style=\"color: #98c379;\">\"send\"<\/span>,                              <span style=\"color: #5c6370;\">\/\/ Optional: View\/tab to open<\/span><br \/>\n    <span style=\"color: #ff6666;\">\"action\"<\/span>: <span style=\"color: #d19a66;\">1<\/span>,                                  <span style=\"color: #5c6370;\">\/\/ Optional: Action ID to execute<\/span><br \/>\n    <span style=\"color: #ff6666;\">\"data\"<\/span>: {                                      <span style=\"color: #5c6370;\">\/\/ Optional: Action parameters<\/span><br \/>\n        <span style=\"color: #ff6666;\">\"address\"<\/span>: <span style=\"color: #98c379;\">\"alice\"<\/span>,<br \/>\n        <span style=\"color: #ff6666;\">\"amount\"<\/span>: <span style=\"color: #98c379;\">\"100\"<\/span><br \/>\n    }<br \/>\n}<\/code>\n<\/div>\n<p><!-- Field Descriptions Table --><\/p>\n<div style=\"background: #0a0e27; padding: 30px; border-radius: 8px; margin: 30px 0; border: 1px solid #2a2e4f;\">\n<table style=\"width: 100%; border-collapse: collapse; color: #e0e0e0;\">\n<tr style=\"border-bottom: 2px solid #2a2e4f;\">\n<th style=\"text-align: left; padding: 15px; color: #00ffff; width: 15%;\">Field<\/th>\n<th style=\"text-align: left; padding: 15px; color: #00ffff; width: 15%;\">Type<\/th>\n<th style=\"text-align: left; padding: 15px; color: #00ffff; width: 15%;\">Required<\/th>\n<th style=\"text-align: left; padding: 15px; color: #00ffff;\">Description<\/th>\n<\/tr>\n<tr style=\"border-bottom: 1px solid #2a2e4f;\">\n<td style=\"padding: 15px;\"><code style=\"color: #ff6666;\">app<\/code><\/td>\n<td style=\"padding: 15px; color: #a0a0a0;\">string<\/td>\n<td style=\"padding: 15px;\"><span style=\"color: #00ff00; font-weight: 600;\">Yes<\/span><\/td>\n<td style=\"padding: 15px;\">Package ID of the target UI dApp. Must be a valid installed application.<\/td>\n<\/tr>\n<tr style=\"border-bottom: 1px solid #2a2e4f;\">\n<td style=\"padding: 15px;\"><code style=\"color: #ff6666;\">view<\/code><\/td>\n<td style=\"padding: 15px; color: #a0a0a0;\">string<\/td>\n<td style=\"padding: 15px;\"><span style=\"color: #ffff00;\">No<\/span><\/td>\n<td style=\"padding: 15px;\">Specific view, tab, or section within the dApp to navigate to.<\/td>\n<\/tr>\n<tr style=\"border-bottom: 1px solid #2a2e4f;\">\n<td style=\"padding: 15px;\"><code style=\"color: #ff6666;\">action<\/code><\/td>\n<td style=\"padding: 15px; color: #a0a0a0;\">number<\/td>\n<td style=\"padding: 15px;\"><span style=\"color: #ffff00;\">No<\/span><\/td>\n<td style=\"padding: 15px;\">Numeric action ID. Each dApp defines its own action constants.<\/td>\n<\/tr>\n<tr>\n<td style=\"padding: 15px;\"><code style=\"color: #ff6666;\">data<\/code><\/td>\n<td style=\"padding: 15px; color: #a0a0a0;\">object<\/td>\n<td style=\"padding: 15px;\"><span style=\"color: #ffff00;\">No<\/span><\/td>\n<td style=\"padding: 15px;\">Arbitrary data object passed to the dApp for processing the action.<\/td>\n<\/tr>\n<\/table>\n<\/div>\n<h3 style=\"color: #00ffff; font-size: 1.6em; margin-top: 40px; margin-bottom: 20px;\">Known Package IDs<\/h3>\n<div style=\"background: #1a1e3f; padding: 25px 30px; border-radius: 8px; margin: 30px 0; border: 1px solid #2a2e4f;\">\n<table style=\"width: 100%; border-collapse: collapse; color: #e0e0e0;\">\n<tr style=\"border-bottom: 1px solid #2a2e4f;\">\n<th style=\"text-align: left; padding: 12px; color: #ff00ff;\">Application<\/th>\n<th style=\"text-align: left; padding: 12px; color: #ff00ff;\">Package ID<\/th>\n<\/tr>\n<tr style=\"border-bottom: 1px solid #2a2e4f;\">\n<td style=\"padding: 12px;\">Wallet<\/td>\n<td style=\"padding: 12px;\"><code style=\"color: #00ffff;\">org.gridnetproject.UIdApps.wallet<\/code><\/td>\n<\/tr>\n<tr style=\"border-bottom: 1px solid #2a2e4f;\">\n<td style=\"padding: 12px;\">Blockchain Explorer<\/td>\n<td style=\"padding: 12px;\"><code style=\"color: #00ffff;\">org.gridnetproject.UIdApps.BlockchainExplorer<\/code><\/td>\n<\/tr>\n<tr style=\"border-bottom: 1px solid #2a2e4f;\">\n<td style=\"padding: 12px;\">File Manager<\/td>\n<td style=\"padding: 12px;\"><code style=\"color: #00ffff;\">org.gridnetproject.UIdApps.fileManager<\/code><\/td>\n<\/tr>\n<tr style=\"border-bottom: 1px solid #2a2e4f;\">\n<td style=\"padding: 12px;\">Editor<\/td>\n<td style=\"padding: 12px;\"><code style=\"color: #00ffff;\">org.gridnetproject.UIdApps.editor<\/code><\/td>\n<\/tr>\n<tr>\n<td style=\"padding: 12px;\">Image Viewer<\/td>\n<td style=\"padding: 12px;\"><code style=\"color: #00ffff;\">org.gridnetproject.UIdApps.imageViewer<\/code><\/td>\n<\/tr>\n<\/table>\n<\/div>\n<p><!-- Section 3: The GLink Lifecycle --><\/p>\n<h2 id=\"lifecycle\" style=\"color: #ff00ff; font-size: 2.2em; margin-top: 60px; margin-bottom: 30px; padding-bottom: 15px; border-bottom: 2px solid #ff00ff; text-shadow: 0 0 15px rgba(255, 0, 255, 0.3);\">3. The GLink Lifecycle<\/h2>\n<p style=\"margin-bottom: 20px; font-size: 1.1em; color: #e0e0e0;\">Understanding the complete lifecycle of a GLink is essential for both users and developers. From the moment a GLink URL is clicked to the final confirmation, here&#8217;s what happens:<\/p>\n<p><!-- GLink Lifecycle Flow Diagram --><\/p>\n<div style=\"background: linear-gradient(135deg, #0a0e27 0%, #1a1e3f 100%); padding: 40px 30px; border-radius: 12px; margin: 30px 0; border: 1px solid #2a2e4f; box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);\">\n<p>    <!-- Header --><\/p>\n<div style=\"text-align: center; margin-bottom: 40px;\">\n<div style=\"display: inline-block; background: linear-gradient(90deg, #00ffff, #ff00ff); padding: 2px; border-radius: 8px;\">\n<div style=\"background: #0a0e27; padding: 12px 40px; border-radius: 6px;\">\n                <span style=\"font-size: 1.3em; font-weight: 700; background: linear-gradient(90deg, #00ffff, #ff00ff); -webkit-background-clip: text; -webkit-text-fill-color: transparent; letter-spacing: 2px;\">GLINK LIFECYCLE FLOW<\/span>\n            <\/div>\n<\/p><\/div>\n<\/p><\/div>\n<p>    <!-- Flow Steps --><\/p>\n<div style=\"display: flex; flex-direction: column; gap: 0;\">\n<p>        <!-- Step 1: URL Detection --><\/p>\n<div style=\"display: flex; align-items: stretch; gap: 15px;\">\n<div style=\"background: linear-gradient(180deg, #00ffff, #0088aa); width: 50px; min-width: 50px; border-radius: 8px; display: flex; align-items: center; justify-content: center;\">\n                <span style=\"color: #0a0e27; font-weight: 700; font-size: 1.2em;\">1<\/span>\n            <\/div>\n<div style=\"background: #1a1e3f; border-radius: 8px; padding: 15px; flex: 1; border-left: 3px solid #00ffff;\">\n<div style=\"color: #00ffff; font-weight: 600; font-size: 1em; margin-bottom: 5px;\">URL Detection<\/div>\n<div style=\"color: #e0e0e0; font-size: 0.9em;\">User clicks GLink URL. CGLinkHandler detects <code style=\"color: #ffff00;\">?glink=<\/code> parameter on page load.<\/div>\n<p>                <code style=\"display: block; margin-top: 8px; padding: 8px; background: rgba(0, 255, 255, 0.1); border-radius: 4px; color: #88ffff; font-size: 0.8em;\">CGLinkHandler.initialize() \u2192 CGLink.getFromCurrentURL()<\/code>\n            <\/div>\n<\/p><\/div>\n<p>        <!-- Arrow --><\/p>\n<div style=\"display: flex; justify-content: center; padding: 4px 0;\">\n<div style=\"width: 2px; height: 16px; background: linear-gradient(180deg, #00ffff, #ff00ff);\"><\/div>\n<\/p><\/div>\n<p>        <!-- Step 2: Show Indicator --><\/p>\n<div style=\"display: flex; align-items: stretch; gap: 15px;\">\n<div style=\"background: linear-gradient(180deg, #ff00ff, #aa0088); width: 50px; min-width: 50px; border-radius: 8px; display: flex; align-items: center; justify-content: center;\">\n                <span style=\"color: #ffffff; font-weight: 700; font-size: 1.2em;\">2<\/span>\n            <\/div>\n<div style=\"background: #1a1e3f; border-radius: 8px; padding: 15px; flex: 1; border-left: 3px solid #ff00ff;\">\n<div style=\"color: #ff00ff; font-weight: 600; font-size: 1em; margin-bottom: 5px;\">Progress Indicator<\/div>\n<div style=\"color: #e0e0e0; font-size: 0.9em;\">Visual indicator shows &#8220;GLink detected&#8221; with target app name.<\/div>\n<p>                <code style=\"display: block; margin-top: 8px; padding: 8px; background: rgba(255, 0, 255, 0.1); border-radius: 4px; color: #ff88ff; font-size: 0.8em;\">showIndicator() \u2192 updateIndicator('GLink detected', 10, appName)<\/code>\n            <\/div>\n<\/p><\/div>\n<p>        <!-- Arrow --><\/p>\n<div style=\"display: flex; justify-content: center; padding: 4px 0;\">\n<div style=\"width: 2px; height: 16px; background: linear-gradient(180deg, #ff00ff, #ffff00);\"><\/div>\n<\/p><\/div>\n<p>        <!-- Step 3: System Ready --><\/p>\n<div style=\"display: flex; align-items: stretch; gap: 15px;\">\n<div style=\"background: linear-gradient(180deg, #ffff00, #aa8800); width: 50px; min-width: 50px; border-radius: 8px; display: flex; align-items: center; justify-content: center;\">\n                <span style=\"color: #0a0e27; font-weight: 700; font-size: 1.2em;\">3<\/span>\n            <\/div>\n<div style=\"background: #1a1e3f; border-radius: 8px; padding: 15px; flex: 1; border-left: 3px solid #ffff00;\">\n<div style=\"color: #ffff00; font-weight: 600; font-size: 1em; margin-bottom: 5px;\">Wait for System Ready<\/div>\n<div style=\"color: #e0e0e0; font-size: 0.9em;\">GRIDNET OS initializes: Window Manager, Package Manager, CVMContext.<\/div>\n<p>                <code style=\"display: block; margin-top: 8px; padding: 8px; background: rgba(255, 255, 0, 0.1); border-radius: 4px; color: #ffff88; font-size: 0.8em;\">systemReady(windowManager, packageManager, vmContext)<\/code>\n            <\/div>\n<\/p><\/div>\n<p>        <!-- Arrow --><\/p>\n<div style=\"display: flex; justify-content: center; padding: 4px 0;\">\n<div style=\"width: 2px; height: 16px; background: linear-gradient(180deg, #ffff00, #00ff00);\"><\/div>\n<\/p><\/div>\n<p>        <!-- Step 4: User Authentication --><\/p>\n<div style=\"display: flex; align-items: stretch; gap: 15px;\">\n<div style=\"background: linear-gradient(180deg, #00ff00, #008800); width: 50px; min-width: 50px; border-radius: 8px; display: flex; align-items: center; justify-content: center;\">\n                <span style=\"color: #0a0e27; font-weight: 700; font-size: 1.2em;\">4<\/span>\n            <\/div>\n<div style=\"background: #1a1e3f; border-radius: 8px; padding: 15px; flex: 1; border-left: 3px solid #00ff00;\">\n<div style=\"color: #00ff00; font-weight: 600; font-size: 1em; margin-bottom: 5px;\">User Authentication<\/div>\n<div style=\"color: #e0e0e0; font-size: 0.9em;\">Wait for user logon (anonymous or authenticated session).<\/div>\n<p>                <code style=\"display: block; margin-top: 8px; padding: 8px; background: rgba(0, 255, 0, 0.1); border-radius: 4px; color: #88ff88; font-size: 0.8em;\">userLoggedIn() \u2192 processGLink(glinkData)<\/code>\n            <\/div>\n<\/p><\/div>\n<p>        <!-- Arrow --><\/p>\n<div style=\"display: flex; justify-content: center; padding: 4px 0;\">\n<div style=\"width: 2px; height: 16px; background: linear-gradient(180deg, #00ff00, #00ffff);\"><\/div>\n<\/p><\/div>\n<p>        <!-- Step 5: Launch dApp --><\/p>\n<div style=\"display: flex; align-items: stretch; gap: 15px;\">\n<div style=\"background: linear-gradient(180deg, #00ffff, #0088aa); width: 50px; min-width: 50px; border-radius: 8px; display: flex; align-items: center; justify-content: center;\">\n                <span style=\"color: #0a0e27; font-weight: 700; font-size: 1.2em;\">5<\/span>\n            <\/div>\n<div style=\"background: #1a1e3f; border-radius: 8px; padding: 15px; flex: 1; border-left: 3px solid #00ffff;\">\n<div style=\"color: #00ffff; font-weight: 600; font-size: 1em; margin-bottom: 5px;\">Launch Target dApp<\/div>\n<div style=\"color: #e0e0e0; font-size: 0.9em;\">Window Manager launches target app with GLink data as parameters.<\/div>\n<p>                <code style=\"display: block; margin-top: 8px; padding: 8px; background: rgba(0, 255, 255, 0.1); border-radius: 4px; color: #88ffff; font-size: 0.8em;\">windowManager.launchApp(app, true, launchData, 'glink')<\/code>\n            <\/div>\n<\/p><\/div>\n<p>        <!-- Arrow --><\/p>\n<div style=\"display: flex; justify-content: center; padding: 4px 0;\">\n<div style=\"width: 2px; height: 16px; background: linear-gradient(180deg, #00ffff, #ff00ff);\"><\/div>\n<\/p><\/div>\n<p>        <!-- Step 6: dApp Processing --><\/p>\n<div style=\"display: flex; align-items: stretch; gap: 15px;\">\n<div style=\"background: linear-gradient(180deg, #ff00ff, #aa0088); width: 50px; min-width: 50px; border-radius: 8px; display: flex; align-items: center; justify-content: center;\">\n                <span style=\"color: #ffffff; font-weight: 700; font-size: 1.2em;\">6<\/span>\n            <\/div>\n<div style=\"background: #1a1e3f; border-radius: 8px; padding: 15px; flex: 1; border-left: 3px solid #ff00ff;\">\n<div style=\"color: #ff00ff; font-weight: 600; font-size: 1em; margin-bottom: 5px;\">dApp Processes GLink<\/div>\n<div style=\"color: #e0e0e0; font-size: 0.9em;\">dApp&#8217;s <code style=\"color: #ffff00;\">processGLink()<\/code> accepts, navigates to view, executes action.<\/div>\n<p>                <code style=\"display: block; margin-top: 8px; padding: 8px; background: rgba(255, 0, 255, 0.1); border-radius: 4px; color: #ff88ff; font-size: 0.8em;\">acceptGLink() \u2192 switchView() \u2192 executeAction()<\/code>\n            <\/div>\n<\/p><\/div>\n<p>        <!-- Arrow --><\/p>\n<div style=\"display: flex; justify-content: center; padding: 4px 0;\">\n<div style=\"width: 2px; height: 16px; background: linear-gradient(180deg, #ff00ff, #00ff00);\"><\/div>\n<\/p><\/div>\n<p>        <!-- Step 7: Confirmation --><\/p>\n<div style=\"display: flex; align-items: stretch; gap: 15px;\">\n<div style=\"background: linear-gradient(180deg, #00ff00, #008800); width: 50px; min-width: 50px; border-radius: 8px; display: flex; align-items: center; justify-content: center;\">\n                <span style=\"color: #0a0e27; font-weight: 700; font-size: 1.2em;\">7<\/span>\n            <\/div>\n<div style=\"background: #0e2a1e; border-radius: 8px; padding: 15px; flex: 1; border: 2px solid #00ff00;\">\n<div style=\"color: #00ff00; font-weight: 600; font-size: 1em; margin-bottom: 5px;\">Confirmation \/ Rejection<\/div>\n<div style=\"color: #e0e0e0; font-size: 0.9em;\">dApp reports success\/failure. Indicator fades. URL parameter cleared.<\/div>\n<p>                <code style=\"display: block; margin-top: 8px; padding: 8px; background: rgba(0, 255, 0, 0.15); border-radius: 4px; color: #88ff88; font-size: 0.8em;\">confirmGLinkProcessed('Success!') or rejectGLink('Error')<\/code>\n            <\/div>\n<\/p><\/div>\n<\/p><\/div>\n<p>    <!-- Legend --><\/p>\n<div style=\"margin-top: 35px; padding-top: 25px; border-top: 1px solid #2a2e4f;\">\n<div style=\"display: flex; flex-wrap: wrap; justify-content: center; gap: 20px;\">\n<div style=\"display: flex; align-items: center; gap: 8px;\">\n<div style=\"width: 14px; height: 14px; background: #00ffff; border-radius: 3px;\"><\/div>\n<p>                <span style=\"color: #a0a0a0; font-size: 0.85em;\">System Operations<\/span>\n            <\/div>\n<div style=\"display: flex; align-items: center; gap: 8px;\">\n<div style=\"width: 14px; height: 14px; background: #ff00ff; border-radius: 3px;\"><\/div>\n<p>                <span style=\"color: #a0a0a0; font-size: 0.85em;\">Handler Operations<\/span>\n            <\/div>\n<div style=\"display: flex; align-items: center; gap: 8px;\">\n<div style=\"width: 14px; height: 14px; background: #ffff00; border-radius: 3px;\"><\/div>\n<p>                <span style=\"color: #a0a0a0; font-size: 0.85em;\">Initialization<\/span>\n            <\/div>\n<div style=\"display: flex; align-items: center; gap: 8px;\">\n<div style=\"width: 14px; height: 14px; background: #00ff00; border-radius: 3px;\"><\/div>\n<p>                <span style=\"color: #a0a0a0; font-size: 0.85em;\">Success\/Completion<\/span>\n            <\/div>\n<\/p><\/div>\n<\/p><\/div>\n<\/div>\n<div style=\"background: #1a1e3f; border-left: 4px solid #ff00ff; padding: 25px 30px; margin: 30px 0; border-radius: 4px;\">\n<h4 style=\"color: #ff00ff; font-size: 1.3em; margin-top: 0; margin-bottom: 15px;\">Timeout Protection<\/h4>\n<p style=\"margin-bottom: 0; font-size: 1.1em; color: #e0e0e0;\">The GLink handler implements a <strong style=\"color: #00ffff; font-weight: 600;\">15-second timeout<\/strong> for dApps to respond. If a dApp calls <code style=\"color: #ffff00;\">acceptGLink()<\/code>, the timeout extends to <strong style=\"color: #00ffff; font-weight: 600;\">3 minutes<\/strong> for complex operations. This ensures users aren&#8217;t left waiting indefinitely while still giving dApps time for heavy processing.<\/p>\n<\/div>\n<p><!-- Section 4: Implementing GLink Support --><\/p>\n<h2 id=\"dapp-integration\" style=\"color: #ff00ff; font-size: 2.2em; margin-top: 60px; margin-bottom: 30px; padding-bottom: 15px; border-bottom: 2px solid #ff00ff; text-shadow: 0 0 15px rgba(255, 0, 255, 0.3);\">4. Implementing GLink Support in Your UI dApp<\/h2>\n<p style=\"margin-bottom: 20px; font-size: 1.1em; color: #e0e0e0;\">Now that you understand how GLinks work conceptually, let&#8217;s build support into your own dApp. The process follows a clear pattern: <strong style=\"color: #00ffff;\">detect \u2192 accept \u2192 process \u2192 confirm<\/strong>. Each step serves a specific purpose in ensuring a smooth user experience.<\/p>\n<p style=\"margin-bottom: 20px; font-size: 1.1em; color: #e0e0e0;\">The most important thing to understand is <em>why<\/em> we structure things this way: the CGLinkHandler has strict timeouts (15 seconds initially, extending to 3 minutes after acceptance). If your dApp doesn&#8217;t respond in time, the GLink fails and the user sees an error. The pattern below ensures you always respond promptly while still having enough time to do complex operations.<\/p>\n<h3 style=\"color: #00ffff; font-size: 1.6em; margin-top: 40px; margin-bottom: 20px;\">Step 1: Import GLink Classes<\/h3>\n<p style=\"margin-bottom: 20px; font-size: 1.05em; color: #c0c0c0;\">You&#8217;ll need both classes: <code style=\"color: #ffff00;\">CGLink<\/code> for creating GLinks programmatically (e.g., &#8220;Copy GLink to clipboard&#8221; buttons), and <code style=\"color: #ffff00;\">CGLinkHandler<\/code> for responding to incoming GLinks:<\/p>\n<p><code style=\"display: block; background: #0a0e27; padding: 25px; border-radius: 8px; overflow-x: auto; margin: 20px 0; color: #e0e0e0; font-size: 1em; line-height: 1.6; white-space: pre;\"><span style=\"color: #c678dd;\">import<\/span> {<br \/>\n    CGLink,<br \/>\n    CGLinkHandler<br \/>\n} <span style=\"color: #c678dd;\">from<\/span> <span style=\"color: #98c379;\">'\/lib\/GLink.js'<\/span>;<\/code><\/p>\n<h3 style=\"color: #00ffff; font-size: 1.6em; margin-top: 40px; margin-bottom: 20px;\">Step 2: Detect and Accept GLink on Initialize<\/h3>\n<p style=\"margin-bottom: 20px; font-size: 1.1em; color: #e0e0e0;\">When your dApp starts, the first thing you need to check is: &#8220;Was I launched because of a GLink?&#8221; This check happens in your <code style=\"color: #ffff00;\">initialize()<\/code> method, and the answer comes from inherited CWindow properties.<\/p>\n<p style=\"margin-bottom: 20px; font-size: 1.1em; color: #e0e0e0;\"><strong style=\"color: #ff6666;\">Critical:<\/strong> Call <code style=\"color: #ffff00;\">acceptGLink()<\/code> as soon as you detect the GLink\u2014this extends your timeout from 15 seconds to 3 minutes. Don&#8217;t wait until you&#8217;re ready to process; accept first, then take your time:<\/p>\n<p><code style=\"display: block; background: #0a0e27; padding: 25px; border-radius: 8px; overflow-x: auto; margin: 20px 0; color: #e0e0e0; font-size: 1em; line-height: 1.6; white-space: pre;\"><span style=\"color: #c678dd;\">async<\/span> <span style=\"color: #61afef;\">initialize<\/span>() {<br \/>\n    <span style=\"color: #5c6370;\">\/\/ ... your normal initialization code ...<\/span><br \/>\n    <span style=\"color: #5c6370;\">\/\/ Check if launched via GLink<\/span><br \/>\n    <span style=\"color: #c678dd;\">if<\/span> (<span style=\"color: #c678dd;\">this<\/span>.wasLaunchedViaGLink) {<br \/>\n        <span style=\"color: #e5c07b;\">console<\/span>.<span style=\"color: #61afef;\">log<\/span>(<span style=\"color: #98c379;\">'[MyApp] Detected launch via GLink'<\/span>);<br \/>\n        <span style=\"color: #5c6370;\">\/\/ Get the GLink data passed to this dApp<\/span><br \/>\n        <span style=\"color: #c678dd;\">const<\/span> glinkData = <span style=\"color: #c678dd;\">this<\/span>.getGLinkData;<br \/>\n        <span style=\"color: #5c6370;\">\/\/ Accept immediately - this extends the timeout and shows progress<\/span><br \/>\n        <span style=\"color: #c678dd;\">const<\/span> glinkHandler = CGLinkHandler.<span style=\"color: #61afef;\">getInstance<\/span>();<br \/>\n        glinkHandler.<span style=\"color: #61afef;\">acceptGLink<\/span>(<span style=\"color: #98c379;\">'MyApp initializing...'<\/span>);<br \/>\n        <span style=\"color: #5c6370;\">\/\/ Process after a short delay to allow UI to stabilize<\/span><br \/>\n        <span style=\"color: #61afef;\">setTimeout<\/span>(() => {<br \/>\n            <span style=\"color: #c678dd;\">this<\/span>.<span style=\"color: #61afef;\">processGLink<\/span>(glinkData);<br \/>\n        }, <span style=\"color: #d19a66;\">2000<\/span>);<br \/>\n    }<br \/>\n}<\/code><\/p>\n<div style=\"background: #1a1e3f; border-left: 4px solid #00ff00; padding: 25px 30px; margin: 30px 0; border-radius: 4px;\">\n<h4 style=\"color: #00ff00; font-size: 1.3em; margin-top: 0; margin-bottom: 15px;\">Key Properties (Inherited from CWindow)<\/h4>\n<ul style=\"margin: 0; padding-left: 40px; color: #e0e0e0;\">\n<li style=\"margin-bottom: 10px; font-size: 1.05em;\"><code style=\"color: #ffff00;\">this.wasLaunchedViaGLink<\/code> &#8211; Boolean, true if app was launched via GLink<\/li>\n<li style=\"margin-bottom: 0; font-size: 1.05em;\"><code style=\"color: #ffff00;\">this.getGLinkData<\/code> &#8211; Object containing {view, action, data} from the GLink<\/li>\n<\/ul>\n<\/div>\n<h3 style=\"color: #00ffff; font-size: 1.6em; margin-top: 40px; margin-bottom: 20px;\">Step 3: Implement the processGLink Method<\/h3>\n<p style=\"margin-bottom: 20px; font-size: 1.1em; color: #e0e0e0;\">The <code style=\"color: #ffff00;\">processGLink()<\/code> method is where the actual work happens. This is your dApp&#8217;s contract with the GLink system: you receive structured data (view, action, data) and you&#8217;re responsible for making something happen.<\/p>\n<p style=\"margin-bottom: 20px; font-size: 1.1em; color: #e0e0e0;\">The pattern here is important: <strong style=\"color: #00ffff;\">navigate first, then act<\/strong>. If the GLink specifies a view, switch to it before executing the action. This ensures your action has the right DOM context to work with. Always wrap everything in try\/catch and always end with either <code style=\"color: #ffff00;\">confirmGLinkProcessed()<\/code> or <code style=\"color: #ffff00;\">rejectGLink()<\/code>\u2014never leave the handler hanging.<\/p>\n<p><code style=\"display: block; background: #0a0e27; padding: 25px; border-radius: 8px; overflow-x: auto; margin: 20px 0; color: #e0e0e0; font-size: 1em; line-height: 1.6; white-space: pre;\"><span style=\"color: #5c6370;\">\/**<br \/>\n * Process GLink data - handle deep link navigation.<br \/>\n * This method is the heart of your GLink support.<br \/>\n * @param {Object} glinkData - The parsed GLink data {view, action, data}<br \/>\n *\/<\/span><br \/>\n<span style=\"color: #61afef;\">processGLink<\/span>(glinkData) {<br \/>\n    <span style=\"color: #c678dd;\">const<\/span> glinkHandler = CGLinkHandler.<span style=\"color: #61afef;\">getInstance<\/span>();<br \/>\n    <span style=\"color: #c678dd;\">if<\/span> (!glinkData) {<br \/>\n        glinkHandler.<span style=\"color: #61afef;\">rejectGLink<\/span>(<span style=\"color: #98c379;\">'No GLink data provided'<\/span>);<br \/>\n        <span style=\"color: #c678dd;\">return<\/span>;<br \/>\n    }<br \/>\n    <span style=\"color: #5c6370;\">\/\/ Accept the GLink (in case not already accepted)<\/span><br \/>\n    glinkHandler.<span style=\"color: #61afef;\">acceptGLink<\/span>(<span style=\"color: #98c379;\">'Processing...'<\/span>);<br \/>\n    <span style=\"color: #c678dd;\">const<\/span> { view, action, data } = glinkData;<br \/>\n    <span style=\"color: #c678dd;\">try<\/span> {<br \/>\n        <span style=\"color: #5c6370;\">\/\/ Step 1: Navigate to specified view (if any)<\/span><br \/>\n        <span style=\"color: #c678dd;\">if<\/span> (view) {<br \/>\n            <span style=\"color: #c678dd;\">this<\/span>.<span style=\"color: #61afef;\">switchToView<\/span>(view);<br \/>\n        }<br \/>\n        <span style=\"color: #5c6370;\">\/\/ Step 2: Execute action (if any)<\/span><br \/>\n        <span style=\"color: #c678dd;\">if<\/span> (action !== <span style=\"color: #c678dd;\">null<\/span> && action !== <span style=\"color: #c678dd;\">undefined<\/span>) {<br \/>\n            <span style=\"color: #c678dd;\">this<\/span>.<span style=\"color: #61afef;\">executeGLinkAction<\/span>(action, data);<br \/>\n        }<br \/>\n        <span style=\"color: #5c6370;\">\/\/ Step 3: Confirm success<\/span><br \/>\n        glinkHandler.<span style=\"color: #61afef;\">confirmGLinkProcessed<\/span>(<span style=\"color: #98c379;\">'Action completed successfully'<\/span>);<br \/>\n    } <span style=\"color: #c678dd;\">catch<\/span> (error) {<br \/>\n        <span style=\"color: #e5c07b;\">console<\/span>.<span style=\"color: #61afef;\">error<\/span>(<span style=\"color: #98c379;\">'[MyApp] GLink error:'<\/span>, error);<br \/>\n        glinkHandler.<span style=\"color: #61afef;\">rejectGLink<\/span>(<span style=\"color: #98c379;\">`Error: <\/span><span style=\"color: #c678dd;\">${<\/span>error.message<span style=\"color: #c678dd;\">}<\/span><span style=\"color: #98c379;\">`<\/span>);<br \/>\n    }<br \/>\n}<br \/>\n<span style=\"color: #5c6370;\">\/**<br \/>\n * Execute a specific GLink action<br \/>\n *\/<\/span><br \/>\n<span style=\"color: #61afef;\">executeGLinkAction<\/span>(actionId, data) {<br \/>\n    <span style=\"color: #c678dd;\">switch<\/span> (actionId) {<br \/>\n        <span style=\"color: #c678dd;\">case<\/span> <span style=\"color: #d19a66;\">1<\/span>: <span style=\"color: #5c6370;\">\/\/ Example: View item details<\/span><br \/>\n            <span style=\"color: #c678dd;\">this<\/span>.<span style=\"color: #61afef;\">viewItemDetails<\/span>(data.itemId);<br \/>\n            <span style=\"color: #c678dd;\">break<\/span>;<br \/>\n        <span style=\"color: #c678dd;\">case<\/span> <span style=\"color: #d19a66;\">2<\/span>: <span style=\"color: #5c6370;\">\/\/ Example: Pre-fill form<\/span><br \/>\n            <span style=\"color: #c678dd;\">this<\/span>.<span style=\"color: #61afef;\">prefillForm<\/span>(data);<br \/>\n            <span style=\"color: #c678dd;\">break<\/span>;<br \/>\n        <span style=\"color: #c678dd;\">default<\/span>:<br \/>\n            <span style=\"color: #c678dd;\">throw new<\/span> <span style=\"color: #e5c07b;\">Error<\/span>(<span style=\"color: #98c379;\">`Unknown action ID: <\/span><span style=\"color: #c678dd;\">${<\/span>actionId<span style=\"color: #c678dd;\">}<\/span><span style=\"color: #98c379;\">`<\/span>);<br \/>\n    }<br \/>\n}<\/code><\/p>\n<h3 style=\"color: #00ffff; font-size: 1.6em; margin-top: 40px; margin-bottom: 20px;\">Step 4: Define Your Action IDs<\/h3>\n<p style=\"margin-bottom: 20px; font-size: 1.1em; color: #e0e0e0;\">Each dApp should define its own action constants as static properties:<\/p>\n<p><code style=\"display: block; background: #0a0e27; padding: 25px; border-radius: 8px; overflow-x: auto; margin: 20px 0; color: #e0e0e0; font-size: 1em; line-height: 1.6; white-space: pre;\"><span style=\"color: #5c6370;\">\/\/ Define action constants for your dApp<\/span><br \/>\n<span style=\"color: #c678dd;\">static<\/span> <span style=\"color: #c678dd;\">get<\/span> <span style=\"color: #61afef;\">GLinkActions<\/span>() {<br \/>\n    <span style=\"color: #c678dd;\">return<\/span> {<br \/>\n        VIEW_ITEM: <span style=\"color: #d19a66;\">1<\/span>,<br \/>\n        PREFILL_FORM: <span style=\"color: #d19a66;\">2<\/span>,<br \/>\n        SEARCH: <span style=\"color: #d19a66;\">3<\/span>,<br \/>\n        NAVIGATE: <span style=\"color: #d19a66;\">4<\/span><br \/>\n    };<br \/>\n}<\/code><\/p>\n<p><!-- GLink Handler Methods Diagram --><\/p>\n<div style=\"background: linear-gradient(135deg, #0a0e27 0%, #1a1e3f 100%); padding: 35px 30px; border-radius: 12px; margin: 30px 0; border: 1px solid #2a2e4f;\">\n<div style=\"text-align: center; margin-bottom: 30px;\">\n        <span style=\"color: #ff00ff; font-weight: 700; font-size: 1.2em; letter-spacing: 1px;\">GLINK HANDLER METHODS<\/span>\n    <\/div>\n<div style=\"display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 20px;\">\n<div style=\"background: #1a1e3f; border-radius: 8px; padding: 20px; border: 2px solid #00ffff;\">\n<div style=\"color: #00ffff; font-weight: 600; font-size: 1.1em; margin-bottom: 10px;\">acceptGLink(message)<\/div>\n<div style=\"color: #a0a0a0; font-size: 0.9em; margin-bottom: 10px;\">Acknowledges receipt of GLink. Extends timeout to 3 minutes.<\/div>\n<div style=\"color: #88ffff; font-size: 0.85em;\"><strong>When:<\/strong> As early as possible after detecting GLink<\/div>\n<\/p><\/div>\n<div style=\"background: #1a1e3f; border-radius: 8px; padding: 20px; border: 2px solid #00ff00;\">\n<div style=\"color: #00ff00; font-weight: 600; font-size: 1.1em; margin-bottom: 10px;\">confirmGLinkProcessed(message)<\/div>\n<div style=\"color: #a0a0a0; font-size: 0.9em; margin-bottom: 10px;\">Signals successful completion. Hides progress indicator with success animation.<\/div>\n<div style=\"color: #88ff88; font-size: 0.85em;\"><strong>When:<\/strong> After action is fully executed<\/div>\n<\/p><\/div>\n<div style=\"background: #1a1e3f; border-radius: 8px; padding: 20px; border: 2px solid #ff6666;\">\n<div style=\"color: #ff6666; font-weight: 600; font-size: 1.1em; margin-bottom: 10px;\">rejectGLink(reason)<\/div>\n<div style=\"color: #a0a0a0; font-size: 0.9em; margin-bottom: 10px;\">Signals failure or rejection. Shows error state before hiding indicator.<\/div>\n<div style=\"color: #ffaaaa; font-size: 0.85em;\"><strong>When:<\/strong> On error or invalid GLink data<\/div>\n<\/p><\/div>\n<\/p><\/div>\n<\/div>\n<p><!-- Section 5: Wallet Case Study --><\/p>\n<h2 id=\"wallet-example\" style=\"color: #ff00ff; font-size: 2.2em; margin-top: 60px; margin-bottom: 30px; padding-bottom: 15px; border-bottom: 2px solid #ff00ff; text-shadow: 0 0 15px rgba(255, 0, 255, 0.3);\">5. Case Study: Wallet UI dApp<\/h2>\n<p style=\"margin-bottom: 20px; font-size: 1.1em; color: #e0e0e0;\">The Wallet UI dApp presents an interesting implementation challenge: <strong style=\"color: #00ffff;\">what happens when a GLink arrives but the wallet is PIN-locked?<\/strong> You can&#8217;t just ignore the GLink\u2014the user clicked a payment link for a reason. But you also can&#8217;t process financial operations without the user first proving they have access to their wallet.<\/p>\n<p style=\"margin-bottom: 20px; font-size: 1.1em; color: #e0e0e0;\">The Wallet solves this elegantly by <strong style=\"color: #00ffff;\">accepting the GLink immediately<\/strong> (to extend the timeout and provide feedback), <strong style=\"color: #00ffff;\">storing it for later<\/strong>, and then processing it once the user unlocks with their PIN. Let&#8217;s examine how this works in practice.<\/p>\n<h3 style=\"color: #00ffff; font-size: 1.6em; margin-top: 40px; margin-bottom: 20px;\">Wallet GLink Actions<\/h3>\n<p style=\"margin-bottom: 20px; font-size: 1.05em; color: #c0c0c0;\">The Wallet defines five actions, covering the primary user workflows: sending funds, receiving funds, viewing history, and managing keychains and settings.<\/p>\n<div style=\"background: #0a0e27; padding: 30px; border-radius: 8px; margin: 30px 0; border: 1px solid #2a2e4f;\">\n<table style=\"width: 100%; border-collapse: collapse; color: #e0e0e0;\">\n<tr style=\"border-bottom: 2px solid #2a2e4f;\">\n<th style=\"text-align: left; padding: 15px; color: #00ffff;\">Action ID<\/th>\n<th style=\"text-align: left; padding: 15px; color: #00ffff;\">Name<\/th>\n<th style=\"text-align: left; padding: 15px; color: #00ffff;\">Data Fields<\/th>\n<th style=\"text-align: left; padding: 15px; color: #00ffff;\">Description<\/th>\n<\/tr>\n<tr style=\"border-bottom: 1px solid #2a2e4f;\">\n<td style=\"padding: 15px;\"><code style=\"color: #d19a66;\">1<\/code><\/td>\n<td style=\"padding: 15px;\">PREFILL_SEND<\/td>\n<td style=\"padding: 15px;\"><code style=\"color: #98c379;\">address, amount<\/code><br \/><span style=\"color: #606080; font-size: 0.85em;\">or <code style=\"color: #98c379;\">recipients[]<\/code><\/span><\/td>\n<td style=\"padding: 15px;\">Pre-fill send form with recipient(s). Supports both single recipient shorthand and multiple recipients array.<\/td>\n<\/tr>\n<tr style=\"border-bottom: 1px solid #2a2e4f;\">\n<td style=\"padding: 15px;\"><code style=\"color: #d19a66;\">2<\/code><\/td>\n<td style=\"padding: 15px;\">SHOW_RECEIVE<\/td>\n<td style=\"padding: 15px;\"><code style=\"color: #98c379;\">(none)<\/code><\/td>\n<td style=\"padding: 15px;\">Open the Receive tab to display the user&#8217;s wallet address and QR code.<\/td>\n<\/tr>\n<tr style=\"border-bottom: 1px solid #2a2e4f;\">\n<td style=\"padding: 15px;\"><code style=\"color: #d19a66;\">3<\/code><\/td>\n<td style=\"padding: 15px;\">VIEW_HISTORY<\/td>\n<td style=\"padding: 15px;\"><code style=\"color: #98c379;\">filter<\/code> <span style=\"color: #606080;\">(optional)<\/span><\/td>\n<td style=\"padding: 15px;\">Open the transaction history view, optionally with a filter applied.<\/td>\n<\/tr>\n<tr style=\"border-bottom: 1px solid #2a2e4f;\">\n<td style=\"padding: 15px;\"><code style=\"color: #d19a66;\">4<\/code><\/td>\n<td style=\"padding: 15px;\">OPEN_KEYCHAIN<\/td>\n<td style=\"padding: 15px;\"><code style=\"color: #98c379;\">(none)<\/code><\/td>\n<td style=\"padding: 15px;\">Open the keychain management view.<\/td>\n<\/tr>\n<tr>\n<td style=\"padding: 15px;\"><code style=\"color: #d19a66;\">5<\/code><\/td>\n<td style=\"padding: 15px;\">OPEN_SETTINGS<\/td>\n<td style=\"padding: 15px;\"><code style=\"color: #98c379;\">(none)<\/code><\/td>\n<td style=\"padding: 15px;\">Open the wallet settings view.<\/td>\n<\/tr>\n<\/table>\n<\/div>\n<div style=\"background: #1a1e3f; border-left: 4px solid #00ffff; padding: 20px 25px; margin: 30px 0; border-radius: 4px;\">\n<h4 style=\"color: #00ffff; margin-top: 0; margin-bottom: 10px;\">Multiple Recipients Support<\/h4>\n<p style=\"margin: 0; color: #e0e0e0;\">The Wallet&#8217;s PREFILL_SEND action supports two data formats: a simple <code style=\"color: #ffff00;\">{address, amount}<\/code> object for single recipients, or a <code style=\"color: #ffff00;\">{recipients: [{address, amount}, ...]}<\/code> array for batch payments. This flexibility lets you create both simple payment links and complex multi-recipient invoices.<\/p>\n<\/div>\n<h3 style=\"color: #00ffff; font-size: 1.6em; margin-top: 40px; margin-bottom: 20px;\">Handling PIN-Locked State<\/h3>\n<p style=\"margin-bottom: 20px; font-size: 1.1em; color: #e0e0e0;\">Here&#8217;s where things get interesting. The CGLinkHandler has a 15-second timeout\u2014if the dApp doesn&#8217;t respond, the GLink fails. But what if the user needs to enter their PIN first? That could easily take longer than 15 seconds.<\/p>\n<p style=\"margin-bottom: 20px; font-size: 1.1em; color: #e0e0e0;\">The solution is a two-phase approach: <strong style=\"color: #00ffff;\">accept immediately<\/strong> to extend the timeout to 3 minutes, then <strong style=\"color: #00ffff;\">defer processing<\/strong> until the wallet is unlocked. The code stores the GLink data in a member variable and processes it after the PIN unlock callback fires:<\/p>\n<p><code style=\"display: block; background: #0a0e27; padding: 25px; border-radius: 8px; overflow-x: auto; margin: 20px 0; color: #e0e0e0; font-size: 1em; line-height: 1.6; white-space: pre;\"><span style=\"color: #5c6370;\">\/\/ In initialize()<\/span><br \/>\n<span style=\"color: #c678dd;\">if<\/span> (<span style=\"color: #c678dd;\">this<\/span>.wasLaunchedViaGLink) {<br \/>\n    <span style=\"color: #c678dd;\">const<\/span> glinkHandler = CGLinkHandler.<span style=\"color: #61afef;\">getInstance<\/span>();<br \/>\n    <span style=\"color: #c678dd;\">const<\/span> glinkData = <span style=\"color: #c678dd;\">this<\/span>.getGLinkData;<br \/>\n    <span style=\"color: #5c6370;\">\/\/ Accept immediately to extend timeout<\/span><br \/>\n    glinkHandler.<span style=\"color: #61afef;\">acceptGLink<\/span>(<span style=\"color: #98c379;\">'Wallet received GLink'<\/span>);<br \/>\n    <span style=\"color: #5c6370;\">\/\/ Store for later processing<\/span><br \/>\n    <span style=\"color: #c678dd;\">this<\/span>.mPendingGLinkData = glinkData;<br \/>\n    <span style=\"color: #5c6370;\">\/\/ Process immediately if not locked, otherwise wait for unlock<\/span><br \/>\n    <span style=\"color: #61afef;\">setTimeout<\/span>(() => {<br \/>\n        <span style=\"color: #c678dd;\">if<\/span> (!<span style=\"color: #c678dd;\">this<\/span>.mIsLocked && <span style=\"color: #c678dd;\">this<\/span>.mPendingGLinkData) {<br \/>\n            <span style=\"color: #c678dd;\">this<\/span>.<span style=\"color: #61afef;\">processGLink<\/span>(<span style=\"color: #c678dd;\">this<\/span>.mPendingGLinkData);<br \/>\n            <span style=\"color: #c678dd;\">this<\/span>.mPendingGLinkData = <span style=\"color: #c678dd;\">null<\/span>;<br \/>\n        }<br \/>\n    }, <span style=\"color: #d19a66;\">1000<\/span>);<br \/>\n}<br \/>\n<span style=\"color: #5c6370;\">\/\/ In onPINUnlock() handler<\/span><br \/>\n<span style=\"color: #c678dd;\">if<\/span> (<span style=\"color: #c678dd;\">this<\/span>.mPendingGLinkData) {<br \/>\n    <span style=\"color: #e5c07b;\">console<\/span>.<span style=\"color: #61afef;\">log<\/span>(<span style=\"color: #98c379;\">'[Wallet] Processing pending GLink after unlock...'<\/span>);<br \/>\n    <span style=\"color: #c678dd;\">this<\/span>.<span style=\"color: #61afef;\">processGLink<\/span>(<span style=\"color: #c678dd;\">this<\/span>.mPendingGLinkData);<br \/>\n    <span style=\"color: #c678dd;\">this<\/span>.mPendingGLinkData = <span style=\"color: #c678dd;\">null<\/span>;<br \/>\n}<\/code><\/p>\n<h3 style=\"color: #00ffff; font-size: 1.6em; margin-top: 40px; margin-bottom: 20px;\">Example: Payment Request GLink<\/h3>\n<p><code style=\"display: block; background: #0a0e27; padding: 25px; border-radius: 8px; overflow-x: auto; margin: 20px 0; color: #e0e0e0; font-size: 1em; line-height: 1.6; white-space: pre;\"><span style=\"color: #5c6370;\">\/\/ Create a GLink for a payment request<\/span><br \/>\n<span style=\"color: #c678dd;\">const<\/span> paymentGLink = CGLink.<span style=\"color: #61afef;\">create<\/span>(<br \/>\n    CGLink.PackageIDs.WALLET,    <span style=\"color: #5c6370;\">\/\/ Target: Wallet dApp<\/span><br \/>\n    <span style=\"color: #98c379;\">'send'<\/span>,                      <span style=\"color: #5c6370;\">\/\/ View: Send tab<\/span><br \/>\n    <span style=\"color: #d19a66;\">1<\/span>,                           <span style=\"color: #5c6370;\">\/\/ Action: PREFILL_SEND<\/span><br \/>\n    {<br \/>\n        address: <span style=\"color: #98c379;\">'alice.grid'<\/span>,    <span style=\"color: #5c6370;\">\/\/ Recipient address<\/span><br \/>\n        amount: <span style=\"color: #98c379;\">'100'<\/span>             <span style=\"color: #5c6370;\">\/\/ Amount in GNC<\/span><br \/>\n    }<br \/>\n);<br \/>\n<span style=\"color: #5c6370;\">\/\/ Result: https:\/\/ui.gridnet.org\/?glink=eyJhcHAiOiJvcmcuZ3JpZG5ldHByb2plY3QuVUlkQXBwcy53YWxsZXQiLCJ2aWV3Ijoic2VuZCIsImFjdGlvbiI6MSwiZGF0YSI6eyJhZGRyZXNzIjoiYWxpY2UuZ3JpZCIsImFtb3VudCI6IjEwMCJ9fQ<\/span><\/code><\/p>\n<p><!-- Section 6: Explorer Case Study --><\/p>\n<h2 id=\"explorer-example\" style=\"color: #ff00ff; font-size: 2.2em; margin-top: 60px; margin-bottom: 30px; padding-bottom: 15px; border-bottom: 2px solid #ff00ff; text-shadow: 0 0 15px rgba(255, 0, 255, 0.3);\">6. Case Study: Blockchain Explorer UI dApp<\/h2>\n<p style=\"margin-bottom: 20px; font-size: 1.1em; color: #e0e0e0;\">While the Wallet dealt with deferred processing (PIN unlock), the Blockchain Explorer faces a different challenge: <strong style=\"color: #00ffff;\">asynchronous data loading<\/strong>. When you click a GLink to view a specific transaction, the Explorer needs to fetch that transaction from the blockchain before it can display it.<\/p>\n<p style=\"margin-bottom: 20px; font-size: 1.1em; color: #e0e0e0;\">The Explorer&#8217;s approach is simpler than the Wallet&#8217;s because it doesn&#8217;t have a PIN gate. It accepts the GLink during initialization, waits a brief moment for the UI to stabilize, then processes the action. The key insight here is the use of <strong style=\"color: #00ffff;\">a 2-second delay<\/strong> after accepting\u2014this gives the Explorer&#8217;s data fetching mechanisms time to initialize without blocking the GLink timeout.<\/p>\n<h3 style=\"color: #00ffff; font-size: 1.6em; margin-top: 40px; margin-bottom: 20px;\">Explorer GLink Actions<\/h3>\n<p style=\"margin-bottom: 20px; font-size: 1.05em; color: #c0c0c0;\">The Explorer exposes four actions focused on blockchain data exploration:<\/p>\n<div style=\"background: #0a0e27; padding: 30px; border-radius: 8px; margin: 30px 0; border: 1px solid #2a2e4f;\">\n<table style=\"width: 100%; border-collapse: collapse; color: #e0e0e0;\">\n<tr style=\"border-bottom: 2px solid #2a2e4f;\">\n<th style=\"text-align: left; padding: 15px; color: #00ffff;\">Action ID<\/th>\n<th style=\"text-align: left; padding: 15px; color: #00ffff;\">Name<\/th>\n<th style=\"text-align: left; padding: 15px; color: #00ffff;\">Data Fields<\/th>\n<th style=\"text-align: left; padding: 15px; color: #00ffff;\">Description<\/th>\n<\/tr>\n<tr style=\"border-bottom: 1px solid #2a2e4f;\">\n<td style=\"padding: 15px;\"><code style=\"color: #d19a66;\">1<\/code><\/td>\n<td style=\"padding: 15px;\">VIEW_BLOCK<\/td>\n<td style=\"padding: 15px;\"><code style=\"color: #98c379;\">blockId<\/code><\/td>\n<td style=\"padding: 15px;\">Fetch and display details of a specific block by its ID or height.<\/td>\n<\/tr>\n<tr style=\"border-bottom: 1px solid #2a2e4f;\">\n<td style=\"padding: 15px;\"><code style=\"color: #d19a66;\">2<\/code><\/td>\n<td style=\"padding: 15px;\">VIEW_TRANSACTION<\/td>\n<td style=\"padding: 15px;\"><code style=\"color: #98c379;\">txId<\/code><\/td>\n<td style=\"padding: 15px;\">Fetch and display details of a specific transaction by its hash.<\/td>\n<\/tr>\n<tr style=\"border-bottom: 1px solid #2a2e4f;\">\n<td style=\"padding: 15px;\"><code style=\"color: #d19a66;\">3<\/code><\/td>\n<td style=\"padding: 15px;\">SEARCH_DOMAIN<\/td>\n<td style=\"padding: 15px;\"><code style=\"color: #98c379;\">domain<\/code><\/td>\n<td style=\"padding: 15px;\">Look up a GRIDNET domain name and display its registration info.<\/td>\n<\/tr>\n<tr>\n<td style=\"padding: 15px;\"><code style=\"color: #d19a66;\">4<\/code><\/td>\n<td style=\"padding: 15px;\">SEARCH<\/td>\n<td style=\"padding: 15px;\"><code style=\"color: #98c379;\">query<\/code><\/td>\n<td style=\"padding: 15px;\">Execute a general search query (blocks, transactions, domains, addresses).<\/td>\n<\/tr>\n<\/table>\n<\/div>\n<h3 style=\"color: #00ffff; font-size: 1.6em; margin-top: 40px; margin-bottom: 20px;\">Explorer processGLink Implementation<\/h3>\n<p style=\"margin-bottom: 20px; font-size: 1.05em; color: #c0c0c0;\">Notice how the Explorer&#8217;s implementation is more straightforward\u2014it doesn&#8217;t need the deferred processing pattern because there&#8217;s no unlock step. It switches to the specified view (if any), then executes the action based on the numeric ID:<\/p>\n<p><code style=\"display: block; background: #0a0e27; padding: 25px; border-radius: 8px; overflow-x: auto; margin: 20px 0; color: #e0e0e0; font-size: 1em; line-height: 1.6; white-space: pre;\"><span style=\"color: #61afef;\">processGLink<\/span>(glinkData) {<br \/>\n    <span style=\"color: #c678dd;\">const<\/span> glinkHandler = CGLinkHandler.<span style=\"color: #61afef;\">getInstance<\/span>();<br \/>\n    <span style=\"color: #c678dd;\">if<\/span> (!glinkData) {<br \/>\n        glinkHandler.<span style=\"color: #61afef;\">rejectGLink<\/span>(<span style=\"color: #98c379;\">'No GLink data provided'<\/span>);<br \/>\n        <span style=\"color: #c678dd;\">return<\/span>;<br \/>\n    }<br \/>\n    glinkHandler.<span style=\"color: #61afef;\">acceptGLink<\/span>(<span style=\"color: #98c379;\">'Explorer processing...'<\/span>);<br \/>\n    <span style=\"color: #c678dd;\">const<\/span> { view, action, data } = glinkData;<br \/>\n    <span style=\"color: #c678dd;\">try<\/span> {<br \/>\n        <span style=\"color: #5c6370;\">\/\/ Navigate to view if specified<\/span><br \/>\n        <span style=\"color: #c678dd;\">if<\/span> (view) {<br \/>\n            <span style=\"color: #c678dd;\">this<\/span>.ui.<span style=\"color: #61afef;\">switchToSection<\/span>(view);<br \/>\n        }<br \/>\n        <span style=\"color: #5c6370;\">\/\/ Execute action based on numeric ID<\/span><br \/>\n        <span style=\"color: #c678dd;\">if<\/span> (action !== <span style=\"color: #c678dd;\">null<\/span>) {<br \/>\n            <span style=\"color: #c678dd;\">switch<\/span> (action) {<br \/>\n                <span style=\"color: #c678dd;\">case<\/span> <span style=\"color: #d19a66;\">1<\/span>: <span style=\"color: #5c6370;\">\/\/ VIEW_BLOCK<\/span><br \/>\n                    <span style=\"color: #c678dd;\">this<\/span>.<span style=\"color: #61afef;\">viewBlockDetails<\/span>(data.blockId);<br \/>\n                    <span style=\"color: #c678dd;\">break<\/span>;<br \/>\n                <span style=\"color: #c678dd;\">case<\/span> <span style=\"color: #d19a66;\">2<\/span>: <span style=\"color: #5c6370;\">\/\/ VIEW_TRANSACTION<\/span><br \/>\n                    <span style=\"color: #c678dd;\">this<\/span>.<span style=\"color: #61afef;\">viewTransactionDetails<\/span>(data.txId);<br \/>\n                    <span style=\"color: #c678dd;\">break<\/span>;<br \/>\n                <span style=\"color: #c678dd;\">case<\/span> <span style=\"color: #d19a66;\">3<\/span>: <span style=\"color: #5c6370;\">\/\/ VIEW_DOMAIN<\/span><br \/>\n                    <span style=\"color: #c678dd;\">this<\/span>.<span style=\"color: #61afef;\">searchDomain<\/span>(data.domain);<br \/>\n                    <span style=\"color: #c678dd;\">break<\/span>;<br \/>\n                <span style=\"color: #c678dd;\">case<\/span> <span style=\"color: #d19a66;\">4<\/span>: <span style=\"color: #5c6370;\">\/\/ SEARCH<\/span><br \/>\n                    <span style=\"color: #c678dd;\">this<\/span>.<span style=\"color: #61afef;\">performSearch<\/span>(data.query);<br \/>\n                    <span style=\"color: #c678dd;\">break<\/span>;<br \/>\n                <span style=\"color: #c678dd;\">default<\/span>:<br \/>\n                    glinkHandler.<span style=\"color: #61afef;\">rejectGLink<\/span>(<span style=\"color: #98c379;\">`Unknown action: <\/span><span style=\"color: #c678dd;\">${<\/span>action<span style=\"color: #c678dd;\">}<\/span><span style=\"color: #98c379;\">`<\/span>);<br \/>\n                    <span style=\"color: #c678dd;\">return<\/span>;<br \/>\n            }<br \/>\n            glinkHandler.<span style=\"color: #61afef;\">confirmGLinkProcessed<\/span>(<span style=\"color: #98c379;\">'Action completed'<\/span>);<br \/>\n        } <span style=\"color: #c678dd;\">else<\/span> <span style=\"color: #c678dd;\">if<\/span> (view) {<br \/>\n            glinkHandler.<span style=\"color: #61afef;\">confirmGLinkProcessed<\/span>(<span style=\"color: #98c379;\">'View opened'<\/span>);<br \/>\n        } <span style=\"color: #c678dd;\">else<\/span> {<br \/>\n            glinkHandler.<span style=\"color: #61afef;\">rejectGLink<\/span>(<span style=\"color: #98c379;\">'No action or view specified'<\/span>);<br \/>\n        }<br \/>\n    } <span style=\"color: #c678dd;\">catch<\/span> (error) {<br \/>\n        glinkHandler.<span style=\"color: #61afef;\">rejectGLink<\/span>(<span style=\"color: #98c379;\">`Error: <\/span><span style=\"color: #c678dd;\">${<\/span>error.message<span style=\"color: #c678dd;\">}<\/span><span style=\"color: #98c379;\">`<\/span>);<br \/>\n    }<br \/>\n}<\/code><\/p>\n<h3 style=\"color: #00ffff; font-size: 1.6em; margin-top: 40px; margin-bottom: 20px;\">Creating Explorer GLinks<\/h3>\n<p><code style=\"display: block; background: #0a0e27; padding: 25px; border-radius: 8px; overflow-x: auto; margin: 20px 0; color: #e0e0e0; font-size: 1em; line-height: 1.6; white-space: pre;\"><span style=\"color: #5c6370;\">\/\/ View a specific transaction<\/span><br \/>\n<span style=\"color: #c678dd;\">const<\/span> txGLink = CGLink.<span style=\"color: #61afef;\">create<\/span>(<br \/>\n    CGLink.PackageIDs.EXPLORER,<br \/>\n    <span style=\"color: #98c379;\">'transactions'<\/span>,<br \/>\n    <span style=\"color: #d19a66;\">2<\/span>, <span style=\"color: #5c6370;\">\/\/ VIEW_TRANSACTION<\/span><br \/>\n    { txId: <span style=\"color: #98c379;\">'abc123...'<\/span> }<br \/>\n);<br \/>\n<span style=\"color: #5c6370;\">\/\/ View a specific block<\/span><br \/>\n<span style=\"color: #c678dd;\">const<\/span> blockGLink = CGLink.<span style=\"color: #61afef;\">create<\/span>(<br \/>\n    CGLink.PackageIDs.EXPLORER,<br \/>\n    <span style=\"color: #98c379;\">'blocks'<\/span>,<br \/>\n    <span style=\"color: #d19a66;\">1<\/span>, <span style=\"color: #5c6370;\">\/\/ VIEW_BLOCK<\/span><br \/>\n    { blockId: <span style=\"color: #98c379;\">'12345'<\/span> }<br \/>\n);<br \/>\n<span style=\"color: #5c6370;\">\/\/ Search for a domain<\/span><br \/>\n<span style=\"color: #c678dd;\">const<\/span> domainGLink = CGLink.<span style=\"color: #61afef;\">create<\/span>(<br \/>\n    CGLink.PackageIDs.EXPLORER,<br \/>\n    <span style=\"color: #98c379;\">'search'<\/span>,<br \/>\n    <span style=\"color: #d19a66;\">3<\/span>, <span style=\"color: #5c6370;\">\/\/ VIEW_DOMAIN<\/span><br \/>\n    { domain: <span style=\"color: #98c379;\">'alice.grid'<\/span> }<br \/>\n);<\/code><\/p>\n<p><!-- Section 7: Creating GLinks --><\/p>\n<h2 id=\"creating-glinks\" style=\"color: #ff00ff; font-size: 2.2em; margin-top: 60px; margin-bottom: 30px; padding-bottom: 15px; border-bottom: 2px solid #ff00ff; text-shadow: 0 0 15px rgba(255, 0, 255, 0.3);\">7. Creating GLinks Programmatically<\/h2>\n<p style=\"margin-bottom: 20px; font-size: 1.1em; color: #e0e0e0;\">So far we&#8217;ve talked about receiving and processing GLinks. But what about creating them? When a user wants to share a transaction, copy a payment request link, or generate a QR code for their wallet address, your dApp needs to create GLinks on the fly.<\/p>\n<p style=\"margin-bottom: 20px; font-size: 1.1em; color: #e0e0e0;\">The <code style=\"color: #ffff00;\">CGLink<\/code> class makes this trivial. The <code style=\"color: #ffff00;\">create()<\/code> method handles all the JSON construction and URL-safe Base64 encoding automatically\u2014you just provide the semantic data.<\/p>\n<h3 style=\"color: #00ffff; font-size: 1.6em; margin-top: 40px; margin-bottom: 20px;\">Basic Creation<\/h3>\n<p style=\"margin-bottom: 20px; font-size: 1.05em; color: #c0c0c0;\">The method signature is <code style=\"color: #ffff00;\">CGLink.create(appPackageID, view?, action?, data?)<\/code>. Only the first parameter is required; everything else is optional:<\/p>\n<p><code style=\"display: block; background: #0a0e27; padding: 25px; border-radius: 8px; overflow-x: auto; margin: 20px 0; color: #e0e0e0; font-size: 1em; line-height: 1.6; white-space: pre;\"><span style=\"color: #c678dd;\">import<\/span> { CGLink } <span style=\"color: #c678dd;\">from<\/span> <span style=\"color: #98c379;\">'\/lib\/GLink.js'<\/span>;<br \/>\n<span style=\"color: #5c6370;\">\/\/ Simplest GLink - just launch the app (no specific action)<\/span><br \/>\n<span style=\"color: #c678dd;\">const<\/span> simpleLink = CGLink.<span style=\"color: #61afef;\">create<\/span>(<span style=\"color: #98c379;\">'org.myapp.MyDApp'<\/span>);<br \/>\n<span style=\"color: #5c6370;\">\/\/ With view - open app to a specific tab<\/span><br \/>\n<span style=\"color: #c678dd;\">const<\/span> viewLink = CGLink.<span style=\"color: #61afef;\">create<\/span>(<span style=\"color: #98c379;\">'org.myapp.MyDApp'<\/span>, <span style=\"color: #98c379;\">'settings'<\/span>);<br \/>\n<span style=\"color: #5c6370;\">\/\/ With view and action - open tab and do something<\/span><br \/>\n<span style=\"color: #c678dd;\">const<\/span> actionLink = CGLink.<span style=\"color: #61afef;\">create<\/span>(<span style=\"color: #98c379;\">'org.myapp.MyDApp'<\/span>, <span style=\"color: #98c379;\">'items'<\/span>, <span style=\"color: #d19a66;\">1<\/span>);<br \/>\n<span style=\"color: #5c6370;\">\/\/ Complete GLink with data - the most common case<\/span><br \/>\n<span style=\"color: #c678dd;\">const<\/span> fullLink = CGLink.<span style=\"color: #61afef;\">create<\/span>(<br \/>\n    <span style=\"color: #98c379;\">'org.myapp.MyDApp'<\/span>,<br \/>\n    <span style=\"color: #98c379;\">'items'<\/span>,<br \/>\n    <span style=\"color: #d19a66;\">1<\/span>,<br \/>\n    { itemId: <span style=\"color: #98c379;\">'abc123'<\/span>, highlight: <span style=\"color: #c678dd;\">true<\/span> }<br \/>\n);<\/code><\/p>\n<h3 style=\"color: #00ffff; font-size: 1.6em; margin-top: 40px; margin-bottom: 20px;\">Adding a &#8220;Copy GLink&#8221; Button<\/h3>\n<p style=\"margin-bottom: 20px; font-size: 1.05em; color: #c0c0c0;\">A common UX pattern is to let users copy a GLink to their clipboard so they can share it. The <code style=\"color: #ffff00;\">CGLink.copyToClipboard()<\/code> method handles both modern and legacy browser APIs:<\/p>\n<p><code style=\"display: block; background: #0a0e27; padding: 25px; border-radius: 8px; overflow-x: auto; margin: 20px 0; color: #e0e0e0; font-size: 1em; line-height: 1.6; white-space: pre;\"><span style=\"color: #5c6370;\">\/\/ Add a \"Share\" button to your UI<\/span><br \/>\ncopyGLinkBtn.<span style=\"color: #61afef;\">addEventListener<\/span>(<span style=\"color: #98c379;\">'click'<\/span>, <span style=\"color: #c678dd;\">async<\/span> () => {<br \/>\n    <span style=\"color: #5c6370;\">\/\/ Generate a GLink for the current state<\/span><br \/>\n    <span style=\"color: #c678dd;\">const<\/span> glink = CGLink.<span style=\"color: #61afef;\">create<\/span>(<br \/>\n        MyDApp.<span style=\"color: #61afef;\">getPackageID<\/span>(),<br \/>\n        <span style=\"color: #c678dd;\">this<\/span>.currentView,<br \/>\n        MyDApp.GLinkActions.VIEW_CURRENT,<br \/>\n        { itemId: <span style=\"color: #c678dd;\">this<\/span>.currentItemId }<br \/>\n    );<br \/>\n    <span style=\"color: #5c6370;\">\/\/ Copy to clipboard with fallback for older browsers<\/span><br \/>\n    <span style=\"color: #c678dd;\">const<\/span> success = <span style=\"color: #c678dd;\">await<\/span> CGLink.<span style=\"color: #61afef;\">copyToClipboard<\/span>(glink);<br \/>\n    <span style=\"color: #c678dd;\">if<\/span> (success) {<br \/>\n        <span style=\"color: #c678dd;\">this<\/span>.<span style=\"color: #61afef;\">showNotification<\/span>(<span style=\"color: #98c379;\">'GLink copied! Share it anywhere.'<\/span>);<br \/>\n    }<br \/>\n});<\/code><\/p>\n<p><!-- Section 8: API Reference --><\/p>\n<h2 id=\"api-reference\" style=\"color: #ff00ff; font-size: 2.2em; margin-top: 60px; margin-bottom: 30px; padding-bottom: 15px; border-bottom: 2px solid #ff00ff; text-shadow: 0 0 15px rgba(255, 0, 255, 0.3);\">8. API Reference<\/h2>\n<p style=\"margin-bottom: 20px; font-size: 1.1em; color: #e0e0e0;\">This section provides a complete reference for all GLink-related APIs. Use this as your go-to documentation when implementing GLink support.<\/p>\n<h3 style=\"color: #00ffff; font-size: 1.6em; margin-top: 40px; margin-bottom: 20px;\">CGLink Class<\/h3>\n<p style=\"margin-bottom: 20px; font-size: 1.05em; color: #c0c0c0;\">The <code style=\"color: #ffff00;\">CGLink<\/code> class is a static utility for creating and parsing GLinks. You never instantiate it\u2014just call its static methods directly.<\/p>\n<div style=\"background: #0a0e27; padding: 30px; border-radius: 8px; margin: 30px 0; border: 1px solid #2a2e4f;\">\n<table style=\"width: 100%; border-collapse: collapse; color: #e0e0e0;\">\n<tr style=\"border-bottom: 2px solid #2a2e4f;\">\n<th style=\"text-align: left; padding: 15px; color: #00ffff;\">Method<\/th>\n<th style=\"text-align: left; padding: 15px; color: #00ffff;\">Parameters<\/th>\n<th style=\"text-align: left; padding: 15px; color: #00ffff;\">Returns<\/th>\n<th style=\"text-align: left; padding: 15px; color: #00ffff;\">Description<\/th>\n<\/tr>\n<tr style=\"border-bottom: 1px solid #2a2e4f;\">\n<td style=\"padding: 15px;\"><code style=\"color: #61afef;\">create()<\/code><\/td>\n<td style=\"padding: 15px; font-size: 0.9em;\"><code>app, view?, action?, data?<\/code><\/td>\n<td style=\"padding: 15px;\"><code style=\"color: #98c379;\">string<\/code><\/td>\n<td style=\"padding: 15px;\">Create a GLink URL<\/td>\n<\/tr>\n<tr style=\"border-bottom: 1px solid #2a2e4f;\">\n<td style=\"padding: 15px;\"><code style=\"color: #61afef;\">parse()<\/code><\/td>\n<td style=\"padding: 15px; font-size: 0.9em;\"><code>input<\/code><\/td>\n<td style=\"padding: 15px;\"><code style=\"color: #98c379;\">Object|null<\/code><\/td>\n<td style=\"padding: 15px;\">Parse GLink from URL or string<\/td>\n<\/tr>\n<tr style=\"border-bottom: 1px solid #2a2e4f;\">\n<td style=\"padding: 15px;\"><code style=\"color: #61afef;\">hasGLink()<\/code><\/td>\n<td style=\"padding: 15px; font-size: 0.9em;\"><code>none<\/code><\/td>\n<td style=\"padding: 15px;\"><code style=\"color: #98c379;\">boolean<\/code><\/td>\n<td style=\"padding: 15px;\">Check if current URL has GLink<\/td>\n<\/tr>\n<tr style=\"border-bottom: 1px solid #2a2e4f;\">\n<td style=\"padding: 15px;\"><code style=\"color: #61afef;\">getFromCurrentURL()<\/code><\/td>\n<td style=\"padding: 15px; font-size: 0.9em;\"><code>none<\/code><\/td>\n<td style=\"padding: 15px;\"><code style=\"color: #98c379;\">Object|null<\/code><\/td>\n<td style=\"padding: 15px;\">Get parsed GLink from current URL<\/td>\n<\/tr>\n<tr style=\"border-bottom: 1px solid #2a2e4f;\">\n<td style=\"padding: 15px;\"><code style=\"color: #61afef;\">clearFromURL()<\/code><\/td>\n<td style=\"padding: 15px; font-size: 0.9em;\"><code>none<\/code><\/td>\n<td style=\"padding: 15px;\"><code style=\"color: #98c379;\">void<\/code><\/td>\n<td style=\"padding: 15px;\">Remove GLink from browser URL<\/td>\n<\/tr>\n<tr>\n<td style=\"padding: 15px;\"><code style=\"color: #61afef;\">copyToClipboard()<\/code><\/td>\n<td style=\"padding: 15px; font-size: 0.9em;\"><code>glinkURL<\/code><\/td>\n<td style=\"padding: 15px;\"><code style=\"color: #98c379;\">Promise&lt;boolean&gt;<\/code><\/td>\n<td style=\"padding: 15px;\">Copy GLink to clipboard<\/td>\n<\/tr>\n<\/table>\n<\/div>\n<h3 style=\"color: #00ffff; font-size: 1.6em; margin-top: 40px; margin-bottom: 20px;\">CGLinkHandler Class<\/h3>\n<p style=\"margin-bottom: 20px; font-size: 1.05em; color: #c0c0c0;\">The <code style=\"color: #ffff00;\">CGLinkHandler<\/code> is a singleton that manages the GLink lifecycle at the system level. Your dApp interacts with it through its instance methods, primarily <code style=\"color: #ffff00;\">acceptGLink()<\/code>, <code style=\"color: #ffff00;\">confirmGLinkProcessed()<\/code>, and <code style=\"color: #ffff00;\">rejectGLink()<\/code>.<\/p>\n<div style=\"background: #0a0e27; padding: 30px; border-radius: 8px; margin: 30px 0; border: 1px solid #2a2e4f;\">\n<table style=\"width: 100%; border-collapse: collapse; color: #e0e0e0;\">\n<tr style=\"border-bottom: 2px solid #2a2e4f;\">\n<th style=\"text-align: left; padding: 15px; color: #00ffff;\">Method<\/th>\n<th style=\"text-align: left; padding: 15px; color: #00ffff;\">Parameters<\/th>\n<th style=\"text-align: left; padding: 15px; color: #00ffff;\">Description<\/th>\n<\/tr>\n<tr style=\"border-bottom: 1px solid #2a2e4f;\">\n<td style=\"padding: 15px;\"><code style=\"color: #61afef;\">getInstance()<\/code><\/td>\n<td style=\"padding: 15px; font-size: 0.9em;\"><code>none<\/code><\/td>\n<td style=\"padding: 15px;\">Get singleton instance (always use this, never <code>new<\/code>)<\/td>\n<\/tr>\n<tr style=\"border-bottom: 1px solid #2a2e4f;\">\n<td style=\"padding: 15px;\"><code style=\"color: #61afef;\">acceptGLink()<\/code><\/td>\n<td style=\"padding: 15px; font-size: 0.9em;\"><code>message?<\/code><\/td>\n<td style=\"padding: 15px;\">Acknowledge receipt, extend timeout to 3 minutes<\/td>\n<\/tr>\n<tr style=\"border-bottom: 1px solid #2a2e4f;\">\n<td style=\"padding: 15px;\"><code style=\"color: #61afef;\">confirmGLinkProcessed()<\/code><\/td>\n<td style=\"padding: 15px; font-size: 0.9em;\"><code>message?<\/code><\/td>\n<td style=\"padding: 15px;\">Signal successful completion<\/td>\n<\/tr>\n<tr style=\"border-bottom: 1px solid #2a2e4f;\">\n<td style=\"padding: 15px;\"><code style=\"color: #61afef;\">rejectGLink()<\/code><\/td>\n<td style=\"padding: 15px; font-size: 0.9em;\"><code>reason?<\/code><\/td>\n<td style=\"padding: 15px;\">Signal failure or rejection<\/td>\n<\/tr>\n<tr style=\"border-bottom: 1px solid #2a2e4f;\">\n<td style=\"padding: 15px;\"><code style=\"color: #61afef;\">hasPendingGLink()<\/code><\/td>\n<td style=\"padding: 15px; font-size: 0.9em;\"><code>none<\/code><\/td>\n<td style=\"padding: 15px;\">Check if there&#8217;s a pending GLink<\/td>\n<\/tr>\n<tr>\n<td style=\"padding: 15px;\"><code style=\"color: #61afef;\">getPendingGLink()<\/code><\/td>\n<td style=\"padding: 15px; font-size: 0.9em;\"><code>none<\/code><\/td>\n<td style=\"padding: 15px;\">Get pending GLink data<\/td>\n<\/tr>\n<\/table>\n<\/div>\n<h3 style=\"color: #00ffff; font-size: 1.6em; margin-top: 40px; margin-bottom: 20px;\">CWindow Properties (Inherited)<\/h3>\n<p style=\"margin-bottom: 20px; font-size: 1.05em; color: #c0c0c0;\">All UI dApps extend <code style=\"color: #ffff00;\">CWindow<\/code>, which provides these GLink-related properties. You don&#8217;t need to do anything to get them\u2014they&#8217;re automatically populated when your app is launched via GLink.<\/p>\n<div style=\"background: #0a0e27; padding: 30px; border-radius: 8px; margin: 30px 0; border: 1px solid #2a2e4f;\">\n<table style=\"width: 100%; border-collapse: collapse; color: #e0e0e0;\">\n<tr style=\"border-bottom: 2px solid #2a2e4f;\">\n<th style=\"text-align: left; padding: 15px; color: #00ffff;\">Property<\/th>\n<th style=\"text-align: left; padding: 15px; color: #00ffff;\">Type<\/th>\n<th style=\"text-align: left; padding: 15px; color: #00ffff;\">Description<\/th>\n<\/tr>\n<tr style=\"border-bottom: 1px solid #2a2e4f;\">\n<td style=\"padding: 15px;\"><code style=\"color: #61afef;\">wasLaunchedViaGLink<\/code><\/td>\n<td style=\"padding: 15px;\"><code style=\"color: #98c379;\">boolean<\/code><\/td>\n<td style=\"padding: 15px;\">True if this window was launched via a GLink (check this first!)<\/td>\n<\/tr>\n<tr>\n<td style=\"padding: 15px;\"><code style=\"color: #61afef;\">getGLinkData<\/code><\/td>\n<td style=\"padding: 15px;\"><code style=\"color: #98c379;\">Object<\/code><\/td>\n<td style=\"padding: 15px;\">Returns {view, action, data} from the GLink (only valid if wasLaunchedViaGLink is true)<\/td>\n<\/tr>\n<\/table>\n<\/div>\n<p><!-- Section 9: Best Practices --><\/p>\n<h2 id=\"best-practices\" style=\"color: #ff00ff; font-size: 2.2em; margin-top: 60px; margin-bottom: 30px; padding-bottom: 15px; border-bottom: 2px solid #ff00ff; text-shadow: 0 0 15px rgba(255, 0, 255, 0.3);\">9. Best Practices<\/h2>\n<p style=\"margin-bottom: 20px; font-size: 1.1em; color: #e0e0e0;\">Over time, we&#8217;ve learned what works and what doesn&#8217;t when implementing GLink support. Here are the patterns that consistently lead to a great user experience:<\/p>\n<div style=\"display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 25px; margin: 30px 0;\">\n<div style=\"background: #1a1e3f; border-radius: 8px; padding: 25px; border-left: 4px solid #00ff00;\">\n<h4 style=\"color: #00ff00; margin-top: 0; margin-bottom: 15px;\">Accept Early<\/h4>\n<p style=\"color: #e0e0e0; font-size: 0.95em; margin: 0;\">Call <code style=\"color: #ffff00;\">acceptGLink()<\/code> as soon as possible after detecting a GLink. This extends the timeout and provides immediate feedback to the user.<\/p>\n<\/p><\/div>\n<div style=\"background: #1a1e3f; border-radius: 8px; padding: 25px; border-left: 4px solid #00ffff;\">\n<h4 style=\"color: #00ffff; margin-top: 0; margin-bottom: 15px;\">Handle Delays Gracefully<\/h4>\n<p style=\"color: #e0e0e0; font-size: 0.95em; margin: 0;\">If your dApp needs time to initialize (like Wallet&#8217;s PIN unlock), store the GLink data and process it later. Don&#8217;t block or timeout.<\/p>\n<\/p><\/div>\n<div style=\"background: #1a1e3f; border-radius: 8px; padding: 25px; border-left: 4px solid #ff00ff;\">\n<h4 style=\"color: #ff00ff; margin-top: 0; margin-bottom: 15px;\">Always Confirm or Reject<\/h4>\n<p style=\"color: #e0e0e0; font-size: 0.95em; margin: 0;\">Every GLink must end with either <code style=\"color: #ffff00;\">confirmGLinkProcessed()<\/code> or <code style=\"color: #ffff00;\">rejectGLink()<\/code>. Never leave a GLink hanging.<\/p>\n<\/p><\/div>\n<div style=\"background: #1a1e3f; border-radius: 8px; padding: 25px; border-left: 4px solid #ffff00;\">\n<h4 style=\"color: #ffff00; margin-top: 0; margin-bottom: 15px;\">Validate Data<\/h4>\n<p style=\"color: #e0e0e0; font-size: 0.95em; margin: 0;\">Always validate the GLink data before processing. Check for required fields and reasonable values. Reject with clear error messages.<\/p>\n<\/p><\/div>\n<div style=\"background: #1a1e3f; border-radius: 8px; padding: 25px; border-left: 4px solid #00ff00;\">\n<h4 style=\"color: #00ff00; margin-top: 0; margin-bottom: 15px;\">Document Your Actions<\/h4>\n<p style=\"color: #e0e0e0; font-size: 0.95em; margin: 0;\">Clearly document your dApp&#8217;s action IDs, supported views, and expected data fields. Other developers may want to create GLinks to your app.<\/p>\n<\/p><\/div>\n<div style=\"background: #1a1e3f; border-radius: 8px; padding: 25px; border-left: 4px solid #00ffff;\">\n<h4 style=\"color: #00ffff; margin-top: 0; margin-bottom: 15px;\">Use Meaningful Messages<\/h4>\n<p style=\"color: #e0e0e0; font-size: 0.95em; margin: 0;\">Provide descriptive messages in your <code style=\"color: #ffff00;\">acceptGLink()<\/code>, <code style=\"color: #ffff00;\">confirmGLinkProcessed()<\/code>, and <code style=\"color: #ffff00;\">rejectGLink()<\/code> calls. Users see these in the progress indicator.<\/p>\n<\/p><\/div>\n<\/div>\n<p><!-- Section 10: Encoding Flow --><\/p>\n<h2 id=\"encoding-flow\" style=\"color: #ff00ff; font-size: 2.2em; margin-top: 60px; margin-bottom: 30px; padding-bottom: 15px; border-bottom: 2px solid #ff00ff; text-shadow: 0 0 15px rgba(255, 0, 255, 0.3);\">10. The Encoding\/Decoding Flow<\/h2>\n<p style=\"margin-bottom: 20px; font-size: 1.1em; color: #e0e0e0;\">You&#8217;ll rarely need to manually encode or decode GLinks\u2014the CGLink class handles it for you. But when debugging a misbehaving GLink or when you want to construct one by hand for testing, understanding the encoding process is invaluable.<\/p>\n<p style=\"margin-bottom: 20px; font-size: 1.1em; color: #e0e0e0;\">GLinks use <strong style=\"color: #00ffff;\">URL-safe Base64<\/strong>, which is slightly different from standard Base64. The reason is simple: standard Base64 includes <code style=\"color: #ff6666;\">+<\/code>, <code style=\"color: #ff6666;\">\/<\/code>, and <code style=\"color: #ff6666;\">=<\/code> characters, which have special meaning in URLs. URL-safe Base64 replaces these with URL-friendly alternatives.<\/p>\n<p><!-- Encoding Flow Diagram --><\/p>\n<div style=\"background: linear-gradient(135deg, #0a0e27 0%, #1a1e3f 100%); padding: 40px 30px; border-radius: 12px; margin: 30px 0; border: 1px solid #2a2e4f; box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);\">\n<div style=\"text-align: center; margin-bottom: 30px;\">\n        <span style=\"color: #00ffff; font-weight: 700; font-size: 1.2em; letter-spacing: 1px;\">GLINK ENCODING PIPELINE<\/span>\n    <\/div>\n<p>    <!-- Encoding Flow --><\/p>\n<div style=\"display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 15px; margin-bottom: 40px;\">\n<p>        <!-- Step 1: JSON Object --><\/p>\n<div style=\"background: #1a1e3f; border: 2px solid #00ff00; border-radius: 8px; padding: 15px 20px; min-width: 180px; text-align: center;\">\n<div style=\"color: #00ff00; font-weight: 600; font-size: 0.85em; margin-bottom: 8px;\">1. JSON Object<\/div>\n<p>            <code style=\"color: #98c379; font-size: 0.8em; display: block; word-break: break-all;\">{\"app\":\"wallet\",\"view\":\"send\"}<\/code>\n        <\/div>\n<div style=\"color: #ff00ff; font-size: 1.5em;\">\u2192<\/div>\n<p>        <!-- Step 2: UTF-8 Bytes --><\/p>\n<div style=\"background: #1a1e3f; border: 2px solid #ffff00; border-radius: 8px; padding: 15px 20px; min-width: 180px; text-align: center;\">\n<div style=\"color: #ffff00; font-weight: 600; font-size: 0.85em; margin-bottom: 8px;\">2. UTF-8 Bytes<\/div>\n<p>            <code style=\"color: #ffff88; font-size: 0.8em;\">TextEncoder.encode()<\/code>\n        <\/div>\n<div style=\"color: #ff00ff; font-size: 1.5em;\">\u2192<\/div>\n<p>        <!-- Step 3: Base64 --><\/p>\n<div style=\"background: #1a1e3f; border: 2px solid #ff00ff; border-radius: 8px; padding: 15px 20px; min-width: 180px; text-align: center;\">\n<div style=\"color: #ff00ff; font-weight: 600; font-size: 0.85em; margin-bottom: 8px;\">3. Base64 Encode<\/div>\n<p>            <code style=\"color: #ff88ff; font-size: 0.8em;\">btoa(binary)<\/code>\n        <\/div>\n<div style=\"color: #ff00ff; font-size: 1.5em;\">\u2192<\/div>\n<p>        <!-- Step 4: URL-Safe --><\/p>\n<div style=\"background: #1a1e3f; border: 2px solid #00ffff; border-radius: 8px; padding: 15px 20px; min-width: 180px; text-align: center;\">\n<div style=\"color: #00ffff; font-weight: 600; font-size: 0.85em; margin-bottom: 8px;\">4. URL-Safe<\/div>\n<p>            <code style=\"color: #88ffff; font-size: 0.75em;\">+ \u2192 -  \/ \u2192 _  = removed<\/code>\n        <\/div>\n<\/p><\/div>\n<p>    <!-- URL-Safe Base64 Details --><\/p>\n<div style=\"background: #0a0e27; border-radius: 8px; padding: 20px; margin-top: 20px;\">\n<div style=\"color: #ff00ff; font-weight: 600; margin-bottom: 15px;\">URL-Safe Base64 Transformations:<\/div>\n<div style=\"display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 15px;\">\n<div style=\"background: #1a1e3f; padding: 12px; border-radius: 6px; text-align: center;\">\n                <span style=\"color: #ff6666; font-size: 1.2em;\">+<\/span><br \/>\n                <span style=\"color: #a0a0a0; margin: 0 10px;\">\u2192<\/span><br \/>\n                <span style=\"color: #00ff00; font-size: 1.2em;\">&#8211;<\/span><\/p>\n<div style=\"color: #606080; font-size: 0.8em; margin-top: 5px;\">Plus becomes hyphen<\/div>\n<\/p><\/div>\n<div style=\"background: #1a1e3f; padding: 12px; border-radius: 6px; text-align: center;\">\n                <span style=\"color: #ff6666; font-size: 1.2em;\">\/<\/span><br \/>\n                <span style=\"color: #a0a0a0; margin: 0 10px;\">\u2192<\/span><br \/>\n                <span style=\"color: #00ff00; font-size: 1.2em;\">_<\/span><\/p>\n<div style=\"color: #606080; font-size: 0.8em; margin-top: 5px;\">Slash becomes underscore<\/div>\n<\/p><\/div>\n<div style=\"background: #1a1e3f; padding: 12px; border-radius: 6px; text-align: center;\">\n                <span style=\"color: #ff6666; font-size: 1.2em;\">=<\/span><br \/>\n                <span style=\"color: #a0a0a0; margin: 0 10px;\">\u2192<\/span><br \/>\n                <span style=\"color: #00ff00; font-size: 1.2em;\">(removed)<\/span><\/p>\n<div style=\"color: #606080; font-size: 0.8em; margin-top: 5px;\">Padding stripped<\/div>\n<\/p><\/div>\n<\/p><\/div>\n<\/p><\/div>\n<\/div>\n<h3 style=\"color: #00ffff; font-size: 1.6em; margin-top: 40px; margin-bottom: 20px;\">Manual Testing with Browser Console<\/h3>\n<p><code style=\"display: block; background: #0a0e27; padding: 25px; border-radius: 8px; overflow-x: auto; margin: 20px 0; color: #e0e0e0; font-size: 1em; line-height: 1.6; white-space: pre;\"><span style=\"color: #5c6370;\">\/\/ Encode a GLink manually (for testing)<\/span><br \/>\n<span style=\"color: #c678dd;\">const<\/span> data = { app: <span style=\"color: #98c379;\">'org.gridnetproject.UIdApps.wallet'<\/span>, view: <span style=\"color: #98c379;\">'send'<\/span> };<br \/>\n<span style=\"color: #c678dd;\">const<\/span> json = JSON.<span style=\"color: #61afef;\">stringify<\/span>(data);<br \/>\n<span style=\"color: #c678dd;\">const<\/span> utf8 = <span style=\"color: #c678dd;\">new<\/span> TextEncoder().<span style=\"color: #61afef;\">encode<\/span>(json);<br \/>\n<span style=\"color: #c678dd;\">let<\/span> binary = <span style=\"color: #98c379;\">''<\/span>;<br \/>\nutf8.<span style=\"color: #61afef;\">forEach<\/span>(b => binary += String.<span style=\"color: #61afef;\">fromCharCode<\/span>(b));<br \/>\n<span style=\"color: #c678dd;\">const<\/span> base64 = <span style=\"color: #61afef;\">btoa<\/span>(binary).<span style=\"color: #61afef;\">replace<\/span>(<span style=\"color: #98c379;\">\/\\+\/g<\/span>, <span style=\"color: #98c379;\">'-'<\/span>).<span style=\"color: #61afef;\">replace<\/span>(<span style=\"color: #98c379;\">\/\\\/\/g<\/span>, <span style=\"color: #98c379;\">'_'<\/span>).<span style=\"color: #61afef;\">replace<\/span>(<span style=\"color: #98c379;\">\/=\/g<\/span>, <span style=\"color: #98c379;\">''<\/span>);<br \/>\n<span style=\"color: #e5c07b;\">console<\/span>.<span style=\"color: #61afef;\">log<\/span>(<span style=\"color: #98c379;\">`https:\/\/ui.gridnet.org\/?glink=<\/span><span style=\"color: #c678dd;\">${<\/span>base64<span style=\"color: #c678dd;\">}<\/span><span style=\"color: #98c379;\">`<\/span>);<br \/>\n<span style=\"color: #5c6370;\">\/\/ Decode a GLink manually (for debugging)<\/span><br \/>\n<span style=\"color: #c678dd;\">const<\/span> encoded = <span style=\"color: #98c379;\">'eyJhcHAiOiJ3YWxsZXQifQ'<\/span>;<br \/>\n<span style=\"color: #c678dd;\">let<\/span> restored = encoded.<span style=\"color: #61afef;\">replace<\/span>(<span style=\"color: #98c379;\">\/-\/g<\/span>, <span style=\"color: #98c379;\">'+'<\/span>).<span style=\"color: #61afef;\">replace<\/span>(<span style=\"color: #98c379;\">\/_\/g<\/span>, <span style=\"color: #98c379;\">'\/'<\/span>);<br \/>\n<span style=\"color: #c678dd;\">while<\/span> (restored.length % <span style=\"color: #d19a66;\">4<\/span>) restored += <span style=\"color: #98c379;\">'='<\/span>;<br \/>\n<span style=\"color: #c678dd;\">const<\/span> decoded = <span style=\"color: #61afef;\">atob<\/span>(restored);<br \/>\n<span style=\"color: #c678dd;\">const<\/span> bytes = <span style=\"color: #c678dd;\">new<\/span> Uint8Array(decoded.length);<br \/>\n<span style=\"color: #c678dd;\">for<\/span> (<span style=\"color: #c678dd;\">let<\/span> i = <span style=\"color: #d19a66;\">0<\/span>; i < decoded.length; i++) bytes[i] = decoded.<span style=\"color: #61afef;\">charCodeAt<\/span>(i);<br \/>\n<span style=\"color: #e5c07b;\">console<\/span>.<span style=\"color: #61afef;\">log<\/span>(JSON.<span style=\"color: #61afef;\">parse<\/span>(<span style=\"color: #c678dd;\">new<\/span> TextDecoder().<span style=\"color: #61afef;\">decode<\/span>(bytes)));<\/code><\/p>\n<p><!-- Section 11: Sequence Diagram --><\/p>\n<h2 id=\"sequence\" style=\"color: #ff00ff; font-size: 2.2em; margin-top: 60px; margin-bottom: 30px; padding-bottom: 15px; border-bottom: 2px solid #ff00ff; text-shadow: 0 0 15px rgba(255, 0, 255, 0.3);\">11. Communication Sequence Diagram<\/h2>\n<p style=\"margin-bottom: 20px; font-size: 1.1em; color: #e0e0e0;\">This diagram shows the exact sequence of calls between the CGLinkHandler and your UI dApp:<\/p>\n<p><!-- Sequence Diagram - Simplified Table Layout --><\/p>\n<div style=\"background: linear-gradient(135deg, #0a0e27 0%, #1a1e3f 100%); padding: 30px 20px; border-radius: 12px; margin: 30px 0; border: 1px solid #2a2e4f; overflow-x: auto;\">\n<div style=\"text-align: center; margin-bottom: 20px;\">\n        <span style=\"color: #ff00ff; font-weight: 700; font-size: 1.1em; letter-spacing: 1px;\">HANDLER \u2194 DAPP COMMUNICATION<\/span>\n    <\/div>\n<table style=\"width: 100%; min-width: 500px; border-collapse: collapse;\">\n        <!-- Header Row: Participants --><\/p>\n<tr>\n<td style=\"width: 25%; text-align: center; padding: 10px; vertical-align: bottom;\">\n<div style=\"background: #00ffff; color: #0a0e27; padding: 8px 15px; border-radius: 6px; font-weight: 600; font-size: 0.9em; display: inline-block;\">Browser<\/div>\n<\/td>\n<td style=\"width: 25%; text-align: center; padding: 10px; vertical-align: bottom;\">\n<div style=\"background: #ff00ff; color: #ffffff; padding: 8px 15px; border-radius: 6px; font-weight: 600; font-size: 0.9em; display: inline-block;\">CGLinkHandler<\/div>\n<\/td>\n<td style=\"width: 25%; text-align: center; padding: 10px; vertical-align: bottom;\">\n<div style=\"background: #00ff00; color: #0a0e27; padding: 8px 15px; border-radius: 6px; font-weight: 600; font-size: 0.9em; display: inline-block;\">UI dApp<\/div>\n<\/td>\n<\/tr>\n<p>        <!-- Vertical Lines Row --><\/p>\n<tr>\n<td style=\"text-align: center; padding: 0;\">\n<div style=\"width: 2px; height: 15px; background: rgba(0,255,255,0.4); margin: 0 auto;\"><\/div>\n<\/td>\n<td style=\"text-align: center; padding: 0;\">\n<div style=\"width: 2px; height: 15px; background: rgba(255,0,255,0.4); margin: 0 auto;\"><\/div>\n<\/td>\n<td style=\"text-align: center; padding: 0;\">\n<div style=\"width: 2px; height: 15px; background: rgba(0,255,0,0.4); margin: 0 auto;\"><\/div>\n<\/td>\n<\/tr>\n<p>        <!-- Step 1: Browser loads URL --><\/p>\n<tr>\n<td style=\"text-align: center; padding: 8px;\">\n<div style=\"background: #1a1e3f; border: 1px solid #00ffff; border-radius: 4px; padding: 6px 10px; display: inline-block;\">\n                    <span style=\"color: #00ffff; font-size: 0.8em;\">1. URL with ?glink=<\/span>\n                <\/div>\n<\/td>\n<td style=\"text-align: center; padding: 8px;\">\n<div style=\"width: 2px; height: 100%; min-height: 30px; background: rgba(255,0,255,0.3); margin: 0 auto;\"><\/div>\n<\/td>\n<td style=\"text-align: center; padding: 8px;\">\n<div style=\"width: 2px; height: 100%; min-height: 30px; background: rgba(0,255,0,0.3); margin: 0 auto;\"><\/div>\n<\/td>\n<\/tr>\n<p>        <!-- Step 2: Handler parses --><\/p>\n<tr>\n<td style=\"text-align: center; padding: 8px;\">\n<div style=\"width: 2px; height: 100%; min-height: 30px; background: rgba(0,255,255,0.3); margin: 0 auto;\"><\/div>\n<\/td>\n<td style=\"text-align: center; padding: 8px;\">\n<div style=\"background: #1a1e3f; border: 1px solid #ff00ff; border-radius: 4px; padding: 6px 10px; display: inline-block;\">\n                    <span style=\"color: #ff00ff; font-size: 0.8em;\">2. initialize() \u2192 parse<\/span>\n                <\/div>\n<\/td>\n<td style=\"text-align: center; padding: 8px;\">\n<div style=\"width: 2px; height: 100%; min-height: 30px; background: rgba(0,255,0,0.3); margin: 0 auto;\"><\/div>\n<\/td>\n<\/tr>\n<p>        <!-- Step 3: Show indicator --><\/p>\n<tr>\n<td style=\"text-align: center; padding: 8px;\">\n<div style=\"width: 2px; height: 100%; min-height: 30px; background: rgba(0,255,255,0.3); margin: 0 auto;\"><\/div>\n<\/td>\n<td style=\"text-align: center; padding: 8px;\">\n<div style=\"background: #1a1e3f; border: 1px solid #ff00ff; border-radius: 4px; padding: 6px 10px; display: inline-block;\">\n                    <span style=\"color: #ff00ff; font-size: 0.8em;\">3. showIndicator()<\/span>\n                <\/div>\n<\/td>\n<td style=\"text-align: center; padding: 8px;\">\n<div style=\"width: 2px; height: 100%; min-height: 30px; background: rgba(0,255,0,0.3); margin: 0 auto;\"><\/div>\n<\/td>\n<\/tr>\n<p>        <!-- Step 4: Arrow Handler \u2192 dApp --><\/p>\n<tr>\n<td style=\"text-align: center; padding: 4px;\">\n<div style=\"width: 2px; height: 25px; background: rgba(0,255,255,0.3); margin: 0 auto;\"><\/div>\n<\/td>\n<td colspan=\"2\" style=\"padding: 4px 15px;\">\n<div style=\"display: flex; align-items: center;\">\n<div style=\"flex: 1; height: 2px; background: linear-gradient(90deg, #ff00ff, #00ff00);\"><\/div>\n<p>                    <span style=\"color: #00ff00; margin-left: 4px;\">\u25b6<\/span>\n                <\/div>\n<div style=\"text-align: center; color: #a0a0a0; font-size: 0.75em; margin-top: 2px;\">4. launchApp(data, &#8216;glink&#8217;)<\/div>\n<\/td>\n<\/tr>\n<p>        <!-- Step 5: Arrow dApp \u2192 Handler --><\/p>\n<tr>\n<td style=\"text-align: center; padding: 4px;\">\n<div style=\"width: 2px; height: 25px; background: rgba(0,255,255,0.3); margin: 0 auto;\"><\/div>\n<\/td>\n<td colspan=\"2\" style=\"padding: 4px 15px;\">\n<div style=\"display: flex; align-items: center;\">\n                    <span style=\"color: #ff00ff; margin-right: 4px;\">\u25c0<\/span><\/p>\n<div style=\"flex: 1; height: 2px; background: linear-gradient(90deg, #ff00ff, #00ff00);\"><\/div>\n<\/p><\/div>\n<div style=\"text-align: center; color: #a0a0a0; font-size: 0.75em; margin-top: 2px;\">5. acceptGLink(&#8216;Processing&#8230;&#8217;)<\/div>\n<\/td>\n<\/tr>\n<p>        <!-- Step 6: dApp processes --><\/p>\n<tr>\n<td style=\"text-align: center; padding: 8px;\">\n<div style=\"width: 2px; height: 100%; min-height: 30px; background: rgba(0,255,255,0.3); margin: 0 auto;\"><\/div>\n<\/td>\n<td style=\"text-align: center; padding: 8px;\">\n<div style=\"width: 2px; height: 100%; min-height: 30px; background: rgba(255,0,255,0.3); margin: 0 auto;\"><\/div>\n<\/td>\n<td style=\"text-align: center; padding: 8px;\">\n<div style=\"background: #0e2a1e; border: 1px solid #00ff00; border-radius: 4px; padding: 6px 10px; display: inline-block;\">\n                    <span style=\"color: #00ff00; font-size: 0.8em;\">6. processGLink()<\/span>\n                <\/div>\n<\/td>\n<\/tr>\n<p>        <!-- Step 7: Arrow dApp \u2192 Handler (confirm) --><\/p>\n<tr>\n<td style=\"text-align: center; padding: 4px;\">\n<div style=\"width: 2px; height: 25px; background: rgba(0,255,255,0.3); margin: 0 auto;\"><\/div>\n<\/td>\n<td colspan=\"2\" style=\"padding: 4px 15px;\">\n<div style=\"display: flex; align-items: center;\">\n                    <span style=\"color: #ff00ff; margin-right: 4px;\">\u25c0<\/span><\/p>\n<div style=\"flex: 1; height: 2px; background: linear-gradient(90deg, #ff00ff, #00ff00);\"><\/div>\n<\/p><\/div>\n<div style=\"text-align: center; color: #88ff88; font-size: 0.75em; margin-top: 2px;\">7. confirmGLinkProcessed(&#8216;Success!&#8217;)<\/div>\n<\/td>\n<\/tr>\n<p>        <!-- Step 8: Hide indicator --><\/p>\n<tr>\n<td style=\"text-align: center; padding: 8px;\">\n<div style=\"width: 2px; height: 100%; min-height: 30px; background: rgba(0,255,255,0.3); margin: 0 auto;\"><\/div>\n<\/td>\n<td style=\"text-align: center; padding: 8px;\">\n<div style=\"background: #0e2a1e; border: 1px solid #00ff00; border-radius: 4px; padding: 6px 10px; display: inline-block;\">\n                    <span style=\"color: #00ff00; font-size: 0.8em;\">8. hideIndicator() \u2713<\/span>\n                <\/div>\n<\/td>\n<td style=\"text-align: center; padding: 8px;\">\n<div style=\"width: 2px; height: 100%; min-height: 30px; background: rgba(0,255,0,0.3); margin: 0 auto;\"><\/div>\n<\/td>\n<\/tr>\n<\/table>\n<\/div>\n<p><!-- Section 12: Real-World Use Cases --><\/p>\n<h2 id=\"use-cases\" style=\"color: #ff00ff; font-size: 2.2em; margin-top: 60px; margin-bottom: 30px; padding-bottom: 15px; border-bottom: 2px solid #ff00ff; text-shadow: 0 0 15px rgba(255, 0, 255, 0.3);\">12. Real-World Use Cases<\/h2>\n<p style=\"margin-bottom: 20px; font-size: 1.1em; color: #e0e0e0;\">Theory is great, but let&#8217;s see GLinks in action. Here are practical examples showing how GLinks solve real problems and create better user experiences across GRIDNET OS.<\/p>\n<h3 style=\"color: #00ffff; font-size: 1.6em; margin-top: 40px; margin-bottom: 20px;\">Payment Request Links<\/h3>\n<p style=\"margin-bottom: 20px; font-size: 1.1em; color: #e0e0e0;\">Perhaps the most compelling use case: imagine sending someone a link that opens their wallet with everything pre-filled\u2014recipient, amount, even a memo. No manual typing, no copy-paste errors:<\/p>\n<p><code style=\"display: block; background: #0a0e27; padding: 25px; border-radius: 8px; overflow-x: auto; margin: 20px 0; color: #e0e0e0; font-size: 1em; line-height: 1.6; white-space: pre;\"><span style=\"color: #5c6370;\">\/\/ Generate payment request for an invoice<\/span><br \/>\n<span style=\"color: #c678dd;\">function<\/span> <span style=\"color: #61afef;\">generateInvoiceLink<\/span>(recipientDomain, amountGNC, invoiceId) {<br \/>\n    <span style=\"color: #c678dd;\">return<\/span> CGLink.<span style=\"color: #61afef;\">create<\/span>(<br \/>\n        CGLink.PackageIDs.WALLET,<br \/>\n        <span style=\"color: #98c379;\">'send'<\/span>,<br \/>\n        <span style=\"color: #d19a66;\">1<\/span>, <span style=\"color: #5c6370;\">\/\/ PREFILL_SEND action<\/span><br \/>\n        {<br \/>\n            address: recipientDomain,<br \/>\n            amount: amountGNC.toString(),<br \/>\n            memo: <span style=\"color: #98c379;\">`Invoice #<\/span><span style=\"color: #c678dd;\">${<\/span>invoiceId<span style=\"color: #c678dd;\">}<\/span><span style=\"color: #98c379;\">`<\/span><br \/>\n        }<br \/>\n    );<br \/>\n}<br \/>\n<span style=\"color: #5c6370;\">\/\/ Example: Generate link for $50 payment<\/span><br \/>\n<span style=\"color: #c678dd;\">const<\/span> paymentLink = <span style=\"color: #61afef;\">generateInvoiceLink<\/span>(<span style=\"color: #98c379;\">'merchant.grid'<\/span>, <span style=\"color: #d19a66;\">50<\/span>, <span style=\"color: #98c379;\">'INV-2025-001'<\/span>);<br \/>\n<span style=\"color: #5c6370;\">\/\/ Can be embedded in email, QR code, or web page<\/span><\/code><\/p>\n<h3 style=\"color: #00ffff; font-size: 1.6em; margin-top: 40px; margin-bottom: 20px;\">Transaction Verification Links<\/h3>\n<p style=\"margin-bottom: 20px; font-size: 1.1em; color: #e0e0e0;\">Share links to verify transactions on the blockchain explorer:<\/p>\n<p><code style=\"display: block; background: #0a0e27; padding: 25px; border-radius: 8px; overflow-x: auto; margin: 20px 0; color: #e0e0e0; font-size: 1em; line-height: 1.6; white-space: pre;\"><span style=\"color: #5c6370;\">\/\/ After sending a transaction, generate verification link<\/span><br \/>\n<span style=\"color: #c678dd;\">async function<\/span> <span style=\"color: #61afef;\">sendAndGetVerificationLink<\/span>(recipient, amount) {<br \/>\n    <span style=\"color: #5c6370;\">\/\/ Send the transaction<\/span><br \/>\n    <span style=\"color: #c678dd;\">const<\/span> txResult = <span style=\"color: #c678dd;\">await<\/span> <span style=\"color: #c678dd;\">this<\/span>.vmContext.<span style=\"color: #61afef;\">sendTransaction<\/span>(recipient, amount);<br \/>\n    <span style=\"color: #c678dd;\">if<\/span> (txResult.success) {<br \/>\n        <span style=\"color: #5c6370;\">\/\/ Generate explorer link for recipient to verify<\/span><br \/>\n        <span style=\"color: #c678dd;\">const<\/span> verifyLink = CGLink.<span style=\"color: #61afef;\">create<\/span>(<br \/>\n            CGLink.PackageIDs.EXPLORER,<br \/>\n            <span style=\"color: #98c379;\">'transactions'<\/span>,<br \/>\n            <span style=\"color: #d19a66;\">2<\/span>, <span style=\"color: #5c6370;\">\/\/ VIEW_TRANSACTION<\/span><br \/>\n            { txId: txResult.transactionId }<br \/>\n        );<br \/>\n        <span style=\"color: #c678dd;\">return<\/span> {<br \/>\n            txId: txResult.transactionId,<br \/>\n            verificationLink: verifyLink<br \/>\n        };<br \/>\n    }<br \/>\n}<\/code><\/p>\n<h3 style=\"color: #00ffff; font-size: 1.6em; margin-top: 40px; margin-bottom: 20px;\">Domain Profile Links<\/h3>\n<p><code style=\"display: block; background: #0a0e27; padding: 25px; border-radius: 8px; overflow-x: auto; margin: 20px 0; color: #e0e0e0; font-size: 1em; line-height: 1.6; white-space: pre;\"><span style=\"color: #5c6370;\">\/\/ Create shareable profile link for a domain<\/span><br \/>\n<span style=\"color: #c678dd;\">const<\/span> profileLink = CGLink.<span style=\"color: #61afef;\">create<\/span>(<br \/>\n    CGLink.PackageIDs.EXPLORER,<br \/>\n    <span style=\"color: #98c379;\">'search'<\/span>,<br \/>\n    <span style=\"color: #d19a66;\">3<\/span>, <span style=\"color: #5c6370;\">\/\/ VIEW_DOMAIN<\/span><br \/>\n    { domain: <span style=\"color: #98c379;\">'alice.grid'<\/span> }<br \/>\n);<br \/>\n<span style=\"color: #5c6370;\">\/\/ Use in social media bio, email signature, etc.<\/span><br \/>\n<span style=\"color: #5c6370;\">\/\/ \"View my GRIDNET profile: [GLink URL]\"<\/span><\/code><\/p>\n<p><!-- Section 13: Troubleshooting --><\/p>\n<h2 id=\"troubleshooting\" style=\"color: #ff00ff; font-size: 2.2em; margin-top: 60px; margin-bottom: 30px; padding-bottom: 15px; border-bottom: 2px solid #ff00ff; text-shadow: 0 0 15px rgba(255, 0, 255, 0.3);\">13. Troubleshooting Guide<\/h2>\n<p style=\"margin-bottom: 20px; font-size: 1.1em; color: #e0e0e0;\">GLink issues usually fall into a few common categories: timing problems, missing handler calls, or race conditions with UI rendering. Here are the most frequent problems and their solutions, gathered from real debugging sessions:<\/p>\n<div style=\"display: grid; grid-template-columns: 1fr; gap: 20px; margin: 30px 0;\">\n<p>    <!-- Problem 1 --><\/p>\n<div style=\"background: #1a1e3f; border-radius: 8px; padding: 25px; border-left: 4px solid #ff6666;\">\n<h4 style=\"color: #ff6666; margin-top: 0; margin-bottom: 15px;\">Problem: GLink times out with &#8220;App did not respond&#8221;<\/h4>\n<p style=\"color: #e0e0e0; margin-bottom: 15px;\"><strong style=\"color: #ffff00;\">Cause:<\/strong> Your dApp is not calling <code style=\"color: #00ffff;\">acceptGLink()<\/code> or <code style=\"color: #00ffff;\">confirmGLinkProcessed()<\/code>. This is the most common GLink bug.<\/p>\n<p style=\"color: #e0e0e0; margin-bottom: 0;\"><strong style=\"color: #00ff00;\">Solution:<\/strong> Ensure your <code style=\"color: #00ffff;\">initialize()<\/code> method checks <code style=\"color: #00ffff;\">wasLaunchedViaGLink<\/code> and calls <code style=\"color: #00ffff;\">acceptGLink()<\/code> immediately. Then call <code style=\"color: #00ffff;\">confirmGLinkProcessed()<\/code> or <code style=\"color: #00ffff;\">rejectGLink()<\/code> when done.<\/p>\n<\/p><\/div>\n<p>    <!-- Problem 2 --><\/p>\n<div style=\"background: #1a1e3f; border-radius: 8px; padding: 25px; border-left: 4px solid #ff6666;\">\n<h4 style=\"color: #ff6666; margin-top: 0; margin-bottom: 15px;\">Problem: GLink data is undefined in processGLink()<\/h4>\n<p style=\"color: #e0e0e0; margin-bottom: 15px;\"><strong style=\"color: #ffff00;\">Cause:<\/strong> Accessing <code style=\"color: #00ffff;\">getGLinkData<\/code> too early or the GLink was malformed.<\/p>\n<p style=\"color: #e0e0e0; margin-bottom: 0;\"><strong style=\"color: #00ff00;\">Solution:<\/strong> Access <code style=\"color: #00ffff;\">this.getGLinkData<\/code> only after checking <code style=\"color: #00ffff;\">this.wasLaunchedViaGLink === true<\/code>. Use a short <code style=\"color: #00ffff;\">setTimeout<\/code> delay if accessing during initialize.<\/p>\n<\/p><\/div>\n<p>    <!-- Problem 3 --><\/p>\n<div style=\"background: #1a1e3f; border-radius: 8px; padding: 25px; border-left: 4px solid #ff6666;\">\n<h4 style=\"color: #ff6666; margin-top: 0; margin-bottom: 15px;\">Problem: Progress indicator stays visible after action completes<\/h4>\n<p style=\"color: #e0e0e0; margin-bottom: 15px;\"><strong style=\"color: #ffff00;\">Cause:<\/strong> Missing <code style=\"color: #00ffff;\">confirmGLinkProcessed()<\/code> or <code style=\"color: #00ffff;\">rejectGLink()<\/code> call.<\/p>\n<p style=\"color: #e0e0e0; margin-bottom: 0;\"><strong style=\"color: #00ff00;\">Solution:<\/strong> Ensure every code path ends with either <code style=\"color: #00ffff;\">confirmGLinkProcessed()<\/code> or <code style=\"color: #00ffff;\">rejectGLink()<\/code>. Use try\/catch and call <code style=\"color: #00ffff;\">rejectGLink()<\/code> in the catch block.<\/p>\n<\/p><\/div>\n<p>    <!-- Problem 4 --><\/p>\n<div style=\"background: #1a1e3f; border-radius: 8px; padding: 25px; border-left: 4px solid #ff6666;\">\n<h4 style=\"color: #ff6666; margin-top: 0; margin-bottom: 15px;\">Problem: View switches but action doesn&#8217;t execute<\/h4>\n<p style=\"color: #e0e0e0; margin-bottom: 15px;\"><strong style=\"color: #ffff00;\">Cause:<\/strong> Race condition &#8211; action executed before view transition completed.<\/p>\n<p style=\"color: #e0e0e0; margin-bottom: 0;\"><strong style=\"color: #00ff00;\">Solution:<\/strong> Use <code style=\"color: #00ffff;\">requestAnimationFrame<\/code> or a short delay after switching views before executing actions that depend on view-specific DOM elements.<\/p>\n<\/p><\/div>\n<p>    <!-- Problem 5 --><\/p>\n<div style=\"background: #1a1e3f; border-radius: 8px; padding: 25px; border-left: 4px solid #ff6666;\">\n<h4 style=\"color: #ff6666; margin-top: 0; margin-bottom: 15px;\">Problem: GLink works first time but not on subsequent visits<\/h4>\n<p style=\"color: #e0e0e0; margin-bottom: 15px;\"><strong style=\"color: #ffff00;\">Cause:<\/strong> GLink URL parameter remains in browser history.<\/p>\n<p style=\"color: #e0e0e0; margin-bottom: 0;\"><strong style=\"color: #00ff00;\">Solution:<\/strong> <code style=\"color: #00ffff;\">CGLink.clearFromURL()<\/code> is called automatically after successful processing. If implementing custom handling, call it manually after processing.<\/p>\n<\/p><\/div>\n<\/div>\n<p><!-- Section 14: Security --><\/p>\n<h2 id=\"security\" style=\"color: #ff00ff; font-size: 2.2em; margin-top: 60px; margin-bottom: 30px; padding-bottom: 15px; border-bottom: 2px solid #ff00ff; text-shadow: 0 0 15px rgba(255, 0, 255, 0.3);\">14. Security Considerations<\/h2>\n<p style=\"margin-bottom: 20px; font-size: 1.1em; color: #e0e0e0;\">GLinks are a powerful feature, but with power comes responsibility. Remember: the data in a GLink ultimately comes from an external source\u2014a URL that could have been crafted by anyone. A malicious actor could create a GLink with unexpected values, attempting to trick users or exploit vulnerabilities in your dApp.<\/p>\n<div style=\"background: #1a1e3f; border-left: 4px solid #ff6666; padding: 25px 30px; margin: 30px 0; border-radius: 4px;\">\n<h4 style=\"color: #ff6666; font-size: 1.3em; margin-top: 0; margin-bottom: 15px;\">\u26a0\ufe0f The Cardinal Rule<\/h4>\n<p style=\"margin-bottom: 0; font-size: 1.1em; color: #e0e0e0;\">GLinks should <strong style=\"color: #ff6666;\">never<\/strong> automatically execute sensitive operations. They can pre-fill forms, navigate to views, and prepare data\u2014but the user must always explicitly confirm any action that affects their assets or identity.<\/p>\n<\/div>\n<div style=\"display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 25px; margin: 30px 0;\">\n<div style=\"background: #1a1e3f; border-radius: 8px; padding: 25px; border-left: 4px solid #00ffff;\">\n<h4 style=\"color: #00ffff; margin-top: 0; margin-bottom: 15px;\">Validate All Input<\/h4>\n<p style=\"color: #e0e0e0; font-size: 0.95em; margin: 0;\">Never trust GLink data blindly. Validate addresses, amounts, IDs, and all other fields before use. Check for reasonable lengths and formats.<\/p>\n<\/p><\/div>\n<div style=\"background: #1a1e3f; border-radius: 8px; padding: 25px; border-left: 4px solid #00ffff;\">\n<h4 style=\"color: #00ffff; margin-top: 0; margin-bottom: 15px;\">Don&#8217;t Auto-Execute Transactions<\/h4>\n<p style=\"color: #e0e0e0; font-size: 0.95em; margin: 0;\">GLinks should pre-fill forms but never automatically execute transactions. Always require explicit user confirmation for any blockchain operation.<\/p>\n<\/p><\/div>\n<div style=\"background: #1a1e3f; border-radius: 8px; padding: 25px; border-left: 4px solid #00ffff;\">\n<h4 style=\"color: #00ffff; margin-top: 0; margin-bottom: 15px;\">Sanitize Display Content<\/h4>\n<p style=\"color: #e0e0e0; font-size: 0.95em; margin: 0;\">If displaying GLink data (like memo fields), sanitize to prevent XSS. Never use <code style=\"color: #ffff00;\">innerHTML<\/code> with unsanitized GLink data.<\/p>\n<\/p><\/div>\n<div style=\"background: #1a1e3f; border-radius: 8px; padding: 25px; border-left: 4px solid #00ffff;\">\n<h4 style=\"color: #00ffff; margin-top: 0; margin-bottom: 15px;\">Handle Unknown Actions Gracefully<\/h4>\n<p style=\"color: #e0e0e0; font-size: 0.95em; margin: 0;\">If a GLink contains an unknown action ID, reject it clearly. Don&#8217;t attempt to &#8220;guess&#8221; what was intended.<\/p>\n<\/p><\/div>\n<\/div>\n<h3 style=\"color: #00ffff; font-size: 1.6em; margin-top: 40px; margin-bottom: 20px;\">Example: Secure GLink Processing<\/h3>\n<p><code style=\"display: block; background: #0a0e27; padding: 25px; border-radius: 8px; overflow-x: auto; margin: 20px 0; color: #e0e0e0; font-size: 1em; line-height: 1.6; white-space: pre;\"><span style=\"color: #61afef;\">processGLink<\/span>(glinkData) {<br \/>\n    <span style=\"color: #c678dd;\">const<\/span> glinkHandler = CGLinkHandler.<span style=\"color: #61afef;\">getInstance<\/span>();<br \/>\n    <span style=\"color: #c678dd;\">try<\/span> {<br \/>\n        <span style=\"color: #5c6370;\">\/\/ Validate required fields<\/span><br \/>\n        <span style=\"color: #c678dd;\">if<\/span> (!glinkData || <span style=\"color: #c678dd;\">typeof<\/span> glinkData !== <span style=\"color: #98c379;\">'object'<\/span>) {<br \/>\n            <span style=\"color: #c678dd;\">throw new<\/span> <span style=\"color: #e5c07b;\">Error<\/span>(<span style=\"color: #98c379;\">'Invalid GLink data format'<\/span>);<br \/>\n        }<br \/>\n        <span style=\"color: #c678dd;\">const<\/span> { action, data } = glinkData;<br \/>\n        <span style=\"color: #5c6370;\">\/\/ Validate action is a known integer<\/span><br \/>\n        <span style=\"color: #c678dd;\">if<\/span> (action !== <span style=\"color: #c678dd;\">null<\/span> && (!Number.<span style=\"color: #61afef;\">isInteger<\/span>(action) || action < <span style=\"color: #d19a66;\">1<\/span> || action > <span style=\"color: #d19a66;\">10<\/span>)) {<br \/>\n            <span style=\"color: #c678dd;\">throw new<\/span> <span style=\"color: #e5c07b;\">Error<\/span>(<span style=\"color: #98c379;\">'Invalid action ID'<\/span>);<br \/>\n        }<br \/>\n        <span style=\"color: #5c6370;\">\/\/ Validate specific data fields based on action<\/span><br \/>\n        <span style=\"color: #c678dd;\">if<\/span> (action === <span style=\"color: #d19a66;\">1<\/span>) { <span style=\"color: #5c6370;\">\/\/ PREFILL_SEND<\/span><br \/>\n            <span style=\"color: #c678dd;\">if<\/span> (!data?.address || <span style=\"color: #c678dd;\">typeof<\/span> data.address !== <span style=\"color: #98c379;\">'string'<\/span>) {<br \/>\n                <span style=\"color: #c678dd;\">throw new<\/span> <span style=\"color: #e5c07b;\">Error<\/span>(<span style=\"color: #98c379;\">'Invalid recipient address'<\/span>);<br \/>\n            }<br \/>\n            <span style=\"color: #c678dd;\">if<\/span> (data.address.length > <span style=\"color: #d19a66;\">64<\/span>) { <span style=\"color: #5c6370;\">\/\/ Max domain length<\/span><br \/>\n                <span style=\"color: #c678dd;\">throw new<\/span> <span style=\"color: #e5c07b;\">Error<\/span>(<span style=\"color: #98c379;\">'Address too long'<\/span>);<br \/>\n            }<br \/>\n            <span style=\"color: #c678dd;\">if<\/span> (data.amount) {<br \/>\n                <span style=\"color: #c678dd;\">const<\/span> amount = <span style=\"color: #61afef;\">parseFloat<\/span>(data.amount);<br \/>\n                <span style=\"color: #c678dd;\">if<\/span> (<span style=\"color: #61afef;\">isNaN<\/span>(amount) || amount <= <span style=\"color: #d19a66;\">0<\/span>) {<br \/>\n                    <span style=\"color: #c678dd;\">throw new<\/span> <span style=\"color: #e5c07b;\">Error<\/span>(<span style=\"color: #98c379;\">'Invalid amount'<\/span>);<br \/>\n                }<br \/>\n            }<br \/>\n        }<br \/>\n        <span style=\"color: #5c6370;\">\/\/ Accept and process<\/span><br \/>\n        glinkHandler.<span style=\"color: #61afef;\">acceptGLink<\/span>(<span style=\"color: #98c379;\">'Validated, processing...'<\/span>);<br \/>\n        <span style=\"color: #c678dd;\">this<\/span>.<span style=\"color: #61afef;\">executeValidatedAction<\/span>(action, data);<br \/>\n        glinkHandler.<span style=\"color: #61afef;\">confirmGLinkProcessed<\/span>(<span style=\"color: #98c379;\">'Success'<\/span>);<br \/>\n    } <span style=\"color: #c678dd;\">catch<\/span> (error) {<br \/>\n        <span style=\"color: #e5c07b;\">console<\/span>.<span style=\"color: #61afef;\">error<\/span>(<span style=\"color: #98c379;\">'[Security] GLink validation failed:'<\/span>, error);<br \/>\n        glinkHandler.<span style=\"color: #61afef;\">rejectGLink<\/span>(error.message);<br \/>\n    }<br \/>\n}<\/code><\/p>\n<p><!-- Conclusion --><\/p>\n<div style=\"background: linear-gradient(135deg, #1a1e3f 0%, #0a0e27 100%); border-left: 4px solid #00ff00; padding: 40px; margin-top: 60px; border-radius: 8px; box-shadow: 0 10px 40px rgba(0, 255, 0, 0.1);\">\n<h2 style=\"color: #00ff00; margin-top: 0; font-size: 1.8em;\">The Future of Decentralized UX<\/h2>\n<p style=\"font-size: 1.1em; line-height: 1.6; color: #e0e0e0;\">GLinks represent more than just a convenience feature\u2014they&#8217;re a fundamental building block for making decentralized applications accessible to everyone. By enabling one-click spawning of a complete decentralized operating system with pre-configured state, we&#8217;ve eliminated one of the biggest friction points in blockchain adoption.<\/p>\n<p style=\"font-size: 1.1em; line-height: 1.6; color: #e0e0e0; margin-top: 15px;\">Share a transaction link on Twitter. Embed a payment request in an invoice. Create a QR code that opens someone&#8217;s wallet ready to send. <strong style=\"color: #00ffff; font-weight: 600;\">The decentralized web is no longer just for developers\u2014it&#8217;s for everyone.<\/strong><\/p>\n<div style=\"color: #a0a0a0; font-style: italic; margin-top: 25px; padding-top: 20px; border-top: 1px solid #2a2e4f;\">\u2014 The GRIDNET OS Development Team<\/div>\n<\/div>\n<p><!-- Footer --><\/p>\n<div style=\"text-align: center; margin-top: 60px; padding: 30px; color: #606080; font-size: 0.9em;\">\n<div style=\"margin-bottom: 15px;\">\n        <span style=\"color: #ff00ff;\">GRIDNET<\/span> <span style=\"color: #00ffff;\">OS<\/span> \u2014 The World&#8217;s First Windowed Decentralized Operating System\n    <\/div>\n<div>\n        <a href=\"https:\/\/gridnet.org\" style=\"color: #00ffff; text-decoration: none; margin: 0 15px;\">Website<\/a><br \/>\n        <a href=\"https:\/\/github.com\/nickmmark\/gridnet\" style=\"color: #00ffff; text-decoration: none; margin: 0 15px;\">GitHub<\/a><br \/>\n        <a href=\"https:\/\/discord.com\/invite\/sN4uyfBSh6\" style=\"color: #00ffff; text-decoration: none; margin: 0 15px;\">Discord<\/a><br \/>\n        <a href=\"https:\/\/www.youtube.com\/@GRIDNETProject\" style=\"color: #00ffff; text-decoration: none; margin: 0 15px;\">YouTube<\/a>\n    <\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>NOW LIVE GLinks are available in GRIDNET Core 1.9.4+ Deep linking for decentralized applications 350TB+ LIVE Coding Join Discord One Click to Spawn a Decentralized Operating System Imagine clicking a single link and watching a complete decentralized operating system materialize in your browser\u2014pre-configured to show exactly the transaction, wallet address, or block you wanted to [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":811519,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[125,10,16],"tags":[],"class_list":["post-811395","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-documentation","category-os-news","category-web-ui"],"_links":{"self":[{"href":"https:\/\/gridnet.org\/wpp\/index.php\/wp-json\/wp\/v2\/posts\/811395","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/gridnet.org\/wpp\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/gridnet.org\/wpp\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/gridnet.org\/wpp\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/gridnet.org\/wpp\/index.php\/wp-json\/wp\/v2\/comments?post=811395"}],"version-history":[{"count":4,"href":"https:\/\/gridnet.org\/wpp\/index.php\/wp-json\/wp\/v2\/posts\/811395\/revisions"}],"predecessor-version":[{"id":811546,"href":"https:\/\/gridnet.org\/wpp\/index.php\/wp-json\/wp\/v2\/posts\/811395\/revisions\/811546"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/gridnet.org\/wpp\/index.php\/wp-json\/wp\/v2\/media\/811519"}],"wp:attachment":[{"href":"https:\/\/gridnet.org\/wpp\/index.php\/wp-json\/wp\/v2\/media?parent=811395"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/gridnet.org\/wpp\/index.php\/wp-json\/wp\/v2\/categories?post=811395"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/gridnet.org\/wpp\/index.php\/wp-json\/wp\/v2\/tags?post=811395"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}