OpenRealm issues offchain ENS names under qcast.id, allowing users to register names like wvrld.qcast.id and use them as @wvrld in OpenRealm-compatible applications. This system involves a signed message from an account without an existing qname and is managed by the Qname Registry server and the Qname Resolver, in line with ENSIP-16 and ERC-3668.

Qname Usage Policy

To deter squatting and impersonation, OpenRealm implements a usage policy for qnames:

  1. Names linked to public figures or entities can be reclaimed (e.g., @google).
  2. Names unused for over 60 days are subject to reclamation.
  3. Decisions often need human judgement and are made by the OpenRealm core team. For example, if @elon is claimed and Elon Musk desires the name, the decision is based on the current user’s activity level, content quality on OpenRealm, and the legitimacy of their claim to the name.

Qnames also have specific restrictions:

  1. An account (qid) can only hold one qname at a time.
  2. Qname changes are limited to once every 28 days per qid.

Qname Registry API

It’s a simple HTTP service that’s responsible for issuing and tracking qnames. All Qname changes are recorded as a transfer. Registering an qname is a transfer from qid 0 to the user’s qid. Transferring an qname is a transfer from the user’s qid to another qid. Unregistering an qname is a transfer from the user’s qid to qid 0.

Get Transfer History

To get a history of all transfers, make a GET request to /transfers

curl https://qnames.openrealm.social/transfers | jq

It also accepts the following query parameters:

  • from_id - The transfer id to start from for pagination
  • name - The qname to filter by
  • qid - The qid (either from or to) to filter by
  • from_ts - The timestamp (in seconds) to start from for pagination

Get current qname or qid

To get the most recent transfer event for an qid or qname, make a GET request to /transfers/current

e.g. To determine the qid of @openrealm, make the following call and use the value from the to field in the return value

curl https://qnames.openrealm.social/transfers?name=openrealm | jq

To determine the qname of qid 1, make the following call and use the value from the username field in the return value

curl https://qnames.openrealm.social/transfers?qid=1 | jq

Both will return the same transfer object:

{
  "transfer": {
    "id": 1,
    "timestamp": 1628882891,
    "username": "openrealm",
    "owner": "0x0x4E0514a30B7877a5a8105AA3794E8E7abc18Ee84",
    "from": 0,
    "to": 1,
    "user_signature": "0xa6fdd2a69deab5633636fdb430a54b21b27dff12676481532746ex5ca18cd84048488a98ca4aaf90f4d29b7e181c4540b3604a0721b928e50ffcd495734ef8471b",
    "server_signature": "0xb7xd1760f14eda0228e0b647ff15f45233526ced3b4ae07fcce06144473d32960d3253776e62f761363fb8137087193347763f4af831250a96f3885f3c2289c41b"
  }
}

Register or transfer an qname

To register a new qid, e.g. hubble, first make sure the qname is not already registered.

Then make a POST request to /transfers with the following body:

{
  "name": "wvrld", // Name to register
  "from": 0,  // qid to transfer from (0 for a new registration)
  "to": 123, // qid to transfer to (0 to unregister)
  "qid": 123, // qid making the request (must match from or to)
  "owner": "0x...", // Custody address of qid making the request
  "timestamp": 1641234567,  // Current timestamp in seconds
  "signature": "0x..."  // EIP-712 signature signed by the custody address of the qid
}

To generate the EIP-712 signature, use the following code:

import { makeUserNameProofClaim, EIP712Signer } from "@openrealm/hub-nodejs";
const signer: EIP712Signer = undefined // Signer for the custody address (use appropriate subclass from hub-nodejs for ethers or viem)

const claim = makeUserNameProofClaim({
    name: 'wvrld',
    owner: '0x...',
    timestamp: Math.floor(Date.now() / 1000),
});
const signature = (await signer.signUserNameProofClaim(claim))._unsafeUnwrap();

This is the exact same kind of signature used in the ENS UsernameProofs provided to hubs to prove ownership of an ENS name.

e.g.

curl -X POST https://qnames.openrealm.social/transfers \
  -H "Content-Type: application/json" \
  -d \
'{"name": "wvrld", "owner": "0x...", "signature": "0x...", "from": 0, "to": 1000, "timestamp": 1641234567, qid: 1000}'

Once a name is registered, it still needs a UserData message to be sent to the hub in order to actually set the username for the user.