DEV Community

Peter Okoh
Peter Okoh

Posted on

DAY 55 #100DaysOfSolana: Three Token-2022 Mints in One Week: Transfer Fees, Interest-Bearing Tokens, and Soulbound Assets

Coming from Web2, I used to think a token was just a balance in a database. If you wanted extra behavior—transaction fees, rewards, or restrictions—you'd probably build it into your application logic.

Token-2022 changed that perspective for me. It's the upgraded SPL Token Program that lets you attach extensions directly to a token mint. I like to think of these extensions as middleware. Instead of creating an entirely new token standard, you opt into the features your application needs while keeping the same underlying protocol. This week, I experimented with three different extensions, and each one completely changed how I think about designing tokens on Solana.

1. Transfer Fee Extension

Creating the mint

spl-token create-token \
  --program-id TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb \
  --decimals 6 \
  --transfer-fee-basis-points 100 \
  --transfer-fee-maximum-fee 1000000
Enter fullscreen mode Exit fullscreen mode

After minting tokens, I transferred 1,000 tokens to another wallet.

Something interesting happened.

The recipient didn't receive 1,000 tokens.

Instead, the balance became:

Balance: 990
Transfer fees withheld: 10000000
Enter fullscreen mode Exit fullscreen mode

The remaining tokens were automatically withheld as transfer fees by the token program itself.

Later, I withdrew the withheld fees:

spl-token withdraw-withheld-tokens $MY_TA $RECIPIENT_TA
Enter fullscreen mode Exit fullscreen mode

After that:

Balance: 1000
Transfer fees withheld: 0
Enter fullscreen mode Exit fullscreen mode

Watching the fee move through the system automatically made the feature click for me.

When would I actually use this?

This extension makes perfect sense for a community token or creator economy where every transfer contributes a small percentage to a project treasury. Instead of relying on off-chain accounting, the token program enforces the fee every single time.

2. Interest-Bearing Extension

Creating the mint

spl-token create-token \
  --program-id TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb \
  --decimals 6 \
  --transfer-fee-basis-points 100 \
  --transfer-fee-maximum-fee 1000000 \
  --interest-rate 5000
Enter fullscreen mode Exit fullscreen mode

After minting tokens, I checked the balance twice, about 30 seconds apart.

The displayed balance changed from:

1000062.476727
Enter fullscreen mode Exit fullscreen mode

to

1000062.967937
Enter fullscreen mode Exit fullscreen mode

That was unexpected.

At first, I assumed new tokens were being minted.

They weren't.

The Interest-Bearing extension **does not create additional supply.

Instead, it updates the displayed UI amount using the configured interest rate while the underlying token supply remains unchanged. That distinction is subtle, but it's an important one because it changes how you think about accounting and token economics.

3. Non-Transferable (Soul-Bound) Token

Creating the mint

spl-token create-token \
  --program-2022 \
  --enable-non-transferable
Enter fullscreen mode Exit fullscreen mode

I minted one token to my wallet and then created another wallet to test whether I could transfer it.

Naturally, I expected the transfer to work.

It didn't.

Running:

spl-token transfer $MINT 1 $RECIPIENT --allow-unfunded-recipient
Enter fullscreen mode Exit fullscreen mode

returned:

Program log: Transfer is disabled for this mint
Enter fullscreen mode Exit fullscreen mode

That single error message perfectly demonstrates the purpose of this extension.

Once a token is marked as non-transferable, ownership cannot simply be passed around like a regular SPL token.

I immediately started thinking about applications like:

  • digital certificates
  • university credentials
  • employee IDs
  • membership badges
  • proof-of-attendance tokens

These are assets that represent identity rather than value, so allowing them to be traded would defeat their purpose.

Final Thoughts

This week completely changed how I think about tokens on Solana.

Before Token-2022, I imagined every special token behavior required a custom smart contract. Instead, I learned that many of these capabilities already exist as modular extensions you can opt into when creating a mint.

The Transfer Fee extension showed me how protocol-level fees can replace application logic. The Interest-Bearing extension taught me the difference between changing displayed balances and changing token supply. And the Non-Transferable extension demonstrated how the token program itself can enforce ownership rules without any additional code.

If I were building a real product today, I'd happily reach for these extensions instead of reinventing them. That's probably the biggest lesson I've taken away from this part of my Solana journey: sometimes the best engineering decision isn't writing more code—it's knowing which features the platform already gives you.

This post is part of my #100DaysOfSolana journey. If you're exploring Solana from a Web2 background, I hope this saves you a few hours of experimentation. Feel free to connect or share what you're building, I'd love to learn from your experience too.

Top comments (0)