flowexecutor's picture
Upload 2 files
4c8b86e verified
Raw History Blame Contribute Delete
9.08 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Flow Verification Desk</title>
<style>
:root { color-scheme: dark; }
body { font-family: system-ui, -apple-system, Segoe UI, Roboto, sans-serif;
background: #0b1020; color: #e8ecf4; margin: 0; padding: 24px 16px 48px; }
main { max-width: 760px; margin: 0 auto; }
h1 { font-size: 28px; margin: 0 0 8px; }
h2 { font-size: 20px; margin: 28px 0 8px; }
p, li { line-height: 1.55; }
.standing { font-style: italic; color: #9fb4d8; }
.card { background: #131a2e; border: 1px solid #263252; border-radius: 12px;
padding: 18px; margin-top: 16px; }
label { display: block; font-size: 14px; color: #b9c6de; margin-bottom: 6px; }
.row { display: flex; gap: 8px; flex-wrap: wrap; }
input { flex: 1 1 320px; background: #0b1020; color: #e8ecf4; border: 1px solid #33436b;
border-radius: 8px; padding: 10px 12px; font-size: 15px; }
button { background: #2563eb; color: #fff; border: 0; border-radius: 8px;
padding: 10px 18px; font-size: 15px; cursor: pointer; }
button:disabled { opacity: .55; cursor: default; }
#out { margin-top: 16px; white-space: pre-wrap; word-break: break-word; }
#out pre { background: #0b1020; border: 1px solid #263252; border-radius: 8px;
padding: 12px; overflow-x: auto; white-space: pre; }
a { color: #7aa5ff; }
.muted { color: #93a3c0; font-size: 14px; }
</style>
</head>
<body>
<main>
<h1>Flow Verification Desk</h1>
<p>Flow is the checker for agent payments on Base. Agents are paying
each other now, but a claim is not a record. This desk runs one free
check: paste a Base address and read the verdict the evidence
supports.</p>
<p class="standing">Claims frozen. Recomputed from source. Receipts public.</p>
<div class="card">
<label for="addr">Base address (contract or wallet)</label>
<div class="row">
<input id="addr" type="text" placeholder="0x..." autocomplete="off" spellcheck="false">
<button id="run" type="button">Run the free check</button>
</div>
<div id="out" aria-live="polite"></div>
<p class="muted">This page runs in your browser and calls Flow's public
endpoint directly. A grade is shown only when the endpoint actually
returns one β€” if the verifier cannot be reached, the result is
UNVERIFIED and no grade is shown. A verdict is a check against the
evidence readable at call time, not a certification of safety.</p>
</div>
<h2>The paid doors</h2>
<p>The check above is the free basic tier. The full menu runs over x402
at <a href="https://flow-kg4x.vercel.app">flow-kg4x.vercel.app</a> β€”
prices printed before any sale, the same for everyone:</p>
<ul>
<li><strong>PayCheck β€” $0.50 USDC.</strong> Before you pay this agent,
check. One call grades a payee before payment: payee kind and history,
address-poisoning look-alike detection, wallet approval exposure,
contract safety, and recent settlement history β€” one finished grade
with the evidence under it.</li>
<li><strong>Scope Report β€” $25 USDC.</strong> The full authorization
scope of a Base wallet: enumerated ERC-20 allowances, EIP-7702
delegation status, Permit2 allowances, and the worst-case outflow
derived two ways. Evidence fields and counts only β€” no composite
score.</li>
<li><strong>Full-Surface Audit β€” $500 USDC.</strong> Flow's audit
machinery turned on your own surface: claims frozen byte-exact,
recomputed from source, graded leg by leg. No promised grade; a grade
is what the evidence supports, published with its recompute.</li>
</ul>
<h2>Free, forever</h2>
<p><strong>Proof Index β€” GET
<a href="https://flow-kg4x.vercel.app/api/index">flow-kg4x.vercel.app/api/index</a>.</strong>
The public, read-only directory of checked payees: signed, hash-chained
evidence records anyone can verify offline. Counts only β€” no
percentages, no composite scores, no rankings.</p>
<p>Every sale splits 20 / 50 / 30: 20% back to the buyer, 50% Flow
keeps, 30% to the Uplift Fund for the Flow network and its users.</p>
<p class="standing">Claims frozen. Recomputed from source. Receipts public.</p>
</main>
<script>
"use strict";
var VERIFY_URL = "https://flow-kg4x.vercel.app/api/verify";
var SITE_URL = "https://flow-kg4x.vercel.app";
var STANDING_LINE = "Claims frozen. Recomputed from source. Receipts public.";
function esc(s) {
return String(s).replace(/[&<>"']/g, function (c) {
return { "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;", "'": "&#39;" }[c];
});
}
function unverifiedHTML(address, reason) {
return "<h2>Result: UNVERIFIED</h2>" +
"<p>The verifier did not return a grade for <code>" + esc(address) + "</code> (" +
esc(reason) + ").</p>" +
"<p>No grade is shown, because no check completed. An unreachable verifier " +
"is not evidence about this address in either direction.</p>" +
"<p>Try again, or run the check at <a href=\"" + SITE_URL + "\">" + SITE_URL + "</a>.</p>" +
"<p class=\"standing\">" + STANDING_LINE + "</p>";
}
function pick(data) {
var names = Array.prototype.slice.call(arguments, 1);
for (var i = 0; i < names.length; i++) {
var v = data[names[i]];
if (v !== null && v !== undefined && v !== "") return v;
}
return null;
}
function renderVerdict(data, address) {
if (!data || typeof data !== "object" || Array.isArray(data)) {
return unverifiedHTML(address, "response was not a JSON object");
}
var verdict = pick(data, "verdict", "grade", "result", "status");
var score = pick(data, "score", "safetyScore", "safety_score");
var flags = pick(data, "redFlags", "red_flags", "flags", "risks") || [];
var advice = pick(data, "advice", "summary", "recommendation", "notes");
if (verdict === null && score === null) {
// The endpoint answered, but not with a verdict shape we can
// honestly restate. Show exactly what it said, labeled as raw.
var raw = JSON.stringify(data, null, 2);
return "<h2>Verifier response (raw)</h2>" +
"<p>Address: <code>" + esc(address) + "</code></p>" +
"<p>The endpoint responded, but its reply carried no verdict or score " +
"field this desk can restate. It is shown verbatim below β€” nothing has " +
"been added to it.</p><pre>" + esc(raw) + "</pre>" +
"<p class=\"standing\">" + STANDING_LINE + "</p>";
}
var html = "<h2>Verification result</h2>" +
"<p>Address: <code>" + esc(address) + "</code></p>";
if (verdict !== null) {
html += "<p><strong>Verdict:</strong> " + esc(verdict) + " (safe | caution | danger)</p>";
}
if (score !== null) {
html += "<p><strong>Score:</strong> " + esc(score) + " / 100</p>";
}
if (Array.isArray(flags) && flags.length) {
html += "<p><strong>Red flags:</strong></p><ul>";
flags.forEach(function (flag) {
var label;
if (flag && typeof flag === "object") {
label = pick(flag, "flag", "name", "title", "description") || JSON.stringify(flag);
} else {
label = flag;
}
html += "<li>" + esc(label) + "</li>";
});
html += "</ul>";
} else {
html += "<p><strong>Red flags:</strong> none reported in this response.</p>";
}
if (advice) {
html += "<p><strong>Advice:</strong></p><p>" + esc(advice) + "</p>";
}
html += "<p>A verdict is a check against the evidence readable at call " +
"time β€” not a certification of safety, and not a promise about any " +
"future state of this address.</p>" +
"<p class=\"standing\">" + STANDING_LINE + "</p>";
return html;
}
function runCheck() {
var input = document.getElementById("addr");
var out = document.getElementById("out");
var btn = document.getElementById("run");
var address = (input.value || "").trim();
if (!address) {
out.innerHTML = "<h2>No address given</h2><p>Paste a Base address " +
"(contract or wallet) and run the check.</p>";
return;
}
btn.disabled = true;
out.innerHTML = "<p>Checking <code>" + esc(address) + "</code>…</p>";
fetch(VERIFY_URL, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ address: address })
}).then(function (resp) {
if (!resp.ok) {
out.innerHTML = unverifiedHTML(address, "endpoint returned HTTP " + resp.status);
return null;
}
return resp.json().then(function (data) {
out.innerHTML = renderVerdict(data, address);
}).catch(function () {
out.innerHTML = unverifiedHTML(address, "endpoint returned a non-JSON response");
});
}).catch(function () {
out.innerHTML = unverifiedHTML(address, "request failed in the browser (network or cross-origin block)");
}).then(function () {
btn.disabled = false;
});
}
document.getElementById("run").addEventListener("click", runCheck);
document.getElementById("addr").addEventListener("keydown", function (e) {
if (e.key === "Enter") runCheck();
});
</script>
</body>
</html>