Token profile
Links, a banner and a resolver in a token's own metadata: a standard any launchpad, wallet or explorer can follow. Version 1.2 · 2026-10-09
The shape
A token's SET_INFO carries a metadata field: the base64 of a JSON document. The Keeta SDK reads decimalPlaces and logoURI from it. The profile adds three keys beside them, each optional; a reader that does not know them passes them by.
{
"decimalPlaces": 9,
"logoURI": "https://example.org/logo.png",
"bannerURI": "https://example.org/banner.png",
"links": {
"website": "https://example.org",
"x": "https://x.com/alice",
"telegram": "https://t.me/alice"
},
"resolver": "keeta_aab…"
}The keys
| Key | Type | What it is |
|---|---|---|
links | object | One link per kind: the kind as the key, an https URL as the value. |
bannerURI | string | A banner picture, 3:1, at least 1200 by 400 pixels. |
resolver | string | The Keeta address of the resolver where wallets find the services that trade the token. |
Link kinds
| Kind | Shown as | May go to |
|---|---|---|
website | Website | any public host |
docs | Docs | any public host |
whitepaper | Whitepaper | any public host |
x | X | x.com, twitter.com |
telegram | Telegram | t.me, telegram.me |
discord | Discord | discord.gg, discord.com |
farcaster | Farcaster | farcaster.xyz, warpcast.com |
bluesky | Bluesky | bsky.app |
reddit | reddit.com | |
facebook | facebook.com, fb.com | |
instagram | instagram.com | |
tiktok | TikTok | tiktok.com |
youtube | YouTube | youtube.com, youtu.be |
medium | Medium | medium.com |
linkedin | linkedin.com | |
github | GitHub | github.com |
coinmarketcap | CoinMarketCap | coinmarketcap.com |
coingecko | CoinGecko | coingecko.com |
A host includes its subdomains: www.x.com and mobile.twitter.com are X. A kind not in this list is not shown.
A link is shown only if
- it starts with
https:// - it is at most 200 characters, without spaces or control characters
- it has no user name or password before the host:
https://[email protected]goes to other.example - it names no port, and its host is a name, not a network address
- for a network, its host is that network's, as in the table above
- for a network, it does not hand the reader on: no other address in its query or after its #, and not through the network's link redirector, as
l.facebook.comoryoutube.com/redirect?q=
A link that breaks a rule is left out on its own; the others are shown.
The banner and the resolver
Banner
PNG, JPEG, GIF or WebP, not SVG; at https://, ipfs:// or as a data:image URI. Shown cut to 3:1 from the centre.
Never let readers' browsers load it from the issuer's server: that tells the server who is reading and shows whatever it sends. This site fetches it once, re-encodes it as a 1200 by 400 WebP and serves only that copy, as it does a logo.
Resolver
The address of a resolver root: the account whose metadata lists services, as the Resolver of @keetanetwork/anchor takes it in root. A launchpad that runs the market for its tokens names its own; a wallet that adds it finds the FX services that quote the token. A Keeta account, not a token.
Writing it
import * as KeetaNet from '@keetanetwork/keetanet-client';
// client: a UserClient for an account that may set the token's info.
const metadata = Buffer.from(JSON.stringify({
decimalPlaces: 9,
logoURI: 'https://example.org/logo.png',
bannerURI: 'https://example.org/banner.png',
links: { website: 'https://example.org', x: 'https://x.com/alice' },
resolver: 'keeta_aab…'
}), 'utf8').toString('base64');
const builder = client.initBuilder();
builder.setInfo({
name: 'ALICE', // the symbol
description: 'Alice token', // the name
metadata,
defaultPermission: new KeetaNet.lib.Permissions(['ACCESS']) // as it is now
}, { account: token });
await client.publishBuilder(builder);
- SET_INFO replaces the whole declaration. Send the name, the description and the default permission again, and every metadata key, decimalPlaces above all: without it every amount of the token reads with 0 decimals.
- Build the JSON yourself. encodeTokenMetadata() of @keetanetwork/anchor writes only decimalPlaces and logoURI and drops every other key. Its decodeTokenMetadata() keeps them.
- Whoever may set the token's info controls its links. A launchpad that keeps that permission keeps the links; a token that hands it on hands them on.
- Keep it small. Every SET_INFO stays on the chain for good, the whole document with it.
How this site shows it
- In the Links box on the token's page, a few minutes after the declaration settles; the banner once the archive has washed it, within about a quarter of an hour.
- This site never opens a link: no preview, no check that it answers. A click shows where the link goes and a warning first; only then does it open, in a new tab, without telling the other site where the reader came from.
- The token's Metadata tab lists what it declares, what was left out and why. A declaration that changes the links is in the token's changelog.
Versions
| Version | Date | What changed |
|---|---|---|
| 1.2 | 2026-10-09 | A network link that hands the reader on to another address -- in its query or after its #, or through the network's own link redirector -- is not shown. |
| 1.1 | 2026-10-09 | Seven link kinds: whitepaper, farcaster, bluesky, facebook, linkedin, coinmarketcap, coingecko. |
| 1 | 2026-10-09 | links (eleven kinds), bannerURI, resolver. |
A new version adds kinds, or leaves out a kind of link that could mislead a reader. A reader that does not know a kind passes it by.