@@ -18,7 +18,7 @@ use crate::object::connection::page_info::PageInfoObject;
18
18
use crate :: object:: connection:: {
19
19
connection_arguments, cursor, parse_connection_arguments, ConnectionArguments ,
20
20
} ;
21
- use crate :: object:: erc:: erc_token:: Erc721Token ;
21
+ use crate :: object:: erc:: erc_token:: { Erc1155Token , Erc721Token } ;
22
22
use crate :: object:: { BasicObject , ResolvableObject } ;
23
23
use crate :: query:: order:: { CursorDirection , Direction } ;
24
24
use crate :: types:: TypeMapping ;
@@ -240,72 +240,17 @@ fn token_transfers_connection_output<'a>(
240
240
241
241
for row in data {
242
242
let row = TransferQueryResultRaw :: from_row ( row) ?;
243
- let transaction_hash = get_transaction_hash_from_event_id ( & row. id ) ;
244
243
let cursor = cursor:: encode ( & row. id , & row. id ) ;
245
244
246
- let transfer_node = match row. contract_type . to_lowercase ( ) . as_str ( ) {
247
- "erc20" => {
248
- let token_metadata = ErcTokenType :: Erc20 ( Erc20Token {
249
- contract_address : row. contract_address ,
250
- name : row. name ,
251
- symbol : row. symbol ,
252
- decimals : row. decimals ,
253
- amount : row. amount ,
254
- } ) ;
255
-
256
- TokenTransferNode {
257
- from : row. from_address ,
258
- to : row. to_address ,
259
- executed_at : row. executed_at ,
260
- token_metadata,
261
- transaction_hash,
262
- }
263
- }
264
- "erc721" => {
265
- // contract_address:token_id
266
- let token_id = row. token_id . split ( ':' ) . collect :: < Vec < & str > > ( ) ;
267
- assert ! ( token_id. len( ) == 2 ) ;
268
-
269
- let metadata_str = row. metadata ;
270
- let metadata: serde_json:: Value =
271
- serde_json:: from_str ( & metadata_str) . expect ( "metadata is always json" ) ;
272
- let metadata_name =
273
- metadata. get ( "name" ) . map ( |v| v. to_string ( ) . trim_matches ( '"' ) . to_string ( ) ) ;
274
- let metadata_description = metadata
275
- . get ( "description" )
276
- . map ( |v| v. to_string ( ) . trim_matches ( '"' ) . to_string ( ) ) ;
277
- let metadata_attributes =
278
- metadata. get ( "attributes" ) . map ( |v| v. to_string ( ) . trim_matches ( '"' ) . to_string ( ) ) ;
279
-
280
- let image_path = format ! ( "{}/{}" , token_id. join( "/" ) , "image" ) ;
281
-
282
- let token_metadata = ErcTokenType :: Erc721 ( Erc721Token {
283
- name : row. name ,
284
- metadata : metadata_str. to_owned ( ) ,
285
- contract_address : row. contract_address ,
286
- symbol : row. symbol ,
287
- token_id : token_id[ 1 ] . to_string ( ) ,
288
- metadata_name,
289
- metadata_description,
290
- metadata_attributes,
291
- image_path,
292
- } ) ;
293
-
294
- TokenTransferNode {
295
- from : row. from_address ,
296
- to : row. to_address ,
297
- executed_at : row. executed_at ,
298
- token_metadata,
299
- transaction_hash,
300
- }
245
+ match token_transfer_mapping_from_row ( & row) {
246
+ Ok ( transfer_node) => {
247
+ edges. push ( ConnectionEdge { node : transfer_node, cursor } ) ;
301
248
}
302
- _ => {
303
- warn ! ( "Unknown contract type : {}" , row . contract_type ) ;
249
+ Err ( err ) => {
250
+ warn ! ( "Failed to transform row to TokenTransferNode : {}" , err ) ;
304
251
continue ;
305
252
}
306
- } ;
307
-
308
- edges. push ( ConnectionEdge { node : transfer_node, cursor } ) ;
253
+ }
309
254
}
310
255
311
256
Ok ( FieldValue :: owned_any ( Connection {
@@ -315,6 +260,128 @@ fn token_transfers_connection_output<'a>(
315
260
} ) )
316
261
}
317
262
263
+ /// Transforms a TransferQueryResultRaw into a TokenTransferNode
264
+ pub fn token_transfer_mapping_from_row (
265
+ row : & TransferQueryResultRaw ,
266
+ ) -> Result < TokenTransferNode , String > {
267
+ let transaction_hash = get_transaction_hash_from_event_id ( & row. id ) ;
268
+
269
+ match row. contract_type . to_lowercase ( ) . as_str ( ) {
270
+ "erc20" => {
271
+ let token_metadata = ErcTokenType :: Erc20 ( Erc20Token {
272
+ contract_address : row. contract_address . clone ( ) ,
273
+ name : row. name . clone ( ) ,
274
+ symbol : row. symbol . clone ( ) ,
275
+ decimals : row. decimals ,
276
+ amount : row. amount . clone ( ) ,
277
+ } ) ;
278
+
279
+ Ok ( TokenTransferNode {
280
+ from : row. from_address . clone ( ) ,
281
+ to : row. to_address . clone ( ) ,
282
+ executed_at : row. executed_at . clone ( ) ,
283
+ token_metadata,
284
+ transaction_hash,
285
+ } )
286
+ }
287
+ "erc721" => {
288
+ // contract_address:token_id
289
+ let token_id = row. token_id . split ( ':' ) . collect :: < Vec < & str > > ( ) ;
290
+ if token_id. len ( ) != 2 {
291
+ return Err ( format ! ( "Invalid token_id format: {}" , row. token_id) ) ;
292
+ }
293
+
294
+ let metadata_str = & row. metadata ;
295
+ let metadata: serde_json:: Value = match serde_json:: from_str ( metadata_str) {
296
+ Ok ( value) => value,
297
+ Err ( e) => return Err ( format ! ( "Failed to parse metadata as JSON: {}" , e) ) ,
298
+ } ;
299
+
300
+ let metadata_name =
301
+ metadata. get ( "name" ) . map ( |v| v. to_string ( ) . trim_matches ( '"' ) . to_string ( ) ) ;
302
+ let metadata_description =
303
+ metadata. get ( "description" ) . map ( |v| v. to_string ( ) . trim_matches ( '"' ) . to_string ( ) ) ;
304
+ let metadata_attributes =
305
+ metadata. get ( "attributes" ) . map ( |v| v. to_string ( ) . trim_matches ( '"' ) . to_string ( ) ) ;
306
+
307
+ let image_path = format ! ( "{}/{}" , token_id. join( "/" ) , "image" ) ;
308
+
309
+ let token_metadata = ErcTokenType :: Erc721 ( Erc721Token {
310
+ name : row. name . clone ( ) ,
311
+ metadata : metadata_str. to_owned ( ) ,
312
+ contract_address : row. contract_address . clone ( ) ,
313
+ symbol : row. symbol . clone ( ) ,
314
+ token_id : token_id[ 1 ] . to_string ( ) ,
315
+ metadata_name,
316
+ metadata_description,
317
+ metadata_attributes,
318
+ image_path,
319
+ } ) ;
320
+
321
+ Ok ( TokenTransferNode {
322
+ from : row. from_address . clone ( ) ,
323
+ to : row. to_address . clone ( ) ,
324
+ executed_at : row. executed_at . clone ( ) ,
325
+ token_metadata,
326
+ transaction_hash,
327
+ } )
328
+ }
329
+ "erc1155" => {
330
+ // contract_address:token_id
331
+ let token_id = row. token_id . split ( ':' ) . collect :: < Vec < & str > > ( ) ;
332
+ if token_id. len ( ) != 2 {
333
+ return Err ( format ! ( "Invalid token_id format: {}" , row. token_id) ) ;
334
+ }
335
+
336
+ let metadata_str = & row. metadata ;
337
+ let ( metadata_name, metadata_description, metadata_attributes, image_path) =
338
+ if metadata_str. is_empty ( ) {
339
+ ( None , None , None , String :: new ( ) )
340
+ } else {
341
+ let metadata: serde_json:: Value = match serde_json:: from_str ( metadata_str) {
342
+ Ok ( value) => value,
343
+ Err ( e) => return Err ( format ! ( "Failed to parse metadata as JSON: {}" , e) ) ,
344
+ } ;
345
+
346
+ let metadata_name =
347
+ metadata. get ( "name" ) . map ( |v| v. to_string ( ) . trim_matches ( '"' ) . to_string ( ) ) ;
348
+ let metadata_description = metadata
349
+ . get ( "description" )
350
+ . map ( |v| v. to_string ( ) . trim_matches ( '"' ) . to_string ( ) ) ;
351
+ let metadata_attributes = metadata
352
+ . get ( "attributes" )
353
+ . map ( |v| v. to_string ( ) . trim_matches ( '"' ) . to_string ( ) ) ;
354
+
355
+ let image_path = format ! ( "{}/{}" , token_id. join( "/" ) , "image" ) ;
356
+
357
+ ( metadata_name, metadata_description, metadata_attributes, image_path)
358
+ } ;
359
+
360
+ let token_metadata = ErcTokenType :: Erc1155 ( Erc1155Token {
361
+ name : row. name . clone ( ) ,
362
+ metadata : metadata_str. to_owned ( ) ,
363
+ contract_address : row. contract_address . clone ( ) ,
364
+ symbol : row. symbol . clone ( ) ,
365
+ token_id : token_id[ 1 ] . to_string ( ) ,
366
+ amount : row. amount . clone ( ) ,
367
+ metadata_name,
368
+ metadata_description,
369
+ metadata_attributes,
370
+ image_path,
371
+ } ) ;
372
+
373
+ Ok ( TokenTransferNode {
374
+ from : row. from_address . clone ( ) ,
375
+ to : row. to_address . clone ( ) ,
376
+ executed_at : row. executed_at . clone ( ) ,
377
+ token_metadata,
378
+ transaction_hash,
379
+ } )
380
+ }
381
+ _ => Err ( format ! ( "Unknown contract type: {}" , row. contract_type) ) ,
382
+ }
383
+ }
384
+
318
385
// TODO: This would be required when subscriptions are needed
319
386
// impl ErcTransferObject {
320
387
// pub fn value_mapping(entity: ErcBalance) -> ValueMapping {
@@ -325,7 +392,7 @@ fn token_transfers_connection_output<'a>(
325
392
326
393
#[ derive( FromRow , Deserialize , Debug , Clone ) ]
327
394
#[ serde( rename_all = "camelCase" ) ]
328
- struct TransferQueryResultRaw {
395
+ pub struct TransferQueryResultRaw {
329
396
pub id : String ,
330
397
pub contract_address : String ,
331
398
pub from_address : String ,
0 commit comments