metaboss 0.49.0

The Metaplex NFT-standard Swiss Army Knife tool.
Documentation
use std::str::FromStr;

use anyhow::Result;
use mpl_token_metadata::instructions::{
    ApproveUseAuthorityBuilder, RevokeUseAuthorityBuilder, UtilizeBuilder,
};
use solana_client::rpc_client::RpcClient;
use solana_sdk::{pubkey::Pubkey, signer::Signer};

use crate::{
    derive::{derive_metadata_pda, derive_use_authority_record},
    parse::{parse_keypair, parse_solana_config},
    utils::send_and_confirm_transaction,
};

pub fn approve_use_delegate(
    client: &RpcClient,
    keypair_path: Option<String>,
    nft_mint: String,
    use_auth_delegate: String,
    owner_nft_token_account: String,
    burner_program_id: String,
    number_of_uses: u64,
) -> Result<()> {
    let nft_pubkey = Pubkey::from_str(&nft_mint)?;
    let solana_opts = parse_solana_config();
    let keypair = parse_keypair(keypair_path, solana_opts);

    let delegate_pubkey = Pubkey::from_str(&use_auth_delegate)?;
    let owner_nft_token_pubkey = Pubkey::from_str(&owner_nft_token_account)?;
    let burner_program_pubkey = Pubkey::from_str(&burner_program_id)?;

    let (use_authority_record, _bump) = derive_use_authority_record(&nft_pubkey, &delegate_pubkey);

    let nft_metadata = derive_metadata_pda(&nft_pubkey);

    let approve_use_auth_ix = ApproveUseAuthorityBuilder::new()
        .use_authority_record(use_authority_record)
        .metadata(nft_metadata)
        .owner(keypair.pubkey())
        .payer(keypair.pubkey())
        .mint(nft_pubkey)
        .burner(burner_program_pubkey)
        .owner_token_account(owner_nft_token_pubkey)
        .user(delegate_pubkey)
        .number_of_uses(number_of_uses)
        .instruction();

    send_and_confirm_transaction(client, keypair, &[approve_use_auth_ix])?;

    Ok(())
}

pub fn revoke_use_delegate(
    client: &RpcClient,
    keypair_path: Option<String>,
    nft_mint: String,
    use_auth_delegate: String,
    owner_nft_token_account: String,
) -> Result<()> {
    let nft_pubkey = Pubkey::from_str(&nft_mint)?;
    let solana_opts = parse_solana_config();
    let keypair = parse_keypair(keypair_path, solana_opts);

    let delegate_pubkey = Pubkey::from_str(&use_auth_delegate)?;
    let owner_nft_token_pubkey = Pubkey::from_str(&owner_nft_token_account)?;

    let (use_authority_record, _bump) = derive_use_authority_record(&nft_pubkey, &delegate_pubkey);

    let nft_metadata = derive_metadata_pda(&nft_pubkey);

    let revoke_use_auth_ix = RevokeUseAuthorityBuilder::new()
        .use_authority_record(use_authority_record)
        .user(delegate_pubkey)
        .owner(keypair.pubkey())
        .owner_token_account(owner_nft_token_pubkey)
        .metadata(nft_metadata)
        .mint(nft_pubkey)
        .instruction();

    send_and_confirm_transaction(client, keypair, &[revoke_use_auth_ix])?;

    Ok(())
}

pub fn utilize_nft(
    client: &RpcClient,
    keypair_path: Option<String>,
    nft_mint: String,
    nft_owner: String,
    owner_nft_token_account: String,
    burner_program_id: Option<String>,
    is_delegate_present: bool,
) -> Result<()> {
    let nft_pubkey = Pubkey::from_str(&nft_mint)?;
    let solana_opts = parse_solana_config();
    let keypair = parse_keypair(keypair_path, solana_opts);

    let nft_owner = Pubkey::from_str(&nft_owner)?;
    let owner_nft_token_pubkey = Pubkey::from_str(&owner_nft_token_account)?;
    let delegate_pubkey = keypair.pubkey();
    let nft_metadata = derive_metadata_pda(&nft_pubkey);

    let use_authority_record = match is_delegate_present {
        true => Some(derive_use_authority_record(&nft_pubkey, &delegate_pubkey).0),
        false => None,
    };

    let burner_program_pubkey = if let Some(burner_program_id) = burner_program_id {
        Some(Pubkey::from_str(&burner_program_id)?)
    } else {
        None
    };

    let mut builder = UtilizeBuilder::new();
    builder
        .metadata(nft_metadata)
        .token_account(owner_nft_token_pubkey)
        .mint(nft_pubkey)
        .owner(nft_owner)
        .number_of_uses(1);

    if let Some(use_authority_record) = use_authority_record {
        builder.use_authority_record(Some(use_authority_record));
    }
    if let Some(burner_program_pubkey) = burner_program_pubkey {
        builder.burner(Some(burner_program_pubkey));
    }
    let utilize_nft_ix = builder.instruction();

    send_and_confirm_transaction(client, keypair, &[utilize_nft_ix])?;

    Ok(())
}