Skip to content

feat: custom proposal templates (authoring + fill + opt-in gating) - #993

Merged
frol merged 3 commits into
NEAR-DevHub:mainfrom
khorolets:feat/custom-proposal-templates
Jun 29, 2026
Merged

feat: custom proposal templates (authoring + fill + opt-in gating)#993
frol merged 3 commits into
NEAR-DevHub:mainfrom
khorolets:feat/custom-proposal-templates

Conversation

@khorolets

Copy link
Copy Markdown
Contributor

Hello Trezu team! Love the project, great job!

Motivation

My colleague reached me out with the case that is solvable by DAO and I was sure it's a perfect match for Trezu. However, I've figured that Trezu is focused on the payments use-cases and doesn't support the creation of other FunctionCall proposals. That was a missing piece to be a perfect fit for us.

That's why I brought you Custom Proposal Templates [engine].

The improvement that covers advanced use-cases and doesn't affect those who don't care. With this feature enabled any Trezu user can create a form to submit a proposal they need, fully customizable for their use case with close to no limits.

How it works

The sad part, it requires some Domain Specific Language (DSL) to describe the form that will be rendered using the Trezu shared components (natively). As the base for the language I've chosen the familiar JSON and tried to keep the DSL as simple as possible.

The documentation for the feature and DSL is ready for review in the corresponding repository NEAR-DevHub/trezu-docs#9

To avoid poking around with the JSON directly this PR introduces a visual constructor for the custom proposal requests. To cover everyone this PR also contains a distributable skill for the LLM agents so any user can install the skill to whatever they use (claude-code, claude chat, codex, etc.) and ask the LLM to generate the form they need and just paste it.

Notes on backend

Since the feature is built to be native for Trezu, it needs to store data and it does it in the Trezu DB. All the CRUD API, all the tests are in place.

Notes on frontend

As agreed with the Trezu team the feature is opt-in, a new Developer category is introduced in the Settings (ref: #974). All the requirements and recommendations of UI/UX designer have been followed and double-checked.

Unit and playwright e2e tests created.

Demo

I am attaching a recording of the end-to-end demo of the feature. Small note: the designer pointed that all the buttons labels must start each word from the capital letter and the demo was captured before this change. The titles are correct in the PR

demo_apple2.mp4

Notes for reviewers:

  • I've noticed you squash commits so I brought everything in a single one. The story behind is that I had 20 commits and a rebase with upstream would require resolving the same conflicts over and over to be ended in a squashed commit, so that's why it's a single one.
  • The commit touches some repo meta like CLAUDE.md, docs/, skills/. Just letting you know so it's not a surprise (I've already mentioned about the skill for DSL)

P.S.: I've decided to avoid poisoning readers of the PR description with the ai-written one, so it might be not that well-covered. Please let me know if you have any areas you need me to elaborate.

Reusable templates for arbitrary FunctionCall proposals: a manifest DSL, Visual/Code authoring, a generated fill form, and per-treasury opt-in. ChangePolicy-gated writes; the produced proposal is an ordinary FunctionCall. Includes nt-be CRUD API + tests, nt-fe engine/UI + unit + e2e, docs and an authoring skill. Logging uses tracing to match the backend.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds an opt-in “Custom Requests / Request Templates” feature that lets DAOs author, store, and fill manifest-driven custom FunctionCall proposal forms (with a visual builder + code editor), plus supporting backend CRUD/flag endpoints and documentation/agent skills.

Changes:

  • Implement manifest schema + placeholder substitution + form-schema generation + visual draft/args-tree tooling (with unit tests) for authoring and filing custom templates.
  • Add backend storage and CRUD endpoints for proposal_templates, plus a per-treasury custom_requests_enabled flag (ChangePolicy-gated) and expanded test scaffolding.
  • Wire opt-in exposure via Settings → Developer, sidebar navigation (including pinned templates), and an onboarding tour; add docs and distributable skills.

Reviewed changes

Copilot reviewed 56 out of 64 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
skills/trezu-custom-proposal-template/SKILL.md Portable LLM skill spec to generate template manifest JSON without repo access.
skills/trezu-custom-proposal-template/README.md Installation/usage instructions for the portable skill.
.agents/skills/author-custom-proposal-template/SKILL.md Repo-local agent skill for authoring/editing manifests against Trezu’s validator.
docs/CUSTOM_PROPOSAL_TEMPLATES.md Canonical DSL + architecture + UX documentation for custom proposal templates.
CLAUDE.md Adds a pointer to the new custom templates documentation.
nt-fe/features/proposal-templates/types.ts Frontend type for backend-returned proposal templates.
nt-fe/features/proposal-templates/api.ts Axios client for templates CRUD + custom-requests flag endpoints.
nt-fe/features/proposal-templates/hooks/use-proposal-templates.ts React Query hook to list templates for the current treasury.
nt-fe/features/proposal-templates/hooks/use-proposal-template-mutations.ts React Query mutations + targeted cache invalidation for template CRUD.
nt-fe/features/proposal-templates/hooks/use-custom-requests-enabled.ts React Query hook/mutation for the opt-in custom-requests flag.
nt-fe/features/proposal-templates/manifest.ts Zod manifest validator + placeholder extraction/substitution helpers.
nt-fe/features/proposal-templates/manifest.test.ts Unit tests for manifest validation, placeholder rules, and error formatting.
nt-fe/features/proposal-templates/form-schema.ts Builds RHF/zod validation + default values from a validated manifest.
nt-fe/features/proposal-templates/form-schema.test.ts Unit tests for form-schema validation and default value coercion.
nt-fe/features/proposal-templates/error-map.ts Maps path: message errors to inline-friendly UI strings.
nt-fe/features/proposal-templates/error-map.test.ts Unit tests for error mapping and inline-path routing.
nt-fe/features/proposal-templates/build-proposal.ts Engine: manifest + filled values → SputnikDAO FunctionCall proposal payload.
nt-fe/features/proposal-templates/build-proposal.test.ts Unit tests for args interpolation and proposal construction.
nt-fe/features/proposal-templates/draft.ts Visual-builder draft model + manifest↔draft conversion + field normalization.
nt-fe/features/proposal-templates/draft.test.ts Unit tests for draft round-tripping, lenient hydration, normalization behavior.
nt-fe/features/proposal-templates/args-node.ts Args-tree editor helpers (value typing, dynamic arg detection, dupe keys).
nt-fe/features/proposal-templates/args-node.test.ts Unit tests for args-node helper behaviors.
nt-fe/features/proposal-templates/components/manifest-form.tsx Renders a validated manifest as a fillable form (RHF + design system).
nt-fe/features/proposal-templates/components/template-editor.tsx Shared create/edit authoring UI with Visual/Code modes and validation gating.
nt-fe/features/proposal-templates/components/visual-builder.tsx Visual authoring UI sections for meta, binding, args-tree, and field config.
nt-fe/features/proposal-templates/components/touched-gating.test.tsx Ensures “no red until touched” behavior for authoring UI.
nt-fe/features/onboarding/steps/page-tours.tsx Adds a one-step tour pointing to the newly revealed sidebar section.
nt-fe/features/onboarding/steps/index.tsx Registers the new onboarding tour.
nt-fe/components/animate-ui/icons/code-xml.tsx Adds an animated “code” icon used for the sidebar entry.
nt-fe/components/sidebar.tsx Adds sidebar section gated by custom-requests flag + pinned templates submenu.
nt-fe/app/(treasury)/[treasuryId]/settings/page.tsx Adds a Developer tab (hidden for guest treasuries) and deep-link support.
nt-fe/app/(treasury)/[treasuryId]/settings/components/developer-tab.tsx Developer tab card to enable/disable Custom Requests + fire onboarding tour.
nt-fe/app/(treasury)/[treasuryId]/custom-templates/layout.tsx Layout/metadata for the Request Templates section.
nt-fe/app/(treasury)/[treasuryId]/custom-templates/page.tsx Templates index page (list, pin/unpin, delete, create/edit navigation).
nt-fe/app/(treasury)/[treasuryId]/custom-templates/create/page.tsx Create-template page using TemplateEditor + create mutation.
nt-fe/app/(treasury)/[treasuryId]/custom-templates/[slug]/page.tsx Per-template fill-and-file page (build + submit proposal).
nt-fe/app/(treasury)/[treasuryId]/custom-templates/[slug]/edit/page.tsx Edit/delete page using TemplateEditor + update/delete mutations.
nt-be/migrations/20260619000001_create_proposal_templates.sql Creates proposal_templates table + indexes + updated_at trigger.
nt-be/migrations/20260627000002_add_pinned_to_proposal_templates.sql Adds pinned column for sidebar pinning behavior.
nt-be/migrations/20260627000001_add_custom_requests_enabled.sql Adds per-treasury custom_requests_enabled flag column.
nt-be/src/handlers/proposal_templates.rs Backend CRUD endpoints + manifest structural validation + tests.
nt-be/src/handlers/treasury/custom_requests.rs Backend GET/PUT for custom-requests enable flag + tests.
nt-be/src/handlers/treasury/mod.rs Registers the new custom_requests treasury handler module.
nt-be/src/routes/mod.rs Wires proposal-templates CRUD + custom-requests flag routes.
nt-be/src/handlers/mod.rs Exposes the new proposal_templates handler module.
nt-be/src/handlers/treasury/policy.rs Extracts shared treasury_policy_cache_key helper for caching/test seeding.
nt-be/src/utils/test_utils.rs Adds test helpers for policy seeding, auth cookies, and request dispatch.
nt-be/src/auth/error.rs Centralizes AuthError → (status,message) mapping for reuse by handlers.
nt-be/src/auth/middleware.rs Adds verify_dao_member_for_http and tests around policy evaluation/cache use.
nt-be/src/handlers/address_book.rs Fixes sqlx nullability override for created_by_wallet + regression test.
nt-be/.sqlx/query-fd881f5e05e9494b1ca87f66d411ed04133e0d66df5d949b10f5eb78b0676c37.json sqlx metadata for proposal_templates INSERT.
nt-be/.sqlx/query-f0909d35187099eca523e0e0a0be2547de92116765a206e148e3a80968c975c2.json sqlx metadata for proposal_templates fetch-by-id (with nullable creator).
nt-be/.sqlx/query-e648a256a6492374d9c39511c1ecc63a03f5d653bd018e8a2d90b2951c09081c.json sqlx metadata for proposal_templates UPDATE.
nt-be/.sqlx/query-a999e96f58c9e0f5e0af26d859955ac7c5d65094b52d2944d2551eb735d4861d.json sqlx metadata for proposal_templates LIST.
nt-be/.sqlx/query-498093aafc01d2c8e39728c8edb132571cb34e99964883c0bf99eae3fdbe06f6.json sqlx metadata for proposal_templates DELETE.
nt-be/.sqlx/query-0d0919b0bc0e734a5155a2766337c005bf863105549661b4889b74dc6e60c181.json sqlx metadata for reading custom_requests_enabled.
nt-be/.sqlx/query-3abe05be828d94bd877028f9c5c269ec479c5a5b9dc94a1d1cf254236e6b7382.json sqlx metadata for updating custom_requests_enabled.
nt-be/.sqlx/query-5f205588489df021222df4247d494a6ad21c0216728876d457954378fcaca1a3.json sqlx metadata update for address_book export nullability override.
nt-be/.sqlx/query-3eb239014126a32c3fb4793277485fd23afb943625065102af61fd7432bbfb52.json sqlx metadata update for address_book list nullability override.
nt-be/.sqlx/query-36567cc2245450fcf3089d57db17d3c4a7fc68b261d3081a18728b80eb0142a9.json sqlx metadata update for address_book list (alternate query) nullability override.
nt-be/.sqlx/query-57e6d33d9168ec4314e8db17f256b14eb9cfee654db2842fe5ac72731d3b0df9.json Removes stale sqlx metadata for a confidential_intents query no longer using offline macros.
Files not reviewed (8)
  • nt-be/.sqlx/query-0d0919b0bc0e734a5155a2766337c005bf863105549661b4889b74dc6e60c181.json: Generated file
  • nt-be/.sqlx/query-3abe05be828d94bd877028f9c5c269ec479c5a5b9dc94a1d1cf254236e6b7382.json: Generated file
  • nt-be/.sqlx/query-498093aafc01d2c8e39728c8edb132571cb34e99964883c0bf99eae3fdbe06f6.json: Generated file
  • nt-be/.sqlx/query-57e6d33d9168ec4314e8db17f256b14eb9cfee654db2842fe5ac72731d3b0df9.json: Generated file
  • nt-be/.sqlx/query-a999e96f58c9e0f5e0af26d859955ac7c5d65094b52d2944d2551eb735d4861d.json: Generated file
  • nt-be/.sqlx/query-e648a256a6492374d9c39511c1ecc63a03f5d653bd018e8a2d90b2951c09081c.json: Generated file
  • nt-be/.sqlx/query-f0909d35187099eca523e0e0a0be2547de92116765a206e148e3a80968c975c2.json: Generated file
  • nt-be/.sqlx/query-fd881f5e05e9494b1ca87f66d411ed04133e0d66df5d949b10f5eb78b0676c37.json: Generated file

Comment thread nt-fe/features/proposal-templates/manifest.ts
Comment thread nt-fe/features/onboarding/steps/page-tours.tsx
Comment thread nt-fe/app/(treasury)/[treasuryId]/custom-templates/page.tsx
Comment thread nt-fe/features/proposal-templates/build-proposal.ts Outdated
Comment thread nt-fe/app/(treasury)/[treasuryId]/custom-templates/[slug]/edit/page.tsx Outdated
Comment thread nt-fe/app/(treasury)/[treasuryId]/custom-templates/[slug]/edit/page.tsx Outdated
Comment thread nt-fe/app/(treasury)/[treasuryId]/custom-templates/[slug]/edit/page.tsx Outdated
Comment thread nt-fe/app/(treasury)/[treasuryId]/custom-templates/layout.tsx Outdated
Comment thread nt-fe/app/(treasury)/[treasuryId]/custom-templates/page.tsx
Comment thread nt-fe/components/sidebar.tsx
Comment thread skills/trezu-custom-proposal-template/SKILL.md
Comment thread .agents/skills/author-custom-proposal-template/SKILL.md Outdated
khorolets added a commit to khorolets/trezu that referenced this pull request Jun 29, 2026
…review

- Translate the whole custom-templates feature (customTemplates namespace,
  13 locales) instead of leaving it English-only
- Tour copy via PageTourContent/pageTours.requestTemplates (was hardcoded JSX)
- Sidebar pinned templates use a real <Link> href, not onClick-only
- build-proposal docstring: correct the string-substitution vs typed-args contract
- Drop the agent/portable skills; the DSL is maintained in docs/
khorolets added a commit to khorolets/trezu that referenced this pull request Jun 29, 2026
…review

- Translate the whole custom-templates feature (customTemplates namespace,
  13 locales) instead of leaving it English-only
- Tour copy via PageTourContent/pageTours.requestTemplates (was hardcoded JSX)
- Sidebar pinned templates use a real <Link> href, not onClick-only
- build-proposal docstring: correct the string-substitution vs typed-args contract
- Drop the agent/portable skills; the DSL is maintained in docs/
Copilot AI review requested due to automatic review settings June 29, 2026 16:34
@khorolets
khorolets force-pushed the feat/custom-proposal-templates branch from 4218e78 to f8ad635 Compare June 29, 2026 16:34

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 68 out of 76 changed files in this pull request and generated 5 comments.

Files not reviewed (8)
  • nt-be/.sqlx/query-0d0919b0bc0e734a5155a2766337c005bf863105549661b4889b74dc6e60c181.json: Generated file
  • nt-be/.sqlx/query-3abe05be828d94bd877028f9c5c269ec479c5a5b9dc94a1d1cf254236e6b7382.json: Generated file
  • nt-be/.sqlx/query-498093aafc01d2c8e39728c8edb132571cb34e99964883c0bf99eae3fdbe06f6.json: Generated file
  • nt-be/.sqlx/query-57e6d33d9168ec4314e8db17f256b14eb9cfee654db2842fe5ac72731d3b0df9.json: Generated file
  • nt-be/.sqlx/query-a999e96f58c9e0f5e0af26d859955ac7c5d65094b52d2944d2551eb735d4861d.json: Generated file
  • nt-be/.sqlx/query-e648a256a6492374d9c39511c1ecc63a03f5d653bd018e8a2d90b2951c09081c.json: Generated file
  • nt-be/.sqlx/query-f0909d35187099eca523e0e0a0be2547de92116765a206e148e3a80968c975c2.json: Generated file
  • nt-be/.sqlx/query-fd881f5e05e9494b1ca87f66d411ed04133e0d66df5d949b10f5eb78b0676c37.json: Generated file
Comments suppressed due to low confidence (1)

nt-fe/components/sidebar.tsx:194

  • Add a useTranslations("customTemplates") instance so the new sidebar section label can be localized (instead of hardcoded English).

Comment thread nt-fe/messages/en.json
Comment thread nt-fe/messages/fr.json
},
]
: []),
...(showDeveloper ? [{ value: "developer", label: "Developer" }] : []),
Comment on lines +393 to +397
tooltipContent={
showLabels
? undefined
: "Request Templates"
}
Comment thread nt-fe/components/sidebar.tsx Outdated
khorolets added a commit to khorolets/trezu that referenced this pull request Jun 29, 2026
…review

- Translate the whole custom-templates feature (customTemplates namespace,
  13 locales) instead of leaving it English-only
- Tour copy via PageTourContent/pageTours.requestTemplates (was hardcoded JSX)
- Sidebar pinned templates use a real <Link> href, not onClick-only
- build-proposal docstring: correct the string-substitution vs typed-args contract
- Drop the agent/portable skills; the DSL is maintained in docs/
@khorolets
khorolets force-pushed the feat/custom-proposal-templates branch from f8ad635 to d2bb790 Compare June 29, 2026 16:44
khorolets added a commit to khorolets/trezu that referenced this pull request Jun 29, 2026
…review

- Translate the whole custom-templates feature (customTemplates namespace,
  13 locales) instead of leaving it English-only
- Tour copy via PageTourContent/pageTours.requestTemplates (was hardcoded JSX)
- Sidebar pinned templates use a real <Link> href, not onClick-only
- build-proposal docstring: correct the string-substitution vs typed-args contract
- Drop the agent/portable skills; the DSL is maintained in docs/
Copilot AI review requested due to automatic review settings June 29, 2026 16:59
@khorolets
khorolets force-pushed the feat/custom-proposal-templates branch from d2bb790 to ba588dd Compare June 29, 2026 16:59

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 68 out of 76 changed files in this pull request and generated 2 comments.

Files not reviewed (8)
  • nt-be/.sqlx/query-0d0919b0bc0e734a5155a2766337c005bf863105549661b4889b74dc6e60c181.json: Generated file
  • nt-be/.sqlx/query-3abe05be828d94bd877028f9c5c269ec479c5a5b9dc94a1d1cf254236e6b7382.json: Generated file
  • nt-be/.sqlx/query-498093aafc01d2c8e39728c8edb132571cb34e99964883c0bf99eae3fdbe06f6.json: Generated file
  • nt-be/.sqlx/query-57e6d33d9168ec4314e8db17f256b14eb9cfee654db2842fe5ac72731d3b0df9.json: Generated file
  • nt-be/.sqlx/query-a999e96f58c9e0f5e0af26d859955ac7c5d65094b52d2944d2551eb735d4861d.json: Generated file
  • nt-be/.sqlx/query-e648a256a6492374d9c39511c1ecc63a03f5d653bd018e8a2d90b2951c09081c.json: Generated file
  • nt-be/.sqlx/query-f0909d35187099eca523e0e0a0be2547de92116765a206e148e3a80968c975c2.json: Generated file
  • nt-be/.sqlx/query-fd881f5e05e9494b1ca87f66d411ed04133e0d66df5d949b10f5eb78b0676c37.json: Generated file

Comment thread nt-fe/features/proposal-templates/form-schema.ts
Comment thread nt-fe/messages/en.json Outdated
khorolets added a commit to khorolets/trezu that referenced this pull request Jun 29, 2026
…review

- Translate the whole custom-templates feature (customTemplates namespace,
  13 locales) instead of leaving it English-only
- Tour copy via PageTourContent/pageTours.requestTemplates (was hardcoded JSX)
- Sidebar pinned templates use a real <Link> href, not onClick-only
- build-proposal docstring: correct the string-substitution vs typed-args contract
- Drop the agent/portable skills; the DSL is maintained in docs/
@khorolets
khorolets force-pushed the feat/custom-proposal-templates branch from ba588dd to f0f5f2f Compare June 29, 2026 17:41
@Megha-Dev-19

Copy link
Copy Markdown
Collaborator

hey @khorolets few UI change requests

  1. can we make the padding of the secondary button conistent on hover
image
  1. we need to add some checks for the receiver type and method type, as it allows invalid type
image image

@khorolets

Copy link
Copy Markdown
Contributor Author

@Megha-Dev-19

Yeah, the bg on the secondary is barely visible on my screen I haven't noticed it's smaller. Thank you for the heads-up. Fixed

image

For no validation on those field, I have no excuse 🤦
image

…review

- Translate the whole custom-templates feature (customTemplates namespace,
  13 locales) instead of leaving it English-only
- Tour copy via PageTourContent/pageTours.requestTemplates (was hardcoded JSX)
- Sidebar pinned templates use a real <Link> href, not onClick-only
- build-proposal docstring: correct the string-substitution vs typed-args contract
- Drop the agent/portable skills; the DSL is maintained in docs/
Copilot AI review requested due to automatic review settings June 29, 2026 18:04
@khorolets
khorolets force-pushed the feat/custom-proposal-templates branch from f0f5f2f to 2291ca0 Compare June 29, 2026 18:04
Comment on lines +63 to +71
it("stringifies number, boolean, and json values", () => {
expect(
interpolateArgs("{{n}}/{{b}}/{{j}}", {
n: 7,
b: true,
j: { k: 1 },
}),
).toBe('7/true/{"k":1}');
});

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

number / bool member inputs reach the contract as JSON strings. A dynamic input always serializes as "{{key}}" → a string, so a bool toggle yields {"approved": "true"} and a number yields {"count": "5"}. Most contracts will reject these (serde won't coerce "true"→true or "5"→5), which makes the number/bool types unusable for the methods they imply. Was this intentional?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oof! That's a catch indeed. Not intentional, fixing. Thank you!

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 68 out of 76 changed files in this pull request and generated 2 comments.

Files not reviewed (8)
  • nt-be/.sqlx/query-0d0919b0bc0e734a5155a2766337c005bf863105549661b4889b74dc6e60c181.json: Generated file
  • nt-be/.sqlx/query-3abe05be828d94bd877028f9c5c269ec479c5a5b9dc94a1d1cf254236e6b7382.json: Generated file
  • nt-be/.sqlx/query-498093aafc01d2c8e39728c8edb132571cb34e99964883c0bf99eae3fdbe06f6.json: Generated file
  • nt-be/.sqlx/query-57e6d33d9168ec4314e8db17f256b14eb9cfee654db2842fe5ac72731d3b0df9.json: Generated file
  • nt-be/.sqlx/query-a999e96f58c9e0f5e0af26d859955ac7c5d65094b52d2944d2551eb735d4861d.json: Generated file
  • nt-be/.sqlx/query-e648a256a6492374d9c39511c1ecc63a03f5d653bd018e8a2d90b2951c09081c.json: Generated file
  • nt-be/.sqlx/query-f0909d35187099eca523e0e0a0be2547de92116765a206e148e3a80968c975c2.json: Generated file
  • nt-be/.sqlx/query-fd881f5e05e9494b1ca87f66d411ed04133e0d66df5d949b10f5eb78b0676c37.json: Generated file

Comment thread nt-fe/features/proposal-templates/manifest.ts Outdated
Comment on lines +105 to +110
const required = field.required === true;
let schema: z.ZodTypeAny = z
.string()
.refine((value) => value !== "" || !required, {
message: `${field.label} is required`,
})
A member-filled value reached the contract as a string: a `{{field}}`
placeholder always stringified, so a bool toggle serialized as
{"approved":"true"} and a number as {"count":"5"} — which serde-based
contracts reject. That made the `bool` and `number` field types effectively
unusable for the methods they imply.

A lone `{{field}}` bound to a bool/number/json field now resolves to its
typed JSON value (true / 5 / parsed object), while u128 uint/amount and any
composed value stay strings. Covered by build-proposal tests.

Also folds in the review fixes made alongside it:
- validate binding.receiver_id (NEAR account) and method_name (identifier)
  in the manifest validator and backend validate_manifest
- drop the RegExp lookbehind in the placeholder matcher (Safari <16.4 throws
  at module load); handle escaped {{{{...}}}} via alternation instead
- cap the author regex pattern and the input fed to pattern.test (ReDoS)
- localize the Developer tab, the Request Templates sidebar entry, and
  member-facing form-validation messages across all 13 locales
- both sidebar navigations use a real <Link> href
- move the distributable skill from skills/ to docs/
- How It Works empty-state button -> outline; tour copy grammar; wrap the
  touched-gating SSR test in an intl provider
@khorolets
khorolets requested a review from frol June 29, 2026 19:14

@frol frol left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems to be good enough to get it merged and start testing on staging.

@frol
frol merged commit 3f8d3b2 into NEAR-DevHub:main Jun 29, 2026
7 checks passed
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.

4 participants