sugar_cli/
pdas.rs

1use anchor_client::{solana_sdk::pubkey::Pubkey, Program};
2use anyhow::{anyhow, Result};
3use mpl_token_metadata::{
4    pda::{find_master_edition_account, find_metadata_account},
5    state::{Key, MasterEditionV2, Metadata, TokenMetadataAccount, MAX_MASTER_EDITION_LEN},
6    utils::try_from_slice_checked,
7};
8
9use crate::candy_machine::CANDY_MACHINE_ID;
10
11pub type PdaInfo<T> = (Pubkey, T);
12
13pub struct CollectionPDA {
14    pub mint: Pubkey,
15    pub candy_machine: Pubkey,
16}
17
18pub fn find_metadata_pda(mint: &Pubkey) -> Pubkey {
19    let (pda, _bump) = find_metadata_account(mint);
20
21    pda
22}
23
24pub fn get_metadata_pda(mint: &Pubkey, program: &Program) -> Result<PdaInfo<Metadata>> {
25    let metadata_pubkey = find_metadata_pda(mint);
26    let metadata_account = program.rpc().get_account(&metadata_pubkey).map_err(|_| {
27        anyhow!(
28            "Couldn't find metadata account: {}",
29            &metadata_pubkey.to_string()
30        )
31    })?;
32    let metadata = Metadata::safe_deserialize(metadata_account.data.as_slice());
33    metadata.map(|m| (metadata_pubkey, m)).map_err(|_| {
34        anyhow!(
35            "Failed to deserialize metadata account: {}",
36            &metadata_pubkey.to_string()
37        )
38    })
39}
40
41pub fn find_master_edition_pda(mint: &Pubkey) -> Pubkey {
42    let (pda, _bump) = find_master_edition_account(mint);
43
44    pda
45}
46
47pub fn get_master_edition_pda(
48    mint: &Pubkey,
49    program: &Program,
50) -> Result<PdaInfo<MasterEditionV2>> {
51    let master_edition_pubkey = find_master_edition_pda(mint);
52    let master_edition_account =
53        program
54            .rpc()
55            .get_account(&master_edition_pubkey)
56            .map_err(|_| {
57                anyhow!(
58                    "Couldn't find master edition account: {}",
59                    &master_edition_pubkey.to_string()
60                )
61            })?;
62    let master_edition = try_from_slice_checked(
63        master_edition_account.data.as_slice(),
64        Key::MasterEditionV2,
65        MAX_MASTER_EDITION_LEN,
66    );
67    master_edition
68        .map(|m| (master_edition_pubkey, m))
69        .map_err(|_| {
70            anyhow!(
71                "Invalid master edition account: {}",
72                &master_edition_pubkey.to_string()
73            )
74        })
75}
76
77pub fn find_candy_machine_creator_pda(candy_machine_id: &Pubkey) -> (Pubkey, u8) {
78    // Derive metadata account
79    let creator_seeds = &["candy_machine".as_bytes(), candy_machine_id.as_ref()];
80
81    Pubkey::find_program_address(creator_seeds, &CANDY_MACHINE_ID)
82}
83
84pub fn find_collection_pda(candy_machine_id: &Pubkey) -> (Pubkey, u8) {
85    // Derive collection PDA address
86    let collection_seeds = &["collection".as_bytes(), candy_machine_id.as_ref()];
87
88    Pubkey::find_program_address(collection_seeds, &CANDY_MACHINE_ID)
89}