Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add metadata rules #11

Merged
merged 3 commits into from
Apr 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 17 additions & 5 deletions src/premints/zora_premint_v2/rules.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<T: Premint>(premint: &T) -> eyre::Result<bool> {
pub async fn is_authorized_to_create_premint(
premint: ZoraPremintV2,
context: RuleContext,
) -> eyre::Result<bool> {
// * 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
Expand All @@ -38,6 +40,16 @@ pub async fn is_valid_signature(
Ok(signer == premint.collection.contractAdmin)
}

pub fn all_rules() -> Vec<Box<dyn Rule>> {
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;
Expand Down
56 changes: 56 additions & 0 deletions src/rules.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<bool> {
$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) => {{
Expand Down Expand Up @@ -67,6 +91,15 @@ pub struct RulesEngine {
rules: Vec<Box<dyn Rule>>,
}

fn all_rules() -> Vec<Box<dyn Rule>> {
let mut rules: Vec<Box<dyn Rule>> = 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![] }
Expand Down Expand Up @@ -102,6 +135,29 @@ impl RulesEngine {
}
}

mod general {
use crate::rules::{Rule, RuleContext};
use crate::types::PremintMetadata;

pub fn all_rules() -> Vec<Box<dyn Rule>> {
vec![Box::new(metadata_rule!(token_uri_length))]
}

pub async fn token_uri_length(
meta: PremintMetadata,
context: RuleContext,
) -> eyre::Result<bool> {
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;
Expand Down
Loading