use crate::state::StoreConfig;
use {
crate::{
error::MetaplexError,
state::{Key, Store, CONFIG, MAX_STORE_CONFIG_V1_SIZE, MAX_STORE_SIZE, PREFIX},
utils::{
assert_derivation, assert_owned_by, assert_signer, create_or_allocate_account_raw,
},
},
borsh::BorshSerialize,
solana_program::{
account_info::{next_account_info, AccountInfo},
entrypoint::ProgramResult,
pubkey::Pubkey,
},
};
pub fn set_store_logic<'a>(
public: bool,
program_id: &Pubkey,
auction_program_info: &'a AccountInfo<'a>,
token_vault_program_info: &'a AccountInfo<'a>,
rent_info: &'a AccountInfo<'a>,
system_info: &'a AccountInfo<'a>,
token_metadata_program_info: &'a AccountInfo<'a>,
token_program_info: &'a AccountInfo<'a>,
store_info: &'a AccountInfo<'a>,
admin_wallet_info: &'a AccountInfo<'a>,
payer_info: &'a AccountInfo<'a>,
) -> ProgramResult {
assert_signer(payer_info)?;
assert_signer(admin_wallet_info)?;
if !store_info.data_is_empty() {
assert_owned_by(store_info, program_id)?;
}
let store_bump = assert_derivation(
program_id,
store_info,
&[
PREFIX.as_bytes(),
program_id.as_ref(),
admin_wallet_info.key.as_ref(),
],
)?;
if store_info.data_is_empty() {
create_or_allocate_account_raw(
*program_id,
store_info,
rent_info,
system_info,
payer_info,
MAX_STORE_SIZE,
&[
PREFIX.as_bytes(),
program_id.as_ref(),
admin_wallet_info.key.as_ref(),
&[store_bump],
],
)?;
}
let mut store = Store::from_account_info(store_info)?;
store.key = Key::StoreV1;
store.public = public;
if store.token_program == solana_program::system_program::id() {
store.token_program = *token_program_info.key;
}
if store.token_program != spl_token::id() {
return Err(MetaplexError::InvalidTokenProgram.into());
}
if store.token_vault_program == solana_program::system_program::id() {
store.token_vault_program = *token_vault_program_info.key;
}
if store.token_metadata_program == solana_program::system_program::id() {
store.token_metadata_program = *token_metadata_program_info.key;
}
if store.auction_program == solana_program::system_program::id() {
store.auction_program = *auction_program_info.key;
}
store.serialize(&mut *store_info.data.borrow_mut())?;
Ok(())
}
pub fn process_set_store<'a>(
program_id: &'a Pubkey,
accounts: &'a [AccountInfo<'a>],
public: bool,
) -> ProgramResult {
let account_info_iter = &mut accounts.iter();
let store_info = next_account_info(account_info_iter)?;
let admin_wallet_info = next_account_info(account_info_iter)?;
let payer_info = next_account_info(account_info_iter)?;
let token_program_info = next_account_info(account_info_iter)?;
let token_vault_program_info = next_account_info(account_info_iter)?;
let token_metadata_program_info = next_account_info(account_info_iter)?;
let auction_program_info = next_account_info(account_info_iter)?;
let system_info = next_account_info(account_info_iter)?;
let rent_info = next_account_info(account_info_iter)?;
set_store_logic(
public,
program_id,
auction_program_info,
token_vault_program_info,
rent_info,
system_info,
token_metadata_program_info,
token_program_info,
store_info,
admin_wallet_info,
payer_info,
)
}
pub fn process_set_store_v2<'a>(
program_id: &'a Pubkey,
accounts: &'a [AccountInfo<'a>],
public: bool,
settings_uri: Option<String>,
) -> ProgramResult {
let account_info_iter = &mut accounts.iter();
let store_info = next_account_info(account_info_iter)?;
let store_config_info = next_account_info(account_info_iter)?;
let admin_wallet_info = next_account_info(account_info_iter)?;
let payer_info = next_account_info(account_info_iter)?;
let token_program_info = next_account_info(account_info_iter)?;
let token_vault_program_info = next_account_info(account_info_iter)?;
let token_metadata_program_info = next_account_info(account_info_iter)?;
let auction_program_info = next_account_info(account_info_iter)?;
let system_info = next_account_info(account_info_iter)?;
let rent_info = next_account_info(account_info_iter)?;
let res = set_store_logic(
public,
program_id,
auction_program_info,
token_vault_program_info,
rent_info,
system_info,
token_metadata_program_info,
token_program_info,
store_info,
admin_wallet_info,
payer_info,
);
if res.is_err() {
return res;
}
if !store_config_info.data_is_empty() {
assert_owned_by(store_config_info, program_id)?;
}
let store_config_bump = assert_derivation(
program_id,
store_config_info,
&[
PREFIX.as_bytes(),
program_id.as_ref(),
CONFIG.as_bytes(),
store_info.key.as_ref(),
],
)?;
if store_config_info.data_is_empty() {
create_or_allocate_account_raw(
*program_id,
store_config_info,
rent_info,
system_info,
payer_info,
MAX_STORE_CONFIG_V1_SIZE,
&[
PREFIX.as_bytes(),
program_id.as_ref(),
CONFIG.as_bytes(),
store_info.key.as_ref(),
&[store_config_bump],
],
)?;
}
let mut config = StoreConfig::from_account_info(store_config_info)?;
config.key = Key::StoreConfigV1;
config.settings_uri = settings_uri;
config.serialize(&mut *store_config_info.data.borrow_mut())?;
Ok(())
}