2

I am building a Solana program using Anchor and I would like to know which is the recommended way to authenticate/validate users allowed to execute certain Solana instructions. For what I have seen so far the Metaplex Token metadata program provides the NFT metadata required to validate the NFTs, but I couldn't find examples on Solana's cookbook.

2 Answers 2

3

Manual implementations

A brief question that calls for an in-depth answer, I think this has been asked many times before:

Using Sol Cerberus (recommended)

Probably the quickest implementation and the most reliable option at the moment is using Sol Cerberus, an on-chain Solana authentication program funded by the Solana Foundation which allows you to create access rules and assign roles to the users of your program through a simple user interface.

Integration

The integration is pretty straightforward and explained in the docs. In a nutshell you just need to do three things:

Taking the SC demo program as an example, for creating a square it uses the Add permission on the Square resource. Therefore only the roles with the Square -> Add permission will be allowed to execute the instruction:

 # RUST
 use sol_cerberus_macros::rule;

 declare_id!("THE_PROGRAM_ID");

 #[program]
 pub mod sol_cerberus_demo {

     use super::*;

     #[rule(Square, Add)]
     pub fn add_square(ctx: Context<Add>, color: String, size: u16) -> Result<()> {
         instructions::add::add(ctx, "square", &color, size)
     }

 }

and in the frontend:

// Javascript

let solCerberus = new SolCerberus(connection, myWallet);
await myProgram.methods.addSquare(color, size)
     .accounts({
       demo: pdas.demoPda,
       ...(await solCerberus.accounts("Square", "Add")),
     })
     .rpc();
0

This is the way to validate the wallet address.

#[account(mut, constraint = signer.key() == "GEPxxxxx...".parse::<Pubkey>().unwrap())]
pub signer: Signer<'info>

This is way to verify NFT. As you know to verify the nft on Solana, we can use the creator address.

 let nft_metadata = Metadata::from_account_info(mint_metadata)?;

    if let Some(creators) = nft_metadata.data.creators {
        let mut valid: u8 = 0;
        for creator in creators {
            if creator.address == CREATOR.parse::<Pubkey>().unwrap() && creator.verified == true
            {
                valid = 1;
                break;
            }
        }
        if valid != 1 {
            return Err();
        }
    } else {
        return Err();
    };

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.