Connect your wallet and enter your Premium position on the Polygon smart contract — paid straight from your wallet, verifiable on-chain. You’ll be placed under the current team position automatically. New here? Watch the training first.
+
+
Loading the current team placement…
+
+
+
1 · Connect your wallet
+
Use MetaMask or Trust Wallet on Polygon, funded with enough POL for your Premium entry plus a little gas.
+
+
+
Wallet—
+
NetworkPolygon Mainnet ✓
+
Balance—
+
+
+
+
+
+
2 · Join
+
TierPremium (the tier the team builds at)
+
You will pay—
+
+
Confirm the amount in your wallet before signing. If anything is off, the contract simply rejects it and you keep your POL.
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 ab7080d..41d5e7a 100644
--- a/public/direct-join.js
+++ b/public/direct-join.js
@@ -78,7 +78,7 @@
function receiptEventId(rc,topic0){
var id=null; (rc.logs||[]).forEach(function(l){ if(l.address&&l.address.toLowerCase()===CONTRACT&&l.topics&&l.topics[0]===topic0) id=parseInt(l.topics[1],16); }); return id;
}
- function showResult(big,sub){ var el=$('result'); if(!el) return; $('resultId').textContent=big; $('resultSub').textContent=sub; el.style.display='block'; try{el.scrollIntoView({behavior:'smooth',block:'center'});}catch(e){} }
+ 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; }
@@ -123,7 +123,7 @@
if(rc.status==='0x0'){ log('⚠️ Reverted on-chain — no position created; your POL was returned (minus gas). Re-check the sponsor ID and amount.','err'); return; }
refreshBalance();
var newId=receiptEventId(rc,T_REGISTERED);
- if(newId){ showResult('#'+newId,'Your new position under sponsor #'+sponsor+' is live. Save this ID.'); log('🎉 Confirmed — your new position is #'+newId+'.','ok'); }
+ if(newId){ showResult('#'+newId,'Your new position under sponsor #'+sponsor+' is live. Save this ID.',newId); log('🎉 Confirmed — your new position is #'+newId+'.','ok'); }
else log('Confirmed on-chain, but could not read the ID from the receipt — check the tx on Polygonscan.','ok');
}catch(e){ log('Register failed / rejected: '+(e.message||e),'err'); }
}
diff --git a/public/join-now.js b/public/join-now.js
new file mode 100644
index 0000000..0799d86
--- /dev/null
+++ b/public/join-now.js
@@ -0,0 +1,112 @@
+/* RM Circle — public direct-join engine (dormant fallback; served only when
+ config.dappFallbackPublic is on). Talks only to window.ethereum (CSP-safe).
+ Auto-assigns the current rotation sponsor, registers the member's own wallet,
+ then sends them to their live position page /my/. Zero custody. */
+(function(){
+ 'use strict';
+ var CONTRACT='0x33bdaeefd6d17d80ae53816c916dfb26c4fb2daf';
+ var POLYGON_HEX='0x89';
+ var SEL_REGISTER='0x30de37e4'; // register(uint48 sponsorId, uint8 tier) payable
+ var SEL_GETMEMBER='0x2ada2596'; // getMember(address)
+ var SEL_GETCOSTS='0x735f87b9'; // getAllCosts()
+ var T_REGISTERED='0xe4a74887d749eb048f14bfef37b204477f3a5ff67055908b7c8cc62c202aef17';
+
+ var $=function(id){return document.getElementById(id);};
+ var eth=window.ethereum;
+ 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;}
+ function word(n){return BigInt(n).toString(16).padStart(64,'0');}
+ function addrWord(a){return a.toLowerCase().replace(/^0x/,'').padStart(64,'0');}
+ function polStr(wei){return (Number(wei)/1e18).toFixed(2);}
+ function hexWei(wei){return '0x'+BigInt(wei).toString(16);}
+ async function req(method,params){ if(!eth) throw new Error('No wallet found'); return await eth.request({method:method,params:params||[]}); }
+ async function ethCall(data){ return await req('eth_call',[{to:CONTRACT,data:data},'latest']); }
+
+ async function loadCosts(){
+ var r=await ethCall(SEL_GETCOSTS); var d=r.slice(2), w=[];
+ for(var i=0;i#'+sp.id+(sp.name?' ('+sp.name+')':'')+' — the current team placement.'; }
+ else { $('sponsorLine').textContent='Loading the current team placement…'; }
+ }catch(e){ $('sponsorLine').textContent='Could not load the current sponsor — please refresh.'; }
+ }
+
+ 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{
+ log('Requesting wallet connection…');
+ var accs=await req('eth_requestAccounts'); account=accs[0];
+ await ensurePolygon(); await loadCosts();
+ $('wallet').textContent=account.slice(0,6)+'…'+account.slice(-4);
+ $('connected').style.display='block'; $('connectBtn').style.display='none';
+ await refreshBalance();
+ $('joinCost').textContent=polStr(regValue())+' POL';
+ var pos=await readPosition(account);
+ if(pos){ $('already').style.display='block'; $('already').innerHTML='This wallet already holds position — open your dashboard. To create a new position, connect a different wallet.'; $('joinBtn').disabled=true; }
+ $('joinBox').style.display='block';
+ log('Connected. Review the amount, then Join.','ok');
+ }catch(e){ log('Connect failed: '+(e.message||e),'err'); }
+ }
+
+ async function doJoin(){
+ try{
+ if(!sponsorId){ log('Still loading the current sponsor — one moment.','err'); await loadSponsor(); if(!sponsorId) return; }
+ await ensurePolygon();
+ var val=regValue();
+ var data=SEL_REGISTER+word(sponsorId)+word(2);
+ log('Joining under #'+sponsorId+', Premium — paying '+polStr(val)+' POL. Confirm in your wallet…');
+ $('joinBtn').disabled=true;
+ var tx=await req('eth_sendTransaction',[{from:account,to:CONTRACT,value:hexWei(val),data:data}]);
+ log('Submitted — waiting for confirmation… view tx','ok');
+ var rc=await waitReceipt(tx);
+ if(!rc){ log('Still pending. Once it mines, open your dashboard at /my.',''); $('joinBtn').disabled=false; return; }
+ if(rc.status==='0x0'){ log('⚠️ The transaction reverted — no position created, and your POL was returned (minus gas). Please try again.','err'); $('joinBtn').disabled=false; return; }
+ var newId=receiptEventId(rc);
+ if(newId){
+ $('result').style.display='block';
+ $('resultId').textContent='#'+newId;
+ $('resultSub').innerHTML='Welcome to the team! Taking you to your position page…';
+ $('resultLink').href='/my/'+newId; $('resultLink').style.display='inline-flex';
+ log('🎉 Confirmed — your position is #'+newId+'. Redirecting to your dashboard…','ok');
+ try{ el_scroll('result'); }catch(e){}
+ setTimeout(function(){ location.href='/my/'+newId; }, 4500);
+ } else {
+ log('Confirmed on-chain. Open your dashboard at /my and enter your new ID (also shown on Polygonscan).','ok');
+ $('joinBtn').disabled=false;
+ }
+ }catch(e){ log('Join failed / rejected: '+(e.message||e),'err'); $('joinBtn').disabled=false; }
+ }
+ function el_scroll(id){ var e=$(id); if(e&&e.scrollIntoView) e.scrollIntoView({behavior:'smooth',block:'center'}); }
+
+ 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/server.js b/server.js
index ff5b380..376925e 100644
--- a/server.js
+++ b/server.js
@@ -557,7 +557,7 @@ async function handleApi(req,res,pathname){
const maxOrder=sponsors.reduce((m,s)=>Math.max(m,s.sortOrder||0),0);sponsors.push({id:String(id).trim(),name:String(name).trim(),parentId:String(parentId||'').trim(),directs:0,level,status:sponsors.some(s=>s.status==='active')?'waiting':'active',sortOrder:maxOrder+10,clicks:0,notes:String(notes||'').trim(),email:String(email||'').trim().slice(0,120)});sponsors=normalizeStatuses(sponsors);saveSponsors(sponsors);return json(res,201,{sponsors});
}
if(req.method==='PATCH'&&pathname==='/api/admin/config'){
- const b=await bodyJson(req),cur=getConfig(),next={...cur};for(const k of ['siteName','programName','bridgeHeadline','bridgeSubheadline','premiumEntryPol','dappReferralBaseUrl','telegramUrl','supportLabel','showSponsorName','showQueueProgress','bemobPostbackUrl','telegramBotToken','telegramChatId','telegramTopicId','telegramRecruitTopicId','teamRootId','emailFrom','teamAlertEmail','ownerIds','ownerAlertEmail','orgRootId','tweetEnabled','tweetCtaUrl','tweetHashtags','blotatoTwitterId'])if(Object.prototype.hasOwnProperty.call(b,k))next[k]=b[k];next.premiumEntryPol=Number(next.premiumEntryPol)||362;next.updatedAt=new Date().toISOString();writeJson(CONFIG_FILE,next);return json(res,200,{config:next});
+ const b=await bodyJson(req),cur=getConfig(),next={...cur};for(const k of ['siteName','programName','bridgeHeadline','bridgeSubheadline','premiumEntryPol','dappReferralBaseUrl','telegramUrl','supportLabel','showSponsorName','showQueueProgress','bemobPostbackUrl','telegramBotToken','telegramChatId','telegramTopicId','telegramRecruitTopicId','teamRootId','emailFrom','teamAlertEmail','ownerIds','ownerAlertEmail','orgRootId','tweetEnabled','tweetCtaUrl','tweetHashtags','blotatoTwitterId','dappFallbackPublic'])if(Object.prototype.hasOwnProperty.call(b,k))next[k]=b[k];next.premiumEntryPol=Number(next.premiumEntryPol)||362;next.updatedAt=new Date().toISOString();writeJson(CONFIG_FILE,next);return json(res,200,{config:next});
}
const m=pathname.match(/^\/api\/admin\/sponsors\/([^/]+)(?:\/(increment|activate|qualify|reset|move))?$/);
if(m){const id=decodeURIComponent(m[1]),action=m[2]||null;let sponsors=getSponsors(),idx=sponsors.findIndex(s=>s.id===id);if(idx<0)return json(res,404,{error:'Sponsor not found.'});
@@ -619,7 +619,7 @@ const server=http.createServer(async(req,res)=>{
if((mj=pathname.match(/^\/join\/(\d{1,15})$/)))return serveMemberPage(req,res,path.join(PUBLIC_DIR,'join.html'),'join',mj[1]);
}
let file;
- if(pathname==='/')file=path.join(PUBLIC_DIR,'index.html');else if(pathname==='/start'||pathname==='/start/')file=path.join(PUBLIC_DIR,'start.html');else if(pathname==='/training'||pathname==='/training/')file=path.join(PUBLIC_DIR,'training.html');else if(pathname==='/admin'||pathname==='/admin/')file=path.join(PUBLIC_DIR,'admin.html');else if(pathname==='/my'||pathname==='/my/'||/^\/my\/\d{1,15}$/.test(pathname))file=path.join(PUBLIC_DIR,'my.html');else if(pathname==='/contract'||pathname==='/contract/')file=path.join(PUBLIC_DIR,'contract.html');else if(pathname==='/disclaimer'||pathname==='/disclaimer/')file=path.join(PUBLIC_DIR,'disclaimer.html');else if(pathname==='/how-pay-works'||pathname==='/how-pay-works/')file=path.join(PUBLIC_DIR,'how-pay-works.html');else if(pathname==='/tools'||pathname==='/tools/')file=path.join(PUBLIC_DIR,'tools.html');else if(pathname==='/direct-join'||pathname==='/direct-join/'){if(!getSession(req)){res.writeHead(302,{Location:'/admin'});return res.end();}file=path.join(ROOT,'private','direct-join.html');}else if(/^\/join\/\d{1,15}$/.test(pathname))file=path.join(PUBLIC_DIR,'join.html');else if(pathname==='/join'||pathname==='/join/'){res.writeHead(302,{Location:'/start'});return res.end();}else{
+ if(pathname==='/')file=path.join(PUBLIC_DIR,'index.html');else if(pathname==='/start'||pathname==='/start/')file=path.join(PUBLIC_DIR,'start.html');else if(pathname==='/training'||pathname==='/training/')file=path.join(PUBLIC_DIR,'training.html');else if(pathname==='/admin'||pathname==='/admin/')file=path.join(PUBLIC_DIR,'admin.html');else if(pathname==='/my'||pathname==='/my/'||/^\/my\/\d{1,15}$/.test(pathname))file=path.join(PUBLIC_DIR,'my.html');else if(pathname==='/contract'||pathname==='/contract/')file=path.join(PUBLIC_DIR,'contract.html');else if(pathname==='/disclaimer'||pathname==='/disclaimer/')file=path.join(PUBLIC_DIR,'disclaimer.html');else if(pathname==='/how-pay-works'||pathname==='/how-pay-works/')file=path.join(PUBLIC_DIR,'how-pay-works.html');else if(pathname==='/tools'||pathname==='/tools/')file=path.join(PUBLIC_DIR,'tools.html');else if(pathname==='/direct-join'||pathname==='/direct-join/'){if(!getSession(req)){res.writeHead(302,{Location:'/admin'});return res.end();}file=path.join(ROOT,'private','direct-join.html');}else if(pathname==='/join-now'||pathname==='/join-now/'){if(!getConfig().dappFallbackPublic){res.writeHead(302,{Location:'/start'});return res.end();}file=path.join(ROOT,'private','join-now.html');}else if(/^\/join\/\d{1,15}$/.test(pathname))file=path.join(PUBLIC_DIR,'join.html');else if(pathname==='/join'||pathname==='/join/'){res.writeHead(302,{Location:'/start'});return res.end();}else{
const safe=path.normalize(pathname).replace(/^([.][.][/\\])+/, '').replace(/^[/\\]+/,'');file=path.join(PUBLIC_DIR,safe);if(!file.startsWith(PUBLIC_DIR))file='';
}
if(file&&staticFile(req,res,file))return;return staticFile(req,res,path.join(PUBLIC_DIR,'404.html'),404);