From c851178add70ff2b78bf014c4a8e4d7f091b0182 Mon Sep 17 00:00:00 2001 From: imabdulbasit Date: Mon, 11 Sep 2023 19:13:18 +0500 Subject: [PATCH 01/20] Open Drop API --- api/proto.lock | 18 +- api/proto.toml | 14 +- api/src/blockchains/mod.rs | 18 +- api/src/blockchains/polygon.rs | 87 +++++--- api/src/blockchains/solana.rs | 172 +++++++++++++--- api/src/dataloaders/collection_mints.rs | 11 +- api/src/entities/collection_mints.rs | 4 +- api/src/entities/drops.rs | 3 +- api/src/entities/sea_orm_active_enums.rs | 11 + api/src/events.rs | 26 +-- api/src/mutations/drop.rs | 193 +++++++++++------- api/src/mutations/transfer.rs | 33 +-- api/src/objects/collection_mint.rs | 2 +- api/src/objects/drop.rs | 3 +- api/src/objects/holder.rs | 2 +- migration/src/lib.rs | 6 + .../src/m20230905_100852_add_type_to_drop.rs | 66 ++++++ ...4731_add_queued_variant_to_mints_status.rs | 24 +++ ...42_make_owner_address_optional_for_mint.rs | 35 ++++ 19 files changed, 529 insertions(+), 199 deletions(-) create mode 100644 migration/src/m20230905_100852_add_type_to_drop.rs create mode 100644 migration/src/m20230910_204731_add_queued_variant_to_mints_status.rs create mode 100644 migration/src/m20230910_212742_make_owner_address_optional_for_mint.rs diff --git a/api/proto.lock b/api/proto.lock index ecab697..0c75d46 100644 --- a/api/proto.lock +++ b/api/proto.lock @@ -1,27 +1,27 @@ [[schemas]] subject = "customer" -version = 2 +version = 1 sha512 = "d75800df0d4744c6b0f4d9a9952d3bfd0bb6b24a8babd19104cc11b54a525f85551b3c7375d69aeabbcf629cd826aa0bc6b0c0467add20716c504f5e856ce1c5" [[schemas]] subject = "nfts" -version = 28 -sha512 = "25960e99e2eb1edeb70b7619918926d877b834640cf44fcc8104da5be6e213c05be18f8f49dba35e649d751bc62e16d9ca428cbafdb432b7c0b7f40a6cef7483" +version = 2 +sha512 = "db8fa9f4b2874ab79305997c3b255a9b9c1b04d291c66f1cb97f332b32758055c01e6ba0e7a4089255c664324c51fc4fe25a9d138698b7a999b1f4d2b5503a48" [[schemas]] subject = "organization" -version = 5 +version = 1 sha512 = "9fb28ac73d9712292297394a5fa53a7dae9deba6847353582987ba749859301c23c05fd49d2ce84a1640f8864c5c04d59fa38907700b280000e5c4afc96654bf" [[schemas]] subject = "polygon_nfts" -version = 6 +version = 1 sha512 = "c5ddf43d2958ec690ee2261d0ff9808b67ce810d2fc4b6077f96f561929a920f03509fc8bd7adbda219250eb019f5f7be8a3f51c554f665ea1881f7a973ef2a6" [[schemas]] subject = "solana_nfts" -version = 10 -sha512 = "1bcb166ab5dfdf4841d60caa07a4098dcec03d7e3b0e63adb090ed2f5fe990c1e13826867e8df7521ec631027d5a931a08865fd2cf2daa905807c4b7dca40213" +version = 1 +sha512 = "37fd0e45d12271323d8abfe7343c08e475ca4737014d6181dcdcbcd683ebc33ab7cea1f4da00673e7ad2f0e1ae5ae917f16175b0650df357f649545928685a50" [[schemas]] subject = "timestamp" @@ -30,5 +30,5 @@ sha512 = "d167e0a143c813073eef8597f0b237e5a8eaf32abbf709724e8071b2dd73ce0438b82f [[schemas]] subject = "treasury" -version = 22 -sha512 = "bde788b07f818aa52e684dcbd91e1f1e3db82f242f616ec2a42ab6d412df33a1461677c229f2f9bae345938c2f325e6332a95caef2c7e01a47531af53e39bf03" +version = 1 +sha512 = "03580129f0561b3d153f83b9f2729bd18e27c7d29815c9c3b7493e57e3cad3ea56f6e803e0ec5f19e8c17669de5ef8c0eb1bd59cfbae5f400741d0a73a464ba5" diff --git a/api/proto.toml b/api/proto.toml index 3d92c89..030a40b 100644 --- a/api/proto.toml +++ b/api/proto.toml @@ -1,11 +1,11 @@ [registry] -endpoint = "https://schemas.holaplex.tools" +endpoint = "http://localhost:8081" [schemas] -organization = 5 -nfts = 28 -customer = 2 -treasury = 22 -solana_nfts = 10 -polygon_nfts = 6 +organization = 1 +nfts = 2 +customer = 1 +treasury = 1 +solana_nfts = 1 +polygon_nfts = 1 timestamp = 1 \ No newline at end of file diff --git a/api/src/blockchains/mod.rs b/api/src/blockchains/mod.rs index 6aab281..954e6ec 100644 --- a/api/src/blockchains/mod.rs +++ b/api/src/blockchains/mod.rs @@ -3,8 +3,11 @@ pub mod solana; use hub_core::anyhow::Result; -use crate::proto::{ - NftEventKey, RetryUpdateSolanaMintPayload, SwitchCollectionPayload, UpdateSolanaMintPayload, +use crate::{ + entities::sea_orm_active_enums::DropType, + proto::{ + NftEventKey, RetryUpdateSolanaMintPayload, SwitchCollectionPayload, UpdateSolanaMintPayload, + }, }; /// Represents a response from a transaction on the blockchain. This struct @@ -19,9 +22,14 @@ pub struct TransactionResponse { #[async_trait::async_trait] pub trait DropEvent { - async fn create_drop(&self, key: NftEventKey, payload: A) -> Result<()>; - async fn retry_create_drop(&self, key: NftEventKey, payload: A) -> Result<()>; - async fn update_drop(&self, key: NftEventKey, payload: C) -> Result<()>; + async fn create_drop(&self, drop_type: DropType, key: NftEventKey, payload: A) -> Result<()>; + async fn retry_create_drop( + &self, + drop_type: DropType, + key: NftEventKey, + payload: A, + ) -> Result<()>; + async fn update_drop(&self, drop_type: DropType, key: NftEventKey, payload: C) -> Result<()>; async fn mint_drop(&self, key: NftEventKey, payload: B) -> Result<()>; async fn retry_mint_drop(&self, key: NftEventKey, payload: B) -> Result<()>; } diff --git a/api/src/blockchains/polygon.rs b/api/src/blockchains/polygon.rs index b2853ff..d1c9146 100644 --- a/api/src/blockchains/polygon.rs +++ b/api/src/blockchains/polygon.rs @@ -1,13 +1,16 @@ -use hub_core::{anyhow::Result, producer::Producer}; +use hub_core::{anyhow::Result, prelude::bail, producer::Producer}; use super::{DropEvent, TransferEvent}; -use crate::proto::{ - nft_events::Event::{ - PolygonCreateDrop, PolygonMintDrop, PolygonRetryDrop, PolygonRetryMintDrop, - PolygonTransferAsset, PolygonUpdateDrop, +use crate::{ + entities::sea_orm_active_enums::DropType, + proto::{ + nft_events::Event::{ + PolygonCreateDrop, PolygonMintDrop, PolygonRetryDrop, PolygonRetryMintDrop, + PolygonTransferAsset, PolygonUpdateDrop, + }, + CreateEditionTransaction, MintEditionTransaction, NftEventKey, NftEvents, + TransferPolygonAsset, UpdateEdtionTransaction, }, - CreateEditionTransaction, MintEditionTransaction, NftEventKey, NftEvents, TransferPolygonAsset, - UpdateEdtionTransaction, }; #[derive(Clone)] @@ -25,7 +28,7 @@ impl Polygon { pub fn event( &self, ) -> impl DropEvent - + TransferEvent { + + TransferEvent { self.clone() } } @@ -34,46 +37,69 @@ impl Polygon { impl DropEvent for Polygon { - async fn create_drop(&self, key: NftEventKey, payload: CreateEditionTransaction) -> Result<()> { - let event = NftEvents { - event: Some(PolygonCreateDrop(payload)), + async fn create_drop( + &self, + drop_type: DropType, + key: NftEventKey, + payload: CreateEditionTransaction, + ) -> Result<()> { + let event = match drop_type { + DropType::Edition => Some(PolygonCreateDrop(payload)), + DropType::Open => bail!("Open drops are not supported on Polygon"), }; - self.producer.send(Some(&event), Some(&key)).await?; + self.producer + .send(Some(&NftEvents { event }), Some(&key)) + .await?; Ok(()) } async fn retry_create_drop( &self, + drop_type: DropType, key: NftEventKey, payload: CreateEditionTransaction, ) -> Result<()> { - let event = NftEvents { - event: Some(PolygonRetryDrop(payload)), + let event = match drop_type { + DropType::Edition => Some(PolygonRetryDrop(payload)), + DropType::Open => bail!("Open drops are not supported on Polygon"), }; - self.producer.send(Some(&event), Some(&key)).await?; + self.producer + .send(Some(&NftEvents { event }), Some(&key)) + .await?; Ok(()) } - async fn update_drop(&self, key: NftEventKey, payload: UpdateEdtionTransaction) -> Result<()> { - let event = NftEvents { - event: Some(PolygonUpdateDrop(payload)), + async fn update_drop( + &self, + drop_type: DropType, + key: NftEventKey, + payload: UpdateEdtionTransaction, + ) -> Result<()> { + let event = match drop_type { + DropType::Edition => Some(PolygonUpdateDrop(payload)), + DropType::Open => bail!("Open drops are not supported on Polygon"), }; - self.producer.send(Some(&event), Some(&key)).await?; + self.producer + .send(Some(&NftEvents { event }), Some(&key)) + .await?; Ok(()) } async fn mint_drop(&self, key: NftEventKey, payload: MintEditionTransaction) -> Result<()> { - let event = NftEvents { - event: Some(PolygonMintDrop(payload)), - }; - - self.producer.send(Some(&event), Some(&key)).await?; + self.producer + .send( + Some(&NftEvents { + event: Some(PolygonMintDrop(payload)), + }), + Some(&key), + ) + .await?; Ok(()) } @@ -83,11 +109,14 @@ impl DropEvent Result<()> { - let event = NftEvents { - event: Some(PolygonRetryMintDrop(payload)), - }; - - self.producer.send(Some(&event), Some(&key)).await?; + self.producer + .send( + Some(&NftEvents { + event: Some(PolygonRetryMintDrop(payload)), + }), + Some(&key), + ) + .await?; Ok(()) } diff --git a/api/src/blockchains/solana.rs b/api/src/blockchains/solana.rs index ac999a6..3fd24ac 100644 --- a/api/src/blockchains/solana.rs +++ b/api/src/blockchains/solana.rs @@ -1,23 +1,34 @@ use hub_core::{anyhow::Result, producer::Producer}; use super::{CollectionEvent, DropEvent, TransferEvent}; -use crate::proto::{ - nft_events::Event::{ - SolanaCreateCollection, SolanaCreateDrop, SolanaMintDrop, SolanaMintToCollection, - SolanaRetryCreateCollection, SolanaRetryDrop, SolanaRetryMintDrop, - SolanaRetryMintToCollection, SolanaRetryUpdatedCollectionMint, - SolanaSwitchMintCollectionRequested, SolanaTransferAsset, SolanaUpdateCollection, - SolanaUpdateDrop, SolanaUpdatedCollectionMint, +use crate::{ + entities::sea_orm_active_enums::DropType, + proto::{ + nft_events::Event::{ + SolanaCreateCollection, SolanaCreateEditionDrop, SolanaCreateOpenDrop, + SolanaMintEditionDrop, SolanaMintOpenDrop, SolanaMintToCollection, + SolanaRetryCreateCollection, SolanaRetryEditionDrop, SolanaRetryMintEditionDrop, + SolanaRetryMintOpenDrop, SolanaRetryMintToCollection, SolanaRetryOpenDrop, + SolanaRetryUpdatedCollectionMint, SolanaSwitchMintCollectionRequested, + SolanaTransferAsset, SolanaUpdateCollection, SolanaUpdateEditionDrop, + SolanaUpdateOpenDrop, SolanaUpdatedCollectionMint, + }, + MetaplexMasterEditionTransaction, MintMetaplexEditionTransaction, + MintMetaplexMetadataTransaction, NftEventKey, NftEvents, RetryUpdateSolanaMintPayload, + SwitchCollectionPayload, TransferMetaplexAssetTransaction, UpdateSolanaMintPayload, }, - MetaplexMasterEditionTransaction, MintMetaplexEditionTransaction, - MintMetaplexMetadataTransaction, NftEventKey, NftEvents, RetryUpdateSolanaMintPayload, - SwitchCollectionPayload, TransferMetaplexAssetTransaction, UpdateSolanaMintPayload, }; + #[derive(Clone)] pub struct Solana { producer: Producer, } +pub enum MintDropTransaction { + Edition(MintMetaplexEditionTransaction), + Open(MintMetaplexMetadataTransaction), +} + impl Solana { #[must_use] pub fn new(producer: Producer) -> Self { @@ -29,7 +40,7 @@ impl Solana { &self, ) -> impl DropEvent< MetaplexMasterEditionTransaction, - MintMetaplexEditionTransaction, + MintDropTransaction, MetaplexMasterEditionTransaction, > + TransferEvent + CollectionEvent< @@ -42,51 +53,59 @@ impl Solana { } #[async_trait::async_trait] -impl - DropEvent< - MetaplexMasterEditionTransaction, - MintMetaplexEditionTransaction, - MetaplexMasterEditionTransaction, - > for Solana +impl DropEvent + for Solana { async fn create_drop( &self, + drop_type: DropType, key: NftEventKey, payload: MetaplexMasterEditionTransaction, ) -> Result<()> { - let event = NftEvents { - event: Some(SolanaCreateDrop(payload)), + let event = match drop_type { + DropType::Edition => Some(SolanaCreateEditionDrop(payload)), + DropType::Open => Some(SolanaCreateOpenDrop(payload)), }; - self.producer.send(Some(&event), Some(&key)).await?; + self.producer + .send(Some(&NftEvents { event }), Some(&key)) + .await?; Ok(()) } async fn retry_create_drop( &self, + drop_type: DropType, key: NftEventKey, payload: MetaplexMasterEditionTransaction, ) -> Result<()> { - let event = NftEvents { - event: Some(SolanaRetryDrop(payload)), + let event = match drop_type { + DropType::Edition => Some(SolanaRetryEditionDrop(payload)), + DropType::Open => Some(SolanaRetryOpenDrop(payload)), }; - self.producer.send(Some(&event), Some(&key)).await?; + self.producer + .send(Some(&NftEvents { event }), Some(&key)) + .await?; Ok(()) } async fn update_drop( &self, + drop_type: DropType, key: NftEventKey, payload: MetaplexMasterEditionTransaction, ) -> Result<()> { - let event = NftEvents { - event: Some(SolanaUpdateDrop(payload)), + let event = match drop_type { + DropType::Edition => Some(SolanaUpdateEditionDrop(payload)), + DropType::Open => Some(SolanaUpdateOpenDrop(payload)), }; - self.producer.send(Some(&event), Some(&key)).await?; + self.producer + .send(Some(&NftEvents { event }), Some(&key)) + .await?; Ok(()) } @@ -94,13 +113,16 @@ impl async fn mint_drop( &self, key: NftEventKey, - payload: MintMetaplexEditionTransaction, + payload: MintDropTransaction, ) -> Result<()> { - let event = NftEvents { - event: Some(SolanaMintDrop(payload)), + let event = match payload { + MintDropTransaction::Edition(p) => Some(SolanaMintEditionDrop(p)), + MintDropTransaction::Open(p) => Some(SolanaMintOpenDrop(p)), }; - self.producer.send(Some(&event), Some(&key)).await?; + self.producer + .send(Some(&NftEvents { event }), Some(&key)) + .await?; Ok(()) } @@ -108,13 +130,16 @@ impl async fn retry_mint_drop( &self, key: NftEventKey, - payload: MintMetaplexEditionTransaction, + payload: MintDropTransaction, ) -> Result<()> { - let event = NftEvents { - event: Some(SolanaRetryMintDrop(payload)), + let event = match payload { + MintDropTransaction::Edition(tx) => Some(SolanaRetryMintEditionDrop(tx)), + MintDropTransaction::Open(tx) => Some(SolanaRetryMintOpenDrop(tx)), }; - self.producer.send(Some(&event), Some(&key)).await?; + self.producer + .send(Some(&NftEvents { event }), Some(&key)) + .await?; Ok(()) } @@ -255,3 +280,82 @@ impl Ok(()) } } + +// #[async_trait::async_trait] +// impl +// OpenDropEvent< +// MetaplexMasterEditionTransaction, +// MintMetaplexMetadataTransaction, +// MetaplexMasterEditionTransaction, +// > for Solana +// { +// async fn create_open_drop( +// &self, +// key: NftEventKey, +// payload: MetaplexMasterEditionTransaction, +// ) -> Result<()> { +// let event = NftEvents { +// event: Some(SolanaCreateOpenDrop(payload)), +// }; + +// self.producer.send(Some(&event), Some(&key)).await?; + +// Ok(()) +// } + +// async fn retry_create_open_drop( +// &self, +// key: NftEventKey, +// payload: MetaplexMasterEditionTransaction, +// ) -> Result<()> { +// let event = NftEvents { +// event: Some(SolanaRetryOpenDrop(payload)), +// }; + +// self.producer.send(Some(&event), Some(&key)).await?; + +// Ok(()) +// } + +// async fn update_open_drop( +// &self, +// key: NftEventKey, +// payload: MetaplexMasterEditionTransaction, +// ) -> Result<()> { +// let event = NftEvents { +// event: Some(SolanaUpdateOpenDrop(payload)), +// }; + +// self.producer.send(Some(&event), Some(&key)).await?; + +// Ok(()) +// } + +// async fn mint_open_drop( +// &self, +// key: NftEventKey, +// payload: MintMetaplexMetadataTransaction, +// ) -> Result<()> { +// let event = NftEvents { +// event: Some(SolanaMintOpenDrop(payload)), +// }; + +// self.producer.send(Some(&event), Some(&key)).await?; + +// Ok(()) +// } + +// async fn retry_mint_open_drop( +// &self, +// key: NftEventKey, +// payload: MintMetaplexMetadataTransaction, +// ) -> Result<()> { +// let event = NftEvents { +// event: Some(SolanaRetryMintOpenDrop(payload)), +// }; + +// self.producer.send(Some(&event), Some(&key)).await?; + +// Ok(()) +// } +// } diff --git a/api/src/dataloaders/collection_mints.rs b/api/src/dataloaders/collection_mints.rs index 1e37b6f..1993d3e 100644 --- a/api/src/dataloaders/collection_mints.rs +++ b/api/src/dataloaders/collection_mints.rs @@ -74,12 +74,11 @@ impl DataLoader for OwnerLoader { Ok(collection_mints .into_iter() .fold(HashMap::new(), |mut acc, collection_mint| { - acc.entry(collection_mint.owner.clone()) - .or_insert_with(Vec::new); - - acc.entry(collection_mint.owner.clone()) - .and_modify(|collection_mints| collection_mints.push(collection_mint.into())); - + if let Some(owner) = collection_mint.owner.clone() { + acc.entry(owner.clone()) + .or_insert_with(Vec::new) + .push(collection_mint.into()); + } acc })) } diff --git a/api/src/entities/collection_mints.rs b/api/src/entities/collection_mints.rs index 940ab90..730f98d 100644 --- a/api/src/entities/collection_mints.rs +++ b/api/src/entities/collection_mints.rs @@ -13,8 +13,8 @@ pub struct Model { pub collection_id: Uuid, #[sea_orm(column_type = "Text", nullable)] pub address: Option, - #[sea_orm(column_type = "Text")] - pub owner: String, + #[sea_orm(column_type = "Text", nullable)] + pub owner: Option, pub creation_status: CreationStatus, pub created_by: Uuid, pub created_at: DateTimeWithTimeZone, diff --git a/api/src/entities/drops.rs b/api/src/entities/drops.rs index b19c1b2..ed5a48e 100644 --- a/api/src/entities/drops.rs +++ b/api/src/entities/drops.rs @@ -2,7 +2,7 @@ use sea_orm::entity::prelude::*; -use super::sea_orm_active_enums::CreationStatus; +use super::sea_orm_active_enums::{CreationStatus, DropType}; #[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] #[sea_orm(table_name = "drops")] @@ -20,6 +20,7 @@ pub struct Model { pub paused_at: Option, pub shutdown_at: Option, pub credits_deduction_id: Option, + pub drop_type: DropType, } #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] diff --git a/api/src/entities/sea_orm_active_enums.rs b/api/src/entities/sea_orm_active_enums.rs index db967e9..824c485 100644 --- a/api/src/entities/sea_orm_active_enums.rs +++ b/api/src/entities/sea_orm_active_enums.rs @@ -43,4 +43,15 @@ pub enum CreationStatus { Pending, #[sea_orm(string_value = "rejected")] Rejected, + #[sea_orm(string_value = "queued")] + Queued, +} + +#[derive(Debug, Clone, PartialEq, Eq, EnumIter, DeriveActiveEnum, Enum, Copy)] +#[sea_orm(rs_type = "String", db_type = "Enum", enum_name = "drop_type")] +pub enum DropType { + #[sea_orm(string_value = "edition")] + Edition, + #[sea_orm(string_value = "open")] + Open, } diff --git a/api/src/events.rs b/api/src/events.rs index 8a2dd9a..40e5eac 100644 --- a/api/src/events.rs +++ b/api/src/events.rs @@ -71,6 +71,8 @@ pub enum ProcessorErrorKind { #[error("Database record contains no deduction ID")] RecordMissingDeductionId, + #[error("Database record contains no owner address")] + RecordMissingOwner, #[error("Invalid basis point value for seller fee")] #[permanent] @@ -188,8 +190,8 @@ impl Processor { e, ) => match e.event { Some( - SolanaNftsEvent::CreateDropSubmitted(payload) - | SolanaNftsEvent::RetryCreateDropSubmitted(payload), + SolanaNftsEvent::CreateEditionDropSubmitted(payload) + | SolanaNftsEvent::RetryCreateEditionDropSubmitted(payload), ) => { self.drop_created(id, MintResult::Success(payload.into())) .await @@ -202,8 +204,8 @@ impl Processor { .await }, Some( - SolanaNftsEvent::MintDropSubmitted(payload) - | SolanaNftsEvent::RetryMintDropSubmitted(payload), + SolanaNftsEvent::MintEditionDropSubmitted(payload) + | SolanaNftsEvent::RetryMintEditionDropSubmitted(payload), ) => { self.drop_minted(id, MintResult::Success(payload.into())) .await @@ -229,14 +231,14 @@ impl Processor { .await }, Some( - SolanaNftsEvent::CreateDropFailed(_) - | SolanaNftsEvent::RetryCreateDropFailed(_), + SolanaNftsEvent::CreateEditionDropFailed(_) + | SolanaNftsEvent::RetryCreateEditionDropFailed(_), ) => self.drop_created(id, MintResult::Failure).await, Some( SolanaNftsEvent::CreateCollectionFailed(_) | SolanaNftsEvent::RetryCreateCollectionFailed(_), ) => self.collection_created(id, MintResult::Failure).await, - Some(SolanaNftsEvent::MintDropFailed(_)) => { + Some(SolanaNftsEvent::MintEditionDropFailed(_)) => { self.drop_minted(id, MintResult::Failure).await }, Some( @@ -246,7 +248,7 @@ impl Processor { Some(SolanaNftsEvent::TransferAssetFailed(_)) => { self.mint_transferred(id, TransferResult::Failure).await }, - Some(SolanaNftsEvent::RetryMintDropFailed(_)) => { + Some(SolanaNftsEvent::RetryMintEditionDropFailed(_)) => { self.drop_minted(id, MintResult::Failure).await }, Some( @@ -390,7 +392,7 @@ impl Processor { id: Set(id.parse()?), collection_id: Set(collection_id.parse()?), address: Set(Some(mint_address)), - owner: Set(owner), + owner: Set(Some(owner)), creation_status: Set(CreationStatus::Created), created_by: Set(created_by.parse()?), created_at: Set(Utc::now().into()), @@ -463,7 +465,7 @@ impl Processor { .ok_or(ProcessorErrorKind::DbMissingCollectionMint)?; let mut mint_am: collection_mints::ActiveModel = mint.into(); - mint_am.owner = Set(payload.recipient.clone()); + mint_am.owner = Set(Some(payload.recipient.clone())); mint_am.update(self.db.get()).await?; @@ -514,13 +516,13 @@ impl Processor { for mint in mints { let mut mint_am: collection_mints::ActiveModel = mint.clone().into(); - mint_am.owner = Set(new_owner.clone()); + mint_am.owner = Set(Some(new_owner.clone())); mint_am.update(&txn).await?; let nft_transfers = nft_transfers::ActiveModel { tx_signature: Set(Some(transaction_hash.clone())), collection_mint_id: Set(mint.id), - sender: Set(mint.owner), + sender: Set(mint.owner.ok_or(ProcessorErrorKind::RecordMissingOwner)?), recipient: Set(new_owner.clone()), created_at: Set(created_at), ..Default::default() diff --git a/api/src/mutations/drop.rs b/api/src/mutations/drop.rs index 71e0a64..670bd02 100644 --- a/api/src/mutations/drop.rs +++ b/api/src/mutations/drop.rs @@ -15,7 +15,7 @@ use crate::{ collection_creators, collections, drops, metadata_jsons, prelude::{CollectionCreators, Collections, Drops, MetadataJsons}, project_wallets, - sea_orm_active_enums::{Blockchain as BlockchainEnum, CreationStatus}, + sea_orm_active_enums::{Blockchain as BlockchainEnum, CreationStatus, DropType}, }, metadata_json::MetadataJson, objects::{Creator, Drop, MetadataJsonInput}, @@ -98,7 +98,14 @@ impl Mutation { .save(db) .await?; - let metadata_json = MetadataJson::new(input.metadata_json) + let metadata_jsons::Model { + name, + symbol, + uri, + description, + image, + .. + } = MetadataJson::new(input.metadata_json) .upload(nft_storage) .await? .save(collection.id, db) @@ -114,6 +121,7 @@ impl Mutation { created_by: Set(user_id), created_at: Set(Utc::now().into()), credits_deduction_id: Set(Some(credits_deduction_id)), + drop_type: Set(input.drop_type), ..Default::default() }; @@ -124,47 +132,56 @@ impl Mutation { project_id: input.project.to_string(), }; + + + let payload = proto::MetaplexMasterEditionTransaction { + master_edition: Some(proto::MasterEdition { + owner_address: owner_address.clone(), + supply: input.supply.map(TryInto::try_into).transpose()?, + name: name.clone(), + symbol, + metadata_uri: uri.clone(), + seller_fee_basis_points: seller_fee_basis_points.into(), + creators: input + .creators + .clone() + .into_iter() + .map(TryFrom::try_from) + .collect::>()?, + }), + }; + match input.blockchain { BlockchainEnum::Solana => { solana .event() - .create_drop(event_key, proto::MetaplexMasterEditionTransaction { - master_edition: Some(proto::MasterEdition { - owner_address, - supply: input.supply.map(TryInto::try_into).transpose()?, - name: metadata_json.name, - symbol: metadata_json.symbol, - metadata_uri: metadata_json.uri, - seller_fee_basis_points: seller_fee_basis_points.into(), - creators: input - .creators - .into_iter() - .map(TryFrom::try_from) - .collect::>()?, - }), - }) + .create_drop(input.drop_type, event_key, payload) .await?; }, BlockchainEnum::Polygon => { let amount = input.supply.ok_or(Error::new("supply is required"))?; polygon - .create_drop(event_key, proto::CreateEditionTransaction { - amount: amount.try_into()?, - edition_info: Some(proto::EditionInfo { - creator: input - .creators - .get(0) - .ok_or(Error::new("creator is required"))? - .clone() - .address, - collection: metadata_json.name, - uri: metadata_json.uri, - description: metadata_json.description, - image_uri: metadata_json.image, - }), - fee_receiver: owner_address.clone(), - fee_numerator: seller_fee_basis_points.into(), - }) + .create_drop( + input.drop_type, + event_key, + proto::CreateEditionTransaction { + amount: amount.try_into()?, + edition_info: Some(proto::EditionInfo { + creator: input + .creators + .get(0) + .ok_or(Error::new("creator is required"))? + .clone() + .address, + collection: name, + uri, + description, + image_uri: image, + }), + fee_receiver: owner_address, + fee_numerator: seller_fee_basis_points.into(), + }, + ) .await?; }, BlockchainEnum::Ethereum => { @@ -269,24 +286,28 @@ impl Mutation { BlockchainEnum::Solana => { solana .event() - .retry_create_drop(event_key, proto::MetaplexMasterEditionTransaction { - master_edition: Some(proto::MasterEdition { - owner_address, - supply: collection.supply.map(TryInto::try_into).transpose()?, - name: metadata_json.name, - symbol: metadata_json.symbol, - metadata_uri: metadata_json.uri, - seller_fee_basis_points: collection.seller_fee_basis_points.into(), - creators: creators - .into_iter() - .map(|c| proto::Creator { - address: c.address, - verified: c.verified, - share: c.share, - }) - .collect(), - }), - }) + .retry_create_drop( + drop.drop_type, + event_key, + proto::MetaplexMasterEditionTransaction { + master_edition: Some(proto::MasterEdition { + owner_address, + supply: collection.supply.map(TryInto::try_into).transpose()?, + name: metadata_json.name, + symbol: metadata_json.symbol, + metadata_uri: metadata_json.uri, + seller_fee_basis_points: collection.seller_fee_basis_points.into(), + creators: creators + .into_iter() + .map(|c| proto::Creator { + address: c.address, + verified: c.verified, + share: c.share, + }) + .collect(), + }), + }, + ) .await?; }, BlockchainEnum::Polygon => { @@ -296,12 +317,16 @@ impl Mutation { polygon .event() - .retry_create_drop(event_key, proto::CreateEditionTransaction { - edition_info: None, - amount, - fee_receiver: owner_address, - fee_numerator: collection.seller_fee_basis_points.into(), - }) + .retry_create_drop( + drop.drop_type, + event_key, + proto::CreateEditionTransaction { + edition_info: None, + amount, + fee_receiver: owner_address, + fee_numerator: collection.seller_fee_basis_points.into(), + }, + ) .await?; }, BlockchainEnum::Ethereum => { @@ -569,17 +594,21 @@ impl Mutation { solana .event() - .update_drop(event_key, proto::MetaplexMasterEditionTransaction { - master_edition: Some(proto::MasterEdition { - owner_address, - supply: collection.supply.map(TryInto::try_into).transpose()?, - name: metadata_json_model.name, - symbol: metadata_json_model.symbol, - metadata_uri: metadata_json_model.uri, - seller_fee_basis_points: collection.seller_fee_basis_points.into(), - creators, - }), - }) + .update_drop( + drop_model.drop_type, + event_key, + proto::MetaplexMasterEditionTransaction { + master_edition: Some(proto::MasterEdition { + owner_address, + supply: collection.supply.map(TryInto::try_into).transpose()?, + name: metadata_json_model.name, + symbol: metadata_json_model.symbol, + metadata_uri: metadata_json_model.uri, + seller_fee_basis_points: collection.seller_fee_basis_points.into(), + creators, + }), + }, + ) .await?; }, BlockchainEnum::Polygon => { @@ -595,15 +624,19 @@ impl Mutation { polygon .event() - .update_drop(event_key, proto::UpdateEdtionTransaction { - edition_info: Some(EditionInfo { - description: metadata_json_model.description, - image_uri: metadata_json_model.image, - collection: metadata_json_model.name, - uri: metadata_json_model.uri, - creator, - }), - }) + .update_drop( + drop_model.drop_type, + event_key, + proto::UpdateEdtionTransaction { + edition_info: Some(EditionInfo { + description: metadata_json_model.description, + image_uri: metadata_json_model.image, + collection: metadata_json_model.name, + uri: metadata_json_model.uri, + creator, + }), + }, + ) .await?; }, BlockchainEnum::Ethereum => { @@ -644,7 +677,7 @@ pub struct CreateDropPayload { drop: Drop, } -#[derive(Debug, Clone, Serialize, Deserialize, InputObject)] +#[derive(Debug, Clone, InputObject)] pub struct CreateDropInput { pub project: Uuid, pub price: Option, @@ -655,6 +688,8 @@ pub struct CreateDropInput { pub blockchain: BlockchainEnum, pub creators: Vec, pub metadata_json: MetadataJsonInput, + #[graphql(name = "type")] + pub drop_type: DropType, } impl CreateDropInput { diff --git a/api/src/mutations/transfer.rs b/api/src/mutations/transfer.rs index 98ea103..4d27341 100644 --- a/api/src/mutations/transfer.rs +++ b/api/src/mutations/transfer.rs @@ -64,7 +64,10 @@ impl Mutation { let collection = collection.ok_or(Error::new("collection not found"))?; input.validate_recipient_address(collection.blockchain)?; - let owner_address = collection_mint_model.owner.clone(); + let owner_address = collection_mint_model + .owner + .clone() + .ok_or(Error::new("NFT is not owned by any wallet"))?; CustomerWallets::find_by_address(owner_address.clone()) .one(conn) @@ -102,23 +105,29 @@ impl Mutation { solana .event() - .transfer_asset(event_key, proto::TransferMetaplexAssetTransaction { - recipient_address, - owner_address, - collection_mint_id, - }) + .transfer_asset( + event_key, + proto::TransferMetaplexAssetTransaction { + recipient_address, + owner_address, + collection_mint_id, + }, + ) .await?; }, Blockchain::Polygon => { let polygon = ctx.data::()?; polygon .event() - .transfer_asset(event_key, TransferPolygonAsset { - collection_mint_id, - owner_address, - recipient_address, - amount: 1, - }) + .transfer_asset( + event_key, + TransferPolygonAsset { + collection_mint_id, + owner_address, + recipient_address, + amount: 1, + }, + ) .await?; }, Blockchain::Ethereum => { diff --git a/api/src/objects/collection_mint.rs b/api/src/objects/collection_mint.rs index a7c6b21..a4b79a8 100644 --- a/api/src/objects/collection_mint.rs +++ b/api/src/objects/collection_mint.rs @@ -25,7 +25,7 @@ pub struct CollectionMint { /// On EVM chains it is the concatenation of the contract address and the token id `{contractAddress}:{tokenId}`. pub address: Option, /// The wallet address of the owner of the NFT. - pub owner: String, + pub owner: Option, /// The status of the NFT creation. pub creation_status: CreationStatus, /// The unique ID of the creator of the NFT. diff --git a/api/src/objects/drop.rs b/api/src/objects/drop.rs index 2231872..580c535 100644 --- a/api/src/objects/drop.rs +++ b/api/src/objects/drop.rs @@ -1,4 +1,4 @@ -use async_graphql::{Context, Enum, Object, Result}; +use async_graphql::{Context, Enum, Object, Result, Error}; use hub_core::chrono::Utc; use sea_orm::entity::prelude::*; @@ -121,6 +121,7 @@ impl Drop { (_, _, Some(false), ..) | (_, _, None, _, _, CreationStatus::Created) => { Ok(DropStatus::Minting) }, + (_, _, _, _, _, CreationStatus::Queued) => Err(Error::new("Invalid Drop Status")), } } diff --git a/api/src/objects/holder.rs b/api/src/objects/holder.rs index e33aed4..c417a7d 100644 --- a/api/src/objects/holder.rs +++ b/api/src/objects/holder.rs @@ -31,7 +31,7 @@ impl Holder { .unwrap_or_default(); Ok(mints.into_iter().fold(Vec::new(), |mut acc, mint| { - if mint.owner == self.address { + if mint.owner == Some(self.address.clone()) { acc.push(mint.id); } diff --git a/migration/src/lib.rs b/migration/src/lib.rs index 5ec6e56..48935ec 100644 --- a/migration/src/lib.rs +++ b/migration/src/lib.rs @@ -53,6 +53,9 @@ mod m20230725_144506_drop_solana_collections_table; mod m20230807_090847_create_histories_table; mod m20230818_163948_downcase_polygon_addresses; mod m20230821_131630_create_switch_collection_histories_table; +mod m20230905_100852_add_type_to_drop; +mod m20230910_204731_add_queued_variant_to_mints_status; +mod m20230910_212742_make_owner_address_optional_for_mint; pub struct Migrator; @@ -113,6 +116,9 @@ impl MigratorTrait for Migrator { Box::new(m20230807_090847_create_histories_table::Migration), Box::new(m20230818_163948_downcase_polygon_addresses::Migration), Box::new(m20230821_131630_create_switch_collection_histories_table::Migration), + Box::new(m20230905_100852_add_type_to_drop::Migration), + Box::new(m20230910_204731_add_queued_variant_to_mints_status::Migration), + Box::new(m20230910_212742_make_owner_address_optional_for_mint::Migration), ] } } diff --git a/migration/src/m20230905_100852_add_type_to_drop.rs b/migration/src/m20230905_100852_add_type_to_drop.rs new file mode 100644 index 0000000..7db9fdb --- /dev/null +++ b/migration/src/m20230905_100852_add_type_to_drop.rs @@ -0,0 +1,66 @@ +use sea_orm_migration::{prelude::*, sea_query::extension::postgres::Type}; + +#[derive(DeriveMigrationName)] +pub struct Migration; + +#[async_trait::async_trait] +impl MigrationTrait for Migration { + async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { + manager + .create_type( + Type::create() + .as_enum(DropType::Type) + .values([DropType::Edition, DropType::Open]) + .to_owned(), + ) + .await?; + + manager + .alter_table( + Table::alter() + .table(Drops::Table) + .add_column_if_not_exists( + ColumnDef::new(Drops::DropType) + .custom(DropType::Type) + .default("edition") + .not_null(), + ) + .to_owned(), + ) + .await + } + + async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> { + manager + .alter_table( + Table::alter() + .table(Drops::Table) + .drop_column(Drops::DropType) + .to_owned(), + ) + .await + } +} + +#[derive(Iden)] +enum Drops { + Table, + DropType, +} + +pub enum DropType { + Type, + Edition, + Open, +} + +impl Iden for DropType { + fn unquoted(&self, s: &mut dyn std::fmt::Write) { + write!(s, "{}", match self { + Self::Type => "drop_type", + Self::Edition => "edition", + Self::Open => "open", + }) + .unwrap(); + } +} diff --git a/migration/src/m20230910_204731_add_queued_variant_to_mints_status.rs b/migration/src/m20230910_204731_add_queued_variant_to_mints_status.rs new file mode 100644 index 0000000..e2b4095 --- /dev/null +++ b/migration/src/m20230910_204731_add_queued_variant_to_mints_status.rs @@ -0,0 +1,24 @@ +use sea_orm_migration::{prelude::*, sea_query::extension::postgres::Type}; + +use crate::m20230214_212301_create_collections_table::CreationStatus; + +#[derive(DeriveMigrationName)] +pub struct Migration; + +#[async_trait::async_trait] +impl MigrationTrait for Migration { + async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { + manager + .alter_type( + Type::alter() + .name(CreationStatus::Type) + .add_value(Alias::new("queued")) + .to_owned(), + ) + .await + } + + async fn down(&self, _manager: &SchemaManager) -> Result<(), DbErr> { + Ok(()) + } +} diff --git a/migration/src/m20230910_212742_make_owner_address_optional_for_mint.rs b/migration/src/m20230910_212742_make_owner_address_optional_for_mint.rs new file mode 100644 index 0000000..093455c --- /dev/null +++ b/migration/src/m20230910_212742_make_owner_address_optional_for_mint.rs @@ -0,0 +1,35 @@ +use sea_orm_migration::prelude::*; + +#[derive(DeriveMigrationName)] +pub struct Migration; + +#[async_trait::async_trait] +impl MigrationTrait for Migration { + async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { + manager + .alter_table( + Table::alter() + .table(CollectionMints::Table) + .modify_column(ColumnDef::new(CollectionMints::OwnerAddress).text().null()) + .to_owned(), + ) + .await + } + + async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> { + manager + .alter_table( + Table::alter() + .table(CollectionMints::Table) + .modify_column(ColumnDef::new(CollectionMints::OwnerAddress).text().not_null()) + .to_owned(), + ) + .await + } +} + +#[derive(Iden)] +enum CollectionMints { + Table, + OwnerAddress, +} From dd4eecc3f5e01673c308f84ae9b3764c0abf8ae9 Mon Sep 17 00:00:00 2001 From: imabdulbasit Date: Mon, 11 Sep 2023 19:13:39 +0500 Subject: [PATCH 02/20] Mint open drop --- api/src/mutations/mint.rs | 456 +++++++++++++++++++++++++++++++++----- 1 file changed, 395 insertions(+), 61 deletions(-) diff --git a/api/src/mutations/mint.rs b/api/src/mutations/mint.rs index 263bd3a..c5b7383 100644 --- a/api/src/mutations/mint.rs +++ b/api/src/mutations/mint.rs @@ -6,16 +6,20 @@ use hub_core::{ credits::{CreditsClient, TransactionId}, producer::Producer, }; -use sea_orm::{prelude::*, JoinType, QuerySelect, Set, TransactionTrait}; +use sea_orm::{prelude::*, JoinType, Order, QueryOrder, QuerySelect, Set, TransactionTrait}; use super::collection::{ fetch_owner, validate_creators, validate_json, validate_solana_creator_verification, }; use crate::{ - blockchains::{polygon::Polygon, solana::Solana, CollectionEvent, DropEvent}, + blockchains::{ + polygon::Polygon, + solana::{MintDropTransaction, Solana}, + CollectionEvent, DropEvent, + }, entities::{ - collection_mints, collections, drops, mint_creators, mint_histories, - prelude::{CollectionMints, Collections, Drops}, + collection_creators, collection_mints, collections, drops, mint_creators, mint_histories, + prelude::{CollectionCreators, CollectionMints, Collections, Drops}, project_wallets, sea_orm_active_enums::{Blockchain as BlockchainEnum, CreationStatus}, update_histories, @@ -114,7 +118,7 @@ impl Mutation { // insert a collection mint record into database let collection_mint_active_model = collection_mints::ActiveModel { collection_id: Set(collection.id), - owner: Set(input.recipient.clone()), + owner: Set(Some(input.recipient.clone())), creation_status: Set(CreationStatus::Pending), seller_fee_basis_points: Set(collection.seller_fee_basis_points), created_by: Set(user_id), @@ -139,22 +143,28 @@ impl Mutation { solana .event() - .mint_drop(event_key, proto::MintMetaplexEditionTransaction { - recipient_address: input.recipient.to_string(), - owner_address: owner_address.to_string(), - edition, - collection_id: collection.id.to_string(), - }) + .mint_drop( + event_key, + MintDropTransaction::Edition(proto::MintMetaplexEditionTransaction { + recipient_address: input.recipient.to_string(), + owner_address: owner_address.to_string(), + edition, + collection_id: collection.id.to_string(), + }), + ) .await?; }, BlockchainEnum::Polygon => { polygon .event() - .mint_drop(event_key, proto::MintEditionTransaction { - receiver: input.recipient.to_string(), - amount: 1, - collection_id: collection.id.to_string(), - }) + .mint_drop( + event_key, + proto::MintEditionTransaction { + receiver: input.recipient.to_string(), + amount: 1, + collection_id: collection.id.to_string(), + }, + ) .await?; }, BlockchainEnum::Ethereum => { @@ -253,7 +263,11 @@ impl Mutation { let drop_model = drop.ok_or(Error::new("drop not found"))?; - let recipient = collection_mint_model.owner.clone(); + let recipient = collection_mint_model + .owner + .clone() + .ok_or(Error::new("collection mint does not have an owner"))?; + let edition = collection_mint_model.edition; let project_id = drop_model.project_id; @@ -294,22 +308,28 @@ impl Mutation { BlockchainEnum::Solana => { solana .event() - .retry_mint_drop(event_key, proto::MintMetaplexEditionTransaction { - recipient_address: recipient.to_string(), - owner_address: owner_address.to_string(), - edition, - collection_id: collection.id.to_string(), - }) + .retry_mint_drop( + event_key, + MintDropTransaction::Edition(proto::MintMetaplexEditionTransaction { + recipient_address: recipient.to_string(), + owner_address: owner_address.to_string(), + edition, + collection_id: collection.id.to_string(), + }), + ) .await?; }, BlockchainEnum::Polygon => { polygon .event() - .retry_mint_drop(event_key, proto::MintEditionTransaction { - receiver: recipient.to_string(), - amount: 1, - collection_id: collection.id.to_string(), - }) + .retry_mint_drop( + event_key, + proto::MintEditionTransaction { + receiver: recipient.to_string(), + amount: 1, + collection_id: collection.id.to_string(), + }, + ) .await?; }, BlockchainEnum::Ethereum => { @@ -398,7 +418,7 @@ impl Mutation { // insert a collection mint record into database let collection_mint_active_model = collection_mints::ActiveModel { collection_id: Set(collection.id), - owner: Set(input.recipient.clone()), + owner: Set(Some(input.recipient.clone())), creation_status: Set(CreationStatus::Pending), seller_fee_basis_points: Set(collection.seller_fee_basis_points), created_by: Set(user_id), @@ -436,22 +456,25 @@ impl Mutation { BlockchainEnum::Solana => { solana .event() - .mint_to_collection(event_key, proto::MintMetaplexMetadataTransaction { - metadata: Some(MetaplexMetadata { - owner_address, - name: metadata_json.name, - symbol: metadata_json.symbol, - metadata_uri: metadata_json.uri, - seller_fee_basis_points: seller_fee_basis_points.into(), - creators: creators - .into_iter() - .map(TryFrom::try_from) - .collect::>()?, - }), - recipient_address: input.recipient.to_string(), - compressed, - collection_id: collection.id.to_string(), - }) + .mint_to_collection( + event_key, + proto::MintMetaplexMetadataTransaction { + metadata: Some(MetaplexMetadata { + owner_address, + name: metadata_json.name, + symbol: metadata_json.symbol, + metadata_uri: metadata_json.uri, + seller_fee_basis_points: seller_fee_basis_points.into(), + creators: creators + .into_iter() + .map(TryFrom::try_from) + .collect::>()?, + }), + recipient_address: input.recipient.to_string(), + compressed, + collection_id: collection.id.to_string(), + }, + ) .await?; }, BlockchainEnum::Ethereum | BlockchainEnum::Polygon => { @@ -764,7 +787,11 @@ impl Mutation { let collection = collection.ok_or(Error::new("collection not found"))?; - let recipient = collection_mint_model.owner.clone(); + let recipient = collection_mint_model + .owner + .clone() + .ok_or(Error::new("collection mint does not have an owner"))?; + let project_id = collection.project_id; let blockchain = collection.blockchain; @@ -798,21 +825,24 @@ impl Mutation { BlockchainEnum::Solana => { solana .event() - .retry_mint_to_collection(event_key, proto::MintMetaplexMetadataTransaction { - metadata: Some(MetaplexMetadata { - owner_address, - name: metadata_json.name, - symbol: metadata_json.symbol, - metadata_uri: uri.ok_or(Error::new("metadata uri not found"))?, - seller_fee_basis_points: collection_mint_model - .seller_fee_basis_points - .into(), - creators: creators.into_iter().map(Into::into).collect(), - }), - recipient_address: recipient.to_string(), - compressed: collection_mint_model.compressed, - collection_id: collection_mint_model.collection_id.to_string(), - }) + .retry_mint_to_collection( + event_key, + proto::MintMetaplexMetadataTransaction { + metadata: Some(MetaplexMetadata { + owner_address, + name: metadata_json.name, + symbol: metadata_json.symbol, + metadata_uri: uri.ok_or(Error::new("metadata uri not found"))?, + seller_fee_basis_points: collection_mint_model + .seller_fee_basis_points + .into(), + creators: creators.into_iter().map(Into::into).collect(), + }), + recipient_address: recipient.to_string(), + compressed: collection_mint_model.compressed, + collection_id: collection_mint_model.collection_id.to_string(), + }, + ) .await?; }, BlockchainEnum::Ethereum | BlockchainEnum::Polygon => { @@ -824,6 +854,280 @@ impl Mutation { collection_mint: collection_mint_model.into(), }) } + + async fn queue_mint_to_drop( + &self, + ctx: &Context<'_>, + input: QueueMintToDropInput, + ) -> Result { + let AppContext { db, user_id, .. } = ctx.data::()?; + + let conn = db.get(); + let nft_storage = ctx.data::()?; + + let UserID(id) = user_id; + let user_id = id.ok_or(Error::new("X-USER-ID header not found"))?; + + let (drop, collection) = drops::Entity::find_by_id(input.drop) + .find_also_related(Collections) + .one(conn) + .await? + .ok_or(Error::new("drop not found"))?; + + let collection_model = collection.ok_or(Error::new("collection not found"))?; + + let mint = collection_mints::ActiveModel { + collection_id: Set(drop.collection_id), + owner: Set(None), + creation_status: Set(CreationStatus::Queued), + seller_fee_basis_points: Set(collection_model.seller_fee_basis_points), + created_by: Set(user_id), + compressed: Set(false), + ..Default::default() + }; + + let mint_model = mint.insert(conn).await?; + + MetadataJson::new(input.metadata_json) + .upload(nft_storage) + .await? + .save(mint_model.id, db) + .await?; + + let creators = CollectionCreators::find() + .filter(collection_creators::Column::CollectionId.eq(collection_model.id)) + .all(conn) + .await?; + + let mint_creators: Vec<_> = creators + .iter() + .map(|creator| mint_creators::ActiveModel { + collection_mint_id: Set(mint_model.id), + address: Set(creator.address.clone()), + verified: Set(creator.verified), + share: Set(creator.share), + }) + .collect(); + + mint_creators::Entity::insert_many(mint_creators) + .exec(conn) + .await?; + + Ok(QueueMintToDropPayload { + collection_mint: mint_model.into(), + }) + } + + async fn mint_queued( + &self, + ctx: &Context<'_>, + input: MintQueuedInput, + ) -> Result { + let AppContext { + db, + user_id, + organization_id, + balance, + .. + } = ctx.data::()?; + let credits = ctx.data::>()?; + let conn = db.get(); + let solana = ctx.data::()?; + + let UserID(id) = user_id; + let OrganizationId(org) = organization_id; + + let user_id = id.ok_or(Error::new("X-USER-ID header not found"))?; + let org_id = org.ok_or(Error::new("X-ORGANIZATION-ID header not found"))?; + let balance = balance + .0 + .ok_or(Error::new("X-CREDIT-BALANCE header not found"))?; + + let (mint, collection) = collection_mints::Entity::find_by_id_with_collection(input.mint) + .one(conn) + .await? + .ok_or(Error::new("collection mint not found"))?; + + if mint.creation_status != CreationStatus::Queued { + return Err(Error::new("mint is not queued")); + } + + let collection = collection.ok_or(Error::new("collection not found"))?; + + let project_id = collection.project_id; + let blockchain = collection.blockchain; + + let owner_address = fetch_owner(conn, project_id, blockchain).await?; + + let MetadataJson { + metadata_json, uri, .. + } = MetadataJson::fetch(mint.id, db).await?; + + let event_key = NftEventKey { + id: mint.id.to_string(), + user_id: user_id.to_string(), + project_id: project_id.to_string(), + }; + + let creators = mint_creators::Entity::find_by_collection_mint_id(mint.id) + .all(conn) + .await?; + + let TransactionId(_) = credits + .submit_pending_deduction( + org_id, + user_id, + Actions::Mint, + collection.blockchain.into(), + balance, + ) + .await?; + + match collection.blockchain { + BlockchainEnum::Solana => { + solana + .event() + .mint_drop( + event_key, + MintDropTransaction::Open(proto::MintMetaplexMetadataTransaction { + metadata: Some(MetaplexMetadata { + owner_address, + name: metadata_json.name, + symbol: metadata_json.symbol, + metadata_uri: uri.unwrap(), + seller_fee_basis_points: mint.seller_fee_basis_points.into(), + creators: creators.into_iter().map(Into::into).collect(), + }), + recipient_address: input.recipient.to_string(), + compressed: input.compressed, + collection_id: collection.id.to_string(), + }), + ) + .await?; + }, + BlockchainEnum::Ethereum | BlockchainEnum::Polygon => { + return Err(Error::new("blockchain not supported as this time")); + }, + }; + + let mut mint_am: collection_mints::ActiveModel = mint.into(); + mint_am.creation_status = Set(CreationStatus::Pending); + let mint = mint_am.update(conn).await?; + + Ok(MintQueuedPayload { + collection_mint: mint.into(), + }) + } + + async fn mint_random_queued( + &self, + ctx: &Context<'_>, + input: MintRandomQueuedInput, + ) -> Result { + let AppContext { + db, + user_id, + organization_id, + balance, + .. + } = ctx.data::()?; + let credits = ctx.data::>()?; + let conn = db.get(); + let solana = ctx.data::()?; + + let UserID(id) = user_id; + let OrganizationId(org) = organization_id; + + let user_id = id.ok_or(Error::new("X-USER-ID header not found"))?; + let org_id = org.ok_or(Error::new("X-ORGANIZATION-ID header not found"))?; + let balance = balance + .0 + .ok_or(Error::new("X-CREDIT-BALANCE header not found"))?; + + let drop = drops::Entity::find_by_id(input.drop) + .one(conn) + .await? + .ok_or(Error::new("drop not found"))?; + + let (mint, collection) = CollectionMints::find() + .join( + JoinType::InnerJoin, + collection_mints::Relation::Collections.def(), + ) + .select_also(collections::Entity) + .filter(collection_mints::Column::CollectionId.eq(drop.collection_id)) + .filter(collection_mints::Column::CreationStatus.eq(CreationStatus::Queued)) + .order_by(sea_orm::sea_query::Func::random(), Order::Asc) + .one(conn) + .await? + .ok_or(Error::new("No Queued mint found for the drop"))?; + + let collection = collection.ok_or(Error::new("collection not found"))?; + + let project_id = collection.project_id; + let blockchain = collection.blockchain; + + let owner_address = fetch_owner(conn, project_id, blockchain).await?; + + let MetadataJson { + metadata_json, uri, .. + } = MetadataJson::fetch(mint.id, db).await?; + + let event_key = NftEventKey { + id: mint.id.to_string(), + user_id: user_id.to_string(), + project_id: project_id.to_string(), + }; + + let creators = mint_creators::Entity::find_by_collection_mint_id(mint.id) + .all(conn) + .await?; + + let TransactionId(_) = credits + .submit_pending_deduction( + org_id, + user_id, + Actions::Mint, + collection.blockchain.into(), + balance, + ) + .await?; + + match collection.blockchain { + BlockchainEnum::Solana => { + solana + .event() + .mint_drop( + event_key, + MintDropTransaction::Open(proto::MintMetaplexMetadataTransaction { + metadata: Some(MetaplexMetadata { + owner_address, + name: metadata_json.name, + symbol: metadata_json.symbol, + metadata_uri: uri.unwrap(), + seller_fee_basis_points: mint.seller_fee_basis_points.into(), + creators: creators.into_iter().map(Into::into).collect(), + }), + recipient_address: input.recipient.to_string(), + compressed: input.compressed, + collection_id: collection.id.to_string(), + }), + ) + .await?; + }, + BlockchainEnum::Ethereum | BlockchainEnum::Polygon => { + return Err(Error::new("blockchain not supported as this time")); + }, + }; + + let mut mint_am: collection_mints::ActiveModel = mint.into(); + mint_am.creation_status = Set(CreationStatus::Pending); + let mint = mint_am.update(conn).await?; + + Ok(MintQueuedPayload { + collection_mint: mint.into(), + }) + } } fn validate_compress(blockchain: BlockchainEnum, compressed: bool) -> Result<(), Error> { @@ -973,3 +1277,33 @@ pub struct RetryUpdateMintInput { pub struct RetryUpdateMintPayload { status: CreationStatus, } + +#[derive(Debug, Clone, InputObject)] +pub struct QueueMintToDropInput { + drop: Uuid, + metadata_json: MetadataJsonInput, +} + +#[derive(Debug, Clone, SimpleObject)] +pub struct QueueMintToDropPayload { + collection_mint: CollectionMint, +} + +#[derive(Debug, Clone, InputObject)] +pub struct MintQueuedInput { + mint: Uuid, + recipient: String, + compressed: bool, +} + +#[derive(Debug, Clone, SimpleObject)] +pub struct MintQueuedPayload { + collection_mint: CollectionMint, +} + +#[derive(Debug, Clone, InputObject)] +pub struct MintRandomQueuedInput { + drop: Uuid, + recipient: String, + compressed: bool, +} From adfd25e3abe976e474f969a809d2d19ab8801f06 Mon Sep 17 00:00:00 2001 From: imabdulbasit Date: Mon, 11 Sep 2023 19:28:39 +0500 Subject: [PATCH 03/20] fmt --- api/proto.lock | 4 +- api/proto.toml | 2 +- api/src/blockchains/polygon.rs | 2 +- api/src/blockchains/solana.rs | 20 ++-- api/src/mutations/drop.rs | 18 ++-- api/src/mutations/mint.rs | 94 ++++++++----------- api/src/mutations/transfer.rs | 28 +++--- api/src/objects/drop.rs | 2 +- ...42_make_owner_address_optional_for_mint.rs | 8 +- 9 files changed, 77 insertions(+), 101 deletions(-) diff --git a/api/proto.lock b/api/proto.lock index 0c75d46..4c30c53 100644 --- a/api/proto.lock +++ b/api/proto.lock @@ -5,8 +5,8 @@ sha512 = "d75800df0d4744c6b0f4d9a9952d3bfd0bb6b24a8babd19104cc11b54a525f85551b3c [[schemas]] subject = "nfts" -version = 2 -sha512 = "db8fa9f4b2874ab79305997c3b255a9b9c1b04d291c66f1cb97f332b32758055c01e6ba0e7a4089255c664324c51fc4fe25a9d138698b7a999b1f4d2b5503a48" +version = 3 +sha512 = "b3b2136bd6c7a136d317da84395661de5fc056e8270510575a3281d78884d99a0d89f444754ed02cb18ad26dcc7cd65300c1df73b9d74d2edc6bcc8d552465d0" [[schemas]] subject = "organization" diff --git a/api/proto.toml b/api/proto.toml index 030a40b..77c8551 100644 --- a/api/proto.toml +++ b/api/proto.toml @@ -3,7 +3,7 @@ endpoint = "http://localhost:8081" [schemas] organization = 1 -nfts = 2 +nfts = 3 customer = 1 treasury = 1 solana_nfts = 1 diff --git a/api/src/blockchains/polygon.rs b/api/src/blockchains/polygon.rs index d1c9146..8696a33 100644 --- a/api/src/blockchains/polygon.rs +++ b/api/src/blockchains/polygon.rs @@ -28,7 +28,7 @@ impl Polygon { pub fn event( &self, ) -> impl DropEvent - + TransferEvent { + + TransferEvent { self.clone() } } diff --git a/api/src/blockchains/solana.rs b/api/src/blockchains/solana.rs index 3fd24ac..f99ad76 100644 --- a/api/src/blockchains/solana.rs +++ b/api/src/blockchains/solana.rs @@ -53,8 +53,12 @@ impl Solana { } #[async_trait::async_trait] -impl DropEvent - for Solana +impl + DropEvent< + MetaplexMasterEditionTransaction, + MintDropTransaction, + MetaplexMasterEditionTransaction, + > for Solana { async fn create_drop( &self, @@ -110,11 +114,7 @@ impl DropEvent Result<()> { + async fn mint_drop(&self, key: NftEventKey, payload: MintDropTransaction) -> Result<()> { let event = match payload { MintDropTransaction::Edition(p) => Some(SolanaMintEditionDrop(p)), MintDropTransaction::Open(p) => Some(SolanaMintOpenDrop(p)), @@ -127,11 +127,7 @@ impl DropEvent Result<()> { + async fn retry_mint_drop(&self, key: NftEventKey, payload: MintDropTransaction) -> Result<()> { let event = match payload { MintDropTransaction::Edition(tx) => Some(SolanaRetryMintEditionDrop(tx)), MintDropTransaction::Open(tx) => Some(SolanaRetryMintOpenDrop(tx)), diff --git a/api/src/mutations/drop.rs b/api/src/mutations/drop.rs index 670bd02..dc42084 100644 --- a/api/src/mutations/drop.rs +++ b/api/src/mutations/drop.rs @@ -132,8 +132,6 @@ impl Mutation { project_id: input.project.to_string(), }; - - let payload = proto::MetaplexMasterEditionTransaction { master_edition: Some(proto::MasterEdition { owner_address: owner_address.clone(), @@ -317,16 +315,12 @@ impl Mutation { polygon .event() - .retry_create_drop( - drop.drop_type, - event_key, - proto::CreateEditionTransaction { - edition_info: None, - amount, - fee_receiver: owner_address, - fee_numerator: collection.seller_fee_basis_points.into(), - }, - ) + .retry_create_drop(drop.drop_type, event_key, proto::CreateEditionTransaction { + edition_info: None, + amount, + fee_receiver: owner_address, + fee_numerator: collection.seller_fee_basis_points.into(), + }) .await?; }, BlockchainEnum::Ethereum => { diff --git a/api/src/mutations/mint.rs b/api/src/mutations/mint.rs index c5b7383..b1adbc0 100644 --- a/api/src/mutations/mint.rs +++ b/api/src/mutations/mint.rs @@ -157,14 +157,11 @@ impl Mutation { BlockchainEnum::Polygon => { polygon .event() - .mint_drop( - event_key, - proto::MintEditionTransaction { - receiver: input.recipient.to_string(), - amount: 1, - collection_id: collection.id.to_string(), - }, - ) + .mint_drop(event_key, proto::MintEditionTransaction { + receiver: input.recipient.to_string(), + amount: 1, + collection_id: collection.id.to_string(), + }) .await?; }, BlockchainEnum::Ethereum => { @@ -322,14 +319,11 @@ impl Mutation { BlockchainEnum::Polygon => { polygon .event() - .retry_mint_drop( - event_key, - proto::MintEditionTransaction { - receiver: recipient.to_string(), - amount: 1, - collection_id: collection.id.to_string(), - }, - ) + .retry_mint_drop(event_key, proto::MintEditionTransaction { + receiver: recipient.to_string(), + amount: 1, + collection_id: collection.id.to_string(), + }) .await?; }, BlockchainEnum::Ethereum => { @@ -456,25 +450,22 @@ impl Mutation { BlockchainEnum::Solana => { solana .event() - .mint_to_collection( - event_key, - proto::MintMetaplexMetadataTransaction { - metadata: Some(MetaplexMetadata { - owner_address, - name: metadata_json.name, - symbol: metadata_json.symbol, - metadata_uri: metadata_json.uri, - seller_fee_basis_points: seller_fee_basis_points.into(), - creators: creators - .into_iter() - .map(TryFrom::try_from) - .collect::>()?, - }), - recipient_address: input.recipient.to_string(), - compressed, - collection_id: collection.id.to_string(), - }, - ) + .mint_to_collection(event_key, proto::MintMetaplexMetadataTransaction { + metadata: Some(MetaplexMetadata { + owner_address, + name: metadata_json.name, + symbol: metadata_json.symbol, + metadata_uri: metadata_json.uri, + seller_fee_basis_points: seller_fee_basis_points.into(), + creators: creators + .into_iter() + .map(TryFrom::try_from) + .collect::>()?, + }), + recipient_address: input.recipient.to_string(), + compressed, + collection_id: collection.id.to_string(), + }) .await?; }, BlockchainEnum::Ethereum | BlockchainEnum::Polygon => { @@ -825,24 +816,21 @@ impl Mutation { BlockchainEnum::Solana => { solana .event() - .retry_mint_to_collection( - event_key, - proto::MintMetaplexMetadataTransaction { - metadata: Some(MetaplexMetadata { - owner_address, - name: metadata_json.name, - symbol: metadata_json.symbol, - metadata_uri: uri.ok_or(Error::new("metadata uri not found"))?, - seller_fee_basis_points: collection_mint_model - .seller_fee_basis_points - .into(), - creators: creators.into_iter().map(Into::into).collect(), - }), - recipient_address: recipient.to_string(), - compressed: collection_mint_model.compressed, - collection_id: collection_mint_model.collection_id.to_string(), - }, - ) + .retry_mint_to_collection(event_key, proto::MintMetaplexMetadataTransaction { + metadata: Some(MetaplexMetadata { + owner_address, + name: metadata_json.name, + symbol: metadata_json.symbol, + metadata_uri: uri.ok_or(Error::new("metadata uri not found"))?, + seller_fee_basis_points: collection_mint_model + .seller_fee_basis_points + .into(), + creators: creators.into_iter().map(Into::into).collect(), + }), + recipient_address: recipient.to_string(), + compressed: collection_mint_model.compressed, + collection_id: collection_mint_model.collection_id.to_string(), + }) .await?; }, BlockchainEnum::Ethereum | BlockchainEnum::Polygon => { diff --git a/api/src/mutations/transfer.rs b/api/src/mutations/transfer.rs index 4d27341..5da8778 100644 --- a/api/src/mutations/transfer.rs +++ b/api/src/mutations/transfer.rs @@ -105,29 +105,23 @@ impl Mutation { solana .event() - .transfer_asset( - event_key, - proto::TransferMetaplexAssetTransaction { - recipient_address, - owner_address, - collection_mint_id, - }, - ) + .transfer_asset(event_key, proto::TransferMetaplexAssetTransaction { + recipient_address, + owner_address, + collection_mint_id, + }) .await?; }, Blockchain::Polygon => { let polygon = ctx.data::()?; polygon .event() - .transfer_asset( - event_key, - TransferPolygonAsset { - collection_mint_id, - owner_address, - recipient_address, - amount: 1, - }, - ) + .transfer_asset(event_key, TransferPolygonAsset { + collection_mint_id, + owner_address, + recipient_address, + amount: 1, + }) .await?; }, Blockchain::Ethereum => { diff --git a/api/src/objects/drop.rs b/api/src/objects/drop.rs index 580c535..3286ef1 100644 --- a/api/src/objects/drop.rs +++ b/api/src/objects/drop.rs @@ -1,4 +1,4 @@ -use async_graphql::{Context, Enum, Object, Result, Error}; +use async_graphql::{Context, Enum, Error, Object, Result}; use hub_core::chrono::Utc; use sea_orm::entity::prelude::*; diff --git a/migration/src/m20230910_212742_make_owner_address_optional_for_mint.rs b/migration/src/m20230910_212742_make_owner_address_optional_for_mint.rs index 093455c..5c91d27 100644 --- a/migration/src/m20230910_212742_make_owner_address_optional_for_mint.rs +++ b/migration/src/m20230910_212742_make_owner_address_optional_for_mint.rs @@ -21,13 +21,17 @@ impl MigrationTrait for Migration { .alter_table( Table::alter() .table(CollectionMints::Table) - .modify_column(ColumnDef::new(CollectionMints::OwnerAddress).text().not_null()) + .modify_column( + ColumnDef::new(CollectionMints::OwnerAddress) + .text() + .not_null(), + ) .to_owned(), ) .await } } - + #[derive(Iden)] enum CollectionMints { Table, From ae1a301a52ae939a554cab698781328f8a6cd81a Mon Sep 17 00:00:00 2001 From: imabdulbasit Date: Mon, 11 Sep 2023 19:54:36 +0500 Subject: [PATCH 04/20] make mints compressed column nullable --- api/src/entities/collection_mints.rs | 3 +- api/src/events.rs | 2 +- api/src/mutations/collection.rs | 2 +- api/src/mutations/mint.rs | 11 ++++-- api/src/objects/collection_mint.rs | 2 +- migration/src/lib.rs | 2 + ..._144938_make_compressed_column_optional.rs | 39 +++++++++++++++++++ 7 files changed, 53 insertions(+), 8 deletions(-) create mode 100644 migration/src/m20230911_144938_make_compressed_column_optional.rs diff --git a/api/src/entities/collection_mints.rs b/api/src/entities/collection_mints.rs index 730f98d..27dd451 100644 --- a/api/src/entities/collection_mints.rs +++ b/api/src/entities/collection_mints.rs @@ -23,7 +23,8 @@ pub struct Model { pub edition: i64, pub seller_fee_basis_points: i16, pub credits_deduction_id: Option, - pub compressed: bool, + #[sea_orm(nullable)] + pub compressed: Option, } #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] diff --git a/api/src/events.rs b/api/src/events.rs index 40e5eac..9132466 100644 --- a/api/src/events.rs +++ b/api/src/events.rs @@ -402,7 +402,7 @@ impl Processor { .try_into() .map_err(ProcessorErrorKind::InvalidSellerFee)?), credits_deduction_id: Set(None), - compressed: Set(compressed), + compressed: Set(Some(compressed)), }; let mint_model = mint_am.insert(self.db.get()).await?; diff --git a/api/src/mutations/collection.rs b/api/src/mutations/collection.rs index f7ad8cb..e1ce85d 100644 --- a/api/src/mutations/collection.rs +++ b/api/src/mutations/collection.rs @@ -521,7 +521,7 @@ impl Mutation { return Err(Error::new("New collection must be Metaplex Certified")); } - if mint.compressed == true { + if let Some(true) = mint.compressed { return Err(Error::new( "Switching collection is only supported for uncompressed mint", )); diff --git a/api/src/mutations/mint.rs b/api/src/mutations/mint.rs index b1adbc0..5186e6e 100644 --- a/api/src/mutations/mint.rs +++ b/api/src/mutations/mint.rs @@ -416,7 +416,7 @@ impl Mutation { creation_status: Set(CreationStatus::Pending), seller_fee_basis_points: Set(collection.seller_fee_basis_points), created_by: Set(user_id), - compressed: Set(compressed), + compressed: Set(Some(compressed)), credits_deduction_id: Set(Some(credits_deduction_id)), ..Default::default() }; @@ -556,7 +556,7 @@ impl Mutation { return Err(Error::new("Mint is an edition and cannot be updated")); } - if mint.compressed { + if let Some(true) = mint.compressed { return Err(Error::new("Mint is compressed and cannot be updated")); } @@ -785,6 +785,9 @@ impl Mutation { let project_id = collection.project_id; let blockchain = collection.blockchain; + let compressed = collection_mint_model.compressed.ok_or(Error::new( + "collection mint does not have a compressed value", + ))?; let owner_address = fetch_owner(conn, project_id, blockchain).await?; @@ -828,7 +831,7 @@ impl Mutation { creators: creators.into_iter().map(Into::into).collect(), }), recipient_address: recipient.to_string(), - compressed: collection_mint_model.compressed, + compressed, collection_id: collection_mint_model.collection_id.to_string(), }) .await?; @@ -870,7 +873,7 @@ impl Mutation { creation_status: Set(CreationStatus::Queued), seller_fee_basis_points: Set(collection_model.seller_fee_basis_points), created_by: Set(user_id), - compressed: Set(false), + compressed: Set(None), ..Default::default() }; diff --git a/api/src/objects/collection_mint.rs b/api/src/objects/collection_mint.rs index a4b79a8..8893cd6 100644 --- a/api/src/objects/collection_mint.rs +++ b/api/src/objects/collection_mint.rs @@ -41,7 +41,7 @@ pub struct CollectionMint { /// credits deduction id pub credits_deduction_id: Option, /// Indicates if the NFT is compressed. Compression is only supported on Solana. - pub compressed: bool, + pub compressed: Option, } #[ComplexObject] diff --git a/migration/src/lib.rs b/migration/src/lib.rs index 48935ec..f227465 100644 --- a/migration/src/lib.rs +++ b/migration/src/lib.rs @@ -56,6 +56,7 @@ mod m20230821_131630_create_switch_collection_histories_table; mod m20230905_100852_add_type_to_drop; mod m20230910_204731_add_queued_variant_to_mints_status; mod m20230910_212742_make_owner_address_optional_for_mint; +mod m20230911_144938_make_compressed_column_optional; pub struct Migrator; @@ -119,6 +120,7 @@ impl MigratorTrait for Migrator { Box::new(m20230905_100852_add_type_to_drop::Migration), Box::new(m20230910_204731_add_queued_variant_to_mints_status::Migration), Box::new(m20230910_212742_make_owner_address_optional_for_mint::Migration), + Box::new(m20230911_144938_make_compressed_column_optional::Migration), ] } } diff --git a/migration/src/m20230911_144938_make_compressed_column_optional.rs b/migration/src/m20230911_144938_make_compressed_column_optional.rs new file mode 100644 index 0000000..536e90b --- /dev/null +++ b/migration/src/m20230911_144938_make_compressed_column_optional.rs @@ -0,0 +1,39 @@ +use sea_orm_migration::prelude::*; + +#[derive(DeriveMigrationName)] +pub struct Migration; + +#[async_trait::async_trait] +impl MigrationTrait for Migration { + async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { + manager + .alter_table( + Table::alter() + .table(CollectionMints::Table) + .modify_column(ColumnDef::new(CollectionMints::Compressed).text().null()) + .to_owned(), + ) + .await + } + + async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> { + manager + .alter_table( + Table::alter() + .table(CollectionMints::Table) + .modify_column( + ColumnDef::new(CollectionMints::Compressed) + .text() + .not_null(), + ) + .to_owned(), + ) + .await + } +} + +#[derive(Iden)] +enum CollectionMints { + Table, + Compressed, +} From f98fd9d94287dcac7bf51159d2823b8eddb729b3 Mon Sep 17 00:00:00 2001 From: imabdulbasit Date: Tue, 12 Sep 2023 17:48:01 +0500 Subject: [PATCH 05/20] Process successful transaction events to update drop status --- api/proto.lock | 4 +- api/proto.toml | 2 +- api/src/blockchains/solana.rs | 79 ------------------- api/src/events.rs | 21 +++++ api/src/mutations/collection.rs | 2 +- api/src/mutations/drop.rs | 10 ++- api/src/mutations/mint.rs | 22 +++++- ...42_make_owner_address_optional_for_mint.rs | 10 +-- ..._144938_make_compressed_column_optional.rs | 4 +- 9 files changed, 57 insertions(+), 97 deletions(-) diff --git a/api/proto.lock b/api/proto.lock index 4c30c53..50ab138 100644 --- a/api/proto.lock +++ b/api/proto.lock @@ -20,8 +20,8 @@ sha512 = "c5ddf43d2958ec690ee2261d0ff9808b67ce810d2fc4b6077f96f561929a920f03509f [[schemas]] subject = "solana_nfts" -version = 1 -sha512 = "37fd0e45d12271323d8abfe7343c08e475ca4737014d6181dcdcbcd683ebc33ab7cea1f4da00673e7ad2f0e1ae5ae917f16175b0650df357f649545928685a50" +version = 4 +sha512 = "967fefde938a0f6ce05194e4fca15673e681caac54d8aeec114c5d38418632b9696dbaf5362345a15114e5abb49de55d0af8b9edcc0f2c91f9ef1ccc4ff55d68" [[schemas]] subject = "timestamp" diff --git a/api/proto.toml b/api/proto.toml index 77c8551..9326838 100644 --- a/api/proto.toml +++ b/api/proto.toml @@ -6,6 +6,6 @@ organization = 1 nfts = 3 customer = 1 treasury = 1 -solana_nfts = 1 +solana_nfts = 4 polygon_nfts = 1 timestamp = 1 \ No newline at end of file diff --git a/api/src/blockchains/solana.rs b/api/src/blockchains/solana.rs index f99ad76..838775a 100644 --- a/api/src/blockchains/solana.rs +++ b/api/src/blockchains/solana.rs @@ -276,82 +276,3 @@ impl Ok(()) } } - -// #[async_trait::async_trait] -// impl -// OpenDropEvent< -// MetaplexMasterEditionTransaction, -// MintMetaplexMetadataTransaction, -// MetaplexMasterEditionTransaction, -// > for Solana -// { -// async fn create_open_drop( -// &self, -// key: NftEventKey, -// payload: MetaplexMasterEditionTransaction, -// ) -> Result<()> { -// let event = NftEvents { -// event: Some(SolanaCreateOpenDrop(payload)), -// }; - -// self.producer.send(Some(&event), Some(&key)).await?; - -// Ok(()) -// } - -// async fn retry_create_open_drop( -// &self, -// key: NftEventKey, -// payload: MetaplexMasterEditionTransaction, -// ) -> Result<()> { -// let event = NftEvents { -// event: Some(SolanaRetryOpenDrop(payload)), -// }; - -// self.producer.send(Some(&event), Some(&key)).await?; - -// Ok(()) -// } - -// async fn update_open_drop( -// &self, -// key: NftEventKey, -// payload: MetaplexMasterEditionTransaction, -// ) -> Result<()> { -// let event = NftEvents { -// event: Some(SolanaUpdateOpenDrop(payload)), -// }; - -// self.producer.send(Some(&event), Some(&key)).await?; - -// Ok(()) -// } - -// async fn mint_open_drop( -// &self, -// key: NftEventKey, -// payload: MintMetaplexMetadataTransaction, -// ) -> Result<()> { -// let event = NftEvents { -// event: Some(SolanaMintOpenDrop(payload)), -// }; - -// self.producer.send(Some(&event), Some(&key)).await?; - -// Ok(()) -// } - -// async fn retry_mint_open_drop( -// &self, -// key: NftEventKey, -// payload: MintMetaplexMetadataTransaction, -// ) -> Result<()> { -// let event = NftEvents { -// event: Some(SolanaRetryMintOpenDrop(payload)), -// }; - -// self.producer.send(Some(&event), Some(&key)).await?; - -// Ok(()) -// } -// } diff --git a/api/src/events.rs b/api/src/events.rs index 9132466..8d5969f 100644 --- a/api/src/events.rs +++ b/api/src/events.rs @@ -273,6 +273,27 @@ impl Processor { ) .await }, + Some( + SolanaNftsEvent::CreateOpenDropSubmitted(payload) + | SolanaNftsEvent::RetryCreateOpenDropSubmitted(payload), + ) => { + self.drop_created(id, MintResult::Success(payload.into())) + .await + }, + Some( + SolanaNftsEvent::MintOpenDropSubmitted(payload) + | SolanaNftsEvent::RetryMintOpenDropSubmitted(payload), + ) => { + self.drop_minted(id, MintResult::Success(payload.into())) + .await + }, + Some( + SolanaNftsEvent::CreateOpenDropFailed(_) + | SolanaNftsEvent::RetryCreateOpenDropFailed(_), + ) => self.drop_created(id, MintResult::Failure).await, + Some(SolanaNftsEvent::MintOpenDropFailed(_)) => { + self.drop_minted(id, MintResult::Failure).await + }, None | Some(_) => Ok(()), }, Services::Polygon(_, e) => match e.event { diff --git a/api/src/mutations/collection.rs b/api/src/mutations/collection.rs index e1ce85d..02238c8 100644 --- a/api/src/mutations/collection.rs +++ b/api/src/mutations/collection.rs @@ -521,7 +521,7 @@ impl Mutation { return Err(Error::new("New collection must be Metaplex Certified")); } - if let Some(true) = mint.compressed { + if Some(true) == mint.compressed { return Err(Error::new( "Switching collection is only supported for uncompressed mint", )); diff --git a/api/src/mutations/drop.rs b/api/src/mutations/drop.rs index dc42084..6a8c86d 100644 --- a/api/src/mutations/drop.rs +++ b/api/src/mutations/drop.rs @@ -63,7 +63,11 @@ impl Mutation { let nfts_producer = ctx.data::>()?; let owner_address = fetch_owner(conn, input.project, input.blockchain).await?; - + let supply = if input.drop_type == DropType::Open { + Some(0) + } else { + input.supply.map(TryInto::try_into).transpose()? + }; input.validate()?; if input.blockchain == BlockchainEnum::Solana { @@ -84,7 +88,7 @@ impl Mutation { let collection_am = collections::ActiveModel { blockchain: Set(input.blockchain), - supply: Set(input.supply.map(TryFrom::try_from).transpose()?), + supply: Set(supply), creation_status: Set(CreationStatus::Pending), seller_fee_basis_points: Set(seller_fee_basis_points.try_into()?), created_by: Set(user_id), @@ -135,7 +139,7 @@ impl Mutation { let payload = proto::MetaplexMasterEditionTransaction { master_edition: Some(proto::MasterEdition { owner_address: owner_address.clone(), - supply: input.supply.map(TryInto::try_into).transpose()?, + supply, name: name.clone(), symbol, metadata_uri: uri.clone(), diff --git a/api/src/mutations/mint.rs b/api/src/mutations/mint.rs index 5186e6e..4c9c087 100644 --- a/api/src/mutations/mint.rs +++ b/api/src/mutations/mint.rs @@ -556,7 +556,7 @@ impl Mutation { return Err(Error::new("Mint is an edition and cannot be updated")); } - if let Some(true) = mint.compressed { + if Some(true) == mint.compressed { return Err(Error::new("Mint is compressed and cannot be updated")); } @@ -964,11 +964,17 @@ impl Mutation { .all(conn) .await?; + let action = if input.compressed { + Actions::MintCompressed + } else { + Actions::Mint + }; + let TransactionId(_) = credits .submit_pending_deduction( org_id, user_id, - Actions::Mint, + action, collection.blockchain.into(), balance, ) @@ -1005,6 +1011,18 @@ impl Mutation { mint_am.creation_status = Set(CreationStatus::Pending); let mint = mint_am.update(conn).await?; + let mint_history_am = mint_histories::ActiveModel { + mint_id: Set(mint.id), + wallet: Set(input.recipient), + collection_id: Set(collection.id), + tx_signature: Set(None), + status: Set(CreationStatus::Pending), + created_at: Set(Utc::now().into()), + ..Default::default() + }; + + mint_history_am.insert(conn).await?; + Ok(MintQueuedPayload { collection_mint: mint.into(), }) diff --git a/migration/src/m20230910_212742_make_owner_address_optional_for_mint.rs b/migration/src/m20230910_212742_make_owner_address_optional_for_mint.rs index 5c91d27..93dc88f 100644 --- a/migration/src/m20230910_212742_make_owner_address_optional_for_mint.rs +++ b/migration/src/m20230910_212742_make_owner_address_optional_for_mint.rs @@ -10,7 +10,7 @@ impl MigrationTrait for Migration { .alter_table( Table::alter() .table(CollectionMints::Table) - .modify_column(ColumnDef::new(CollectionMints::OwnerAddress).text().null()) + .modify_column(ColumnDef::new(CollectionMints::Owner).text().null()) .to_owned(), ) .await @@ -21,11 +21,7 @@ impl MigrationTrait for Migration { .alter_table( Table::alter() .table(CollectionMints::Table) - .modify_column( - ColumnDef::new(CollectionMints::OwnerAddress) - .text() - .not_null(), - ) + .modify_column(ColumnDef::new(CollectionMints::Owner).text().not_null()) .to_owned(), ) .await @@ -35,5 +31,5 @@ impl MigrationTrait for Migration { #[derive(Iden)] enum CollectionMints { Table, - OwnerAddress, + Owner, } diff --git a/migration/src/m20230911_144938_make_compressed_column_optional.rs b/migration/src/m20230911_144938_make_compressed_column_optional.rs index 536e90b..a4305cf 100644 --- a/migration/src/m20230911_144938_make_compressed_column_optional.rs +++ b/migration/src/m20230911_144938_make_compressed_column_optional.rs @@ -10,7 +10,7 @@ impl MigrationTrait for Migration { .alter_table( Table::alter() .table(CollectionMints::Table) - .modify_column(ColumnDef::new(CollectionMints::Compressed).text().null()) + .modify_column(ColumnDef::new(CollectionMints::Compressed).boolean().null()) .to_owned(), ) .await @@ -23,7 +23,7 @@ impl MigrationTrait for Migration { .table(CollectionMints::Table) .modify_column( ColumnDef::new(CollectionMints::Compressed) - .text() + .boolean() .not_null(), ) .to_owned(), From a13290585bf30d45bff23613173dd35ed2ab647c Mon Sep 17 00:00:00 2001 From: imabdulbasit Date: Tue, 12 Sep 2023 18:18:45 +0500 Subject: [PATCH 06/20] update protobuf schemas version --- api/proto.lock | 14 +++++++------- api/proto.toml | 14 +++++++------- .../dataloaders/switch_collection_histories.rs | 6 +++--- api/src/events.rs | 7 +++++++ api/src/mutations/collection.rs | 15 +++++++++++++++ api/src/mutations/mint.rs | 5 +++++ 6 files changed, 44 insertions(+), 17 deletions(-) diff --git a/api/proto.lock b/api/proto.lock index 50ab138..d5d8369 100644 --- a/api/proto.lock +++ b/api/proto.lock @@ -1,26 +1,26 @@ [[schemas]] subject = "customer" -version = 1 +version = 2 sha512 = "d75800df0d4744c6b0f4d9a9952d3bfd0bb6b24a8babd19104cc11b54a525f85551b3c7375d69aeabbcf629cd826aa0bc6b0c0467add20716c504f5e856ce1c5" [[schemas]] subject = "nfts" -version = 3 +version = 29 sha512 = "b3b2136bd6c7a136d317da84395661de5fc056e8270510575a3281d78884d99a0d89f444754ed02cb18ad26dcc7cd65300c1df73b9d74d2edc6bcc8d552465d0" [[schemas]] subject = "organization" -version = 1 +version = 5 sha512 = "9fb28ac73d9712292297394a5fa53a7dae9deba6847353582987ba749859301c23c05fd49d2ce84a1640f8864c5c04d59fa38907700b280000e5c4afc96654bf" [[schemas]] subject = "polygon_nfts" -version = 1 +version = 6 sha512 = "c5ddf43d2958ec690ee2261d0ff9808b67ce810d2fc4b6077f96f561929a920f03509fc8bd7adbda219250eb019f5f7be8a3f51c554f665ea1881f7a973ef2a6" [[schemas]] subject = "solana_nfts" -version = 4 +version = 11 sha512 = "967fefde938a0f6ce05194e4fca15673e681caac54d8aeec114c5d38418632b9696dbaf5362345a15114e5abb49de55d0af8b9edcc0f2c91f9ef1ccc4ff55d68" [[schemas]] @@ -30,5 +30,5 @@ sha512 = "d167e0a143c813073eef8597f0b237e5a8eaf32abbf709724e8071b2dd73ce0438b82f [[schemas]] subject = "treasury" -version = 1 -sha512 = "03580129f0561b3d153f83b9f2729bd18e27c7d29815c9c3b7493e57e3cad3ea56f6e803e0ec5f19e8c17669de5ef8c0eb1bd59cfbae5f400741d0a73a464ba5" +version = 23 +sha512 = "0e4d77999767d5971122e720c1cee7a57c3e47ce69f58a582f1762d8e65e031ea3bd9024cfc21bd7da5db6e38a71657151c58cdfa21d9ff643fb2fc657105cf5" diff --git a/api/proto.toml b/api/proto.toml index 9326838..e66a353 100644 --- a/api/proto.toml +++ b/api/proto.toml @@ -1,11 +1,11 @@ [registry] -endpoint = "http://localhost:8081" +endpoint = "https://schemas.holaplex.tools" [schemas] -organization = 1 -nfts = 3 -customer = 1 -treasury = 1 -solana_nfts = 4 -polygon_nfts = 1 +organization = 5 +nfts = 29 +customer = 2 +treasury = 23 +solana_nfts = 11 +polygon_nfts = 6 timestamp = 1 \ No newline at end of file diff --git a/api/src/dataloaders/switch_collection_histories.rs b/api/src/dataloaders/switch_collection_histories.rs index c1653bf..ceade5f 100644 --- a/api/src/dataloaders/switch_collection_histories.rs +++ b/api/src/dataloaders/switch_collection_histories.rs @@ -37,11 +37,11 @@ impl DataLoader for SwitchCollectionHistoryLoader { Ok(switch_histories.into_iter().fold( HashMap::new(), |mut acc: HashMap>, switch_history| { - acc.entry(switch_history.collection_mint_id.clone()) + acc.entry(switch_history.collection_mint_id) .or_insert_with(Vec::new); - acc.entry(switch_history.collection_mint_id.clone()) - .and_modify(|switch_histories| switch_histories.push(switch_history.into())); + acc.entry(switch_history.collection_mint_id) + .and_modify(|switch_histories| switch_histories.push(switch_history)); acc }, diff --git a/api/src/events.rs b/api/src/events.rs index 8d5969f..62d4c20 100644 --- a/api/src/events.rs +++ b/api/src/events.rs @@ -159,6 +159,13 @@ impl Processor { } } + #[allow(clippy::too_many_lines)] + + /// Processes incoming messages related to different services like Treasury and Solana. + /// Routes each message to the corresponding handler based on the type of service and the specific event. + + /// # Errors + /// - Returns an error wrapped in `ProcessorError` if any of the operations inside the function fail. pub async fn process(&self, msg: Services) -> Result<()> { match msg { Services::Treasury(TreasuryEventKey { id, .. }, e) => match e.event { diff --git a/api/src/mutations/collection.rs b/api/src/mutations/collection.rs index 02238c8..b8bafbc 100644 --- a/api/src/mutations/collection.rs +++ b/api/src/mutations/collection.rs @@ -577,6 +577,11 @@ impl Mutation { } } +/// Fetches the owner's wallet address for a given project and blockchain. +/// # Returns +/// - Returns a `Result` containing the wallet address of the owner if the operation is successful. +/// # Errors +/// - Returns an error if no project wallet is found for the specified blockchain. pub async fn fetch_owner( conn: &DatabaseConnection, project: Uuid, @@ -634,6 +639,10 @@ impl CreateCollectionInput { } } +/// Validates the Solana creator verification based on project treasury wallet address and the list of creators. +/// # Errors +/// - Returns an error if any of the creators are verified but their address does not match +/// the project treasury wallet address. pub fn validate_solana_creator_verification( project_treasury_wallet_address: &str, creators: &Vec, @@ -695,6 +704,9 @@ pub fn validate_creators(blockchain: BlockchainEnum, creators: &Vec) -> Ok(()) } +/// Validates a Solana address +/// # Errors +/// - Returns an error if the provided address is not a valid Solana address. pub fn validate_solana_address(address: &str) -> Result<()> { if Pubkey::from_str(address).is_err() { return Err(Error::new(format!( @@ -705,6 +717,9 @@ pub fn validate_solana_address(address: &str) -> Result<()> { Ok(()) } +/// Validates an EVM (Ethereum Virtual Machine) address format. +/// # Errors +/// - Returns an error if the provided address does not match the required EVM address format. pub fn validate_evm_address(address: &str) -> Result<()> { let err = Err(Error::new(format!("{address} is not a valid EVM address"))); diff --git a/api/src/mutations/mint.rs b/api/src/mutations/mint.rs index 4c9c087..d85e873 100644 --- a/api/src/mutations/mint.rs +++ b/api/src/mutations/mint.rs @@ -1287,17 +1287,20 @@ pub struct RetryUpdateMintPayload { status: CreationStatus, } +/// Represents input data for `queue_mint_to_drop` mutation #[derive(Debug, Clone, InputObject)] pub struct QueueMintToDropInput { drop: Uuid, metadata_json: MetadataJsonInput, } +/// Represents payload data for `queue_mint_to_drop` mutation #[derive(Debug, Clone, SimpleObject)] pub struct QueueMintToDropPayload { collection_mint: CollectionMint, } +/// Represents input data for `mint_queued` mutation #[derive(Debug, Clone, InputObject)] pub struct MintQueuedInput { mint: Uuid, @@ -1305,11 +1308,13 @@ pub struct MintQueuedInput { compressed: bool, } +/// Represents payload data for `mint_queued` mutation #[derive(Debug, Clone, SimpleObject)] pub struct MintQueuedPayload { collection_mint: CollectionMint, } +/// Represents input data for `mint_random_queued` mutation #[derive(Debug, Clone, InputObject)] pub struct MintRandomQueuedInput { drop: Uuid, From 1c43201f5d8cc9e275fdffc4d930a99d68640b52 Mon Sep 17 00:00:00 2001 From: imabdulbasit Date: Thu, 14 Sep 2023 15:54:28 +0500 Subject: [PATCH 07/20] make Edition as default drop type and emit events for hub-permissions --- api/src/entities/sea_orm_active_enums.rs | 6 +++ api/src/mutations/drop.rs | 2 +- api/src/mutations/mint.rs | 59 +++++++++++++++++++++++- 3 files changed, 65 insertions(+), 2 deletions(-) diff --git a/api/src/entities/sea_orm_active_enums.rs b/api/src/entities/sea_orm_active_enums.rs index 824c485..a453bc0 100644 --- a/api/src/entities/sea_orm_active_enums.rs +++ b/api/src/entities/sea_orm_active_enums.rs @@ -55,3 +55,9 @@ pub enum DropType { #[sea_orm(string_value = "open")] Open, } + +impl Default for DropType { + fn default() -> Self { + DropType::Edition + } +} diff --git a/api/src/mutations/drop.rs b/api/src/mutations/drop.rs index 6a8c86d..9e900df 100644 --- a/api/src/mutations/drop.rs +++ b/api/src/mutations/drop.rs @@ -686,7 +686,7 @@ pub struct CreateDropInput { pub blockchain: BlockchainEnum, pub creators: Vec, pub metadata_json: MetadataJsonInput, - #[graphql(name = "type")] + #[graphql(name = "type", default)] pub drop_type: DropType, } diff --git a/api/src/mutations/mint.rs b/api/src/mutations/mint.rs index d85e873..2b33ed3 100644 --- a/api/src/mutations/mint.rs +++ b/api/src/mutations/mint.rs @@ -846,6 +846,9 @@ impl Mutation { }) } + // Add a mint to the queue for a drop. + // The queued mint can be minted by calling `mint_queued` mutation for specific mint + // or `mint_random_queued_to_drop` for random mint. async fn queue_mint_to_drop( &self, ctx: &Context<'_>, @@ -909,6 +912,7 @@ impl Mutation { }) } + /// This mutation mints a specific queued drop mint. async fn mint_queued( &self, ctx: &Context<'_>, @@ -924,6 +928,7 @@ impl Mutation { let credits = ctx.data::>()?; let conn = db.get(); let solana = ctx.data::()?; + let nfts_producer = ctx.data::>()?; let UserID(id) = user_id; let OrganizationId(org) = organization_id; @@ -1011,6 +1016,28 @@ impl Mutation { mint_am.creation_status = Set(CreationStatus::Pending); let mint = mint_am.update(conn).await?; + let drop = drops::Entity::find() + .filter(drops::Column::CollectionId.eq(collection.id)) + .one(conn) + .await? + .ok_or(Error::new("drop not found"))?; + + nfts_producer + .send( + Some(&NftEvents { + event: Some(NftEvent::DropMinted(MintCreation { + drop_id: drop.id.to_string(), + status: NftCreationStatus::InProgress as i32, + })), + }), + Some(&NftEventKey { + id: mint.id.to_string(), + project_id: drop.project_id.to_string(), + user_id: user_id.to_string(), + }), + ) + .await?; + let mint_history_am = mint_histories::ActiveModel { mint_id: Set(mint.id), wallet: Set(input.recipient), @@ -1028,7 +1055,8 @@ impl Mutation { }) } - async fn mint_random_queued( + /// This mutation mints a random queued drop mint. + async fn mint_random_queued_to_drop( &self, ctx: &Context<'_>, input: MintRandomQueuedInput, @@ -1043,6 +1071,7 @@ impl Mutation { let credits = ctx.data::>()?; let conn = db.get(); let solana = ctx.data::()?; + let nfts_producer = ctx.data::>()?; let UserID(id) = user_id; let OrganizationId(org) = organization_id; @@ -1133,6 +1162,34 @@ impl Mutation { mint_am.creation_status = Set(CreationStatus::Pending); let mint = mint_am.update(conn).await?; + let mint_history_am = mint_histories::ActiveModel { + mint_id: Set(mint.id), + wallet: Set(input.recipient), + collection_id: Set(collection.id), + tx_signature: Set(None), + status: Set(CreationStatus::Pending), + created_at: Set(Utc::now().into()), + ..Default::default() + }; + + mint_history_am.insert(conn).await?; + + nfts_producer + .send( + Some(&NftEvents { + event: Some(NftEvent::DropMinted(MintCreation { + drop_id: drop.id.to_string(), + status: NftCreationStatus::InProgress as i32, + })), + }), + Some(&NftEventKey { + id: mint.id.to_string(), + project_id: drop.project_id.to_string(), + user_id: user_id.to_string(), + }), + ) + .await?; + Ok(MintQueuedPayload { collection_mint: mint.into(), }) From 3ab49bfb331693ca80af44dd88d6c818affe4821 Mon Sep 17 00:00:00 2001 From: Kyle Espinola Date: Thu, 14 Sep 2023 08:38:50 -0400 Subject: [PATCH 08/20] Update collection_mints.rs refactor:no need to clone owner --- api/src/dataloaders/collection_mints.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/dataloaders/collection_mints.rs b/api/src/dataloaders/collection_mints.rs index 1993d3e..5924358 100644 --- a/api/src/dataloaders/collection_mints.rs +++ b/api/src/dataloaders/collection_mints.rs @@ -75,7 +75,7 @@ impl DataLoader for OwnerLoader { .into_iter() .fold(HashMap::new(), |mut acc, collection_mint| { if let Some(owner) = collection_mint.owner.clone() { - acc.entry(owner.clone()) + acc.entry(owner) .or_insert_with(Vec::new) .push(collection_mint.into()); } From 28c5b594247027ed0171b972cc5f569b100df8dc Mon Sep 17 00:00:00 2001 From: imabdulbasit Date: Thu, 14 Sep 2023 19:34:26 +0500 Subject: [PATCH 09/20] Update sea-orm crate to 0.12.2 --- Cargo.lock | 1646 ++++++++++------------ api/Cargo.toml | 6 +- api/src/entities/sea_orm_active_enums.rs | 9 +- api/src/events.rs | 4 +- api/src/mutations/collection.rs | 2 +- api/src/mutations/drop.rs | 2 +- api/src/mutations/mint.rs | 12 +- migration/Cargo.toml | 2 +- 8 files changed, 753 insertions(+), 930 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 78ff428..b7e6b09 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -14,9 +14,9 @@ dependencies = [ [[package]] name = "addr2line" -version = "0.20.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4fa78e18c64fce05e902adecd7a5eed15a5e0a3439f7b0e169f0252214865e3" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" dependencies = [ "gimli", ] @@ -52,9 +52,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.0.3" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b8f9420f797f2d9e935edf629310eb938a0d839f984e25327f3c7eed22300c" +checksum = "0c378d78423fdad8089616f827526ee33c19f2fddbd5de1629152c9593ba4783" dependencies = [ "memchr", ] @@ -88,24 +88,23 @@ dependencies = [ [[package]] name = "anstream" -version = "0.3.2" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ca84f3628370c59db74ee214b3263d58f9aadd9b4fe7e711fd87dc452b7f163" +checksum = "b1f58811cfac344940f1a400b6e6231ce35171f614f26439e80f8c1465c5cc0c" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", - "is-terminal", "utf8parse", ] [[package]] name = "anstyle" -version = "1.0.1" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a30da5c5f2d5e72842e00bcb57657162cdabef0931f40e2deb9b4140440cecd" +checksum = "b84bf0a05bbb2a83e5eb6fa36bb6e87baa08193c35ff52bbf6b38d8af2890e46" [[package]] name = "anstyle-parse" @@ -127,9 +126,9 @@ dependencies = [ [[package]] name = "anstyle-wincon" -version = "1.0.2" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c677ab05e09154296dd37acecd46420c17b9713e8366facafa8fc0885167cf4c" +checksum = "58f54d10c6dfa51283a066ceab3ec1ab78d13fae00aa49243a45e4571fb79dfd" dependencies = [ "anstyle", "windows-sys", @@ -137,136 +136,13 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.72" +version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b13c32d80ecc7ab747b80c3784bce54ee8a7a0cc4fbda9bf4cda2cf6fe90854" +checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" dependencies = [ "backtrace", ] -[[package]] -name = "ark-bn254" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a22f4561524cd949590d78d7d4c5df8f592430d221f7f3c9497bbafd8972120f" -dependencies = [ - "ark-ec", - "ark-ff", - "ark-std", -] - -[[package]] -name = "ark-ec" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "defd9a439d56ac24968cca0571f598a61bc8c55f71d50a89cda591cb750670ba" -dependencies = [ - "ark-ff", - "ark-poly", - "ark-serialize", - "ark-std", - "derivative", - "hashbrown 0.13.2", - "itertools", - "num-traits", - "zeroize", -] - -[[package]] -name = "ark-ff" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" -dependencies = [ - "ark-ff-asm", - "ark-ff-macros", - "ark-serialize", - "ark-std", - "derivative", - "digest 0.10.7", - "itertools", - "num-bigint", - "num-traits", - "paste", - "rustc_version", - "zeroize", -] - -[[package]] -name = "ark-ff-asm" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" -dependencies = [ - "quote", - "syn 1.0.109", -] - -[[package]] -name = "ark-ff-macros" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" -dependencies = [ - "num-bigint", - "num-traits", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "ark-poly" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d320bfc44ee185d899ccbadfa8bc31aab923ce1558716e1997a1e74057fe86bf" -dependencies = [ - "ark-ff", - "ark-serialize", - "ark-std", - "derivative", - "hashbrown 0.13.2", -] - -[[package]] -name = "ark-serialize" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" -dependencies = [ - "ark-serialize-derive", - "ark-std", - "digest 0.10.7", - "num-bigint", -] - -[[package]] -name = "ark-serialize-derive" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae3281bc6d0fd7e549af32b52511e1302185bd688fd3359fa36423346ff682ea" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "ark-std" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" -dependencies = [ - "num-traits", - "rand 0.8.5", -] - -[[package]] -name = "array-bytes" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ad284aeb45c13f2fb4f084de4a420ebf447423bdf9386c0540ce33cb3ef4b8c" - [[package]] name = "arrayref" version = "0.3.7" @@ -297,7 +173,7 @@ dependencies = [ "async-stream", "async-trait", "base64 0.13.1", - "bytes 1.4.0", + "bytes 1.5.0", "chrono", "fast_chemail", "fnv", @@ -371,7 +247,7 @@ version = "5.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d461325bfb04058070712296601dfe5e5bd6cdff84780a0a8c569ffb15c87eb3" dependencies = [ - "bytes 1.4.0", + "bytes 1.5.0", "indexmap 1.9.3", "serde", "serde_json", @@ -396,40 +272,29 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.33", ] [[package]] name = "async-trait" -version = "0.1.72" +version = "0.1.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc6dde6e4ed435a4c1ee4e73592f5ba9da2151af10076cc04858746af9352d09" +checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.33", ] [[package]] name = "atoi" -version = "1.0.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7c57d12312ff59c811c0643f4d80830505833c9ffaebd193d819392b265be8e" +checksum = "f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528" dependencies = [ "num-traits", ] -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi 0.1.19", - "libc", - "winapi", -] - [[package]] name = "autocfg" version = "1.1.0" @@ -450,9 +315,9 @@ dependencies = [ [[package]] name = "backtrace" -version = "0.3.68" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4319208da049c43661739c5fade2ba182f09d1dc2299b32298d3a31692b17e12" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" dependencies = [ "addr2line", "cc", @@ -463,19 +328,6 @@ dependencies = [ "rustc-demangle", ] -[[package]] -name = "bae" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33b8de67cc41132507eeece2584804efcb15f85ba516e34c944b7667f480397a" -dependencies = [ - "heck 0.3.3", - "proc-macro-error", - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "base-x" version = "0.2.11" @@ -496,9 +348,26 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64" -version = "0.21.2" +version = "0.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2" + +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + +[[package]] +name = "bigdecimal" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" +checksum = "a6773ddc0eafc0e509fb60e48dff7f450f8e674a0686ae8605e8d9901bd5eefa" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", +] [[package]] name = "bincode" @@ -517,17 +386,11 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42" - -[[package]] -name = "bitmaps" -version = "2.1.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "031043d04099746d8db04daf1fa424b2bc8bd69d92b25962dcde24da39ab64a2" +checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" dependencies = [ - "typenum", + "serde", ] [[package]] @@ -544,24 +407,24 @@ dependencies = [ [[package]] name = "blake2b_simd" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c2f0dc9a68c6317d884f97cc36cf5a3d20ba14ce404227df55e1af708ab04bc" +checksum = "23285ad32269793932e830392f2fe2f83e26488fd3ec778883a93c8323735780" dependencies = [ "arrayref", "arrayvec", - "constant_time_eq 0.2.6", + "constant_time_eq", ] [[package]] name = "blake2s_simd" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6637f448b9e61dfadbdcbae9a885fadee1f3eaffb1f8d3c1965d3ade8bdfd44f" +checksum = "94230421e395b9920d23df13ea5d77a20e1725331f90fbbf6df6040b33f756ae" dependencies = [ "arrayref", "arrayvec", - "constant_time_eq 0.2.6", + "constant_time_eq", ] [[package]] @@ -574,7 +437,7 @@ dependencies = [ "arrayvec", "cc", "cfg-if", - "constant_time_eq 0.3.0", + "constant_time_eq", "digest 0.10.7", ] @@ -741,22 +604,22 @@ dependencies = [ [[package]] name = "bytemuck" -version = "1.13.1" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17febce684fd15d89027105661fec94afb475cb995fbc59d2865198446ba2eea" +checksum = "374d28ec25809ee0e23827c2ab573d729e293f281dfe393500e7ad618baa61c6" dependencies = [ "bytemuck_derive", ] [[package]] name = "bytemuck_derive" -version = "1.4.1" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdde5c9cd29ebd706ce1b35600920a33550e402fc998a2e53ad3b42c3c47a192" +checksum = "965ab7eb5f8f97d2a083c799f3a1b994fc397b2fe2da5d1da1626ce15a39f2b1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.33", ] [[package]] @@ -773,18 +636,18 @@ checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38" [[package]] name = "bytes" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" dependencies = [ "serde", ] [[package]] name = "cc" -version = "1.0.82" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "305fe645edc1442a0fa8b6726ba61d422798d37a52e12eaecf4b022ebbb88f01" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" dependencies = [ "jobserver", "libc", @@ -798,18 +661,17 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.26" +version = "0.4.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5" +checksum = "defd4e7873dbddba6c7c91e199c7fcb946abc4a6a4ac3195400bcfb01b5de877" dependencies = [ "android-tzdata", "iana-time-zone", "js-sys", "num-traits", "serde", - "time 0.1.45", "wasm-bindgen", - "winapi", + "windows-targets", ] [[package]] @@ -827,84 +689,43 @@ dependencies = [ [[package]] name = "clap" -version = "3.2.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123" -dependencies = [ - "atty", - "bitflags 1.3.2", - "clap_derive 3.2.25", - "clap_lex 0.2.4", - "indexmap 1.9.3", - "once_cell", - "strsim", - "termcolor", - "textwrap", -] - -[[package]] -name = "clap" -version = "4.3.21" +version = "4.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c27cdf28c0f604ba3f512b0c9a409f8de8513e4816705deb0498b627e7c3a3fd" +checksum = "84ed82781cea27b43c9b106a979fe450a13a31aab0500595fb3fc06616de08e6" dependencies = [ "clap_builder", - "clap_derive 4.3.12", - "once_cell", + "clap_derive", ] [[package]] name = "clap_builder" -version = "4.3.21" +version = "4.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08a9f1ab5e9f01a9b81f202e8562eb9a10de70abf9eaeac1be465c28b75aa4aa" +checksum = "2bb9faaa7c2ef94b2743a21f5a29e6f0010dff4caa69ac8e9d6cf8b6fa74da08" dependencies = [ "anstream", "anstyle", - "clap_lex 0.5.0", - "once_cell", + "clap_lex", "strsim", ] [[package]] name = "clap_derive" -version = "3.2.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae6371b8bdc8b7d3959e9cf7b22d4435ef3e79e138688421ec654acf8c81b008" -dependencies = [ - "heck 0.4.1", - "proc-macro-error", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "clap_derive" -version = "4.3.12" +version = "4.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54a9bb5758fc5dfe728d1019941681eccaf0cf8a4189b692a0ee2f2ecf90a050" +checksum = "0862016ff20d69b84ef8247369fabf5c008a7417002411897d40ee1f4532b873" dependencies = [ - "heck 0.4.1", + "heck", "proc-macro2", "quote", - "syn 2.0.28", -] - -[[package]] -name = "clap_lex" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" -dependencies = [ - "os_str_bytes", + "syn 2.0.33", ] [[package]] name = "clap_lex" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b" +checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961" [[package]] name = "colorchoice" @@ -933,10 +754,10 @@ dependencies = [ ] [[package]] -name = "constant_time_eq" -version = "0.2.6" +name = "const-oid" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21a53c0a4d288377e7415b53dcfc3c04da5cdc2cc95c8d5ac178b58f0b861ad6" +checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" [[package]] name = "constant_time_eq" @@ -993,40 +814,6 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9cace84e55f07e7301bae1c519df89cdad8cc3cd868413d3fdbdeca9ff3db484" -[[package]] -name = "crossbeam-channel" -version = "0.5.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" -dependencies = [ - "cfg-if", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-deque" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" -dependencies = [ - "cfg-if", - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" -dependencies = [ - "autocfg", - "cfg-if", - "crossbeam-utils", - "memoffset", - "scopeguard", -] - [[package]] name = "crossbeam-queue" version = "0.3.8" @@ -1074,14 +861,13 @@ dependencies = [ [[package]] name = "curve25519-dalek" -version = "3.2.1" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90f9d052967f590a76e62eb387bd0bbb1b000182c3cefe5364db6b7211651bc0" +checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" dependencies = [ "byteorder", "digest 0.9.0", "rand_core 0.5.1", - "serde", "subtle", "zeroize", ] @@ -1131,7 +917,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.28", + "syn 2.0.33", ] [[package]] @@ -1153,7 +939,7 @@ checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" dependencies = [ "darling_core 0.20.3", "quote", - "syn 2.0.28", + "syn 2.0.33", ] [[package]] @@ -1182,11 +968,22 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "der" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +dependencies = [ + "const-oid", + "pem-rfc7468", + "zeroize", +] + [[package]] name = "deranged" -version = "0.3.7" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7684a49fb1af197853ef7b2ee694bc1f5b4179556f1e5710e1760c5db6f5e929" +checksum = "f2696e8a945f658fd14dc3b87242e6b80cd0f36ff04ea560fa39082368847946" dependencies = [ "serde", ] @@ -1218,30 +1015,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer 0.10.4", + "const-oid", "crypto-common", "subtle", ] -[[package]] -name = "dirs" -version = "4.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" -dependencies = [ - "dirs-sys", -] - -[[package]] -name = "dirs-sys" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" -dependencies = [ - "libc", - "redox_users", - "winapi", -] - [[package]] name = "dotenv" version = "0.15.0" @@ -1271,12 +1049,15 @@ name = "either" version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +dependencies = [ + "serde", +] [[package]] name = "encoding_rs" -version = "0.8.32" +version = "0.8.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394" +checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" dependencies = [ "cfg-if", ] @@ -1289,9 +1070,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b30f669a7961ef1631673d2766cc92f52d64f7ef354d4fe0ddfd30ed52f0f4f" +checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd" dependencies = [ "errno-dragonfly", "libc", @@ -1308,6 +1089,17 @@ dependencies = [ "libc", ] +[[package]] +name = "etcetera" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "136d1b5283a1ab77bd9257427ffd09d8667ced0570b6f938942bc7568ed5b943" +dependencies = [ + "cfg-if", + "home", + "windows-sys", +] + [[package]] name = "event-listener" version = "2.5.3" @@ -1344,12 +1136,30 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "835a3dc7d1ec9e75e2b5fb4ba75396837112d2060b03f7d43bc1897c7f7211da" +[[package]] +name = "finl_unicode" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fcfdc7a0362c9f4444381a9e697c79d435fe65b52a37466fc2c1184cee9edc6" + [[package]] name = "fixedbitset" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" +[[package]] +name = "flume" +version = "0.10.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1657b4441c3403d9f7b3409e47575237dac27b1b5726df654a6ecbf92f0f7577" +dependencies = [ + "futures-core", + "futures-sink", + "pin-project 1.1.3", + "spin 0.9.8", +] + [[package]] name = "fnv" version = "1.0.7" @@ -1430,13 +1240,13 @@ dependencies = [ [[package]] name = "futures-intrusive" -version = "0.4.2" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a604f7a68fbf8103337523b1fadc8ade7361ee3f112f7c680ad179651616aed5" +checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f" dependencies = [ "futures-core", "lock_api", - "parking_lot 0.11.2", + "parking_lot", ] [[package]] @@ -1453,7 +1263,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.33", ] [[package]] @@ -1535,25 +1345,29 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" dependencies = [ "cfg-if", - "js-sys", "libc", "wasi 0.11.0+wasi-snapshot-preview1", - "wasm-bindgen", ] [[package]] name = "gimli" -version = "0.27.3" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" + +[[package]] +name = "glob" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] name = "h2" -version = "0.3.20" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97ec8491ebaf99c8eaa73058b045fe58073cd6be7f596ac993ced0b0a0c01049" +checksum = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833" dependencies = [ - "bytes 1.4.0", + "bytes 1.5.0", "fnv", "futures-core", "futures-sink", @@ -1568,9 +1382,9 @@ dependencies = [ [[package]] name = "handlebars" -version = "4.3.7" +version = "4.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83c3372087601b532857d332f5957cbae686da52bb7810bf038c3e3c3cc2fa0d" +checksum = "c39b3bc2a8f715298032cf5087e58573809374b08160aa7d750582bdb82d2683" dependencies = [ "log", "pest", @@ -1619,22 +1433,21 @@ dependencies = [ [[package]] name = "hashlink" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "312f66718a2d7789ffef4f4b7b213138ed9f1eb3aa1d0d82fc99f88fb3ffd26f" +checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" dependencies = [ "hashbrown 0.14.0", ] [[package]] name = "headers" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3e372db8e5c0d213e0cd0b9be18be2aca3d44cf2fe30a9d46a65581cd454584" +checksum = "06683b93020a07e3dbcf5f8c0f6d40080d725bea7936fc01ad345c01b97dc270" dependencies = [ - "base64 0.13.1", - "bitflags 1.3.2", - "bytes 1.4.0", + "base64 0.21.4", + "bytes 1.5.0", "headers-core", "http", "httpdate", @@ -1651,15 +1464,6 @@ dependencies = [ "http", ] -[[package]] -name = "heck" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" -dependencies = [ - "unicode-segmentation", -] - [[package]] name = "heck" version = "0.4.1" @@ -1669,15 +1473,6 @@ dependencies = [ "unicode-segmentation", ] -[[package]] -name = "hermit-abi" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] - [[package]] name = "hermit-abi" version = "0.3.2" @@ -1734,8 +1529,8 @@ dependencies = [ [[package]] name = "holaplex-hub-core" -version = "0.5.3" -source = "git+https://github.com/holaplex/hub-core?branch=stable#40a8dfab0dbf2d01b0eda61ff1ce831e1ea4a10b" +version = "0.5.4" +source = "git+https://github.com/holaplex/hub-core?branch=stable#1122dc679042e397360da0f85b20babff4c7ea12" dependencies = [ "anyhow", "async-trait", @@ -1743,7 +1538,7 @@ dependencies = [ "bs58 0.5.0", "chrono", "cid", - "clap 4.3.21", + "clap", "dotenv", "futures-util", "holaplex-hub-core-macros", @@ -1759,10 +1554,10 @@ dependencies = [ "sea-orm", "serde_json", "serde_with", - "strum", + "strum 0.24.1", "thiserror", "tokio", - "toml 0.7.6", + "toml 0.7.8", "tracing", "tracing-loki", "tracing-subscriber", @@ -1773,7 +1568,7 @@ dependencies = [ [[package]] name = "holaplex-hub-core-build" version = "0.2.1" -source = "git+https://github.com/holaplex/hub-core?branch=stable#40a8dfab0dbf2d01b0eda61ff1ce831e1ea4a10b" +source = "git+https://github.com/holaplex/hub-core?branch=stable#1122dc679042e397360da0f85b20babff4c7ea12" dependencies = [ "anyhow", "dotenv", @@ -1792,18 +1587,18 @@ dependencies = [ [[package]] name = "holaplex-hub-core-macros" version = "0.1.0" -source = "git+https://github.com/holaplex/hub-core?branch=stable#40a8dfab0dbf2d01b0eda61ff1ce831e1ea4a10b" +source = "git+https://github.com/holaplex/hub-core?branch=stable#1122dc679042e397360da0f85b20babff4c7ea12" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.33", "thiserror", ] [[package]] name = "holaplex-hub-core-schemas" version = "0.3.2" -source = "git+https://github.com/holaplex/hub-core?branch=stable#40a8dfab0dbf2d01b0eda61ff1ce831e1ea4a10b" +source = "git+https://github.com/holaplex/hub-core?branch=stable#1122dc679042e397360da0f85b20babff4c7ea12" dependencies = [ "holaplex-hub-core-build", "prost", @@ -1826,7 +1621,16 @@ dependencies = [ "serde", "serde_json", "solana-program", - "strum", + "strum 0.24.1", +] + +[[package]] +name = "home" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" +dependencies = [ + "windows-sys", ] [[package]] @@ -1846,7 +1650,7 @@ version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" dependencies = [ - "bytes 1.4.0", + "bytes 1.5.0", "fnv", "itoa", ] @@ -1857,7 +1661,7 @@ version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" dependencies = [ - "bytes 1.4.0", + "bytes 1.5.0", "http", "pin-project-lite", ] @@ -1870,9 +1674,9 @@ checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" [[package]] name = "httpdate" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "hyper" @@ -1880,7 +1684,7 @@ version = "0.14.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" dependencies = [ - "bytes 1.4.0", + "bytes 1.5.0", "futures-channel", "futures-core", "futures-util", @@ -1904,7 +1708,7 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" dependencies = [ - "bytes 1.4.0", + "bytes 1.5.0", "hyper", "native-tls", "tokio", @@ -1950,22 +1754,6 @@ dependencies = [ "unicode-normalization", ] -[[package]] -name = "im" -version = "15.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0acd33ff0285af998aaf9b57342af478078f53492322fafc47450e09397e0e9" -dependencies = [ - "bitmaps", - "rand_core 0.6.4", - "rand_xoshiro", - "rayon", - "serde", - "sized-chunks", - "typenum", - "version_check", -] - [[package]] name = "indexmap" version = "1.9.3" @@ -1987,6 +1775,17 @@ dependencies = [ "hashbrown 0.14.0", ] +[[package]] +name = "inherent" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce243b1bfa62ffc028f1cc3b6034ec63d649f3031bc8a4fbbb004e1ac17d1f68" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.33", +] + [[package]] name = "instant" version = "0.1.12" @@ -2003,21 +1802,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6" [[package]] -name = "is-terminal" -version = "0.4.9" +name = "itertools" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" dependencies = [ - "hermit-abi 0.3.2", - "rustix", - "windows-sys", + "either", ] [[package]] name = "itertools" -version = "0.10.5" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" dependencies = [ "either", ] @@ -2060,12 +1857,21 @@ name = "lazy_static" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +dependencies = [ + "spin 0.5.2", +] [[package]] name = "libc" -version = "0.2.147" +version = "0.2.148" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b" + +[[package]] +name = "libm" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" +checksum = "f7012b1bbb0719e1097c47611d3898568c546d597c2e74d66f6087edd5233ff4" [[package]] name = "libsecp256k1" @@ -2115,6 +1921,17 @@ dependencies = [ "libsecp256k1-core", ] +[[package]] +name = "libsqlite3-sys" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afc22eff61b133b115c6e8c74e818c628d6d5e7a502afea6f64dee076dd94326" +dependencies = [ + "cc", + "pkg-config", + "vcpkg", +] + [[package]] name = "libz-sys" version = "1.1.12" @@ -2129,9 +1946,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.4.5" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57bcfdad1b858c2db7c38303a6d2ad4dfaf5eb53dfeb0910128b2c26d6158503" +checksum = "1a9bad9f94746442c783ca431b22403b519cd7fbeed0533fdd6328b2f2212128" [[package]] name = "lock_api" @@ -2145,9 +1962,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.19" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "loki-api" @@ -2194,9 +2011,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.5.0" +version = "2.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" [[package]] name = "memmap2" @@ -2207,15 +2024,6 @@ dependencies = [ "libc", ] -[[package]] -name = "memoffset" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" -dependencies = [ - "autocfg", -] - [[package]] name = "migration" version = "0.1.0" @@ -2262,7 +2070,7 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "01acbdc23469fd8fe07ab135923371d5f5a422fbf9c522158677c8eb15bc51c2" dependencies = [ - "bytes 1.4.0", + "bytes 1.5.0", "encoding_rs", "futures-util", "http", @@ -2362,15 +2170,32 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f" +checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" dependencies = [ "autocfg", "num-integer", "num-traits", ] +[[package]] +name = "num-bigint-dig" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151" +dependencies = [ + "byteorder", + "lazy_static", + "libm", + "num-integer", + "num-iter", + "num-traits", + "rand 0.8.5", + "smallvec", + "zeroize", +] + [[package]] name = "num-derive" version = "0.3.3" @@ -2392,6 +2217,17 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-iter" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.16" @@ -2399,6 +2235,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" dependencies = [ "autocfg", + "libm", ] [[package]] @@ -2407,7 +2244,7 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi 0.3.2", + "hermit-abi", "libc", ] @@ -2434,9 +2271,9 @@ dependencies = [ [[package]] name = "object" -version = "0.31.1" +version = "0.32.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" dependencies = [ "memchr", ] @@ -2455,11 +2292,11 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "openssl" -version = "0.10.56" +version = "0.10.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "729b745ad4a5575dd06a3e1af1414bd330ee561c01b3899eb584baeaa8def17e" +checksum = "bac25ee399abb46215765b1cb35bc0212377e58a061560d8b29b024fd0430e7c" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.4.0", "cfg-if", "foreign-types", "libc", @@ -2476,7 +2313,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.33", ] [[package]] @@ -2487,9 +2324,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.91" +version = "0.9.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "866b5f16f90776b9bb8dc1e1802ac6f0513de3a7a7465867bfbc563dc737faac" +checksum = "db4d56a4c0478783083cfafcc42493dd4a981d41669da64b4572a2a089b51b1d" dependencies = [ "cc", "libc", @@ -2497,6 +2334,15 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "ordered-float" +version = "3.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a54938017eacd63036332b4ae5c8a49fc8c0c1d6d629893057e4f13609edd06" +dependencies = [ + "num-traits", +] + [[package]] name = "os_pipe" version = "1.1.4" @@ -2507,33 +2353,28 @@ dependencies = [ "windows-sys", ] -[[package]] -name = "os_str_bytes" -version = "6.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d5d9eb14b174ee9aa2ef96dc2b94637a2d4b6e7cb873c7e171f0c20c6cf3eac" - [[package]] name = "ouroboros" -version = "0.15.6" +version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1358bd1558bd2a083fed428ffeda486fbfb323e698cdda7794259d592ca72db" +checksum = "e2ba07320d39dfea882faa70554b4bd342a5f273ed59ba7c1c6b4c840492c954" dependencies = [ "aliasable", "ouroboros_macro", + "static_assertions", ] [[package]] name = "ouroboros_macro" -version = "0.15.6" +version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f7d21ccd03305a674437ee1248f3ab5d4b1db095cf1caf49f1713ddf61956b7" +checksum = "ec4c6225c69b4ca778c0aea097321a64c421cf4577b331c61b229267edabb6f8" dependencies = [ - "Inflector", + "heck", "proc-macro-error", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.33", ] [[package]] @@ -2542,17 +2383,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" -[[package]] -name = "parking_lot" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" -dependencies = [ - "instant", - "lock_api", - "parking_lot_core 0.8.6", -] - [[package]] name = "parking_lot" version = "0.12.1" @@ -2560,21 +2390,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" dependencies = [ "lock_api", - "parking_lot_core 0.9.8", -] - -[[package]] -name = "parking_lot_core" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" -dependencies = [ - "cfg-if", - "instant", - "libc", - "redox_syscall 0.2.16", - "smallvec", - "winapi", + "parking_lot_core", ] [[package]] @@ -2585,7 +2401,7 @@ checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.3.5", + "redox_syscall", "smallvec", "windows-targets", ] @@ -2597,12 +2413,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" [[package]] -name = "pbkdf2" -version = "0.4.0" +name = "pem-rfc7468" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "216eaa586a190f0a738f2f918511eecfa90f13295abec0e457cdebcceda80cbd" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" dependencies = [ - "crypto-mac", + "base64ct", ] [[package]] @@ -2613,19 +2429,20 @@ checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" [[package]] name = "pest" -version = "2.7.2" +version = "2.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1acb4a4365a13f749a93f1a094a7805e5cfa0955373a9de860d962eaa3a5fe5a" +checksum = "d7a4d085fd991ac8d5b05a147b437791b4260b76326baf0fc60cf7c9c27ecd33" dependencies = [ + "memchr", "thiserror", "ucd-trie", ] [[package]] name = "pest_derive" -version = "2.7.2" +version = "2.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "666d00490d4ac815001da55838c500eafb0320019bbaa44444137c48b443a853" +checksum = "a2bee7be22ce7918f641a33f08e3f43388c7656772244e2bbb2477f44cc9021a" dependencies = [ "pest", "pest_generator", @@ -2633,22 +2450,22 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.2" +version = "2.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68ca01446f50dbda87c1786af8770d535423fa8a53aec03b8f4e3d7eb10e0929" +checksum = "d1511785c5e98d79a05e8a6bc34b4ac2168a0e3e92161862030ad84daa223141" dependencies = [ "pest", "pest_meta", "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.33", ] [[package]] name = "pest_meta" -version = "2.7.2" +version = "2.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56af0a30af74d0445c0bf6d9d051c979b516a1a5af790d251daee76005420a48" +checksum = "b42f0394d3123e33353ca5e1e89092e533d2cc490389f2bd6131c43c634ebc5f" dependencies = [ "once_cell", "pest", @@ -2657,12 +2474,12 @@ dependencies = [ [[package]] name = "petgraph" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dd7d28ee937e54fe3080c91faa1c3a46c06de6252988a7f4592ba2310ef22a4" +checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" dependencies = [ "fixedbitset", - "indexmap 1.9.3", + "indexmap 2.0.0", ] [[package]] @@ -2702,14 +2519,14 @@ checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.33", ] [[package]] name = "pin-project-lite" -version = "0.2.12" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12cc1b0bf1727a77a54b6654e7b5f1af8604923edc8b81885f8ec92f9e3f0a05" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" [[package]] name = "pin-utils" @@ -2717,6 +2534,27 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pkcs1" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" +dependencies = [ + "der", + "pkcs8", + "spki", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + [[package]] name = "pkg-config" version = "0.3.27" @@ -2725,20 +2563,20 @@ checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" [[package]] name = "poem" -version = "1.3.57" +version = "1.3.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0d92c532a37a9e98c0e9a0411e6852b8acccf9ec07d5e6e450b01cbf947d90b" +checksum = "ebc7ae19f3e791ae8108b08801abb3708d64d3a16490c720e0b81040cae87b5d" dependencies = [ "anyhow", "async-trait", - "base64 0.21.2", - "bytes 1.4.0", + "base64 0.21.4", + "bytes 1.5.0", "futures-util", "headers", "http", "hyper", "mime", - "parking_lot 0.12.1", + "parking_lot", "percent-encoding", "pin-project-lite", "poem-derive", @@ -2759,14 +2597,14 @@ dependencies = [ [[package]] name = "poem-derive" -version = "1.3.57" +version = "1.3.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5dd58846a1f582215370384c3090c62c9ef188e9d798ffc67ea90d0a1a8a3b8" +checksum = "2550a0bce7273b278894ef3ccc5a6869e7031b6870042f3cc6826ed9faa980a6" dependencies = [ "proc-macro-crate 1.1.3", "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.33", ] [[package]] @@ -2830,9 +2668,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.66" +version = "1.0.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" +checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328" dependencies = [ "unicode-ident", ] @@ -2843,7 +2681,7 @@ version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" dependencies = [ - "bytes 1.4.0", + "bytes 1.5.0", "prost-derive", ] @@ -2853,9 +2691,9 @@ version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "119533552c9a7ffacc21e099c24a0ac8bb19c2a2a3f363de84cd9b844feab270" dependencies = [ - "bytes 1.4.0", - "heck 0.4.1", - "itertools", + "bytes 1.5.0", + "heck", + "itertools 0.10.5", "lazy_static", "log", "multimap", @@ -2876,7 +2714,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" dependencies = [ "anyhow", - "itertools", + "itertools 0.10.5", "proc-macro2", "quote", "syn 1.0.109", @@ -2913,9 +2751,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.32" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ "proc-macro2", ] @@ -2997,37 +2835,6 @@ dependencies = [ "rand_core 0.5.1", ] -[[package]] -name = "rand_xoshiro" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f97cdb2a36ed4183de61b2f824cc45c9f1037f28afe0a322e9fff4c108b5aaa" -dependencies = [ - "rand_core 0.6.4", -] - -[[package]] -name = "rayon" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b" -dependencies = [ - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d" -dependencies = [ - "crossbeam-channel", - "crossbeam-deque", - "crossbeam-utils", - "num_cpus", -] - [[package]] name = "rdkafka" version = "0.29.0" @@ -3048,9 +2855,9 @@ dependencies = [ [[package]] name = "rdkafka-sys" -version = "4.5.0+1.9.2" +version = "4.6.0+2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bb0676c2112342ac7165decdedbc4e7086c0af384479ccce534546b10687a5d" +checksum = "ad63c279fca41a27c231c450a2d2ad18288032e9cbb159ad16c9d96eba35aaaf" dependencies = [ "libc", "libz-sys", @@ -3061,15 +2868,6 @@ dependencies = [ "zstd-sys", ] -[[package]] -name = "redox_syscall" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" -dependencies = [ - "bitflags 1.3.2", -] - [[package]] name = "redox_syscall" version = "0.3.5" @@ -3079,27 +2877,16 @@ dependencies = [ "bitflags 1.3.2", ] -[[package]] -name = "redox_users" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" -dependencies = [ - "getrandom 0.2.10", - "redox_syscall 0.2.16", - "thiserror", -] - [[package]] name = "regex" -version = "1.9.3" +version = "1.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81bc1d4caf89fac26a70747fe603c130093b53c773888797a6329091246d651a" +checksum = "697061221ea1b4a94a624f67d0ae2bfe4e22b8a17b6a192afb11046542cc8c47" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.3.6", - "regex-syntax 0.7.4", + "regex-automata 0.3.8", + "regex-syntax 0.7.5", ] [[package]] @@ -3113,13 +2900,13 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.3.6" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fed1ceff11a1dddaee50c9dc8e4938bd106e9d89ae372f192311e7da498e3b69" +checksum = "c2f401f4955220693b56f8ec66ee9c78abffd8d1c4f23dc41a23839eb88f0795" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.7.4", + "regex-syntax 0.7.5", ] [[package]] @@ -3130,9 +2917,9 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2" +checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" [[package]] name = "rend" @@ -3145,12 +2932,12 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.11.18" +version = "0.11.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cde824a14b7c14f85caff81225f411faacc04a2013f41670f41443742b1c1c55" +checksum = "3e9ad3fe7488d7e34558a2033d45a0c90b72d97b4f80705666fea71472e2e6a1" dependencies = [ - "base64 0.21.2", - "bytes 1.4.0", + "base64 0.21.4", + "bytes 1.5.0", "encoding_rs", "futures-core", "futures-util", @@ -3234,16 +3021,37 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "rsa" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ab43bb47d23c1a631b4b680199a45255dce26fa9ab2fa902581f624ff13e6a8" +dependencies = [ + "byteorder", + "const-oid", + "digest 0.10.7", + "num-bigint-dig", + "num-integer", + "num-iter", + "num-traits", + "pkcs1", + "pkcs8", + "rand_core 0.6.4", + "signature", + "spki", + "subtle", + "zeroize", +] + [[package]] name = "rust_decimal" -version = "1.31.0" +version = "1.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a2ab0025103a60ecaaf3abf24db1db240a4e1c15837090d2c32f625ac98abea" +checksum = "a4c4216490d5a413bc6d10fa4742bd7d4955941d062c0ef873141d6b0e7b30fd" dependencies = [ "arrayvec", "borsh 0.10.3", - "byteorder", - "bytes 1.4.0", + "bytes 1.5.0", "num-traits", "rand 0.8.5", "rkyv", @@ -3257,12 +3065,6 @@ version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - [[package]] name = "rustc_version" version = "0.4.0" @@ -3274,11 +3076,11 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.7" +version = "0.38.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "172891ebdceb05aa0005f533a6cbfca599ddd7d966f6f5d4d9b2e70478e70399" +checksum = "d7db8590df6dfcd144d22afd1b83b36c21a18d7cbc1dc4bb5295a8712e9eb662" dependencies = [ - "bitflags 2.3.3", + "bitflags 2.4.0", "errno", "libc", "linux-raw-sys", @@ -3287,14 +3089,13 @@ dependencies = [ [[package]] name = "rustls" -version = "0.20.8" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fff78fc74d175294f4e83b28343315ffcfb114b156f0185e9741cb5570f50e2f" +checksum = "cd8d6c9f025a446bc4d18ad9632e69aec8f287aa84499ee335599fabd20c3fd8" dependencies = [ - "log", "ring", + "rustls-webpki", "sct", - "webpki", ] [[package]] @@ -3303,7 +3104,17 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" dependencies = [ - "base64 0.21.2", + "base64 0.21.4", +] + +[[package]] +name = "rustls-webpki" +version = "0.101.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45a27e3b59326c16e23d30aeb7a36a24cc0d29e71d68ff611cdfb4a01d013bed" +dependencies = [ + "ring", + "untrusted", ] [[package]] @@ -3355,29 +3166,42 @@ dependencies = [ "untrusted", ] +[[package]] +name = "sea-bae" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bd3534a9978d0aa7edd2808dc1f8f31c4d0ecd31ddf71d997b3c98e9f3c9114" +dependencies = [ + "heck", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.33", +] + [[package]] name = "sea-orm" -version = "0.10.7" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88694d01b528a94f90ad87f8d2f546d060d070eee180315c67d158cb69476034" +checksum = "61f6c7daef05dde3476d97001e11fca7a52b655aa3bf4fd610ab2da1176a2ed5" dependencies = [ "async-stream", "async-trait", + "bigdecimal", "chrono", "futures", - "futures-util", "log", "ouroboros", "rust_decimal", "sea-orm-macros", "sea-query", "sea-query-binder", - "sea-strum", "serde", "serde_json", "sqlx", + "strum 0.25.0", "thiserror", - "time 0.3.25", + "time", "tracing", "url", "uuid", @@ -3385,13 +3209,14 @@ dependencies = [ [[package]] name = "sea-orm-cli" -version = "0.10.7" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ebe1f820fe8949cf6a57272ba9ebd0be766e47c9b85c04b3cabea40ab9459b3" +checksum = "3e3f0ff2fa5672e2e7314d107c6498a18e469beeb340a0ed84e3075fce73c2cd" dependencies = [ "chrono", - "clap 3.2.25", + "clap", "dotenvy", + "glob", "regex", "sea-schema", "tracing", @@ -3401,26 +3226,28 @@ dependencies = [ [[package]] name = "sea-orm-macros" -version = "0.10.7" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7216195de9c6b2474fd0efab486173dccd0eff21f28cc54aa4c0205d52fb3af0" +checksum = "cd90e73d5f5b184bad525767da29fbfec132b4e62ebd6f60d2f2737ec6468f62" dependencies = [ - "bae", - "heck 0.3.3", + "heck", "proc-macro2", "quote", - "syn 1.0.109", + "sea-bae", + "syn 2.0.33", + "unicode-ident", ] [[package]] name = "sea-orm-migration" -version = "0.10.7" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ed3cdfa669e4c385922f902b9a58e0c2128782a4d0fe79c6c34f3b927565e5b" +checksum = "21f673fcefb3a7e7b89a12b6c0e854ec0be14367635ac3435369c8ad7f11e09e" dependencies = [ "async-trait", - "clap 3.2.25", + "clap", "dotenvy", + "futures", "sea-orm", "sea-orm-cli", "sea-schema", @@ -3430,40 +3257,45 @@ dependencies = [ [[package]] name = "sea-query" -version = "0.27.2" +version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4f0fc4d8e44e1d51c739a68d336252a18bc59553778075d5e32649be6ec92ed" +checksum = "28c05a5bf6403834be253489bbe95fa9b1e5486bc843b61f60d26b5c9c1e244b" dependencies = [ + "bigdecimal", "chrono", + "derivative", + "inherent", + "ordered-float", "rust_decimal", "sea-query-derive", "serde_json", - "time 0.3.25", + "time", "uuid", ] [[package]] name = "sea-query-binder" -version = "0.2.2" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c2585b89c985cfacfe0ec9fc9e7bb055b776c1a2581c4e3c6185af2b8bf8865" +checksum = "36bbb68df92e820e4d5aeb17b4acd5cc8b5d18b2c36a4dd6f4626aabfa7ab1b9" dependencies = [ + "bigdecimal", "chrono", "rust_decimal", "sea-query", "serde_json", "sqlx", - "time 0.3.25", + "time", "uuid", ] [[package]] name = "sea-query-derive" -version = "0.2.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34cdc022b4f606353fe5dc85b09713a04e433323b70163e81513b141c6ae6eb5" +checksum = "bd78f2e0ee8e537e9195d1049b752e0433e2cac125426bccb7b5c3e508096117" dependencies = [ - "heck 0.3.3", + "heck", "proc-macro2", "quote", "syn 1.0.109", @@ -3472,9 +3304,9 @@ dependencies = [ [[package]] name = "sea-schema" -version = "0.10.3" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d5fda574d980e9352b6c7abd6fc75697436fe0078cac2b548559b52643ad3b" +checksum = "0cd9561232bd1b82ea748b581f15909d11de0db6563ddcf28c5d908aee8282f1" dependencies = [ "futures", "sea-query", @@ -3483,35 +3315,13 @@ dependencies = [ [[package]] name = "sea-schema-derive" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56821b7076f5096b8f726e2791ad255a99c82498e08ec477a65a96c461ff1927" -dependencies = [ - "heck 0.3.3", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "sea-strum" -version = "0.23.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "391d06a6007842cfe79ac6f7f53911b76dfd69fc9a6769f1cf6569d12ce20e1b" -dependencies = [ - "sea-strum_macros", -] - -[[package]] -name = "sea-strum_macros" -version = "0.23.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69b4397b825df6ccf1e98bcdabef3bbcfc47ff5853983467850eeab878384f21" +checksum = "c6f686050f76bffc4f635cda8aea6df5548666b830b52387e8bc7de11056d11e" dependencies = [ - "heck 0.3.3", + "heck", "proc-macro2", "quote", - "rustversion", "syn 1.0.109", ] @@ -3552,9 +3362,9 @@ checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" [[package]] name = "serde" -version = "1.0.183" +version = "1.0.188" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32ac8da02677876d532745a130fc9d8e6edfa81a269b107c5b00829b91d8eb3c" +checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" dependencies = [ "serde_derive", ] @@ -3570,20 +3380,20 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.183" +version = "1.0.188" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aafe972d60b0b9bee71a91b92fee2d4fb3c9d7e8f6b179aa99f27203d99a4816" +checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.33", ] [[package]] name = "serde_json" -version = "1.0.104" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "076066c5f1078eac5b722a31827a8832fe108bed65dfa75e233c89f8206e976c" +checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" dependencies = [ "itoa", "ryu", @@ -3624,7 +3434,7 @@ dependencies = [ "serde", "serde_json", "serde_with_macros", - "time 0.3.25", + "time", ] [[package]] @@ -3636,7 +3446,7 @@ dependencies = [ "darling 0.20.3", "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.33", ] [[package]] @@ -3704,26 +3514,26 @@ dependencies = [ ] [[package]] -name = "simdutf8" -version = "0.1.4" +name = "signature" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" +checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" +dependencies = [ + "digest 0.10.7", + "rand_core 0.6.4", +] [[package]] -name = "sized-chunks" -version = "0.6.5" +name = "simdutf8" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16d69225bde7a69b235da73377861095455d298f2b970996eec25ddbb42b3d1e" -dependencies = [ - "bitmaps", - "typenum", -] +checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" [[package]] name = "slab" -version = "0.4.8" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" dependencies = [ "autocfg", ] @@ -3752,9 +3562,9 @@ dependencies = [ [[package]] name = "socket2" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2538b18701741680e0322a2302176d3253a35388e2e62f172f64f4f16605f877" +checksum = "4031e820eb552adee9295814c0ced9e5cf38ddf1e8b7d566d6de8e2538ea989e" dependencies = [ "libc", "windows-sys", @@ -3762,115 +3572,88 @@ dependencies = [ [[package]] name = "solana-frozen-abi" -version = "1.16.7" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bee2b96d4150d9ebf55e903014bc332ac64c642837d7f1e6f7b911d709331380" +checksum = "1f704637b29f1d58b819601efede8eff0998ec10381cb96796dacfe4cfea5581" dependencies = [ - "ahash 0.8.3", - "blake3", - "block-buffer 0.10.4", "bs58 0.4.0", "bv", - "byteorder", - "cc", - "either", "generic-array", - "getrandom 0.1.16", - "im", - "lazy_static", "log", "memmap2", - "once_cell", - "rand_core 0.6.4", "rustc_version", "serde", - "serde_bytes", "serde_derive", - "serde_json", "sha2 0.10.7", "solana-frozen-abi-macro", - "subtle", "thiserror", ] [[package]] name = "solana-frozen-abi-macro" -version = "1.16.7" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942534eb972f955ed186175495654cabece6261a8ac3211e5791440d40a1ed96" +checksum = "96bf045e938c042c59739ba3a77bf1d25cb7cf073bbf3690cc2d56c7cff27ba2" dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn 2.0.28", + "syn 1.0.109", ] [[package]] name = "solana-program" -version = "1.16.7" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f81c59ed0b65b403cc5db459dd1214dfab89ccd3ce20aadf98102b072d08562" +checksum = "888f50c71dc45a528cb63df960e657601fe6fa3d643159d93ebff1dd1cc00b63" dependencies = [ - "ark-bn254", - "ark-ec", - "ark-ff", - "ark-serialize", - "array-bytes", - "base64 0.21.2", + "base64 0.13.1", "bincode", "bitflags 1.3.2", "blake3", - "borsh 0.10.3", "borsh 0.9.3", + "borsh-derive 0.9.3", "bs58 0.4.0", "bv", "bytemuck", - "cc", "console_error_panic_hook", "console_log", "curve25519-dalek", - "getrandom 0.2.10", - "itertools", + "getrandom 0.1.16", + "itertools 0.10.5", "js-sys", "lazy_static", - "libc", "libsecp256k1", "log", - "memoffset", - "num-bigint", "num-derive", "num-traits", - "parking_lot 0.12.1", + "parking_lot", "rand 0.7.3", - "rand_chacha 0.2.2", "rustc_version", "rustversion", "serde", "serde_bytes", "serde_derive", - "serde_json", "sha2 0.10.7", "sha3", "solana-frozen-abi", "solana-frozen-abi-macro", "solana-sdk-macro", "thiserror", - "tiny-bip39", "wasm-bindgen", - "zeroize", ] [[package]] name = "solana-sdk-macro" -version = "1.16.7" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e7d686e405694cd6510cd77bb87d0eeda64ad3df08d3293278ba47ca78b8e5e" +checksum = "2388e9b1690e83413393f3e20d98551cbebae9d9385397600d25ae9992873736" dependencies = [ "bs58 0.4.0", "proc-macro2", "quote", "rustversion", - "syn 2.0.28", + "syn 1.0.109", ] [[package]] @@ -3884,115 +3667,246 @@ name = "spin" version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + +[[package]] +name = "spki" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" +dependencies = [ + "base64ct", + "der", +] [[package]] name = "sqlformat" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c12bc9199d1db8234678b7051747c07f517cdcf019262d1847b94ec8b1aee3e" +checksum = "6b7b278788e7be4d0d29c0f39497a0eef3fba6bbc8e70d8bf7fde46edeaa9e85" dependencies = [ - "itertools", + "itertools 0.11.0", "nom", "unicode_categories", ] [[package]] name = "sqlx" -version = "0.6.3" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8de3b03a925878ed54a954f621e64bf55a3c1bd29652d0d1a17830405350188" +checksum = "8e58421b6bc416714d5115a2ca953718f6c621a51b68e4f4922aea5a4391a721" dependencies = [ "sqlx-core", "sqlx-macros", + "sqlx-mysql", + "sqlx-postgres", + "sqlx-sqlite", ] [[package]] name = "sqlx-core" -version = "0.6.3" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa8241483a83a3f33aa5fff7e7d9def398ff9990b2752b6c6112b83c6d246029" +checksum = "dd4cef4251aabbae751a3710927945901ee1d97ee96d757f6880ebb9a79bfd53" dependencies = [ - "ahash 0.7.6", + "ahash 0.8.3", "atoi", - "base64 0.13.1", - "bitflags 1.3.2", + "bigdecimal", "byteorder", - "bytes 1.4.0", + "bytes 1.5.0", "chrono", "crc", "crossbeam-queue", - "dirs", "dotenvy", "either", "event-listener", "futures-channel", "futures-core", "futures-intrusive", + "futures-io", "futures-util", "hashlink", "hex", - "hkdf", - "hmac 0.12.1", - "indexmap 1.9.3", - "itoa", - "libc", + "indexmap 2.0.0", "log", - "md-5", "memchr", - "num-bigint", "once_cell", "paste", "percent-encoding", - "rand 0.8.5", "rust_decimal", "rustls", "rustls-pemfile", "serde", "serde_json", - "sha1", "sha2 0.10.7", "smallvec", "sqlformat", - "sqlx-rt", - "stringprep", "thiserror", - "time 0.3.25", + "time", + "tokio", "tokio-stream", + "tracing", "url", "uuid", "webpki-roots", - "whoami", ] [[package]] name = "sqlx-macros" -version = "0.6.3" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "208e3165167afd7f3881b16c1ef3f2af69fa75980897aac8874a0696516d12c2" +dependencies = [ + "proc-macro2", + "quote", + "sqlx-core", + "sqlx-macros-core", + "syn 1.0.109", +] + +[[package]] +name = "sqlx-macros-core" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9966e64ae989e7e575b19d7265cb79d7fc3cbbdf179835cb0d716f294c2049c9" +checksum = "8a4a8336d278c62231d87f24e8a7a74898156e34c1c18942857be2acb29c7dfc" dependencies = [ "dotenvy", "either", - "heck 0.4.1", + "heck", + "hex", "once_cell", "proc-macro2", "quote", + "serde", "serde_json", "sha2 0.10.7", "sqlx-core", - "sqlx-rt", + "sqlx-mysql", + "sqlx-postgres", + "sqlx-sqlite", "syn 1.0.109", + "tempfile", + "tokio", "url", ] [[package]] -name = "sqlx-rt" -version = "0.6.3" +name = "sqlx-mysql" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "804d3f245f894e61b1e6263c84b23ca675d96753b5abfd5cc8597d86806e8024" +checksum = "8ca69bf415b93b60b80dc8fda3cb4ef52b2336614d8da2de5456cc942a110482" dependencies = [ + "atoi", + "base64 0.21.4", + "bigdecimal", + "bitflags 2.4.0", + "byteorder", + "bytes 1.5.0", + "chrono", + "crc", + "digest 0.10.7", + "dotenvy", + "either", + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "generic-array", + "hex", + "hkdf", + "hmac 0.12.1", + "itoa", + "log", + "md-5", + "memchr", "once_cell", - "tokio", - "tokio-rustls", + "percent-encoding", + "rand 0.8.5", + "rsa", + "rust_decimal", + "serde", + "sha1", + "sha2 0.10.7", + "smallvec", + "sqlx-core", + "stringprep", + "thiserror", + "time", + "tracing", + "uuid", + "whoami", +] + +[[package]] +name = "sqlx-postgres" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0db2df1b8731c3651e204629dd55e52adbae0462fa1bdcbed56a2302c18181e" +dependencies = [ + "atoi", + "base64 0.21.4", + "bigdecimal", + "bitflags 2.4.0", + "byteorder", + "chrono", + "crc", + "dotenvy", + "etcetera", + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "hex", + "hkdf", + "hmac 0.12.1", + "home", + "itoa", + "log", + "md-5", + "memchr", + "num-bigint", + "once_cell", + "rand 0.8.5", + "rust_decimal", + "serde", + "serde_json", + "sha1", + "sha2 0.10.7", + "smallvec", + "sqlx-core", + "stringprep", + "thiserror", + "time", + "tracing", + "uuid", + "whoami", +] + +[[package]] +name = "sqlx-sqlite" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4c21bf34c7cae5b283efb3ac1bcc7670df7561124dc2f8bdc0b59be40f79a2" +dependencies = [ + "atoi", + "chrono", + "flume", + "futures-channel", + "futures-core", + "futures-executor", + "futures-intrusive", + "futures-util", + "libsqlite3-sys", + "log", + "percent-encoding", + "serde", + "sqlx-core", + "time", + "tracing", + "url", + "uuid", ] [[package]] @@ -4015,10 +3929,11 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "stringprep" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db3737bde7edce97102e0e2b15365bf7a20bfdb5f60f4f9e8d7004258a51a8da" +checksum = "bb41d74e231a107a1b4ee36bd1214b11285b77768d2e3824aedafa988fd36ee6" dependencies = [ + "finl_unicode", "unicode-bidi", "unicode-normalization", ] @@ -4038,13 +3953,19 @@ dependencies = [ "strum_macros", ] +[[package]] +name = "strum" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" + [[package]] name = "strum_macros" version = "0.24.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" dependencies = [ - "heck 0.4.1", + "heck", "proc-macro2", "quote", "rustversion", @@ -4070,9 +3991,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.28" +version = "2.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04361975b3f5e348b2189d8dc55bc942f278b2d482a6a0365de5bdd62d351567" +checksum = "9caece70c63bfba29ec2fed841a09851b14a235c60010fa4de58089b6c025668" dependencies = [ "proc-macro2", "quote", @@ -4099,50 +4020,35 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tempfile" -version = "3.7.1" +version = "3.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc02fddf48964c42031a0b3fe0428320ecf3a73c401040fc0096f97794310651" +checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" dependencies = [ "cfg-if", "fastrand 2.0.0", - "redox_syscall 0.3.5", + "redox_syscall", "rustix", "windows-sys", ] -[[package]] -name = "termcolor" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "textwrap" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" - [[package]] name = "thiserror" -version = "1.0.44" +version = "1.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "611040a08a0439f8248d1990b111c95baa9c704c805fa1f62104b39655fd7f90" +checksum = "9d6d7a740b8a666a7e828dd00da9c0dc290dff53154ea77ac109281de90589b7" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.44" +version = "1.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "090198534930841fab3a5d1bb637cde49e339654e606195f8d9c76eeb081dc96" +checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.33", ] [[package]] @@ -4157,20 +4063,9 @@ dependencies = [ [[package]] name = "time" -version = "0.1.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" -dependencies = [ - "libc", - "wasi 0.10.0+wasi-snapshot-preview1", - "winapi", -] - -[[package]] -name = "time" -version = "0.3.25" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fdd63d58b18d663fbdf70e049f00a22c8e42be082203be7f26589213cd75ea" +checksum = "17f6bb557fd245c28e6411aa56b6403c689ad95061f50e4be16c274e70a17e48" dependencies = [ "deranged", "itoa", @@ -4187,32 +4082,13 @@ checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" [[package]] name = "time-macros" -version = "0.2.11" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb71511c991639bb078fd5bf97757e03914361c48100d52878b8e52b46fb92cd" +checksum = "1a942f44339478ef67935ab2bbaec2fb0322496cf3cbe84b261e06ac3814c572" dependencies = [ "time-core", ] -[[package]] -name = "tiny-bip39" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffc59cb9dfc85bb312c3a78fd6aa8a8582e310b0fa885d5bb877f6dcc601839d" -dependencies = [ - "anyhow", - "hmac 0.8.1", - "once_cell", - "pbkdf2", - "rand 0.7.3", - "rustc-hash", - "sha2 0.9.9", - "thiserror", - "unicode-normalization", - "wasm-bindgen", - "zeroize", -] - [[package]] name = "tinyvec" version = "1.6.0" @@ -4230,18 +4106,18 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.30.0" +version = "1.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d3ce25f50619af8b0aec2eb23deebe84249e19e2ddd393a6e16e3300a6dadfd" +checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9" dependencies = [ "backtrace", - "bytes 1.4.0", + "bytes 1.5.0", "libc", "mio", "num_cpus", - "parking_lot 0.12.1", + "parking_lot", "pin-project-lite", - "socket2 0.5.3", + "socket2 0.5.4", "tokio-macros", "windows-sys", ] @@ -4254,7 +4130,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.33", ] [[package]] @@ -4267,17 +4143,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "tokio-rustls" -version = "0.23.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59" -dependencies = [ - "rustls", - "tokio", - "webpki", -] - [[package]] name = "tokio-stream" version = "0.1.14" @@ -4291,9 +4156,9 @@ dependencies = [ [[package]] name = "tokio-tungstenite" -version = "0.19.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec509ac96e9a0c43427c74f003127d953a265737636129424288d27cb5c4b12c" +checksum = "2b2dbec703c26b00d74844519606ef15d09a7d6857860f84ad223dec002ddea2" dependencies = [ "futures-util", "log", @@ -4307,7 +4172,7 @@ version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" dependencies = [ - "bytes 1.4.0", + "bytes 1.5.0", "futures-core", "futures-io", "futures-sink", @@ -4328,9 +4193,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.7.6" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c17e963a819c331dcacd7ab957d80bc2b9a9c1e71c804826d2f283dd65306542" +checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257" dependencies = [ "serde", "serde_spanned", @@ -4349,9 +4214,9 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.19.14" +version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8123f27e969974a3dfba720fdb560be359f57b44302d280ba72e76a74480e8a" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ "indexmap 2.0.0", "serde", @@ -4387,7 +4252,7 @@ checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.33", ] [[package]] @@ -4468,12 +4333,12 @@ checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" [[package]] name = "tungstenite" -version = "0.19.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15fba1a6d6bb030745759a9a2a588bfe8490fc8b4751a277db3a0be1c9ebbf67" +checksum = "e862a1c4128df0112ab625f55cd5c934bcb4312ba80b39ae4b4835a3fd58e649" dependencies = [ "byteorder", - "bytes 1.4.0", + "bytes 1.5.0", "data-encoding", "http", "httparse", @@ -4514,9 +4379,9 @@ checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" [[package]] name = "unicode-ident" -version = "1.0.11" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "unicode-normalization" @@ -4547,9 +4412,9 @@ checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" [[package]] name = "unsigned-varint" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d86a8dc7f45e4c1b0d30e43038c38f274e77af056aa5f74b93c2cf9eb3c1c836" +checksum = "6889a77d49f1f013504cec6bf97a2c730394adedaeb1deb5ea08949a50541105" [[package]] name = "untrusted" @@ -4559,9 +4424,9 @@ checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" [[package]] name = "url" -version = "2.4.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb" +checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" dependencies = [ "form_urlencoded", "idna", @@ -4624,12 +4489,6 @@ version = "0.9.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" -[[package]] -name = "wasi" -version = "0.10.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" - [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -4657,7 +4516,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.33", "wasm-bindgen-shared", ] @@ -4691,7 +4550,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.33", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -4704,9 +4563,9 @@ checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" [[package]] name = "wasm-streams" -version = "0.2.3" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bbae3363c08332cadccd13b67db371814cd214c2524020932f0804b8cf7c078" +checksum = "b4609d447824375f43e1ffbc051b50ad8f4b3ae8219680c94452ea05eb240ac7" dependencies = [ "futures-util", "js-sys", @@ -4725,34 +4584,25 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "webpki" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd" -dependencies = [ - "ring", - "untrusted", -] - [[package]] name = "webpki-roots" -version = "0.22.6" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87" +checksum = "b291546d5d9d1eab74f069c77749f2cb8504a12caa20f0f2de93ddbf6f411888" dependencies = [ - "webpki", + "rustls-webpki", ] [[package]] name = "which" -version = "4.4.0" +version = "4.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2441c784c52b289a054b7201fc93253e288f094e2f4be9058343127c4226a269" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" dependencies = [ "either", - "libc", + "home", "once_cell", + "rustix", ] [[package]] @@ -4760,10 +4610,6 @@ name = "whoami" version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22fc3756b8a9133049b26c7f61ab35416c130e8c09b660f5b3958b446f52cc50" -dependencies = [ - "wasm-bindgen", - "web-sys", -] [[package]] name = "winapi" @@ -4781,15 +4627,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -[[package]] -name = "winapi-util" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" -dependencies = [ - "winapi", -] - [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" @@ -4816,9 +4653,9 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.48.1" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ "windows_aarch64_gnullvm", "windows_aarch64_msvc", @@ -4831,62 +4668,63 @@ dependencies = [ [[package]] name = "windows_aarch64_gnullvm" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_i686_gnu" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_x86_64_gnu" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnullvm" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "winnow" -version = "0.5.4" +version = "0.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acaaa1190073b2b101e15083c38ee8ec891b5e05cbee516521e94ec008f61e64" +checksum = "7c2e3184b9c4e92ad5167ca73039d0c42476302ab603e2fec4487511f38ccefc" dependencies = [ "memchr", ] [[package]] name = "winreg" -version = "0.10.1" +version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" dependencies = [ - "winapi", + "cfg-if", + "windows-sys", ] [[package]] @@ -4900,23 +4738,9 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4756f7db3f7b5574938c3eb1c117038b8e07f95ee6718c0efad4ac21508f1efd" -dependencies = [ - "zeroize_derive", -] - -[[package]] -name = "zeroize_derive" -version = "1.4.2" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.28", -] +checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" [[package]] name = "zstd-sys" diff --git a/api/Cargo.toml b/api/Cargo.toml index 95c168f..c75d0ec 100644 --- a/api/Cargo.toml +++ b/api/Cargo.toml @@ -17,7 +17,7 @@ categories = ["cryptography::cryptocurrencies", "web-programming"] [lib] [dependencies] -sea-orm = { version = "^0.10.0", features = [ +sea-orm = { version = "0.12.2", features = [ "debug-print", "runtime-tokio-rustls", "sqlx-postgres", @@ -31,7 +31,7 @@ async-graphql = { version = "5.0.4", features = [ ] } serde = { version = "1.0.152", features = ["derive"] } serde_json = "1.0.93" -solana-program = "1.15.0" +solana-program = "1" poem = { version = "1.3.50", features = ["anyhow", "test"] } async-graphql-poem = "5.0.3" prost = "0.11.9" @@ -42,7 +42,7 @@ strum = { version = "0.24.1", features = ["derive"] } [dependencies.hub-core] package = "holaplex-hub-core" -version = "0.5.3" +version = "0.5.4" git = "https://github.com/holaplex/hub-core" branch = "stable" features = ["kafka", "credits", "asset_proxy", "sea-orm"] diff --git a/api/src/entities/sea_orm_active_enums.rs b/api/src/entities/sea_orm_active_enums.rs index a453bc0..69989a4 100644 --- a/api/src/entities/sea_orm_active_enums.rs +++ b/api/src/entities/sea_orm_active_enums.rs @@ -47,17 +47,12 @@ pub enum CreationStatus { Queued, } -#[derive(Debug, Clone, PartialEq, Eq, EnumIter, DeriveActiveEnum, Enum, Copy)] +#[derive(Debug, Clone, Default, PartialEq, Eq, EnumIter, DeriveActiveEnum, Enum, Copy)] #[sea_orm(rs_type = "String", db_type = "Enum", enum_name = "drop_type")] pub enum DropType { + #[default] #[sea_orm(string_value = "edition")] Edition, #[sea_orm(string_value = "open")] Open, } - -impl Default for DropType { - fn default() -> Self { - DropType::Edition - } -} diff --git a/api/src/events.rs b/api/src/events.rs index 62d4c20..7da54e5 100644 --- a/api/src/events.rs +++ b/api/src/events.rs @@ -522,7 +522,7 @@ impl Processor { let created_at = timestamp .and_then(|t| { - Some(DateTime::from_utc( + Some(DateTime::from_naive_utc_and_offset( NaiveDateTime::from_timestamp_opt(t.seconds, t.nanos.try_into().ok()?)?, Utc.fix(), )) @@ -863,7 +863,7 @@ impl Processor { } async fn mint_updated(&self, id: String, payload: UpdateResult) -> ProcessResult<()> { - let update_history = UpdateHistories::find_by_id(id.parse()?) + let update_history = UpdateHistories::find_by_id(Uuid::from_str(&id)?) .one(self.db.get()) .await? .ok_or(ProcessorErrorKind::DbMissingUpdateHistory)?; diff --git a/api/src/mutations/collection.rs b/api/src/mutations/collection.rs index b8bafbc..574ed91 100644 --- a/api/src/mutations/collection.rs +++ b/api/src/mutations/collection.rs @@ -598,7 +598,7 @@ pub async fn fetch_owner( let owner = wallet .ok_or(Error::new(format!( - "no project wallet found for {blockchain} blockchain" + "no project wallet found for {blockchain:?} blockchain" )))? .wallet_address; Ok(owner) diff --git a/api/src/mutations/drop.rs b/api/src/mutations/drop.rs index 9e900df..0a68410 100644 --- a/api/src/mutations/drop.rs +++ b/api/src/mutations/drop.rs @@ -664,7 +664,7 @@ async fn fetch_owner( let owner = wallet .ok_or(Error::new(format!( - "no project wallet found for {blockchain} blockchain" + "no project wallet found for {blockchain:?} blockchain" )))? .wallet_address; Ok(owner) diff --git a/api/src/mutations/mint.rs b/api/src/mutations/mint.rs index 2b33ed3..71b6f28 100644 --- a/api/src/mutations/mint.rs +++ b/api/src/mutations/mint.rs @@ -6,7 +6,11 @@ use hub_core::{ credits::{CreditsClient, TransactionId}, producer::Producer, }; -use sea_orm::{prelude::*, JoinType, Order, QueryOrder, QuerySelect, Set, TransactionTrait}; +use sea_orm::{ + prelude::*, + sea_query::{Func, SimpleExpr}, + JoinType, Order, QueryOrder, QuerySelect, Set, TransactionTrait, +}; use super::collection::{ fetch_owner, validate_creators, validate_json, validate_solana_creator_verification, @@ -100,7 +104,7 @@ impl Mutation { let owner_address = wallet .ok_or(Error::new(format!( - "no project wallet found for {} blockchain", + "no project wallet found for {:?} blockchain", collection.blockchain )))? .wallet_address; @@ -280,7 +284,7 @@ impl Mutation { let owner_address = wallet .ok_or(Error::new(format!( - "no project wallet found for {} blockchain", + "no project wallet found for {:?} blockchain", collection.blockchain )))? .wallet_address; @@ -1095,7 +1099,7 @@ impl Mutation { .select_also(collections::Entity) .filter(collection_mints::Column::CollectionId.eq(drop.collection_id)) .filter(collection_mints::Column::CreationStatus.eq(CreationStatus::Queued)) - .order_by(sea_orm::sea_query::Func::random(), Order::Asc) + .order_by(SimpleExpr::FunctionCall(Func::random()), Order::Asc) .one(conn) .await? .ok_or(Error::new("No Queued mint found for the drop"))?; diff --git a/migration/Cargo.toml b/migration/Cargo.toml index 3a06bbc..c3ae2b0 100644 --- a/migration/Cargo.toml +++ b/migration/Cargo.toml @@ -25,7 +25,7 @@ name = "migration" tokio = { version = "1.22.0", features = ["macros"] } [dependencies.sea-orm-migration] -version = "^0.10.0" +version = "0.12.2" features = [ "runtime-tokio-rustls", "sqlx-postgres", From 9f3100a07af13fb338924c12b341345c5e6e6316 Mon Sep 17 00:00:00 2001 From: mpw Date: Thu, 14 Sep 2023 15:11:49 -0300 Subject: [PATCH 10/20] implement mint time metrics (#223) * implement mint time metrics * make clippy happy * add label with mint status * fix cargo lock --- .github/workflows/cargo.yml | 2 +- .gitignore | 2 +- Cargo.lock | 133 ++++++++++++++++++++++++++++++++++-- Cargo.toml | 2 +- api/Cargo.toml | 5 +- api/src/events.rs | 20 +++++- api/src/handlers.rs | 20 +++++- api/src/lib.rs | 5 ++ api/src/main.rs | 22 ++++-- api/src/metrics.rs | 47 +++++++++++++ api/src/mutations/mint.rs | 3 +- migration/Cargo.toml | 6 +- 12 files changed, 241 insertions(+), 26 deletions(-) create mode 100644 api/src/metrics.rs diff --git a/.github/workflows/cargo.yml b/.github/workflows/cargo.yml index 0101f95..b70bd85 100644 --- a/.github/workflows/cargo.yml +++ b/.github/workflows/cargo.yml @@ -38,7 +38,7 @@ jobs: - name: Install latest nightly uses: actions-rs/toolchain@v1 with: - toolchain: nightly-2022-12-11 + toolchain: 1.71.0 override: true components: rustfmt, clippy diff --git a/.gitignore b/.gitignore index 1bbc4c4..d6c7de5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ /target/ .env.local keypair.json -.vscode \ No newline at end of file +.vscode diff --git a/Cargo.lock b/Cargo.lock index b7e6b09..a6a3ea0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -814,6 +814,16 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9cace84e55f07e7301bae1c519df89cdad8cc3cd868413d3fdbdeca9ff3db484" +[[package]] +name = "crossbeam-channel" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + [[package]] name = "crossbeam-queue" version = "0.3.8" @@ -1529,8 +1539,8 @@ dependencies = [ [[package]] name = "holaplex-hub-core" -version = "0.5.4" -source = "git+https://github.com/holaplex/hub-core?branch=stable#1122dc679042e397360da0f85b20babff4c7ea12" +version = "0.5.5" +source = "git+https://github.com/holaplex/hub-core#be11206ecb91d819d5ebf34c00eb8a1294f54026" dependencies = [ "anyhow", "async-trait", @@ -1545,7 +1555,11 @@ dependencies = [ "holaplex-hub-core-schemas", "hostname", "num_cpus", + "opentelemetry", + "opentelemetry-prometheus", + "opentelemetry_sdk", "pin-project-lite", + "prometheus", "prost", "prost-types", "rand 0.8.5", @@ -1584,10 +1598,29 @@ dependencies = [ "url", ] +[[package]] +name = "holaplex-hub-core-build" +version = "0.2.1" +source = "git+https://github.com/holaplex/hub-core#be11206ecb91d819d5ebf34c00eb8a1294f54026" +dependencies = [ + "anyhow", + "dotenv", + "futures-util", + "hex", + "prost-build", + "reqwest", + "serde", + "sha2 0.10.7", + "tempfile", + "tokio", + "toml 0.5.11", + "url", +] + [[package]] name = "holaplex-hub-core-macros" version = "0.1.0" -source = "git+https://github.com/holaplex/hub-core?branch=stable#1122dc679042e397360da0f85b20babff4c7ea12" +source = "git+https://github.com/holaplex/hub-core#be11206ecb91d819d5ebf34c00eb8a1294f54026" dependencies = [ "proc-macro2", "quote", @@ -1598,9 +1631,9 @@ dependencies = [ [[package]] name = "holaplex-hub-core-schemas" version = "0.3.2" -source = "git+https://github.com/holaplex/hub-core?branch=stable#1122dc679042e397360da0f85b20babff4c7ea12" +source = "git+https://github.com/holaplex/hub-core#be11206ecb91d819d5ebf34c00eb8a1294f54026" dependencies = [ - "holaplex-hub-core-build", + "holaplex-hub-core-build 0.2.1 (git+https://github.com/holaplex/hub-core)", "prost", ] @@ -1612,7 +1645,7 @@ dependencies = [ "async-graphql-poem", "async-trait", "holaplex-hub-core", - "holaplex-hub-core-build", + "holaplex-hub-core-build 0.2.1 (git+https://github.com/holaplex/hub-core?branch=stable)", "poem", "prost", "prost-types", @@ -2334,6 +2367,67 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "opentelemetry" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9591d937bc0e6d2feb6f71a559540ab300ea49955229c347a517a28d27784c54" +dependencies = [ + "opentelemetry_api", + "opentelemetry_sdk", +] + +[[package]] +name = "opentelemetry-prometheus" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7d81bc254e2d572120363a2b16cdb0d715d301b5789be0cfc26ad87e4e10e53" +dependencies = [ + "once_cell", + "opentelemetry_api", + "opentelemetry_sdk", + "prometheus", + "protobuf", +] + +[[package]] +name = "opentelemetry_api" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a81f725323db1b1206ca3da8bb19874bbd3f57c3bcd59471bfb04525b265b9b" +dependencies = [ + "futures-channel", + "futures-util", + "indexmap 1.9.3", + "js-sys", + "once_cell", + "pin-project-lite", + "thiserror", + "urlencoding", +] + +[[package]] +name = "opentelemetry_sdk" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa8e705a0612d48139799fcbaba0d4a90f06277153e43dd2bdc16c6f0edd8026" +dependencies = [ + "async-trait", + "crossbeam-channel", + "futures-channel", + "futures-executor", + "futures-util", + "once_cell", + "opentelemetry_api", + "ordered-float", + "percent-encoding", + "rand 0.8.5", + "regex", + "thiserror", + "tokio", + "tokio-stream", +] + [[package]] name = "ordered-float" version = "3.9.1" @@ -2675,6 +2769,21 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "prometheus" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "449811d15fbdf5ceb5c1144416066429cf82316e2ec8ce0c1f6f8a02e7bbcf8c" +dependencies = [ + "cfg-if", + "fnv", + "lazy_static", + "memchr", + "parking_lot", + "protobuf", + "thiserror", +] + [[package]] name = "prost" version = "0.11.9" @@ -2729,6 +2838,12 @@ dependencies = [ "prost", ] +[[package]] +name = "protobuf" +version = "2.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "106dd99e98437432fed6519dedecfade6a06a73bb7b2a1e019fdd2bee5778d94" + [[package]] name = "ptr_meta" version = "0.1.4" @@ -4434,6 +4549,12 @@ dependencies = [ "serde", ] +[[package]] +name = "urlencoding" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" + [[package]] name = "utf-8" version = "0.7.6" diff --git a/Cargo.toml b/Cargo.toml index 6a72d43..3b2f56a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,3 +1,3 @@ [workspace] members = ["api", "migration"] -resolver = "2" \ No newline at end of file +resolver = "2" diff --git a/api/Cargo.toml b/api/Cargo.toml index c75d0ec..1d22fc5 100644 --- a/api/Cargo.toml +++ b/api/Cargo.toml @@ -42,10 +42,9 @@ strum = { version = "0.24.1", features = ["derive"] } [dependencies.hub-core] package = "holaplex-hub-core" -version = "0.5.4" +version = "0.5.5" git = "https://github.com/holaplex/hub-core" -branch = "stable" -features = ["kafka", "credits", "asset_proxy", "sea-orm"] +features = ["kafka", "credits", "asset_proxy", "sea-orm", "metrics"] [build-dependencies.hub-core-build] package = "holaplex-hub-core-build" diff --git a/api/src/events.rs b/api/src/events.rs index 7da54e5..bd73902 100644 --- a/api/src/events.rs +++ b/api/src/events.rs @@ -1,6 +1,7 @@ use hub_core::{ chrono::{DateTime, NaiveDateTime, Offset, Utc}, credits::{CreditsClient, TransactionId}, + metrics::KeyValue, prelude::*, producer::Producer, thiserror, @@ -26,6 +27,7 @@ use crate::{ sea_orm_active_enums::{Blockchain, CreationStatus}, switch_collection_histories, transfer_charges, update_histories, }, + metrics::Metrics, proto::{ nft_events::Event as NftEvent, polygon_nft_events::Event as PolygonNftEvents, @@ -113,6 +115,7 @@ pub struct Processor { pub db: Connection, pub credits: CreditsClient, pub producer: Producer, + pub metrics: Metrics, } #[derive(Clone)] @@ -151,16 +154,17 @@ impl Processor { db: Connection, credits: CreditsClient, producer: Producer, + metrics: Metrics, ) -> Self { Self { db, credits, producer, + metrics, } } #[allow(clippy::too_many_lines)] - /// Processes incoming messages related to different services like Treasury and Solana. /// Routes each message to the corresponding handler based on the type of service and the specific event. @@ -817,6 +821,17 @@ impl Processor { creation_status = NftCreationStatus::Failed; } + let now = Utc::now(); + let elapsed = now + .signed_duration_since(collection_mint.created_at) + .num_milliseconds(); + self.metrics + .mint_duration_ms_bucket + .record(elapsed, &[KeyValue::new( + "status", + creation_status.as_str_name(), + )]); + self.producer .send( Some(&NftEvents { @@ -863,7 +878,8 @@ impl Processor { } async fn mint_updated(&self, id: String, payload: UpdateResult) -> ProcessResult<()> { - let update_history = UpdateHistories::find_by_id(Uuid::from_str(&id)?) + let id: Uuid = id.parse()?; + let update_history = UpdateHistories::find_by_id(id) .one(self.db.get()) .await? .ok_or(ProcessorErrorKind::DbMissingUpdateHistory)?; diff --git a/api/src/handlers.rs b/api/src/handlers.rs index d1a32bb..5c3aa37 100644 --- a/api/src/handlers.rs +++ b/api/src/handlers.rs @@ -1,16 +1,22 @@ use async_graphql::http::{playground_source, GraphQLPlaygroundConfig}; use async_graphql_poem::{GraphQLRequest, GraphQLResponse}; -use hub_core::anyhow::Result; +use hub_core::{ + anyhow::Result, + metrics::{Encoder, TextEncoder}, +}; use poem::{ handler, + http::StatusCode, web::{Data, Html}, IntoResponse, }; -use crate::{AppContext, AppState, Balance, OrganizationId, UserID}; +use crate::{AppContext, AppState, Balance, Metrics, OrganizationId, UserID}; #[handler] -pub fn health() {} +pub fn health() -> StatusCode { + StatusCode::OK +} #[handler] pub fn playground() -> impl IntoResponse { @@ -42,3 +48,11 @@ pub async fn graphql_handler( .await .into()) } + +#[handler] +pub fn metrics_handler(Data(metrics): Data<&Metrics>) -> Result { + let mut buffer = vec![]; + let encoder = TextEncoder::new(); + encoder.encode(&metrics.registry.gather(), &mut buffer)?; + Ok(String::from_utf8_lossy(&buffer).into_owned()) +} diff --git a/api/src/lib.rs b/api/src/lib.rs index 7254b3c..6ad411d 100644 --- a/api/src/lib.rs +++ b/api/src/lib.rs @@ -10,6 +10,7 @@ pub mod entities; pub mod events; pub mod handlers; pub mod metadata_json; +pub mod metrics; pub mod mutations; pub mod nft_storage; pub mod objects; @@ -41,6 +42,7 @@ use hub_core::{ tokio, uuid::Uuid, }; +use metrics::Metrics; use mutations::Mutation; use nft_storage::NftStorageClient; use poem::{async_trait, FromRequest, Request, RequestBody}; @@ -239,6 +241,7 @@ pub struct AppState { impl AppState { #[must_use] + #[allow(clippy::too_many_arguments)] pub fn new( schema: AppSchema, connection: Connection, @@ -292,6 +295,7 @@ pub struct AppContext { impl AppContext { #[must_use] + #[allow(clippy::similar_names)] pub fn new( db: Connection, user_id: UserID, @@ -338,6 +342,7 @@ impl AppContext { 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, diff --git a/api/src/main.rs b/api/src/main.rs index 15dcc7c..b7c3369 100644 --- a/api/src/main.rs +++ b/api/src/main.rs @@ -5,7 +5,8 @@ use holaplex_hub_nfts::{ build_schema, db::Connection, events, - handlers::{graphql_handler, health, playground}, + handlers::{graphql_handler, health, metrics_handler, playground}, + metrics::Metrics, nft_storage::NftStorageClient, proto, Actions, AppState, Args, Services, }; @@ -38,8 +39,15 @@ pub fn main() { .await?; let credits = common.credits_cfg.build::().await?; let nft_storage = NftStorageClient::new(nft_storage)?; - let event_processor = - events::Processor::new(connection.clone(), credits.clone(), producer.clone()); + + let metrics = Metrics::new()?; + + let event_processor = events::Processor::new( + connection.clone(), + credits.clone(), + producer.clone(), + metrics.clone(), + ); let solana = Solana::new(producer.clone()); let polygon = Polygon::new(producer.clone()); @@ -72,9 +80,13 @@ pub fn main() { Server::new(TcpListener::bind(format!("0.0.0.0:{port}"))) .run( Route::new() - .at("/graphql", post(graphql_handler).with(AddData::new(state))) + .at( + "/graphql", + post(graphql_handler).with(AddData::new(state.clone())), + ) .at("/playground", get(playground)) - .at("/health", get(health)), + .at("/health", get(health)) + .at("/metrics", get(metrics_handler).with(AddData::new(metrics))), ) .await .context("failed to build graphql server") diff --git a/api/src/metrics.rs b/api/src/metrics.rs new file mode 100644 index 0000000..9533325 --- /dev/null +++ b/api/src/metrics.rs @@ -0,0 +1,47 @@ +#[allow(clippy::wildcard_imports)] +use hub_core::{ + anyhow::{anyhow, Result}, + metrics::*, +}; + +#[derive(Clone)] +pub struct Metrics { + pub registry: Registry, + pub provider: MeterProvider, + pub mint_duration_ms_bucket: Histogram, +} + +impl Metrics { + /// Res + /// # Errors + pub fn new() -> Result { + let registry = Registry::new(); + let exporter = hub_core::metrics::exporter() + .with_registry(registry.clone()) + .with_namespace("hub_nfts") + .build() + .map_err(|e| anyhow!("Failed to build exporter: {}", e))?; + + let provider = MeterProvider::builder() + .with_reader(exporter) + .with_resource(Resource::new(vec![KeyValue::new( + "service.name", + "hub-nfts", + )])) + .build(); + + let meter = provider.meter("hub-nfts"); + + let mint_duration_ms_bucket = meter + .i64_histogram("mint.time") + .with_unit(Unit::new("ms")) + .with_description("Mint duration time in milliseconds.") + .init(); + + Ok(Self { + registry, + provider, + mint_duration_ms_bucket, + }) + } +} diff --git a/api/src/mutations/mint.rs b/api/src/mutations/mint.rs index 71b6f28..76085c5 100644 --- a/api/src/mutations/mint.rs +++ b/api/src/mutations/mint.rs @@ -744,7 +744,8 @@ impl Mutation { }) } - // Retries a mint which failed by passing its ID. + /// Retries a mint which failed by passing its ID. + /// # Errors pub async fn retry_mint_to_collection( &self, ctx: &Context<'_>, diff --git a/migration/Cargo.toml b/migration/Cargo.toml index c3ae2b0..6ab8d30 100644 --- a/migration/Cargo.toml +++ b/migration/Cargo.toml @@ -22,11 +22,11 @@ name = "migration" [dependencies] -tokio = { version = "1.22.0", features = ["macros"] } +tokio = { version = "1.32.0", features = ["macros"] } [dependencies.sea-orm-migration] version = "0.12.2" features = [ "runtime-tokio-rustls", - "sqlx-postgres", -] + "sqlx-postgres", +] \ No newline at end of file From fd86a9c464959f957a585ab90fc04cc41aa3e8de Mon Sep 17 00:00:00 2001 From: imabdulbasit Date: Fri, 15 Sep 2023 16:26:02 +0500 Subject: [PATCH 11/20] open drop queries --- api/src/dataloaders/collection_mints.rs | 47 ++++++++++++++++++- api/src/dataloaders/mod.rs | 2 +- api/src/lib.rs | 5 +- api/src/objects/drop.rs | 14 +++++- migration/src/lib.rs | 2 + ...111128_create_mints_creation_status_idx.rs | 26 ++++++++++ 6 files changed, 90 insertions(+), 6 deletions(-) create mode 100644 migration/src/m20230915_111128_create_mints_creation_status_idx.rs diff --git a/api/src/dataloaders/collection_mints.rs b/api/src/dataloaders/collection_mints.rs index 5924358..ede98b2 100644 --- a/api/src/dataloaders/collection_mints.rs +++ b/api/src/dataloaders/collection_mints.rs @@ -2,9 +2,13 @@ use std::{borrow::Cow, collections::HashMap}; use async_graphql::{dataloader::Loader as DataLoader, FieldError, Result}; use poem::async_trait; -use sea_orm::prelude::*; +use sea_orm::{prelude::*, JoinType, QuerySelect}; -use crate::{db::Connection, entities::collection_mints, objects::CollectionMint}; +use crate::{ + db::Connection, + entities::{collection_mints, collections, drops, sea_orm_active_enums::CreationStatus}, + objects::CollectionMint, +}; #[derive(Debug, Clone)] pub struct Loader { @@ -28,6 +32,7 @@ impl DataLoader for Loader { .filter( collection_mints::Column::CollectionId.is_in(keys.iter().map(ToOwned::to_owned)), ) + .filter(collection_mints::Column::CreationStatus.ne(CreationStatus::Queued)) .all(self.db.get()) .await?; @@ -113,3 +118,41 @@ impl DataLoader for CollectionMintLoader { .collect()) } } + +/// Dataloader for queued mints for a drop +#[derive(Debug, Clone)] +pub struct QueuedMintsLoader { + pub db: Connection, +} + +impl QueuedMintsLoader { + #[must_use] + pub fn new(db: Connection) -> Self { + Self { db } + } +} + +#[async_trait] +impl DataLoader for QueuedMintsLoader { + type Error = FieldError; + type Value = Vec; + + async fn load(&self, keys: &[Uuid]) -> Result, Self::Error> { + let drop_mints = drops::Entity::find() + .select_with(collection_mints::Entity) + .join( + JoinType::InnerJoin, + collection_mints::Relation::Collections.def(), + ) + .join(JoinType::InnerJoin, collections::Relation::Drop.def()) + .filter(collection_mints::Column::CreationStatus.eq(CreationStatus::Queued)) + .filter(drops::Column::Id.is_in(keys.iter().map(ToOwned::to_owned))) + .all(self.db.get()) + .await?; + + Ok(drop_mints + .into_iter() + .map(|(drop, mints)| (drop.id, mints.into_iter().map(Into::into).collect())) + .collect()) + } +} diff --git a/api/src/dataloaders/mod.rs b/api/src/dataloaders/mod.rs index b2244cb..f6648c7 100644 --- a/api/src/dataloaders/mod.rs +++ b/api/src/dataloaders/mod.rs @@ -18,7 +18,7 @@ pub use collection::Loader as CollectionLoader; pub use collection_drop::Loader as CollectionDropLoader; pub use collection_mints::{ CollectionMintLoader, Loader as CollectionMintsLoader, - OwnerLoader as CollectionMintsOwnerLoader, + OwnerLoader as CollectionMintsOwnerLoader, QueuedMintsLoader, }; pub use creators::Loader as CreatorsLoader; pub use drop::Loader as DropLoader; diff --git a/api/src/lib.rs b/api/src/lib.rs index 6ad411d..51ea412 100644 --- a/api/src/lib.rs +++ b/api/src/lib.rs @@ -27,7 +27,7 @@ use dataloaders::{ CollectionMintMintHistoryLoader, CollectionMintTransfersLoader, CollectionMintsLoader, CollectionMintsOwnerLoader, CreatorsLoader, DropLoader, DropMintHistoryLoader, HoldersLoader, MetadataJsonAttributesLoader, MetadataJsonLoader, MintCreatorsLoader, MinterMintHistoryLoader, - ProjectCollectionLoader, ProjectCollectionsLoader, ProjectDropsLoader, + ProjectCollectionLoader, ProjectCollectionsLoader, ProjectDropsLoader, QueuedMintsLoader, SwitchCollectionHistoryLoader, UpdateMintHistoryLoader, }; use db::Connection; @@ -291,6 +291,7 @@ pub struct AppContext { collection_mint_mint_history_loader: DataLoader, collection_mint_transfers_loader: DataLoader, switch_collection_history_loader: DataLoader, + queued_mints_loader: DataLoader, } impl AppContext { @@ -342,6 +343,7 @@ impl AppContext { DataLoader::new(CollectionMintTransfersLoader::new(db.clone()), tokio::spawn); let switch_collection_history_loader = DataLoader::new(SwitchCollectionHistoryLoader::new(db.clone()), tokio::spawn); + let queued_mints_loader = DataLoader::new(QueuedMintsLoader::new(db.clone()), tokio::spawn); Self { db, @@ -369,6 +371,7 @@ impl AppContext { collection_mint_mint_history_loader, collection_mint_transfers_loader, switch_collection_history_loader, + queued_mints_loader, } } } diff --git a/api/src/objects/drop.rs b/api/src/objects/drop.rs index 3286ef1..200330b 100644 --- a/api/src/objects/drop.rs +++ b/api/src/objects/drop.rs @@ -2,7 +2,7 @@ use async_graphql::{Context, Enum, Error, Object, Result}; use hub_core::chrono::Utc; use sea_orm::entity::prelude::*; -use super::Collection; +use super::{Collection, CollectionMint}; use crate::{ entities::{collections, drops, mint_histories, sea_orm_active_enums::CreationStatus}, AppContext, @@ -88,10 +88,11 @@ impl Drop { let paused_at = self.drop.paused_at; let shutdown_at = self.drop.shutdown_at; + let total_mints = self.collection.total_mints; let minted = self .collection .supply - .map(|supply| supply == self.collection.total_mints); + .map(|supply| supply == total_mints && total_mints > 0); match ( scheduled, @@ -125,6 +126,15 @@ impl Drop { } } + async fn queued_mints(&self, ctx: &Context<'_>) -> Result>> { + let AppContext { + queued_mints_loader, + .. + } = ctx.data::()?; + + queued_mints_loader.load_one(self.drop.id).await + } + #[graphql(deprecation = "Use `mint_histories` under `Collection` Object instead.")] /// A list of all NFT purchases from this drop. async fn purchases(&self, ctx: &Context<'_>) -> Result>> { diff --git a/migration/src/lib.rs b/migration/src/lib.rs index f227465..46e80fd 100644 --- a/migration/src/lib.rs +++ b/migration/src/lib.rs @@ -57,6 +57,7 @@ mod m20230905_100852_add_type_to_drop; mod m20230910_204731_add_queued_variant_to_mints_status; mod m20230910_212742_make_owner_address_optional_for_mint; mod m20230911_144938_make_compressed_column_optional; +mod m20230915_111128_create_mints_creation_status_idx; pub struct Migrator; @@ -121,6 +122,7 @@ impl MigratorTrait for Migrator { Box::new(m20230910_204731_add_queued_variant_to_mints_status::Migration), Box::new(m20230910_212742_make_owner_address_optional_for_mint::Migration), Box::new(m20230911_144938_make_compressed_column_optional::Migration), + Box::new(m20230915_111128_create_mints_creation_status_idx::Migration), ] } } diff --git a/migration/src/m20230915_111128_create_mints_creation_status_idx.rs b/migration/src/m20230915_111128_create_mints_creation_status_idx.rs new file mode 100644 index 0000000..5b603af --- /dev/null +++ b/migration/src/m20230915_111128_create_mints_creation_status_idx.rs @@ -0,0 +1,26 @@ +use sea_orm_migration::prelude::*; + +use crate::m20230220_223223_create_collection_mints_table::CollectionMints; + +#[derive(DeriveMigrationName)] +pub struct Migration; + +#[async_trait::async_trait] +impl MigrationTrait for Migration { + async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { + manager + .create_index( + IndexCreateStatement::new() + .name("collection-mints-creation-status-idx") + .table(CollectionMints::Table) + .col(CollectionMints::CreationStatus) + .index_type(IndexType::BTree) + .to_owned(), + ) + .await + } + + async fn down(&self, _manager: &SchemaManager) -> Result<(), DbErr> { + Ok(()) + } +} From 02c082a2ee9e70805d51bf91dc2ef1b9ff38c867 Mon Sep 17 00:00:00 2001 From: imabdulbasit Date: Sat, 16 Sep 2023 02:56:17 +0500 Subject: [PATCH 12/20] Fix queued mints dataloader --- api/src/dataloaders/collection_mints.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/src/dataloaders/collection_mints.rs b/api/src/dataloaders/collection_mints.rs index ede98b2..22a1383 100644 --- a/api/src/dataloaders/collection_mints.rs +++ b/api/src/dataloaders/collection_mints.rs @@ -140,11 +140,11 @@ impl DataLoader for QueuedMintsLoader { async fn load(&self, keys: &[Uuid]) -> Result, Self::Error> { let drop_mints = drops::Entity::find() .select_with(collection_mints::Entity) + .join(JoinType::InnerJoin, drops::Relation::Collections.def()) .join( JoinType::InnerJoin, - collection_mints::Relation::Collections.def(), + collections::Relation::CollectionMints.def(), ) - .join(JoinType::InnerJoin, collections::Relation::Drop.def()) .filter(collection_mints::Column::CreationStatus.eq(CreationStatus::Queued)) .filter(drops::Column::Id.is_in(keys.iter().map(ToOwned::to_owned))) .all(self.db.get()) From 7d219d44ac181a0ca773a70bee8531e877566673 Mon Sep 17 00:00:00 2001 From: Kyle Espinola Date: Mon, 18 Sep 2023 14:31:22 +0200 Subject: [PATCH 13/20] fix: only check no zero supploy on edition type. increment supply when queue mint to open drop. increment total mints when user mints queued for open drop. --- api/src/mutations/drop.rs | 2 +- api/src/mutations/mint.rs | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/api/src/mutations/drop.rs b/api/src/mutations/drop.rs index 0a68410..63882aa 100644 --- a/api/src/mutations/drop.rs +++ b/api/src/mutations/drop.rs @@ -703,7 +703,7 @@ impl CreateDropInput { /// # Errors /// - Err with an appropriate error message if any validation fails. pub fn validate(&self) -> Result<()> { - if self.supply == Some(0) { + if self.supply == Some(0) && self.drop_type == DropType::Edition { return Err(Error::new("Supply must be greater than 0 or undefined")); }; diff --git a/api/src/mutations/mint.rs b/api/src/mutations/mint.rs index 76085c5..a6eab6d 100644 --- a/api/src/mutations/mint.rs +++ b/api/src/mutations/mint.rs @@ -875,6 +875,12 @@ impl Mutation { let collection_model = collection.ok_or(Error::new("collection not found"))?; + let mut collection_am: collections::ActiveModel = collection_model.clone().into(); + + collection_am.supply = Set(collection_model.supply.map(|supply| supply.add(1))); + + collection_am.update(conn).await?; + let mint = collection_mints::ActiveModel { collection_id: Set(drop.collection_id), owner: Set(None), @@ -990,6 +996,10 @@ impl Mutation { ) .await?; + let mut collection_am = collections::ActiveModel::from(collection.clone()); + collection_am.total_mints = Set(collection.total_mints.add(1)); + collection_am.update(conn).await?; + match collection.blockchain { BlockchainEnum::Solana => { solana @@ -1136,6 +1146,10 @@ impl Mutation { ) .await?; + let mut collection_am = collections::ActiveModel::from(collection.clone()); + collection_am.total_mints = Set(collection.total_mints.add(1)); + collection_am.update(conn).await?; + match collection.blockchain { BlockchainEnum::Solana => { solana From abab893232da58b902cfd7f503d4e85b8e220c79 Mon Sep 17 00:00:00 2001 From: Kyle Espinola Date: Mon, 18 Sep 2023 15:16:33 +0200 Subject: [PATCH 14/20] feat: allow user to access the drop type field on the drop --- api/src/objects/drop.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/api/src/objects/drop.rs b/api/src/objects/drop.rs index 200330b..500aed5 100644 --- a/api/src/objects/drop.rs +++ b/api/src/objects/drop.rs @@ -4,7 +4,10 @@ use sea_orm::entity::prelude::*; use super::{Collection, CollectionMint}; use crate::{ - entities::{collections, drops, mint_histories, sea_orm_active_enums::CreationStatus}, + entities::{ + collections, drops, mint_histories, + sea_orm_active_enums::{CreationStatus, DropType}, + }, AppContext, }; /// An NFT campaign that controls the minting rules for a collection, such as its start date and end date. @@ -28,6 +31,11 @@ impl Drop { self.drop.id } + // The type of the drop. + async fn drop_type(&self) -> DropType { + self.drop.drop_type + } + /// The identifier of the project to which the drop is associated. async fn project_id(&self) -> Uuid { self.drop.project_id From a48f8f5f1f2e4eeb3c7ee54f6817e88dd3c1155b Mon Sep 17 00:00:00 2001 From: imabdulbasit Date: Tue, 19 Sep 2023 16:59:46 +0500 Subject: [PATCH 15/20] Save deduction id for queued mints & filter holders where owner is null --- api/src/dataloaders/holders.rs | 1 + api/src/mutations/mint.rs | 22 ++++++++++++---------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/api/src/dataloaders/holders.rs b/api/src/dataloaders/holders.rs index 46914b8..dbed271 100644 --- a/api/src/dataloaders/holders.rs +++ b/api/src/dataloaders/holders.rs @@ -28,6 +28,7 @@ impl DataLoader for Loader { .filter( collection_mints::Column::CollectionId.is_in(keys.iter().map(ToOwned::to_owned)), ) + .filter(collection_mints::Column::Owner.is_not_null()) .select_only() .column(collection_mints::Column::CollectionId) .column_as(collection_mints::Column::Owner, "address") diff --git a/api/src/mutations/mint.rs b/api/src/mutations/mint.rs index a6eab6d..c60cfd9 100644 --- a/api/src/mutations/mint.rs +++ b/api/src/mutations/mint.rs @@ -986,7 +986,7 @@ impl Mutation { Actions::Mint }; - let TransactionId(_) = credits + let TransactionId(deduction_id) = credits .submit_pending_deduction( org_id, user_id, @@ -1000,6 +1000,11 @@ impl Mutation { collection_am.total_mints = Set(collection.total_mints.add(1)); collection_am.update(conn).await?; + let mut mint_am: collection_mints::ActiveModel = mint.clone().into(); + mint_am.credits_deduction_id = Set(Some(deduction_id)); + mint_am.creation_status = Set(CreationStatus::Pending); + mint_am.update(conn).await?; + match collection.blockchain { BlockchainEnum::Solana => { solana @@ -1027,10 +1032,6 @@ impl Mutation { }, }; - let mut mint_am: collection_mints::ActiveModel = mint.into(); - mint_am.creation_status = Set(CreationStatus::Pending); - let mint = mint_am.update(conn).await?; - let drop = drops::Entity::find() .filter(drops::Column::CollectionId.eq(collection.id)) .one(conn) @@ -1136,7 +1137,7 @@ impl Mutation { .all(conn) .await?; - let TransactionId(_) = credits + let TransactionId(deduction_id) = credits .submit_pending_deduction( org_id, user_id, @@ -1150,6 +1151,11 @@ impl Mutation { collection_am.total_mints = Set(collection.total_mints.add(1)); collection_am.update(conn).await?; + let mut mint_am: collection_mints::ActiveModel = mint.clone().into(); + mint_am.credits_deduction_id = Set(Some(deduction_id)); + mint_am.creation_status = Set(CreationStatus::Pending); + mint_am.update(conn).await?; + match collection.blockchain { BlockchainEnum::Solana => { solana @@ -1177,10 +1183,6 @@ impl Mutation { }, }; - let mut mint_am: collection_mints::ActiveModel = mint.into(); - mint_am.creation_status = Set(CreationStatus::Pending); - let mint = mint_am.update(conn).await?; - let mint_history_am = mint_histories::ActiveModel { mint_id: Set(mint.id), wallet: Set(input.recipient), From 0c28335cf2369c149b41395bd4164c2ffcadc165 Mon Sep 17 00:00:00 2001 From: imabdulbasit Date: Tue, 19 Sep 2023 19:36:41 +0500 Subject: [PATCH 16/20] Emit DropMinted event with Queued status --- api/proto.lock | 4 ++-- api/proto.toml | 2 +- api/src/mutations/mint.rs | 17 +++++++++++++++++ 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/api/proto.lock b/api/proto.lock index d5d8369..2fbdf20 100644 --- a/api/proto.lock +++ b/api/proto.lock @@ -5,8 +5,8 @@ sha512 = "d75800df0d4744c6b0f4d9a9952d3bfd0bb6b24a8babd19104cc11b54a525f85551b3c [[schemas]] subject = "nfts" -version = 29 -sha512 = "b3b2136bd6c7a136d317da84395661de5fc056e8270510575a3281d78884d99a0d89f444754ed02cb18ad26dcc7cd65300c1df73b9d74d2edc6bcc8d552465d0" +version = 30 +sha512 = "bee70bd6f0f18a8049f93bceb9c4b500b49352f9d19d55d5a411da92cbd786c88bec47f73e1ef6946ceefc7de8e558f704bf8187be9d9f4e49bd102baec29327" [[schemas]] subject = "organization" diff --git a/api/proto.toml b/api/proto.toml index e66a353..44a45d7 100644 --- a/api/proto.toml +++ b/api/proto.toml @@ -3,7 +3,7 @@ endpoint = "https://schemas.holaplex.tools" [schemas] organization = 5 -nfts = 29 +nfts = 30 customer = 2 treasury = 23 solana_nfts = 11 diff --git a/api/src/mutations/mint.rs b/api/src/mutations/mint.rs index c60cfd9..c60aa39 100644 --- a/api/src/mutations/mint.rs +++ b/api/src/mutations/mint.rs @@ -863,6 +863,7 @@ impl Mutation { let conn = db.get(); let nft_storage = ctx.data::()?; + let nfts_producer = ctx.data::>()?; let UserID(id) = user_id; let user_id = id.ok_or(Error::new("X-USER-ID header not found"))?; @@ -918,6 +919,22 @@ impl Mutation { .exec(conn) .await?; + nfts_producer + .send( + Some(&NftEvents { + event: Some(NftEvent::DropMinted(MintCreation { + drop_id: drop.id.to_string(), + status: NftCreationStatus::Queued as i32, + })), + }), + Some(&NftEventKey { + id: mint_model.id.to_string(), + project_id: drop.project_id.to_string(), + user_id: user_id.to_string(), + }), + ) + .await?; + Ok(QueueMintToDropPayload { collection_mint: mint_model.into(), }) From 61ab6af695fe07b96fc296e2b280f47461bef5ef Mon Sep 17 00:00:00 2001 From: mpw Date: Tue, 19 Sep 2023 14:07:08 -0300 Subject: [PATCH 17/20] use stable branch for hub-core --- Cargo.lock | 109 ++++++++++++++++++++----------------------------- api/Cargo.toml | 1 + 2 files changed, 46 insertions(+), 64 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a6a3ea0..aecea8a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -52,9 +52,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.0.5" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c378d78423fdad8089616f827526ee33c19f2fddbd5de1629152c9593ba4783" +checksum = "0f2135563fb5c609d2b2b87c1e8ce7bc41b0b45430fa9661f457981503dd5bf0" dependencies = [ "memchr", ] @@ -272,7 +272,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.37", ] [[package]] @@ -283,7 +283,7 @@ checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.37", ] [[package]] @@ -566,9 +566,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.13.0" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" [[package]] name = "bv" @@ -619,7 +619,7 @@ checksum = "965ab7eb5f8f97d2a083c799f3a1b994fc397b2fe2da5d1da1626ce15a39f2b1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.37", ] [[package]] @@ -661,9 +661,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.30" +version = "0.4.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "defd4e7873dbddba6c7c91e199c7fcb946abc4a6a4ac3195400bcfb01b5de877" +checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" dependencies = [ "android-tzdata", "iana-time-zone", @@ -689,9 +689,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.3" +version = "4.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84ed82781cea27b43c9b106a979fe450a13a31aab0500595fb3fc06616de08e6" +checksum = "b1d7b8d5ec32af0fadc644bf1fd509a688c2103b185644bb1e29d164e0703136" dependencies = [ "clap_builder", "clap_derive", @@ -699,9 +699,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.2" +version = "4.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bb9faaa7c2ef94b2743a21f5a29e6f0010dff4caa69ac8e9d6cf8b6fa74da08" +checksum = "5179bb514e4d7c2051749d8fcefa2ed6d06a9f4e6d69faf3805f5d80b8cf8d56" dependencies = [ "anstream", "anstyle", @@ -718,7 +718,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.37", ] [[package]] @@ -927,7 +927,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.33", + "syn 2.0.37", ] [[package]] @@ -949,7 +949,7 @@ checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" dependencies = [ "darling_core 0.20.3", "quote", - "syn 2.0.33", + "syn 2.0.37", ] [[package]] @@ -1273,7 +1273,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.37", ] [[package]] @@ -1485,9 +1485,9 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" +checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" [[package]] name = "hex" @@ -1540,7 +1540,7 @@ dependencies = [ [[package]] name = "holaplex-hub-core" version = "0.5.5" -source = "git+https://github.com/holaplex/hub-core#be11206ecb91d819d5ebf34c00eb8a1294f54026" +source = "git+https://github.com/holaplex/hub-core?branch=stable#ffd5b04a3f411d2bae8af317f2b8626012ec3c0b" dependencies = [ "anyhow", "async-trait", @@ -1582,26 +1582,7 @@ dependencies = [ [[package]] name = "holaplex-hub-core-build" version = "0.2.1" -source = "git+https://github.com/holaplex/hub-core?branch=stable#1122dc679042e397360da0f85b20babff4c7ea12" -dependencies = [ - "anyhow", - "dotenv", - "futures-util", - "hex", - "prost-build", - "reqwest", - "serde", - "sha2 0.10.7", - "tempfile", - "tokio", - "toml 0.5.11", - "url", -] - -[[package]] -name = "holaplex-hub-core-build" -version = "0.2.1" -source = "git+https://github.com/holaplex/hub-core#be11206ecb91d819d5ebf34c00eb8a1294f54026" +source = "git+https://github.com/holaplex/hub-core?branch=stable#ffd5b04a3f411d2bae8af317f2b8626012ec3c0b" dependencies = [ "anyhow", "dotenv", @@ -1620,20 +1601,20 @@ dependencies = [ [[package]] name = "holaplex-hub-core-macros" version = "0.1.0" -source = "git+https://github.com/holaplex/hub-core#be11206ecb91d819d5ebf34c00eb8a1294f54026" +source = "git+https://github.com/holaplex/hub-core?branch=stable#ffd5b04a3f411d2bae8af317f2b8626012ec3c0b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.37", "thiserror", ] [[package]] name = "holaplex-hub-core-schemas" version = "0.3.2" -source = "git+https://github.com/holaplex/hub-core#be11206ecb91d819d5ebf34c00eb8a1294f54026" +source = "git+https://github.com/holaplex/hub-core?branch=stable#ffd5b04a3f411d2bae8af317f2b8626012ec3c0b" dependencies = [ - "holaplex-hub-core-build 0.2.1 (git+https://github.com/holaplex/hub-core)", + "holaplex-hub-core-build", "prost", ] @@ -1645,7 +1626,7 @@ dependencies = [ "async-graphql-poem", "async-trait", "holaplex-hub-core", - "holaplex-hub-core-build 0.2.1 (git+https://github.com/holaplex/hub-core?branch=stable)", + "holaplex-hub-core-build", "poem", "prost", "prost-types", @@ -1816,7 +1797,7 @@ checksum = "ce243b1bfa62ffc028f1cc3b6034ec63d649f3031bc8a4fbbb004e1ac17d1f68" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.37", ] [[package]] @@ -2346,7 +2327,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.37", ] [[package]] @@ -2468,7 +2449,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.37", ] [[package]] @@ -2552,7 +2533,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.37", ] [[package]] @@ -2613,7 +2594,7 @@ checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.37", ] [[package]] @@ -2698,7 +2679,7 @@ dependencies = [ "proc-macro-crate 1.1.3", "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.37", ] [[package]] @@ -3291,7 +3272,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.37", ] [[package]] @@ -3349,7 +3330,7 @@ dependencies = [ "proc-macro2", "quote", "sea-bae", - "syn 2.0.33", + "syn 2.0.37", "unicode-ident", ] @@ -3501,7 +3482,7 @@ checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.37", ] [[package]] @@ -3561,7 +3542,7 @@ dependencies = [ "darling 0.20.3", "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.37", ] [[package]] @@ -4106,9 +4087,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.33" +version = "2.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9caece70c63bfba29ec2fed841a09851b14a235c60010fa4de58089b6c025668" +checksum = "7303ef2c05cd654186cb250d29049a24840ca25d2747c25c0381c8d9e2f582e8" dependencies = [ "proc-macro2", "quote", @@ -4163,7 +4144,7 @@ checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.37", ] [[package]] @@ -4245,7 +4226,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.37", ] [[package]] @@ -4367,7 +4348,7 @@ checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.37", ] [[package]] @@ -4467,9 +4448,9 @@ dependencies = [ [[package]] name = "typenum" -version = "1.16.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "ucd-trie" @@ -4637,7 +4618,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.37", "wasm-bindgen-shared", ] @@ -4671,7 +4652,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.37", "wasm-bindgen-backend", "wasm-bindgen-shared", ] diff --git a/api/Cargo.toml b/api/Cargo.toml index 1d22fc5..21dfc72 100644 --- a/api/Cargo.toml +++ b/api/Cargo.toml @@ -44,6 +44,7 @@ strum = { version = "0.24.1", features = ["derive"] } package = "holaplex-hub-core" version = "0.5.5" git = "https://github.com/holaplex/hub-core" +branch = "stable" features = ["kafka", "credits", "asset_proxy", "sea-orm", "metrics"] [build-dependencies.hub-core-build] From e799d6932c9cd0623aff638d3f20f7f44879b00b Mon Sep 17 00:00:00 2001 From: Kyle Espinola Date: Wed, 20 Sep 2023 13:42:40 +0200 Subject: [PATCH 18/20] fix: set info on collection mint when queued mints are created that until minted are unknown --- api/src/mutations/mint.rs | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/api/src/mutations/mint.rs b/api/src/mutations/mint.rs index c60aa39..1d0a7db 100644 --- a/api/src/mutations/mint.rs +++ b/api/src/mutations/mint.rs @@ -886,7 +886,6 @@ impl Mutation { collection_id: Set(drop.collection_id), owner: Set(None), creation_status: Set(CreationStatus::Queued), - seller_fee_basis_points: Set(collection_model.seller_fee_basis_points), created_by: Set(user_id), compressed: Set(None), ..Default::default() @@ -1017,10 +1016,15 @@ impl Mutation { collection_am.total_mints = Set(collection.total_mints.add(1)); collection_am.update(conn).await?; - let mut mint_am: collection_mints::ActiveModel = mint.clone().into(); - mint_am.credits_deduction_id = Set(Some(deduction_id)); + let mut mint_am: collection_mints::ActiveModel = mint.into(); + mint_am.creation_status = Set(CreationStatus::Pending); - mint_am.update(conn).await?; + mint_am.credits_deduction_id = Set(Some(deduction_id)); + mint_am.compressed = Set(Some(input.compressed)); + mint_am.owner = Set(Some(input.recipient.clone())); + mint_am.seller_fee_basis_points = Set(collection.seller_fee_basis_points); + + let mint = mint_am.update(conn).await?; match collection.blockchain { BlockchainEnum::Solana => { @@ -1033,7 +1037,8 @@ impl Mutation { owner_address, name: metadata_json.name, symbol: metadata_json.symbol, - metadata_uri: uri.unwrap(), + metadata_uri: uri + .ok_or(Error::new("No metadata json uri found"))?, seller_fee_basis_points: mint.seller_fee_basis_points.into(), creators: creators.into_iter().map(Into::into).collect(), }), @@ -1168,10 +1173,15 @@ impl Mutation { collection_am.total_mints = Set(collection.total_mints.add(1)); collection_am.update(conn).await?; - let mut mint_am: collection_mints::ActiveModel = mint.clone().into(); - mint_am.credits_deduction_id = Set(Some(deduction_id)); + let mut mint_am: collection_mints::ActiveModel = mint.into(); + mint_am.creation_status = Set(CreationStatus::Pending); - mint_am.update(conn).await?; + mint_am.credits_deduction_id = Set(Some(deduction_id)); + mint_am.compressed = Set(Some(input.compressed)); + mint_am.owner = Set(Some(input.recipient.clone())); + mint_am.seller_fee_basis_points = Set(collection.seller_fee_basis_points); + + let mint = mint_am.update(conn).await?; match collection.blockchain { BlockchainEnum::Solana => { @@ -1184,7 +1194,7 @@ impl Mutation { owner_address, name: metadata_json.name, symbol: metadata_json.symbol, - metadata_uri: uri.unwrap(), + metadata_uri: uri.ok_or(Error::new("No metadata json uri"))?, seller_fee_basis_points: mint.seller_fee_basis_points.into(), creators: creators.into_iter().map(Into::into).collect(), }), From 5e525e3a62f0692b97cdc0f84a6c2ecbaa0905ca Mon Sep 17 00:00:00 2001 From: Kyle Espinola Date: Wed, 20 Sep 2023 14:25:37 +0200 Subject: [PATCH 19/20] fix: set seller fee basis points to what is on the collection at the time of mint to avoid saving non-nullable column --- api/src/mutations/mint.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/api/src/mutations/mint.rs b/api/src/mutations/mint.rs index 1d0a7db..94a4b45 100644 --- a/api/src/mutations/mint.rs +++ b/api/src/mutations/mint.rs @@ -888,6 +888,7 @@ impl Mutation { creation_status: Set(CreationStatus::Queued), created_by: Set(user_id), compressed: Set(None), + seller_fee_basis_points: Set(collection_model.seller_fee_basis_points), ..Default::default() }; From 75069f1c18b7bf49a931c8dcb82380fb19bf8b1b Mon Sep 17 00:00:00 2001 From: imabdulbasit Date: Wed, 20 Sep 2023 19:38:16 +0500 Subject: [PATCH 20/20] Use Validate address util from hub-core --- api/src/mutations/collection.rs | 21 ++++----------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/api/src/mutations/collection.rs b/api/src/mutations/collection.rs index 574ed91..d1c0476 100644 --- a/api/src/mutations/collection.rs +++ b/api/src/mutations/collection.rs @@ -5,11 +5,11 @@ use hub_core::{ chrono::Utc, credits::{CreditsClient, TransactionId}, producer::Producer, + util::ValidateAddress, }; use reqwest::Url; use sea_orm::{prelude::*, ModelTrait, Set, TransactionTrait}; use serde::{Deserialize, Serialize}; -use solana_program::pubkey::Pubkey; use crate::{ blockchains::{polygon::Polygon, solana::Solana, CollectionEvent}, @@ -708,7 +708,7 @@ pub fn validate_creators(blockchain: BlockchainEnum, creators: &Vec) -> /// # Errors /// - Returns an error if the provided address is not a valid Solana address. pub fn validate_solana_address(address: &str) -> Result<()> { - if Pubkey::from_str(address).is_err() { + if !ValidateAddress::is_solana_address(&address) { return Err(Error::new(format!( "{address} is not a valid Solana address" ))); @@ -721,21 +721,8 @@ pub fn validate_solana_address(address: &str) -> Result<()> { /// # Errors /// - Returns an error if the provided address does not match the required EVM address format. pub fn validate_evm_address(address: &str) -> Result<()> { - let err = Err(Error::new(format!("{address} is not a valid EVM address"))); - - // Ethereum address must start with '0x' - if !address.starts_with("0x") { - return err; - } - - // Ethereum address must be exactly 40 characters long after removing '0x' - if address.len() != 42 { - return err; - } - - // Check that the address contains only hexadecimal characters - if !address[2..].chars().all(|c| c.is_ascii_hexdigit()) { - return err; + if !ValidateAddress::is_evm_address(&address) { + return Err(Error::new(format!("{address} is not a valid EVM address"))); } Ok(())