New members are signed in to their inbox right after registering, so the profile gate actually fires

Found by checking the live data: 59 positions registered in the 36h to 2026-09-16 and not one has a
profile row, including #785 which registered 20 minutes after the gate deployed. The join flow
redirects to /my/<newId> but the member arrives with no inbox session, so the gate never runs and the
leader still cannot reach them. join-now.js now takes the one free personal_sign immediately after the
registration confirms, while the wallet is still connected, which is the cheapest moment to ask.
Best-effort: declining does not block the join, and they are asked again on their next sign-in.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
martbost
2026-09-16 18:11:12 -05:00
parent 2f90e1a97f
commit 6f1c9ff8ca
+17
View File
@@ -77,6 +77,22 @@ fetch('/api/public/config').then(function(r){return r.json()}).then(function(c){
}
var lastBal=null;
// One free signature straight after the join, while the wallet is still connected:
// it opens their inbox session so the member-profile gate can ask for a username
// and email on the dashboard. Best-effort — if they decline, the join still stands
// and they are asked again the first time they sign in.
async function signInNewMember(newId){
try{
$('resultSub').innerHTML='Welcome to the team! One free signature sets up your member profile…';
var ch=await (await fetch('/api/public/msg-challenge',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({address:account})})).json();
if(!ch||!ch.message) return;
var hex='0x'; for(var i=0,b=new TextEncoder().encode(ch.message);i<b.length;i++) hex+=b[i].toString(16).padStart(2,'0');
var sig=await req('personal_sign',[hex,account]);
var v=await (await fetch('/api/public/msg-verify',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({address:account,signature:sig})})).json();
if(v&&v.ok) $('resultSub').innerHTML='Signed in. Taking you to your position page…';
else $('resultSub').innerHTML='Welcome to the team! Taking you to your position page…';
}catch(e){ try{ $('resultSub').innerHTML='Welcome to the team! Taking you to your position page…'; }catch(x){} }
}
async function refreshBalance(){ try{ var b=await req('eth_getBalance',[account,'latest']); lastBal=BigInt(b); $('bal').textContent=polStr(lastBal)+' POL'; updateFundBox(); }catch(e){} }
// Card on-ramp: shown only when the connected wallet can't cover the entry.
@@ -174,6 +190,7 @@ fetch('/api/public/config').then(function(r){return r.json()}).then(function(c){
log('🎉 Confirmed — your position is <strong>#'+newId+'</strong>. Redirecting to your dashboard…','ok');
try{ el_scroll('result'); }catch(e){}
try{sessionStorage.setItem('rmc.fresh','1');}catch(e){}
signInNewMember(newId);
setTimeout(function(){ location.href='/my/'+newId; }, 4500);
} else {
log('Confirmed on-chain. Open your dashboard at <a href="/my">/my</a> and enter your new ID (also shown on Polygonscan).','ok');