Docs
ShakeX lists Handshake names whose owners have published for sale TXT records on chain. The site only reads the chain. It never holds names, keys or funds; buyers deal with sellers directly. Never pay before the name is transferred to you: buy safely with Bob Wallet.
List a name
1. Write the TXT records
The format follows RFC 10023 (_for-sale). On-chain Handshake records can't have subdomains, so they go on the name itself. Each TXT record starts with v=FORSALE1; and carries exactly one tag:
v=FORSALE1;fval=HNS5000 v=FORSALE1;fval=USD120 v=FORSALE1;furi=mailto:me@example.com v=FORSALE1;ftxt=X @me
| Tag | Meaning | Rules |
|---|---|---|
fval | Asking price | Unit followed by amount, e.g. HNS5000, BTC0.0015. Units: HNS, USD, EUR, BTC, ETH. Optional: without one the name is shown as "Make an offer". Add several for several currencies. |
furi | Contact link | https:, http:, mailto: or tel: URI. |
ftxt | Contact text | Free text, up to 239 characters. Some forms become links, see Contacts. |
A name is listed when it has at least one contact (furi or ftxt), so a single v=FORSALE1;ftxt=X @meis enough (shown as "Make an offer"). It must also be registered, not expired, not revoked and not in the middle of a transfer. A name's whole on-chain resource is limited to 512 bytes, so keep the records short.
2. Publish them with your wallet
An update replaces all of a name's records. Always include the records you already have (NS, DS, GLUE…) alongside the new TXT records, or the name stops resolving.
Bob Wallet: open the name in the Domain Manager, add one TXT record per line above next to your existing records, and submit the update.
hsd: check the current records, then send the full set:
hsd-rpc getnameresource example
hsw-rpc sendupdate example '{"records": [
{"type": "NS", "ns": "ns1.example."},
{"type": "TXT", "txt": ["v=FORSALE1;fval=HNS5000"]},
{"type": "TXT", "txt": ["v=FORSALE1;ftxt=X @me"]}
]}'Many names in one transaction. As with sendupdate, include each name's existing records in its list:
hsw-rpc sendbatch '[
["UPDATE", "name1", {"records": [{"type": "TXT", "txt": ["v=FORSALE1;fval=HNS5000"]}, {"type": "TXT", "txt": ["v=FORSALE1;ftxt=X @me"]}]}],
["UPDATE", "name2", {"records": [{"type": "TXT", "txt": ["v=FORSALE1;fval=HNS900"]}, {"type": "TXT", "txt": ["v=FORSALE1;ftxt=X @me"]}]}]
]'3. Verify
Wait for one confirmation (about 10 minutes), then click List names, paste your names (up to 100 at a time) and verify. Each name shows whether it was listed or why not.
Contacts
Contacts are shown exactly as written on chain, with known platforms turned into links:
| Record | Shown as |
|---|---|
furi=mailto:me@example.com | Email link |
furi=tel:+40712345678 | Phone link |
furi=https://x.com/me | X @me (t.me and discord.com links are labelled too) |
furi=https://example.com/sell | Web link |
ftxt=X @me | Link to https://x.com/me (Twitter @me works too) |
ftxt=Telegram @me | Link to https://t.me/me |
ftxt=Discord 123456789012345678 | Link to the Discord profile. Needs your numeric user ID; a username is shown as text with a copy button |
ftxt=Call after 6pm CET | Plain text |
Update or delist
Listings are re-checked against the chain automatically. To apply a change sooner, verify the name again from List names.
- Change price or contact: update the TXT records.
- Delist: remove the
v=FORSALE1TXT records. The listing is removed after a few failed checks. - After a sale:records survive a transfer, so the new owner should remove or replace them. A listed name stays listed while it is being transferred; other names can't be listed mid-transfer.
Buy and sell safely
A deal for a listed name can close in a single Handshake transaction with Bob Wallet's Finalize With Payment: the buyer pays and receives the name at the same moment, so neither side has to trust the other. No escrow, no fees. The deal page guides both sides and checks each step on chain.
- Buyer:after agreeing on a price, open the listing's contact button → Buy safely, enter your Bob address and the price, and send the deal link to the seller.
- Seller:in Bob, transfer the name to the buyer's address. Handshake holds every transfer for about 2 days; the buyer hasn't paid yet and the seller can still cancel.
- Seller: open the name in Bob → Finalize With Payment, enter the price, paste the result on the deal page and send the payment link to the buyer.
- Buyer: copy the payment request, then in Bob open Domain Manager → Claim Paid Transfer, paste it, verify and confirm.
A payment request stays valid for about 4 months, or until the seller cancels the transfer. Deal links only carry public data: the name, addresses, price and the seller's signed transaction. Once the payment confirms, the sale is listed on Stats with the name, price and date.
Quality score
Every listing gets a 0–100 quality score, recomputed each time it is verified. Listings scoring below 30 are hidden by default. Anyone can show them with the Show low quality switch, so nothing is removed. The score is a heuristic for ranking and spam filtering, not a valuation.
| Signal | Effect |
|---|---|
| Length | Shorter is better. A single letter always scores 100. A single digit also starts at 100, and no longer name can reach it. Two letters that form a word or well-known abbreviation (e.g. go, ok, ai, tv) come right after; other two-letter names rank with three-letter words; other short names score high, falling off after about 8 characters |
| Characters | Letters only score best; 2-character letter–digit combos (e.g. a1, 3d) score like short letter names; short numbers (up to 4 digits) do well; hyphens and underscores cost points |
| Words | Common English words score highest, then less common words and two joined words (e.g. bluesky). A word plus digits (e.g. web3) gets a smaller boost |
| Pronounceable | Non-words with a natural vowel mix get a small boost; long consonant runs cost points |
| Emoji | A single base emoji (e.g. 🔥) scores 90. Variants score less: flags 80, skin tones and keycaps 70, joined sequences 60–65 (e.g. ❤️🔥, 👨👩👧). Names with two or more emoji always score below any single emoji, and lower the more they have. Emoji names never score above 90 |
| Lookalikes | Names that mix alphabets (e.g. a Cyrillic а in “аpple”), contain invisible characters such as a stray zero-width joiner (shown as ?), or are punycode for a plain name lose 60 points and get a Lookalike badge |
| Other scripts | Names in any alphabet (e.g. Cyrillic, Chinese) are scored by length |
| On chain | Auction price paid (100+ and 1000+ HNS score more), renewals, and reserved names claimed by their owner |
| Asking price | Compared with the name's quality from the signals above: the expected ceiling is about $3 at quality 20, $300 at 60 and $30k at 100. Every 10× above it costs 15 points (up to 60), so the more a weak name asks, the lower it drops. The HNS locked in the name counts too: asking up to 10× what was paid at auction is never penalized, and asking no more than it (for names that locked 100+ HNS) adds 10 points. Names without a price and single letters aren't affected |
Boost
A boost moves a listing up the Best ranking for 30 to 180 days: 100 HNS per point for every 30 days, sent from any wallet. Active boosts add up to +10, shown next to the score (e.g. 77+5). Anyone can boost a listed name. Lookalikes and listings hidden by the quality score can't be boosted: a boost changes the order, not what is shown.
Send the exact amount the boost page shows: its decimals identify the name and the period. Then paste the transaction ID on the page. The boost starts once the payment confirms.
Public API
Read-only JSON over HTTPS. No key needed, and CORS is open, so it can be called from any website, wallet or script. Responses are cached for up to 60 seconds. Each IP can make 120 requests per minute; beyond that the API returns 429.
GET /api/listings
All listings, newest first.
curl https://shakex.fun/api/listings
{ "listings": [ Listing, ... ] }GET /api/listings/{name}
One listing. Returns 404 with {"error": "Not listed"} if the name isn't for sale, and 400 for an invalid name. Unicode names are accepted and converted to punycode.
curl https://shakex.fun/api/listings/example
Listing object
{
"name": "example",
"prices": [
{ "unit": "HNS", "amount": "5000" },
{ "unit": "BTC", "amount": "0.0015" }
],
"contacts": [
{ "type": "uri", "value": "mailto:me@example.com" },
{ "type": "text", "value": "X @me" }
],
"usd": 98.5,
"score": 67,
"boost": 0,
"locked": 1250,
"createdAt": "2026-09-19T10:00:00.000Z",
"verifiedAt": "2026-09-19T14:00:00.000Z"
}| Field | Description |
|---|---|
name | Handshake name, punycode for unicode names |
prices | Asking prices from fval records, empty if the seller takes offers. amount is a decimal string, to keep precision |
contacts | Raw contacts: uri from furi (only https, http, mailto, tel), text from ftxt |
usd | Lowest price converted to USD at current CoinGecko rates, or null if there is no price or no rate. An estimate |
score | Quality score 0–100, see Quality score. The API returns all listings; filter on score >= 30 to match the site's default view |
boost | Paid rank points, 0–10, see Boost. The site ranks by score + boost |
locked | HNS locked in the name since its auction: the price the winner paid, which stays in the name for good. 0 for claimed names |
createdAt | When the name was first listed here |
verifiedAt | Last time the on-chain records were checked |
The API serves a cache of on-chain data, re-checked regularly. Contact values are written by sellers, so treat them as untrusted input. Always confirm ownership on chain before paying.