1

I'm creating a custom NFT program and SPL token (2 token programs).

I need to add additional logic so I am creating a wrapper around the existing SPL token functions.

Do I need to add wrappers for transfers as well? I have the following code but am not sure if it allows other programs / apps like NFT marketplaces like Tensor or Jupiter, to be able to interface with my wrappers if I give them custom transfer fn names.

pub fn transfer_nft(ctx: Context<TransferNFT>) -> Result<()> {
        let destination = &ctx.accounts.to_account;
        let source = &ctx.accounts.from_account;
        let token_program = &ctx.accounts.token_program;
        let authority = &ctx.accounts.signer;
    
        // Transfer tokens from source to destination
        let cpi_accounts = Transfer {
            from: source.to_account_info().clone(),
            to: destination.to_account_info().clone(),
            authority: authority.to_account_info().clone(),
        };
        let cpi_program = token_program.to_account_info();
        
        transfer(
            CpiContext::new(cpi_program, cpi_accounts),
        1)?;

        Ok(())
    }

for the NFT I mint in a custom wrapper fn that has this code:

create_metadata_accounts_v3(
    CpiContext::new(
        ctx.accounts.token_metadata_program.to_account_info(),
        CreateMetadataAccountsV3 {
            metadata: ctx.accounts.metadata.to_account_info(),
            mint: ctx.accounts.nft_pda.to_account_info(),
            mint_authority: ctx.accounts.nft_pda.to_account_info(),
            update_authority: ctx.accounts.nft_pda.to_account_info(),
            payer: ctx.accounts.winner.to_account_info(),
            system_program: ctx.accounts.system_program.to_account_info(),
            rent: ctx.accounts.rent.to_account_info(),
        },
    )
    .with_signer(signer_seeds),
    DataV2 {
        name: ctx.accounts.username.clone(),
        symbol: "test"
        uri: "https://example.com/nft".to_string(), // Placeholder URI, should be replaced with dynamic content
        seller_fee_basis_points: 0,
        creators: None,
        collection: None,
        uses: None,
    },
    true, // is_mutable
    true, // update_authority_is_signer
    None, // collection_details
)?;

// Invoke the mint_to instruction on the token program to mint the NFT to the winner's account
mint_to(
    CpiContext::new_with_signer(
        ctx.accounts.token_program.to_account_info(),
        MintTo {
            mint: ctx.accounts.nft_pda.to_account_info(),
            to: ctx.accounts.token_account.to_account_info(),
            authority: ctx.accounts.nft_pda.to_account_info(),
        },
        signer_seeds,
    ),
    1, // Mint 1 NFT
)?;

1 Answer 1

0

There's a few things to keep in mind if you're creating a wrapper program.

If the wrapper program is just calling into an SPL token program inside, then its interface will definitely diverge from the SPL token interface, since your program must also accept the token program to CPI into, whereas the SPL token program does not require an additional program for CPI.

Since your program's instruction interface is different, dapps like Tensor or Jupiter will not know how to use it and can't directly call into it as they would any SPL token program.

Additionally, dapps need to trust your program in order to call into it, so you'll likely need to reach out to them so they can integrate your program.

If the tokens you create in your program are normal SPL tokens, however, you shouldn't need a wrapper program -- let people call SPL token / metaplex directly! But in that case, I'm not sure what your program is providing other than some slightly easier interfaces to call into existing programs.

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.