Skip to content

Code pages ​

A code page is a coin page its creator writes in HTML and CSS instead of arranging tiles, placing apps with a <cd-app> tag. Code pages are not open to creators yet. This contract is fixed at version 1.0, so an app built for it now works on them when they open.

How your app shows ​

ModeWhat the page decidesWhat your app keeps
Hosted (every app)Where your app's box is and how big, never under your minimumEverything inside the box
Themed (if your manifest says so)Hosted, plus the page's colours for the tokens you listYour layout, words and behaviour

Every app is hosted with nothing to declare: an app that works on a tile works on a code page. A page that asks for an app in a mode the app does not allow gets it hosted.

What a page can never do to your app ​

These hold on every code page, whatever its creator writes.

  • It cannot shrink your app. A page sizes your box with width, height, grid or flex, but never under your minimum: display.minWidth and minHeight if your manifest has them, else your smallest tile (120 px for each of minColSpan, 60 px for each of minRowSpan plus 10 px between rows). Our rule for it sits in a cascade layer that outranks every rule a page can write, !important included.
  • It cannot style the inside of your app. A page's CSS is scoped to the page and stops at the edge of every app's box, so your prices, warnings and buttons look as you drew them. A themed app gets colours only through the tokens it lists.
  • It cannot run code. A page's HTML is never put on the page as HTML. It is read into a tree of allowed elements and drawn by us, so there is nowhere for a script to be: <script>, <iframe>, <form>, <svg>, on… handlers and inline style are dropped. Links are https, relative or mailto; images are https; a page's ids are prefixed so none can stand in for one of ours. In its CSS, @import, @font-face and @layer are dropped, url() is https only, and its animations are renamed so they cannot replace ours.
  • It cannot act for your app or the visitor. A page's button can do three things, and each opens our own sheet. A page cannot call your app, ask for a signature or take a payment.
  • It cannot cover the coin page's own controls. A code page is contained: position: fixed and z-index work inside the page and cannot reach over the Buy button, the menu or a wallet prompt.

The coin page's Content Security Policy allows inline scripts, so it is not what keeps a code page safe; these rules are. Your app keeps its own sandbox too, exactly as on a tile page: What your app must do.

Declaring themed ​

List the page colours your app takes in presentation.themeTokens:

json
"presentation": { "themeTokens": ["--cd-accent", "--cd-surface", "--cd-text"] }

On a page that shows your app themed, each token you list arrives in the theme your app already gets, as the field below; the rest keep the visitor's theme. List only the ones your app reads.

TokenArrives asWhat it colours
--cd-accenttheme.accentColorAccents and buttons
--cd-surfacetheme.cardBackgroundThe card your app sits on (we draw it under your box)
--cd-texttheme.textPrimaryBody text
--cd-text-mutedtheme.textSecondarySecondary text
--cd-bordertheme.borderColorBorders and dividers

No other token can be listed, and an empty list is refused: leave presentation out to be hosted only.

What a page writes ​

For reference: a page uses three tags of ours. Everything else is plain HTML and CSS.

<cd-app> places an installed app.

Attribute
appThe app's id
instanceWhich one, for an app placed more than once
modehosted (the default) or themed
class, id, title, aria-*, data-*As on any element, for the page's CSS

A <cd-app> is empty: your app draws the whole box, and anything a page puts inside it is not shown.

<cd-data bind="…" format="…"> shows a value from the coin's own data, by the names the app SDK uses. A missing value shows —.

bind
symbolThe ticker, such as PEPE
tokenNameThe coin's full name
descriptionThe coin's description
chainNameThe chain, such as Base
tokenAddressThe coin's contract address
ownerThe wallet that holds the page's crown
statusThe crown's status
market.pricePrice in US dollars
market.marketCapMarket cap in US dollars
market.volume24hTrading volume over 24 hours, in US dollars
market.liquidityLiquidity in US dollars
market.holdersHow many wallets hold it
market.totalSupplyTotal supply
market.circulatingSupplyCirculating supply
market.txns24hTrades over 24 hours
market.priceChange1hPrice change over 1 hour, in percent
market.priceChange6hPrice change over 6 hours, in percent
market.priceChange24hPrice change over 24 hours, in percent
formatShows
number (the default)12.3K
usd$0.0042
usd-compact$1.2M
percent5%

<button cd-action="…"> runs one of our actions. A button with no action, or any other, does nothing.

cd-actionOpens
buyOur buy sheet for the coin
sign-inOur sign-in
connect-walletOur wallet connection

Example ​

A store app that takes the page's accent, surface and text colours declares, in its capp.json:

json
"minColSpan": 2,
"minRowSpan": 4,
"display": { "minWidth": 280, "minHeight": 320 },
"presentation": { "themeTokens": ["--cd-accent", "--cd-surface", "--cd-text"] }

A page places it, themed, beside its own hero:

html
<main class="page">
  <section class="hero">
    <h1>$<cd-data bind="symbol"></cd-data></h1>
    <p><cd-data bind="market.price" format="usd"></cd-data> ·
       <cd-data bind="market.holders"></cd-data> holders</p>
    <button cd-action="buy">Buy</button>
  </section>
  <cd-app app="my-store" mode="themed" class="store"></cd-app>
</main>
css
.page {
  display: grid;
  grid-template-columns: 2fr 1fr;
  gap: 16px;
  --cd-accent: #ff4fa3;
  --cd-surface: #1b1030;
  --cd-text: #fdf2ff;
}
.store { height: 420px; border-radius: 16px; }
@container page (max-width: 640px) {
  .page { grid-template-columns: 1fr; }
}

The store draws itself in the page's pink, dark purple and white. On a phone the page stacks it under the hero, and if the page had set height: 100px, the store would still be 320 px tall.

The schema and its versions ​

The manifest schema, presentation included, is published:

  • the latest: https://docs.chaindaddy.io/schemas/capp.schema.json
  • each version: https://docs.chaindaddy.io/schemas/capp/<version>.json, starting at https://docs.chaindaddy.io/schemas/capp/1.0.0.json

A published version never changes. A new field or value is a new minor version, and every manifest valid under an older version stays valid. A page drawing an app's UI itself, from data the app publishes, is planned for a later version; until then a manifest cannot declare it.