Skip to content

Add a designed, CI-verified sdk-js cookbook (69 recipes) + agent on-ramp - #1199

Open
lamentierschweinchen wants to merge 26 commits into
multiversx:developmentfrom
lamentierschweinchen:cookbook-design-layer
Open

Add a designed, CI-verified sdk-js cookbook (69 recipes) + agent on-ramp#1199
lamentierschweinchen wants to merge 26 commits into
multiversx:developmentfrom
lamentierschweinchen:cookbook-design-layer

Conversation

@lamentierschweinchen

@lamentierschweinchen lamentierschweinchen commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

What this is

A structured, browsable replacement for docs/sdk-and-tools/sdk-js/sdk-js-cookbook-v15.md (the ~128 KB single-file cookbook): 69 atomic, copy-paste recipes across 13 sections, each solving one concrete task and showing every file it needs. It covers sdk-core, sdk-dapp v5, and the sdk-rs contract framework where that is the right tool.

Three things make it more than a reorganization:

  1. Every recipe's code is CI-verified. A new TypeScript verification harness extracts the code fences from each page and runs tsc --noEmit --strict over them. The teal Verified badge on a recipe means that check passed on the date shown. What a reader copies is what compiles.
  2. It is designed. A small set of React components renders a per-recipe meta strip (difficulty, estimated time, verified badge, SDK versions) and a browsable card index, styled on the MultiversX design tokens.
  3. It has an agent on-ramp. A "Agent or agentic engineer? Start here" page routes human developers to recipes and coding agents to the machine-readable surface (llms.txt / llms-full.txt), which now includes every recipe.

Why

The current sdk-js-cookbook-v15.md is a single 128 KB file. This restructures the same intent into a per-recipe, navigable, verifiable cookbook. It is a strict superset: a coverage diff against the existing v15 (and v14 where still relevant) confirmed that every topic it covers is present here, and gaps were filled before this PR. Nothing the current cookbook has is dropped.

The CI harness (mirrors your existing Rust tutorial CI)

The repo already verifies tutorial code for Rust: testing/extract-tutorial-code extracts fenced code from the crowdfunding tutorial and runs cargo test (testing/rust-tutorial-ci.sh, .github/workflows/rust-tutorial-ci.yml). There was no equivalent for JS/TS, so the sdk-js cookbook's code was untested.

This PR adds the TS mirror of that exact pattern:

Existing (Rust) Added (TypeScript)
testing/extract-tutorial-code/ testing/cookbook-ts/
testing/rust-tutorial-ci.sh testing/cookbook-ts-ci.sh
.github/workflows/rust-tutorial-ci.yml .github/workflows/cookbook-ts-ci.yml
cargo runcargo test npm run extracttsc --noEmit --strict

Only titled fences (```ts title="src/foo.ts") are extracted and type-checked; untitled fences and bash/text blocks are illustrative. testing/cookbook-ts/CONVENTION.md documents the authoring rule ("what is shown is what is compiled").

Footprint (deliberately small)

  • src/components/cookbook/ — a handful of plain React + CSS-module components (RecipeCard, the meta chips, the verified badge, the index grid).
  • src/theme/DocItem/Content/index.js — one guarded swizzle that renders the meta strip only on cookbook pages (frontmatter-gated); all other docs are untouched.
  • src/css/cookbook.css — a scoped Infima reskin on the MultiversX tokens; no global chrome is changed.
  • scripts/generate-cookbook-manifest.js — build-time index manifest from recipe frontmatter.
  • scripts/generate-llms-txt.js — extended (not forked) so recipes appear in llms.txt / llms-full.txt.

Verification

  • testing/cookbook-ts-ci.sh (npm ci → extract → tsc --noEmit --strict): green.
  • docusaurus build: green; zero broken links originate from or point into the cookbook.
  • codespell (your .codespell config): clean.
  • markdownlint (your .markdownlint.jsonc): clean except one MD033/no-inline-html on the index page's <CookbookIndex> grid component (intrinsic to rendering the card grid; markdownlint is not a CI gate here and does not scan .mdx by default).

Decisions for the maintainer

  1. Replaces sdk-js-cookbook-v15.md. This PR removes the v15 monolith and adds a client redirect from its URL (/sdk-and-tools/sdk-js/sdk-js-cookbook) to the new cookbook index, and repoints the five in-repo links that pointed into it (the three anchored ones now target the specific new recipes). Coverage was diffed first, so nothing the old cookbook covered is lost. The v14 legacy file is untouched. If you would rather keep v15 around for a deprecation window, that is a one-line revert.
  2. The TS CI workflow. New for JS/TS docs. It mirrors your Rust one and keeps the cookbook honest, but it is a workflow your team would own. If you would rather not add JS CI, the recipes still stand as designed pages.
  3. One superset tsconfig compiles all recipes together (a small strictness relaxation for maintainability); per-recipe configs are the alternative.
  4. MD033 on the index (the <CookbookIndex> grid) — kept, since suppressing it via an HTML comment would break MDX parsing.
  5. Agent stack references are conservative: the on-ramp links the existing learn/ai-agents page and the served llms.txt, and does not feature emerging/devnet-preview items to avoid overclaiming on a docs surface.

Credit

Recipes were authored and verified against the live network and the installed SDKs (sdk-core 15.4.1, sdk-dapp v5). Verification surfaced a handful of real SDK issues along the way, which are being reported to the sdk-js team separately.


Round 3 — reviewer findings addressed

All nine findings from the 2026-07-27 audit are fixed on 8890854d.

F1 (blocker), advisory gate. next pins postcss@8.4.31 as an exact dependency, and so does next@latest, so no Next release resolves the two PostCSS advisories. @multiversx/sdk-dapp and @multiversx/sdk-dapp-ui are already at their latest published versions, so the brace-expansion chain has no upstream bump either. Overrides were therefore the only available mechanism: postcss now resolves to 8.5.25 and brace-expansion to 5.0.8. Both packages disappear from the audit output rather than being suppressed. The allowlist is unchanged at a single sharp entry, and the two remaining high entries are sharp and next, where next.via is exactly ["sharp"]. The overrides are applied to the ten recipe manifests that pull the affected packages, not only to the test harness, so a reader copying any starter gets the patched tree.

F2 (blocker), transaction lifecycle. sign-and-send no longer reports completion before confirmation. done is set only from sdk-dapp's session-specific onSuccess callback; the state moves to tracking when the send promise resolves, and submission stays disabled for the whole signing/tracking window. A synchronous guard rejects a same-tick second submission before React renders disabled=true, and an early-terminal path covers the callback landing before the send promise resolves. The dead sending state is removed. Three runtime lifecycle tests cover success, failure, and a rejected rapid second submission.

F5. audit-project.mjs accepts --directory, and each of the five freshly installed dependency environments is audited before its projects build, so the gate now covers the trees actually built rather than only the committed lock.

F3 browser-only scope corrected and the useGetPendingTransactions arity fixed. F4 static/llms*.txt untracked and ignored, matching the manifest's existing generate-and-ignore policy; a clean build no longer dirties the tree. F6 stray fence removed. F7 expected-output count corrected to four. F8 clientName added across all entrypoint constructions.

Non-cookbook work included in this comparison

The reviewer comparison starts at 11e23b17, while this branch was created from
the merged main snapshot 0fa8ec03. That starting snapshot already contained
three documentation changes unrelated to the cookbook:

  • docs/sdk-and-tools/rest-api/gateway-overview.md: adds public Gateway rate
    limits. This round also removes the stray final code fence found during
    review.
  • docs/sdk-and-tools/rest-api/multiversx-api.md: expands REST and WebSocket
    rate-limit guidance.
  • docs/welcome/terminology.md: rewrites glossary headings, cross-links, and
    source labels across the full terminology page.

They remain in the branch because they were inherited from its merged base, not
introduced by a cookbook commit, and the round-3 decision is to avoid a late
history split. Review ownership for those three files therefore remains
explicitly separate from cookbook ownership.

The branch also changes these files outside the cookbook directory as required
cookbook integration work:

  • docs/developers/relayed-transactions.md,
    docs/developers/sc-calls-format.md,
    docs/developers/signing-transactions/signing-programmatically.md,
    docs/sdk-and-tools/overview.md, and
    docs/sdk-and-tools/sdk-js/writing-and-running-sdk-js-snippets.md retarget
    inbound links from the deleted v15 monolith to the relevant recipe or index.
  • docusaurus.config.js redirects the former v15 cookbook URL, and
    sidebars.js replaces the monolith entry with the categorized recipe tree.

Those cross-link, redirect, and navigation edits are kept with the cookbook so
the replacement does not ship dead inbound routes.

popenta and others added 16 commits July 6, 2026 13:46
…lar recipes

Add a TypeScript verification harness for the sdk-js cookbook, mirroring the
repo's Rust tutorial CI (testing/rust-tutorial-ci.sh + extract-tutorial-code):

- testing/cookbook-ts/: a fence extractor (parser.ts + extract.ts) that pulls
  titled ts/tsx fences from cookbook recipe MDX into a strict TS project, plus
  CONVENTION.md documenting the authoring convention.
- testing/cookbook-ts-ci.sh + .github/workflows/cookbook-ts-ci.yml: extract then
  tsc --noEmit --strict, the "what is shown is what is compiled" gate.
- Three exemplar recipes ported to docs/sdk-and-tools/sdk-js/cookbook/, carrying
  the meta-strip frontmatter the Track A swizzle reads: a read-side
  network-providers recipe, a write-side transactions recipe, and a dApp/React
  sdk-dapp recipe.
- sidebars.js: a "Cookbook (recipes)" category.

Verified: extractor assembles 10 files across 3 recipes; tsc --noEmit --strict
passes; a deliberate type error is rejected (TS2322); Docusaurus build is green
with the meta strip server-rendered; markdownlint + codespell pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Port 14 recipes onto the proven TS-verification harness + design layer:

- start-here (5): vite-react-minimal, nextjs-minimal, local-https-setup,
  sign-and-send, v4-to-v5-migration
- migration (3): dapp-provider-to-initapp, get-account-info-v4-vs-v5,
  send-transactions-to-transaction-manager
- wallets (6): wallet-login-button, defi-extension-login, walletconnect-login,
  ledger-login, native-auth, typescript-strict-mode-checklist

Each page inlines its source verbatim as titled ts/tsx fences (v4 "before"
and next/vite config files shown as untitled illustrative fences since they
can't compile against the harness deps). Internal-only doc references scrubbed
from comments. Sidebar wired under "Cookbook (recipes)".

Verified: cookbook-ts extract + tsc --noEmit --strict green (57 files / 16
recipes incl. exemplars); docusaurus build green, all pages generate, no new
broken links; markdownlint + codespell clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Port the entire prototype `accounts` section (14 recipes) onto the proven
TS-verification template, under docs/.../cookbook/accounts/:

- Key management: generate-mnemonic-derive-keys, account-from-keys,
  keystore-save-load, pem-save-load
- Addresses & state: address-utilities, fetch-account-state, manage-nonces
- Signing: sign-verify-message, sign-verify-transaction,
  hash-signing-transaction
- Guardians & relayed: set-guardian, guard-unguard-account,
  apply-guardian-to-transaction, relayed-v3-transaction

Each page carries the meta-strip frontmatter (difficulty + sdk_versions),
last_validated normalized to 2026-07-16, Docusaurus admonitions in place of
Starlight <Aside>, and every compile-required source file inlined verbatim as
a titled ts fence. Internal-only references (CLAUDE.md, authoring-process
notes) scrubbed from prose and comments; cross-links to unported pages
reworded to avoid new broken links. Added an "Accounts and signing" category
to sidebars.js under Cookbook (recipes).

Verified: `npm run extract` + `tsc --noEmit --strict` green across all 30
recipes (74 files); markdownlint (0 errors) and codespell clean on the 14 new
pages; `docusaurus build` succeeds with all pages generated and no new broken
links.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Port 13 recipes onto the verified Docusaurus cookbook template:
- tokens (8): issue fungible/NFT/SFT, set special roles, local mint/burn,
  lifecycle (freeze/pause/wipe), fetch metadata, fetch balances
- transactions (3): send-esdt, multi-token-transfer, track-transaction-status
- governance (2): create-proposal, vote-close-proposal

Frontmatter meta strip (difficulty + sdk_versions), admonitions, and titled
code fences match waves 1-2. Public-valuable SDK-bug pitfalls kept (unset-role
wrong-flag, pause/freeze/wipe wrong-receiver, LocaMinting typo); internal-only
references scrubbed. Adds Tokens and Governance sidebar categories and appends
the new transactions.

tsc --noEmit --strict green across all cookbook recipes; Docusaurus build green
with no new broken links; markdownlint and codespell clean on the new pages.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ave 4)

Port 14 recipes onto the verified TS cookbook template:
- network-providers (6): fetch-network-config-status, fetch-a-block,
  await-account-on-condition, await-transaction-on-condition,
  simulate-estimate-transaction, custom-api-request
- delegation (5): create-delegation-contract, delegate-stake,
  claim-and-redelegate-rewards, undelegate-and-withdraw,
  query-delegation-contract
- multisig (3): propose-action, sign-perform-action, read-multisig-state

Add Delegation and Multisig sidebar categories and append the six
network-providers pages to the existing category. Extract + strict tsc,
markdownlint, codespell, and the Docusaurus build all pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…s (wave 5)

Final port wave. Adds 11 recipes across three new "Cookbook (recipes)"
categories:

Smart contracts (call & query): load-abi, query-contract-view,
call-contract-endpoint, call-payable-endpoint, decode-return-data,
decode-contract-events.

Smart contracts (deploy & upgrade): compute-contract-address,
deploy-contract, upgrade-contract.

Smart contracts (Rust authoring): new-contract-from-template,
storage-mapper-decision-table.

The ABI-loading TS recipes take an Abi-typed parameter (subject files) or
read the ABI JSON at runtime via fs (load-abi's index.ts), so every titled
ts fence type-checks under the harness with no bare JSON import. The Rust
authoring recipes ship illustrative rust fences (not extracted/compiled).

Verified: extract + tsc --noEmit --strict green across all 66 recipes;
docusaurus build green with no new broken links; markdownlint and codespell
clean on the 11 new pages.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ss A)

Build the cookbook's browsable entry points on top of the 69 ported recipes
and retire the Track-A demo pages.

- Landing page (docs/.../cookbook/index.mdx, slug = cookbook root) renders all
  69 recipes grouped by the 13 sections via the Track-A RecipeGrid/RecipeCard
  components. Cards are driven by a build-time manifest
  (scripts/generate-cookbook-manifest.js -> src/data/cookbook-manifest.json)
  that reads each recipe's real frontmatter and mirrors the curated sidebar
  order, so no list is hand-maintained. New CookbookIndex component adds a
  manifest-driven jump-nav with per-section counts.
- Agent on-ramp (docs/.../cookbook/agents.mdx) routes human devs to the recipes
  and coding agents to the machine-readable surface (llms.txt / llms-full.txt)
  and the existing learn/ai-agents page (mx-ai-skills). Placed first in the
  cookbook sidebar.
- Retire cookbook-preview.mdx + cookbook-preview-recipe.mdx and their sidebar
  entries; make the index the "Cookbook (recipes)" category link.
- Regenerate static/llms.txt + llms-full.txt: all 69 recipes now appear as
  tagged lines / full content. Wire the manifest generator into prebuild.

Build green; TS harness (extract + tsc --strict) green; codespell clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ass B)

All 69 recipes now exist, so the inter-recipe cross-links the porting waves
dropped (to avoid links to then-unported pages) can be real again. Restore
them from the prototype's see_also curation, and lightly restore em-dashes
where a wave's comma/colon substitution left a run-on.

Cross-links (18 see_also edges across 12 recipes):
- Convert 9 plain-texted "covered in the X recipes" See also bullets back into
  real recipe links (address-utilities, create-delegation-contract,
  create-proposal, fetch-account-state, issue-nft-collection, propose-action,
  query-delegation-contract, vote-close-proposal, manage-nonces).
- Restore the prototype's curated See also set on 3 recipes the waves had
  filled with placeholder links (configure-network-provider,
  read-connected-account, send-egld).
- All targets are real ported pages under
  /sdk-and-tools/sdk-js/cookbook/<section>/<slug>. No fabricated links.
  wallet-login-button left as-is: its rendered base-setup link (vite-react-minimal)
  is correct; the stale frontmatter see_also (nextjs-minimal) was never rendered.

Em-dashes (6 surgical restorations, 5 recipes): manage-nonces (x2),
await-account-on-condition, await-transaction-on-condition, native-auth,
simulate-estimate-transaction, only where a comma splice or emphatic appositive
read as a run-on. No code fences touched.

Additive, prose-only. Verified green: extract + tsc --noEmit --strict via
testing/cookbook-ts-ci.sh; Docusaurus build (zero cookbook broken links);
markdownlint-cli2 (only the known index.mdx MD033/CookbookIndex); codespell clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Surgical copy pass across the sdk-js cookbook recipe pages. Removes the self-narrating "this recipe shows/demonstrates/walks" frame, throat-clearing ("worth noting", "it is tempting to", "the point is"), and cutesy filler ("out of the box", "under the hood") in favour of plain, direct wording matching the already-rewritten index/agents front door.

Prose only: no code fences, links, admonitions, or technical claims changed. 17 recipe pages edited; the rest left as-is. Front-door index/agents rewrites (already done) are included in this commit.

Verified: docusaurus build green (no new broken links); cookbook-ts extract + tsc --noEmit --strict green; markdownlint + codespell clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@lamentierschweinchen
lamentierschweinchen marked this pull request as ready for review July 16, 2026 12:13
@popenta
popenta changed the base branch from main to development July 16, 2026 13:01
lamentierschweinchen and others added 10 commits July 21, 2026 09:00
The generated manifest and llms files are no longer committed, and the
prebuild lifecycle hook only fires on 'npm run build'. Without this,
'npm start' would come up with a missing cookbook manifest.
- Bump next 15.5.18 -> 15.5.21 in both starters and the harness (clears the new
  Server Actions DoS + SSRF HIGH advisories). Regenerated lockfiles; both Next
  production builds pass on Node 20.19.0.
- Add a dependency-free high/critical npm-audit gate (testing/cookbook-ts/audit-project.mjs)
  wired as its own CI step. It fails on any new high and allow-lists only the
  unreachable sharp/libvips advisory (no recipe uses next/image). Closes the
  advisory-treadmill gap so a future Next CVE fails CI, not a reviewer.
- Declare gray-matter@4.0.3 directly (was resolving via a Docusaurus transitive hoist).
- Soften the two Rust reference pages to 'manually verified at authoring time,
  not continuously built'.
- gitignore /src/data/ so builds no longer leave the generated manifest untracked.

Per maintainer decision: the tracked static/llms*.txt keep their current (old)
versions; regeneration comes as a separate PR. Targets development.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…erated artifacts

F1: postcss and brace-expansion resolved via overrides to 8.5.25 and 5.0.8.
next pins postcss 8.4.31 exactly (so does next@latest), and sdk-dapp /
sdk-dapp-ui are already at their latest published versions, so no upstream
bump exists for either chain. Overrides applied to the ten recipe manifests
that pull the affected packages, not only the test harness, so a reader
copying a starter gets the patched tree. Allowlist unchanged at one entry.

F5: audit-project.mjs takes --directory; each of the five freshly installed
dependency environments is audited before its projects build.

F2: sign-and-send no longer reports completion before confirmation. 'done' is
set only from sdk-dapp's session-specific onSuccess callback; the state moves
to 'tracking' when send resolves and submission stays disabled through it. A
synchronous guard rejects a same-tick second submission before React renders
disabled=true, and an early-terminal path covers the callback landing before
the send promise resolves. The dead 'sending' state is removed. Three runtime
lifecycle tests added.

F3: helper re-described as React-independent browser-side sdk-dapp code;
server and CLI use pointed at sdk-core. useGetPendingTransactions arity fixed.
F4: static/llms*.txt untracked and ignored, matching the manifest policy.
F6: stray fence removed. F7: expected-output count corrected to four.
F8: clientName added across all entrypoint constructions.
F9: non-cookbook changes disclosed in the PR description.

Verified on Node 20.19.0: advisory gate green, 11/11 extractor tests,
3/3 lifecycle tests, strict TypeScript, 5/5 environments audited,
61/61 projects built, 8/8 Vite and 2/2 Next production builds, clean
Docusaurus build, 6 offline and 10 live read-only runtime examples.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@lamentierschweinchen

Copy link
Copy Markdown
Contributor Author

Reply to Alexandru — review round 3

Post as a PR comment when the branch is pushed.


Thanks for the round-3 pass, and for running the whole matrix yourself. Both blockers are fixed, along with F3 through F9. Everything below was re-verified from the repository root on Node 20.19.0.

F1 — advisory gate is green.

next pins postcss@8.4.31 as an exact dependency, and so does next@latest, so no Next release resolves the two PostCSS advisories. @multiversx/sdk-dapp@5.7.1 and @multiversx/sdk-dapp-ui@0.1.24 are already the latest published versions, so the brace-expansion chain has no upstream bump either. Overrides were the only mechanism available.

postcss now resolves to 8.5.25 and brace-expansion to 5.0.8. Both packages have disappeared from the audit output entirely rather than being suppressed. The allowlist is unchanged at a single entry, and the only remaining high findings are sharp and next, where next.via is exactly ["sharp"] — it inherits the one documented exception.

The overrides are applied to the ten recipe manifests that actually pull the affected packages, not only to the test harness. A reader copying any starter gets the patched tree. The other 51 projects are unaffected and were left alone.

F5 — the gate now audits what is built. audit-project.mjs takes a --directory argument, and each of the five freshly installed dependency environments is audited before its projects build. The --ignore-scripts limitation is documented.

F2 — lifecycle and nonce reuse.

'done' is now set only from sdk-dapp's session-specific onSuccess callback. When sendEgld() returns, the state moves to 'tracking', and submission stays disabled for the whole signing/tracking window. A synchronous guard rejects a second submission in the same tick, before React has rendered disabled=true, and an early-terminal path handles the case where the callback fires before the send promise resolves. The dead 'sending' state is gone.

Three runtime tests cover it: sent to pending to confirmed success, sent to pending to confirmed failure, and a rapid second submission rejected until the first session reaches a terminal state.

F3. Re-described as React-independent, browser-side sdk-dapp code, with server and CLI use pointed at sdk-core with its own signer and network provider. The useGetPendingTransactions(sessionId) references are corrected.

F4. Both static/llms*.txt are untracked and ignored, matching the recipe manifest's existing generate-and-ignore policy, and generation is wired into build, start and deploy. A clean build no longer dirties the tree.

F6. Stray fence removed. F7. Corrected to four. F8. clientName added across all 45 entrypoint constructions; no bare new DevnetEntrypoint() remains.

F9. The pull-request description now has a labelled section listing the non-cookbook changes carried by the branch, so ownership is explicit rather than implied.

Verification: advisory gate green, 11/11 extractor tests, 3/3 lifecycle tests, strict TypeScript, 5/5 fresh environments audited, 61/61 projects built across five dependency sets, 8/8 Vite and 2/2 Next production builds, clean Docusaurus build with no new broken links, six offline runtime examples and ten live read-only examples. No transaction was broadcast.

Happy to walk through any of it.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants