use {
crate::state::{Assembler, AssemblingAction, Creator, TokenStandard},
anchor_lang::prelude::*,
anchor_spl::token::{self, Mint, Token},
hpl_events::HplEvents,
hpl_hive_control::{
program::HplHiveControl,
state::{DelegateAuthority, Project},
},
hpl_utils::create_nft,
mpl_token_metadata::state::AssetData,
};
#[derive(Accounts)]
pub struct CreateAssembler<'info> {
#[account(mut)]
pub project: Box<Account<'info, Project>>,
#[account(
init, payer = payer,
space = Assembler::LEN ,
seeds = [
b"assembler".as_ref(),
collection_mint.key().as_ref(),
],
bump,
)]
pub assembler: Account<'info, Assembler>,
#[account(
init,
payer = payer,
mint::decimals = 0,
mint::authority = assembler,
mint::freeze_authority = assembler,
)]
pub collection_mint: Box<Account<'info, Mint>>,
#[account(mut)]
pub collection_metadata: AccountInfo<'info>,
#[account(mut)]
pub collection_master_edition: AccountInfo<'info>,
#[account(has_one = authority)]
pub delegate_authority: Option<Account<'info, DelegateAuthority>>,
pub authority: Signer<'info>,
#[account(mut)]
pub payer: Signer<'info>,
#[account(mut)]
pub vault: AccountInfo<'info>,
pub system_program: Program<'info, System>,
pub hive_control: Program<'info, HplHiveControl>,
#[account(address = token::ID)]
pub token_program: Program<'info, Token>,
pub token_metadata_program: AccountInfo<'info>,
pub hpl_events: Program<'info, HplEvents>,
pub clock_sysvar: Sysvar<'info, Clock>,
pub rent_sysvar: Sysvar<'info, Rent>,
#[account(address = anchor_lang::solana_program::sysvar::instructions::ID)]
pub instructions_sysvar: AccountInfo<'info>,
}
#[derive(AnchorSerialize, AnchorDeserialize, Clone)]
pub struct CreateAssemblerArgs {
assembling_action: AssemblingAction,
collection_name: String,
collection_symbol: String,
collection_uri: String,
collection_description: String,
nft_base_uri: String,
allow_duplicates: Option<bool>,
default_royalty: Option<u16>,
token_standard: Option<TokenStandard>,
rule_set: Option<Pubkey>,
default_creators: Vec<Creator>,
}
pub fn create_assembler(ctx: Context<CreateAssembler>, args: CreateAssemblerArgs) -> Result<()> {
let assembler = &mut ctx.accounts.assembler;
assembler.bump = ctx.bumps["assembler"];
assembler.project = ctx.accounts.project.key();
assembler.collection = ctx.accounts.collection_mint.key();
assembler.collection_name = args.collection_name;
assembler.collection_symbol = args.collection_symbol;
assembler.collection_description = args.collection_description;
assembler.nft_base_uri = args.nft_base_uri;
assembler.assembling_action = args.assembling_action;
assembler.nfts = 0;
assembler.allow_duplicates = args.allow_duplicates.unwrap_or(false);
assembler.default_royalty = args.default_royalty.unwrap_or(0);
assembler.token_standard = args
.token_standard
.unwrap_or(crate::state::TokenStandard::NonFungible);
assembler.rule_set = args.rule_set;
assembler.default_creators = args.default_creators;
let assembler_seeds = &[
b"assembler".as_ref(),
assembler.collection.as_ref(),
&[assembler.bump],
];
let assembler_signer = &[&assembler_seeds[..]];
create_nft(
AssetData {
name: assembler.collection_name.clone(),
symbol: assembler.collection_symbol.clone(),
uri: args.collection_uri,
seller_fee_basis_points: assembler.default_royalty,
creators: Some(
[
vec![mpl_token_metadata::state::Creator {
address: assembler.key(),
verified: true,
share: 0,
}],
assembler
.default_creators
.clone()
.iter()
.map(|c| mpl_token_metadata::state::Creator {
address: c.address,
verified: false,
share: c.share,
})
.collect(),
]
.concat(),
),
primary_sale_happened: false,
is_mutable: true,
token_standard: mpl_token_metadata::state::TokenStandard::NonFungible,
collection: None,
uses: None,
collection_details: None,
rule_set: assembler.rule_set,
},
false,
true,
ctx.accounts.collection_metadata.to_account_info(),
ctx.accounts.collection_master_edition.to_account_info(),
ctx.accounts.collection_mint.to_account_info(),
assembler.to_account_info(),
ctx.accounts.payer.to_account_info(),
assembler.to_account_info(),
ctx.accounts.system_program.to_account_info(),
ctx.accounts.instructions_sysvar.to_account_info(),
ctx.accounts.token_program.to_account_info(),
Some(assembler_signer),
)?;
Ok(())
}
#[derive(Accounts)]
pub struct UpdateAssembler<'info> {
#[account()]
pub project: Box<Account<'info, Project>>,
#[account(mut, has_one = project)]
pub assembler: Account<'info, Assembler>,
#[account(has_one = authority)]
pub delegate_authority: Option<Account<'info, DelegateAuthority>>,
pub authority: Signer<'info>,
pub payer: Signer<'info>,
#[account(mut)]
pub vault: AccountInfo<'info>,
pub system_program: Program<'info, System>,
pub hive_control: Program<'info, HplHiveControl>,
#[account(address = anchor_lang::solana_program::sysvar::instructions::ID)]
pub instructions_sysvar: AccountInfo<'info>,
}
#[derive(AnchorSerialize, AnchorDeserialize, Clone)]
pub struct UpdateAssemblerArgs {
assembling_action: AssemblingAction,
nft_base_uri: String,
allow_duplicates: Option<bool>,
default_royalty: Option<u16>,
}
pub fn update_assembler(ctx: Context<UpdateAssembler>, args: UpdateAssemblerArgs) -> Result<()> {
let assembler = &mut ctx.accounts.assembler;
assembler.nft_base_uri = args.nft_base_uri;
assembler.assembling_action = args.assembling_action;
assembler.allow_duplicates = args.allow_duplicates.unwrap_or(assembler.allow_duplicates);
assembler.default_royalty = args.default_royalty.unwrap_or(assembler.default_royalty);
Ok(())
}