Skip to content

Commit

Permalink
Merge pull request #136 from holaplex/main
Browse files Browse the repository at this point in the history
Release 7/06
  • Loading branch information
kespinola authored Jul 6, 2023
2 parents 1c5e439 + 5241076 commit 86afe89
Show file tree
Hide file tree
Showing 19 changed files with 397 additions and 68 deletions.
3 changes: 2 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions api/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "holaplex-hub-nfts"
version = "0.1.0"
version = "0.1.1"
publish = false
authors = [
"Holaplex <[email protected]>",
Expand Down Expand Up @@ -34,7 +34,8 @@ serde_json = "1.0.93"
solana-program = "1.15.0"
poem = { version = "1.3.50", features = ["anyhow", "test"] }
async-graphql-poem = "5.0.3"
prost = "0.11.5"
prost = "0.11.9"
prost-types = "0.11.9"
reqwest = { version = "0.11.14", features = ["json"] }
async-trait = "0.1.68"
strum = { version = "0.24.1", features = ["derive"] }
Expand Down
4 changes: 2 additions & 2 deletions api/proto.lock
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,5 @@ sha512 = "d167e0a143c813073eef8597f0b237e5a8eaf32abbf709724e8071b2dd73ce0438b82f

[[schemas]]
subject = "treasury"
version = 16
sha512 = "bf8ad07bb11acefeaced6e5da417a9b49bad3770e4dd7f3d29b743fb943da973ab8587f7fef10a40a76b2e477d1c3956410de8403b7fb6efa80b95f2c3b8e8cf"
version = 17
sha512 = "c4caa4f7d032686dff56840909254f5bbb21c12b5e01cf890443dbe4d9806be637e5bbd09a66176152ecd42687fd7bc7008b50f00aec46ff941f4eb04bee25f2"
2 changes: 1 addition & 1 deletion api/proto.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ endpoint = "https://schemas.holaplex.tools"
organization = 5
nfts = 19
customer = 2
treasury = 16
treasury = 17
solana_nfts = 4
polygon_nfts = 6
timestamp = 1
21 changes: 21 additions & 0 deletions api/src/entities/customer_wallets.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3

use sea_orm::entity::prelude::*;

use super::sea_orm_active_enums::Blockchain;

#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)]
#[sea_orm(table_name = "customer_wallets")]
pub struct Model {
#[sea_orm(primary_key, auto_increment = false)]
pub id: Uuid,
pub customer_id: Uuid,
#[sea_orm(column_type = "Text")]
pub address: String,
pub blockchain: Blockchain,
}

#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {}

impl ActiveModelBehavior for ActiveModel {}
2 changes: 2 additions & 0 deletions api/src/entities/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ pub mod prelude;
pub mod collection_creators;
pub mod collection_mints;
pub mod collections;
pub mod customer_wallets;
pub mod drops;
pub mod metadata_json_attributes;
pub mod metadata_json_files;
Expand All @@ -14,3 +15,4 @@ pub mod nft_transfers;
pub mod project_wallets;
pub mod purchases;
pub mod sea_orm_active_enums;
pub mod transfer_charges;
1 change: 0 additions & 1 deletion api/src/entities/nft_transfers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ pub struct Model {
pub sender: String,
pub recipient: String,
pub created_at: DateTimeWithTimeZone,
pub credits_deduction_id: Option<Uuid>,
}

#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
Expand Down
6 changes: 3 additions & 3 deletions api/src/entities/prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

pub use super::{
collection_creators::Entity as CollectionCreators, collection_mints::Entity as CollectionMints,
collections::Entity as Collections, drops::Entity as Drops,
metadata_json_attributes::Entity as MetadataJsonAttributes,
collections::Entity as Collections, customer_wallets::Entity as CustomerWallets,
drops::Entity as Drops, metadata_json_attributes::Entity as MetadataJsonAttributes,
metadata_json_files::Entity as MetadataJsonFiles, metadata_jsons::Entity as MetadataJsons,
nft_transfers::Entity as NftTransfers, project_wallets::Entity as ProjectWallets,
purchases::Entity as Purchases,
purchases::Entity as Purchases, transfer_charges::Entity as TransferCharges,
};
16 changes: 16 additions & 0 deletions api/src/entities/transfer_charges.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.10.5

use sea_orm::entity::prelude::*;

#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)]
#[sea_orm(table_name = "transfer_charges")]
pub struct Model {
#[sea_orm(primary_key, auto_increment = false)]
pub id: Uuid,
pub credits_deduction_id: Option<Uuid>,
}

#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {}

impl ActiveModelBehavior for ActiveModel {}
117 changes: 93 additions & 24 deletions api/src/events.rs
Original file line number Diff line number Diff line change
@@ -1,33 +1,35 @@
use hub_core::{
chrono::Utc,
chrono::{DateTime, NaiveDateTime, Utc},
credits::{CreditsClient, TransactionId},
prelude::*,
producer::Producer,
uuid::Uuid,
};
use sea_orm::{
ActiveModelTrait, ColumnTrait, EntityTrait, JoinType, QueryFilter, QuerySelect, RelationTrait,
Set,
Set, TransactionTrait,
};

use crate::{
db::Connection,
entities::{
collection_mints, collections, drops, nft_transfers,
collection_mints, collections, customer_wallets, drops, nft_transfers,
prelude::{CollectionMints, Purchases},
project_wallets, purchases,
sea_orm_active_enums::{Blockchain, CreationStatus},
transfer_charges,
},
proto::{
nft_events::Event as NftEvent,
polygon_nft_events::Event as PolygonNftEvents,
solana_nft_events::Event as SolanaNftsEvent,
treasury_events::{
Blockchain as ProtoBlockchainEnum, Event as TreasuryEvent, PolygonTransactionResult,
ProjectWallet, TransactionStatus,
Blockchain as ProtoBlockchainEnum, CustomerWallet, Event as TreasuryEvent,
PolygonTransactionResult, ProjectWallet, TransactionStatus,
},
CreationStatus as NftCreationStatus, DropCreation, MintCreation, MintOwnershipUpdate,
NftEventKey, NftEvents, SolanaCompletedMintTransaction, SolanaCompletedTransferTransaction,
SolanaNftEventKey, TreasuryEventKey,
MintedTokensOwnershipUpdate, NftEventKey, NftEvents, SolanaCompletedMintTransaction,
SolanaCompletedTransferTransaction, SolanaNftEventKey, TreasuryEventKey,
},
Actions, Services,
};
Expand Down Expand Up @@ -77,6 +79,9 @@ impl Processor {
Some(TreasuryEvent::ProjectWalletCreated(payload)) => {
self.project_wallet_created(payload).await
},
Some(TreasuryEvent::CustomerWalletCreated(payload)) => {
self.customer_wallet_created(payload).await
},
Some(
TreasuryEvent::PolygonCreateDropTxnSubmitted(payload)
| TreasuryEvent::PolygonRetryCreateDropSubmitted(payload),
Expand Down Expand Up @@ -129,6 +134,12 @@ impl Processor {
Some(SolanaNftsEvent::UpdateMintOwner(e)) => self.update_mint_owner(id, e).await,
None | Some(_) => Ok(()),
},
Services::Polygon(_, e) => match e.event {
Some(PolygonNftEvents::UpdateMintsOwner(p)) => {
self.update_polygon_mints_owner(p).await
},
None | Some(_) => Ok(()),
},
}
}

Expand All @@ -153,11 +164,59 @@ impl Processor {
sender: Set(payload.sender),
recipient: Set(payload.recipient),
created_at: Set(Utc::now().into()),
credits_deduction_id: Set(None),
..Default::default()
};

nft_transfer.insert(db).await?;
Ok(())
}
async fn update_polygon_mints_owner(&self, payload: MintedTokensOwnershipUpdate) -> Result<()> {
let MintedTokensOwnershipUpdate {
mint_ids,
new_owner,
timestamp,
transaction_hash,
} = payload;

let ts = timestamp.context("No timestamp found")?;
let created_at = DateTime::<Utc>::from_utc(
NaiveDateTime::from_timestamp_opt(ts.seconds, ts.nanos.try_into()?)
.context("failed to parse to NaiveDateTime")?,
Utc,
)
.into();

let db = self.db.get();
let txn = db.begin().await?;

let mint_ids = mint_ids
.into_iter()
.map(|s| Uuid::from_str(&s))
.collect::<Result<Vec<Uuid>, _>>()?;

let mints = CollectionMints::find()
.filter(collection_mints::Column::Id.is_in(mint_ids))
.all(db)
.await?;

for mint in mints {
let mut mint_am: collection_mints::ActiveModel = mint.clone().into();
mint_am.owner = Set(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),
recipient: Set(new_owner.clone()),
created_at: Set(created_at),
..Default::default()
};

nft_transfers.insert(&txn).await?;
}

txn.commit().await?;

Ok(())
}
Expand All @@ -184,6 +243,27 @@ impl Processor {
Ok(())
}

async fn customer_wallet_created(&self, payload: CustomerWallet) -> Result<()> {
let conn = self.db.get();

let blockchain = ProtoBlockchainEnum::from_i32(payload.blockchain)
.context("failed to get blockchain enum variant")?;

let active_model = customer_wallets::ActiveModel {
customer_id: Set(payload.customer_id.parse()?),
address: Set(payload.wallet_address),
blockchain: Set(blockchain.try_into()?),
..Default::default()
};

active_model
.insert(conn)
.await
.context("failed to insert customer wallet")?;

Ok(())
}

async fn drop_created(&self, id: String, payload: MintResult) -> Result<()> {
let conn = self.db.get();
let collection_id = Uuid::from_str(&id)?;
Expand Down Expand Up @@ -311,22 +391,14 @@ impl Processor {
let conn = self.db.get();
let transfer_id = Uuid::from_str(&id)?;

let (nft_transfer, collection_mint) = nft_transfers::Entity::find_by_id(transfer_id)
.find_also_related(collection_mints::Entity)
let transfer_charge = transfer_charges::Entity::find()
.filter(transfer_charges::Column::CreditsDeductionId.eq(transfer_id))
.one(conn)
.await?
.context("failed to load nft transfer from db")?;
.context("failed to load transfer charge from db")?;

let collection_mint = collection_mint.context("collection mint not found")?;

let mut collection_mint_am: collection_mints::ActiveModel = collection_mint.into();
let mut nft_transfer_am: nft_transfers::ActiveModel = nft_transfer.clone().into();

if let TransferResult::Success(signature) = payload {
collection_mint_am.owner = Set(nft_transfer.recipient.clone());
nft_transfer_am.tx_signature = Set(Some(signature));

let deduction_id = nft_transfer
if let TransferResult::Success(_) = payload {
let deduction_id = transfer_charge
.credits_deduction_id
.context("deduction id not found")?;

Expand All @@ -335,9 +407,6 @@ impl Processor {
.await?;
}

collection_mint_am.update(conn).await?;
nft_transfer_am.insert(conn).await?;

Ok(())
}
}
Expand Down
11 changes: 10 additions & 1 deletion api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ pub mod proto {
include!(concat!(env!("OUT_DIR"), "/nfts.proto.rs"));
include!(concat!(env!("OUT_DIR"), "/treasury.proto.rs"));
include!(concat!(env!("OUT_DIR"), "/solana_nfts.proto.rs"));
include!(concat!(env!("OUT_DIR"), "/polygon_nfts.proto.rs"));
}

use proto::NftEvents;
Expand All @@ -60,10 +61,12 @@ impl hub_core::producer::Message for proto::NftEvents {
pub enum Services {
Treasury(proto::TreasuryEventKey, proto::TreasuryEvents),
Solana(proto::SolanaNftEventKey, proto::SolanaNftEvents),
Polygon(proto::PolygonNftEventKey, proto::PolygonNftEvents),
}

impl hub_core::consumer::MessageGroup for Services {
const REQUESTED_TOPICS: &'static [&'static str] = &["hub-treasuries", "hub-nfts-solana"];
const REQUESTED_TOPICS: &'static [&'static str] =
&["hub-treasuries", "hub-nfts-solana", "hub-nfts-polygon"];

fn from_message<M: hub_core::consumer::Message>(msg: &M) -> Result<Self, RecvError> {
let topic = msg.topic();
Expand All @@ -84,6 +87,12 @@ impl hub_core::consumer::MessageGroup for Services {

Ok(Services::Solana(key, val))
},
"hub-nfts-polygon" => {
let key = proto::PolygonNftEventKey::decode(key)?;
let val = proto::PolygonNftEvents::decode(val)?;

Ok(Services::Polygon(key, val))
},
t => Err(RecvError::BadTopic(t.into())),
}
}
Expand Down
Loading

0 comments on commit 86afe89

Please sign in to comment.