diff --git a/public/chat.js b/public/chat.js index 2fae541..af4f2fd 100644 --- a/public/chat.js +++ b/public/chat.js @@ -49,7 +49,7 @@ {k:['tier','standard','premium tier','standard tier','premium vs standard','which tier','half','smaller payment','less than expected','why is my payment'], a:()=>`There are two tiers. Premium is what our whole team builds at (${pol()} POL entry) — full payments. Standard costs about half and pays/earns half at every level. So if a payment ever comes in smaller than expected, it usually came from a Standard-tier position below you. Your tier is set when you join and can't be changed later (upgrading advances your level, not your tier), so always join Premium and make sure the people you bring on do too. Full breakdown: how-pay-works.`}, {k:['dashboard','my dashboard','my page','my position','my team','check my','see my','pipeline','my stats','alerts','notify me','email me','get notified','message','messages','contact my sponsor','contact my upline','contact my downline','reach my team'], - a:()=>`Your Member Dashboard is at rmcircle.team/my — enter your ID to see your position, your team (with a depth summary showing members per generation), your payments, your pipeline (money forming below you), any spillover under you, and a Coach Your Team panel that tells you exactly who in your leg needs a nudge and what to say. You can also turn on email alerts there, and use Messages — wallet-verified messaging with your upline and your team (sign in once with your wallet; no email needed; only people on your matrix lines can message you). To share, use your personal invite page: rmcircle.team/join/<your ID>.`}, + a:()=>`Your Member Dashboard is at rmcircle.team/my — enter your ID to see your position, your team (with a depth summary showing members per generation), your payments, your pipeline (money forming below you), any spillover under you, and a Coach Your Team panel that tells you exactly who in your leg needs a nudge and what to say. When you're qualified, you can also upgrade your level right from your dashboard — connect the wallet that owns your position and confirm; the exact cost is read live from the contract. You can also turn on email alerts there, and use Messages — wallet-verified messaging with your upline and your team (sign in once with your wallet; no email needed; only people on your matrix lines can message you). To share, use your personal invite page: rmcircle.team/join/<your ID>.`}, {k:['level','levels','upgrade','scintilla','ascensus','fabrica','culmen','apex','fastigium','vertex','corona','8 levels'], a:()=>`There are 8 Premium levels: Scintilla, Ascensus, Fabrica, Culmen, Apex, Fastigium, Vertex, Corona. Everyone starts at Scintilla. Upgrade as quickly as practical — ideally using earned POL — because the first two payments at each level are designed to help fund your next upgrade. Stay aware of your active downline's levels so you don't fall behind.`}, {k:['30 positions','goal','milestone','matrix','how many people','team size'], diff --git a/public/my.html b/public/my.html index 860fdbb..9d14657 100644 --- a/public/my.html +++ b/public/my.html @@ -16,7 +16,7 @@
-
+

Your team

Your position's matrix — the rollup line on each card counts everyone underneath, all the way down. Click a position to drill into that leg. Open slots are where the next placements land.

✓ qualified (2/2 directs) · P Premium · S Standard · ⬇ everyone below that position (all generations) and the POL they've earned · ↧ spillover = placed there by upline activity; only members who join with a position's own ID count toward its 2/2

Your pipeline

Money forming below you. Each generation in your leg pays your position at exactly one level — when a member's level catches up to their depth, their next upgrade comes to you.

diff --git a/public/my.js b/public/my.js index eef9e78..86cb4ec 100644 --- a/public/my.js +++ b/public/my.js @@ -122,6 +122,7 @@ ?`
${inc.map(p=>``).join('')}
WhenFrom memberForAmount
${date(p.ts)}#${p.fromId}${esc(p.desc)}${fmt(p.pol)} POL
` :'
No payments yet — they appear here the moment they land on-chain.
'; renderNextStep(d); + renderUpgradeCTA(d); renderGens(d); renderPipeline(d); renderCoach(d); @@ -159,6 +160,75 @@ }).join(''); el.innerHTML=`
Team depth — members per generation
${rows}

Full generations duplicate: each one can hold twice the last. A generation pays this position at exactly one level — stay qualified and at that level to catch it.

`; } + // On-page upgrade: connect the wallet that OWNS this position, read the + // exact next-level cost from the contract (BigInt — never float-derived), + // send upgrade(). Wrong value would simply revert; ownership is enforced by + // matching the connected account to the position's on-chain account. + const UPG={CONTRACT:'0x33bdaeefd6d17d80ae53816c916dfb26c4fb2daf',POLYGON:'0x89',SEL_UPGRADE:'0xd55ec697',SEL_GETCOSTS:'0x735f87b9'}; + let upEth=null; + function renderUpgradeCTA(d){ + const el=document.getElementById('dUpgrade');if(!el)return; + const ns=d.nextStep||{}; + if(ns.kind!=='upgrade'||d.directCount<2){el.innerHTML='';return;} + const name=LEVELS[ns.nextLevel-1]||('Level '+ns.nextLevel); + el.innerHTML=`
+

⬆️ Upgrade to ${esc(name)} — right from this page

+

Exact cost ${fmt(ns.cost)} POL, read live from the contract. Connect the wallet that owns position #${d.id}, confirm once, done. ${ns.funded?'Your wallet already covers it ✓':'Your wallet does not cover it yet — you can time it to your next catches, or top up below.'}

+ + ${ns.funded?'':``} + +
+

Upgrades are optional and self-paced — never use funds you can't afford to lose. If anything is off, the contract simply rejects it and you keep your POL (minus tiny gas).

+
`; + const go=document.getElementById('upgGo');if(go)go.addEventListener('click',function(){doUpgrade(d,ns);}); + const fu=document.getElementById('upgFund');if(fu)fu.addEventListener('click',async function(){ + try{const need=Math.max(62,Math.ceil(ns.cost- (0))+5);const r=await(await fetch('/api/public/moonpay-url?address='+encodeURIComponent(d.account||'')+'&pol='+need)).json();if(r&&r.url)window.open(r.url,'_blank','noopener');}catch(e){} + }); + } + function upgLog(msg,bad){const l=document.getElementById('upgLog');if(l){l.innerHTML=msg;l.style.color=bad?'var(--danger)':'var(--muted)';}} + async function doUpgrade(d,ns){ + try{ + upgLog('Looking for your wallet…'); + upEth=await window.RMCWallet.pick(); + if(!upEth){ + const h=document.getElementById('upgHelp');if(h){h.style.display='block'; + const here=location.host+location.pathname+location.search; + document.getElementById('upgMM').href='https://metamask.app.link/dapp/'+here; + document.getElementById('upgTW').href='https://link.trustwallet.com/open_url?coin_id=966&url='+encodeURIComponent(location.href);} + upgLog('No wallet in this browser — use the wallet-app links above, or install MetaMask on desktop.',true);return; + } + const accs=await upEth.request({method:'eth_requestAccounts'});const account=(accs[0]||'').toLowerCase(); + if(!d.account||account!==String(d.account).toLowerCase()){ + upgLog('This wallet ('+account.slice(0,6)+'…'+account.slice(-4)+') does not own position #'+d.id+' — connect the wallet that registered it ('+String(d.account||'').slice(0,6)+'…'+String(d.account||'').slice(-4)+').',true);return; + } + // network + const cid=await upEth.request({method:'eth_chainId'}); + if(cid!==UPG.POLYGON){ + upgLog('Switching to Polygon…'); + try{await upEth.request({method:'wallet_switchEthereumChain',params:[{chainId:UPG.POLYGON}]});} + catch(e){if(e&&e.code===4902){await upEth.request({method:'wallet_addEthereumChain',params:[{chainId:UPG.POLYGON,chainName:'Polygon Mainnet',nativeCurrency:{name:'POL',symbol:'POL',decimals:18},rpcUrls:['https://polygon-rpc.com'],blockExplorerUrls:['https://polygonscan.com']}]});}else{throw e;}} + } + // exact cost from the contract (BigInt) + upgLog('Reading the exact upgrade cost from the contract…'); + const r=await upEth.request({method:'eth_call',params:[{to:UPG.CONTRACT,data:UPG.SEL_GETCOSTS},'latest']}); + const words=[];for(let i=2;iview tx'); + for(let i=0;i<60;i++){ + try{const rc=await upEth.request({method:'eth_getTransactionReceipt',params:[tx]}); + if(rc){if(rc.status==='0x0'){upgLog('⚠️ The upgrade reverted — your POL was returned (minus gas). Wait a moment and try again.',true);return;} + upgLog('🎉 Upgraded! Refreshing your dashboard…');setTimeout(function(){location.reload();},2500);return;} + }catch(e){} + await new Promise(function(s){setTimeout(s,3000);}); + } + upgLog('Still pending — it will land shortly; refresh in a minute.'); + }catch(e){upgLog('Upgrade failed / rejected: '+esc(e.message||String(e)),true);} + } + // Wallet-verified messaging: sign-in = one free personal_sign; identity is // the wallet that owns a position; permissions follow the matrix lines. function renderMessages(d){ diff --git a/server.js b/server.js index a259a3e..324875a 100644 --- a/server.js +++ b/server.js @@ -47,6 +47,7 @@ FACTS: - RESILIENCE ("what if the creators disappear / owner loses keys / it falls apart over time"): the contract is autonomous and immutable — NO admin action, heartbeat, or living operator is required for joins, upgrades, matrix placement, or payouts; there is no pause switch and no expiry. Verified on-chain that the founder, development, and fee-receiver wallets are ordinary wallets (EOAs), NOT smart contracts — an ordinary wallet always accepts incoming POL even if its key is lost forever, so a dead or abandoned admin wallet cannot block any member payment (only the project's OWN uncollected fee would sit idle). The contract stores no balance (every payment is delivered in the same transaction). If the owner's key were lost, only the four limited admin powers freeze in place; members are unaffected. Details in section 6 of https://rmcircle.team/contract. - Current team sponsor: ${a ? `ID ${a.id}${c.showSponsorName && a.name ? ` (${a.name})` : ''}, ${a.directs}/2 directs` : 'shown on the start page'}. ${waiting} placement(s) waiting. Placements rotate as positions qualify — always verify on https://rmcircle.team/start right before joining. - Site pages: https://rmcircle.team/ (strategy overview + roadmap + live team stats), https://rmcircle.team/start (current sponsor + join steps), https://rmcircle.team/training (6 videos — team overview, wallet setup, funding, the new connect-wallet join flow on the site, the dApp backup method, how payments work — + spillover article), https://rmcircle.team/how-pay-works (the two income streams shown as a pay-flow diagram + Premium/Standard tier comparison), https://rmcircle.team/contract (plain-language security review of the verified smart contract — code can't change, no pooled funds, locked rules, honest list of operator powers), https://rmcircle.team/my (member dashboard), https://rmcircle.team/tools (for existing team members who want to promote — share-ready promo videos, copy-paste social posts, short/long email swipes, and a downloadable banner kit in every standard size; to write promos in their own voice, mybrandedvoice.com), https://rmcircle.team/disclaimer (affiliate/earnings/risk disclosures). +- UPGRADING FROM THE DASHBOARD: a qualified member can upgrade their level directly on their dashboard (rmcircle.team/my/) — an "Upgrade" card appears with the exact next-level cost read live from the contract; they connect the wallet that OWNS the position, confirm one transaction, done. The site never touches the funds (wallet pays the contract directly). If the wallet doesn't cover the cost, the card offers the MoonPay card-buy option. On phones, open the page inside the wallet app's browser. - MESSAGES (on-site, wallet-verified): every member dashboard has a Messages panel — sign in once with the wallet that owns your position (a free signature, cannot move funds), then message your upline or anyone in your own team, or broadcast to your whole team. Spam-proof by design: messaging only works along your own matrix lines, so strangers can't message you. Unread messages show as a bell on your dashboard. Members are told the team admin can review messages for abuse. No email address needed. - BUYING POL WITH A CARD (for people brand new to crypto): the site links to MoonPay (moonpay.com/buy/pol) on the training page, the start page, and automatically on the join page when a connected wallet's balance is short. Guidance to give: choose POL on the POLYGON network, send it to YOUR OWN wallet address, buy about entry + gas (~385 POL). MoonPay is an independent company (merchant of record) — it handles ID verification and charges its own card fee (~4.5%); this site never touches or holds anyone's money. First purchases can take a few minutes to arrive. - COACHING DOCTRINE (teach forward): whenever you give a member guidance about helping their team, frame it so they learn to run the same play for their own two — e.g. "do X, then show your two how to spot this on THEIR dashboard's Coach Your Team panel." The goal is never just fixing one member's next step; it is teaching people how to teach. Every member's dashboard has the same Coach Your Team panel, so the play duplicates at every depth.