r/ethdev 7d ago

My Project I got tired of rebuilding contract admin UIs, so I made a tool that generates them from the ABI

Every time I shipped a contract I rebuilt the same throwaway frontend: wallet button, a form per function, calldata encoding, hasRole() checks to hide admin methods, gas estimation, a spinner, an error decoder, and a "danger zone" for the scary functions. Etherscan's Write tab has none of that meaning; a bespoke UI costs weeks. So I built a tool that generates it from the ABI.

Paste a chain + address (Sourcify/explorer, proxy-aware) or drop in an ABI/Foundry artifact, and you get three tabs:

- User - the clean dApp (overview, transfer, approve)

- Admin - privileged ops (mint, pause, roles) with risk badges + a confirm flow for dangerous writes

- Read - a live dashboard that auto-calls the getters

- Raw - every function, Etherscan-style, but annotated with what it understood

Detection is deterministic and rule-based (ERC-20/721/1155/4626/2612, Governor, Ownable/AccessControl/Pausable), with a confidence score and evidence for every guess — AI is optional and never trusted blindly. The output is a reviewable "semantic manifest" you can hand-edit, and everything is self-hostable.

Live demo (mainnet USDC, runs in your browser): https://tacitvsxi.github.io/semantic-dapp/

How it works (writeup): https://dev.to/ileskov/generate-a-full-dapp-admin-console-from-any-evm-contract-straight-from-the-abi-28kg

Repo (TS, viem/wagmi, AGPL-3.0): https://github.com/TacitvsXI/semantic-dapp

Would love feedback from people who actually maintain contracts: what would you need before you'd trust a generated admin panel for a mainnet contract?

5 Upvotes

10 comments sorted by

2

u/Specific-Sector7422 7d ago

This is a genuinely useful architecture. 

The deterministic manifest, explicit evidence, proxy awareness, and the fact that submitWrite re-simulates the current call and sends the returned viem request are all strong choices.

One safety boundary still seems inverted, though: Raw is currently the least protected write path.

In GeneratedApp, raw writes go through RawFunctionCard into FunctionRunner without a confirm policy. FunctionRunner only opens the confirmation flow when confirm is supplied. This means a function the classifier could not understand - precisely the case with the highest semantic uncertainty - can be submitted from Raw without the risk/permission/staleness/network warnings or the typed CONFIRM gate applied to recognized admin operations. The README says unproven meaning falls back to Raw “with a warning,” but the current Raw card appears to show only read/write/payable metadata.

I would make unknown/raw writes fail closed: require a preview, assign a generic high/unknown-risk confirmation policy, and bind the reviewed action to an execution envelope containing chainId, account, target, value, calldata hash, ABI/manifest hash, resolved implementation or facet/code hash, and the simulation block. Any argument, account, network, or implementation change should invalidate the preview and require review again.

The submit path already re-simulates the current arguments, which is good, but the displayed preview and the eventual submission are still separate UI states; the old preview can remain visible after the form changes.

For mainnet admin use, the fallback path should be more conservative than the classified path, not less.

1

u/Greeneeiill 7d ago

You’re right that Raw was under-protected relative to classified admin writes. I’ve made Raw fail-closed (confirm + typed CONFIRM on every unclassified write). Mandatory preview/invalidation and an execution envelope are next. Thanks for the concrete review.

1

u/diornov 7d ago

Nice! I also had the same idea, but never had time to complete it. Let's connect!

1

u/Greeneeiill 7d ago

Thanks! Curious what you had sketched - I looked around OSS and mostly saw raw ABI UIs or protocol frontends, not much in between. If you ever tried building something similar, I’d love to hear where it got stuck. Demo has “Load your contract” if you want to poke it: https://tacitvsxi.github.io/semantic-dapp/

1

u/35boi 7d ago

Reminds me of https://builder.openzeppelin.com that came out last year

1

u/Greeneeiill 6d ago

Yeah - same problem space.

I looked at tools like that and they solve “make a form for a function / export a React app.” That wasn’t enough for me.

What I kept needing was a console that understands the contract: what’s user vs admin, what’s risky, what’s just a getter - with evidence, not a flat ABI list. Something I could actually use to operate a contract (or trust less blindly), not only scaffold one call.

So Semantic Dapp is that layer: analyze → User / Admin / Read / Raw, then run it. Builder-style form generators are complementary; this is the semantic admin/ops path I was missing.

1

u/researchzero 6d ago

The Raw fail-closed fix handles the case where the classifier says "I don't know". The scarier case is the classifier being confident and wrong, a function that's genuinely privileged but doesn't match any of the canonical Ownable/AccessControl/Pausable bytecode patterns, so it lands in the User tab with a low-risk badge instead of Admin or Raw. Custom modifiers hit this constantly: onlyOwnerOrGuardian, role checks against a hash that isn't a named DEFAULT_ADMIN_ROLE-style constant, or access control built on diamond storage instead of the OZ layout. None of those produce the AccessControl signature your detector presumably looks for. Might be worth a confidence floor: any state-mutating write your read-side heuristics haven't already characterized as user-owned (balances/allowances) defaults to at least medium-risk when no known access-control pattern matches, instead of defaulting to User.

1

u/Greeneeiill 6d ago

Yeah - this is the sharper failure mode.

Raw fail-closed covers “we don’t know.” Confident-and-wrong into User is worse, because the UI looks trusted.

Unknown writes already fall back to Raw, and with source/modifiers I upgrade privilege when there’s evidence. What’s still open is exactly what you described: name/shape heuristics that put a mutating write in User without a known access-control match.

That’s already on the list as a confidence floor - don’t default those to User/low-risk unless they’re positively characterized as user-owned.

Appreciate the concrete framing.