Skip to content

Contract Studio: IDE layout with file explorer, tabs, and multi-file compilation#36

Merged
itsyogesh merged 20 commits intomasterfrom
feat/contract-studio
Mar 20, 2026
Merged

Contract Studio: IDE layout with file explorer, tabs, and multi-file compilation#36
itsyogesh merged 20 commits intomasterfrom
feat/contract-studio

Conversation

@itsyogesh
Copy link
Copy Markdown
Owner

@itsyogesh itsyogesh commented Mar 19, 2026

Summary

Redesigns Contract Studio from a basic 3-panel form into a proper IDE experience for the Polkadot Solidity Hackathon:

  • File explorer (left sidebar) — Create, rename, delete, search, and upload .sol files. Flat namespace with duplicate rejection and last-file guard.
  • Tabbed editor (center) — Monaco editor with per-file model isolation, dirty indicators, and collapsible output panel showing compile results.
  • Compile/Deploy accordion (right sidebar) — EVM/PVM toggle, compile with race protection, contract selector with smart re-selection, bytecode/ABI upload with full artifact reset rules, deploy gates per artifact source.
  • Status bar — Chain, address, artifact mode badge (from last compile, not target toggle), compile status, dirty indicator.
  • Multi-file compilation — All workspace files sent to /api/compile via sources param. Flat namespace validation, import hint for relative paths, user files sorted first.
  • Builder parity/builder updated with compile race protection (compileIdRef), artifact preservation on compile failure, bytecodeSource tracking, and upload input reset.

Commits

  1. State foundationStudioState types, contentHash utility, StudioProvider with useReducer, bytecodeSource/nullable mode in ContractCompilationState
  2. Builder parity — Race protection, artifact tracking, failure policy, upload fixes in contract-code.tsx
  3. IDE layout & components — 10 new components: StudioLayout, FileExplorer, FileTreeItem, EditorTabs, EditorArea, OutputPanel, CompilerSection, DeploySection, RightSidebar, StatusBar
  4. Multi-file compilationcompileSoliditySources(), extended /api/compile route, resolveAllImportsSources()
  5. Tests — 35 new tests: reducer (23) + integration (12) covering file ops, dirty tracking, compile race, upload cancellation, mixed artifact flows, deploy gates
  6. Cleanup — Remove contract-studio.tsx, compile-panel.tsx, editor-panel.tsx

Test plan

  • yarn build passes
  • yarn test passes (1020 tests, 91 suites)
  • Studio loads with 3-panel layout + status bar
  • Create/rename/delete files; rename rejects duplicates; delete blocked on last file
  • Tab switching preserves editor content; close focuses neighbor
  • PVM compile populates constructor form + contract info card
  • Edit after compile shows dirty indicator + "Recompile first" warning
  • EVM compile shows "Switch to PVM" deploy gate
  • .bin upload resets artifacts; .json ABI layers on top with "unverified" warning
  • Status bar shows artifact mode badge (PVM/EVM), not compile target toggle
  • Builder at /builder → Revive → instantiate_with_code still works end-to-end

Introduce chain-types.ts with GenericChainClient, AssetHubApi union type,
isAssetHubGenesis() and hasReviveApi() type guard. Refactor ClientProvider
to instantiate typed DedotClient based on genesis hash (PolkadotAssetHubApi,
WestendAssetHubApi, PaseoAssetHubApi) and expose isAssetHub in context.
Widen DedotClient<PolkadotApi> to GenericChainClient across downstream
consumers (types.ts, parser.ts, hooks).
New useGasEstimation hook performs reviveApi.instantiate dry-runs with
10% safety buffer on weight/storage. Only populates estimate state on
successful dry-runs to prevent consumers from acting on failed results.

Add fee-display.ts for formatting planck amounts and weight values.
Extract shared compile logic into compile-client.ts.

Fix Struct component to sync local state from external value prop
(needed for gas estimation auto-fill) and pass values to child inputs.
Widen BuilderFormValues index signature to support object values.
New /studio route with CompilePanel (left), EditorPanel (center, Monaco
+ output), and DeployPanel (right, constructor form + gas estimation +
deploy + transaction log).

ContractProvider context replaces the global singleton for Studio state
to avoid mount/unmount reset conflicts between panels.

Constructor form validates all fields before encoding (matching builder
behavior), resets state on ABI changes, and provides hex fallback input
with validation for unsupported constructor types.

Deploy panel clears stale constructor data on contract switches, logs
estimation failures to the transaction log, and validates hex inputs
at the form boundary.

Upload handler routes .sol files to the editor and validates .bin/.hex
uploads for even-length hex.
Show Estimate Gas button and Open in Contract Studio link when
pallet=Revive, method=instantiate_with_code. Auto-fill weight_limit
(using metadata-derived field names) and storage_deposit_limit (Charge
only) from dry-run results.

Fix information-pane argValuesKey to use JSON.stringify for object values
so weight struct changes trigger re-encoding.

Refactor contract-code.tsx to use shared compile-client.ts.
Hardcode Builder and Studio links in both desktop nav and mobile Sheet
menu, with active-state highlighting based on layout segment.
New use-gas-estimation.test.ts: success path with 10% buffer, Refund
no-buffer, dispatch error leaves estimate state null, RPC exceptions,
guard checks for missing client/account/bytecode.

Extend extrinsic-builder tests: Estimate Gas button visibility for
Revive, Studio link presence, hidden for non-Revive pallets.

Extend information-pane tests: object-valued arg changes trigger
re-encoding via JSON.stringify serialization.

Extend struct tests: external value hydration, no infinite loop on
same-value rerender, object-valued onChange emission.
@vercel
Copy link
Copy Markdown
Contributor

vercel bot commented Mar 19, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
relaycode Ready Ready Preview, Comment Mar 20, 2026 4:33am

Request Review

@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented Mar 19, 2026

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 14.40257% with 2930 lines in your changes missing coverage. Please review.
✅ Project coverage is 50.49%. Comparing base (4cd37ba) to head (0914f9d).

Files with missing lines Patch % Lines
components/studio/deploy-section.tsx 0.00% 422 Missing ⚠️
components/studio/compiler-section.tsx 0.00% 352 Missing ⚠️
components/studio/deploy-panel.tsx 0.00% 319 Missing ⚠️
components/studio/constructor-form.tsx 0.00% 205 Missing ⚠️
components/studio/file-explorer.tsx 0.00% 163 Missing ⚠️
components/studio/output-panel.tsx 0.00% 132 Missing ⚠️
components/studio/file-tree-item.tsx 0.00% 126 Missing ⚠️
context/studio-provider.tsx 61.20% 116 Missing ⚠️
lib/compile-client.ts 17.96% 105 Missing ⚠️
components/studio/status-bar.tsx 0.00% 88 Missing ⚠️
... and 21 more
❗ Your organization needs to install the Codecov GitHub app to enable full functionality.
Additional details and impacted files
@@            Coverage Diff             @@
##           master      #36      +/-   ##
==========================================
- Coverage   56.80%   50.49%   -6.31%     
==========================================
  Files         155      178      +23     
  Lines       18907    22233    +3326     
  Branches     1158     1236      +78     
==========================================
+ Hits        10740    11227     +487     
- Misses       8121    10958    +2837     
- Partials       46       48       +2     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

…hains

Dedot's proxy chains execute API spec lookups on property access, so
merely checking typeof client.call.reviveApi.instantiate throws
UnknownApiError on chains without ReviveApi. Wrap in try/catch.
Use percentage strings for react-resizable-panels v2 defaultSize/minSize/
maxSize (plain numbers are treated as pixels in v2, not percentages).
Remove footer from Studio layout for full-height IDE experience.
Use flex-1 + min-h-0 for proper height propagation.
Add flex flex-col to main element so flex-1 on children propagates
height correctly through the layout → page → studio component chain.
…king

- Add types/studio.ts with StudioFile, StudioState, StudioAction types,
  content hash utility (djb2), and workspace helpers
- Add bytecodeSource ("compile" | "upload" | null) and nullable mode to
  ContractCompilationState in contract-store and contract-provider
- Add StudioProvider with useReducer for file system, tabs, and UI state,
  including debounced sessionStorage persistence
- Add shadcn accordion component for right sidebar sections
- Add crypto.randomUUID polyfill for jsdom test environment
- Add compileIdRef token pattern to prevent stale compile responses from
  overwriting newer state after uploads or recompiles
- Set bytecodeSource on compile success ("compile") and bytecode upload
  ("upload" with full artifact reset)
- Preserve previous successful artifacts on compile failure instead of
  calling resetCompilationState
- Clear local isCompiling spinner on bytecode upload to prevent stuck UI
- Reset file inputs after selection to allow re-uploading the same file
- Guard "Compiled" indicator with bytecodeSource === "compile" check
…debar

- Add StudioLayout with resizable 3-panel layout (file explorer, editor,
  sidebar) and fixed status bar
- Add FileExplorer with search, file tree, inline rename with duplicate
  rejection, delete with last-file guard, and .sol upload
- Add EditorTabs with open/close/switch, dirty dot indicator, and new
  file button
- Add EditorArea combining tabs, Monaco editor (keyed by file ID for
  model isolation), and collapsible OutputPanel
- Add CompilerSection with EVM/PVM toggle, compile button with race
  protection (compileIdRef), contract selector with smart re-selection,
  bytecode/ABI upload with full artifact reset rules
- Add DeploySection with deploy gates per bytecodeSource (compile vs
  upload), dirty/mode warnings, no-ABI hex fallback, unverified ABI
  warning, and transaction log
- Add RightSidebar wrapping compile and deploy as accordion sections
- Add StatusBar showing chain, address, artifact mode badge (from
  compilation.mode, not compile target), and compile status
- Update page.tsx with StudioProvider in the provider hierarchy
- Add compileSoliditySources() client function with 450KB size preflight
- Extend /api/compile to accept sources (multi-file) alongside source
  (single-file, backward compatible)
- Validate flat namespace: reject source keys containing / or ..
- Add flat-namespace error hint for relative imports (./Token.sol) when
  basename matches a user source file
- Raise body size limit from 100KB to 500KB for multi-file workspaces
- Add resolveAllImportsSources() with user-source authority and CDN
  shadowing prevention
- Sort compiled contracts with user files first, dependencies last
- Add studio-reducer.test.ts (23 tests): file ops (create, rename with
  duplicate rejection, delete with last-file guard), dirty tracking
  (content hash changes on edit/rename/delete/create), tab management
  (open, close with neighbor focus, switch), content hash determinism
- Add studio-integration.test.ts (12 tests): compile race protection
  (stale response discard, upload-during-compile cancellation), compile
  failure artifact preservation, mixed artifact transitions (EVM→ABI,
  PVM→upload, upload→ABI layering), deploy gate rules
Remove contract-studio.tsx, compile-panel.tsx, and editor-panel.tsx.
These are fully replaced by the new studio-layout.tsx, file-explorer.tsx,
editor-area.tsx, compiler-section.tsx, and deploy-section.tsx components.
@itsyogesh itsyogesh changed the title Add Contract Studio and gas estimation for Revive contracts Contract Studio: IDE layout with file explorer, tabs, and multi-file compilation Mar 20, 2026
- Invalidate weightRequired/storageDeposit when deploy inputs (value,
  code, data, salt) change, preventing deploy with stale gas limits
- Narrow CDN shadowing check to exact key match only; basename collision
  was blocking legitimate dependencies like @openzeppelin/.../Context.sol
  when a user file shared the same basename
- Reject filenames containing /, .., or \ in CREATE_FILE and RENAME_FILE
  reducer actions, matching the flat namespace rules enforced by
  /api/compile
… account change

- Builder compile failure/error now clears hexValue and calls
  onChange(undefined) so the extrinsic form cannot submit outdated
  bytecode that no longer matches the editor source
- Add origin (account address) to gas estimate invalidation effect so
  wallet switches clear stale dry-run results and deployed address
- Replace LunoKit's isPending with local isSubmitting state managed in
  try/finally, ensuring the button always resets even if the wallet
  interaction hangs or the extension crashes
- Add spinner icon to submitting state for clearer feedback
- Improve signing toast to prompt user to approve in wallet extension
- Distinguish user rejection (cancelled/rejected) from actual errors
  with appropriate toast messages
- Check receipt.status === "failed" after block inclusion to surface
  on-chain dispatch errors (e.g., module errors from pallet-revive)
  instead of showing a false success toast
- Add "Signing... approve in your wallet extension" log entry in Studio
  deploy section for intermediate feedback
- Distinguish user wallet rejection from actual transaction errors in
  Studio deploy log (info vs error)
Replace the flex-based 50/50 split between Monaco editor and output
panel with a vertical ResizablePanelGroup (75/25 default). Users can
now drag the handle to resize the editor vs output area.
@itsyogesh itsyogesh merged commit fef903b into master Mar 20, 2026
5 checks passed
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