Skip to content

feat(solana): support token icons and descriptions on wrapped tokens - #199

Open
jackchuma wants to merge 1 commit into
mainfrom
jack/wrapped-token-metadata-uri
Open

jackchuma wants to merge 1 commit into
mainfrom
jack/wrapped-token-metadata-uri

Conversation

@jackchuma

@jackchuma jackchuma commented Sep 16, 2026

Copy link
Copy Markdown
Collaborator

What changed? Why?

Adds an optional metadata URI when creating Solana wrapped tokens so wallets and indexers can retrieve an icon and description from the URI's offchain JSON metadata.

  • Adds wrap_token_v2, which accepts the URI and stores it in the Token-2022 metadata extension.
  • Keeps the existing wrap_token instruction and its wire format unchanged; it delegates to the shared handler with an empty URI so existing clients remain compatible.
  • Adds PartialTokenMetadataV1 with the existing layout and discriminator, exports MAX_URI_LEN (200) through the Anchor IDL, and regenerates both checked-in IDL artifacts.

The wrapped-mint PDA derivation intentionally continues to exclude the URI. This preserves derivation of deployed wrapped mints and prevents a URI-only change from disrupting bridging or supply accounting.

Notes to reviewers

  • Metadata is immutable after creation. Existing wrapped tokens and tokens created through the legacy instruction will continue to have an empty URI; there is no backfill or update instruction.
  • The first successful wrapper chooses the URI for a canonical mint. This can affect displayed token metadata, but does not affect the mint identity because name, symbol, remote token, and scaler remain committed to the mint derivation.
  • The program changes are fully additive: one instruction and one error code (UriTooLong, 12706) are added without changing existing instruction discriminators or error codes.
  • Follow-up PRs update the generated TypeScript client and wrap-token CLI.

How has it been tested?

  • 111 tests pass and Clippy is clean.
  • test_wrap_token_legacy_wire_format_is_unchanged hand-encodes the legacy instruction to verify its discriminator and argument ordering remain compatible.
  • test_wrap_token_v2_stores_uri_on_mint verifies URI persistence and the additional mint funding required for Token-2022 metadata allocation.
  • deployed_mint_still_derives verifies a deployed mainnet wrapped mint still derives after the change, and v1_hashes_identically_and_converts_to_an_empty_uri verifies the legacy metadata conversion and hash invariants.

@cb-heimdall

Copy link
Copy Markdown
Collaborator

🟡 Heimdall Review Status

Requirement Status More Info
Reviews 🟡 0/1
Denominator calculation
Show calculation
1 if user is bot 0
1 if user is external 0
2 if repo is sensitive 0
From .codeflow.yml 1
Additional review requirements
Show calculation
Max 0
0
From CODEOWNERS 0
Global minimum 0
Max 1
1
1 if commit is unverified 0
Sum 1

Token-2022 has no icon or description fields; both are served from the
off-chain JSON document that its `uri` field points at. That field was
initialized to an empty string, so wrapped tokens could never carry either.

Adds `uri` to `PartialTokenMetadata` and passes it through to the metadata
initialize CPI. It is deliberately excluded from the mint's PDA hash: that
hash is recomputed from onchain metadata to authenticate a mint as a wrapped
token, so extending the preimage would move every already-deployed mint to an
address the program no longer derives.

`wrap_token` keeps its exact wire format, taking a `PartialTokenMetadataV1`
argument whose layout is byte-identical to the previous type, and delegates
with an empty uri. `wrap_token_v2` accepts the uri. Both derive the same mint.

Also fixes `create_mock_wrapped_mint`, which left `update_authority` and `mint`
at their defaults rather than mirroring a real wrapped mint.

Co-authored-by: Cursor <cursoragent@cursor.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.

2 participants