diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml deleted file mode 100644 index 825c1c7..0000000 --- a/.github/workflows/release.yaml +++ /dev/null @@ -1,14 +0,0 @@ -name: release -on: - push: - branches: - - nothing - -jobs: - release: - runs-on: ubuntu-latest - steps: - - run: echo "implement this" - -# TODO: To add more, supposingly CI should run build, and CD(this ci) should run release. -# Ideally we should have a comprehensive CD to push to crates.io \ No newline at end of file diff --git a/.github/workflows/sync-changes-to-release-branch.yaml b/.github/workflows/sync-changes-to-release-branch.yaml deleted file mode 100644 index 602f6e7..0000000 --- a/.github/workflows/sync-changes-to-release-branch.yaml +++ /dev/null @@ -1,67 +0,0 @@ -name: Sync changes to release branches -on: - push: - branches: - - main - -permissions: - contents: write - -# Syncing branches are currently the solution as long as -# we have multiple binaries version based on Cairo. -# As we move away from that this should be migrated to a normal rust -# release flow. -jobs: - sync-branches: - # strategy: - # matrix: - # supported-version: - # [ - # "1.1.0", - # "1.1.1", - # "2.0.1", - # "2.0.2", - # "2.1.0", - # "2.1.1", - # "2.2.0", - # "2.3.0", - # "2.3.1", - # "2.4.0", - # "2.4.1", - # "2.4.2", - # "2.4.3", - # "2.4.4", - # "2.5.0", - # "2.5.1", - # "2.5.2", - # "2.5.3", - # "2.5.4", - # "2.6.0", - # "2.6.1", - # "2.6.2", - # "2.6.3", - # ] - runs-on: ubuntu-latest - steps: - # Do nothing for now since the newest changes include version updates. - - name: Do nothing - run: echo nothing - # - name: Checkout - # uses: actions/checkout@v4 - # with: - # fetch-depth: 0 - - # # This user can be anything using any email, just for git to work as expected. - # - name: setup git configs - # run: | - # git config user.name "cwkang1998 (Github Action)" - # git config user.email "23054115+cwkang1998@users.noreply.github.com" - - # - name: update all release branches - # run: | - # git checkout main - # git fetch origin - # git checkout release/${{ matrix.supported-version }} - # git pull - # git merge origin/main - # git push origin release/${{ matrix.supported-version }} diff --git a/.tool-versions b/.tool-versions deleted file mode 100644 index ff54753..0000000 --- a/.tool-versions +++ /dev/null @@ -1 +0,0 @@ -scarb 2.8.4 diff --git a/Cargo.lock b/Cargo.lock index e763568..c6f7722 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,30 +17,6 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" -[[package]] -name = "aes" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" -dependencies = [ - "cfg-if", - "cipher", - "cpufeatures", -] - -[[package]] -name = "ahash" -version = "0.8.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" -dependencies = [ - "cfg-if", - "getrandom", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "aho-corasick" version = "1.1.3" @@ -50,42 +26,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "alloc-no-stdlib" -version = "2.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" - -[[package]] -name = "alloc-stdlib" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" -dependencies = [ - "alloc-no-stdlib", -] - -[[package]] -name = "allocator-api2" -version = "0.2.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" - -[[package]] -name = "android-tzdata" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" - -[[package]] -name = "android_system_properties" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" -dependencies = [ - "libc", -] - [[package]] name = "anstream" version = "0.6.18" @@ -137,6071 +77,1254 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.93" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775" +checksum = "c1fd03a028ef38ba2276dce7e33fcd6369c158a1bca17946c4b1b701891c1ff7" [[package]] -name = "arc-swap" -version = "1.7.1" +name = "autocfg" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] -name = "ark-ff" -version = "0.4.2" +name = "backon" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" +checksum = "ba5289ec98f68f28dd809fd601059e6aa908bb8f6108620930828283d4ee23d7" dependencies = [ - "ark-ff-asm", - "ark-ff-macros", - "ark-serialize", - "ark-std", - "derivative", - "digest", - "itertools 0.10.5", - "num-bigint", - "num-traits", - "paste", - "rustc_version", - "zeroize", + "fastrand", ] [[package]] -name = "ark-ff-asm" -version = "0.4.2" +name = "backtrace" +version = "0.3.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" dependencies = [ - "quote", - "syn 1.0.109", + "addr2line", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", + "windows-targets 0.52.6", ] [[package]] -name = "ark-ff-macros" -version = "0.4.2" +name = "base64" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" -dependencies = [ - "num-bigint", - "num-traits", - "proc-macro2", - "quote", - "syn 1.0.109", -] +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] -name = "ark-serialize" -version = "0.4.2" +name = "bitflags" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" -dependencies = [ - "ark-std", - "digest", - "num-bigint", -] +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] -name = "ark-std" -version = "0.4.0" +name = "bitflags" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" -dependencies = [ - "num-traits", - "rand", -] +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] -name = "arrayvec" -version = "0.7.6" +name = "bumpalo" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] -name = "ascii-canvas" -version = "3.0.0" +name = "bytes" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8824ecca2e851cec16968d54a01dd372ef8f95b244fb84b84e70128be347c3c6" -dependencies = [ - "term", -] +checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b" [[package]] -name = "assert_matches" -version = "1.5.0" +name = "camino" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" +checksum = "8b96ec4966b5813e2c0507c1f86115c8c5abaadc3980879c3424042a02fd1ad3" +dependencies = [ + "serde", +] [[package]] -name = "async-compression" -version = "0.4.17" +name = "cc" +version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cb8f1d480b0ea3783ab015936d2a55c87e219676f0c0b7dec61494043f21857" +checksum = "27f657647bcff5394bf56c7317665bbf790a137a50eaaa5c6bfbb9e27a518f2d" dependencies = [ - "brotli", - "flate2", - "futures-core", - "memchr", - "pin-project-lite", - "tokio", + "shlex", ] [[package]] -name = "async-trait" -version = "0.1.83" +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "clap" +version = "4.5.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" +checksum = "3135e7ec2ef7b10c6ed8950f0f792ed96ee093fa088608f1c76e569722700c84" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.87", + "clap_builder", + "clap_derive", ] [[package]] -name = "atty" -version = "0.2.14" +name = "clap_builder" +version = "4.5.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +checksum = "30582fc632330df2bd26877bde0c1f4470d57c582bbc070376afcd04d8cb4838" dependencies = [ - "hermit-abi 0.1.19", - "libc", - "winapi", + "anstream", + "anstyle", + "clap_lex", + "strsim", + "unicase", + "unicode-width", ] [[package]] -name = "auto_impl" -version = "1.2.0" +name = "clap_derive" +version = "4.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" +checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" dependencies = [ + "heck", "proc-macro2", "quote", - "syn 2.0.87", + "syn", ] [[package]] -name = "autocfg" -version = "1.4.0" +name = "clap_lex" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" [[package]] -name = "backtrace" -version = "0.3.74" +name = "colorchoice" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" dependencies = [ - "addr2line", - "cfg-if", + "core-foundation-sys", "libc", - "miniz_oxide", - "object", - "rustc-demangle", - "windows-targets 0.52.6", ] [[package]] -name = "base64" -version = "0.13.1" +name = "core-foundation-sys" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] -name = "base64" -version = "0.21.7" +name = "displaydoc" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] [[package]] -name = "bigdecimal" -version = "0.3.1" +name = "either" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6773ddc0eafc0e509fb60e48dff7f450f8e674a0686ae8605e8d9901bd5eefa" -dependencies = [ - "num-bigint", - "num-integer", - "num-traits", - "serde", -] +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] -name = "bit-set" -version = "0.5.3" +name = "encoding_rs" +version = "0.8.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" dependencies = [ - "bit-vec", + "cfg-if", ] [[package]] -name = "bit-vec" -version = "0.6.3" +name = "equivalent" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] -name = "bitflags" -version = "1.3.2" +name = "errno" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" +dependencies = [ + "libc", + "windows-sys 0.59.0", +] [[package]] -name = "bitflags" -version = "2.6.0" +name = "fastrand" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" [[package]] -name = "bitvec" -version = "1.0.1" +name = "fnv" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" -dependencies = [ - "funty", - "radium", - "tap", - "wyz", -] +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] -name = "block-buffer" -version = "0.10.4" +name = "foreign-types" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" dependencies = [ - "generic-array", + "foreign-types-shared", ] [[package]] -name = "brotli" -version = "7.0.0" +name = "foreign-types-shared" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc97b8f16f944bba54f0433f07e30be199b6dc2bd25937444bbad560bcea29bd" -dependencies = [ - "alloc-no-stdlib", - "alloc-stdlib", - "brotli-decompressor", -] +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] -name = "brotli-decompressor" -version = "4.0.1" +name = "form_urlencoded" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a45bd2e4095a8b518033b128020dd4a55aab1c0a381ba4404a472630f4bc362" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" dependencies = [ - "alloc-no-stdlib", - "alloc-stdlib", + "percent-encoding", ] [[package]] -name = "bstr" -version = "1.10.0" +name = "futures-channel" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40723b8fb387abc38f4f4a37c09073622e41dd12327033091ef8950659e6dc0c" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" dependencies = [ - "memchr", - "regex-automata 0.4.8", - "serde", + "futures-core", ] [[package]] -name = "bumpalo" -version = "3.16.0" +name = "futures-core" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" [[package]] -name = "byte-slice-cast" -version = "1.2.2" +name = "futures-io" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" [[package]] -name = "byteorder" -version = "1.5.0" +name = "futures-sink" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" [[package]] -name = "bytes" -version = "1.8.0" +name = "futures-task" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" [[package]] -name = "bytesize" -version = "1.3.0" +name = "futures-util" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e368af43e418a04d52505cf3dbc23dda4e3407ae2fa99fd0e4f308ce546acc" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +dependencies = [ + "futures-core", + "futures-io", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] [[package]] -name = "cairo-lang-casm" -version = "2.8.4" +name = "gimli" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd4d6659539ace9649c8e8a7434e51b0c50a7a700111d0a2b967dde220ddff49" -dependencies = [ - "cairo-lang-utils", - "indoc 2.0.5", - "num-bigint", - "num-traits", - "parity-scale-codec", - "serde", -] +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" [[package]] -name = "cairo-lang-compiler" -version = "2.8.4" +name = "h2" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2016966ed29f3a44487fd1bbdb05320fb6ea8ec46201c04c6b222ccb5264e0a" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" dependencies = [ - "anyhow", - "cairo-lang-defs", - "cairo-lang-diagnostics", - "cairo-lang-filesystem", - "cairo-lang-lowering", - "cairo-lang-parser", - "cairo-lang-project", - "cairo-lang-semantic", - "cairo-lang-sierra", - "cairo-lang-sierra-generator", - "cairo-lang-syntax", - "cairo-lang-utils", - "indoc 2.0.5", - "rayon", - "rust-analyzer-salsa", - "semver", - "smol_str", - "thiserror", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", ] [[package]] -name = "cairo-lang-debug" -version = "2.8.4" +name = "hashbrown" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50c804649297ca417206435ee3e8041d2100cc31ebf4a95bc4b92ed02dc63469" -dependencies = [ - "cairo-lang-utils", -] +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" [[package]] -name = "cairo-lang-defs" -version = "2.8.4" +name = "heck" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8fbda467ac36f73bb1879e1f741898fc719d6f9239a01cc422e6a023281319b" -dependencies = [ - "cairo-lang-debug", - "cairo-lang-diagnostics", - "cairo-lang-filesystem", - "cairo-lang-parser", - "cairo-lang-syntax", - "cairo-lang-utils", - "itertools 0.12.1", - "rust-analyzer-salsa", - "smol_str", -] +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] -name = "cairo-lang-diagnostics" -version = "2.8.4" +name = "http" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c843ef4715e3d21de5388d02206db2506e2d2ec0e80e2629e0ae9900a08b8674" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" dependencies = [ - "cairo-lang-debug", - "cairo-lang-filesystem", - "cairo-lang-utils", - "itertools 0.12.1", + "bytes", + "fnv", + "itoa", ] [[package]] -name = "cairo-lang-doc" -version = "2.8.4" +name = "http-body" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a932262ab491cf248283ccbe6d584a76fd55fc85ae0c7879b2ad687c512a115" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" dependencies = [ - "cairo-lang-defs", - "cairo-lang-formatter", - "cairo-lang-parser", - "cairo-lang-syntax", - "cairo-lang-utils", - "itertools 0.12.1", - "rust-analyzer-salsa", + "bytes", + "http", + "pin-project-lite", ] [[package]] -name = "cairo-lang-eq-solver" -version = "2.8.4" +name = "httparse" +version = "1.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33a416c5871960fb4823160ebef2abc51e0c1b86fef1e97a1ebb2e5f3c3795d3" -dependencies = [ - "cairo-lang-utils", - "good_lp", -] +checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946" [[package]] -name = "cairo-lang-filesystem" -version = "2.8.4" +name = "httpdate" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47189e0cb84b21defd201af4cf24a94c6b0d09f48706cf659c9ffa0def8a7a43" -dependencies = [ - "cairo-lang-debug", - "cairo-lang-utils", - "path-clean", - "rust-analyzer-salsa", - "semver", - "serde", - "smol_str", -] +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] -name = "cairo-lang-formatter" -version = "2.8.4" +name = "hyper" +version = "0.14.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6409ff1f4a93ce7c0968d9d857d2a8c03657617a827159d33f978110b718b31d" +checksum = "8c08302e8fa335b151b788c775ff56e7a03ae64ff85c548ee820fecb70356e85" dependencies = [ - "anyhow", - "cairo-lang-diagnostics", - "cairo-lang-filesystem", - "cairo-lang-parser", - "cairo-lang-syntax", - "cairo-lang-utils", - "diffy", - "ignore", - "itertools 0.12.1", - "rust-analyzer-salsa", - "serde", - "smol_str", - "thiserror", + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", + "want", ] [[package]] -name = "cairo-lang-language-server" -version = "2.8.4" +name = "hyper-tls" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5dad8906d9d4b3876e6b2061f9ddd499f0514368e3e7e0aeaea70e80c3608a" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" dependencies = [ - "anyhow", - "cairo-lang-compiler", - "cairo-lang-defs", - "cairo-lang-diagnostics", - "cairo-lang-doc", - "cairo-lang-filesystem", - "cairo-lang-formatter", - "cairo-lang-lowering", - "cairo-lang-parser", - "cairo-lang-project", - "cairo-lang-semantic", - "cairo-lang-starknet", - "cairo-lang-syntax", - "cairo-lang-test-plugin", - "cairo-lang-utils", - "indent", - "indoc 2.0.5", - "itertools 0.12.1", - "rust-analyzer-salsa", - "scarb-metadata 1.13.0", - "serde", - "serde_json", - "smol_str", - "tempfile", + "bytes", + "hyper", + "native-tls", "tokio", - "tower-lsp", - "tracing", - "tracing-chrome", - "tracing-subscriber", + "tokio-native-tls", ] [[package]] -name = "cairo-lang-lowering" -version = "2.8.4" +name = "icu_collections" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e224e006c82ef21bd9e243390992de2be25ae6fbbdaa8544067b3f0c31977f1" +checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" dependencies = [ - "cairo-lang-debug", - "cairo-lang-defs", - "cairo-lang-diagnostics", - "cairo-lang-filesystem", - "cairo-lang-parser", - "cairo-lang-proc-macros", - "cairo-lang-semantic", - "cairo-lang-syntax", - "cairo-lang-utils", - "id-arena", - "itertools 0.12.1", - "log", - "num-bigint", - "num-traits", - "rust-analyzer-salsa", - "smol_str", + "displaydoc", + "yoke", + "zerofrom", + "zerovec", ] [[package]] -name = "cairo-lang-macro" -version = "0.1.0" -source = "git+https://github.com/software-mansion/scarb?rev=2aa4e19#2aa4e193ec930417a8789ceafcfb9dc29963f8e7" +name = "icu_locid" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" dependencies = [ - "cairo-lang-macro-attributes", - "cairo-lang-macro-stable", - "linkme", + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", ] [[package]] -name = "cairo-lang-macro-attributes" -version = "0.1.0" +name = "icu_locid_transform" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e32e958decd95ae122ee64daa26721da2f76e83231047f947fd9cdc5d3c90cc6" +checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" dependencies = [ - "quote", - "scarb-stable-hash 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 2.0.87", + "displaydoc", + "icu_locid", + "icu_locid_transform_data", + "icu_provider", + "tinystr", + "zerovec", ] [[package]] -name = "cairo-lang-macro-stable" -version = "1.0.0" +name = "icu_locid_transform_data" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c49906d6b1c215e5814be7c5c65ecf2328898b335bee8c2409ec07cfb5530daf" +checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" [[package]] -name = "cairo-lang-parser" -version = "2.8.4" +name = "icu_normalizer" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afb260ba349c2b699639e56f9b64deb969ff01179a0253087e2c8ceec7e32157" +checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" dependencies = [ - "cairo-lang-diagnostics", - "cairo-lang-filesystem", - "cairo-lang-syntax", - "cairo-lang-syntax-codegen", - "cairo-lang-utils", - "colored", - "itertools 0.12.1", - "num-bigint", - "num-traits", - "rust-analyzer-salsa", - "smol_str", - "unescaper", + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "utf16_iter", + "utf8_iter", + "write16", + "zerovec", ] [[package]] -name = "cairo-lang-plugins" -version = "2.8.4" +name = "icu_normalizer_data" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05a2e500dc8ddea4d25a866d8a839158b0e4c41a6c023f21911e2da252bd91b3" -dependencies = [ - "cairo-lang-defs", - "cairo-lang-diagnostics", - "cairo-lang-filesystem", - "cairo-lang-parser", - "cairo-lang-syntax", - "cairo-lang-utils", - "indent", - "indoc 2.0.5", - "itertools 0.12.1", - "rust-analyzer-salsa", - "smol_str", -] +checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" [[package]] -name = "cairo-lang-proc-macros" -version = "2.8.4" +name = "icu_properties" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d72f17373740f242d6995e896b9195c2cedff7e8b14e496afdd16b405039d1fb" +checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" dependencies = [ - "cairo-lang-debug", - "quote", - "syn 2.0.87", + "displaydoc", + "icu_collections", + "icu_locid_transform", + "icu_properties_data", + "icu_provider", + "tinystr", + "zerovec", ] [[package]] -name = "cairo-lang-project" -version = "2.8.4" +name = "icu_properties_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" + +[[package]] +name = "icu_provider" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13294f08d2013fcd6e815e7235935680963dec3390e5baf454f33da866fc44b6" +checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" dependencies = [ - "cairo-lang-filesystem", - "cairo-lang-utils", - "serde", - "smol_str", - "thiserror", - "toml 0.8.19", + "displaydoc", + "icu_locid", + "icu_provider_macros", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerovec", ] [[package]] -name = "cairo-lang-semantic" -version = "2.8.4" +name = "icu_provider_macros" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6936215bca75c23e71873998420a3d46c322507a09917ce676c8d39f8c1bd6fe" +checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" dependencies = [ - "cairo-lang-debug", - "cairo-lang-defs", - "cairo-lang-diagnostics", - "cairo-lang-filesystem", - "cairo-lang-parser", - "cairo-lang-plugins", - "cairo-lang-proc-macros", - "cairo-lang-syntax", - "cairo-lang-test-utils", - "cairo-lang-utils", - "id-arena", - "indoc 2.0.5", - "itertools 0.12.1", - "num-bigint", - "num-traits", - "rust-analyzer-salsa", - "smol_str", - "toml 0.8.19", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "cairo-lang-sierra" -version = "2.8.4" +name = "idna" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "424f55450494e959c1ae26c52a71075767a90f76e3ecca6e81056dd7517e8ba0" +checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" dependencies = [ - "anyhow", - "cairo-lang-utils", - "const-fnv1a-hash", - "convert_case", - "derivative", - "itertools 0.12.1", - "lalrpop", - "lalrpop-util", - "num-bigint", - "num-integer", - "num-traits", - "regex", - "rust-analyzer-salsa", - "serde", - "serde_json", - "sha3", - "smol_str", - "starknet-types-core", - "thiserror", + "idna_adapter", + "smallvec", + "utf8_iter", ] [[package]] -name = "cairo-lang-sierra-ap-change" -version = "2.8.4" +name = "idna_adapter" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "053dd520e0b9d1c1078d93ea69045f6f334c3d41b4b75db183ab33e32cfd8570" +checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" dependencies = [ - "cairo-lang-eq-solver", - "cairo-lang-sierra", - "cairo-lang-sierra-type-size", - "cairo-lang-utils", - "itertools 0.12.1", - "num-bigint", - "num-traits", - "thiserror", + "icu_normalizer", + "icu_properties", ] [[package]] -name = "cairo-lang-sierra-gas" -version = "2.8.4" +name = "indexmap" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a73227867377efc62ebb893cddaa88df3940bf2be5dbdc2f0b00f9edf69288e" +checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" dependencies = [ - "cairo-lang-eq-solver", - "cairo-lang-sierra", - "cairo-lang-sierra-type-size", - "cairo-lang-utils", - "itertools 0.12.1", - "num-bigint", - "num-traits", - "thiserror", + "equivalent", + "hashbrown", ] [[package]] -name = "cairo-lang-sierra-generator" -version = "2.8.4" +name = "ipnet" +version = "2.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3752cacd475ea089d9a536357804150e693a124e703fcc33a55566d568094b3" -dependencies = [ - "cairo-lang-debug", - "cairo-lang-defs", - "cairo-lang-diagnostics", - "cairo-lang-filesystem", - "cairo-lang-lowering", - "cairo-lang-parser", - "cairo-lang-semantic", - "cairo-lang-sierra", - "cairo-lang-syntax", - "cairo-lang-utils", - "itertools 0.12.1", - "num-traits", - "rust-analyzer-salsa", - "serde", - "serde_json", - "smol_str", -] +checksum = "ddc24109865250148c2e0f3d25d4f0f479571723792d3802153c60922a4fb708" [[package]] -name = "cairo-lang-sierra-to-casm" -version = "2.8.4" +name = "is_terminal_polyfill" +version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7162fb3c93960dfc6d8005b65064e518e3f1ed6102e8981b42ea41879c331184" -dependencies = [ - "assert_matches", - "cairo-lang-casm", - "cairo-lang-sierra", - "cairo-lang-sierra-ap-change", - "cairo-lang-sierra-gas", - "cairo-lang-sierra-type-size", - "cairo-lang-utils", - "indoc 2.0.5", - "itertools 0.12.1", - "num-bigint", - "num-traits", - "starknet-types-core", - "thiserror", -] +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" [[package]] -name = "cairo-lang-sierra-type-size" -version = "2.8.4" +name = "itertools" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a51b80c117e2b05a6d300f2e2247892cc99e42e950e79f6085e6ed6cbcb44d12" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" dependencies = [ - "cairo-lang-sierra", - "cairo-lang-utils", + "either", ] [[package]] -name = "cairo-lang-starknet" -version = "2.8.4" +name = "itoa" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aafaabc43f78dfa2f45d935993ba21c05c164bbb3bf277d348847a51e5939a9f" -dependencies = [ - "anyhow", - "cairo-lang-compiler", - "cairo-lang-defs", - "cairo-lang-diagnostics", - "cairo-lang-filesystem", - "cairo-lang-lowering", - "cairo-lang-plugins", - "cairo-lang-semantic", - "cairo-lang-sierra", - "cairo-lang-sierra-generator", - "cairo-lang-starknet-classes", - "cairo-lang-syntax", - "cairo-lang-utils", - "const_format", - "indent", - "indoc 2.0.5", - "itertools 0.12.1", - "serde", - "serde_json", - "smol_str", - "starknet-types-core", - "thiserror", -] +checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" [[package]] -name = "cairo-lang-starknet-classes" -version = "2.8.4" +name = "js-sys" +version = "0.3.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "832fd9072ddf4204ca6d227c0238929349f10146bd066a98025d51ac15d27fad" +checksum = "6717b6b5b077764fb5966237269cb3c64edddde4b14ce42647430a78ced9e7b7" dependencies = [ - "cairo-lang-casm", - "cairo-lang-sierra", - "cairo-lang-sierra-to-casm", - "cairo-lang-utils", - "convert_case", - "itertools 0.12.1", - "num-bigint", - "num-integer", - "num-traits", - "serde", - "serde_json", - "sha3", - "smol_str", - "starknet-types-core", - "thiserror", + "once_cell", + "wasm-bindgen", ] [[package]] -name = "cairo-lang-syntax" -version = "2.8.4" +name = "libc" +version = "0.2.168" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cebe67c0d68f9acf8709d170c1308ca57a778d22f70da38a57f74ae250eee28a" -dependencies = [ - "cairo-lang-debug", - "cairo-lang-filesystem", - "cairo-lang-utils", - "num-bigint", - "num-traits", - "rust-analyzer-salsa", - "smol_str", - "unescaper", -] +checksum = "5aaeb2981e0606ca11d79718f8bb01164f1d6ed75080182d3abf017e6d244b6d" [[package]] -name = "cairo-lang-syntax-codegen" -version = "2.8.4" +name = "linux-raw-sys" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31cef5b4347626e61bad8f070495cd35d637a5cb6744c34d20dd382c7431aff8" -dependencies = [ - "genco", - "xshell", -] +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] -name = "cairo-lang-test-plugin" -version = "2.8.4" +name = "litemap" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d5f036132e07b7829cb1d61b1ecc02789a70c7d16b2733722a2aca992492bc3" -dependencies = [ - "anyhow", - "cairo-lang-compiler", - "cairo-lang-debug", - "cairo-lang-defs", - "cairo-lang-filesystem", - "cairo-lang-lowering", - "cairo-lang-semantic", - "cairo-lang-sierra", - "cairo-lang-sierra-generator", - "cairo-lang-starknet", - "cairo-lang-starknet-classes", - "cairo-lang-syntax", - "cairo-lang-utils", - "indoc 2.0.5", - "itertools 0.12.1", - "num-bigint", - "num-traits", - "serde", - "starknet-types-core", -] +checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104" [[package]] -name = "cairo-lang-test-utils" -version = "2.8.4" +name = "log" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "060c61ac4a3ae0428771244ff8db903105f127392b7d725d919fe3fb1ec4132f" -dependencies = [ - "cairo-lang-formatter", - "cairo-lang-utils", - "colored", - "log", - "pretty_assertions", -] +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] -name = "cairo-lang-utils" -version = "2.8.4" +name = "memchr" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bfc6372538143afad658c853a35bdc9f5210c5cb54e0c8f04ab78e268139466" -dependencies = [ - "env_logger 0.11.5", - "hashbrown 0.14.5", - "indexmap 2.6.0", - "itertools 0.12.1", - "log", - "num-bigint", - "num-traits", - "schemars", - "serde", - "time", -] +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] -name = "camino" -version = "1.1.9" +name = "mime" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b96ec4966b5813e2c0507c1f86115c8c5abaadc3980879c3424042a02fd1ad3" -dependencies = [ - "serde", -] +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] -name = "cargo-platform" -version = "0.1.8" +name = "mime_guess" +version = "2.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24b1f0365a6c6bb4020cd05806fd0d33c44d38046b8bd7f0e40814b9763cabfc" +checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" dependencies = [ - "serde", + "mime", + "unicase", ] [[package]] -name = "cargo_metadata" -version = "0.18.1" +name = "miniz_oxide" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d886547e41f740c616ae73108f6eb70afe6d940c7bc697cb30f13daec073037" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" dependencies = [ - "camino", - "cargo-platform", - "semver", - "serde", - "serde_json", - "thiserror", + "adler2", ] [[package]] -name = "cc" -version = "1.1.36" +name = "mio" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baee610e9452a8f6f0a1b6194ec09ff9e2d85dea54432acdae41aa0761c95d70" +checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" dependencies = [ - "jobserver", "libc", - "shlex", + "wasi", + "windows-sys 0.52.0", ] [[package]] -name = "cfg-if" -version = "1.0.0" +name = "native-tls" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "chrono" -version = "0.4.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" -dependencies = [ - "android-tzdata", - "iana-time-zone", - "num-traits", - "serde", - "windows-targets 0.52.6", -] - -[[package]] -name = "cipher" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" -dependencies = [ - "crypto-common", - "inout", -] - -[[package]] -name = "clap" -version = "4.5.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8" -dependencies = [ - "clap_builder", - "clap_derive", -] - -[[package]] -name = "clap_builder" -version = "4.5.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54" -dependencies = [ - "anstream", - "anstyle", - "clap_lex", - "strsim", -] - -[[package]] -name = "clap_derive" -version = "4.5.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" -dependencies = [ - "heck 0.5.0", - "proc-macro2", - "quote", - "syn 2.0.87", -] - -[[package]] -name = "clap_lex" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" - -[[package]] -name = "cli" -version = "0.1.0" -dependencies = [ - "anyhow", - "camino", - "clap", - "comfy-table", - "console", - "dialoguer 0.10.4", - "dirs", - "dotenv", - "dyn-compiler", - "indicatif", - "regex", - "reqwest", - "serde", - "smol_str", - "strum 0.25.0", - "strum_macros 0.25.3", - "thiserror", - "tokio", - "toml 0.4.10", - "url", - "voyager-resolver-cairo", - "walkdir", -] - -[[package]] -name = "clru" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbd0f76e066e64fdc5631e3bb46381254deab9ef1158292f27c8c57e3bf3fe59" - -[[package]] -name = "colorchoice" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" - -[[package]] -name = "colored" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbf2150cce219b664a8a70df7a1f933836724b503f8a413af9365b4dcc4d90b8" -dependencies = [ - "lazy_static", - "windows-sys 0.48.0", -] - -[[package]] -name = "comfy-table" -version = "6.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e959d788268e3bf9d35ace83e81b124190378e4c91c9067524675e33394b8ba" -dependencies = [ - "crossterm", - "strum 0.24.1", - "strum_macros 0.24.3", - "unicode-width", -] - -[[package]] -name = "console" -version = "0.15.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb" -dependencies = [ - "encode_unicode", - "lazy_static", - "libc", - "unicode-width", - "windows-sys 0.52.0", -] - -[[package]] -name = "const-fnv1a-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32b13ea120a812beba79e34316b3942a857c86ec1593cb34f27bb28272ce2cca" - -[[package]] -name = "const_format" -version = "0.2.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50c655d81ff1114fb0dcdea9225ea9f0cc712a6f8d189378e82bdf62a473a64b" -dependencies = [ - "const_format_proc_macros", -] - -[[package]] -name = "const_format_proc_macros" -version = "0.2.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eff1a44b93f47b1bac19a27932f5c591e43d1ba357ee4f61526c8a25603f0eb1" -dependencies = [ - "proc-macro2", - "quote", - "unicode-xid", -] - -[[package]] -name = "convert_case" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" -dependencies = [ - "unicode-segmentation", -] - -[[package]] -name = "core-foundation" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "core-foundation" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b55271e5c8c478ad3f38ad24ef34923091e0548492a266d19b3c0b4d82574c63" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "core-foundation-sys" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" - -[[package]] -name = "cpufeatures" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" -dependencies = [ - "libc", -] - -[[package]] -name = "crc32fast" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "create-output-dir" -version = "1.0.0" -source = "git+https://github.com/software-mansion/scarb?rev=2aa4e19#2aa4e193ec930417a8789ceafcfb9dc29963f8e7" -dependencies = [ - "anyhow", - "core-foundation 0.10.0", - "tempfile", - "winapi", -] - -[[package]] -name = "crossbeam-channel" -version = "0.5.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-deque" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" -dependencies = [ - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" - -[[package]] -name = "crossterm" -version = "0.26.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a84cda67535339806297f1b331d6dd6320470d2a0fe65381e79ee9e156dd3d13" -dependencies = [ - "bitflags 1.3.2", - "crossterm_winapi", - "libc", - "mio 0.8.11", - "parking_lot 0.12.3", - "signal-hook", - "signal-hook-mio", - "winapi", -] - -[[package]] -name = "crossterm_winapi" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b" -dependencies = [ - "winapi", -] - -[[package]] -name = "crunchy" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" - -[[package]] -name = "crypto-bigint" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" -dependencies = [ - "generic-array", - "subtle", - "zeroize", -] - -[[package]] -name = "crypto-common" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" -dependencies = [ - "generic-array", - "typenum", -] - -[[package]] -name = "ctr" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" -dependencies = [ - "cipher", -] - -[[package]] -name = "darling" -version = "0.20.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" -dependencies = [ - "darling_core", - "darling_macro", -] - -[[package]] -name = "darling_core" -version = "0.20.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim", - "syn 2.0.87", -] - -[[package]] -name = "darling_macro" -version = "0.20.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" -dependencies = [ - "darling_core", - "quote", - "syn 2.0.87", -] - -[[package]] -name = "dashmap" -version = "5.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" -dependencies = [ - "cfg-if", - "hashbrown 0.14.5", - "lock_api", - "once_cell", - "parking_lot_core 0.9.10", -] - -[[package]] -name = "dashmap" -version = "6.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf" -dependencies = [ - "cfg-if", - "crossbeam-utils", - "hashbrown 0.14.5", - "lock_api", - "once_cell", - "parking_lot_core 0.9.10", -] - -[[package]] -name = "data-encoding" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" - -[[package]] -name = "deno_task_shell" -version = "0.18.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f444918f7102c1a5a143e9d57809e499fb4d365070519bf2e8bdb16d586af2a" -dependencies = [ - "anyhow", - "futures", - "glob", - "monch", - "os_pipe", - "path-dedot", - "thiserror", - "tokio", - "tokio-util", -] - -[[package]] -name = "deranged" -version = "0.3.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" -dependencies = [ - "powerfmt", - "serde", -] - -[[package]] -name = "derivative" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "derive_builder" -version = "0.20.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "507dfb09ea8b7fa618fcf76e953f4f5e192547945816d5358edffe39f6f94947" -dependencies = [ - "derive_builder_macro", -] - -[[package]] -name = "derive_builder_core" -version = "0.20.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d5bcf7b024d6835cfb3d473887cd966994907effbe9227e8c8219824d06c4e8" -dependencies = [ - "darling", - "proc-macro2", - "quote", - "syn 2.0.87", -] - -[[package]] -name = "derive_builder_macro" -version = "0.20.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c" -dependencies = [ - "derive_builder_core", - "syn 2.0.87", -] - -[[package]] -name = "dialoguer" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59c6f2989294b9a498d3ad5491a79c6deb604617378e1cdc4bfc1c1361fe2f87" -dependencies = [ - "console", - "fuzzy-matcher", - "shell-words", - "tempfile", - "zeroize", -] - -[[package]] -name = "dialoguer" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "658bce805d770f407bc62102fca7c2c64ceef2fbcb2b8bd19d2765ce093980de" -dependencies = [ - "console", - "shell-words", - "tempfile", - "thiserror", - "zeroize", -] - -[[package]] -name = "diff" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" - -[[package]] -name = "diffy" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e616e59155c92257e84970156f506287853355f58cd4a6eb167385722c32b790" -dependencies = [ - "nu-ansi-term", -] - -[[package]] -name = "digest" -version = "0.10.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" -dependencies = [ - "block-buffer", - "crypto-common", - "subtle", -] - -[[package]] -name = "directories" -version = "5.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a49173b84e034382284f27f1af4dcbbd231ffa358c0fe316541a7337f376a35" -dependencies = [ - "dirs-sys 0.4.1", -] - -[[package]] -name = "dirs" -version = "4.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" -dependencies = [ - "dirs-sys 0.3.7", -] - -[[package]] -name = "dirs-next" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" -dependencies = [ - "cfg-if", - "dirs-sys-next", -] - -[[package]] -name = "dirs-sys" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" -dependencies = [ - "libc", - "redox_users", - "winapi", -] - -[[package]] -name = "dirs-sys" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" -dependencies = [ - "libc", - "option-ext", - "redox_users", - "windows-sys 0.48.0", -] - -[[package]] -name = "dirs-sys-next" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" -dependencies = [ - "libc", - "redox_users", - "winapi", -] - -[[package]] -name = "displaydoc" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.87", -] - -[[package]] -name = "dotenv" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" - -[[package]] -name = "dunce" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" - -[[package]] -name = "dyn-clone" -version = "1.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" - -[[package]] -name = "dyn-compiler" -version = "0.1.0" -dependencies = [ - "anyhow", - "camino", -] - -[[package]] -name = "either" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" - -[[package]] -name = "ena" -version = "0.14.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d248bdd43ce613d87415282f69b9bb99d947d290b10962dd6c56233312c2ad5" -dependencies = [ - "log", -] - -[[package]] -name = "encode_unicode" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" - -[[package]] -name = "encoding_rs" -version = "0.8.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "env_filter" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f2c92ceda6ceec50f43169f9ee8424fe2db276791afde7b2cd8bc084cb376ab" -dependencies = [ - "log", - "regex", -] - -[[package]] -name = "env_logger" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a12e6657c4c97ebab115a42dcee77225f7f482cdd841cf7088c657a42e9e00e7" -dependencies = [ - "atty", - "humantime", - "log", - "regex", - "termcolor", -] - -[[package]] -name = "env_logger" -version = "0.11.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13fa619b91fb2381732789fc5de83b45675e882f66623b7d8cb4f643017018d" -dependencies = [ - "anstream", - "anstyle", - "env_filter", - "humantime", - "log", -] - -[[package]] -name = "equivalent" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" - -[[package]] -name = "erased-serde" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24e2389d65ab4fab27dc2a5de7b191e1f6617d1f1c8855c0dc569c94a4cbb18d" -dependencies = [ - "serde", - "typeid", -] - -[[package]] -name = "errno" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] - -[[package]] -name = "eth-keystore" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fda3bf123be441da5260717e0661c25a2fd9cb2b2c1d20bf2e05580047158ab" -dependencies = [ - "aes", - "ctr", - "digest", - "hex", - "hmac", - "pbkdf2", - "rand", - "scrypt", - "serde", - "serde_json", - "sha2", - "sha3", - "thiserror", - "uuid", -] - -[[package]] -name = "ethbloom" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c22d4b5885b6aa2fe5e8b9329fb8d232bf739e434e6b87347c63bdd00c120f60" -dependencies = [ - "crunchy", - "fixed-hash", - "impl-rlp", - "impl-serde", - "tiny-keccak", -] - -[[package]] -name = "ethereum-types" -version = "0.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02d215cbf040552efcbe99a38372fe80ab9d00268e20012b79fcd0f073edd8ee" -dependencies = [ - "ethbloom", - "fixed-hash", - "impl-rlp", - "impl-serde", - "primitive-types", - "uint", -] - -[[package]] -name = "faster-hex" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2a2b11eda1d40935b26cf18f6833c526845ae8c41e58d09af6adeb6f0269183" -dependencies = [ - "serde", -] - -[[package]] -name = "fastrand" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" - -[[package]] -name = "filetime" -version = "0.2.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35c0522e981e68cbfa8c3f978441a5f34b30b96e146b33cd3359176b50fe8586" -dependencies = [ - "cfg-if", - "libc", - "libredox", - "windows-sys 0.59.0", -] - -[[package]] -name = "fixed-hash" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "835c052cb0c08c1acf6ffd71c022172e18723949c8282f2b9f27efbc51e64534" -dependencies = [ - "byteorder", - "rand", - "rustc-hex", - "static_assertions", -] - -[[package]] -name = "fixedbitset" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d" - -[[package]] -name = "fixedbitset" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" - -[[package]] -name = "flate2" -version = "1.0.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1b589b4dc103969ad3cf85c950899926ec64300a1a46d76c03a6072957036f0" -dependencies = [ - "crc32fast", - "miniz_oxide", -] - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - -[[package]] -name = "form_urlencoded" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" -dependencies = [ - "percent-encoding", -] - -[[package]] -name = "fs4" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29f9df8a11882c4e3335eb2d18a0137c505d9ca927470b0cac9c6f0ae07d28f7" -dependencies = [ - "async-trait", - "rustix", - "tokio", - "windows-sys 0.48.0", -] - -[[package]] -name = "fs_extra" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" - -[[package]] -name = "funty" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" - -[[package]] -name = "futures" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" -dependencies = [ - "futures-channel", - "futures-core", - "futures-executor", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-channel" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" -dependencies = [ - "futures-core", - "futures-sink", -] - -[[package]] -name = "futures-core" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" - -[[package]] -name = "futures-executor" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" -dependencies = [ - "futures-core", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-io" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" - -[[package]] -name = "futures-macro" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.87", -] - -[[package]] -name = "futures-sink" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" - -[[package]] -name = "futures-task" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" - -[[package]] -name = "futures-timer" -version = "3.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" - -[[package]] -name = "futures-util" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" -dependencies = [ - "futures-channel", - "futures-core", - "futures-io", - "futures-macro", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite", - "pin-utils", - "slab", -] - -[[package]] -name = "fuzzy-matcher" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54614a3312934d066701a80f20f15fa3b56d67ac7722b39eea5b4c9dd1d66c94" -dependencies = [ - "thread_local", -] - -[[package]] -name = "genco" -version = "0.17.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afac3cbb14db69ac9fef9cdb60d8a87e39a7a527f85a81a923436efa40ad42c6" -dependencies = [ - "genco-macros", - "relative-path", - "smallvec", -] - -[[package]] -name = "genco-macros" -version = "0.17.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "553630feadf7b76442b0849fd25fdf89b860d933623aec9693fed19af0400c78" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.87", -] - -[[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "getrandom" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" -dependencies = [ - "cfg-if", - "js-sys", - "libc", - "wasi", - "wasm-bindgen", -] - -[[package]] -name = "gimli" -version = "0.31.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" - -[[package]] -name = "gix" -version = "0.67.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7d3e78ddac368d3e3bfbc2862bc2aafa3d89f1b15fed898d9761e1ec6f3f17f" -dependencies = [ - "gix-actor", - "gix-archive", - "gix-attributes", - "gix-command", - "gix-commitgraph", - "gix-config", - "gix-credentials", - "gix-date", - "gix-diff", - "gix-dir", - "gix-discover", - "gix-features", - "gix-filter", - "gix-fs", - "gix-glob", - "gix-hash", - "gix-hashtable", - "gix-ignore", - "gix-index", - "gix-lock", - "gix-mailmap", - "gix-merge", - "gix-negotiate", - "gix-object", - "gix-odb", - "gix-pack", - "gix-path", - "gix-pathspec", - "gix-prompt", - "gix-ref", - "gix-refspec", - "gix-revision", - "gix-revwalk", - "gix-sec", - "gix-status", - "gix-submodule", - "gix-tempfile", - "gix-trace", - "gix-traverse", - "gix-url", - "gix-utils", - "gix-validate", - "gix-worktree", - "gix-worktree-state", - "gix-worktree-stream", - "once_cell", - "parking_lot 0.12.3", - "regex", - "signal-hook", - "smallvec", - "thiserror", -] - -[[package]] -name = "gix-actor" -version = "0.33.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59226ef06661c756e664b46b1d3b2c198f6adc5407a484c086d0171108a70027" -dependencies = [ - "bstr", - "gix-date", - "gix-utils", - "itoa", - "thiserror", - "winnow 0.6.20", -] - -[[package]] -name = "gix-archive" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4771188ac63c8f597042bd86561ad66cb1b5f795f963f6e5f71fc4f04853126" -dependencies = [ - "bstr", - "gix-date", - "gix-object", - "gix-worktree-stream", - "jiff", - "thiserror", -] - -[[package]] -name = "gix-attributes" -version = "0.23.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31a102d201ef0e5a848458a82292581e7641e52f0f52e693b6cbdd05a652c029" -dependencies = [ - "bstr", - "gix-glob", - "gix-path", - "gix-quote", - "gix-trace", - "kstring", - "smallvec", - "thiserror", - "unicode-bom", -] - -[[package]] -name = "gix-bitmap" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10f78312288bd02052be5dbc2ecbc342c9f4eb791986d86c0a5c06b92dc72efa" -dependencies = [ - "thiserror", -] - -[[package]] -name = "gix-chunk" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c28b58ba04f0c004722344390af9dbc85888fbb84be1981afb934da4114d4cf" -dependencies = [ - "thiserror", -] - -[[package]] -name = "gix-command" -version = "0.3.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c201d2b9e9cce2365a6638fd0a966f751ed92d74be5c0727ac331e6a29ef5846" -dependencies = [ - "bstr", - "gix-path", - "gix-trace", - "shell-words", -] - -[[package]] -name = "gix-commitgraph" -version = "0.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41db900b189e62dc61575f06fdf1a3b6901d264a99be9d32b286af6b2e3984e1" -dependencies = [ - "bstr", - "gix-chunk", - "gix-features", - "gix-hash", - "memmap2", - "thiserror", -] - -[[package]] -name = "gix-config" -version = "0.41.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bedd1bf1c7b994be9d57207e8e0de79016c05e2e8701d3015da906e65ac445e" -dependencies = [ - "bstr", - "gix-config-value", - "gix-features", - "gix-glob", - "gix-path", - "gix-ref", - "gix-sec", - "memchr", - "once_cell", - "smallvec", - "thiserror", - "unicode-bom", - "winnow 0.6.20", -] - -[[package]] -name = "gix-config-value" -version = "0.14.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3de3fdca9c75fa4b83a76583d265fa49b1de6b088ebcd210749c24ceeb74660" -dependencies = [ - "bitflags 2.6.0", - "bstr", - "gix-path", - "libc", - "thiserror", -] - -[[package]] -name = "gix-credentials" -version = "0.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d713bac4bf7df5801012285366dae6625d675baec4ba6e443d64e83559bec068" -dependencies = [ - "bstr", - "gix-command", - "gix-config-value", - "gix-path", - "gix-prompt", - "gix-sec", - "gix-trace", - "gix-url", - "thiserror", -] - -[[package]] -name = "gix-date" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d10d543ac13c97292a15e8e8b7889cd006faf739777437ed95362504b8fe81a0" -dependencies = [ - "bstr", - "itoa", - "jiff", - "thiserror", -] - -[[package]] -name = "gix-diff" -version = "0.47.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9850fd0c15af113db6f9e130d13091ba0d3754e570a2afdff9e2f3043da260e" -dependencies = [ - "bstr", - "gix-command", - "gix-filter", - "gix-fs", - "gix-hash", - "gix-object", - "gix-path", - "gix-tempfile", - "gix-trace", - "gix-traverse", - "gix-worktree", - "imara-diff", - "thiserror", -] - -[[package]] -name = "gix-dir" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbf6c29bf17baf3996d4925fad5e10c1a12eac9b3a0d8475d89292e0e5ba34a3" -dependencies = [ - "bstr", - "gix-discover", - "gix-fs", - "gix-ignore", - "gix-index", - "gix-object", - "gix-path", - "gix-pathspec", - "gix-trace", - "gix-utils", - "gix-worktree", - "thiserror", -] - -[[package]] -name = "gix-discover" -version = "0.36.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c522e31f458f50af09dfb014e10873c5378f702f8049c96f508989aad59671f6" -dependencies = [ - "bstr", - "dunce", - "gix-fs", - "gix-hash", - "gix-path", - "gix-ref", - "gix-sec", - "thiserror", -] - -[[package]] -name = "gix-features" -version = "0.39.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e0eb9efdf96c35c0bed7596d1bef2d4ce6360a1d09738001f9d3e402aa7ba3e" -dependencies = [ - "bytes", - "bytesize", - "crc32fast", - "crossbeam-channel", - "flate2", - "gix-hash", - "gix-trace", - "gix-utils", - "libc", - "once_cell", - "parking_lot 0.12.3", - "prodash", - "sha1_smol", - "thiserror", - "walkdir", -] - -[[package]] -name = "gix-filter" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b37f82359a4485770ed8993ae715ced1bf674f2a63e45f5a0786d38310665ea" -dependencies = [ - "bstr", - "encoding_rs", - "gix-attributes", - "gix-command", - "gix-hash", - "gix-object", - "gix-packetline-blocking", - "gix-path", - "gix-quote", - "gix-trace", - "gix-utils", - "smallvec", - "thiserror", -] - -[[package]] -name = "gix-fs" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34740384d8d763975858fa2c176b68652a6fcc09f616e24e3ce967b0d370e4d8" -dependencies = [ - "fastrand", - "gix-features", - "gix-utils", -] - -[[package]] -name = "gix-glob" -version = "0.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "254b5101cf7facc00d9b5ff564cf46302ca76695cca23d33bc958a707b6fc857" -dependencies = [ - "bitflags 2.6.0", - "bstr", - "gix-features", - "gix-path", -] - -[[package]] -name = "gix-hash" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "952c3a29f1bc1007cc901abce7479943abfa42016db089de33d0a4fa3c85bfe8" -dependencies = [ - "faster-hex", - "thiserror", -] - -[[package]] -name = "gix-hashtable" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ef65b256631078ef733bc5530c4e6b1c2e7d5c2830b75d4e9034ab3997d18fe" -dependencies = [ - "gix-hash", - "hashbrown 0.14.5", - "parking_lot 0.12.3", -] - -[[package]] -name = "gix-ignore" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba55a9b582dc26a639875497615959a8127ac5c37b2426dc50f037fada33a4b7" -dependencies = [ - "bstr", - "gix-glob", - "gix-path", - "gix-trace", - "unicode-bom", -] - -[[package]] -name = "gix-index" -version = "0.36.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27619009ca1ea33fd885041273f5fa5a09163a5c1d22a913b28d7b985e66fe29" -dependencies = [ - "bitflags 2.6.0", - "bstr", - "filetime", - "fnv", - "gix-bitmap", - "gix-features", - "gix-fs", - "gix-hash", - "gix-lock", - "gix-object", - "gix-traverse", - "gix-utils", - "gix-validate", - "hashbrown 0.14.5", - "itoa", - "libc", - "memmap2", - "rustix", - "smallvec", - "thiserror", -] - -[[package]] -name = "gix-lock" -version = "15.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5102acdf4acae2644e38dbbd18cdfba9597a218f7d85f810fe5430207e03c2de" -dependencies = [ - "gix-tempfile", - "gix-utils", - "thiserror", -] - -[[package]] -name = "gix-mailmap" -version = "0.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27d6ac205276a817b6efec0fdb6c62861d01d71f344dc7e5ebe81ab2907ebd0a" -dependencies = [ - "bstr", - "gix-actor", - "gix-date", - "thiserror", -] - -[[package]] -name = "gix-merge" -version = "0.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fef00c86d0a5a12d95fd73dfa30608882c1d2366c7ad8a27322283a2e6fa0048" -dependencies = [ - "bstr", - "gix-command", - "gix-filter", - "gix-fs", - "gix-hash", - "gix-object", - "gix-path", - "gix-quote", - "gix-tempfile", - "gix-trace", - "gix-worktree", - "imara-diff", - "thiserror", -] - -[[package]] -name = "gix-negotiate" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "414806291838c3349ea939c6d840ff854f84cd29bd3dde8f904f60b0e5b7d0bd" -dependencies = [ - "bitflags 2.6.0", - "gix-commitgraph", - "gix-date", - "gix-hash", - "gix-object", - "gix-revwalk", - "smallvec", - "thiserror", -] - -[[package]] -name = "gix-object" -version = "0.45.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a77b6e7753d298553d9ae8b1744924481e7a49170983938bb578dccfbc6fc1a" -dependencies = [ - "bstr", - "gix-actor", - "gix-date", - "gix-features", - "gix-hash", - "gix-hashtable", - "gix-utils", - "gix-validate", - "itoa", - "smallvec", - "thiserror", - "winnow 0.6.20", -] - -[[package]] -name = "gix-odb" -version = "0.64.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bb86aadf7f1b2f980601b4fc94309706f9700f8008f935dc512d556c9e60f61" -dependencies = [ - "arc-swap", - "gix-date", - "gix-features", - "gix-fs", - "gix-hash", - "gix-hashtable", - "gix-object", - "gix-pack", - "gix-path", - "gix-quote", - "parking_lot 0.12.3", - "tempfile", - "thiserror", -] - -[[package]] -name = "gix-pack" -version = "0.54.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "363e6e59a855ba243672408139db68e2478126cdcfeabb420777df4a1f20026b" -dependencies = [ - "clru", - "gix-chunk", - "gix-features", - "gix-hash", - "gix-hashtable", - "gix-object", - "gix-path", - "memmap2", - "smallvec", - "thiserror", - "uluru", -] - -[[package]] -name = "gix-packetline-blocking" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "decace940e8ba8e29d29b73b843a6cbae67503887f3e5fb7e688d0f4f6ee0757" -dependencies = [ - "bstr", - "faster-hex", - "gix-trace", - "thiserror", -] - -[[package]] -name = "gix-path" -version = "0.10.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c04e5a94fdb56b1e91eb7df2658ad16832428b8eeda24ff1a0f0288de2bce554" -dependencies = [ - "bstr", - "gix-trace", - "home", - "once_cell", - "thiserror", -] - -[[package]] -name = "gix-pathspec" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70f02bf7625dbf15bf9fedbeace2ac1ce1c5177806bdbc24c441d664c75c00e4" -dependencies = [ - "bitflags 2.6.0", - "bstr", - "gix-attributes", - "gix-config-value", - "gix-glob", - "gix-path", - "thiserror", -] - -[[package]] -name = "gix-prompt" -version = "0.8.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57944bbdb87f7a9893907032276e99ff4eba3640d8db1bdfb1eba8c07edfd006" -dependencies = [ - "gix-command", - "gix-config-value", - "parking_lot 0.12.3", - "rustix", - "thiserror", -] - -[[package]] -name = "gix-quote" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f89f9a1525dcfd9639e282ea939f5ab0d09d93cf2b90c1fc6104f1b9582a8e49" -dependencies = [ - "bstr", - "gix-utils", - "thiserror", -] - -[[package]] -name = "gix-ref" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a47385e71fa2d9da8c35e642ef4648808ddf0a52bc93425879088c706dfeaea2" -dependencies = [ - "gix-actor", - "gix-features", - "gix-fs", - "gix-hash", - "gix-lock", - "gix-object", - "gix-path", - "gix-tempfile", - "gix-utils", - "gix-validate", - "memmap2", - "thiserror", - "winnow 0.6.20", -] - -[[package]] -name = "gix-refspec" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0022038a09d80d9abf773be8efcbb502868d97f6972b8633bfb52ab6edaac442" -dependencies = [ - "bstr", - "gix-hash", - "gix-revision", - "gix-validate", - "smallvec", - "thiserror", -] - -[[package]] -name = "gix-revision" -version = "0.30.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ee8eb4088fece3562af4a5d751e069f90e93345524ad730512185234c4b55f1" -dependencies = [ - "bitflags 2.6.0", - "bstr", - "gix-commitgraph", - "gix-date", - "gix-hash", - "gix-hashtable", - "gix-object", - "gix-revwalk", - "gix-trace", - "thiserror", -] - -[[package]] -name = "gix-revwalk" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c9a9496da98d36ff19063a8576bf09a87425583b709a56dc5594fffa9d39b2" -dependencies = [ - "gix-commitgraph", - "gix-date", - "gix-hash", - "gix-hashtable", - "gix-object", - "smallvec", - "thiserror", -] - -[[package]] -name = "gix-sec" -version = "0.10.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2007538eda296445c07949cf04f4a767307d887184d6b3e83e2d636533ddc6e" -dependencies = [ - "bitflags 2.6.0", - "gix-path", - "libc", - "windows-sys 0.52.0", -] - -[[package]] -name = "gix-status" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57414886e750161b4c86d8bca6b2d15bcc87f37ddc46684bb05cebbd29390543" -dependencies = [ - "bstr", - "filetime", - "gix-diff", - "gix-dir", - "gix-features", - "gix-filter", - "gix-fs", - "gix-hash", - "gix-index", - "gix-object", - "gix-path", - "gix-pathspec", - "gix-worktree", - "portable-atomic", - "thiserror", -] - -[[package]] -name = "gix-submodule" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ed099621873cd36c580fc822176a32a7e50fef15a5c2ed81aaa087296f0497a" -dependencies = [ - "bstr", - "gix-config", - "gix-path", - "gix-pathspec", - "gix-refspec", - "gix-url", - "thiserror", -] - -[[package]] -name = "gix-tempfile" -version = "15.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2feb86ef094cc77a4a9a5afbfe5de626897351bbbd0de3cb9314baf3049adb82" -dependencies = [ - "dashmap 6.1.0", - "gix-fs", - "libc", - "once_cell", - "parking_lot 0.12.3", - "signal-hook", - "signal-hook-registry", - "tempfile", -] - -[[package]] -name = "gix-trace" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04bdde120c29f1fc23a24d3e115aeeea3d60d8e65bab92cc5f9d90d9302eb952" - -[[package]] -name = "gix-traverse" -version = "0.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f20f1b13cc4fa6ba92b24e6aa0c2fb6a34beb4458ef88c6300212db504e818df" -dependencies = [ - "bitflags 2.6.0", - "gix-commitgraph", - "gix-date", - "gix-hash", - "gix-hashtable", - "gix-object", - "gix-revwalk", - "smallvec", - "thiserror", -] - -[[package]] -name = "gix-url" -version = "0.28.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33e7c297c3265015c133a2c02199610b6e1373a09dc4be057d0c1b5285737f06" -dependencies = [ - "bstr", - "gix-features", - "gix-path", - "thiserror", - "url", -] - -[[package]] -name = "gix-utils" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba427e3e9599508ed98a6ddf8ed05493db114564e338e41f6a996d2e4790335f" -dependencies = [ - "bstr", - "fastrand", - "unicode-normalization", -] - -[[package]] -name = "gix-validate" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e187b263461bc36cea17650141567753bc6207d036cedd1de6e81a52f277ff68" -dependencies = [ - "bstr", - "thiserror", -] - -[[package]] -name = "gix-worktree" -version = "0.37.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d345e5b523550fe4fa0e912bf957de752011ccfc87451968fda1b624318f29c" -dependencies = [ - "bstr", - "gix-attributes", - "gix-features", - "gix-fs", - "gix-glob", - "gix-hash", - "gix-ignore", - "gix-index", - "gix-object", - "gix-path", - "gix-validate", -] - -[[package]] -name = "gix-worktree-state" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e72b00e02f3bd737caae9c20a98e70749f42ae18c8f0b68aac3210b42a0b8da" -dependencies = [ - "bstr", - "gix-features", - "gix-filter", - "gix-fs", - "gix-glob", - "gix-hash", - "gix-index", - "gix-object", - "gix-path", - "gix-worktree", - "io-close", - "thiserror", -] - -[[package]] -name = "gix-worktree-stream" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81d351819e81b97e4d5657db097fad8f91a5b2ec6d7151b2dae9c3e6dc642a66" -dependencies = [ - "gix-attributes", - "gix-features", - "gix-filter", - "gix-fs", - "gix-hash", - "gix-object", - "gix-path", - "gix-traverse", - "parking_lot 0.12.3", - "thiserror", -] - -[[package]] -name = "glob" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" - -[[package]] -name = "globset" -version = "0.4.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15f1ce686646e7f1e19bf7d5533fe443a45dbfb990e00629110797578b42fb19" -dependencies = [ - "aho-corasick", - "bstr", - "log", - "regex-automata 0.4.8", - "regex-syntax 0.8.5", -] - -[[package]] -name = "good_lp" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97630e1e456d7081c524488a87d8f8f7ed0fd3100ba10c55e3cfa7add5ce05c6" -dependencies = [ - "fnv", - "microlp", -] - -[[package]] -name = "h2" -version = "0.3.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" -dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http", - "indexmap 2.6.0", - "slab", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" - -[[package]] -name = "hashbrown" -version = "0.14.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" -dependencies = [ - "ahash", - "allocator-api2", - "serde", -] - -[[package]] -name = "hashbrown" -version = "0.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3" - -[[package]] -name = "heck" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" -dependencies = [ - "unicode-segmentation", -] - -[[package]] -name = "heck" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" - -[[package]] -name = "heck" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" - -[[package]] -name = "hermit-abi" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] - -[[package]] -name = "hermit-abi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" - -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" - -[[package]] -name = "hmac" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" -dependencies = [ - "digest", -] - -[[package]] -name = "home" -version = "0.5.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" -dependencies = [ - "windows-sys 0.52.0", -] - -[[package]] -name = "http" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - -[[package]] -name = "http-body" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" -dependencies = [ - "bytes", - "http", - "pin-project-lite", -] - -[[package]] -name = "httparse" -version = "1.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946" - -[[package]] -name = "httpdate" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" - -[[package]] -name = "human_format" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c3b1f728c459d27b12448862017b96ad4767b1ec2ec5e6434e99f1577f085b8" - -[[package]] -name = "humantime" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" - -[[package]] -name = "hyper" -version = "0.14.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c08302e8fa335b151b788c775ff56e7a03ae64ff85c548ee820fecb70356e85" -dependencies = [ - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "httparse", - "httpdate", - "itoa", - "pin-project-lite", - "socket2", - "tokio", - "tower-service", - "tracing", - "want", -] - -[[package]] -name = "hyper-rustls" -version = "0.24.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" -dependencies = [ - "futures-util", - "http", - "hyper", - "rustls", - "tokio", - "tokio-rustls", -] - -[[package]] -name = "hyper-tls" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" -dependencies = [ - "bytes", - "hyper", - "native-tls", - "tokio", - "tokio-native-tls", -] - -[[package]] -name = "iana-time-zone" -version = "0.1.61" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" -dependencies = [ - "android_system_properties", - "core-foundation-sys", - "iana-time-zone-haiku", - "js-sys", - "wasm-bindgen", - "windows-core", -] - -[[package]] -name = "iana-time-zone-haiku" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" -dependencies = [ - "cc", -] - -[[package]] -name = "icu_collections" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" -dependencies = [ - "displaydoc", - "yoke", - "zerofrom", - "zerovec", -] - -[[package]] -name = "icu_locid" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" -dependencies = [ - "displaydoc", - "litemap", - "tinystr", - "writeable", - "zerovec", -] - -[[package]] -name = "icu_locid_transform" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" -dependencies = [ - "displaydoc", - "icu_locid", - "icu_locid_transform_data", - "icu_provider", - "tinystr", - "zerovec", -] - -[[package]] -name = "icu_locid_transform_data" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" - -[[package]] -name = "icu_normalizer" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" -dependencies = [ - "displaydoc", - "icu_collections", - "icu_normalizer_data", - "icu_properties", - "icu_provider", - "smallvec", - "utf16_iter", - "utf8_iter", - "write16", - "zerovec", -] - -[[package]] -name = "icu_normalizer_data" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" - -[[package]] -name = "icu_properties" -version = "1.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" -dependencies = [ - "displaydoc", - "icu_collections", - "icu_locid_transform", - "icu_properties_data", - "icu_provider", - "tinystr", - "zerovec", -] - -[[package]] -name = "icu_properties_data" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" - -[[package]] -name = "icu_provider" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" -dependencies = [ - "displaydoc", - "icu_locid", - "icu_provider_macros", - "stable_deref_trait", - "tinystr", - "writeable", - "yoke", - "zerofrom", - "zerovec", -] - -[[package]] -name = "icu_provider_macros" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.87", -] - -[[package]] -name = "id-arena" -version = "2.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25a2bc672d1148e28034f176e01fffebb08b35768468cc954630da77a1449005" - -[[package]] -name = "ident_case" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" - -[[package]] -name = "idna" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" -dependencies = [ - "idna_adapter", - "smallvec", - "utf8_iter", -] - -[[package]] -name = "idna_adapter" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" -dependencies = [ - "icu_normalizer", - "icu_properties", -] - -[[package]] -name = "ignore" -version = "0.4.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d89fd380afde86567dfba715db065673989d6253f42b88179abd3eae47bda4b" -dependencies = [ - "crossbeam-deque", - "globset", - "log", - "memchr", - "regex-automata 0.4.8", - "same-file", - "walkdir", - "winapi-util", -] - -[[package]] -name = "imara-diff" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc9da1a252bd44cd341657203722352efc9bc0c847d06ea6d2dc1cd1135e0a01" -dependencies = [ - "ahash", - "hashbrown 0.14.5", -] - -[[package]] -name = "impl-codec" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" -dependencies = [ - "parity-scale-codec", -] - -[[package]] -name = "impl-rlp" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f28220f89297a075ddc7245cd538076ee98b01f2a9c23a53a4f1105d5a322808" -dependencies = [ - "rlp", -] - -[[package]] -name = "impl-serde" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc88fc67028ae3db0c853baa36269d398d5f45b6982f95549ff5def78c935cd" -dependencies = [ - "serde", -] - -[[package]] -name = "impl-trait-for-tuples" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "include_dir" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "923d117408f1e49d914f1a379a309cffe4f18c05cf4e3d12e613a15fc81bd0dd" -dependencies = [ - "include_dir_macros", -] - -[[package]] -name = "include_dir_macros" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cab85a7ed0bd5f0e76d93846e0147172bed2e2d3f859bcc33a8d9699cad1a75" -dependencies = [ - "proc-macro2", - "quote", -] - -[[package]] -name = "indent" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9f1a0777d972970f204fdf8ef319f1f4f8459131636d7e3c96c5d59570d0fa6" - -[[package]] -name = "indexmap" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" -dependencies = [ - "autocfg", - "hashbrown 0.12.3", - "serde", -] - -[[package]] -name = "indexmap" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" -dependencies = [ - "equivalent", - "hashbrown 0.15.1", - "serde", -] - -[[package]] -name = "indicatif" -version = "0.17.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "763a5a8f45087d6bcea4222e7b72c291a054edf80e4ef6efd2a4979878c7bea3" -dependencies = [ - "console", - "instant", - "number_prefix", - "portable-atomic", - "unicode-width", -] - -[[package]] -name = "indoc" -version = "1.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa799dd5ed20a7e349f3b4639aa80d74549c81716d9ec4f994c9b5815598306" - -[[package]] -name = "indoc" -version = "2.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b248f5224d1d606005e02c97f5aa4e88eeb230488bcc03bc9ca4d7991399f2b5" - -[[package]] -name = "inout" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" -dependencies = [ - "generic-array", -] - -[[package]] -name = "instant" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "io-close" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cadcf447f06744f8ce713d2d6239bb5bde2c357a452397a9ed90c625da390bc" -dependencies = [ - "libc", - "winapi", -] - -[[package]] -name = "ipnet" -version = "2.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddc24109865250148c2e0f3d25d4f0f479571723792d3802153c60922a4fb708" - -[[package]] -name = "is_terminal_polyfill" -version = "1.70.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" - -[[package]] -name = "itertools" -version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" -dependencies = [ - "either", -] - -[[package]] -name = "itertools" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" -dependencies = [ - "either", -] - -[[package]] -name = "itertools" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" -dependencies = [ - "either", -] - -[[package]] -name = "itoa" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" - -[[package]] -name = "jiff" -version = "0.1.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d9d414fc817d3e3d62b2598616733f76c4cc74fbac96069674739b881295c8" -dependencies = [ - "jiff-tzdb-platform", - "windows-sys 0.59.0", -] - -[[package]] -name = "jiff-tzdb" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91335e575850c5c4c673b9bd467b0e025f164ca59d0564f69d0c2ee0ffad4653" - -[[package]] -name = "jiff-tzdb-platform" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9835f0060a626fe59f160437bc725491a6af23133ea906500027d1bd2f8f4329" -dependencies = [ - "jiff-tzdb", -] - -[[package]] -name = "jobserver" -version = "0.1.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" -dependencies = [ - "libc", -] - -[[package]] -name = "js-sys" -version = "0.3.72" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9" -dependencies = [ - "wasm-bindgen", -] - -[[package]] -name = "keccak" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" -dependencies = [ - "cpufeatures", -] - -[[package]] -name = "kstring" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "558bf9508a558512042d3095138b1f7b8fe90c5467d94f9f1da28b3731c5dbd1" -dependencies = [ - "static_assertions", -] - -[[package]] -name = "lalrpop" -version = "0.20.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55cb077ad656299f160924eb2912aa147d7339ea7d69e1b5517326fdcec3c1ca" -dependencies = [ - "ascii-canvas", - "bit-set", - "ena", - "itertools 0.11.0", - "lalrpop-util", - "petgraph 0.6.5", - "pico-args", - "regex", - "regex-syntax 0.8.5", - "string_cache", - "term", - "tiny-keccak", - "unicode-xid", - "walkdir", -] - -[[package]] -name = "lalrpop-util" -version = "0.20.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "507460a910eb7b32ee961886ff48539633b788a36b65692b95f225b844c82553" -dependencies = [ - "regex-automata 0.4.8", -] - -[[package]] -name = "lambdaworks-crypto" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbc2a4da0d9e52ccfe6306801a112e81a8fc0c76aa3e4449fefeda7fef72bb34" -dependencies = [ - "lambdaworks-math", - "serde", - "sha2", - "sha3", -] - -[[package]] -name = "lambdaworks-math" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1bd2632acbd9957afc5aeec07ad39f078ae38656654043bf16e046fa2730e23" -dependencies = [ - "serde", - "serde_json", -] - -[[package]] -name = "lazy_static" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" - -[[package]] -name = "libc" -version = "0.2.161" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" - -[[package]] -name = "libloading" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" -dependencies = [ - "cfg-if", - "windows-targets 0.52.6", -] - -[[package]] -name = "libredox" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" -dependencies = [ - "bitflags 2.6.0", - "libc", - "redox_syscall 0.5.7", -] - -[[package]] -name = "linkme" -version = "0.3.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70fe496a7af8c406f877635cbf3cd6a9fac9d6f443f58691cd8afe6ce0971af4" -dependencies = [ - "linkme-impl", -] - -[[package]] -name = "linkme-impl" -version = "0.3.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b01f197a15988fb5b2ec0a5a9800c97e70771499c456ad757d63b3c5e9b96e75" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.87", -] - -[[package]] -name = "linux-raw-sys" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" - -[[package]] -name = "litemap" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "643cb0b8d4fcc284004d5fd0d67ccf61dfffadb7f75e1e71bc420f4688a3a704" - -[[package]] -name = "lock_api" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" -dependencies = [ - "autocfg", - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" - -[[package]] -name = "lsp-types" -version = "0.94.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c66bfd44a06ae10647fe3f8214762e9369fd4248df1350924b4ef9e770a85ea1" -dependencies = [ - "bitflags 1.3.2", - "serde", - "serde_json", - "serde_repr", - "url", -] - -[[package]] -name = "matchers" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" -dependencies = [ - "regex-automata 0.1.10", -] - -[[package]] -name = "matrixmultiply" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9380b911e3e96d10c1f415da0876389aaf1b56759054eeb0de7df940c456ba1a" -dependencies = [ - "autocfg", - "rawpointer", -] - -[[package]] -name = "memchr" -version = "2.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" - -[[package]] -name = "memmap2" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd3f7eed9d3848f8b98834af67102b720745c4ec028fcd0aa0239277e7de374f" -dependencies = [ - "libc", -] - -[[package]] -name = "microlp" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4190b5ca62abfbc95a81d57f4a8e3e3872289d656f3eeea5820b3046a1f81d4b" -dependencies = [ - "log", - "sprs", -] - -[[package]] -name = "mime" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" - -[[package]] -name = "mime_guess" -version = "2.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" -dependencies = [ - "mime", - "unicase", -] - -[[package]] -name = "miniz_oxide" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" -dependencies = [ - "adler2", -] - -[[package]] -name = "mio" -version = "0.8.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" -dependencies = [ - "libc", - "log", - "wasi", - "windows-sys 0.48.0", -] - -[[package]] -name = "mio" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" -dependencies = [ - "hermit-abi 0.3.9", - "libc", - "wasi", - "windows-sys 0.52.0", -] - -[[package]] -name = "monch" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b52c1b33ff98142aecea13138bd399b68aa7ab5d9546c300988c345004001eea" - -[[package]] -name = "native-tls" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" -dependencies = [ - "libc", - "log", - "openssl", - "openssl-probe", - "openssl-sys", - "schannel", - "security-framework", - "security-framework-sys", - "tempfile", -] - -[[package]] -name = "ndarray" -version = "0.16.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "882ed72dce9365842bf196bdeedf5055305f11fc8c03dee7bb0194a6cad34841" -dependencies = [ - "matrixmultiply", - "num-complex", - "num-integer", - "num-traits", - "portable-atomic", - "portable-atomic-util", - "rawpointer", -] - -[[package]] -name = "new_debug_unreachable" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" - -[[package]] -name = "nu-ansi-term" -version = "0.46.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" -dependencies = [ - "overload", - "winapi", -] - -[[package]] -name = "num-bigint" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" -dependencies = [ - "num-integer", - "num-traits", - "serde", -] - -[[package]] -name = "num-complex" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" -dependencies = [ - "num-traits", -] - -[[package]] -name = "num-conv" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" - -[[package]] -name = "num-integer" -version = "0.1.46" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" -dependencies = [ - "num-traits", -] - -[[package]] -name = "num-traits" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg", -] - -[[package]] -name = "num_threads" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9" -dependencies = [ - "libc", -] - -[[package]] -name = "number_prefix" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" - -[[package]] -name = "object" -version = "0.36.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" -dependencies = [ - "memchr", -] - -[[package]] -name = "once_cell" -version = "1.20.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" - -[[package]] -name = "oorandom" -version = "11.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b410bbe7e14ab526a0e86877eb47c6996a2bd7746f027ba551028c925390e4e9" - -[[package]] -name = "openssl" -version = "0.10.68" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6174bc48f102d208783c2c84bf931bb75927a617866870de8a4ea85597f871f5" -dependencies = [ - "bitflags 2.6.0", - "cfg-if", - "foreign-types", - "libc", - "once_cell", - "openssl-macros", - "openssl-sys", -] - -[[package]] -name = "openssl-macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.87", -] - -[[package]] -name = "openssl-probe" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" - -[[package]] -name = "openssl-sys" -version = "0.9.104" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45abf306cbf99debc8195b66b7346498d7b10c210de50418b5ccd7ceba08c741" -dependencies = [ - "cc", - "libc", - "pkg-config", - "vcpkg", -] - -[[package]] -name = "option-ext" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" - -[[package]] -name = "ordered-float" -version = "2.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68f19d67e5a2795c94e73e0bb1cc1a7edeb2e28efd39e2e1c9b7a40c1108b11c" -dependencies = [ - "num-traits", -] - -[[package]] -name = "os_pipe" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ffd2b0a5634335b135d5728d84c5e0fd726954b87111f7506a61c502280d982" -dependencies = [ - "libc", - "windows-sys 0.59.0", -] - -[[package]] -name = "overload" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" - -[[package]] -name = "parity-scale-codec" -version = "3.6.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "306800abfa29c7f16596b5970a588435e3d5b3149683d00c12b699cc19f895ee" -dependencies = [ - "arrayvec", - "bitvec", - "byte-slice-cast", - "impl-trait-for-tuples", - "parity-scale-codec-derive", - "serde", -] - -[[package]] -name = "parity-scale-codec-derive" -version = "3.6.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d830939c76d294956402033aee57a6da7b438f2294eb94864c37b0569053a42c" -dependencies = [ - "proc-macro-crate", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "parking_lot" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" -dependencies = [ - "instant", - "lock_api", - "parking_lot_core 0.8.6", -] - -[[package]] -name = "parking_lot" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" -dependencies = [ - "lock_api", - "parking_lot_core 0.9.10", -] - -[[package]] -name = "parking_lot_core" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" -dependencies = [ - "cfg-if", - "instant", - "libc", - "redox_syscall 0.2.16", - "smallvec", - "winapi", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall 0.5.7", - "smallvec", - "windows-targets 0.52.6", -] - -[[package]] -name = "paste" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" - -[[package]] -name = "path-clean" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17359afc20d7ab31fdb42bb844c8b3bb1dabd7dcf7e68428492da7f16966fcef" - -[[package]] -name = "path-dedot" -version = "3.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07ba0ad7e047712414213ff67533e6dd477af0a4e1d14fb52343e53d30ea9397" -dependencies = [ - "once_cell", -] - -[[package]] -name = "pathdiff" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d61c5ce1153ab5b689d0c074c4e7fc613e942dfb7dd9eea5ab202d2ad91fe361" -dependencies = [ - "camino", -] - -[[package]] -name = "pbkdf2" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" -dependencies = [ - "digest", -] - -[[package]] -name = "percent-encoding" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" - -[[package]] -name = "petgraph" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "467d164a6de56270bd7c4d070df81d07beace25012d5103ced4e9ff08d6afdb7" -dependencies = [ - "fixedbitset 0.2.0", - "indexmap 1.9.3", -] - -[[package]] -name = "petgraph" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" -dependencies = [ - "fixedbitset 0.4.2", - "indexmap 2.6.0", -] - -[[package]] -name = "phf_shared" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" -dependencies = [ - "siphasher", -] - -[[package]] -name = "pico-args" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" - -[[package]] -name = "pin-project" -version = "1.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be57f64e946e500c8ee36ef6331845d40a93055567ec57e8fae13efd33759b95" -dependencies = [ - "pin-project-internal", -] - -[[package]] -name = "pin-project-internal" -version = "1.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c0f5fad0874fc7abcd4d750e76917eaebbecaa2c20bde22e1dbeeba8beb758c" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.87", -] - -[[package]] -name = "pin-project-lite" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "pkg-config" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" - -[[package]] -name = "portable-atomic" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc9c68a3f6da06753e9335d63e27f6b9754dd1920d941135b7ea8224f141adb2" - -[[package]] -name = "portable-atomic-util" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90a7d5beecc52a491b54d6dd05c7a45ba1801666a5baad9fdbfc6fef8d2d206c" -dependencies = [ - "portable-atomic", -] - -[[package]] -name = "powerfmt" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" - -[[package]] -name = "ppv-lite86" -version = "0.2.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" -dependencies = [ - "zerocopy", -] - -[[package]] -name = "precomputed-hash" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" - -[[package]] -name = "pretty_assertions" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ae130e2f271fbc2ac3a40fb1d07180839cdbbe443c7a27e1e3c13c5cac0116d" -dependencies = [ - "diff", - "yansi", -] - -[[package]] -name = "primitive-types" -version = "0.12.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b34d9fd68ae0b74a41b21c03c2f62847aa0ffea044eee893b4c140b37e244e2" -dependencies = [ - "fixed-hash", - "impl-codec", - "impl-rlp", - "impl-serde", - "uint", -] - -[[package]] -name = "proc-macro-crate" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" -dependencies = [ - "toml_edit 0.22.22", -] - -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn 1.0.109", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", -] - -[[package]] -name = "proc-macro2" -version = "1.0.89" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "prodash" -version = "29.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a266d8d6020c61a437be704c5e618037588e1985c7dbb7bf8d265db84cffe325" -dependencies = [ - "bytesize", - "human_format", - "log", - "parking_lot 0.12.3", -] - -[[package]] -name = "quote" -version = "1.0.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "ra_ap_toolchain" -version = "0.0.218" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53393fc4d85057bcca4dd2d7fa24929a094bb94712980814695f56cb9aa0b1e2" -dependencies = [ - "camino", - "home", -] - -[[package]] -name = "radium" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" - -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha", - "rand_core", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom", -] - -[[package]] -name = "rawpointer" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" - -[[package]] -name = "rayon" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" -dependencies = [ - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" -dependencies = [ - "crossbeam-deque", - "crossbeam-utils", -] - -[[package]] -name = "redb" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84b1de48a7cf7ba193e81e078d17ee2b786236eed1d3f7c60f8a09545efc4925" -dependencies = [ - "libc", -] - -[[package]] -name = "redox_syscall" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" -dependencies = [ - "bitflags 1.3.2", -] - -[[package]] -name = "redox_syscall" -version = "0.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" -dependencies = [ - "bitflags 2.6.0", -] - -[[package]] -name = "redox_users" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" -dependencies = [ - "getrandom", - "libredox", - "thiserror", -] - -[[package]] -name = "regex" -version = "1.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata 0.4.8", - "regex-syntax 0.8.5", -] - -[[package]] -name = "regex-automata" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" -dependencies = [ - "regex-syntax 0.6.29", -] - -[[package]] -name = "regex-automata" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax 0.8.5", -] - -[[package]] -name = "regex-syntax" -version = "0.6.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" - -[[package]] -name = "regex-syntax" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" - -[[package]] -name = "relative-path" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba39f3699c378cd8970968dcbff9c43159ea4cfbd88d43c00b22f2ef10a435d2" - -[[package]] -name = "reqwest" -version = "0.11.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" -dependencies = [ - "async-compression", - "base64 0.21.7", - "bytes", - "encoding_rs", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "hyper", - "hyper-rustls", - "hyper-tls", - "ipnet", - "js-sys", - "log", - "mime", - "mime_guess", - "native-tls", - "once_cell", - "percent-encoding", - "pin-project-lite", - "rustls", - "rustls-native-certs", - "rustls-pemfile", - "serde", - "serde_json", - "serde_urlencoded", - "sync_wrapper", - "system-configuration", - "tokio", - "tokio-native-tls", - "tokio-rustls", - "tokio-util", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "wasm-streams", - "web-sys", - "webpki-roots", - "winreg", -] - -[[package]] -name = "rfc6979" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" -dependencies = [ - "hmac", - "subtle", -] - -[[package]] -name = "ring" -version = "0.17.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" -dependencies = [ - "cc", - "cfg-if", - "getrandom", - "libc", - "spin", - "untrusted", - "windows-sys 0.52.0", -] - -[[package]] -name = "rlp" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb919243f34364b6bd2fc10ef797edbfa75f33c252e7998527479c6d6b47e1ec" -dependencies = [ - "bytes", - "rustc-hex", -] - -[[package]] -name = "rstest" -version = "0.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de1bb486a691878cd320c2f0d319ba91eeaa2e894066d8b5f8f117c000e9d962" -dependencies = [ - "futures", - "futures-timer", - "rstest_macros", - "rustc_version", -] - -[[package]] -name = "rstest_macros" -version = "0.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290ca1a1c8ca7edb7c3283bd44dc35dd54fdec6253a3912e201ba1072018fca8" -dependencies = [ - "cfg-if", - "proc-macro2", - "quote", - "rustc_version", - "syn 1.0.109", - "unicode-ident", -] - -[[package]] -name = "rust-analyzer-salsa" -version = "0.17.0-pre.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719825638c59fd26a55412a24561c7c5bcf54364c88b9a7a04ba08a6eafaba8d" -dependencies = [ - "indexmap 2.6.0", - "lock_api", - "oorandom", - "parking_lot 0.12.3", - "rust-analyzer-salsa-macros", - "rustc-hash", - "smallvec", - "tracing", - "triomphe", -] - -[[package]] -name = "rust-analyzer-salsa-macros" -version = "0.17.0-pre.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d96498e9684848c6676c399032ebc37c52da95ecbefa83d71ccc53b9f8a4a8e" -dependencies = [ - "heck 0.4.1", - "proc-macro2", - "quote", - "syn 2.0.87", -] - -[[package]] -name = "rustc-demangle" -version = "0.1.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" - -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - -[[package]] -name = "rustc-hex" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" - -[[package]] -name = "rustc_version" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" -dependencies = [ - "semver", -] - -[[package]] -name = "rustix" -version = "0.38.39" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "375116bee2be9ed569afe2154ea6a99dfdffd257f533f187498c2a8f5feaf4ee" -dependencies = [ - "bitflags 2.6.0", - "errno", - "libc", - "linux-raw-sys", - "windows-sys 0.52.0", -] - -[[package]] -name = "rustls" -version = "0.21.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" -dependencies = [ - "log", - "ring", - "rustls-webpki", - "sct", -] - -[[package]] -name = "rustls-native-certs" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" -dependencies = [ - "openssl-probe", - "rustls-pemfile", - "schannel", - "security-framework", -] - -[[package]] -name = "rustls-pemfile" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" -dependencies = [ - "base64 0.21.7", -] - -[[package]] -name = "rustls-webpki" -version = "0.101.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" -dependencies = [ - "ring", - "untrusted", -] - -[[package]] -name = "rustversion" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" - -[[package]] -name = "ryu" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" - -[[package]] -name = "salsa" -version = "0.16.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b84d9f96071f3f3be0dc818eae3327625d8ebc95b58da37d6850724f31d3403" -dependencies = [ - "crossbeam-utils", - "indexmap 1.9.3", - "lock_api", - "log", - "oorandom", - "parking_lot 0.11.2", - "rustc-hash", - "salsa-macros", - "smallvec", -] - -[[package]] -name = "salsa-macros" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd3904a4ba0a9d0211816177fd34b04c7095443f8cdacd11175064fe541c8fe2" -dependencies = [ - "heck 0.3.3", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "salsa20" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97a22f5af31f73a954c10289c93e8a50cc23d971e80ee446f1f6f7137a088213" -dependencies = [ - "cipher", -] - -[[package]] -name = "same-file" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "scarb" -version = "2.8.4" -source = "git+https://github.com/software-mansion/scarb?rev=2aa4e19#2aa4e193ec930417a8789ceafcfb9dc29963f8e7" -dependencies = [ - "anyhow", - "async-trait", - "cairo-lang-compiler", - "cairo-lang-defs", - "cairo-lang-diagnostics", - "cairo-lang-filesystem", - "cairo-lang-formatter", - "cairo-lang-lowering", - "cairo-lang-macro", - "cairo-lang-macro-stable", - "cairo-lang-parser", - "cairo-lang-semantic", - "cairo-lang-sierra", - "cairo-lang-sierra-to-casm", - "cairo-lang-starknet", - "cairo-lang-starknet-classes", - "cairo-lang-syntax", - "cairo-lang-test-plugin", - "cairo-lang-utils", - "camino", - "clap", - "convert_case", - "create-output-dir", - "data-encoding", - "deno_task_shell", - "derive_builder", - "dialoguer 0.11.0", - "directories", - "dunce", - "fs4", - "fs_extra", - "futures", - "gix", - "gix-path", - "glob", - "ignore", - "include_dir", - "indoc 2.0.5", - "itertools 0.12.1", - "libloading", - "once_cell", - "pathdiff", - "petgraph 0.6.5", - "ra_ap_toolchain", - "redb", - "reqwest", - "scarb-build-metadata", - "scarb-metadata 1.12.0", - "scarb-stable-hash 1.0.0 (git+https://github.com/software-mansion/scarb?rev=2aa4e19)", - "scarb-ui", - "semver", - "serde", - "serde-untagged", - "serde-value", - "serde_json", - "serde_repr", - "sha2", - "smallvec", - "smol_str", - "tar", - "thiserror", - "tokio", - "toml 0.8.19", - "toml_edit 0.22.22", - "tracing", - "tracing-subscriber", - "typed-builder", - "url", - "walkdir", - "which", - "windows-sys 0.59.0", - "zip", - "zstd", -] - -[[package]] -name = "scarb-build-metadata" -version = "2.8.4" -source = "git+https://github.com/software-mansion/scarb?rev=2aa4e19#2aa4e193ec930417a8789ceafcfb9dc29963f8e7" -dependencies = [ - "cargo_metadata", -] - -[[package]] -name = "scarb-metadata" -version = "1.12.0" -source = "git+https://github.com/software-mansion/scarb?rev=2aa4e19#2aa4e193ec930417a8789ceafcfb9dc29963f8e7" -dependencies = [ - "camino", - "derive_builder", - "semver", - "serde", - "serde_json", - "thiserror", -] - -[[package]] -name = "scarb-metadata" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a8b71f63999dbb6d269fbc6fd61310016ab3a160fb13e52a6511a2b904359f0" -dependencies = [ - "camino", - "semver", - "serde", - "serde_json", - "thiserror", -] - -[[package]] -name = "scarb-stable-hash" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1902536b23a05dd165d3992865870aaf1b0650317767cbf171ed2ca5903732a9" -dependencies = [ - "data-encoding", - "xxhash-rust", -] - -[[package]] -name = "scarb-stable-hash" -version = "1.0.0" -source = "git+https://github.com/software-mansion/scarb?rev=2aa4e19#2aa4e193ec930417a8789ceafcfb9dc29963f8e7" -dependencies = [ - "data-encoding", - "xxhash-rust", -] - -[[package]] -name = "scarb-ui" -version = "0.1.5" -source = "git+https://github.com/software-mansion/scarb?rev=2aa4e19#2aa4e193ec930417a8789ceafcfb9dc29963f8e7" -dependencies = [ - "anyhow", - "camino", - "clap", - "console", - "indicatif", - "scarb-metadata 1.12.0", - "serde", - "serde_json", - "tracing-core", -] - -[[package]] -name = "schannel" -version = "0.1.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01227be5826fa0690321a2ba6c5cd57a19cf3f6a09e76973b58e61de6ab9d1c1" -dependencies = [ - "windows-sys 0.59.0", -] - -[[package]] -name = "schemars" -version = "0.8.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09c024468a378b7e36765cd36702b7a90cc3cba11654f6685c8f233408e89e92" -dependencies = [ - "dyn-clone", - "indexmap 1.9.3", - "schemars_derive", - "serde", - "serde_json", -] - -[[package]] -name = "schemars_derive" -version = "0.8.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1eee588578aff73f856ab961cd2f79e36bc45d7ded33a7562adba4667aecc0e" -dependencies = [ - "proc-macro2", - "quote", - "serde_derive_internals", - "syn 2.0.87", -] - -[[package]] -name = "scopeguard" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" - -[[package]] -name = "scrypt" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f9e24d2b632954ded8ab2ef9fea0a0c769ea56ea98bddbafbad22caeeadf45d" -dependencies = [ - "hmac", - "pbkdf2", - "salsa20", - "sha2", -] - -[[package]] -name = "sct" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" -dependencies = [ - "ring", - "untrusted", -] - -[[package]] -name = "security-framework" -version = "2.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" -dependencies = [ - "bitflags 2.6.0", - "core-foundation 0.9.4", - "core-foundation-sys", - "libc", - "security-framework-sys", -] - -[[package]] -name = "security-framework-sys" -version = "2.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea4a292869320c0272d7bc55a5a6aafaff59b4f63404a003887b679a2e05b4b6" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "semver" -version = "1.0.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" -dependencies = [ - "serde", -] - -[[package]] -name = "serde" -version = "1.0.214" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f55c3193aca71c12ad7890f1785d2b73e1b9f63a0bbc353c08ef26fe03fc56b5" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde-untagged" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2676ba99bd82f75cae5cbd2c8eda6fa0b8760f18978ea840e980dd5567b5c5b6" -dependencies = [ - "erased-serde", - "serde", - "typeid", -] - -[[package]] -name = "serde-value" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3a1a3341211875ef120e117ea7fd5228530ae7e7036a779fdc9117be6b3282c" -dependencies = [ - "ordered-float", - "serde", -] - -[[package]] -name = "serde_derive" -version = "1.0.214" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.87", -] - -[[package]] -name = "serde_derive_internals" -version = "0.29.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.87", -] - -[[package]] -name = "serde_json" -version = "1.0.132" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03" -dependencies = [ - "itoa", - "memchr", - "ryu", - "serde", -] - -[[package]] -name = "serde_json_pythonic" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62212da9872ca2a0cad0093191ee33753eddff9266cbbc1b4a602d13a3a768db" -dependencies = [ - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "serde_repr" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.87", -] - -[[package]] -name = "serde_spanned" -version = "0.6.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" -dependencies = [ - "serde", -] - -[[package]] -name = "serde_urlencoded" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" -dependencies = [ - "form_urlencoded", - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "serde_with" -version = "2.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07ff71d2c147a7b57362cead5e22f772cd52f6ab31cfcd9edcd7f6aeb2a0afbe" -dependencies = [ - "base64 0.13.1", - "chrono", - "hex", - "indexmap 1.9.3", - "serde", - "serde_json", - "serde_with_macros", - "time", -] - -[[package]] -name = "serde_with_macros" -version = "2.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "881b6f881b17d13214e5d494c939ebab463d01264ce1811e9d4ac3a882e7695f" -dependencies = [ - "darling", - "proc-macro2", - "quote", - "syn 2.0.87", -] - -[[package]] -name = "sha1_smol" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbfa15b3dddfee50a0fff136974b3e1bde555604ba463834a7eb7deb6417705d" - -[[package]] -name = "sha2" -version = "0.10.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - -[[package]] -name = "sha3" -version = "0.10.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" -dependencies = [ - "digest", - "keccak", -] - -[[package]] -name = "sharded-slab" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" -dependencies = [ - "lazy_static", -] - -[[package]] -name = "shell-words" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde" - -[[package]] -name = "shlex" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" - -[[package]] -name = "signal-hook" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801" -dependencies = [ - "libc", - "signal-hook-registry", -] - -[[package]] -name = "signal-hook-mio" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34db1a06d485c9142248b7a054f034b349b212551f3dfd19c94d45a754a217cd" -dependencies = [ - "libc", - "mio 0.8.11", - "signal-hook", -] - -[[package]] -name = "signal-hook-registry" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" -dependencies = [ - "libc", -] - -[[package]] -name = "siphasher" -version = "0.3.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" - -[[package]] -name = "slab" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" -dependencies = [ - "autocfg", -] - -[[package]] -name = "smallvec" -version = "1.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" - -[[package]] -name = "smol_str" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd538fb6910ac1099850255cf94a94df6551fbdd602454387d0adb2d1ca6dead" -dependencies = [ - "serde", -] - -[[package]] -name = "socket2" -version = "0.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" dependencies = [ "libc", - "windows-sys 0.52.0", -] - -[[package]] -name = "spin" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" - -[[package]] -name = "sprs" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "704ef26d974e8a452313ed629828cd9d4e4fa34667ca1ad9d6b1fffa43c6e166" -dependencies = [ - "ndarray", - "num-complex", - "num-traits", - "smallvec", -] - -[[package]] -name = "stable_deref_trait" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" - -[[package]] -name = "starknet" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36f8002bf3d750dd2c0434aca8b5e88e2438cd6c452f4c18f34d0a8a9f42cb1a" -dependencies = [ - "starknet-accounts", - "starknet-contract", - "starknet-core 0.9.0", - "starknet-crypto", - "starknet-ff", - "starknet-macros", - "starknet-providers", - "starknet-signers", -] - -[[package]] -name = "starknet-accounts" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8e39a5807a735343493781dd5e640c4af838de470b0a73f420bed642fdc2ff1" -dependencies = [ - "async-trait", - "auto_impl", - "starknet-core 0.9.0", - "starknet-providers", - "starknet-signers", - "thiserror", -] - -[[package]] -name = "starknet-contract" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4996991356cd0e9499c663680eba7e77de4109e4995f652c1608899a65c09ee" -dependencies = [ - "serde", - "serde_json", - "serde_with", - "starknet-accounts", - "starknet-core 0.9.0", - "starknet-providers", - "thiserror", -] - -[[package]] -name = "starknet-core" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b15034c07557615f6bea248cb2ac91a103f56792c515319025a5edc4de2a60e" -dependencies = [ - "base64 0.21.7", - "flate2", - "hex", - "serde", - "serde_json", - "serde_json_pythonic", - "serde_with", - "sha3", - "starknet-crypto", - "starknet-ff", -] - -[[package]] -name = "starknet-core" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ed286d637e34fb8ae1cd2f9615120ec8ff38d1cffd311ed7fdd497cdd2bd01f" -dependencies = [ - "base64 0.21.7", - "flate2", - "hex", - "serde", - "serde_json", - "serde_json_pythonic", - "serde_with", - "sha3", - "starknet-crypto", - "starknet-ff", -] - -[[package]] -name = "starknet-crypto" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e2c30c01e8eb0fc913c4ee3cf676389fffc1d1182bfe5bb9670e4e72e968064" -dependencies = [ - "crypto-bigint", - "hex", - "hmac", - "num-bigint", - "num-integer", - "num-traits", - "rfc6979", - "sha2", - "starknet-crypto-codegen", - "starknet-curve", - "starknet-ff", - "zeroize", -] - -[[package]] -name = "starknet-crypto-codegen" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbc159a1934c7be9761c237333a57febe060ace2bc9e3b337a59a37af206d19f" -dependencies = [ - "starknet-curve", - "starknet-ff", - "syn 2.0.87", -] - -[[package]] -name = "starknet-curve" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1c383518bb312751e4be80f53e8644034aa99a0afb29d7ac41b89a997db875b" -dependencies = [ - "starknet-ff", -] - -[[package]] -name = "starknet-ff" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7abf1b44ec5b18d87c1ae5f54590ca9d0699ef4dd5b2ffa66fc97f24613ec585" -dependencies = [ - "ark-ff", - "bigdecimal", - "crypto-bigint", - "getrandom", - "hex", - "num-bigint", - "serde", -] - -[[package]] -name = "starknet-macros" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95d549d3078bdbe775d0deaa8ddb57a19942989ce7c1f2dfd60beeb322bb4945" -dependencies = [ - "starknet-core 0.10.0", - "syn 2.0.87", -] - -[[package]] -name = "starknet-providers" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a4bd1c262936543d6d14d299f476585e8c9625a4e284d9255b54f1c2e68e64a" -dependencies = [ - "async-trait", - "auto_impl", - "ethereum-types", - "flate2", "log", - "reqwest", - "serde", - "serde_json", - "serde_with", - "starknet-core 0.9.0", - "thiserror", - "url", -] - -[[package]] -name = "starknet-signers" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c5eb659e66b56ceafb9025cd601226d8f34d273f1b826cd4053ab6333ff0898" -dependencies = [ - "async-trait", - "auto_impl", - "crypto-bigint", - "eth-keystore", - "rand", - "starknet-core 0.9.0", - "starknet-crypto", - "thiserror", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", ] [[package]] -name = "starknet-types-core" -version = "0.1.7" +name = "object" +version = "0.36.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa1b9e01ccb217ab6d475c5cda05dbb22c30029f7bb52b192a010a00d77a3d74" +checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" dependencies = [ - "lambdaworks-crypto", - "lambdaworks-math", - "lazy_static", - "num-bigint", - "num-integer", - "num-traits", - "serde", + "memchr", ] [[package]] -name = "static_assertions" -version = "1.1.0" +name = "once_cell" +version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" [[package]] -name = "string_cache" -version = "0.8.7" +name = "openssl" +version = "0.10.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b" +checksum = "6174bc48f102d208783c2c84bf931bb75927a617866870de8a4ea85597f871f5" dependencies = [ - "new_debug_unreachable", + "bitflags 2.6.0", + "cfg-if", + "foreign-types", + "libc", "once_cell", - "parking_lot 0.12.3", - "phf_shared", - "precomputed-hash", -] - -[[package]] -name = "strsim" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" - -[[package]] -name = "strum" -version = "0.24.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f" - -[[package]] -name = "strum" -version = "0.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" - -[[package]] -name = "strum_macros" -version = "0.24.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" -dependencies = [ - "heck 0.4.1", - "proc-macro2", - "quote", - "rustversion", - "syn 1.0.109", -] - -[[package]] -name = "strum_macros" -version = "0.25.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" -dependencies = [ - "heck 0.4.1", - "proc-macro2", - "quote", - "rustversion", - "syn 2.0.87", -] - -[[package]] -name = "subtle" -version = "2.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" - -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.87" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", + "openssl-macros", + "openssl-sys", ] [[package]] -name = "sync_wrapper" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" - -[[package]] -name = "synstructure" -version = "0.13.1" +name = "openssl-macros" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", -] - -[[package]] -name = "system-configuration" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" -dependencies = [ - "bitflags 1.3.2", - "core-foundation 0.9.4", - "system-configuration-sys", -] - -[[package]] -name = "system-configuration-sys" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" -dependencies = [ - "core-foundation-sys", - "libc", + "syn", ] [[package]] -name = "tap" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" - -[[package]] -name = "tar" -version = "0.4.43" +name = "openssl-probe" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c65998313f8e17d0d553d28f91a0df93e4dbbbf770279c7bc21ca0f09ea1a1f6" -dependencies = [ - "filetime", - "libc", - "xattr", -] +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] -name = "tempfile" -version = "3.13.0" +name = "openssl-sys" +version = "0.9.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0f2c9fc62d0beef6951ccffd757e241266a2c833136efbe35af6cd2567dca5b" +checksum = "45abf306cbf99debc8195b66b7346498d7b10c210de50418b5ccd7ceba08c741" dependencies = [ - "cfg-if", - "fastrand", - "once_cell", - "rustix", - "windows-sys 0.59.0", + "cc", + "libc", + "pkg-config", + "vcpkg", ] [[package]] -name = "term" -version = "0.7.0" +name = "percent-encoding" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c59df8ac95d96ff9bede18eb7300b0fda5e5d8d90960e76f8e14ae765eedbf1f" -dependencies = [ - "dirs-next", - "rustversion", - "winapi", -] +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] -name = "termcolor" -version = "1.4.1" +name = "pin-project-lite" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" -dependencies = [ - "winapi-util", -] +checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" [[package]] -name = "test-case" -version = "2.2.2" +name = "pin-utils" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21d6cf5a7dffb3f9dceec8e6b8ca528d9bd71d36c9f074defb548ce161f598c0" -dependencies = [ - "test-case-macros", -] +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] -name = "test-case-macros" -version = "2.2.2" +name = "pkg-config" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e45b7bf6e19353ddd832745c8fcf77a17a93171df7151187f26623f2b75b5b26" -dependencies = [ - "cfg-if", - "proc-macro-error", - "proc-macro2", - "quote", - "syn 1.0.109", -] +checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" [[package]] -name = "test-log" -version = "0.2.16" +name = "proc-macro2" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dffced63c2b5c7be278154d76b479f9f9920ed34e7574201407f0b14e2bbb93" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" dependencies = [ - "env_logger 0.11.5", - "test-log-macros", - "tracing-subscriber", + "unicode-ident", ] [[package]] -name = "test-log-macros" -version = "0.2.16" +name = "quote" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5999e24eaa32083191ba4e425deb75cdf25efefabe5aaccb7446dd0d4122a3f5" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", - "quote", - "syn 2.0.87", ] [[package]] -name = "thiserror" -version = "1.0.68" +name = "regex" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02dd99dc800bbb97186339685293e1cc5d9df1f8fae2d0aecd9ff1c77efea892" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ - "thiserror-impl", + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", ] [[package]] -name = "thiserror-impl" -version = "1.0.68" +name = "regex-automata" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7c61ec9a6f64d2793d8a45faba21efbe3ced62a886d44c36a009b2b519b4c7e" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.87", + "aho-corasick", + "memchr", + "regex-syntax", ] [[package]] -name = "thread_local" -version = "1.1.8" +name = "regex-syntax" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" -dependencies = [ - "cfg-if", - "once_cell", -] +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] -name = "time" -version = "0.3.36" +name = "reqwest" +version = "0.11.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" +checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" dependencies = [ - "deranged", - "itoa", - "libc", - "num-conv", - "num_threads", - "powerfmt", + "base64", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-tls", + "ipnet", + "js-sys", + "log", + "mime", + "mime_guess", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls-pemfile", "serde", - "time-core", - "time-macros", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "system-configuration", + "tokio", + "tokio-native-tls", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winreg", ] [[package]] -name = "time-core" -version = "0.1.2" +name = "rustc-demangle" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] -name = "time-macros" -version = "0.2.18" +name = "rustix" +version = "0.38.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" +checksum = "f93dc38ecbab2eb790ff964bb77fa94faf256fd3e73285fd7ba0903b76bedb85" dependencies = [ - "num-conv", - "time-core", + "bitflags 2.6.0", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.59.0", ] [[package]] -name = "tiny-keccak" -version = "2.0.2" +name = "rustls-pemfile" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" dependencies = [ - "crunchy", + "base64", ] [[package]] -name = "tinystr" -version = "0.7.6" +name = "ryu" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" dependencies = [ - "displaydoc", - "zerovec", + "winapi-util", ] [[package]] -name = "tinyvec" -version = "1.8.0" +name = "scarb-metadata" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" +checksum = "1a8b71f63999dbb6d269fbc6fd61310016ab3a160fb13e52a6511a2b904359f0" dependencies = [ - "tinyvec_macros", + "camino", + "semver", + "serde", + "serde_json", + "thiserror 1.0.69", ] [[package]] -name = "tinyvec_macros" -version = "0.1.1" +name = "schannel" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" +checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" +dependencies = [ + "windows-sys 0.59.0", +] [[package]] -name = "tokio" -version = "1.41.1" +name = "security-framework" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22cfb5bee7a6a52939ca9224d6ac897bb669134078daa8735560897f69de4d33" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ - "backtrace", - "bytes", + "bitflags 2.6.0", + "core-foundation", + "core-foundation-sys", "libc", - "mio 1.0.2", - "parking_lot 0.12.3", - "pin-project-lite", - "signal-hook-registry", - "socket2", - "tokio-macros", - "windows-sys 0.52.0", + "security-framework-sys", ] [[package]] -name = "tokio-macros" -version = "2.4.0" +name = "security-framework-sys" +version = "2.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" +checksum = "fa39c7303dc58b5543c94d22c1766b0d31f2ee58306363ea622b10bbc075eaa2" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.87", + "core-foundation-sys", + "libc", ] [[package]] -name = "tokio-native-tls" -version = "0.3.1" +name = "semver" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" dependencies = [ - "native-tls", - "tokio", + "serde", ] [[package]] -name = "tokio-rustls" -version = "0.24.1" +name = "serde" +version = "1.0.216" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +checksum = "0b9781016e935a97e8beecf0c933758c97a5520d32930e460142b4cd80c6338e" dependencies = [ - "rustls", - "tokio", + "serde_derive", ] [[package]] -name = "tokio-util" -version = "0.7.12" +name = "serde_derive" +version = "1.0.216" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" +checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e" dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "pin-project-lite", - "tokio", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "toml" -version = "0.4.10" +name = "serde_json" +version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "758664fc71a3a69038656bee8b6be6477d2a6c315a6b81f7081f591bffa4111f" +checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377" dependencies = [ + "itoa", + "memchr", + "ryu", "serde", ] [[package]] -name = "toml" -version = "0.8.19" +name = "serde_urlencoded" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" dependencies = [ + "form_urlencoded", + "itoa", + "ryu", "serde", - "serde_spanned", - "toml_datetime", - "toml_edit 0.22.22", ] [[package]] -name = "toml_datetime" -version = "0.6.8" +name = "shlex" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" -dependencies = [ - "serde", -] +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] -name = "toml_edit" -version = "0.19.15" +name = "slab" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" dependencies = [ - "indexmap 2.6.0", - "toml_datetime", - "winnow 0.5.40", + "autocfg", ] [[package]] -name = "toml_edit" -version = "0.22.22" +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "socket2" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" +checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8" dependencies = [ - "indexmap 2.6.0", - "serde", - "serde_spanned", - "toml_datetime", - "winnow 0.6.20", + "libc", + "windows-sys 0.52.0", ] [[package]] -name = "tower" -version = "0.4.13" +name = "spdx" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +checksum = "bae30cc7bfe3656d60ee99bf6836f472b0c53dddcbf335e253329abb16e535a2" dependencies = [ - "futures-core", - "futures-util", - "pin-project", - "pin-project-lite", - "tower-layer", - "tower-service", + "smallvec", ] [[package]] -name = "tower-layer" -version = "0.3.3" +name = "stable_deref_trait" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] -name = "tower-lsp" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4ba052b54a6627628d9b3c34c176e7eda8359b7da9acd497b9f20998d118508" +name = "starknet-contract-verifier" +version = "1.0.0-rc.1" dependencies = [ - "async-trait", - "auto_impl", - "bytes", - "dashmap 5.5.3", - "futures", - "httparse", - "lsp-types", - "memchr", + "anyhow", + "backon", + "camino", + "clap", + "itertools", + "regex", + "reqwest", + "scarb-metadata", + "semver", "serde", "serde_json", - "tokio", - "tokio-util", - "tower", - "tower-lsp-macros", - "tracing", + "spdx", + "thiserror 2.0.6", + "url", + "walkdir", ] [[package]] -name = "tower-lsp-macros" -version = "0.9.0" +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "syn" +version = "2.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84fd902d4e0b9a4b27f2f440108dc034e1758628a9b702f8ec61ad66355422fa" +checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "unicode-ident", ] [[package]] -name = "tower-service" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" - -[[package]] -name = "tracing" -version = "0.1.40" +name = "sync_wrapper" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" -dependencies = [ - "pin-project-lite", - "tracing-attributes", - "tracing-core", -] +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" [[package]] -name = "tracing-attributes" -version = "0.1.27" +name = "synstructure" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", -] - -[[package]] -name = "tracing-chrome" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf0a738ed5d6450a9fb96e86a23ad808de2b727fd1394585da5cdd6788ffe724" -dependencies = [ - "serde_json", - "tracing-core", - "tracing-subscriber", + "syn", ] [[package]] -name = "tracing-core" -version = "0.1.32" +name = "system-configuration" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" dependencies = [ - "once_cell", - "valuable", + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys", ] [[package]] -name = "tracing-log" -version = "0.2.0" +name = "system-configuration-sys" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" dependencies = [ - "log", - "once_cell", - "tracing-core", + "core-foundation-sys", + "libc", ] [[package]] -name = "tracing-subscriber" -version = "0.3.18" +name = "tempfile" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c" dependencies = [ - "matchers", - "nu-ansi-term", + "cfg-if", + "fastrand", "once_cell", - "regex", - "sharded-slab", - "smallvec", - "thread_local", - "tracing", - "tracing-core", - "tracing-log", + "rustix", + "windows-sys 0.59.0", ] [[package]] -name = "triomphe" -version = "0.1.14" +name = "thiserror" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef8f7726da4807b58ea5c96fdc122f80702030edc33b35aff9190a51148ccc85" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ - "serde", - "stable_deref_trait", + "thiserror-impl 1.0.69", ] [[package]] -name = "try-lock" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" - -[[package]] -name = "typed-builder" -version = "0.20.0" +name = "thiserror" +version = "2.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e14ed59dc8b7b26cacb2a92bad2e8b1f098806063898ab42a3bd121d7d45e75" +checksum = "8fec2a1820ebd077e2b90c4df007bebf344cd394098a13c563957d0afc83ea47" dependencies = [ - "typed-builder-macro", + "thiserror-impl 2.0.6", ] [[package]] -name = "typed-builder-macro" -version = "0.20.0" +name = "thiserror-impl" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "560b82d656506509d43abe30e0ba64c56b1953ab3d4fe7ba5902747a7a3cedd5" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn", ] [[package]] -name = "typeid" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e13db2e0ccd5e14a544e8a246ba2312cd25223f616442d7f2cb0e3db614236e" - -[[package]] -name = "typenum" -version = "1.17.0" +name = "thiserror-impl" +version = "2.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +checksum = "d65750cab40f4ff1929fb1ba509e9914eb756131cef4210da8d5d700d26f6312" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] [[package]] -name = "uint" -version = "0.9.5" +name = "tinystr" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" +checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" dependencies = [ - "byteorder", - "crunchy", - "hex", - "static_assertions", + "displaydoc", + "zerovec", ] [[package]] -name = "uluru" -version = "3.1.0" +name = "tokio" +version = "1.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c8a2469e56e6e5095c82ccd3afb98dad95f7af7929aab6d8ba8d6e0f73657da" +checksum = "5cec9b21b0450273377fc97bd4c33a8acffc8c996c987a7c5b319a0083707551" dependencies = [ - "arrayvec", + "backtrace", + "bytes", + "libc", + "mio", + "pin-project-lite", + "socket2", + "windows-sys 0.52.0", ] [[package]] -name = "unescaper" -version = "0.1.5" +name = "tokio-native-tls" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c878a167baa8afd137494101a688ef8c67125089ff2249284bd2b5f9bfedb815" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" dependencies = [ - "thiserror", + "native-tls", + "tokio", ] [[package]] -name = "unicase" -version = "2.8.0" +name = "tokio-util" +version = "0.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e51b68083f157f853b6379db119d1c1be0e6e4dec98101079dec41f6f5cf6df" +checksum = "d7fcaa8d55a2bdd6b83ace262b016eca0d79ee02818c5c1bcdf0305114081078" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", +] [[package]] -name = "unicode-bom" -version = "2.0.3" +name = "tower-service" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eec5d1121208364f6793f7d2e222bf75a915c19557537745b195b253dd64217" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] -name = "unicode-ident" -version = "1.0.13" +name = "tracing" +version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" +dependencies = [ + "pin-project-lite", + "tracing-core", +] [[package]] -name = "unicode-normalization" -version = "0.1.24" +name = "tracing-core" +version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" dependencies = [ - "tinyvec", + "once_cell", ] [[package]] -name = "unicode-segmentation" -version = "1.12.0" +name = "try-lock" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] -name = "unicode-width" -version = "0.1.14" +name = "unicase" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" +checksum = "7e51b68083f157f853b6379db119d1c1be0e6e4dec98101079dec41f6f5cf6df" [[package]] -name = "unicode-xid" -version = "0.2.6" +name = "unicode-ident" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" [[package]] -name = "untrusted" -version = "0.9.0" +name = "unicode-width" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" +checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" [[package]] name = "url" -version = "2.5.3" +version = "2.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d157f1b96d14500ffdc1f10ba712e780825526c03d9a49b4d0324b0d9113ada" +checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" dependencies = [ "form_urlencoded", "idna", "percent-encoding", - "serde", ] [[package]] @@ -6222,82 +1345,12 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" -[[package]] -name = "uuid" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" -dependencies = [ - "getrandom", - "serde", -] - -[[package]] -name = "valuable" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" - [[package]] name = "vcpkg" version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" -[[package]] -name = "version_check" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" - -[[package]] -name = "voyager-resolver-cairo" -version = "0.1.0" -dependencies = [ - "anyhow", - "cairo-lang-casm", - "cairo-lang-compiler", - "cairo-lang-debug", - "cairo-lang-defs", - "cairo-lang-diagnostics", - "cairo-lang-filesystem", - "cairo-lang-formatter", - "cairo-lang-language-server", - "cairo-lang-lowering", - "cairo-lang-parser", - "cairo-lang-plugins", - "cairo-lang-project", - "cairo-lang-semantic", - "cairo-lang-sierra-generator", - "cairo-lang-starknet", - "cairo-lang-syntax", - "cairo-lang-test-utils", - "cairo-lang-utils", - "camino", - "dyn-compiler", - "env_logger 0.9.3", - "indoc 1.0.9", - "itertools 0.10.5", - "petgraph 0.5.1", - "pretty_assertions", - "regex", - "rstest", - "salsa", - "scarb", - "scarb-metadata 1.13.0", - "scarb-ui", - "serde", - "serde_json", - "smol_str", - "starknet", - "test-case", - "test-case-macros", - "test-log", - "toml 0.4.10", - "toml_edit 0.19.15", - "tracing", -] - [[package]] name = "walkdir" version = "2.5.0" @@ -6325,9 +1378,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.95" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e" +checksum = "a474f6281d1d70c17ae7aa6a613c87fce69a127e2624002df63dcb39d6cf6396" dependencies = [ "cfg-if", "once_cell", @@ -6336,36 +1389,36 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.95" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358" +checksum = "5f89bb38646b4f81674e8f5c3fb81b562be1fd936d84320f3264486418519c79" dependencies = [ "bumpalo", "log", - "once_cell", "proc-macro2", "quote", - "syn 2.0.87", + "syn", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.45" +version = "0.4.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc7ec4f8827a71586374db3e87abdb5a2bb3a15afed140221307c3ec06b1f63b" +checksum = "38176d9b44ea84e9184eff0bc34cc167ed044f816accfe5922e54d84cf48eca2" dependencies = [ "cfg-if", "js-sys", + "once_cell", "wasm-bindgen", "web-sys", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.95" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56" +checksum = "2cc6181fd9a7492eef6fef1f33961e3695e4579b9872a6f7c83aee556666d4fe" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -6373,81 +1426,33 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.95" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" +checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.95" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" - -[[package]] -name = "wasm-streams" -version = "0.4.2" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65" -dependencies = [ - "futures-util", - "js-sys", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", -] +checksum = "943aab3fdaaa029a6e0271b35ea10b72b943135afe9bffca82384098ad0e06a6" [[package]] name = "web-sys" -version = "0.3.72" +version = "0.3.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6488b90108c040df0fe62fa815cbdee25124641df01814dd7282749234c6112" +checksum = "04dd7223427d52553d3702c004d3b2fe07c148165faa56313cb00211e31c12bc" dependencies = [ "js-sys", "wasm-bindgen", ] -[[package]] -name = "webpki-roots" -version = "0.25.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" - -[[package]] -name = "which" -version = "5.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bf3ea8596f3a0dd5980b46430f2058dfe2c36a27ccfbb1845d6fbfcd9ba6e14" -dependencies = [ - "either", - "home", - "once_cell", - "rustix", - "windows-sys 0.48.0", -] - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - [[package]] name = "winapi-util" version = "0.1.9" @@ -6457,21 +1462,6 @@ dependencies = [ "windows-sys 0.59.0", ] -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "windows-core" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" -dependencies = [ - "windows-targets 0.52.6", -] - [[package]] name = "windows-sys" version = "0.48.0" @@ -6620,24 +1610,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" -[[package]] -name = "winnow" -version = "0.5.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" -dependencies = [ - "memchr", -] - -[[package]] -name = "winnow" -version = "0.6.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" -dependencies = [ - "memchr", -] - [[package]] name = "winreg" version = "0.50.0" @@ -6660,58 +1632,11 @@ version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" -[[package]] -name = "wyz" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" -dependencies = [ - "tap", -] - -[[package]] -name = "xattr" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8da84f1a25939b27f6820d92aed108f83ff920fdf11a7b19366c27c4cda81d4f" -dependencies = [ - "libc", - "linux-raw-sys", - "rustix", -] - -[[package]] -name = "xshell" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db0ab86eae739efd1b054a8d3d16041914030ac4e01cd1dca0cf252fd8b6437" -dependencies = [ - "xshell-macros", -] - -[[package]] -name = "xshell-macros" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d422e8e38ec76e2f06ee439ccc765e9c6a9638b9e7c9f2e8255e4d41e8bd852" - -[[package]] -name = "xxhash-rust" -version = "0.8.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a5cbf750400958819fb6178eaa83bee5cd9c29a26a40cc241df8c70fdd46984" - -[[package]] -name = "yansi" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" - [[package]] name = "yoke" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c5b1314b079b0930c31e3af543d8ee1757b1951ae1e1565ec704403a7240ca5" +checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" dependencies = [ "serde", "stable_deref_trait", @@ -6721,78 +1646,37 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95" +checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn", "synstructure", ] -[[package]] -name = "zerocopy" -version = "0.7.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" -dependencies = [ - "byteorder", - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.87", -] - [[package]] name = "zerofrom" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ec111ce797d0e0784a1116d0ddcdbea84322cd79e5d5ad173daeba4f93ab55" +checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e" dependencies = [ "zerofrom-derive", ] [[package]] name = "zerofrom-derive" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5" +checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn", "synstructure", ] -[[package]] -name = "zeroize" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" -dependencies = [ - "zeroize_derive", -] - -[[package]] -name = "zeroize_derive" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.87", -] - [[package]] name = "zerovec" version = "0.10.4" @@ -6812,45 +1696,5 @@ checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", -] - -[[package]] -name = "zip" -version = "0.6.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261" -dependencies = [ - "byteorder", - "crc32fast", - "crossbeam-utils", - "flate2", -] - -[[package]] -name = "zstd" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcf2b778a664581e31e389454a7072dab1647606d44f7feea22cd5abb9c9f3f9" -dependencies = [ - "zstd-safe", -] - -[[package]] -name = "zstd-safe" -version = "7.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54a3ab4db68cea366acc5c897c7b4d4d1b8994a9cd6e6f841f8964566a419059" -dependencies = [ - "zstd-sys", -] - -[[package]] -name = "zstd-sys" -version = "2.0.13+zstd.1.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38ff0f21cfee8f97d94cef41359e0c89aa6113028ab0291aa8ca0038995a95aa" -dependencies = [ - "cc", - "pkg-config", + "syn", ] diff --git a/Cargo.toml b/Cargo.toml index 7aa7867..26b685e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,39 +1,33 @@ -[workspace] -members = [ - "crates/cli", - "crates/voyager-resolver-cairo", - "crates/dyn-compiler", -] -"resolver" = "2" - -[workspace.package] -version = "0.1.0" -edition = "2021" -repository = "https://github.com/NethermindEth/starknet-contract-verifier" +[package] +authors = ["Nethermind"] +description = "`Contract class verification tool that allows you to verify your starknet classes on a block explorer." license = "Apache-2.0" -license-file = "LICENSE" +name = "starknet-contract-verifier" +repository = "https://github.com/NethermindEth/starknet-contract-verifier" +version = "1.0.0-rc.1" +default-run = "starknet-contract-verifier" +edition = "2021" -[workspace.dependencies] +[dependencies] anyhow = "1.0.66" +backon = { version = "1.2.0", default-features = false, features = ["std-blocking-sleep"] } camino = { version = "1.1.2", features = ["serde1"] } -clap = { version = "4.3", features = ["derive"] } -colored = "2" -env_logger = "0.9.3" -indoc = "1.0.7" +clap = { version = "4.5.20", features = ["derive", "unicode", "env", "string"] } itertools = "0.10.3" -num-bigint = "0.4" -pretty_assertions = "1.2.1" -rayon = "0.9.0" -salsa = "0.16.1" +regex = "1" +reqwest = { version = "=0.11", features = ["blocking", "json", "multipart"] } +scarb-metadata = "1.13.0" +semver = "1.0.23" serde = { version = "1.0.130", features = ["derive"] } serde_json = "1.0" -smol_str = "0.2.0" -thiserror = "1.0.32" -toml = "0.4.2" -test-log = "0.2.11" +spdx = "0.10.6" +thiserror = "2.0.6" +url = "2.2.2" +walkdir = "2.3.3" -# Starknet related dependencies -starknet = "0.9.0" -scarb-metadata = "1.13.0" -cairo-felt = "0.9.1" -cairo-vm = "0.9.2" +[lib] +name = "verifier" + +[[bin]] +name = "starknet-contract-verifier" +path = "src/main.rs" \ No newline at end of file diff --git a/HOW_IT_WORKS.md b/HOW_IT_WORKS.md deleted file mode 100644 index c3f7e08..0000000 --- a/HOW_IT_WORKS.md +++ /dev/null @@ -1,111 +0,0 @@ -# How it works - -## Documentation - -### Overview - -Cairo 1 adopts a crate/module-centric approach, inspired by Rust's design, to group related items into coherent units, facilitating the organization of code within a project. To declare the root of a crate, Cairo uses a `lib.cairo` file, which attaches all the modules to the module tree, making them accessible to the rest of the project. - -The challenge in designing this contract verifier is that, to verify a contract within a project, we need to provide the compiler with the entire project, as it must resolve all the modules declared in the `lib.cairo` file and their submodules. However, to improve performance, we want to minimize the number of files sent to our backend. - -To verify a contract, we only need to send the contract itself and its dependent modules. However, the compiler requires a valid Cairo project to compile. Therefore, we must send a Cairo crate, with a `lib.cairo` file that declares all the modules on which the contract depends, including their submodules. To accomplish this, we follow these steps: - -- Gather the list of imports used by each module in the crate. -- Resolve the file path of each module, ignoring virtual file modules generated by compiler plugins. -- Create a directed graph that links module files together based on their dependencies. -- Generate a new crate that includes only the required files. -- Generate the "attachment" files that link the modules to the module tree up to the top-level lib.rs file. - -As an example, let's consider the following project structure: - -``` -. -├── cairo_ds -│   ├── Scarb.toml -│   └── src -│   ├── contracts -│   │   └── erc20.cairo -│   ├── contracts.cairo -│   ├── lib.cairo -│   ├── tests -│   │   └── test_erc20.cairo -│   └── tests.cairo -└── dependency - ├── Scarb.toml - └── src - ├── lib.cairo - └── main.cairo - -``` - -To verify the erc20.cairo contract that imports `use dependency::main::foo;`, we generate a new crate that contains only the required files. -In this case, our contract depends on the external `dependency dependency::main::foo`. The resolver generates two crates: one for the cairo_ds project and one for the dependency project. Both crates contain only the necessary files. - -### Output - -Here is the generated minimal `cairo_ds` crate that can be sent to our backend for verification: - -``` -. -├── cairo_ds -│   ├── Scarb.toml -│   └── src -│   ├── contracts -│   │   └── ERC20.cairo -│   ├── contracts.cairo -│   └── lib.cairo -└── dependency - ├── Scarb.toml - └── src - ├── lib.cairo - └── main.cairo -``` - -You will notice here that everything related to `tests` is gone, as it is not required to compile the `erc20.cairo` contract. - -This reduced project is generated under the `voyager-verify` directory, which is created in the root of the project. - -### Scarb - -Our verifier will use a `tool` section inside the Scarb manifest file to know which contracts it should verify. -Users will create a section `tool.voyager`, under which they will declare the name of the contracts they want -to verify, followed by the path to the contract file and the address the associated on-chain address. - -```toml -[tool.voyager] -ERC20 ={path= "contracts/ERC20.cairo", address = "0x12345"} -``` - -### Sequence Diagram - -```mermaid -sequenceDiagram - User ->> CLI: voyager-verify [args] - CLI ->> Resolver: compile(workspace) - Resolver ->> CairoCompiler: RootDatabase.[...]build() - CairoCompiler --> Resolver: db - Resolver ->> Scarb: read_scarb_metadata(manifest_path) - Scarb -->> Resolver: metadata - Resolver ->> CairoCompiler: update_crate_roots_from_metadata(metadata) - Resolver ->> CairoCompiler: get_main_crate_ids_from_project(db, config) - CairoCompiler -->> Resolver: Vec - loop crate_id - CairoCompiler-->>Resolver: crate_root_dir - CairoCompiler-->>Resolver: main_file_path - Resolver ->> Queries: extract_crate_modules(db, crate_id) - loop crate_modules - Queries -->> Queries: get_module_file(db, module_id) - Queries -->> Queries: extract_file_imports(db, module_id, file) - Queries -->> Queries: CairoModule{...} - end - Queries -->> Resolver: crate_modules - end - - Resolver ->> Graph: create_graph(all_modules) - Graph -->> Resolver: graph - Resolver ->> Graph: get_reduced_project(graph, modules_to_verify) - Graph -->> Resolver: (required_modules_paths, attachment_modules_data) - Resolver ->> Filesystem: create_attachment_files() - Resolver ->> Filesystem: copy_required_files() - Resolver ->> Filesystem: generate_scarb_updated_files -``` diff --git a/README.md b/README.md index 0deacf0..56ba437 100644 --- a/README.md +++ b/README.md @@ -1,79 +1,20 @@ # starknet-contract-verifier -`starknet-contract-verifier` is a contract class verification cli that allows you to verify your starknet classes on a block explorer. +Client for the [Voyager Starknet block explorer](https://voyager.online), that allows you to verify your starknet classes. -#### The list of the block explorer we currently support are: -- [Voyager Starknet block explorer](https://voyager.online). +## Quickstart guide +### Scarb -#### We currently support the following Cairo version & Scarb version. -- [x] Cairo 1.1.0 & Scarb v0.4.0 -- [x] Cairo 1.1.1 & Scarb v0.4.1 -- [x] Cairo 2.0.1 & Scarb v0.5.1 -- [x] Cairo 2.0.2 & Scarb v0.5.2 -- [x] Cairo 2.1.0 & Scarb v0.6.1 -- [x] Cairo 2.1.1 & Scarb v0.6.2 -- [x] Cairo 2.2.0 & Scarb v0.7.0 -- [x] Cairo & Scarb 2.3.0 -- [x] Cairo & Scarb 2.3.1 -- [x] Cairo & Scarb 2.4.0 -- [x] Cairo & Scarb 2.4.1 -- [x] Cairo & Scarb 2.4.2 -- [x] Cairo & Scarb 2.4.3 -- [x] Cairo & Scarb 2.4.4 -- [x] Cairo & Scarb 2.5.0 -- [x] Cairo & Scarb 2.5.1 -- [x] Cairo & Scarb 2.5.2 -- [x] Cairo & Scarb 2.5.3 -- [x] Cairo & Scarb 2.5.4 -- [x] Cairo & Scarb 2.6.0 -- [x] Cairo & Scarb 2.6.1 -- [x] Cairo & Scarb 2.6.2 -- [x] Cairo & Scarb 2.6.3 -- [x] Cairo 2.6.3 & Scarb 2.6.4 -- [x] Cairo 2.6.4 & Scarb 2.6.5 -- [x] Cairo 2.7.0 & Scarb 2.7.0 -- [x] Cairo 2.7.1 & Scarb 2.7.1 -- [x] Cairo 2.8.0 & Scarb 2.8.0 -- [x] Cairo 2.8.0 & Scarb 2.8.1 -- [x] Cairo 2.8.2 & Scarb 2.8.2 -- [x] Cairo 2.8.2 & Scarb 2.8.3 -- [x] Cairo 2.8.4 & Scarb 2.8.4 +Contract verifier works with [Scarb](https://docs.swmansion.com/scarb) based projects. The tool assumes that `scarb` command is available in the envirenment and project is building properly by executing `scarb bulid`. -The source code release for each version is available at their respective branch at `release/2..`. For example, the release for `2.4.3` would live at `release/2.4.3`. +#### Supported verisons +Client is version agnostic, the Scarb/Cairo versions support is determined by the server availability. As of writing this (09/01/2025) Cairo up to 2.9.1 is supported with newer versions being added few a slight lag after release. -## Getting started +### Project configuration -### Prerequisite - -#### Installing Scarb - -This CLI relies upon Scarb for dependencies resolving during compilation and thus require you to have Scarb installed for it to work properly. You can install Scarb following the instruction on their documentation at https://docs.swmansion.com/scarb. - -Note that CLI version that you install should follow the version of the Scarb you have installed for it to work as expected. - - - -#### Adding configuration for the verification - -In order to start verification, you'll need to add a table in your `Scarb.toml` as such: +In order to verify your contract, you'll need to add a `tool.voyager` table in your `Scarb.toml`, for example: ```toml [package] @@ -88,87 +29,69 @@ sierra = true # Add the following section [tool.voyager] -my_contract = { path = "main.cairo" } +my_contract = { path = "src/main.cairo" } ``` -The path should be set to the path of whichever contract you would like to verify, relative to your `src` directory. For the example above, the cairo contract is located at `src/main.cairo` and as such the path should be set to `main.cairo`. - -Note that only one contract should be provided in this section as multi contract verification is not supported yet. - -### Verification +The `my_contract` field name have to match the name of the contract that we want to verify. The path should point to the file containing cairo module that you wish to verify. In the example above, the cairo contract in question is located at `src/main.cairo`. -First do a clone of this repository. +*Note* that only one contract should be provided in this section as multi contract verification is not supported yet. -```bash -git clone git@github.com:NethermindEth/starknet-contract-verifier.git -``` +### Get `starknet-contract-verifier` -After cloning the repository, checkout to the release branch corresponding to the cairo version that your contract uses. For example, if you write your contract in `cairo 2.5.4`, you would do the following: +Right now in order to obtain the `starknet-contract-verifier`, clone this repository: -```bash +``` bash +git clone https://github.com/NethermindEth/starknet-contract-verifier.git cd starknet-contract-verifier -git checkout release/2.5.4 -``` - -To start the verifier, you can do the following command, and a prompt should guide you through the verification process. - -```bash -cargo run --bin starknet-contract-verifier -``` - -If you are using `asdf` for the management of scarb binary on a project basis, you should make sure that the verifier runs in the directory of the project so that the verifier will detect and use the correct `scarb` binary for that project. - -You can build the binaries and add it to path to make it easier to use the verifier. - -```bash -# build all binaries -cargo build --all --release - -# then add build target directory to path -# depending on your shell this might be different. -# Add the following to the end of your shell configuration file -export PATH="$PATH:/path/to/starknet-contract-verifier/target/release" - -# you should now be able to call the verifier directly if build succeeds. -starknet-contract-verifier ``` -You should be greeted with prompts that asks for the details of your cairo project & contracts, and will be guided step by step through the verification process. +### Setup rust -## Building from source - -If you are developing and building the project from source, you will first need to install rust. +`starknet-contract-verifier` is a rust/cargo project. In order to build it you'll need rust and cargo set up. You can do it easily using [rustup](https://rustup.rs/). ```bash curl https://sh.rustup.rs -sSf | sh -s ``` -> Note: Builds for 2.4.3 and below only works with < Rust 1.77. As such please make sure that you have the correct rust version before building. +### Submit your contract -To build the project, simply do +You are good to go, execute: -```bash -cargo build +``` bash +cargo run -- --network mainnet submit \ + --name \ + --hash \ + --path ``` -and the project should start building. +When successful you'll be given verification job id, which you can pass to: -## Limitations and Known Issues +``` bash +cargo run -- --network mainnet status --job +``` -There's a few known issue with the current implementation of this verifier. +to check the verification status. Afterwards visit [Voyager website]() and search for your class hash to see *verified* badge. +## Detailed information -### 1. Rearranging and restructure of the resulting verified files +### Verification -It's possible that your modules get re-arranged after verification as the verifier tries to resolve your dependencies from the main contract and re-generate them into a new project. This is known and we are working towards making the generated project look as closely as possible with the original module structure. +`starknet-contract-verifier` provides two subcommands: `submit` and `status`. For both cases user needs to select the network with which they want to interact via the `--network` argument. Possible cases are: +- `mainnet`, main starknet newtwork, +- `sepolia`, test network, +- `custom`, set provide custom addresses via `--public` and `--private arguments. +#### Submiting for verification -### 2. Scarb.toml specified starknet versioning affects which binaries work with the verifier +In order to submit contract for verification user needs to provide several arguments: +- `--path`, path to directory containing scarb project (If omitted it will use current workingi directory), +- `--name`, name which will be used in the block explorer for the verified contract, +- `--hash`, class hash of the declared contract. -The verifier would usually work cairo compiler versions that are lower than its version given no breaking changes between compiler versions, meaning using a `2.4.3` verifier with a compiler version of less than 2.4.3 would work as long as you specify in your `Scarb.toml` file the starknet version with a range including the verifier version (for example, `>=2.4.0` & `2.2.0` usually works for verifier `2.4.3`) If you use strict versioning for your starknet version in form of `=2.4.3` for example, it would stop working with verifier of other versions. +there are more options, each of them is documented in the `--help` output. -## Contributing +If the submission is successful, client will output the verification job id. -We welcome any form of contribution to this project! +#### Checking job status -To start, you can take a look at the issues that's available for taking and work on whichever you might be interested in. Do leave a comment so we can assign the issue to you! +User can query the verification job status using `status` command and providing job id as the `--job` argument value. diff --git a/RUNNING_LOCALLY.md b/RUNNING_LOCALLY.md deleted file mode 100644 index 89b1f7d..0000000 --- a/RUNNING_LOCALLY.md +++ /dev/null @@ -1,25 +0,0 @@ -# Running the verifier locally - -You might want to run the verifier locally in order to test some features of the verification stack. We cover some cases here which might be helpful to devs. - -### Running it against a dev environment - -In order to run the cli against the dev environment, you can utilize the custom api endpoint env vars to pass your desired api endpoints and thus allow the cli to interact with the dev environment. - -For example, if your dev environment is located locally at your machine, you can do the following: - -```bash -CUSTOM_INTERNAL_API_ENDPOINT_URL="http://localhost:3030" CUSTOM_PUBLIC_API_ENDPOINT_URL="http://localhost:3034" cargo run --bin starknet-contract-verifier -``` - -## Running the verification stack locally -This details the steps in order to run the stack for our verification flow locally. The first 3 steps includes components not in this repository. This is usually done by developer working on these components and want to perform manual testing of the verification stack. - -1. Setup your database. For convenience sake you can connect to a database with data like those in integration or dev env for the network db, and you can run a local centralized db for easier monitoring, -2. Run the Cairo compiler service -3. Run the backend verification api service -4. Pass the custom endpoints env vars in order to set your endpoint urls. - -With this you should be able to run the whole stack for testing verification locally. - -Make sure the changes you want to test is already propagated to the dev env. If the api endpoint is unknown to you, please ask the Voyager team to provide you with the information. diff --git a/cliff.toml b/cliff.toml deleted file mode 100644 index ba12c0b..0000000 --- a/cliff.toml +++ /dev/null @@ -1,89 +0,0 @@ -# git-cliff ~ default configuration file -# https://git-cliff.org/docs/configuration -# -# Lines starting with "#" are comments. -# Configuration options are organized into tables and keys. -# See documentation for more information on available options. - -[changelog] -# template for the changelog footer -header = """ -# Changelog\n -All notable changes to this project will be documented in this file.\n -""" -# template for the changelog body -# https://keats.github.io/tera/docs/#introduction -body = """ -{% if version %}\ - ## [{{ version | trim_start_matches(pat="v") }}] - {{ timestamp | date(format="%Y-%m-%d") }} -{% else %}\ - ## [unreleased] -{% endif %}\ -{% for group, commits in commits | group_by(attribute="group") %} - ### {{ group | striptags | trim | upper_first }} - {% for commit in commits %} - - {% if commit.scope %}*({{ commit.scope }})* {% endif %}\ - {% if commit.breaking %}[**breaking**] {% endif %}\ - {{ commit.message | upper_first }}\ - {% endfor %} -{% endfor %}\n -""" -# template for the changelog footer -footer = """ - -""" -# remove the leading and trailing s -trim = true -# postprocessors -postprocessors = [ - # { pattern = '', replace = "https://github.com/orhun/git-cliff" }, # replace repository URL -] - -[git] -# parse the commits based on https://www.conventionalcommits.org -conventional_commits = true -# filter out the commits that are not conventional -filter_unconventional = true -# process each line of a commit as an individual commit -split_commits = false -# regex for preprocessing the commit messages -commit_preprocessors = [ - # Replace issue numbers - #{ pattern = '\((\w+\s)?#([0-9]+)\)', replace = "([#${2}](/issues/${2}))"}, - # Check spelling of the commit with https://github.com/crate-ci/typos - # If the spelling is incorrect, it will be automatically fixed. - #{ pattern = '.*', replace_command = 'typos --write-changes -' }, -] -# regex for parsing and grouping commits -commit_parsers = [ - { message = "^feat", group = "🚀 Features" }, - { message = "^fix", group = "🐛 Bug Fixes" }, - { message = "^doc", group = "📚 Documentation" }, - { message = "^perf", group = "⚡ Performance" }, - { message = "^refactor", group = "🚜 Refactor" }, - { message = "^style", group = "🎨 Styling" }, - { message = "^test", group = "🧪 Testing" }, - { message = "^chore\\(release\\): prepare for", skip = true }, - { message = "^chore\\(deps.*\\)", skip = true }, - { message = "^chore\\(pr\\)", skip = true }, - { message = "^chore\\(pull\\)", skip = true }, - { message = "^chore|^ci", group = "⚙️ Miscellaneous Tasks" }, - { body = ".*security", group = "🛡️ Security" }, - { message = "^revert", group = "◀️ Revert" }, -] -# protect breaking changes from being skipped due to matching a skipping commit_parser -protect_breaking_commits = false -# filter out the commits that are not matched by commit parsers -filter_commits = false -# regex for matching git tags -# tag_pattern = "v[0-9].*" -# regex for skipping tags -# skip_tags = "" -# regex for ignoring tags -# ignore_tags = "" -# sort the tags topologically -topo_order = false -# sort the commits inside sections by oldest/newest order -sort_commits = "oldest" -# limit the number of commits included in the changelog. -# limit_commits = 42 diff --git a/crates/cli/Cargo.toml b/crates/cli/Cargo.toml deleted file mode 100644 index 010fc18..0000000 --- a/crates/cli/Cargo.toml +++ /dev/null @@ -1,39 +0,0 @@ -[package] -name = "cli" -version = "0.1.0" -edition = "2021" - -[dependencies] -anyhow.workspace = true -camino.workspace = true -clap.workspace = true -comfy-table = "6.0.0" -serde.workspace = true -smol_str.workspace = true -thiserror.workspace = true -toml.workspace = true -reqwest = { version = "=0.11", features = ["blocking", "json", "multipart"] } -tokio = { version = "1.28.2", features = ["full"] } -url = "2.2.2" -dialoguer = { version = "0.10", features = ["fuzzy-select", "completion"] } -console = "0.15.8" -regex = "1" -indicatif = "0.17.7" -strum = "0.25.0" -strum_macros = "0.25.0" -dirs = "4.0" -dotenv = "0.15" - -dyn-compiler = { path = "../dyn-compiler" } - -# All resolver versions, based on Scarb + Cairo -voyager-resolver-cairo = { path = "../voyager-resolver-cairo" } -walkdir = "2.3.3" - -[[bin]] -name = "starknet-contract-verifier" -path = "src/cli.rs" - -[[bin]] -name = "starknet-contract-resolver" -path = "src/resolver-cli.rs" diff --git a/crates/cli/README.md b/crates/cli/README.md deleted file mode 100644 index b83d258..0000000 --- a/crates/cli/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# cli crate - -Handles the command line interface for the voyager verify tool. \ No newline at end of file diff --git a/crates/cli/src/api.rs b/crates/cli/src/api.rs deleted file mode 100644 index 1d761a6..0000000 --- a/crates/cli/src/api.rs +++ /dev/null @@ -1,361 +0,0 @@ -use std::fmt::Display; -use std::path::PathBuf; -use std::{env, fs}; -use std::{str::FromStr, thread::sleep}; - -use anyhow::{anyhow, Error, Ok, Result}; -use dyn_compiler::dyn_compiler::{SupportedCairoVersions, SupportedScarbVersions}; -use reqwest::{ - blocking::{get, multipart, Client}, - StatusCode, -}; - -#[derive(Debug, Clone)] -pub enum Network { - Mainnet, - Sepolia, - Local, - Custom, -} - -impl Display for Network { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - Network::Mainnet => write!(f, "mainnet"), - Network::Sepolia => write!(f, "sepolia"), - Network::Local => write!(f, "local"), - Network::Custom => write!(f, "custom"), - } - } -} - -impl FromStr for Network { - type Err = Error; - - fn from_str(s: &str) -> std::result::Result { - match s.to_lowercase().as_str() { - "mainnet" => Ok(Network::Mainnet), - "sepolia" => Ok(Network::Sepolia), - "local" => Ok(Network::Local), - "custom" => Ok(Network::Custom), - _ => Err(anyhow!("Unknown network: {}", s)), - } - } -} - -#[derive(Debug, serde::Deserialize)] -pub enum VerifyJobStatus { - Submitted, - Compiled, - CompileFailed, - Fail, - Success, -} - -impl VerifyJobStatus { - fn from_u8(status: u8) -> Self { - match status { - 0 => Self::Submitted, - 1 => Self::Compiled, - 2 => Self::CompileFailed, - 3 => Self::Fail, - 4 => Self::Success, - _ => panic!("Unknown status: {}", status), - } - } -} - -impl Display for VerifyJobStatus { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - VerifyJobStatus::Submitted => write!(f, "Submitted"), - VerifyJobStatus::Compiled => write!(f, "Compiled"), - VerifyJobStatus::CompileFailed => write!(f, "CompileFailed"), - VerifyJobStatus::Fail => write!(f, "Fail"), - VerifyJobStatus::Success => write!(f, "Success"), - } - } -} - -/** - * Currently only GetJobStatus and VerifyClass are public available apis. - * In the future, the get class api should be moved to using public apis too. - * TODO: Change get class api to use public apis. - */ -pub enum ApiEndpoints { - GetClass, - GetJobStatus, - VerifyClass, -} - -impl ApiEndpoints { - fn as_str(&self) -> String { - match self { - ApiEndpoints::GetClass => "/api/class/{class_hash}".to_owned(), - ApiEndpoints::GetJobStatus => "/class-verify/job/{job_id}".to_owned(), - ApiEndpoints::VerifyClass => "/class-verify/{class_hash}".to_owned(), - } - } - - fn to_api_path(&self, param: String) -> String { - match self { - ApiEndpoints::GetClass => self.as_str().replace("{class_hash}", param.as_str()), - ApiEndpoints::GetJobStatus => self.as_str().replace("{job_id}", param.as_str()), - ApiEndpoints::VerifyClass => self.as_str().replace("{class_hash}", param.as_str()), - } - } -} - -pub fn get_network_api(network: Network) -> (String, String) { - let url = match network { - Network::Mainnet => "https://voyager.online".to_string(), - Network::Sepolia => "https://sepolia.voyager.online".to_string(), - Network::Local => "http://localhost:8899".to_string(), - Network::Custom => match env::var("CUSTOM_INTERNAL_API_ENDPOINT_URL") { - std::result::Result::Ok(url) => url.to_string(), - _ => "".to_string(), - }, - }; - - let public_url = match network { - Network::Mainnet => "https://api.voyager.online/beta".to_string(), - Network::Sepolia => "https://sepolia-api.voyager.online/beta".to_string(), - Network::Local => "http://localhost:30380".to_string(), - Network::Custom => match env::var("CUSTOM_PUBLIC_API_ENDPOINT_URL") { - std::result::Result::Ok(url) => url.to_string(), - _ => "".to_string(), - }, - }; - - (url, public_url) -} - -#[derive(Debug, serde::Deserialize)] -pub struct ApiError { - error: String, -} - -#[derive(Debug, serde::Deserialize)] -pub struct VerificationJobDispatch { - job_id: String, -} - -#[allow(dead_code)] -#[derive(Debug, serde::Deserialize)] -pub struct VerificationJob { - job_id: String, - status: u8, - status_description: Option, - class_hash: String, - created_timestamp: Option, - updated_timestamp: Option, - address: Option, - contract_file: Option, - name: Option, - version: Option, - license: Option, -} - -#[derive(Debug)] -pub struct FileInfo { - pub name: String, - pub path: PathBuf, -} - -pub fn does_class_exist(network: Network, class_hash: &str) -> Result { - let (url, _) = get_network_api(network); - let path_with_params = ApiEndpoints::GetClass.to_api_path(class_hash.to_owned()); - let result = get(url + path_with_params.as_str())?; - match result.status() { - StatusCode::OK => Ok(true), - StatusCode::NOT_FOUND => Ok(false), - _ => Err(anyhow::anyhow!( - "Unexpected status code {} when trying to get class hash with error {}", - result.status(), - result.text()? - )), - } -} - -#[derive(Debug, Clone)] -pub struct ProjectMetadataInfo { - pub cairo_version: SupportedCairoVersions, - pub scarb_version: SupportedScarbVersions, - pub project_dir_path: String, - pub contract_file: String, -} - -pub fn dispatch_class_verification_job( - _api_key: &str, - network: Network, - address: &str, - license: &str, - name: &str, - project_metadata: ProjectMetadataInfo, - files: Vec, -) -> Result { - // Construct form body - let mut body = multipart::Form::new() - .percent_encode_noop() - .text( - "compiler_version", - project_metadata.cairo_version.to_string(), - ) - .text("scarb_version", project_metadata.scarb_version.to_string()) - .text("license", license.to_string()) - .text("name", name.to_string()) - .text("contract_file", project_metadata.contract_file) - .text("project_dir_path", project_metadata.project_dir_path); - - for file in files.iter() { - let file_content = fs::read_to_string(file.path.as_path())?; - body = body.text(format!("files__{}", file.name.clone()), file_content); - } - - let (_, public_url) = get_network_api(network); - let client = Client::new(); - - let path_with_param = ApiEndpoints::VerifyClass.to_api_path(address.to_owned()); - - let response = client - .post(public_url + path_with_param.as_str()) - // .header("x-api-key", api_key) - .multipart(body) - .send()?; - - match response.status() { - StatusCode::OK => (), - StatusCode::NOT_FOUND => { - return Err(anyhow!("Job not found")); - } - StatusCode::BAD_REQUEST => { - let err_response = response.json::()?; - - return Err(anyhow!( - "Failed to dispatch verification job with status 400: {}", - err_response.error - )); - } - unknown_status_code => { - return Err(anyhow!( - "Failed to dispatch verification job with status {}: {}", - unknown_status_code, - response.text()? - )); - } - } - - let data = response.json::().unwrap(); - - Ok(data.job_id) -} - -pub fn poll_verification_status( - _api_key: &str, - network: Network, - job_id: &str, - max_retries: u32, -) -> Result { - // Get network api url - let (_, public_url) = get_network_api(network); - - // Blocking loop that polls every 5 seconds - static RETRY_INTERVAL: u64 = 5000; // Ms - let mut retries: u32 = 0; - let client = Client::new(); - - let path_with_param = ApiEndpoints::GetJobStatus.to_api_path(job_id.to_owned()); - - let use_max_retries = match env::var("USE_POLLING_MAX_RETRIES") { - std::result::Result::Ok(value) => value.to_lowercase() == "true", - Err(_) => false, - }; - // Retry every 2000ms until we hit maxRetries - loop { - let result = client - .get(public_url.clone() + path_with_param.as_str()) - // .header("x-api-key", api_key) - .send()?; - match result.status() { - StatusCode::OK => (), - StatusCode::NOT_FOUND => { - return Err(anyhow!("Job not found")); - } - unknown_status_code => { - return Err(anyhow!( - "Unexpected status code: {}, with error message: {}", - unknown_status_code, - result.text()? - )); - } - } - - // Go through the possible status - let data = result.json::()?; - match VerifyJobStatus::from_u8(data.status) { - VerifyJobStatus::Success => return Ok(data), - VerifyJobStatus::Fail => { - return Err(anyhow!( - "Failed to verify: {:?}", - data.status_description - .unwrap_or("unknown failure".to_owned()) - )) - } - VerifyJobStatus::CompileFailed => { - return Err(anyhow!( - "Compilation failed: {:?}", - data.status_description - .unwrap_or("unknown failure".to_owned()) - )) - } - _ => (), - } - retries += 1; - if use_max_retries && retries > max_retries { - break; - } - sleep(std::time::Duration::from_millis(RETRY_INTERVAL)); - } - - // If we hit maxRetries, throw an timeout error - Err(anyhow!( - "Timeout: Verification job took too long to complete" - )) -} - -#[cfg(test)] -mod tests { - use super::*; - use std::env; - - #[test] - fn test_getting_default_voyager_endpoints() { - let selected_network = Network::Sepolia; - let actual_network_api = get_network_api(selected_network); - - // Assert that the internal api is correct - assert_eq!(actual_network_api.0, "https://sepolia.voyager.online"); - // Assert that the public api is correct`` - assert_eq!( - actual_network_api.1, - "https://sepolia-api.voyager.online/beta" - ); - } - - #[test] - fn test_getting_custom_endpoints() { - let my_internal_api_url = "https://my-instance-internal-api.com"; - let my_public_api_url = "https://my-instance-public-api.com"; - // set env vars for this testing case - env::set_var("CUSTOM_INTERNAL_API_ENDPOINT_URL", my_internal_api_url); - env::set_var("CUSTOM_PUBLIC_API_ENDPOINT_URL", my_public_api_url); - - let selected_network = Network::Custom; - let actual_network_api = get_network_api(selected_network); - - // Assert that the internal api is correct - assert_eq!(actual_network_api.0, my_internal_api_url); - // Assert that the public api is correct`` - assert_eq!(actual_network_api.1, my_public_api_url); - } -} diff --git a/crates/cli/src/cli.rs b/crates/cli/src/cli.rs deleted file mode 100644 index e5303aa..0000000 --- a/crates/cli/src/cli.rs +++ /dev/null @@ -1,267 +0,0 @@ -mod api; -mod license; -mod resolver; -mod utils; -mod validation; -mod verify; - -use crate::api::{does_class_exist, Network}; -use crate::license::LicenseType; -use crate::resolver::TargetType; -use crate::utils::detect_local_tools; -use camino::Utf8PathBuf; -use console::{style, Emoji}; -use dialoguer::{theme::ColorfulTheme, Input, Select}; -use dirs::home_dir; -use dotenv::dotenv; -use indicatif::{HumanDuration, ProgressBar, ProgressStyle}; -use std::{ - env, - str::FromStr, - time::{Duration, Instant}, -}; -use strum::IntoEnumIterator; -use validation::is_class_hash_valid; -use verify::VerifyProjectArgs; - -fn main() -> anyhow::Result<()> { - dotenv().ok(); - - // TODO: make this cli use a secure api - // let api_key = match env::var("API_KEY") { - // Ok(api_key) => Some(api_key), - // Err(_) => None, - // }; - - // let api_key = match api_key { - // Some(key_values) => key_values, - // None => { - // println!("API_KEY not detected in environment variables. You can get one at https://forms.gle/34RE6d4aiiv16HoW6"); - // return Ok(()); - // } - // }; - println!( - "{} {} Getting project information...", - style("[1/4]").bold().dim(), - Emoji("📝", "") - ); - - // Project type + Path entry - let target_type = TargetType::ScarbProject; // by default we assume the user is in a Scarb project - let is_current_dir_scarb = env::current_dir()?.join("Scarb.toml").exists(); - let utf8_path = if is_current_dir_scarb { - let current_path = env::current_dir()?.to_str().unwrap().trim().to_string(); - Utf8PathBuf::from(¤t_path) - } else { - loop { - // TODO, add TargetType::File path input here - let input_path = Input::::with_theme(&ColorfulTheme::default()) - .with_prompt("Enter Path to Scarb project root:") - .interact_text() - .expect("Aborted at path input, terminating...") - .trim() - .to_string(); - let mut utf8_input_path: Utf8PathBuf = Utf8PathBuf::from(&input_path); - // Resolve path - if utf8_input_path.starts_with("~") { - if let Some(home) = home_dir() { - let home_utf8 = Utf8PathBuf::from_path_buf(home).unwrap(); - utf8_input_path = home_utf8.join(utf8_input_path.strip_prefix("~").unwrap()); - } - } - if utf8_input_path.exists() { - break utf8_input_path; - } else { - println!("Path does not exist. Please try again."); - } - } - }; - - // Start the whole process - let _spinner_style = ProgressStyle::with_template("{prefix:.bold.dim} {spinner} {wide_msg}") - .unwrap() - .tick_chars("⠁⠂⠄⡀⢀⠠⠐⠈"); - - println!( - "{} {} Resolving project...", - style("[2/4]").bold().dim(), - Emoji("🔗", "") - ); - - // Resolve project - let (project_files, project_metadata) = match target_type { - TargetType::File => { - panic!("Single contract file verification is not yet implemented, please use a Scarb project instead."); - } - TargetType::ScarbProject => { - let (local_scarb_version, local_cairo_version) = detect_local_tools(); - // TODO: do a first pass to find all the contracts in the project - // For now we keep using the hardcoded value in the Scarb.toml file - - resolver::resolve_scarb(utf8_path.clone(), local_cairo_version, local_scarb_version)? - } - }; - - // TODO: try to calculate the class hash automatically later after contract selection? - // println!( - // "{} {} Calculating class hash...", - // style("[x/x]").bold().dim(), - // Emoji("🔍 ", "") - // ); - println!( - "{} {} Getting verification information...", - style("[3/4]").bold().dim(), - Emoji("🔍 ", "") - ); - - // -- Network selection -- - - // Custom network selection - let custom_internal_api_endpoint_url = env::var("CUSTOM_INTERNAL_API_ENDPOINT_URL"); - let custom_public_api_endpoint_url = env::var("CUSTOM_PUBLIC_API_ENDPOINT_URL"); - let is_custom_network = - custom_internal_api_endpoint_url.is_ok() && custom_public_api_endpoint_url.is_ok(); - - // Only show local if debug network option is up. - let is_debug_network = match env::var("DEBUG_NETWORK") { - Ok(value) => value.to_lowercase() == "true", - Err(_) => false, - }; - let network_items = if is_debug_network { - vec!["Mainnet", "Sepolia", "Integration", "Local"] - } else { - vec!["Mainnet", "Sepolia"] - }; - - // defaults to the first item. - let selected_network = if !is_custom_network { - let network_index = Select::with_theme(&ColorfulTheme::default()) - .items(&network_items) - .with_prompt("Which network would you like to verify on : ") - .default(0) - .interact_opt() - .expect("Aborted at network selection, terminating...") - .expect("Aborted at network selection, terminating..."); - - network_items[network_index] - } else { - println!( - "🔔 {}", - style("Custom verification endpoint provided:").bold() - ); - println!( - "Internal endpoint url: {}", - custom_internal_api_endpoint_url.unwrap_or("".to_string()) - ); - println!( - "Public endpoint url: {}", - custom_public_api_endpoint_url.unwrap_or("".to_string()) - ); - - "custom" - }; - - let network_enum = Network::from_str(selected_network)?; - let mut class_hash: String; - loop { - class_hash = Input::with_theme(&ColorfulTheme::default()) - .with_prompt("Input class hash to verify : ") - .validate_with(|input: &String| -> Result<(), &str> { - if is_class_hash_valid(input) { - Ok(()) - } else { - Err("This is not a class hash.") - } - }) - .interact()?; - - // Check if the class exists on the network - match does_class_exist(network_enum.clone(), &class_hash) { - Ok(true) => break, - Ok(false) => { - println!("This class hash does not exist for the given network. Please try again.") - } - Err(e) => { - return Err(anyhow::anyhow!( - "Error while checking if class exists: {}", - e - )) - } - } - } - - // Get name that you want to use for the contract - let class_name: String = Input::with_theme(&ColorfulTheme::default()) - .with_prompt("Enter your desired class name: ") - .validate_with(|input: &String| -> Result<(), &str> { - if input.len() > 50 { - Err("Given name is too long") - } else { - Ok(()) - } - }) - .interact_text() - .expect("Aborted at class name input, terminating...") - .trim() - .to_string(); - - // Set license for your contract code - let licenses: Vec = LicenseType::iter().collect(); - let license_index = Select::with_theme(&ColorfulTheme::default()) - .with_prompt("Select license you'd like to verify under :") - .items(&licenses) - .default(0) - .interact_opt() - .expect("Aborted at license version selection, terminating...") - .expect("Aborted at license version selection, terminating..."); - - let verification_start = Instant::now(); - println!( - "{} {} Verifying project...", - style("[4/4]").bold().dim(), - Emoji("🔍", "") - ); - - // Create and configure a progress bar - let pb_verification = ProgressBar::new_spinner(); - pb_verification.set_style(_spinner_style); - pb_verification.enable_steady_tick(Duration::from_millis(100)); - pb_verification.set_message("Please wait..."); - - // Parse args into VerifyProjectArgs - let verify_args = VerifyProjectArgs { - network: selected_network.to_string(), - hash: class_hash, - license: licenses[license_index], - name: class_name, - max_retries: Some(10), - api_key: "".to_string(), - path: utf8_path, - }; - - let verification_result = match target_type { - TargetType::ScarbProject => { - verify::verify_project(verify_args, project_metadata, project_files) - } - TargetType::File => panic!("Single contract file verification is not yet implemented"), - }; - - // Stop and clear the progress bar - pb_verification.finish_with_message("Done"); - - match verification_result { - Ok(_) => { - println!( - "{} Successfully verified in {}", - Emoji("✅", ""), - HumanDuration(verification_start.elapsed()) - ); - Ok(()) - } - Err(e) => Err(anyhow::anyhow!( - "Verification failed! {} {}", - Emoji("❌", ""), - e - )), - } -} diff --git a/crates/cli/src/license.rs b/crates/cli/src/license.rs deleted file mode 100644 index 6d94e89..0000000 --- a/crates/cli/src/license.rs +++ /dev/null @@ -1,109 +0,0 @@ -use clap::{builder::PossibleValue, ValueEnum}; -use strum_macros::EnumIter; - -#[derive(Debug, Clone, EnumIter, Copy)] -pub enum LicenseType { - NoLicense, - Unlicense, - MIT, - GPLv2, - GPLv3, - LGPLv2_1, - LGPLv3, - BSD2Clause, - BSD3Clause, - MPL2, - OSL3, - Apache2, - AGPLv3, - BSL1_1, -} - -impl LicenseType { - pub fn to_long_string(&self) -> String { - let string_repr = match *self { - Self::NoLicense => "No License (None)", - Self::Unlicense => "The Unlicense (Unlicense)", - Self::MIT => "MIT License (MIT)", - Self::GPLv2 => "GNU General Public License v2.0 (GNU GPLv2)", - Self::GPLv3 => "GNU General Public License v3.0 (GNU GPLv3)", - Self::LGPLv2_1 => "GNU Lesser General Public License v2.1 (GNU LGPLv2.1)", - Self::LGPLv3 => "GNU Lesser General Public License v3.0 (GNU LGPLv3)", - Self::BSD2Clause => "BSD 2-clause \"Simplified\" license (BSD-2-Clause)", - Self::BSD3Clause => "BSD 3-clause \"New\" Or Revisited license (BSD-3-Clause)", - Self::MPL2 => "Mozilla Public License 2.0 (MPL-2.0)", - Self::OSL3 => "Open Software License 3.0 (OSL-3.0)", - Self::Apache2 => "Apache 2.0 (Apache-2.0)", - Self::AGPLv3 => "GNU Affero General Public License (GNU AGPLv3)", - Self::BSL1_1 => "Business Source License (BSL 1.1)", - }; - string_repr.to_owned() - } -} - -impl ToString for LicenseType { - fn to_string(&self) -> String { - let string_repr = match *self { - Self::NoLicense => "NoLicense", - Self::Unlicense => "Unlicense", - Self::MIT => "MIT", - Self::GPLv2 => "GPLv2", - Self::GPLv3 => "GPLv3", - Self::LGPLv2_1 => "LGPLv2_1", - Self::LGPLv3 => "LGPLv3", - Self::BSD2Clause => "BSD2Clause", - Self::BSD3Clause => "BSD3Clause", - Self::MPL2 => "MPL2", - Self::OSL3 => "OSL3", - Self::Apache2 => "Apache2", - Self::AGPLv3 => "AGPLv3", - Self::BSL1_1 => "BSL1_1", - }; - string_repr.to_owned() - } -} - -impl ValueEnum for LicenseType { - fn from_str(input: &str, _ignore_case: bool) -> std::result::Result { - match input { - "NoLicense" => Ok(LicenseType::NoLicense), - "Unlicense" => Ok(LicenseType::Unlicense), - "MIT" => Ok(LicenseType::MIT), - "GPLv2" => Ok(LicenseType::GPLv2), - "GPLc3" => Ok(LicenseType::GPLv3), - "LGPLv2_1" => Ok(LicenseType::LGPLv2_1), - "LGPLv3" => Ok(LicenseType::LGPLv3), - "BSD2Clause" => Ok(LicenseType::BSD2Clause), - "BSD3Clause" => Ok(LicenseType::BSD3Clause), - "MPL2" => Ok(LicenseType::MPL2), - "OSL3" => Ok(LicenseType::OSL3), - "Apache2" => Ok(LicenseType::Apache2), - "AGPLv3" => Ok(LicenseType::AGPLv3), - "BSL1_1" => Ok(LicenseType::BSL1_1), - _ => Err(format!("Unknown license type: {}", input)), - } - } - - fn to_possible_value(&self) -> Option { - PossibleValue::new(self.to_string()).into() - } - - fn value_variants<'a>() -> &'a [Self] { - &[ - Self::NoLicense, - Self::Unlicense, - Self::MIT, - Self::GPLv2, - Self::GPLv3, - Self::LGPLv2_1, - Self::LGPLv3, - Self::BSD2Clause, - Self::BSD3Clause, - Self::MPL2, - Self::OSL3, - Self::Apache2, - Self::AGPLv3, - Self::BSL1_1, - ] - } -} diff --git a/crates/cli/src/resolver-cli.rs b/crates/cli/src/resolver-cli.rs deleted file mode 100644 index 4104d1f..0000000 --- a/crates/cli/src/resolver-cli.rs +++ /dev/null @@ -1,71 +0,0 @@ -mod api; -mod resolver; -mod utils; - -use crate::resolver::{resolve_scarb, TargetType}; -use crate::utils::detect_local_tools; - -use camino::Utf8PathBuf; -use console::{style, Emoji}; -use dialoguer::{theme::ColorfulTheme, Input}; -use dirs::home_dir; -use std::env; - -fn main() -> anyhow::Result<()> { - println!( - "{} {} Getting project information...", - style("[1/2]").bold().dim(), - Emoji("📝", "") - ); - - // Project type + Path entry - let target_type = TargetType::ScarbProject; // by default we assume the user is in a Scarb project - let is_current_dir_scarb = env::current_dir()?.join("Scarb.toml").exists(); - let utf8_path = if is_current_dir_scarb { - let current_path = env::current_dir()?.to_str().unwrap().trim().to_string(); - Utf8PathBuf::from(¤t_path) - } else { - loop { - // TODO, add TargetType::File path input here - let input_path = Input::::with_theme(&ColorfulTheme::default()) - .with_prompt("Enter Path to Scarb project root:") - .interact_text() - .expect("Aborted at path input, terminating...") - .trim() - .to_string(); - let mut utf8_input_path: Utf8PathBuf = Utf8PathBuf::from(&input_path); - // Resolve path - if utf8_input_path.starts_with("~") { - if let Some(home) = home_dir() { - let home_utf8 = Utf8PathBuf::from_path_buf(home).unwrap(); - utf8_input_path = home_utf8.join(utf8_input_path.strip_prefix("~").unwrap()); - } - } - if utf8_input_path.exists() { - break utf8_input_path; - } else { - println!("Path does not exist. Please try again."); - } - } - }; - - println!( - "{} {} Resolving project...", - style("[2/2]").bold().dim(), - Emoji("🔗", "") - ); - - // Resolve project - let (_project_files, _project_metadata) = match target_type { - TargetType::File => { - panic!("Single contract file verification is not yet implemented, please use a Scarb project instead."); - } - TargetType::ScarbProject => { - let (local_scarb_version, local_cairo_version) = detect_local_tools(); - resolve_scarb(utf8_path.clone(), local_cairo_version, local_scarb_version)? - } - }; - - println!("{} Successfully resolved!", Emoji("✅", "")); - Ok(()) -} diff --git a/crates/cli/src/resolver.rs b/crates/cli/src/resolver.rs deleted file mode 100644 index aa1ea97..0000000 --- a/crates/cli/src/resolver.rs +++ /dev/null @@ -1,139 +0,0 @@ -use camino::Utf8PathBuf; -use serde::{Deserialize, Serialize}; -use std::fs; -use walkdir::{DirEntry, WalkDir}; - -use crate::api::{FileInfo, ProjectMetadataInfo}; -use dyn_compiler::dyn_compiler::{DynamicCompiler, SupportedCairoVersions, SupportedScarbVersions}; -use voyager_resolver_cairo::compiler::scarb_utils::read_additional_scarb_manifest_metadata; -use voyager_resolver_cairo::dyn_compiler::VoyagerGeneratorWrapper as VoyagerGenerator; - -#[allow(dead_code)] -pub enum TargetType { - ScarbProject, - File, -} - -pub fn get_dynamic_compiler(cairo_version: SupportedCairoVersions) -> Box { - match cairo_version { - SupportedCairoVersions::V2_8_4 => Box::new(VoyagerGenerator), - } -} - -#[derive(Debug, Deserialize, Serialize)] -struct ScarbTomlRawPackageData { - name: String, - version: String, -} - -#[derive(Debug, Deserialize, Serialize)] -struct ScarbTomlRawData { - package: ScarbTomlRawPackageData, -} - -pub fn resolve_scarb( - path: Utf8PathBuf, - cairo_version: SupportedCairoVersions, - scarb_version: SupportedScarbVersions, -) -> anyhow::Result<(Vec, ProjectMetadataInfo)> { - // Extract necessary files from the Scarb project for the verified contract - let source_dir = if path.is_absolute() { - path - } else { - let mut current_path = std::env::current_dir().unwrap(); - current_path.push(path); - Utf8PathBuf::from_path_buf(current_path).unwrap() - }; - - let compiler = get_dynamic_compiler(cairo_version); - let contract_paths = compiler.get_contracts_to_verify_path(&source_dir)?; - - // TODO move the contract selection before the resolving step as a 'pre-resolving' step - // in order to allow for automatic contracts discovery and selection - if contract_paths.is_empty() { - return Err(anyhow::anyhow!("No contracts to verify")); - } - if contract_paths.len() > 1 { - return Err(anyhow::anyhow!( - "Only one contract can be verified at a time" - )); - } - - // Read the Scarb metadata to get more information - // TODO: switch this to using scarb-metadata - let scarb_toml_content = fs::read_to_string(source_dir.join("Scarb.toml"))?; - let extracted_scarb_toml_data = - read_additional_scarb_manifest_metadata(scarb_toml_content.as_str())?; - - // Compiler and extract the necessary files - compiler.compile_project(&source_dir)?; - - // Since we know that we extract the files into the `voyager-verify` directory, - // we'll read the files from there. - let extracted_files_dir = source_dir.join("voyager-verify"); - - // The compiler compiles into the original scarb package name - // As such we have to craft the correct path to the main package - let project_dir_path = extracted_files_dir.join(extracted_scarb_toml_data.name.clone()); - let project_dir_path = project_dir_path - .strip_prefix(extracted_files_dir.clone()) - .unwrap(); - - // Read project directory - let project_files = WalkDir::new(extracted_files_dir.as_path()) - .into_iter() - .filter_map(|f| f.ok()) - .filter(|f| f.file_type().is_file()) - .filter(|f| { - let file_path = f.path(); - - let is_cairo_file = match file_path.extension() { - Some(ext) => ext == "cairo", - None => false, - }; - let file_entry_name = file_path - .file_name() - .map(|f| f.to_string_lossy().into_owned()) - .unwrap_or("".into()); - - let is_supplementary_file = file_entry_name.to_lowercase() == "scarb.toml" - || file_entry_name == extracted_scarb_toml_data.license_file - || file_entry_name == extracted_scarb_toml_data.readme; - - is_cairo_file || is_supplementary_file - }) - .collect::>(); - - let project_files = project_files - .iter() - .map(|f| { - let actual_path = f.path().to_owned(); - let file_name = actual_path - .strip_prefix(&extracted_files_dir) - .unwrap() - .to_str() - .to_owned() - .unwrap() - .to_string(); - FileInfo { - name: file_name, - path: actual_path, - } - }) - .collect::>(); - - let contract_file = format!( - "{}/src/{}", - extracted_scarb_toml_data.name.clone(), - contract_paths[0].as_str() - ); - - let project_metadata = ProjectMetadataInfo { - cairo_version, - scarb_version, - contract_file, - project_dir_path: project_dir_path.as_str().to_owned(), - }; - - Ok((project_files, project_metadata)) -} diff --git a/crates/cli/src/utils.rs b/crates/cli/src/utils.rs deleted file mode 100644 index 1fe6be0..0000000 --- a/crates/cli/src/utils.rs +++ /dev/null @@ -1,45 +0,0 @@ -use dyn_compiler::dyn_compiler::{SupportedCairoVersions, SupportedScarbVersions}; -use std::process::Command; - -const SCARB_VERSION_OUTPUT_LINES: usize = 3; - -pub fn detect_local_tools() -> (SupportedScarbVersions, SupportedCairoVersions) { - let versioning = Command::new("scarb").arg("--version").output().expect( - " - Unable to detect local Scarb installation. - This CLI depends on Scarb and thus require it to be installed in the local machine. - You can install Scarb at https://docs.swmansion.com/scarb/. - ", - ); - - let versioning_str = String::from_utf8(versioning.stdout).unwrap(); - let version_list = versioning_str - .split('\n') - .filter(|x| !x.is_empty()) - .collect::>(); - if version_list.len() != SCARB_VERSION_OUTPUT_LINES { - panic!("{}", String::from_utf8(versioning.stderr).unwrap()); - } - let scarb_version = versioning_str.split('\n').collect::>()[0] - .split(" ") - .collect::>()[1]; - let cairo_version = versioning_str.split('\n').collect::>()[1] - .split(" ") - .collect::>()[1]; - - let scarb_version = match scarb_version { - "2.8.4" => SupportedScarbVersions::V2_8_4, - _ => panic!("Unsupported Scarb version: {}", scarb_version), - }; - - let cairo_version = match cairo_version { - "2.8.4" => SupportedCairoVersions::V2_8_4, - _ => { - println!("Unsupported Cairo version {}. We thus do not guarantee compatibility and compilation might fail as a result.", cairo_version); - // Use latest Scarb version as default. - SupportedCairoVersions::V2_8_4 - } - }; - - (scarb_version, cairo_version) -} diff --git a/crates/cli/src/validation.rs b/crates/cli/src/validation.rs deleted file mode 100644 index 005635b..0000000 --- a/crates/cli/src/validation.rs +++ /dev/null @@ -1,43 +0,0 @@ -use regex::Regex; - -const NORMALIZED_HASH_LENGTH: usize = 66; -const CLASS_HASH_PATTERN: &str = r"^0x[a-fA-F0-9]+$"; - -pub fn is_class_hash_valid(hash: &str) -> bool { - let re = Regex::new(CLASS_HASH_PATTERN).unwrap(); - - if hash.len() <= NORMALIZED_HASH_LENGTH && re.is_match(hash) { - return true; - } - - false -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_valid_class_hash_normalized() { - let valid_hash = "0x044dc2b3239382230d8b1e943df23b96f52eebcac93efe6e8bde92f9a2f1da18"; - assert!(is_class_hash_valid(valid_hash)); - } - - #[test] - fn test_valid_class_hash_without_leading_zeros() { - let valid_hash = "0x44dc2b3239382230d8b1e943df23b96f52eebcac93efe6e8bde92f9a2f1da18"; - assert!(is_class_hash_valid(valid_hash)); - } - - #[test] - fn test_invalid_class_hash_pattern() { - let invalid_hash = "0xGHIJKLMNOPQRSTUVWXYZ"; - assert!(!is_class_hash_valid(invalid_hash)); - } - - #[test] - fn test_invalid_class_hash_no_prefix() { - let invalid_hash = "1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef"; - assert!(!is_class_hash_valid(invalid_hash)); - } -} diff --git a/crates/cli/src/verify.rs b/crates/cli/src/verify.rs deleted file mode 100644 index 05a2186..0000000 --- a/crates/cli/src/verify.rs +++ /dev/null @@ -1,107 +0,0 @@ -use std::{env::current_dir, str::FromStr}; - -use anyhow::Result; -use camino::Utf8PathBuf; -use clap::{arg, Args}; - -use dyn_compiler::dyn_compiler::SupportedCairoVersions; - -use crate::{ - api::{ - dispatch_class_verification_job, poll_verification_status, FileInfo, Network, - ProjectMetadataInfo, - }, - license::LicenseType, - resolver::get_dynamic_compiler, -}; - -#[derive(Args, Debug)] -pub struct VerifyProjectArgs { - #[arg( - help = "Network to verify against", - default_value_t=String::from("mainnet"), - required = true - )] - pub network: String, - - #[arg(help = "Class hash to verify", required = true)] - pub hash: String, - - #[arg(help = "license type", required = true)] - pub license: LicenseType, - - #[arg(help = "Name", required = true)] - pub name: String, - - #[arg(help = "Source directory", required = true)] - pub path: Utf8PathBuf, - - #[arg(long, help = "Max retries")] - pub max_retries: Option, - - pub api_key: String, -} - -#[derive(Args, Debug)] -pub struct VerifyFileArgs { - #[arg(help = "File path")] - path: Utf8PathBuf, -} - -pub fn verify_project( - args: VerifyProjectArgs, - metadata: ProjectMetadataInfo, - files: Vec, -) -> Result<()> { - let network_enum = Network::from_str(args.network.as_str())?; - - let dispatch_response = dispatch_class_verification_job( - args.api_key.as_str(), - network_enum.clone(), - &args.hash, - args.license.to_long_string().as_str(), - &args.name, - metadata, - files, - ); - - let job_id = match dispatch_response { - Ok(response) => response, - Err(e) => { - return Err(anyhow::anyhow!( - "Failed to dispatch verification job: {}", - e - )); - } - }; - - // Retry for 5 minutes - let poll_result = poll_verification_status( - args.api_key.as_str(), - network_enum, - &job_id, - args.max_retries.unwrap_or(180), - ); - - match poll_result { - Ok(_response) => Ok(()), - Err(e) => Err(anyhow::anyhow!( - "Error while polling verification status: {}", - e - )), - } -} - -pub fn _verify_file(args: VerifyFileArgs, cairo_version: SupportedCairoVersions) -> Result<()> { - let file_dir: Utf8PathBuf = match args.path.is_absolute() { - true => args.path.clone(), - false => { - let mut current_path = current_dir().unwrap(); - current_path.push(args.path); - Utf8PathBuf::from_path_buf(current_path).unwrap() - } - }; - - let compiler = get_dynamic_compiler(cairo_version); - compiler.compile_file(&file_dir) -} diff --git a/crates/dyn-compiler/Cargo.toml b/crates/dyn-compiler/Cargo.toml deleted file mode 100644 index 8cd81e9..0000000 --- a/crates/dyn-compiler/Cargo.toml +++ /dev/null @@ -1,8 +0,0 @@ -[package] -name = "dyn-compiler" -version = "0.1.0" -edition = "2021" - -[dependencies] -camino.workspace = true -anyhow.workspace = true diff --git a/crates/dyn-compiler/README.md b/crates/dyn-compiler/README.md deleted file mode 100644 index 1e27718..0000000 --- a/crates/dyn-compiler/README.md +++ /dev/null @@ -1 +0,0 @@ -# dyn-compiler crate diff --git a/crates/dyn-compiler/src/dyn_compiler.rs b/crates/dyn-compiler/src/dyn_compiler.rs deleted file mode 100644 index bca6a3a..0000000 --- a/crates/dyn-compiler/src/dyn_compiler.rs +++ /dev/null @@ -1,45 +0,0 @@ -use anyhow::Result; -use camino::Utf8PathBuf; - -#[derive(Debug, Clone, Copy)] -pub enum SupportedCairoVersions { - V2_8_4, -} - -impl ToString for SupportedCairoVersions { - fn to_string(&self) -> String { - match self { - SupportedCairoVersions::V2_8_4 => "2.8.4".into(), - } - } -} - -#[derive(Debug, Clone, Copy)] -pub enum SupportedScarbVersions { - V2_8_4, -} - -impl ToString for SupportedScarbVersions { - fn to_string(&self) -> String { - match self { - SupportedScarbVersions::V2_8_4 => "2.8.4".into(), - } - } -} - -/** - * This trait is required to be implemented by the voyager resolvers. - * This allows us to use multiple version of Scarb + Cairo in the same project, - * and compile Scarb projects easily, - */ -pub trait DynamicCompiler { - fn get_supported_scarb_versions(&self) -> Vec; - - fn get_supported_cairo_versions(&self) -> Vec; - - fn get_contracts_to_verify_path(&self, project_path: &Utf8PathBuf) -> Result>; - - fn compile_project(&self, project_path: &Utf8PathBuf) -> Result<()>; - - fn compile_file(&self, file_path: &Utf8PathBuf) -> Result<()>; -} diff --git a/crates/dyn-compiler/src/lib.rs b/crates/dyn-compiler/src/lib.rs deleted file mode 100644 index b86113a..0000000 --- a/crates/dyn-compiler/src/lib.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod dyn_compiler; diff --git a/crates/voyager-resolver-cairo/Cargo.toml b/crates/voyager-resolver-cairo/Cargo.toml deleted file mode 100644 index 7860fed..0000000 --- a/crates/voyager-resolver-cairo/Cargo.toml +++ /dev/null @@ -1,57 +0,0 @@ -[package] -name = "voyager-resolver-cairo" -version.workspace = true -edition.workspace = true -repository.workspace = true -license-file.workspace = true - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -anyhow.workspace = true -starknet.workspace = true -indoc.workspace = true -itertools.workspace = true -salsa = "0.16.1" -scarb-metadata.workspace = true -serde.workspace = true -serde_json.workspace = true -smol_str.workspace = true -tracing = "0.1.37" -regex = "1.7.1" -petgraph = "0.5.0" -toml.workspace = true -toml_edit = "0.19.8" -rstest = "0.17.0" -camino.workspace = true -dyn-compiler = { path = "../dyn-compiler" } - -# All version dependent dependencies -cairo-lang-casm = "=2.8.4" -cairo-lang-compiler = "=2.8.4" -cairo-lang-debug = "=2.8.4" -cairo-lang-defs = "=2.8.4" -cairo-lang-diagnostics = "=2.8.4" -cairo-lang-filesystem = "=2.8.4" -cairo-lang-language-server = "=2.8.4" -cairo-lang-lowering = "=2.8.4" -cairo-lang-parser = "=2.8.4" -cairo-lang-plugins = "=2.8.4" -cairo-lang-project = "=2.8.4" -cairo-lang-semantic = "=2.8.4" -cairo-lang-sierra-generator = "=2.8.4" -cairo-lang-starknet = "=2.8.4" -cairo-lang-syntax = "=2.8.4" -cairo-lang-utils = "=2.8.4" -scarb = { git = "https://github.com/software-mansion/scarb", version = "=2.8.4", rev = "2aa4e19" } -scarb-ui = { git = "https://github.com/software-mansion/scarb", version = "=0.1.5", rev = "2aa4e19" } - -[dev-dependencies] -env_logger.workspace = true -cairo-lang-formatter = "=2.8.4" -cairo-lang-semantic = "=2.8.4" -cairo-lang-test-utils = "=2.8.4" -pretty_assertions.workspace = true -test-case = "2.2.2" -test-case-macros = "2.2.2" -test-log.workspace = true diff --git a/crates/voyager-resolver-cairo/src/compiler/mod.rs b/crates/voyager-resolver-cairo/src/compiler/mod.rs deleted file mode 100644 index c518885..0000000 --- a/crates/voyager-resolver-cairo/src/compiler/mod.rs +++ /dev/null @@ -1,582 +0,0 @@ -use anyhow::{anyhow, Context, Result}; -use cairo_lang_compiler::db::RootDatabase; -use cairo_lang_defs::ids::ModuleId; -use cairo_lang_filesystem::db::FilesGroup; -use cairo_lang_filesystem::ids::{CrateId, CrateLongId, FileLongId}; -use camino::Utf8PathBuf; -use scarb_utils::get_external_nonlocal_packages; -use std::clone; -use std::collections::HashMap; -use std::path::{Path, PathBuf}; -use std::thread::sleep; -use std::time::Duration; - -use cairo_lang_defs::db::DefsGroup; -use cairo_lang_diagnostics::ToOption; -use cairo_lang_utils::Upcast; -use petgraph::Graph; - -use crate::compiler::queries::collect_crate_module_files; -use crate::model::{CairoAttachmentModule, CairoCrate, CairoModule, ModulePath}; - -use crate::utils::{ - copy_required_files, create_attachment_files, generate_attachment_module_data, - get_import_remaps, run_scarb_build, -}; - -use crate::compiler::scarb_utils::{ - generate_scarb_updated_files, get_contracts_to_verify, read_scarb_metadata, - update_crate_roots_from_metadata, -}; -use crate::graph::{ - create_graph, get_required_module_for_contracts, EdgeWeight, _display_graphviz, -}; -use scarb::compiler::{CairoCompilationUnit, CompilationUnitAttributes, Compiler}; -use scarb::core::{TargetKind, Workspace}; -use scarb::flock::Filesystem; - -pub struct VoyagerGenerator; - -pub mod queries; -pub mod scarb_utils; - -impl Compiler for VoyagerGenerator { - fn target_kind(&self) -> TargetKind { - TargetKind::STARKNET_CONTRACT - } - - /// This function does not actually compile the code. Rather, it extracts - /// information about the project's crates, modules, and dependencies to perform various tasks related - /// to verifying and copying the Cairo code. These tasks include: - /// - /// - Building the project configuration, overriding it with the local corelib. - /// - Collecting the main crate IDs from the compilation unit and the compiler database, after updating it with Scarb's metadata. - /// - Extracting a vector of `CairoCrate` structs, which contain the crate root directory, main file, and modules for each crate in the project. - /// - Creating a graph where nodes are Cairo modules, and edges are the dependencies between modules. - /// - Reading the Scarb manifest file to get the list of contracts to verify from the [tool.voyager] section. - /// - Finding all module dependencies for the contracts to verify using the graph. - /// - Finding all "attachment" modules for the required modules. Attachment modules are modules that attach other modules to the module tree. - /// - Creating the attachment files for these modules. - /// - Getting the Cairo Modules corresponding to the required modules paths and copying these modules in the target directory. - /// - Generating the Scarb manifest files for the output directory, updating the dependencies to include the required modules as local dependencies. - /// - /// # Arguments - /// - /// * `unit` - The `CompilationUnit` containing the Cairo code to compile. - /// * `ws` - The `Workspace` containing the project. - /// - /// # Errors - /// - /// This function returns an error if any of the following occur: - /// - /// - The target has parameters. - /// - There is a problem getting the corelib path. - /// - There is a problem building the project configuration. - /// - There is a problem reading the Scarb metadata from the manifest file. - /// - There is a problem extracting the modules from a crate. - /// - There is a problem creating the graph. - /// - There is a problem getting the contracts to verify. - /// - There is a problem creating the attachment files. - /// - There is a problem copying the required modules to the target directory. - /// - There is a problem generating the Scarb manifest files for the output directory. - fn compile( - &self, - unit: CairoCompilationUnit, - db: &mut RootDatabase, - ws: &Workspace<'_>, - ) -> Result<()> { - // TODO: Do we still need this check?! - // Get the properties of the target to ensure it has no parameters - // As our custom compiler target is starknet-contracts by default. - // let props = unit.target.kind.downcast::(); - //ensure!( - // props.params.is_empty(), - // "target `{}` does not accept any parameters", - // props.kind_name - //); - - //let mut db = RootDatabase::builder() - // .with_project_config(config.clone()) - // .with_starknet() - // .build()?; - - // We can use Scarb metadata to update crate root info with external dependencies, - // This updates the compiler database with the crate roots of the external dependencies. - // This enables resolving external dependencies paths. - let manifest_path: PathBuf = unit.main_component().package.manifest_path().into(); - let root_path = match manifest_path.parent() { - Some(path) => path, - None => Path::new(""), - }; - let metadata = read_scarb_metadata(&manifest_path) - .expect("Failed to obtain Scarb metadata from manifest file."); - update_crate_roots_from_metadata(db, metadata.clone()); - - // We need all crate ids different than `core` - let project_crate_ids = unit - .components - .iter() - .filter(|component| component.cairo_package_name() != "core") - .map(|component| db.intern_crate(CrateLongId::Real(component.cairo_package_name()))) - .collect(); - - // Get a vector of CairoCrate, which contain the crate root directory, main file and modules for each crate in the project. - let project_crates = self.get_project_crates(db, project_crate_ids)?; - - // Collect all modules from all crates in the project. - let project_modules = project_crates - .iter() - .flat_map(|c| c.modules.iter().cloned()) - .collect::>(); - - // Creates a graph where nodes are Cairo modules, and edges are the dependencies between modules. - let graph = create_graph(&project_modules); - - // Read Scarb manifest file to get the list of contracts to verify from the [tool.voyager] section. - // This returns the relative file paths of the contracts to verify. - let contracts_to_verify = get_contracts_to_verify(&unit.main_component().package)?; - - if contracts_to_verify.is_empty() { - return Err(anyhow!("No contracts found.")); - } - if contracts_to_verify.len() > 1 { - return Err(anyhow!("Currently doesn't support multiple contracts.")); - } - - // Check if the path exists, which requires us to know the absolute path. - if !root_path - .join("src") - .join(contracts_to_verify[0].clone()) - .exists() - { - return Err(anyhow!( - "Unable to find the contract file given in Scarb.toml" - )); - } - - // Collect the CairoModule corresponding to the file paths of the contracts. - let modules_to_verify = project_modules - .iter() - .filter(|m| contracts_to_verify.contains(&m.relative_filepath)) - .collect::>(); - - let external_packages = get_external_nonlocal_packages(metadata.clone()); - - let (required_modules_paths, attachment_modules_data) = - self.get_reduced_project(&graph, modules_to_verify.clone())?; - - // Filter away packages that are external, imported from git repository & std. - let attachment_modules_data = attachment_modules_data - .iter() - .filter(|(k, _)| { - let base_package_name = &k.0.split("::").collect::>()[0].to_string(); - !external_packages.contains(base_package_name) && base_package_name != "super" - }) - .map(|(k, v)| (k.clone(), v.clone())) - .collect::>(); - - let target_dir = Utf8PathBuf::from( - manifest_path - .parent() - .unwrap() - .join("voyager-verify") - .to_str() - .unwrap(), - ); - - // Clean directory - std::fs::remove_dir_all(target_dir.clone()).unwrap_or_else(|e| { - if e.kind() != std::io::ErrorKind::NotFound { - panic!( - "Error removing target directory \"{}\" caused by:\n{}", - target_dir, e - ) - } - }); - - // treat target dir as a Filesystem - let target_dir = Filesystem::new(target_dir); - - create_attachment_files(&attachment_modules_data, &target_dir) - .with_context(|| "Failed to create attachment files")?; - - // Get the Cairo Modules corresponding to the required modules paths. - let required_modules = project_modules - .iter() - .filter(|m| { - let base_package_name = &m.path.0.split("::").collect::>()[0].trim(); - required_modules_paths.contains(&m.path) - && !external_packages.contains(&base_package_name.to_string()) - }) - .collect::>(); - // Copy these modules in the target directory. - // Copy readme files and license files over too - copy_required_files(&required_modules, &target_dir, ws)?; - - // Generate each of the Scarb manifest files for the output directory. - // The dependencies are updated to include the required modules as local dependencies. - generate_scarb_updated_files(metadata, &target_dir, required_modules, external_packages)?; - - let package_name = unit.main_component().package.id.name.to_string(); - let generated_crate_dir = target_dir.path_existent().unwrap().join(package_name); - - // Problem with this step is that sometimes the build happens faster than the Scarb.toml is actually created and detected. - // For some weird reason this is only an issue before Cairo 2.6? - // Adding this artificial delay here in order to hopefully resolve this, or at least reduce its occurrences. - // TODO: actually addressing this, or not. Likely related to this https://github.com/rust-lang/rust/issues/51775 - // likely also related to the fact that during compilation and resolving the git cloned libraries takes some time to be - // pulled and updated, which might have caused this. - sleep(Duration::from_secs(2)); - - // Locally run Scarb build to make sure that everything compiles correctly before sending the files to voyager. - run_scarb_build(generated_crate_dir.as_str())?; - - Ok(()) - } -} - -impl VoyagerGenerator { - /// Gets a vector of `CairoCrate` structs, given a database and a list of crate IDs - /// - /// # Arguments - /// * `db` - a mutable reference to the root database - /// * `project_crate_ids` - a vector of `CrateId` values representing the IDs of the crates to be retrieved - /// - /// # Returns - /// `Result>` - a vector of `CairoCrate` structs. - /// Returns `Ok` with the vector if the operation is successful, otherwise returns `Err`. - fn get_project_crates( - &self, - db: &mut RootDatabase, - project_crate_ids: Vec, - ) -> Result> { - let project_crates = project_crate_ids - .iter() - .map(|crate_id| -> Result { - let crate_id = *crate_id; - - // Get the root directory and main file (lib.cairo) for the crate. - // The main file is expected to be an OnDisk file. - let defs_db = db.upcast(); - let crate_root_dir = defs_db - .crate_config(crate_id) - .expect( - format!( - "Failed to get crate root directory for crate ID {:?}", - crate_id - ) - .as_str(), - ) - .root; - - let main_file = defs_db - .module_main_file(ModuleId::CrateRoot(crate_id)) - .to_option() - .with_context(|| { - format!("Failed to get main file for crate ID {:?}", crate_id) - })?; - let main_file_path = match db.lookup_intern_file(main_file) { - FileLongId::OnDisk(path) => path, - FileLongId::Virtual(_) => panic!("Expected OnDisk file, found Virtual."), - FileLongId::External(_) => panic!("Expected OnDisk file, found External."), - }; - - // Extract a vector of modules for the crate. - // We only collect "file" modules, which are related to a Cairo file. - // Internal modules are not collected here. - let crate_modules = collect_crate_module_files(db, crate_id)?; - Ok(CairoCrate { - root_dir: crate_root_dir, - main_file: main_file_path, - modules: crate_modules, - }) - }) - .collect::>>()?; - Ok(project_crates) - } - - /// Given the module graph and a list of module contracts to verify, - /// returns the path of the modules required for compilation, and the data for the attachment modules. - /// Attachment modules are modules that declare submodules, attaching them to the module tree. - /// These modules don't have content that is required by the contracts to verify, - /// but they are required for compilation as they structure the module tree. - /// - /// # Arguments - /// * `graph` - a reference to the graph containing the module dependencies - /// * `modules_to_verify` - a vector of references to `CairoModule` structs that need to be verified - /// - /// # Returns - /// `Result<(Vec, HashMap)>` - a tuple containing a vector of module paths and a hash map of module paths to `CairoAttachmentModule` structs. - /// Returns `Ok` with the tuple if the operation is successful, otherwise returns `Err`. - pub fn get_reduced_project( - &self, - graph: &Graph, - modules_to_verify: Vec<&CairoModule>, - ) -> Result<(Vec, HashMap)> { - // Using the graph, find all module dependencies for the contracts to verify. - // Modules forward declarations are not included in the dependencies. - let required_modules_paths = get_required_module_for_contracts(graph, &modules_to_verify)?; - - // Find all "attachment" modules for the required modules. Attachment modules are modules that forward declare submodules, - // attaching them to the module tree. - // We then create the attachment files for these modules. - let imports_path_not_matching_resolved_path = get_import_remaps(modules_to_verify); - - let attachment_modules_data = generate_attachment_module_data( - &required_modules_paths, - imports_path_not_matching_resolved_path.clone(), - ); - - let unrequired_attachment_modules: HashMap = - attachment_modules_data - .iter() - .filter(|(k, _)| !required_modules_paths.contains(k)) - .map(|(k, v)| (k.clone(), v.clone())) - .collect(); - Ok((required_modules_paths, unrequired_attachment_modules)) - } -} - -#[cfg(test)] -mod tests { - use crate::compiler::queries::collect_crate_module_files; - use crate::compiler::VoyagerGenerator; - use crate::graph::create_graph; - use crate::model::{CairoAttachmentModule, ModulePath}; - use crate::utils::test_utils::set_file_content; - use cairo_lang_compiler::db::RootDatabase; - use cairo_lang_filesystem::db::{CrateConfiguration, FilesGroup, FilesGroupEx}; - use cairo_lang_filesystem::ids::{CrateLongId, Directory}; - use cairo_lang_semantic::plugin::PluginSuite; - use cairo_lang_starknet::plugin::StarkNetPlugin; - use std::collections::HashSet; - use std::path::PathBuf; - - #[test] - fn test_reduced_project_no_remap() { - let db = &mut RootDatabase::builder() - .with_plugin_suite( - PluginSuite::default() - .add_plugin::() - .to_owned(), - ) - .build() - .unwrap(); - - let crate_id = db.intern_crate(CrateLongId::Real("test".into())); - let root = Directory::Real("src".into()); - db.set_crate_config(crate_id, Some(CrateConfiguration::default_for_root(root))); - - // Main module file - set_file_content(db, "src/lib.cairo", "mod submod;\n mod contract;"); - - // Contract module file - set_file_content( - db, - "src/contract.cairo", - &format!( - " - #[contract] - mod ERC20 {{ - use {path}; - }} - ", - path = ModulePath::new("test::submod::subsubmod::foo") - ), - ); - - // Submod and subsubmod module files - set_file_content(db, "src/submod.cairo", "mod subsubmod;"); - set_file_content( - db, - "src/submod/subsubmod.cairo", - &format!( - " - {implementation} - ", - implementation = "fn foo(){}".to_owned(), - ), - ); - - let modules = collect_crate_module_files(db, crate_id).unwrap(); - let graph = create_graph(&modules); - let contracts_to_verify = vec![PathBuf::from("contract.cairo")]; - // Map the relative file paths to the module paths inside the crate. - let modules_to_verify = modules - .iter() - .filter(|m| contracts_to_verify.contains(&m.relative_filepath)) - .collect::>(); - - let voyager_compiler = VoyagerGenerator {}; - let (required_modules_paths, _) = voyager_compiler - .get_reduced_project(&graph, modules_to_verify) - .unwrap(); - assert_eq!(required_modules_paths.len(), 2); - assert_eq!(required_modules_paths[0], ModulePath::new("test::contract")); - assert_eq!( - required_modules_paths[1], - ModulePath::new("test::submod::subsubmod") - ) - } - - #[test] - fn test_reduced_project_with_remap() { - let db = &mut RootDatabase::builder() - .with_plugin_suite( - PluginSuite::default() - .add_plugin::() - .to_owned(), - ) - .build() - .unwrap(); - - let crate_id = db.intern_crate(CrateLongId::Real("test".into())); - - let root = Directory::Real("src".into()); - db.set_crate_config(crate_id, Some(CrateConfiguration::default_for_root(root))); - - // Main module file - set_file_content( - db, - "src/lib.cairo", - "mod submod;\n mod contract\n; \ - use submod::subsubmod::foo;", - ); - - // Contract module file - set_file_content( - db, - "src/contract.cairo", - &format!( - " - #[contract] - mod ERC20 {{ - use {path}; - }} - ", - path = ModulePath::new("test::foo") - ), - ); - - // Submod and subsubmod module files - set_file_content(db, "src/submod.cairo", "mod subsubmod;"); - set_file_content( - db, - "src/submod/subsubmod.cairo", - &format!( - " - {implementation} - ", - implementation = "fn foo(){}".to_owned(), - ), - ); - - let modules = collect_crate_module_files(db, crate_id).unwrap(); - let graph = create_graph(&modules); - let contracts_to_verify = vec![PathBuf::from("contract.cairo")]; - // Map the relative file paths to the module paths inside the crate. - let modules_to_verify = modules - .iter() - .filter(|m| contracts_to_verify.contains(&m.relative_filepath)) - .collect::>(); - - let voyager_compiler = VoyagerGenerator {}; - let (required_modules_paths, attachment_modules_data) = voyager_compiler - .get_reduced_project(&graph, modules_to_verify) - .unwrap(); - - // contract.cairo depends on test::submod::submod(::foo) - assert_eq!(required_modules_paths.len(), 2); - assert_eq!(required_modules_paths[0], ModulePath::new("test::contract")); - assert_eq!( - required_modules_paths[1], - ModulePath::new("test::submod::subsubmod") - ); - - // lib.cairo imports test::submod::subsubmod::foo and makes it available in the root module - assert_eq!(attachment_modules_data.len(), 2); - assert_eq!( - attachment_modules_data - .get(&ModulePath::new("test")) - .unwrap(), - &CairoAttachmentModule { - path: ModulePath::new("test"), - children: HashSet::from([ModulePath::new("submod"), ModulePath::new("contract")]), - imports: HashSet::from([ModulePath::new("test::submod::subsubmod::foo")]), - } - ); - - assert_eq!( - attachment_modules_data - .get(&ModulePath::new("test::submod")) - .unwrap(), - &CairoAttachmentModule { - path: ModulePath::new("test::submod"), - children: HashSet::from([ModulePath::new("subsubmod")]), - imports: HashSet::new(), - } - ); - } - - #[test] - fn test_reduced_project_import_from_attachment() { - let db = &mut RootDatabase::builder() - .with_plugin_suite( - PluginSuite::default() - .add_plugin::() - .to_owned(), - ) - .build() - .unwrap(); - - let crate_id = db.intern_crate(CrateLongId::Real("test".into())); - let root = Directory::Real("src".into()); - db.set_crate_config(crate_id, Some(CrateConfiguration::default_for_root(root))); - - // Main module file - set_file_content(db, "src/lib.cairo", "mod submod;\n mod contract;"); - - // Contract module file - set_file_content( - db, - "src/contract.cairo", - &format!( - " - #[contract] - mod ERC20 {{ - use {path}; - }} - ", - path = ModulePath::new("test::submod::foo") - ), - ); - - // Submod and subsubmod module files - set_file_content(db, "src/submod.cairo", "mod subsubmod;\n fn foo(){}"); - set_file_content(db, "src/submod/subsubmod.cairo", ""); - - let modules = collect_crate_module_files(db, crate_id).unwrap(); - let graph = create_graph(&modules); - let contracts_to_verify = vec![PathBuf::from("contract.cairo")]; - // Map the relative file paths to the module paths inside the crate. - let modules_to_verify = modules - .iter() - .filter(|m| contracts_to_verify.contains(&m.relative_filepath)) - .collect::>(); - - let voyager_compiler = VoyagerGenerator {}; - let (required_modules_paths, _attachment_modules_data) = voyager_compiler - .get_reduced_project(&graph, modules_to_verify) - .unwrap(); - - // Here, subsubmod is required because we import a content from its parent "submod". - // Therefore, the whole `submod` file is required. - assert_eq!(required_modules_paths.len(), 3); - assert_eq!(required_modules_paths[0], ModulePath::new("test::contract")); - assert_eq!(required_modules_paths[1], ModulePath::new("test::submod")); - assert_eq!( - required_modules_paths[2], - ModulePath::new("test::submod::subsubmod") - ); - } -} diff --git a/crates/voyager-resolver-cairo/src/compiler/queries.rs b/crates/voyager-resolver-cairo/src/compiler/queries.rs deleted file mode 100644 index a7a2f3f..0000000 --- a/crates/voyager-resolver-cairo/src/compiler/queries.rs +++ /dev/null @@ -1,966 +0,0 @@ -use anyhow::{anyhow, Context, Result}; -use cairo_lang_compiler::db::RootDatabase; -use cairo_lang_defs::db::DefsGroup; -use cairo_lang_defs::ids::{ - FileIndex, LanguageElementId, ModuleFileId, ModuleId, NamedLanguageElementId, - TopLevelLanguageElementId, UseId, UseLongId, VarId, -}; -use cairo_lang_filesystem::db::FilesGroup; -use cairo_lang_filesystem::ids::{CrateId, Directory, FileId, FileLongId}; -use cairo_lang_semantic::diagnostic::NotFoundItemType; -use cairo_lang_semantic::expr::inference::InferenceId; -use cairo_lang_semantic::items::us::get_use_segments; -use cairo_lang_semantic::resolve::{ResolvedGenericItem, Resolver}; -use cairo_lang_syntax::node::ast::{MaybeModuleBody, UsePath, UsePathLeaf}; -use cairo_lang_syntax::node::{ast, Terminal, TypedSyntaxNode}; -use cairo_lang_utils::ordered_hash_map::OrderedHashMap; -use cairo_lang_utils::Upcast; -use itertools::Itertools; -use std::collections::{HashMap, HashSet}; -use std::fmt::Debug; - -use crate::model::{CairoImport, CairoImportType, CairoModule, CairoSubmodules, ModulePath}; -use cairo_lang_diagnostics::{DiagnosticsBuilder, ToOption}; -use cairo_lang_semantic::items::functions::GenericFunctionId; - -use std::path::PathBuf; - -#[derive(Clone, Debug, Hash, PartialEq, Eq)] -pub struct FileData { - pub id: FileId, - pub name: String, - pub path: PathBuf, - pub index: usize, -} - -impl FileData { - pub fn new(id: FileId, name: String, path: PathBuf, index: usize) -> Self { - Self { - id, - name, - path, - index, - } - } - - pub fn get_path(&self) -> PathBuf { - self.path.clone() - } - - pub fn get_relative_path(&self, root: &PathBuf) -> Result { - Ok(self - .path - .strip_prefix(root) - .with_context(|| format!("Couldn't strip prefix {}", root.display()))? - .to_path_buf()) - } -} - -/// Extracts the imports of a child module and adds them to a hash map. -/// -/// The function recursively processes the child module's top-level items. If a child module -/// contains a `use` statement, it's added to a hash map with the corresponding `UseId`. If it -/// contains another child module, the function is called recursively on that child module. -/// -/// # Arguments -/// -/// * `db` - A trait object that provides access to the database. -/// * `module_ast` - The syntax tree node for the child module to process. -/// * `module_file_id` - The ID of the file that contains the child module. -/// * `module_uses` - A mutable hash map that stores the `UseId` and syntax tree node for each -/// `use` statement found in the module and its children. -/// -fn extract_child_module_imports( - db: &dyn DefsGroup, - module_ast: &ast::ItemModule, - module_file_id: ModuleFileId, - module_uses: &mut OrderedHashMap, -) { - if let MaybeModuleBody::Some(module_body) = module_ast.body(db.upcast()) { - module_body - .items(db.upcast()) - .elements(db.upcast()) - .iter() - .for_each(|el| match el { - ast::ModuleItem::Use(item_use) => capture_imports( - db, - module_file_id, - module_uses, - item_use.use_path(db.upcast()), - ), - ast::ModuleItem::Module(item_module) => { - extract_child_module_imports(db, item_module, module_file_id, module_uses); - } - _ => {} - }); - } -} - -pub fn capture_modules_submodules( - db: &RootDatabase, - file_id: FileId, - module_id: ModuleId, -) -> Result> { - let mut submodules: Vec = vec![]; - // We check if there are any defined submodules in the given module. - // If so recursively resolve them. - let found_submodules = match db.module_submodules_ids(module_id) { - Ok(submod) => submod, - Err(_) => return Err(anyhow!("Fail to resolve module submodules")), - }; - - for submod in found_submodules.iter() { - let submod_id = ModuleId::Submodule(*submod); - // Check that the location of the submodule is of the same as the module's file. - // This prevent over-resoluting the modules. - if let Some(submod_file_data) = get_module_file(db, submod_id) { - if submod_file_data.id == file_id { - let root_mod_path = module_id.full_path(db); - let current_mod_path = submod_id.full_path(db); - let mod_name = match current_mod_path - .strip_prefix(format!("{}::", root_mod_path.as_str()).as_str()) - { - Some(name) => name.to_string(), - None => return Err(anyhow!("Fail to compute submod name from path")), - }; - submodules.push(CairoSubmodules { - name: mod_name, - parent_path: ModulePath::new(root_mod_path), - path: ModulePath::new(current_mod_path), - }); - let submod_submods = capture_modules_submodules(db, file_id, submod_id)?; - submodules.extend(submod_submods); - } - } - } - - Ok(submodules) -} - -/// Recursively capture all the use statements of a given file, inclusive of the root -/// module of the file and also the submodules of the file, while retaining the -/// context of the modules in which the use statements were at. -fn capture_file_modules_uses( - db: &RootDatabase, - file_id: FileId, - module_id: ModuleId, - module_uses: &mut OrderedHashMap, -) -> Result<()> { - // First we capture the given module id imports. - let found_module_uses = match db.module_uses(module_id) { - Ok(mods) => mods, - Err(_) => return Err(anyhow!("Fail to resolve modules uses")), - }; - - for (use_id, use_path_leaf) in found_module_uses.iter() { - module_uses.insert(*use_id, (use_path_leaf.clone(), module_id)); - } - - // We then check if there are any defined submodules in the given module. - // If so recursively resolve them. - let found_submodules = match db.module_submodules_ids(module_id) { - Ok(submod) => submod, - Err(_) => return Err(anyhow!("Fail to resolve module submodules")), - }; - - for submod in found_submodules.iter() { - let submod_id = ModuleId::Submodule(*submod); - // Check that the location of the submodule is of the same as the module's file. - // This prevent over-resoluting the modules. - if let Some(submod_file_data) = get_module_file(db, submod_id) { - if submod_file_data.id == file_id { - capture_file_modules_uses(db, file_id, submod_id, module_uses)?; - } - } - } - - Ok(()) -} - -/// Extracts the imports of a child module and adds them to a hash map. -/// -/// The function recursively processes a use import. If a path containts only an -/// import, the use statmenent is added to the hash map with the corresponding `UseId`. -/// If a use contains more than one use path, it is recursively added. -/// -/// # Arguments -/// -/// * `db` - A trait object that provides access to the database. -/// * `module_file_id` - The ID of the file that contains the child module. -/// * `module_uses` - A mutable hash map that stores the `UseId` and syntax tree node for each -/// * `item_use` - The use statment -/// * `use_path` - The use path of the use statement -/// -fn capture_imports( - db: &dyn DefsGroup, - module_file_id: ModuleFileId, - module_uses: &mut OrderedHashMap, - use_path: UsePath, -) { - match use_path { - UsePath::Leaf(use_path_leaf) => { - let use_id = db.intern_use(UseLongId(module_file_id, use_path_leaf.stable_ptr())); - module_uses.insert(use_id, use_path_leaf.clone()); - } - UsePath::Single(use_path_single) => capture_imports( - db, - module_file_id, - module_uses, - use_path_single.use_path(db.upcast()), - ), - UsePath::Multi(use_path_multiple) => { - use_path_multiple - .use_paths(db.upcast()) - .elements(db.upcast()) - .into_iter() - .for_each(|use_path_i| { - capture_imports(db, module_file_id, module_uses, use_path_i) - }); - } - }; -} - -/// This function extracts the modules for a given crate and returns them as a vector of `CairoModule`s. -/// -/// # Arguments -/// -/// * `db` - A reference to the root database to search for the crate and module data. -/// * `crate_id` - The `CrateId` of the crate for which to extract module data. -/// -/// # Returns -/// -/// * A `Vec` representing the modules for the given crate, if they exist. -/// -/// # Example -/// -pub fn collect_crate_module_files( - db: &RootDatabase, - crate_id: CrateId, -) -> Result> { - let mut crate_modules = vec![]; - let defs_db: &dyn DefsGroup = db.upcast(); - let mut visited_files = HashMap::new(); - - let crate_root_dir = match db - .crate_config(crate_id) - .expect( - format!( - "Failed to get crate root directory for crate ID {:?}", - crate_id - ) - .as_str(), - ) - .root - { - Directory::Real(path) => path.display().to_string(), - Directory::Virtual { .. } => { - return Err(anyhow!("Virtual directories are not supported")); - } - }; - - // Piece of code for debugging. Leaving this in for later usage. - // for module_id in &*defs_db.crate_modules(crate_id) { - // println!("******"); - // println!("module id {:?}", module_id); - // println!("module id full path {:?}", module_id.full_path(db)); - // let module_file_data: Option = get_module_file(db, *module_id); - // println!("module file {:?}", module_file_data.clone()); - // } - - for module_id in &*defs_db.crate_modules(crate_id) { - let module_file = defs_db - .module_main_file(ModuleId::CrateRoot(crate_id)) - .to_option() - .with_context(|| format!("Expected module file for module {:?}", module_id))?; - let main_file_path = match db.lookup_intern_file(module_file) { - FileLongId::OnDisk(path) => Ok(path), - FileLongId::Virtual(_) => { - Err(anyhow!("Expected OnDisk file for module {:?}", module_id)) - } - FileLongId::External(_) => { - Err(anyhow!("Expected OnDisk file for module {:?}", module_id)) - } - }?; - let module_file_data = get_module_file(db, *module_id); - - // A module without a file means that it's a submodule inside a file module. - if let Some(file) = module_file_data { - // Skip files that have already been visited. - // This happens when a file defines multiple modules. - if visited_files.contains_key(&file) { - continue; - } - visited_files.insert(file.clone(), true); - - let defs_group: &dyn DefsGroup = db.upcast(); - let module_dir: String = match defs_group - .module_dir(*module_id) - .to_option() - .with_context(|| { - format!("Could not get module directory for module {:?}", module_id) - })? { - Directory::Real(path) => path.display().to_string(), - Directory::Virtual { .. } => { - return Err(anyhow!("Virtual directories are not supported")); - } - }; - let module_imports = HashSet::from_iter(extract_file_imports(db, *module_id, &file)?); - let module_submodules = capture_modules_submodules(db, file.id, *module_id)?; - let cairo_module_data = CairoModule { - dir: module_dir.into(), - main_file: main_file_path, - path: ModulePath::new(module_id.full_path(db.upcast())), - filepath: file.path.clone(), - relative_filepath: file.get_relative_path(&PathBuf::from(&crate_root_dir))?, - imports: module_imports, - submodules: module_submodules, - }; - crate_modules.push(cairo_module_data); - } - } - Ok(crate_modules) -} - -/// This function extracts the file data for a given module and returns it as an `Option`. -/// -/// # Arguments -/// -/// * `db` - A reference to the root database to search for the module and file data. -/// * `module_id` - The `ModuleId` of the module for which to extract file data. -/// -/// # Returns -/// -/// * An `Option` representing the file data for the given module, if it exists. Returns `None` if the file is a virtual file. -pub fn get_module_file(db: &RootDatabase, module_id: ModuleId) -> Option { - // Get the module's files. Only gets OnDisk files, no virtual files. - // If the module in question is not the root module of the file, - // it returns the file that contains the module. - let module_file_ids = db.module_files(module_id).to_option()?; - let module_file = - module_file_ids - .iter() - .find(|file_id| match db.lookup_intern_file(**file_id) { - FileLongId::OnDisk(_) => true, - FileLongId::Virtual(_) => false, - FileLongId::External(_) => false, - })?; - match db.lookup_intern_file(*module_file) { - FileLongId::OnDisk(path) => Some(FileData { - id: *module_file, - name: module_file.file_name(db), - path, - index: 0, - }), - FileLongId::Virtual(_) => None, - FileLongId::External(_) => None, - } -} - -fn collect_submodule_declarations( - db: &RootDatabase, - module_id: &ModuleId, - parent_path: &str, -) -> Vec { - let mut imports = Vec::new(); - let arc_module_declarations = db.module_submodules(*module_id).unwrap(); - - let module_declarations = (*arc_module_declarations).clone(); - - for (k, v) in module_declarations.iter() { - let submodule_name = v.name(db).text(db); - let submodule_path = format!("{}::{}", parent_path, submodule_name); - match v.body(db) { - MaybeModuleBody::None(_) => { - imports.push(CairoImport { - name: submodule_name.to_string(), - path: ModulePath::new(submodule_path.clone()), - resolved_path: ModulePath::new(submodule_path), - import_type: CairoImportType::Module, - }); - } - - MaybeModuleBody::Some(_body) => { - let module_id = ModuleId::Submodule(*k); - let mut declared_modules = - collect_submodule_declarations(db, &module_id, &submodule_path); - imports.append(&mut declared_modules); - } - } - } - // TODO: maybe we need to make this unique via a hashmap? - imports -} - -/// This function extracts the imports from a file and returns them as a `Vec` of `CairoImport`s. -/// -/// # Arguments -/// -/// * `db` - A reference to the root database to search for the file and resolve imports. -/// * `module_id` - The `ModuleId` of the module containing the file for which to extract imports. -/// * `file_data` - A reference to a `FileData` struct representing the file for which to extract imports. -/// -/// # Returns -/// -/// * A `Vec` of `CairoImport`s representing the imports in the given file. -pub fn extract_file_imports( - db: &RootDatabase, - module_id: ModuleId, - file_data: &FileData, -) -> Result> { - let mut imports: Vec = vec![]; - let mut module_uses: OrderedHashMap = OrderedHashMap::default(); - - // Attempt to capture all modules uses for this module recursively - match capture_file_modules_uses(db, file_data.id, module_id, &mut module_uses) { - Ok(_) => (), - Err(err) => return Err(err), - }; - - let file_module_name = module_id.full_path(db); - let submodules_declarations = collect_submodule_declarations(db, &module_id, &file_module_name); - imports.extend(submodules_declarations); - - // Resolve the module's imports - // the resolver depends on the current module file id - let mut diagnostics = DiagnosticsBuilder::default(); - - for (use_id, (use_path, use_mod_id)) in module_uses.iter() { - // Use Path needs to break down into segments - let mut segments = vec![]; - get_use_segments(db, &ast::UsePath::Leaf(use_path.clone()), &mut segments).unwrap(); - - let import_path = segments - .clone() - .into_iter() - .map(|x| x.as_syntax_node().get_text(db).trim().to_string()) - .join("::"); - - // The resolver must resolve using the correct module that is importing it. - let mut resolver = Resolver::new( - db, - ModuleFileId(*use_mod_id, FileIndex(0)), - InferenceId::NoContext, - ); - - let resolved_item_maybe = - resolver.resolve_generic_path(&mut diagnostics, segments, NotFoundItemType::Identifier); - - // If the import is resolved, get the full path - if let Ok(resolved_item) = resolved_item_maybe { - let full_path = get_full_path(db.upcast(), &resolved_item); - let import_type = match resolved_item { - ResolvedGenericItem::Module(_) => CairoImportType::Module, - _ => CairoImportType::Other, - }; - - // Turns out there are generated code that are considered uses even - // when there's no 'use' keyword used. These usually start with dunder (__), - // or double underscore. We avoid those. - // TODO: Since there is a chance where people do use dunder for their module imports - // this will not work foolproof. Fix that! - // We also don't want anything starting with core (which are builtins). - if !import_path.starts_with("__") && !full_path.starts_with("core") { - imports.push(CairoImport { - name: use_id.name(db).to_string(), - path: ModulePath::new(import_path.clone()), - resolved_path: ModulePath::new(full_path), - import_type, - }); - } - } else { - return Err(anyhow!( - "IMPORT NOT RESOLVED: {}", - use_path.as_syntax_node().get_text(db.upcast()) - )); - } - } - - Ok(imports) -} - -/// Returns the full path of a resolved generic item in the compiler database. -/// -/// # Arguments -/// -/// * `db` - A reference to the root database to search for the resolved generic item. -/// * `resolved_item` - The resolved generic item for which to retrieve the full path. -/// -/// # Returns -/// -/// * A `String` representing the full path of the resolved generic item if successful. -/// -fn get_full_path(db: &RootDatabase, resolved_item: &ResolvedGenericItem) -> String { - match resolved_item { - ResolvedGenericItem::Trait(trait_id) => trait_id.full_path(db), - ResolvedGenericItem::GenericConstant(const_id) => const_id.full_path(db), - ResolvedGenericItem::Module(module_id) => module_id.full_path(db), - ResolvedGenericItem::GenericFunction(generic_func_id) => { - match generic_func_id { - GenericFunctionId::Free(id) => id.full_path(db), - GenericFunctionId::Extern(id) => id.full_path(db), - GenericFunctionId::Impl(id) => { - //TODO figure out whether trait_id or impl_id is required here - id.function.full_path(db) - } - GenericFunctionId::Trait(concrete_trait_generic_function_id) => { - concrete_trait_generic_function_id - .trait_function(db) - .full_path(db) - } - } - } - ResolvedGenericItem::TraitFunction(trait_func_id) => trait_func_id.full_path(db), - ResolvedGenericItem::GenericType(generic_type_id) => generic_type_id.full_path(db), - ResolvedGenericItem::GenericTypeAlias(generic_type_alias) => { - generic_type_alias.full_path(db) - } - ResolvedGenericItem::Variant(variant) => variant.enum_id.full_path(db), - ResolvedGenericItem::Impl(impl_id) => impl_id.full_path(db), - ResolvedGenericItem::GenericImplAlias(impl_alias) => impl_alias.full_path(db), - ResolvedGenericItem::Variable(var_id) => match var_id { - VarId::Param(param_id) => param_id.full_path(db), - VarId::Local(local_var_id) => local_var_id.module_file_id(db).0.full_path(db), - }, - } -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::utils::test_utils::{set_file_content, setup_test_files_with_imports, TestImport}; - use cairo_lang_defs::db::DefsGroup; - use cairo_lang_filesystem::db::{CrateConfiguration, FilesGroup, FilesGroupEx}; - use cairo_lang_filesystem::ids::{CrateLongId, Directory}; - use cairo_lang_semantic::plugin::PluginSuite; - use cairo_lang_starknet::plugin::StarkNetPlugin; - - fn setup_default_environment( - path: &str, - implementation: &str, - _import_type: CairoImportType, - ) -> Result<(RootDatabase, ModuleId, FileData, CrateId)> { - let db = &mut RootDatabase::builder() - .with_plugin_suite( - PluginSuite::default() - .add_plugin::() - .to_owned(), - ) - .build()?; - - let test_import = TestImport { - path: ModulePath::new(path), - implementation: implementation.to_owned(), - }; - let _crate_id = setup_test_files_with_imports(db, test_import); - let path: PathBuf = "src/contract.cairo".into(); - let module_id = db.file_modules(FileId::new(db, path.clone())).unwrap()[0]; - let file_id = db.intern_file(FileLongId::OnDisk(path.clone())); - let file_data = FileData { - id: file_id, - name: file_id.file_name(db), - path, - index: 0, - }; - - Ok((db.snapshot(), module_id, file_data, _crate_id)) - } - - macro_rules! assert_import_properties { - ($import:expr, $name:expr, $resolved_path:expr, $import_type:expr) => { - assert_eq!($import.name, $name); - assert_eq!($import.resolved_path, ModulePath::new($resolved_path)); - assert_eq!($import.import_type, $import_type); - }; - } - - #[test] - fn test_extract_import_module() -> Result<(), Box> { - let (db, module_id, file_data, _) = setup_default_environment( - "test::submod::subsubmod::mod_a", - "mod mod_a{}", - CairoImportType::Module, - )?; - - let import = extract_file_imports(&db, module_id, &file_data)?[0].clone(); - assert_import_properties!( - import, - "mod_a", - "test::submod::subsubmod::mod_a", - CairoImportType::Module - ); - - Ok(()) - } - - #[test] - fn test_extract_declared_module() -> Result<(), Box> { - let db = &mut RootDatabase::builder() - .with_plugin_suite( - PluginSuite::default() - .add_plugin::() - .to_owned(), - ) - .build()?; - - let crate_id = db.intern_crate(CrateLongId::Real("test".into())); - let root = Directory::Real("src".into()); - db.set_crate_config(crate_id, Some(CrateConfiguration::default_for_root(root))); - set_file_content(db, "src/lib.cairo", "mod submod;"); - set_file_content(db, "src/submod.cairo", "fn foo{}"); - let path: PathBuf = "src/lib.cairo".into(); - let module_id = db.file_modules(FileId::new(db, path.clone())).unwrap()[0]; - let file_id = db.intern_file(FileLongId::OnDisk(path.clone())); - let file_data = FileData { - id: file_id, - name: file_id.file_name(db), - path, - index: 0, - }; - let import = extract_file_imports(db, module_id, &file_data)?[0].clone(); - assert_import_properties!(import, "submod", "test::submod", CairoImportType::Module); - - Ok(()) - } - - #[test] - fn test_extract_declared_module_nested() -> Result<()> { - let db = &mut RootDatabase::builder() - .with_plugin_suite( - PluginSuite::default() - .add_plugin::() - .to_owned(), - ) - .build()?; - - let crate_id = db.intern_crate(CrateLongId::Real("test".into())); - let root = Directory::Real("src".into()); - db.set_crate_config(crate_id, Some(CrateConfiguration::default_for_root(root))); - set_file_content( - db, - "src/lib.cairo", - "use test::submod::subsubmod::foo;\n \ - mod submod {mod subsubmod;}\n", - ); - set_file_content(db, "src/submod/subsubmod.cairo", "fn foo{}"); - let path: PathBuf = "src/lib.cairo".into(); - let module_id = db.file_modules(FileId::new(db, path.clone())).unwrap()[0]; - let file_id = db.intern_file(FileLongId::OnDisk(path.clone())); - let file_data = FileData { - id: file_id, - name: file_id.file_name(db), - path, - index: 0, - }; - let imports = extract_file_imports(db, module_id, &file_data)?; - assert_import_properties!( - imports[0], - "subsubmod", - "test::submod::subsubmod", - CairoImportType::Module - ); - - assert_import_properties!( - imports[1], - "foo", - "test::submod::subsubmod::foo", - CairoImportType::Other - ); - - Ok(()) - } - - #[test] - fn test_extract_import_struct() -> Result<()> { - let (db, module_id, file_data, _) = setup_default_environment( - "test::submod::subsubmod::MyStruct", - "struct MyStruct{}", - CairoImportType::Other, - )?; - - let import = extract_file_imports(&db, module_id, &file_data)?[0].clone(); - assert_import_properties!( - import, - "MyStruct", - "test::submod::subsubmod::MyStruct", - CairoImportType::Other - ); - - Ok(()) - } - - #[test] - fn test_extract_import_trait() -> Result<()> { - let (db, module_id, file_data, _) = setup_default_environment( - "test::submod::subsubmod::MyTrait", - "trait MyTrait{}", - CairoImportType::Other, - )?; - - let import = extract_file_imports(&db, module_id, &file_data)?[0].clone(); - assert_import_properties!( - import, - "MyTrait", - "test::submod::subsubmod::MyTrait", - CairoImportType::Other - ); - - Ok(()) - } - - #[test] - fn test_extract_import_constant() -> Result<()> { - let (db, module_id, file_data, _) = setup_default_environment( - "test::submod::subsubmod::MY_CONST", - "const MY_CONST = 10;", - CairoImportType::Other, - )?; - - let import = extract_file_imports(&db, module_id, &file_data)?[0].clone(); - assert_import_properties!( - import, - "MY_CONST", - "test::submod::subsubmod::MY_CONST", - CairoImportType::Other - ); - Ok(()) - } - - #[test] - fn test_extract_import_generic() -> Result<()> { - let (db, module_id, file_data, _) = setup_default_environment( - "test::submod::subsubmod::foo_generic", - "fn foo_generic(value:T){}", - CairoImportType::Other, - )?; - - let import = extract_file_imports(&db, module_id, &file_data)?[0].clone(); - assert_import_properties!( - import, - "foo_generic", - "test::submod::subsubmod::foo_generic", - CairoImportType::Other - ); - Ok(()) - } - //TODO add more tests for the rest of import types - - #[test] - fn test_extract_crate_modules() { - let db = &mut RootDatabase::builder() - .with_plugin_suite( - PluginSuite::default() - .add_plugin::() - .to_owned(), - ) - .build() - .unwrap(); - - let crate_id = setup_test_files_with_imports( - db, - TestImport { - path: ModulePath::new("test::submod::subsubmod::foo"), - implementation: "fn foo(){}".to_owned(), - }, - ); - let actual_modules = collect_crate_module_files(db, crate_id).unwrap(); - - // Only resolves modules that are files. Modules inside of files are not extracted, but their imports are - // added to the file imports. - let expected_modules = vec![ - CairoModule { - dir: PathBuf::from("src"), - main_file: PathBuf::from("src/lib.cairo"), - path: ModulePath::new("test"), - filepath: PathBuf::from("src/lib.cairo"), - relative_filepath: PathBuf::from("src/lib.cairo"), - imports: HashSet::from([ - CairoImport { - name: "submod".to_owned(), - path: ModulePath::new("test::submod"), - resolved_path: ModulePath::new("test::submod"), - import_type: CairoImportType::Module, - }, - CairoImport { - name: "contract".to_owned(), - path: ModulePath::new("test::contract"), - resolved_path: ModulePath::new("test::contract"), - import_type: CairoImportType::Module, - }, - ]), - submodules: vec![], - }, - CairoModule { - dir: PathBuf::from("src/submod"), - main_file: PathBuf::from("src/lib.cairo"), - path: ModulePath::new("test::submod"), - filepath: PathBuf::from("src/submod.cairo"), - relative_filepath: PathBuf::from("src/lib.cairo"), - imports: HashSet::from([CairoImport { - name: "subsubmod".to_owned(), - path: ModulePath::new("test::submod::subsubmod"), - resolved_path: ModulePath::new("test::submod::subsubmod"), - import_type: CairoImportType::Module, - }]), - submodules: vec![], - }, - CairoModule { - dir: PathBuf::from("src/submod/subsubmod"), - main_file: PathBuf::from("src/lib.cairo"), - path: ModulePath::new("test::submod::subsubmod"), - filepath: PathBuf::from("src/submod/subsubmod.cairo"), - relative_filepath: PathBuf::from("src/lib.cairo"), - imports: Default::default(), - submodules: vec![], - }, - CairoModule { - dir: PathBuf::from("src/contract"), - main_file: PathBuf::from("src/lib.cairo"), - path: ModulePath::new("test::contract"), - filepath: PathBuf::from("src/contract.cairo"), - relative_filepath: PathBuf::from("src/lib.cairo"), - imports: HashSet::from([CairoImport { - name: "foo".to_owned(), - path: ModulePath::new("test::submod::subsubmod::foo"), - resolved_path: ModulePath::new("test::submod::subsubmod::foo"), - import_type: CairoImportType::Other, - }]), - submodules: vec![], - }, - ]; - - assert_eq!( - expected_modules.len(), - actual_modules.len(), - "Expected {} CairoModules but got {}", - expected_modules.len(), - actual_modules.len() - ); - - for (expected, actual) in expected_modules.iter().zip(actual_modules.iter()) { - assert_eq!(expected.dir, actual.dir); - assert_eq!(expected.main_file, actual.main_file); - assert_eq!(expected.path, actual.path); - assert_eq!(expected.filepath, actual.filepath); - assert_eq!(expected.imports, actual.imports); - } - } - - #[test] - fn test_get_module_file() { - let db = &mut RootDatabase::builder() - .with_plugin_suite( - PluginSuite::default() - .add_plugin::() - .to_owned(), - ) - .build() - .unwrap(); - - let crate_id = setup_test_files_with_imports( - db, - TestImport { - path: ModulePath::new("test::submod::subsubmod::foo"), - implementation: "fn foo(){}".to_owned(), - }, - ); - let crate_modules = db.crate_modules(crate_id); - let module_id = crate_modules[1]; - let file_data = get_module_file(db, module_id).unwrap(); - assert_eq!(file_data.name, "submod.cairo"); - assert_eq!(file_data.index, 0); - assert_eq!(file_data.path.to_str().unwrap(), "src/submod.cairo"); - } - - #[test] - fn test_module_submodules_should_extract_single_level_submodules() { - let db = &mut RootDatabase::builder() - .with_plugin_suite( - PluginSuite::default() - .add_plugin::() - .to_owned(), - ) - .build() - .unwrap(); - - let crate_id = setup_test_files_with_imports( - db, - TestImport { - path: ModulePath::new("test::submod::subsubmod::inlinemod::foo"), - implementation: " - mod inlinemod { - fn foo(){} - } - " - .to_owned(), - }, - ); - let crate_modules = db.crate_modules(crate_id); - // The second modules found will be the subsubmod.cairo file. - let module_id = crate_modules[2]; - let file_data = get_module_file(db, module_id).unwrap(); - - let submodules = capture_modules_submodules(db, file_data.id, module_id).unwrap(); - assert_eq!(submodules.len(), 1); - assert_eq!( - submodules[0], - CairoSubmodules { - name: "inlinemod".to_string(), - path: ModulePath::new("test::submod::subsubmod::inlinemod"), - parent_path: ModulePath::new("test::submod::subsubmod") - } - ) - } - - #[test] - fn test_module_submodules_should_extract_multi_level_submodules() { - let db = &mut RootDatabase::builder() - .with_plugin_suite( - PluginSuite::default() - .add_plugin::() - .to_owned(), - ) - .build() - .unwrap(); - - let crate_id = setup_test_files_with_imports( - db, - TestImport { - path: ModulePath::new("test::submod::subsubmod::inlinemod::inline2mod::foo"), - implementation: " - mod inlinemod { - mod inline2mod { - fn foo(){} - } - mod inline3mod { - fn bar(){} - } - } - " - .to_owned(), - }, - ); - let crate_modules = db.crate_modules(crate_id); - // The second modules found will be the subsubmod.cairo file. - let module_id = crate_modules[2]; - let file_data = get_module_file(db, module_id).unwrap(); - - let submodules = capture_modules_submodules(db, file_data.id, module_id).unwrap(); - assert_eq!(submodules.len(), 3); - assert_eq!( - submodules[1], - CairoSubmodules { - name: "inline2mod".to_string(), - path: ModulePath::new("test::submod::subsubmod::inlinemod::inline2mod"), - parent_path: ModulePath::new("test::submod::subsubmod::inlinemod") - } - ); - assert_eq!( - submodules[2], - CairoSubmodules { - name: "inline3mod".to_string(), - path: ModulePath::new("test::submod::subsubmod::inlinemod::inline3mod"), - parent_path: ModulePath::new("test::submod::subsubmod::inlinemod") - } - ); - } -} diff --git a/crates/voyager-resolver-cairo/src/compiler/scarb_utils.rs b/crates/voyager-resolver-cairo/src/compiler/scarb_utils.rs deleted file mode 100644 index 66aba97..0000000 --- a/crates/voyager-resolver-cairo/src/compiler/scarb_utils.rs +++ /dev/null @@ -1,367 +0,0 @@ -use anyhow::{anyhow, ensure, Context, Result}; -use itertools::Itertools; -use scarb::flock::Filesystem; -use scarb_metadata::Metadata; -use serde::Deserialize; -use std::collections::HashSet; -use std::fs::{self, File}; -use std::io::Write; -use std::path::{Path, PathBuf}; -use std::str::FromStr; -use toml_edit::{Document, Formatted, InlineTable, Item, Table, Value}; - -use cairo_lang_filesystem::db::FilesGroupEx; -use cairo_lang_filesystem::ids::{CrateLongId, Directory}; -use cairo_lang_semantic::db::SemanticGroup; -use scarb::core::Package; - -use crate::model::CairoModule; - -#[derive(Debug, Deserialize)] -struct ScarbTomlRawPackageData { - name: String, - license_file: Option, - readme: Option, -} - -#[derive(Debug, Deserialize)] -struct ScarbTomlRawData { - package: ScarbTomlRawPackageData, -} - -#[derive(Debug)] -pub struct AdditionalScarbManifestMetadata { - pub name: String, - pub license_file: String, - pub readme: String, -} - -// Get the MetadataManifest from the Scarb.toml -// TODO: replace this with the scarb-metadata as an alternative. -pub fn read_additional_scarb_manifest_metadata( - scarb_toml_content: &str, -) -> Result { - let scarb_metadata = toml::from_str::(scarb_toml_content)?; - - let scarb_metadata_package_name = scarb_metadata.package.name; - let scarb_metadata_package_license_file = - scarb_metadata.package.license_file.unwrap_or("".into()); - let scarb_metadata_package_readme = scarb_metadata.package.readme.unwrap_or("".into()); - - Ok(AdditionalScarbManifestMetadata { - name: scarb_metadata_package_name, - license_file: scarb_metadata_package_license_file, - readme: scarb_metadata_package_readme, - }) -} - -/// Reads Scarb project metadata from manifest file. -pub fn read_scarb_metadata(manifest_path: &PathBuf) -> anyhow::Result { - scarb_metadata::MetadataCommand::new() - .manifest_path(manifest_path) - .inherit_stderr() - .exec() - .map_err(Into::into) -} - -/// Extract non-local external packages, which comes from a source that is not -/// - local -/// - a std library -/// The extract list should only contain dependencies coming from -/// - package registry -/// - github registry -pub fn get_external_nonlocal_packages(metadata: Metadata) -> Vec { - let mut package_set: HashSet = HashSet::new(); - - for p in metadata.packages.iter() { - if p.source.repr != "std" - && !p.source.repr.starts_with("path") - && p.source.repr != "registry+https://there-is-no-default-registry-yet.com/" - { - package_set.insert(p.name.clone()); - } - for dep in p.dependencies.clone() { - if dep.source.repr != "std" - && !dep.source.repr.starts_with("path") - && dep.source.repr != "registry+https://there-is-no-default-registry-yet.com/" - { - package_set.insert(dep.name.clone()); - } - } - } - - package_set.iter().map(|p| p.to_owned()).collect_vec() -} - -/// Updates the crate roots in the compiler database using the metadata from a Scarb compilation. -/// The crate roots are set to the source roots of each compilation unit in the metadata. -/// The function does not return a value, but modifies the semantic group object referenced by `db`. -/// # Arguments -/// -/// * `db` - A mutable reference to a `SemanticGroup` trait object. -/// * `scarb_metadata` - A `scarb_metadata::Metadata` struct containing metadata from a Scarb project. -pub fn update_crate_roots_from_metadata( - db: &mut dyn SemanticGroup, - scarb_metadata: scarb_metadata::Metadata, -) { - for unit in scarb_metadata.compilation_units { - // Filter out test crates since these causes error when attempting - // to load the configurations below from the db. - // TODO: Investigate inherent reason why test crates causes this issue. - if unit.target.kind.eq("test") { - continue; - } - for component in unit.components { - let root = component.source_root(); - - if root.exists() { - let crate_id = db.intern_crate(CrateLongId::Real(component.name.as_str().into())); - let mut crate_config = db - .crate_config(crate_id) - .expect("Failed to get crate root directory") - .clone(); - crate_config.root = Directory::Real(root.into()); - db.set_crate_config(crate_id, Some(crate_config)); - }; - } - } -} - -/// Extracted from Scarb's crate. -pub fn get_table_mut<'a>(doc: &'a mut Document, path: &[&str]) -> Result<&'a mut Item> { - return visit(doc.as_item_mut(), path); - - fn visit<'a>(item: &'a mut Item, path: &[&str]) -> Result<&'a mut Item> { - if let Some(segment) = path.first() { - let item = item[segment].or_insert({ - let mut table = Table::new(); - table.set_implicit(true); - Item::Table(table) - }); - - ensure!( - item.is_table_like(), - "the table `{segment}` could not be found." - ); - visit(item, &path[1..]) - } else { - assert!(item.is_table_like()); - Ok(item) - } - } -} - -/// Generates an updated Scarb.toml files for all the packages in the given Scarb metadata. -/// To resolve dependencies to local paths. -/// -/// # Arguments -/// -/// * `scarb_metadata` - A `scarb_metadata::Metadata` object containing information about Scarb packages. -/// * `target_dir` - A `Filesystem` object representing the target directory where updated Scarb.toml files will be generated. -/// * `required_modules` - A `Vec` of `CairoModule` objects representing the modules required by the compiler. -/// -/// # Errors -/// -/// This function returns an error if: -/// -/// * The `target_dir` is not valid. -/// * Generating an updated Scarb.toml file fails. -pub fn generate_scarb_updated_files( - scarb_metadata: scarb_metadata::Metadata, - target_dir: &Filesystem, - required_modules: Vec<&CairoModule>, - external_packages: Vec, -) -> Result<()> { - let mut metadata = scarb_metadata.clone(); - let required_packages = required_modules - .iter() - .map(|m| m.path.get_crate()) - .collect::>(); - - // Delete all unused packages from metadata - // This include "core", "starknet" and scarb's "test_plugin" - // and any other external dependencies not used in target contracts - metadata - .packages - .retain(|package| required_packages.contains(&package.name)); - - for package in metadata.packages.clone() { - let manifest_path = package.manifest_path; - let target_path = target_dir.path_existent()?.join(package.name); - generate_updated_scarb_toml( - manifest_path.clone().into_std_path_buf(), - target_path.as_std_path(), - &required_packages, - &external_packages, - )?; - } - - Ok(()) -} - -/** - * Generates a new Scarb.toml manifest file that points to local dependencies. - * - * # Arguments - * - * * `manifest_path` - A `PathBuf` of the Scarb.toml file to be updated. - * * `target_path` - A `Path` to the target directory for the updated Scarb.toml file. - * * `required_packages` - A `Vec` of `String`s representing the names of the packages required by the compiler. - * - * # Errors - * - * This function will return an error if any of the following conditions are met: - * - * * The specified manifest_path does not exist. - * * The specified manifest_path cannot be read. - * * The specified manifest_path is not a valid TOML document. - * * The specified target_path cannot be created. - * * The updated Scarb.toml file cannot be written to the specified target_path. - */ -pub fn generate_updated_scarb_toml( - manifest_path: PathBuf, - target_path: &Path, - required_packages: &[String], - external_packages: &[String], -) -> Result<()> { - let manifest_path = fs::canonicalize(manifest_path)?; - let original_raw_manifest = fs::read_to_string(&manifest_path)?; - - let mut doc = Document::from_str(&original_raw_manifest).with_context(|| { - format!( - "failed to read manifest at `{}`", - manifest_path.to_string_lossy() - ) - })?; - - let tab = get_table_mut(&mut doc, &["dependencies"])?; - - let binding = tab.clone(); - let table_keys = binding - .as_table_like() - .unwrap() - .get_values() - .iter() - .map(|(k, _)| k[0].get()) - .collect::>(); - - table_keys.iter().for_each(|k| { - // starknet package dependency is builtin within the compiler - if *k == "starknet" { - return; - } - - // Ignore any external packages and keep as it is. - if external_packages.contains(&k.to_string()) { - return; - } - - // remove unused dependencies - if !required_packages.contains(&k.to_string()) && *k != "starknet" { - tab.as_table_like_mut().unwrap().remove(k); - return; - } - - let mut new_table = InlineTable::new(); - new_table.insert("path", Value::String(Formatted::new(format!("../{}", k)))); - tab.as_table_like_mut() - .unwrap() - .insert(k, Item::Value(Value::InlineTable(new_table))); - }); - - let new_raw_manifest = doc.to_string(); - - let new_manifest_path = target_path.join("Scarb.toml"); - // Create the parent directories for the destination file if they don't exist - if let Some(parent) = new_manifest_path.parent() { - fs::create_dir_all(parent)?; - } - fs::write(new_manifest_path, new_raw_manifest.as_bytes())?; - - Ok(()) -} - -/// This function retrieves the relative path of the contracts that need to be verified from a -/// package's tool metadata. -/// -/// # Arguments -/// -/// * `package` - A reference to the package from which to retrieve the contracts to verify. -/// -/// # Returns -/// -/// * A `Result` containing a `Vec` of `String`s representing the contracts relative path to verify if successful. -/// -/// # Errors -/// -/// The function returns an error if: -/// -/// * The tool metadata for "voyager" cannot be fetched from the package. -/// * The tool metadata is not a table. -/// -pub fn get_contracts_to_verify(package: &Package) -> Result> { - let verify_metadata = package - .fetch_tool_metadata("voyager") - .with_context(|| "manifest has no [tool.voyager] section which is required")?; - let table_values = verify_metadata - .as_table() - .ok_or_else(|| anyhow!("verify metadata is not a table"))? - .values() - .map(|v| PathBuf::from(v.get("path").unwrap().as_str().unwrap())) - .collect::>(); - - Ok(table_values) -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn should_correctly_extract_the_scarb_toml_metadata() { - let scarb_toml_content = r#" - [package] - name = "test_data" - version = "0.1.0" - license_file = "LICENSE" - readme = "README.md" - "#; - - let data = read_additional_scarb_manifest_metadata(scarb_toml_content).unwrap(); - - assert_eq!(data.name, "test_data"); - assert_eq!(data.license_file, "LICENSE"); - assert_eq!(data.readme, "README.md"); - } - - #[test] - fn should_correctly_extract_empty_scarb_toml_metadata() { - let scarb_toml_content = r#" - [package] - name = "test_data_2" - version = "0.1.0" - "#; - - let data = read_additional_scarb_manifest_metadata(scarb_toml_content).unwrap(); - - assert_eq!(data.name, "test_data_2"); - assert_eq!(data.license_file, ""); - assert_eq!(data.readme, ""); - } - - #[test] - fn should_correctly_extract_existing_scarb_toml_metadata() { - let scarb_toml_content = r#" - [package] - name = "test_data_2" - version = "0.1.0" - readme = "README.md" - "#; - - let data = read_additional_scarb_manifest_metadata(scarb_toml_content).unwrap(); - - assert_eq!(data.name, "test_data_2"); - assert_eq!(data.license_file, ""); - assert_eq!(data.readme, "README.md"); - } -} diff --git a/crates/voyager-resolver-cairo/src/dyn_compiler.rs b/crates/voyager-resolver-cairo/src/dyn_compiler.rs deleted file mode 100644 index c856b59..0000000 --- a/crates/voyager-resolver-cairo/src/dyn_compiler.rs +++ /dev/null @@ -1,88 +0,0 @@ -use std::env; - -use anyhow::Result; -use camino::Utf8PathBuf; -use dyn_compiler::dyn_compiler::{DynamicCompiler, SupportedCairoVersions, SupportedScarbVersions}; -use itertools::Itertools; -use scarb::{ - compiler::CompilerRepository, - core::{Config, TargetKind}, - ops, -}; - -use crate::{ - compiler::{scarb_utils::get_contracts_to_verify, VoyagerGenerator}, - utils::run_starknet_compile, -}; - -pub struct VoyagerGeneratorWrapper; - -impl DynamicCompiler for VoyagerGeneratorWrapper { - fn get_supported_scarb_versions(&self) -> Vec { - vec![SupportedScarbVersions::V2_8_4] - } - fn get_supported_cairo_versions(&self) -> Vec { - vec![SupportedCairoVersions::V2_8_4] - } - - fn get_contracts_to_verify_path(&self, project_path: &Utf8PathBuf) -> Result> { - let manifest_path = project_path.join("Scarb.toml"); - - let mut compilers = CompilerRepository::empty(); - compilers.add(Box::new(VoyagerGenerator)).unwrap(); - - let config = Config::builder(manifest_path) - // .ui_verbosity(Verbosity::Verbose) - .log_filter_directive(env::var_os("SCARB_LOG")) - .compilers(compilers) - .build() - .unwrap(); - - let ws = ops::read_workspace(config.manifest_path(), &config).unwrap_or_else(|err| { - eprintln!("Error: {}", err); - std::process::exit(1); - }); - let package = ws.current_package().unwrap(); - let contracts_path = get_contracts_to_verify(package)?; - - Ok(contracts_path - .iter() - .map(|p| Utf8PathBuf::from_path_buf(p.to_path_buf()).unwrap()) - .collect_vec()) - } - - fn compile_project(&self, project_path: &Utf8PathBuf) -> Result<()> { - let manifest_path = project_path.join("Scarb.toml"); - - let mut compilers = CompilerRepository::empty(); - compilers.add(Box::new(VoyagerGenerator)).unwrap(); - - let config = Config::builder(manifest_path) - .ui_verbosity(scarb_ui::Verbosity::Verbose) - .log_filter_directive(env::var_os("SCARB_LOG")) - .compilers(compilers) - .build() - .unwrap(); - - let ws = ops::read_workspace(config.manifest_path(), &config).unwrap(); - let package_ids = ws.members().map(|p| p.id).collect(); - let compile_opts = ops::CompileOpts { - include_target_kinds: vec![TargetKind::STARKNET_CONTRACT], - exclude_target_kinds: Vec::new(), - include_target_names: Vec::new(), - features: ops::FeaturesOpts { - features: ops::FeaturesSelector::AllFeatures, - no_default_features: true, - }, - }; - - ops::compile(package_ids, compile_opts, &ws) - } - - fn compile_file(&self, file_path: &Utf8PathBuf) -> Result<()> { - //TODO detect_corelib will try to use the local corelib. - // Once Cairo is released, it will probably be able to use - // the corelib from the release. - run_starknet_compile(file_path.as_str()) - } -} diff --git a/crates/voyager-resolver-cairo/src/graph/mod.rs b/crates/voyager-resolver-cairo/src/graph/mod.rs deleted file mode 100644 index 6a495a6..0000000 --- a/crates/voyager-resolver-cairo/src/graph/mod.rs +++ /dev/null @@ -1,192 +0,0 @@ -use crate::model::{CairoModule, ModulePath}; - -use anyhow::Context; -use anyhow::Result; -use petgraph::dot::{Config, Dot}; -use petgraph::graph::NodeIndex; -use petgraph::Graph; -use std::collections::{HashMap, VecDeque}; -use std::fmt; -use std::fmt::Display; - -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub struct EdgeWeight(()); - -impl Display for EdgeWeight { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "") - } -} - -/// Creates a directed graph of module dependencies from a list of Cairo modules. -/// For each module in the input list, a node is added to the graph with the module's path as the node label. -/// Edges are then added between nodes based on the imports of each module. -/// An edge is added from the source module to the target module if the target module is imported by the source module. -/// # Arguments -/// -/// * `modules` - A vector of references to CairoModule structs representing the modules to create a graph of. -/// -/// # Returns -/// -/// A directed graph of module dependencies represented by a `Graph` struct. -pub fn create_graph(modules: &Vec) -> Graph { - let mut graph = Graph::::new(); - - // Create nodes for each file - let mut file_nodes: HashMap = HashMap::new(); - for module in modules { - let module_path = module.path.clone(); - let node = graph.add_node(module_path.clone()); - file_nodes.insert(module_path, node); - } - - // Add edges based on the imports - for module in modules { - let module_path = module.path.clone(); - // Get the imports of each file module (inline modules not included) - // and attempt to resolve them with the modules we have. - for import in module.imports.iter() { - let import_path = import.get_import_module(); - - for target_module in modules.iter() { - // When attempting to add by comparing the modules by path works for most cases - // it does not work when we have imports of nested modules. - if target_module.is_module_path_resolved(import_path.clone()) { - if let (Some(&src), Some(&dst)) = ( - file_nodes.get(&module_path.clone()), - file_nodes.get(&target_module.path), - ) { - graph.add_edge(src, dst, EdgeWeight(())); - } - break; - } - } - } - } - - graph -} - -pub fn _display_graphviz(graph: &Graph) { - println!("{:#?}", Dot::with_config(&graph, &[Config::EdgeNoLabel])); -} - -/// Extracts the source and destination nodes from each edge in a directed graph, -/// and returns a vector of unique node labels representing the required files for compilation. -/// The function takes a reference to a `Graph` struct representing the directed graph of module dependencies. -/// The function returns a vector of unique `String` node labels representing the required files for compilation. The node labels are sorted and deduplicated. -/// # Arguments -/// -/// * `graph` - A reference to a `Graph` struct representing the directed graph of module dependencies. -/// -/// # Returns -/// -/// A vector of unique `String` node labels representing the required files for compilation. -#[allow(dead_code)] -pub fn get_required_project_modules( - graph: &Graph, -) -> Result> { - let mut required_files: Vec = Vec::new(); - - for edge in graph.edge_indices() { - let (src, dst) = graph - .edge_endpoints(edge) - .with_context(|| format!("Couldn't get edge endpoints {}", edge.index()))?; - required_files.push(graph[src].clone()); - required_files.push(graph[dst].clone()); - } - - required_files.sort(); - required_files.dedup(); - Ok(required_files) -} - -/// This function retrieves the required dependency modules paths for a set of CairoModules -/// from a dependency graph. -/// The object returned also contains the path to the contract modules themselves. -/// -/// # Arguments -/// -/// * `graph` - A reference to the dependency graph from which to retrieve the required modules. -/// * `contracts_modules` - A `Vec` of `&CairoModule` references representing the modules containing the contracts. -/// -/// # Returns -/// -/// * A `Vec` of `String`s representing the required modules if successful. -/// -pub fn get_required_module_for_contracts( - graph: &Graph, - contracts_modules: &Vec<&CairoModule>, -) -> Result> { - let mut required_modules: Vec = Vec::new(); - let mut queue: VecDeque = VecDeque::new(); - - for contract_module in contracts_modules { - let module_path = contract_module.path.clone(); - required_modules.push(module_path.clone()); - // Find the node for the contract module - let contract_node = graph - .node_indices() - .find(|&index| graph[index] == module_path) - .with_context(|| format!("Couldn't find corresponding module for {module_path}"))?; - - for neighbor in graph.neighbors(contract_node) { - queue.push_back(neighbor); - } - } - - // Traverse the graph in a BFS order, adding each node to the required modules list - while let Some(node) = queue.pop_front() { - let node_name = &graph[node]; - - // Skip nodes that are already in the required modules list - if required_modules.contains(node_name) { - continue; - } - - // Add the node to the required modules list and push its neighbors to the queue - required_modules.push(node_name.clone()); - for neighbor in graph.neighbors(node) { - queue.push_back(neighbor); - } - } - - required_modules.sort(); - Ok(required_modules) -} - -#[cfg(test)] -mod tests { - use crate::graph::{create_graph, get_required_project_modules, EdgeWeight}; - use crate::model::ModulePath; - use crate::utils::test_utils::setup_simple_modules; - - #[test] - fn test_create_graph() { - let modules = setup_simple_modules(); - let graph = create_graph(&modules); - let _required_modules = get_required_project_modules(&graph).unwrap(); - assert_eq!(graph.node_count(), 4); - assert_eq!(graph.edge_count(), 1); - - let node_indices = graph.node_indices().collect::>(); - assert_eq!( - graph.edge_weight( - graph - .find_edge(node_indices[3], node_indices[2]) - .unwrap_or_else(|| panic!("Couldn't find edge")) - ), - Some(&EdgeWeight(())) - ); - } - - #[test] - fn test_list_edges_and_required_files() { - let modules = setup_simple_modules(); - let graph = create_graph(&modules); - let required_modules = get_required_project_modules(&graph).unwrap(); - assert_eq!(required_modules.len(), 2); - assert!(required_modules.contains(&ModulePath::new("test::contract"))); - assert!(required_modules.contains(&ModulePath::new("test::submod::subsubmod"))); - } -} diff --git a/crates/voyager-resolver-cairo/src/lib.rs b/crates/voyager-resolver-cairo/src/lib.rs deleted file mode 100644 index 7f33954..0000000 --- a/crates/voyager-resolver-cairo/src/lib.rs +++ /dev/null @@ -1,5 +0,0 @@ -pub mod compiler; -pub mod dyn_compiler; -mod graph; -mod model; -pub mod utils; diff --git a/crates/voyager-resolver-cairo/src/model/mod.rs b/crates/voyager-resolver-cairo/src/model/mod.rs deleted file mode 100644 index 098b7c6..0000000 --- a/crates/voyager-resolver-cairo/src/model/mod.rs +++ /dev/null @@ -1,169 +0,0 @@ -use anyhow::{Context, Result}; -use cairo_lang_filesystem::ids::Directory; -use std::collections::HashSet; -use std::fmt::{Debug, Display}; -use std::path::PathBuf; - -#[derive(Clone, PartialEq, Eq, Hash, Ord, PartialOrd)] -pub struct ModulePath(pub(crate) String); - -impl ModulePath { - pub fn new(path: T) -> Self - where - T: ToString, - { - ModulePath(path.to_string()) - } - - pub fn get_path(&self) -> &String { - &self.0 - } - - pub fn get_parent_path(&self) -> ModulePath { - let path = self.0.clone(); - let mut parent_path = path.split("::").collect::>(); - parent_path.pop(); - let res = parent_path.join("::"); - ModulePath(res) - } - - pub fn get_crate(&self) -> String { - let path = self.0.clone(); - let crate_name = path.split("::").collect::>()[0]; - crate_name.to_string() - } - - pub fn get_modules(&self) -> Vec<&str> { - self.0.split("::").collect::>() - } -} - -impl Display for ModulePath { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self.0) - } -} - -impl Debug for ModulePath { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self.0) - } -} - -#[derive(Debug, Clone)] -pub struct CairoCrate { - pub root_dir: Directory, - pub main_file: PathBuf, - pub modules: Vec, -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct CairoModule { - pub dir: PathBuf, - pub main_file: PathBuf, - pub path: ModulePath, - pub filepath: PathBuf, - pub relative_filepath: PathBuf, - pub submodules: Vec, - pub imports: HashSet, -} - -impl Display for CairoModule { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "CairoModule {{ path: {:?} }}", self.path,) - } -} - -impl CairoModule { - pub(crate) fn get_root_dir(&self) -> Result { - let module_root = self.main_file.clone(); - Ok(module_root - .parent() - .with_context(|| format!("Failed to get parent of {:?}", module_root))? - .parent() - .with_context(|| format!("Failed to get grandparent of {:?}", module_root))? - .to_path_buf()) - } - - /// Attempt to check if a ModulePath given will resolve into a CairoModule or - /// a CairoSubmodule. - pub fn is_module_path_resolved(&self, mod_path: ModulePath) -> bool { - if mod_path == self.path { - return true; - } - if self.submodules.iter().any(|submod| submod.path == mod_path) { - return true; - } - false - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct CairoSubmodules { - pub name: String, - pub parent_path: ModulePath, - pub path: ModulePath, -} - -#[derive(Debug, Clone, Hash, PartialEq, Eq)] -pub struct CairoImport { - pub name: String, - pub path: ModulePath, - pub resolved_path: ModulePath, - pub import_type: CairoImportType, -} - -impl CairoImport { - pub fn get_import_module(&self) -> ModulePath { - match self.import_type { - CairoImportType::Module => ModulePath::new(self.resolved_path.clone()), - CairoImportType::Other => self.resolved_path.get_parent_path(), - } - } - - pub fn is_remapped(&self) -> bool { - self.path != ModulePath::new(self.resolved_path.clone()) - } - pub fn is_super_import(&self) -> bool { - self.path.0.starts_with("super") - } - - pub fn resolved_parent_module(&self) -> ModulePath { - self.resolved_path.get_parent_path() - } - - pub fn unresolved_parent_module(&self) -> ModulePath { - self.path.get_parent_path() - } -} - -#[derive(Debug, Clone, Hash, PartialEq, Eq)] -pub enum CairoImportType { - Module, - Other, -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct CairoAttachmentModule { - pub path: ModulePath, - pub children: HashSet, - pub imports: HashSet, -} - -impl CairoAttachmentModule { - pub fn new(path: ModulePath) -> Self { - CairoAttachmentModule { - path, - children: HashSet::new(), - imports: HashSet::new(), - } - } - - pub fn add_child(&mut self, child: ModulePath) { - self.children.insert(child); - } - - pub fn add_import(&mut self, import: ModulePath) { - self.imports.insert(import); - } -} diff --git a/crates/voyager-resolver-cairo/src/utils/mod.rs b/crates/voyager-resolver-cairo/src/utils/mod.rs deleted file mode 100644 index 6557b4b..0000000 --- a/crates/voyager-resolver-cairo/src/utils/mod.rs +++ /dev/null @@ -1,281 +0,0 @@ -use anyhow::Result; - -use crate::compiler::scarb_utils::read_additional_scarb_manifest_metadata; -use crate::model::{CairoAttachmentModule, CairoImport, CairoModule, ModulePath}; - -use scarb::core::Workspace; -use scarb::flock::Filesystem; -use std::collections::HashMap; - -use std::fs; -use std::fs::{copy, File}; -use std::io::{BufWriter, Write}; -use std::ops::Add; -use std::path::Path; -use std::process::Command; - -#[cfg(any(feature = "testing", test))] -pub mod test_utils; - -/// Finds the modules of the crate that attach other modules to the module tree. -/// # Arguments -/// -/// * `required_modules` - A `Vec` of `String`s containing the paths of the required modules for the project. -/// # Returns -/// -/// A `HashMap` where the keys are the parent modules and the values are `HashSet`s containing the names of the child modules. -/// -/// # Example -/// Let `test::submod::contract` be a required module for our compilation. -/// This function will return a HashMap with entries `test -> [submod], submod -> [contract]` -pub fn generate_attachment_module_data( - required_modules: &Vec, - remapped_imports: Vec, -) -> HashMap { - let mut declaration_modules: HashMap = HashMap::new(); - - for required_module in required_modules { - let required_parts: Vec<&str> = required_module.get_modules(); - let mut parent_module = String::new(); - - for i in 0..required_parts.len() - 1 { - if i > 0 { - parent_module.push_str("::"); - } - parent_module.push_str(required_parts[i]); - let parent_module = ModulePath::new(parent_module.clone()); - - declaration_modules - .entry(parent_module.clone()) - .or_insert(CairoAttachmentModule::new(parent_module.clone())) - .add_child(ModulePath::new(required_parts[i + 1].to_string())); - } - } - - remapped_imports.iter().for_each(|i| { - let parent_module = i.unresolved_parent_module(); - declaration_modules - .entry(parent_module.clone()) - .or_insert(CairoAttachmentModule::new(parent_module)) - .add_import(i.resolved_path.clone()); - }); - - declaration_modules -} - -pub fn get_import_remaps(modules_to_verify: Vec<&CairoModule>) -> Vec { - let all_imports = modules_to_verify - .iter() - .map(|m| m.imports.clone()) - .collect::>(); - let imports_path_not_matching_resolved_path = all_imports - .iter() - .flat_map(|i| i.iter()) - .filter(|i| i.is_remapped()) - .cloned() - .collect::>(); - imports_path_not_matching_resolved_path -} - -/// Generate .cairo files for each attachment module in the `attachment_modules` HashMap, writing `mod` declaration statements -/// for each submodule of the parent. -/// -/// # Arguments -/// -/// * `declaration_modules` - A `HashMap>` containing the parent modules and the forward declarations of child modules. -/// * `target_dir` - The directory in which to generate the .cairo files. -pub fn create_attachment_files( - attachment_modules: &HashMap, - target_dir: &Filesystem, -) -> Result<()> { - for (parent_module, attachment_module) in attachment_modules { - let child_modules = &attachment_module.children; - let mut filename = String::new(); - let path_split = parent_module.0.split("::"); - let crate_name = parent_module.get_crate(); - let target_path = target_dir.path_existent()?; - let source_path = target_path.join(crate_name).join("src"); - filename = match path_split.clone().count() { - 1 => "lib.cairo".to_string(), - _ => { - for part in path_split { - filename = part.to_string().add(".cairo") - } - filename - } - }; - - let dest_path = Path::new(&source_path).join(filename); - // Create the parent directories for the destination file if they don't exist - if let Some(parent) = dest_path.parent() { - fs::create_dir_all(parent)?; - } - let file = File::create(dest_path)?; - let mut writer = BufWriter::new(file); - - for child_module in child_modules { - writeln!(writer, "mod {};", child_module)?; - } - - for import in &attachment_module.imports { - writeln!(writer, "use {};", import)?; - } - } - - Ok(()) -} - -/// Copies the required Cairo modules' files to the target directory. -/// -/// # Arguments -/// -/// * `required_modules` - A vector containing references to the CairoModule instances that need to be copied. -/// * `target_dir` - A reference to the target directory where the files should be copied. -/// * `ws` - A reference to the Workspace. -/// -/// # Errors -/// -/// Returns an error if the function encounters an error while copying files or creating directories. -/// TODO: add comprehensive test for this. -pub fn copy_required_files( - required_modules: &Vec<&CairoModule>, - target_dir: &Filesystem, - ws: &Workspace, -) -> Result<()> { - let root_path = ws.root(); - let mut root_parts = root_path.components().peekable(); - let target_path = target_dir.path_existent()?; - - // Skip the first component if it is the Windows or Unix root - if let Some(component) = root_parts.peek() { - if component.as_os_str().is_empty() { - root_parts.next(); - } - } - - // Copy each required module's .cairo file to the target directory - for module in required_modules { - let crate_name = module.path.get_crate(); - let filepath = Path::new(&module.filepath); - let mut filepath_parts = filepath.components().peekable(); - - // Skip the first component if it is the project root - if let Some(component) = filepath_parts.peek() { - if component.as_os_str() == root_path { - filepath_parts.next(); - } - } - - // Construct the destination path for the .cairo & readme & license file - let root_dir = module.get_root_dir()?; - let filepath_relative = filepath.strip_prefix(root_dir.clone())?; - let dest_path = Path::new(target_path) - .join(crate_name.clone()) - .join(filepath_relative); - - let manifest_path = root_dir.clone().join("Scarb.toml"); - let scarb_toml_content = fs::read_to_string(&manifest_path)?; - let additional_metadata = - read_additional_scarb_manifest_metadata(scarb_toml_content.as_str())?; - - // Create the parent directories for the destination file if they don't exist - if let Some(parent) = dest_path.parent() { - fs::create_dir_all(parent)?; - } - - // Copy the .cairo file to the destination path - let source_path = Path::new(&module.filepath); - copy(source_path, &dest_path)?; - - // Attempt to copy the readme and license files to the target directory - let root_dir_clone = root_dir.clone(); - let base_source_root_path = Path::new(&root_dir_clone); - let base_dest_root_path = Path::new(target_path).join(crate_name); - - let readme_source_path = base_source_root_path.join(&additional_metadata.readme); - let readme_dest_path = base_dest_root_path.join(&additional_metadata.readme); - let license_file_source_path = - base_source_root_path.join(&additional_metadata.license_file); - let license_file_dest_path = base_dest_root_path.join(&additional_metadata.license_file); - - // Only copy if there is a readme or license file - if !additional_metadata.readme.is_empty() && readme_source_path.exists() { - copy(readme_source_path, readme_dest_path)?; - } - - if !additional_metadata.license_file.is_empty() && license_file_source_path.exists() { - copy(license_file_source_path, license_file_dest_path)?; - } - } - - Ok(()) -} - -pub fn run_scarb_build(path: &str) -> Result<()> { - let output = Command::new("scarb") - .arg("build") - .current_dir(path) - .output()?; - - if output.status.success() { - Ok(()) - } else { - panic!("{}", String::from_utf8_lossy(&output.stdout)); - } -} - -pub fn run_starknet_compile(path: &str) -> Result<()> { - let output = Command::new("starknet-compile").arg(path).output()?; - - if output.status.success() { - Ok(()) - } else { - panic!("{}", String::from_utf8_lossy(&output.stderr)); - } -} - -#[cfg(test)] -mod tests { - use crate::model::ModulePath; - use crate::utils::generate_attachment_module_data; - - #[test] - fn test_find_attachment_modules() { - let required_modules = vec![ - ModulePath::new("test::module::child"), - ModulePath::new("test::module::child2"), - ModulePath::new("test::module2::child"), - ModulePath::new("test::module2::child2"), - ModulePath::new("test::module2::child3"), - ModulePath::new("test::module3"), - ]; - - let declaration_modules = generate_attachment_module_data(&required_modules, vec![]); - - assert_eq!(declaration_modules.len(), 3); - assert_eq!( - declaration_modules - .get(&ModulePath::new("test")) - .unwrap() - .children - .len(), - 3 - ); - assert_eq!( - declaration_modules - .get(&ModulePath::new("test::module")) - .unwrap() - .children - .len(), - 2 - ); - assert_eq!( - declaration_modules - .get(&ModulePath::new("test::module2")) - .unwrap() - .children - .len(), - 3 - ); - } -} diff --git a/crates/voyager-resolver-cairo/src/utils/test_utils.rs b/crates/voyager-resolver-cairo/src/utils/test_utils.rs deleted file mode 100644 index 8f3daf8..0000000 --- a/crates/voyager-resolver-cairo/src/utils/test_utils.rs +++ /dev/null @@ -1,116 +0,0 @@ -use cairo_lang_filesystem::ids::{CrateId, CrateLongId, Directory, FileLongId}; -use std::collections::HashSet; -use std::path::PathBuf; - -use cairo_lang_compiler::db::RootDatabase; -use cairo_lang_filesystem::db::{AsFilesGroupMut, FilesGroupEx}; -use cairo_lang_filesystem::db::{CrateConfiguration, FilesGroup}; -use std::sync::Arc; - -use crate::model::{CairoImport, CairoImportType, CairoModule, ModulePath}; - -/// Struct representing an import for tests - the path (module) of the item being imported and the implementation of the item. -pub struct TestImport { - pub path: ModulePath, - pub implementation: String, -} - -/// Sets up test files for the given database and import to test -/// Creates the `src/lib.cairo` file, the `src/contract.cairo` file -/// and the `src/submod.cairo` file. -/// The `src/contract.cairo` file imports the given `test_import` path. -/// The `src/submod.cairo` file defines the given `test_import` implementation. -pub fn setup_test_files_with_imports(db: &mut RootDatabase, test_import: TestImport) -> CrateId { - let crate_id = db.intern_crate(CrateLongId::Real("test".into())); - let root = Directory::Real("src".into()); - db.set_crate_config(crate_id, Some(CrateConfiguration::default_for_root(root))); - - // Main module file - set_file_content(db, "src/lib.cairo", "mod submod;\n mod contract;"); - - // Contract module file - set_file_content( - db, - "src/contract.cairo", - &format!( - " - #[contract] - mod ERC20 {{ - use {path}; - }} - ", - path = test_import.path - ), - ); - - // Submod and subsubmod module files - set_file_content(db, "src/submod.cairo", "mod subsubmod;"); - set_file_content( - db, - "src/submod/subsubmod.cairo", - &format!( - " - {implementation} - ", - implementation = &test_import.implementation - ), - ); - crate_id -} - -/// Sets the content of the file with the given path -pub fn set_file_content(db: &mut RootDatabase, path: &str, content: &str) { - let file_id = db.intern_file(FileLongId::OnDisk(path.into())); - db.as_files_group_mut() - .override_file_content(file_id, Some(Arc::from(content))); -} - -pub fn setup_simple_modules() -> Vec { - let module_0 = CairoModule { - dir: PathBuf::from("src"), - main_file: PathBuf::from("src/lib.cairo"), - path: ModulePath::new("test"), - filepath: PathBuf::from("src/lib.cairo"), - relative_filepath: PathBuf::from("lib.cairo"), - imports: Default::default(), - submodules: vec![], - }; - - let module_1 = CairoModule { - dir: PathBuf::from("src/submod"), - main_file: PathBuf::from("src/lib.cairo"), - path: ModulePath::new("test::submod"), - filepath: PathBuf::from("src/submod.cairo"), - relative_filepath: PathBuf::from("submod.cairo"), - imports: Default::default(), - submodules: vec![], - }; - - let module_2 = CairoModule { - dir: PathBuf::from("src/submod/subsubmod"), - main_file: PathBuf::from("src/lib.cairo"), - path: ModulePath::new("test::submod::subsubmod"), - filepath: PathBuf::from("src/submod/subsubmod.cairo"), - relative_filepath: PathBuf::from("subsubmod.cairo"), - imports: Default::default(), - submodules: vec![], - }; - - let module_3 = CairoModule { - dir: PathBuf::from("src/submod/subsubmod"), - main_file: PathBuf::from("src/lib.cairo"), - path: ModulePath::new("test::contract"), - filepath: PathBuf::from("src/contract.cairo"), - relative_filepath: PathBuf::from("contract.cairo"), - imports: HashSet::from([CairoImport { - name: "foo".to_owned(), - path: ModulePath::new("test::submod::subsubmod::foo"), - resolved_path: ModulePath::new("test::submod::subsubmod::foo"), - import_type: CairoImportType::Other, - }]), - submodules: vec![], - }; - - let modules = vec![module_0, module_1, module_2, module_3]; - modules -} diff --git a/crates/voyager-resolver-cairo/tests/integration_test.rs b/crates/voyager-resolver-cairo/tests/integration_test.rs deleted file mode 100644 index f9d9ede..0000000 --- a/crates/voyager-resolver-cairo/tests/integration_test.rs +++ /dev/null @@ -1,275 +0,0 @@ -use std::env; - -use anyhow::{anyhow, Result}; -use scarb::compiler::CompilerRepository; -use scarb::core::{Config, TargetKind}; -use scarb::ops; -use scarb_ui::Verbosity; -use std::path::PathBuf; - -use voyager_resolver_cairo::compiler::scarb_utils::get_contracts_to_verify; -use voyager_resolver_cairo::compiler::VoyagerGenerator; -use voyager_resolver_cairo::utils::run_scarb_build; - -#[test] -fn test_incorrect_contract_path_given() -> Result<()> { - let mut compilers = CompilerRepository::empty(); - compilers.add(Box::new(VoyagerGenerator)).unwrap(); - let source_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")) - .join("tests/test_data") - .join("project_w_incorrect_contract_path"); - let manifest_path = source_dir.join("Scarb.toml"); - - let config = Config::builder(manifest_path.to_str().unwrap()) - .ui_verbosity(Verbosity::Verbose) - .log_filter_directive(env::var_os("SCARB_LOG")) - .compilers(compilers) - .build() - .unwrap(); - - let ws = ops::read_workspace(config.manifest_path(), &config).unwrap_or_else(|err| { - eprintln!("Error: {}", err); - std::process::exit(1); - }); - let package_ids = ws.members().map(|p| p.id.clone()).collect(); - let compile_opts = ops::CompileOpts { - include_target_kinds: vec![TargetKind::STARKNET_CONTRACT], - exclude_target_kinds: Vec::new(), - include_target_names: Vec::new(), - features: ops::FeaturesOpts { - features: ops::FeaturesSelector::AllFeatures, - no_default_features: true, - }, - }; - - let result = ops::compile(package_ids, compile_opts, &ws); - assert!(result.is_err()); - - let reduced_project_path = source_dir.join("voyager-verify/project_w_incorrect_contract_path"); - let compile_result = run_scarb_build(reduced_project_path.to_str().unwrap()); - assert!(compile_result.is_err()); - Ok(()) -} - -#[test] -fn test_get_contracts_to_verify() { - let mut compilers = CompilerRepository::empty(); - compilers.add(Box::new(VoyagerGenerator)).unwrap(); - let source_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")) - .join("tests/test_data") - .join("simple_project"); - let manifest_path = source_dir.join("Scarb.toml"); - - let config = Config::builder(manifest_path.to_str().unwrap()) - .ui_verbosity(Verbosity::Verbose) - .log_filter_directive(env::var_os("SCARB_LOG")) - .compilers(compilers) - .build() - .unwrap(); - - let ws = ops::read_workspace(config.manifest_path(), &config).unwrap_or_else(|err| { - eprintln!("Error: {}", err); - std::process::exit(1); - }); - // - let package = ws.current_package().unwrap(); - let contracts = get_contracts_to_verify(package).unwrap(); - assert_eq!(contracts.len(), 1); - assert_eq!(contracts[0], PathBuf::from("contracts/ERC20.cairo")) -} - -#[test] -fn test_simple_project() -> Result<()> { - let source_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")) - .join("tests/test_data") - .join("simple_project"); - let mut compilers = CompilerRepository::empty(); - compilers.add(Box::new(VoyagerGenerator)).unwrap(); - - let manifest_path = source_dir.join("Scarb.toml"); - - let config = Config::builder(manifest_path.to_str().unwrap()) - .ui_verbosity(Verbosity::Verbose) - .log_filter_directive(env::var_os("SCARB_LOG")) - .compilers(compilers) - .build() - .unwrap(); - - let ws = ops::read_workspace(config.manifest_path(), &config).unwrap_or_else(|err| { - eprintln!("Error: {}", err); - std::process::exit(1); - }); - let package_ids = ws.members().map(|p| p.id.clone()).collect(); - let compile_opts = ops::CompileOpts { - include_target_kinds: vec![TargetKind::STARKNET_CONTRACT], - exclude_target_kinds: Vec::new(), - include_target_names: Vec::new(), - features: ops::FeaturesOpts { - features: ops::FeaturesSelector::AllFeatures, - no_default_features: true, - }, - }; - - ops::compile(package_ids, compile_opts, &ws).unwrap(); - - let reduced_project_path = source_dir.join("voyager-verify/local"); - run_scarb_build(reduced_project_path.to_str().unwrap()).unwrap(); - Ok(()) -} - -#[test] -fn test_project_with_remap() -> Result<()> { - let source_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")) - .join("tests/test_data") - .join("project_with_remap"); - let mut compilers = CompilerRepository::empty(); - compilers.add(Box::new(VoyagerGenerator)).unwrap(); - - let manifest_path = source_dir.join("Scarb.toml"); - - let config = Config::builder(manifest_path.to_str().unwrap()) - .ui_verbosity(Verbosity::Verbose) - .log_filter_directive(env::var_os("SCARB_LOG")) - .compilers(compilers) - .build() - .unwrap(); - - let ws = ops::read_workspace(config.manifest_path(), &config).unwrap_or_else(|err| { - eprintln!("Error: {}", err); - std::process::exit(1); - }); - let package_ids = ws.members().map(|p| p.id.clone()).collect(); - let compile_opts = ops::CompileOpts { - include_target_kinds: vec![TargetKind::STARKNET_CONTRACT], - exclude_target_kinds: Vec::new(), - include_target_names: Vec::new(), - features: ops::FeaturesOpts { - features: ops::FeaturesSelector::AllFeatures, - no_default_features: true, - }, - }; - - ops::compile(package_ids, compile_opts, &ws).unwrap(); - - let reduced_project_path = source_dir.join("voyager-verify/project_with_remap"); - run_scarb_build(reduced_project_path.to_str().unwrap()).unwrap(); - Ok(()) -} - -#[test] -fn test_project_w_import_from_attachment() -> Result<()> { - let source_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")) - .join("tests/test_data") - .join("project_w_import_from_attachment"); - let mut compilers = CompilerRepository::empty(); - compilers.add(Box::new(VoyagerGenerator)).unwrap(); - - let manifest_path = source_dir.join("Scarb.toml"); - - let config = Config::builder(manifest_path.to_str().unwrap()) - .ui_verbosity(Verbosity::Verbose) - .log_filter_directive(env::var_os("SCARB_LOG")) - .compilers(compilers) - .build() - .unwrap(); - - let ws = ops::read_workspace(config.manifest_path(), &config).unwrap_or_else(|err| { - eprintln!("Error: {}", err); - std::process::exit(1); - }); - let package_ids = ws.members().map(|p| p.id.clone()).collect(); - let compile_opts = ops::CompileOpts { - include_target_kinds: vec![TargetKind::STARKNET_CONTRACT], - exclude_target_kinds: Vec::new(), - include_target_names: Vec::new(), - features: ops::FeaturesOpts { - features: ops::FeaturesSelector::AllFeatures, - no_default_features: true, - }, - }; - - ops::compile(package_ids, compile_opts, &ws).unwrap(); - - let reduced_project_path = source_dir.join("voyager-verify/local"); - run_scarb_build(reduced_project_path.to_str().unwrap()).unwrap(); - Ok(()) -} - -#[test] -fn test_project_with_simple_super_import() -> Result<()> { - let source_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")) - .join("tests/test_data") - .join("simple_super_import"); - let mut compilers = CompilerRepository::empty(); - compilers.add(Box::new(VoyagerGenerator)).unwrap(); - - let manifest_path = source_dir.join("Scarb.toml"); - - let config = Config::builder(manifest_path.to_str().unwrap()) - .ui_verbosity(Verbosity::Verbose) - .log_filter_directive(env::var_os("SCARB_LOG")) - .compilers(compilers) - .build() - .unwrap(); - - let ws = ops::read_workspace(config.manifest_path(), &config).unwrap_or_else(|err| { - eprintln!("Error: {}", err); - std::process::exit(1); - }); - let package_ids = ws.members().map(|p| p.id).collect(); - let compile_opts = ops::CompileOpts { - include_target_kinds: vec![TargetKind::STARKNET_CONTRACT], - exclude_target_kinds: Vec::new(), - include_target_names: Vec::new(), - features: ops::FeaturesOpts { - features: ops::FeaturesSelector::AllFeatures, - no_default_features: true, - }, - }; - - ops::compile(package_ids, compile_opts, &ws).unwrap(); - - let reduced_project_path = source_dir.join("voyager-verify/simple_super_import"); - run_scarb_build(reduced_project_path.to_str().unwrap()).unwrap(); - Ok(()) -} - -#[test] -fn test_project_with_external_import_resolved() -> Result<()> { - let source_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")) - .join("tests/test_data") - .join("import_external_deps_with_workspace"); - let mut compilers: CompilerRepository = CompilerRepository::empty(); - compilers.add(Box::new(VoyagerGenerator)).unwrap(); - - let manifest_path = source_dir.join("Scarb.toml"); - - let config = Config::builder(manifest_path.to_str().unwrap()) - .ui_verbosity(Verbosity::Verbose) - .log_filter_directive(env::var_os("SCARB_LOG")) - .compilers(compilers) - .build() - .unwrap(); - - let ws = ops::read_workspace(config.manifest_path(), &config).unwrap_or_else(|err| { - eprintln!("Error: {}", err); - std::process::exit(1); - }); - let package_ids = ws.members().map(|p| p.id).collect(); - let compile_opts = ops::CompileOpts { - include_target_kinds: vec![TargetKind::STARKNET_CONTRACT], - exclude_target_kinds: Vec::new(), - include_target_names: Vec::new(), - features: ops::FeaturesOpts { - features: ops::FeaturesSelector::AllFeatures, - no_default_features: true, - }, - }; - - ops::compile(package_ids, compile_opts, &ws).unwrap(); - - let reduced_project_path = - source_dir.join("voyager-verify/import_external_deps_with_workspace"); - run_scarb_build(reduced_project_path.to_str().unwrap()).unwrap(); - Ok(()) -} diff --git a/crates/voyager-resolver-cairo/tests/test_data/dependency/Scarb.toml b/crates/voyager-resolver-cairo/tests/test_data/dependency/Scarb.toml deleted file mode 100644 index 9052159..0000000 --- a/crates/voyager-resolver-cairo/tests/test_data/dependency/Scarb.toml +++ /dev/null @@ -1,3 +0,0 @@ -[package] -name = "dependency" -version = "0.1.0" \ No newline at end of file diff --git a/crates/voyager-resolver-cairo/tests/test_data/dependency/src/lib.cairo b/crates/voyager-resolver-cairo/tests/test_data/dependency/src/lib.cairo deleted file mode 100644 index 018cdff..0000000 --- a/crates/voyager-resolver-cairo/tests/test_data/dependency/src/lib.cairo +++ /dev/null @@ -1 +0,0 @@ -mod main; \ No newline at end of file diff --git a/crates/voyager-resolver-cairo/tests/test_data/dependency/src/main.cairo b/crates/voyager-resolver-cairo/tests/test_data/dependency/src/main.cairo deleted file mode 100644 index dc898af..0000000 --- a/crates/voyager-resolver-cairo/tests/test_data/dependency/src/main.cairo +++ /dev/null @@ -1 +0,0 @@ -fn foo(){} \ No newline at end of file diff --git a/crates/voyager-resolver-cairo/tests/test_data/import_external_deps_with_workspace/Scarb.lock b/crates/voyager-resolver-cairo/tests/test_data/import_external_deps_with_workspace/Scarb.lock deleted file mode 100644 index 92da268..0000000 --- a/crates/voyager-resolver-cairo/tests/test_data/import_external_deps_with_workspace/Scarb.lock +++ /dev/null @@ -1,119 +0,0 @@ -# Code generated by scarb DO NOT EDIT. -version = 1 - -[[package]] -name = "dependency" -version = "0.1.0" - -[[package]] -name = "import_external_deps_with_workspace" -version = "0.1.0" -dependencies = [ - "dependency", - "openzeppelin", -] - -[[package]] -name = "openzeppelin" -version = "0.18.0" -source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.18.0#2f37306b490e63c0afa9e33ad192ba428141b487" -dependencies = [ - "openzeppelin_access", - "openzeppelin_account", - "openzeppelin_finance", - "openzeppelin_governance", - "openzeppelin_introspection", - "openzeppelin_merkle_tree", - "openzeppelin_presets", - "openzeppelin_security", - "openzeppelin_token", - "openzeppelin_upgrades", - "openzeppelin_utils", -] - -[[package]] -name = "openzeppelin_access" -version = "0.18.0" -source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.18.0#2f37306b490e63c0afa9e33ad192ba428141b487" -dependencies = [ - "openzeppelin_introspection", - "openzeppelin_utils", -] - -[[package]] -name = "openzeppelin_account" -version = "0.18.0" -source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.18.0#2f37306b490e63c0afa9e33ad192ba428141b487" -dependencies = [ - "openzeppelin_introspection", - "openzeppelin_utils", -] - -[[package]] -name = "openzeppelin_finance" -version = "0.18.0" -source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.18.0#2f37306b490e63c0afa9e33ad192ba428141b487" -dependencies = [ - "openzeppelin_access", - "openzeppelin_token", -] - -[[package]] -name = "openzeppelin_governance" -version = "0.18.0" -source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.18.0#2f37306b490e63c0afa9e33ad192ba428141b487" -dependencies = [ - "openzeppelin_access", - "openzeppelin_account", - "openzeppelin_introspection", - "openzeppelin_token", -] - -[[package]] -name = "openzeppelin_introspection" -version = "0.18.0" -source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.18.0#2f37306b490e63c0afa9e33ad192ba428141b487" - -[[package]] -name = "openzeppelin_merkle_tree" -version = "0.18.0" -source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.18.0#2f37306b490e63c0afa9e33ad192ba428141b487" - -[[package]] -name = "openzeppelin_presets" -version = "0.18.0" -source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.18.0#2f37306b490e63c0afa9e33ad192ba428141b487" -dependencies = [ - "openzeppelin_access", - "openzeppelin_account", - "openzeppelin_finance", - "openzeppelin_introspection", - "openzeppelin_token", - "openzeppelin_upgrades", - "openzeppelin_utils", -] - -[[package]] -name = "openzeppelin_security" -version = "0.18.0" -source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.18.0#2f37306b490e63c0afa9e33ad192ba428141b487" - -[[package]] -name = "openzeppelin_token" -version = "0.18.0" -source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.18.0#2f37306b490e63c0afa9e33ad192ba428141b487" -dependencies = [ - "openzeppelin_account", - "openzeppelin_introspection", - "openzeppelin_utils", -] - -[[package]] -name = "openzeppelin_upgrades" -version = "0.18.0" -source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.18.0#2f37306b490e63c0afa9e33ad192ba428141b487" - -[[package]] -name = "openzeppelin_utils" -version = "0.18.0" -source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.18.0#2f37306b490e63c0afa9e33ad192ba428141b487" diff --git a/crates/voyager-resolver-cairo/tests/test_data/import_external_deps_with_workspace/Scarb.toml b/crates/voyager-resolver-cairo/tests/test_data/import_external_deps_with_workspace/Scarb.toml deleted file mode 100644 index 7264993..0000000 --- a/crates/voyager-resolver-cairo/tests/test_data/import_external_deps_with_workspace/Scarb.toml +++ /dev/null @@ -1,23 +0,0 @@ -[package] -name = "import_external_deps_with_workspace" -version = "0.1.0" - -# See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest - -[dependencies] -starknet = ">=2.3.0" -dependency = { path = "../dependency" } -openzeppelin = { git = "https://github.com/OpenZeppelin/cairo-contracts.git", tag = "v0.18.0" } - - -[[target.starknet-contract]] -sierra = true -casm = true -casm-add-pythonic-hints = true - -[lib] -sierra = true -casm = true - -[tool.voyager] -contract = { path = "main.cairo", address = "0x12345" } \ No newline at end of file diff --git a/crates/voyager-resolver-cairo/tests/test_data/import_external_deps_with_workspace/src/lib.cairo b/crates/voyager-resolver-cairo/tests/test_data/import_external_deps_with_workspace/src/lib.cairo deleted file mode 100644 index 018cdff..0000000 --- a/crates/voyager-resolver-cairo/tests/test_data/import_external_deps_with_workspace/src/lib.cairo +++ /dev/null @@ -1 +0,0 @@ -mod main; \ No newline at end of file diff --git a/crates/voyager-resolver-cairo/tests/test_data/import_external_deps_with_workspace/src/main.cairo b/crates/voyager-resolver-cairo/tests/test_data/import_external_deps_with_workspace/src/main.cairo deleted file mode 100644 index 92b6e68..0000000 --- a/crates/voyager-resolver-cairo/tests/test_data/import_external_deps_with_workspace/src/main.cairo +++ /dev/null @@ -1,18 +0,0 @@ -#[starknet::contract] -mod contract { - use openzeppelin::token::erc1155::erc1155::ERC1155Component::InternalTrait; - use openzeppelin::{ - introspection::{src5::SRC5Component}, access::ownable::OwnableComponent, - token::erc1155::{ERC1155Component, ERC1155HooksEmptyImpl, interface::IERC1155MetadataURI}, - upgrades::{UpgradeableComponent, interface::IUpgradeable}, - }; - use starknet::{get_contract_address, get_caller_address}; - use starknet::{ContractAddress, ClassHash}; - - #[storage] - struct Storage {} - - fn value(self: @ContractState, ) -> felt252 { - 42 - } -} diff --git a/crates/voyager-resolver-cairo/tests/test_data/project_w_import_from_attachment/.gitignore b/crates/voyager-resolver-cairo/tests/test_data/project_w_import_from_attachment/.gitignore deleted file mode 100644 index 7a1f954..0000000 --- a/crates/voyager-resolver-cairo/tests/test_data/project_w_import_from_attachment/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -target -voyager-verify diff --git a/crates/voyager-resolver-cairo/tests/test_data/project_w_import_from_attachment/Scarb.lock b/crates/voyager-resolver-cairo/tests/test_data/project_w_import_from_attachment/Scarb.lock deleted file mode 100644 index d92ce5f..0000000 --- a/crates/voyager-resolver-cairo/tests/test_data/project_w_import_from_attachment/Scarb.lock +++ /dev/null @@ -1,13 +0,0 @@ -# Code generated by scarb DO NOT EDIT. -version = 1 - -[[package]] -name = "dependency" -version = "0.1.0" - -[[package]] -name = "local" -version = "0.1.0" -dependencies = [ - "dependency", -] diff --git a/crates/voyager-resolver-cairo/tests/test_data/project_w_import_from_attachment/Scarb.toml b/crates/voyager-resolver-cairo/tests/test_data/project_w_import_from_attachment/Scarb.toml deleted file mode 100644 index fd1c004..0000000 --- a/crates/voyager-resolver-cairo/tests/test_data/project_w_import_from_attachment/Scarb.toml +++ /dev/null @@ -1,15 +0,0 @@ -[package] -name = "local" -version = "0.1.0" - -# See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest - -[dependencies] -starknet = ">=2.6.3" -dependency = { path = "../dependency" } - -[[target.starknet-contract]] - -[tool.voyager] -ERC20 = { path = "contracts/ERC20.cairo", address = "0x12345" } - diff --git a/crates/voyager-resolver-cairo/tests/test_data/project_w_import_from_attachment/src/contracts.cairo b/crates/voyager-resolver-cairo/tests/test_data/project_w_import_from_attachment/src/contracts.cairo deleted file mode 100644 index 13e7de1..0000000 --- a/crates/voyager-resolver-cairo/tests/test_data/project_w_import_from_attachment/src/contracts.cairo +++ /dev/null @@ -1 +0,0 @@ -mod ERC20; \ No newline at end of file diff --git a/crates/voyager-resolver-cairo/tests/test_data/project_w_import_from_attachment/src/contracts/ERC20.cairo b/crates/voyager-resolver-cairo/tests/test_data/project_w_import_from_attachment/src/contracts/ERC20.cairo deleted file mode 100644 index b7e365d..0000000 --- a/crates/voyager-resolver-cairo/tests/test_data/project_w_import_from_attachment/src/contracts/ERC20.cairo +++ /dev/null @@ -1,162 +0,0 @@ -#[starknet::contract] -mod ERC20 { - use zeroable::Zeroable; - use starknet::get_caller_address; - use starknet::contract_address_const; - use starknet::ContractAddress; - use dependency::main::foo; - use local::bar; - - #[storage] - struct Storage { - name: felt252, - symbol: felt252, - decimals: u8, - total_supply: u256, - balances: LegacyMap::, - allowances: LegacyMap::<(ContractAddress, ContractAddress), u256>, - } - - #[event] - #[derive(Drop, starknet::Event)] - enum Event { - Approval: Approval, - Transfer: Transfer, - } - - #[derive(Drop, starknet::Event)] - struct Transfer { - from: ContractAddress, - to: ContractAddress, - value: u256 - } - - #[derive(Drop, starknet::Event)] - struct Approval { - owner: ContractAddress, - spender: ContractAddress, - value: u256 - } - - #[constructor] - fn constructor( - ref self: ContractState, - name_: felt252, - symbol_: felt252, - decimals_: u8, - initial_supply: u256, - recipient: ContractAddress - ) { - self.name.write(name_); - self.symbol.write(symbol_); - self.decimals.write(decimals_); - assert(!recipient.is_zero(), 'ERC20: mint to the 0 address'); - self.total_supply.write(initial_supply); - self.balances.write(recipient, initial_supply); - self - .emit( - Transfer { - from: contract_address_const::<0>(), to: recipient, value: initial_supply - } - ); - } - - #[external(v0)] - fn get_name(self: @ContractState) -> felt252 { - self.name.read() - } - - #[external(v0)] - fn get_symbol(self: @ContractState) -> felt252 { - self.symbol.read() - } - - #[external(v0)] - fn get_decimals(self: @ContractState) -> u8 { - self.decimals.read() - } - - #[external(v0)] - fn get_total_supply(self: @ContractState) -> u256 { - self.total_supply.read() - } - - #[external(v0)] - fn balance_of(self: @ContractState, account: ContractAddress) -> u256 { - self.balances.read(account) - } - - #[external(v0)] - fn allowance(self: @ContractState, owner: ContractAddress, spender: ContractAddress) -> u256 { - self.allowances.read((owner, spender)) - } - - #[external(v0)] - fn transfer(ref self: ContractState, recipient: ContractAddress, amount: u256) { - let sender = get_caller_address(); - transfer_helper(ref self, sender, recipient, amount); - } - - #[external(v0)] - fn transfer_from( - ref self: ContractState, sender: ContractAddress, recipient: ContractAddress, amount: u256 - ) { - let caller = get_caller_address(); - spend_allowance(ref self, sender, caller, amount); - transfer_helper(ref self, sender, recipient, amount); - } - - #[external(v0)] - fn approve(ref self: ContractState, spender: ContractAddress, amount: u256) { - let caller = get_caller_address(); - approve_helper(ref self, caller, spender, amount); - } - - #[external(v0)] - fn increase_allowance(ref self: ContractState, spender: ContractAddress, added_value: u256) { - let caller = get_caller_address(); - approve_helper( - ref self, caller, spender, self.allowances.read((caller, spender)) + added_value - ); - } - - #[external(v0)] - fn decrease_allowance( - ref self: ContractState, spender: ContractAddress, subtracted_value: u256 - ) { - let caller = get_caller_address(); - approve_helper( - ref self, caller, spender, self.allowances.read((caller, spender)) - subtracted_value - ); - } - - fn transfer_helper( - ref self: ContractState, sender: ContractAddress, recipient: ContractAddress, amount: u256 - ) { - assert(!sender.is_zero(), 'ERC20: transfer from 0'); - assert(!recipient.is_zero(), 'ERC20: transfer to 0'); - self.balances.write(sender, self.balances.read(sender) - amount); - self.balances.write(recipient, self.balances.read(recipient) + amount); - self.emit(Transfer { from: sender, to: recipient, value: amount }) - } - - fn spend_allowance( - ref self: ContractState, owner: ContractAddress, spender: ContractAddress, amount: u256 - ) { - let current_allowance = self.allowances.read((owner, spender)); - let ONES_MASK = 0xffffffffffffffffffffffffffffffff_u128; - let is_unlimited_allowance = current_allowance.low == ONES_MASK - && current_allowance.high == ONES_MASK; - if !is_unlimited_allowance { - approve_helper(ref self, owner, spender, current_allowance - amount); - } - } - - fn approve_helper( - ref self: ContractState, owner: ContractAddress, spender: ContractAddress, amount: u256 - ) { - assert(!spender.is_zero(), 'ERC20: approve from 0'); - self.allowances.write((owner, spender), amount); - self.emit(Approval { owner, spender, value: amount }); - } -} diff --git a/crates/voyager-resolver-cairo/tests/test_data/project_w_import_from_attachment/src/lib.cairo b/crates/voyager-resolver-cairo/tests/test_data/project_w_import_from_attachment/src/lib.cairo deleted file mode 100644 index 13974b1..0000000 --- a/crates/voyager-resolver-cairo/tests/test_data/project_w_import_from_attachment/src/lib.cairo +++ /dev/null @@ -1,4 +0,0 @@ -mod contracts; -mod tests; - -fn bar(){} \ No newline at end of file diff --git a/crates/voyager-resolver-cairo/tests/test_data/project_w_import_from_attachment/src/tests.cairo b/crates/voyager-resolver-cairo/tests/test_data/project_w_import_from_attachment/src/tests.cairo deleted file mode 100644 index 479760f..0000000 --- a/crates/voyager-resolver-cairo/tests/test_data/project_w_import_from_attachment/src/tests.cairo +++ /dev/null @@ -1 +0,0 @@ -mod test_erc20; \ No newline at end of file diff --git a/crates/voyager-resolver-cairo/tests/test_data/project_w_import_from_attachment/src/tests/test_erc20.cairo b/crates/voyager-resolver-cairo/tests/test_data/project_w_import_from_attachment/src/tests/test_erc20.cairo deleted file mode 100644 index 22a4b77..0000000 --- a/crates/voyager-resolver-cairo/tests/test_data/project_w_import_from_attachment/src/tests/test_erc20.cairo +++ /dev/null @@ -1 +0,0 @@ -use local::contracts::ERC20; \ No newline at end of file diff --git a/crates/voyager-resolver-cairo/tests/test_data/project_w_incorrect_contract_path/.gitignore b/crates/voyager-resolver-cairo/tests/test_data/project_w_incorrect_contract_path/.gitignore deleted file mode 100644 index 7a1f954..0000000 --- a/crates/voyager-resolver-cairo/tests/test_data/project_w_incorrect_contract_path/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -target -voyager-verify diff --git a/crates/voyager-resolver-cairo/tests/test_data/project_w_incorrect_contract_path/Scarb.lock b/crates/voyager-resolver-cairo/tests/test_data/project_w_incorrect_contract_path/Scarb.lock deleted file mode 100644 index 8c4bb6b..0000000 --- a/crates/voyager-resolver-cairo/tests/test_data/project_w_incorrect_contract_path/Scarb.lock +++ /dev/null @@ -1,6 +0,0 @@ -# Code generated by scarb DO NOT EDIT. -version = 1 - -[[package]] -name = "project_w_incorrect_contract_path" -version = "0.1.0" diff --git a/crates/voyager-resolver-cairo/tests/test_data/project_w_incorrect_contract_path/Scarb.toml b/crates/voyager-resolver-cairo/tests/test_data/project_w_incorrect_contract_path/Scarb.toml deleted file mode 100644 index 3536cad..0000000 --- a/crates/voyager-resolver-cairo/tests/test_data/project_w_incorrect_contract_path/Scarb.toml +++ /dev/null @@ -1,14 +0,0 @@ -[package] -name = "project_w_incorrect_contract_path" -version = "0.1.0" - -# See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest - -[dependencies] -starknet = ">=2.6.3" - -[[target.starknet-contract]] - -[tool.voyager] -# Explicitly incorrect -ERC20 = { path = "ERC20.cairo", address = "0x12345" } diff --git a/crates/voyager-resolver-cairo/tests/test_data/project_w_incorrect_contract_path/src/contracts.cairo b/crates/voyager-resolver-cairo/tests/test_data/project_w_incorrect_contract_path/src/contracts.cairo deleted file mode 100644 index 13e7de1..0000000 --- a/crates/voyager-resolver-cairo/tests/test_data/project_w_incorrect_contract_path/src/contracts.cairo +++ /dev/null @@ -1 +0,0 @@ -mod ERC20; \ No newline at end of file diff --git a/crates/voyager-resolver-cairo/tests/test_data/project_w_incorrect_contract_path/src/contracts/ERC20.cairo b/crates/voyager-resolver-cairo/tests/test_data/project_w_incorrect_contract_path/src/contracts/ERC20.cairo deleted file mode 100644 index 357fe0e..0000000 --- a/crates/voyager-resolver-cairo/tests/test_data/project_w_incorrect_contract_path/src/contracts/ERC20.cairo +++ /dev/null @@ -1,160 +0,0 @@ -#[starknet::contract] -mod ERC20 { - use zeroable::Zeroable; - use starknet::get_caller_address; - use starknet::contract_address_const; - use starknet::ContractAddress; - - #[storage] - struct Storage { - name: felt252, - symbol: felt252, - decimals: u8, - total_supply: u256, - balances: LegacyMap::, - allowances: LegacyMap::<(ContractAddress, ContractAddress), u256>, - } - - #[event] - #[derive(Drop, starknet::Event)] - enum Event { - Approval: Approval, - Transfer: Transfer, - } - - #[derive(Drop, starknet::Event)] - struct Transfer { - from: ContractAddress, - to: ContractAddress, - value: u256 - } - - #[derive(Drop, starknet::Event)] - struct Approval { - owner: ContractAddress, - spender: ContractAddress, - value: u256 - } - - #[constructor] - fn constructor( - ref self: ContractState, - name_: felt252, - symbol_: felt252, - decimals_: u8, - initial_supply: u256, - recipient: ContractAddress - ) { - self.name.write(name_); - self.symbol.write(symbol_); - self.decimals.write(decimals_); - assert(!recipient.is_zero(), 'ERC20: mint to the 0 address'); - self.total_supply.write(initial_supply); - self.balances.write(recipient, initial_supply); - self - .emit( - Transfer { - from: contract_address_const::<0>(), to: recipient, value: initial_supply - } - ); - } - - #[external(v0)] - fn get_name(self: @ContractState) -> felt252 { - self.name.read() - } - - #[external(v0)] - fn get_symbol(self: @ContractState) -> felt252 { - self.symbol.read() - } - - #[external(v0)] - fn get_decimals(self: @ContractState) -> u8 { - self.decimals.read() - } - - #[external(v0)] - fn get_total_supply(self: @ContractState) -> u256 { - self.total_supply.read() - } - - #[external(v0)] - fn balance_of(self: @ContractState, account: ContractAddress) -> u256 { - self.balances.read(account) - } - - #[external(v0)] - fn allowance(self: @ContractState, owner: ContractAddress, spender: ContractAddress) -> u256 { - self.allowances.read((owner, spender)) - } - - #[external(v0)] - fn transfer(ref self: ContractState, recipient: ContractAddress, amount: u256) { - let sender = get_caller_address(); - transfer_helper(ref self, sender, recipient, amount); - } - - #[external(v0)] - fn transfer_from( - ref self: ContractState, sender: ContractAddress, recipient: ContractAddress, amount: u256 - ) { - let caller = get_caller_address(); - spend_allowance(ref self, sender, caller, amount); - transfer_helper(ref self, sender, recipient, amount); - } - - #[external(v0)] - fn approve(ref self: ContractState, spender: ContractAddress, amount: u256) { - let caller = get_caller_address(); - approve_helper(ref self, caller, spender, amount); - } - - #[external(v0)] - fn increase_allowance(ref self: ContractState, spender: ContractAddress, added_value: u256) { - let caller = get_caller_address(); - approve_helper( - ref self, caller, spender, self.allowances.read((caller, spender)) + added_value - ); - } - - #[external(v0)] - fn decrease_allowance( - ref self: ContractState, spender: ContractAddress, subtracted_value: u256 - ) { - let caller = get_caller_address(); - approve_helper( - ref self, caller, spender, self.allowances.read((caller, spender)) - subtracted_value - ); - } - - fn transfer_helper( - ref self: ContractState, sender: ContractAddress, recipient: ContractAddress, amount: u256 - ) { - assert(!sender.is_zero(), 'ERC20: transfer from 0'); - assert(!recipient.is_zero(), 'ERC20: transfer to 0'); - self.balances.write(sender, self.balances.read(sender) - amount); - self.balances.write(recipient, self.balances.read(recipient) + amount); - self.emit(Transfer { from: sender, to: recipient, value: amount }); - } - - fn spend_allowance( - ref self: ContractState, owner: ContractAddress, spender: ContractAddress, amount: u256 - ) { - let current_allowance = self.allowances.read((owner, spender)); - let ONES_MASK = 0xffffffffffffffffffffffffffffffff_u128; - let is_unlimited_allowance = current_allowance.low == ONES_MASK - && current_allowance.high == ONES_MASK; - if !is_unlimited_allowance { - approve_helper(ref self, owner, spender, current_allowance - amount); - } - } - - fn approve_helper( - ref self: ContractState, owner: ContractAddress, spender: ContractAddress, amount: u256 - ) { - assert(!spender.is_zero(), 'ERC20: approve from 0'); - self.allowances.write((owner, spender), amount); - self.emit(Approval { owner, spender, value: amount }); - } -} diff --git a/crates/voyager-resolver-cairo/tests/test_data/project_w_incorrect_contract_path/src/lib.cairo b/crates/voyager-resolver-cairo/tests/test_data/project_w_incorrect_contract_path/src/lib.cairo deleted file mode 100644 index 16d4bf2..0000000 --- a/crates/voyager-resolver-cairo/tests/test_data/project_w_incorrect_contract_path/src/lib.cairo +++ /dev/null @@ -1 +0,0 @@ -mod contracts; \ No newline at end of file diff --git a/crates/voyager-resolver-cairo/tests/test_data/project_with_remap/.gitignore b/crates/voyager-resolver-cairo/tests/test_data/project_with_remap/.gitignore deleted file mode 100644 index 7a1f954..0000000 --- a/crates/voyager-resolver-cairo/tests/test_data/project_with_remap/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -target -voyager-verify diff --git a/crates/voyager-resolver-cairo/tests/test_data/project_with_remap/Scarb.lock b/crates/voyager-resolver-cairo/tests/test_data/project_with_remap/Scarb.lock deleted file mode 100644 index 37cedcd..0000000 --- a/crates/voyager-resolver-cairo/tests/test_data/project_with_remap/Scarb.lock +++ /dev/null @@ -1,13 +0,0 @@ -# Code generated by scarb DO NOT EDIT. -version = 1 - -[[package]] -name = "dependency" -version = "0.1.0" - -[[package]] -name = "project_with_remap" -version = "0.1.0" -dependencies = [ - "dependency", -] diff --git a/crates/voyager-resolver-cairo/tests/test_data/project_with_remap/Scarb.toml b/crates/voyager-resolver-cairo/tests/test_data/project_with_remap/Scarb.toml deleted file mode 100644 index 2f5be32..0000000 --- a/crates/voyager-resolver-cairo/tests/test_data/project_with_remap/Scarb.toml +++ /dev/null @@ -1,14 +0,0 @@ -[package] -name = "project_with_remap" -version = "0.1.0" - -# See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest.html - -[dependencies] -starknet = ">=2.6.3" -dependency = { path = "../dependency" } - -[[target.starknet-contract]] - -[tool.voyager] -ERC20 = { path = "contracts/ERC20.cairo", address = "0x12345" } diff --git a/crates/voyager-resolver-cairo/tests/test_data/project_with_remap/src/contracts.cairo b/crates/voyager-resolver-cairo/tests/test_data/project_with_remap/src/contracts.cairo deleted file mode 100644 index 8dde0a6..0000000 --- a/crates/voyager-resolver-cairo/tests/test_data/project_with_remap/src/contracts.cairo +++ /dev/null @@ -1,4 +0,0 @@ -mod ERC20; -mod utils; - -use utils::bar; \ No newline at end of file diff --git a/crates/voyager-resolver-cairo/tests/test_data/project_with_remap/src/contracts/ERC20.cairo b/crates/voyager-resolver-cairo/tests/test_data/project_with_remap/src/contracts/ERC20.cairo deleted file mode 100644 index 2d36ed6..0000000 --- a/crates/voyager-resolver-cairo/tests/test_data/project_with_remap/src/contracts/ERC20.cairo +++ /dev/null @@ -1,162 +0,0 @@ -#[starknet::contract] -mod ERC20 { - use zeroable::Zeroable; - use starknet::get_caller_address; - use starknet::contract_address_const; - use starknet::ContractAddress; - use dependency::main::foo; - use project_with_remap::contracts::bar; - - #[storage] - struct Storage { - name: felt252, - symbol: felt252, - decimals: u8, - total_supply: u256, - balances: LegacyMap::, - allowances: LegacyMap::<(ContractAddress, ContractAddress), u256>, - } - - #[event] - #[derive(Drop, starknet::Event)] - enum Event { - Approval: Approval, - Transfer: Transfer, - } - - #[derive(Drop, starknet::Event)] - struct Transfer { - from: ContractAddress, - to: ContractAddress, - value: u256 - } - - #[derive(Drop, starknet::Event)] - struct Approval { - owner: ContractAddress, - spender: ContractAddress, - value: u256 - } - - #[constructor] - fn constructor( - ref self: ContractState, - name_: felt252, - symbol_: felt252, - decimals_: u8, - initial_supply: u256, - recipient: ContractAddress - ) { - self.name.write(name_); - self.symbol.write(symbol_); - self.decimals.write(decimals_); - assert(!recipient.is_zero(), 'ERC20: mint to the 0 address'); - self.total_supply.write(initial_supply); - self.balances.write(recipient, initial_supply); - self - .emit( - Transfer { - from: contract_address_const::<0>(), to: recipient, value: initial_supply - } - ); - } - - #[external(v0)] - fn get_name(self: @ContractState) -> felt252 { - self.name.read() - } - - #[external(v0)] - fn get_symbol(self: @ContractState) -> felt252 { - self.symbol.read() - } - - #[external(v0)] - fn get_decimals(self: @ContractState) -> u8 { - self.decimals.read() - } - - #[external(v0)] - fn get_total_supply(self: @ContractState) -> u256 { - self.total_supply.read() - } - - #[external(v0)] - fn balance_of(self: @ContractState, account: ContractAddress) -> u256 { - self.balances.read(account) - } - - #[external(v0)] - fn allowance(self: @ContractState, owner: ContractAddress, spender: ContractAddress) -> u256 { - self.allowances.read((owner, spender)) - } - - #[external(v0)] - fn transfer(ref self: ContractState, recipient: ContractAddress, amount: u256) { - let sender = get_caller_address(); - transfer_helper(ref self, sender, recipient, amount); - } - - #[external(v0)] - fn transfer_from( - ref self: ContractState, sender: ContractAddress, recipient: ContractAddress, amount: u256 - ) { - let caller = get_caller_address(); - spend_allowance(ref self, sender, caller, amount); - transfer_helper(ref self, sender, recipient, amount); - } - - #[external(v0)] - fn approve(ref self: ContractState, spender: ContractAddress, amount: u256) { - let caller = get_caller_address(); - approve_helper(ref self, caller, spender, amount); - } - - #[external(v0)] - fn increase_allowance(ref self: ContractState, spender: ContractAddress, added_value: u256) { - let caller = get_caller_address(); - approve_helper( - ref self, caller, spender, self.allowances.read((caller, spender)) + added_value - ); - } - - #[external(v0)] - fn decrease_allowance( - ref self: ContractState, spender: ContractAddress, subtracted_value: u256 - ) { - let caller = get_caller_address(); - approve_helper( - ref self, caller, spender, self.allowances.read((caller, spender)) - subtracted_value - ); - } - - fn transfer_helper( - ref self: ContractState, sender: ContractAddress, recipient: ContractAddress, amount: u256 - ) { - assert(!sender.is_zero(), 'ERC20: transfer from 0'); - assert(!recipient.is_zero(), 'ERC20: transfer to 0'); - self.balances.write(sender, self.balances.read(sender) - amount); - self.balances.write(recipient, self.balances.read(recipient) + amount); - self.emit(Transfer { from: sender, to: recipient, value: amount }) - } - - fn spend_allowance( - ref self: ContractState, owner: ContractAddress, spender: ContractAddress, amount: u256 - ) { - let current_allowance = self.allowances.read((owner, spender)); - let ONES_MASK = 0xffffffffffffffffffffffffffffffff_u128; - let is_unlimited_allowance = current_allowance.low == ONES_MASK - && current_allowance.high == ONES_MASK; - if !is_unlimited_allowance { - approve_helper(ref self, owner, spender, current_allowance - amount); - } - } - - fn approve_helper( - ref self: ContractState, owner: ContractAddress, spender: ContractAddress, amount: u256 - ) { - assert(!spender.is_zero(), 'ERC20: approve from 0'); - self.allowances.write((owner, spender), amount); - self.emit(Approval { owner, spender, value: amount }); - } -} diff --git a/crates/voyager-resolver-cairo/tests/test_data/project_with_remap/src/contracts/utils.cairo b/crates/voyager-resolver-cairo/tests/test_data/project_with_remap/src/contracts/utils.cairo deleted file mode 100644 index 89414dc..0000000 --- a/crates/voyager-resolver-cairo/tests/test_data/project_with_remap/src/contracts/utils.cairo +++ /dev/null @@ -1 +0,0 @@ -fn bar(){} \ No newline at end of file diff --git a/crates/voyager-resolver-cairo/tests/test_data/project_with_remap/src/lib.cairo b/crates/voyager-resolver-cairo/tests/test_data/project_with_remap/src/lib.cairo deleted file mode 100644 index 51c5d8a..0000000 --- a/crates/voyager-resolver-cairo/tests/test_data/project_with_remap/src/lib.cairo +++ /dev/null @@ -1,2 +0,0 @@ -mod contracts; -mod tests; \ No newline at end of file diff --git a/crates/voyager-resolver-cairo/tests/test_data/project_with_remap/src/tests.cairo b/crates/voyager-resolver-cairo/tests/test_data/project_with_remap/src/tests.cairo deleted file mode 100644 index 479760f..0000000 --- a/crates/voyager-resolver-cairo/tests/test_data/project_with_remap/src/tests.cairo +++ /dev/null @@ -1 +0,0 @@ -mod test_erc20; \ No newline at end of file diff --git a/crates/voyager-resolver-cairo/tests/test_data/project_with_remap/src/tests/test_erc20.cairo b/crates/voyager-resolver-cairo/tests/test_data/project_with_remap/src/tests/test_erc20.cairo deleted file mode 100644 index 7193778..0000000 --- a/crates/voyager-resolver-cairo/tests/test_data/project_with_remap/src/tests/test_erc20.cairo +++ /dev/null @@ -1 +0,0 @@ -use project_with_remap::contracts::ERC20; \ No newline at end of file diff --git a/crates/voyager-resolver-cairo/tests/test_data/simple_project/.gitignore b/crates/voyager-resolver-cairo/tests/test_data/simple_project/.gitignore deleted file mode 100644 index 7a1f954..0000000 --- a/crates/voyager-resolver-cairo/tests/test_data/simple_project/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -target -voyager-verify diff --git a/crates/voyager-resolver-cairo/tests/test_data/simple_project/Scarb.lock b/crates/voyager-resolver-cairo/tests/test_data/simple_project/Scarb.lock deleted file mode 100644 index d92ce5f..0000000 --- a/crates/voyager-resolver-cairo/tests/test_data/simple_project/Scarb.lock +++ /dev/null @@ -1,13 +0,0 @@ -# Code generated by scarb DO NOT EDIT. -version = 1 - -[[package]] -name = "dependency" -version = "0.1.0" - -[[package]] -name = "local" -version = "0.1.0" -dependencies = [ - "dependency", -] diff --git a/crates/voyager-resolver-cairo/tests/test_data/simple_project/Scarb.toml b/crates/voyager-resolver-cairo/tests/test_data/simple_project/Scarb.toml deleted file mode 100644 index 7892b0e..0000000 --- a/crates/voyager-resolver-cairo/tests/test_data/simple_project/Scarb.toml +++ /dev/null @@ -1,14 +0,0 @@ -[package] -name = "local" -version = "0.1.0" - -# See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest - -[dependencies] -starknet = ">=2.6.3" -dependency = { path = "../dependency" } - -[[target.starknet-contract]] - -[tool.voyager] -ERC20 = { path = "contracts/ERC20.cairo", address = "0x12345" } diff --git a/crates/voyager-resolver-cairo/tests/test_data/simple_project/src/contracts.cairo b/crates/voyager-resolver-cairo/tests/test_data/simple_project/src/contracts.cairo deleted file mode 100644 index 13e7de1..0000000 --- a/crates/voyager-resolver-cairo/tests/test_data/simple_project/src/contracts.cairo +++ /dev/null @@ -1 +0,0 @@ -mod ERC20; \ No newline at end of file diff --git a/crates/voyager-resolver-cairo/tests/test_data/simple_project/src/contracts/ERC20.cairo b/crates/voyager-resolver-cairo/tests/test_data/simple_project/src/contracts/ERC20.cairo deleted file mode 100644 index 578ae77..0000000 --- a/crates/voyager-resolver-cairo/tests/test_data/simple_project/src/contracts/ERC20.cairo +++ /dev/null @@ -1,161 +0,0 @@ -#[starknet::contract] -mod ERC20 { - use zeroable::Zeroable; - use starknet::get_caller_address; - use starknet::contract_address_const; - use starknet::ContractAddress; - use dependency::main::foo; - - #[storage] - struct Storage { - name: felt252, - symbol: felt252, - decimals: u8, - total_supply: u256, - balances: LegacyMap::, - allowances: LegacyMap::<(ContractAddress, ContractAddress), u256>, - } - - #[event] - #[derive(Drop, starknet::Event)] - enum Event { - Approval: Approval, - Transfer: Transfer, - } - - #[derive(Drop, starknet::Event)] - struct Transfer { - from: ContractAddress, - to: ContractAddress, - value: u256 - } - - #[derive(Drop, starknet::Event)] - struct Approval { - owner: ContractAddress, - spender: ContractAddress, - value: u256 - } - - #[constructor] - fn constructor( - ref self: ContractState, - name_: felt252, - symbol_: felt252, - decimals_: u8, - initial_supply: u256, - recipient: ContractAddress - ) { - self.name.write(name_); - self.symbol.write(symbol_); - self.decimals.write(decimals_); - assert(!recipient.is_zero(), 'ERC20: mint to the 0 address'); - self.total_supply.write(initial_supply); - self.balances.write(recipient, initial_supply); - self - .emit( - Transfer { - from: contract_address_const::<0>(), to: recipient, value: initial_supply - } - ); - } - - #[external(v0)] - fn get_name(self: @ContractState) -> felt252 { - self.name.read() - } - - #[external(v0)] - fn get_symbol(self: @ContractState) -> felt252 { - self.symbol.read() - } - - #[external(v0)] - fn get_decimals(self: @ContractState) -> u8 { - self.decimals.read() - } - - #[external(v0)] - fn get_total_supply(self: @ContractState) -> u256 { - self.total_supply.read() - } - - #[external(v0)] - fn balance_of(self: @ContractState, account: ContractAddress) -> u256 { - self.balances.read(account) - } - - #[external(v0)] - fn allowance(self: @ContractState, owner: ContractAddress, spender: ContractAddress) -> u256 { - self.allowances.read((owner, spender)) - } - - #[external(v0)] - fn transfer(ref self: ContractState, recipient: ContractAddress, amount: u256) { - let sender = get_caller_address(); - transfer_helper(ref self, sender, recipient, amount); - } - - #[external(v0)] - fn transfer_from( - ref self: ContractState, sender: ContractAddress, recipient: ContractAddress, amount: u256 - ) { - let caller = get_caller_address(); - spend_allowance(ref self, sender, caller, amount); - transfer_helper(ref self, sender, recipient, amount); - } - - #[external(v0)] - fn approve(ref self: ContractState, spender: ContractAddress, amount: u256) { - let caller = get_caller_address(); - approve_helper(ref self, caller, spender, amount); - } - - #[external(v0)] - fn increase_allowance(ref self: ContractState, spender: ContractAddress, added_value: u256) { - let caller = get_caller_address(); - approve_helper( - ref self, caller, spender, self.allowances.read((caller, spender)) + added_value - ); - } - - #[external(v0)] - fn decrease_allowance( - ref self: ContractState, spender: ContractAddress, subtracted_value: u256 - ) { - let caller = get_caller_address(); - approve_helper( - ref self, caller, spender, self.allowances.read((caller, spender)) - subtracted_value - ); - } - - fn transfer_helper( - ref self: ContractState, sender: ContractAddress, recipient: ContractAddress, amount: u256 - ) { - assert(!sender.is_zero(), 'ERC20: transfer from 0'); - assert(!recipient.is_zero(), 'ERC20: transfer to 0'); - self.balances.write(sender, self.balances.read(sender) - amount); - self.balances.write(recipient, self.balances.read(recipient) + amount); - self.emit(Transfer { from: sender, to: recipient, value: amount }); - } - - fn spend_allowance( - ref self: ContractState, owner: ContractAddress, spender: ContractAddress, amount: u256 - ) { - let current_allowance = self.allowances.read((owner, spender)); - let ONES_MASK = 0xffffffffffffffffffffffffffffffff_u128; - let is_unlimited_allowance = current_allowance.low == ONES_MASK - && current_allowance.high == ONES_MASK; - if !is_unlimited_allowance { - approve_helper(ref self, owner, spender, current_allowance - amount); - } - } - - fn approve_helper( - ref self: ContractState, owner: ContractAddress, spender: ContractAddress, amount: u256 - ) { - assert(!spender.is_zero(), 'ERC20: approve from 0'); - self.allowances.write((owner, spender), amount); - self.emit(Approval { owner, spender, value: amount }); - } -} diff --git a/crates/voyager-resolver-cairo/tests/test_data/simple_project/src/lib.cairo b/crates/voyager-resolver-cairo/tests/test_data/simple_project/src/lib.cairo deleted file mode 100644 index 51c5d8a..0000000 --- a/crates/voyager-resolver-cairo/tests/test_data/simple_project/src/lib.cairo +++ /dev/null @@ -1,2 +0,0 @@ -mod contracts; -mod tests; \ No newline at end of file diff --git a/crates/voyager-resolver-cairo/tests/test_data/simple_project/src/tests.cairo b/crates/voyager-resolver-cairo/tests/test_data/simple_project/src/tests.cairo deleted file mode 100644 index 479760f..0000000 --- a/crates/voyager-resolver-cairo/tests/test_data/simple_project/src/tests.cairo +++ /dev/null @@ -1 +0,0 @@ -mod test_erc20; \ No newline at end of file diff --git a/crates/voyager-resolver-cairo/tests/test_data/simple_project/src/tests/test_erc20.cairo b/crates/voyager-resolver-cairo/tests/test_data/simple_project/src/tests/test_erc20.cairo deleted file mode 100644 index 22a4b77..0000000 --- a/crates/voyager-resolver-cairo/tests/test_data/simple_project/src/tests/test_erc20.cairo +++ /dev/null @@ -1 +0,0 @@ -use local::contracts::ERC20; \ No newline at end of file diff --git a/crates/voyager-resolver-cairo/tests/test_data/simple_super_import/.gitignore b/crates/voyager-resolver-cairo/tests/test_data/simple_super_import/.gitignore deleted file mode 100644 index 7a1f954..0000000 --- a/crates/voyager-resolver-cairo/tests/test_data/simple_super_import/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -target -voyager-verify diff --git a/crates/voyager-resolver-cairo/tests/test_data/simple_super_import/Scarb.lock b/crates/voyager-resolver-cairo/tests/test_data/simple_super_import/Scarb.lock deleted file mode 100644 index 786f339..0000000 --- a/crates/voyager-resolver-cairo/tests/test_data/simple_super_import/Scarb.lock +++ /dev/null @@ -1,6 +0,0 @@ -# Code generated by scarb DO NOT EDIT. -version = 1 - -[[package]] -name = "simple_super_import" -version = "0.1.0" diff --git a/crates/voyager-resolver-cairo/tests/test_data/simple_super_import/Scarb.toml b/crates/voyager-resolver-cairo/tests/test_data/simple_super_import/Scarb.toml deleted file mode 100644 index a45cf33..0000000 --- a/crates/voyager-resolver-cairo/tests/test_data/simple_super_import/Scarb.toml +++ /dev/null @@ -1,25 +0,0 @@ -[package] -name = "simple_super_import" -version = "0.1.0" - -# See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest - -[dependencies] -starknet = ">=2.0.0" - -[[target.starknet-contract]] -# Enable Sierra codegen. -sierra = true - -# Enable CASM codegen. -casm = false -# Emit Python-powered hints in order to run compiled CASM class with legacy Cairo VM. -casm-add-pythonic-hints = false - -# Enable allowed libfuncs validation. -allowed-libfuncs = true -# Raise errors instead of warnings if disallowed libfuncs are found. -allowed-libfuncs-deny = false - -[tool.voyager] -Simple = { path = "simple.cairo", address = "0x12345" } \ No newline at end of file diff --git a/crates/voyager-resolver-cairo/tests/test_data/simple_super_import/src/contracts.cairo b/crates/voyager-resolver-cairo/tests/test_data/simple_super_import/src/contracts.cairo deleted file mode 100644 index 272a717..0000000 --- a/crates/voyager-resolver-cairo/tests/test_data/simple_super_import/src/contracts.cairo +++ /dev/null @@ -1,3 +0,0 @@ -mod constants { - const VALUE: felt252 = 100; -} \ No newline at end of file diff --git a/crates/voyager-resolver-cairo/tests/test_data/simple_super_import/src/lib.cairo b/crates/voyager-resolver-cairo/tests/test_data/simple_super_import/src/lib.cairo deleted file mode 100644 index 28def18..0000000 --- a/crates/voyager-resolver-cairo/tests/test_data/simple_super_import/src/lib.cairo +++ /dev/null @@ -1,2 +0,0 @@ -mod simple; -mod contracts; \ No newline at end of file diff --git a/crates/voyager-resolver-cairo/tests/test_data/simple_super_import/src/simple.cairo b/crates/voyager-resolver-cairo/tests/test_data/simple_super_import/src/simple.cairo deleted file mode 100644 index 2a654f9..0000000 --- a/crates/voyager-resolver-cairo/tests/test_data/simple_super_import/src/simple.cairo +++ /dev/null @@ -1,21 +0,0 @@ -mod a { - const A: felt252 = 42; -} - -#[starknet::contract] -mod contract { - use super::a; - use super::super::contracts::constants; - - #[storage] - struct Storage {} - - #[generate_trait] - impl InternalImpl of InternalTrait { - fn _value( - self: @ContractState, - ) -> felt252 { - return constants::VALUE + a::A; - } - } -} \ No newline at end of file diff --git a/example.env b/example.env deleted file mode 100644 index 2163298..0000000 --- a/example.env +++ /dev/null @@ -1,2 +0,0 @@ -DEBUG_NETWORK=false -USE_POLLING_MAX_RETRIES=false \ No newline at end of file diff --git a/examples/cairo_2_4_3/.gitignore b/examples/cairo_2_4_3/.gitignore deleted file mode 100644 index 7a1f954..0000000 --- a/examples/cairo_2_4_3/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -target -voyager-verify diff --git a/examples/cairo_2_4_3/Scarb.lock b/examples/cairo_2_4_3/Scarb.lock deleted file mode 100644 index 30d4c57..0000000 --- a/examples/cairo_2_4_3/Scarb.lock +++ /dev/null @@ -1,6 +0,0 @@ -# Code generated by scarb DO NOT EDIT. -version = 1 - -[[package]] -name = "cairo_2_4_3" -version = "0.1.0" diff --git a/crates/voyager-resolver-cairo/tests/test_data/import_external_deps_with_workspace/.gitignore b/examples/cairo_2_6_4/.gitignore similarity index 100% rename from crates/voyager-resolver-cairo/tests/test_data/import_external_deps_with_workspace/.gitignore rename to examples/cairo_2_6_4/.gitignore diff --git a/crates/voyager-resolver-cairo/tests/test_data/dependency/Scarb.lock b/examples/cairo_2_6_4/Scarb.lock similarity index 79% rename from crates/voyager-resolver-cairo/tests/test_data/dependency/Scarb.lock rename to examples/cairo_2_6_4/Scarb.lock index 8078956..2464703 100644 --- a/crates/voyager-resolver-cairo/tests/test_data/dependency/Scarb.lock +++ b/examples/cairo_2_6_4/Scarb.lock @@ -2,5 +2,5 @@ version = 1 [[package]] -name = "dependency" +name = "cairo_2_6_3" version = "0.1.0" diff --git a/examples/cairo_2_4_3/Scarb.toml b/examples/cairo_2_6_4/Scarb.toml similarity index 93% rename from examples/cairo_2_4_3/Scarb.toml rename to examples/cairo_2_6_4/Scarb.toml index 9be8da0..23a1915 100644 --- a/examples/cairo_2_4_3/Scarb.toml +++ b/examples/cairo_2_6_4/Scarb.toml @@ -1,11 +1,11 @@ [package] -name = "cairo_2_4_3" +name = "cairo_2_6_3" version = "0.1.0" # See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest [dependencies] -starknet = ">=2.2.0" +starknet = ">=2.6.3" [[target.starknet-contract]] # Enable Sierra codegen. diff --git a/examples/cairo_2_4_3/src/erc_20.cairo b/examples/cairo_2_6_4/src/erc_20.cairo similarity index 100% rename from examples/cairo_2_4_3/src/erc_20.cairo rename to examples/cairo_2_6_4/src/erc_20.cairo diff --git a/examples/cairo_2_4_3/src/lib.cairo b/examples/cairo_2_6_4/src/lib.cairo similarity index 100% rename from examples/cairo_2_4_3/src/lib.cairo rename to examples/cairo_2_6_4/src/lib.cairo diff --git a/examples/cairo_ds/Scarb.toml b/examples/cairo_ds/Scarb.toml index f6dc049..e737085 100644 --- a/examples/cairo_ds/Scarb.toml +++ b/examples/cairo_ds/Scarb.toml @@ -5,7 +5,7 @@ version = "0.1.0" # See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest [dependencies] -starknet = ">=2.6.3" +starknet = "=2.6.4" dependency = { path = "../dependency" } [[target.starknet-contract]] diff --git a/release-plz.toml b/release-plz.toml deleted file mode 100644 index 903bbcf..0000000 --- a/release-plz.toml +++ /dev/null @@ -1,27 +0,0 @@ -[workspace] -# path of the git-cliff configuration -changelog_config = "cliff.toml" - -# enable changelog updates -changelog_update = true - -# update dependencies with `cargo update` -dependencies_update = true - -# create tags for the releases -git_tag_enable = true - -# disable GitHub releases -git_release_enable = false - -# labels for the release PR -pr_labels = ["release"] - -# disallow updating repositories with uncommitted changes -allow_dirty = false - -# disallow packaging with uncommitted changes -publish_allow_dirty = false - -# disable running `cargo-semver-checks` -semver_check = false \ No newline at end of file diff --git a/rust-toolchain b/rust-toolchain index 31578d3..1a4239a 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,2 +1,2 @@ [toolchain] -channel = "stable" \ No newline at end of file +channel = "1.76.0" \ No newline at end of file diff --git a/src/api.rs b/src/api.rs new file mode 100644 index 0000000..72a0d8e --- /dev/null +++ b/src/api.rs @@ -0,0 +1,334 @@ +use std::{fmt::Display, fs, path::PathBuf, time::Duration}; + +use backon::{BlockingRetryable, ExponentialBuilder}; +use reqwest::{ + blocking::{self, multipart, Client}, + StatusCode, +}; +use semver; +use thiserror::Error; +use url::Url; + +use crate::{ + class_hash::ClassHash, + errors::{self, RequestFailure}, +}; + +#[derive(Debug, serde::Deserialize)] +pub enum VerifyJobStatus { + Submitted, + Compiled, + CompileFailed, + Fail, + Success, +} + +#[derive(Debug, Error)] +pub enum VerificationError { + #[error("Compilation failed: {0}")] + CompilationFailure(String), + + #[error("Compilation failed: {0}")] + VerificationFailure(String), +} + +// TODO: Option blindness? +type JobStatus = Option; + +impl From for VerifyJobStatus { + fn from(value: u8) -> Self { + match value { + 0 => Self::Submitted, + 1 => Self::Compiled, + 2 => Self::CompileFailed, + 3 => Self::Fail, + 4 => Self::Success, + _ => panic!("Unknown status: {}", value), + } + } +} + +impl Display for VerifyJobStatus { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + VerifyJobStatus::Submitted => write!(f, "Submitted"), + VerifyJobStatus::Compiled => write!(f, "Compiled"), + VerifyJobStatus::CompileFailed => write!(f, "CompileFailed"), + VerifyJobStatus::Fail => write!(f, "Fail"), + VerifyJobStatus::Success => write!(f, "Success"), + } + } +} + +#[derive(Clone)] +pub struct ApiClient { + base: Url, + client: Client, +} + +#[derive(Error, Debug)] +pub enum ApiClientError { + #[error("{0} cannot be base, provide valid URL")] + CannotBeBase(Url), + + #[error(transparent)] + Reqwest(#[from] reqwest::Error), + + #[error("Verification job is still in progress")] + InProgress, + + #[error(transparent)] + Failure(#[from] errors::RequestFailure), + + #[error("Job {0} not found")] + JobNotFound(String), + + #[error(transparent)] + Verify(#[from] VerificationError), + + #[error(transparent)] + IoError(#[from] std::io::Error), +} + +/** + * Currently only GetJobStatus and VerifyClass are public available apis. + * In the future, the get class api should be moved to using public apis too. + * TODO: Change get class api to use public apis. + */ +// TODO: Perhaps make a client and make this execute calls +impl ApiClient { + pub fn new(base: Url) -> Result { + // Test here so that we are sure path_segments_mut succeeds + if base.cannot_be_a_base() { + Err(ApiClientError::CannotBeBase(base)) + } else { + Ok(Self { + base, + client: blocking::Client::new(), + }) + } + } + + pub fn get_class_url(&self, class_hash: &ClassHash) -> Url { + let mut url = self.base.clone(); + url.path_segments_mut() + .expect("") + .extend(&["api", "class", class_hash.as_ref()]); + url + } + + pub fn get_class(&self, class_hash: &ClassHash) -> Result { + let url = self.get_class_url(&class_hash); + let result = self + .client + .get(url.clone()) + .send() + .map_err(ApiClientError::from)?; + + match result.status() { + StatusCode::OK => Ok(true), + StatusCode::NOT_FOUND => Ok(false), + _ => Err(ApiClientError::from(RequestFailure::new( + url, + result.status(), + result.text()?, + ))), + } + } + + pub fn verify_class_url(&self, class_hash: ClassHash) -> Url { + let mut url = self.base.clone(); + url.path_segments_mut() + .expect("") + .extend(&["class-verify", class_hash.as_ref()]); + url + } + + pub fn verify_class( + &self, + class_hash: ClassHash, + license: &str, + name: &str, + project_metadata: ProjectMetadataInfo, + files: Vec, + ) -> Result { + let mut body = multipart::Form::new() + .percent_encode_noop() + .text( + "compiler_version", + project_metadata.cairo_version.to_string(), + ) + .text("scarb_version", project_metadata.scarb_version.to_string()) + .text("license", license.to_string()) + .text("name", name.to_string()) + .text("contract_file", project_metadata.contract_file) + .text("project_dir_path", project_metadata.project_dir_path); + + for file in files.iter() { + let file_content = fs::read_to_string(file.path.as_path())?; + body = body.text(format!("files__{}", file.name.clone()), file_content); + } + + let url = self.verify_class_url(class_hash); + + let response = self + .client + .post(url.clone()) + .multipart(body) + // shouldn't `?` be enough? + .send() + .map_err(ApiClientError::Reqwest)?; + + match response.status() { + StatusCode::OK => (), + StatusCode::BAD_REQUEST => { + return Err(ApiClientError::from(RequestFailure::new( + url, + StatusCode::BAD_REQUEST, + response.json::()?.error, + ))); + } + status_code => { + return Err(ApiClientError::from(RequestFailure::new( + url, + status_code, + response.text()?, + ))); + } + } + + Ok(response.json::()?.job_id) + } + + pub fn get_job_status_url(&self, job_id: impl AsRef) -> Url { + let mut url = self.base.clone(); + url.path_segments_mut() + .expect("") + .extend(&["class-verify", "job", job_id.as_ref()]); + url + } + + pub fn get_job_status( + &self, + job_id: impl Into + Clone, + ) -> Result { + let url = self.get_job_status_url(job_id.clone().into()); + let response = self.client.get(url.clone()).send()?; + + match response.status() { + StatusCode::OK => (), + StatusCode::NOT_FOUND => return Err(ApiClientError::JobNotFound(job_id.into())), + status_code => { + return Err(ApiClientError::from(RequestFailure::new( + url, + status_code, + response.text()?, + ))); + } + } + + let data = response.json::()?; + match VerifyJobStatus::from(data.status) { + VerifyJobStatus::Success => return Ok(Some(data)), + VerifyJobStatus::Fail => { + return Err(ApiClientError::from( + VerificationError::VerificationFailure( + data.status_description + .unwrap_or("unknown failure".to_owned()), + ), + )) + } + VerifyJobStatus::CompileFailed => { + return Err(ApiClientError::from(VerificationError::CompilationFailure( + data.status_description + .unwrap_or("unknown failure".to_owned()), + ))) + } + _ => Ok(None), + } + } +} + +#[derive(Debug, serde::Deserialize)] +pub struct ApiError { + error: String, +} + +#[derive(Debug, serde::Deserialize)] +pub struct VerificationJobDispatch { + job_id: String, +} + +#[allow(dead_code)] +#[derive(Debug, serde::Deserialize)] +pub struct VerificationJob { + job_id: String, + status: u8, + status_description: Option, + class_hash: String, + created_timestamp: Option, + updated_timestamp: Option, + address: Option, + contract_file: Option, + name: Option, + version: Option, + license: Option, +} + +#[derive(Debug, Eq, PartialEq)] +pub struct FileInfo { + pub name: String, + pub path: PathBuf, +} + +#[derive(Debug, Clone)] +pub struct ProjectMetadataInfo { + pub cairo_version: semver::Version, + pub scarb_version: semver::Version, + pub project_dir_path: String, + pub contract_file: String, +} + +pub enum Status { + InProgress, + Finished(ApiClientError), +} + +fn is_is_progress(status: &Status) -> bool { + match status { + Status::InProgress => true, + Status::Finished(_) => false, + } +} + +pub fn poll_verification_status( + api: ApiClient, + job_id: &str, +) -> Result { + let fetch = || -> Result { + let result: Option = api + .get_job_status(job_id.to_owned()) + .map_err(Status::Finished)?; + + result.ok_or(Status::InProgress) + }; + + // So verbose because it has problems with inference + fetch + .retry( + ExponentialBuilder::default() + .with_max_times(0) + .with_min_delay(Duration::from_secs(2)) + .with_max_delay(Duration::from_secs(300)) // 5 mins + .with_max_times(20), + ) + .when(is_is_progress) + .notify(|_, dur: Duration| { + println!("Job: {} didn't finish, retrying in {:?}", job_id, dur); + }) + .call() + .map_err(|err| match err { + Status::InProgress => ApiClientError::InProgress, + Status::Finished(e) => e, + }) +} diff --git a/src/args.rs b/src/args.rs new file mode 100644 index 0000000..5f78a4e --- /dev/null +++ b/src/args.rs @@ -0,0 +1,327 @@ +use camino::Utf8PathBuf; +use clap; +use reqwest::Url; +use scarb_metadata::{Metadata, MetadataCommand, MetadataCommandError}; +use spdx::LicenseId; +use std::{env, io, path::PathBuf, string::ToString}; +use thiserror::Error; + +use verifier::class_hash::ClassHash; + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct Project(Metadata); + +#[derive(Error, Debug)] +pub enum ProjectError { + #[error("{0} doesn't contain Scarb project manifest")] + MissingManifest(Utf8PathBuf), + + #[error("scarb metadata command failed")] + MetadataError(#[from] MetadataCommandError), + + #[error("IO error")] + Io(#[from] io::Error), + + #[error("UTF-8 error")] + Utf8(#[from] camino::FromPathBufError), +} + +#[allow(dead_code)] +impl Project { + pub fn new(manifest: Utf8PathBuf) -> Result { + manifest.try_exists().map_err(|err| match err.kind() { + io::ErrorKind::NotFound => ProjectError::MissingManifest(manifest.clone()), + _ => ProjectError::from(err), + })?; + + let root = manifest.parent().ok_or(ProjectError::Io(io::Error::new( + io::ErrorKind::NotFound, + "Couldn't get parent directory of Scarb manifest file", + )))?; + + let metadata = MetadataCommand::new() + .json() + .manifest_path(&manifest) + .current_dir(root) + .exec()?; + + Ok(Project(metadata)) + } + + pub fn manifest_path(&self) -> &Utf8PathBuf { + &self.0.workspace.manifest_path + } + + pub fn root_dir(&self) -> &Utf8PathBuf { + &self.0.workspace.root + } + + pub fn metadata(&self) -> &Metadata { + &self.0 + } +} + +impl ToString for Project { + fn to_string(&self) -> String { + self.manifest_path().to_string() + } +} + +pub fn project_value_parser(raw: &str) -> Result { + let path = PathBuf::from(raw); + + let absolute = if path.is_absolute() { + path + } else { + let mut cwd = env::current_dir()?; + cwd.push(path); + cwd + }; + + let utf8 = Utf8PathBuf::try_from(absolute)?; + + let manifest = if utf8.is_file() { + utf8 + } else { + utf8.join("Scarb.toml") + }; + + Project::new(manifest) +} + +#[derive(clap::Parser)] +#[command(name = "Starknet Contract Verifier")] +#[command(author = "Nethermind")] +#[command(version = "0.1.0")] +#[command(about = "Verify Starknet classes on Voyager block explorer")] +#[command(long_about = "")] +pub struct Args { + #[command(subcommand)] + pub command: Commands, + + /// Network to verify on + #[arg(long, value_enum)] + pub network: NetworkKind, + + #[command(flatten)] + pub network_url: Network, +} + +#[derive(clap::Subcommand)] +pub enum Commands { + /// Submit smart contract for verification. + /// + /// By default it will only report back to user what it is about + /// to do. In order to actually execute pass --exectue flag. + Submit(SubmitArgs), + + /// Check verification job status + Status { + /// Verification job id + #[arg(long, value_name = "UUID")] + job: String, + }, +} + +fn license_value_parser(license: &str) -> Result { + let id = spdx::license_id(license); + id.ok_or({ + let guess = spdx::imprecise_license_id(license) + .map_or(String::new(), |(lic, _): (LicenseId, usize)| { + format!(", do you mean: {}?", lic.name) + }); + format!("Unrecognized license: {license}{guess}") + }) +} + +#[derive(clap::Args)] +pub struct SubmitArgs { + /// Submit contract for verification. + #[arg(short = 'x', long, default_value_t = false)] + pub execute: bool, + + /// Path to Scarb project + #[arg( + long, + value_name = "DIR", + value_hint = clap::ValueHint::DirPath, + value_parser = project_value_parser, + default_value = env::current_dir().unwrap().into_os_string() + )] + pub path: Project, + + /// Class HASH to verify + #[arg( + long, + value_name = "HASH", + value_parser = ClassHash::new + )] + pub hash: ClassHash, + + /// Desired class NAME + #[arg(long, value_name = "NAME")] + pub name: String, + + /// Wait indefinitely for verification result + #[arg(long, default_value_t = false)] + pub watch: bool, + + /// SPDX license identifier + #[arg( + long, + value_name = "SPDX", + value_parser = license_value_parser, + )] + pub license: Option, + + /// Select contract for submission + #[arg(long, value_name = "NAME")] + pub contract: Option, +} + +#[derive(clap::ValueEnum, Clone)] +pub enum NetworkKind { + /// Target the Mainnet + Mainnet, + + /// Target Sepolia testnet + Sepolia, + + /// Target custom network + Custom, +} + +#[derive(Clone)] +pub struct Network { + /// Custom public API adress + pub public: Url, + + /// Custom interval API address + pub private: Url, +} + +impl clap::FromArgMatches for Network { + fn from_arg_matches(matches: &clap::ArgMatches) -> Result { + Ok(Self { + public: matches + // this cast is possible because we set value_parser + .get_one::("public") + // This should never panic because of the default_value + // and required_if_eq used in the clap::Args + // implementation for Network + .expect("Custom network API public Url is missig!") + .to_owned(), + private: matches + // this cast is possible because we set value_parser + .get_one::("private") + // This should never panic because of the default_value + // and required_if_eq used in the clap::Args + // implementation for Network + .expect("Custom network API private Url is missig!") + .to_owned(), + }) + } + + fn from_arg_matches_mut(matches: &mut clap::ArgMatches) -> Result { + Self::from_arg_matches(matches) + } + + fn update_from_arg_matches(&mut self, matches: &clap::ArgMatches) -> Result<(), clap::Error> { + let mut matches = matches.clone(); + self.update_from_arg_matches_mut(&mut matches) + } + + fn update_from_arg_matches_mut( + &mut self, + matches: &mut clap::ArgMatches, + ) -> Result<(), clap::Error> { + self.public = matches + // this cast is possible because we set value_parser + .get_one::("private") + // This should never panic because of the default_value + // and required_if_eq used in the clap::Args + // implementation for Network + .expect("Custom network API private URL is missig!") + .to_owned(); + self.private = matches + // this cast is possible because we set value_parser + .get_one::("private") + // This should never panic because of the default_value + // and required_if_eq used in the clap::Args + // implementation for Network + .expect("Custom network API private URL is missig!") + .to_owned(); + Ok(()) + } +} + +// Can't derive the default value logic, hence hand rolled instance +impl clap::Args for Network { + fn augment_args(cmd: clap::Command) -> clap::Command { + cmd.arg( + clap::Arg::new("public") + .long("public") + .help("Custom public API address") + .value_hint(clap::ValueHint::Url) + .value_parser(Url::parse) + .default_value_ifs([ + ("network", "mainnet", "https://api.voyager.online/beta"), + ( + "network", + "sepolia", + "https://sepolia-api.voyager.online/beta", + ), + ]) + .required_if_eq("network", "custom"), + // this would overwrite the defaults in _all_ the cases + // .env("CUSTOM_PUBLIC_API_ENDPOINT_URL"), + ) + .arg( + clap::Arg::new("private") + .long("private") + .help("Custom interval API address") + .value_hint(clap::ValueHint::Url) + .value_parser(Url::parse) + .default_value_ifs([ + ("network", "mainnet", "https://voyager.online"), + ("network", "sepolia", "https://sepolia.voyager.online"), + ]) + .required_if_eq("network", "custom"), + // this would overwrite the defaults in _all_ the cases + // .env("CUSTOM_INTERNAL_API_ENDPOINT_URL"), + ) + } + + fn augment_args_for_update(cmd: clap::Command) -> clap::Command { + cmd.arg( + clap::Arg::new("public") + .long("public") + .help("Custom public API address") + .value_hint(clap::ValueHint::Url) + .default_value_ifs([ + ("network", "mainnet", "https://api.voyager.online/beta"), + ( + "network", + "sepolia", + "https://sepolia-api.voyager.online/beta", + ), + ]) + .required_if_eq("network", "custom"), + // this would overwrite the defaults in _all_ the cases + // .env("CUSTOM_PUBLIC_API_ENDPOINT_URL"), + ) + .arg( + clap::Arg::new("private") + .long("private") + .help("Custom interval API address") + .value_hint(clap::ValueHint::Url) + .default_value_ifs([ + ("network", "mainnet", "https://api.voyager.online"), + ("network", "sepolia", "https://sepolia-api.voyager.online"), + ]) + .required_if_eq("network", "custom"), + // this would overwrite the defaults in _all_ the cases + // .env("CUSTOM_INTERNAL_API_ENDPOINT_URL"), + ) + } +} diff --git a/src/class_hash.rs b/src/class_hash.rs new file mode 100644 index 0000000..6080b60 --- /dev/null +++ b/src/class_hash.rs @@ -0,0 +1,76 @@ +use regex::Regex; +use std::fmt; +use thiserror::Error; + +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] +pub struct ClassHash(String); + +#[derive(Error, Debug, Clone, PartialEq)] +pub enum ClassHashError { + #[error("{0} is not valid class hash")] + Match(String), + #[error("Class hash regex error")] + Regex(#[from] regex::Error), +} + +impl ClassHash { + const NORMALIZED_LENGTH: usize = 66; + const PATTERN: &str = r"^0x[a-fA-F0-9]+$"; + + pub fn new(raw: &str) -> Result { + let re = Regex::new(Self::PATTERN)?; + + if raw.len() <= Self::NORMALIZED_LENGTH && re.is_match(raw) { + Ok(Self(raw.into())) + } else { + Err(ClassHashError::Match(raw.to_string())) + } + } +} + +impl fmt::Display for ClassHash { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", self.0) + } +} + +impl AsRef for ClassHash { + fn as_ref(&self) -> &str { + &self.0.as_str() + } +} + +impl AsRef for ClassHash { + fn as_ref(&self) -> &String { + &self.0 + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_valid_class_hash_normalized() { + let valid_hash = "0x044dc2b3239382230d8b1e943df23b96f52eebcac93efe6e8bde92f9a2f1da18"; + assert!(ClassHash::new(valid_hash).is_ok()); + } + + #[test] + fn test_valid_class_hash_without_leading_zeros() { + let valid_hash = "0x44dc2b3239382230d8b1e943df23b96f52eebcac93efe6e8bde92f9a2f1da18"; + assert!(ClassHash::new(valid_hash).is_ok()); + } + + #[test] + fn test_invalid_class_hash_pattern() { + let invalid_hash = "0xGHIJKLMNOPQRSTUVWXYZ"; + assert!(ClassHash::new(invalid_hash).is_err()); + } + + #[test] + fn test_invalid_class_hash_no_prefix() { + let invalid_hash = "1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef"; + assert!(ClassHash::new(invalid_hash).is_err()); + } +} diff --git a/src/errors.rs b/src/errors.rs new file mode 100644 index 0000000..6d220c2 --- /dev/null +++ b/src/errors.rs @@ -0,0 +1,87 @@ +use reqwest::StatusCode; +use scarb_metadata::{Metadata, PackageId}; +use std::fmt::{self, Formatter}; +use thiserror::Error; +use url::Url; + +#[derive(Debug, Error)] +pub struct MissingPackage { + pub package_id: PackageId, + pub available: Vec, +} + +impl MissingPackage { + pub fn new(package_id: &PackageId, metadata: &Metadata) -> Self { + Self { + package_id: package_id.clone(), + available: metadata.workspace.members.clone(), + } + } +} + +impl fmt::Display for MissingPackage { + fn fmt(&self, formatter: &mut Formatter) -> fmt::Result { + write!( + formatter, + "Couldn't find package: {}, workspace have those packages available:\n", + self.package_id + )?; + + for package in &self.available { + writeln!(formatter, "{}", package)?; + } + + Ok(()) + } +} + +#[derive(Debug, Error)] +pub struct RequestFailure { + pub url: Url, + pub status: StatusCode, + pub msg: String, +} + +impl RequestFailure { + pub fn new(url: Url, status: StatusCode, msg: impl Into) -> Self { + Self { + url, + status, + msg: msg.into(), + } + } +} + +impl fmt::Display for RequestFailure { + fn fmt(&self, formatter: &mut Formatter) -> fmt::Result { + write!( + formatter, + "{:?}\n returned {}, with:\n{}", + self.url, self.status, self.msg + ) + } +} + +// TODO: Display suggestions +#[derive(Debug, Error)] +pub struct MissingContract { + pub name: String, + pub available: Vec, +} + +impl MissingContract { + pub fn new(name: String, available: Vec) -> Self { + Self { name, available } + } +} + +impl fmt::Display for MissingContract { + fn fmt(&self, formatter: &mut Formatter) -> fmt::Result { + let contracts = self.available.join(", "); + write!( + formatter, + "Contract: {} is not defined in the manifest file. Did you mean one of: {}?", + self.name, contracts + ) + } +} diff --git a/src/fmt.rs b/src/fmt.rs new file mode 100644 index 0000000..9e3504d --- /dev/null +++ b/src/fmt.rs @@ -0,0 +1,9 @@ +pub fn fmt() -> () { + let a = [FileInfo { + name: "contracts/src/utils.cairo", + path: "/home/nat/work/nethermind/cairo/starknet-contract-verifier/examples/starknet-staking/workspace/apps/staking/contracts/src/utils.cairo" + }, FileInfo { + name: "contracts/src/errors.cairo", path: "/home/nat/work/nethermind/cairo/starknet-contract-verifier/examples/starknet-staking/workspace/apps/staking/contracts/src/errors.cairo" + }, FileInfo { name: "contracts/src/staking/staking_tester.cairo", path: "/home/nat/work/nethermind/cairo/starknet-contract-verifier/examples/starknet-staking/workspace/apps/staking/contracts/src/staking/staking_tester.cairo" }, FileInfo { name: "contracts/src/staking/test.cairo", path: "/home/nat/work/nethermind/cairo/starknet-contract-verifier/examples/starknet-staking/workspace/apps/staking/contracts/src/staking/test.cairo" }, FileInfo { name: "contracts/src/staking/pause_test.cairo", path: "/home/nat/work/nethermind/cairo/starknet-contract-verifier/examples/starknet-staking/workspace/apps/staking/contracts/src/staking/pause_test.cairo" }, FileInfo { name: "contracts/src/staking/align_upg_vars_eic.cairo", path: "/home/nat/work/nethermind/cairo/starknet-contract-verifier/examples/starknet-staking/workspace/apps/staking/contracts/src/staking/align_upg_vars_eic.cairo" }, FileInfo { name: "contracts/src/staking/staking.cairo", path: "/home/nat/work/nethermind/cairo/starknet-contract-verifier/examples/starknet-staking/workspace/apps/staking/contracts/src/staking/staking.cairo" }, FileInfo { name: "contracts/src/staking/interface.cairo", path: "/home/nat/work/nethermind/cairo/starknet-contract-verifier/examples/starknet-staking/workspace/apps/staking/contracts/src/staking/interface.cairo" }, FileInfo { name: "contracts/src/staking/objects.cairo", path: "/home/nat/work/nethermind/cairo/starknet-contract-verifier/examples/starknet-staking/workspace/apps/staking/contracts/src/staking/objects.cairo" }, FileInfo { name: "contracts/src/staking.cairo", path: "/home/nat/work/nethermind/cairo/starknet-contract-verifier/examples/starknet-staking/workspace/apps/staking/contracts/src/staking.cairo" }, FileInfo { name: "contracts/src/reward_supplier/test.cairo", path: "/home/nat/work/nethermind/cairo/starknet-contract-verifier/examples/starknet-staking/workspace/apps/staking/contracts/src/reward_supplier/test.cairo" }, FileInfo { name: "contracts/src/reward_supplier/reward_supplier.cairo", path: "/home/nat/work/nethermind/cairo/starknet-contract-verifier/examples/starknet-staking/workspace/apps/staking/contracts/src/reward_supplier/reward_supplier.cairo" }, FileInfo { name: "contracts/src/reward_supplier/interface.cairo", path: "/home/nat/work/nethermind/cairo/starknet-contract-verifier/examples/starknet-staking/workspace/apps/staking/contracts/src/reward_supplier/interface.cairo" }, FileInfo { name: "contracts/src/event_test_utils.cairo", path: "/home/nat/work/nethermind/cairo/starknet-contract-verifier/examples/starknet-staking/workspace/apps/staking/contracts/src/event_test_utils.cairo" }, FileInfo { name: "contracts/src/constants.cairo", path: "/home/nat/work/nethermind/cairo/starknet-contract-verifier/examples/starknet-staking/workspace/apps/staking/contracts/src/constants.cairo" }, FileInfo { name: "contracts/src/minting_curve/test.cairo", path: "/home/nat/work/nethermind/cairo/starknet-contract-verifier/examples/starknet-staking/workspace/apps/staking/contracts/src/minting_curve/test.cairo" }, FileInfo { name: "contracts/src/minting_curve/minting_curve.cairo", path: "/home/nat/work/nethermind/cairo/starknet-contract-verifier/examples/starknet-staking/workspace/apps/staking/contracts/src/minting_curve/minting_curve.cairo" }, FileInfo { name: "contracts/src/minting_curve/interface.cairo", path: "/home/nat/work/nethermind/cairo/starknet-contract-verifier/examples/starknet-staking/workspace/apps/staking/contracts/src/minting_curve/interface.cairo" }, FileInfo { name: "contracts/src/types.cairo", path: "/home/nat/work/nethermind/cairo/starknet-contract-verifier/examples/starknet-staking/workspace/apps/staking/contracts/src/types.cairo" }, FileInfo { name: "contracts/src/minting_curve.cairo", path: "/home/nat/work/nethermind/cairo/starknet-contract-verifier/examples/starknet-staking/workspace/apps/staking/contracts/src/minting_curve.cairo" }, FileInfo { name: "contracts/src/pool.cairo", path: "/home/nat/work/nethermind/cairo/starknet-contract-verifier/examples/starknet-staking/workspace/apps/staking/contracts/src/pool.cairo" }, FileInfo { name: "contracts/src/lib.cairo", path: "/home/nat/work/nethermind/cairo/starknet-contract-verifier/examples/starknet-staking/workspace/apps/staking/contracts/src/lib.cairo" }, FileInfo { name: "contracts/src/flow_test.cairo", path: "/home/nat/work/nethermind/cairo/starknet-contract-verifier/examples/starknet-staking/workspace/apps/staking/contracts/src/flow_test.cairo" }, FileInfo { name: "contracts/src/reward_supplier.cairo", path: "/home/nat/work/nethermind/cairo/starknet-contract-verifier/examples/starknet-staking/workspace/apps/staking/contracts/src/reward_supplier.cairo" }, FileInfo { name: "contracts/src/flow_test/test.cairo", path: "/home/nat/work/nethermind/cairo/starknet-contract-verifier/examples/starknet-staking/workspace/apps/staking/contracts/src/flow_test/test.cairo" }, FileInfo { name: "contracts/src/flow_test/utils.cairo", path: "/home/nat/work/nethermind/cairo/starknet-contract-verifier/examples/starknet-staking/workspace/apps/staking/contracts/src/flow_test/utils.cairo" }, FileInfo { name: "contracts/src/test_utils.cairo", path: "/home/nat/work/nethermind/cairo/starknet-contract-verifier/examples/starknet-staking/workspace/apps/staking/contracts/src/test_utils.cairo" }, FileInfo { name: "contracts/src/pool/interface.cairo", path: "/home/nat/work/nethermind/cairo/starknet-contract-verifier/examples/starknet-staking/workspace/apps/staking/contracts/src/pool/interface.cairo" }, FileInfo { name: "contracts/src/pool/test.cairo", path: "/home/nat/work/nethermind/cairo/starknet-contract-verifier/examples/starknet-staking/workspace/apps/staking/contracts/src/pool/test.cairo" }, FileInfo { name: "contracts/src/pool/pool.cairo", path: "/home/nat/work/nethermind/cairo/starknet-contract-verifier/examples/starknet-staking/workspace/apps/staking/contracts/src/pool/pool.cairo" }, FileInfo { name: "contracts/src/constants.cairo", path: "/home/nat/work/nethermind/cairo/starknet-contract-verifier/examples/starknet-staking/workspace/packages/contracts/src/constants.cairo" }, FileInfo { name: "contracts/src/components.cairo", path: "/home/nat/work/nethermind/cairo/starknet-contract-verifier/examples/starknet-staking/workspace/packages/contracts/src/components.cairo" }, FileInfo { name: "contracts/src/interfaces.cairo", path: "/home/nat/work/nethermind/cairo/starknet-contract-verifier/examples/starknet-staking/workspace/packages/contracts/src/interfaces.cairo" }, FileInfo { name: "contracts/src/test_utils.cairo", path: "/home/nat/work/nethermind/cairo/starknet-contract-verifier/examples/starknet-staking/workspace/packages/contracts/src/test_utils.cairo" }, FileInfo { name: "contracts/src/lib.cairo", path: "/home/nat/work/nethermind/cairo/starknet-contract-verifier/examples/starknet-staking/workspace/packages/contracts/src/lib.cairo" }, FileInfo { name: "contracts/src/interfaces/identity.cairo", path: "/home/nat/work/nethermind/cairo/starknet-contract-verifier/examples/starknet-staking/workspace/packages/contracts/src/interfaces/identity.cairo" }, FileInfo { name: "contracts/src/errors.cairo", path: "/home/nat/work/nethermind/cairo/starknet-contract-verifier/examples/starknet-staking/workspace/packages/contracts/src/errors.cairo" }, FileInfo { name: "contracts/src/bit_set.cairo", path: "/home/nat/work/nethermind/cairo/starknet-contract-verifier/examples/starknet-staking/workspace/packages/contracts/src/bit_set.cairo" }, FileInfo { name: "contracts/src/components/roles/roles.cairo", path: "/home/nat/work/nethermind/cairo/starknet-contract-verifier/examples/starknet-staking/workspace/packages/contracts/src/components/roles/roles.cairo" }, FileInfo { name: "contracts/src/components/roles/interface.cairo", path: "/home/nat/work/nethermind/cairo/starknet-contract-verifier/examples/starknet-staking/workspace/packages/contracts/src/components/roles/interface.cairo" }, FileInfo { name: "contracts/src/components/pausable/pausable.cairo", path: "/home/nat/work/nethermind/cairo/starknet-contract-verifier/examples/starknet-staking/workspace/packages/contracts/src/components/pausable/pausable.cairo" }, FileInfo { name: "contracts/src/components/pausable/interface.cairo", path: "/home/nat/work/nethermind/cairo/starknet-contract-verifier/examples/starknet-staking/workspace/packages/contracts/src/components/pausable/interface.cairo" }, FileInfo { name: "contracts/src/components/replaceability.cairo", path: "/home/nat/work/nethermind/cairo/starknet-contract-verifier/examples/starknet-staking/workspace/packages/contracts/src/components/replaceability.cairo" }, FileInfo { name: "contracts/src/components/pausable.cairo", path: "/home/nat/work/nethermind/cairo/starknet-contract-verifier/examples/starknet-staking/workspace/packages/contracts/src/components/pausable.cairo" }, FileInfo { name: "contracts/src/components/roles.cairo", path: "/home/nat/work/nethermind/cairo/starknet-contract-verifier/examples/starknet-staking/workspace/packages/contracts/src/components/roles.cairo" }, FileInfo { name: "contracts/src/components/replaceability/interface.cairo", path: "/home/nat/work/nethermind/cairo/starknet-contract-verifier/examples/starknet-staking/workspace/packages/contracts/src/components/replaceability/interface.cairo" }, FileInfo { name: "contracts/src/components/replaceability/test_utils.cairo", path: "/home/nat/work/nethermind/cairo/starknet-contract-verifier/examples/starknet-staking/workspace/packages/contracts/src/components/replaceability/test_utils.cairo" }, FileInfo { name: "contracts/src/components/replaceability/eic_test_contract.cairo", path: "/home/nat/work/nethermind/cairo/starknet-contract-verifier/examples/starknet-staking/workspace/packages/contracts/src/components/replaceability/eic_test_contract.cairo" }, FileInfo { name: "contracts/src/components/replaceability/mock.cairo", path: "/home/nat/work/nethermind/cairo/starknet-contract-verifier/examples/starknet-staking/workspace/packages/contracts/src/components/replaceability/mock.cairo" }, FileInfo { name: "contracts/src/components/replaceability/test.cairo", path: "/home/nat/work/nethermind/cairo/starknet-contract-verifier/examples/starknet-staking/workspace/packages/contracts/src/components/replaceability/test.cairo" }, FileInfo { name: "contracts/src/components/replaceability/replaceability.cairo", path: "/home/nat/work/nethermind/cairo/starknet-contract-verifier/examples/starknet-staking/workspace/packages/contracts/src/components/replaceability/replaceability.cairo" }, FileInfo { name: "contracts/src/types/time.cairo", path: "/home/nat/work/nethermind/cairo/starknet-contract-verifier/examples/starknet-staking/workspace/packages/contracts/src/types/time.cairo" }, FileInfo { name: "contracts/src/types/fixed_two_decimal.cairo", path: "/home/nat/work/nethermind/cairo/starknet-contract-verifier/examples/starknet-staking/workspace/packages/contracts/src/types/fixed_two_decimal.cairo" }, FileInfo { name: "contracts/src/bit_mask.cairo", path: "/home/nat/work/nethermind/cairo/starknet-contract-verifier/examples/starknet-staking/workspace/packages/contracts/src/bit_mask.cairo" }, FileInfo { name: "contracts/src/erc20_mocks.cairo", path: "/home/nat/work/nethermind/cairo/starknet-contract-verifier/examples/starknet-staking/workspace/packages/contracts/src/erc20_mocks.cairo" }, FileInfo { name: "contracts/src/math.cairo", path: "/home/nat/work/nethermind/cairo/starknet-contract-verifier/examples/starknet-staking/workspace/packages/contracts/src/math.cairo" }, FileInfo { name: "contracts/src/types.cairo", path: "/home/nat/work/nethermind/cairo/starknet-contract-verifier/examples/starknet-staking/workspace/packages/contracts/src/types.cairo" }]; + () +} diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..5a75cad --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,5 @@ +pub mod api; +pub mod class_hash; +pub mod errors; +pub mod resolver; +pub mod voyager; diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..fa2877d --- /dev/null +++ b/src/main.rs @@ -0,0 +1,268 @@ +mod args; +use crate::args::{Args, Commands, SubmitArgs}; + +use camino::{Utf8Path, Utf8PathBuf}; +use clap::Parser; +use itertools::Itertools; +use scarb_metadata::PackageMetadata; +use std::collections::HashMap; +use thiserror::Error; +use verifier::{ + api::{ + poll_verification_status, ApiClient, ApiClientError, FileInfo, ProjectMetadataInfo, + VerificationJob, + }, + class_hash::ClassHash, + errors, + resolver::{self, ResolverError}, + voyager::{self, VoyagerError}, +}; + +#[derive(Debug, Error)] +pub enum CliError { + #[error(transparent)] + Api(#[from] ApiClientError), + + #[error(transparent)] + MissingPackage(#[from] errors::MissingPackage), + + #[error("Class hash {0} is not declared")] + NotDeclared(ClassHash), + + #[error("Submit dry run")] + DryRun, + + #[error( + "No contracts selected for verification. Add [tool.voyager] section to Scarb.toml file" + )] + NoTarget, + + #[error("Only single contract verification is supported. Select one with --contract argument")] + MultipleContracts, + + // TODO: Display suggestions + #[error(transparent)] + MissingContract(#[from] errors::MissingContract), + + #[error(transparent)] + Resolver(#[from] ResolverError), + + #[error("Couldn't strip {prefix} from {path}")] + StripPrefix { + path: Utf8PathBuf, + prefix: Utf8PathBuf, + }, + + #[error(transparent)] + Utf8(#[from] camino::FromPathBufError), + + #[error(transparent)] + Voyager(#[from] VoyagerError), +} + +fn main() -> anyhow::Result<()> { + let Args { + command: cmd, + network_url: network, + network: _, + } = Args::parse(); + let public = ApiClient::new(network.public)?; + let private = ApiClient::new(network.private)?; + + match &cmd { + Commands::Submit(args) => { + if args.license.is_none() { + println!("[WARNING] No license provided, defaults to All Rights Reserved") + } + + let job_id = submit(public, private, args)?; + println!("verification job id: {}", job_id); + } + Commands::Status { job } => { + let status = check(public, job)?; + println!("{status:?}") + } + } + Ok(()) +} + +fn submit(public: ApiClient, private: ApiClient, args: &SubmitArgs) -> Result { + let metadata = args.path.metadata(); + + let mut packages: Vec = vec![]; + resolver::gather_packages(metadata, &mut packages)?; + + let mut sources: Vec = vec![]; + for package in &packages { + let mut package_sources = resolver::package_sources(package)?; + sources.append(&mut package_sources); + } + + let prefix = resolver::biggest_common_prefix(&sources, args.path.root_dir()); + let manifest_path = voyager::manifest_path(metadata); + let manifest = manifest_path + .strip_prefix(&prefix) + .map_err(|_| CliError::StripPrefix { + path: manifest_path.clone(), + prefix: prefix.clone(), + })?; + + let mut files: HashMap = sources + .iter() + .map(|p| -> Result<(String, Utf8PathBuf), CliError> { + let name = p.strip_prefix(&prefix).map_err(|_| CliError::StripPrefix { + path: p.clone(), + prefix: prefix.clone(), + })?; + Ok((name.to_string(), p.clone())) + }) + .try_collect()?; + files.insert( + manifest.to_string(), + voyager::manifest_path(metadata).clone(), + ); + + let tool_sections = voyager::tool_section(metadata)?; + + let contract_names: Vec = tool_sections + .iter() + .flat_map(|(_id, v)| v.iter().map(|(name, _attrs)| name.clone()).collect_vec()) + .collect_vec(); + + if let Some(to_submit) = args.contract.to_owned() { + if !contract_names.contains(&to_submit) { + return Err(CliError::from(errors::MissingContract::new( + to_submit, + contract_names, + ))); + } + } else if contract_names.len() != 1 { + return Err(CliError::MultipleContracts); + } + + let cairo_version = metadata.app_version_info.cairo.version.clone(); + let scarb_version = metadata.app_version_info.version.clone(); + + for (package_id, tools) in &tool_sections { + for (contract_name, voyager) in tools { + // We should probably remove this and submit everything + if let Some(to_submit) = args.contract.to_owned() { + if &to_submit != contract_name { + continue; + } + } + + let package_meta = metadata.get_package(package_id).ok_or(CliError::from( + errors::MissingPackage::new(package_id, metadata), + ))?; + let project_dir_path = args + .path + .root_dir() + .strip_prefix(&prefix) + .map_err(|_| CliError::StripPrefix { + path: args.path.root_dir().clone(), + prefix: prefix.clone(), + }) + // backend expects this for cwd + .map(|p| { + if p == Utf8Path::new("") { + Utf8Path::new(".") + } else { + p + } + })?; + + let contract_dir = Utf8PathBuf::try_from(package_meta.root.join_os(&voyager.path))?; + let contract_file = + contract_dir + .strip_prefix(prefix.clone()) + .map_err(|_| CliError::StripPrefix { + path: contract_dir.clone(), + prefix, + })?; + let project_meta = ProjectMetadataInfo { + cairo_version: cairo_version.clone(), + scarb_version: scarb_version.clone(), + contract_file: contract_file.to_string(), + project_dir_path: project_dir_path.to_string(), + }; + + // TODO: switch backend to use SPDX identifiers + let license: String = match args.license { + None => "No License (None)".to_string(), + Some(id) => match id.name { + "Unlicense" => "The Unlicense (Unlicense)".to_string(), + "MIT" => "MIT License (MIT)".to_string(), + "GPL-2.0" => "GNU General Public License v2.0 (GNU GPLv2)".to_string(), + "GPL-3.0" => "GNU General Public License v3.0 (GNU GPLv3)".to_string(), + "LGPL-2.1" => { + "GNU Lesser General Public License v2.1 (GNU LGPLv2.1)".to_string() + } + "LGPL-3.0" => "GNU Lesser General Public License v3.0 (GNU LGPLv3)".to_string(), + "BSD-2-Clause" => { + r#"BSD 2-clause "Simplified" license (BSD-2-Clause)"#.to_string() + } + "BSD-3-Clause" => { + r#"BSD 3-clause "New" Or "Revisited license (BSD-3-Clause)"#.to_string() + } + "MPL-2.0" => "Mozilla Public License 2.0 (MPL-2.0)".to_string(), + "OSL-3.0" => "Open Software License 3.0 (OSL-3.0)".to_string(), + "Apache-2.0" => "Apache 2.0 (Apache-2.0)".to_string(), + "AGPL-3.0" => "GNU Affero General Public License (GNU AGPLv3)".to_string(), + "BUSL-1.1" => "Business Source License (BSL 1.1)".to_string(), + _ => format!("{} ({})", id.full_name, id.name), + }, + }; + + println!( + "Submiting contract: {} from {},", + contract_name, contract_file + ); + println!("under the name of: {},", args.name); + println!("licensed with: {}.", license); + println!("using cairo: {} and scarb {}", cairo_version, scarb_version); + println!("These are the files that I'm about to transfer:"); + for (_name, path) in &files { + println!("{path}"); + } + + if args.execute { + private + .get_class(&args.hash) + .map_err(CliError::from) + .and_then(|does_exist| { + if !does_exist { + Err(CliError::NotDeclared(args.hash.clone())) + } else { + Ok(does_exist) + } + })?; + + return public + .verify_class( + args.hash.clone(), + license.as_str(), + args.name.as_ref(), + project_meta, + files + .into_iter() + .map(|(name, path)| FileInfo { + name, + path: path.into_std_path_buf(), + }) + .collect_vec(), + ) + .map_err(CliError::from); + } else { + println!("Nothing to do, add `--execute` flag to actually submit contract"); + return Err(CliError::DryRun); + } + } + } + + Err(CliError::NoTarget) +} + +fn check(public: ApiClient, job_id: &String) -> Result { + poll_verification_status(public, job_id).map_err(CliError::from) +} diff --git a/src/resolver.rs b/src/resolver.rs new file mode 100644 index 0000000..1d61f77 --- /dev/null +++ b/src/resolver.rs @@ -0,0 +1,145 @@ +use camino::{Utf8Path, Utf8PathBuf}; +use itertools::Itertools; +use scarb_metadata::{Metadata, MetadataCommand, PackageMetadata}; +use std::{collections::HashMap, ffi::OsStr, path::PathBuf}; +use thiserror::Error; +use url::Url; +use walkdir::WalkDir; + +#[derive(Debug, Error)] +pub enum ResolverError { + #[error("Couldn't parse {name} path: {path}")] + DependencyPath { name: String, path: String }, + + #[error("scarb metadata failed for {name}: {path}")] + MetadataError { name: String, path: PathBuf }, + + #[error(transparent)] + Utf8(#[from] camino::FromPathBufError), +} + +pub fn gather_packages( + metadata: &Metadata, + packages: &mut Vec, +) -> Result<(), ResolverError> { + let mut workspace_packages: Vec = metadata + .packages + .clone() + .into_iter() + .filter(|package_meta| metadata.workspace.members.contains(&package_meta.id)) + .filter(|package_meta| !packages.contains(package_meta)) + .collect(); + + let workspace_packages_names = workspace_packages + .iter() + .map(|package| package.name.clone()) + .collect_vec(); + + // find all dependencies listed by path + let mut dependencies: HashMap = HashMap::new(); + for package in &workspace_packages { + for dependency in &package.dependencies { + let name = &dependency.name; + let url = + Url::parse(&dependency.source.repr).map_err(|_| ResolverError::DependencyPath { + name: name.clone(), + path: dependency.source.repr.clone(), + })?; + + if url.scheme().starts_with("path") { + let path = url + .to_file_path() + .map_err(|_| ResolverError::DependencyPath { + name: name.clone(), + path: dependency.source.repr.clone(), + })?; + dependencies.insert(name.clone(), path); + } + } + } + + packages.append(&mut workspace_packages); + + // filter out dependencies already covered by workspace + let out_of_workspace_dependencies: HashMap<&String, &PathBuf> = dependencies + .iter() + .filter(|&(k, _)| !workspace_packages_names.contains(&k)) + .collect(); + + for (name, manifest) in out_of_workspace_dependencies { + let new_meta = MetadataCommand::new() + .json() + .manifest_path(manifest) + .exec() + .map_err(|_| ResolverError::MetadataError { + name: name.clone(), + path: manifest.clone(), + })?; + gather_packages(&new_meta, packages)?; + } + + Ok(()) +} + +pub fn package_sources( + package_metadata: &PackageMetadata, +) -> Result, ResolverError> { + let mut sources: Vec = WalkDir::new(package_metadata.root.clone()) + .into_iter() + .filter_map(|f| f.ok()) + .filter(|f| f.file_type().is_file()) + .filter(|f| { + if let Some(ext) = f.path().extension() { + if ext == OsStr::new(CAIRO_EXT) { + return true; + } + }; + + return false; + }) + .map(|dir_entry| dir_entry.into_path()) + .map(Utf8PathBuf::try_from) + .try_collect()?; + + sources.push(package_metadata.manifest_path.clone().into()); + let package_root = &package_metadata.root; + + if let Some(lic) = package_metadata + .manifest_metadata + .license_file + .as_ref() + .map(Utf8Path::new) + .map(Utf8Path::to_path_buf) + { + sources.push(package_root.join(lic)) + } + + if let Some(readme) = package_metadata + .manifest_metadata + .readme + .as_deref() + .map(Utf8Path::new) + .map(Utf8Path::to_path_buf) + { + sources.push(package_root.join(readme)); + } + + Ok(sources) +} + +pub fn biggest_common_prefix + Clone>( + paths: &Vec, + first_guess: P, +) -> Utf8PathBuf { + let mut ancestors = Utf8Path::ancestors(first_guess.as_ref()); + let mut biggest_prefix: &Utf8Path = first_guess.as_ref(); + while let Some(prefix) = ancestors.next() { + if paths.iter().all(|src| src.starts_with(prefix)) { + biggest_prefix = prefix; + break; + } + } + biggest_prefix.to_path_buf() +} + +const CAIRO_EXT: &str = "cairo"; diff --git a/src/voyager.rs b/src/voyager.rs new file mode 100644 index 0000000..48f7352 --- /dev/null +++ b/src/voyager.rs @@ -0,0 +1,50 @@ +use camino::Utf8PathBuf; +use scarb_metadata::{Metadata, PackageId}; +use serde::Deserialize; +use std::{collections::HashMap, path::PathBuf}; +use thiserror::Error; + +pub type ContractMap = HashMap; + +#[allow(dead_code)] +#[derive(Clone, Debug, Deserialize)] +pub struct Voyager { + pub path: PathBuf, + pub address: Option, +} + +#[derive(Debug, Error)] +pub enum VoyagerError { + #[error(transparent)] + DeserializationEorror(#[from] serde_json::Error), +} + +// Use this instead of metadata.runtime_manifest, because of: +// https://docs.rs/scarb-metadata/latest/scarb_metadata/struct.Metadata.html#compatibility +// > With very old Scarb versions (<0.5.0), this field may end up being +// > empty path upon deserializing from scarb metadata call. In this +// > case, fall back to WorkspaceMetadata.manifest field value. +// but I've actually got this in scarb 0.5.1, so... +pub fn manifest_path(metadata: &Metadata) -> &Utf8PathBuf { + if metadata.runtime_manifest == Utf8PathBuf::new() { + &metadata.workspace.manifest_path + } else { + &metadata.runtime_manifest + } +} + +pub fn tool_section(metadata: &Metadata) -> Result, VoyagerError> { + let mut voyager: HashMap = HashMap::new(); + for package in &metadata.packages { + if !metadata.workspace.members.contains(&package.id) { + continue; + } + + if let Some(tool) = package.tool_metadata("voyager") { + let contracts = + serde_json::from_value::(tool.clone()).map_err(VoyagerError::from)?; + voyager.insert(package.id.clone(), contracts); + } + } + Ok(voyager) +}