diff --git a/Cargo.lock b/Cargo.lock index 4b5ab11232..9f0ece5dd8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2091,8 +2091,8 @@ dependencies = [ [[package]] name = "blockifier" -version = "0.8.0-rc.3" -source = "git+https://github.com/dojoengine/sequencer?rev=adae779#adae779dd758fb3cdedec0af61651f80ec463279" +version = "0.0.0" +source = "git+https://github.com/dojoengine/sequencer?rev=802c5dc#802c5dc1b3ca231d96b65ffcada349f4b5ab0e3b" dependencies = [ "anyhow", "ark-ec", @@ -2103,31 +2103,32 @@ dependencies = [ "cairo-lang-casm", "cairo-lang-runner", "cairo-lang-starknet-classes", - "cairo-lang-utils", "cairo-vm", "derive_more 0.99.18", "indexmap 2.5.0", - "itertools 0.10.5", + "itertools 0.12.1", "keccak", "log", "num-bigint", "num-integer", "num-rational", "num-traits 0.2.19", - "once_cell", + "papyrus_config", "paste", "phf", "rand", "rstest 0.17.0", + "semver 1.0.23", "serde", "serde_json", "sha2", - "sha3", "starknet-types-core", "starknet_api", "strum 0.25.0", "strum_macros 0.25.3", + "tempfile", "thiserror 1.0.63", + "toml 0.8.19", ] [[package]] @@ -2434,7 +2435,7 @@ dependencies = [ "anyhow", "async-trait", "cainome-cairo-serde 0.1.0 (git+https://github.com/cartridge-gg/cainome?tag=v0.4.11)", - "cainome-cairo-serde-derive 0.1.0 (git+https://github.com/cartridge-gg/cainome?tag=v0.4.11)", + "cainome-cairo-serde-derive", "cainome-parser 0.1.0 (git+https://github.com/cartridge-gg/cainome?tag=v0.4.11)", "cainome-rs 0.1.0 (git+https://github.com/cartridge-gg/cainome?tag=v0.4.11)", "cainome-rs-macro 0.1.0 (git+https://github.com/cartridge-gg/cainome?tag=v0.4.11)", @@ -2452,32 +2453,6 @@ dependencies = [ "url", ] -[[package]] -name = "cainome" -version = "0.4.11" -source = "git+https://github.com/cartridge-gg/cainome?tag=v0.4.12#d83de9302e77a5eb1bad3c827bf91b96614d0ebe" -dependencies = [ - "anyhow", - "async-trait", - "cainome-cairo-serde 0.1.0 (git+https://github.com/cartridge-gg/cainome?tag=v0.4.12)", - "cainome-cairo-serde-derive 0.1.0 (git+https://github.com/cartridge-gg/cainome?tag=v0.4.12)", - "cainome-parser 0.1.0 (git+https://github.com/cartridge-gg/cainome?tag=v0.4.12)", - "cainome-rs 0.1.0 (git+https://github.com/cartridge-gg/cainome?tag=v0.4.12)", - "cainome-rs-macro 0.1.0 (git+https://github.com/cartridge-gg/cainome?tag=v0.4.12)", - "camino", - "clap", - "clap_complete", - "convert_case 0.6.0", - "serde", - "serde_json", - "starknet", - "starknet-types-core", - "thiserror 1.0.63", - "tracing", - "tracing-subscriber", - "url", -] - [[package]] name = "cainome-cairo-serde" version = "0.1.0" @@ -2490,18 +2465,6 @@ dependencies = [ "thiserror 1.0.63", ] -[[package]] -name = "cainome-cairo-serde" -version = "0.1.0" -source = "git+https://github.com/cartridge-gg/cainome?tag=v0.4.12#d83de9302e77a5eb1bad3c827bf91b96614d0ebe" -dependencies = [ - "num-bigint", - "serde", - "serde_with", - "starknet", - "thiserror 1.0.63", -] - [[package]] name = "cainome-cairo-serde" version = "0.1.0" @@ -2523,17 +2486,6 @@ dependencies = [ "unzip-n", ] -[[package]] -name = "cainome-cairo-serde-derive" -version = "0.1.0" -source = "git+https://github.com/cartridge-gg/cainome?tag=v0.4.12#d83de9302e77a5eb1bad3c827bf91b96614d0ebe" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.90", - "unzip-n", -] - [[package]] name = "cainome-parser" version = "0.1.0" @@ -2547,19 +2499,6 @@ dependencies = [ "thiserror 1.0.63", ] -[[package]] -name = "cainome-parser" -version = "0.1.0" -source = "git+https://github.com/cartridge-gg/cainome?tag=v0.4.12#d83de9302e77a5eb1bad3c827bf91b96614d0ebe" -dependencies = [ - "convert_case 0.6.0", - "quote", - "serde_json", - "starknet", - "syn 2.0.90", - "thiserror 1.0.63", -] - [[package]] name = "cainome-parser" version = "0.1.0" @@ -2591,24 +2530,6 @@ dependencies = [ "thiserror 1.0.63", ] -[[package]] -name = "cainome-rs" -version = "0.1.0" -source = "git+https://github.com/cartridge-gg/cainome?tag=v0.4.12#d83de9302e77a5eb1bad3c827bf91b96614d0ebe" -dependencies = [ - "anyhow", - "cainome-cairo-serde 0.1.0 (git+https://github.com/cartridge-gg/cainome?tag=v0.4.12)", - "cainome-parser 0.1.0 (git+https://github.com/cartridge-gg/cainome?tag=v0.4.12)", - "camino", - "prettyplease", - "proc-macro2", - "quote", - "serde_json", - "starknet", - "syn 2.0.90", - "thiserror 1.0.63", -] - [[package]] name = "cainome-rs" version = "0.1.0" @@ -2645,24 +2566,6 @@ dependencies = [ "thiserror 1.0.63", ] -[[package]] -name = "cainome-rs-macro" -version = "0.1.0" -source = "git+https://github.com/cartridge-gg/cainome?tag=v0.4.12#d83de9302e77a5eb1bad3c827bf91b96614d0ebe" -dependencies = [ - "anyhow", - "cainome-cairo-serde 0.1.0 (git+https://github.com/cartridge-gg/cainome?tag=v0.4.12)", - "cainome-parser 0.1.0 (git+https://github.com/cartridge-gg/cainome?tag=v0.4.12)", - "cainome-rs 0.1.0 (git+https://github.com/cartridge-gg/cainome?tag=v0.4.12)", - "proc-macro-error", - "proc-macro2", - "quote", - "serde_json", - "starknet", - "syn 2.0.90", - "thiserror 1.0.63", -] - [[package]] name = "cainome-rs-macro" version = "0.1.0" @@ -3926,7 +3829,7 @@ dependencies = [ [[package]] name = "create-output-dir" version = "1.0.0" -source = "git+https://github.com/dojoengine/scarb?rev=da5f683adbd25361d080c2d9f624924aa9f112d1#da5f683adbd25361d080c2d9f624924aa9f112d1" +source = "git+https://github.com/dojoengine/scarb?rev=a3b3c7fae12aecd3ce1502b1a651fced6be546df#a3b3c7fae12aecd3ce1502b1a651fced6be546df" dependencies = [ "anyhow", "core-foundation 0.10.0", @@ -4598,12 +4501,12 @@ checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" [[package]] name = "dojo-bindgen" -version = "1.1.2" +version = "1.0.12" dependencies = [ "anyhow", "assert_matches", "async-trait", - "cainome 0.4.11 (git+https://github.com/cartridge-gg/cainome?tag=v0.4.12)", + "cainome 0.4.11", "camino", "chrono", "convert_case 0.6.0", @@ -4621,16 +4524,15 @@ dependencies = [ [[package]] name = "dojo-contracts" -version = "1.1.2" +version = "1.0.12" [[package]] name = "dojo-examples-spawn-and-move" -version = "1.1.2" +version = "1.0.12" [[package]] name = "dojo-lang" -version = "1.1.1" -source = "git+https://github.com/dojoengine/dojo?rev=17cda07a333e8c157c38dc455ad27472bbd75740#17cda07a333e8c157c38dc455ad27472bbd75740" +version = "1.0.12" dependencies = [ "anyhow", "cairo-lang-defs", @@ -4640,7 +4542,7 @@ dependencies = [ "cairo-lang-semantic", "cairo-lang-syntax", "cairo-lang-utils", - "dojo-types 1.1.1", + "dojo-types 1.0.12", "itertools 0.12.1", "serde", "smol_str", @@ -4651,7 +4553,8 @@ dependencies = [ [[package]] name = "dojo-lang" -version = "1.1.2" +version = "1.0.12" +source = "git+https://github.com/dojoengine/dojo?rev=d32e89a1035a8cd6abafe2e35b2c640b4d43de38#d32e89a1035a8cd6abafe2e35b2c640b4d43de38" dependencies = [ "anyhow", "cairo-lang-defs", @@ -4661,7 +4564,7 @@ dependencies = [ "cairo-lang-semantic", "cairo-lang-syntax", "cairo-lang-utils", - "dojo-types 1.1.2", + "dojo-types 1.0.12 (git+https://github.com/dojoengine/dojo?rev=d32e89a1035a8cd6abafe2e35b2c640b4d43de38)", "itertools 0.12.1", "serde", "smol_str", @@ -4672,16 +4575,16 @@ dependencies = [ [[package]] name = "dojo-language-server" -version = "1.1.2" +version = "1.0.12" dependencies = [ "cairo-lang-language-server", "clap", - "dojo-lang 1.1.2", + "dojo-lang 1.0.12", ] [[package]] name = "dojo-metrics" -version = "1.1.2" +version = "1.0.12" dependencies = [ "hyper 0.14.30", "jemalloc-ctl", @@ -4697,7 +4600,7 @@ dependencies = [ [[package]] name = "dojo-test-utils" -version = "1.1.2" +version = "1.0.12" dependencies = [ "anyhow", "assert_fs", @@ -4721,11 +4624,10 @@ dependencies = [ [[package]] name = "dojo-types" -version = "1.1.1" -source = "git+https://github.com/dojoengine/dojo?rev=17cda07a333e8c157c38dc455ad27472bbd75740#17cda07a333e8c157c38dc455ad27472bbd75740" +version = "1.0.12" dependencies = [ "anyhow", - "cainome 0.4.11 (git+https://github.com/cartridge-gg/cainome?tag=v0.4.11)", + "cainome 0.4.11", "crypto-bigint", "hex", "indexmap 2.5.0", @@ -4743,10 +4645,11 @@ dependencies = [ [[package]] name = "dojo-types" -version = "1.1.2" +version = "1.0.12" +source = "git+https://github.com/dojoengine/dojo?rev=d32e89a1035a8cd6abafe2e35b2c640b4d43de38#d32e89a1035a8cd6abafe2e35b2c640b4d43de38" dependencies = [ "anyhow", - "cainome 0.4.11 (git+https://github.com/cartridge-gg/cainome?tag=v0.4.12)", + "cainome 0.4.11", "crypto-bigint", "hex", "indexmap 2.5.0", @@ -4764,7 +4667,7 @@ dependencies = [ [[package]] name = "dojo-utils" -version = "1.1.2" +version = "1.0.12" dependencies = [ "anyhow", "assert_matches", @@ -4782,13 +4685,13 @@ dependencies = [ [[package]] name = "dojo-world" -version = "1.1.2" +version = "1.0.12" dependencies = [ "anyhow", "async-trait", - "cainome 0.4.11 (git+https://github.com/cartridge-gg/cainome?tag=v0.4.12)", + "cainome 0.4.11", "cairo-lang-starknet-classes", - "dojo-types 1.1.2", + "dojo-types 1.0.12", "futures", "hex", "hex-literal", @@ -4809,10 +4712,10 @@ dependencies = [ [[package]] name = "dojo-world-abigen" -version = "1.1.2" +version = "1.0.12" dependencies = [ "anyhow", - "cainome 0.4.11 (git+https://github.com/cartridge-gg/cainome?tag=v0.4.12)", + "cainome 0.4.11", "cairo-lang-starknet", "cairo-lang-starknet-classes", "camino", @@ -6686,15 +6589,6 @@ dependencies = [ "thiserror 1.0.63", ] -[[package]] -name = "hash32" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47d60b12902ba28e2730cd37e95b8c9223af2808df9e902d4df49588d1470606" -dependencies = [ - "byteorder", -] - [[package]] name = "hashbrown" version = "0.12.3" @@ -6768,17 +6662,6 @@ dependencies = [ "http 0.2.12", ] -[[package]] -name = "heapless" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bfb9eb618601c89945a70e254898da93b13be0388091d42117462b265bb3fad" -dependencies = [ - "hash32", - "serde", - "stable_deref_trait", -] - [[package]] name = "heck" version = "0.4.1" @@ -7224,6 +7107,17 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" +[[package]] +name = "idna" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" +dependencies = [ + "matches", + "unicode-bidi", + "unicode-normalization", +] + [[package]] name = "idna" version = "0.4.0" @@ -7273,6 +7167,12 @@ dependencies = [ "windows 0.51.1", ] +[[package]] +name = "if_chain" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb56e1aa765b4b4f3aadfab769793b7087bb03a4ea4920644a6d238e2df5b9ed" + [[package]] name = "igd-next" version = "0.14.3" @@ -7479,6 +7379,15 @@ dependencies = [ "str_stack", ] +[[package]] +name = "infra_utils" +version = "0.0.0" +source = "git+https://github.com/dojoengine/sequencer?rev=802c5dc#802c5dc1b3ca231d96b65ffcada349f4b5ab0e3b" +dependencies = [ + "tokio", + "tracing", +] + [[package]] name = "inotify" version = "0.10.2" @@ -7999,12 +7908,12 @@ dependencies = [ [[package]] name = "katana" -version = "1.1.2" +version = "1.0.12" dependencies = [ "anyhow", "assert_matches", "byte-unit", - "cainome 0.4.11 (git+https://github.com/cartridge-gg/cainome?tag=v0.4.12)", + "cainome 0.4.11", "clap", "clap_complete", "comfy-table", @@ -8027,12 +7936,11 @@ dependencies = [ "thiserror 1.0.63", "tokio", "tracing", - "url", ] [[package]] name = "katana-cairo" -version = "1.1.2" +version = "1.0.12" dependencies = [ "cairo-lang-casm", "cairo-lang-runner", @@ -8047,17 +7955,13 @@ dependencies = [ [[package]] name = "katana-chain-spec" -version = "1.1.2" +version = "1.0.12" dependencies = [ "alloy-primitives", "anyhow", "dirs 6.0.0", - "katana-executor", "katana-primitives", - "katana-provider", "lazy_static", - "num-traits 0.2.19", - "rstest 0.18.2", "serde", "serde_json", "similar-asserts", @@ -8070,7 +7974,7 @@ dependencies = [ [[package]] name = "katana-cli" -version = "1.1.2" +version = "1.0.12" dependencies = [ "alloy-primitives", "anyhow", @@ -8099,7 +8003,7 @@ dependencies = [ [[package]] name = "katana-codecs" -version = "1.1.2" +version = "1.0.12" dependencies = [ "bytes", "katana-primitives", @@ -8107,7 +8011,7 @@ dependencies = [ [[package]] name = "katana-codecs-derive" -version = "1.1.2" +version = "1.0.12" dependencies = [ "proc-macro2", "quote", @@ -8117,7 +8021,7 @@ dependencies = [ [[package]] name = "katana-core" -version = "1.1.2" +version = "1.0.12" dependencies = [ "alloy-contract 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "alloy-network 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -8151,7 +8055,6 @@ dependencies = [ "rand", "rayon", "reqwest 0.11.27", - "rstest 0.18.2", "serde", "serde_json", "starknet", @@ -8166,7 +8069,7 @@ dependencies = [ [[package]] name = "katana-db" -version = "1.1.2" +version = "1.0.12" dependencies = [ "anyhow", "arbitrary", @@ -8193,7 +8096,7 @@ dependencies = [ [[package]] name = "katana-executor" -version = "1.1.2" +version = "1.0.12" dependencies = [ "alloy-primitives", "anyhow", @@ -8221,7 +8124,7 @@ dependencies = [ [[package]] name = "katana-feeder-gateway" -version = "1.1.2" +version = "1.0.12" dependencies = [ "katana-primitives", "katana-rpc-types", @@ -8236,7 +8139,7 @@ dependencies = [ [[package]] name = "katana-grpc" -version = "1.1.2" +version = "1.0.12" dependencies = [ "tonic 0.11.0", "tonic-build 0.11.0", @@ -8245,7 +8148,7 @@ dependencies = [ [[package]] name = "katana-node" -version = "1.1.2" +version = "1.0.12" dependencies = [ "anyhow", "clap", @@ -8288,7 +8191,7 @@ dependencies = [ [[package]] name = "katana-node-bindings" -version = "1.1.2" +version = "1.0.12" dependencies = [ "regex", "serde", @@ -8303,7 +8206,7 @@ dependencies = [ [[package]] name = "katana-pipeline" -version = "1.1.2" +version = "1.0.12" dependencies = [ "async-trait", "futures", @@ -8317,7 +8220,7 @@ dependencies = [ [[package]] name = "katana-pool" -version = "1.1.2" +version = "1.0.12" dependencies = [ "futures", "futures-util", @@ -8333,7 +8236,7 @@ dependencies = [ [[package]] name = "katana-primitives" -version = "1.1.2" +version = "1.0.12" dependencies = [ "alloy-primitives", "anyhow", @@ -8343,7 +8246,6 @@ dependencies = [ "criterion", "derive_more 0.99.18", "flate2", - "heapless", "katana-cairo", "lazy_static", "num-bigint", @@ -8367,7 +8269,7 @@ dependencies = [ [[package]] name = "katana-provider" -version = "1.1.2" +version = "1.0.12" dependencies = [ "alloy-primitives", "anyhow", @@ -8396,13 +8298,13 @@ dependencies = [ [[package]] name = "katana-rpc" -version = "1.1.2" +version = "1.0.12" dependencies = [ "alloy", "alloy-primitives", "anyhow", "assert_matches", - "cainome 0.4.11 (git+https://github.com/cartridge-gg/cainome?tag=v0.4.12)", + "cainome 0.4.11", "dojo-metrics", "dojo-test-utils", "dojo-utils", @@ -8411,7 +8313,6 @@ dependencies = [ "indexmap 2.5.0", "jsonrpsee", "katana-cairo", - "katana-chain-spec", "katana-core", "katana-executor", "katana-node", @@ -8442,7 +8343,7 @@ dependencies = [ [[package]] name = "katana-rpc-api" -version = "1.1.2" +version = "1.0.12" dependencies = [ "jsonrpsee", "katana-core", @@ -8453,7 +8354,7 @@ dependencies = [ [[package]] name = "katana-rpc-types" -version = "1.1.2" +version = "1.0.12" dependencies = [ "alloy-primitives", "anyhow", @@ -8481,7 +8382,7 @@ dependencies = [ [[package]] name = "katana-rpc-types-builder" -version = "1.1.2" +version = "1.0.12" dependencies = [ "anyhow", "katana-executor", @@ -8493,7 +8394,7 @@ dependencies = [ [[package]] name = "katana-runner" -version = "1.1.2" +version = "1.0.12" dependencies = [ "anyhow", "assert_fs", @@ -8506,7 +8407,7 @@ dependencies = [ [[package]] name = "katana-runner-macro" -version = "1.1.2" +version = "1.0.12" dependencies = [ "proc-macro2", "quote", @@ -8515,7 +8416,7 @@ dependencies = [ [[package]] name = "katana-slot-controller" -version = "1.1.2" +version = "1.0.12" dependencies = [ "alloy-primitives", "anyhow", @@ -8533,7 +8434,7 @@ dependencies = [ [[package]] name = "katana-stage" -version = "1.1.2" +version = "1.0.12" dependencies = [ "anyhow", "async-trait", @@ -8556,7 +8457,7 @@ dependencies = [ [[package]] name = "katana-tasks" -version = "1.1.2" +version = "1.0.12" dependencies = [ "futures", "rayon", @@ -8569,7 +8470,7 @@ dependencies = [ [[package]] name = "katana-trie" -version = "1.1.2" +version = "1.0.12" dependencies = [ "anyhow", "bitvec", @@ -9435,6 +9336,12 @@ dependencies = [ "regex-automata 0.1.10", ] +[[package]] +name = "matches" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" + [[package]] name = "matchit" version = "0.7.3" @@ -10429,6 +10336,21 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "papyrus_config" +version = "0.0.0" +source = "git+https://github.com/dojoengine/sequencer?rev=802c5dc#802c5dc1b3ca231d96b65ffcada349f4b5ab0e3b" +dependencies = [ + "clap", + "infra_utils", + "itertools 0.12.1", + "serde", + "serde_json", + "strum_macros 0.25.3", + "thiserror 1.0.63", + "validator", +] + [[package]] name = "parity-scale-codec" version = "3.6.12" @@ -12479,7 +12401,7 @@ dependencies = [ [[package]] name = "scarb" version = "2.9.2" -source = "git+https://github.com/dojoengine/scarb?rev=da5f683adbd25361d080c2d9f624924aa9f112d1#da5f683adbd25361d080c2d9f624924aa9f112d1" +source = "git+https://github.com/dojoengine/scarb?rev=a3b3c7fae12aecd3ce1502b1a651fced6be546df#a3b3c7fae12aecd3ce1502b1a651fced6be546df" dependencies = [ "anyhow", "async-trait", @@ -12511,7 +12433,7 @@ dependencies = [ "derive_builder", "dialoguer", "directories", - "dojo-lang 1.1.1", + "dojo-lang 1.0.12 (git+https://github.com/dojoengine/dojo?rev=d32e89a1035a8cd6abafe2e35b2c640b4d43de38)", "dunce", "flate2", "fs4", @@ -12532,9 +12454,9 @@ dependencies = [ "redb", "reqwest 0.11.27", "scarb-build-metadata", - "scarb-metadata 1.13.0 (git+https://github.com/dojoengine/scarb?rev=da5f683adbd25361d080c2d9f624924aa9f112d1)", - "scarb-proc-macro-server-types 0.1.0 (git+https://github.com/dojoengine/scarb?rev=da5f683adbd25361d080c2d9f624924aa9f112d1)", - "scarb-stable-hash 1.0.0 (git+https://github.com/dojoengine/scarb?rev=da5f683adbd25361d080c2d9f624924aa9f112d1)", + "scarb-metadata 1.13.0 (git+https://github.com/dojoengine/scarb?rev=a3b3c7fae12aecd3ce1502b1a651fced6be546df)", + "scarb-proc-macro-server-types 0.1.0 (git+https://github.com/dojoengine/scarb?rev=a3b3c7fae12aecd3ce1502b1a651fced6be546df)", + "scarb-stable-hash 1.0.0 (git+https://github.com/dojoengine/scarb?rev=a3b3c7fae12aecd3ce1502b1a651fced6be546df)", "scarb-ui", "semver 1.0.23", "serde", @@ -12564,7 +12486,7 @@ dependencies = [ [[package]] name = "scarb-build-metadata" version = "2.9.2" -source = "git+https://github.com/dojoengine/scarb?rev=da5f683adbd25361d080c2d9f624924aa9f112d1#da5f683adbd25361d080c2d9f624924aa9f112d1" +source = "git+https://github.com/dojoengine/scarb?rev=a3b3c7fae12aecd3ce1502b1a651fced6be546df#a3b3c7fae12aecd3ce1502b1a651fced6be546df" dependencies = [ "cargo_metadata", ] @@ -12585,7 +12507,7 @@ dependencies = [ [[package]] name = "scarb-metadata" version = "1.13.0" -source = "git+https://github.com/dojoengine/scarb?rev=da5f683adbd25361d080c2d9f624924aa9f112d1#da5f683adbd25361d080c2d9f624924aa9f112d1" +source = "git+https://github.com/dojoengine/scarb?rev=a3b3c7fae12aecd3ce1502b1a651fced6be546df#a3b3c7fae12aecd3ce1502b1a651fced6be546df" dependencies = [ "camino", "derive_builder", @@ -12609,7 +12531,7 @@ dependencies = [ [[package]] name = "scarb-proc-macro-server-types" version = "0.1.0" -source = "git+https://github.com/dojoengine/scarb?rev=da5f683adbd25361d080c2d9f624924aa9f112d1#da5f683adbd25361d080c2d9f624924aa9f112d1" +source = "git+https://github.com/dojoengine/scarb?rev=a3b3c7fae12aecd3ce1502b1a651fced6be546df#a3b3c7fae12aecd3ce1502b1a651fced6be546df" dependencies = [ "cairo-lang-macro", "serde", @@ -12629,7 +12551,7 @@ dependencies = [ [[package]] name = "scarb-stable-hash" version = "1.0.0" -source = "git+https://github.com/dojoengine/scarb?rev=da5f683adbd25361d080c2d9f624924aa9f112d1#da5f683adbd25361d080c2d9f624924aa9f112d1" +source = "git+https://github.com/dojoengine/scarb?rev=a3b3c7fae12aecd3ce1502b1a651fced6be546df#a3b3c7fae12aecd3ce1502b1a651fced6be546df" dependencies = [ "data-encoding", "xxhash-rust", @@ -12638,14 +12560,14 @@ dependencies = [ [[package]] name = "scarb-ui" version = "0.1.5" -source = "git+https://github.com/dojoengine/scarb?rev=da5f683adbd25361d080c2d9f624924aa9f112d1#da5f683adbd25361d080c2d9f624924aa9f112d1" +source = "git+https://github.com/dojoengine/scarb?rev=a3b3c7fae12aecd3ce1502b1a651fced6be546df#a3b3c7fae12aecd3ce1502b1a651fced6be546df" dependencies = [ "anyhow", "camino", "clap", "console", "indicatif", - "scarb-metadata 1.13.0 (git+https://github.com/dojoengine/scarb?rev=da5f683adbd25361d080c2d9f624924aa9f112d1)", + "scarb-metadata 1.13.0 (git+https://github.com/dojoengine/scarb?rev=a3b3c7fae12aecd3ce1502b1a651fced6be546df)", "serde", "serde_json", "tracing-core", @@ -13335,11 +13257,11 @@ dependencies = [ [[package]] name = "sozo" -version = "1.1.2" +version = "1.0.12" dependencies = [ "anyhow", "async-trait", - "cainome 0.4.11 (git+https://github.com/cartridge-gg/cainome?tag=v0.4.12)", + "cainome 0.4.11", "cairo-lang-sierra", "cairo-lang-test-plugin", "cairo-lang-test-runner", @@ -13349,7 +13271,7 @@ dependencies = [ "colored", "dojo-bindgen", "dojo-test-utils", - "dojo-types 1.1.2", + "dojo-types 1.0.12", "dojo-utils", "dojo-world", "katana-rpc-api", @@ -13357,7 +13279,7 @@ dependencies = [ "notify", "reqwest 0.11.27", "scarb", - "scarb-metadata 1.13.0 (git+https://github.com/dojoengine/scarb?rev=da5f683adbd25361d080c2d9f624924aa9f112d1)", + "scarb-metadata 1.13.0 (git+https://github.com/dojoengine/scarb?rev=a3b3c7fae12aecd3ce1502b1a651fced6be546df)", "scarb-ui", "semver 1.0.23", "serde", @@ -13381,16 +13303,16 @@ dependencies = [ [[package]] name = "sozo-ops" -version = "1.1.2" +version = "1.0.12" dependencies = [ "anyhow", "assert_fs", "async-trait", - "cainome 0.4.11 (git+https://github.com/cartridge-gg/cainome?tag=v0.4.12)", + "cainome 0.4.11", "colored", "colored_json", "dojo-test-utils", - "dojo-types 1.1.2", + "dojo-types 1.0.12", "dojo-utils", "dojo-world", "futures", @@ -13413,7 +13335,7 @@ dependencies = [ [[package]] name = "sozo-scarbext" -version = "1.1.2" +version = "1.0.12" dependencies = [ "anyhow", "camino", @@ -13426,7 +13348,7 @@ dependencies = [ [[package]] name = "sozo-signers" -version = "1.1.2" +version = "1.0.12" dependencies = [ "anyhow", "starknet", @@ -13434,7 +13356,7 @@ dependencies = [ [[package]] name = "sozo-walnut" -version = "1.1.2" +version = "1.0.12" dependencies = [ "anyhow", "clap", @@ -13447,7 +13369,6 @@ dependencies = [ "serde_json", "starknet", "thiserror 1.0.63", - "toml 0.8.19", "url", "urlencoding", "walkdir", @@ -13795,26 +13716,6 @@ dependencies = [ "starknet-types-core", ] -[[package]] -name = "starknet-crypto" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3f2175b0b3fc24ff2ec6dc07f5a720498994effca7e78b11a6e1c1bd02cad52" -dependencies = [ - "crypto-bigint", - "hex", - "hmac", - "num-bigint", - "num-integer", - "num-traits 0.2.19", - "rfc6979", - "sha2", - "starknet-crypto-codegen", - "starknet-curve 0.3.0", - "starknet-ff", - "zeroize", -] - [[package]] name = "starknet-crypto" version = "0.6.2" @@ -13865,15 +13766,6 @@ dependencies = [ "syn 2.0.90", ] -[[package]] -name = "starknet-curve" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "252610baff59e4c4332ce3569f7469c5d3f9b415a2240d698fb238b2b4fc0942" -dependencies = [ - "starknet-ff", -] - [[package]] name = "starknet-curve" version = "0.4.2" @@ -13971,24 +13863,27 @@ dependencies = [ [[package]] name = "starknet_api" -version = "0.13.0-rc.1" -source = "git+https://github.com/dojoengine/sequencer?rev=adae779#adae779dd758fb3cdedec0af61651f80ec463279" +version = "0.0.0" +source = "git+https://github.com/dojoengine/sequencer?rev=802c5dc#802c5dc1b3ca231d96b65ffcada349f4b5ab0e3b" dependencies = [ "bitvec", + "cairo-lang-runner", "cairo-lang-starknet-classes", "derive_more 0.99.18", "hex", "indexmap 2.5.0", "itertools 0.12.1", - "once_cell", + "num-bigint", + "pretty_assertions", "primitive-types", + "semver 1.0.23", "serde", "serde_json", "sha3", - "starknet-crypto 0.5.2", + "starknet-crypto 0.7.2", "starknet-types-core", - "strum 0.24.1", - "strum_macros 0.24.3", + "strum 0.25.0", + "strum_macros 0.25.3", "thiserror 1.0.63", ] @@ -14046,12 +13941,6 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" -[[package]] -name = "strum" -version = "0.24.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f" - [[package]] name = "strum" version = "0.25.0" @@ -14067,19 +13956,6 @@ dependencies = [ "strum_macros 0.26.4", ] -[[package]] -name = "strum_macros" -version = "0.24.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" -dependencies = [ - "heck 0.4.1", - "proc-macro2", - "quote", - "rustversion", - "syn 1.0.109", -] - [[package]] name = "strum_macros" version = "0.25.3" @@ -14890,7 +14766,7 @@ dependencies = [ [[package]] name = "torii" -version = "1.1.2" +version = "1.0.12" dependencies = [ "anyhow", "clap", @@ -14901,7 +14777,7 @@ dependencies = [ [[package]] name = "torii-cli" -version = "1.1.2" +version = "1.0.12" dependencies = [ "anyhow", "assert_matches", @@ -14917,12 +14793,12 @@ dependencies = [ [[package]] name = "torii-client" -version = "1.1.2" +version = "1.0.12" dependencies = [ "async-trait", "camino", "crypto-bigint", - "dojo-types 1.1.2", + "dojo-types 1.0.12", "dojo-world", "futures", "futures-util", @@ -14945,7 +14821,7 @@ dependencies = [ [[package]] name = "torii-graphql" -version = "1.1.2" +version = "1.0.12" dependencies = [ "anyhow", "async-graphql", @@ -14956,7 +14832,7 @@ dependencies = [ "chrono", "convert_case 0.6.0", "dojo-test-utils", - "dojo-types 1.1.2", + "dojo-types 1.0.12", "dojo-utils", "dojo-world", "katana-runner", @@ -14986,13 +14862,13 @@ dependencies = [ [[package]] name = "torii-grpc" -version = "1.1.2" +version = "1.0.12" dependencies = [ - "cainome 0.4.11 (git+https://github.com/cartridge-gg/cainome?tag=v0.4.12)", + "cainome 0.4.11", "camino", "crypto-bigint", "dojo-test-utils", - "dojo-types 1.1.2", + "dojo-types 1.0.12", "dojo-utils", "dojo-world", "futures", @@ -15034,18 +14910,18 @@ dependencies = [ [[package]] name = "torii-indexer" -version = "1.1.2" +version = "1.0.12" dependencies = [ "anyhow", "async-trait", "base64 0.21.7", "bitflags 2.6.0", - "cainome 0.4.11 (git+https://github.com/cartridge-gg/cainome?tag=v0.4.12)", + "cainome 0.4.11", "chrono", "crypto-bigint", "data-url", "dojo-test-utils", - "dojo-types 1.1.2", + "dojo-types 1.0.12", "dojo-utils", "dojo-world", "futures-channel", @@ -15053,7 +14929,6 @@ dependencies = [ "hashlink", "ipfs-api-backend-hyper", "katana-runner", - "lazy_static", "num-traits 0.2.19", "once_cell", "reqwest 0.11.27", @@ -15075,11 +14950,11 @@ dependencies = [ [[package]] name = "torii-relay" -version = "1.1.2" +version = "1.0.12" dependencies = [ "anyhow", "chrono", - "dojo-types 1.1.2", + "dojo-types 1.0.12", "dojo-world", "futures", "indexmap 2.5.0", @@ -15109,7 +14984,7 @@ dependencies = [ [[package]] name = "torii-runner" -version = "1.1.2" +version = "1.0.12" dependencies = [ "anyhow", "assert_matches", @@ -15119,7 +14994,7 @@ dependencies = [ "chrono", "ctrlc", "dojo-metrics", - "dojo-types 1.1.2", + "dojo-types 1.0.12", "dojo-utils", "dojo-world", "either", @@ -15157,7 +15032,7 @@ dependencies = [ [[package]] name = "torii-server" -version = "1.1.2" +version = "1.0.12" dependencies = [ "anyhow", "async-trait", @@ -15191,18 +15066,18 @@ dependencies = [ [[package]] name = "torii-sqlite" -version = "1.1.2" +version = "1.0.12" dependencies = [ "anyhow", "async-trait", "base64 0.21.7", "bitflags 2.6.0", - "cainome 0.4.11 (git+https://github.com/cartridge-gg/cainome?tag=v0.4.12)", + "cainome 0.4.11", "chrono", "crypto-bigint", "data-url", "dojo-test-utils", - "dojo-types 1.1.2", + "dojo-types 1.0.12", "dojo-utils", "dojo-world", "futures-channel", @@ -15230,11 +15105,11 @@ dependencies = [ [[package]] name = "torii-typed-data" -version = "1.1.2" +version = "1.0.12" dependencies = [ - "cainome 0.4.11 (git+https://github.com/cartridge-gg/cainome?tag=v0.4.12)", + "cainome 0.4.11", "crypto-bigint", - "dojo-types 1.1.2", + "dojo-types 1.0.12", "indexmap 2.5.0", "serde", "serde_json", @@ -15580,7 +15455,7 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "types-test" -version = "1.1.2" +version = "1.0.12" [[package]] name = "u256-literal" @@ -15820,6 +15695,45 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "validator" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d6937c33ec6039d8071bcf72933146b5bbe378d645d8fa59bdadabfc2a249" +dependencies = [ + "idna 0.2.3", + "lazy_static", + "regex", + "serde", + "serde_derive", + "serde_json", + "url", + "validator_derive", + "validator_types", +] + +[[package]] +name = "validator_derive" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4286b4497f270f59276a89ae0ad109d5f8f18c69b613e3fb22b61201aadb0c4d" +dependencies = [ + "if_chain", + "lazy_static", + "proc-macro-error", + "proc-macro2", + "quote", + "regex", + "syn 1.0.109", + "validator_types", +] + +[[package]] +name = "validator_types" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad9680608df133af2c1ddd5eaf1ddce91d60d61b6bc51494ef326458365a470a" + [[package]] name = "valuable" version = "0.1.0" @@ -15882,7 +15796,7 @@ dependencies = [ [[package]] name = "verify_db_balances" -version = "1.1.2" +version = "1.0.12" dependencies = [ "clap", "num-traits 0.2.19", @@ -16963,7 +16877,7 @@ checksum = "9d422e8e38ec76e2f06ee439ccc765e9c6a9638b9e7c9f2e8255e4d41e8bd852" [[package]] name = "xtask-generate-test-db" -version = "1.1.2" +version = "1.0.12" dependencies = [ "anyhow", "dojo-test-utils", diff --git a/crates/torii/indexer/src/engine.rs b/crates/torii/indexer/src/engine.rs index 42acd8e8e9..8d3abbbef5 100644 --- a/crates/torii/indexer/src/engine.rs +++ b/crates/torii/indexer/src/engine.rs @@ -29,6 +29,8 @@ use tracing::{debug, error, info, trace, warn}; use crate::constants::LOG_TARGET; use crate::processors::controller::ControllerProcessor; +use crate::processors::erc1155_transfer_batch::Erc1155TransferBatchProcessor; +use crate::processors::erc1155_transfer_single::Erc1155TransferSingleProcessor; use crate::processors::erc20_legacy_transfer::Erc20LegacyTransferProcessor; use crate::processors::erc20_transfer::Erc20TransferProcessor; use crate::processors::erc721_legacy_transfer::Erc721LegacyTransferProcessor; @@ -107,6 +109,13 @@ impl Processors

{ Box::new(Erc721LegacyTransferProcessor) as Box>, ], ), + ( + ContractType::ERC1155, + vec![ + Box::new(Erc1155TransferBatchProcessor) as Box>, + Box::new(Erc1155TransferSingleProcessor) as Box>, + ], + ), (ContractType::UDC, vec![Box::new(ControllerProcessor) as Box>]), ]; diff --git a/crates/torii/indexer/src/processors/erc1155_transfer_batch.rs b/crates/torii/indexer/src/processors/erc1155_transfer_batch.rs new file mode 100644 index 0000000000..3738983755 --- /dev/null +++ b/crates/torii/indexer/src/processors/erc1155_transfer_batch.rs @@ -0,0 +1,113 @@ +use anyhow::Error; +use async_trait::async_trait; +use cainome::cairo_serde::{CairoSerde, U256 as U256Cainome}; +use dojo_world::contracts::world::WorldContractReader; +use starknet::core::types::{Event, U256}; +use starknet::providers::Provider; +use torii_sqlite::Sql; +use tracing::debug; + +use super::{EventProcessor, EventProcessorConfig}; +use crate::task_manager::{self, TaskId, TaskPriority}; + +pub(crate) const LOG_TARGET: &str = "torii_indexer::processors::erc1155_transfer_batch"; + +#[derive(Default, Debug)] +pub struct Erc1155TransferBatchProcessor; + +#[async_trait] +impl

EventProcessor

for Erc1155TransferBatchProcessor +where + P: Provider + Send + Sync + std::fmt::Debug, +{ + fn event_key(&self) -> String { + "TransferBatch".to_string() + } + + fn validate(&self, event: &Event) -> bool { + // key: [hash(TransferBatch), operator, from, to] + // data: [ids_len, ids[0].low, ids[0].high, ..., values_len, values[0].low, values[0].high, + // ...] + event.keys.len() == 4 && !event.data.is_empty() + } + + fn task_priority(&self) -> TaskPriority { + 1 + } + + fn task_identifier(&self, _event: &Event) -> TaskId { + task_manager::TASK_ID_SEQUENTIAL + } + + async fn process( + &self, + _world: &WorldContractReader

, + db: &mut Sql, + block_number: u64, + block_timestamp: u64, + event_id: &str, + event: &Event, + _config: &EventProcessorConfig, + ) -> Result<(), Error> { + let token_address = event.from_address; + let from = event.keys[2]; + let to = event.keys[3]; + + // ERC1155 TransferBatch event data format: + // - ids_len: felt (first element) + // - ids: U256[] (each element stored as 2 felts: [low, high]) + // - values_len: felt + // - values: U256[] (each element stored as 2 felts: [low, high]) + // Spec reference: https://eips.ethereum.org/EIPS/eip-1155#transferbatch + let ids_len = event.data[0].try_into().unwrap_or(0u64) as usize; + let mut current_idx = 1; + + // First pass: read all token IDs + let mut token_ids = Vec::with_capacity(ids_len); + for _ in 0..ids_len { + if current_idx + 1 >= event.data.len() { + break; + } + let token_id = U256Cainome::cairo_deserialize(&event.data, current_idx)?; + token_ids.push(U256::from_words(token_id.low, token_id.high)); + current_idx += 2; + } + + // Move index to values array + let values_len = event.data[current_idx].try_into().unwrap_or(0u64) as usize; + current_idx += 1; + + // Second pass: read and process amounts + for (idx, token_id) in token_ids.iter().enumerate() { + if idx >= values_len || current_idx + (idx * 2) + 1 >= event.data.len() { + break; + } + + let amount = U256Cainome::cairo_deserialize(&event.data, current_idx + (idx * 2))?; + let amount = U256::from_words(amount.low, amount.high); + + db.handle_nft_transfer( + token_address, + from, + to, + *token_id, + amount, + block_timestamp, + event_id, + block_number, + ) + .await?; + + debug!( + target: LOG_TARGET, + from = ?from, + to = ?to, + token_id = ?token_id, + amount = ?amount, + "ERC1155 TransferBatch" + ); + } + + Ok(()) + } +} diff --git a/crates/torii/indexer/src/processors/erc1155_transfer_single.rs b/crates/torii/indexer/src/processors/erc1155_transfer_single.rs new file mode 100644 index 0000000000..f9deecc729 --- /dev/null +++ b/crates/torii/indexer/src/processors/erc1155_transfer_single.rs @@ -0,0 +1,76 @@ +use anyhow::Error; +use async_trait::async_trait; +use cainome::cairo_serde::{CairoSerde, U256 as U256Cainome}; +use dojo_world::contracts::world::WorldContractReader; +use starknet::core::types::{Event, U256}; +use starknet::providers::Provider; +use torii_sqlite::Sql; +use tracing::debug; + +use super::{EventProcessor, EventProcessorConfig}; +use crate::task_manager::{self, TaskId, TaskPriority}; + +pub(crate) const LOG_TARGET: &str = "torii_indexer::processors::erc1155_transfer_single"; + +#[derive(Default, Debug)] +pub struct Erc1155TransferSingleProcessor; + +#[async_trait] +impl

EventProcessor

for Erc1155TransferSingleProcessor +where + P: Provider + Send + Sync + std::fmt::Debug, +{ + fn event_key(&self) -> String { + "TransferSingle".to_string() + } + + fn validate(&self, event: &Event) -> bool { + // key: [hash(TransferSingle), operator, from, to] + // data: [id.low, id.high, value.low, value.high] + event.keys.len() == 4 && event.data.len() == 4 + } + + fn task_priority(&self) -> TaskPriority { + 1 + } + + fn task_identifier(&self, _event: &Event) -> TaskId { + task_manager::TASK_ID_SEQUENTIAL + } + + async fn process( + &self, + _world: &WorldContractReader

, + db: &mut Sql, + block_number: u64, + block_timestamp: u64, + event_id: &str, + event: &Event, + _config: &EventProcessorConfig, + ) -> Result<(), Error> { + let token_address = event.from_address; + let from = event.keys[2]; + let to = event.keys[3]; + + let token_id = U256Cainome::cairo_deserialize(&event.data, 0)?; + let token_id = U256::from_words(token_id.low, token_id.high); + + let amount = U256Cainome::cairo_deserialize(&event.data, 2)?; + let amount = U256::from_words(amount.low, amount.high); + + db.handle_nft_transfer( + token_address, + from, + to, + token_id, + amount, + block_timestamp, + event_id, + block_number, + ) + .await?; + debug!(target: LOG_TARGET, from = ?from, to = ?to, token_id = ?token_id, amount = ?amount, "ERC1155 TransferSingle"); + + Ok(()) + } +} diff --git a/crates/torii/indexer/src/processors/erc721_legacy_transfer.rs b/crates/torii/indexer/src/processors/erc721_legacy_transfer.rs index e7b7a856be..4a8414b422 100644 --- a/crates/torii/indexer/src/processors/erc721_legacy_transfer.rs +++ b/crates/torii/indexer/src/processors/erc721_legacy_transfer.rs @@ -80,11 +80,12 @@ where let token_id = U256Cainome::cairo_deserialize(&event.data, 2)?; let token_id = U256::from_words(token_id.low, token_id.high); - db.handle_erc721_transfer( + db.handle_nft_transfer( token_address, from, to, token_id, + U256::from(1u8), block_timestamp, event_id, block_number, diff --git a/crates/torii/indexer/src/processors/erc721_transfer.rs b/crates/torii/indexer/src/processors/erc721_transfer.rs index 8ecc84ba49..c05f75274b 100644 --- a/crates/torii/indexer/src/processors/erc721_transfer.rs +++ b/crates/torii/indexer/src/processors/erc721_transfer.rs @@ -80,11 +80,12 @@ where let token_id = U256Cainome::cairo_deserialize(&event.keys, 3)?; let token_id = U256::from_words(token_id.low, token_id.high); - db.handle_erc721_transfer( + db.handle_nft_transfer( token_address, from, to, token_id, + U256::from(1u8), block_timestamp, event_id, block_number, diff --git a/crates/torii/indexer/src/processors/mod.rs b/crates/torii/indexer/src/processors/mod.rs index 96d2b250f2..af80648cde 100644 --- a/crates/torii/indexer/src/processors/mod.rs +++ b/crates/torii/indexer/src/processors/mod.rs @@ -10,6 +10,8 @@ use torii_sqlite::Sql; use crate::task_manager::{TaskId, TaskPriority}; pub mod controller; +pub mod erc1155_transfer_batch; +pub mod erc1155_transfer_single; pub mod erc20_legacy_transfer; pub mod erc20_transfer; pub mod erc721_legacy_transfer; diff --git a/crates/torii/migrations/20250212025607_transfers_event_id.sql b/crates/torii/migrations/20250212025607_transfers_event_id.sql new file mode 100644 index 0000000000..e07ec3d195 --- /dev/null +++ b/crates/torii/migrations/20250212025607_transfers_event_id.sql @@ -0,0 +1,2 @@ +ALTER TABLE token_transfers +ADD COLUMN event_id TEXT; diff --git a/crates/torii/sqlite/src/erc.rs b/crates/torii/sqlite/src/erc.rs index 427a49a8d8..f75a08fc2d 100644 --- a/crates/torii/sqlite/src/erc.rs +++ b/crates/torii/sqlite/src/erc.rs @@ -10,9 +10,9 @@ use starknet::providers::Provider; use super::utils::{u256_to_sql_string, I256}; use super::{Sql, SQL_FELT_DELIMITER}; use crate::constants::TOKEN_TRANSFER_TABLE; +use crate::executor::erc::RegisterNftTokenQuery; use crate::executor::{ ApplyBalanceDiffQuery, Argument, QueryMessage, QueryType, RegisterErc20TokenQuery, - RegisterErc721TokenQuery, }; use crate::types::ContractType; use crate::utils::{ @@ -79,12 +79,13 @@ impl Sql { } #[allow(clippy::too_many_arguments)] - pub async fn handle_erc721_transfer( + pub async fn handle_nft_transfer( &mut self, contract_address: Felt, from_address: Felt, to_address: Felt, token_id: U256, + amount: U256, block_timestamp: u64, event_id: &str, block_number: u64, @@ -95,15 +96,14 @@ impl Sql { let token_exists: bool = self.local_cache.contains_token_id(&token_id).await; if !token_exists { - self.register_erc721_token_metadata(contract_address, &token_id, actual_token_id) - .await?; + self.register_nft_token_metadata(contract_address, &token_id, actual_token_id).await?; } self.store_erc_transfer_event( contract_address, from_address, to_address, - U256::from(1u8), + amount, &token_id, block_timestamp, event_id, @@ -120,7 +120,7 @@ impl Sql { ); let from_balance = erc_cache.entry((ContractType::ERC721, from_balance_id)).or_default(); - *from_balance -= I256::from(1u8); + *from_balance -= I256::from(amount); } if to_address != Felt::ZERO { @@ -128,7 +128,7 @@ impl Sql { format!("{}{SQL_FELT_DELIMITER}{}", felt_to_sql_string(&to_address), &token_id); let to_balance = erc_cache.entry((ContractType::ERC721, to_balance_id)).or_default(); - *to_balance += I256::from(1u8); + *to_balance += I256::from(amount); } } @@ -220,7 +220,7 @@ impl Sql { Ok(()) } - async fn register_erc721_token_metadata( + async fn register_nft_token_metadata( &mut self, contract_address: Felt, token_id: &str, @@ -229,7 +229,7 @@ impl Sql { self.executor.send(QueryMessage::new( "".to_string(), vec![], - QueryType::RegisterErc721Token(RegisterErc721TokenQuery { + QueryType::RegisterNftToken(RegisterNftTokenQuery { token_id: token_id.to_string(), contract_address, actual_token_id, @@ -256,20 +256,22 @@ impl Sql { block_timestamp: u64, event_id: &str, ) -> Result<()> { + let id = format!("{}:{}", event_id, token_id); let insert_query = format!( "INSERT INTO {TOKEN_TRANSFER_TABLE} (id, contract_address, from_address, to_address, \ - amount, token_id, executed_at) VALUES (?, ?, ?, ?, ?, ?, ?)" + amount, token_id, event_id, executed_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?)" ); self.executor.send(QueryMessage::new( insert_query.to_string(), vec![ - Argument::String(event_id.to_string()), + Argument::String(id), Argument::FieldElement(contract_address), Argument::FieldElement(from), Argument::FieldElement(to), Argument::String(u256_to_sql_string(&amount)), Argument::String(token_id.to_string()), + Argument::String(event_id.to_string()), Argument::String(utc_dt_string_from_timestamp(block_timestamp)), ], QueryType::TokenTransfer, diff --git a/crates/torii/sqlite/src/executor/erc.rs b/crates/torii/sqlite/src/executor/erc.rs index 4359206f8c..245c3f56da 100644 --- a/crates/torii/sqlite/src/executor/erc.rs +++ b/crates/torii/sqlite/src/executor/erc.rs @@ -23,15 +23,15 @@ use crate::utils::{ }; #[derive(Debug, Clone)] -pub struct RegisterErc721TokenQuery { +pub struct RegisterNftTokenQuery { pub token_id: String, pub contract_address: Felt, pub actual_token_id: U256, } #[derive(Debug, Clone)] -pub struct RegisterErc721TokenMetadata { - pub query: RegisterErc721TokenQuery, +pub struct RegisterNftTokenMetadata { + pub query: RegisterNftTokenQuery, pub name: String, pub symbol: String, pub metadata: String, @@ -85,6 +85,26 @@ impl<'c, P: Provider + Sync + Send + 'static> Executor<'c, P> { let contract_address = id[1]; let token_id = id[1]; + self.apply_balance_diff_helper( + id_str, + account_address, + contract_address, + token_id, + balance, + Arc::clone(&provider), + apply_balance_diff.block_id, + ) + .await + .with_context(|| "Failed to apply balance diff in apply_cache_diff")?; + } + ContractType::ERC1155 => { + // account_address/contract_address:id => ERC1155 + assert!(id.len() == 2); + let account_address = id[0]; + let token_id = id[1]; + let mid = token_id.split(":").collect::>(); + let contract_address = mid[0]; + self.apply_balance_diff_helper( id_str, account_address, @@ -181,20 +201,20 @@ impl<'c, P: Provider + Sync + Send + 'static> Executor<'c, P> { Ok(()) } - pub async fn process_register_erc721_token_query( - register_erc721_token: RegisterErc721TokenQuery, + pub async fn process_register_nft_token_query( + register_nft_token: RegisterNftTokenQuery, provider: Arc

, name: String, symbol: String, - ) -> Result { + ) -> Result { let token_uri = if let Ok(token_uri) = provider .call( FunctionCall { - contract_address: register_erc721_token.contract_address, + contract_address: register_nft_token.contract_address, entry_point_selector: get_selector_from_name("token_uri").unwrap(), calldata: vec![ - register_erc721_token.actual_token_id.low().into(), - register_erc721_token.actual_token_id.high().into(), + register_nft_token.actual_token_id.low().into(), + register_nft_token.actual_token_id.high().into(), ], }, BlockId::Tag(BlockTag::Pending), @@ -205,11 +225,28 @@ impl<'c, P: Provider + Sync + Send + 'static> Executor<'c, P> { } else if let Ok(token_uri) = provider .call( FunctionCall { - contract_address: register_erc721_token.contract_address, + contract_address: register_nft_token.contract_address, entry_point_selector: get_selector_from_name("tokenURI").unwrap(), calldata: vec![ - register_erc721_token.actual_token_id.low().into(), - register_erc721_token.actual_token_id.high().into(), + register_nft_token.actual_token_id.low().into(), + register_nft_token.actual_token_id.high().into(), + ], + }, + BlockId::Tag(BlockTag::Pending), + ) + .await + { + token_uri + } + // erc1155 + else if let Ok(token_uri) = provider + .call( + FunctionCall { + contract_address: register_nft_token.contract_address, + entry_point_selector: get_selector_from_name("uri").unwrap(), + calldata: vec![ + register_nft_token.actual_token_id.low().into(), + register_nft_token.actual_token_id.high().into(), ], }, BlockId::Tag(BlockTag::Pending), @@ -219,8 +256,8 @@ impl<'c, P: Provider + Sync + Send + 'static> Executor<'c, P> { token_uri } else { warn!( - contract_address = format!("{:#x}", register_erc721_token.contract_address), - token_id = %register_erc721_token.actual_token_id, + contract_address = format!("{:#x}", register_nft_token.contract_address), + token_id = %register_nft_token.actual_token_id, "Error fetching token URI, empty metadata will be used instead.", ); @@ -228,7 +265,7 @@ impl<'c, P: Provider + Sync + Send + 'static> Executor<'c, P> { ByteArray::cairo_serialize(&"".try_into().unwrap()) }; - let token_uri = if let Ok(byte_array) = ByteArray::cairo_deserialize(&token_uri, 0) { + let mut token_uri = if let Ok(byte_array) = ByteArray::cairo_deserialize(&token_uri, 0) { byte_array.to_string().expect("Return value not String") } else if let Ok(felt_array) = Vec::::cairo_deserialize(&token_uri, 0) { felt_array @@ -238,31 +275,43 @@ impl<'c, P: Provider + Sync + Send + 'static> Executor<'c, P> { .map(|strings| strings.join("")) .map_err(|_| anyhow::anyhow!("Failed parsing Array to String"))? } else { - return Err(anyhow::anyhow!("token_uri is neither ByteArray nor Array")); + debug!( + contract_address = format!("{:#x}", register_nft_token.contract_address), + token_id = %register_nft_token.actual_token_id, + token_uri = %token_uri.iter().map(|f| format!("{:#x}", f)).collect::>().join(", "), + "token_uri is neither ByteArray nor Array" + ); + "".to_string() }; + // ERC1155 standard (https://eips.ethereum.org/EIPS/eip-1155#metadata) + // requires replacing {id} in the URI with the hex representation of the token ID + // padded to 64 hex chars (32 bytes). Example: + // "ipfs://QmSome/metadata/{id}.json" -> + // "ipfs://QmSome/metadata/000000000000000000000000000000000000000000000000000000000000000a. + // json" + let token_id_hex = format!("{:064x}", register_nft_token.actual_token_id); + token_uri = token_uri.replace("{id}", &token_id_hex); + let metadata = if token_uri.is_empty() { "".to_string() } else { let metadata = Self::fetch_metadata(&token_uri).await; - match metadata { - Ok(metadata) => { - serde_json::to_string(&metadata).context("Failed to serialize metadata")? - } - Err(err) => { - debug!(error = %err, token_uri = %token_uri, "Error fetching metadata"); - warn!( - contract_address = format!("{:#x}", register_erc721_token.contract_address), - token_id = %register_erc721_token.actual_token_id, - "Error fetching metadata, empty metadata will be used instead.", - ); - "".to_string() - } + if let Ok(metadata) = metadata { + serde_json::to_string(&metadata).context("Failed to serialize metadata")? + } else { + warn!( + contract_address = format!("{:#x}", register_nft_token.contract_address), + token_id = %register_nft_token.actual_token_id, + token_uri = %token_uri, + "Error fetching metadata, empty metadata will be used instead.", + ); + "".to_string() } }; - Ok(RegisterErc721TokenMetadata { query: register_erc721_token, metadata, name, symbol }) + Ok(RegisterNftTokenMetadata { query: register_nft_token, metadata, name, symbol }) } // given a uri which can be either http/https url or data uri, fetch the metadata erc721 @@ -336,9 +385,9 @@ impl<'c, P: Provider + Sync + Send + 'static> Executor<'c, P> { } } - pub async fn handle_erc721_token_metadata( + pub async fn handle_nft_token_metadata( &mut self, - result: RegisterErc721TokenMetadata, + result: RegisterNftTokenMetadata, ) -> Result<()> { let query = sqlx::query_as::<_, Token>( "INSERT INTO tokens (id, contract_address, name, symbol, decimals, metadata) VALUES \ diff --git a/crates/torii/sqlite/src/executor/mod.rs b/crates/torii/sqlite/src/executor/mod.rs index c067feee55..2b1883589d 100644 --- a/crates/torii/sqlite/src/executor/mod.rs +++ b/crates/torii/sqlite/src/executor/mod.rs @@ -7,6 +7,7 @@ use std::time::{SystemTime, UNIX_EPOCH}; use anyhow::{Context, Result}; use cainome::cairo_serde::{ByteArray, CairoSerde}; use dojo_types::schema::{Struct, Ty}; +use erc::RegisterNftTokenMetadata; use sqlx::{FromRow, Pool, Sqlite, Transaction}; use starknet::core::types::{BlockId, BlockTag, Felt, FunctionCall}; use starknet::core::utils::{get_selector_from_name, parse_cairo_short_string}; @@ -28,7 +29,7 @@ use crate::types::{ use crate::utils::{felt_to_sql_string, I256}; pub mod erc; -pub use erc::{RegisterErc20TokenQuery, RegisterErc721TokenMetadata, RegisterErc721TokenQuery}; +pub use erc::{RegisterErc20TokenQuery, RegisterNftTokenQuery}; pub(crate) const LOG_TARGET: &str = "torii::sqlite::executor"; @@ -111,7 +112,7 @@ pub enum QueryType { DeleteEntity(DeleteEntityQuery), EventMessage(EventMessageQuery), ApplyBalanceDiff(ApplyBalanceDiffQuery), - RegisterErc721Token(RegisterErc721TokenQuery), + RegisterNftToken(RegisterNftTokenQuery), RegisterErc20Token(RegisterErc20TokenQuery), TokenTransfer, RegisterModel, @@ -135,7 +136,7 @@ pub struct Executor<'c, P: Provider + Sync + Send + 'static> { shutdown_rx: Receiver<()>, // These tasks are spawned to fetch ERC721 token metadata from the chain // to not block the main loop - register_tasks: JoinSet>, + register_tasks: JoinSet>, // Some queries depends on the metadata being registered, so we defer them // until the metadata is fetched deferred_query_messages: Vec, @@ -275,7 +276,7 @@ impl<'c, P: Provider + Sync + Send + 'static> Executor<'c, P> { } Some(result) = self.register_tasks.join_next() => { let result = result??; - self.handle_erc721_token_metadata(result).await?; + self.handle_nft_token_metadata(result).await?; } } } @@ -618,68 +619,72 @@ impl<'c, P: Provider + Sync + Send + 'static> Executor<'c, P> { self.apply_balance_diff(apply_balance_diff, self.provider.clone()).await?; debug!(target: LOG_TARGET, duration = ?instant.elapsed(), "Applied balance diff."); } - QueryType::RegisterErc721Token(register_erc721_token) => { + QueryType::RegisterNftToken(register_nft_token) => { let semaphore = self.semaphore.clone(); let provider = self.provider.clone(); let res = sqlx::query_as::<_, (String, String)>(&format!( "SELECT name, symbol FROM {TOKENS_TABLE} WHERE contract_address = ? LIMIT 1" )) - .bind(felt_to_sql_string(®ister_erc721_token.contract_address)) + .bind(felt_to_sql_string(®ister_nft_token.contract_address)) .fetch_one(&mut **tx) .await; // If we find a token already registered for this contract_address we dont need to - // refetch the data since its same for all ERC721 tokens + // refetch the data since its same for all tokens of this contract let (name, symbol) = match res { Ok((name, symbol)) => { debug!( - contract_address = %felt_to_sql_string(®ister_erc721_token.contract_address), + contract_address = %felt_to_sql_string(®ister_nft_token.contract_address), "Token already registered for contract_address, so reusing fetched data", ); (name, symbol) } Err(_) => { - // Fetch token information from the chain - let name = provider + // Try to fetch name, use empty string if it fails + let name = match provider .call( FunctionCall { - contract_address: register_erc721_token.contract_address, + contract_address: register_nft_token.contract_address, entry_point_selector: get_selector_from_name("name").unwrap(), calldata: vec![], }, BlockId::Tag(BlockTag::Pending), ) - .await?; - - // len = 1 => return value felt (i.e. legacy erc721 token) - // len > 1 => return value ByteArray (i.e. new erc721 token) - let name = if name.len() == 1 { - parse_cairo_short_string(&name[0]).unwrap() - } else { - ByteArray::cairo_deserialize(&name, 0) - .expect("Return value not ByteArray") - .to_string() - .expect("Return value not String") + .await + { + Ok(name) => { + // len = 1 => return value felt (i.e. legacy erc721 token) + // len > 1 => return value ByteArray (i.e. new erc721 token) + if name.len() == 1 { + parse_cairo_short_string(&name[0])? + } else { + ByteArray::cairo_deserialize(&name, 0)?.to_string()? + } + } + Err(_) => "".to_string(), }; - let symbol = provider + // Try to fetch symbol, use empty string if it fails + let symbol = match provider .call( FunctionCall { - contract_address: register_erc721_token.contract_address, + contract_address: register_nft_token.contract_address, entry_point_selector: get_selector_from_name("symbol").unwrap(), calldata: vec![], }, BlockId::Tag(BlockTag::Pending), ) - .await?; - let symbol = if symbol.len() == 1 { - parse_cairo_short_string(&symbol[0]).unwrap() - } else { - ByteArray::cairo_deserialize(&symbol, 0) - .expect("Return value not ByteArray") - .to_string() - .expect("Return value not String") + .await + { + Ok(symbol) => { + if symbol.len() == 1 { + parse_cairo_short_string(&symbol[0])? + } else { + ByteArray::cairo_deserialize(&symbol, 0)?.to_string()? + } + } + Err(_) => "".to_string(), }; (name, symbol) @@ -689,8 +694,8 @@ impl<'c, P: Provider + Sync + Send + 'static> Executor<'c, P> { self.register_tasks.spawn(async move { let permit = semaphore.acquire().await.unwrap(); - let result = Self::process_register_erc721_token_query( - register_erc721_token, + let result = Self::process_register_nft_token_query( + register_nft_token, provider, name, symbol, @@ -793,7 +798,7 @@ impl<'c, P: Provider + Sync + Send + 'static> Executor<'c, P> { while let Some(result) = self.register_tasks.join_next().await { let result = result??; - self.handle_erc721_token_metadata(result).await?; + self.handle_nft_token_metadata(result).await?; } let mut deferred_query_messages = mem::take(&mut self.deferred_query_messages); diff --git a/crates/torii/sqlite/src/types.rs b/crates/torii/sqlite/src/types.rs index f01829427d..ab76bbd9e5 100644 --- a/crates/torii/sqlite/src/types.rs +++ b/crates/torii/sqlite/src/types.rs @@ -156,6 +156,7 @@ pub enum ContractType { WORLD, ERC20, ERC721, + ERC1155, UDC, } @@ -173,6 +174,7 @@ impl FromStr for ContractType { "world" => Ok(ContractType::WORLD), "erc20" => Ok(ContractType::ERC20), "erc721" => Ok(ContractType::ERC721), + "erc1155" => Ok(ContractType::ERC1155), "udc" => Ok(ContractType::UDC), _ => Err(anyhow::anyhow!("Invalid ERC type: {}", input)), } @@ -185,6 +187,7 @@ impl std::fmt::Display for ContractType { ContractType::WORLD => write!(f, "WORLD"), ContractType::ERC20 => write!(f, "ERC20"), ContractType::ERC721 => write!(f, "ERC721"), + ContractType::ERC1155 => write!(f, "ERC1155"), ContractType::UDC => write!(f, "UDC"), } } diff --git a/crates/torii/sqlite/src/utils.rs b/crates/torii/sqlite/src/utils.rs index be11b9c8a5..9aa8c3d107 100644 --- a/crates/torii/sqlite/src/utils.rs +++ b/crates/torii/sqlite/src/utils.rs @@ -10,7 +10,7 @@ use ipfs_api_backend_hyper::{IpfsApi, IpfsClient, TryFromUri}; use starknet::core::types::U256; use starknet_crypto::Felt; use tokio_util::bytes::Bytes; -use tracing::warn; +use tracing::debug; use crate::constants::{ IPFS_CLIENT_MAX_RETRY, IPFS_CLIENT_PASSWORD, IPFS_CLIENT_URL, IPFS_CLIENT_USERNAME, @@ -116,7 +116,7 @@ pub async fn fetch_content_from_ipfs(cid: &str) -> Result { Ok(stream) => return Ok(Bytes::from(stream)), Err(e) => { retries -= 1; - warn!( + debug!( error = %e, remaining_attempts = retries, cid = cid,