Skip to main content
This page documents the on-chain Registrar interface for claiming a name such as alice.acme. For application code, start with the Owner and Holder SDK walkthrough. A username claim issues a name within an existing namespace. It does not use the top-level namespace Allocator or its objection and refund process. Universal Lookup remains the shared read entry point. A typical integration follows four steps:
  1. Check the namespace’s native contracts and claim configuration.
  2. Request a quote for the label and claimant.
  3. Build and authorize the exact claim intent, including its destination and fee.
  4. Submit the transaction and retain its request ID to recover the receipt.
Use the current deployment addresses and the stored and request types that match them.

Network fees

Network execution and storage fees are separate from any username price, including a zero price. Owner 0.12.0 and Holder 0.10.0 default maxNetworkFeeStroops to 50_000_000n (5 XLM) per transaction, including storage restoration. Native operations also respect maxNativeFeeStroops; when both options are set, the lower limit applies. They reject a higher estimate before signing. See write-client fee limits. Initial storage rent can exceed that limit. Review the estimate before explicitly choosing a higher limit; this does not change the on-chain username price.

Capability and bindings

native_contracts checks the required namespace record, Registry-deployed attestations, clean provenance, selected Resolver pointer and current Wasm hashes against the Registry’s per-namespace code pins in governed mode, or factory templates on historical deployments. It does not call the Registrar or Resolver. This permits its use while either contract is already executing. A namespace owner’s ownership epoch changes on every completed ownership transition. Returning the namespace to a former owner does not restore old claim settings. Epoch numbers increase but are not necessarily consecutive for one namespace. Verify code, provenance and version answers before using native claims. A failed or unsupported capability read does not mean public claiming is open.

Owner controls

Administrative writes require the current Registry owner. Console operator roles do not replace on-chain authorization. Unless shown otherwise, the methods below return Result<result, Error>.

Read and configure policy

Reserve and assign labels

Read usage

Policy behavior

Before configuration, manual owner issuance is available and public claiming is unavailable. Configuration sets the mode (Manual or Public), enablement, admission rule, fee, G treasury and usage limits. It also records the current ownership epoch: the version of namespace ownership against which the settings were authorized. A new owner must configure claiming explicitly. Old settings cannot be enabled under a different ownership epoch. Configuration, pause and re-enable advance the policy and approval-grant epochs; reservation changes advance the policy version. Public mode blocks the manual issue and issue_batch methods even while paused. A public label must use public rules. The explicit reserved path is the administrative exception to public username prices and quotas. It still rejects an active name and records separate reserved-issuance usage.

Reservation behavior

Reservation batches are atomic, contain 1–23 distinct canonical labels and reject active names when reserving them. Releasing a reservation leaves any holder unchanged. An issued reserved name stays reserved until the namespace owner releases the reservation, including after the name expires. issue_reserved uses owner authorization and the holder’s default address. The atomic custom-destination variant requires both owner and holder authorization. The Owner SDK exposes simple assignment. Calling the atomic reserved method for different owner and holder accounts requires an integration that collects both authorizations.

Claim and recovery

Quote

A quote reports availability, reservation, current configuration, ownership epoch, record generation/expiry and lifetime usage. It does not reserve the label. Availability respects the applicable renewal grace period, not just the expiry timestamp. available: true alone does not mean claiming is enabled or that the wallet is eligible. Inspect all relevant fields and the current policy.

Submit a claim

Current public claims support a G or C claimant as holder and username-fee payer. Check contract_claim_version() == 1 before using a C claimant; claim_version() == 1 alone does not establish that support. A C claimant needs an integration with its contract wallet’s authorization rules, and a separate G transaction source pays network fees. The receiving destination can independently be G without a memo, G with ID/Text/Hash memo, M with its muxed ID, or C without a memo. The transaction records future receiving instructions; it does not make a payment to that destination. A fresh claim checks the complete signed context, current policy and owner epochs, fixed namespace term, exact fee, expected name generation/expiry, availability, reservation, wallet limit and admission rule. It then issues the name, transfers any fee directly to the treasury, initializes the destination and writes usage and a receipt in one transaction. Any failure rolls back those business effects. Network fees are separate.

Recover a result

A matching existing receipt returns Replayed before fresh deadline, policy and authorization checks. It does not charge, increment usage, issue another name or rewrite a later destination. Reusing a request ID with a different operation or intent returns RequestIdConflict. Keep request IDs stable only for the same immutable intent. Credential nonce/signature renewal does not change that intent. After recovering a receipt, verify the current holder and generation through Lookup before associating a name with an app account. The receipt records a historical result. A missing receipt or interrupted RPC read does not prove that a transaction failed. Reconcile the original transaction before replacing it.

Exact authorization

For claim, claimant and optional approver each authorize the single argument [intent] with native Soroban authorization. The Merkle proof is not part of the signed intent; it can only demonstrate membership in the already committed root. The claimant’s authorization has these children, in order:
  1. Native asset contract transfer(claimant, fee_recipient, fee_amount) when the fee is nonzero.
  2. Resolver initialize_destination(label, claimant, fresh_generation, destination).
The optional G approver’s claim authorization has no children. The approver does not authorize a fee transfer or substitute for claimant authorization. G identities use native account signer/threshold rules; a C claimant uses its contract’s __check_auth implementation. The backend signs the approver’s authorization entry independently of the claimant’s authorization and the transaction-source signature. An intent binds network, Registry, Registrar, namespace, request ID, execution window, label, claimant, complete destination, Resolver, existing generation/expiry, term, policy/owner/grant epochs and exact fee token/amount/recipient. See the type definitions. The business execution window is inclusive: valid_after <= now <= deadline. Its positive span must be at most 3600 seconds. Approval mode may configure a shorter maximum. Native credential expiration is a separate ledger-based limit; an expired or rotated credential is not proof that a previous request never completed.

Admission rules

Allowlist proof

The leaf is SHA-256 of this Soroban XDR tuple:
For each sibling, order the two 32-byte hashes lexicographically and compute SHA256(0x01 || smaller || larger). Use the final value as the root. This username allowlist is separate from the Allocator’s top-level namespace reservation proof.

Wallet and approval limits

Wallet limits count cumulative public claims, including expiry/reissue claims. wallet_limit = 0 means unlimited. They do not count current holdings or prove one person. Reserved assignments have their own count. The G approver must differ from the namespace owner, fee recipient and claimant. Approval requires a nonzero cumulative allowance, rate limit, window and lifetime. The owner chooses these numbers. The window is at most 31536000 seconds; approval lifetime is at most 3600 seconds. Counts survive mode, key, policy and owner changes. An active window cannot be reset or shortened by reconfiguration; a longer window may extend its end. The next approved claim starts a new window after expiry. The lifetime allowance is an absolute ceiling; only an explicit owner increase provides more headroom.

Transfer and renewal

Accept a transfer

Transfer acceptance requires the intended recipient. It checks the exact current holder, generation, name expiry and pending proposal expiry. It preserves the name’s expiry, advances the generation and initializes the selected destination atomically. A failed destination write leaves the existing holder and proposal unchanged. Claim pause, app admission and claim quotas do not gate this operation.

Renew a name

Holder renewal uses the immutable positive default term. It checks the recorded holder, generation and expiry, then extends from max(now, old_expiry). It preserves the generation and existing records. It is available within the shorter of 30 days or one policy term before expiry, subject to the resulting expiry being no more than 100 years from execution and within the signed result bounds. Zero-expiry or permanent names cannot use it. The legacy owner renewal method also rejects zero extension and leases beyond the same 100-year bound. The owner can configure renewal grace from zero (the default) through 90 days. Enabling it protects names whose expiry is at or after its activation timestamp. Changing one positive duration to another retains that cutoff; disabling and re-enabling starts a new activation. Each change advances the claim policy version. Grace prevents ordinary reissue until ledger time is strictly greater than expiry + applicable grace; it does not keep an expired name resolving or remove any owner reclaim power. After that protection ends, an expired holder can still renew while it remains the recorded holder and no reissue has won, unless the owner has reserved the now-reissuable label. Read both grace getters and the current name state; a nonzero duration without an activation timestamp provides no protection. preview_destination returns the exact-generation receiving instructions, including when inactive. It rejects mismatched generations and invalid configured payment records. Ordinary payment resolution still rejects expired names. Preview is not a new payment destination or a bypass of live resolution.

Destination initialization

The initializer is restricted to the bound native Registrar and exact holder consent. It accepts only a destination for a generation freshly created by claim, reserved assignment or accepted transfer. It derives the node from its bound namespace, checks native bindings, rejects already initialized/same-or-newer data, and makes no callback into the active Registrar. It is not a general owner record setter, and renewal does not call it.

Errors and compatibility

Existing Registrar error codes 1–20 retain their values. The native claim methods add the codes below.

Configuration and reservations

Admission and limits

Request and execution errors

These are the claim and renewal-related codes, not the full Registrar error catalogue. Code 37 remains in the ABI; current contract-claim capability 1 permits both G and C claimants. Registry additionally reports OwnershipEpochUnavailable (29) and OwnershipEpochOverflow (30). Resolver adds InitializationContextMismatch (22), DestinationAlreadyInitialized (23) and GenerationMismatch (24). An atomic Registrar call maps a failed initializer to Registrar error 41 and aborts the whole operation. A contract rejection does not authorize changing the destination, dropping a memo, opening admission or charging different terms on a retry. Changing a Registry deployment template affects future contracts. Existing governed testnet contracts can receive compatible authorized upgrades at the same address; neither operation automatically changes their stored lifecycle policies. Choose those rules during namespace activation.