Skip to content

Commit

Permalink
Switch collection history field in mint object
Browse files Browse the repository at this point in the history
  • Loading branch information
imabdulbasit committed Aug 28, 2023
1 parent 7142051 commit 0bfcfc2
Show file tree
Hide file tree
Showing 17 changed files with 278 additions and 196 deletions.
8 changes: 4 additions & 4 deletions api/src/dataloaders/collection_mints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use async_graphql::{dataloader::Loader as DataLoader, FieldError, Result};
use poem::async_trait;
use sea_orm::prelude::*;

use crate::{db::Connection, entities::collection_mints};
use crate::{db::Connection, entities::collection_mints, objects::CollectionMint};

#[derive(Debug, Clone)]
pub struct Loader {
Expand All @@ -21,7 +21,7 @@ impl Loader {
#[async_trait]
impl DataLoader<Uuid> for Loader {
type Error = FieldError;
type Value = Vec<collection_mints::CollectionMint>;
type Value = Vec<CollectionMint>;

async fn load(&self, keys: &[Uuid]) -> Result<HashMap<Uuid, Self::Value>, Self::Error> {
let collection_mints = collection_mints::Entity::find()
Expand Down Expand Up @@ -60,7 +60,7 @@ impl OwnerLoader {
#[async_trait]
impl DataLoader<String> for OwnerLoader {
type Error = FieldError;
type Value = Vec<collection_mints::CollectionMint>;
type Value = Vec<CollectionMint>;

async fn load(&self, keys: &[String]) -> Result<HashMap<String, Self::Value>, Self::Error> {
let collection_mints = collection_mints::Entity::find()
Expand Down Expand Up @@ -100,7 +100,7 @@ impl CollectionMintLoader {
#[async_trait]
impl DataLoader<Uuid> for CollectionMintLoader {
type Error = FieldError;
type Value = collection_mints::CollectionMint;
type Value = CollectionMint;

async fn load(&self, keys: &[Uuid]) -> Result<HashMap<Uuid, Self::Value>, Self::Error> {
let collection_mints = collection_mints::Entity::find()
Expand Down
2 changes: 2 additions & 0 deletions api/src/dataloaders/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ mod mint_histories;
mod nft_transfers;
mod project_collection;
mod project_collections;
mod switch_collection_histories;
mod update_histories;

pub use collection::Loader as CollectionLoader;
Expand All @@ -34,4 +35,5 @@ pub use mint_histories::{
pub use nft_transfers::CollectionMintTransfersLoader;
pub use project_collection::ProjectCollectionLoader;
pub use project_collections::ProjectCollectionsLoader;
pub use switch_collection_histories::SwitchCollectionHistoryLoader;
pub use update_histories::UpdateMintHistoryLoader;
50 changes: 50 additions & 0 deletions api/src/dataloaders/switch_collection_histories.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
use std::collections::HashMap;

use async_graphql::{dataloader::Loader as DataLoader, FieldError, Result};
use poem::async_trait;
use sea_orm::{prelude::*, Order, QueryOrder};

use crate::{db::Connection, entities::switch_collection_histories};

#[derive(Debug, Clone)]
pub struct SwitchCollectionHistoryLoader {
pub db: Connection,
}

impl SwitchCollectionHistoryLoader {
#[must_use]
pub fn new(db: Connection) -> Self {
Self { db }
}
}

#[async_trait]
impl DataLoader<Uuid> for SwitchCollectionHistoryLoader {
type Error = FieldError;
type Value = Vec<switch_collection_histories::Model>;

async fn load(&self, keys: &[Uuid]) -> Result<HashMap<Uuid, Self::Value>, Self::Error> {
let conn = self.db.get();
let switch_histories = switch_collection_histories::Entity::find()
.filter(
switch_collection_histories::Column::CollectionMintId
.is_in(keys.iter().map(ToOwned::to_owned)),
)
.order_by(switch_collection_histories::Column::CreatedAt, Order::Desc)
.all(conn)
.await?;

Ok(switch_histories.into_iter().fold(
HashMap::new(),
|mut acc: HashMap<Uuid, Vec<switch_collection_histories::Model>>, switch_history| {
acc.entry(switch_history.collection_mint_id.clone())

Check warning on line 40 in api/src/dataloaders/switch_collection_histories.rs

View workflow job for this annotation

GitHub Actions / clippy/check/doc

using `clone` on type `Uuid` which implements the `Copy` trait
.or_insert_with(Vec::new);

acc.entry(switch_history.collection_mint_id.clone())

Check warning on line 43 in api/src/dataloaders/switch_collection_histories.rs

View workflow job for this annotation

GitHub Actions / clippy/check/doc

using `clone` on type `Uuid` which implements the `Copy` trait
.and_modify(|switch_histories| switch_histories.push(switch_history.into()));

Check warning on line 44 in api/src/dataloaders/switch_collection_histories.rs

View workflow job for this annotation

GitHub Actions / clippy/check/doc

useless conversion to the same type: `entities::switch_collection_histories::Model`

acc
},
))
}
}
154 changes: 2 additions & 152 deletions api/src/entities/collection_mints.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,9 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.0

use async_graphql::{ComplexObject, Context, Error, Result, SimpleObject};
use async_graphql::Result;
use sea_orm::{entity::prelude::*, JoinType, QuerySelect, SelectTwo};

use super::{
collections, mint_creators, mint_histories, nft_transfers,
sea_orm_active_enums::{Blockchain, CreationStatus},
update_histories,
};
use crate::{
objects::{Collection, MetadataJson},
AppContext,
};
use super::{collections, sea_orm_active_enums::CreationStatus};

#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)]
#[sea_orm(table_name = "collection_mints")]
Expand All @@ -34,148 +26,6 @@ pub struct Model {
pub compressed: bool,
}

/// Represents a single NFT minted from a collection.
#[derive(Clone, Debug, PartialEq, Eq, SimpleObject)]
#[graphql(complex)]
pub struct CollectionMint {
/// The unique ID of the minted NFT.
pub id: Uuid,
/// The ID of the collection the NFT was minted from.
pub collection_id: Uuid,
/// The address of the NFT
/// On Solana this is the mint address.
/// On EVM chains it is the concatenation of the contract address and the token id `{contractAddress}:{tokenId}`.
pub address: Option<String>,
/// The wallet address of the owner of the NFT.
pub owner: String,
/// The status of the NFT creation.
pub creation_status: CreationStatus,
/// The unique ID of the creator of the NFT.
pub created_by: Uuid,
/// The date and time when the NFT was created.
pub created_at: DateTimeWithTimeZone,
/// The transaction signature associated with the NFT.
pub signature: Option<String>,
/// The unique edition number of the NFT.
pub edition: i64,
/// The seller fee basis points (ie royalties) for the NFT.
pub seller_fee_basis_points: i16,
/// credits deduction id
pub credits_deduction_id: Option<Uuid>,
/// Indicates if the NFT is compressed. Compression is only supported on Solana.
pub compressed: bool,
}

#[ComplexObject]
impl CollectionMint {
/// The collection the NFT was minted from.
async fn collection(&self, ctx: &Context<'_>) -> Result<Option<Collection>> {
let AppContext {
collection_loader, ..
} = ctx.data::<AppContext>()?;

collection_loader.load_one(self.collection_id).await
}

/// The metadata json associated to the collection.
/// [Metaplex v1.1.0 Standard](https://docs.metaplex.com/programs/token-metadata/token-standard)
async fn metadata_json(&self, ctx: &Context<'_>) -> Result<Option<MetadataJson>> {
let AppContext {
metadata_json_loader,
..
} = ctx.data::<AppContext>()?;
let collection = self.collection(ctx).await?.ok_or(Error::new(format!(
"Collection not found for collection mint {:?}",
&self.id
)))?;

match collection.blockchain {
Blockchain::Solana => metadata_json_loader.load_one(self.id).await,
Blockchain::Polygon => metadata_json_loader.load_one(self.collection_id).await,
Blockchain::Ethereum => Err(Error::new("Ethereum not supported")),
}
}

/// The update history of the mint.
async fn update_histories(
&self,
ctx: &Context<'_>,
) -> Result<Option<Vec<update_histories::Model>>> {
let AppContext {
update_mint_history_loader,
..
} = ctx.data::<AppContext>()?;

update_mint_history_loader.load_one(self.id).await
}
/// The creators of the mint. Includes the creator addresses and their shares.
async fn creators(&self, ctx: &Context<'_>) -> Result<Option<Vec<mint_creators::Model>>> {
let AppContext {
mint_creators_loader,
..
} = ctx.data::<AppContext>()?;

mint_creators_loader.load_one(self.id).await
}

/// The record of the original mint.
async fn mint_history(&self, ctx: &Context<'_>) -> Result<Option<mint_histories::Model>> {
let AppContext {
collection_mint_mint_history_loader,
..
} = ctx.data::<AppContext>()?;

collection_mint_mint_history_loader.load_one(self.id).await
}

/// The history of transfers for the mint.
async fn transfer_histories(
&self,
ctx: &Context<'_>,
) -> Result<Option<Vec<nft_transfers::Model>>> {
let AppContext {
collection_mint_transfers_loader,
..
} = ctx.data::<AppContext>()?;

collection_mint_transfers_loader.load_one(self.id).await
}
}

impl From<Model> for CollectionMint {
fn from(
Model {
id,
collection_id,
address,
owner,
creation_status,
created_by,
created_at,
signature,
edition,
seller_fee_basis_points,
credits_deduction_id,
compressed,
}: Model,
) -> Self {
Self {
id,
collection_id,
address,
owner,
creation_status,
created_by,
created_at,
signature,
edition,
seller_fee_basis_points,
credits_deduction_id,
compressed,
}
}
}

#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(
Expand Down
4 changes: 2 additions & 2 deletions api/src/entities/mint_histories.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
use async_graphql::{ComplexObject, Context, Result, SimpleObject};
use sea_orm::entity::prelude::*;

use super::{collection_mints::CollectionMint, sea_orm_active_enums::CreationStatus};
use crate::AppContext;
use super::sea_orm_active_enums::CreationStatus;
use crate::{objects::CollectionMint, AppContext};

/// A record of a minted NFT.
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, SimpleObject)]
Expand Down
5 changes: 3 additions & 2 deletions api/src/entities/switch_collection_histories.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3

use async_graphql::SimpleObject;
use sea_orm::entity::prelude::*;

use super::sea_orm_active_enums::CreationStatus;

#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)]
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, SimpleObject)]
#[sea_orm(table_name = "switch_collection_histories")]
#[graphql(concrete(name = "SwitchCollectionHistory", params()))]
pub struct Model {
#[sea_orm(primary_key, auto_increment = false)]
pub id: Uuid,
Expand Down
16 changes: 11 additions & 5 deletions api/src/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ pub enum ProcessorErrorKind {
DbMissingTransferCharge,
#[error("No associated update history found in database")]
DbMissingUpdateHistory,
#[error("No associated switch collection history found in database")]
DbMissingSwitchCollectionHistory,

#[error("Database record contains no deduction ID")]
RecordMissingDeductionId,
Expand Down Expand Up @@ -251,6 +253,10 @@ impl Processor {
SolanaNftsEvent::UpdateCollectionMintFailed(_)
| SolanaNftsEvent::RetryUpdateMintFailed(_),
) => self.mint_updated(id, UpdateResult::Failure).await,
Some(SolanaNftsEvent::SwitchMintCollectionFailed(_)) => {
self.switch_collection_submitted(id, SwitchCollectionResult::Failure)
.await
},
Some(SolanaNftsEvent::UpdateMintOwner(e)) => self.update_mint_owner(id, e).await,
Some(SolanaNftsEvent::ImportedExternalCollection(e)) => {
self.index_collection(id, project_id, user_id, e).await
Expand Down Expand Up @@ -304,10 +310,10 @@ impl Processor {
} = metadata.ok_or(ProcessorErrorKind::MissingCollectionMetadata)?;

let collection_am = collections::ActiveModel {
id: Set(id.parse()?),
id: Set(Uuid::from_str(&id)?),
blockchain: Set(Blockchain::Solana),
supply: Set(supply.map(Into::into)),
project_id: Set(project_id.parse()?),
project_id: Set(Uuid::from_str(&project_id)?),
credits_deduction_id: Set(None),
creation_status: Set(CreationStatus::Created),
total_mints: Set(0),
Expand Down Expand Up @@ -851,17 +857,17 @@ impl Processor {
&self,
id: String,
payload: SwitchCollectionResult,
) -> Result<()> {
) -> ProcessResult<()> {
let history_id = Uuid::from_str(&id)?;
let history = SwitchCollectionHistories::find_by_id(history_id)
.one(self.db.get())
.await?
.context("Switch collection history record not found")?;
.ok_or(ProcessorErrorKind::DbMissingSwitchCollectionHistory)?;

let mint = CollectionMints::find_by_id(history.collection_mint_id)
.one(self.db.get())
.await?
.context("Mint record not found")?;
.ok_or(ProcessorErrorKind::DbMissingCollectionMint)?;

let mut history_am: switch_collection_histories::ActiveModel = history.clone().into();

Expand Down
8 changes: 6 additions & 2 deletions api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ use dataloaders::{
CollectionMintMintHistoryLoader, CollectionMintTransfersLoader, CollectionMintsLoader,
CollectionMintsOwnerLoader, CreatorsLoader, DropLoader, DropMintHistoryLoader, HoldersLoader,
MetadataJsonAttributesLoader, MetadataJsonLoader, MintCreatorsLoader, MinterMintHistoryLoader,
ProjectCollectionLoader, ProjectCollectionsLoader, ProjectDropsLoader, UpdateMintHistoryLoader,
ProjectCollectionLoader, ProjectCollectionsLoader, ProjectDropsLoader,
SwitchCollectionHistoryLoader, UpdateMintHistoryLoader,
};
use db::Connection;
use hub_core::{
Expand Down Expand Up @@ -286,6 +287,7 @@ pub struct AppContext {
mint_creators_loader: DataLoader<MintCreatorsLoader>,
collection_mint_mint_history_loader: DataLoader<CollectionMintMintHistoryLoader>,
collection_mint_transfers_loader: DataLoader<CollectionMintTransfersLoader>,
switch_collection_history_loader: DataLoader<SwitchCollectionHistoryLoader>,
}

impl AppContext {
Expand Down Expand Up @@ -334,7 +336,8 @@ impl AppContext {
);
let collection_mint_transfers_loader =
DataLoader::new(CollectionMintTransfersLoader::new(db.clone()), tokio::spawn);

let switch_collection_history_loader =
DataLoader::new(SwitchCollectionHistoryLoader::new(db.clone()), tokio::spawn);
Self {
db,
user_id,
Expand All @@ -360,6 +363,7 @@ impl AppContext {
mint_creators_loader,
collection_mint_mint_history_loader,
collection_mint_transfers_loader,
switch_collection_history_loader,
}
}
}
Expand Down
Loading

0 comments on commit 0bfcfc2

Please sign in to comment.