The eight branded types in v1.1.1#
VestingId, AirdropId, DisperseId, EncryptedHandle, ExternalInputProof, Signature, TxHash, and Role.
Each is a structural type with a unique brand symbol — zero-overhead at runtime, full type-safety at compile time. Pattern Z in the SDK's codebase audit.
How to make one#
import { asVestingId, type VestingId } from "@tokenops/sdk";
import type { Hex } from "viem";
// "0x12...ab" as Hex
const rawHex: Hex = "0x12abc...";
// At the validation boundary — convert once, type-check forever after.
const vestingId: VestingId = asVestingId(rawHex);
// Compile error: VestingId is not assignable to AirdropId
manager.revoke({ airdropId: vestingId });
// The contract sees a plain Hex; the brand is compile-time only.The as* constructors are zero-cost compile-time casts — the caller is responsible for prior validation (e.g. viem's isHex). The brand is an annotation, not a runtime guard: asVestingId is defined as (h: Hex): VestingId => h and performs no length or prefix check.
Receiving values from outside the SDK#
Form inputs, URL params, JSON RPC responses — all of these arrive as plain strings. Call the as* constructor at the entry point. After that, the rest of the codebase trusts the type.