← Contract Hero · WorkLearnPlugins
acc-evm-wal
Lesson 02 · TypeScript

Publish a static frontend as a Sui object without leaving Claude Code.

Port publish.sh to TypeScript: validate publish inputs, build the site-builder argv, parse the site_object_id out of stdout, then construct the SuiNS link Move call that points a name at the new site. Replaces the IPNS + Cloudflare gateway stack with one Sui object and one SuiNS transaction.

Slug: 02-walrus-sites Stack: TS · vitest · viem-free Sections: 4 Final gate: pnpm vitest run · 23 tests

What you'll write

Two TypeScript modules — src/publish.ts (input validation, argv building, output parsing) and src/suins-link.ts (the SuiNS Move call payload). Pure functions only; the vitest suite asserts on return values without ever spawning a real CLI.

  • s01 · validate inputs

    Validating publish inputs

    The site-name regex ^[A-Za-z0-9._-]{1,64}$ is a conservative-shell-safety hat. site-builder itself accepts almost anything, but the name flows through bash wrappers, CI logs, and (after linking) a SuiNS label — restricting it to filename-safe characters means no entry in the pipeline has to defend against quoting, control chars, or pathological lengths.

  • s02 · build argv

    Building the site-builder argv

    --context <network> is a GLOBAL flag on site-builder, not a subcommand flag — it must precede publish in the argv. The function returns the argv as a string array (not a single shell-quoted string) so callers feed it to execFile / spawn, which sidesteps shell injection on the site name.

  • s03 · parse output

    Parsing site_object_id from stdout

    Anchoring on the line shape (with the m regex flag) rather than greedy text matching keeps the parser tolerant to upstream log changes — a future CLI version can rearrange the surrounding text without breaking us as long as the line site_object_id: 0x<hex> survives.

  • s04 · suins link

    Building the SuiNS link Move call

    One Sui Move call to <suins-pkg>::controller::set_target_walrus_site, taking the NameRegistration object id and the site object id (in that order). Returning the payload as data — { target, args } — instead of a built Transaction lets the test assert on PTB shape without pulling in @mysten/sui, and lets the caller pick either tx.moveCall(...) or sui client call.

Verification

Two vitest suites, 23 tests total. Run them inside the workspace:

pnpm install
pnpm vitest run

publish.test.ts (16) covers validation, argv layout, stdout parsing, and the MAX_EPOCHS=53 Walrus cap. suins-link.test.ts (7) pins the target string, arg order, network-keyed package id, and the package-id override path.

Sources

Read the reference-app on GitHub, or follow the design context on the upstream walkthrough.