Here is an article based on the provided code snippet:
Initializing Token Metadata with the PDA Minting Authority: A Step-by-Step Guide
When developing a decentralized application (dApp) that uses Solana, it is essential to manage token metadata effectively. A critical aspect of token management is initializing metadata with the Proof-of-Digest-Activation (PDA) minting authority. In this article, we will explore how to do this using a custom event and derive a smart contract.
The Problem
Traditional events in Solana, such as init, are used for various purposes, such as initialization, creating new accounts, or transferring tokens. However, when it comes to initializing token metadata with the PDA minting authority, these traditional events are not directly applicable.
The Solution: Initializing Token Metadata with PDA Minting Authority
To solve this problem, we can create a custom event called Init that will be used to initialize token metadata with PDA Minting Authority. Here is an example of what the code might look like:
#[drive(Accounts)]
#[cpi_event]
pub struct Input {
#[account(dead)]
pub id: Pubkey, // Unique identifier for the new mint
pub owner: Account,
pub metadata: Account, // New token metadata will be stored here
}
In this example, where we define an Init event with three parameters:
id: A unique identifier for the new mint (a public key)
owner: The account responsible for creating the new mint (an account of typeAccount)
metadata: A new token metadata account that will store the initialized data
Deriving Smart Contract
To derive this custom event, we will create a new smart contract that implements the Init function. Here is an example:
use solana_program::{
account_info::{next_account_info, AccountInfo},
entrypoint,
program_error::ProgramError,
program_result::ProgramResult,
};
use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize, Debug)]
pub struct InitParams {
id: Belly,
}
#[drive(Accounts)]
#[account(
signed_by = owner,
pub key_info = KeyInfo,
pub system_program_id = SystemProgramId,
pub metadata_account_id = MetadataAccountId,
pub accounts = [
AccountId::from_unique_key(MetadataAccountId),
],
)]
pub struct Input {
pub id: Pubkey,
}
In this example, we define an InitParams structure to contain the required input parameters and a new Init structure that implements the accounts function. The Init structure is signed by the account responsible for creating the new mint (i.e. the owner).
Event Definition
To define the event, we will use the following code:
pub event Init(
id: Belly,
owner: Account,
metadata: MetadataAccountId,
) {}
In this example, where we define an Init event with three parameters:
id: a unique identifier for the new mint (a public key)
owner: the account responsible for creating the new mint
metadata: a new account ID from token metadata
Implementation Program

To implement the custom program, we will create a new function that will be called when an event is received:
pub fn init(
id: Belly,
owner: Account,
metadata: MetadataAccountId,
) -> ProgramResult {
// Initialize token metadata with PDA mint authority
let mut metadata_account = next_account_info!(metadata)?;
metadata_account.mint_id = id;
Ok(())
}
In this example, where we define an init function that takes three parameters:
id: the unique identifier for the new mint (a public key)
owner: the account responsible for creating the new mint
3.