Skip to content

On-chain storage

contracts/src/Sonoglyph.sol is an ERC-721 with fully on-chain rendering. Each token preserves the complete record of one descent in contract storage; nothing about the visible artifact lives in external metadata or off-chain JSON.

FieldTypeSource
glyphstringThe 32×16 ASCII art from Kimi
journalstringThe 3-paragraph field journal
audioCidstringIPFS CIDv1 of the WebM recording
sessionCodestring6-char descent code
creatoraddressAddress that completed the descent
mintedAtuint256Block timestamp at mint

Only the audio CID is an off-chain pointer, and even that pointer resolves to a file pinned by us (Pinata) with its CID embedded in the on-chain animation_url so any IPFS gateway can serve it.

Returns a base64-encoded JSON data URI containing two rendered media:

data:image/svg+xml;base64,... — the glyph drawn as monospace text on a black background. This is what marketplaces use for grid previews. It’s a static SVG, no animation, no JavaScript. It’s constructed string-by-string from the on-chain glyph field at tokenURI call time.

data:text/html;base64,... — a self-contained page that renders the glyph plus an <audio> element fetching the recording from an IPFS gateway. One click on a marketplace listing → the user sees the glyph and hears the descent simultaneously.

The HTML is also constructed at tokenURI time. Contract storage holds the raw fields; the renderer composes them on read. This means we can update the visual style by deploying a renderer contract upgrade in future without re-minting tokens (the constructor takes a renderer address; storage is preserved across renderer upgrades).

Three reasons.

1. The glyph is the artifact. We don’t want it to be an IPFS link that could rot. The 32×16 string is ~520 bytes per token; storage cost on Monad mainnet is far below the scale where this becomes a concern.

2. Marketplaces should “just work”. Any marketplace that supports the ERC-721 metadata standard already understands tokenURI returning a data URI. No custom rendering server, no IPFS dependency at the metadata layer.

3. The audio + glyph belong together. Embedding the audio player in animation_url means a marketplace listing is the experience — you don’t need to leave the listing page to hear the descent. The visual and the sound co-arrive.

Only the contract owner (the bridge’s signing wallet) can mint, and it mints to the player’s chosen address.

function mintDescent(
address to,
string calldata glyph,
string calldata journal,
string calldata audioCid,
string calldata sessionCode
) external onlyOwner returns (uint256 tokenId)

We trade trustlessness for curation — every minted token came from a real completed descent the bridge witnessed end-to-end. If the bridge wallet is ever compromised the worst case is junk tokens, not stolen ones.

Per mint on Monad mainnet, with current gas levels, a Sonoglyph mint costs a small fraction of a cent. The on-chain string storage dominates the gas; the actual ERC-721 logic is standard OpenZeppelin plus the renderer dispatch.