Project Structure

May 29, 2026 · View on GitHub

A map of the repository: directory layout, package responsibilities, and where each concern lives. For how these pieces interact at runtime see ARCHITECTURE.md.

Repository layout

web3_decoder_2/
├── README.md                     # Project overview + links to these docs
├── docs/                         # This documentation set
├── settings.gradle               # Gradle multi-project definition (root + :web3-decoder)
├── gradle/
│   ├── libs.versions.toml        # Version catalog (Gradle-init leftover; see notes)
│   └── wrapper/                  # Gradle 8.8 wrapper
├── gradlew / gradlew.bat         # Gradle wrapper launchers
└── web3-decoder/                 # The extension module
    ├── build.gradle              # Dependencies, fat-jar packaging, test config
    └── src/
        ├── main/
        │   ├── java/com/nccgroup/web3decoder/
        │   │   ├── Web3DecoderExtension.java        # BurpExtension entry point
        │   │   ├── Web3EditorTabProvider.java       # Editor factory
        │   │   ├── Web3RequestEditor.java           # "Web3 Request" tab
        │   │   ├── Web3ResponseEditor.java          # "Web3 Response" tab
        │   │   ├── Web3RequestContextDecoder.java   # Headless decode orchestration
        │   │   ├── RequestContextStore.java         # Request→response context bridge
        │   │   ├── abi/                             # ABI resolution (chain-scoped chain)
        │   │   ├── annotation/                      # HTTP-handler history-row annotator
        │   │   ├── decoder/                         # Decode/encode core
        │   │   ├── detection/                      # Passive ABI detection (scan check, pool)
        │   │   ├── proxies/                         # Proxy detection
        │   │   ├── persistence/                     # Config + caches
        │   │   ├── ui/                              # Swing panels (Web3 suite tab)
        │   │   │   └── editor/                      # Custom JSON editor component
        │   └── resources/
        │       ├── chains.json                      # Default chain registry
        │       └── builtin-abis/multicall3.json     # Bundled Multicall3 ABI
        └── test/
            ├── java/com/nccgroup/web3_decoder/...   # JUnit 5 tests
            └── resources/                           # Sample ABIs + fixtures

The Gradle group is com.nccgroup.web3-decoder; runtime Java packages are under com.nccgroup.web3decoder (production) and com.nccgroup.web3_decoder (tests).

Package responsibilities

graph LR
    ROOT["web3decoder<br/>(entry + editors + orchestration)"]
    ABI["web3decoder.abi<br/>(ABI resolution)"]
    DEC["web3decoder.decoder<br/>(encode/decode core)"]
    DET["web3decoder.detection<br/>(passive ABI detection + pool)"]
    PROX["web3decoder.proxies<br/>(proxy detection)"]
    PERS["web3decoder.persistence<br/>(config + caches)"]
    UI["web3decoder.ui<br/>(suite-tab Swing panels)"]

    ROOT --> DEC
    ROOT --> ABI
    ROOT --> DET
    ROOT --> PROX
    ROOT --> PERS
    UI --> DEC
    UI --> ABI
    UI --> DET
    UI --> PROX
    UI --> PERS
    DEC --> ABI
    DEC --> DET
    DEC --> PROX
    ABI --> PERS
    DET --> PERS

com.nccgroup.web3decoder (root)

FileResponsibility
Web3DecoderExtensionBurpExtension entry point; registers editors + suite tab.
Web3EditorTabProviderCreates per-context request/response editor instances.
Web3RequestEditorRenders decoded calldata; re-encodes edited args on send.
Web3ResponseEditorDecodes JSON-RPC result; enriches multicall return data.
Web3RequestContextDecoderHeadless decode of all eth_call items; populates the context store; resolves chain id.
RequestContextStoreStatic map bridging request decode → response decode, keyed by request + item.

com.nccgroup.web3decoder.decoder

FileResponsibility
Web3DataDecoderPer-call orchestration: proxy → ABI source → decode, with detected-pool and 4byte fallbacks. Tolerates a null AbiProvider for chain-agnostic decode.
ABIInputDecoderweb3j-backed engine: selector hashing, type mapping, input/output decode, encode. Has a CLI main().
MulticallRecursiveDecoderDetects/decodes the six Multicall3 aggregate variants recursively.

com.nccgroup.web3decoder.abi

FileResponsibility
IAbiProviderSingle-method interface: getAbi(address).
AbiProviderComposite: cache → builtin → explorer, with caching of explorer hits + lastAbiSource.
CachedAbiProviderReads from the persistent CachedAbis store.
BuiltinAbiProviderServes bundled ABIs (Multicall3 at its canonical address).
EtherscanAbiProviderEtherscan v2 multichain fetch with legacy /api fallback + support cache.
FourByteSignatureProvider4byte selector lookup + synthetic-ABI generation.

com.nccgroup.web3decoder.detection

FileResponsibility
AbiDetectionScanCheckBurp PassiveScanCheck registered as PER_REQUEST. Runs the pipeline on every audited response and raises a Solidity-ABI-detected audit issue per response that introduces a new ABI.
AbiDetectionPipelineStateless facade: body → tokens → boundaries → normalize → validate → deduplicated list of DetectedAbi.
AbiTokenScannerFixed-needle search over the body. Returns ascending byte offsets of candidate ABI internals.
AbiBoundaryExtractorString-aware, depth-tracking walk to the outermost enclosing [{...}] array of each hit. Computes the body's inString bitmap once and reuses it across all hits.
AbiNormalizerJackson lenient parse with minified !0/!1true/false preprocessing, re-serialised as sorted-keys canonical JSON.
AbiValidatorType-vocabulary check, content fingerprint (SHA-256 of canonical JSON), and selector list extracted via AbiSelectorBuilder.
AbiSelectorBuilderShared canonical-signature + 4-byte selector logic. Extracted from ABIInputDecoder so both decoder and validator reuse one implementation.
DetectedAbiImmutable value object: fingerprint, canonical JSON, selectors. Equality and hash are fingerprint-only.
DetectedAbiStoreProject-scoped persistence over Burp PersistedObject (extensionData → detected_ABIs). Maintains an in-memory selector→fingerprint index, FIFO eviction at capacity, and exposes saveIfNew / findBySelector / snapshot / remove.

com.nccgroup.web3decoder.proxies

FileResponsibility
IProxyDetectorSingle-method interface: getImplementationAddress(address).
ProxyDetectorComposite + shared cache; runs each detector in order.
ERC1967ProxyDetectorReads the EIP-1967 implementation storage slot.
ZeppelinOSProxyDetectorReads the legacy ZeppelinOS/OpenZeppelin slot.

com.nccgroup.web3decoder.persistence

FileResponsibility
ExtensionConfigChain registry + API keys (Preferences), deprecated-chain migration, key resolution.
ChainInfoJackson POJO: chainId, name, explorer, explorerAPIKey.
CachedAbisABI cache over Burp PersistedObject, keyed chainId_address.

com.nccgroup.web3decoder.annotation

FileResponsibility
Web3HistoryAnnotatorHttpHandler that annotates Burp's Proxy/HTTP history rows with the decoded Web3 function name (synchronously, before the handler returns). Also threads the shared DetectedAbiStore into the context decoder.
AnnotationNoteBuilderBuilds the actual annotation string from a decoded request (multicall-aware).

com.nccgroup.web3decoder.ui

FileResponsibility
MainChainsPanel2×2 dashboard. The bottom-left slot is a JSplitPane of "Cached ABIs" + "Detected ABIs" when a detected pool is wired.
ChainsListPanelChain CRUD table, per-chain + shared Etherscan API key management.
CachedAbisListPanelCached-ABI list; add manually or fetch from explorer; remove.
DetectedAbisListPanelDetected-ABI list (fingerprint, function count, first-seen URL); open in editor; remove.
AbiEditorPanelView/edit/save a cached ABI (setAbi) or view a detected ABI read-only with a context header (setDetectedAbi).
CalldataCodecPanelStandalone decode/re-encode tool with optional RPC + proxy + multicall.

com.nccgroup.web3decoder.ui.editor

FileResponsibility
Web3JsonEditorPublic reusable Swing JSON editor component; assembles gutter, text pane, and search bar. Used by both HTTP message tabs and the Calldata Codec.
JsonStyleScannerPure-logic scanner; produces a list of StyleSpan (token ranges + StyleKind) from raw JSON text.
JsonSearchEnginePure-logic search; finds all match ranges for a query string within the editor text.
JsonValidatorPure-logic validator; checks JSON well-formedness and reports the first error offset.
BracketMatcherPure-logic matcher; locates the paired bracket for a given caret position; also defines StyleKind, StyleSpan, and Range value types.
EditorThemeSwing support; defines color constants (background, tokens, highlights) for the editor.
LineNumberGutterSwing support; JComponent painted alongside the text pane to show line numbers.
SearchBarSwing support; toolbar panel wiring together the search field, match navigation, and result count label.

Resources

ResourcePurpose
resources/chains.jsonDefault chain registry (chainId → {name, explorer}); merged with user Preferences at load. All entries target the unified Etherscan v2 host api.etherscan.io.
resources/builtin-abis/multicall3.jsonCanonical Multicall3 ABI served by BuiltinAbiProvider for 0xca11bde0…ca11 on every chain.

Tests

JUnit 5 + Mockito, under src/test/java/com/nccgroup/web3_decoder/:

TestCovers
decoder/ABIInputDecoderTestCore type encode/decode (scalars, arrays, tuples).
decoder/ABIInputDecoderRealTransactionsTestDecode against captured real-world calldata fixtures.
decoder/NestedStructOutputDecodeTestNested struct/tuple output decoding.
decoder/MulticallRecursiveDecoderTestMulticall variant detection + recursive decode.
decoder/Web3DataDecoderTestPer-call strategy incl. proxy/detected/4byte fallbacks (mocked).
abi/FourByteSignatureProviderTestSelector lookup + synthetic ABI generation.
detection/AbiTokenScannerTest / AbiBoundaryExtractorTest / AbiNormalizerTest / AbiValidatorTestPer-stage unit tests for the passive detection pipeline.
detection/AbiSelectorBuilderTestCanonical signature / selector calculation.
detection/AbiDetectionPipelineTestFacade integration test, including a real-bundle excerpt fixture.
detection/DetectedAbiStoreTestPersistence + selector index + FIFO eviction + restart-reload semantics.
detection/AbiDetectionScanCheckTestScan check happy path, dedup contract, audit-issue detail format.
RequestContextStoreTestContext store keying/retrieval semantics.

Fixtures live in src/test/resources/ (sample contract ABIs, decoder edge cases, captured real-transaction cases, and a trimmed minified-bundle excerpt for ABI detection at abi-detection/hive-auth-svelte-excerpt.js).

Notes & loose ends

  • gradle/libs.versions.toml is a gradle init leftover (declares guava and a junit-jupiter alias) and is not referenced by build.gradle, which pins versions directly. Treat the catalog as vestigial.
  • Main-Class is ABIInputDecoder — the packaged jar doubles as a small CLI for decoding/encoding from an ABI file (see TECH_STACK.md).
  • Jackson and BouncyCastle are not declared directly; they arrive transitively through org.web3j:core.