NFT Minting Example
A comprehensive example of minting NFTs on Solana using the Gold Digger Factory Program.
This example demonstrates how to mint an NFT on the Solana blockchain using the Gold Digger Factory Program. The code handles the entire process from creating the mint account to setting up metadata and creating a master edition.
- Complete NFT minting process
- Metaplex metadata integration
- Royalty configuration
- Error handling
- Associated token account creation
The example uses a structured metadata format that follows the Metaplex standard. This includes basic information like name and symbol, as well as more advanced features like creators, royalties, and attributes.
{
"name": "Gold Digger NFT #1",
"symbol": "GOLD",
"uri": "https://arweave.net/your-metadata-uri",
"seller_fee_basis_points": 500,
"creators": [
{
"address": "YOUR_WALLET_ADDRESS",
"verified": true,
"share": 100
}
],
"collection": {
"name": "Gold Digger Collection",
"family": "Gold Digger",
"verified": true
},
"attributes": [
{
"trait_type": "Rarity",
"value": "Legendary"
},
{
"trait_type": "Mining Power",
"value": "100"
}
],
"external_url": "https://golddigger.io"
}
Step-by-Step Process
- Create Mint Account
First, we create a new account that will represent our NFT mint. This account will store the mint data.
- Initialize Mint
We initialize the mint with the SPL Token program, setting the mint authority and freeze authority.
- Create Associated Token Account
We create an associated token account for the owner to hold the NFT.
- Mint Token
We mint exactly one token to the associated token account.
- Create Metadata
We create a metadata account using the Metaplex Token Metadata program.
- Create Master Edition
Finally, we create a master edition account that makes the token non-fungible.

Visual representation of the NFT minting process
use solana_client::rpc_client::RpcClient;
use solana_program::{
pubkey::Pubkey,
system_instruction,
};
use solana_sdk::{
commitment_config::CommitmentConfig,
signature::{Keypair, read_keypair_file},
signer::Signer,
transaction::Transaction,
};
use spl_token::{
instruction as token_instruction,
state::{Mint, Account},
};
use spl_associated_token_account::{
get_associated_token_address,
instruction::create_associated_token_account,
};
use metaplex_token_metadata::{
instruction::{create_metadata_accounts_v3, create_master_edition_v3},
state::{DataV2, Creator, Collection, Uses, UseMethod},
};
// Main NFT minting function
pub async fn mint_nft(
rpc_url: &str,
payer_keypair_path: &str,
metadata: &NFTMetadata,
is_mutable: bool,
) -> Result<String, MintError> {
// Connect to Solana cluster
let client = RpcClient::new_with_commitment(
rpc_url.to_string(),
CommitmentConfig::confirmed(),
);
// Load the payer's keypair from file
let payer = match read_keypair_file(payer_keypair_path) {
Ok(keypair) => keypair,
Err(_) => return Err(MintError::WalletError("Failed to read keypair file".to_string())),
};
// Generate a new keypair for the NFT mint
let mint_keypair = Keypair::new();
// Get the associated token account for the payer
let associated_token_account = get_associated_token_address(
&payer.pubkey(),
&mint_keypair.pubkey(),
);
// Create all the necessary instructions
let instructions = vec![
// Create mint account
system_instruction::create_account(
&payer.pubkey(),
&mint_keypair.pubkey(),
client.get_minimum_balance_for_rent_exemption(Mint::LEN).unwrap(),
Mint::LEN as u64,
&spl_token::ID,
),
// Initialize mint
token_instruction::initialize_mint(
&spl_token::ID,
&mint_keypair.pubkey(),
&payer.pubkey(),
Some(&payer.pubkey()),
0,
).unwrap(),
// Create associated token account
create_associated_token_account(
&payer.pubkey(),
&payer.pubkey(),
&mint_keypair.pubkey(),
),
// Mint one token to the associated token account
token_instruction::mint_to(
&spl_token::ID,
&mint_keypair.pubkey(),
&associated_token_account,
&payer.pubkey(),
&[&payer.pubkey()],
1,
).unwrap(),
// Create metadata account
create_metadata_accounts_v3(
metaplex_token_metadata::ID,
metadata_account,
mint_keypair.pubkey(),
payer.pubkey(),
payer.pubkey(),
payer.pubkey(),
metadata.name.clone(),
metadata.symbol.clone(),
metadata.uri.clone(),
creators.clone(),
metadata.seller_fee_basis_points,
true,
is_mutable,
None,
None,
None,
),
// Create master edition (makes the NFT non-fungible)
create_master_edition_v3(
metaplex_token_metadata::ID,
master_edition,
mint_keypair.pubkey(),
payer.pubkey(),
payer.pubkey(),
metadata_account,
payer.pubkey(),
Some(0), // Max supply of 0 means the NFT cannot be duplicated
),
];
// Create and sign the transaction
let recent_blockhash = match client.get_latest_blockhash() {
Ok(hash) => hash,
Err(e) => return Err(MintError::TransactionError(format!("Failed to get blockhash: {}", e))),
};
let transaction = Transaction::new_signed_with_payer(
&instructions,
Some(&payer.pubkey()),
&[&payer, &mint_keypair],
recent_blockhash,
);
// Send and confirm the transaction
match client.send_and_confirm_transaction(&transaction) {
Ok(signature) => {
println!("✅ NFT created successfully!");
println!("Transaction signature: {}", signature);
Ok(signature.to_string())
},
Err(e) => Err(MintError::TransactionError(format!("Transaction failed: {}", e))),
}
}
The example includes a comprehensive error handling system using custom error types. This makes it easier to identify and debug issues during the minting process.
#[derive(Error, Debug)]
pub enum MintError {
#[error("Failed to connect to Solana: {0}")]
ConnectionError(String),
#[error("Invalid wallet data: {0}")]
WalletError(String),
#[error("Transaction error: {0}")]
TransactionError(String),
#[error("Metadata error: {0}")]
MetadataError(String),
#[error("Token error: {0}")]
TokenError(String),
#[error("IO error: {0}")]
IoError(String),
}
Each error type provides specific information about what went wrong, making it easier to troubleshoot issues. The error messages are designed to be user-friendly while still providing enough technical detail for debugging.