Skip to content

Commit

Permalink
Adding candy guard parser
Browse files Browse the repository at this point in the history
Parses `CandyGuard` struct as well as default and optional guards.
Also parses `MintCounter` PDA.
  • Loading branch information
danenbm committed Sep 20, 2022
1 parent 7fdcbc9 commit ab43aa0
Show file tree
Hide file tree
Showing 5 changed files with 143 additions and 0 deletions.
55 changes: 55 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions blockbuster/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ readme = "../README.md"
[dependencies]
spl-account-compression = { version = "0.1.0", features = ["no-entrypoint"] }
spl-noop = { version = "0.1.0", features = ["no-entrypoint"] }
mpl-candy-guard = { git = "https://github.com/metaplex-foundation/candy-guard", branch = "danenbm/expose-mint-counter", features = ["no-entrypoint"] }
mpl-candy-machine-core = { git = "https://github.com/metaplex-foundation/metaplex-program-library", branch = "febo/candy-machine-core", features = ["no-entrypoint"] }
mpl-bubblegum = { version = "0.1.0", features = ["no-entrypoint"] }
mpl-token-metadata = { version = "1.3.6", features = ["no-entrypoint"] }
Expand Down
2 changes: 2 additions & 0 deletions blockbuster/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ pub enum BlockbusterError {
FailedToDeserializeToMasterEdition,
#[error("Uninitialized account type")]
UninitializedAccount,
#[error("Could not custom deserialize candy guards")]
CandyGuardDataCustomDeserError,
}

impl From<std::io::Error> for BlockbusterError {
Expand Down
82 changes: 82 additions & 0 deletions blockbuster/src/programs/candy_guard/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
use crate::{
error::BlockbusterError,
instruction::InstructionBundle,
program_handler::{NotUsed, ParseResult, ProgramParser},
programs::ProgramParseResult,
};
use borsh::BorshDeserialize;
use mpl_candy_guard::{
guards::MintCounter,
state::{CandyGuard, CandyGuardData, DATA_OFFSET},
};
use plerkle_serialization::AccountInfo;
use solana_sdk::{pubkey::Pubkey, pubkeys};
use std::convert::TryInto;

pubkeys!(
candy_guard_id,
"CnDYGRdU51FsSyLnVgSd19MCFxA4YHT5h3nacvCKMPUJ"
);

// Anchor account discriminators.
const CANDY_GUARD_DISCRIMINATOR: [u8; 8] = [44, 207, 199, 184, 112, 103, 34, 181];
const MINT_COUNTER_DISCRIMINATOR: [u8; 8] = [29, 59, 15, 69, 46, 22, 227, 173];

pub enum CandyGuardAccountData {
CandyGuard(CandyGuard, CandyGuardData),
MintCounter(MintCounter),
}

impl ParseResult for CandyGuardAccountData {
fn result_type(&self) -> ProgramParseResult {
ProgramParseResult::CandyGuard(self)
}
}

pub struct CandyGuardParser;

impl ProgramParser for CandyGuardParser {
fn key(&self) -> Pubkey {
candy_guard_id()
}

fn key_match(&self, key: &Pubkey) -> bool {
key == &candy_guard_id()
}

fn handle_account(
&self,
account_info: &AccountInfo,
) -> Result<Box<dyn ParseResult>, BlockbusterError> {
let account_data = if let Some(account_info) = account_info.data() {
account_info
} else {
return Err(BlockbusterError::DeserializationError);
};

let discriminator: [u8; 8] = account_data[0..8].try_into().unwrap();

let account_type = match discriminator {
CANDY_GUARD_DISCRIMINATOR => {
let candy_guard = CandyGuard::try_from_slice(&account_data[8..])?;
let candy_guard_data = CandyGuardData::load(&account_data[DATA_OFFSET..])
.map_err(|_| BlockbusterError::CandyGuardDataCustomDeserError)?;
CandyGuardAccountData::CandyGuard(candy_guard, candy_guard_data)
}
MINT_COUNTER_DISCRIMINATOR => {
let mint_counter = MintCounter::try_from_slice(&account_data[8..])?;
CandyGuardAccountData::MintCounter(mint_counter)
}
_ => return Err(BlockbusterError::UnknownAccountDiscriminator),
};

Ok(Box::new(account_type))
}

fn handle_instruction(
&self,
_bundle: &InstructionBundle,
) -> Result<Box<dyn ParseResult>, BlockbusterError> {
Ok(Box::new(NotUsed::new()))
}
}
3 changes: 3 additions & 0 deletions blockbuster/src/programs/mod.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
use bubblegum::BubblegumInstruction;
use candy_guard::CandyGuardAccountData;
use candy_machine::CandyMachineAccountData;
use candy_machine_core::CandyMachineCoreAccountData;
use token_account::TokenProgramAccount;
use token_metadata::TokenMetadataAccountState;

pub mod bubblegum;
pub mod candy_guard;
pub mod candy_machine;
pub mod candy_machine_core;
pub mod token_account;
Expand All @@ -15,6 +17,7 @@ pub enum ProgramParseResult<'a> {
Bubblegum(&'a BubblegumInstruction),
TokenMetadata(&'a TokenMetadataAccountState),
TokenProgramAccount(&'a TokenProgramAccount),
CandyGuard(&'a CandyGuardAccountData),
CandyMachine(&'a CandyMachineAccountData),
CandyMachineCore(&'a CandyMachineCoreAccountData),
Unknown,
Expand Down

0 comments on commit ab43aa0

Please sign in to comment.