[Stellar] Add toggle to switch from default to explicit trait implementation
Fixes #706
Summary
Enable UI and tooling to use explicit Soroban trait implementations instead of relying solely on #[default_impl], adding regression coverage and docs for the new option.
Motivation / Context
Contract authors asked for a way to inspect and customize every generated Soroban trait function instead of depending on #[default_impl]. This work exposes that capability in the builders, UI, and MCP tools without changing the default experience.
Changes
- [x] Major feature: optional explicit trait implementations throughout Stellar contract builders, plus access-control and token module plumbing updates.
- [x] Config / tooling: UI control section, AI descriptions, schema, and MCP tool changes so the new option can be toggled and validated end-to-end.
Description
-
packages/core/stellar/src/common-options.ts:10-36and the builder defaults now carry anexplicitImplementationsflag so every contract kind can opt in to non-macro trait bodies. -
packages/core/stellar/src/contract.ts:188-192introducesaddTraitForEachFunctions, letting trait mixins add all functions programmatically when macros are disabled. - Access-control helpers (
packages/core/stellar/src/set-access-control.ts:18-235,packages/core/stellar/src/add-pausable.ts:4-44,packages/core/stellar/src/add-upgradeable.ts:4-45) accept the flag, generate Ownable/AccessControl function bodies, and still enforce the same role/owner checks. - Token builders propagate the choice through every feature (
packages/core/stellar/src/fungible.ts:25-210,packages/core/stellar/src/non-fungible.ts:28-305,packages/core/stellar/src/stablecoin.ts:48-101) and update generation blueprints so option sweeps include the new mode. - UI/tooling surfaces the toggle (
packages/ui/src/stellar/TraitImplementationSection.svelte:1-33plus imports in each controls file) while schemas/prompts describe and validate it (packages/mcp/src/stellar/schemas.ts:24-35,packages/mcp/src/stellar/tools/fungible.ts:10-40,packages/common/src/ai/descriptions/stellar.ts:12-20). - New compile tests, scenario docs, and MCP tool suites cover explicit builds across fungible, non-fungible, and stablecoin variants (
packages/core/stellar/src/*.compile.test.ts,packages/core/stellar/src/*.test.ts/.md,packages/mcp/src/stellar/tools/*.test.ts).
Affected Functions
-
packages/core/stellar/src/contract.ts:188— newaddTraitForEachFunctionshelper to bulk-attach trait methods when macros are skipped. -
packages/core/stellar/src/set-access-control.ts:18—setAccessControlaccepts the explicit flag and adds per-function trait impls for Ownable/AccessControl when needed. -
packages/core/stellar/src/set-access-control.ts:84—requireAccessControlforwards the explicit flag so pausable/upgradeable traits stay consistent. -
packages/core/stellar/src/add-pausable.ts:4&packages/core/stellar/src/add-upgradeable.ts:4— feature mixins now require the explicit flag and pass it through to access control. -
packages/core/stellar/src/fungible.ts:63&:137— base, burnable, and mintable helpers emit explicit trait functions when requested. -
packages/core/stellar/src/non-fungible.ts:91&:212— non-fungible base, burnable/enumerable/consecutive modules support explicit implementations. -
packages/core/stellar/src/stablecoin.ts:48— limitation helpers forward the flag so allow/blocklist operations can be emitted explicitly.
Security Impact
- ✅ No new security concerns; explicit implementations call the same helper libraries and still rely on
requireAccessControlfor gating. - [ ] Security-sensitive modifications: not applicable.
Testing
- [x] Added compile regressions for each contract family with
explicitImplementationsenabled (packages/core/stellar/src/fungible.compile.test.ts,non-fungible.compile.test.ts,stablecoin.compile.test.ts). - [x] Added scenario/API tests, markdown snapshots, and MCP tool coverage for the new option (
packages/core/stellar/src/*.test.ts,.md,.snap, andpackages/mcp/src/stellar/tools/*.test.ts).
Manual verification:
- In the UI, toggle "Explicit trait methods" for each contract type and confirm the preview drops
#[default_impl]and shows explicit bodies. - Run
pnpm test --filter='packages/core/stellar/src/*explicit*'and the relevant MCP tool tests to ensure the new flag compiles cleanly.
Backward Compatibility
- ✅ No breaking changes; the wizard still uses
#[default_impl]unless the new toggle is enabled. - ✅ No migration needed; existing saved configs remain valid and ignore the new option.
[!IMPORTANT]
Review skipped
Auto incremental reviews are disabled on this repository.
Please check the settings in the CodeRabbit UI or the
.coderabbit.yamlfile in this repository. To trigger a single review, invoke the@coderabbitai reviewcommand.You can disable this status message by setting the
reviews.review_statustofalsein the CodeRabbit configuration file.
Walkthrough
The PR introduces an explicitImplementations boolean configuration option enabling contracts to use explicit trait implementations instead of the #[default_impl] macro. This flag is propagated through contract builders and conditionally adjusts code generation, imports, and trait wiring across fungible, non-fungible, and stablecoin contracts, with corresponding UI and test coverage.
Changes
| Cohort / File(s) | Summary |
|---|---|
Configuration & Schemas packages/common/src/ai/descriptions/stellar.ts, packages/core/stellar/src/common-options.ts, packages/mcp/src/stellar/schemas.ts |
Added explicitImplementations property to common descriptions, CommonContractOptions interface with default value false, and MCP schema. |
Access Control packages/core/stellar/src/set-access-control.ts |
Extended setAccessControl and requireAccessControl signatures to accept explicitImplementations parameter; added conditional trait wiring via defineFunctions for explicit implementations mode. |
Core Builder Functions packages/core/stellar/src/add-pausable.ts, packages/core/stellar/src/add-upgradeable.ts |
Updated addPausable and addUpgradeable signatures to accept and propagate explicitImplementations parameter to requireAccessControl calls. |
Contract Builder packages/core/stellar/src/contract.ts |
Added new addTraitForEachFunctions method to batch-add trait functions. |
Fungible Contracts packages/core/stellar/src/fungible.ts, packages/core/stellar/src/generate/fungible.ts |
Extended buildFungible, addBase, addMintable, and addBurnable signatures; added conditional trait implementation generation and function lists (fungibleTokenTraitFunctions, fungibleBurnableFunctions); added explicitImplementations field to generator blueprint. |
Non-Fungible Contracts packages/core/stellar/src/non-fungible.ts, packages/core/stellar/src/generate/non-fungible.ts |
Updated defaults to include explicitImplementations; extended builder functions to conditionally generate explicit trait implementations; added explicitImplementations to generator blueprint. |
Stablecoin Contracts packages/core/stellar/src/stablecoin.ts, packages/core/stellar/src/generate/stablecoin.ts |
Extended addLimitations signature and propagated explicitImplementations through access control calls; added field to generator blueprint. |
Test Cases packages/core/stellar/src/fungible.test.ts, packages/core/stellar/src/fungible.compile.test.ts, packages/core/stellar/src/non-fungible.test.ts, packages/core/stellar/src/non-fungible.compile.test.ts, packages/core/stellar/src/stablecoin.test.ts, packages/core/stellar/src/stablecoin.compile.test.ts |
Added new test cases verifying explicit trait implementations for fungible, non-fungible, and stablecoin contracts. |
Test Snapshots packages/core/stellar/src/fungible.test.ts.md, packages/core/stellar/src/non-fungible.test.ts.md, packages/core/stellar/src/stablecoin.test.ts.md |
Added new snapshot blocks demonstrating generated Rust code with explicit trait implementations; updated imports to include Symbol where needed. |
MCP Tools packages/mcp/src/stellar/tools/fungible.ts, packages/mcp/src/stellar/tools/non-fungible.ts (implied), packages/mcp/src/stellar/tools/stablecoin.ts (implied) |
Added explicitImplementations parameter destructuring and propagation in tool registration callbacks. |
MCP Tool Tests packages/mcp/src/stellar/tools/fungible.test.ts, packages/mcp/src/stellar/tools/non-fungible.test.ts, packages/mcp/src/stellar/tools/stablecoin.test.ts |
Extended all-fields test parameters to include explicitImplementations: true. |
UI Components packages/ui/src/stellar/TraitImplementationSection.svelte |
New UI component providing radio selection between default implementation and explicit trait methods modes. |
UI Control Updates packages/ui/src/stellar/FungibleControls.svelte, packages/ui/src/stellar/NonFungibleControls.svelte, packages/ui/src/stellar/StablecoinControls.svelte |
Integrated TraitImplementationSection component with two-way binding to opts.explicitImplementations. |
Sequence Diagram(s)
sequenceDiagram
participant User as User/Config
participant Builder as Contract Builder
participant AC as Access Control
participant Gen as Code Generator
User->>Builder: buildFungible({explicitImplementations: true})
activate Builder
Builder->>Builder: addBase(c, name, symbol, pausable, true)
note over Builder: Set trait tags to ['contractimpl']<br/>conditionally import types
alt explicitImplementations = true
Builder->>Gen: addTraitForEachFunctions(trait,<br/>fungibleTokenTraitFunctions)
note over Gen: Generate explicit<br/>function implementations
else explicitImplementations = false
Builder->>Gen: Add default_impl macro
note over Gen: Use default_impl<br/>+ contractimpl
end
Builder->>Builder: addMintable(c, access, pausable, true)
Builder->>AC: requireAccessControl(..., true)
activate AC
AC->>AC: setAccessControl(..., true)
alt explicitImplementations = true
AC->>Gen: defineFunctions(ownableFunctions)
AC->>Builder: addTraitForEachFunctions(trait, fns)
else
AC->>Gen: Use default_impl blocks
end
deactivate AC
deactivate Builder
Gen-->>User: Generated Rust code<br/>(explicit or default mode)
Estimated code review effort
🎯 3 (Moderate) | ⏱️ ~25 minutes
- Complexity drivers: Conditional logic branching throughout contract builders; new parameter propagation pattern repeated across multiple function signatures; changes to trait wiring and code generation paths; new UI component with reactive state management
- Mitigating factors: Consistent pattern application across files (homogeneous parameter additions); no changes to public API contracts beyond adding optional flag; test coverage provided
-
Areas requiring attention:
-
packages/core/stellar/src/set-access-control.ts— Dynamic function definition logic and conditional trait wiring -
packages/core/stellar/src/fungible.tsandpackages/core/stellar/src/non-fungible.ts— Conditional trait function list application and import management -
packages/ui/src/stellar/TraitImplementationSection.svelte— Reactive bindings and state synchronization patterns - Snapshot files — Verify generated Rust code structure and trait method signatures match expected patterns
-
Possibly related issues
- OpenZeppelin/contracts-wizard#706 — Implements requested UI toggle for default_impl vs explicit trait implementations mode; the PR adds configuration option, conditional code generation, and UI component to select between the two approaches.
Suggested reviewers
- ericglau
- ericnordelo
Pre-merge checks and finishing touches
❌ Failed checks (1 warning)
| Check name | Status | Explanation | Resolution |
|---|---|---|---|
| Docstring Coverage | ⚠️ Warning | Docstring coverage is 9.52% which is insufficient. The required threshold is 80.00%. | You can run @coderabbitai generate docstrings to improve docstring coverage. |
✅ Passed checks (2 passed)
| Check name | Status | Explanation |
|---|---|---|
| Title check | ✅ Passed | The PR title accurately and specifically describes the main feature: adding a toggle to switch between default and explicit trait implementations in Stellar contracts. |
| Description check | ✅ Passed | The PR description is comprehensive and directly related to the changeset, detailing the motivation, changes across multiple modules, security impact, testing approach, and backward compatibility. |
Comment @coderabbitai help to get the list of available commands and usage tips.
The comments above need to be addressed before this can be merged.