Problem
Tag letters are reused across NIPs with different semantics. Today codegen generates one generic type per tag letter:
type NTag = readonly ["n", "mainnet" | "testnet" | "signet" | "regtest"];
But NIP-66 uses n for "clearnet" | "tor" | "i2p" | "loki". A developer building a kind 30166 event gets the wrong autocomplete and wrong documentation from the generic NTag type.
Similarly:
c = commitment (generic) vs. check type in NIP-66 (open, read, write, ssl, dns, geo, info)
s = status (generic) vs. software name in NIP-66
Proposal
Generate tag types scoped to each kind, derived from the kind schema's tag constraints:
// Generic (existing, keep as-is)
export type NTag = readonly ["n", "mainnet" | "testnet" | "signet" | "regtest"];
// Kind-scoped (new)
export type Kind30166_NTag = readonly ["n", "clearnet" | "tor" | "i2p" | "loki"];
export type Kind30166_RTag = readonly ["R", `${"!" | ""}${"auth" | "payment" | "pow" | "ssl"}`];
export type Kind10166_CTag = readonly ["c", "open" | "read" | "write" | "ssl" | "dns" | "geo" | "info"];
Where the data comes from
The kind schemas already contain per-tag value constraints via if/then on tag position 0 and enum/pattern on subsequent positions. schemata PR #106 adds these for NIP-66 kinds. The codegen planner (plan-validators.ts) already extracts this info to generate validators — the same data can drive kind-scoped type emission.
Scope
- New emitter logic (or extension of
emit-typescript.ts) that walks kind tag constraints
- Output: additional type aliases in
kinds.d.ts or a new kind-tags.d.ts
- Keep generic tag types in
tags.d.ts unchanged (they're still useful for cross-kind tag handling)
Effort: Medium | Impact: Medium
Problem
Tag letters are reused across NIPs with different semantics. Today codegen generates one generic type per tag letter:
But NIP-66 uses
nfor"clearnet" | "tor" | "i2p" | "loki". A developer building a kind 30166 event gets the wrong autocomplete and wrong documentation from the genericNTagtype.Similarly:
c= commitment (generic) vs. check type in NIP-66 (open,read,write,ssl,dns,geo,info)s= status (generic) vs. software name in NIP-66Proposal
Generate tag types scoped to each kind, derived from the kind schema's tag constraints:
Where the data comes from
The kind schemas already contain per-tag value constraints via
if/thenon tag position 0 andenum/patternon subsequent positions. schemata PR #106 adds these for NIP-66 kinds. The codegen planner (plan-validators.ts) already extracts this info to generate validators — the same data can drive kind-scoped type emission.Scope
emit-typescript.ts) that walks kind tag constraintskinds.d.tsor a newkind-tags.d.tstags.d.tsunchanged (they're still useful for cross-kind tag handling)Effort: Medium | Impact: Medium