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 { "&": "&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>