diff --git a/css/soldomains.css b/css/soldomains.css index 8ef4758..3a5f3e6 100644 --- a/css/soldomains.css +++ b/css/soldomains.css @@ -446,3 +446,155 @@ font-size: 0.6rem; color: rgba(255, 255, 255, 0.3); } + +/* Wallet Modal */ +.sol-modal { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 9999; + display: flex; + align-items: center; + justify-content: center; +} + +.sol-modal.hidden { + display: none !important; +} + +.sol-modal-backdrop { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: rgba(0, 0, 0, 0.75); + backdrop-filter: blur(4px); +} + +.sol-modal-content { + position: relative; + background: rgba(12, 12, 12, 0.98); + border: 1px solid rgba(138, 43, 226, 0.3); + border-top: 2px solid #a855f7; + width: 90%; + max-width: 420px; + max-height: 80vh; + overflow-y: auto; +} + +.sol-modal-header { + display: flex; + justify-content: space-between; + align-items: center; + padding: 1rem 1.25rem; + border-bottom: 1px solid rgba(138, 43, 226, 0.15); +} + +.sol-modal-title { + font-family: 'Orbitron', monospace; + font-size: 0.7rem; + color: #a855f7; + letter-spacing: 3px; +} + +.sol-modal-close { + background: transparent; + border: 1px solid rgba(255, 255, 255, 0.15); + color: rgba(255, 255, 255, 0.5); + font-size: 0.75rem; + width: 28px; + height: 28px; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + transition: all 0.2s ease; +} + +.sol-modal-close:hover { + border-color: rgba(255, 50, 50, 0.5); + color: rgba(255, 50, 50, 0.8); +} + +.sol-modal-body { + padding: 0.75rem; +} + +.sol-modal-footer { + padding: 0.75rem 1.25rem; + border-top: 1px solid rgba(138, 43, 226, 0.1); +} + +.sol-modal-hint { + font-family: 'JetBrains Mono', monospace; + font-size: 0.55rem; + color: rgba(255, 255, 255, 0.25); + letter-spacing: 1px; +} + +/* Wallet Options */ +.sol-wallet-option { + display: flex; + align-items: center; + gap: 0.75rem; + width: 100%; + padding: 0.85rem 1rem; + background: rgba(20, 20, 20, 0.6); + border: 1px solid rgba(138, 43, 226, 0.12); + color: #ffffff; + cursor: pointer; + transition: all 0.2s ease; + margin-bottom: 0.4rem; + text-decoration: none; +} + +.sol-wallet-option:hover { + background: rgba(138, 43, 226, 0.1); + border-color: rgba(138, 43, 226, 0.35); + transform: translateX(3px); +} + +.sol-wallet-option.not-installed { + opacity: 0.45; +} + +.sol-wallet-option.not-installed:hover { + opacity: 0.7; +} + +.sol-wallet-option-icon { + font-size: 1.2rem; + width: 28px; + text-align: center; +} + +.sol-wallet-option-name { + font-family: 'Orbitron', monospace; + font-size: 0.65rem; + letter-spacing: 2px; + flex: 1; +} + +.sol-wallet-option-status { + font-family: 'JetBrains Mono', monospace; + font-size: 0.5rem; + letter-spacing: 1px; + color: #00cc44; +} + +.sol-wallet-option.not-installed .sol-wallet-option-status { + color: rgba(255, 255, 255, 0.3); +} + +.sol-wallet-divider { + font-family: 'JetBrains Mono', monospace; + font-size: 0.5rem; + color: rgba(255, 255, 255, 0.2); + letter-spacing: 2px; + padding: 0.75rem 1rem 0.4rem; + border-top: 1px solid rgba(255, 255, 255, 0.05); + margin-top: 0.25rem; +} diff --git a/js/soldomains.js b/js/soldomains.js index e678b64..48f765c 100644 --- a/js/soldomains.js +++ b/js/soldomains.js @@ -244,10 +244,109 @@ async function doReverse() { } // ─── WALLET ───────────────────────────────────────────────── +let connectedProvider = null; + +const WALLETS = [ + { name: 'PHANTOM', icon: '👻', detect: () => window.phantom?.solana, url: 'https://phantom.app' }, + { name: 'SOLFLARE', icon: '🔆', detect: () => window.solflare, url: 'https://solflare.com' }, + { name: 'BACKPACK', icon: '🎒', detect: () => window.backpack, url: 'https://backpack.app' }, + { name: 'COINBASE', icon: '🔵', detect: () => window.coinbaseSolana, url: 'https://coinbase.com/wallet' }, + { name: 'TRUST', icon: '🛡️', detect: () => window.trustwallet?.solana, url: 'https://trustwallet.com' }, + { name: 'METAMASK', icon: '🦊', detect: () => window.ethereum?.isSolana ? window.ethereum : null, url: 'https://metamask.io' }, +]; + +function getAvailableWallets() { + const available = []; + for (const w of WALLETS) { + try { + const provider = w.detect(); + if (provider) available.push({ ...w, provider }); + } catch(e) {} + } + // Fallback: check generic window.solana if no specific wallet matched + if (available.length === 0 && window.solana) { + available.push({ name: 'SOLANA WALLET', icon: '◈', provider: window.solana, url: '#' }); + } + return available; +} + function initWallet() { const btn = $('#wallet-btn'); if (!btn) return; btn.addEventListener('click', toggleWallet); + createWalletModal(); +} + +function createWalletModal() { + const modal = document.createElement('div'); + modal.id = 'wallet-modal'; + modal.className = 'sol-modal hidden'; + modal.innerHTML = ` +
+
+
+ SELECT WALLET + +
+
+ +
+ `; + document.body.appendChild(modal); + + modal.querySelector('.sol-modal-backdrop').addEventListener('click', closeModal); + modal.querySelector('#modal-close').addEventListener('click', closeModal); +} + +function openModal() { + const modal = $('#wallet-modal'); + const list = $('#wallet-list'); + const available = getAvailableWallets(); + + let html = ''; + + if (available.length > 0) { + html += available.map(w => ` + + `).join(''); + } + + // Show install links for wallets not detected + const notInstalled = WALLETS.filter(w => { try { return !w.detect(); } catch(e) { return true; } }); + if (notInstalled.length > 0) { + html += '
NOT INSTALLED
'; + html += notInstalled.map(w => ` + + ${w.icon} + ${w.name} + INSTALL ↗ + + `).join(''); + } + + list.innerHTML = html; + + // Bind click handlers for detected wallets + list.querySelectorAll('.sol-wallet-option:not(.not-installed)').forEach(btn => { + btn.addEventListener('click', () => { + const name = btn.dataset.wallet; + const wallet = available.find(w => w.name === name); + if (wallet) connectWallet(wallet); + }); + }); + + modal.classList.remove('hidden'); +} + +function closeModal() { + const modal = $('#wallet-modal'); + if (modal) modal.classList.add('hidden'); } async function toggleWallet() { @@ -255,26 +354,29 @@ async function toggleWallet() { disconnectWallet(); return; } + openModal(); +} - // Check for Phantom - if (!window.solana || !window.solana.isPhantom) { - const bar = $('#wallet-status'); - if (bar) bar.innerHTML = 'PHANTOM WALLET NOT DETECTED — INSTALL'; - return; - } - +async function connectWallet(wallet) { try { - const resp = await window.solana.connect(); + closeModal(); + const resp = await wallet.provider.connect(); walletAddress = resp.publicKey.toString(); + connectedProvider = wallet; updateWalletUI(); } catch(err) { console.error('Wallet connection failed:', err); + const status = $('#wallet-status'); + if (status) status.innerHTML = `CONNECTION REJECTED`; } } function disconnectWallet() { - if (window.solana) window.solana.disconnect(); + if (connectedProvider && connectedProvider.provider) { + try { connectedProvider.provider.disconnect(); } catch(e) {} + } walletAddress = null; + connectedProvider = null; updateWalletUI(); } @@ -283,8 +385,10 @@ function updateWalletUI() { const btn = $('#wallet-btn'); if (walletAddress) { + const wName = connectedProvider ? connectedProvider.name : 'WALLET'; + const wIcon = connectedProvider ? connectedProvider.icon : '◈'; status.className = 'sol-wallet-status connected'; - status.innerHTML = `● CONNECTED ${truncAddr(walletAddress)}`; + status.innerHTML = `● CONNECTED VIA ${wIcon} ${wName} ${truncAddr(walletAddress)}`; btn.className = 'sol-wallet-btn disconnect'; btn.textContent = 'DISCONNECT'; } else { @@ -292,7 +396,6 @@ function updateWalletUI() { status.innerHTML = '○ NOT CONNECTED'; btn.className = 'sol-wallet-btn'; btn.textContent = 'CONNECT WALLET'; - // Clear my domains const panel = $('#mydomains-content'); if (panel) panel.innerHTML = `
CONNECT WALLET TO VIEW YOUR DOMAINS
`; }