Token Metadata
Theme

Features

Programmable NFTs (pNFTs)

As mentioned in the overview page, Programmable NFTs (pNFTs) are a new asset standard that allows creators to define custom rules on specific operations and delegate more granularly to third-party authorities.

No More Bypassing Token Metadata

Because the Token Metadata program is built on top of the SPL Token program, any owner or spl-token delegate can interact with the SPL Token program directly and bypass the Token Metadata program on vital operations like transferring and burning. Whilst this creates a nice composability pattern between programs it also means the Token Metadata program cannot enforce any rules on behalf of the creators.

A good example of why this can be problematic is that Token Metadata cannot enforce secondary sales royalties. Even though the royalty percentage is stored on the Metadata account, it is up to the user or program that performs the transfer to decide whether they want to honor it or not. We talk more about this and how pNFTs fix this issue in a section below.

Programmable NFTs are introduced to solve this issue in a flexible way that allows creators to customize the authorization layer of their assets.

Programmable NFTs work as follows:

  • The Token account of the pNFT is always frozen on the SPL Token program, regardless of whether the pNFT is delegated or not. This ensures that no one can bypass the Token Metadata program by interacting with the SPL Token program directly.
  • Whenever an operation is performed on the Token account of a pNFT, the Token Metadata program thaws the account, performs the operation, and then freezes the account again. All of this happens atomically in the same instruction. That way, all operations that could be made on the SPL Token program are still available to pNFTs but they are always performed through the Token Metadata program.
  • When a Token Delegate is set on a pNFT, the information is stored in a Token Record account. Since pNFTs are always frozen on the SPL Token program, it is the responsibility of the Token Record account to keep track of whether the pNFT is really locked or not.
  • Because every single operation that affects a pNFT must go through the Token Metadata program, we created a bottleneck that allows us to enforce authorization rules for these operations. These rules are defined in a Rule Set account managed by the Token Auth Rules program.

Essentially, this gives pNFTs the ability to:

  1. Have more granular delegates.
  2. Enforce rules on any operation.

Let's dive into these two abilities in more detail.

More granular delegates

Since all pNFTs operations must go through the Token Metadata program, it can create a new delegate system on top of the spl-token delegate. One that is more granular and allows pNFT owners to pick the operations they want to delegate to a third party.

Information for this new delegate system is stored on a special Token Record PDA that is derived from both the Mint and the Token accounts of the pNFT. When a new delegate authority is assigned to a pNFT, the Token Metadata program synchronizes that information on both the Token account and the Token Record account.

We discuss these delegates in more detail in the "Token Delegates" section of the Delegated Authorities page.

Additional Accounts

pNFTs require additional accounts for most operations and these include tokenRecord, authorizationRules, authorizationRulesProgram.

Token Record

A tokenRecord account is responsible for holding details regarding the token and its state such as delegates, it's lock state.

There are a few ways to access the tokenRecord account and that is either by fetchDigitalAssetWithAssociatedToken which returns all needed accounts including metadata, token account, and token record. An alternative is generate the token record PDA address using the mint ID and the token account address with the findTokenRecordPda function.

Asset With Token

You can fetch all accounts needed with the fetchDigitalAssetWithAssociatedToken function which returns data such as the pNFT metadata account, the token account, and the token record account.

const assetWithToken = await fetchDigitalAssetWithAssociatedToken(
    // Umi instance
    umi,
    // Mint ID
    publicKey("11111111111111111111111111111111"),
    // Owner
    publicKey("22222222222222222222222222222222")
);

Token Record PDA

Generates the PDA address for the tokenRecord account with the mintId and tokenAccount of the wallet the pNFT asset is stored in.

const tokenRecordPda = findTokenRecordPda(umi, {
    // pNFT mint ID
    mint: publicKey("11111111111111111111111111111111")s,
    // Token Account
    token: publicKey("22222222222222222222222222222222"),
});

RuleSet

If you have the metadata account data available you will be able to use an unwrap to check for the programableConfig field on the metadata account.

const ruleSet = unwrapOptionRecursively(assetWithToken.metadata.programmableConfig)?.ruleSet

Authorization Rules Program

If you have a ruleSet set on your pNFT Asset you will need to pass in the Authorization Rules Program ID so the ruleSet can be validated. There are two was to get this ID, either from the mpl-token-auth-rules npm package or by manually pasting in the ID.

mpl-token-auth-rules

const authorizationRulesProgram = getMplTokenAuthRulesProgramId(umi)

or

Program Address

const authorizationRulesProgram = pubicKey("auth9SigNpDKz4sJJ1DfCTuZrZNSAgh9sFD3rboVmgg")

Authorization Data

If you have a ruleSet on your pNFT Asset that requires additional data for validation you would pass it in here.

const = authorizationData: { payload: ... },

Enforcing rules on any operation

One of the most important features of Programmable NFTs is their ability to enforce a set of rules on any operation that affects them. The entire authorization layer is provided by another Metaplex program called Token Auth Rules. Whilst that program is used to make pNFTs programmable, it is a generic program that can be used to create and validate authorization rules for any use case.

In the case of pNFTs, the following operations are supported:

OperationDescription
Transfer:OwnerTransfer initiated by the owner of the pNFT
Transfer:SaleDelegateTransfer initiated by a Sale delegate
Transfer:TransferDelegateTransfer initiated by a Transfer or Locked Transfer delegate
Transfer:MigrationDelegateTransfer initiated by a Migration delegate (legacy delegate used during the pNFT migration period)
Transfer:WalletToWalletTransfer between wallets (currently not in use)
Delegate:SaleApprove a Sale delegate
Delegate:TransferApprove a Transfer delegate
Delegate:LockedTransferApprove a Locked Transfer delegate
Delegate:UtilityApprove a Utility delegate
Delegate:StakingApprove a Staking delegate

Creators can assign a custom Rule to any of these operations. When that operation is performed, the Token Metadata program will ensure the rule is valid before allowing the operation to go through. The available rules are documented by the Token Auth Rules program directly but it is worth noting that there are two types of rules:

  • Primitive Rules: These rules explicitly tell us if an operation is allowed or not. For instance: the PubkeyMatch rule will pass if and only if the public key at the given field matches the given public key; the ProgramOwnedList will pass if and only if the program owning the account at the given field is part of a given list of programs; the Pass rule will always pass; etc.
  • Composite Rules: These rules aggregate multiple rules together to create a more complex authorization logic. For instance: the All rule will pass if and only if all of the rules it contains pass; the Any rule will pass if and only if at least one of the rules it contains passes; the Not rule will pass if and only if the rule it contains does not pass; etc.

Once we have all the rules for our operations defined, we can store them in a Rule Set account on the Token Auth Rules program. Whenever we need to make a change to this Rule Set, a new Rule Set Revision is appended to the Rule Set account. This ensures any pNFT currently locked within a specific revision can be unlocked before moving on to the latest revision.

Use-case: Royalty enforcement

Now that we understand pNFTs a bit better, let's look at a concrete use case that can be solved with PNFTs: royalty enforcement.

As mentioned above, without pNFTs, anyone can bypass the royalty percentage stored on the Metadata account by interacting with the SPL Token program directly. This means creators must rely on the goodwill of the users and programs that interact with their assets.

However, with pNFTs, creators can design a Rule Set that ensures programs that do not enforce royalties are forbidden to perform transfers on their assets. They can use a combination of Rules to create an allow list or a deny list depending on their needs.

Additionally, since Rule Sets can be shared and reused across multiple pNFTs, creators can create and share Community Rule Sets to ensure that any program that stops supporting royalties is immediately banned from interacting with any pNFTs that use such Community Rule Set. This creates a strong incentive for programs to support royalties as they would otherwise be banned from interacting with a large number of assets.

Previous
Locking Assets