// server.js const http = require('http'); const https = require('https'); const url = require('url'); class ENSVisionRouter { constructor() { this.validENSPattern = /^[a-z0-9-]+$/i; this.port = process.env.PORT || 3000; } // Extract ENS name from subdomain extractENSName(hostname) { const parts = hostname.split('.'); // Expected format: {ensname}.eth.vision.io if (parts.length >= 4 && parts[1] === 'eth' && parts[2] === 'vision' && parts[3] === 'io') { return parts[0]; } return null; } // Validate ENS name format (basic validation) isValidENSName(name) { if (!name || name.length === 0) return false; if (name.length > 63) return false; // DNS label limit if (name.startsWith('-') || name.endsWith('-')) return false; return this.validENSPattern.test(name); } // Optional: Check if ENS name exists (requires Web3 provider) async checkENSExists(ensName) { // This is a placeholder - implement actual ENS resolution // You can use ethers.js or web3.js for this try { // const provider = new ethers.providers.JsonRpcProvider('your-rpc-url'); // const resolver = await provider.getResolver(ensName + '.eth'); // return resolver !== null; // For now, return true (skip validation) return true; } catch (error) { console.error('ENS validation error:', error); return true; // Fail open } } // Handle the request and redirect async handleRequest(req, res) { try { const hostname = req.headers.host; const ensName = this.extractENSName(hostname); console.log(`Request from: ${hostname}, extracted ENS: ${ensName}`); // Handle root domain or invalid format if (!ensName) { this.sendErrorPage(res, 'Invalid ENS format', 400); return; } // Validate ENS name format if (!this.isValidENSName(ensName)) { this.sendErrorPage(res, 'Invalid ENS name format', 400); return; } // Optional: Check if ENS exists const ensExists = await this.checkENSExists(ensName); if (!ensExists) { this.sendErrorPage(res, 'ENS name not found', 404); return; } // Construct Vision.io profile URL const visionURL = `https://vision.io/profile/${ensName}.eth`; console.log(`Redirecting to: ${visionURL}`); // Send redirect res.writeHead(302, { 'Location': visionURL, 'Cache-Control': 'public, max-age=300', // Cache for 5 minutes 'X-ENS-Name': ensName + '.eth' }); res.end(); } catch (error) { console.error('Error handling request:', error); this.sendErrorPage(res, 'Internal server error', 500); } } // Send error page sendErrorPage(res, message, statusCode = 404) { res.writeHead(statusCode, { 'Content-Type': 'text/html', 'Cache-Control': 'no-cache' }); const errorPage = ` ENS Vision Router - Error

Error ${statusCode}

${message}

Expected format: {ensname}.eth.vision.io

Example: vitalik.eth.vision.iohttps://vision.io/profile/vitalik.eth

`; res.end(errorPage); } // Start the server start() { const server = http.createServer((req, res) => { this.handleRequest(req, res); }); server.listen(this.port, () => { console.log(`ENS Vision Router running on port ${this.port}`); console.log(`Handling wildcards for *.eth.vision.io`); }); // Graceful shutdown process.on('SIGTERM', () => { console.log('Shutting down server...'); server.close(() => { console.log('Server closed'); process.exit(0); }); }); } } // Start the router const router = new ENSVisionRouter(); router.start();