diff --git a/private/direct-join.html b/private/direct-join.html index 1c170ee..1211e31 100644 --- a/private/direct-join.html +++ b/private/direct-join.html @@ -78,4 +78,4 @@

No income is guaranteed. Cryptocurrency and smart-contract participation carry risk. Only use funds you can afford to lose.

- + diff --git a/private/join-now.html b/private/join-now.html index 4675190..26315f3 100644 --- a/private/join-now.html +++ b/private/join-now.html @@ -49,4 +49,4 @@

No income is guaranteed. Cryptocurrency and smart-contract participation carry risk. Only use funds you can afford to lose.

- + diff --git a/public/direct-join.js b/public/direct-join.js index 41d5e7a..ca00c86 100644 --- a/public/direct-join.js +++ b/public/direct-join.js @@ -18,7 +18,7 @@ var LEVELS=['','Scintilla','Ascensus','Fabrica','Culmen','Apex','Fastigium','Vertex','Corona']; var $=function(id){return document.getElementById(id);}; - var eth=window.ethereum; + var eth=null; // resolved via the wallet picker on connect var account=null, costs=null; function log(msg,kind){var b=$('log');var d=document.createElement('div');d.className='dj-log '+(kind||'');d.innerHTML=msg;b.appendChild(d);b.scrollTop=b.scrollHeight;} @@ -81,8 +81,10 @@ function showResult(big,sub,linkId){ var el=$('result'); if(!el) return; $('resultId').textContent=big; $('resultSub').textContent=sub; var lk=$('resultLink'); if(lk){ if(linkId){ lk.href='/my/'+linkId; lk.style.display='inline-flex'; } else lk.style.display='none'; } el.style.display='block'; try{el.scrollIntoView({behavior:'smooth',block:'center'});}catch(e){} } async function connect(){ - if(!eth){ log('No wallet detected. Open this page in a browser with MetaMask (extension or the MetaMask in-app browser).','err'); return; } try{ + eth=await window.RMCWallet.pick(); + if(!eth){ log('No wallet selected or detected. Install/unlock MetaMask, Trust, or SafePal and try again.','err'); return; } + attachWalletEvents(); log('Requesting wallet connection…'); var accs=await req('eth_requestAccounts'); account=accs[0]; await ensurePolygon(); @@ -152,17 +154,17 @@ $('connectBtn').addEventListener('click',connect); $('registerBtn').addEventListener('click',doRegister); var ub=$('upgradeBtn'); if(ub) ub.addEventListener('click',doUpgrade); - // Update in place on wallet events — do NOT location.reload() here: some wallets - // (Trust Wallet in Brave) fire chainChanged on load, and reloading re-arms the - // handler → infinite refresh loop that blocks the Connect button. - if(eth && eth.on){ - eth.on('accountsChanged',function(accs){ - account=(accs&&accs[0])||null; - if(!account){ $('connected').style.display='none'; $('connectBtn').style.display=''; log('Wallet disconnected.','err'); } - else { $('wallet').textContent=account.slice(0,6)+'…'+account.slice(-4); refreshBalance(); } - }); - eth.on('chainChanged',function(){ if(account) refreshBalance(); }); - } - if(!eth) log('No wallet detected in this browser. Use MetaMask or Trust Wallet (extension, or the wallet app’s in-app browser).','err'); }); + // Update in place on wallet events — do NOT location.reload() here: some wallets + // (Trust Wallet in Brave) fire chainChanged on load, and reloading re-arms the + // handler → infinite refresh loop. Bound once, after the picker resolves the provider. + function attachWalletEvents(){ + if(!eth||!eth.on||eth.__rmcBound) return; eth.__rmcBound=true; + eth.on('accountsChanged',function(accs){ + account=(accs&&accs[0])||null; + if(!account){ $('connected').style.display='none'; $('connectBtn').style.display=''; log('Wallet disconnected.','err'); } + else { $('wallet').textContent=account.slice(0,6)+'…'+account.slice(-4); refreshBalance(); } + }); + eth.on('chainChanged',function(){ if(account) refreshBalance(); }); + } })(); diff --git a/public/join-now.js b/public/join-now.js index 323a4b1..5d7b304 100644 --- a/public/join-now.js +++ b/public/join-now.js @@ -12,7 +12,7 @@ var T_REGISTERED='0xe4a74887d749eb048f14bfef37b204477f3a5ff67055908b7c8cc62c202aef17'; var $=function(id){return document.getElementById(id);}; - var eth=window.ethereum; + var eth=null; // resolved via the wallet picker on connect var account=null, costs=null, sponsorId=null; function log(msg,kind){var b=$('log');if(!b)return;var d=document.createElement('div');d.className='dj-log '+(kind||'');d.innerHTML=msg;b.appendChild(d);b.scrollTop=b.scrollHeight;} @@ -60,8 +60,10 @@ async function refreshBalance(){ try{ var b=await req('eth_getBalance',[account,'latest']); $('bal').textContent=polStr(BigInt(b))+' POL'; }catch(e){} } async function connect(){ - if(!eth){ log('No wallet detected. Open this page in MetaMask or Trust Wallet (extension, or the wallet app’s in-app browser).','err'); return; } try{ + eth=await window.RMCWallet.pick(); + if(!eth){ log('No wallet selected or detected. Install/unlock MetaMask, Trust, or SafePal and try again.','err'); return; } + attachWalletEvents(); log('Requesting wallet connection…'); var accs=await req('eth_requestAccounts'); account=accs[0]; await ensurePolygon(); await loadCosts(); @@ -106,14 +108,14 @@ } function el_scroll(id){ var e=$(id); if(e&&e.scrollIntoView) e.scrollIntoView({behavior:'smooth',block:'center'}); } + function attachWalletEvents(){ + if(!eth||!eth.on||eth.__rmcBound) return; eth.__rmcBound=true; + eth.on('accountsChanged',function(accs){ account=(accs&&accs[0])||null; if(!account){ $('connected').style.display='none'; $('connectBtn').style.display=''; } else { $('wallet').textContent=account.slice(0,6)+'…'+account.slice(-4); refreshBalance(); } }); + eth.on('chainChanged',function(){ if(account) refreshBalance(); }); + } document.addEventListener('DOMContentLoaded',function(){ loadSponsor(); $('connectBtn').addEventListener('click',connect); $('joinBtn').addEventListener('click',doJoin); - if(eth&ð.on){ - eth.on('accountsChanged',function(accs){ account=(accs&&accs[0])||null; if(!account){ $('connected').style.display='none'; $('connectBtn').style.display=''; } else { $('wallet').textContent=account.slice(0,6)+'…'+account.slice(-4); refreshBalance(); } }); - eth.on('chainChanged',function(){ if(account) refreshBalance(); }); - } - if(!eth) log('No wallet detected. Use MetaMask or Trust Wallet (extension, or the wallet app’s in-app browser).','err'); }); })(); diff --git a/public/rmc-wallet.js b/public/rmc-wallet.js new file mode 100644 index 0000000..e5e637a --- /dev/null +++ b/public/rmc-wallet.js @@ -0,0 +1,57 @@ +/* RM Circle — EIP-6963 multi-wallet discovery + picker. + Lets the user choose among ALL injected wallets (Brave, MetaMask, SafePal, + Trust, Coinbase…) instead of whatever won the window.ethereum fight — which is + why "connect" silently hangs when e.g. Brave's built-in wallet grabs the slot. + CSP-safe: no external libs, and EIP-6963 wallet icons are data: URIs. */ +(function(){ + 'use strict'; + var found=[], seen={}; + function onAnnounce(e){ + var d=e&&e.detail; if(!d||!d.info||!d.provider) return; + var key=d.info.uuid||d.info.rdns||d.info.name; if(seen[key]) return; seen[key]=1; + found.push({info:d.info, provider:d.provider}); + } + window.addEventListener('eip6963:announceProvider', onAnnounce); + function request(){ try{ window.dispatchEvent(new Event('eip6963:requestProvider')); }catch(e){} } + request(); + + function showPicker(list){ + return new Promise(function(resolve){ + var ov=document.createElement('div'); + ov.style.cssText='position:fixed;inset:0;background:rgba(3,10,18,.74);display:flex;align-items:center;justify-content:center;z-index:99999;padding:20px'; + var box=document.createElement('div'); + box.style.cssText='background:#0b1e30;border:1px solid #27445e;border-radius:16px;padding:20px;max-width:360px;width:100%;box-shadow:0 20px 60px rgba(0,0,0,.55)'; + var h=document.createElement('div'); h.style.cssText='font-weight:800;font-size:17px;color:#f7f9fc;margin-bottom:4px'; h.textContent='Choose your wallet'; box.appendChild(h); + var s=document.createElement('div'); s.style.cssText='color:#aebdca;font-size:13px;margin-bottom:14px'; s.textContent='Pick the wallet you want to connect with.'; box.appendChild(s); + list.forEach(function(w){ + var b=document.createElement('button'); + b.style.cssText='display:flex;align-items:center;gap:12px;width:100%;text-align:left;background:#132c43;border:1px solid #294a65;border-radius:11px;padding:12px 14px;margin-bottom:8px;cursor:pointer;color:#f7f9fc;font-weight:700;font-size:15px'; + if(w.info.icon){ var img=document.createElement('img'); img.src=w.info.icon; img.alt=''; img.style.cssText='width:26px;height:26px;border-radius:6px;flex:none'; b.appendChild(img); } + var sp=document.createElement('span'); sp.textContent=w.info.name||'Wallet'; b.appendChild(sp); + b.addEventListener('click',function(){ try{document.body.removeChild(ov);}catch(e){} resolve(w.provider); }); + box.appendChild(b); + }); + var c=document.createElement('button'); c.textContent='Cancel'; + c.style.cssText='width:100%;background:transparent;border:0;color:#8498aa;padding:8px;margin-top:2px;cursor:pointer;font-size:13px'; + c.addEventListener('click',function(){ try{document.body.removeChild(ov);}catch(e){} resolve(null); }); + box.appendChild(c); + ov.appendChild(box); document.body.appendChild(ov); + }); + } + + window.RMCWallet={ + // Resolve a provider: 0 discovered -> legacy window.ethereum; 1 -> use it; 2+ -> ask. + pick:function(){ + return new Promise(function(resolve){ + request(); + setTimeout(function(){ + var list=found.slice(); + if(list.length===0){ resolve(window.ethereum||null); return; } + if(list.length===1){ resolve(list[0].provider); return; } + showPicker(list).then(resolve); + }, 160); + }); + }, + list:function(){ return found.slice(); } + }; +})();