diff --git a/js/soldomains.js b/js/soldomains.js index 17e3bc5..d945002 100644 --- a/js/soldomains.js +++ b/js/soldomains.js @@ -1,8 +1,9 @@ /* .SOL DOMAINS — Solana Name Service Lookup & Registration */ const SNS_API = 'https://sns-sdk-proxy.bonfida.workers.dev'; -const BONFIDA_REG = 'https://naming.bonfida.org/#/domain/'; +const SNS_REG = 'https://www.sns.id/domain/'; const SOLSCAN = 'https://solscan.io/account/'; +const REFERRAL_WALLET = '9NuiHh5wgRPx69BFGP1ZR8kHiBENGoJrXs5GpZzKAyn8'; let walletAddress = null; let currentTab = 'search'; @@ -31,7 +32,6 @@ function switchTab(t) { currentTab = t; $$('.sol-tab').forEach(tab => tab.classList.toggle('active', tab.dataset.tab === t)); $$('.sol-panel').forEach(p => p.classList.toggle('hidden', p.id !== `panel-${t}`)); - if (t === 'mydomains' && walletAddress) loadMyDomains(); } @@ -40,11 +40,9 @@ function initSearch() { const input = $('#sol-search'); const btn = $('#sol-search-go'); if (!input || !btn) return; - btn.addEventListener('click', () => doSearch()); input.addEventListener('keydown', e => { if (e.key === 'Enter') doSearch(); }); - // Reverse lookup const revInput = $('#sol-reverse'); const revBtn = $('#sol-reverse-go'); if (revInput && revBtn) { @@ -56,8 +54,6 @@ function initSearch() { async function doSearch() { const raw = $('#sol-search').value.trim().toLowerCase(); if (!raw) return; - - // Strip .sol if user typed it const domain = raw.replace(/\.sol$/i, ''); const results = $('#search-results'); results.innerHTML = loadingHTML('RESOLVING DOMAIN...'); @@ -65,12 +61,9 @@ async function doSearch() { try { const res = await fetch(`${SNS_API}/resolve/${domain}`); const data = await res.json(); - if (data.s === 'ok' && data.result) { - // Domain is registered — show owner info await showTakenDomain(domain, data.result); } else { - // Domain is available showAvailableDomain(domain); } } catch (err) { @@ -80,25 +73,11 @@ async function doSearch() { async function showTakenDomain(domain, owner) { const results = $('#search-results'); - - // Try to get more data - let records = {}; - try { - const recRes = await fetch(`${SNS_API}/record-v2/${domain}/SOL`); - if (recRes.ok) { - const recData = await recRes.json(); - records.sol = recData.result || null; - } - } catch(e) {} - - // Try favourite domain of owner let favourite = null; try { const favRes = await fetch(`${SNS_API}/favourite-domain/${owner}`); - if (favRes.ok) { - const favData = await favRes.json(); - favourite = favData.result || null; - } + const favData = await favRes.json(); + if (favData.s === 'ok') favourite = favData.result || null; } catch(e) {} results.innerHTML = ` @@ -129,9 +108,9 @@ async function showTakenDomain(domain, owner) {
- BONFIDA + SNS
- View on Bonfida ↗ + View on SNS.id ↗
@@ -150,6 +129,8 @@ function showAvailableDomain(domain) { else if (len === 4) priceEstimate = '~160 USDC'; else priceEstimate = '~20 USDC'; + const regUrl = `${SNS_REG}${encodeURIComponent(domain)}?ref=${REFERRAL_WALLET}`; + results.innerHTML = `
@@ -174,9 +155,9 @@ function showAvailableDomain(domain) {
REGISTRATION -
Register via Bonfida's official portal
+
Purchase your .sol domain
- REGISTER ${esc(domain.toUpperCase())}.SOL ↗ + REGISTER ${esc(domain.toUpperCase())}.SOL ↗
@@ -192,28 +173,34 @@ async function doReverse() { results.innerHTML = loadingHTML('SCANNING WALLET...'); try { - // Get all domains for this wallet const res = await fetch(`${SNS_API}/domains/${addr}`); - if (!res.ok) { - results.innerHTML = errorHTML('Could not resolve wallet. Check the address.'); - return; - } const data = await res.json(); - const domains = data.result || data; - if (!domains || !domains.length) { + // Normalise response to array — API may return various formats + let domains = []; + if (Array.isArray(data)) { + domains = data; + } else if (data && typeof data === 'object') { + if (Array.isArray(data.result)) { + domains = data.result; + } else if (typeof data.result === 'string') { + domains = [data.result]; + } else if (data.result && typeof data.result === 'object' && !Array.isArray(data.result)) { + // Single domain object + domains = [data.result]; + } + } + + if (!domains || domains.length === 0) { results.innerHTML = `
NO .SOL DOMAINS FOUND FOR THIS WALLET
`; return; } - // Get favourite let favourite = null; try { const favRes = await fetch(`${SNS_API}/favourite-domain/${addr}`); - if (favRes.ok) { - const favData = await favRes.json(); - favourite = favData.result || null; - } + const favData = await favRes.json(); + if (favData.s === 'ok') favourite = favData.result || null; } catch(e) {} results.innerHTML = ` @@ -224,7 +211,7 @@ async function doReverse() {
${domains.map(d => { - const name = typeof d === 'string' ? d : (d.domain || d); + const name = typeof d === 'string' ? d : (d.domain || d.name || String(d)); const isFav = favourite && name === favourite; return `
@@ -244,26 +231,93 @@ async function doReverse() { 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' }, + { + name: 'PHANTOM', + icon: '👻', + detect: () => { + const p = window.phantom?.solana; + return (p && p.isPhantom) ? p : null; + }, + url: 'https://phantom.app' + }, + { + name: 'JUPITER', + icon: '🪐', + detect: () => { + if (window.jupiter?.solana) return window.jupiter.solana; + if (window.solana?.isJupiter) return window.solana; + return null; + }, + url: 'https://jup.ag' + }, + { + name: 'SOLFLARE', + icon: '🔆', + detect: () => { + const s = window.solflare; + return (s && s.isSolflare) ? s : null; + }, + url: 'https://solflare.com' + }, + { + name: 'BACKPACK', + icon: '🎒', + detect: () => { + const b = window.backpack; + return (b && b.isBackpack) ? b : null; + }, + url: 'https://backpack.app' + }, + { + name: 'COINBASE', + icon: '🔵', + detect: () => window.coinbaseSolana || null, + url: 'https://coinbase.com/wallet' + }, + { + name: 'TRUST', + icon: '🛡️', + detect: () => window.trustwallet?.solana || null, + url: 'https://trustwallet.com' + }, + { + name: 'METAMASK', + icon: '🦊', + detect: () => { + // MetaMask Solana injects at window.solana with isMetaMask + if (window.solana?.isMetaMask) return window.solana; + // Or check ethereum provider flags + if (window.ethereum?.isMetaMask && window.ethereum?.solana) return window.ethereum.solana; + return null; + }, + url: 'https://metamask.io' + }, ]; function getAvailableWallets() { const available = []; + const matchedProviders = new Set(); + for (const w of WALLETS) { try { const provider = w.detect(); - if (provider) available.push({ ...w, provider }); + if (provider && !matchedProviders.has(provider)) { + available.push({ ...w, provider }); + matchedProviders.add(provider); + } } catch(e) {} } - // Fallback: check generic window.solana if no specific wallet matched + + // Generic fallback: window.solana if nothing matched if (available.length === 0 && window.solana) { - available.push({ name: 'SOLANA WALLET', icon: '◈', provider: window.solana, url: '#' }); + available.push({ + name: 'SOLANA WALLET', + icon: '◈', + provider: window.solana, + url: '#' + }); } + return available; } @@ -292,7 +346,6 @@ function createWalletModal() {
`; document.body.appendChild(modal); - modal.querySelector('.sol-modal-backdrop').addEventListener('click', closeModal); modal.querySelector('#modal-close').addEventListener('click', closeModal); } @@ -301,21 +354,24 @@ function openModal() { const modal = $('#wallet-modal'); const list = $('#wallet-list'); const available = getAvailableWallets(); + const detectedNames = new Set(available.map(w => w.name)); let html = ''; + // Show detected wallets as clickable buttons if (available.length > 0) { + html += '
DETECTED
'; 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; } }); + // Show not-installed wallets as links (exclude detected ones) + const notInstalled = WALLETS.filter(w => !detectedNames.has(w.name)); if (notInstalled.length > 0) { html += '
NOT INSTALLED
'; html += notInstalled.map(w => ` @@ -327,11 +383,17 @@ function openModal() { `).join(''); } + if (available.length === 0) { + html = '
NO SOLANA WALLETS DETECTED

Install a Solana wallet extension to connect.
'; + } + list.innerHTML = html; - // Bind click handlers for detected wallets - list.querySelectorAll('.sol-wallet-option:not(.not-installed)').forEach(btn => { - btn.addEventListener('click', () => { + // Bind click handlers only for detected wallets (buttons, not links) + list.querySelectorAll('.sol-wallet-option.detected').forEach(btn => { + btn.addEventListener('click', (e) => { + e.preventDefault(); + e.stopPropagation(); const name = btn.dataset.wallet; const wallet = available.find(w => w.name === name); if (wallet) connectWallet(wallet); @@ -406,29 +468,35 @@ async function loadMyDomains() { try { const res = await fetch(`${SNS_API}/domains/${walletAddress}`); - if (!res.ok) { - content.innerHTML = errorHTML('Failed to load domains.'); - return; + const data = await res.json(); + + // Normalise to array + let domains = []; + if (Array.isArray(data)) { + domains = data; + } else if (data && typeof data === 'object') { + if (Array.isArray(data.result)) { + domains = data.result; + } else if (typeof data.result === 'string') { + domains = [data.result]; + } else if (data.result && typeof data.result === 'object') { + domains = [data.result]; + } } - const data = await res.json(); - const domains = data.result || data; - - // Get favourite let favourite = null; try { const favRes = await fetch(`${SNS_API}/favourite-domain/${walletAddress}`); - if (favRes.ok) { - const favData = await favRes.json(); - favourite = favData.result || null; - } + const favData = await favRes.json(); + if (favData.s === 'ok') favourite = favData.result || null; } catch(e) {} - if (!domains || !domains.length) { + if (!domains || domains.length === 0) { + const regUrl = `${SNS_REG}?ref=${REFERRAL_WALLET}`; content.innerHTML = `
NO .SOL DOMAINS FOUND
- Register one on Bonfida ↗ + Register one on SNS.id ↗
`; return; @@ -441,7 +509,7 @@ async function loadMyDomains() {
${domains.map(d => { - const name = typeof d === 'string' ? d : (d.domain || d); + const name = typeof d === 'string' ? d : (d.domain || d.name || String(d)); const isFav = favourite && name === favourite; return `