-
Notifications
You must be signed in to change notification settings - Fork 371
V2 docs WIP #543
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
wentelteefje
wants to merge
53
commits into
ensdomains:master
Choose a base branch
from
wentelteefje:feature/ensv2-docs
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
V2 docs WIP #543
Changes from 5 commits
Commits
Show all changes
53 commits
Select commit
Hold shift + click to select a range
422480a
Add comprehensive ENSv2 documentation
wentelteefje f3b5a22
ENSv2 docs: structural improvements, widgets, and FrenCallout
wentelteefje 6ef27db
Remove working files and clean up .gitignore
wentelteefje 16f979b
Change overview title, add what's new in v2 to PermReg page
wentelteefje 69150c9
ERC1155Singleton fixes, reverse resolution page, widget subsections
wentelteefje cb63ffb
- Add ContractReference expandable component for contract reference s…
wentelteefje fcccad3
Move widgets to H3 sections, add title for frencallout
wentelteefje b71f987
Add new migration page template (WIP)
wentelteefje c156303
Fix migration page: correct BONUS_PERIOD (62 days, not 90), add time …
wentelteefje 1adec41
Update migration page for case study revisions
wentelteefje 91503fd
Add self-hosted ABC fonts and Tailwind font families
ali-rasheed 9a730bb
Use bunx for all Vocs script invocations.
ali-rasheed 2cad38f
Apply ENS typography defaults and font tuning.
ali-rasheed 78848c4
Update src/pages/contracts/ensv2/mutable-token-ids.mdx
wentelteefje 80f217a
Revert "Use bunx for all Vocs script invocations."
ali-rasheed 9b1f084
Align docs design tokens with ENS Core palette and document UI patterns.
ali-rasheed 693ee7c
Adjust profile and button shape/ring styling to match updated UI lang…
ali-rasheed 31859f4
Ignore local Netlify metadata in the repository.
ali-rasheed e21f001
Fix resolver scope to per-account, restore 28-day grace period, add n…
wentelteefje 380ab0e
Remove misleading from overview, clarify v1 registrations and renewa…
wentelteefje f0567e9
Add on-chain DNSSEC note to DNS resolvers page, add RegistryCreated e…
wentelteefje 18e8100
Merge remote-tracking branch 'upstream/master' into feature/ensv2-docs
wentelteefje 9371ade
Add verifiable-factory repo link, clarify BatchRegistrar for ENSv1 mi…
wentelteefje ab9af22
Fix reverse resolution intro to credit v1 for multi-chain support, fi…
wentelteefje e11efbb
restructure overview page, clarify factory is default not but not req…
wentelteefje 835cdf5
style(docs): refresh global styles and design tokens
ali-rasheed 9588c49
chore(vocs): tune theme and normalize config formatting
ali-rasheed 3d888b2
style(components): use semi-mono for ENS name labels
ali-rasheed 521d84b
style(docs): refresh global styles and design tokens
ali-rasheed d9da958
chore(vocs): tune theme and normalize config formatting
ali-rasheed 9adffed
style(components): use semi-mono for ENS name labels
ali-rasheed afec27a
Merge branch 'ensdomains:ens-brand-refresh' into ens-brand-refresh
ali-rasheed 09d1977
Apply fixes to migration page based on post-audit branch
wentelteefje acf81a8
Merge pull request #1 from ali-rasheed/ens-brand-refresh
wentelteefje b9c1d19
adjust eth registrar, perm resolver, migration and registry temp page…
wentelteefje 7998689
more registrar fixes
wentelteefje af66267
overhaul permissioned registry prose, refactor metadata for post-audi…
wentelteefje 266e87f
overhaul universal resolver v2 page, verify and fix dns-resolvers pag…
wentelteefje 22e633b
Overhaul registry-template page, fix verifiable-factory technical ina…
wentelteefje 559342c
Address Ram's comments on EAC, PermReg pages
wentelteefje b4462d2
pull scripts/ensips.ts from upstream master
wentelteefje de678fd
Fix technical inaccuracies across ENSv2 docs (dns-resolvers, emancipa…
wentelteefje 0251d20
Add MonoDiagram component for box-drawing diagrams, replace code bloc…
wentelteefje 5b878fb
Fix cross-page consistency issues, broken links, and factual inaccura…
wentelteefje 67e22d9
Align EAC, PermReg, and PermResolver docs with post-audit PRs #333 an…
wentelteefje 778d004
Add proxy deployment code example to Verifiable Factory
wentelteefje 86c2fd8
Fix code example accuracy and add missing examples across ENSv2 docs …
wentelteefje 4da9572
Add contract developers tutorial (subname registrar guide); add resol…
wentelteefje 8d7e352
Refactor subregistry deployment on Subregistrar guide page, add some …
wentelteefje de1055b
Fix indexing page: event order, TokenResource at registration only, P…
wentelteefje 6240b74
Add ENS Explorer (Sepolia) link to ENSv2 overview
wentelteefje 0b3e708
Add sepolia-official-v1-20260525-r2 ENSv2 deployments table to overv…
wentelteefje 25fe646
Expand indexing page with subgraph research findings; fix migration p…
wentelteefje File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,78 @@ | ||
| import type { PropsWithChildren } from 'react' | ||
|
|
||
| type Fren = 'earl' | 'bittu' | 'kuzco' | 'lili' | 'peanut' | ||
| type Variant = 'note' | 'tip' | 'warning' | ||
|
|
||
| const FREN_IMAGES: Record<Fren, string> = { | ||
| earl: '/img/frens/Earl_padding.png', | ||
| bittu: '/img/frens/Bittu_padding.png', | ||
| kuzco: '/img/frens/Kuzco_padding.png', | ||
| lili: '/img/frens/Lili_padding.png', | ||
| peanut: '/img/frens/Peanut_padding.png', | ||
| } | ||
|
|
||
| const VARIANT_STYLES: Record<Variant, { bg: string; border: string }> = { | ||
| note: { | ||
| bg: 'var(--vocs-color_noteBackground, #f0f4f8)', | ||
| border: 'var(--vocs-color_noteBorder, #d0d7de)', | ||
| }, | ||
| tip: { | ||
| bg: 'var(--vocs-color_tipBackground, #f0fdf4)', | ||
| border: 'var(--vocs-color_tipBorder, #86efac)', | ||
| }, | ||
| warning: { | ||
| bg: 'var(--vocs-color_warningBackground, #fffbeb)', | ||
| border: 'var(--vocs-color_warningBorder, #fcd34d)', | ||
| }, | ||
| } | ||
|
|
||
| interface FrenCalloutProps { | ||
| fren: Fren | ||
| variant?: Variant | ||
| title?: string | ||
| } | ||
|
|
||
| export function FrenCallout({ | ||
| fren, | ||
| variant = 'note', | ||
| title, | ||
| children, | ||
| }: PropsWithChildren<FrenCalloutProps>) { | ||
| const style = VARIANT_STYLES[variant] | ||
| const image = FREN_IMAGES[fren] | ||
|
|
||
| return ( | ||
| <aside | ||
| style={{ | ||
| display: 'flex', | ||
| gap: '16px', | ||
| alignItems: 'flex-start', | ||
| padding: '16px', | ||
| borderRadius: '8px', | ||
| border: `1px solid ${style.border}`, | ||
| backgroundColor: style.bg, | ||
| marginBottom: '16px', | ||
| fontSize: '14px', | ||
| lineHeight: 1.6, | ||
| }} | ||
| > | ||
| <img | ||
| src={image} | ||
| alt={fren} | ||
| style={{ | ||
| width: '56px', | ||
| height: '56px', | ||
| objectFit: 'contain', | ||
| flexShrink: 0, | ||
| marginTop: '2px', | ||
| }} | ||
| /> | ||
| <div style={{ width: '100%' }}> | ||
| {title && ( | ||
| <div style={{ fontWeight: 600, marginBottom: '4px' }}>{title}</div> | ||
| )} | ||
| {children} | ||
| </div> | ||
| </aside> | ||
| ) | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,169 @@ | ||
| import { useMemo, useState } from 'react' | ||
| import { keccak256, toHex } from 'viem' | ||
|
|
||
| import { Input } from '../ui/Input' | ||
|
|
||
| function SplitId({ | ||
| label, | ||
| upper, | ||
| lower, | ||
| lowerLabel, | ||
| }: { | ||
| label: string | ||
| upper: string | ||
| lower: string | ||
| lowerLabel: string | ||
| }) { | ||
| const full = `0x${upper}${lower}` | ||
| return ( | ||
| <div className="flex flex-col gap-1"> | ||
| <label className="text-grey px-2 leading-none font-semibold">{label}</label> | ||
| <div className="flex gap-1 items-center"> | ||
| <div className="flex-1 min-w-0"> | ||
| <input | ||
| className="border-border disabled:bg-grey-light disabled:text-grey z-0 w-full rounded-md border px-3 py-2.5 leading-none font-mono text-xs font-normal outline-none truncate" | ||
| value={`0x${upper}...`} | ||
| disabled | ||
| title="Upper 224 bits (from labelhash)" | ||
| /> | ||
| </div> | ||
| <div className="w-[120px] shrink-0"> | ||
| <input | ||
| className="border-border disabled:bg-grey-light z-0 w-full rounded-md border px-3 py-2.5 leading-none font-mono text-xs font-bold outline-none text-[var(--vocs-color_textAccent)]" | ||
| value={lower} | ||
| disabled | ||
| title={lowerLabel} | ||
| /> | ||
| </div> | ||
| <button | ||
| className="!bg-background text-text-secondary hover:text-text border-border rounded border p-1.5 text-xs leading-none transition shrink-0" | ||
| onClick={async () => { | ||
| await navigator.clipboard.writeText(full) | ||
| }} | ||
| title="Copy full value" | ||
| > | ||
| <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"> | ||
| <rect x="9" y="9" width="13" height="13" rx="2" ry="2" /> | ||
| <path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" /> | ||
| </svg> | ||
| </button> | ||
| </div> | ||
| <div className="flex gap-1 px-2"> | ||
| <span className="flex-1 text-xs text-grey truncate">upper 224 bits (labelhash)</span> | ||
| <span className="w-[120px] shrink-0 text-xs text-grey">{lowerLabel}</span> | ||
| <span className="w-[28px] shrink-0" /> | ||
| </div> | ||
| </div> | ||
| ) | ||
| } | ||
|
|
||
| export function IdExplorer() { | ||
| const [label, setLabel] = useState('alice') | ||
| const [eacVersionId, setEacVersionId] = useState(0) | ||
| const [tokenVersionId, setTokenVersionId] = useState(0) | ||
|
|
||
| const computed = useMemo(() => { | ||
| if (!label) return null | ||
| try { | ||
| const labelhashHex = keccak256(toHex(label)) | ||
| const labelhashBigInt = BigInt(labelhashHex) | ||
|
|
||
| // Canonical ID: zero the lower 32 bits | ||
| const canonicalId = labelhashBigInt ^ (labelhashBigInt & 0xFFFFFFFFn) | ||
|
|
||
| // Token ID: canonical ID | tokenVersionId | ||
| const tokenId = canonicalId | BigInt(tokenVersionId) | ||
|
|
||
| // Resource: canonical ID | eacVersionId | ||
| const resource = canonicalId | BigInt(eacVersionId) | ||
|
|
||
| // Split into upper (56 hex = 224 bits) and lower (8 hex = 32 bits) | ||
| const fullLabelhash = labelhashHex.slice(2).padStart(64, '0') | ||
| const upperHex = fullLabelhash.slice(0, 56) | ||
|
|
||
| const canonicalLower = '00000000' | ||
| const tokenLower = BigInt(tokenVersionId).toString(16).padStart(8, '0') | ||
| const resourceLower = BigInt(eacVersionId).toString(16).padStart(8, '0') | ||
|
|
||
| return { | ||
| labelhash: labelhashHex, | ||
| labelhashLower: fullLabelhash.slice(56), | ||
| upperHex, | ||
| canonicalLower, | ||
| tokenLower, | ||
| resourceLower, | ||
| } | ||
| } catch { | ||
| return null | ||
| } | ||
| }, [label, eacVersionId, tokenVersionId]) | ||
|
|
||
| return ( | ||
| <div className="flex flex-col gap-4"> | ||
| <Input | ||
| label="Label" | ||
| value={label} | ||
| onChange={(e) => setLabel(e.target.value)} | ||
| placeholder="alice" | ||
| /> | ||
|
|
||
| <div className="flex gap-3"> | ||
| <div className="flex-1"> | ||
| <label className="text-grey px-2 leading-none font-semibold text-sm"> | ||
| tokenVersionId: {tokenVersionId} | ||
| </label> | ||
| <input | ||
| type="range" | ||
| min={0} | ||
| max={10} | ||
| value={tokenVersionId} | ||
| onChange={(e) => setTokenVersionId(Number(e.target.value))} | ||
| className="w-full mt-2" | ||
| /> | ||
| </div> | ||
| <div className="flex-1"> | ||
| <label className="text-grey px-2 leading-none font-semibold text-sm"> | ||
| eacVersionId: {eacVersionId} | ||
| </label> | ||
| <input | ||
| type="range" | ||
| min={0} | ||
| max={10} | ||
| value={eacVersionId} | ||
| onChange={(e) => setEacVersionId(Number(e.target.value))} | ||
| className="w-full mt-2" | ||
| /> | ||
| </div> | ||
| </div> | ||
|
|
||
| {computed && ( | ||
| <> | ||
| <SplitId | ||
| label="Labelhash" | ||
| upper={computed.upperHex} | ||
| lower={computed.labelhashLower} | ||
| lowerLabel="lower 32 bits" | ||
| /> | ||
| <SplitId | ||
| label="Canonical ID" | ||
| upper={computed.upperHex} | ||
| lower={computed.canonicalLower} | ||
| lowerLabel="zeroed" | ||
| /> | ||
| <SplitId | ||
| label="Token ID" | ||
| upper={computed.upperHex} | ||
| lower={computed.tokenLower} | ||
| lowerLabel="tokenVersionId" | ||
| /> | ||
| <SplitId | ||
| label="Resource" | ||
| upper={computed.upperHex} | ||
| lower={computed.resourceLower} | ||
| lowerLabel="eacVersionId" | ||
| /> | ||
| </> | ||
| )} | ||
| </div> | ||
| ) | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,141 @@ | ||
| import { useMemo, useState } from 'react' | ||
| import { keccak256, namehash, encodeAbiParameters, toHex } from 'viem' | ||
| import { packetToBytes } from 'viem/ens' | ||
|
|
||
| import { Input } from '../ui/Input' | ||
|
|
||
| type RecordType = 'name' | 'text' | 'addr' | ||
|
|
||
| export function ResourceCalculator() { | ||
| const [name, setName] = useState('alice.eth') | ||
| const [recordType, setRecordType] = useState<RecordType>('text') | ||
| const [textKey, setTextKey] = useState('avatar') | ||
| const [coinType, setCoinType] = useState('60') | ||
|
|
||
| const computed = useMemo(() => { | ||
| if (!name) return null | ||
| try { | ||
| const node = namehash(name) | ||
|
|
||
| let part: `0x${string}` | ||
| let partLabel: string | ||
| let authorizeFunction: string | ||
| let authorizeArgs: string | ||
|
|
||
| const dnsName = toHex(packetToBytes(name)) | ||
|
|
||
| if (recordType === 'name') { | ||
| part = '0x0000000000000000000000000000000000000000000000000000000000000000' | ||
| partLabel = 'bytes32(0) (name-level)' | ||
| authorizeFunction = 'authorizeNameRoles' | ||
| authorizeArgs = `(${dnsName}, roleBitmap, account, true)` | ||
| } else if (recordType === 'text') { | ||
| // partHash(key) = keccak256(bytes(key)) | ||
| part = keccak256(toHex(textKey)) | ||
| partLabel = `partHash("${textKey}") = keccak256(bytes("${textKey}"))` | ||
| authorizeFunction = 'authorizeTextRoles' | ||
| authorizeArgs = `(${dnsName}, "${textKey}", account, true)` | ||
| } else { | ||
| // partHash(coinType) = keccak256(abi.encode(coinType)) | ||
| const coinTypeNum = BigInt(coinType || '0') | ||
| part = keccak256( | ||
| encodeAbiParameters([{ type: 'uint256' }], [coinTypeNum]) | ||
| ) | ||
| partLabel = `partHash(${coinType}) = keccak256(abi.encode(${coinType}))` | ||
| authorizeFunction = 'authorizeAddrRoles' | ||
| authorizeArgs = `(${dnsName}, ${coinType}, account, true)` | ||
| } | ||
|
|
||
| // resource = keccak256(node, part) | ||
| // Special case: resource(0, 0) = ROOT_RESOURCE = 0 | ||
| let resource: string | ||
| if (node === '0x0000000000000000000000000000000000000000000000000000000000000000' && | ||
| part === '0x0000000000000000000000000000000000000000000000000000000000000000') { | ||
| resource = '0x0000000000000000000000000000000000000000000000000000000000000000' | ||
| } else { | ||
| resource = keccak256( | ||
| encodeAbiParameters( | ||
| [{ type: 'bytes32' }, { type: 'bytes32' }], | ||
| [node, part] | ||
| ) | ||
| ) | ||
| } | ||
|
|
||
| return { | ||
| node, | ||
| part, | ||
| partLabel, | ||
| resource, | ||
| authorizeFunction, | ||
| authorizeArgs, | ||
| dnsName, | ||
| } | ||
| } catch { | ||
| return null | ||
| } | ||
| }, [name, recordType, textKey, coinType]) | ||
|
|
||
| return ( | ||
| <div className="flex flex-col gap-4"> | ||
| <Input | ||
| label="Name" | ||
| value={name} | ||
| onChange={(e) => setName(e.target.value)} | ||
| placeholder="alice.eth" | ||
| /> | ||
|
|
||
| <div className="flex flex-col gap-2"> | ||
| <label className="text-grey px-2 leading-none font-semibold"> | ||
| Scope | ||
| </label> | ||
| <div className="flex gap-2 px-2"> | ||
| {(['name', 'text', 'addr'] as const).map((type) => ( | ||
| <button | ||
| key={type} | ||
| onClick={() => setRecordType(type)} | ||
| className={`rounded-md border px-3 py-1.5 text-sm font-medium transition ${ | ||
| recordType === type | ||
| ? 'border-[var(--vocs-color_borderAccent)] bg-[var(--vocs-color_borderAccent)] text-white' | ||
| : 'border-border hover:border-[var(--vocs-color_borderAccent)]' | ||
| }`} | ||
| > | ||
| {type === 'name' ? 'Name-level' : type === 'text' ? 'Text key' : 'Coin type'} | ||
| </button> | ||
| ))} | ||
| </div> | ||
| </div> | ||
|
|
||
| {recordType === 'text' && ( | ||
| <Input | ||
| label="Text key" | ||
| value={textKey} | ||
| onChange={(e) => setTextKey(e.target.value)} | ||
| placeholder="avatar" | ||
| /> | ||
| )} | ||
|
|
||
| {recordType === 'addr' && ( | ||
| <Input | ||
| label="Coin type" | ||
| value={coinType} | ||
| onChange={(e) => setCoinType(e.target.value)} | ||
| placeholder="60" | ||
| /> | ||
| )} | ||
|
|
||
| {computed && ( | ||
| <> | ||
| <Input label="node (namehash)" value={computed.node} disabled copyButton /> | ||
| <Input label={`part (${computed.partLabel})`} value={computed.part} disabled copyButton /> | ||
| <Input label="resource = keccak256(node, part)" value={computed.resource} disabled copyButton /> | ||
| <Input | ||
| label={`To grant: ${computed.authorizeFunction}`} | ||
| value={computed.authorizeArgs} | ||
| disabled | ||
| copyButton | ||
| /> | ||
| </> | ||
| )} | ||
| </div> | ||
| ) | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The sliders don't seem to change any of the values for me
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They even increment in your animation :D
tokenVersionIdincrements the lower 32 bits of Token ID.eacVersionIdincrements the lower 32 bits of resource.The canonicalId always zeroes out the lower 32 bits, so nothing changes there and the labelhash is just a constant 256bit hash. But it's good feedback that you didn't even realize them changing. Maybe I should add some visual effect to the values when the slider is used.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh whoops, ya i was looking at the left side 😅
seems maybe weird to display the same value 4 times when only the right side changes, but not a big deal for now