flowexecutor commited on
Commit
c3ea3ad
Β·
verified Β·
1 Parent(s): ee78115

Upload 3 files

Browse files
Files changed (3) hide show
  1. README.md +53 -5
  2. app.py +202 -0
  3. requirements.txt +2 -0
README.md CHANGED
@@ -1,10 +1,58 @@
1
  ---
2
  title: Flow Verification Desk
3
- emoji: ⚑
4
- colorFrom: indigo
5
- colorTo: blue
6
- sdk: static
 
7
  pinned: false
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
  title: Flow Verification Desk
3
+ emoji: 🧾
4
+ colorFrom: blue
5
+ colorTo: indigo
6
+ sdk: gradio
7
+ app_file: app.py
8
  pinned: false
9
+ license: other
10
  ---
11
 
12
+ # Flow Verification Desk
13
+
14
+ Flow is the checker for agent payments on Base. This Space is the free
15
+ front door: paste a Base address (contract or wallet) and the desk
16
+ calls Flow's public `/api/verify` endpoint and shows the verdict it
17
+ returns β€” safe | caution | danger, the score, the red flags, and the
18
+ advice, exactly as returned.
19
+
20
+ **Claims frozen. Recomputed from source. Receipts public.**
21
+
22
+ ## What a result is β€” and is not
23
+
24
+ - A result is a check against the evidence the endpoint could read at
25
+ call time. It is **not** a certification of safety, and no grade is
26
+ ever promised in advance: a grade is what the evidence supports.
27
+ - If the verifier cannot be reached, the desk says so and grades the
28
+ result **UNVERIFIED**. It never invents, estimates, or caches a
29
+ grade. An unreachable verifier is not evidence about an address in
30
+ either direction.
31
+
32
+ ## The rest of the menu
33
+
34
+ Prices printed before any sale, the same for everyone, paid in USDC
35
+ via x402 at https://flow-kg4x.vercel.app:
36
+
37
+ - **PayCheck β€” $0.50 USDC** β€” a pre-payment payee grade: before you
38
+ pay this agent, check.
39
+ - **Scope Report β€” $25 USDC** β€” the full authorization scope of a Base
40
+ wallet, with the worst-case outflow derived two ways.
41
+ - **Full-Surface Audit β€” $500 USDC** β€” Flow's audit machinery turned
42
+ on your own surface, graded leg by leg with the recompute attached.
43
+
44
+ Free, forever: the **Proof Index** β€” `GET
45
+ https://flow-kg4x.vercel.app/api/index` β€” signed, hash-chained
46
+ evidence records of checked payees, verifiable offline. Counts only:
47
+ no percentages, no composite scores, no rankings.
48
+
49
+ Every sale splits 20 / 50 / 30: 20% back to the buyer, 50% Flow keeps,
50
+ 30% to the Uplift Fund for the Flow network and its users.
51
+
52
+ ## Links
53
+
54
+ - Site: https://flow-kg4x.vercel.app
55
+ - X: [@FlowExecutor](https://x.com/FlowExecutor)
56
+
57
+ Receipts, not revenue claims: Flow's grades stand on whether a third
58
+ party can recompute them from the same source.
app.py ADDED
@@ -0,0 +1,202 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Flow Verification Desk β€” a Hugging Face Space front door to Flow's
2
+ public contract-safety check.
3
+
4
+ What this does: takes a Base address (contract or wallet), calls Flow's
5
+ public free endpoint POST https://flow-kg4x.vercel.app/api/verify with
6
+ {"address": "<address>"}, and renders the returned verdict as readable
7
+ Markdown.
8
+
9
+ Honesty rules (load-bearing):
10
+ - A grade is shown ONLY when the endpoint actually returned one.
11
+ - Any fetch failure, timeout, non-200 status, or malformed response
12
+ renders an explicit "verifier unreachable / result UNVERIFIED"
13
+ message. This app never invents, estimates, or caches a grade.
14
+ - No result here is a certification of safety. A verdict is a check
15
+ against the evidence the endpoint could read at call time.
16
+
17
+ Claims frozen. Recomputed from source. Receipts public.
18
+ """
19
+
20
+ import json
21
+
22
+ try:
23
+ import requests
24
+ except ImportError: # pragma: no cover - requests is in requirements.txt
25
+ requests = None
26
+
27
+ try:
28
+ import gradio as gr
29
+ except ImportError: # allows local import/render tests without gradio
30
+ gr = None
31
+
32
+ VERIFY_URL = "https://flow-kg4x.vercel.app/api/verify"
33
+ SITE_URL = "https://flow-kg4x.vercel.app"
34
+ STANDING_LINE = "Claims frozen. Recomputed from source. Receipts public."
35
+ TIMEOUT_SECONDS = 30
36
+
37
+
38
+ def unverified_message(address, reason):
39
+ """The only honest output when no grade was actually returned."""
40
+ return (
41
+ "## Result: UNVERIFIED\n\n"
42
+ f"The verifier did not return a grade for `{address}` "
43
+ f"({reason}).\n\n"
44
+ "No grade is shown, because no check completed. An unreachable "
45
+ "verifier is not evidence about this address in either "
46
+ "direction.\n\n"
47
+ f"Try again, or run the check at {SITE_URL}.\n\n"
48
+ f"*{STANDING_LINE}*"
49
+ )
50
+
51
+
52
+ def _pick(data, *names):
53
+ for name in names:
54
+ if isinstance(data, dict) and data.get(name) not in (None, ""):
55
+ return data[name]
56
+ return None
57
+
58
+
59
+ def render_verdict(data, address):
60
+ """Render one /api/verify JSON response as readable Markdown.
61
+
62
+ Pure function of the endpoint's response: every value printed here
63
+ comes out of `data`. Unknown shapes are shown as the raw response
64
+ rather than paraphrased into a grade the endpoint never gave.
65
+ """
66
+ if not isinstance(data, dict):
67
+ return unverified_message(address, "response was not a JSON object")
68
+
69
+ verdict = _pick(data, "verdict", "grade", "result", "status")
70
+ score = _pick(data, "score", "safetyScore", "safety_score")
71
+ flags = _pick(data, "redFlags", "red_flags", "flags", "risks") or []
72
+ advice = _pick(data, "advice", "summary", "recommendation", "notes")
73
+
74
+ if verdict is None and score is None:
75
+ # The endpoint answered, but not with a verdict shape we can
76
+ # honestly restate. Show exactly what it said, labeled as raw.
77
+ raw = json.dumps(data, indent=2, sort_keys=True)
78
+ return (
79
+ "## Verifier response (raw)\n\n"
80
+ f"Address: `{address}`\n\n"
81
+ "The endpoint responded, but its reply carried no verdict "
82
+ "or score field this desk can restate. It is shown verbatim "
83
+ "below β€” nothing has been added to it.\n\n"
84
+ f"```json\n{raw}\n```\n\n"
85
+ f"*{STANDING_LINE}*"
86
+ )
87
+
88
+ lines = ["## Verification result", "", f"Address: `{address}`", ""]
89
+ if verdict is not None:
90
+ lines.append(f"**Verdict:** {verdict} (safe | caution | danger)")
91
+ if score is not None:
92
+ lines.append(f"**Score:** {score} / 100")
93
+ lines.append("")
94
+ if flags:
95
+ lines.append("**Red flags:**")
96
+ for flag in flags:
97
+ if isinstance(flag, dict):
98
+ label = _pick(flag, "flag", "name", "title", "description") or json.dumps(flag, sort_keys=True)
99
+ lines.append(f"- {label}")
100
+ else:
101
+ lines.append(f"- {flag}")
102
+ else:
103
+ lines.append("**Red flags:** none reported in this response.")
104
+ lines.append("")
105
+ if advice:
106
+ lines.append("**Advice:**")
107
+ lines.append("")
108
+ lines.append(str(advice))
109
+ lines.append("")
110
+ lines.append(
111
+ "A verdict is a check against the evidence readable at call "
112
+ "time β€” not a certification of safety, and not a promise about "
113
+ "any future state of this address."
114
+ )
115
+ lines.append("")
116
+ lines.append(f"*{STANDING_LINE}*")
117
+ return "\n".join(lines)
118
+
119
+
120
+ def check_address(address):
121
+ """Call the live /api/verify endpoint and render what it returns."""
122
+ address = (address or "").strip()
123
+ if not address:
124
+ return "## No address given\n\nPaste a Base address (contract or wallet) and run the check."
125
+ if requests is None:
126
+ return unverified_message(address, "the requests library is not installed in this Space")
127
+ try:
128
+ resp = requests.post(VERIFY_URL, json={"address": address}, timeout=TIMEOUT_SECONDS)
129
+ except Exception as exc: # network down, DNS, timeout β€” all the same honest answer
130
+ return unverified_message(address, f"request failed: {exc.__class__.__name__}")
131
+ if resp.status_code != 200:
132
+ return unverified_message(address, f"endpoint returned HTTP {resp.status_code}")
133
+ try:
134
+ data = resp.json()
135
+ except Exception:
136
+ return unverified_message(address, "endpoint returned a non-JSON response")
137
+ return render_verdict(data, address)
138
+
139
+
140
+ PAID_DOORS_MD = f"""## The paid doors
141
+
142
+ The check above is the free basic tier. The full menu runs over x402
143
+ at {SITE_URL} β€” prices printed before any sale, the same for everyone:
144
+
145
+ - **PayCheck β€” $0.50 USDC.** Before you pay this agent, check. One call
146
+ grades a payee before payment: payee kind and history, address-
147
+ poisoning look-alike detection, wallet approval exposure, contract
148
+ safety, and recent settlement history β€” one finished grade with the
149
+ evidence under it.
150
+ - **Scope Report β€” $25 USDC.** The full authorization scope of a Base
151
+ wallet: enumerated ERC-20 allowances, EIP-7702 delegation status,
152
+ Permit2 allowances, and the worst-case outflow derived two ways.
153
+ Evidence fields and counts only β€” no composite score.
154
+ - **Full-Surface Audit β€” $500 USDC.** Flow's audit machinery turned on
155
+ your own surface: claims frozen byte-exact, recomputed from source,
156
+ graded leg by leg. No promised grade; a grade is what the evidence
157
+ supports, published with its recompute.
158
+
159
+ ## Free, forever
160
+
161
+ - **Proof Index β€” GET {SITE_URL}/api/index.** The public, read-only
162
+ directory of checked payees: signed, hash-chained evidence records
163
+ anyone can verify offline. Counts only β€” no percentages, no
164
+ composite scores, no rankings.
165
+
166
+ Every sale splits 20 / 50 / 30: 20% back to the buyer, 50% Flow
167
+ keeps, 30% to the Uplift Fund for the Flow network and its users.
168
+
169
+ *{STANDING_LINE}*
170
+ """
171
+
172
+ INTRO_MD = f"""# Flow Verification Desk
173
+
174
+ Flow is the checker for agent payments on Base. Agents are paying
175
+ each other now, but a claim is not a record. This desk runs one free
176
+ check: paste a Base address and read the verdict the evidence
177
+ supports.
178
+
179
+ {STANDING_LINE}
180
+ """
181
+
182
+
183
+ def build_ui():
184
+ with gr.Blocks(title="Flow Verification Desk") as demo:
185
+ gr.Markdown(INTRO_MD)
186
+ with gr.Tab("Check an address"):
187
+ address_in = gr.Textbox(
188
+ label="Base address (contract or wallet)",
189
+ placeholder="0x...",
190
+ )
191
+ run_btn = gr.Button("Run the free check")
192
+ out = gr.Markdown()
193
+ run_btn.click(check_address, inputs=address_in, outputs=out)
194
+ with gr.Tab("Paid doors & the Proof Index"):
195
+ gr.Markdown(PAID_DOORS_MD)
196
+ return demo
197
+
198
+
199
+ if __name__ == "__main__":
200
+ if gr is None:
201
+ raise SystemExit("gradio is not installed β€” see requirements.txt")
202
+ build_ui().launch()
requirements.txt ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ gradio
2
+ requests