Skip to content

Conversation

@glihm
Copy link
Collaborator

@glihm glihm commented Dec 19, 2025

Due to some limitation in straknet.js and ABI parsing in Dojo.js, this update allows the user to define the ABI format in the manifest.

Currently the limitation is that, if two contracts have the same function name, but different parameters, the lookup in the ABI will only keep the first one found. Which leads to mismatch between the function to be called in certain cases.

This update introduces two level of configuration:

  1. In the profile (dojo_.toml) file where the manifest_abi_format key under [migration] could be set to per_contract or all_in_one.
  2. The migrate command now has a new option manifest-abi-format that accepts the exact same values per_contract or all_in_one.

By default, the all_in_one is used. So if the across the whole dojo project there is no duplicated function names, it will work fine. Otherwise, it is required for now to switch to per_contract ABI.

Summary by CodeRabbit

  • New Features
    • Added CLI option to select manifest ABI format (AllInOne or PerContract) during migration
    • Manifest ABI format can now be configured per-profile or per-migration
    • Enhanced manifest generation to support different ABI layout strategies

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 19, 2025

Ohayo sensei! 👋

Walkthrough

This PR adds support for selecting how ABIs are written in generated manifests via a new CLI option. Users can choose between AllInOne format (global ABI map) or PerContract format (per-contract inline ABIs), with configuration read from migration settings and merged with CLI arguments.

Changes

Cohort / File(s) Summary
CLI argument & conversion
bin/sozo/src/commands/migrate.rs
Added public enum ManifestAbiFormatArg with variants AllInOne and PerContract. Added From conversion to ManifestAbiFormat. Extended MigrateArgs struct with new manifest_abi_format field and CLI parsing via #[arg(long, value_enum)].
Configuration enum
crates/dojo/world/src/config/migration_config.rs
Added public enum ManifestAbiFormat with serde support (rename_all = "snake_case") and Default impl (defaulting to AllInOne). Extended MigrationConfig with new optional field manifest_abi_format.
Manifest serialization logic
crates/dojo/world/src/diff/manifest.rs
Updated ABI fields across Manifest and multiple related structs to use serde(default, skip_serializing_if = "...") instead of skip attributes. Added public methods strip_inline_abis() and apply_abi_format() to Manifest. Included unit tests validating AllInOne and PerContract serialization behavior.

Sequence Diagram

sequenceDiagram
    participant User
    participant CLI as MigrateArgs<br/>(CLI Parser)
    participant Config as MigrationConfig
    participant Manifest
    
    User->>CLI: Provide --manifest-abi-format
    CLI->>CLI: Parse ManifestAbiFormatArg
    CLI->>Config: Read per-migration config
    Config-->>CLI: Return manifest_abi_format
    CLI->>CLI: Merge CLI arg with config<br/>(CLI takes priority)
    CLI->>CLI: Convert to ManifestAbiFormat
    CLI->>Manifest: Call apply_abi_format(format)
    alt AllInOne Format
        Manifest->>Manifest: strip_inline_abis()
        Manifest-->>User: Global abis map retained
    else PerContract Format
        Manifest->>Manifest: Clear global abis map
        Manifest-->>User: Per-contract inline ABIs retained
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Manifest serialization changes: Verify the serde attribute changes (default + skip_serializing_if) across six structs produce correct JSON serialization behavior in both AllInOne and PerContract modes
  • ABI format application logic: Ensure apply_abi_format() correctly strips/clears ABIs based on format choice and that the precedence between CLI args and config settings works as intended
  • Test coverage: Confirm unit tests adequately validate the three serialization scenarios (default, AllInOne, PerContract)

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: adding a parameter to control ABI format in the manifest, which is the core feature across all modified files.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/sozo/manifest-abi-format

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
crates/dojo/world/src/config/migration_config.rs (1)

3-14: Ohayo, sensei! Clean enum definition with a minor simplification opportunity.

The enum and default impl look good. Consider using the #[default] derive attribute to reduce boilerplate:

🔎 Suggested simplification
-#[derive(Debug, Clone, Deserialize)]
+#[derive(Debug, Clone, Default, Deserialize)]
 #[serde(rename_all = "snake_case")]
 pub enum ManifestAbiFormat {
+    #[default]
     AllInOne,
     PerContract,
 }
-
-impl Default for ManifestAbiFormat {
-    fn default() -> Self {
-        Self::AllInOne
-    }
-}
bin/sozo/src/commands/migrate.rs (1)

43-46: Ohayo sensei! Consider adding help text for clarity.

The option works, but users running --help would benefit from knowing what each format does:

🔎 Add descriptive help text
     /// Select how ABIs are written in the generated manifest.
-    #[arg(long, value_enum, value_name = "FORMAT")]
+    #[arg(long, value_enum, value_name = "FORMAT", help = "Select how ABIs are written in the generated manifest: 'all_in_one' merges ABIs into a global map, 'per_contract' keeps ABIs inline per contract.")]
     pub manifest_abi_format: Option<ManifestAbiFormatArg>,
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7c52a41 and e103970.

📒 Files selected for processing (3)
  • bin/sozo/src/commands/migrate.rs (5 hunks)
  • crates/dojo/world/src/config/migration_config.rs (2 hunks)
  • crates/dojo/world/src/diff/manifest.rs (10 hunks)
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2024-11-05T04:30:12.852Z
Learnt from: glihm
Repo: dojoengine/dojo PR: 2633
File: crates/dojo/world/src/contracts/abigen/world.rs:3809-0
Timestamp: 2024-11-05T04:30:12.852Z
Learning: Code in `crates/dojo/world/src/contracts/abigen/` is auto-generated and should be excluded from code reviews.

Applied to files:

  • crates/dojo/world/src/diff/manifest.rs
📚 Learning: 2025-10-30T22:20:34.112Z
Learnt from: glihm
Repo: dojoengine/dojo PR: 3370
File: crates/dojo/world/src/diff/manifest.rs:454-523
Timestamp: 2025-10-30T22:20:34.112Z
Learning: In Cairo ABIs, functions are typically inside interfaces whose names include the full Cairo path (e.g., `dojo::core::IWorldProvider`), making interface names inherently unique. When deduplicating ABI entries in Dojo's manifest by name (get_abi_name), collisions don't occur because interface names encode their paths, and Impl entries are intentionally filtered out while keeping interfaces.

Applied to files:

  • crates/dojo/world/src/diff/manifest.rs
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: fmt
🔇 Additional comments (7)
crates/dojo/world/src/config/migration_config.rs (1)

26-27: LGTM!

The optional field integrates cleanly with the existing config structure, sensei.

bin/sozo/src/commands/migrate.rs (2)

91-97: LGTM! Clean precedence logic.

The priority chain (CLI → config → default) is correctly implemented, sensei. This is idiomatic Rust with proper use of Option combinators.


140-154: LGTM! Proper separation between CLI and domain types.

Having a distinct ManifestAbiFormatArg for CLI parsing keeps the clap dependency isolated from the core config module. The From conversion is straightforward, sensei.

crates/dojo/world/src/diff/manifest.rs (4)

29-35: Ohayo sensei! Good serde configuration.

The combination of default for deserialization and skip_serializing_if = "HashMap::is_empty" for serialization correctly handles both reading manifests with missing abis and writing manifests where the field should be omitted in PerContract mode.


53-55: LGTM! Consistent serde attributes across all ABI-bearing structs.

All inline abi fields now use #[serde(default, skip_serializing_if = "Vec::is_empty")], which enables clean omission in the AllInOne format while still supporting deserialization, sensei.

Also applies to: 67-69, 88-90, 115-117, 144-146, 172-174


256-272: LGTM! Clean implementation of the format selection logic.

The two methods work well together:

  • strip_inline_abis clears per-resource ABIs for AllInOne mode
  • apply_abi_format dispatches based on the chosen format

This correctly handles the starknet.js limitation mentioned in the PR objectives. Based on learnings, Cairo ABI interface names include full paths making them inherently unique, so the global abis map deduplication is safe, sensei.


553-611: Ohayo! Solid test coverage, sensei.

The test validates all three serialization scenarios:

  1. Default (before applying format) → both inline and global ABIs present
  2. AllInOne → inline ABIs stripped, global abis retained
  3. PerContract → inline ABIs retained, global abis cleared

This directly tests the serialization behavior which is the core functionality of this PR.

@glihm glihm merged commit e8d8b44 into main Dec 19, 2025
10 checks passed
@glihm glihm deleted the fix/sozo/manifest-abi-format branch December 19, 2025 17:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants