Show the new position ID (and upgrade result) in /direct-join

After submit, poll eth_getTransactionReceipt and read the member id from the
MemberRegistered event (topics[1]); surface it in a prominent success box plus
the activity log, instead of leaving the user to find it in Telegram. Same for
upgrades (shows the new level). Reverts are reported clearly.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
martbost
2026-08-18 06:22:07 -05:00
parent c5b5ef7f86
commit 962eacd44c
2 changed files with 33 additions and 4 deletions
+6
View File
@@ -64,6 +64,12 @@
<p style="color:var(--muted);font-size:12px;margin:0">Only use this if you need to send a specific amount. The auto amount is read live from the contract's own price table.</p> <p style="color:var(--muted);font-size:12px;margin:0">Only use this if you need to send a specific amount. The auto amount is read live from the contract's own price table.</p>
</div> </div>
<div id="result" class="dj-card dj-hide" style="border-color:var(--ok);background:rgba(123,224,161,.08);text-align:center">
<div style="font-size:12px;text-transform:uppercase;letter-spacing:.12em;color:var(--ok);font-weight:800">✅ Success — save this</div>
<div id="resultId" style="font-size:46px;font-weight:900;color:var(--gold);margin:6px 0;letter-spacing:-1px">—</div>
<div id="resultSub" style="color:var(--muted);font-size:14px"></div>
</div>
<div class="dj-card"> <div class="dj-card">
<h2 style="margin:0 0 8px;font-size:16px">Activity</h2> <h2 style="margin:0 0 8px;font-size:16px">Activity</h2>
<div id="logWrap"><div id="log"></div></div> <div id="logWrap"><div id="log"></div></div>
+27 -4
View File
@@ -13,6 +13,8 @@
var SEL_UPGRADE ='0xd55ec697'; // upgrade() payable var SEL_UPGRADE ='0xd55ec697'; // upgrade() payable
var SEL_GETMEMBER='0x2ada2596';// getMember(address) view var SEL_GETMEMBER='0x2ada2596';// getMember(address) view
var SEL_GETCOSTS='0x735f87b9'; // getAllCosts() view -> 4x uint256[8] (reg std, reg prem, up std, up prem) var SEL_GETCOSTS='0x735f87b9'; // getAllCosts() view -> 4x uint256[8] (reg std, reg prem, up std, up prem)
var T_REGISTERED='0xe4a74887d749eb048f14bfef37b204477f3a5ff67055908b7c8cc62c202aef17'; // MemberRegistered(uint48 id,...)
var T_UPGRADED='0xc0b79a9e133d4dcbb1a606a57591d98dce93c7d5c86197a5caae22c4a1480049'; // MemberUpgraded(uint48 id,...)
var LEVELS=['','Scintilla','Ascensus','Fabrica','Culmen','Apex','Fastigium','Vertex','Corona']; var LEVELS=['','Scintilla','Ascensus','Fabrica','Culmen','Apex','Fastigium','Vertex','Corona'];
var $=function(id){return document.getElementById(id);}; var $=function(id){return document.getElementById(id);};
@@ -67,6 +69,16 @@
async function refreshBalance(){ async function refreshBalance(){
try{ var b=await req('eth_getBalance',[account,'latest']); $('bal').textContent=polStr(BigInt(b))+' POL'; }catch(e){} try{ var b=await req('eth_getBalance',[account,'latest']); $('bal').textContent=polStr(BigInt(b))+' POL'; }catch(e){}
} }
// poll for the mined receipt (via the wallet's own RPC)
async function waitReceipt(tx){
for(var i=0;i<60;i++){ try{ var r=await req('eth_getTransactionReceipt',[tx]); if(r) return r; }catch(e){} await new Promise(function(s){setTimeout(s,3000);}); }
return null;
}
// pull the member id from a contract event in the receipt (topics[1] = uint48 id)
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){} }
async function connect(){ 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; } if(!eth){ log('No wallet detected. Open this page in a browser with MetaMask (extension or the MetaMask in-app browser).','err'); return; }
@@ -105,8 +117,14 @@
var data=SEL_REGISTER+word(sponsor)+word(tier); var data=SEL_REGISTER+word(sponsor)+word(tier);
log('Sending REGISTER — sponsor #'+sponsor+', '+(tier===2?'Premium':'Standard')+', paying '+polStr(val)+' POL. Confirm in your wallet…'); log('Sending REGISTER — sponsor #'+sponsor+', '+(tier===2?'Premium':'Standard')+', paying '+polStr(val)+' POL. Confirm in your wallet…');
var tx=await req('eth_sendTransaction',[{from:account,to:CONTRACT,value:hexWei(val),data:data}]); var tx=await req('eth_sendTransaction',[{from:account,to:CONTRACT,value:hexWei(val),data:data}]);
log('✅ Submitted: <a href="https://polygonscan.com/tx/'+tx+'" target="_blank" rel="noopener">'+tx.slice(0,18)+'…</a> — wait for it to confirm, then your position is live.','ok'); log('Submitted: <a href="https://polygonscan.com/tx/'+tx+'" target="_blank" rel="noopener">'+tx.slice(0,18)+'…</a> — waiting for confirmation…','ok');
setTimeout(refreshBalance,4000); var rc=await waitReceipt(tx);
if(!rc){ log('Still pending after a few minutes — your new ID will appear on Polygonscan once it mines.',''); return; }
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 <strong>#'+newId+'</strong>.','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'); } }catch(e){ log('Register failed / rejected: '+(e.message||e),'err'); }
} }
@@ -120,8 +138,13 @@
var data=SEL_UPGRADE; var data=SEL_UPGRADE;
log('Sending UPGRADE '+LEVELS[level]+' → '+LEVELS[level+1]+', paying '+polStr(val)+' POL. Confirm in your wallet…'); log('Sending UPGRADE '+LEVELS[level]+' → '+LEVELS[level+1]+', paying '+polStr(val)+' POL. Confirm in your wallet…');
var tx=await req('eth_sendTransaction',[{from:account,to:CONTRACT,value:hexWei(val),data:data}]); var tx=await req('eth_sendTransaction',[{from:account,to:CONTRACT,value:hexWei(val),data:data}]);
log('✅ Submitted: <a href="https://polygonscan.com/tx/'+tx+'" target="_blank" rel="noopener">'+tx.slice(0,18)+'…</a>','ok'); log('Submitted: <a href="https://polygonscan.com/tx/'+tx+'" target="_blank" rel="noopener">'+tx.slice(0,18)+'…</a> — waiting for confirmation…','ok');
setTimeout(refreshBalance,4000); var rc=await waitReceipt(tx);
if(!rc){ log('Still pending — check the tx on Polygonscan.',''); return; }
if(rc.status==='0x0'){ log('⚠️ Upgrade reverted — your POL was returned (minus gas).','err'); return; }
refreshBalance();
showResult(LEVELS[level+1],'Upgraded to level '+(level+1)+' of 8.');
log('🎉 Confirmed — upgraded to <strong>'+LEVELS[level+1]+'</strong>.','ok');
}catch(e){ log('Upgrade failed / rejected: '+(e.message||e),'err'); } }catch(e){ log('Upgrade failed / rejected: '+(e.message||e),'err'); }
} }