Skip to content

feat(explorer): drag-and-drop ABI and source import from acton build/project folders - #1228

Open
1IxI1 wants to merge 4 commits into
ton-blockchain:masterfrom
1IxI1:abi-build-dir-import
Open

feat(explorer): drag-and-drop ABI and source import from acton build/project folders#1228
1IxI1 wants to merge 4 commits into
ton-blockchain:masterfrom
1IxI1:abi-build-dir-import

Conversation

@1IxI1

@1IxI1 1IxI1 commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

What

Two commits, one theme — stop cherry-picking JSON files into the catalogs by hand:

  • ABI catalog (/abi): drag-and-drop an acton build/ directory anywhere onto the table (or click the new Import build folder button) and every contract's ABI registers in one batch, with code hashes filled in automatically.
  • Source catalog (/sources): drag-and-drop the whole project root (or click Import project folder) and every source artifact found in the tree — typically build/sources/<Name>.source.json — registers in one batch. If a project has no generated artifacts yet, the error says exactly what to run (acton build --output-sources build/sources).

The existing one-file manual forms are unchanged on both pages.

Why

Registering ABIs for a multi-contract project is one file at a time: pick the right JSON out of build/abi/ (not obvious which), then hand-copy the code hash from the matching build/<Name>.json. The source form is worse — it wants one very specific JSON per contract and nothing on the page says which file that is. For a 5-contract project that's ten rounds of guesswork the build output already knows the answers to.

How

Shared importer in explorer-core/src/components/buildImport.ts, used by both catalogs:

  • Recursively walks the dropped entries (webkitGetAsEntry, draining readEntries chunks), collecting only .json files; cache/ (stale contract versions), logs/, sessions/, node_modules/, target/, dist/ and hidden directories are skipped. Detection is shape-based, not name-based, so stray project JSON is ignored silently.
  • ABI plan: pairs build/abi/<Name>.json (raw compiler ABI) with build/<Name>.json ({code_boc64, hash}) by basename, falling back to the ABI's contract_name. When same-named artifacts exist in several places, the one next to the abi/ directory wins; genuinely different hashes all attach to the one ABI. Hashes normalize (hex or base64), duplicates collapse, unmatched ABIs surface as warnings in the toast. Files already carrying inline code_hashes (exported extended ABIs) register as-is.
  • Source plan: accepts both artifact shapes — the current {code_hash, verified, bundle} and the legacy bundles array emitted by CLIs predating fcb3a1a (feat(verifier): single bundle for one code hash). The manual form shares the parser, so it now takes legacy artifacts too. Registrations dedupe by code hash.
  • Everything goes through one registerCompilerAbis / registerSources batch per drop.

Also fixes the environment badge sitting above the vertical center of its row (leftover top: -4px).

Testing

  • 15 unit tests (tests/buildImport.test.ts): basename + contract_name matching, sibling-dir preference, multi-hash artifacts, cache/logs filtering, base64 normalization, inline-hash passthrough, dedupe, warning on unmatched ABI; source-artifact discovery in a project tree, legacy bundles shape, code-hash dedupe, skipped dirs, no-artifacts hint.
  • Verified against a real 5-contract acton project: both plans find all 5 contracts, ABI hashes byte-identical to the on-disk build/<Name>.json, source code hashes cross-match them; the real source artifacts were generated by a pre-fcb3a1a1d CLI, so the legacy path is exercised with production data.
  • Drag-and-drop of the build directory exercised manually in the vite dev app (Chrome); browser end-to-end via CDP for the folder-picker path — picking the real project directory registered all 5 sources in the table with correct entrypoints, code hashes and compiler versions.
  • bun fmt / bun lint / tsc --noEmit / full bun test (169 tests) clean.

🤖 Generated with Claude Code

Registering ABIs one by one is tedious for multi-contract projects: each
file needs a manual pick plus a hand-copied code hash. Let the ABI
catalog accept a whole acton build/ directory instead - drag-and-drop it
anywhere onto the table (or use the new "Import build folder" button)
and every contract registers in one go.

The import pairs build/abi/<Name>.json (raw compiler ABI) with
build/<Name>.json ({code_boc64, hash}) by basename, falling back to the
ABI's contract_name; when same-named artifacts exist in several places,
the one next to the abi/ directory wins, and genuinely different hashes
all attach to the ABI. cache/ (stale versions), logs/, sessions/ and
hidden directories are skipped, hashes are normalized (hex or base64),
duplicates collapse, and ABIs with no matching code artifact surface as
warnings in the result toast. Files that already carry inline
code_hashes (exported extended ABIs) register as-is.

Also drop the top: -4px offset that pushed the "environment" badge
above the vertical center of its row.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@1IxI1
1IxI1 requested a review from i582 as a code owner August 15, 2026 13:04
@netlify

netlify Bot commented Aug 15, 2026

Copy link
Copy Markdown

Deploy Preview for acton-staging canceled.

Name Link
🔨 Latest commit 9d86c5f
🔍 Latest deploy log https://app.netlify.com/projects/acton-staging/deploys/6a80903ce1e1fe000892deb8

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4332fd8c0e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +325 to +327
const key = registration.abi.code_hashes[0]
if (key && seen.has(key)) {
continue

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve aliases when deduplicating registrations

When two imported extended ABIs share their first code hash but contain different additional hashes, this drops the entire later registration, so its unique aliases never reach registerCompilerAbis. Overlaps on a non-first hash are conversely retained as conflicting registrations; BrowserMetadataRegistry.getCompilerAbis then returns whichever matching entry appears first in storage. Deduplicate or merge registrations using the complete code_hashes sets rather than only element zero.

Useful? React with 👍 / 👎.

The source catalog's manual form wants one very specific JSON per
contract, and nothing on the page says which file that is. Let the page
take the whole project instead: drag-and-drop the project root (or use
the new "Import project folder" button) and every source artifact found
anywhere in the tree - typically build/sources/<Name>.source.json -
registers in one batch. If none are found, the error explains how to
generate them (acton build --output-sources build/sources).

Artifact detection is shape-based and accepts both the current
{code_hash, verified, bundle} artifact and the legacy bundles-array
emitted by CLIs predating fcb3a1a (feat(verifier): single bundle for
one code hash); the manual form now takes the legacy shape too, since
it shares the parser. Registrations dedupe by code hash.

The ABI catalog's drop importer generalizes to buildImport.ts to host
the shared directory walker and the new source plan; its behavior is
unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@1IxI1 1IxI1 changed the title feat(explorer): import all ABIs from a dropped acton build/ directory feat(explorer): drag-and-drop ABI and source import from acton build/project folders Aug 15, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 92d7263dc8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

return path
.split("/")
.slice(0, -1)
.some(segment => SKIPPED_DIRS.has(segment) || segment.startsWith("."))

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Allow source artifacts inside hidden output directories

When --output-sources targets a hidden directory, folder import silently excludes every artifact because this predicate rejects any path segment beginning with .. This is a supported configuration exercised by tests/integration/flags_tests.rs:1463-1470, which generates .studio/sources/simple.source.json; dropping that project therefore reports that no source artifacts were found even though the generated artifact is present. Hidden-directory filtering should not discard recognized source artifacts, or .studio/sources should be explicitly allowed.

Useful? React with 👍 / 👎.

… registry

Source deletion always went through the localnet control API
(acton_deleteVerifiedSourceArtifact), which does not exist for the
browser environment registry actonscan uses - so deleting a source
registered on the site always failed with "Failed to delete source
artifact" while ABI deletion (which goes through the registry) worked.
Route deletion by origin: entries with a backend artifactId keep using
the control API, browser-environment entries delete from the metadata
registry by code hash.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7528e59ec2

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +158 to +159
if (seenAbiBases.has(candidate.base)) {
continue

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Keep same-named ABIs from separate build trees

When the selected directory contains multiple build trees with the same contract artifact basename—for example project-a/build/abi/Wallet.json and project-b/build/abi/Wallet.json—this global basename set skips the later raw ABI before its sibling code artifact can be matched. If those builds have different code hashes or ABI versions, only the first is registered; scope this deduplication to the ABI directory or merge candidates after matching their hashes.

Useful? React with 👍 / 👎.

Three edge cases from review of the drop importer:

- Registration dedup now works over the COMPLETE code-hash sets: a later
  registration sharing any hash with an earlier one merges its remaining
  hashes into that entry instead of being dropped whole (losing aliases)
  or slipping through as a conflicting duplicate when the overlap was on
  a non-first hash.
- ABI-candidate dedup keys on dir+basename instead of basename alone, so
  a drop spanning several build trees keeps same-named contracts with
  different code hashes; the final hash-set dedup still collapses true
  duplicates.
- .studio/ is exempt from the hidden-directory skip: acton-studio keeps
  generated source artifacts there (--output-sources .studio/sources),
  and dropping such a project found nothing. Other dot-dirs (.git etc.)
  stay skipped.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9d86c5fc23

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +483 to +485
const existingIndex = hashes
.map(hash => indexByHash.get(hash))
.find((index): index is number => index !== undefined)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Merge all overlapping hash groups

When a later extended ABI bridges two previously separate groups—for example registrations with hashes [A, B], [C, D], then [B, C]—this selects only the first matching index and leaves the second group intact, producing entries [A, B, C] and [C, D] that still conflict on C. Fresh evidence in the revised implementation is this single existingIndex lookup; merge every existing group referenced by the incoming hashes and remap all of their hashes to the consolidated entry.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant