File size: 9,079 Bytes
4c8b86e ee78115 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 | <!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 { "&": "&", "<": "<", ">": ">", '"': """, "'": "'" }[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>
|