Skip to content

Commit

Permalink
feat(torii/graphql): cleanup names and add imagePath and metadata to …
Browse files Browse the repository at this point in the history
…erc_token

commit-id:21a1c0a5
  • Loading branch information
lambda-0x committed Oct 26, 2024
1 parent 042ac6a commit c4725cb
Show file tree
Hide file tree
Showing 15 changed files with 215 additions and 91 deletions.
3 changes: 3 additions & 0 deletions crates/torii/core/src/constants.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pub const TOKEN_BALANCE_TABLE: &str = "token_balances";
pub const TOKEN_TRANSFER_TABLE: &str = "token_transfers";
pub const TOKENS_TABLE: &str = "tokens";
42 changes: 29 additions & 13 deletions crates/torii/core/src/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use tokio::task::JoinSet;
use tokio::time::Instant;
use tracing::{debug, error, trace};

use crate::constants::{TOKENS_TABLE, TOKEN_BALANCE_TABLE};
use crate::simple_broker::SimpleBroker;
use crate::sql::utils::{felt_to_sql_string, sql_string_to_u256, u256_to_sql_string, I256};
use crate::sql::FELT_DELIMITER;
Expand Down Expand Up @@ -563,9 +564,9 @@ impl<'c, P: Provider + Sync + Send + 'static> Executor<'c, P> {
let semaphore = self.semaphore.clone();
let artifacts_path = self.artifacts_path.clone();
let provider = self.provider.clone();
let res = sqlx::query_as::<_, (String, String)>(
"SELECT name, symbol FROM tokens WHERE contract_address = ?",
)
let res = sqlx::query_as::<_, (String, String)>(&format!(
"SELECT name, symbol FROM {TOKENS_TABLE} WHERE contract_address = ?"
))

Check warning on line 569 in crates/torii/core/src/executor.rs

View check run for this annotation

Codecov / codecov/patch

crates/torii/core/src/executor.rs#L567-L569

Added lines #L567 - L569 were not covered by tests
.bind(felt_to_sql_string(&register_erc721_token.contract_address))
.fetch_one(&mut **tx)
.await;
Expand Down Expand Up @@ -801,7 +802,7 @@ impl<'c, P: Provider + Sync + Send + 'static> Executor<'c, P> {
) -> Result<()> {
let tx = &mut self.transaction;
let balance: Option<(String,)> =
sqlx::query_as("SELECT balance FROM balances WHERE id = ?")
sqlx::query_as(&format!("SELECT balance FROM {TOKEN_BALANCE_TABLE} WHERE id = ?"))

Check warning on line 805 in crates/torii/core/src/executor.rs

View check run for this annotation

Codecov / codecov/patch

crates/torii/core/src/executor.rs#L805

Added line #L805 was not covered by tests
.bind(id)
.fetch_optional(&mut **tx)
.await?;
Expand All @@ -822,10 +823,10 @@ impl<'c, P: Provider + Sync + Send + 'static> Executor<'c, P> {
}

// write the new balance to the database
sqlx::query(
"INSERT OR REPLACE INTO balances (id, contract_address, account_address, token_id, \
balance) VALUES (?, ?, ?, ?, ?)",
)
sqlx::query(&format!(
"INSERT OR REPLACE INTO {TOKEN_BALANCE_TABLE} (id, contract_address, account_address, \
token_id, balance) VALUES (?, ?, ?, ?, ?)",
))

Check warning on line 829 in crates/torii/core/src/executor.rs

View check run for this annotation

Codecov / codecov/patch

crates/torii/core/src/executor.rs#L826-L829

Added lines #L826 - L829 were not covered by tests
.bind(id)
.bind(contract_address)
.bind(account_address)
Expand Down Expand Up @@ -891,7 +892,12 @@ impl<'c, P: Provider + Sync + Send + 'static> Executor<'c, P> {
return Err(anyhow::anyhow!("token_uri is neither ByteArray nor Array<Felt>"));
};

let metadata = Self::fetch_metadata(&token_uri).await?;
let metadata = Self::fetch_metadata(&token_uri).await.with_context(|| {
format!(
"Failed to fetch metadata for token_id: {}",
register_erc721_token.actual_token_id
)
})?;

Check warning on line 900 in crates/torii/core/src/executor.rs

View check run for this annotation

Codecov / codecov/patch

crates/torii/core/src/executor.rs#L895-L900

Added lines #L895 - L900 were not covered by tests
let metadata = serde_json::to_string(&metadata).context("Failed to serialize metadata")?;
Ok(RegisterErc721TokenMetadata { query: register_erc721_token, metadata, name, symbol })
}
Expand Down Expand Up @@ -937,17 +943,27 @@ impl<'c, P: Provider + Sync + Send + 'static> Executor<'c, P> {
// Parse and decode data URI
debug!("Parsing metadata from data URI");
trace!(data_uri = %token_uri);
let data_url = DataUrl::process(token_uri).context("Failed to parse data URI")?;

// HACK: https://github.com/servo/rust-url/issues/908
let uri = token_uri.replace("#", "%23");

Check warning on line 948 in crates/torii/core/src/executor.rs

View check run for this annotation

Codecov / codecov/patch

crates/torii/core/src/executor.rs#L948

Added line #L948 was not covered by tests

let data_url = DataUrl::process(&uri).context("Failed to parse data URI")?;

Check warning on line 950 in crates/torii/core/src/executor.rs

View check run for this annotation

Codecov / codecov/patch

crates/torii/core/src/executor.rs#L950

Added line #L950 was not covered by tests

// Ensure the MIME type is JSON
if data_url.mime_type() != &Mime::from_str("application/json").unwrap() {
return Err(anyhow::anyhow!("Data URI is not of JSON type"));
}

let decoded = data_url.decode_to_vec().context("Failed to decode data URI")?;

let json: serde_json::Value = serde_json::from_slice(&decoded.0)
.context(format!("Failed to parse metadata JSON from data URI: {:?}", &uri))?;
// HACK: Loot Survior NFT metadata contains control characters which makes the json
// DATA invalid so filter them out
let decoded_str = String::from_utf8_lossy(&decoded.0)
.chars()
.filter(|c| !c.is_ascii_control())
.collect::<String>();

Check warning on line 963 in crates/torii/core/src/executor.rs

View check run for this annotation

Codecov / codecov/patch

crates/torii/core/src/executor.rs#L960-L963

Added lines #L960 - L963 were not covered by tests

let json: serde_json::Value = serde_json::from_str(&decoded_str)
.context(format!("Failed to parse metadata JSON from data URI: {}", &uri))?;

Check warning on line 966 in crates/torii/core/src/executor.rs

View check run for this annotation

Codecov / codecov/patch

crates/torii/core/src/executor.rs#L965-L966

Added lines #L965 - L966 were not covered by tests

Ok(json)
}
Expand Down
1 change: 1 addition & 0 deletions crates/torii/core/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#![warn(unused_crate_dependencies)]

pub mod constants;
pub mod engine;
pub mod error;
pub mod executor;
Expand Down
10 changes: 6 additions & 4 deletions crates/torii/core/src/sql/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use sqlx::{Pool, Sqlite, SqlitePool};
use starknet_crypto::Felt;
use tokio::sync::RwLock;

use crate::constants::TOKEN_BALANCE_TABLE;
use crate::error::{Error, ParseError, QueryError};
use crate::model::{parse_sql_model_members, SqlModelMember};
use crate::sql::utils::I256;
Expand Down Expand Up @@ -140,10 +141,11 @@ impl Clone for LocalCache {
impl LocalCache {
pub async fn new(pool: Pool<Sqlite>) -> Self {
// read existing token_id's from balances table and cache them
let token_id_registry: Vec<(String,)> = sqlx::query_as("SELECT token_id FROM balances")
.fetch_all(&pool)
.await
.expect("Should be able to read token_id's from blances table");
let token_id_registry: Vec<(String,)> =
sqlx::query_as(&format!("SELECT token_id FROM {TOKEN_BALANCE_TABLE}"))
.fetch_all(&pool)
.await
.expect("Should be able to read token_id's from blances table");

let token_id_registry = token_id_registry.into_iter().map(|token_id| token_id.0).collect();

Expand Down
8 changes: 5 additions & 3 deletions crates/torii/core/src/sql/erc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use starknet::providers::Provider;

use super::utils::{u256_to_sql_string, I256};
use super::{Sql, FELT_DELIMITER};
use crate::constants::TOKEN_TRANSFER_TABLE;
use crate::executor::{
ApplyBalanceDiffQuery, Argument, QueryMessage, QueryType, RegisterErc20TokenQuery,
RegisterErc721TokenQuery,
Expand Down Expand Up @@ -249,9 +250,10 @@ impl Sql {
block_timestamp: u64,
event_id: &str,
) -> Result<()> {
let insert_query = "INSERT INTO erc_transfers (id, contract_address, from_address, \
to_address, amount, token_id, executed_at) VALUES (?, ?, ?, ?, ?, ?, \
?)";
let insert_query = format!(
"INSERT INTO {TOKEN_TRANSFER_TABLE} (id, contract_address, from_address, to_address, \
amount, token_id, executed_at) VALUES (?, ?, ?, ?, ?, ?, ?)"
);

Check warning on line 256 in crates/torii/core/src/sql/erc.rs

View check run for this annotation

Codecov / codecov/patch

crates/torii/core/src/sql/erc.rs#L253-L256

Added lines #L253 - L256 were not covered by tests

self.executor.send(QueryMessage::new(
insert_query.to_string(),
Expand Down
1 change: 0 additions & 1 deletion crates/torii/core/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ use ipfs_api_backend_hyper::{IpfsApi, IpfsClient, TryFromUri};
use tokio_util::bytes::Bytes;
use tracing::info;

// pub const IPFS_URL: &str = "https://cartridge.infura-ipfs.io/ipfs/";
pub const IPFS_URL: &str = "https://ipfs.io/ipfs/";
pub const MAX_RETRY: u8 = 3;

Expand Down
16 changes: 8 additions & 8 deletions crates/torii/graphql/src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ pub const EVENT_MESSAGE_TABLE: &str = "event_messages";
pub const MODEL_TABLE: &str = "models";
pub const TRANSACTION_TABLE: &str = "transactions";
pub const METADATA_TABLE: &str = "metadata";
pub const ERC_BALANCE_TABLE: &str = "balances";
pub const ERC_TRANSFER_TABLE: &str = "erc_transfers";

pub const ID_COLUMN: &str = "id";
pub const EVENT_ID_COLUMN: &str = "event_id";
Expand All @@ -35,9 +33,10 @@ pub const QUERY_TYPE_NAME: &str = "World__Query";
pub const SUBSCRIPTION_TYPE_NAME: &str = "World__Subscription";
pub const MODEL_ORDER_TYPE_NAME: &str = "World__ModelOrder";
pub const MODEL_ORDER_FIELD_TYPE_NAME: &str = "World__ModelOrderField";
pub const ERC_BALANCE_TYPE_NAME: &str = "ERC__Balance";
pub const ERC_TRANSFER_TYPE_NAME: &str = "ERC__Transfer";
pub const ERC_TOKEN_TYPE_NAME: &str = "ERC__Token";
pub const TOKEN_BALANCE_TYPE_NAME: &str = "Token__Balance";
pub const TOKEN_TRANSFER_TYPE_NAME: &str = "Token__Transfer";
pub const TOKEN_TYPE_NAME: &str = "ERC__Token";
pub const ERC721_METADATA_TYPE_NAME: &str = "ERC721__Metadata";

// objects' single and plural names
pub const ENTITY_NAMES: (&str, &str) = ("entity", "entities");
Expand All @@ -49,10 +48,11 @@ pub const CONTENT_NAMES: (&str, &str) = ("content", "contents");
pub const METADATA_NAMES: (&str, &str) = ("metadata", "metadatas");
pub const TRANSACTION_NAMES: (&str, &str) = ("transaction", "transactions");
pub const PAGE_INFO_NAMES: (&str, &str) = ("pageInfo", "");
pub const TOKEN_NAME: (&str, &str) = ("token", "tokens");
pub const TOKEN_BALANCE_NAME: (&str, &str) = ("", "tokenBalances");
pub const TOKEN_TRANSFER_NAME: (&str, &str) = ("", "tokenTransfers");

pub const ERC_BALANCE_NAME: (&str, &str) = ("ercBalance", "");
pub const ERC_TOKEN_NAME: (&str, &str) = ("ercToken", "");
pub const ERC_TRANSFER_NAME: (&str, &str) = ("ercTransfer", "");
pub const ERC721_METADATA_NAME: (&str, &str) = ("erc721Metadata", "");

// misc
pub const ORDER_DIR_TYPE_NAME: &str = "OrderDirection";
Expand Down
30 changes: 22 additions & 8 deletions crates/torii/graphql/src/mapping.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ use async_graphql::Name;
use dojo_types::primitive::Primitive;
use lazy_static::lazy_static;

use crate::constants::{CONTENT_TYPE_NAME, ERC_TOKEN_TYPE_NAME, SOCIAL_TYPE_NAME};
use crate::constants::{
CONTENT_TYPE_NAME, ERC721_METADATA_TYPE_NAME, SOCIAL_TYPE_NAME, TOKEN_TYPE_NAME,
};
use crate::types::{GraphqlType, TypeData, TypeMapping};

lazy_static! {
Expand Down Expand Up @@ -145,27 +147,39 @@ lazy_static! {
),
]);

pub static ref ERC_BALANCE_TYPE_MAPPING: TypeMapping = IndexMap::from([
pub static ref TOKEN_BALANCE_TYPE_MAPPING: TypeMapping = IndexMap::from([
(Name::new("balance"), TypeData::Simple(TypeRef::named_nn(TypeRef::STRING))),
(Name::new("type"), TypeData::Simple(TypeRef::named_nn(TypeRef::STRING))),
(Name::new("tokenMetadata"), TypeData::Simple(TypeRef::named_nn(ERC_TOKEN_TYPE_NAME))),
(Name::new("tokenMetadata"), TypeData::Simple(TypeRef::named_nn(TOKEN_TYPE_NAME))),
]);

pub static ref ERC_TRANSFER_TYPE_MAPPING: TypeMapping = IndexMap::from([
pub static ref TOKEN_TRANSFER_TYPE_MAPPING: TypeMapping = IndexMap::from([
(Name::new("from"), TypeData::Simple(TypeRef::named_nn(TypeRef::STRING))),
(Name::new("to"), TypeData::Simple(TypeRef::named_nn(TypeRef::STRING))),
(Name::new("amount"), TypeData::Simple(TypeRef::named_nn(TypeRef::STRING))),
(Name::new("type"), TypeData::Simple(TypeRef::named_nn(TypeRef::STRING))),
(Name::new("executedAt"), TypeData::Simple(TypeRef::named_nn(TypeRef::STRING))),
(Name::new("tokenMetadata"), TypeData::Simple(TypeRef::named_nn(ERC_TOKEN_TYPE_NAME))),
(Name::new("tokenMetadata"), TypeData::Simple(TypeRef::named_nn(TOKEN_TYPE_NAME))),
(Name::new("transactionHash"), TypeData::Simple(TypeRef::named_nn(TypeRef::STRING))),
]);

pub static ref ERC_TOKEN_TYPE_MAPPING: TypeMapping = IndexMap::from([
pub static ref TOKEN_TYPE_MAPPING: TypeMapping = IndexMap::from([
(Name::new("name"), TypeData::Simple(TypeRef::named_nn(TypeRef::STRING))),
(Name::new("symbol"), TypeData::Simple(TypeRef::named_nn(TypeRef::STRING))),
(Name::new("tokenId"), TypeData::Simple(TypeRef::named_nn(TypeRef::STRING))),
(Name::new("decimals"), TypeData::Simple(TypeRef::named_nn(TypeRef::STRING))),
(Name::new("contractAddress"), TypeData::Simple(TypeRef::named_nn(TypeRef::STRING))),
(Name::new("decimals"), TypeData::Simple(TypeRef::named(TypeRef::STRING))),
(
Name::new("erc721"),
TypeData::Nested((TypeRef::named(ERC721_METADATA_TYPE_NAME), IndexMap::new()))
),
]);

pub static ref ERC721_METADATA_TYPE_MAPPING: TypeMapping = IndexMap::from([
(Name::new("tokenId"), TypeData::Simple(TypeRef::named_nn(TypeRef::STRING))),
(Name::new("name"), TypeData::Simple(TypeRef::named_nn(TypeRef::STRING))),
(Name::new("description"), TypeData::Simple(TypeRef::named_nn(TypeRef::STRING))),
(Name::new("attributes"), TypeData::Simple(TypeRef::named_nn(TypeRef::STRING))),
(Name::new("imagePath"), TypeData::Simple(TypeRef::named_nn(TypeRef::STRING))),
(Name::new("metadata"), TypeData::Simple(TypeRef::named_nn(TypeRef::STRING))),
]);
}
29 changes: 24 additions & 5 deletions crates/torii/graphql/src/object/erc/erc_token.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use crate::constants::{ERC_TOKEN_NAME, ERC_TOKEN_TYPE_NAME};
use crate::mapping::ERC_TOKEN_TYPE_MAPPING;
use crate::constants::{
ERC721_METADATA_NAME, ERC721_METADATA_TYPE_NAME, TOKEN_NAME, TOKEN_TYPE_NAME,
};
use crate::mapping::{ERC721_METADATA_TYPE_MAPPING, TOKEN_TYPE_MAPPING};
use crate::object::BasicObject;
use crate::types::TypeMapping;

Expand All @@ -8,14 +10,31 @@ pub struct ErcTokenObject;

impl BasicObject for ErcTokenObject {
fn name(&self) -> (&str, &str) {
ERC_TOKEN_NAME
TOKEN_NAME

Check warning on line 13 in crates/torii/graphql/src/object/erc/erc_token.rs

View check run for this annotation

Codecov / codecov/patch

crates/torii/graphql/src/object/erc/erc_token.rs#L13

Added line #L13 was not covered by tests
}

fn type_name(&self) -> &str {
ERC_TOKEN_TYPE_NAME
TOKEN_TYPE_NAME
}

fn type_mapping(&self) -> &TypeMapping {
&ERC_TOKEN_TYPE_MAPPING
&TOKEN_TYPE_MAPPING
}
}

#[derive(Debug)]
pub struct Erc721MetadataObject;

impl BasicObject for Erc721MetadataObject {
fn name(&self) -> (&str, &str) {
ERC721_METADATA_NAME
}

Check warning on line 31 in crates/torii/graphql/src/object/erc/erc_token.rs

View check run for this annotation

Codecov / codecov/patch

crates/torii/graphql/src/object/erc/erc_token.rs#L29-L31

Added lines #L29 - L31 were not covered by tests

fn type_name(&self) -> &str {
ERC721_METADATA_TYPE_NAME
}

fn type_mapping(&self) -> &TypeMapping {
&ERC721_METADATA_TYPE_MAPPING
}
}
4 changes: 2 additions & 2 deletions crates/torii/graphql/src/object/erc/mod.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use super::connection::cursor;
use crate::query::order::CursorDirection;

pub mod erc_balance;
pub mod erc_token;
pub mod erc_transfer;
pub mod token_balance;
pub mod token_transfer;

fn handle_cursor(
cursor: &str,
Expand Down
Loading

0 comments on commit c4725cb

Please sign in to comment.