Skip to main content

What are Solana SPL Token Extensions and How to Get Started?

Created on
Updated on
Feb 7, 2024

4 min read

Overview

Solana Labs has released an extension to the native SPL token program, Token-2022. Token 2022 is a new standard that extends the SPL token program and adds additional functionality through Token Extensions. The Token-2022 program is designed to be a more flexible and extensible token standard that allows for more complex tokenomics and control for developers.

What are Token Extensions?

Token Extensions (also known as Token-2022) are an advanced token program on the Solana blockchain, extending the capabilities of the existing Token Program. It's designed to offer developers enhanced flexibility and additional functionalities without compromising the safety of current tokens.

This program encompasses all features of its predecessor (it maintains compatibility with the original Token instruction and account layouts) while providing new instructions and functionality. These extensions introduce new fields in mints and accounts.

Mint extensions currently include:

FeatureDescription
Transfer FeesFees (or taxes) associated with transferring tokens.
Confidential TransfersAllows for private transfer of tokens.
Closing MintPermits the termination of empty mint accounts.
Interest-bearing TokensTokens that accumulate interest over time.
Non-transferable TokensTokens cannot be transferred once issued (a.k.a., soulbound tokens).
Permanent DelegatesThis authority has unlimited delegate privileges over any account for that mint, meaning that it can burn or transfer any amount of tokens.
Transfer HookA program that is required to interact with a token instruction (e.g., royalty enforcement)
Metadata PointerA pointer to a metadata account that contains information about the mint.
MetadataStores information about the mint, such as the name, symbol, and logo (or other custom fields).

Account extensions currently include:

FeatureDescription
Memo Required on Incoming TransfersA note must accompany all incoming transfers (similar to a bank account).
Immutable OwnershipLock ownership of an account cannot be changed once set.
Default Account StatePre-set conditions that apply to the account.
CPI GuardProhibits certain actions inside cross-program invocations

It is important to note that the Associated Token Program remains unchanged, meaning it can be used with both the original Token Program and the Token-2022 Program. However, using existing methods, programs, and instructions will require you to pass the Token-2022 program ID as the programId parameter. For example, let's look at the getAssociatedTokenAddressSync from the @solana/spl-token library:

/**
* Get the address of the associated token account for a given mint and owner
*
* @param mint Token mint account
* @param owner Owner of the new account
* @param allowOwnerOffCurve Allow the owner account to be a PDA (Program Derived Address)
* @param programId SPL Token program account
* @param associatedTokenProgramId SPL Associated Token program account
*
* @return Address of the associated token account
*/
export function getAssociatedTokenAddressSync(
mint: PublicKey,
owner: PublicKey,
allowOwnerOffCurve = false,
programId = TOKEN_PROGRAM_ID,
associatedTokenProgramId = ASSOCIATED_TOKEN_PROGRAM_ID
): PublicKey {
if (!allowOwnerOffCurve && !PublicKey.isOnCurve(owner.toBuffer())) throw new TokenOwnerOffCurveError();

const [address] = PublicKey.findProgramAddressSync(
[owner.toBuffer(), programId.toBuffer(), mint.toBuffer()],
associatedTokenProgramId
);

return address;
}

As you can see above, the getAssociatedTokenAddressSync function takes in a programId parameter that defaults to the original Token Program ID (typical for many SPL token methods). To use the Token-2022 program, you must pass in the Token-2022 program ID as the programId parameter. The example below shows the derivation of ata addresses for both the original Token Program and the Token-2022 program:

import { TOKEN_2022_PROGRAM_ID, getAssociatedTokenAddressSync } from "@solana/spl-token";
// ...
const mint: PublicKey = new PublicKey(SOME_TOKEN_MINT); // a mint of a token created with the original standard
const mint2022: PublicKey = new PublicKey(SOME_TOKEN_MINT_2022); // a mint of a token created with the Token-2022 standard
const ataOld = getAssociatedTokenAddressSync(mint, owner, false);
const ata2022 = getAssociatedTokenAddressSync(mint2022, owner, false, TOKEN_2022_PROGRAM_ID); // 👈 pass in the Token-2022 program ID

Note that for mint2022, we had to pass the TOKEN_2022_PROGRAM_ID (TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb) as the programId parameter.

The 2022 program is still under audit but is accessible for testing and development.

How to Get Started with Token Extensions

Check out our guides on how to get started with the Token-2022 program:

We ❤️ Feedback!

Let us know if you have any feedback or requests for new topics. We'd love to hear from you.

Share this guide