// AAA Production Entry Point – Coinbase Wallet Direct Integration // --------------------------------------------------------------- // Version: 2.1.0 - RainbowKit + Wagmi + Early Farcaster Ready // Essential browser compatibility & node-style globals (Buffer, process, …) // Initialize environment validation immediately import { env } from './config/env'; console.log(`[Main] Starting DCW Frontend in ${env.isDev ? 'DEV' : 'PROD'} mode`); // ============================================================================= // CRITICAL: EARLY PLATFORM DETECTION & SDK LOADING // This MUST happen before React mounts to prevent Warpcast reload // ============================================================================= if (typeof window !== 'undefined') { const ua = navigator.userAgent || ''; const href = window.location.href || ''; const referrer = document.referrer || ''; // Global diagnostics object for debugging window.DCW_DIAGNOSTICS = { timestamp: new Date().toISOString(), userAgent: ua, href: href, referrer: referrer, hasMiniKit: !!window.miniKit, miniKitFrame: window.miniKit?.isFrameContext, hasFarcaster: !!window.farcaster, hasEthereum: !!window.ethereum, ethereumIsBase: !!window.ethereum?.isBase, ethereumIsCoinbase: !!window.ethereum?.isCoinbaseWallet, isIframe: window.parent !== window, detectedPlatform: null, sdkReadyCalled: false, errors: [] }; // FARCASTER DETECTION const isFarcasterLikely = ( /warpcast|farcaster/i.test(ua) || /warpcast|farcaster/i.test(referrer) || /warpcast|farcaster|\.fc\./i.test(href) || window.farcaster || window.__farcaster_miniapp__ || (window.miniKit && window.miniKit.isFrameContext === true) || (window.parent !== window && (referrer.includes('warpcast') || referrer.includes('farcaster'))) ); // BASE DETECTION (Check BEFORE Farcaster to avoid false positives from miniKit) const isBaseLikely = !isFarcasterLikely && ( /base\.app/i.test(referrer) || /base\.app/i.test(href) || window.ethereum?.isBase || window.ethereum?.isBaseMiniKit || window.baseMiniKit || (window.miniKit && window.miniKit.isFrameContext !== true) ); console.log('[Main] 🔍 EARLY DETECTION:', { isFarcaster: isFarcasterLikely, isBase: isBaseLikely, ua: ua.substring(0, 60), referrer: referrer.substring(0, 60) }); if (isFarcasterLikely) { window.DCW_DIAGNOSTICS.detectedPlatform = 'farcaster'; console.log('[Main] 🟣 Farcaster detected EARLY - loading SDK IMMEDIATELY'); // Dynamic import the SDK and call ready() ASAP import('@farcaster/miniapp-sdk') .then(module => { const sdk = module.default || module; window.DCW_DIAGNOSTICS.sdkLoaded = true; window.DCW_FARCASTER_SDK = sdk; if (sdk?.actions?.ready) { sdk.actions.ready(); console.log('[Main] 🚀 EARLY sdk.actions.ready() called BEFORE React mount'); window.DCW_DIAGNOSTICS.sdkReadyCalled = true; } else { console.warn('[Main] SDK loaded but no actions.ready() method'); window.DCW_DIAGNOSTICS.errors.push('No actions.ready method'); } }) .catch(e => { console.error('[Main] Early Farcaster SDK load FAILED:', e); window.DCW_DIAGNOSTICS.errors.push('SDK load failed: ' + e.message); }); } else if (isBaseLikely) { window.DCW_DIAGNOSTICS.detectedPlatform = 'base'; console.log('[Main] 🔵 Base detected EARLY'); } else { window.DCW_DIAGNOSTICS.detectedPlatform = 'web'; console.log('[Main] 🌐 Web/Desktop detected'); } // Expose debug function window.dcwDebug = function() { console.log('=== DCW DIAGNOSTICS ==='); console.table(window.DCW_DIAGNOSTICS); return window.DCW_DIAGNOSTICS; }; } // Local wallet-request guard: no provider popup without explicit user intent. if (typeof window !== 'undefined' && import.meta.env.DEV && /^(localhost|127\.0\.0\.1|\[::1\])$/.test(window.location.hostname)) { window.__DCW_WALLET_BLOCKS = []; const sensitive = new Set([ 'eth_requestAccounts', 'personal_sign', 'wallet_requestPermissions', 'wallet_switchEthereumChain', 'wallet_addEthereumChain', 'eth_sendTransaction', ]); const installGuard = () => { const eth = window.ethereum; if (!eth || eth.__dcwGuarded || typeof eth.request !== 'function') return false; const original = eth.request.bind(eth); eth.request = async (args) => { const method = args?.method; if (sensitive.has(method) && !window.__DCW_ALLOW_WALLET) { window.__DCW_WALLET_BLOCKS.push({ method, at: Date.now(), stack: new Error().stack }); console.warn('[DCW] Blocked wallet request without user intent:', method); throw new Error(`Wallet request blocked until CONNECT WALLET (${method})`); } return original(args); }; eth.__dcwGuarded = true; console.log('[DCW] Local wallet-request guard installed'); return true; }; installGuard(); const guardTimer = setInterval(() => { if (installGuard()) clearInterval(guardTimer); }, 500); } // Define ALL globals immediately (before ANY other imports) if (typeof window !== 'undefined') { // Define global first (this is what the polyfill plugins expect) window.global = window; // Define GLOBAL (some libraries expect this) window.GLOBAL = window; // Define process if (typeof window.process === 'undefined') { window.process = { env: {}, browser: true, version: 'v18.0.0', versions: { node: '18.0.0' }, platform: 'browser', arch: 'web' }; } // Define Buffer with complete implementation if (typeof window.Buffer === 'undefined') { window.Buffer = { isBuffer: function (obj) { return obj != null && obj._isBuffer === true; }, from: function (data, encoding) { if (typeof data === 'string') { return new TextEncoder().encode(data); } if (Array.isArray(data)) { return new Uint8Array(data); } return new Uint8Array(data); }, alloc: function (size) { return new Uint8Array(size); }, allocUnsafe: function (size) { return new Uint8Array(size); }, concat: function (buffers) { let totalLength = 0; for (const buffer of buffers) { totalLength += buffer.length; } const result = new Uint8Array(totalLength); let offset = 0; for (const buffer of buffers) { result.set(buffer, offset); offset += buffer.length; } return result; }, byteLength: function (string, encoding) { return new TextEncoder().encode(string).length; } }; console.log('[Main] All globals defined'); } } // Import polyfills import './polyfills/nodeGlobals.js'; // Additional global shims // Verify globals are available console.log('[Main] Globals status:', { hasBuffer: !!window.Buffer, hasGlobal: !!window.global, hasProcess: !!window.process }); import React from 'react'; import ReactDOM from 'react-dom/client'; import App from './App'; import './App.css'; import './index.css'; // Farcaster Mini App Bridge import { initFrameBridge } from './engine/frameBridge.js'; // Initialize Farcaster SDK if in a Frame environment // This is safe to call unconditionally as it performs its own environment checks initFrameBridge().catch(err => { console.error('[Main] Failed to initialize Frame Bridge:', err); }); // Expose device helpers for E2E tests import * as device from './engine/device.js'; if (typeof window !== 'undefined') { window.DCW_Device = device; } // --------------------------------------------------------------------------- // React root // --------------------------------------------------------------------------- const rootEl = document.getElementById('root'); const app = ; ReactDOM.createRoot(rootEl).render( import.meta.env.VITE_QA_E2E === 'true' ? app : ( {app} ), );