DEV Community

Cover image for Token Design on Solana — What Metadata, Fees, and Soulbound Rules Taught Me
Zoe Lin
Zoe Lin

Posted on

Token Design on Solana — What Metadata, Fees, and Soulbound Rules Taught Me

Coming from a Web2 background, I originally thought about tokens in a very simple way. A token was something you create, mint, and transfer, while anything more interesting, like fees, restrictions, or identity, would probably live in the backend. Working through Solana token exercises changed that assumption for me.

Over the past few days, I built several kinds of tokens on Solana devnet: a basic token, a token with metadata, a token with transfer fees, a token that combined metadata and transfer fees, and finally a non-transferable token. What stood out most was not just that Solana lets you issue tokens, but that it lets you encode rules directly into the token itself through Token-2022 extensions.

A mint is not the same as a balance

One of the first ideas that became clearer to me was that creating a token is not the same thing as holding one. A mint defines the token, while a token account holds the balance of that token for a specific wallet. That separation felt unfamiliar at first, but after repeating the workflow a few times, it started to feel much more structured than my original mental model.

A basic flow looked like this:

spl-token create-token
spl-token create-account <MINT_ADDRESS>
spl-token mint <MINT_ADDRESS> 100
spl-token balance <MINT_ADDRESS>
Enter fullscreen mode Exit fullscreen mode

That sequence helped me stop thinking of a wallet as the direct container for every balance. On Solana, the mint defines the asset, and token accounts are where balances actually live.

Metadata made the token feel usable

A token without metadata technically exists, but it does not feel meaningful to people. Once I added metadata, the token started to feel less like a raw address and more like something a user or developer could recognize. Giving it a name, symbol, and URI was a small technical step, but conceptually it made a big difference.

Using Token-2022, I initialized metadata directly on the mint:

spl-token initialize-metadata <MINT_ADDRESS> "ReinforceCoin" "RFC" "<METADATA_URI>"
Enter fullscreen mode Exit fullscreen mode

That made me appreciate the difference between protocol-level existence and human-readable usability. The chain does not need a token name to function, but people do.

Transfer fees changed how I think about token rules

The most interesting part of this week for me was transfer fees. In a typical Web2 system, if you want to take a fee whenever value moves, you usually implement that in your backend. Your server calculates the fee, stores the result, and makes sure users cannot bypass the rule.

On Solana, I could configure that behavior at the token-program level. I created a Token-2022 mint with a transfer fee extension, minted supply, transferred tokens to a second wallet, and then observed how part of the transfer was withheld as a fee. What made this especially useful as a learning moment was that the fee was not simply sent to me immediately. Instead, it was withheld in token-account state and later collected by the configured authority.

That gave me a much better understanding of how protocol-enforced rules differ from application-enforced rules.

Putting metadata and fees together made the lifecycle click

One of the most useful exercises in this sequence was creating a token that combined metadata and transfer fees in a single workflow. In one session, I created the mint, initialized metadata, minted supply, transferred tokens, and reviewed the final configuration with spl-token display. That was the point where the token lifecycle stopped feeling like disconnected CLI exercises and started feeling like one coherent system.

The sequence that clicked for me was:

  • create the mint
  • configure token behavior
  • mint supply
  • distribute it
  • review the resulting state

That may sound obvious in hindsight, but doing it end to end made the model much easier to remember.

Soulbound-style tokens were the biggest mindset shift

The most memorable experiment for me was creating a non-transferable token. This was the point where Solana token design felt the least like “database rows with extra steps” and the most like a genuinely different model of digital assets. I created a Token-2022 mint with the non-transferable extension enabled, minted tokens into my own account, created a second wallet for testing, and then tried to transfer the token.

The transfer failed exactly as intended, and that failure was the lesson. The important message in the output was that transfer was disabled for that mint. In other words, the rule was not coming from my frontend, not coming from a backend API, and not coming from an application-level restriction. The token program itself rejected the transfer.

That immediately made use cases like these feel much more concrete:

  • certificates
  • completion badges
  • membership credentials
  • proof-of-attendance tokens
  • verification markers

In Web2, those restrictions are usually enforced by product logic and policy. On Solana, some of them can be enforced as part of the asset itself.

Non-transferable did not mean non-destructible

One detail I found especially useful was that non-transferable tokens can still be burned. That distinction matters. The token could not be moved to another wallet, but I was still able to destroy part of the balance from the token account I controlled. So the holder was not forced to keep the token forever, but they also could not sell or transfer it.

That made the model feel much more practical. It is not just a locked asset. It is an asset with a specific rule about movement.

What surprised me most

The biggest surprise was that the hardest part was not the commands themselves. It was learning to think more carefully about what each account and each rule actually represented.

A few things stood out to me:

  • a mint account and a token account are different things
  • metadata changes how real a token feels
  • transfer fees are not the same thing as an instantly received payment
  • non-transferable tokens make more sense for credentials than currencies
  • small CLI mistakes, especially around long addresses, can completely change the result

I also ran into practical issues like forgetting to replace placeholders, dealing with devnet faucet rate limits, and mistyping long addresses in terminal commands. Those mistakes were frustrating in the moment, but useful in hindsight. They reminded me that blockchain workflows are precise, and the tooling will not guess what I meant.

Why this mattered to me as a Web2 developer

As a Web2 developer, the most valuable shift for me was realizing that not every important rule has to live in backend code. Backend systems still matter, but Solana gave me a much more concrete understanding of what it means for certain economic or identity rules to be enforced directly on-chain.

This week made tokens feel less abstract and much more like product design primitives with protocol-level behavior.

What I want to explore next

I want to keep going deeper into how Token-2022 features affect real application design, especially around authority management, token utility, and how on-chain rules interact with actual user flows.

For now, though, this was the week where token design on Solana started to feel much more concrete to me. Not just because I created tokens, but because I started to understand what kinds of rules those tokens can carry with them.

If you are also coming from Web2, my biggest recommendation is to not stop at creating a basic token. Try metadata. Try transfer fees. Try non-transferable tokens. Each one teaches you something different about what a token can actually be.

Top comments (0)