Skip to content

feat(api): serve Metaplex coin metadata from /v1/coins/:mint/metadata - #1030

Open
dylanjeffers wants to merge 1 commit into
mainfrom
feat/coin-metadata-endpoint
Open

feat(api): serve Metaplex coin metadata from /v1/coins/:mint/metadata#1030
dylanjeffers wants to merge 1 commit into
mainfrom
feat/coin-metadata-endpoint

Conversation

@dylanjeffers

@dylanjeffers dylanjeffers commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Part of the Irys → Audius coin migration (#eng thread).

Coins launched through the launchpad upload their logo and their Metaplex off-chain metadata JSON to Irys/Arweave. We're moving both to Audius. Mediorum can host the image, but it only accepts audio / img_square / img_backdrop templates, so there's nowhere to put a JSON blob — this endpoint is that home.

What this adds

GET /v1/coins/:mint/metadata returns the Metaplex off-chain document built from the artist_coins row:

{
  "name": "Bear Coin",
  "symbol": "BEAR",
  "description": "$BEAR is an artist coin created by @bearartist on Audius. Learn more at https://audius.co/coins/BEAR",
  "image": "https://creatornode.audius.co/content/<cid>",
  "external_url": "https://audius.co/coins/BEAR",
  "attributes": []
}

Served unwrapped — no data envelope — because wallets and explorers read it directly as the standard document. There's a test asserting that specifically, since our convention everywhere else would break it.

Because it's generated per request rather than frozen at mint, name/description/image become editable after launch for new coins. That's a bonus, not the goal.

The description fallback

The launchpad passes a templated description to the relay for on-chain metadata but deliberately never persists it — LAUNCHPAD_COIN_DESCRIPTION in the web client regenerates the same sentence, and storing it would make the Fan Club page cite itself.

So reading artist_coins.description alone would have shipped an empty description to Phantom, Solscan and Jupiter for every launchpad coin. This regenerates the same sentence from the owner's handle when the column is empty. It's duplicated logic against the web client and I've noted that on both sides.

Ordering

This needs to be live before AudiusProject/pedalboard#90 rolls, since that PR starts baking this URL into on-chain metadata that can never be changed.

Testing

TestV1CoinMetadata covers the document shape, the absent envelope, the description fallback, empty-string serialization for nullable columns, and 404 on an unknown mint. Full TestV1Coin* suite passes.

🤖 Generated with Claude Code

Newly launched coins point their on-chain DBC metadata `uri` at Audius
instead of Irys/Arweave, so the API needs to serve the Metaplex off-chain
JSON document itself. Built from the artist_coins row, which also makes
name/description/image editable after launch rather than frozen at mint.

The launchpad deliberately never persists a description - the Fan Club page
builds that sentence client-side and storing it would make the page cite
itself - so regenerate the same sentence here rather than serving an empty
one to wallets and explorers.

Served unwrapped (no `data` envelope) since wallets and explorers read it
directly as the standard document.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant