IDotnsPopController
Inherits: IDotnsController
Title: IDotnsPopController
Interface for the dedicated PoP controller orchestrating lite-person and full-person username issuance on behalf of the PoP gateway pallet.
Deliberately disjoint from @custom:contract IDotnsRegistrarController. The two
controllers coexist on @custom:contract DotnsRegistrar via its multi-controller affordance
and neither imports the other. Collision handling reduces to the registrar's ERC721
availability check (first-to-mint wins). Reservation queuing for reservedBaseLabel is
an intra-PoP coordination mechanism only; it does not block public registrations.
Label formats:
Lite-person usernames (first argument to @custom:function reserveBaseName and the
liteLabel of a LinkKind.LiteUsername link) are DNS labels with exactly two
trailing digits (e.g. alice42) per @custom:function StringUtils.isLitePersonLabel.
The gateway strips any separator before calling so the on-chain label is flat.
Full-person usernames (the label of @custom:function registerBaseName and the
optional reservedBaseLabel of @custom:function reserveBaseName) follow the
DNS-label rules enforced by @custom:function StringUtils.isSingleLabel (e.g.
alice). Lite and public registrations share one namespace; first-to-mint wins at
the ERC721 layer. Cross-flow priority on the stripped base stem is arbitrated by
Notes:
-
function: IPopRules.reserveBaseNameForPop.
-
security-contact: admin@parity.io
Functions
reserveBaseName
Registers a lite-person username on behalf of the supplied user and optionally enqueues a reservation for a base name they intend to claim as a full person later.
Callable only via the registered PoP gateway (otherwise @custom:reverts NotGateway);
the gateway is responsible for asserting substrate Root authority before forwarding
here. The lite leg validates the dotted stem.NN shape and requires the flattened label
to classify as PopLite (otherwise @custom:reverts InvalidLiteLabel), and rejects a
supplied chat key whose length is neither zero nor CHAT_KEY_LENGTH
(otherwise @custom:reverts InvalidChatKey). On a warm-path mint (user already has a
LabelStore) it emits @custom:emits LiteNameReserved and @custom:emits NameRegistered;
on a cold-path mint it emits @custom:emits LiteNameReserved and
Notes:
-
emits: PendingClaimStashed, with @custom:emits NameRegistered deferred to
-
function: claimLabelStore when the user settles. The base-name leg only runs when
reservedBaseLabelis non-empty: it validates the DNS-label shape and requires a true base label with no trailing digits (otherwise @custom:reverts InvalidBaseLabel) before any queue mutation so a bad reservation never touches the queue, advances the head past expired entries (emitting @custom:emits ReservationExpired for each one), removes the user from any prior queue position so a single user holds at most one live reservation across all labels, and enqueues a fresh entry (emitting -
emits: ReservationQueued). The enqueue rejects with @custom:reverts AlreadyReserved when the user already holds a reservation that was not cleared by the prior removal and with @custom:reverts QueueFull when the per-label queue has reached
MAX_RESERVATION_QUEUE. Cross-chain callers pass the ABI-encoded reservation tuple as the call's payload, which Solidity decodes directly.
function reserveBaseName(BaseReservation calldata params) external;
Parameters
| Name | Type | Description |
|---|---|---|
params | BaseReservation | Reservation request; see @custom:struct BaseReservation. |
reserveBaseName
Raw-payload variant of @custom:function reserveBaseName for cross-chain dispatch.
payload is abi.encode(BaseReservation({...})), the bare ABI-encoded struct
with NO function-selector prefix and NO leading bytes-length word. The contract
prepends the typed selector and delegatecalls itself so the typed entrypoint runs
in the original call context and remains the single source of truth, which means the
typed overload's full revert surface bubbles up byte-for-byte: gateway-only access
(otherwise @custom:reverts NotGateway), lite-label shape (otherwise
Notes:
-
reverts: InvalidLiteLabel), base-label shape (otherwise
-
reverts: InvalidBaseLabel), duplicate-reservation guard (otherwise
-
reverts: AlreadyReserved), and queue capacity (otherwise
-
reverts: QueueFull). The success path likewise emits the same events as the typed call: @custom:emits LiteNameReserved and @custom:emits NameRegistered on the lite leg, plus @custom:emits ReservationQueued and any @custom:emits ReservationExpired observed while advancing the queue head when the base-name leg runs. Note:
abi.decodeignores trailing bytes past the encoded struct, so off-chain encoders MUST NOT assume strict length validation.
function reserveBaseName(bytes calldata payload) external;
Parameters
| Name | Type | Description |
|---|---|---|
payload | bytes | abi.encode(BaseReservation) produced by the cross-chain caller. |
reserveBaseNameOnly
Enqueues only the full/base-name reservation for a user.
Callable only via the registered PoP gateway. This is the second step of the split gateway flow: @custom:function reserveLiteName mints the lite username first, then this function reserves the full/base label in a separate transaction so proof-size stays below per-call limits. Reverts with @custom:reverts InvalidBaseLabel when the label is empty, non-canonical, digit-suffixed, or governance-reserved. The caller remains agnostic about backend batching; it simply exposes a small retryable primitive.
function reserveBaseNameOnly(BaseNameReservation calldata params) external;
Parameters
| Name | Type | Description |
|---|---|---|
params | BaseNameReservation | Reservation request; see @custom:struct BaseNameReservation. |
reserveBaseNameOnly
Raw-payload variant of @custom:function reserveBaseNameOnly for cross-chain
dispatch. @param payload abi.encode(BaseNameReservation) produced by the cross-chain
caller.
function reserveBaseNameOnly(bytes calldata payload) external;
reserveLiteName
Registers a lite-person username on behalf of the supplied user without touching the base-name reservation queue.
Callable only via the registered PoP gateway (otherwise @custom:reverts NotGateway);
the gateway is responsible for asserting substrate Root authority before forwarding
here. The supplied label must satisfy the dotted stem.NN shape and the flattened label
must classify as PopLite (otherwise @custom:reverts InvalidLiteLabel); a supplied chat
key whose length is neither zero nor CHAT_KEY_LENGTH reverts
Notes:
-
reverts: InvalidChatKey before mint and resolver writes run. On a warm-path mint emits @custom:emits LiteNameReserved and @custom:emits NameRegistered. On a cold-path mint emits @custom:emits LiteNameReserved and @custom:emits PendingClaimStashed, with
-
emits: NameRegistered deferred to @custom:function claimLabelStore when the user settles. Cross-chain callers pass the ABI-encoded lite-registration tuple as the call's payload, which Solidity decodes directly.
function reserveLiteName(LiteRegistration calldata params) external;
Parameters
| Name | Type | Description |
|---|---|---|
params | LiteRegistration | Registration request; see @custom:struct LiteRegistration. |
reserveLiteName
Raw-payload variant of @custom:function reserveLiteName for cross-chain dispatch.
payload is abi.encode(LiteRegistration({...})), the bare ABI-encoded struct
with NO function-selector prefix and NO leading bytes-length word. The contract
prepends the typed selector and delegatecalls itself so the typed entrypoint runs
in the original call context and remains the single source of truth, so the typed
overload's revert surface bubbles up byte-for-byte: gateway-only access (otherwise
Notes:
-
reverts: NotGateway) and lite-label shape (otherwise
-
reverts: InvalidLiteLabel). The success path emits the same events as the typed call: @custom:emits LiteNameReserved and @custom:emits NameRegistered. Note:
abi.decodeignores trailing bytes past the encoded struct, so off-chain encoders MUST NOT assume strict length validation; pad-only junk past the tail is silently dropped (no state corruption; decoded values are unchanged). Worked example off-chain:bytes payload = abi.encode(LiteRegistration({liteLabel: "alice42", user: u, chatKey: k}));
function reserveLiteName(bytes calldata payload) external;
Parameters
| Name | Type | Description |
|---|---|---|
payload | bytes | abi.encode(LiteRegistration) produced by the cross-chain caller. |
registerBaseName
Registers a full-person username on behalf of the supplied user.
Callable only via the registered PoP gateway (otherwise @custom:reverts NotGateway);
the gateway is responsible for asserting substrate Root authority before forwarding
here. The base label must satisfy the DNS-label shape and be a true base label with no
trailing digits (otherwise @custom:reverts InvalidBaseLabel), and the label must not
classify as governance-reserved (otherwise @custom:reverts InvalidBaseLabel). The
gateway also defers to PopRules as the single cross-flow authority: when PopRules
carries a live base-name slot held by another user (stamped by the public commit-reveal
flow or this controller's prior queue head), the call reverts @custom:reverts NotHolder
before any queue mutation. Two orthogonal axes drive the state machine. The reservation
axis treats the user as claiming if and only if they hold the live head-of-queue
reservation on the base label: a claim wipes the entire queue, releases the PopRules
slot, and emits @custom:emits BaseNameClaimed; a non-claim silently relinquishes any
pending entry the user holds and emits @custom:emits StandaloneNameRegistered. Advancing
the queue head past expired entries emits @custom:emits ReservationExpired for each
one. The chat-key axis selects whether a fresh key is persisted on the resolver or the
new entry inherits its key from a prior lite-person username. The fresh-key branch
rejects a chat key whose length is neither zero nor CHAT_KEY_LENGTH (otherwise
Notes:
-
reverts: InvalidChatKey). The
LiteUsernamebranch validates the lite label'sNAMEXXshape (otherwise @custom:reverts InvalidLiteLabel), requires the registrant to own the lite token (otherwise @custom:reverts LiteLabelNotOwnedByUser), reads the lite node's chat key from the resolver and copies it across; if the lite node carries no chat key the inherited value is empty and the full node's chat-key write is silently skipped (theLiteToFullLinkedevent still fires). Emits @custom:emits LiteToFullLinked alongside the registration event. On a warm-path mint the event order is -
emits: NameRegistered first (from the inner mint), then
-
emits: BaseNameClaimed or @custom:emits StandaloneNameRegistered, then
-
emits: LiteToFullLinked when applicable. On a cold-path mint
-
emits: PendingClaimStashed replaces the initial @custom:emits NameRegistered; the deferred @custom:emits NameRegistered fires later from @custom:function claimLabelStore. Cross-chain callers pass the ABI-encoded full-registration tuple as the call's payload, which Solidity decodes directly.
function registerBaseName(FullRegistration calldata params) external;
Parameters
| Name | Type | Description |
|---|---|---|
params | FullRegistration | Registration request; see @custom:struct FullRegistration. |
registerBaseName
Raw-payload variant of @custom:function registerBaseName for cross-chain dispatch.
payload is abi.encode(FullRegistration({...})), the bare ABI-encoded struct
with NO function-selector prefix and NO leading bytes-length word. The contract
prepends the typed selector and delegatecalls itself so the typed entrypoint runs
in the original call context and remains the single source of truth, so the typed
overload's revert surface bubbles up byte-for-byte: gateway-only access (otherwise
Note:
reverts: NotGateway), base-label shape (otherwise @custom:reverts InvalidBaseLabel),
lite-label shape on the LiteUsername branch (otherwise @custom:reverts InvalidLiteLabel),
and the standalone-mint holder guard (otherwise @custom:reverts NotHolder). The success
path emits the same events as the typed call: @custom:emits BaseNameClaimed on a claim
or @custom:emits StandaloneNameRegistered otherwise, @custom:emits LiteToFullLinked on
the LiteUsername branch, @custom:emits ReservationExpired for each entry reaped while
advancing the queue head, and always @custom:emits NameRegistered.
Note: abi.decode ignores trailing bytes past the encoded struct, so off-chain
encoders MUST NOT assume strict length validation.
function registerBaseName(bytes calldata payload) external;
Parameters
| Name | Type | Description |
|---|---|---|
payload | bytes | abi.encode(FullRegistration) produced by the cross-chain caller. |
expireReservation
Permissionlessly removes expired entries from the head of a reservation queue.
Permissionless on purpose: anyone (typically a UI or a bot) can poke a stale queue
so the next live head takes over without waiting for the next gateway call. Validates
the DNS-label shape of reservedBaseLabel (otherwise @custom:reverts InvalidBaseLabel)
and emits @custom:emits ReservationExpired for every expired entry reaped from the
head. Only base-shaped labels (no trailing digits) ever key a reservation queue, so a
lite-shaped label still passes the shape check but resolves to an empty queue and the
call is a no-op.
function expireReservation(string calldata reservedBaseLabel) external;
relinquishReservation
Lets the caller voluntarily drop their own active reservation.
Reverts with @custom:reverts NoActiveReservation when the caller holds no live reservation. On success the caller's entry is removed from its queue and
Note: emits: ReservationRelinquished is emitted; if the removed entry was the queue head, head advancement may additionally emit @custom:emits ReservationExpired for any stale entries reaped behind it.
function relinquishReservation() external;
isReservedForClaim
Returns whether a label currently has a live reservation at the queue head.
Validates the DNS-label shape of reservedBaseLabel (otherwise
Note: reverts: InvalidBaseLabel) before inspecting the queue.
function isReservedForClaim(string calldata reservedBaseLabel)
external
view
returns (bool reserved, address holder);
setReservationDuration
Updates the reservation duration used to decide when queue entries expire.
Owner-gated (otherwise @custom:reverts OwnableUnauthorizedAccount); emits
Note: emits: ReservationDurationSet on success.
function setReservationDuration(uint64 duration) external;
reservationMeta
Returns the queue metadata (head, tail) for labelhash.
Read-only accessor over the per-label reservation queue. head == tail means
the queue is empty; active entries occupy [head, tail). Exposed on the interface
because invariant tests and off-chain consumers (dotli, dweb) use it to enumerate
live queue state without scanning storage.
function reservationMeta(bytes32 labelhash) external view returns (uint64 head, uint64 tail);
Parameters
| Name | Type | Description |
|---|---|---|
labelhash | bytes32 | Keccak-256 of the base label whose queue is being read. |
Returns
| Name | Type | Description |
|---|---|---|
head | uint64 | Index of the live queue head. |
tail | uint64 | Index one past the last queued entry. |
reservationEntry
Returns the queue entry at index for labelhash.
Sparse storage: a zero entryOwner means the slot was relinquished, expired and
reaped, or never written. Callers pair this with @custom:function reservationMeta to walk
the live window [head, tail).
function reservationEntry(
bytes32 labelhash,
uint64 index
)
external
view
returns (address entryOwner, uint64 joinedAt);
Parameters
| Name | Type | Description |
|---|---|---|
labelhash | bytes32 | Keccak-256 of the base label whose queue is being read. |
index | uint64 | Queue index to look up. |
Returns
| Name | Type | Description |
|---|---|---|
entryOwner | address | Owner of the slot (zero if empty/relinquished). |
joinedAt | uint64 | Timestamp the entry was enqueued (only meaningful when entryOwner != address(0)). |
userReservation
Returns user's current reservation pointer.
A zero labelhash on the returned struct means the user holds no reservation;
index is meaningful only when labelhash is non-zero.
function userReservation(address user)
external
view
returns (UserReservation memory reservation);
Parameters
| Name | Type | Description |
|---|---|---|
user | address | Account whose reservation pointer is being read. |
Returns
| Name | Type | Description |
|---|---|---|
reservation | UserReservation | Per-user reservation pointer; see @custom:struct UserReservation. |
claimLabelStore
Settles the caller's deferred bindings by writing every stashed label into
the caller's LabelStore, deploying the store first if the caller doesn't yet
have one.
User-signed entrypoint: pallet-revive charges any LabelStore storage
deposit against msg.sender's balance through the runtime's configured deposit
backend. This is the only path that can create the store, because the Root gateway
origin cannot instantiate contracts. Reverts with @custom:reverts NoPendingClaim when
the caller holds no live stashed entries. Reuses any existing LabelStore returned by
the factory (settling via this controller after a concurrent public-flow mint, or
settling twice through this controller, both find a live store and skip deployment),
otherwise deploys a fresh store via the protocol-registered factory. Writes each live
label keyed by its node (namehash), clears the pending-claim entries, and emits
Note: emits: PendingClaimSettled and @custom:emits NameRegistered per settled name. Chat-key and lite-link records are not touched here; they are persisted on the PoP resolver at mint time, not at settlement.
function claimLabelStore() external;
claimLabelStoreFor
Gateway-driven variant of @custom:function claimLabelStore for split workflows.
Callable only via the registered PoP gateway. It settles the pending LabelStore claim
for user without requiring a user transaction. The user-signed
Note: function: claimLabelStore remains as a permissioned-by-origin fallback if gateway dispatch fails.
function claimLabelStoreFor(address user) external;
Parameters
| Name | Type | Description |
|---|---|---|
user | address | Account whose pending claim should be settled. |
expirePendingClaim
Permissionlessly reaps a user's deferred bindings that sat unsettled past
reservationDuration.
Permissionless on purpose: anyone (typically a UI or a bot) can poke stale entries so the user's pile cannot grow without bound. Sweeps every expired entry, leaving any still-live ones in place; the user is removed from the enumeration set only when no entries remain. Reverts with @custom:reverts NoPendingClaim when the user holds no entries and with @custom:reverts PendingClaimNotExpired when none of the held entries have lapsed. Emits @custom:emits PendingClaimExpired per swept name.
function expirePendingClaim(address user) external;
Parameters
| Name | Type | Description |
|---|---|---|
user | address | Address whose pending claims are being swept. |
pendingClaims
Returns user's pending-claim entries.
An empty array means the user has no pending claims. A user accumulates one entry per deferred name until a signed-origin @custom:function claimLabelStore settles them.
function pendingClaims(address user) external view returns (PendingClaim[] memory claims);
Parameters
| Name | Type | Description |
|---|---|---|
user | address | Account whose pending claims are being read. |
Returns
| Name | Type | Description |
|---|---|---|
claims | PendingClaim[] | Per-user pending-claim entries; see @custom:struct PendingClaim. |
pendingClaimUserCount
Returns the number of users with at least one live pending claim.
Exact live count, not an all-time tally: fully settled and fully expired users are removed from the enumeration set so off-chain consumers can page through every stalled user without filtering.
function pendingClaimUserCount() external view returns (uint256 count);
Returns
| Name | Type | Description |
|---|---|---|
count | uint256 | Number of users currently holding a pending claim. |
pendingClaimUsers
Returns a paginated slice of users with at least one live pending claim.
Pair with @custom:function pendingClaims to read each user's stashed entries.
Ordering is not chronological; callers MUST NOT assume mintedAt is monotonic
across the slice. Returns an empty array when offset is past the live count.
function pendingClaimUsers(
uint256 offset,
uint256 limit
)
external
view
returns (address[] memory users);
Parameters
| Name | Type | Description |
|---|---|---|
offset | uint256 | Start index. |
limit | uint256 | Maximum entries to return. |
Returns
| Name | Type | Description |
|---|---|---|
users | address[] | Slice of users currently holding a pending claim. |
Events
LiteNameReserved
Emitted when a lite-person username is registered via the PoP gateway.
event LiteNameReserved(bytes32 indexed labelhash, address indexed user, string label);
BaseNameClaimed
Emitted when a full-person username is claimed out of an existing reservation.
event BaseNameClaimed(bytes32 indexed labelhash, address indexed user, string label);
StandaloneNameRegistered
Emitted when a standalone full-person username is registered via the PoP gateway.
event StandaloneNameRegistered(bytes32 indexed labelhash, address indexed user, string label);
ReservationQueued
Emitted when a reservation entry is added to the queue for a base name.
event ReservationQueued(
bytes32 indexed reservedLabelhash, address indexed user, uint64 position
);
Parameters
| Name | Type | Description |
|---|---|---|
reservedLabelhash | bytes32 | |
user | address | |
position | uint64 | Position in the queue at the time of joining (0 = active holder). |
ReservationExpired
Emitted when a reservation entry is removed due to expiry.
event ReservationExpired(bytes32 indexed reservedLabelhash, address indexed user);
ReservationRelinquished
Emitted when a user voluntarily relinquishes their reservation.
event ReservationRelinquished(bytes32 indexed reservedLabelhash, address indexed user);
LiteToFullLinked
Emitted when a full-person username is linked to a lite-person username.
event LiteToFullLinked(bytes32 indexed fullLabelhash, bytes32 indexed liteLabelhash);
ReservationDurationSet
Emitted when the reservation duration is updated.
event ReservationDurationSet(uint64 duration);
NameRegistered
Emitted when a name is successfully registered via the PoP controller.
event NameRegistered(
string indexed label, bytes32 indexed labelhash, address indexed owner, address store
);
Parameters
| Name | Type | Description |
|---|---|---|
label | string | |
labelhash | bytes32 | |
owner | address | |
store | address | The Store instance used to persist the immutable registration record. |
PendingClaimStashed
Emitted when a gateway-path mint defers its LabelStore write into the
pending-claim mapping because the user has no store yet.
event PendingClaimStashed(address indexed user, bytes32 indexed labelhash, string label);
PendingClaimSettled
Emitted when a user settles a deferred binding by deploying their
LabelStore and backfilling the stashed label and chat key.
event PendingClaimSettled(address indexed user, bytes32 indexed labelhash, address store);
PendingClaimExpired
Emitted when a deferred binding is reaped because it sat unsettled past
reservationDuration.
event PendingClaimExpired(address indexed user, bytes32 indexed labelhash);
ReservationHeadAdvanced
Emitted when a reservation queue's head transitions to a new user, either via expiry of the prior head or via the explicit relinquish path.
event ReservationHeadAdvanced(bytes32 indexed labelhash, address indexed newHead);
Parameters
| Name | Type | Description |
|---|---|---|
labelhash | bytes32 | Base-label hash whose queue head changed. |
newHead | address | Address now holding the head slot. |
Errors
NotGateway
Thrown when a gated entrypoint is reached from an address that is not the gateway registered on the protocol registry under the PoP gateway key.
The controller delegates substrate Root-authority verification to the registered gateway, which is the Root gateway dispatcher, and authorises calls solely against the address resolved from the protocol registry. The caller parameter carries the immediate EVM caller observed by this contract for off-chain diagnostics.
error NotGateway(address caller);
Parameters
| Name | Type | Description |
|---|---|---|
caller | address | Immediate EVM caller observed by this contract. |
InvalidLiteLabel
Thrown when a supplied lite-person label does not match NAMEXX.
error InvalidLiteLabel();
InvalidBaseLabel
Thrown when a supplied base label is not a canonical DNS label.
error InvalidBaseLabel();
InvalidChatKey
Thrown when a supplied chat key is non-empty and not exactly 65 bytes long.
Mirrors the resolver's InvalidChatKeyLength so the controller surfaces a
controller-local error before the mint runs.
error InvalidChatKey(uint256 length);
Parameters
| Name | Type | Description |
|---|---|---|
length | uint256 | Caller-supplied chat key length, in bytes. |
NoActiveReservation
Thrown when a user tries to claim or relinquish a reservation that they do not hold.
error NoActiveReservation(address user);
QueueFull
Thrown when a reservation queue has reached its capacity.
error QueueFull(bytes32 labelhash);
AlreadyReserved
Thrown when attempting to enqueue a user who already has an active reservation.
error AlreadyReserved(address user, bytes32 labelhash);
NotHolder
Thrown when someone tries to mint a base label in standalone mode while another user holds the live head-of-queue reservation.
error NotHolder(address user, bytes32 labelhash);
NoPendingClaim
Thrown when @custom:function claimLabelStore is called by a user with no recorded pending-claim entries.
error NoPendingClaim(address user);
Parameters
| Name | Type | Description |
|---|---|---|
user | address | Caller observed by the controller. |
PendingClaimNotExpired
Thrown when @custom:function expirePendingClaim is invoked but the user holds
no entry past its mintedAt + reservationDuration deadline.
error PendingClaimNotExpired(address user);
Parameters
| Name | Type | Description |
|---|---|---|
user | address | Address whose entries are being inspected. |
LiteLabelNotOwnedByUser
Thrown when a lite-link inheritance does not match the registrar-side owner of the lite label.
Prevents identity hijack by ensuring the registrant on the full-name leg actually holds the prior lite identity whose chat key is being inherited.
error LiteLabelNotOwnedByUser(address user, bytes32 liteLabelhash);
Parameters
| Name | Type | Description |
|---|---|---|
user | address | Registrant supplied by the gateway. |
liteLabelhash | bytes32 | Lite label whose ownership did not match. |
ReservationDurationTooLow
Thrown when @custom:function setReservationDuration is called with a value below the protocol minimum.
error ReservationDurationTooLow(uint64 duration);
Parameters
| Name | Type | Description |
|---|---|---|
duration | uint64 | Caller-supplied duration, in seconds. |
Structs
Link
Tagged union selecting the chat-key source for a full-person registration.
struct Link {
LinkKind kind;
string liteLabel;
bytes chatKey;
}
Properties
| Name | Type | Description |
|---|---|---|
kind | LinkKind | |
liteLabel | string | Lite-person NAMEXX label (only read when kind == LiteUsername). |
chatKey | bytes | Chat key bytes (only read when kind == None). |
UserReservation
Per-user reservation pointer: which queue the user sits in and where.
struct UserReservation {
bytes32 labelhash;
uint64 index;
}
Properties
| Name | Type | Description |
|---|---|---|
labelhash | bytes32 | Non-zero when the user holds a live reservation; zero otherwise. |
index | uint64 | Monotonic queue index, meaningful only when labelhash is non-zero. |
ReservationEntry
Reservation queue entry: a user and the timestamp they joined the queue.
Packs into a single storage slot (20 + 8 bytes).
struct ReservationEntry {
address owner;
uint64 joinedAt;
}
ReservationQueueMeta
Metadata describing the occupied range of a reservation queue.
Uses monotonically increasing indices. Active entries occupy [head, tail);
length = tail - head. Slots past head are deleted as the head advances so
garbage never accumulates.
struct ReservationQueueMeta {
uint64 head;
uint64 tail;
}
PendingClaim
Deferred per-user binding of a freshly minted name to its LabelStore.
Recorded by the gateway path when the user has no LabelStore. The user
later settles the binding via @custom:function claimLabelStore, which deploys
the store from a signed origin and writes the stashed label. PoP-resolver records
(chat key, lite link) are persisted eagerly at mint time on
Note:
contract: IDotnsPopResolver, not at settlement, so the resolver carries
the full identity record regardless of whether the user has settled their Store.
A user accumulates one entry per deferred name: the Root gateway path cannot deploy a
LabelStore (contract creation is forbidden from the Root origin), so it keeps stashing
entries until a signed-origin @custom:function claimLabelStore deploys the store and
settles every entry at once. Each entry's expiry is measured from its own mintedAt
against reservationDuration.
struct PendingClaim {
string label;
uint64 mintedAt;
}
Properties
| Name | Type | Description |
|---|---|---|
label | string | Bare DNS label (no TLD); the TLD is appended at settlement time. |
mintedAt | uint64 | Timestamp of the originating mint. |
LiteRegistration
Lite-person registration payload.
Single struct so the gateway can ABI-encode one tuple as the cross-chain payload
and the contract decodes it directly out of msg.data. All fields are required;
chatKey may be empty bytes to skip the resolver write.
struct LiteRegistration {
string liteLabel;
address user;
bytes chatKey;
}
Properties
| Name | Type | Description |
|---|---|---|
liteLabel | string | Lite-person NAMEXX label being minted. |
user | address | Beneficiary account on this chain. |
chatKey | bytes | Chat-key bytes persisted on the PoP resolver. Empty leaves the slot unset. |
BaseReservation
Lite-person registration combined with an optional base-name reservation.
BaseReservation is a @custom:struct LiteRegistration plus a base-label reservation
slot, expressed as composition rather than duplicated fields so internal helpers can
consume the lite leg via params.lite without unpacking. The lite leg always runs;
the reservation leg only runs when reservedBaseLabel is non-empty.
struct BaseReservation {
LiteRegistration lite;
string reservedBaseLabel;
}
Properties
| Name | Type | Description |
|---|---|---|
lite | LiteRegistration | Lite-person registration request; see LiteRegistration. |
reservedBaseLabel | string | Base label to enqueue for a later full-person claim. Empty string skips the reservation leg. |
BaseNameReservation
Base-name reservation payload for the split gateway flow.
This is the reservation-only primitive. The lite username mint is handled by
Notes:
-
function: reserveLiteName, and LabelStore settlement is handled by
-
function: claimLabelStoreFor or the user fallback @custom:function claimLabelStore.
struct BaseNameReservation {
address user;
string reservedBaseLabel;
}
Properties
| Name | Type | Description |
|---|---|---|
user | address | Beneficiary account that will hold the reservation. |
reservedBaseLabel | string | Base label to enqueue for a later full-person claim. |
FullRegistration
Full-person registration payload.
struct FullRegistration {
string label;
address user;
Link link;
}
Properties
| Name | Type | Description |
|---|---|---|
label | string | Base DNS label being minted. |
user | address | Beneficiary account on this chain. |
link | Link | Chat-key source for the new entry; see @custom:struct Link. |
Enums
LinkKind
Discriminant for the Link union supplied to registerBaseName.
Selects the chat-key source for the full-person username. Orthogonal to whether
the registration is a claim or standalone; that is derived from on-chain reservation
state. None means the caller supplies a fresh chat key in link.chatKey.
LiteUsername means the full-person username is linked to a prior lite-person
username (link.liteLabel) and inherits its chat key.
enum LinkKind {
None,
LiteUsername
}