Input Validation
Every input that takes a hash, address, label, or name validates as you type, with a consistent look: a character counter, a clear error message, and a green checkmark once the value is valid.
What gets checked
- Hashes must be 64 hexadecimal characters. A pasted value is auto-formatted: surrounding whitespace and newlines are stripped, a leading
0xis removed, and it is lowercased. - Stacks addresses must start with
SPorSTand pass the checksum. A valid address shows a link to that wallet's profile. - Labels are optional, printable ASCII, and at most 64 characters.
- Group and collection names are required ASCII, and API key names are letters, numbers, and dashes.
- Webhook URLs must be valid http or https URLs.
Forms and pasting
Create and submit buttons stay disabled until the required fields pass validation, so an invalid value cannot be submitted. On the watchlist, pasting a hash or an address auto-detects which it is and switches the watch type to match.
Matching checks at the API
The same rules guard the REST API. Requests with a malformed hash, address, or query come back as a 400 with a clear message rather than failing deeper in, so integrations get fast, specific feedback.
For contributors
Validation lives in lib/validators.ts as small pure functions returning { valid, error }. The ValidatedInput component renders the field, debounced error, counter, and checkmark, and HashInput and AddressInput build on it with their auto-formatting.
import ValidatedInput from "@/app/components/ValidatedInput";
import { validateGroupName } from "@/lib/validators";
<ValidatedInput
label="Group name"
value={name}
onChange={setName}
validator={validateGroupName}
maxLength={64}
required
/>