.fomo developer platform
build with names the family remembers.
Resolve human-readable .fomo identities, read the public registry, surface marketplace listings and verify every paid claim with its Solana transaction proof.
- network
- mainnet-beta
- RPC checking
- latest slot
- —
- protected server RPC
- registry
- — names
- database checking
- claim price
- 0.1 SOL
- one time · no renewal
01 · quick start
resolve a name in seconds.
The resolver is public, read-only and CORS-enabled. No API key or wallet connection is required.
curl https://www.dotfomo.app/api/resolve/legend.fomoconst response = await fetch("https://www.dotfomo.app/api/resolve/legend.fomo");
if (!response.ok) throw new Error("Name not found");
const record = await response.json();
console.log(record.targets.solana);{
"domain": "legend.fomo",
"name": "legend",
"ownerWallet": "<solana-address>",
"targets": { "solana": "<solana-address>" },
"profileUrl": "https://www.dotfomo.app/legend.fomo",
"registrationProofUrl": "https://solscan.io/tx/<signature>"
}02 · architecture
onchain settlement. signed ownership. fast resolution.
.fomo is a hybrid registry. Registration and marketplace payments settle in SOL on Solana mainnet and are verified from RPC transaction data. Name records resolve from the registry database. Transfers, listings and profile edits require an Ed25519 message signed by the current owner wallet.
- 01
reserve
A unique 10-minute reservation and memo are created.
- 02
settle
The wallet sends the exact SOL amount with that memo.
- 03
verify
The server checks signer, recipient, amount, memo and time.
- 04
record
Ownership is written once; the transaction cannot be reused.
Important
.fomo names are registry records, not NFTs or Solana Name Service domains. The onchain transaction is the payment proof; resolution and ownership state are served by this independent registry.
03 · resolve names
one endpoint, chain-aware responses.
- GET
/api/resolve/:nameFull owner and address-target record. - GET
/api/resolve/:name?chain=solanaOnly the requested chain target. - OPTIONS
/api/resolve/:nameCORS preflight for browsers.
:name accepts either legend or legend.fomo. Names are lowercase letters, numbers and single hyphens, 1–32 characters.
04 · registry api
search public registrations and proof.
- GET
/api/registrations?page=1Paginated registrations, 18 per page. - GET
/api/registrations?q=legPrefix search with proof URLs. - GET
/api/availability/:nameRegistered and reservation state. - GET
/api/wallet/:address/namesEvery name a wallet owns. - GET
/api/statusLive Solana RPC and registry health.
type FomoRegistration = {
name: string
domain: string
owner: string
createdAt: string
proofType: "solana" | "admin"
proofUrl: string | null
listPriceLamports: number | null
}
const { registrations, total, pages } = await fetch(
"https://www.dotfomo.app/api/registrations?page=1"
).then((r) => r.json())05 · on-chain records
every .fomo is an SPL Name Service account.
Names live in Solana's Name Service program (namesLPneVptA9Z5rqUDD9tMTWEJwofgaYwp8cawRkX), the same program behind .sol. Each name.fomo is a child of the .fomo top-level record, and its owner field is your wallet — readable by any Solana client, transferable without us. The registrar key only co-signs new names and holds listed names in escrow; it never pays and never holds SOL.
- 1
POST /api/chain/prepareSend { kind: "register", name, wallet }. Returns the exact transaction: 0.1 SOL to the treasury, a memo, and the create of name.fomo owned by your wallet.
- 2
Sign in your walletYour wallet signs as fee payer. You pay the price plus ~0.0016 SOL rent for the on-chain account.
- 3
POST /api/chain/submitSend { reservationId, wallet, transaction }. The registrar co-signs only if the instructions match what /prepare built, then it is sent.
- 4
POST /api/chain/confirmSend { reservationId, wallet, signature }. Checks the payment and that the chain now shows your wallet as owner. 202 means still confirming — retry.
// 0.1 SOL (100,000,000 lamports) · memo program MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr
const { onchain } = await fetch("https://www.dotfomo.app/api/resolve/legend").then((r) => r.json())
const info = await connection.getAccountInfo(new PublicKey(onchain.account))
const owner = new PublicKey(info.data.subarray(32, 64)) // SPL Name Service header: parent | owner | class06 · marketplace
owner-listed names with direct settlement.
Listing moves the on-chain record into escrow held by the registrar. A purchase is one transaction: the buyer's SOL goes straight to the seller and the escrow hands the record to the buyer — both land or neither does. Unlisting returns the record to the seller. Repricing a live listing is a free signature.
- GET
/api/listingsActive listings, stats and recent verified sales. - POST
/api/chain/preparekind "list" | "unlist" | "transfer" | "sale" — builds the on-chain transaction. - POST
/api/chain/submitRegistrar co-signs (escrow moves only) and sends. - POST
/api/chain/confirmVerifies the tx and the new on-chain owner, then updates the registry.
const market = await fetch("https://www.dotfomo.app/api/listings").then((r) => r.json())
console.log(market.stats.floorLamports)
console.table(market.listings.map((l) => [l.domain, l.listPriceLamports]))07 · domain profiles
pictures and social identity, owned by the name.
Every registered name has a public profile at /:name.fomo. The current owner can add a picture, display name, bio, fomo.family link, X, Telegram and website with a wallet-signed update. Profile data is cleared when the name changes hands.
- GET
/api/profiles/:nameProfile, owner, listing, activity and proof. - GET
/api/profiles/:name/avatarThe validated profile picture. - PUT
/api/profiles/:nameMultipart update after a signed challenge.
FOMO account linking
A fomo.family URL is supplied and signed by the .fomo owner. It is displayed as “linked by domain owner”, not as an official fomo.family verification.
08 · wallet actions
prove ownership without spending SOL.
Transfers, listings, unlistings and profile edits use short-lived, single-use challenges. The signed text includes the wallet, action, normalized payload, nonce and expiry — so a signature can only ever do the one thing it describes.
import bs58 from "bs58"
const challenge = await fetch("https://www.dotfomo.app/api/auth/challenge", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ wallet, purpose: "transfer", name: "legend", recipientWallet }),
}).then((r) => r.json())
const { signature } = await provider.signMessage(new TextEncoder().encode(challenge.message), "utf8")
await fetch("https://www.dotfomo.app/api/names/legend/action", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ nonce: challenge.nonce, signature: bs58.encode(signature) }),
})09 · security model
checks that prevent free or replayed claims.
- signer
Wallet must sign
The payer must be a signer in the parsed Solana transaction.
- amount
Exact lamports
Registration and sale amounts must exactly match the reservation.
- memo
Unique intent
Every reservation has an unguessable memo bound to its name and wallet.
- replay
One signature once
Payment signatures are unique in the database and cannot be reused.
- owner
Ed25519 approval
Non-payment changes require the current owner's signature.
- media
Validated uploads
Pictures are ≤ 1 MB, magic-byte checked, hash-bound to the signature, never SVG.
- relay
Payments only
The send relay only forwards transfer + memo transactions.
- secrets
Server-only RPC
Provider credentials never ship to browser JavaScript.
10 · errors & limits
predictable JSON errors.
- 202Payment not confirmed yetRetry the same request in a few seconds.
- 400Invalid input or paymentValidate the name, wallet and signature.
- 403Ownership proof failedThe signature or current owner did not match.
- 404Not foundThe requested name or reservation does not exist.
- 409ConflictAlready registered, reserved by someone else, or the listing changed.
- 429Rate limitedWait for the retry-after header.
- 503Registration pausedThe registry treasury is not configured yet.
Every error body is { "error": "…" }. Back to the registry →