Profiles & Accounts
Every æternity address has a profile page on Superhero, whether or not anyone has set it up. The page merges on-chain links, the API's account aggregate and trading statistics.
The two profile surfaces
| Route | What it is |
|---|---|
/users/:address | The social profile: header, feed, owned and created tokens, transactions |
/user/:address | Legacy path; redirects to /users/:address |
/trends/accounts | The trader index: every account with token activity |
/trends/accounts/:address | The Trendminer view of an account, focused on trading |
/trends/leaderboard | Ranked accounts by portfolio performance |
The social profile is live at https://superhero.com/users/ followed by an ak_ address.
The header
| Element | Source |
|---|---|
| Display name | The linked preferred AENS name, else public_name, else the AENS name resolved for the address, else a shortened ak_… |
| Verified badge | Rendered when an X link exists for the account |
| Bio | links.bio, falling back to profile.bio and then the account's own bio |
| Website | links.site |
| Avatar | The profile's avatarurl, with a deterministic generated fallback |
| Balances and counts | The account aggregate: holdings count and total created tokens |
The account aggregate from GET /api/accounts/{address} carries address, bio,
chain_name, chain_name_updated_at, an embedded profile, public_name, holdings_count,
and a links object keyed by the AddressLink provider ids: x, nostr, bio, site and
prefaens. The links object is authoritative; the flat fields are fallbacks for older
records.
If chain_name_updated_at is older than the staleness window, or has never been set, the
endpoint re-reads the name from the middleware, returns the fresh value, and writes it back
asynchronously. An hourly sweep covers accounts nobody is viewing, so a lapsed or transferred
.chain name disappears from a profile within about an hour.
The tabs
/users/:address has four tabs, selected by a tab query parameter (feed is the default and
omits the parameter):
| Tab | Value | Contents |
|---|---|---|
| Feed | feed | The account's posts and on-chain activity items |
| Owned | owned | Tokens the account holds, ordered by balance |
| Created | created | Tokens the account created |
| Transactions | transactions | The account's trades, with the token expanded |
All four datasets are prefetched when the page loads. The feed tab merges posts from
GET /api/posts?account_address=… with trade and token-creation activity items.
On chain versus API
| Field | Where it lives |
|---|---|
| Preferred AENS name, bio, website, X handle, Nostr key | AddressLink contract state, as provider links, signed by you and submitted by the backend |
| AENS name ownership and pointers | æternity AENS |
| Chain name shown on a profile | Resolved from the middleware and cached on the account; not a contract link |
Fullname, avatar URL, legacy username, chain_expires_at | Legacy profile fields, read-only |
| Follower and following counts | The social-graph tables, when that feature is enabled |
| Posts and comments | Tipping v3 contract, indexed by the API |
| Balances, portfolio history, leaderboard stats | Computed by the API from chain data |
Every field a user controls is written behind their wallet signature; the transaction is submitted by Superhero's provider wallet. See AddressLink.
Editing your own profile
Open Edit SuperheroID on your own profile. It is one modal over several independent operations:
| Field | How it is written |
|---|---|
| Bio | Claim at /api/address-links/bio/claim, sign the returned message, submit at /bio/submit |
| Website | The same pair under /api/address-links/site/, with the scheme stripped from the stored value |
Preferred .chain name | The same pair under /api/address-links/prefered-aens-name/, which uses link_principal and verifies AENS ownership on chain |
| X handle | The OAuth flow; see Verifying Your X Account |
| Nostr key | The same pair under /api/address-links/nostr/, with a signed kind-22242 event as the extra proof |
Each link has a matching unlink: /unclaim returns a message and nonce, you sign it, and
/unclaim/submit relays the removal. The editor reloads its state after each operation.
Every claim reads the contract's own get_nonce(address), and the nonce advances on each link
or unlink. If two devices claim at once, the second submit fails with a nonce mismatch and
restarts from claim.
Fullname, avatar and the legacy username are read-only.
Leaderboards
/trends/leaderboard ranks accounts by portfolio performance from
GET /api/accounts/leaderboard.
| Query parameter | Values |
|---|---|
window | 7d, 30d or all |
sortBy | pnl, roi, aum or mdd |
sortDir | ASC or DESC |
points | Sparkline resolution: 7 for a week, 30 otherwise |
page, limit | Pagination; the client asks for 18 per page |
Each row carries address, chain_name, aum_usd, pnl_usd, roi_pct, mdd_pct,
buy_count, sell_count, volume_usd, created_tokens_count, owned_trends_count and a
portfolio_value_usd_sparkline of timestamp-value pairs.
The default sort direction is descending for every metric except maximum drawdown (mdd),
which sorts ascending because a smaller drawdown is better.
The account index
/trends/accounts reads GET /api/accounts, which pages at 1 to 100 rows and accepts a
search term matched against the address, chain_name, public_name, username and
fullname. order_by takes exactly nine values, and anything else is a 400:
order_by | Ranks by |
|---|---|
total_volume | Trade volume (the default) |
total_tx_count | All trades |
total_buy_tx_count | Buys only |
total_sell_tx_count | Sells only |
total_created_tokens | Tokens the account created |
total_invitation_count | Invitations created |
total_claimed_invitation_count | Invitations redeemed |
total_revoked_invitation_count | Invitations revoked |
created_at | When the account row first appeared |
order_direction is ASC or DESC, defaulting to DESC. has_nostr=true returns only
accounts that have linked a Nostr key, which is useful for a chat-contact suggester.
Both the account index and the leaderboard rank trading activity only; nothing ranks by posting, commenting, tipping or governance.
How public_name is computed
Server-side, by a fixed four-step ladder with no per-account preference:
prefered_aens_name (links.prefaens — the AENS name the user explicitly linked)
chain_name (resolved from the middleware)
username (the legacy profile field)
address (the ak_… itself)See Names.
Related
- SuperheroID: what the profile is a view onto.
- Names: the name types and how one is resolved for display.
- AddressLink: the contract behind every editable field.
- Verifying Your X Account: the X link, and what its badge proves.
- Profile API: the endpoint-level reference.
- Portfolio: the holdings and performance numbers the profile surfaces.