Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Release 7/06 #136

Merged
merged 13 commits into from
Jul 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -71,12 +73,15 @@
}
}

pub async fn process(&self, msg: Services) -> Result<()> {

Check warning on line 76 in api/src/events.rs

View workflow job for this annotation

GitHub Actions / clippy/check/doc

docs for function returning `Result` missing `# Errors` section

Check warning on line 76 in api/src/events.rs

View workflow job for this annotation

GitHub Actions / clippy/check/doc

docs for function returning `Result` missing `# Errors` section
match msg {
Services::Treasury(TreasuryEventKey { id, .. }, e) => match e.event {
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 @@
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 @@
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 @@
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 @@
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 @@
.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 @@
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 @@
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 @@

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 Expand Up @@ -217,7 +226,7 @@

impl AppState {
#[must_use]
pub fn new(

Check warning on line 229 in api/src/lib.rs

View workflow job for this annotation

GitHub Actions / clippy/check/doc

this function has too many arguments (8/7)

Check warning on line 229 in api/src/lib.rs

View workflow job for this annotation

GitHub Actions / clippy/check/doc

this function has too many arguments (8/7)
schema: AppSchema,
connection: Connection,
producer: Producer<NftEvents>,
Expand Down
Loading
Loading