use crate::errors::ErrorCode;
use anchor_lang::prelude::*;
use anchor_lang::{AnchorDeserialize, AnchorSerialize};
use crate::{License, MetadataExtension, Royalties};
#[derive(Clone, AnchorDeserialize, AnchorSerialize)]
pub enum Asset {
None,
Json { url: String },
JsonTemplate { url_parameter: String },
Image { url: String, description: Option<String> },
ChainRenderer {
render_output_address: Pubkey,
program_id: Pubkey,
description: Option<String> },
Inscription { account_id: Pubkey, data_type: String, description: Option<String> },
}
impl Asset {
pub const BASE_SIZE: usize = 2;
pub fn get_size(&self) -> usize {
return Asset::BASE_SIZE
+ match self {
Asset::None => 0,
Asset::Json { url } => 4 + url.len(),
Asset::JsonTemplate { url_parameter } => 4 + url_parameter.len(),
Asset::Image { url , description} => 4 + url.len() + 1 + match &description {Some(x) => 4 + x.len(), None => 0},
Asset::ChainRenderer { render_output_address: _, program_id: _, description } => 32 + 32 + 1 + match &description {Some(x) => 4 + x.len(), None => 0},
Asset::Inscription { account_id: _, data_type, description } => 32
+ 4 + data_type.len()
+ 1 + match &description {Some(x) => 4 + x.len(), None => 0}
};
}
}
#[account]
pub struct Metadata {
pub mint: Pubkey,
pub update_authority: Pubkey,
pub creator: Pubkey,
pub is_mutable: bool,
pub group: Option<Pubkey>,
pub name: String,
pub symbol: String,
pub asset: Asset,
pub extension: MetadataExtension,
}
impl Metadata {
pub const BASE_SIZE: usize = 8
+ 32
+ 32
+ 32
+ 1
+ 1 + 32;
pub fn get_size(&self) -> usize {
let size = Metadata::BASE_SIZE
+ 4
+ self.name.len()
+ 4
+ self.symbol.len()
+ 4
+ self.asset.get_size()
+ 1
+ self.extension.get_size();
return size;
}
}
#[derive(Clone, AnchorDeserialize, AnchorSerialize)]
pub struct AttributesInput {
pub attributes: Vec<u8>,
}
impl AttributesInput {
pub fn get_size(&self) -> usize {
let size = 4 + self.attributes.len();
return size;
}
}
#[derive(Clone, AnchorDeserialize, AnchorSerialize)]
pub struct MetadataExtensionInput {
pub attributes: Vec<u8>, pub royalties: Option<Royalties>,
}
impl MetadataExtensionInput {
pub const BASE_SIZE: usize = 4 + 1 + 1;
pub fn get_size(&self) -> usize {
MetadataExtensionInput::BASE_SIZE
+ self.attributes.len()
+ match &self.royalties {
Some(x) => x.get_size(),
None => 0,
}
}
}
pub fn validate_extend_metadata_input(metadata_input: &MetadataExtensionInput) -> Result<()> {
match &metadata_input.royalties {
Some(royalties) => {
let total_shares: u16 = royalties.shares.iter().map(|x| x.share).sum();
if total_shares != 10000 {
return Err(ErrorCode::RoyaltiesBadSum.into());
}
}
None => {}
}
Ok(())
}
#[repr(C)]
#[derive(Clone, AnchorDeserialize, AnchorSerialize)]
pub struct CreateMetadataInput {
pub name: String,
pub symbol: String,
pub asset: Asset,
pub update_authority: Pubkey,
pub extension: MetadataExtension,
}
impl CreateMetadataInput {
pub fn get_size(&self) -> usize {
let size = 4
+ self.name.len()
+ 4
+ self.symbol.len()
+ 4
+ self.asset.get_size()
+ self.extension.get_size();
return size;
}
}
#[derive(Clone, AnchorDeserialize, AnchorSerialize)]
pub struct UpdateMetadataInput {
pub name: String,
pub symbol: String,
pub asset: Asset,
}
impl UpdateMetadataInput {
pub fn get_size(&self) -> usize {
let size = 4
+ self.name.len()
+ 4
+ self.symbol.len()
+ 4
+ self.asset.get_size();
return size;
}
}
#[derive(Clone, AnchorDeserialize, AnchorSerialize)]
pub enum MetadataEventType {
Create,
Update,
Delete,
}
#[event]
pub struct MetadataEvent {
pub id: Pubkey,
pub mint: Pubkey,
pub event_type: MetadataEventType,
}