Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
austintgriffith avatar

Frontend Ux

  • 37 installs
  • 244 repo stars
  • Updated July 21, 2026
  • austintgriffith/ethskills

frontend-ux is an Ethereum skill that defines mandatory UX rules for dApp frontends to prevent common AI agent UI bugs like double-submit and missing pending states.

About

A set of frontend UX rules for Ethereum dApps that prevent the most common AI-generated UI bugs. It mandates per-button pending states, a four-state action flow (connect, switch network, approve, execute), safe address handling, USD context on token amounts, and readable contract errors. Developers use it while building any dApp frontend to avoid duplicate transactions and confusing wallet flows.

  • Mandatory UX rules for Ethereum dApp frontends: per-button pending states, four-state action flow, address UX, USD conte
  • Explains the double-submit approval bug where isPending drops before onchain confirmation and how two states fix it
  • Covers RPC reliability, theme semantics, contract error translation, and pre-publish metadata

Frontend Ux by the numbers

  • 37 all-time installs (skills.sh)
  • Ranked #1,406 of 2,245 Frontend Development skills by installs in the Skillselion catalog
  • Data as of Aug 4, 2026 (Skillselion catalog sync)
At a glance

frontend-ux capabilities & compatibility

Capabilities
dapp ux rules · wallet flow design · frontend error handling
Use cases
frontend · ui design
From the docs

What frontend-ux says it does

Every Button Interacting Onchain Needs Its Own Pending State
SKILL.md
npx skills add https://github.com/austintgriffith/ethskills --skill frontend-ux

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs37
repo stars244
Last updatedJuly 21, 2026
Repositoryaustintgriffith/ethskills

What it does

Use when building an Ethereum dApp frontend to enforce correct button, approval, address, and error-handling UX.

Who is it for?

Developers building a wallet-connected Ethereum dApp frontend.

Skip if: Backend or smart-contract-only work with no user interface.

When should I use this skill?

Whenever you are building a frontend for an Ethereum dApp.

What you get

Buttons disable immediately with per-action pending states, one primary action shows at a time, and errors and amounts are human-readable.

  • Correct four-state action flow
  • Per-button pending states
  • Human-readable errors and amounts

By the numbers

  • 9+ numbered UX rules
  • 4-state action flow
  • 2 approval states required to prevent double-submit

Files

SKILL.mdMarkdownGitHub ↗

Frontend UX Rules

What You Probably Got Wrong

"The button works." A clickable button is not enough. It must disable immediately, show a clear pending state, and stay locked until onchain confirmation.

"Addresses are just strings." Address UX needs validation, safe formatting, copy support, explorer linking, and ENS/name handling where available.

"Token amounts are clear." Raw token values without USD context force users to guess risk and value. Show dollar context anywhere amounts matter.

---

Rule 1: Every Button Interacting Onchain Needs Its Own Pending State

Any button that triggers an onchain transaction must: 1. Disable immediately on click 2. Show spinner + action text (Approving..., Staking...) 3. Stay disabled until chain state confirms completion 4. Show success/error feedback when done

// Separate loading state per action
const [isApproving, setIsApproving] = useState(false);
const [isStaking, setIsStaking] = useState(false);

<button
  disabled={isApproving}
  onClick={async () => {
    setIsApproving(true);
    try {
      await sendApproveTx();
    } catch (e) {
      notifyError("Approval failed");
    } finally {
      setIsApproving(false); // always release — even on rejection
    }
  }}
>
  {isApproving ? "Approving..." : "Approve"}
</button>

Never use one shared isLoading state for multiple buttons. It causes wrong labels, wrong disabled states, and duplicate submissions.

For approval flows: `isPending` alone is not enough.

isPending drops to false when the wallet returns the tx hash — before on-chain confirmation. There is a window where isPending = false AND the allowance hasn't updated → button re-enables mid-flight and a user can double-submit.

Approval handlers need two states: approvalSubmitting (set on click, cleared in finally {}) to cover the wallet→confirmation gap, and approveCooldown (set after confirm, cleared after 4s + refetch) to cover the confirmation→cache gap. Both go on disabled. finally {} is required — without it a rejected tx locks the button permanently.

---

Rule 2: Four-State Action Flow

Show one primary action at a time:

1. Not connected  -> Connect Wallet
2. Wrong network  -> Switch Network
3. Needs approval -> Approve
4. Ready          -> Execute action (Stake/Deposit/Swap/etc.)

Critical details:

  • Wrong-network check must happen before approval/action checks
  • Never show Approve and Execute simultaneously
  • Approval status must come from fresh onchain state (not stale local state only)
  • Connection state must render a clickable action, not passive text

---

Rule 3: UX Standards for Addresses

Every displayed address should support:

  • ENS/name resolution (where applicable)
  • Explorer linking
  • Copy-to-clipboard
  • Safe truncation + visual identity (avatar/blockie optional)

Every address input should support:

  • Validation
  • Paste normalization
  • ENS/name resolution where available

If your UI kit includes dedicated address components, use them. Do not use a raw free-text field for critical address entry.

---

Rule 4: Show USD Context for Token Values

Every token/ETH amount shown to users should include USD context:

  • Balances
  • Inputs (live preview)
  • Confirmation text
  • Position/portfolio summaries
<span>0.5 ETH (~$1,250.00)</span>
<span>1,000 TOKEN (~$4.20)</span>

Do not show only token units without value context.

---

Rule 5: RPC Reliability and Polling

  • Use a dedicated RPC provider for production (not accidental public fallback only)
  • Keep polling interval in a responsive range (typically ~2-5s for interactive apps)
  • Ensure fallback transports are intentional and rate-limit aware
  • Watch for runaway request patterns (render loops, duplicate watchers, unbounded polling)

Healthy baseline: low, steady request volume. Spiky or sustained high QPS usually indicates frontend hook/config bugs.

---

Rule 6: Theme Semantics, Not Hardcoded Dark Wrappers

Do not hardcode full-page dark backgrounds that ignore theme/system preference.

Use semantic theme tokens/classes so light/dark mode stays coherent across:

  • Page background
  • Surface layers
  • Primary/secondary text
  • Component states

If you intentionally ship dark-only, remove or disable theme controls that no longer apply.

---

Rule 7: Contract Error Translation

Users should never see raw revert selectors or silent failures.

Implement: 1. Error extraction from ABI/custom errors 2. Mapping to human-readable messages 3. Wallet-level error handling (reject, gas issues) 4. Safe fallback message 5. Inline persistent error UI near the triggering action

try {
  await sendTx();
} catch (e) {
  setTxError(parseContractError(e));
}

---

Rule 8: Pre-Publish Metadata and Product Identity

Before production release:

  • Open Graph image URL is absolute and reachable on live domain (https://...)
  • OG/Twitter title + description are set correctly
  • Social preview image is valid and not local/relative
  • Template/default branding is removed or replaced with project identity
  • Favicon and tab title reflect the app

---

Rule 9: Human-Readable Amounts and Decimals

Always convert between contract units and display units:

import { formatEther, formatUnits, parseEther, parseUnits } from "viem";

formatEther(weiAmount);
formatUnits(tokenAmount, tokenDecimals);

parseEther("1.5");
parseUnits("100", 6); // USDC-style 6 decimals

Never show raw base units like 1500000000000000000.

---

Before you finish: send a one-line note via feedback/SKILL.md — issue or praise.

Related skills

FAQ

Why can a user double-submit an approval?

isPending drops to false when the wallet returns the tx hash, before onchain confirmation, so the button re-enables mid-flight; you need approvalSubmitting and approveCooldown states.

Should token amounts show USD?

Yes. Every token or ETH amount shown to users should include USD context on balances, inputs, confirmations, and portfolio summaries.

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.