diff --git a/Cargo.lock b/Cargo.lock index 9403e074b1..58de8ed990 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -465,7 +465,7 @@ dependencies = [ "proc-macro2", "quote", "strum 0.25.0", - "syn 2.0.41", + "syn 2.0.47", "thiserror", ] @@ -572,7 +572,7 @@ checksum = "5fd55a5ba1179988837d24ab4c7cc8ed6efdeff578ede0416b4225a5fca35bd0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.47", ] [[package]] @@ -620,7 +620,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.47", ] [[package]] @@ -637,7 +637,7 @@ checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.47", ] [[package]] @@ -852,7 +852,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.41", + "syn 2.0.47", ] [[package]] @@ -1135,7 +1135,7 @@ dependencies = [ "quote", "serde_json", "starknet", - "syn 2.0.41", + "syn 2.0.47", "thiserror", ] @@ -1151,7 +1151,7 @@ dependencies = [ "quote", "serde_json", "starknet", - "syn 2.0.41", + "syn 2.0.47", "thiserror", ] @@ -1392,7 +1392,7 @@ checksum = "c8cc59c40344194d2cc825071080d887826dcf0df37de71e58fc8aa4c344bb84" dependencies = [ "cairo-lang-debug", "quote", - "syn 2.0.41", + "syn 2.0.47", ] [[package]] @@ -1917,7 +1917,7 @@ dependencies = [ "heck 0.4.1", "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.47", ] [[package]] @@ -2317,7 +2317,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "30d2b3721e861707777e3195b0158f950ae6dc4a27e4d02ff9f67e3eb3de199e" dependencies = [ "quote", - "syn 2.0.41", + "syn 2.0.47", ] [[package]] @@ -2384,7 +2384,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.41", + "syn 2.0.47", ] [[package]] @@ -2406,7 +2406,7 @@ checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" dependencies = [ "darling_core 0.20.3", "quote", - "syn 2.0.41", + "syn 2.0.47", ] [[package]] @@ -2827,7 +2827,7 @@ dependencies = [ [[package]] name = "dojo-world-abigen" -version = "0.1.0" +version = "0.4.4" dependencies = [ "cairo-lang-starknet", "camino", @@ -3136,7 +3136,7 @@ dependencies = [ "reqwest", "serde", "serde_json", - "syn 2.0.41", + "syn 2.0.47", "toml 0.8.8", "walkdir", ] @@ -3154,7 +3154,7 @@ dependencies = [ "proc-macro2", "quote", "serde_json", - "syn 2.0.41", + "syn 2.0.47", ] [[package]] @@ -3180,7 +3180,7 @@ dependencies = [ "serde", "serde_json", "strum 0.25.0", - "syn 2.0.41", + "syn 2.0.47", "tempfile", "thiserror", "tiny-keccak", @@ -3642,7 +3642,7 @@ checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.47", ] [[package]] @@ -3713,7 +3713,7 @@ checksum = "d4cf186fea4af17825116f72932fe52cce9a13bae39ff63b4dc0cfdb3fb4bde1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.47", ] [[package]] @@ -4133,7 +4133,7 @@ checksum = "02a5bcaf6704d9354a3071cede7e77d366a5980c7352e102e2c2f9b645b1d3ae" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.47", ] [[package]] @@ -5477,7 +5477,7 @@ dependencies = [ "proc-macro2", "quote", "serde", - "syn 2.0.41", + "syn 2.0.47", ] [[package]] @@ -5562,8 +5562,11 @@ dependencies = [ "derive_more", "ethers", "flate2", + "num-traits 0.2.17", "serde", "serde_json", + "serde_path_to_error", + "serde_with", "starknet", "starknet_api", "thiserror", @@ -5996,7 +5999,7 @@ checksum = "ddece26afd34c31585c74a4db0630c376df271c285d682d1e55012197830b6df" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.47", ] [[package]] @@ -6427,7 +6430,7 @@ dependencies = [ "proc-macro-crate 2.0.0", "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.47", ] [[package]] @@ -6520,7 +6523,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.47", ] [[package]] @@ -6801,7 +6804,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.47", ] [[package]] @@ -6865,7 +6868,7 @@ dependencies = [ "phf_shared 0.11.2", "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.47", ] [[package]] @@ -6909,7 +6912,7 @@ checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.47", ] [[package]] @@ -7110,7 +7113,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae005bd773ab59b4725093fd7df83fd7892f7d8eafb48dbd7de6e024e4215f9d" dependencies = [ "proc-macro2", - "syn 2.0.41", + "syn 2.0.47", ] [[package]] @@ -7172,9 +7175,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.70" +version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" +checksum = "907a61bd0f64c2f29cd1cf1dc34d05176426a3f504a78010f08416ddb7b13708" dependencies = [ "unicode-ident", ] @@ -7291,7 +7294,7 @@ dependencies = [ "prost 0.12.3", "prost-types 0.12.3", "regex", - "syn 2.0.41", + "syn 2.0.47", "tempfile", "which 4.4.2", ] @@ -7319,7 +7322,7 @@ dependencies = [ "itertools 0.11.0", "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.47", ] [[package]] @@ -7364,9 +7367,9 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" [[package]] name = "quote" -version = "1.0.33" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] @@ -7751,7 +7754,7 @@ dependencies = [ "regex", "relative-path", "rustc_version", - "syn 2.0.41", + "syn 2.0.47", "unicode-ident", ] @@ -7764,7 +7767,7 @@ dependencies = [ "quote", "rand", "rustc_version", - "syn 2.0.41", + "syn 2.0.47", ] [[package]] @@ -8218,9 +8221,9 @@ checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" [[package]] name = "serde" -version = "1.0.193" +version = "1.0.194" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" +checksum = "0b114498256798c94a0689e1a15fec6005dee8ac1f41de56404b67afc2a4b773" dependencies = [ "serde_derive", ] @@ -8247,13 +8250,13 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.193" +version = "1.0.194" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" +checksum = "a3385e45322e8f9931410f01b3031ec534c3947d0e94c18049af4d9f9907d4e0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.47", ] [[package]] @@ -8289,6 +8292,16 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_path_to_error" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebd154a240de39fdebcf5775d2675c204d7c13cf39a4c697be6493c8e734337c" +dependencies = [ + "itoa", + "serde", +] + [[package]] name = "serde_repr" version = "0.1.17" @@ -8297,7 +8310,7 @@ checksum = "3081f5ffbb02284dda55132aa26daecedd7372a42417bbbab6f14ab7d6bb9145" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.47", ] [[package]] @@ -8346,7 +8359,7 @@ dependencies = [ "darling 0.20.3", "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.47", ] [[package]] @@ -8381,7 +8394,7 @@ checksum = "91d129178576168c589c9ec973feedf7d3126c01ac2bf08795109aa35b69fb8f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.47", ] [[package]] @@ -9023,7 +9036,7 @@ checksum = "af6527b845423542c8a16e060ea1bc43f67229848e7cd4c4d80be994a84220ce" dependencies = [ "starknet-curve 0.4.0", "starknet-ff", - "syn 2.0.41", + "syn 2.0.47", ] [[package]] @@ -9066,7 +9079,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "840be1a7eb5735863eee47d3a3f26df45b9be2c519e8da294e74b4d0524d77d1" dependencies = [ "starknet-core", - "syn 2.0.41", + "syn 2.0.47", ] [[package]] @@ -9199,7 +9212,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.41", + "syn 2.0.47", ] [[package]] @@ -9241,9 +9254,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.41" +version = "2.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44c8b28c477cc3bf0e7966561e3460130e1255f7a1cf71931075f1c5e7a7e269" +checksum = "1726efe18f42ae774cc644f330953a5e7b3c3003d3edcecf18850fe9d4dd9afb" dependencies = [ "proc-macro2", "quote", @@ -9363,7 +9376,7 @@ checksum = "7ba277e77219e9eea169e8508942db1bf5d8a41ff2db9b20aab5a5aadc9fa25d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.47", ] [[package]] @@ -9383,7 +9396,7 @@ checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.47", ] [[package]] @@ -9518,7 +9531,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.47", ] [[package]] @@ -9745,7 +9758,7 @@ dependencies = [ "proc-macro2", "prost-build 0.12.3", "quote", - "syn 2.0.41", + "syn 2.0.47", ] [[package]] @@ -10075,7 +10088,7 @@ checksum = "84fd902d4e0b9a4b27f2f440108dc034e1758628a9b702f8ec61ad66355422fa" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.47", ] [[package]] @@ -10104,7 +10117,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.47", ] [[package]] @@ -10223,7 +10236,7 @@ checksum = "982ee4197351b5c9782847ef5ec1fdcaf50503fb19d68f9771adae314e72b492" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.47", ] [[package]] @@ -10521,7 +10534,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.47", "wasm-bindgen-shared", ] @@ -10555,7 +10568,7 @@ checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.47", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -10995,7 +11008,7 @@ checksum = "be912bf68235a88fbefd1b73415cb218405958d1655b2ece9035a19920bdf6ba" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.47", ] [[package]] @@ -11015,7 +11028,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.47", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index e298885dc1..39d7f367cb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -100,7 +100,7 @@ scarb = { git = "https://github.com/software-mansion/scarb", tag = "v2.4.0" } scarb-ui = { git = "https://github.com/software-mansion/scarb", tag = "v2.4.0" } semver = "1.0.5" serde = { version = "1.0.192", features = [ "derive" ] } -serde_json = "1.0" +serde_json = { version = "1.0", features = [ "arbitrary_precision" ] } serde_with = "2.3.1" smol_str = { version = "0.2.0", features = [ "serde" ] } sqlx = { version = "0.7.2", features = [ "chrono", "macros", "regexp", "runtime-async-std", "runtime-tokio", "sqlite", "uuid" ] } diff --git a/crates/katana/primitives/Cargo.toml b/crates/katana/primitives/Cargo.toml index 1398a4ec7a..532ccd37d7 100644 --- a/crates/katana/primitives/Cargo.toml +++ b/crates/katana/primitives/Cargo.toml @@ -12,6 +12,7 @@ cairo-vm.workspace = true derive_more.workspace = true serde.workspace = true serde_json.workspace = true +serde_with.workspace = true starknet.workspace = true thiserror.workspace = true @@ -21,10 +22,12 @@ flate2.workspace = true starknet_api.workspace = true ethers = "2.0.11" +serde_path_to_error = "0.1.15" +num-traits = "0.2.17" [features] -default = [ "blockifier", "rpc", "serde" ] +default = ["blockifier", "rpc", "serde"] -blockifier = [ ] -rpc = [ ] -serde = [ ] +blockifier = [] +rpc = [] +serde = [] diff --git a/crates/katana/primitives/src/conversion/rpc.rs b/crates/katana/primitives/src/conversion/rpc.rs index 653a30412c..7c9a5a2f23 100644 --- a/crates/katana/primitives/src/conversion/rpc.rs +++ b/crates/katana/primitives/src/conversion/rpc.rs @@ -1,11 +1,18 @@ use std::collections::HashMap; -use std::io::{Read, Write}; +use std::io::{self, Read, Write}; +use std::mem; +use std::str::FromStr; use anyhow::{anyhow, Result}; use blockifier::execution::contract_class::ContractClassV0; use cairo_lang_starknet::casm_contract_class::CasmContractClass; -use cairo_vm::serde::deserialize_program::ProgramJson; -use serde_json::json; +use cairo_vm::felt::Felt252; +use cairo_vm::serde::deserialize_program::{ApTracking, OffsetValue, ProgramJson, ValueAddress}; +use cairo_vm::types::instruction::Register; +use cairo_vm::types::program::Program; +use ethers::core::k256::elliptic_curve::PrimeField; +use serde::{Serialize, Serializer}; +use serde_json::{json, Number}; pub use starknet::core::types::contract::legacy::{LegacyContractClass, LegacyProgram}; pub use starknet::core::types::contract::CompiledClass; use starknet::core::types::{ @@ -59,13 +66,10 @@ pub fn legacy_inner_to_rpc_class( let entry_points_by_type = to_rpc_legacy_entry_points_by_type(&legacy_contract_class.entry_points_by_type)?; - let program = { - let program: ProgramJson = legacy_contract_class.program.clone().into(); - compress(&serde_json::to_vec(&program)?)? - }; + let compressed_program = compress_legacy_program_data(legacy_contract_class.program.clone())?; Ok(ContractClass::Legacy(CompressedLegacyContractClass { - program, + program: compressed_program, abi: None, entry_points_by_type, })) @@ -107,20 +111,24 @@ pub fn compiled_class_hash_from_flattened_sierra_class( pub fn legacy_rpc_to_inner_compiled_class( compressed_legacy_contract: &CompressedLegacyContractClass, ) -> Result<(ClassHash, CompiledContractClass)> { - let legacy_program_json = decompress(&compressed_legacy_contract.program)?; - let legacy_program: LegacyProgram = serde_json::from_str(&legacy_program_json)?; + let program = decompress_legacy_program_data(&compressed_legacy_contract.program)?; + // std::fs::write("bruh.json", &raw_json)?; + // let program: ProgramJson = serde_json::from_slice(&raw_json)?; + + // let jd = &mut serde_json::Deserializer::from_slice(&raw_json); + // let program: ProgramJson = serde_path_to_error::deserialize(jd)?; - let flattened = json!({ - "program": legacy_program, + let class_json = json!({ + "program": program, "abi": compressed_legacy_contract.abi, "entry_points_by_type": compressed_legacy_contract.entry_points_by_type, }); - let legacy_contract_class: LegacyContractClass = serde_json::from_value(flattened.clone())?; + let legacy_contract_class: LegacyContractClass = serde_json::from_value(class_json.clone())?; let class_hash = legacy_contract_class.class_hash()?; - let contract_class: ContractClassV0 = serde_json::from_value(flattened)?; - Ok((class_hash, CompiledContractClass::V0(contract_class))) + let class: ContractClassV0 = serde_json::from_value(class_json)?; + Ok((class_hash, CompiledContractClass::V0(class))) } /// Converts `starknet-rs` RPC [FlattenedSierraClass] type to Cairo's @@ -142,15 +150,217 @@ fn rpc_to_cairo_contract_class( }) } -fn compress(data: &[u8]) -> Result, std::io::Error> { +fn compress_legacy_program_data(legacy_program: Program) -> Result, io::Error> { + use cairo_vm::felt::Felt252; + use cairo_vm::serde::deserialize_program::{ + serialize_program_data, Attribute, BuiltinName, DebugInfo, HintParams, Member, + }; + use cairo_vm::types::relocatable::MaybeRelocatable; + + fn felt_as_dec_str( + value: &Option, + serializer: S, + ) -> Result { + let dec_str = format!("{}", value.clone().unwrap_or_default().to_signed_felt()); + let number = Number::from_str(&dec_str).expect("valid number"); + number.serialize(serializer) + } + + fn value_address_in_str_format( + value_address: &ValueAddress, + serializer: S, + ) -> Result { + serializer.serialize_str(&parse_value_address_to_str(value_address.clone())) + } + + #[derive(Serialize)] + struct Identifier { + #[serde(skip_serializing_if = "Option::is_none")] + pc: Option, + #[serde(rename = "type")] + #[serde(skip_serializing_if = "Option::is_none")] + type_: Option, + #[serde(serialize_with = "felt_as_dec_str")] + #[serde(deserialize_with = "felt_from_number")] + #[serde(skip_serializing_if = "Option::is_none")] + value: Option, + #[serde(skip_serializing_if = "Option::is_none")] + full_name: Option, + #[serde(skip_serializing_if = "Option::is_none")] + members: Option>, + #[serde(skip_serializing_if = "Option::is_none")] + cairo_type: Option, + } + + #[derive(Serialize)] + struct Reference { + ap_tracking_data: ApTracking, + pc: Option, + #[serde(rename(serialize = "value"))] + #[serde(serialize_with = "value_address_in_str_format")] + value_address: ValueAddress, + } + + #[derive(Serialize)] + struct ReferenceManager { + references: Vec, + } + + #[derive(Serialize)] + struct SerializableProgramJson { + prime: String, + builtins: Vec, + #[serde(serialize_with = "serialize_program_data")] + data: Vec, + identifiers: HashMap, + hints: HashMap>, + reference_manager: ReferenceManager, + attributes: Vec, + debug_info: Option, + } + + let program: ProgramJson = ProgramJson::from(legacy_program); + // SAFETY: `SerializableProgramJson` MUST maintain same memory layout as `ProgramJson`. This + // would only work if the fields are in the same order and have the same size. + let program: SerializableProgramJson = unsafe { mem::transmute(program) }; + let buffer = serde_json::to_vec(&program)?; + + std::fs::write("account.json", &buffer)?; + let mut gzip_encoder = flate2::write::GzEncoder::new(Vec::new(), flate2::Compression::fast()); - Write::write_all(&mut gzip_encoder, data)?; + Write::write_all(&mut gzip_encoder, &buffer)?; gzip_encoder.finish() } -fn decompress(data: &[u8]) -> Result { +fn decompress_legacy_program_data(data: &[u8]) -> Result { + use cairo_vm::serde::deserialize_program::{ + serialize_program_data, Attribute, BuiltinName, DebugInfo, HintParams, Identifier, + }; + use cairo_vm::types::relocatable::MaybeRelocatable; + + #[derive(Serialize)] + struct Reference { + ap_tracking_data: ApTracking, + pc: Option, + #[serde(rename(deserialize = "value"))] + value_address: ValueAddress, + } + + #[derive(Serialize)] + struct ReferenceManager { + references: Vec, + } + + #[derive(Serialize)] + struct SerializableProgramJson { + prime: String, + builtins: Vec, + #[serde(serialize_with = "serialize_program_data")] + data: Vec, + identifiers: HashMap, + hints: HashMap>, + reference_manager: ReferenceManager, + attributes: Vec, + debug_info: Option, + } + let mut decoder = flate2::read::GzDecoder::new(data); - let mut decoded = String::new(); - Read::read_to_string(&mut decoder, &mut decoded)?; - Ok(decoded) + let mut decoded = Vec::new(); + Read::read_to_end(&mut decoder, &mut decoded)?; + Ok(serde_json::from_slice(&decoded)?) +} + +fn parse_value_address_to_str(value_address: ValueAddress) -> String { + fn handle_offset_ref(offset: i32, str: &mut String) { + if offset == 0 { + return; + } + + str.push_str(" + "); + str.push_str(&if offset.is_negative() { + format!("({})", offset.to_string()) + } else { + offset.to_string() + }) + } + + fn handle_offset_val(value: OffsetValue, str: &mut String) { + match value { + OffsetValue::Reference(rx, offset, deref) => { + let mut tmp = String::from(match rx { + Register::FP => "fp", + Register::AP => "ap", + }); + + handle_offset_ref(offset, &mut tmp); + + if deref { + str.push_str(&format!("[{tmp}]")); + } else { + str.push_str(&tmp); + } + } + + OffsetValue::Value(value) => handle_offset_ref(value, str), + + OffsetValue::Immediate(value) => { + if value == Felt252::from(0u32) { + return; + } + + str.push_str(" + "); + str.push_str(&value.to_string()); + } + } + } + + let mut str = String::new(); + let is_value: bool; + + if let OffsetValue::Immediate(_) = value_address.offset2 { + is_value = false; + } else { + is_value = true; + } + + handle_offset_val(value_address.offset1, &mut str); + println!("{}", str); + handle_offset_val(value_address.offset2, &mut str); + + str.push_str(", "); + str.push_str(&value_address.value_type); + + if is_value { + str.push_str("*"); + } + + str = format!("cast({str})"); + + // do this last + if value_address.dereference { + str = format!("[{str}]"); + } + + str +} + +#[cfg(test)] +mod tests { + use starknet::core::types::ContractClass; + + use super::{legacy_inner_to_rpc_class, legacy_rpc_to_inner_compiled_class}; + use crate::utils::class::parse_compiled_class_v0; + + #[test] + fn legacy_rpc_to_inner_and_back() { + let class_json = include_str!("../../../core/contracts/compiled/account.json"); + let class = parse_compiled_class_v0(class_json).unwrap(); + + let Ok(ContractClass::Legacy(compressed_legacy_class)) = legacy_inner_to_rpc_class(class) + else { + panic!("Expected legacy class"); + }; + + legacy_rpc_to_inner_compiled_class(&compressed_legacy_class).unwrap(); + } }