Skip to content

Commit

Permalink
fmt
Browse files Browse the repository at this point in the history
  • Loading branch information
Larkooo committed Feb 10, 2025
1 parent 4aeae52 commit 4de044d
Show file tree
Hide file tree
Showing 4 changed files with 144 additions and 59 deletions.
13 changes: 6 additions & 7 deletions crates/torii/graphql/src/mapping.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,12 +192,11 @@ lazy_static! {
]);

pub static ref TOKEN_TYPE_MAPPING: TypeMapping = IndexMap::from([
("id".to_string(), TypeRef::named_nn(TypeRef::STRING)),
("contractAddress".to_string(), TypeRef::named_nn(TypeRef::STRING)),
("name".to_string(), TypeRef::named_nn(TypeRef::STRING)),
("symbol".to_string(), TypeRef::named_nn(TypeRef::STRING)),
("decimals".to_string(), TypeRef::named_nn(TypeRef::INT)),
(Name::new("tokenMetadata"), TypeData::Nested((TypeRef::named_nn(TOKEN_UNION_TYPE_NAME), IndexMap::new()))),

(Name::new("id"), TypeData::Simple(TypeRef::named_nn(TypeRef::STRING))),
(Name::new("contractAddress"), TypeData::Simple(TypeRef::named_nn(TypeRef::STRING))),
(Name::new("name"), TypeData::Simple(TypeRef::named_nn(TypeRef::STRING))),
(Name::new("symbol"), TypeData::Simple(TypeRef::named_nn(TypeRef::STRING))),
(Name::new("decimals"), TypeData::Simple(TypeRef::named_nn(TypeRef::INT))),
(Name::new("tokenMetadata"), TypeData::Nested((TypeRef::named_nn(TOKEN_UNION_TYPE_NAME), IndexMap::new()))),
]);
}
156 changes: 120 additions & 36 deletions crates/torii/graphql/src/object/erc/erc_token.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
use async_graphql::dynamic::FieldValue;
use async_graphql::dynamic::{
Field, FieldValue, SubscriptionField, SubscriptionFieldFuture, TypeRef,
};
use async_graphql::{Name, Value};
use sqlx::{Pool, Row, Sqlite};
use tokio_stream::StreamExt;
use torii_sqlite::simple_broker::SimpleBroker;
use torii_sqlite::types::Token;

use crate::constants::{ERC20_TOKEN_NAME, ERC20_TYPE_NAME, ERC721_TOKEN_NAME, ERC721_TYPE_NAME};
use crate::mapping::{ERC20_TOKEN_TYPE_MAPPING, ERC721_TOKEN_TYPE_MAPPING};
use crate::object::BasicObject;
use crate::mapping::{ERC20_TOKEN_TYPE_MAPPING, ERC721_TOKEN_TYPE_MAPPING, TOKEN_TYPE_MAPPING};
use crate::object::{BasicObject, ResolvableObject};
use crate::types::{TypeMapping, ValueMapping};

#[derive(Debug)]
Expand Down Expand Up @@ -126,44 +132,122 @@ impl BasicObject for TokenObject {
}

impl ResolvableObject for TokenObject {
fn resolvers(&self) -> Vec<Field> {
vec![]
}

fn subscriptions(&self) -> Option<Vec<SubscriptionField>> {
Some(vec![
SubscriptionField::new(
"tokenRegistered",
TypeRef::named_nn(self.type_name()),
|ctx| {
SubscriptionFieldFuture::new(async move {
let pool = ctx.data::<Pool<Sqlite>>()?;
Ok(SimpleBroker::<Token>::subscribe()
.then(move |token| {
let pool = pool.clone();
async move {
let query = "SELECT * FROM tokens WHERE id = ?";

let row = match sqlx::query(query)
.bind(&token.id)
.fetch_one(&pool)
.await
Some(vec![SubscriptionField::new(
"tokenRegistered",
TypeRef::named_nn(self.type_name()),
|ctx| {
SubscriptionFieldFuture::new(async move {
let pool = ctx.data::<Pool<Sqlite>>()?;
Ok(SimpleBroker::<Token>::subscribe()
.then(move |token| {
let pool = pool.clone();
async move {
// Fetch complete token data including contract type
let query = "SELECT t.*, c.contract_type
FROM tokens t
JOIN contracts c ON t.contract_address = \
c.contract_address
WHERE t.id = ?";

let row =
match sqlx::query(query).bind(&token.id).fetch_one(&pool).await
{
Ok(row) => row,
Err(_) => return None,
};

Some(Ok(FieldValue::value(Value::Object(ValueMapping::from([
(Name::new("id"), Value::String(token.id)),
(Name::new("contractAddress"), Value::String(token.contract_address)),
(Name::new("name"), Value::String(token.name)),
(Name::new("symbol"), Value::String(token.symbol)),
(Name::new("decimals"), Value::Number(token.decimals.into())),
(Name::new("metadata"), Value::String(token.metadata)),
])))))
}
})
.filter_map(|result| result)
)
})
},
)
])
let contract_type: String = row.get("contract_type");
let token_metadata = match contract_type.to_lowercase().as_str() {
"erc20" => {
let token = Erc20Token {
contract_address: row.get("contract_address"),
name: row.get("name"),
symbol: row.get("symbol"),
decimals: row.get("decimals"),
amount: "0".to_string(), // New token has no balance
};
ErcTokenType::Erc20(token)
}
"erc721" => {
let metadata_str: String = row.get("metadata");
let (
metadata_str,
metadata_name,
metadata_description,
metadata_attributes,
image_path,
) = if metadata_str.is_empty() {
(String::new(), None, None, None, String::new())
} else {
let metadata: serde_json::Value =
serde_json::from_str(&metadata_str)
.expect("metadata is always json");
let metadata_name = metadata.get("name").map(|v| {
v.to_string().trim_matches('"').to_string()
});
let metadata_description =
metadata.get("description").map(|v| {
v.to_string().trim_matches('"').to_string()
});
let metadata_attributes =
metadata.get("attributes").map(|v| {
v.to_string().trim_matches('"').to_string()
});

let contract_address: String =
row.get("contract_address");
let image_path = format!("{}/image", contract_address);

(
metadata_str,
metadata_name,
metadata_description,
metadata_attributes,
image_path,
)
};

let token = Erc721Token {
name: row.get("name"),
metadata: metadata_str,
contract_address: row.get("contract_address"),
symbol: row.get("symbol"),
token_id: "0".to_string(), /* New token has no
* specific token_id */
metadata_name,
metadata_description,
metadata_attributes,
image_path,
};
ErcTokenType::Erc721(token)
}
_ => return None,
};

Some(Ok(FieldValue::value(Value::Object(ValueMapping::from([
(Name::new("id"), Value::String(token.id)),
(
Name::new("contractAddress"),
Value::String(token.contract_address),
),
(Name::new("name"), Value::String(token.name)),
(Name::new("symbol"), Value::String(token.symbol)),
(Name::new("decimals"), Value::Number(token.decimals.into())),
(
Name::new("tokenMetadata"),
token_metadata.to_field_value().as_value().unwrap().clone(),
),
])))))
}
})
.filter_map(|result| result))
})
},
)])
}
}
26 changes: 13 additions & 13 deletions crates/torii/graphql/src/object/erc/token_balance.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use async_graphql::connection::PageInfo;
use async_graphql::dynamic::{Field, FieldFuture, FieldValue, InputValue, SubscriptionField, SubscriptionFieldFuture, TypeRef};
use async_graphql::dynamic::{
Field, FieldFuture, FieldValue, InputValue, SubscriptionField, SubscriptionFieldFuture, TypeRef,
};
use convert_case::{Case, Casing};
use serde::Deserialize;
use sqlx::sqlite::SqliteRow;
Expand Down Expand Up @@ -92,7 +94,7 @@ impl ResolvableObject for ErcBalanceObject {
fn subscriptions(&self) -> Option<Vec<SubscriptionField>> {
Some(vec![
SubscriptionField::new(
"tokenBalanceUpdated",
"tokenBalanceUpdated",
TypeRef::named_nn(format!("{}Connection", self.type_name())),
|ctx| {
SubscriptionFieldFuture::new(async move {
Expand All @@ -115,19 +117,21 @@ impl ResolvableObject for ErcBalanceObject {
}
// Fetch associated token data
let query = format!(
"SELECT b.id, t.contract_address, t.name, t.symbol, t.decimals, b.balance, b.token_id, \
t.metadata, c.contract_type
"SELECT b.id, t.contract_address, t.name, t.symbol, \
t.decimals, b.balance, b.token_id, t.metadata, \
c.contract_type
FROM {} b
JOIN tokens t ON b.token_id = t.id
JOIN contracts c ON t.contract_address = c.contract_address
JOIN contracts c ON t.contract_address = \
c.contract_address
WHERE b.id = ?",
TOKEN_BALANCE_TABLE
);

let row = match sqlx::query(&query)
.bind(&token_balance.id)
.fetch_one(&pool)
.await
.await
{
Ok(row) => row,
Err(_) => return None,
Expand All @@ -136,7 +140,7 @@ impl ResolvableObject for ErcBalanceObject {
// Create connection with single edge
match token_balances_connection_output(
&[row],
1, // total_count
1, // total_count
PageInfo {
has_previous_page: false,
has_next_page: false,
Expand All @@ -149,15 +153,11 @@ impl ResolvableObject for ErcBalanceObject {
}
}
})
.filter_map(|result| result)
)
.filter_map(|result| result))
})
},
)
.argument(InputValue::new(
"accountAddress",
TypeRef::named(TypeRef::STRING),
)),
.argument(InputValue::new("accountAddress", TypeRef::named(TypeRef::STRING))),
])
}
}
Expand Down
8 changes: 5 additions & 3 deletions crates/torii/graphql/src/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use crate::constants::{
};
use crate::object::controller::ControllerObject;
use crate::object::empty::EmptyObject;
use crate::object::erc::erc_token::{Erc20TokenObject, Erc721TokenObject};
use crate::object::erc::erc_token::{Erc20TokenObject, Erc721TokenObject, TokenObject};
use crate::object::erc::token_balance::ErcBalanceObject;
use crate::object::erc::token_transfer::ErcTransferObject;
use crate::object::event_message::EventMessageObject;
Expand Down Expand Up @@ -131,15 +131,17 @@ async fn build_objects(pool: &SqlitePool) -> Result<(Vec<ObjectVariant>, Vec<Uni
ObjectVariant::Basic(Box::new(Erc721TokenObject)),
ObjectVariant::Basic(Box::new(Erc20TokenObject)),
ObjectVariant::Basic(Box::new(EmptyObject)),
ObjectVariant::Resolvable(Box::new(TokenObject)),
];

// model union object
let mut unions: Vec<Union> = Vec::new();
let mut model_union = Union::new("ModelUnion");

// erc_token union object
let erc_token_union =
Union::new(TOKEN_UNION_TYPE_NAME).possible_type(ERC20_TYPE_NAME).possible_type(ERC721_TYPE_NAME);
let erc_token_union = Union::new(TOKEN_UNION_TYPE_NAME)
.possible_type(ERC20_TYPE_NAME)
.possible_type(ERC721_TYPE_NAME);

unions.push(erc_token_union);

Expand Down

0 comments on commit 4de044d

Please sign in to comment.