Skip to content

Commit 27ed418

Browse files
NicoSerranoPclaudeJohnGuilding
authored
Chore/project evaluations content (#34)
* chore(evaluations): add tornado cash and privacy pools * fix: use the branch data json * feat(evaluations): add monero * feat(evaluations): add Tongo evaluation Add Tongo Cash evaluation with all properties filled including confidentiality, anonymity, compliance, state model, and composability. Tongo is a confidential payment protocol on Starknet using ElGamal homomorphic encryption (FHE-HE category). https://claude.ai/code/session_01Mwqt32iHFXeHuF2ZNfuM17 * chore(evaluations): add tongo cash * feat(evaluations): add Intmax evaluation properties Populates the Intmax entry in evaluations.json with all 27 properties covering privacy, decentralisation, compliance, state and composability. Adds zkWormholes to the Intmax categories alongside L2s and Validium. https://claude.ai/code/session_011yaB8BXmP2Z9rMPgr8F8o2 * chore(evaluations): add intmax * Add FluidKey evaluation to project-evaluations Adds a complete evaluation entry for Fluidkey covering all standard properties: stealth address confidentiality/anonymity model, ERC-5564 key derivation, counterfactual Safe smart accounts, ENS off-chain resolver dependency, escape hatch via open-source Stealth Account Kit, selective disclosure via transaction export, and DeFi access via the Earn module. https://claude.ai/code/session_016kNBjRkESWShpCWeqxZeFj * chore(evaluation): add fluidkey * fix(evaluations): use vs settings for same save files * chore(evaluations): add fluidkey * chore(evaluations): add redact * fix(evaluations): fix typos * chore(evaluations): add hinkal * test: assert text equals json text * feat: split json files - json file is split into individual project files - edit projects individually - add zod validation for json files on local import - add zod validation when importing json files - allow downloading all as a zip file - add modal to allow chosing which protocol to export as json - test file compares old json against new json * feat: remove tests and large evaluation file * fix(deps): remove old types * feat(evaluations): remove remote url references * feat(evaluations): format with prettier the downloaded files * chore(evaluations): move schema to src/data/ directory * chore(evaluations): downloaded formatted files * fix(evaluations): larger analysis of tornado cash * chore(evaluations): larger privacy pools description * fix(evaluations): privacy pools is not censorship resistant * chore(evaluation): extend tongo descriptions * chore(evaluations): extended intmax evaluation * chore(evaluations): extended fluid descriptions * chore(evaluations): extended monero descriptions * chore(evaluations): redact extended descriptions * Fill time-to-finality, deposit time, and withdraw time in all evaluations - Time-to-finality (in minutes): - Ethereum mainnet dApps (Fluidkey, Hinkal, Privacy Pools, Railgun, Redact, Tornado Cash): 0.2 min (12-second Ethereum blocktime) - INTMAX (zkRollup on Ethereum): 120 min (~12 blocks/day baseline → ~2 hours L1 finality) - Tongo (Starknet L2): 120 min (~2 hours for Starknet STARK proofs to settle on Ethereum L1) - Monero (alternative L1): 20 min (10 confirmations × 2 min block time) - Deposit time (in seconds): 0 for all protocols (no protocol-enforced pre-deposit waiting period) - Withdraw time (in seconds): - Privacy Pools: 604800 (up to 7 days for ASP vetting before private withdrawal is possible) - All others: 0 (no protocol-enforced withdrawal waiting period) Also adds pnpm-lock.yaml update from installing project-evaluations dependencies. https://claude.ai/code/session_01MfynrQSTrugWfdTEh6CcqT * fix(evaluations): better time notes * feat(evaluations): improve time metrics * feat: update schema * feat: add research script * feat: add zcash analysis * fix(evaluations): zcash grammar fixes * feat: update rules and fix wrong citations * feat: upate rule about blog posts * feat: update schema * feat: update railgun * feat: update fluidkey * feat: update Hinkal * feat: add intmax * feat: update monero * feat: update privacy pools * feat: update tornado cash * feat: update redact * feat: update tongo * feat: push schema updates * feat: add new rules to research script * feat: schema, fluidkey, hinkal updates --------- Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: John Guilding <jwguilding@gmail.com>
1 parent 89c0cb3 commit 27ed418

31 files changed

Lines changed: 3590 additions & 345 deletions

.vscode/settings.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"[json]": {
3+
"editor.defaultFormatter": "esbenp.prettier-vscode"
4+
}
5+
}

pnpm-lock.yaml

Lines changed: 551 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

project-evaluations/.env.example

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ANTHROPIC_API_KEY=your_api_key

project-evaluations/package.json

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,24 @@
77
"scripts": {
88
"dev": "vite",
99
"build": "tsc && vite build",
10-
"preview": "vite preview"
10+
"preview": "vite preview",
11+
"research": "tsx scripts/index.ts"
1112
},
1213
"dependencies": {
14+
"jszip": "^3.10.1",
1315
"react": "^19.1.0",
14-
"react-dom": "^19.1.0"
16+
"react-dom": "^19.1.0",
17+
"zod": "^4.3.6"
1518
},
1619
"devDependencies": {
20+
"@anthropic-ai/sdk": "^0.80.0",
1721
"@tailwindcss/vite": "^4.1.8",
1822
"@types/react": "^19.1.5",
1923
"@types/react-dom": "^19.1.5",
2024
"@vitejs/plugin-react": "^4.5.1",
25+
"dotenv": "^17.3.1",
2126
"tailwindcss": "^4.1.8",
27+
"tsx": "^4.21.0",
2228
"typescript": "^5.9.3",
2329
"vite": "^6.3.5"
2430
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import { readFileSync, writeFileSync } from "fs";
2+
import { configs } from "./research-config";
3+
import { evaluateProperties } from "./research-protocol";
4+
import { Evaluation, Property } from "../src/types";
5+
6+
async function main() {
7+
const args = process.argv.slice(2).filter((a) => a !== "--");
8+
const positional = args.filter((a) => !a.startsWith("--"));
9+
const onlyIdx = args.indexOf("--only");
10+
const only = onlyIdx >= 0 ? args[onlyIdx + 1]?.split(",").map((s) => s.trim()) : undefined;
11+
12+
const protocolId = positional[0];
13+
if (!protocolId || !configs[protocolId]) {
14+
console.error(
15+
`Usage: pnpm run research <protocol> [--only "A,B"]\n` + `Available: ${Object.keys(configs).join(", ")}`,
16+
);
17+
process.exit(1);
18+
}
19+
if (!process.env.ANTHROPIC_API_KEY) {
20+
console.error("ANTHROPIC_API_KEY is required");
21+
process.exit(1);
22+
}
23+
24+
const config = configs[protocolId];
25+
const evalPath = new URL(`../src/data/evaluations/${config.id}.json`, import.meta.url);
26+
const existingProperties: Property[] = JSON.parse(readFileSync(evalPath, "utf-8")).properties;
27+
28+
const properties = await evaluateProperties(config, existingProperties, only ?? []);
29+
30+
const evaluation: Evaluation = {
31+
id: config.id,
32+
title: config.title,
33+
description: config.description,
34+
documentation: config.documentation,
35+
categories: config.categories as Evaluation["categories"],
36+
properties,
37+
};
38+
writeFileSync(evalPath, JSON.stringify(evaluation, null, 2) + "\n");
39+
console.log(`Wrote ${evalPath.pathname}`);
40+
}
41+
42+
main().catch((err) => {
43+
console.error("Fatal:", err);
44+
process.exit(1);
45+
});
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { Evaluation } from "../src/types";
2+
3+
export type ProtocolConfig = Omit<Evaluation, "properties">;
4+
5+
export const configs: Record<string, ProtocolConfig> = {
6+
zcash: {
7+
id: "zcash",
8+
title: "ZCash",
9+
description:
10+
"A privacy-focused cryptocurrency using zk-SNARKs to enable fully shielded transactions" +
11+
" where sender, receiver, and amount are all encrypted on its own proof-of-work blockchain.",
12+
documentation: "https://zcash.readthedocs.io/en/latest/",
13+
categories: ["Alternative L1"],
14+
sourceUrls: [
15+
"https://maxdesalle.com/mastering-zcash",
16+
"https://seanbowe.com/blog/tachyaction-at-a-distance/",
17+
"https://zcash.readthedocs.io/en/latest/",
18+
"https://zcash.github.io/",
19+
],
20+
},
21+
};
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
import type { PropertyContent } from "../src/types.js";
2+
3+
// prettier-ignore
4+
const BASE_PROMPT = (
5+
property: PropertyContent,
6+
protocolName: string,
7+
) => `You are a technical researcher evaluating privacy protocols for an objective report
8+
called "The State of Private Transfers 2026". The report is a comprehensive analysis of the state of
9+
private transfers, including the current landscape, the challenges and opportunities, and the future
10+
of private transfers.
11+
12+
Evaluate the "${property.name}" property for ${protocolName}.
13+
14+
Property definition: ${property.description}
15+
Metric: ${property.metric}
16+
Input type: ${property.inputType}
17+
18+
${property.options ? `Allowed values: ${property.options.join(" / ")}` : `Expected format: ${property.metric}`}`;
19+
20+
// prettier-ignore
21+
const BASE_RULES = `
22+
GENERAL RULES:
23+
1. Start your answer by directly addressing the property. Your first sentence must answer the question.
24+
2. Every sentence must be relevant to the property being evaluated. Do not include general descriptions of the protocol, its history, or features unrelated to this specific property.
25+
3. Prioritize information density. Every sentence should deliver a concrete fact.
26+
4. Only state facts you are highly confident about.
27+
5. If uncertain about a claim, omit it rather than guess. Never invent statistics, percentages, or quotes.
28+
6. Distinguish current live features from planned/future ones. Future features must NOT influence the value chosen.
29+
7. Never use these phrases: "the document", "prior research", "the provided documentation", "indicates", "confirms", "the prior research confirms", "the prior research found". Write as if you are the expert, not reading a source.
30+
8. Never say "since X, the answer is Y". Just state the answer and explain why.
31+
9. Write technically but naturally — not robotic. Avoid marketing language (e.g. "banks", "your money", "advanced applied cryptography", "enhanced privacy", "cutting-edge", "innovative", "first practical application of").
32+
10. Do not reference PRs, config files, variable names, lines of code, or implementation details. Focus on protocol-level facts. You CAN reference technical standards and primitives (e.g. BIP32, BFT, zk-SNARKs, viewing keys, nullifier sets, commitment trees) — aim for a technical assessment, not a code review.
33+
11. Do not reference ZIP/EIP/BIP numbers, improvement proposal processes, or governance token mechanics unless the property is specifically about governance or upgradeability. You may mention that a feature is proposed or in development without naming the specific proposal.
34+
12. For properties with opt-in privacy (e.g. shielded vs transparent): if the privacy feature exists and is usable, the answer is Yes. Opt-in privacy still counts.
35+
13. Only cite text that directly proves or disproves the specific property being evaluated. Do not cite general protocol descriptions, feature overviews, or related but tangential information.
36+
37+
PROPERTY GUIDANCE RULES:
38+
14. For compliance properties: consensus-level validation on permissionless blockchains is NOT compliance enforcement. Compliance means active restriction or filtering by an entity.
39+
15. For cryptographic verifiability: mathematical proofs verify correctness, separate from consensus.
40+
16. For Open Source: find a page that explicitly states the license type (MIT, Apache 2.0, etc.). Prefer official project websites or license pages over GitHub READMEs. Do not mention repository files (e.g. COPYING, LICENSE), GitHub structure, forks, or derived-from relationships.
41+
17. For Deposit time / Withdraw time: For L1 protocols without a distinct deposit/withdraw concept, use N/A.
42+
18. For Escape hatch: For standalone L1 blockchains where funds are native to the chain, this may be N/A.
43+
19. For Asset privacy: For single-asset protocols (e.g. a chain with only one native currency), use No.
44+
20. For Censorship resistance: if the protocol is permissionless and any valid transaction can eventually be included (even if individual miners/validators can soft-censor), the answer is Yes. Soft censorship by some participants does not make the protocol censorship-susceptible if others can still include the transaction. If the protocol uses relayers or broadcasters, mention their role in the description. Relayer dependence alone does not make the protocol censorship-susceptible if users can bypass relayers and interact with the underlying contracts directly.
45+
46+
SOURCE SELECTION RULES:
47+
21. The page must contain specific technical content about this property — not just a table of contents, navigation page, or landing page.
48+
22. Do NOT return PDF URLs — they cannot be processed. Find an HTML alternative.
49+
23. Never use blog posts from exchanges, trading platforms, or non-official sources. Only use blog posts from the protocol's own team or foundation (e.g. electriccoin.co/blog for Zcash, blog.ethereum.org for Ethereum). Prefer official docs, specs, or project websites over any blog.
50+
24. If the best source is a PDF, search for an HTML version of the same content.
51+
52+
ADDITIONAL PROPERTY RULES:
53+
25. For Number of secrets: the value should count only independently stored secrets. If all keys (spending, viewing, encryption) are deterministically derived from one wallet signature or mnemonic, the answer is 1. The notes MUST list all keys the protocol uses, how each is derived, and what cryptographic primitives are used (curves, hash functions, key derivation schemes).
54+
26. For Time-to-finality (apps/L2s/L3s): should be N/A if the protocol is deployed on other blockchains and inherits their finality. List all deployed networks. Exception: L3s may have their own finality time if their settlement adds delay beyond the underlying L2.
55+
27. For Cryptographic verifiability (L1s): transaction correctness can be cryptographically verified (zk-SNARKs, ring signatures, etc.) while consensus uses PoW/PoS (majority-based). Note this distinction. For protocols with additional trust assumptions (upgradable contracts, permissioned gates), the answer may be No even if the proof system is sound.
56+
28. For Open source: must state the specific license (MIT, BSD 3-Clause, GPL-3.0, Unlicense, etc.). Check ALL key repositories — contracts, circuits, SDKs may have different licenses. If any critical component (e.g. ZK circuits) has no license or is "source-available" only, the answer is No.
57+
29. For Plausible deniability: this property asks whether private transfers are indistinguishable from public transfers. For privacy-by-default protocols (e.g. Monero), the answer is No because the entire protocol is a known privacy chain — a user cannot plausibly deny to an exchange or regulator that privacy features are being used. Plausible deniability requires private transactions to be embedded within or indistinguishable from non-private ones (e.g. zkWormholes). For opt-in privacy protocols, plausible deniability is also No because shielded transactions are distinguishable from transparent ones.
58+
30. For Relayers/Broadcasters: if a protocol uses relayers, mention this in Censorship resistance notes but do not change the value to No if users can interact with contracts directly. Mention in External network dependence but mark as No if the relayer is optional.
59+
31. Do not use library names in notes (e.g. "plonky2_bn254", "plonky2_keccak"). Use cryptographic primitive names instead (e.g. "BN254 curve", "Keccak hashing").
60+
32. Do not restate the value as a conclusion at the end of notes (e.g. "Therefore the answer is Yes" or "Therefore there are 2 secrets").`;
61+
62+
// prettier-ignore
63+
export function buildResearchPrompt(
64+
property: PropertyContent,
65+
protocolName: string,
66+
sourceUrls?: string[],
67+
triedUrls: string[] = [],
68+
): string {
69+
return `
70+
${BASE_PROMPT(property, protocolName)}
71+
72+
Hint: ${sourceUrls?.length
73+
? "Suggested starting points for research:\n" + sourceUrls.map((u) => `- ${u}`).join("\n")
74+
: "The latest documentation is a good place to start, but you should expand your search beyond this"}
75+
76+
${triedUrls.length > 0
77+
? "Do NOT use these URLs (already tried means there is insufficient content):\n" + triedUrls.map((u) => `- ${u}`).join("\n")
78+
: ""}
79+
80+
${BASE_RULES}
81+
82+
Search the web for the most authoritative source page for this property.
83+
Respond with ONLY a JSON object: {"url": "best_source_url", "summary": "what you found"}`;
84+
}
85+
86+
// prettier-ignore
87+
export function buildEvaluationPrompt(
88+
property: PropertyContent,
89+
protocolName: string,
90+
researchSummary: string,
91+
): string {
92+
return `
93+
${BASE_PROMPT(property, protocolName)}
94+
95+
Prior research found: ${researchSummary}
96+
97+
${BASE_RULES}
98+
99+
Then output a JSON object (no code fences):
100+
- "value": matching one of the allowed options exactly
101+
- "notes": your 2-4 sentence answer from above
102+
103+
IMPORTANT: If the input type is "multi-select", you MUST format the value as a JSON array string even for a single selection, e.g. ["Option1"]. Never output a plain string for multi-select fields.
104+
If the property is a number or text, provide the value as a string.`;
105+
}

0 commit comments

Comments
 (0)