Skip to content

Commit df7cec5

Browse files
authored
feat(torii-graphql): add erc1155 to union (#3057)
* feat(torii-graphql): add erc1155 to union * f
1 parent 467cad1 commit df7cec5

File tree

5 files changed

+305
-11
lines changed

5 files changed

+305
-11
lines changed

crates/torii/graphql/src/constants.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ pub const TOKEN_UNION_TYPE_NAME: &str = "ERC__Token";
4141

4242
pub const ERC20_TYPE_NAME: &str = "ERC20__Token";
4343
pub const ERC721_TYPE_NAME: &str = "ERC721__Token";
44+
pub const ERC1155_TYPE_NAME: &str = "ERC1155__Token";
4445

4546
// objects' single and plural names
4647
pub const ENTITY_NAMES: (&str, &str) = ("entity", "entities");
@@ -55,6 +56,7 @@ pub const PAGE_INFO_NAMES: (&str, &str) = ("pageInfo", "");
5556

5657
pub const ERC20_TOKEN_NAME: (&str, &str) = ("erc20Token", "");
5758
pub const ERC721_TOKEN_NAME: (&str, &str) = ("erc721Token", "");
59+
pub const ERC1155_TOKEN_NAME: (&str, &str) = ("erc1155Token", "");
5860

5961
pub const TOKEN_BALANCE_NAME: (&str, &str) = ("", "tokenBalances");
6062
pub const TOKEN_TRANSFER_NAME: (&str, &str) = ("", "tokenTransfers");

crates/torii/graphql/src/mapping.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,19 @@ lazy_static! {
177177
(Name::new("imagePath"), TypeData::Simple(TypeRef::named_nn(TypeRef::STRING))),
178178
]);
179179

180+
pub static ref ERC1155_TOKEN_TYPE_MAPPING: TypeMapping = IndexMap::from([
181+
(Name::new("name"), TypeData::Simple(TypeRef::named_nn(TypeRef::STRING))),
182+
(Name::new("symbol"), TypeData::Simple(TypeRef::named_nn(TypeRef::STRING))),
183+
(Name::new("tokenId"), TypeData::Simple(TypeRef::named_nn(TypeRef::STRING))),
184+
(Name::new("contractAddress"), TypeData::Simple(TypeRef::named_nn(TypeRef::STRING))),
185+
(Name::new("amount"), TypeData::Simple(TypeRef::named_nn(TypeRef::STRING))),
186+
(Name::new("metadata"), TypeData::Simple(TypeRef::named_nn(TypeRef::STRING))),
187+
(Name::new("metadataName"), TypeData::Simple(TypeRef::named(TypeRef::STRING))),
188+
(Name::new("metadataDescription"), TypeData::Simple(TypeRef::named(TypeRef::STRING))),
189+
(Name::new("metadataAttributes"), TypeData::Simple(TypeRef::named(TypeRef::STRING))),
190+
(Name::new("imagePath"), TypeData::Simple(TypeRef::named_nn(TypeRef::STRING))),
191+
]);
192+
180193
pub static ref EMPTY_MAPPING: TypeMapping = IndexMap::from([
181194
(Name::new("id"), TypeData::Simple(TypeRef::named(TypeRef::ID))),
182195
]);

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

Lines changed: 169 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,17 @@ use sqlx::{Pool, Row, Sqlite, SqliteConnection};
88
use tokio_stream::StreamExt;
99
use torii_sqlite::simple_broker::SimpleBroker;
1010
use torii_sqlite::types::Token;
11+
use tracing::warn;
1112

1213
use super::handle_cursor;
1314
use crate::constants::{
14-
DEFAULT_LIMIT, ERC20_TOKEN_NAME, ERC20_TYPE_NAME, ERC721_TOKEN_NAME, ERC721_TYPE_NAME,
15-
ID_COLUMN,
15+
DEFAULT_LIMIT, ERC1155_TOKEN_NAME, ERC1155_TYPE_NAME, ERC20_TOKEN_NAME, ERC20_TYPE_NAME,
16+
ERC721_TOKEN_NAME, ERC721_TYPE_NAME, ID_COLUMN,
17+
};
18+
use crate::mapping::{
19+
ERC1155_TOKEN_TYPE_MAPPING, ERC20_TOKEN_TYPE_MAPPING, ERC721_TOKEN_TYPE_MAPPING,
20+
TOKEN_TYPE_MAPPING,
1621
};
17-
use crate::mapping::{ERC20_TOKEN_TYPE_MAPPING, ERC721_TOKEN_TYPE_MAPPING, TOKEN_TYPE_MAPPING};
1822
use crate::object::connection::page_info::PageInfoObject;
1923
use crate::object::connection::{
2024
connection_arguments, cursor, parse_connection_arguments, ConnectionArguments,
@@ -58,10 +62,28 @@ impl BasicObject for Erc721TokenObject {
5862
}
5963
}
6064

65+
#[derive(Debug)]
66+
pub struct Erc1155TokenObject;
67+
68+
impl BasicObject for Erc1155TokenObject {
69+
fn name(&self) -> (&str, &str) {
70+
ERC1155_TOKEN_NAME
71+
}
72+
73+
fn type_name(&self) -> &str {
74+
ERC1155_TYPE_NAME
75+
}
76+
77+
fn type_mapping(&self) -> &TypeMapping {
78+
&ERC1155_TOKEN_TYPE_MAPPING
79+
}
80+
}
81+
6182
#[derive(Debug, Clone)]
6283
pub enum ErcTokenType {
6384
Erc20(Erc20Token),
6485
Erc721(Erc721Token),
86+
Erc1155(Erc1155Token),
6587
}
6688

6789
#[derive(Debug, Clone)]
@@ -86,6 +108,20 @@ pub struct Erc721Token {
86108
pub image_path: String,
87109
}
88110

111+
#[derive(Debug, Clone)]
112+
pub struct Erc1155Token {
113+
pub name: String,
114+
pub symbol: String,
115+
pub token_id: String,
116+
pub contract_address: String,
117+
pub amount: String,
118+
pub metadata: String,
119+
pub metadata_name: Option<String>,
120+
pub metadata_description: Option<String>,
121+
pub metadata_attributes: Option<String>,
122+
pub image_path: String,
123+
}
124+
89125
impl ErcTokenType {
90126
pub fn to_field_value<'a>(self) -> FieldValue<'a> {
91127
match self {
@@ -122,6 +158,30 @@ impl ErcTokenType {
122158
]))),
123159
ERC721_TYPE_NAME.to_string(),
124160
),
161+
ErcTokenType::Erc1155(token) => FieldValue::with_type(
162+
FieldValue::value(Value::Object(ValueMapping::from([
163+
(Name::new("name"), Value::String(token.name)),
164+
(Name::new("symbol"), Value::String(token.symbol)),
165+
(Name::new("tokenId"), Value::String(token.token_id)),
166+
(Name::new("contractAddress"), Value::String(token.contract_address)),
167+
(Name::new("amount"), Value::String(token.amount)),
168+
(Name::new("metadata"), Value::String(token.metadata)),
169+
(
170+
Name::new("metadataName"),
171+
token.metadata_name.map(Value::String).unwrap_or(Value::Null),
172+
),
173+
(
174+
Name::new("metadataDescription"),
175+
token.metadata_description.map(Value::String).unwrap_or(Value::Null),
176+
),
177+
(
178+
Name::new("metadataAttributes"),
179+
token.metadata_attributes.map(Value::String).unwrap_or(Value::Null),
180+
),
181+
(Name::new("imagePath"), Value::String(token.image_path)),
182+
]))),
183+
ERC1155_TYPE_NAME.to_string(),
184+
),
125185
}
126186
}
127187
}
@@ -446,7 +506,65 @@ impl ResolvableObject for TokenObject {
446506
};
447507
ErcTokenType::Erc721(token)
448508
}
449-
_ => return None,
509+
"erc1155" => {
510+
let id = row.get::<String, _>("id");
511+
let token_id =
512+
id.split(':').collect::<Vec<&str>>()[1].to_string();
513+
514+
let metadata_str: String = row.get("metadata");
515+
let (
516+
metadata_str,
517+
metadata_name,
518+
metadata_description,
519+
metadata_attributes,
520+
image_path,
521+
) = if metadata_str.is_empty() {
522+
(String::new(), None, None, None, String::new())
523+
} else {
524+
let metadata: serde_json::Value =
525+
serde_json::from_str(&metadata_str)
526+
.expect("metadata is always json");
527+
let metadata_name = metadata.get("name").map(|v| {
528+
v.to_string().trim_matches('"').to_string()
529+
});
530+
let metadata_description =
531+
metadata.get("description").map(|v| {
532+
v.to_string().trim_matches('"').to_string()
533+
});
534+
let metadata_attributes =
535+
metadata.get("attributes").map(|v| {
536+
v.to_string().trim_matches('"').to_string()
537+
});
538+
539+
let image_path =
540+
format!("{}/image", id.replace(":", "/"));
541+
(
542+
metadata_str,
543+
metadata_name,
544+
metadata_description,
545+
metadata_attributes,
546+
image_path,
547+
)
548+
};
549+
550+
let token = Erc1155Token {
551+
name: row.get("name"),
552+
metadata: metadata_str,
553+
contract_address: row.get("contract_address"),
554+
symbol: row.get("symbol"),
555+
token_id,
556+
amount: "0".to_string(),
557+
metadata_name,
558+
metadata_description,
559+
metadata_attributes,
560+
image_path,
561+
};
562+
ErcTokenType::Erc1155(token)
563+
}
564+
_ => {
565+
warn!("Unknown contract type: {}", contract_type);
566+
return None;
567+
}
450568
};
451569

452570
Some(Ok(FieldValue::owned_any(token_metadata)))
@@ -516,6 +634,52 @@ fn create_token_metadata_from_row(row: &SqliteRow) -> sqlx::Result<ErcTokenType>
516634
};
517635
ErcTokenType::Erc721(token)
518636
}
519-
_ => return Err(sqlx::Error::RowNotFound),
637+
"erc1155" => {
638+
// contract_address:token_id
639+
let id = row.get::<String, _>("id");
640+
let token_id = id.split(':').collect::<Vec<&str>>()[1].to_string();
641+
642+
let metadata_str: String = row.get("metadata");
643+
let (
644+
metadata_str,
645+
metadata_name,
646+
metadata_description,
647+
metadata_attributes,
648+
image_path,
649+
) = if metadata_str.is_empty() {
650+
(String::new(), None, None, None, String::new())
651+
} else {
652+
let metadata: serde_json::Value =
653+
serde_json::from_str(&metadata_str).expect("metadata is always json");
654+
let metadata_name =
655+
metadata.get("name").map(|v| v.to_string().trim_matches('"').to_string());
656+
let metadata_description = metadata
657+
.get("description")
658+
.map(|v| v.to_string().trim_matches('"').to_string());
659+
let metadata_attributes =
660+
metadata.get("attributes").map(|v| v.to_string().trim_matches('"').to_string());
661+
662+
let image_path = format!("{}/image", id.replace(":", "/"));
663+
(metadata_str, metadata_name, metadata_description, metadata_attributes, image_path)
664+
};
665+
666+
let token = Erc1155Token {
667+
name: row.get("name"),
668+
metadata: metadata_str,
669+
contract_address: row.get("contract_address"),
670+
symbol: row.get("symbol"),
671+
token_id,
672+
amount: "0".to_string(),
673+
metadata_name,
674+
metadata_description,
675+
metadata_attributes,
676+
image_path,
677+
};
678+
ErcTokenType::Erc1155(token)
679+
}
680+
_ => {
681+
warn!("Unknown contract type: {}", contract_type);
682+
return Err(sqlx::Error::RowNotFound);
683+
}
520684
})
521685
}

crates/torii/graphql/src/object/erc/token_balance.rs

Lines changed: 113 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use crate::object::connection::page_info::PageInfoObject;
2222
use crate::object::connection::{
2323
connection_arguments, cursor, parse_connection_arguments, ConnectionArguments,
2424
};
25-
use crate::object::erc::erc_token::Erc721Token;
25+
use crate::object::erc::erc_token::{Erc1155Token, Erc721Token};
2626
use crate::object::{BasicObject, ResolvableObject};
2727
use crate::query::data::count_rows;
2828
use crate::query::filter::{Comparator, Filter, FilterValue};
@@ -213,7 +213,66 @@ impl ResolvableObject for ErcBalanceObject {
213213
};
214214
ErcTokenType::Erc721(token_metadata)
215215
}
216-
_ => return None,
216+
"erc1155" => {
217+
let token_id =
218+
row.token_id.split(':').collect::<Vec<&str>>();
219+
assert!(token_id.len() == 2);
220+
221+
let metadata_str = row.metadata;
222+
let (
223+
metadata_str,
224+
metadata_name,
225+
metadata_description,
226+
metadata_attributes,
227+
image_path,
228+
) = if metadata_str.is_empty() {
229+
(String::new(), None, None, None, String::new())
230+
} else {
231+
let metadata: serde_json::Value =
232+
serde_json::from_str(&metadata_str)
233+
.expect("metadata is always json");
234+
let metadata_name = metadata.get("name").map(|v| {
235+
v.to_string().trim_matches('"').to_string()
236+
});
237+
let metadata_description =
238+
metadata.get("description").map(|v| {
239+
v.to_string().trim_matches('"').to_string()
240+
});
241+
let metadata_attributes =
242+
metadata.get("attributes").map(|v| {
243+
v.to_string().trim_matches('"').to_string()
244+
});
245+
246+
let image_path =
247+
format!("{}/{}", token_id.join("/"), "image");
248+
249+
(
250+
metadata_str,
251+
metadata_name,
252+
metadata_description,
253+
metadata_attributes,
254+
image_path,
255+
)
256+
};
257+
258+
let token_metadata = Erc1155Token {
259+
name: row.name,
260+
metadata: metadata_str,
261+
contract_address: row.contract_address,
262+
symbol: row.symbol,
263+
token_id: token_id[1].to_string(),
264+
amount: row.balance,
265+
metadata_name,
266+
metadata_description,
267+
metadata_attributes,
268+
image_path,
269+
};
270+
ErcTokenType::Erc1155(token_metadata)
271+
}
272+
_ => {
273+
warn!("Unknown contract type: {}", row.contract_type);
274+
return None;
275+
}
217276
};
218277

219278
Some(Ok(FieldValue::owned_any(balance_value)))
@@ -427,6 +486,58 @@ fn token_balances_connection_output<'a>(
427486

428487
ErcTokenType::Erc721(token_metadata)
429488
}
489+
"erc1155" => {
490+
// contract_address:token_id
491+
let token_id = row.token_id.split(':').collect::<Vec<&str>>();
492+
assert!(token_id.len() == 2);
493+
494+
let metadata_str = row.metadata;
495+
let (
496+
metadata_str,
497+
metadata_name,
498+
metadata_description,
499+
metadata_attributes,
500+
image_path,
501+
) = if metadata_str.is_empty() {
502+
(String::new(), None, None, None, String::new())
503+
} else {
504+
let metadata: serde_json::Value =
505+
serde_json::from_str(&metadata_str).expect("metadata is always json");
506+
let metadata_name =
507+
metadata.get("name").map(|v| v.to_string().trim_matches('"').to_string());
508+
let metadata_description = metadata
509+
.get("description")
510+
.map(|v| v.to_string().trim_matches('"').to_string());
511+
let metadata_attributes = metadata
512+
.get("attributes")
513+
.map(|v| v.to_string().trim_matches('"').to_string());
514+
515+
let image_path = format!("{}/{}", token_id.join("/"), "image");
516+
517+
(
518+
metadata_str,
519+
metadata_name,
520+
metadata_description,
521+
metadata_attributes,
522+
image_path,
523+
)
524+
};
525+
526+
let token_metadata = Erc1155Token {
527+
name: row.name,
528+
metadata: metadata_str.to_owned(),
529+
contract_address: row.contract_address,
530+
symbol: row.symbol,
531+
token_id: token_id[1].to_string(),
532+
amount: row.balance,
533+
metadata_name,
534+
metadata_description,
535+
metadata_attributes,
536+
image_path,
537+
};
538+
539+
ErcTokenType::Erc1155(token_metadata)
540+
}
430541
_ => {
431542
warn!("Unknown contract type: {}", row.contract_type);
432543
continue;

0 commit comments

Comments
 (0)