neo-decompiler 0.11.0

Neo N3 NEF decompiler: parse, disassemble, lift bytecode to high-level pseudocode and C# skeletons, with a CLI, JSON reports, and optional WebAssembly bindings.
Documentation
use crate::disassembler::Disassembler;
use crate::error::Result;
use crate::nef::NefParser;
use crate::Decompiler;

use super::common::{parse_manifest, unknown_handling};
use super::options::{WebDecompileOptions, WebDisasmOptions};
use super::report::{self, WebDecompileReport, WebDisasmReport, WebInfoReport};

/// Build a browser-friendly NEF info report from in-memory bytes.
///
/// The optional manifest input should be a UTF-8 JSON string.
///
/// # Errors
///
/// Returns an error if the NEF container or manifest is invalid.
pub fn info_report(nef_bytes: &[u8], manifest_json: Option<&str>) -> Result<WebInfoReport> {
    info_report_with_manifest_options(nef_bytes, manifest_json, false)
}

pub(super) fn info_report_with_manifest_options(
    nef_bytes: &[u8],
    manifest_json: Option<&str>,
    strict_manifest: bool,
) -> Result<WebInfoReport> {
    let parse_output = NefParser::new().parse_with_warnings(nef_bytes)?;
    let nef = parse_output.nef;
    let warnings = parse_output
        .warnings
        .iter()
        .map(ToString::to_string)
        .collect::<Vec<_>>();
    let manifest = parse_manifest(manifest_json, strict_manifest)?;
    Ok(report::build_info_report(
        &nef,
        manifest.as_ref(),
        &warnings,
    ))
}

/// Build a browser-friendly disassembly report from in-memory bytes.
///
/// # Errors
///
/// Returns an error if the NEF container is invalid or disassembly fails.
pub fn disasm_report(nef_bytes: &[u8], options: WebDisasmOptions) -> Result<WebDisasmReport> {
    let handling = unknown_handling(options.fail_on_unknown_opcodes);
    // Parse the NEF directly so the report can surface script_hash alongside
    // the instruction stream, preserving parity with info/decompile reports
    // while keeping non-fatal parse warnings.
    let parse_output = NefParser::new().parse_with_warnings(nef_bytes)?;
    let nef = parse_output.nef;
    let warnings = parse_output
        .warnings
        .iter()
        .map(ToString::to_string)
        .collect::<Vec<_>>();
    let output =
        Disassembler::with_unknown_handling(handling).disassemble_with_warnings(&nef.script)?;
    Ok(report::build_disasm_report(&nef, output, &warnings))
}

/// Build a browser-friendly decompilation report from in-memory bytes.
///
/// # Errors
///
/// Returns an error if the NEF container or optional manifest is invalid, or
/// if disassembly/decompilation fails.
pub fn decompile_report(
    nef_bytes: &[u8],
    options: WebDecompileOptions,
) -> Result<WebDecompileReport> {
    let manifest = parse_manifest(options.manifest_json.as_deref(), options.strict_manifest)?;
    let handling = unknown_handling(options.fail_on_unknown_opcodes);
    let decompiler = Decompiler::with_unknown_handling(handling)
        .with_inline_single_use_temps(options.inline_single_use_temps)
        .with_trace_comments(options.emit_trace_comments)
        .with_typed_declarations(options.typed_declarations);
    let result =
        decompiler.decompile_bytes_with_manifest(nef_bytes, manifest, options.output_format)?;
    Ok(report::build_decompile_report(result))
}