diff --git a/src/premints/zora_premint_v2/rules.rs b/src/premints/zora_premint_v2/rules.rs index cd6d07c..24a65fe 100644 --- a/src/premints/zora_premint_v2/rules.rs +++ b/src/premints/zora_premint_v2/rules.rs @@ -4,14 +4,16 @@ use alloy_primitives::Signature; use alloy_sol_types::SolStruct; use crate::premints::zora_premint_v2::types::ZoraPremintV2; -use crate::rules::RuleContext; -use crate::types::Premint; +use crate::rules::{Rule, RuleContext}; +use crate::typed_rule; +use crate::types::{Premint, PremintTypes}; // create premint v2 rule implementations here -// TODO: is there any rust sugar to make this more concise? -// as it stands, it's not defined as an async function, so can't use async stuff -pub async fn is_authorized_to_create_premint(premint: &T) -> eyre::Result { +pub async fn is_authorized_to_create_premint( + premint: ZoraPremintV2, + context: RuleContext, +) -> eyre::Result { // * if contract exists, check if the signer is the contract admin // * if contract does not exist, check if the signer is the proposed contract admin // * this logic exists as a function on the premint executor contract @@ -38,6 +40,16 @@ pub async fn is_valid_signature( Ok(signer == premint.collection.contractAdmin) } +pub fn all_rules() -> Vec> { + vec![ + Box::new(typed_rule!( + PremintTypes::ZoraV2, + is_authorized_to_create_premint + )), + Box::new(typed_rule!(PremintTypes::ZoraV2, is_valid_signature)), + ] +} + #[cfg(test)] mod test { use std::str::FromStr; diff --git a/src/rules.rs b/src/rules.rs index 0b3743b..1874596 100644 --- a/src/rules.rs +++ b/src/rules.rs @@ -36,6 +36,30 @@ macro_rules! rule { }; } +#[macro_export] +macro_rules! metadata_rule { + ($fn:tt) => {{ + struct MetadataRule; + + #[async_trait::async_trait] + impl crate::rules::Rule for MetadataRule { + async fn check( + &self, + item: crate::types::PremintTypes, + context: crate::rules::RuleContext, + ) -> eyre::Result { + $fn(item.metadata(), context).await + } + + fn rule_name(&self) -> &'static str { + concat!("Metadata::", stringify!($fn)) + } + } + + MetadataRule {} + }}; +} + #[macro_export] macro_rules! typed_rule { ($t:path, $fn:tt) => {{ @@ -67,6 +91,15 @@ pub struct RulesEngine { rules: Vec>, } +fn all_rules() -> Vec> { + let mut rules: Vec> = Vec::new(); + + rules.append(&mut general::all_rules()); + rules.append(&mut crate::premints::zora_premint_v2::rules::all_rules()); + + rules +} + impl RulesEngine { pub fn new() -> Self { RulesEngine { rules: vec![] } @@ -102,6 +135,29 @@ impl RulesEngine { } } +mod general { + use crate::rules::{Rule, RuleContext}; + use crate::types::PremintMetadata; + + pub fn all_rules() -> Vec> { + vec![Box::new(metadata_rule!(token_uri_length))] + } + + pub async fn token_uri_length( + meta: PremintMetadata, + context: RuleContext, + ) -> eyre::Result { + let max_allowed = if meta.uri.starts_with("data:") { + // allow some more data for data uris + 8 * 1024 + } else { + 2 * 1024 + }; + + Ok(meta.uri.len() <= max_allowed) + } +} + #[cfg(test)] mod test { use alloy_primitives::U256;