From 1a823c2d594719a51b527212d69b41c570cc809b Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Fri, 13 Feb 2026 17:38:33 +0200 Subject: [PATCH 01/11] multiversx-sc-abi crate, moved base/abi module there --- Cargo.lock | 347 +++++++++--------- Cargo.toml | 2 + chain/core/Cargo.toml | 2 +- contracts/examples/multisig/Cargo.toml | 2 +- data/abi-derive/Cargo.toml | 35 ++ data/abi-derive/README.md | 20 + data/abi-derive/src/lib.rs | 27 ++ data/abi-derive/src/parse/attributes.rs | 67 ++++ data/abi-derive/src/parse/mod.rs | 1 + data/abi-derive/src/type_abi_derive.rs | 214 +++++++++++ data/abi/Cargo.toml | 40 ++ data/abi/README.md | 157 ++++++++ .../abi => data/abi/src}/build_info_abi.rs | 0 .../src/abi => data/abi/src}/contract_abi.rs | 0 .../src/abi => data/abi/src}/endpoint_abi.rs | 0 .../abi/src}/esdt_attribute_abi.rs | 0 .../src/abi => data/abi/src}/event_abi.rs | 0 .../base/src/abi.rs => data/abi/src/lib.rs | 30 +- .../base/src/abi => data/abi/src}/type_abi.rs | 0 .../src/abi => data/abi/src}/type_abi_from.rs | 0 .../abi/src}/type_abi_impl_basic.rs | 2 +- .../abi/src}/type_abi_impl_big_int.rs | 0 .../abi/src}/type_abi_impl_codec_multi.rs | 2 +- .../abi/src}/type_abi_impl_vm_core.rs | 0 .../abi => data/abi/src}/type_description.rs | 0 .../abi/src}/type_description_container.rs | 0 data/abi/src/type_names.rs | 25 ++ data/codec-derive/Cargo.toml | 1 + data/codec/Cargo.toml | 1 + framework/base/Cargo.toml | 4 + framework/base/src/lib.rs | 4 +- framework/meta/Cargo.toml | 2 +- 32 files changed, 792 insertions(+), 193 deletions(-) create mode 100644 data/abi-derive/Cargo.toml create mode 100644 data/abi-derive/README.md create mode 100644 data/abi-derive/src/lib.rs create mode 100644 data/abi-derive/src/parse/attributes.rs create mode 100644 data/abi-derive/src/parse/mod.rs create mode 100644 data/abi-derive/src/type_abi_derive.rs create mode 100644 data/abi/Cargo.toml create mode 100644 data/abi/README.md rename {framework/base/src/abi => data/abi/src}/build_info_abi.rs (100%) rename {framework/base/src/abi => data/abi/src}/contract_abi.rs (100%) rename {framework/base/src/abi => data/abi/src}/endpoint_abi.rs (100%) rename {framework/base/src/abi => data/abi/src}/esdt_attribute_abi.rs (100%) rename {framework/base/src/abi => data/abi/src}/event_abi.rs (100%) rename framework/base/src/abi.rs => data/abi/src/lib.rs (51%) rename {framework/base/src/abi => data/abi/src}/type_abi.rs (100%) rename {framework/base/src/abi => data/abi/src}/type_abi_from.rs (100%) rename {framework/base/src/abi => data/abi/src}/type_abi_impl_basic.rs (99%) rename {framework/base/src/abi => data/abi/src}/type_abi_impl_big_int.rs (100%) rename {framework/base/src/abi => data/abi/src}/type_abi_impl_codec_multi.rs (98%) rename {framework/base/src/abi => data/abi/src}/type_abi_impl_vm_core.rs (100%) rename {framework/base/src/abi => data/abi/src}/type_description.rs (100%) rename {framework/base/src/abi => data/abi/src}/type_description_container.rs (100%) create mode 100644 data/abi/src/type_names.rs diff --git a/Cargo.lock b/Cargo.lock index 516a022463..f3555c0a08 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -167,9 +167,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.100" +version = "1.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" +checksum = "5f0e0fee31ef5ed1ba1316088939cea399010ed7731dba877ed44aeb407a75ea" [[package]] name = "arbitrary" @@ -200,9 +200,9 @@ checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "aws-lc-rs" -version = "1.15.3" +version = "1.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e84ce723ab67259cfeb9877c6a639ee9eb7a27b28123abd71db7f0d5d0cc9d86" +checksum = "7b7b6141e96a8c160799cc2d5adecd5cbbe5054cb8c7c4af53da0f83bb7ad256" dependencies = [ "aws-lc-sys", "zeroize", @@ -210,9 +210,9 @@ dependencies = [ [[package]] name = "aws-lc-sys" -version = "0.36.0" +version = "0.37.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a442ece363113bd4bd4c8b18977a7798dd4d3c3383f34fb61936960e8f4ad8" +checksum = "b092fe214090261288111db7a2b2c2118e5a7f30dc2569f1732c4069a6840549" dependencies = [ "cc", "cmake", @@ -348,7 +348,7 @@ dependencies = [ "regex", "rustc-hash 1.1.0", "shlex", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] @@ -485,7 +485,7 @@ checksum = "89385e82b5d1821d2219e0b095efa2cc1f246cbf99080f3be46a1a85c0d392d9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] @@ -496,9 +496,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.11.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3" +checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" [[package]] name = "cast" @@ -508,9 +508,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.2.52" +version = "1.2.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd4932aefd12402b36c60956a4fe0035421f544799057659ff86f923657aada3" +checksum = "aebf35691d1bfb0ac386a69bac2fde4dd276fb618cf8bf4f5318fe285e821bb2" dependencies = [ "find-msvc-tools", "jobserver", @@ -630,9 +630,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.54" +version = "4.5.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6e6ff9dcd79cff5cd969a17a545d79e84ab086e444102a591e288a8aa3ce394" +checksum = "63be97961acde393029492ce0be7a1af7e323e6bae9511ebfac33751be5e6806" dependencies = [ "clap_builder", "clap_derive", @@ -640,9 +640,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.54" +version = "4.5.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa42cf4d2b7a41bc8f663a7cab4031ebafa1bf3875705bfaf8466dc60ab52c00" +checksum = "7f13174bda5dfd69d7e947827e5af4b0f2f94a4a3ee92912fba07a66150f21e2" dependencies = [ "anstream", "anstyle", @@ -652,21 +652,21 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.49" +version = "4.5.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0b5487afeab2deb2ff4e03a807ad1a03ac532ff5a2cee5d86884440c7f7671" +checksum = "a92793da1a46a5f2a02a6f4c46c6496b28c43638adea8306fcb0caa1634f24e5" dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] name = "clap_lex" -version = "0.7.7" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3e64b0cc0439b12df2fa678eae89a1c56a529fd067a9115f7827f1fffd22b32" +checksum = "3a822ea5bc7590f9d40f1ba12c0dc3c2760f3482c6984db1573ad11031420831" [[package]] name = "cmake" @@ -695,11 +695,11 @@ dependencies = [ [[package]] name = "colored" -version = "3.0.0" +version = "3.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fde0e0ec90c9dfb3b4b1a0891a7dcd0e2bffde2f7efed5fe7c9bb00e5bfb915e" +checksum = "faf9468729b8cbcea668e36183cb69d317348c2e08e994829fb56ebfdfbaac34" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -1017,7 +1017,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] @@ -1040,7 +1040,7 @@ dependencies = [ "ident_case", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] @@ -1051,7 +1051,7 @@ checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" dependencies = [ "darling_core", "quote", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] @@ -1097,7 +1097,7 @@ checksum = "1e567bd82dcff979e4b03460c307b3cdc9e96fde3d73bed1496d2bc75d9dd62a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] @@ -1108,7 +1108,7 @@ checksum = "6edb4b64a43d977b8e99788fe3a04d483834fba1215a7e02caa415b626497f7f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] @@ -1130,7 +1130,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn 2.0.114", + "syn 2.0.115", "unicode-xid", ] @@ -1169,7 +1169,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] @@ -1190,7 +1190,7 @@ dependencies = [ "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] @@ -1305,14 +1305,14 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] name = "env_filter" -version = "0.1.4" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bf3c259d255ca70051b30e2e95b5446cdb8949ac4cd22c0d7fd634d89f568e2" +checksum = "7a1c3cc8e57274ec99de65301228b537f1e4eedc1b8e0f9411c6caac8ae7308f" dependencies = [ "log", "regex", @@ -1320,9 +1320,9 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.11.8" +version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13c863f0904021b108aa8b2f55046443e6b1ebde8fd4a15c399893aae4fa069f" +checksum = "b2daee4ea451f429a58296525ddf28b45a3b64f1acf6587e2067437bb11e218d" dependencies = [ "anstream", "anstyle", @@ -1525,21 +1525,20 @@ checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" [[package]] name = "filetime" -version = "0.2.26" +version = "0.2.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc0505cd1b6fa6580283f6bdf70a73fcf4aba1184038c90902b92b3dd0df63ed" +checksum = "f98844151eee8917efc50bd9e8318cb963ae8b297431495d3f758616ea5c57db" dependencies = [ "cfg-if", "libc", "libredox", - "windows-sys 0.60.2", ] [[package]] name = "find-msvc-tools" -version = "0.1.7" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f449e6c6c08c865631d4890cfacf252b3d396c9bcc83adb6623cdb02a8336c41" +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" [[package]] name = "first-contract" @@ -1560,9 +1559,9 @@ dependencies = [ [[package]] name = "flate2" -version = "1.1.8" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b375d6465b98090a5f25b1c7703f3859783755aa9a80433b36e0379a3ec2f369" +checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c" dependencies = [ "crc32fast", "miniz_oxide", @@ -1763,7 +1762,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] @@ -2092,7 +2091,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] @@ -2295,14 +2294,13 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.19" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "727805d60e7938b76b826a6ef209eb70eaa1812794f9424d4a4e2d740662df5f" +checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" dependencies = [ "base64", "bytes", "futures-channel", - "futures-core", "futures-util", "http 1.4.0", "http-body", @@ -2460,7 +2458,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "699c1b6d335e63d0ba5c1e1c7f647371ce989c3bcbe1f7ed2b85fa56e3bd1a21" dependencies = [ "quote", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] @@ -2544,9 +2542,9 @@ checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" [[package]] name = "jiff" -version = "0.2.18" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e67e8da4c49d6d9909fe03361f9b620f58898859f5c7aded68351e85e71ecf50" +checksum = "c867c356cc096b33f4981825ab281ecba3db0acefe60329f044c1789d94c6543" dependencies = [ "jiff-static", "log", @@ -2557,13 +2555,13 @@ dependencies = [ [[package]] name = "jiff-static" -version = "0.2.18" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0c84ee7f197eca9a86c6fd6cb771e55eb991632f15f2bc3ca6ec838929e6e78" +checksum = "f7946b4325269738f270bb55b3c19ab5c5040525f83fd625259422a9d25d9be5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] @@ -2716,9 +2714,9 @@ checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" [[package]] name = "libc" -version = "0.2.180" +version = "0.2.182" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcc35a38544a891a5f7c865aca548a982ccb3b8650a5b06d0fd33a10283c56fc" +checksum = "6800badb6cb2082ffd7b6a67e6125bb39f18782f793520caee8cb8846be06112" [[package]] name = "libloading" @@ -2738,7 +2736,7 @@ checksum = "3d0b95e02c851351f877147b7deea7b1afb1df71b63aa5f8270716e0c5720616" dependencies = [ "bitflags 2.10.0", "libc", - "redox_syscall 0.7.0", + "redox_syscall 0.7.1", ] [[package]] @@ -2881,7 +2879,7 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb4bdc8b0ce69932332cf76d24af69c3a155242af95c226b2ab6c2e371ed1149" dependencies = [ - "thiserror 2.0.17", + "thiserror 2.0.18", "zerocopy", "zerocopy-derive", ] @@ -2905,9 +2903,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.7.6" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" +checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" [[package]] name = "memmap2" @@ -2993,7 +2991,7 @@ dependencies = [ [[package]] name = "multisig" -version = "1.0.0" +version = "0.0.0" dependencies = [ "hex", "multiversx-sc", @@ -3066,7 +3064,7 @@ version = "0.21.1" dependencies = [ "anyhow", "bitflags 2.10.0", - "colored 3.0.0", + "colored 3.1.1", "ed25519-dalek", "hex", "itertools 0.14.0", @@ -3104,7 +3102,7 @@ dependencies = [ "loupe", "multiversx-chain-vm-executor", "rc-new-cyclic-fallible", - "thiserror 2.0.17", + "thiserror 2.0.18", "wasmer", "wasmer-types", ] @@ -3136,12 +3134,33 @@ dependencies = [ "bitflags 2.10.0", "generic-array 1.3.5", "multiversx-chain-core", + "multiversx-sc-abi", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", "unwrap-infallible", ] +[[package]] +name = "multiversx-sc-abi" +version = "0.24.0" +dependencies = [ + "bitflags 2.10.0", + "multiversx-chain-core", + "multiversx-sc-codec", + "num-bigint", + "unwrap-infallible", +] + +[[package]] +name = "multiversx-sc-abi-derive" +version = "0.24.0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.115", +] + [[package]] name = "multiversx-sc-codec" version = "0.24.0" @@ -3160,7 +3179,7 @@ dependencies = [ "hex", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] @@ -3179,7 +3198,7 @@ dependencies = [ "proc-macro2", "quote", "radix_trie", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] @@ -3189,7 +3208,7 @@ dependencies = [ "anyhow", "bip39", "clap", - "colored 3.0.0", + "colored 3.1.1", "common-path", "convert_case", "copy_dir", @@ -3215,7 +3234,7 @@ name = "multiversx-sc-meta-lib" version = "0.64.1" dependencies = [ "clap", - "colored 3.0.0", + "colored 3.1.1", "convert_case", "hex", "lazy_static", @@ -3242,7 +3261,7 @@ name = "multiversx-sc-scenario" version = "0.64.1" dependencies = [ "base64", - "colored 3.0.0", + "colored 3.1.1", "hex", "hex-literal", "itertools 0.14.0", @@ -3268,7 +3287,7 @@ version = "0.64.1" dependencies = [ "anyhow", "base64", - "colored 3.0.0", + "colored 3.1.1", "env_logger", "futures", "hex", @@ -3382,7 +3401,7 @@ checksum = "4568f25ccbd45ab5d5603dc34318c1ec56b117531781260002151b8530a9f931" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] @@ -3554,9 +3573,9 @@ dependencies = [ [[package]] name = "openssl-probe" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f50d9b3dabb09ecd771ad0aa242ca6894994c130308ca3d7684634df8037391" +checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" [[package]] name = "order-book-factory" @@ -3722,7 +3741,7 @@ checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] @@ -3830,15 +3849,15 @@ dependencies = [ [[package]] name = "portable-atomic" -version = "1.13.0" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f89776e4d69bb58bc6993e99ffa1d11f228b839984854c7daeb5d37f87cbe950" +checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" [[package]] name = "portable-atomic-util" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507" +checksum = "7a9db96d7fa8782dd8c15ce32ffe8680bbd1e978a43bf51a34d39483540495f5" dependencies = [ "portable-atomic", ] @@ -3868,7 +3887,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ "proc-macro2", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] @@ -3924,14 +3943,14 @@ dependencies = [ "proc-macro-error-attr2", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] name = "proc-macro2" -version = "1.0.105" +version = "1.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "535d180e0ecab6268a3e718bb9fd44db66bbbc256257165fc699dadf70d16fe7" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" dependencies = [ "unicode-ident", ] @@ -4022,7 +4041,7 @@ checksum = "7347867d0a7e1208d93b46767be83e2b8f978c3dad35f775ac8d8847551d6fe1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] @@ -4056,7 +4075,7 @@ dependencies = [ "rustc-hash 2.1.1", "rustls", "socket2", - "thiserror 2.0.17", + "thiserror 2.0.18", "tokio", "tracing", "web-time", @@ -4078,7 +4097,7 @@ dependencies = [ "rustls", "rustls-pki-types", "slab", - "thiserror 2.0.17", + "thiserror 2.0.18", "tinyvec", "tracing", "web-time", @@ -4100,9 +4119,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.43" +version = "1.0.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc74d9a594b72ae6656596548f56f667211f8a97b3d4c3d467150794690dc40a" +checksum = "21b2ebcf727b7760c461f091f9f0f539b77b8e87f2fd88131e7f1b433b3cece4" dependencies = [ "proc-macro2", ] @@ -4261,18 +4280,18 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f3fe0889e69e2ae9e41f4d6c4c0181701d00e4697b356fb1f74173a5e0ee27" +checksum = "35985aa610addc02e24fc232012c86fd11f14111180f902b67e2d5331f8ebf2b" dependencies = [ "bitflags 2.10.0", ] [[package]] name = "regex" -version = "1.12.2" +version = "1.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" +checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" dependencies = [ "aho-corasick", "memchr", @@ -4282,9 +4301,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" +checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" dependencies = [ "aho-corasick", "memchr", @@ -4293,9 +4312,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.8" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" +checksum = "a96887878f22d7bad8a3b6dc5b7440e0ada9a245242924394987b21cf2210a4c" [[package]] name = "region" @@ -4320,9 +4339,9 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.13.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04e9018c9d814e5f30cc16a0f03271aeab3571e609612d9fe78c1aa8d11c2f62" +checksum = "ab3f43e3283ab1488b624b44b0e988d0acea0b3214e694730a055cb6b2efa801" dependencies = [ "base64", "bytes", @@ -4393,9 +4412,9 @@ dependencies = [ [[package]] name = "rkyv" -version = "0.8.14" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "360b333c61ae24e5af3ae7c8660bd6b21ccd8200dbbc5d33c2454421e85b9c69" +checksum = "1a30e631b7f4a03dee9056b8ef6982e8ba371dd5bedb74d3ec86df4499132c70" dependencies = [ "bytecheck 0.8.2", "bytes", @@ -4412,13 +4431,13 @@ dependencies = [ [[package]] name = "rkyv_derive" -version = "0.8.14" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c02f8cdd12b307ab69fe0acf4cd2249c7460eb89dce64a0febadf934ebb6a9e" +checksum = "8100bb34c0a1d0f907143db3149e6b4eea3c33b9ee8b189720168e818303986f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] @@ -4548,9 +4567,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.13.2" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21e6f2ab2928ca4291b86736a8bd920a277a399bba1589409d72154ff87c1282" +checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd" dependencies = [ "web-time", "zeroize", @@ -4585,9 +4604,9 @@ checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" [[package]] name = "rustls-webpki" -version = "0.103.8" +version = "0.103.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ffdfa2f5286e2247234e03f680868ac2815974dc39e00ea15adc445d0aafe52" +checksum = "d7df23109aa6c1567d1c575b9952556388da57401e4ace1d15f79eedad0d8f53" dependencies = [ "aws-lc-rs", "ring", @@ -4614,9 +4633,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.22" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a50f4cf475b65d88e057964e0e9bb1f0aa9bbb2036dc65c64596b42932536984" +checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" [[package]] name = "salsa20" @@ -4816,7 +4835,7 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] @@ -4841,7 +4860,7 @@ checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] @@ -4888,7 +4907,7 @@ checksum = "6f50427f258fb77356e4cd4aa0e87e2bd2c66dbcee41dc405282cae2bfc26c83" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] @@ -5001,9 +5020,9 @@ dependencies = [ [[package]] name = "slab" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" [[package]] name = "smallvec" @@ -5013,9 +5032,9 @@ checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" [[package]] name = "socket2" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881" +checksum = "86f4aa3ad99f2088c990dfa82d367e19cb29268ed67c574d10d0a4bfe71f07e0" dependencies = [ "libc", "windows-sys 0.60.2", @@ -5101,9 +5120,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.114" +version = "2.0.115" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4d107df263a3013ef9b1879b0df87d706ff80f65a86ea879bd9c31f9b307c2a" +checksum = "6e614ed320ac28113fa64972c4262d5dbc89deacdfd00c34a3e4cea073243c12" dependencies = [ "proc-macro2", "quote", @@ -5127,14 +5146,14 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] name = "system-configuration" -version = "0.6.1" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" +checksum = "a13f3d0daba03132c0aa9767f98351b3488edc2c100cda2d2ec2b04f3d8d3c8b" dependencies = [ "bitflags 2.10.0", "core-foundation 0.9.4", @@ -5199,11 +5218,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.17" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" +checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" dependencies = [ - "thiserror-impl 2.0.17", + "thiserror-impl 2.0.18", ] [[package]] @@ -5214,18 +5233,18 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] name = "thiserror-impl" -version = "2.0.17" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" +checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] @@ -5323,7 +5342,7 @@ checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] @@ -5379,9 +5398,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.9.11+spec-1.1.0" +version = "0.9.12+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3afc9a848309fe1aaffaed6e1546a7a14de1f935dc9d89d32afd9a44bab7c46" +checksum = "cf92845e79fc2e2def6a5d828f0801e29a2f8acc037becc5ab08595c7d5e9863" dependencies = [ "indexmap", "serde_core", @@ -5420,9 +5439,9 @@ dependencies = [ [[package]] name = "toml_parser" -version = "1.0.6+spec-1.1.0" +version = "1.0.8+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3198b4b0a8e11f09dd03e133c0280504d0801269e9afa46362ffde1cbeebf44" +checksum = "0742ff5ff03ea7e67c8ae6c93cac239e0d9784833362da3f9a9c1da8dfefcbdc" dependencies = [ "winnow 0.7.14", ] @@ -5497,7 +5516,7 @@ checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] @@ -5551,9 +5570,9 @@ checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" [[package]] name = "unicode-ident" -version = "1.0.22" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" +checksum = "537dd038a89878be9b64dd4bd1b260315c1bb94f4d784956b81e27a088d9a09e" [[package]] name = "unicode-normalization" @@ -5644,9 +5663,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.19.0" +version = "1.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2e054861b4bd027cd373e18e8d8d8e6548085000e41290d95ce0c373a654b4a" +checksum = "ee48d38b119b0cd71fe4141b30f5ba9c7c5d9f4e7a3a8b4a674e4b6ef789976f" dependencies = [ "getrandom 0.3.4", "js-sys", @@ -5772,7 +5791,7 @@ dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", "wasm-bindgen-shared", ] @@ -5787,12 +5806,12 @@ dependencies = [ [[package]] name = "wasm-encoder" -version = "0.244.0" +version = "0.245.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" +checksum = "3f9dca005e69bf015e45577e415b9af8c67e8ee3c0e38b5b0add5aa92581ed5c" dependencies = [ "leb128fmt", - "wasmparser 0.244.0", + "wasmparser 0.245.1", ] [[package]] @@ -5962,9 +5981,9 @@ dependencies = [ [[package]] name = "wasmparser" -version = "0.244.0" +version = "0.245.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" +checksum = "4f08c9adee0428b7bddf3890fc27e015ac4b761cc608c822667102b8bfd6995e" dependencies = [ "bitflags 2.10.0", "indexmap", @@ -5984,9 +6003,9 @@ dependencies = [ [[package]] name = "wast" -version = "244.0.0" +version = "245.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2e7b9f9e23311275920e3d6b56d64137c160cf8af4f84a7283b36cfecbf4acb" +checksum = "28cf1149285569120b8ce39db8b465e8a2b55c34cbb586bd977e43e2bc7300bf" dependencies = [ "bumpalo", "leb128fmt", @@ -5997,9 +6016,9 @@ dependencies = [ [[package]] name = "wat" -version = "1.244.0" +version = "1.245.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbf35b87ed352f9ab6cd0732abde5a67dd6153dfd02c493e61459218b19456fa" +checksum = "cd48d1679b6858988cb96b154dda0ec5bbb09275b71db46057be37332d5477be" dependencies = [ "wast", ] @@ -6034,9 +6053,9 @@ dependencies = [ [[package]] name = "webpki-root-certs" -version = "1.0.5" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36a29fc0408b113f68cf32637857ab740edfafdf460c326cd2afaa2d84cc05dc" +checksum = "804f18a4ac2676ffb4e8b5b5fa9ae38af06df08162314f96a68d2a363e21a8ca" dependencies = [ "rustls-pki-types", ] @@ -6374,7 +6393,7 @@ dependencies = [ "rustversion", "serde", "slab", - "thiserror 2.0.17", + "thiserror 2.0.18", "tokio", "tokise", "tracing", @@ -6396,7 +6415,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] @@ -6426,7 +6445,7 @@ checksum = "9e87a3ce33434ab66a700edbaf2cc8a417d9b89f00a6fd8216fd6ac83b0e7b1c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] @@ -6448,28 +6467,28 @@ checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", "synstructure", ] [[package]] name = "zerocopy" -version = "0.8.33" +version = "0.8.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "668f5168d10b9ee831de31933dc111a459c97ec93225beb307aed970d1372dfd" +checksum = "db6d35d663eadb6c932438e763b262fe1a70987f9ae936e60158176d710cae4a" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.33" +version = "0.8.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c7962b26b0a8685668b671ee4b54d007a67d4eaf05fda79ac0ecf41e32270f1" +checksum = "4122cd3169e94605190e77839c9a40d40ed048d305bfdc146e7df40ab0f3e517" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] @@ -6489,7 +6508,7 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", "synstructure", ] @@ -6529,7 +6548,7 @@ checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] @@ -6548,15 +6567,15 @@ dependencies = [ [[package]] name = "zlib-rs" -version = "0.5.5" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40990edd51aae2c2b6907af74ffb635029d5788228222c4bb811e9351c0caad3" +checksum = "a7948af682ccbc3342b6e9420e8c51c1fe5d7bf7756002b4a3c6cabfe96a7e3c" [[package]] name = "zmij" -version = "1.0.14" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd8f3f50b848df28f887acb68e41201b5aea6bc8a8dacc00fb40635ff9a72fea" +checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" [[package]] name = "zopfli" diff --git a/Cargo.toml b/Cargo.toml index d81a5a51b0..465fe27d7e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,6 +2,8 @@ resolver = "3" members = [ + "data/abi", + "data/abi-derive", "data/codec", "data/codec-derive", "data/human-readable", diff --git a/chain/core/Cargo.toml b/chain/core/Cargo.toml index 16df5d9ba6..0369cb4611 100644 --- a/chain/core/Cargo.toml +++ b/chain/core/Cargo.toml @@ -26,6 +26,6 @@ serde = { version = "1.0", features = ["derive"], optional = true } hex = { version = "0.4", optional = true } [dependencies.multiversx-sc-codec] -version = "=0.24.0" +version = "0.24.0" path = "../../data/codec" features = ["derive"] diff --git a/contracts/examples/multisig/Cargo.toml b/contracts/examples/multisig/Cargo.toml index c7d982ad99..57fcf13823 100644 --- a/contracts/examples/multisig/Cargo.toml +++ b/contracts/examples/multisig/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "multisig" -version = "1.0.0" +version = "0.0.0" authors = ["Andrei Marinica "] edition = "2024" publish = false diff --git a/data/abi-derive/Cargo.toml b/data/abi-derive/Cargo.toml new file mode 100644 index 0000000000..2cd9bc6bc6 --- /dev/null +++ b/data/abi-derive/Cargo.toml @@ -0,0 +1,35 @@ +[package] +name = "multiversx-sc-abi-derive" +version = "0.24.0" +edition = "2024" +publish = false + +authors = [ + "Andrei Marinica ", + "MultiversX ", +] +license = "GPL-3.0-only" +readme = "README.md" +repository = "https://github.com/multiversx/mx-sdk-rs" +homepage = "https://multiversx.com/" +documentation = "https://docs.multiversx.com/" +description = "MultiversX ABI derive macros - TypeAbi derive and type_abi attribute" +keywords = ["multiversx", "wasm", "webassembly", "blockchain", "contract"] +categories = [ + "no-std", + "wasm", + "cryptography::cryptocurrencies", + "development-tools", +] + +[dependencies] +proc-macro2 = "1.0" +quote = "1.0" +syn = "2.0" + +[features] +default = ["syn/full", "syn/parsing", "syn/extra-traits"] + +[lib] +name = "multiversx_sc_abi_derive" +proc-macro = true diff --git a/data/abi-derive/README.md b/data/abi-derive/README.md new file mode 100644 index 0000000000..850561fd8d --- /dev/null +++ b/data/abi-derive/README.md @@ -0,0 +1,20 @@ +# multiversx-sc-abi-derive + +Procedural macros for deriving TypeAbi trait implementations in MultiversX smart contracts. + +## Usage + +This crate provides: +- `#[type_abi]` attribute macro for generating TypeAbi implementations +- `#[derive(TypeAbi)]` derive macro (deprecated, use #[type_abi] instead) + +Place the `#[type_abi]` attribute before your derives: + +```rust +#[type_abi] +#[derive(TopEncode, TopDecode, NestedEncode, NestedDecode)] +pub struct MyStruct { + pub field1: u64, + pub field2: String, +} +``` diff --git a/data/abi-derive/src/lib.rs b/data/abi-derive/src/lib.rs new file mode 100644 index 0000000000..d517706234 --- /dev/null +++ b/data/abi-derive/src/lib.rs @@ -0,0 +1,27 @@ +// ensure we don't run out of macro stack +#![recursion_limit = "1024"] +// TODO: remove once minimum version is 1.87+ +#![allow(unknown_lints)] +#![allow(clippy::collapsible_if)] +#![allow(clippy::manual_is_multiple_of)] + +mod parse; +mod type_abi_derive; + +#[deprecated( + since = "0.54.4", + note = "Replace with attribute #[type_abi], which should be placed before all derives. More about this: https://docs.multiversx.com/developers/transactions/tx-migration/#replace-derivetypeabi-with-type_abi" +)] +#[proc_macro_derive(TypeAbi)] +pub fn type_abi_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream { + type_abi_derive::type_abi_derive(input).into() +} + +#[proc_macro_attribute] +pub fn type_abi( + args: proc_macro::TokenStream, + input: proc_macro::TokenStream, +) -> proc_macro::TokenStream { + assert!(args.is_empty(), "#[type_abi] attribute takes no args"); + type_abi_derive::type_abi_full(input).into() +} diff --git a/data/abi-derive/src/parse/attributes.rs b/data/abi-derive/src/parse/attributes.rs new file mode 100644 index 0000000000..286f3e93c4 --- /dev/null +++ b/data/abi-derive/src/parse/attributes.rs @@ -0,0 +1,67 @@ +use quote::ToTokens; + +/// Doc comments are actually syntactic sugar for doc attributes, +/// so extracting doc comments means parsing "doc" attributes. +pub fn extract_doc(attrs: &[syn::Attribute]) -> Vec { + const ATTR_DOC: &str = "doc"; + + attrs + .iter() + .filter(|attr| { + if let Some(first_seg) = attr.path().segments.first() { + first_seg.ident == ATTR_DOC + } else { + false + } + }) + .map(|attr| match attr.meta.clone() { + syn::Meta::Path(_) => panic!("wrong format. expected name value, received path"), + syn::Meta::List(_) => panic!("wrong format. expected name value, received list"), + syn::Meta::NameValue(meta_name_value) => { + if let syn::Expr::Lit(lit_str) = meta_name_value.value { + if meta_name_value.path.is_ident("doc") { + let value = lit_str.lit; + if let Some(tuple) = value + .to_token_stream() + .to_string() + .split_once(char::is_whitespace) + { + remove_backslashes(tuple.1) + } else { + String::new() + } + } else { + panic!("Attribute doesn't have the 'doc' identifier"); + } + } else { + panic!("Value is not a string literal"); + } + } + }) + .collect() +} + +pub fn extract_macro_attributes(attrs: &[syn::Attribute]) -> Vec { + let mut macro_attributes = Vec::new(); + + for a in attrs { + if let syn::Meta::List(list) = &a.meta { + if list.path.is_ident("derive") { + for token in list.tokens.clone().into_iter() { + if let proc_macro2::TokenTree::Ident(ident) = token { + macro_attributes.push(ident.to_string()); + } + } + } + } + } + + macro_attributes +} + +fn remove_backslashes(input: &str) -> String { + input + .trim_matches('\"') + .replace("\\\"", "\"") + .replace("\\'", "'") +} diff --git a/data/abi-derive/src/parse/mod.rs b/data/abi-derive/src/parse/mod.rs new file mode 100644 index 0000000000..9cda54b7c2 --- /dev/null +++ b/data/abi-derive/src/parse/mod.rs @@ -0,0 +1 @@ +pub mod attributes; diff --git a/data/abi-derive/src/type_abi_derive.rs b/data/abi-derive/src/type_abi_derive.rs new file mode 100644 index 0000000000..ca681e192e --- /dev/null +++ b/data/abi-derive/src/type_abi_derive.rs @@ -0,0 +1,214 @@ +use crate::parse::attributes::{extract_doc, extract_macro_attributes}; +use quote::{ToTokens, quote}; + +const BITFLAGS_PATH: &str = ":: __private :: PublicFlags :: Internal"; +const BITFLAGS_PRIMITIVE: &str = "Primitive"; + +pub struct ExplicitDiscriminant { + pub variant_index: usize, + pub value: usize, +} + +fn field_snippet(index: usize, field: &syn::Field) -> proc_macro2::TokenStream { + let field_docs = extract_doc(field.attrs.as_slice()); + let field_name_str = if let Some(ident) = &field.ident { + ident.to_string() + } else { + index.to_string() + }; + let field_ty = sanitize_field_type_path(&field.ty); + quote! { + field_descriptions.push(multiversx_sc_abi::StructFieldDescription::new( + &[ #(#field_docs),* ], + #field_name_str, + <#field_ty>::type_names(), + )); + <#field_ty>::provide_type_descriptions(accumulator); + } +} + +fn sanitize_field_type_path(field_type: &syn::Type) -> syn::Type { + if let syn::Type::Path(p) = field_type { + let mut path = p.path.clone(); + + if path.to_token_stream().to_string().contains(BITFLAGS_PATH) { + let modified_path = path.segments.last_mut().unwrap(); + modified_path.ident = syn::Ident::new(BITFLAGS_PRIMITIVE, modified_path.ident.span()); + + return syn::Type::Path(syn::TypePath { + qself: p.qself.clone(), + path, + }); + } + } + + field_type.clone() +} + +fn fields_snippets(fields: &syn::Fields) -> Vec { + match fields { + syn::Fields::Named(fields_named) => fields_named + .named + .iter() + .enumerate() + .map(|(index, field)| field_snippet(index, field)) + .collect(), + syn::Fields::Unnamed(fields_unnamed) => fields_unnamed + .unnamed + .iter() + .enumerate() + .map(|(index, field)| field_snippet(index, field)) + .collect(), + syn::Fields::Unit => Vec::new(), + } +} + +pub fn type_abi_derive(input: proc_macro::TokenStream) -> proc_macro2::TokenStream { + let ast: syn::DeriveInput = syn::parse(input).unwrap(); + let name = &ast.ident; + let name_str = name.to_string(); + let type_docs = extract_doc(ast.attrs.as_slice()); + let macro_attributes = extract_macro_attributes(ast.attrs.as_slice()); + if macro_attributes.is_empty() { + println!( + "Warning! {name_str} #[type_abi] implementation sees no derive traits. Make sure that the derive attribute comes after #[type_abi]" + ); + } + + let type_description_impl = match &ast.data { + syn::Data::Struct(data_struct) => { + let struct_field_snippets = fields_snippets(&data_struct.fields); + quote! { + fn provide_type_descriptions(accumulator: &mut TDC) { + let type_names = Self::type_names(); + if !accumulator.contains_type(&type_names.abi) { + accumulator.reserve_type_name(type_names.clone()); + let mut field_descriptions = multiversx_sc_abi::types::heap::Vec::new(); + #(#struct_field_snippets)* + accumulator.insert( + type_names.clone(), + multiversx_sc_abi::TypeDescription::new( + &[ #(#type_docs),* ], + type_names, + multiversx_sc_abi::TypeContents::Struct(field_descriptions), + &[ #(#macro_attributes),* ], + ), + ); + } + } + } + } + syn::Data::Enum(data_enum) => { + let mut previous_disc: Vec = Vec::new(); + let enum_variant_snippets: Vec = data_enum + .variants + .iter() + .enumerate() + .map(|(variant_index, variant)| { + let variant_docs = extract_doc(variant.attrs.as_slice()); + let variant_name_str = variant.ident.to_string(); + let variant_field_snippets = fields_snippets(&variant.fields); + let variant_discriminant = + get_discriminant(variant_index, variant, &mut previous_disc); + quote! { + let mut field_descriptions = multiversx_sc_abi::types::heap::Vec::new(); + #(#variant_field_snippets)* + variant_descriptions.push(multiversx_sc_abi::EnumVariantDescription::new( + &[ #(#variant_docs),* ], + #variant_name_str, + #variant_discriminant, + field_descriptions, + )); + } + }) + .collect(); + quote! { + fn provide_type_descriptions(accumulator: &mut TDC) { + let type_names = Self::type_names(); + if !accumulator.contains_type(&type_names.abi) { + accumulator.reserve_type_name(type_names.clone()); + let mut variant_descriptions = multiversx_sc_abi::types::heap::Vec::new(); + #(#enum_variant_snippets)* + accumulator.insert( + type_names.clone(), + multiversx_sc_abi::TypeDescription::new( + &[ #(#type_docs),* ], + type_names, + multiversx_sc_abi::TypeContents::Enum(variant_descriptions), + &[ #(#macro_attributes),* ], + ), + ); + } + } + } + } + syn::Data::Union(_) => panic!("Union not supported!"), + }; + + let (impl_generics, ty_generics, where_clause) = &ast.generics.split_for_impl(); + quote! { + impl #impl_generics multiversx_sc_abi::TypeAbiFrom for #name #ty_generics #where_clause {} + impl #impl_generics multiversx_sc_abi::TypeAbiFrom<&Self> for #name #ty_generics #where_clause {} + + impl #impl_generics multiversx_sc_abi::TypeAbi for #name #ty_generics #where_clause { + type Unmanaged = Self; + + fn type_name() -> multiversx_sc_abi::TypeName { + #name_str.into() + } + #type_description_impl + } + } +} + +pub fn type_abi_full(input: proc_macro::TokenStream) -> proc_macro2::TokenStream { + let input_conv = proc_macro2::TokenStream::from(input.clone()); + let derive_code = type_abi_derive(input); + quote! { + #input_conv + #derive_code + } +} + +pub fn get_discriminant( + variant_index: usize, + variant: &syn::Variant, + previous_disc: &mut Vec, +) -> proc_macro2::TokenStream { + // if it has explicit discriminant + if let Some((_, syn::Expr::Lit(expr))) = &variant.discriminant { + let lit = match &expr.lit { + syn::Lit::Int(val) => { + let value = val.base10_parse().unwrap_or_else(|_| { + panic!("Can not unwrap int value from explicit discriminant") + }); + previous_disc.push(ExplicitDiscriminant { + variant_index, + value, + }); + value + } + _ => panic!("Only integer values as discriminants"), + }; + return quote! { #lit}; + } + + // if no explicit discriminant, check previous discriminants + // get previous explicit + 1 if there has been any explicit before + let next_value = match previous_disc.last() { + // there are previous explicit discriminants + Some(ExplicitDiscriminant { + variant_index: prev_index, + value: prev_value, + }) if *prev_index < variant_index - 1 => prev_value + variant_index - prev_index, + Some(ExplicitDiscriminant { + variant_index: _, + value: prev_value, + }) => prev_value + 1, + + // vec is empty, return index + None => variant_index, + }; + + quote! { #next_value} +} diff --git a/data/abi/Cargo.toml b/data/abi/Cargo.toml new file mode 100644 index 0000000000..f141e56bef --- /dev/null +++ b/data/abi/Cargo.toml @@ -0,0 +1,40 @@ +[package] +name = "multiversx-sc-abi" +version = "0.24.0" +edition = "2024" +publish = false # TEMP + +authors = [ + "Andrei Marinica ", + "MultiversX ", +] +license = "GPL-3.0-only" +readme = "README.md" +repository = "https://github.com/multiversx/mx-sdk-rs" +homepage = "https://multiversx.com/" +documentation = "https://docs.multiversx.com/" +description = "Lightweight binary serializer/deserializer, written especially for MultiversX smart contracts" +keywords = ["multiversx", "wasm", "webassembly", "blockchain", "contract"] +categories = [ + "no-std", + "wasm", + "cryptography::cryptocurrencies", + "development-tools", +] + +[dependencies.multiversx-chain-core] +version = "=0.21.1" +path = "../../chain/core" + +[dependencies.multiversx-sc-codec] +path = "../codec" +version = "0.24.0" + +[dependencies] +num-bigint = { version = "0.4", optional = true } # can only be used in std contexts +unwrap-infallible = "1.0" +bitflags = "2.9" + +# [dev-dependencies.multiversx-sc-codec-derive] +# path = "../codec-derive" +# version = "=0.24.0" diff --git a/data/abi/README.md b/data/abi/README.md new file mode 100644 index 0000000000..5875d9e758 --- /dev/null +++ b/data/abi/README.md @@ -0,0 +1,157 @@ +# multiversx-sc-abi + +ABI (Application Binary Interface) generation and type metadata for MultiversX smart contracts. + +## Overview + +This crate provides the core types and traits for generating ABI metadata in MultiversX smart contracts. The ABI describes: +- Contract endpoints (initialization, upgrades, regular endpoints, callbacks) +- Endpoint parameters and return types +- Events and their data +- ESDT attribute structures +- Custom type descriptions (structs and enums) + +## Features + +### Core Traits + +- **`TypeAbi`** - Main trait implemented by all types that can appear in the ABI (arguments, results, event logs, etc.) +- **`TypeAbiFrom`** - Trait for type conversions in ABI context + +### ABI Components + +- **`ContractAbi`** - Complete contract ABI including endpoints, events, and type descriptions +- **`EndpointAbi`** - Metadata for contract endpoints (init, upgrade, view, external) +- **`EventAbi`** - Event definitions with indexed and non-indexed fields +- **`EsdtAttributeAbi`** - ESDT token attribute descriptions +- **`BuildInfoAbi`** - Build information (framework version, rustc version, etc.) + +### Type Descriptions + +- **`TypeDescription`** - Detailed description of custom types +- **`TypeContents`** - Enum/Struct field information +- **`TypeNames`** - ABI and Rust type name mappings +- **`TypeDescriptionContainer`** - Accumulator for collecting type descriptions + +## Usage + +### Implementing TypeAbi + +For custom types, use the `#[type_abi]` attribute from the [`multiversx-sc-abi-derive`](../abi-derive) crate: + +```rust +use multiversx_sc_abi::TypeAbi; + +#[type_abi] +#[derive(TopEncode, TopDecode, NestedEncode, NestedDecode)] +pub struct MyStruct { + pub field1: u64, + pub field2: BigUint, +} + +#[type_abi] +#[derive(TopEncode, TopDecode, NestedEncode, NestedDecode)] +pub enum MyEnum { + Variant1, + Variant2(u32), + Variant3 { x: u64, y: u64 }, +} +``` + +### Accessing Type Information + +```rust +use multiversx_sc_abi::{TypeAbi, TypeDescriptionContainerImpl}; + +// Get type name +let name = MyStruct::type_name(); + +// Collect type descriptions for ABI generation +let mut accumulator = TypeDescriptionContainerImpl::new(); +MyStruct::provide_type_descriptions(&mut accumulator); +``` + +### Built-in TypeAbi Implementations + +The crate provides `TypeAbi` implementations for: + +- **Primitive types**: `u8`, `u16`, `u32`, `u64`, `u128`, `usize`, `i8`, `i16`, `i32`, `i64`, `isize`, `bool`, `f64` +- **Core types**: `NonZeroUsize` +- **Codec types**: `TopEncodeMulti`, `TopDecodeMulti`, `MultiValueEncoded`, etc. +- **VM core types**: Address, token identifiers, managed types (when available) +- **BigInt types**: `num_bigint::BigUint`, `num_bigint::BigInt` (enabled with `num-bigint` feature) + +## Features + +- **`num-bigint`** - Enables TypeAbi implementations for `num_bigint::BigUint` and `num_bigint::BigInt` + +## Dependencies + +- [`multiversx-chain-core`](../../chain/core) - Core blockchain types +- [`multiversx-sc-codec`](../codec) - Binary serialization/deserialization +- `bitflags` - For bitflag type support +- `unwrap-infallible` - For infallible conversions + +## Integration + +This crate is typically not used directly in smart contracts. Instead: + +1. Smart contract code uses types from `multiversx-sc` framework +2. The `#[type_abi]` attribute from `multiversx-sc-abi-derive` generates implementations +3. The `multiversx-sc-meta` tool uses this crate to generate ABI JSON files + +## ABI Generation Flow + +1. Contract code is annotated with `#[contract]`, `#[module]`, and `#[type_abi]` attributes +2. Procedural macros collect endpoint, event, and type information +3. `ContractAbi` structure is populated with all metadata +4. ABI is serialized to JSON for deployment and interaction tools + +## Example ABI Output + +```json +{ + "name": "MyContract", + "endpoints": [ + { + "name": "myEndpoint", + "inputs": [ + { + "name": "amount", + "type": "BigUint" + } + ], + "outputs": [ + { + "type": "MyStruct" + } + ] + } + ], + "types": { + "MyStruct": { + "type": "struct", + "fields": [ + { + "name": "field1", + "type": "u64" + }, + { + "name": "field2", + "type": "BigUint" + } + ] + } + } +} +``` + +## Related Crates + +- [`multiversx-sc-abi-derive`](../abi-derive) - Procedural macros for deriving TypeAbi +- [`multiversx-sc-codec`](../codec) - Binary serialization used in ABI types +- [`multiversx-sc-meta`](../../framework/meta) - Tools that consume ABI for code generation + +## License + +GPL-3.0-only diff --git a/framework/base/src/abi/build_info_abi.rs b/data/abi/src/build_info_abi.rs similarity index 100% rename from framework/base/src/abi/build_info_abi.rs rename to data/abi/src/build_info_abi.rs diff --git a/framework/base/src/abi/contract_abi.rs b/data/abi/src/contract_abi.rs similarity index 100% rename from framework/base/src/abi/contract_abi.rs rename to data/abi/src/contract_abi.rs diff --git a/framework/base/src/abi/endpoint_abi.rs b/data/abi/src/endpoint_abi.rs similarity index 100% rename from framework/base/src/abi/endpoint_abi.rs rename to data/abi/src/endpoint_abi.rs diff --git a/framework/base/src/abi/esdt_attribute_abi.rs b/data/abi/src/esdt_attribute_abi.rs similarity index 100% rename from framework/base/src/abi/esdt_attribute_abi.rs rename to data/abi/src/esdt_attribute_abi.rs diff --git a/framework/base/src/abi/event_abi.rs b/data/abi/src/event_abi.rs similarity index 100% rename from framework/base/src/abi/event_abi.rs rename to data/abi/src/event_abi.rs diff --git a/framework/base/src/abi.rs b/data/abi/src/lib.rs similarity index 51% rename from framework/base/src/abi.rs rename to data/abi/src/lib.rs index ebdc34630a..7f2932303a 100644 --- a/framework/base/src/abi.rs +++ b/data/abi/src/lib.rs @@ -1,3 +1,6 @@ +// re-export basic heap types +extern crate alloc; + mod build_info_abi; mod contract_abi; mod endpoint_abi; @@ -10,6 +13,7 @@ mod type_abi_impl_codec_multi; mod type_abi_impl_vm_core; mod type_description; mod type_description_container; +mod type_names; #[cfg(feature = "num-bigint")] mod type_abi_impl_big_int; @@ -23,27 +27,7 @@ pub use type_abi::*; pub use type_abi_from::*; pub use type_description::*; pub use type_description_container::*; +pub use type_names::{TypeName, TypeNames}; -pub type TypeName = alloc::string::String; - -#[derive(Clone, Default, Debug, PartialEq, Eq)] -pub struct TypeNames { - pub abi: alloc::string::String, - pub rust: alloc::string::String, -} - -impl TypeNames { - pub const fn new() -> Self { - TypeNames { - abi: alloc::string::String::new(), - rust: alloc::string::String::new(), - } - } - - pub const fn from_abi(abi_name: alloc::string::String) -> Self { - TypeNames { - abi: abi_name, - rust: alloc::string::String::new(), - } - } -} +/// The current version of `multiversx_sc_codec`, re-exported. +pub use multiversx_sc_codec as codec; diff --git a/framework/base/src/abi/type_abi.rs b/data/abi/src/type_abi.rs similarity index 100% rename from framework/base/src/abi/type_abi.rs rename to data/abi/src/type_abi.rs diff --git a/framework/base/src/abi/type_abi_from.rs b/data/abi/src/type_abi_from.rs similarity index 100% rename from framework/base/src/abi/type_abi_from.rs rename to data/abi/src/type_abi_from.rs diff --git a/framework/base/src/abi/type_abi_impl_basic.rs b/data/abi/src/type_abi_impl_basic.rs similarity index 99% rename from framework/base/src/abi/type_abi_impl_basic.rs rename to data/abi/src/type_abi_impl_basic.rs index 8c05c09bac..e49a7cd38c 100644 --- a/framework/base/src/abi/type_abi_impl_basic.rs +++ b/data/abi/src/type_abi_impl_basic.rs @@ -1,5 +1,5 @@ use super::*; -use crate::arrayvec::ArrayVec; +use crate::codec::arrayvec::ArrayVec; use alloc::{ boxed::Box, format, diff --git a/framework/base/src/abi/type_abi_impl_big_int.rs b/data/abi/src/type_abi_impl_big_int.rs similarity index 100% rename from framework/base/src/abi/type_abi_impl_big_int.rs rename to data/abi/src/type_abi_impl_big_int.rs diff --git a/framework/base/src/abi/type_abi_impl_codec_multi.rs b/data/abi/src/type_abi_impl_codec_multi.rs similarity index 98% rename from framework/base/src/abi/type_abi_impl_codec_multi.rs rename to data/abi/src/type_abi_impl_codec_multi.rs index a10755d3e8..49d9ee4aae 100644 --- a/framework/base/src/abi/type_abi_impl_codec_multi.rs +++ b/data/abi/src/type_abi_impl_codec_multi.rs @@ -1,7 +1,7 @@ use alloc::format; use crate::{ - abi::{OutputAbis, TypeAbi, TypeAbiFrom, TypeDescriptionContainer, TypeName}, + OutputAbis, TypeAbi, TypeAbiFrom, TypeDescriptionContainer, TypeName, codec::multi_types::{IgnoreValue, OptionalValue}, }; diff --git a/framework/base/src/abi/type_abi_impl_vm_core.rs b/data/abi/src/type_abi_impl_vm_core.rs similarity index 100% rename from framework/base/src/abi/type_abi_impl_vm_core.rs rename to data/abi/src/type_abi_impl_vm_core.rs diff --git a/framework/base/src/abi/type_description.rs b/data/abi/src/type_description.rs similarity index 100% rename from framework/base/src/abi/type_description.rs rename to data/abi/src/type_description.rs diff --git a/framework/base/src/abi/type_description_container.rs b/data/abi/src/type_description_container.rs similarity index 100% rename from framework/base/src/abi/type_description_container.rs rename to data/abi/src/type_description_container.rs diff --git a/data/abi/src/type_names.rs b/data/abi/src/type_names.rs new file mode 100644 index 0000000000..6b338eb9c6 --- /dev/null +++ b/data/abi/src/type_names.rs @@ -0,0 +1,25 @@ + + +pub type TypeName = alloc::string::String; + +#[derive(Clone, Default, Debug, PartialEq, Eq)] +pub struct TypeNames { + pub abi: alloc::string::String, + pub rust: alloc::string::String, +} + +impl TypeNames { + pub const fn new() -> Self { + TypeNames { + abi: alloc::string::String::new(), + rust: alloc::string::String::new(), + } + } + + pub const fn from_abi(abi_name: alloc::string::String) -> Self { + TypeNames { + abi: abi_name, + rust: alloc::string::String::new(), + } + } +} diff --git a/data/codec-derive/Cargo.toml b/data/codec-derive/Cargo.toml index 02f053cda6..838fbae617 100644 --- a/data/codec-derive/Cargo.toml +++ b/data/codec-derive/Cargo.toml @@ -2,6 +2,7 @@ name = "multiversx-sc-codec-derive" version = "0.24.0" edition = "2024" +publish = false # TEMP authors = ["dorin.iancu ", "Andrei Marinica ", "MultiversX "] license = "GPL-3.0-only" diff --git a/data/codec/Cargo.toml b/data/codec/Cargo.toml index 3be75821d3..ce9355ccd9 100644 --- a/data/codec/Cargo.toml +++ b/data/codec/Cargo.toml @@ -2,6 +2,7 @@ name = "multiversx-sc-codec" version = "0.24.0" edition = "2024" +publish = false # TEMP authors = [ "Andrei Marinica ", diff --git a/framework/base/Cargo.toml b/framework/base/Cargo.toml index 21c24be523..4c836d5c37 100644 --- a/framework/base/Cargo.toml +++ b/framework/base/Cargo.toml @@ -35,6 +35,10 @@ generic-array = "1.2.0" version = "=0.64.1" path = "../derive" +[dependencies.multiversx-sc-abi] +version = "=0.24.0" +path = "../../data/abi" + [dependencies.multiversx-sc-codec] version = "=0.24.0" path = "../../data/codec" diff --git a/framework/base/src/lib.rs b/framework/base/src/lib.rs index 963f56b8f2..f4cb65c106 100644 --- a/framework/base/src/lib.rs +++ b/framework/base/src/lib.rs @@ -17,7 +17,9 @@ pub use crate::codec::arrayvec; /// Reexported for convenience. pub use generic_array::typenum; -pub mod abi; +// TEMP: should adjust imports. +pub use multiversx_sc_abi as abi; + pub mod api; pub mod contract_base; pub mod err_msg; diff --git a/framework/meta/Cargo.toml b/framework/meta/Cargo.toml index 26cd53cdbc..9b5bdb78dc 100644 --- a/framework/meta/Cargo.toml +++ b/framework/meta/Cargo.toml @@ -39,7 +39,7 @@ reqwest = { version = "0.13", features = ["rustls", "blocking", "json"] } zip = { version = "6.0", features = ["deflate"], default-features = false } copy_dir = "0.1.2" pathdiff = "0.2.1" -common-path = "1.0.0" +common-path = "1.0" bip39 = { version = "2.0.0", features = ["rand"] } anyhow = "1.0" hex = "0.4.3" From 7ad991c84d63a1f405951309fabfdeaa2a35686e Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Fri, 13 Feb 2026 18:00:03 +0200 Subject: [PATCH 02/11] abi crate - type + contract abi modules --- data/abi/src/contract_abi.rs | 13 +++++++++- .../src/{ => contract_abi}/build_info_abi.rs | 0 .../src/{ => contract_abi}/endpoint_abi.rs | 3 ++- .../{ => contract_abi}/esdt_attribute_abi.rs | 2 +- data/abi/src/{ => contract_abi}/event_abi.rs | 3 ++- data/abi/src/lib.rs | 26 ++----------------- data/abi/src/types.rs | 17 ++++++++++++ data/abi/src/{ => types}/type_abi.rs | 1 + data/abi/src/{ => types}/type_abi_from.rs | 0 .../src/{ => types}/type_abi_impl_basic.rs | 2 +- .../src/{ => types}/type_abi_impl_big_int.rs | 0 .../{ => types}/type_abi_impl_codec_multi.rs | 0 .../src/{ => types}/type_abi_impl_vm_core.rs | 0 data/abi/src/{ => types}/type_description.rs | 0 .../{ => types}/type_description_container.rs | 0 data/abi/src/{ => types}/type_names.rs | 0 16 files changed, 38 insertions(+), 29 deletions(-) rename data/abi/src/{ => contract_abi}/build_info_abi.rs (100%) rename data/abi/src/{ => contract_abi}/endpoint_abi.rs (99%) rename data/abi/src/{ => contract_abi}/esdt_attribute_abi.rs (90%) rename data/abi/src/{ => contract_abi}/event_abi.rs (96%) create mode 100644 data/abi/src/types.rs rename data/abi/src/{ => types}/type_abi.rs (98%) rename data/abi/src/{ => types}/type_abi_from.rs (100%) rename data/abi/src/{ => types}/type_abi_impl_basic.rs (99%) rename data/abi/src/{ => types}/type_abi_impl_big_int.rs (100%) rename data/abi/src/{ => types}/type_abi_impl_codec_multi.rs (100%) rename data/abi/src/{ => types}/type_abi_impl_vm_core.rs (100%) rename data/abi/src/{ => types}/type_description.rs (100%) rename data/abi/src/{ => types}/type_description_container.rs (100%) rename data/abi/src/{ => types}/type_names.rs (100%) diff --git a/data/abi/src/contract_abi.rs b/data/abi/src/contract_abi.rs index aecfcab79d..6a9bb229fd 100644 --- a/data/abi/src/contract_abi.rs +++ b/data/abi/src/contract_abi.rs @@ -1,9 +1,20 @@ -use super::*; +mod build_info_abi; +mod endpoint_abi; +mod esdt_attribute_abi; +mod event_abi; + +pub use build_info_abi::*; +pub use endpoint_abi::*; +pub use esdt_attribute_abi::EsdtAttributeAbi; +pub use event_abi::*; + use alloc::{ string::{String, ToString}, vec::Vec, }; +use crate::{TypeAbi, TypeDescriptionContainer, TypeDescriptionContainerImpl}; + #[derive(Debug, Default, Clone)] pub struct ContractAbi { pub build_info: BuildInfoAbi, diff --git a/data/abi/src/build_info_abi.rs b/data/abi/src/contract_abi/build_info_abi.rs similarity index 100% rename from data/abi/src/build_info_abi.rs rename to data/abi/src/contract_abi/build_info_abi.rs diff --git a/data/abi/src/endpoint_abi.rs b/data/abi/src/contract_abi/endpoint_abi.rs similarity index 99% rename from data/abi/src/endpoint_abi.rs rename to data/abi/src/contract_abi/endpoint_abi.rs index 8e96554d84..7aa9510ff1 100644 --- a/data/abi/src/endpoint_abi.rs +++ b/data/abi/src/contract_abi/endpoint_abi.rs @@ -1,4 +1,5 @@ -use super::*; +use crate::{TypeAbi, TypeNames}; + use alloc::{ borrow::ToOwned, string::{String, ToString}, diff --git a/data/abi/src/esdt_attribute_abi.rs b/data/abi/src/contract_abi/esdt_attribute_abi.rs similarity index 90% rename from data/abi/src/esdt_attribute_abi.rs rename to data/abi/src/contract_abi/esdt_attribute_abi.rs index ee37466064..acd13d716b 100644 --- a/data/abi/src/esdt_attribute_abi.rs +++ b/data/abi/src/contract_abi/esdt_attribute_abi.rs @@ -1,6 +1,6 @@ use alloc::string::{String, ToString}; -use super::{TypeAbi, TypeDescriptionContainerImpl, TypeName}; +use crate::{TypeAbi, TypeDescriptionContainerImpl, TypeName}; #[derive(Clone, Debug)] pub struct EsdtAttributeAbi { diff --git a/data/abi/src/event_abi.rs b/data/abi/src/contract_abi/event_abi.rs similarity index 96% rename from data/abi/src/event_abi.rs rename to data/abi/src/contract_abi/event_abi.rs index 416e967b75..c48c2e19f9 100644 --- a/data/abi/src/event_abi.rs +++ b/data/abi/src/contract_abi/event_abi.rs @@ -1,4 +1,5 @@ -use super::*; +use crate::{TypeAbi, TypeName}; + use alloc::{ string::{String, ToString}, vec::Vec, diff --git a/data/abi/src/lib.rs b/data/abi/src/lib.rs index 7f2932303a..0f7f3aac20 100644 --- a/data/abi/src/lib.rs +++ b/data/abi/src/lib.rs @@ -1,33 +1,11 @@ // re-export basic heap types extern crate alloc; -mod build_info_abi; mod contract_abi; -mod endpoint_abi; -mod esdt_attribute_abi; -mod event_abi; -mod type_abi; -mod type_abi_from; -mod type_abi_impl_basic; -mod type_abi_impl_codec_multi; -mod type_abi_impl_vm_core; -mod type_description; -mod type_description_container; -mod type_names; +mod types; -#[cfg(feature = "num-bigint")] -mod type_abi_impl_big_int; - -pub use build_info_abi::*; pub use contract_abi::*; -pub use endpoint_abi::*; -pub use esdt_attribute_abi::EsdtAttributeAbi; -pub use event_abi::*; -pub use type_abi::*; -pub use type_abi_from::*; -pub use type_description::*; -pub use type_description_container::*; -pub use type_names::{TypeName, TypeNames}; +pub use types::*; /// The current version of `multiversx_sc_codec`, re-exported. pub use multiversx_sc_codec as codec; diff --git a/data/abi/src/types.rs b/data/abi/src/types.rs new file mode 100644 index 0000000000..506614e94f --- /dev/null +++ b/data/abi/src/types.rs @@ -0,0 +1,17 @@ +mod type_abi; +mod type_abi_from; +mod type_abi_impl_basic; +mod type_abi_impl_codec_multi; +mod type_abi_impl_vm_core; +mod type_description; +mod type_description_container; +mod type_names; + +#[cfg(feature = "num-bigint")] +mod type_abi_impl_big_int; + +pub use type_abi::*; +pub use type_abi_from::*; +pub use type_description::*; +pub use type_description_container::*; +pub use type_names::{TypeName, TypeNames}; diff --git a/data/abi/src/type_abi.rs b/data/abi/src/types/type_abi.rs similarity index 98% rename from data/abi/src/type_abi.rs rename to data/abi/src/types/type_abi.rs index 3e4c451b48..b989ad6ad1 100644 --- a/data/abi/src/type_abi.rs +++ b/data/abi/src/types/type_abi.rs @@ -1,4 +1,5 @@ use super::*; +use crate::contract_abi::{OutputAbi, OutputAbis}; use alloc::{format, string::ToString, vec::Vec}; /// Implemented for all types that can end up in the ABI: diff --git a/data/abi/src/type_abi_from.rs b/data/abi/src/types/type_abi_from.rs similarity index 100% rename from data/abi/src/type_abi_from.rs rename to data/abi/src/types/type_abi_from.rs diff --git a/data/abi/src/type_abi_impl_basic.rs b/data/abi/src/types/type_abi_impl_basic.rs similarity index 99% rename from data/abi/src/type_abi_impl_basic.rs rename to data/abi/src/types/type_abi_impl_basic.rs index e49a7cd38c..bff32fd8b8 100644 --- a/data/abi/src/type_abi_impl_basic.rs +++ b/data/abi/src/types/type_abi_impl_basic.rs @@ -1,5 +1,5 @@ use super::*; -use crate::codec::arrayvec::ArrayVec; +use crate::{codec::arrayvec::ArrayVec, contract_abi::OutputAbis}; use alloc::{ boxed::Box, format, diff --git a/data/abi/src/type_abi_impl_big_int.rs b/data/abi/src/types/type_abi_impl_big_int.rs similarity index 100% rename from data/abi/src/type_abi_impl_big_int.rs rename to data/abi/src/types/type_abi_impl_big_int.rs diff --git a/data/abi/src/type_abi_impl_codec_multi.rs b/data/abi/src/types/type_abi_impl_codec_multi.rs similarity index 100% rename from data/abi/src/type_abi_impl_codec_multi.rs rename to data/abi/src/types/type_abi_impl_codec_multi.rs diff --git a/data/abi/src/type_abi_impl_vm_core.rs b/data/abi/src/types/type_abi_impl_vm_core.rs similarity index 100% rename from data/abi/src/type_abi_impl_vm_core.rs rename to data/abi/src/types/type_abi_impl_vm_core.rs diff --git a/data/abi/src/type_description.rs b/data/abi/src/types/type_description.rs similarity index 100% rename from data/abi/src/type_description.rs rename to data/abi/src/types/type_description.rs diff --git a/data/abi/src/type_description_container.rs b/data/abi/src/types/type_description_container.rs similarity index 100% rename from data/abi/src/type_description_container.rs rename to data/abi/src/types/type_description_container.rs diff --git a/data/abi/src/type_names.rs b/data/abi/src/types/type_names.rs similarity index 100% rename from data/abi/src/type_names.rs rename to data/abi/src/types/type_names.rs From 5978afa233dd76565ebbece7e89bbf714e2a31ab Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Thu, 19 Feb 2026 18:17:41 +0200 Subject: [PATCH 03/11] multiversx-sc-abi-derive-common crate, deduplicated type_abi macros & utils --- Cargo.lock | 376 +++++++++++++----- Cargo.toml | 1 + data/abi-derive-common/Cargo.toml | 28 ++ data/abi-derive-common/README.md | 10 + data/abi-derive-common/src/lib.rs | 13 + .../mod.rs => abi-derive-common/src/parse.rs} | 0 .../src/parse/attributes.rs | 2 +- .../src/type_abi_derive.rs | 82 ++-- data/abi-derive/Cargo.toml | 13 +- data/abi-derive/src/lib.rs | 25 +- data/abi/src/lib.rs | 3 + data/abi/src/types/type_names.rs | 2 - data/codec-derive/Cargo.toml | 3 - framework/derive/Cargo.toml | 16 +- framework/derive/src/lib.rs | 15 +- framework/derive/src/parse/attributes.rs | 6 +- .../derive/src/parse/attributes/doc_attr.rs | 93 ----- .../src/parse/attributes/output_name_attr.rs | 13 + .../derive/src/parse/attributes/title_attr.rs | 11 + .../derive/src/parse/contract_trait_parse.rs | 4 +- framework/derive/src/parse/method_parse.rs | 3 +- framework/derive/src/type_abi_derive.rs | 215 ---------- 22 files changed, 445 insertions(+), 489 deletions(-) create mode 100644 data/abi-derive-common/Cargo.toml create mode 100644 data/abi-derive-common/README.md create mode 100644 data/abi-derive-common/src/lib.rs rename data/{abi-derive/src/parse/mod.rs => abi-derive-common/src/parse.rs} (100%) rename data/{abi-derive => abi-derive-common}/src/parse/attributes.rs (99%) rename data/{abi-derive => abi-derive-common}/src/type_abi_derive.rs (72%) delete mode 100644 framework/derive/src/parse/attributes/doc_attr.rs create mode 100644 framework/derive/src/parse/attributes/output_name_attr.rs create mode 100644 framework/derive/src/parse/attributes/title_attr.rs delete mode 100644 framework/derive/src/type_abi_derive.rs diff --git a/Cargo.lock b/Cargo.lock index f3555c0a08..134f1b54a7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -16,7 +16,7 @@ dependencies = [ name = "abi-tester" version = "0.0.0" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.11.0", "multiversx-sc", "multiversx-sc-meta-lib", "multiversx-sc-scenario", @@ -200,9 +200,9 @@ checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "aws-lc-rs" -version = "1.15.4" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b7b6141e96a8c160799cc2d5adecd5cbbe5054cb8c7c4af53da0f83bb7ad256" +checksum = "d9a7b350e3bb1767102698302bc37256cbd48422809984b98d292c40e2579aa9" dependencies = [ "aws-lc-sys", "zeroize", @@ -337,7 +337,7 @@ version = "0.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f49d8fed880d473ea71efb9bf597651e77201bdd4893efe54c9e5d65ae04ce6f" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.11.0", "cexpr", "clang-sys", "itertools 0.13.0", @@ -348,7 +348,7 @@ dependencies = [ "regex", "rustc-hash 1.1.0", "shlex", - "syn 2.0.115", + "syn 2.0.116", ] [[package]] @@ -381,9 +381,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.10.0" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" +checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af" [[package]] name = "block-buffer" @@ -439,9 +439,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.19.1" +version = "3.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" +checksum = "5c6f81257d10a0f602a294ae4182251151ff97dbb504ef9afcdda4a64b24d9b4" [[package]] name = "bytecheck" @@ -485,7 +485,7 @@ checksum = "89385e82b5d1821d2219e0b095efa2cc1f246cbf99080f3be46a1a85c0d392d9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.116", ] [[package]] @@ -630,9 +630,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.58" +version = "4.5.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63be97961acde393029492ce0be7a1af7e323e6bae9511ebfac33751be5e6806" +checksum = "c5caf74d17c3aec5495110c34cc3f78644bfa89af6c8993ed4de2790e49b6499" dependencies = [ "clap_builder", "clap_derive", @@ -640,9 +640,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.58" +version = "4.5.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f13174bda5dfd69d7e947827e5af4b0f2f94a4a3ee92912fba07a66150f21e2" +checksum = "370daa45065b80218950227371916a1633217ae42b2715b2287b606dcd618e24" dependencies = [ "anstream", "anstyle", @@ -659,7 +659,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.116", ] [[package]] @@ -1017,7 +1017,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.116", ] [[package]] @@ -1040,7 +1040,7 @@ dependencies = [ "ident_case", "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.116", ] [[package]] @@ -1051,7 +1051,7 @@ checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" dependencies = [ "darling_core", "quote", - "syn 2.0.115", + "syn 2.0.116", ] [[package]] @@ -1097,7 +1097,7 @@ checksum = "1e567bd82dcff979e4b03460c307b3cdc9e96fde3d73bed1496d2bc75d9dd62a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.116", ] [[package]] @@ -1108,7 +1108,7 @@ checksum = "6edb4b64a43d977b8e99788fe3a04d483834fba1215a7e02caa415b626497f7f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.116", ] [[package]] @@ -1130,7 +1130,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn 2.0.115", + "syn 2.0.116", "unicode-xid", ] @@ -1169,7 +1169,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.116", ] [[package]] @@ -1184,13 +1184,13 @@ version = "4.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d36219658beb39702975c707dee7895943ca281ca46eebbc5ea395171b9c182b" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.11.0", "byteorder", "lazy_static", "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.116", ] [[package]] @@ -1202,7 +1202,7 @@ dependencies = [ "byteorder", "dynasm", "fnv", - "memmap2 0.9.9", + "memmap2 0.9.10", ] [[package]] @@ -1305,7 +1305,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.116", ] [[package]] @@ -1708,9 +1708,9 @@ checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" [[package]] name = "futures" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" +checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d" dependencies = [ "futures-channel", "futures-core", @@ -1723,9 +1723,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" dependencies = [ "futures-core", "futures-sink", @@ -1733,15 +1733,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" +checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" [[package]] name = "futures-executor" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" +checksum = "baf29c38818342a3b26b5b923639e7b1f4a61fc5e76102d4b1981c6dc7a7579d" dependencies = [ "futures-core", "futures-task", @@ -1750,38 +1750,38 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" +checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" [[package]] name = "futures-macro" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.116", ] [[package]] name = "futures-sink" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" +checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" [[package]] name = "futures-task" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" +checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" [[package]] name = "futures-util" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" dependencies = [ "futures-channel", "futures-core", @@ -1791,7 +1791,6 @@ dependencies = [ "futures-task", "memchr", "pin-project-lite", - "pin-utils", "slab", ] @@ -1853,6 +1852,19 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "getrandom" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "139ef39800118c7683f2fd3c98c1b23c09ae076556b435f8e9064ae108aaeeec" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasip2", + "wasip3", +] + [[package]] name = "gimli" version = "0.28.1" @@ -2091,7 +2103,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.116", ] [[package]] @@ -2398,6 +2410,12 @@ dependencies = [ "zerovec", ] +[[package]] +name = "id-arena" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" + [[package]] name = "ident_case" version = "1.0.1" @@ -2458,7 +2476,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "699c1b6d335e63d0ba5c1e1c7f647371ce989c3bcbe1f7ed2b85fa56e3bd1a21" dependencies = [ "quote", - "syn 2.0.115", + "syn 2.0.116", ] [[package]] @@ -2561,7 +2579,7 @@ checksum = "f7946b4325269738f270bb55b3c19ab5c5040525f83fd625259422a9d25d9be5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.116", ] [[package]] @@ -2608,9 +2626,9 @@ dependencies = [ [[package]] name = "keccak" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" +checksum = "cb26cec98cce3a3d96cbb7bced3c4b16e3d13f27ec56dbd62cbc8f39cfb9d653" dependencies = [ "cpufeatures", ] @@ -2734,7 +2752,7 @@ version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d0b95e02c851351f877147b7deea7b1afb1df71b63aa5f8270716e0c5720616" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.11.0", "libc", "redox_syscall 0.7.1", ] @@ -2918,9 +2936,9 @@ dependencies = [ [[package]] name = "memmap2" -version = "0.9.9" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "744133e4a0e0a658e1374cf3bf8e415c4052a15a111acd372764c55b4177d490" +checksum = "714098028fe011992e1c3962653c96b2d578c4b4bce9036e15ff220319b1e0e3" dependencies = [ "libc", ] @@ -3039,7 +3057,7 @@ name = "multiversx-chain-core" version = "0.21.1" dependencies = [ "bech32", - "bitflags 2.10.0", + "bitflags 2.11.0", "hex", "multiversx-sc-codec", "serde", @@ -3063,7 +3081,7 @@ name = "multiversx-chain-vm" version = "0.21.1" dependencies = [ "anyhow", - "bitflags 2.10.0", + "bitflags 2.11.0", "colored 3.1.1", "ed25519-dalek", "hex", @@ -3131,7 +3149,7 @@ dependencies = [ name = "multiversx-sc" version = "0.64.1" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.11.0", "generic-array 1.3.5", "multiversx-chain-core", "multiversx-sc-abi", @@ -3145,7 +3163,7 @@ dependencies = [ name = "multiversx-sc-abi" version = "0.24.0" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.11.0", "multiversx-chain-core", "multiversx-sc-codec", "num-bigint", @@ -3155,10 +3173,17 @@ dependencies = [ [[package]] name = "multiversx-sc-abi-derive" version = "0.24.0" +dependencies = [ + "multiversx-sc-abi-derive-common", +] + +[[package]] +name = "multiversx-sc-abi-derive-common" +version = "0.24.0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.116", ] [[package]] @@ -3166,7 +3191,7 @@ name = "multiversx-sc-codec" version = "0.24.0" dependencies = [ "arrayvec", - "bitflags 2.10.0", + "bitflags 2.11.0", "multiversx-sc-codec-derive", "num-bigint", "unwrap-infallible", @@ -3179,7 +3204,7 @@ dependencies = [ "hex", "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.116", ] [[package]] @@ -3194,11 +3219,11 @@ dependencies = [ name = "multiversx-sc-derive" version = "0.64.1" dependencies = [ - "hex", + "multiversx-sc-abi-derive-common", "proc-macro2", "quote", "radix_trie", - "syn 2.0.115", + "syn 2.0.116", ] [[package]] @@ -3401,7 +3426,7 @@ checksum = "4568f25ccbd45ab5d5603dc34318c1ec56b117531781260002151b8530a9f931" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.116", ] [[package]] @@ -3741,7 +3766,7 @@ checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.116", ] [[package]] @@ -3887,7 +3912,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ "proc-macro2", - "syn 2.0.115", + "syn 2.0.116", ] [[package]] @@ -3943,7 +3968,7 @@ dependencies = [ "proc-macro-error-attr2", "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.116", ] [[package]] @@ -4041,7 +4066,7 @@ checksum = "7347867d0a7e1208d93b46767be83e2b8f978c3dad35f775ac8d8847551d6fe1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.116", ] [[package]] @@ -4275,7 +4300,7 @@ version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.11.0", ] [[package]] @@ -4284,7 +4309,7 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "35985aa610addc02e24fc232012c86fd11f14111180f902b67e2d5331f8ebf2b" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.11.0", ] [[package]] @@ -4437,7 +4462,7 @@ checksum = "8100bb34c0a1d0f907143db3149e6b4eea3c33b9ee8b189720168e818303986f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.116", ] [[package]] @@ -4532,7 +4557,7 @@ version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.11.0", "errno", "libc", "linux-raw-sys", @@ -4731,11 +4756,11 @@ dependencies = [ [[package]] name = "security-framework" -version = "3.5.1" +version = "3.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3297343eaf830f66ede390ea39da1d462b6b0c1b000f420d0a83f898bbbe6ef" +checksum = "d17b898a6d6948c3a8ee4372c17cb384f90d2e6e912ef00895b14fd7ab54ec38" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.11.0", "core-foundation 0.10.1", "core-foundation-sys", "libc", @@ -4744,9 +4769,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.15.0" +version = "2.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0" +checksum = "321c8673b092a9a42605034a9879d73cb79101ed5fd117bc9a597b89b4e9e61a" dependencies = [ "core-foundation-sys", "libc", @@ -4835,7 +4860,7 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.116", ] [[package]] @@ -4860,7 +4885,7 @@ checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.116", ] [[package]] @@ -4907,7 +4932,7 @@ checksum = "6f50427f258fb77356e4cd4aa0e87e2bd2c66dbcee41dc405282cae2bfc26c83" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.116", ] [[package]] @@ -5120,9 +5145,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.115" +version = "2.0.116" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e614ed320ac28113fa64972c4262d5dbc89deacdfd00c34a3e4cea073243c12" +checksum = "3df424c70518695237746f84cede799c9c58fcb37450d7b23716568cc8bc69cb" dependencies = [ "proc-macro2", "quote", @@ -5146,7 +5171,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.116", ] [[package]] @@ -5155,7 +5180,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a13f3d0daba03132c0aa9767f98351b3488edc2c100cda2d2ec2b04f3d8d3c8b" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.11.0", "core-foundation 0.9.4", "system-configuration-sys", ] @@ -5233,7 +5258,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.116", ] [[package]] @@ -5244,7 +5269,7 @@ checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.116", ] [[package]] @@ -5342,7 +5367,7 @@ checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.116", ] [[package]] @@ -5439,9 +5464,9 @@ dependencies = [ [[package]] name = "toml_parser" -version = "1.0.8+spec-1.1.0" +version = "1.0.9+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0742ff5ff03ea7e67c8ae6c93cac239e0d9784833362da3f9a9c1da8dfefcbdc" +checksum = "702d4415e08923e7e1ef96cd5727c0dfed80b4d2fa25db9647fe5eb6f7c5a4c4" dependencies = [ "winnow 0.7.14", ] @@ -5473,7 +5498,7 @@ version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.11.0", "bytes", "futures-util", "http 1.4.0", @@ -5516,7 +5541,7 @@ checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.116", ] [[package]] @@ -5570,9 +5595,9 @@ checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" [[package]] name = "unicode-ident" -version = "1.0.23" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "537dd038a89878be9b64dd4bd1b260315c1bb94f4d784956b81e27a088d9a09e" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" [[package]] name = "unicode-normalization" @@ -5663,11 +5688,11 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.20.0" +version = "1.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee48d38b119b0cd71fe4141b30f5ba9c7c5d9f4e7a3a8b4a674e4b6ef789976f" +checksum = "b672338555252d43fd2240c714dc444b8c6fb0a5c5335e65a07bba7742735ddb" dependencies = [ - "getrandom 0.3.4", + "getrandom 0.4.1", "js-sys", "wasm-bindgen", ] @@ -5742,7 +5767,16 @@ version = "1.0.1+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" dependencies = [ - "wit-bindgen", + "wit-bindgen 0.46.0", +] + +[[package]] +name = "wasip3" +version = "0.4.0+wasi-0.3.0-rc-2026-01-06" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" +dependencies = [ + "wit-bindgen 0.51.0", ] [[package]] @@ -5791,7 +5825,7 @@ dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.116", "wasm-bindgen-shared", ] @@ -5804,6 +5838,16 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "wasm-encoder" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" +dependencies = [ + "leb128fmt", + "wasmparser 0.244.0", +] + [[package]] name = "wasm-encoder" version = "0.245.1" @@ -5814,6 +5858,18 @@ dependencies = [ "wasmparser 0.245.1", ] +[[package]] +name = "wasm-metadata" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" +dependencies = [ + "anyhow", + "indexmap", + "wasm-encoder 0.244.0", + "wasmparser 0.244.0", +] + [[package]] name = "wasmer" version = "6.1.0" @@ -5963,7 +6019,7 @@ version = "0.224.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04f17a5917c2ddd3819e84c661fae0d6ba29d7b9c1f0e96c708c65a9c4188e11" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.11.0", ] [[package]] @@ -5972,20 +6028,32 @@ version = "0.243.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f6d8db401b0528ec316dfbe579e6ab4152d61739cfe076706d2009127970159d" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.11.0", "hashbrown 0.15.5", "indexmap", "semver", "serde", ] +[[package]] +name = "wasmparser" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" +dependencies = [ + "bitflags 2.11.0", + "hashbrown 0.15.5", + "indexmap", + "semver", +] + [[package]] name = "wasmparser" version = "0.245.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4f08c9adee0428b7bddf3890fc27e015ac4b761cc608c822667102b8bfd6995e" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.11.0", "indexmap", "semver", ] @@ -6011,7 +6079,7 @@ dependencies = [ "leb128fmt", "memchr", "unicode-width", - "wasm-encoder", + "wasm-encoder 0.245.1", ] [[package]] @@ -6356,6 +6424,94 @@ version = "0.46.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" +[[package]] +name = "wit-bindgen" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" +dependencies = [ + "wit-bindgen-rust-macro", +] + +[[package]] +name = "wit-bindgen-core" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" +dependencies = [ + "anyhow", + "heck", + "wit-parser", +] + +[[package]] +name = "wit-bindgen-rust" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" +dependencies = [ + "anyhow", + "heck", + "indexmap", + "prettyplease", + "syn 2.0.116", + "wasm-metadata", + "wit-bindgen-core", + "wit-component", +] + +[[package]] +name = "wit-bindgen-rust-macro" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" +dependencies = [ + "anyhow", + "prettyplease", + "proc-macro2", + "quote", + "syn 2.0.116", + "wit-bindgen-core", + "wit-bindgen-rust", +] + +[[package]] +name = "wit-component" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" +dependencies = [ + "anyhow", + "bitflags 2.11.0", + "indexmap", + "log", + "serde", + "serde_derive", + "serde_json", + "wasm-encoder 0.244.0", + "wasm-metadata", + "wasmparser 0.244.0", + "wit-parser", +] + +[[package]] +name = "wit-parser" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" +dependencies = [ + "anyhow", + "id-arena", + "indexmap", + "log", + "semver", + "serde", + "serde_derive", + "serde_json", + "unicode-xid", + "wasmparser 0.244.0", +] + [[package]] name = "writeable" version = "0.6.2" @@ -6415,7 +6571,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.115", + "syn 2.0.116", ] [[package]] @@ -6445,7 +6601,7 @@ checksum = "9e87a3ce33434ab66a700edbaf2cc8a417d9b89f00a6fd8216fd6ac83b0e7b1c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.116", ] [[package]] @@ -6467,7 +6623,7 @@ checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.116", "synstructure", ] @@ -6488,7 +6644,7 @@ checksum = "4122cd3169e94605190e77839c9a40d40ed048d305bfdc146e7df40ab0f3e517" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.116", ] [[package]] @@ -6508,7 +6664,7 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.116", "synstructure", ] @@ -6548,7 +6704,7 @@ checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.116", ] [[package]] @@ -6567,9 +6723,9 @@ dependencies = [ [[package]] name = "zlib-rs" -version = "0.6.0" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7948af682ccbc3342b6e9420e8c51c1fe5d7bf7756002b4a3c6cabfe96a7e3c" +checksum = "c745c48e1007337ed136dc99df34128b9faa6ed542d80a1c673cf55a6d7236c8" [[package]] name = "zmij" diff --git a/Cargo.toml b/Cargo.toml index 465fe27d7e..82ec90874a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,6 +3,7 @@ resolver = "3" members = [ "data/abi", + "data/abi-derive-common", "data/abi-derive", "data/codec", "data/codec-derive", diff --git a/data/abi-derive-common/Cargo.toml b/data/abi-derive-common/Cargo.toml new file mode 100644 index 0000000000..01a16cb5e2 --- /dev/null +++ b/data/abi-derive-common/Cargo.toml @@ -0,0 +1,28 @@ +[package] +name = "multiversx-sc-abi-derive-common" +version = "0.24.0" +edition = "2024" +publish = false + +authors = [ + "Andrei Marinica ", + "MultiversX ", +] +license = "GPL-3.0-only" +readme = "README.md" +repository = "https://github.com/multiversx/mx-sdk-rs" +homepage = "https://multiversx.com/" +documentation = "https://docs.multiversx.com/" +description = "MultiversX ABI common functionality for derive macros" +keywords = ["multiversx", "wasm", "webassembly", "blockchain", "contract"] +categories = [ + "no-std", + "wasm", + "cryptography::cryptocurrencies", + "development-tools", +] + +[dependencies] +proc-macro2 = "1.0" +quote = "1.0" +syn = "2.0" diff --git a/data/abi-derive-common/README.md b/data/abi-derive-common/README.md new file mode 100644 index 0000000000..86fdba58e9 --- /dev/null +++ b/data/abi-derive-common/README.md @@ -0,0 +1,10 @@ +# multiversx-sc-abi-derive-common + +Common logic for the `TypeAbi` derive macros in MultiversX smart contracts. + +This is a regular library crate (not a proc-macro crate) that contains the shared implementation used by both `multiversx-sc-abi-derive` and `multiversx-sc-derive`. + +## Contents + +- **`type_abi_derive`** — generates `TypeAbi` trait implementations for structs and enums +- **`parse`** — attribute parsing utilities (doc comments, macro attributes) diff --git a/data/abi-derive-common/src/lib.rs b/data/abi-derive-common/src/lib.rs new file mode 100644 index 0000000000..402a4dc571 --- /dev/null +++ b/data/abi-derive-common/src/lib.rs @@ -0,0 +1,13 @@ +// ensure we don't run out of macro stack +#![recursion_limit = "1024"] +// TODO: remove once minimum version is 1.87+ +#![allow(unknown_lints)] +#![allow(clippy::collapsible_if)] +#![allow(clippy::manual_is_multiple_of)] + +/// Common code for derive macros, shared between `data/abi-derive` and `framework/derive`. +pub mod parse; + +mod type_abi_derive; + +pub use type_abi_derive::{TypeAbiImportCrate, type_abi_derive, type_abi_full}; diff --git a/data/abi-derive/src/parse/mod.rs b/data/abi-derive-common/src/parse.rs similarity index 100% rename from data/abi-derive/src/parse/mod.rs rename to data/abi-derive-common/src/parse.rs diff --git a/data/abi-derive/src/parse/attributes.rs b/data/abi-derive-common/src/parse/attributes.rs similarity index 99% rename from data/abi-derive/src/parse/attributes.rs rename to data/abi-derive-common/src/parse/attributes.rs index 286f3e93c4..ebf58b2899 100644 --- a/data/abi-derive/src/parse/attributes.rs +++ b/data/abi-derive-common/src/parse/attributes.rs @@ -4,7 +4,7 @@ use quote::ToTokens; /// so extracting doc comments means parsing "doc" attributes. pub fn extract_doc(attrs: &[syn::Attribute]) -> Vec { const ATTR_DOC: &str = "doc"; - + attrs .iter() .filter(|attr| { diff --git a/data/abi-derive/src/type_abi_derive.rs b/data/abi-derive-common/src/type_abi_derive.rs similarity index 72% rename from data/abi-derive/src/type_abi_derive.rs rename to data/abi-derive-common/src/type_abi_derive.rs index ca681e192e..9243f3fc21 100644 --- a/data/abi-derive/src/type_abi_derive.rs +++ b/data/abi-derive-common/src/type_abi_derive.rs @@ -9,7 +9,24 @@ pub struct ExplicitDiscriminant { pub value: usize, } -fn field_snippet(index: usize, field: &syn::Field) -> proc_macro2::TokenStream { +#[derive(Clone, Copy)] +pub enum TypeAbiImportCrate { + MultiversxSc, + MultiversxScAbi, +} + +fn import_tokens(context: TypeAbiImportCrate) -> proc_macro2::TokenStream { + match context { + TypeAbiImportCrate::MultiversxSc => quote! { multiversx_sc::abi }, + TypeAbiImportCrate::MultiversxScAbi => quote! { multiversx_sc_abi }, + } +} + +fn field_snippet( + index: usize, + field: &syn::Field, + context: TypeAbiImportCrate, +) -> proc_macro2::TokenStream { let field_docs = extract_doc(field.attrs.as_slice()); let field_name_str = if let Some(ident) = &field.ident { ident.to_string() @@ -17,8 +34,9 @@ fn field_snippet(index: usize, field: &syn::Field) -> proc_macro2::TokenStream { index.to_string() }; let field_ty = sanitize_field_type_path(&field.ty); + let imports = import_tokens(context); quote! { - field_descriptions.push(multiversx_sc_abi::StructFieldDescription::new( + field_descriptions.push(#imports::StructFieldDescription::new( &[ #(#field_docs),* ], #field_name_str, <#field_ty>::type_names(), @@ -45,26 +63,32 @@ fn sanitize_field_type_path(field_type: &syn::Type) -> syn::Type { field_type.clone() } -fn fields_snippets(fields: &syn::Fields) -> Vec { +fn fields_snippets( + fields: &syn::Fields, + context: TypeAbiImportCrate, +) -> Vec { match fields { syn::Fields::Named(fields_named) => fields_named .named .iter() .enumerate() - .map(|(index, field)| field_snippet(index, field)) + .map(|(index, field)| field_snippet(index, field, context)) .collect(), syn::Fields::Unnamed(fields_unnamed) => fields_unnamed .unnamed .iter() .enumerate() - .map(|(index, field)| field_snippet(index, field)) + .map(|(index, field)| field_snippet(index, field, context)) .collect(), syn::Fields::Unit => Vec::new(), } } -pub fn type_abi_derive(input: proc_macro::TokenStream) -> proc_macro2::TokenStream { - let ast: syn::DeriveInput = syn::parse(input).unwrap(); +pub fn type_abi_derive( + input: proc_macro2::TokenStream, + context: TypeAbiImportCrate, +) -> proc_macro2::TokenStream { + let ast: syn::DeriveInput = syn::parse2(input).unwrap(); let name = &ast.ident; let name_str = name.to_string(); let type_docs = extract_doc(ast.attrs.as_slice()); @@ -75,22 +99,24 @@ pub fn type_abi_derive(input: proc_macro::TokenStream) -> proc_macro2::TokenStre ); } + let imports = import_tokens(context); + let type_description_impl = match &ast.data { syn::Data::Struct(data_struct) => { - let struct_field_snippets = fields_snippets(&data_struct.fields); + let struct_field_snippets = fields_snippets(&data_struct.fields, context); quote! { - fn provide_type_descriptions(accumulator: &mut TDC) { + fn provide_type_descriptions(accumulator: &mut TDC) { let type_names = Self::type_names(); if !accumulator.contains_type(&type_names.abi) { accumulator.reserve_type_name(type_names.clone()); - let mut field_descriptions = multiversx_sc_abi::types::heap::Vec::new(); + let mut field_descriptions = #imports::Vec::new(); #(#struct_field_snippets)* accumulator.insert( type_names.clone(), - multiversx_sc_abi::TypeDescription::new( + #imports::TypeDescription::new( &[ #(#type_docs),* ], type_names, - multiversx_sc_abi::TypeContents::Struct(field_descriptions), + #imports::TypeContents::Struct(field_descriptions), &[ #(#macro_attributes),* ], ), ); @@ -107,13 +133,13 @@ pub fn type_abi_derive(input: proc_macro::TokenStream) -> proc_macro2::TokenStre .map(|(variant_index, variant)| { let variant_docs = extract_doc(variant.attrs.as_slice()); let variant_name_str = variant.ident.to_string(); - let variant_field_snippets = fields_snippets(&variant.fields); + let variant_field_snippets = fields_snippets(&variant.fields, context); let variant_discriminant = get_discriminant(variant_index, variant, &mut previous_disc); quote! { - let mut field_descriptions = multiversx_sc_abi::types::heap::Vec::new(); + let mut field_descriptions = #imports::Vec::new(); #(#variant_field_snippets)* - variant_descriptions.push(multiversx_sc_abi::EnumVariantDescription::new( + variant_descriptions.push(#imports::EnumVariantDescription::new( &[ #(#variant_docs),* ], #variant_name_str, #variant_discriminant, @@ -123,18 +149,18 @@ pub fn type_abi_derive(input: proc_macro::TokenStream) -> proc_macro2::TokenStre }) .collect(); quote! { - fn provide_type_descriptions(accumulator: &mut TDC) { + fn provide_type_descriptions(accumulator: &mut TDC) { let type_names = Self::type_names(); if !accumulator.contains_type(&type_names.abi) { accumulator.reserve_type_name(type_names.clone()); - let mut variant_descriptions = multiversx_sc_abi::types::heap::Vec::new(); + let mut variant_descriptions = #imports::Vec::new(); #(#enum_variant_snippets)* accumulator.insert( type_names.clone(), - multiversx_sc_abi::TypeDescription::new( + #imports::TypeDescription::new( &[ #(#type_docs),* ], type_names, - multiversx_sc_abi::TypeContents::Enum(variant_descriptions), + #imports::TypeContents::Enum(variant_descriptions), &[ #(#macro_attributes),* ], ), ); @@ -147,13 +173,13 @@ pub fn type_abi_derive(input: proc_macro::TokenStream) -> proc_macro2::TokenStre let (impl_generics, ty_generics, where_clause) = &ast.generics.split_for_impl(); quote! { - impl #impl_generics multiversx_sc_abi::TypeAbiFrom for #name #ty_generics #where_clause {} - impl #impl_generics multiversx_sc_abi::TypeAbiFrom<&Self> for #name #ty_generics #where_clause {} + impl #impl_generics #imports::TypeAbiFrom for #name #ty_generics #where_clause {} + impl #impl_generics #imports::TypeAbiFrom<&Self> for #name #ty_generics #where_clause {} - impl #impl_generics multiversx_sc_abi::TypeAbi for #name #ty_generics #where_clause { + impl #impl_generics #imports::TypeAbi for #name #ty_generics #where_clause { type Unmanaged = Self; - fn type_name() -> multiversx_sc_abi::TypeName { + fn type_name() -> #imports::TypeName { #name_str.into() } #type_description_impl @@ -161,11 +187,13 @@ pub fn type_abi_derive(input: proc_macro::TokenStream) -> proc_macro2::TokenStre } } -pub fn type_abi_full(input: proc_macro::TokenStream) -> proc_macro2::TokenStream { - let input_conv = proc_macro2::TokenStream::from(input.clone()); - let derive_code = type_abi_derive(input); +pub fn type_abi_full( + input: proc_macro2::TokenStream, + context: TypeAbiImportCrate, +) -> proc_macro2::TokenStream { + let derive_code = type_abi_derive(input.clone(), context); quote! { - #input_conv + #input #derive_code } } diff --git a/data/abi-derive/Cargo.toml b/data/abi-derive/Cargo.toml index 2cd9bc6bc6..5f979cf3e6 100644 --- a/data/abi-derive/Cargo.toml +++ b/data/abi-derive/Cargo.toml @@ -22,14 +22,11 @@ categories = [ "development-tools", ] -[dependencies] -proc-macro2 = "1.0" -quote = "1.0" -syn = "2.0" - -[features] -default = ["syn/full", "syn/parsing", "syn/extra-traits"] - [lib] name = "multiversx_sc_abi_derive" proc-macro = true + +[dependencies.multiversx-sc-abi-derive-common] +version = "=0.24.0" +path = "../abi-derive-common" + diff --git a/data/abi-derive/src/lib.rs b/data/abi-derive/src/lib.rs index d517706234..dc706bb5d2 100644 --- a/data/abi-derive/src/lib.rs +++ b/data/abi-derive/src/lib.rs @@ -1,20 +1,13 @@ // ensure we don't run out of macro stack #![recursion_limit = "1024"] -// TODO: remove once minimum version is 1.87+ -#![allow(unknown_lints)] -#![allow(clippy::collapsible_if)] -#![allow(clippy::manual_is_multiple_of)] -mod parse; -mod type_abi_derive; - -#[deprecated( - since = "0.54.4", - note = "Replace with attribute #[type_abi], which should be placed before all derives. More about this: https://docs.multiversx.com/developers/transactions/tx-migration/#replace-derivetypeabi-with-type_abi" -)] #[proc_macro_derive(TypeAbi)] pub fn type_abi_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream { - type_abi_derive::type_abi_derive(input).into() + multiversx_sc_abi_derive_common::type_abi_derive( + input.into(), + multiversx_sc_abi_derive_common::TypeAbiImportCrate::MultiversxScAbi, + ) + .into() } #[proc_macro_attribute] @@ -22,6 +15,10 @@ pub fn type_abi( args: proc_macro::TokenStream, input: proc_macro::TokenStream, ) -> proc_macro::TokenStream { - assert!(args.is_empty(), "#[type_abi] attribute takes no args"); - type_abi_derive::type_abi_full(input).into() + assert!(args.is_empty(), "#[type_abi] attribute takes no arguments"); + multiversx_sc_abi_derive_common::type_abi_full( + input.into(), + multiversx_sc_abi_derive_common::TypeAbiImportCrate::MultiversxScAbi, + ) + .into() } diff --git a/data/abi/src/lib.rs b/data/abi/src/lib.rs index 0f7f3aac20..93691c4609 100644 --- a/data/abi/src/lib.rs +++ b/data/abi/src/lib.rs @@ -9,3 +9,6 @@ pub use types::*; /// The current version of `multiversx_sc_codec`, re-exported. pub use multiversx_sc_codec as codec; + +/// Re-exported for easier import in derive macros. +pub use alloc::vec::Vec; diff --git a/data/abi/src/types/type_names.rs b/data/abi/src/types/type_names.rs index 6b338eb9c6..545e555881 100644 --- a/data/abi/src/types/type_names.rs +++ b/data/abi/src/types/type_names.rs @@ -1,5 +1,3 @@ - - pub type TypeName = alloc::string::String; #[derive(Clone, Default, Debug, PartialEq, Eq)] diff --git a/data/codec-derive/Cargo.toml b/data/codec-derive/Cargo.toml index 838fbae617..5b86d5d50b 100644 --- a/data/codec-derive/Cargo.toml +++ b/data/codec-derive/Cargo.toml @@ -18,9 +18,6 @@ categories = ["no-std", "wasm", "cryptography::cryptocurrencies", "development-t name = "multiversx_sc_codec_derive" proc-macro = true -[features] -default = ["syn/full", "syn/parsing", "syn/extra-traits"] - [dependencies] proc-macro2 = "1.0" quote = "1.0" diff --git a/framework/derive/Cargo.toml b/framework/derive/Cargo.toml index f7a9522c83..6cf841f1ae 100644 --- a/framework/derive/Cargo.toml +++ b/framework/derive/Cargo.toml @@ -13,16 +13,16 @@ description = "MultiversX smart contract API procedural macros" keywords = ["multiversx", "blockchain", "contract"] categories = ["cryptography::cryptocurrencies", "development-tools::procedural-macro-helpers"] +[lib] +name = "multiversx_sc_derive" +proc-macro = true + +[dependencies.multiversx-sc-abi-derive-common] +version = "=0.24.0" +path = "../../data/abi-derive-common" + [dependencies] proc-macro2 = "1.0" quote = "1.0" syn = "2.0" -hex = "0.4" radix_trie = "0.3" - -[features] -default = ["syn/full", "syn/parsing", "syn/extra-traits"] - -[lib] -name = "multiversx_sc_derive" -proc-macro = true diff --git a/framework/derive/src/lib.rs b/framework/derive/src/lib.rs index a781a2556a..5b1cf2792e 100644 --- a/framework/derive/src/lib.rs +++ b/framework/derive/src/lib.rs @@ -21,7 +21,6 @@ mod managed_vec_item_derive; mod model; mod parse; mod preprocessing; -mod type_abi_derive; mod validate; #[proc_macro_attribute] @@ -54,7 +53,11 @@ pub fn proxy( )] #[proc_macro_derive(TypeAbi)] pub fn type_abi_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream { - type_abi_derive::type_abi_derive(input).into() + multiversx_sc_abi_derive_common::type_abi_derive( + input.into(), + multiversx_sc_abi_derive_common::TypeAbiImportCrate::MultiversxSc, + ) + .into() } #[proc_macro_attribute] @@ -62,8 +65,12 @@ pub fn type_abi( args: proc_macro::TokenStream, input: proc_macro::TokenStream, ) -> proc_macro::TokenStream { - assert!(args.is_empty(), "#[type_abi] attribute takes no args"); - type_abi_derive::type_abi_full(input).into() + assert!(args.is_empty(), "#[type_abi] attribute takes no arguments"); + multiversx_sc_abi_derive_common::type_abi_full( + input.into(), + multiversx_sc_abi_derive_common::TypeAbiImportCrate::MultiversxSc, + ) + .into() } #[proc_macro_derive(ManagedVecItem)] diff --git a/framework/derive/src/parse/attributes.rs b/framework/derive/src/parse/attributes.rs index 648fd30e9a..7f40ef79c0 100644 --- a/framework/derive/src/parse/attributes.rs +++ b/framework/derive/src/parse/attributes.rs @@ -1,20 +1,22 @@ mod argument_attr; mod attr_names; -mod doc_attr; mod endpoint_attr; mod event_attr; mod label_attr; +mod output_name_attr; mod payable_attr; mod storage_attr; +mod title_attr; mod trait_argument_prop; mod trait_prop_names; mod util; pub use argument_attr::*; -pub use doc_attr::{OutputNameAttribute, TitleAttribute, extract_doc, extract_macro_attributes}; pub use endpoint_attr::*; pub use event_attr::*; pub use label_attr::*; +pub use output_name_attr::OutputNameAttribute; pub use payable_attr::*; pub use storage_attr::*; +pub use title_attr::TitleAttribute; pub use trait_argument_prop::*; diff --git a/framework/derive/src/parse/attributes/doc_attr.rs b/framework/derive/src/parse/attributes/doc_attr.rs deleted file mode 100644 index f20a9eacec..0000000000 --- a/framework/derive/src/parse/attributes/doc_attr.rs +++ /dev/null @@ -1,93 +0,0 @@ -use quote::ToTokens; - -use super::{attr_names::*, util::*}; - -/// unlike the others, this is standard Rust, -/// all doc comments get automatically transformed into "doc" attributes -static ATTR_DOC: &str = "doc"; - -/// Doc comments are actually syntactic sugar for doc attributes, -/// so extracting doc comments means parsing "doc" attributes. -pub fn extract_doc(attrs: &[syn::Attribute]) -> Vec { - attrs - .iter() - .filter(|attr| { - if let Some(first_seg) = attr.path().segments.first() { - first_seg.ident == ATTR_DOC - } else { - false - } - }) - .map(|attr| match attr.meta.clone() { - syn::Meta::Path(_) => panic!("wrong format. expected name value, received path"), - syn::Meta::List(_) => panic!("wrong format. expected name value, received list"), - syn::Meta::NameValue(meta_name_value) => { - if let syn::Expr::Lit(lit_str) = meta_name_value.value { - if meta_name_value.path.is_ident("doc") { - let value = lit_str.lit; - if let Some(tuple) = value - .to_token_stream() - .to_string() - .split_once(char::is_whitespace) - { - remove_backslashes(tuple.1) - } else { - String::new() - } - } else { - panic!("Attribute doesn't have the 'doc' identifier"); - } - } else { - panic!("Value is not a string literal"); - } - } - }) - .collect() -} - -pub fn extract_macro_attributes(attrs: &[syn::Attribute]) -> Vec { - let mut macro_attributes = Vec::new(); - - for a in attrs { - if let syn::Meta::List(list) = &a.meta { - if list.path.is_ident("derive") { - for token in list.tokens.clone().into_iter() { - if let proc_macro2::TokenTree::Ident(ident) = token { - macro_attributes.push(ident.to_string()); - } - } - } - } - } - - macro_attributes -} - -fn remove_backslashes(input: &str) -> String { - input - .trim_matches('\"') - .replace("\\\"", "\"") - .replace("\\'", "'") -} - -pub struct OutputNameAttribute { - pub output_name: String, -} - -impl OutputNameAttribute { - pub fn parse(attr: &syn::Attribute) -> Option { - is_attr_one_string_arg(attr, ATTR_OUTPUT_NAME).map(|arg_str| OutputNameAttribute { - output_name: arg_str, - }) - } -} - -pub struct TitleAttribute { - pub title: String, -} - -impl TitleAttribute { - pub fn parse(attr: &syn::Attribute) -> Option { - is_attr_one_string_arg(attr, ATTR_TITLE).map(|arg_str| TitleAttribute { title: arg_str }) - } -} diff --git a/framework/derive/src/parse/attributes/output_name_attr.rs b/framework/derive/src/parse/attributes/output_name_attr.rs new file mode 100644 index 0000000000..f7bb12dc85 --- /dev/null +++ b/framework/derive/src/parse/attributes/output_name_attr.rs @@ -0,0 +1,13 @@ +use super::{attr_names::ATTR_OUTPUT_NAME, util::is_attr_one_string_arg}; + +pub struct OutputNameAttribute { + pub output_name: String, +} + +impl OutputNameAttribute { + pub fn parse(attr: &syn::Attribute) -> Option { + is_attr_one_string_arg(attr, ATTR_OUTPUT_NAME).map(|arg_str| OutputNameAttribute { + output_name: arg_str, + }) + } +} diff --git a/framework/derive/src/parse/attributes/title_attr.rs b/framework/derive/src/parse/attributes/title_attr.rs new file mode 100644 index 0000000000..741a9047cc --- /dev/null +++ b/framework/derive/src/parse/attributes/title_attr.rs @@ -0,0 +1,11 @@ +use super::{attr_names::ATTR_TITLE, util::is_attr_one_string_arg}; + +pub struct TitleAttribute { + pub title: String, +} + +impl TitleAttribute { + pub fn parse(attr: &syn::Attribute) -> Option { + is_attr_one_string_arg(attr, ATTR_TITLE).map(|arg_str| TitleAttribute { title: arg_str }) + } +} diff --git a/framework/derive/src/parse/contract_trait_parse.rs b/framework/derive/src/parse/contract_trait_parse.rs index 2600b21fb4..2965a60c90 100644 --- a/framework/derive/src/parse/contract_trait_parse.rs +++ b/framework/derive/src/parse/contract_trait_parse.rs @@ -1,5 +1,7 @@ +use multiversx_sc_abi_derive_common::parse::attributes::extract_doc; + use super::{ - attributes::extract_doc, method_parse::process_method, parse_util::validate_attribute_args, + method_parse::process_method, parse_util::validate_attribute_args, supertrait_parse::parse_supertrait, }; use crate::{ diff --git a/framework/derive/src/parse/method_parse.rs b/framework/derive/src/parse/method_parse.rs index 1d49f03dde..c4e3b75aac 100644 --- a/framework/derive/src/parse/method_parse.rs +++ b/framework/derive/src/parse/method_parse.rs @@ -1,7 +1,8 @@ +use multiversx_sc_abi_derive_common::parse::attributes::extract_doc; + use crate::model::{Method, MethodImpl, MethodPayableMetadata, PublicRole, TraitProperties}; use super::{ - attributes::extract_doc, auto_impl_parse::{ process_event_attribute, process_proxy_attribute, process_storage_clear_attribute, process_storage_get_attribute, process_storage_is_empty_attribute, diff --git a/framework/derive/src/type_abi_derive.rs b/framework/derive/src/type_abi_derive.rs deleted file mode 100644 index 34385cc649..0000000000 --- a/framework/derive/src/type_abi_derive.rs +++ /dev/null @@ -1,215 +0,0 @@ -use crate::parse::attributes::extract_macro_attributes; - -use super::parse::attributes::extract_doc; -use quote::{ToTokens, quote}; - -const BITFLAGS_PATH: &str = ":: __private :: PublicFlags :: Internal"; -const BITFLAGS_PRIMITIVE: &str = "Primitive"; -pub struct ExplicitDiscriminant { - pub variant_index: usize, - pub value: usize, -} - -fn field_snippet(index: usize, field: &syn::Field) -> proc_macro2::TokenStream { - let field_docs = extract_doc(field.attrs.as_slice()); - let field_name_str = if let Some(ident) = &field.ident { - ident.to_string() - } else { - index.to_string() - }; - let field_ty = sanitize_field_type_path(&field.ty); - quote! { - field_descriptions.push(multiversx_sc::abi::StructFieldDescription::new( - &[ #(#field_docs),* ], - #field_name_str, - <#field_ty>::type_names(), - )); - <#field_ty>::provide_type_descriptions(accumulator); - } -} - -fn sanitize_field_type_path(field_type: &syn::Type) -> syn::Type { - if let syn::Type::Path(p) = field_type { - let mut path = p.path.clone(); - - if path.to_token_stream().to_string().contains(BITFLAGS_PATH) { - let modified_path = path.segments.last_mut().unwrap(); - modified_path.ident = syn::Ident::new(BITFLAGS_PRIMITIVE, modified_path.ident.span()); - - return syn::Type::Path(syn::TypePath { - qself: p.qself.clone(), - path, - }); - } - } - - field_type.clone() -} - -fn fields_snippets(fields: &syn::Fields) -> Vec { - match fields { - syn::Fields::Named(fields_named) => fields_named - .named - .iter() - .enumerate() - .map(|(index, field)| field_snippet(index, field)) - .collect(), - syn::Fields::Unnamed(fields_unnamed) => fields_unnamed - .unnamed - .iter() - .enumerate() - .map(|(index, field)| field_snippet(index, field)) - .collect(), - syn::Fields::Unit => Vec::new(), - } -} - -pub fn type_abi_derive(input: proc_macro::TokenStream) -> proc_macro2::TokenStream { - let ast: syn::DeriveInput = syn::parse(input).unwrap(); - let name = &ast.ident; - let name_str = name.to_string(); - let type_docs = extract_doc(ast.attrs.as_slice()); - let macro_attributes = extract_macro_attributes(ast.attrs.as_slice()); - if macro_attributes.is_empty() { - println!( - "Warning! {name_str} #[type_abi] implementation sees no derive traits. Make sure that the derive attribute comes after #[type_abi]" - ); - } - - let type_description_impl = match &ast.data { - syn::Data::Struct(data_struct) => { - let struct_field_snippets = fields_snippets(&data_struct.fields); - quote! { - fn provide_type_descriptions(accumulator: &mut TDC) { - let type_names = Self::type_names(); - if !accumulator.contains_type(&type_names.abi) { - accumulator.reserve_type_name(type_names.clone()); - let mut field_descriptions = multiversx_sc::types::heap::Vec::new(); - #(#struct_field_snippets)* - accumulator.insert( - type_names.clone(), - multiversx_sc::abi::TypeDescription::new( - &[ #(#type_docs),* ], - type_names, - multiversx_sc::abi::TypeContents::Struct(field_descriptions), - &[ #(#macro_attributes),* ], - ), - ); - } - } - } - } - syn::Data::Enum(data_enum) => { - let mut previous_disc: Vec = Vec::new(); - let enum_variant_snippets: Vec = data_enum - .variants - .iter() - .enumerate() - .map(|(variant_index, variant)| { - let variant_docs = extract_doc(variant.attrs.as_slice()); - let variant_name_str = variant.ident.to_string(); - let variant_field_snippets = fields_snippets(&variant.fields); - let variant_discriminant = - get_discriminant(variant_index, variant, &mut previous_disc); - quote! { - let mut field_descriptions = multiversx_sc::types::heap::Vec::new(); - #(#variant_field_snippets)* - variant_descriptions.push(multiversx_sc::abi::EnumVariantDescription::new( - &[ #(#variant_docs),* ], - #variant_name_str, - #variant_discriminant, - field_descriptions, - )); - } - }) - .collect(); - quote! { - fn provide_type_descriptions(accumulator: &mut TDC) { - let type_names = Self::type_names(); - if !accumulator.contains_type(&type_names.abi) { - accumulator.reserve_type_name(type_names.clone()); - let mut variant_descriptions = multiversx_sc::types::heap::Vec::new(); - #(#enum_variant_snippets)* - accumulator.insert( - type_names.clone(), - multiversx_sc::abi::TypeDescription::new( - &[ #(#type_docs),* ], - type_names, - multiversx_sc::abi::TypeContents::Enum(variant_descriptions), - &[ #(#macro_attributes),* ], - ), - ); - } - } - } - } - syn::Data::Union(_) => panic!("Union not supported!"), - }; - - let (impl_generics, ty_generics, where_clause) = &ast.generics.split_for_impl(); - quote! { - impl #impl_generics multiversx_sc::abi::TypeAbiFrom for #name #ty_generics #where_clause {} - impl #impl_generics multiversx_sc::abi::TypeAbiFrom<&Self> for #name #ty_generics #where_clause {} - - impl #impl_generics multiversx_sc::abi::TypeAbi for #name #ty_generics #where_clause { - type Unmanaged = Self; - - fn type_name() -> multiversx_sc::abi::TypeName { - #name_str.into() - } - #type_description_impl - } - } -} - -pub fn type_abi_full(input: proc_macro::TokenStream) -> proc_macro2::TokenStream { - let input_conv = proc_macro2::TokenStream::from(input.clone()); - let derive_code = type_abi_derive(input); - quote! { - #input_conv - #derive_code - } -} - -pub fn get_discriminant( - variant_index: usize, - variant: &syn::Variant, - previous_disc: &mut Vec, -) -> proc_macro2::TokenStream { - // if it has explicit discriminant - if let Some((_, syn::Expr::Lit(expr))) = &variant.discriminant { - let lit = match &expr.lit { - syn::Lit::Int(val) => { - let value = val.base10_parse().unwrap_or_else(|_| { - panic!("Can not unwrap int value from explicit discriminant") - }); - previous_disc.push(ExplicitDiscriminant { - variant_index, - value, - }); - value - } - _ => panic!("Only integer values as discriminants"), // theoretically covered by the compiler - }; - return quote! { #lit}; - } - - // if no explicit discriminant, check previous discriminants - // get previous explicit + 1 if there has been any explicit before - let next_value = match previous_disc.last() { - // there are previous explicit discriminants - Some(ExplicitDiscriminant { - variant_index: prev_index, - value: prev_value, - }) if *prev_index < variant_index - 1 => prev_value + variant_index - prev_index, - Some(ExplicitDiscriminant { - variant_index: _, - value: prev_value, - }) => prev_value + 1, - - // vec is empty, return index - None => variant_index, - }; - - quote! { #next_value} -} From 709774b536c2cf074ceb3bf3b2afe3044b6eb2cb Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Fri, 20 Feb 2026 12:41:31 +0200 Subject: [PATCH 04/11] derive crate fix --- framework/derive/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/derive/Cargo.toml b/framework/derive/Cargo.toml index 6cf841f1ae..f9d9dac485 100644 --- a/framework/derive/Cargo.toml +++ b/framework/derive/Cargo.toml @@ -24,5 +24,5 @@ path = "../../data/abi-derive-common" [dependencies] proc-macro2 = "1.0" quote = "1.0" -syn = "2.0" +syn = { version = "2.0", features = ["extra-traits"] } radix_trie = "0.3" From 8c87364a61e5c3140c8f677a4672624ba0e80d2d Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Fri, 20 Feb 2026 12:43:35 +0200 Subject: [PATCH 05/11] abi crate in abi build info --- .../abi_tester_expected_main.abi.json | 4 +++ .../abi_tester_expected_view.abi.json | 4 +++ .../use_module_expected_main.abi.json | 4 +++ .../use_module_expected_view.abi.json | 4 +++ data/abi/src/contract_abi/build_info_abi.rs | 36 +++++++++++++++---- framework/base/src/lib.rs | 8 +++++ framework/derive/src/generate/abi_gen.rs | 3 +- .../src/abi_json/build_info_abi_json.rs | 3 ++ .../generate_proxy/proxy_generator.rs | 24 ++----------- .../scenario/tests/contract_without_macros.rs | 8 +---- 10 files changed, 63 insertions(+), 35 deletions(-) diff --git a/contracts/feature-tests/abi-tester/abi_tester_expected_main.abi.json b/contracts/feature-tests/abi-tester/abi_tester_expected_main.abi.json index b94c022313..94c552582e 100644 --- a/contracts/feature-tests/abi-tester/abi_tester_expected_main.abi.json +++ b/contracts/feature-tests/abi-tester/abi_tester_expected_main.abi.json @@ -14,6 +14,10 @@ "version": "0.0.0", "gitVersion": "" }, + "abi": { + "name": "multiversx-sc-abi", + "version": "0.24.0" + }, "framework": { "name": "multiversx-sc", "version": "0.64.1" diff --git a/contracts/feature-tests/abi-tester/abi_tester_expected_view.abi.json b/contracts/feature-tests/abi-tester/abi_tester_expected_view.abi.json index 63504fe359..f6680e75a0 100644 --- a/contracts/feature-tests/abi-tester/abi_tester_expected_view.abi.json +++ b/contracts/feature-tests/abi-tester/abi_tester_expected_view.abi.json @@ -14,6 +14,10 @@ "version": "0.0.0", "gitVersion": "" }, + "abi": { + "name": "multiversx-sc-abi", + "version": "0.24.0" + }, "framework": { "name": "multiversx-sc", "version": "0.64.1" diff --git a/contracts/feature-tests/use-module/use_module_expected_main.abi.json b/contracts/feature-tests/use-module/use_module_expected_main.abi.json index 63b298ce5a..76a294aa3f 100644 --- a/contracts/feature-tests/use-module/use_module_expected_main.abi.json +++ b/contracts/feature-tests/use-module/use_module_expected_main.abi.json @@ -14,6 +14,10 @@ "version": "0.0.0", "gitVersion": "" }, + "abi": { + "name": "multiversx-sc-abi", + "version": "0.24.0" + }, "framework": { "name": "multiversx-sc", "version": "0.64.1" diff --git a/contracts/feature-tests/use-module/use_module_expected_view.abi.json b/contracts/feature-tests/use-module/use_module_expected_view.abi.json index b2f50b6110..04e1179d68 100644 --- a/contracts/feature-tests/use-module/use_module_expected_view.abi.json +++ b/contracts/feature-tests/use-module/use_module_expected_view.abi.json @@ -14,6 +14,10 @@ "version": "0.0.0", "gitVersion": "" }, + "abi": { + "name": "multiversx-sc-abi", + "version": "0.24.0" + }, "framework": { "name": "multiversx-sc", "version": "0.64.1" diff --git a/data/abi/src/contract_abi/build_info_abi.rs b/data/abi/src/contract_abi/build_info_abi.rs index 613afd28a1..51d08bf601 100644 --- a/data/abi/src/contract_abi/build_info_abi.rs +++ b/data/abi/src/contract_abi/build_info_abi.rs @@ -7,9 +7,25 @@ use alloc::{borrow::ToOwned, string::String}; pub struct BuildInfoAbi { pub rustc: Option, pub contract_crate: ContractCrateBuildAbi, + pub abi: FrameworkBuildAbi, pub framework: FrameworkBuildAbi, } +impl BuildInfoAbi { + pub fn dummy() -> Self { + BuildInfoAbi { + rustc: None, + contract_crate: ContractCrateBuildAbi { + name: "contract-crate".to_owned(), + version: "0.0.0".to_owned(), + git_version: "0.0.0".to_owned(), + }, + abi: FrameworkBuildAbi::new("abi-crate", "0.0.0"), + framework: FrameworkBuildAbi::new("framework-crate", "0.0.0"), + } + } +} + #[derive(Clone, Default, Debug)] pub struct RustcAbi { pub version: String, @@ -51,13 +67,21 @@ pub struct FrameworkBuildAbi { } impl FrameworkBuildAbi { - /// Called from the ABI generator in every contract. - /// - /// Note: the values are extracted here, this makes them capture the framework crate info. - pub fn create() -> Self { + pub fn new(name: &str, version: &str) -> Self { FrameworkBuildAbi { - name: env!("CARGO_PKG_NAME").to_owned(), - version: env!("CARGO_PKG_VERSION").to_owned(), + name: name.to_owned(), + version: version.to_owned(), } } + + /// Called from the ABI generator in every contract. + /// + /// Contains the ABI crate name and current version. + pub fn abi_crate() -> Self { + FrameworkBuildAbi::new(env!("CARGO_PKG_NAME"), env!("CARGO_PKG_VERSION")) + } + + pub fn dummy() -> Self { + FrameworkBuildAbi::new("", "") + } } diff --git a/framework/base/src/lib.rs b/framework/base/src/lib.rs index f4cb65c106..15fdbffda4 100644 --- a/framework/base/src/lib.rs +++ b/framework/base/src/lib.rs @@ -20,6 +20,14 @@ pub use generic_array::typenum; // TEMP: should adjust imports. pub use multiversx_sc_abi as abi; +/// Must be called from here, to capture the framework crate info, and not the abi crate info. +pub fn framework_build_abi() -> abi::FrameworkBuildAbi { + abi::FrameworkBuildAbi::new( + env!("CARGO_PKG_NAME"), + env!("CARGO_PKG_VERSION"), + ) +} + pub mod api; pub mod contract_base; pub mod err_msg; diff --git a/framework/derive/src/generate/abi_gen.rs b/framework/derive/src/generate/abi_gen.rs index b679c7da95..626b7a9f5c 100644 --- a/framework/derive/src/generate/abi_gen.rs +++ b/framework/derive/src/generate/abi_gen.rs @@ -276,7 +276,8 @@ fn generate_abi_method_body( env!("CARGO_PKG_NAME"), env!("CARGO_PKG_VERSION"), ), - framework: multiversx_sc::abi::FrameworkBuildAbi::create(), + abi: multiversx_sc::abi::FrameworkBuildAbi::abi_crate(), + framework: multiversx_sc::framework_build_abi(), }, &[ #(#contract_docs),* ], #contract_name, diff --git a/framework/meta-lib/src/abi_json/build_info_abi_json.rs b/framework/meta-lib/src/abi_json/build_info_abi_json.rs index e9603f63b0..0166391298 100644 --- a/framework/meta-lib/src/abi_json/build_info_abi_json.rs +++ b/framework/meta-lib/src/abi_json/build_info_abi_json.rs @@ -8,6 +8,7 @@ pub struct BuildInfoAbiJson { #[serde(skip_serializing_if = "Option::is_none")] pub rustc: Option, pub contract_crate: ContractCrateBuildAbiJson, + pub abi: FrameworkBuildAbiJson, pub framework: FrameworkBuildAbiJson, } @@ -16,6 +17,7 @@ impl From<&BuildInfoAbi> for BuildInfoAbiJson { BuildInfoAbiJson { rustc: abi.rustc.as_ref().map(RustcAbiJson::from), contract_crate: ContractCrateBuildAbiJson::from(&abi.contract_crate), + abi: FrameworkBuildAbiJson::from(&abi.abi), framework: FrameworkBuildAbiJson::from(&abi.framework), } } @@ -26,6 +28,7 @@ impl From<&BuildInfoAbiJson> for BuildInfoAbi { BuildInfoAbi { rustc: abi_json.rustc.as_ref().map(RustcAbi::from), contract_crate: ContractCrateBuildAbi::from(&abi_json.contract_crate), + abi: FrameworkBuildAbi::from(&abi_json.abi), framework: FrameworkBuildAbi::from(&abi_json.framework), } } diff --git a/framework/meta-lib/src/contract/generate_proxy/proxy_generator.rs b/framework/meta-lib/src/contract/generate_proxy/proxy_generator.rs index d7d2cc99df..95eea37984 100644 --- a/framework/meta-lib/src/contract/generate_proxy/proxy_generator.rs +++ b/framework/meta-lib/src/contract/generate_proxy/proxy_generator.rs @@ -665,7 +665,7 @@ where #[cfg(test)] pub mod tests { - use multiversx_sc::abi::{BuildInfoAbi, ContractAbi, ContractCrateBuildAbi, FrameworkBuildAbi}; + use multiversx_sc::abi::{BuildInfoAbi, ContractAbi}; use crate::contract::{meta_config::MetaConfig, sc_config::proxy_config::ProxyConfig}; @@ -673,16 +673,7 @@ pub mod tests { #[test] fn clean_paths_unsanitized_test() { - let build_info = BuildInfoAbi { - rustc: None, - contract_crate: ContractCrateBuildAbi { - name: "contract-crate".to_owned(), - version: "0.0.0".to_owned(), - git_version: "0.0.0".to_owned(), - }, - framework: FrameworkBuildAbi::create(), - }; - + let build_info = BuildInfoAbi::dummy(); let original_contract_abi = ContractAbi::new(build_info, &[""], "contract-crate", false); let meta_config = MetaConfig::create(original_contract_abi.clone(), false); let mut proxy_generator = ProxyGenerator { @@ -705,16 +696,7 @@ pub mod tests { #[test] fn clean_paths_sanitized_test() { - let build_info = BuildInfoAbi { - rustc: None, - contract_crate: ContractCrateBuildAbi { - name: "contract-crate".to_owned(), - version: "0.0.0".to_owned(), - git_version: "0.0.0".to_owned(), - }, - framework: FrameworkBuildAbi::create(), - }; - + let build_info = BuildInfoAbi::dummy(); let original_contract_abi = ContractAbi::new(build_info, &[""], "contract-crate", false); let meta_config = MetaConfig::create(original_contract_abi.clone(), false); let mut proxy_generator = ProxyGenerator { diff --git a/framework/scenario/tests/contract_without_macros.rs b/framework/scenario/tests/contract_without_macros.rs index 9e396dc834..32590e2bd2 100644 --- a/framework/scenario/tests/contract_without_macros.rs +++ b/framework/scenario/tests/contract_without_macros.rs @@ -398,13 +398,7 @@ mod sample_adder { type Api = multiversx_sc::api::uncallable::UncallableApi; fn abi() -> multiversx_sc::abi::ContractAbi { let mut contract_abi = multiversx_sc::abi::ContractAbi::new( - multiversx_sc::abi::BuildInfoAbi { - rustc: None, - contract_crate: multiversx_sc::abi::ContractCrateBuildAbi::new( - "adder", "0.0.0", - ), - framework: multiversx_sc::abi::FrameworkBuildAbi::create(), - }, + multiversx_sc::abi::BuildInfoAbi::dummy(), &[ "One of the simplest smart contracts possible,", "it holds a single variable in storage, which anyone can increment.", From 3c2cc4725b3d117bf91244887b7414c45bd755c2 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Fri, 20 Feb 2026 12:44:52 +0200 Subject: [PATCH 06/11] fmt --- framework/base/src/lib.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/framework/base/src/lib.rs b/framework/base/src/lib.rs index 15fdbffda4..5a424edeab 100644 --- a/framework/base/src/lib.rs +++ b/framework/base/src/lib.rs @@ -22,10 +22,7 @@ pub use multiversx_sc_abi as abi; /// Must be called from here, to capture the framework crate info, and not the abi crate info. pub fn framework_build_abi() -> abi::FrameworkBuildAbi { - abi::FrameworkBuildAbi::new( - env!("CARGO_PKG_NAME"), - env!("CARGO_PKG_VERSION"), - ) + abi::FrameworkBuildAbi::new(env!("CARGO_PKG_NAME"), env!("CARGO_PKG_VERSION")) } pub mod api; From 572ba0907c82332128a7a2c6af5e45ea87619541 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Fri, 20 Feb 2026 15:48:31 +0200 Subject: [PATCH 07/11] abi build info backwards compatibility --- .../scenarios/test.scen.json | 4 ++-- data/abi/src/contract_abi/build_info_abi.rs | 4 ++-- framework/derive/src/generate/abi_gen.rs | 2 +- framework/meta-lib/src/abi_json/build_info_abi_json.rs | 8 +++++--- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/contracts/feature-tests/rust-testing-framework-tester/scenarios/test.scen.json b/contracts/feature-tests/rust-testing-framework-tester/scenarios/test.scen.json index d92783c9a0..faa31a4bf3 100644 --- a/contracts/feature-tests/rust-testing-framework-tester/scenarios/test.scen.json +++ b/contracts/feature-tests/rust-testing-framework-tester/scenarios/test.scen.json @@ -50,7 +50,7 @@ }, { "step": "scCall", - "id": "0", + "txId": "0", "tx": { "from": "0x66687aadf862bd776c8fc18b8e9f8e20089714856ee233b3902a591d0d5f2925", "to": "0x0000000000000000fb1397e8225ea85e0f0e6e8c7b126d0016ccbde0e667151e", @@ -85,7 +85,7 @@ }, { "step": "scQuery", - "id": "1", + "txId": "1", "tx": { "to": "0x0000000000000000fb1397e8225ea85e0f0e6e8c7b126d0016ccbde0e667151e", "function": "getTotalValue", diff --git a/data/abi/src/contract_abi/build_info_abi.rs b/data/abi/src/contract_abi/build_info_abi.rs index 51d08bf601..6cdb32f005 100644 --- a/data/abi/src/contract_abi/build_info_abi.rs +++ b/data/abi/src/contract_abi/build_info_abi.rs @@ -7,7 +7,7 @@ use alloc::{borrow::ToOwned, string::String}; pub struct BuildInfoAbi { pub rustc: Option, pub contract_crate: ContractCrateBuildAbi, - pub abi: FrameworkBuildAbi, + pub abi: Option, pub framework: FrameworkBuildAbi, } @@ -20,7 +20,7 @@ impl BuildInfoAbi { version: "0.0.0".to_owned(), git_version: "0.0.0".to_owned(), }, - abi: FrameworkBuildAbi::new("abi-crate", "0.0.0"), + abi: Some(FrameworkBuildAbi::new("abi-crate", "0.0.0")), framework: FrameworkBuildAbi::new("framework-crate", "0.0.0"), } } diff --git a/framework/derive/src/generate/abi_gen.rs b/framework/derive/src/generate/abi_gen.rs index 626b7a9f5c..30894bcabe 100644 --- a/framework/derive/src/generate/abi_gen.rs +++ b/framework/derive/src/generate/abi_gen.rs @@ -276,7 +276,7 @@ fn generate_abi_method_body( env!("CARGO_PKG_NAME"), env!("CARGO_PKG_VERSION"), ), - abi: multiversx_sc::abi::FrameworkBuildAbi::abi_crate(), + abi: Some(multiversx_sc::abi::FrameworkBuildAbi::abi_crate()), framework: multiversx_sc::framework_build_abi(), }, &[ #(#contract_docs),* ], diff --git a/framework/meta-lib/src/abi_json/build_info_abi_json.rs b/framework/meta-lib/src/abi_json/build_info_abi_json.rs index 0166391298..0c896c6a12 100644 --- a/framework/meta-lib/src/abi_json/build_info_abi_json.rs +++ b/framework/meta-lib/src/abi_json/build_info_abi_json.rs @@ -8,7 +8,9 @@ pub struct BuildInfoAbiJson { #[serde(skip_serializing_if = "Option::is_none")] pub rustc: Option, pub contract_crate: ContractCrateBuildAbiJson, - pub abi: FrameworkBuildAbiJson, + #[serde(default)] + #[serde(skip_serializing_if = "Option::is_none")] + pub abi: Option, pub framework: FrameworkBuildAbiJson, } @@ -17,7 +19,7 @@ impl From<&BuildInfoAbi> for BuildInfoAbiJson { BuildInfoAbiJson { rustc: abi.rustc.as_ref().map(RustcAbiJson::from), contract_crate: ContractCrateBuildAbiJson::from(&abi.contract_crate), - abi: FrameworkBuildAbiJson::from(&abi.abi), + abi: abi.abi.as_ref().map(FrameworkBuildAbiJson::from), framework: FrameworkBuildAbiJson::from(&abi.framework), } } @@ -28,7 +30,7 @@ impl From<&BuildInfoAbiJson> for BuildInfoAbi { BuildInfoAbi { rustc: abi_json.rustc.as_ref().map(RustcAbi::from), contract_crate: ContractCrateBuildAbi::from(&abi_json.contract_crate), - abi: FrameworkBuildAbi::from(&abi_json.abi), + abi: abi_json.abi.as_ref().map(FrameworkBuildAbi::from), framework: FrameworkBuildAbi::from(&abi_json.framework), } } From d8affebb84f38341dc1d04c3cc57a6c9e1f7c735 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Fri, 20 Feb 2026 16:28:25 +0200 Subject: [PATCH 08/11] abi crate build fix --- data/abi/src/lib.rs | 2 ++ framework/derive/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/data/abi/src/lib.rs b/data/abi/src/lib.rs index 93691c4609..0f0b7b3c78 100644 --- a/data/abi/src/lib.rs +++ b/data/abi/src/lib.rs @@ -1,3 +1,5 @@ +#![no_std] + // re-export basic heap types extern crate alloc; diff --git a/framework/derive/Cargo.toml b/framework/derive/Cargo.toml index f9d9dac485..2594223a27 100644 --- a/framework/derive/Cargo.toml +++ b/framework/derive/Cargo.toml @@ -24,5 +24,5 @@ path = "../../data/abi-derive-common" [dependencies] proc-macro2 = "1.0" quote = "1.0" -syn = { version = "2.0", features = ["extra-traits"] } +syn = { version = "2.0", features = ["full", "extra-traits"] } radix_trie = "0.3" From 74f912d7c5aa25cbcf85273146af0d4de949f0c6 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Mon, 23 Feb 2026 14:42:37 +0200 Subject: [PATCH 09/11] cleanup --- data/abi/Cargo.toml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/data/abi/Cargo.toml b/data/abi/Cargo.toml index f141e56bef..aa2b108e6c 100644 --- a/data/abi/Cargo.toml +++ b/data/abi/Cargo.toml @@ -34,7 +34,3 @@ version = "0.24.0" num-bigint = { version = "0.4", optional = true } # can only be used in std contexts unwrap-infallible = "1.0" bitflags = "2.9" - -# [dev-dependencies.multiversx-sc-codec-derive] -# path = "../codec-derive" -# version = "=0.24.0" From df6c939312428123d7b6e3ec70b6829d46815d68 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Tue, 3 Mar 2026 11:22:14 +0200 Subject: [PATCH 10/11] syn dependency fix --- data/abi-derive-common/Cargo.toml | 2 +- data/codec-derive/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/data/abi-derive-common/Cargo.toml b/data/abi-derive-common/Cargo.toml index 01a16cb5e2..d6cd9af725 100644 --- a/data/abi-derive-common/Cargo.toml +++ b/data/abi-derive-common/Cargo.toml @@ -25,4 +25,4 @@ categories = [ [dependencies] proc-macro2 = "1.0" quote = "1.0" -syn = "2.0" +syn = { version = "2.0", features = ["full", "extra-traits"] } diff --git a/data/codec-derive/Cargo.toml b/data/codec-derive/Cargo.toml index 5b86d5d50b..abd660ed75 100644 --- a/data/codec-derive/Cargo.toml +++ b/data/codec-derive/Cargo.toml @@ -21,5 +21,5 @@ proc-macro = true [dependencies] proc-macro2 = "1.0" quote = "1.0" -syn = "2.0" +syn = { version = "2.0", features = ["full", "extra-traits"] } hex = "0.4" From a610bc8250b7c35dca009e379244e3822e59bc66 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Tue, 3 Mar 2026 11:23:00 +0200 Subject: [PATCH 11/11] crate description fix --- data/abi/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/abi/Cargo.toml b/data/abi/Cargo.toml index aa2b108e6c..dafa2b0323 100644 --- a/data/abi/Cargo.toml +++ b/data/abi/Cargo.toml @@ -13,7 +13,7 @@ readme = "README.md" repository = "https://github.com/multiversx/mx-sdk-rs" homepage = "https://multiversx.com/" documentation = "https://docs.multiversx.com/" -description = "Lightweight binary serializer/deserializer, written especially for MultiversX smart contracts" +description = "ABI type definitions and metadata for MultiversX smart contracts" keywords = ["multiversx", "wasm", "webassembly", "blockchain", "contract"] categories = [ "no-std",