Wallet system (sats ledger + deposit + spend), HydraProxy fulfillment queue, paid IP-quality scorer (85/100 verified)

This commit is contained in:
drjones
2026-09-20 18:51:47 -07:00
parent 16dde93ce2
commit a7d6b98183
8 changed files with 481 additions and 12 deletions

53
templates/quality.html Normal file
View File

@@ -0,0 +1,53 @@
{% extends "base.html" %}
{% block title %}IP Quality Tester — Clean Proxys{% endblock %}
{% block body %}
<h2>IP Quality <span class="accent">Tester</span></h2>
<p class="sub">Check how clean a proxy is before you trust it. {{ price }} sats (~$0.15) per check, billed to your wallet.</p>
<div class="card">
<h3>Run a check</h3>
<p class="muted" style="font-size:14px">Leave blank to test your own Clean Proxys proxy, or paste any <span class="mono">socks5://</span> or <span class="mono">http://</span> proxy.</p>
<form id="qf" onsubmit="return runQuality(event)">
<label>Proxy (optional)</label>
<input type="text" id="proxy" placeholder="socks5://user:pass@host:1080" style="font-family:var(--mono)">
<input type="submit" value="Run quality check ({{ price }} sats)">
</form>
</div>
<div id="result" style="margin-top:18px"></div>
<script>
async function runQuality(e){
e.preventDefault();
const r = document.getElementById('result');
r.innerHTML = '<div class="card"><p class="muted">Running checks…</p></div>';
const fd = new FormData();
fd.append('proxy', document.getElementById('proxy').value);
let data;
try { data = await (await fetch('/quality/run', {method:'POST', body: fd})).json(); }
catch(err){ r.innerHTML = '<div class="flash warn">Check failed.</div>'; return false; }
if (data.error){
r.innerHTML = '<div class="flash warn">'+data.error+' — <a href="/wallet">deposit</a> first.</div>';
return false;
}
const b = data.breakdown || {};
const checksHtml = (data.checks||[]).map(c =>
'<tr><td>'+(c[1]?'✅':'❌')+'</td><td>'+c[0]+'</td><td class="muted" style="font-size:13px">'+c[2]+'</td></tr>'
).join('');
const scoreColor = data.score >= 70 ? 'var(--neon)' : (data.score >= 40 ? 'var(--warn)' : 'var(--danger)');
const bl = (b.blacklists && b.blacklists.length) ? b.blacklists.join(', ') : 'none';
r.innerHTML =
'<div class="card">'
+ '<div style="display:flex;align-items:center;gap:22px;flex-wrap:wrap">'
+ '<div style="font-size:54px;font-weight:800;font-family:var(--mono);color:'+scoreColor+'">'+data.score+'<span style="font-size:18px;color:var(--muted)">/100</span></div>'
+ '<div><div class="lbl" style="color:var(--muted)">'+ (b.geo||'') + ' · ' + (b.isp||'') + '</div>'
+ '<div class="muted" style="font-size:14px">egress <span class="mono">'+(b.egress_ip||'-')+'</span> · '+ (b.latency_ms||'') +'ms</div>'
+ '<div class="muted" style="font-size:13px">hosting: '+(b.hosting?'yes':'no')+' · proxy-flagged: '+(b.proxy_flagged?'yes':'no')+' · blacklists: '+bl+'</div></div>'
+ '</div>'
+ '<table style="width:100%;margin-top:18px"><tr><th></th><th>Check</th><th>Detail</th></tr>'+checksHtml+'</table>'
+ '<p class="muted" style="font-size:12px;margin-top:12px">charged '+data.charged_sats+' sats</p>'
+ '</div>';
return false;
}
</script>
{% endblock %}