Skip to content

Expose a JSON codec in the Tolk stdlib (typed accessors over fs.readFile) #1096

@zakrad

Description

@zakrad

Summary

There is currently no way to parse JSON from Tolk. fs.readFile can load a .json file, but the result is an unparsable string. This proposes a small JSON module that mirrors the typed-accessor pattern already used by @acton/env.

Motivation

The stdlib's own fs.readFile doc-comment demonstrates the gap:

val configJson = fs.readFile("config/test-settings.json"); // ...then what?

Concrete use cases in tests and scripts:

  • Load test fixtures / config (settings, expected values, scenario tables).
  • Read TEP-64 off-chain/on-chain jetton & NFT metadata.
  • Parse deploy-script inputs and write deployment artifacts (pairs with the existing fs.writeString).

This is the Tolk analog of Foundry's vm.parseJson*. Note Acton already has the harder pieces — fs.* (read/write), ffi.env*, world-state snapshot load/save — so JSON is the missing primitive, not the mechanism.

Proposed API (typed accessors, mirroring @acton/env)

Tolk has no dynamic/variant type, so the natural shape is to return typed values by JSON path rather than a generic object — exactly how @acton/env parses env vars into int/bool/coins/etc:

// @acton/json (illustrative)
fun json.getInt(src: string, path: string): int?
fun json.getBool(src: string, path: string): bool?
fun json.getString(src: string, path: string): string?
fun json.getAddress(src: string, path: string): address?
fun json.exists(src: string, path: string): bool
// optional: fun json.stringify(...) for the write/serialize direction

Open questions: path syntax ($.a.b[0] JSONPath-lite vs dotted keys) and number handling (TON ints are 257-bit; reject/clamp JS-style floats).

Why it's feasible

  • The host already bundles a JSON parser (serde_json) — used internally for ABI output, world-state snapshots, and metadata.
  • fs.readFile already delivers the bytes; this just adds the parse step over the existing ffi/host bridge.

Scope / non-goals

  • Pure, deterministic string→value parsing only. No new hermeticity cost (env vars and fs reads already cross that line).
  • Explicitly not proposing arbitrary external-command execution (vm.ffi-style) here — that is a separate, gated discussion.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions