Skip to content

Consolidate JS API gui module into common crate and rename GUI to OrderBuilder#2479

Open
findolor wants to merge 14 commits intomainfrom
2026-02-23-js-api-consolidation
Open

Consolidate JS API gui module into common crate and rename GUI to OrderBuilder#2479
findolor wants to merge 14 commits intomainfrom
2026-02-23-js-api-consolidation

Conversation

@findolor
Copy link
Copy Markdown
Collaborator

@findolor findolor commented Feb 24, 2026

Dependent PRs

Motivation

The order builder logic (formerly "GUI") lived entirely in crates/js_api/src/gui/, tightly coupled to WASM and JsValue. This made it impossible to reuse from the CLI, REST API, or other Rust consumers. Additionally, the "GUI" naming was misleading since the logic is not UI-specific — it handles field values, deposits, token selection, state serialization, and order calldata generation.

Solution

  • Ported core logic to crates/common/src/raindex_order_builder/ — field values, deposits, select tokens, order operations, state management, and validation now live in a platform-agnostic common crate with no WASM dependencies.
  • Reduced crates/js_api/src/raindex_order_builder/ to thin WASM wrappers that delegate to the common crate, keeping only JsValue conversion and callback handling.
  • Renamed all GUI terminology to OrderBuilder across the entire codebase:
    • Rust types: DotrainOrderGuiRaindexOrderBuilder, DotrainGuiStateV1OrderBuilderStateV1, GuiCfgOrderBuilderCfg, etc.
    • YAML keyword: gui:builder:
    • Settings crate: gui.rsorder_builder.rs
    • Svelte/TS: components, providers, hooks, tests, and documentation updated
    • Test file renamed: gui.test.tsbuilder.test.ts
    • WASM getter: dotrainGuiStateorderBuilderState
  • Bumped lib/rain.interpreter submodule to pull in OrderBuilderStateV1 rename from rain.metadata.
  • Updated all ARCHITECTURE.md files and README documentation.

Checks

By submitting this for review, I'm confirming I've done the following:

  • made this PR as small as possible
  • unit-tested any new functionality
  • linked any relevant issues or PRs
  • included screenshots (if this involves a front-end change)

Summary by CodeRabbit

  • New Features

    • Replaces the GUI surface with a unified "Order Builder": deposits, field values, select-tokens, token info & balances, validation, state serialization/restoration, calldata/deployment-args generation, and related UI provider/hook + WASM/JS bindings.
  • Documentation

    • README and architecture docs updated to show builder-centric examples and workflow.
  • Chores

    • Added encoding/hash utility dependencies (base64, bincode, sha2).

Move core order builder logic (field values, deposits, token selection,
validation, order operations, state management) into the common crate so
it can be shared across targets. Add cfg gates for httpmock-dependent
test submodules that cannot compile on WASM.
Delete the old gui/ module containing duplicated business logic and
replace it with raindex_order_builder/ thin wrappers that delegate
to the common crate's RaindexOrderBuilder. Update registry.rs
references from DotrainOrderGui/GuiError to
RaindexOrderBuilder/RaindexOrderBuilderWasmError.
The consolidation refactor dropped tsify annotations on DepositCalldataResult,
IOVaultIds, and WithdrawCalldataResult, causing undefined Bytes/U256 types
in generated TypeScript declarations.
- Export executeStateUpdateCallback as WASM method
- Restore per-field callback in setFieldValues (was firing once per batch)
- Add preserve_js_class to getAccountBalance so Float methods are available
- Rename DotrainOrderGui to RaindexOrderBuilder in tests
Rename variables, functions, error variants, WASM method names,
test descriptions, and documentation from gui terminology to
builder terminology, aligning with the DotrainOrderGui to
RaindexOrderBuilder class rename. YAML gui: config keys and
settings crate types (GuiCfg, GuiDeploymentCfg, etc.) are
unchanged as they map to the YAML schema.
…lder

Renames gui.rs to order_builder.rs, changes all Gui-prefixed structs/enums/traits
to use OrderBuilder prefix, updates the YAML keyword from "gui" to "builder",
and fixes all references across settings, common, js_api crates, JS test files,
and UI components.
…ferences

Bump rain.interpreter submodule to pull in the OrderBuilderStateV1 rename
from rain.metadata. Update all Rust types, imports, variables, wasm_bindgen
getters, test fixtures, Svelte/TS references, and documentation to replace
GUI terminology with builder/OrderBuilder throughout the codebase.
@findolor findolor self-assigned this Feb 24, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Feb 24, 2026

📝 Walkthrough

Walkthrough

Rebrands and replaces the GUI-centric order builder with a new RaindexOrderBuilder surface across Rust crates, WASM/JS bindings, settings/YAML schema (gui → builder), UI hooks/providers/components/tests, and metadata handling; adds raindex_order_builder internals (deposits, field-values, select-tokens, ops) and related Rust deps.

Changes

Cohort / File(s) Summary
Docs & READMEs
ai_commands/sdk-documentation-update.md, crates/bindings/ARCHITECTURE.md, crates/js_api/ARCHITECTURE.md, crates/settings/ARCHITECTURE.md, packages/orderbook/ARCHITECTURE.md, packages/orderbook/README.md, packages/ui-components/ARCHITECTURE.md, packages/webapp/ARCHITECTURE.md
Replaced GUI-focused narrative and examples with RaindexOrderBuilder / "builder" terminology.
Common: public API & meta parsing
crates/common/src/lib.rs, crates/common/src/add_order.rs, crates/common/src/parsed_meta.rs, crates/common/src/raindex_client/orders.rs
Added raindex_order_builder export; switched meta parsing/accessors and parsed meta types from DotrainGuiStateV1 → OrderBuilderStateV1; renamed getters and updated tests.
Common: dotrain YAML handling
crates/common/src/dotrain_order.rs, crates/common/src/test_helpers.rs
Changed frontmatter subtree key and cloning logic from guibuilder; updated fixtures/tests expecting "builder" and deployments filtering.
Common: new RaindexOrderBuilder internals
crates/common/src/raindex_order_builder/... (mod.rs, deposits.rs, field_values.rs, order_operations.rs, select_tokens.rs, state_management.rs, validation.rs)
Introduced full builder backend: state management, deposits, field-values, select-token discovery/balances, order operations, validation, error types, and extensive unit tests. Many new public methods/types added.
Common: deps
crates/common/Cargo.toml
Added Rust dependencies: base64, bincode, sha2.
JS API: remove old GUI wasm surface
crates/js_api/src/gui/..., crates/js_api/src/lib.rs
Removed gui wasm modules (deposits/field_values/select_tokens) and replaced exported pub mod gui with pub mod raindex_order_builder.
JS API: new wasm bindings for builder
crates/js_api/src/raindex_order_builder/... (mod.rs, deposits.rs, field_values.rs, order_operations.rs, select_tokens.rs, state_management.rs)
Added WASM/TS wrappers and exported methods/types for RaindexOrderBuilder covering deposits, field-values, select-tokens, order operations, and state management with wasm error mapping.
JS API: registry rename
crates/js_api/src/registry.rs
Renamed registry API and wiring from getGui/get_gui → getOrderBuilder/get_order_builder and updated error wrapping.
Settings crate: gui → order_builder migration
crates/settings/src/lib.rs, crates/settings/src/order_builder.rs, crates/settings/src/deployment.rs, crates/settings/src/order.rs, crates/settings/src/yaml/*
Renamed gui module/types to order_builder equivalents, updated parsing entrypoints, canonical root key to builder, context traits, type names (Gui* → OrderBuilder*), and tests.
UI components: hooks & providers
packages/ui-components/src/lib/hooks/useGui.ts (removed), packages/ui-components/src/lib/hooks/useRaindexOrderBuilder.ts, packages/ui-components/src/lib/providers/GuiProvider.svelte (removed), packages/ui-components/src/lib/providers/RaindexOrderBuilderProvider.svelte
Removed GUI context/hook/provider; added RaindexOrderBuilder context key, provider component and hook.
UI components: components & services
packages/ui-components/src/lib/components/..., packages/ui-components/src/lib/services/*, packages/ui-components/src/lib/errors/DeploymentStepsError.ts, packages/ui-components/src/lib/index.ts
Updated components, services, exports and error codes to use RaindexOrderBuilder and OrderBuilder* types; renamed error codes and functions (NO_GUI_* → NO_BUILDER_*, getAllGuiConfig → getAllBuilderConfig, etc.).
UI components: tests & mocks
packages/ui-components/src/__tests__/*, packages/ui-components/test-setup.ts
Rebased tests and mocks from DotrainOrderGui → RaindexOrderBuilder, updated fixtures, hooks, and mocked methods to match new API surface.
Webapp: routes, services & tests
packages/webapp/src/lib/services/handleAddOrder.ts, packages/webapp/src/lib/services/handleUpdateBuilderState.ts, packages/webapp/src/routes/deploy/.../+page.svelte, tests under packages/webapp/src/__tests__
Replaced GUI references with builder equivalents; renamed pushGuiStateToUrlHistory → pushBuilderStateToUrlHistory and updated route/provider wiring and tests.
Orderbook tests & fixtures
packages/orderbook/test/js_api/builder.test.ts, packages/orderbook/test/js_api/dotrainRegistry.test.ts
Updated JS tests and YAML fixtures to builder root key and OrderBuilder* types; test names and variables adjusted.
Submodule & workspace changes
lib/rain.interpreter, Cargo.toml
Updated tracked rain.interpreter submodule ref and specified explicit package names for several workspace dependencies.
Other value change
packages/webapp/src/lib/constants.ts
Updated exported REGISTRY_URL constant to new raw GitHub URL.

Sequence Diagram(s)

sequenceDiagram
    participant JS as JS_Client
    participant WASM as RaindexOrderBuilder (WASM)
    participant INNER as RaindexOrderBuilderInner
    participant SETTINGS as OrderBuilderCfg
    participant RPC as Network/RPC

    JS->>WASM: newWithDeployment(dotrain, settings, deploymentKey, callback)
    WASM->>INNER: instantiate/new_with_deployment(...)
    INNER->>SETTINGS: parse YAML, resolve builder config
    SETTINGS-->>INNER: OrderBuilderCfg (deployments, fields, tokens)
    INNER-->>WASM: return builder instance
    WASM-->>JS: RaindexOrderBuilder wrapper returned
    JS->>WASM: setSelectToken(key, address)
    WASM->>INNER: inner.set_select_token(key, address)
    INNER->>RPC: fetch ERC20 metadata / balance (decimals, name, symbol)
    RPC-->>INNER: token metadata / balance
    INNER->>SETTINGS: update YAML record with token info
    INNER-->>WASM: Result(ok) -> WASM triggers state callback to JS
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Poem

"I am a rabbit, nibbling code so spry,
I hopped from gui to builder in a blink of eye.
YAML seeds I planted under 'builder' green,
New bindings sprout — Raindex on the scene.
Carrots, tests, and callbacks — hop, release, delight! 🥕"

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch 2026-02-23-js-api-consolidation

@findolor findolor requested a review from hardyjosh February 24, 2026 10:40
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 12

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (17)
packages/ui-components/src/lib/services/registry.ts (1)

83-94: ⚠️ Potential issue | 🟠 Major

Correct the error property accessor from .msg to .readableMsg.

Line 86 uses result.error.msg but the @rainlanguage/orderbook API documentation (and other parts of the codebase) consistently use result.error.readableMsg. The Rust bindings export to_readable_msg() which becomes readableMsg in JavaScript. Other UI components correctly access result.error.readableMsg (e.g., VaultsListTable.svelte, OrderDetail.svelte); registry.ts and a few other files use the incorrect .msg property, which will fail at runtime.

Inconsistent usage in codebase

Files using incorrect .msg:

  • packages/ui-components/src/lib/services/registry.ts:86
  • packages/ui-components/src/lib/services/handleShareChoices.ts:12
  • packages/ui-components/src/lib/components/deployment/TokenIOInput.svelte:24, 40

Files using correct .readableMsg:

  • packages/ui-components/src/lib/providers/transactions/TransactionManager.ts:59
  • packages/ui-components/src/lib/components/tables/VaultsListTable.svelte:76, 125, 176, 191
  • packages/ui-components/src/lib/components/detail/OrderDetail.svelte:90
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/ui-components/src/lib/services/registry.ts` around lines 83 - 94,
The code in RaindexOrderBuilder.getOrderDetails handling incorrectly accesses
result.error.msg; update the error property access to result.error.readableMsg
in the failure branch where you throw (inside the function returning { valid:
true, data: ... } path) so the thrown Error uses the exported readableMsg;
locate the usage in registry.ts around the variable registryDotrain and replace
`.msg` with `.readableMsg` (and mirror the same fix in any other files listed
like handleShareChoices.ts and TokenIOInput.svelte if present).
packages/ui-components/src/lib/components/deployment/ComposedRainlangModal.svelte (1)

1-20: ⚠️ Potential issue | 🟠 Major

Provide the required webapp screenshot for this UI change.

Frontend modifications in ui-components require a screenshot of the built webapp; please attach one and include the build/preview steps used.

As per coding guidelines: "packages/{webapp,ui-components}/**/*.{ts,tsx,svelte,js,jsx}: If you modify frontend code or functionality affecting the frontend, you MUST provide a screenshot of the built webapp reflecting your change".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/ui-components/src/lib/components/deployment/ComposedRainlangModal.svelte`
around lines 1 - 20, The PR modifies the UI in ComposedRainlangModal.svelte
(notably the generateRainlang function and UI around rainlangText/open) but
lacks the required built-app screenshot and preview instructions; please attach
a screenshot showing the modal/UI state after building the webapp and include
concise build/preview steps (commands used, environment, branch/commit, and URL
or local port used) so reviewers can reproduce the UI (e.g., build/install, run
dev/preview, navigate to the component and invoke generateRainlang to show the
modal).
packages/ui-components/src/lib/components/deployment/TokenSelectionModal.svelte (1)

5-22: ⚠️ Potential issue | 🟠 Major

Provide an updated webapp screenshot for this UI change.
This swap affects the frontend token source; please attach a screenshot from the built webapp and confirm build/preview.

As per coding guidelines: packages/{webapp,ui-components}/**/*.{ts,tsx,svelte,js,jsx}: If you modify frontend code or functionality affecting the frontend, you MUST provide a screenshot of the built webapp reflecting your change; Frontend verification requires building and previewing the webapp with nix develop -c npm run build -w @rainlanguage/webapp followed by `nix develop -c npm run preview -w `@rainlanguage/webapp.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/ui-components/src/lib/components/deployment/TokenSelectionModal.svelte`
around lines 5 - 22, The reviewer requires a built-webapp screenshot showing the
TokenSelectionModal change: rebuild and preview the webapp and attach a
screenshot showing the updated token source UI (TokenSelectionModal.svelte /
loadTokens -> builder.getAllTokens). Run the prescribed commands to verify the
frontend: `nix develop -c npm run build -w `@rainlanguage/webapp`` then `nix
develop -c npm run preview -w `@rainlanguage/webapp``, open the page where
TokenSelectionModal is used, capture a clear screenshot of the modal/search
results, and add that image to the PR with a short confirmation comment stating
the build and preview commands succeeded.
packages/ui-components/src/lib/components/deployment/SelectToken.svelte (1)

26-40: ⚠️ Potential issue | 🟡 Minor

Silent NPE when result.value is null on mount

When getTokenInfo returns { value: null } (no token configured yet), line 32 sets tokenInfo = null and line 33 immediately throws TypeError: Cannot read properties of null when accessing result.value.address. The outer catch {} silently swallows it, so the UI is unaffected, but the exception is unintended. The fix is optional chaining.

🐛 Proposed fix
         tokenInfo = result.value;
-        if (result.value.address) {
+        if (result.value?.address) {
             inputValue = result.value.address;
             onSelectTokenSelect(token.key);
         }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/ui-components/src/lib/components/deployment/SelectToken.svelte`
around lines 26 - 40, The onMount block may throw a TypeError when
builder.getTokenInfo returns { value: null }; update the logic in the onMount
async handler (the function that calls builder.getTokenInfo) to guard access to
result.value before reading properties: check result.value exists (or use
optional chaining) before assigning tokenInfo, reading result.value.address,
setting inputValue, or calling onSelectTokenSelect(token.key), and preserve the
existing error handling behavior.
crates/settings/src/yaml/emitter.rs (1)

14-33: 🧹 Nitpick | 🔵 Trivial

Breaking change: existing gui: YAML documents will be silently dropped on emit

The rename of the canonical key from "gui" to "builder" means any existing deployment YAML that contains a gui: top-level section will be silently removed when emit_documents runs (keys not in CANONICAL_ROOT_KEYS are filtered out). Additionally, OrderBuilderCfg::parse_from_yaml_optional will return None instead of an error for old gui: files, so there is no failure signal to users.

If this is an upgrade path for existing users, consider adding a guard in validate_and_emit_documents that detects a gui: key and either migrates it to builder: or emits a clear diagnostic error, to avoid silent data loss during the transition.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/settings/src/yaml/emitter.rs` around lines 14 - 33, The
CANONICAL_ROOT_KEYS constant was changed to "builder" which causes top-level
"gui" keys to be filtered out in emit_documents and silent for users because
OrderBuilderCfg::parse_from_yaml_optional returns None; update
validate_and_emit_documents to detect a legacy "gui" top-level key (or detect it
in emit_documents) and either migrate it to "builder" before filtering or emit a
clear diagnostic error instead of silently dropping it, and ensure
OrderBuilderCfg::parse_from_yaml_optional surfaces an error or warning when a
legacy "gui" document is encountered so users are notified of the required
change.
packages/ui-components/src/__tests__/ComposedRainlangModal.test.ts (1)

1-37: ⚠️ Potential issue | 🟡 Minor

Add passthrough mock for @rainlanguage/orderbook

Consistent with other component tests in this codebase (e.g., VaultIdInformation.test.ts, SelectToken.test.ts), this test requires a passthrough vi.mock('@rainlanguage/orderbook') block. The project's test configuration requires this mock even when no exports are overridden, because the hook dependency indirectly loads types from that package.

Add the following after the svelte-codemirror-editor mock:

vi.mock('@rainlanguage/orderbook', async (importOriginal) => {
	return {
		...(await importOriginal())
	};
});
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/ui-components/src/__tests__/ComposedRainlangModal.test.ts` around
lines 1 - 37, Test fails because the package '@rainlanguage/orderbook' needs a
passthrough mock; add a vi.mock for '@rainlanguage/orderbook' immediately after
the svelte-codemirror-editor mock that calls importOriginal and returns a spread
of await importOriginal() so the original exports are preserved (place this mock
near the other vi.mock calls in ComposedRainlangModal.test.ts alongside
useRaindexOrderBuilder and mockBuilder setup).
packages/webapp/src/lib/services/handleAddOrder.ts (1)

1-14: 🧹 Nitpick | 🔵 Trivial

Please confirm required webapp verification steps (and attach screenshot).

This change touches webapp frontend code. Please provide:

  • nix develop -c npm run build -w @rainlanguage/webapp``
  • nix develop -c npm run svelte-lint-format-check -w @rainlanguage/webapp``
  • nix develop -c npm run test -w @rainlanguage/webapp``
  • nix develop -c npm run format, nix develop -c npm run lint, nix develop -c npm run check (for TS/Svelte)
  • Webapp build + preview and a screenshot of the built webapp reflecting the change.

As per coding guidelines: “packages/webapp//*.{ts,tsx,svelte,js,jsx}: … run nix develop -c npm run build -w @rainlanguage/webapp, … `nix develop -c npm run svelte-lint-format-check -w `@rainlanguage/webapp, … nix develop -c npm run test -w @rainlanguage/webapp``”; “/.{ts,tsx,svelte}: Format TypeScript/Svelte code with nix develop -c npm run format … Lint … Run type checks …”; and “packages/{webapp,ui-components}/**/.{ts,tsx,svelte,js,jsx}: … MUST provide a screenshot … build … preview …”.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/webapp/src/lib/services/handleAddOrder.ts` around lines 1 - 14, This
PR touches frontend file handleAddOrder.ts (imports like RaindexOrderBuilder,
RaindexClient, QKEY_ORDERS), so run the required webapp verification: execute
nix develop -c npm run build -w `@rainlanguage/webapp`, nix develop -c npm run
svelte-lint-format-check -w `@rainlanguage/webapp`, and nix develop -c npm run
test -w `@rainlanguage/webapp`; run formatting, linting and type checks via nix
develop -c npm run format, nix develop -c npm run lint, and nix develop -c npm
run check; then start a preview of the built webapp and attach a screenshot that
clearly shows the changed behavior/UI (include timestamp or browser URL in the
shot) to the PR comments so reviewers can confirm the frontend change.
packages/orderbook/test/js_api/dotrainRegistry.test.ts (1)

1-6: 🧹 Nitpick | 🔵 Trivial

Please confirm orderbook package build/lint/test + TS format/check steps.

For changes in packages/orderbook, please provide:

  • nix develop -c npm run build:orderbook
  • nix develop -c npm run check -w @rainlanguage/orderbook``
  • nix develop -c npm run test -w @rainlanguage/orderbook``
  • nix develop -c npm run format, nix develop -c npm run lint, nix develop -c npm run check (for TS/Svelte)

As per coding guidelines: “packages/orderbook//*.{ts,tsx,js,jsx}: … run nix develop -c npm run build:orderbooknix develop -c npm run check -w @rainlanguage/orderbook … `nix develop -c npm run test -w `@rainlanguage/orderbook”; and “/*.{ts,tsx,svelte}: Format TypeScript/Svelte code with nix develop -c npm run format … Lint … Run type checks …”.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/orderbook/test/js_api/dotrainRegistry.test.ts` around lines 1 - 6,
This change touches the orderbook package tests — ensure the package builds,
type-checks, formats and tests by running the required nix/npm commands: execute
`nix develop -c npm run build:orderbook` to build, `nix develop -c npm run check
-w `@rainlanguage/orderbook`` to run TypeScript checks for the package (covers
symbols like OrderbookYaml and DotrainRegistry used in dotrainRegistry.test.ts),
and `nix develop -c npm run test -w `@rainlanguage/orderbook`` to run the package
tests; also run project-wide formatting, linting and checks with `nix develop -c
npm run format`, `nix develop -c npm run lint`, and `nix develop -c npm run
check` to ensure TS/Svelte formatting and lint rules are satisfied before
merging.
packages/ui-components/src/lib/components/deployment/FieldDefinitionInput.svelte (1)

1-55: 🧹 Nitpick | 🔵 Trivial

Please confirm ui-components build/lint/test + TS/Svelte format/check.
Suggested commands:

  • nix develop -c npm run build -w @rainlanguage/ui-components``
  • nix develop -c npm run svelte-lint-format-check -w @rainlanguage/ui-components``
  • nix develop -c npm run test -w @rainlanguage/ui-components``
  • nix develop -c npm run format
  • nix develop -c npm run lint
  • nix develop -c npm run check

As per coding guidelines, “packages/ui-components//*.{ts,tsx,svelte,js,jsx}: … run build … lint … test …” and “/*.{ts,tsx,svelte}: Format … Lint … Run type checks …”.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/ui-components/src/lib/components/deployment/FieldDefinitionInput.svelte`
around lines 1 - 55, Run the full UI components verification for
packages/ui-components to ensure build, lint, format and type checks pass for
this change in FieldDefinitionInput.svelte: run the build and tests (e.g., npm
run build -w `@rainlanguage/ui-components` and npm run test -w
`@rainlanguage/ui-components`), run Svelte/TS formatting and linting (e.g., npm
run svelte-lint-format-check -w `@rainlanguage/ui-components`, npm run format, npm
run lint) and run type checks (npm run check) before merging; if any errors
reference FieldDefinitionInput.svelte (including onMount, handlePresetClick,
handleCustomInputChange or useRaindexOrderBuilder usage), fix
formatting/type/lint issues and re-run the commands until all checks succeed.
packages/webapp/src/routes/deploy/[orderName]/[deploymentKey]/+page.svelte (1)

69-88: ⚠️ Potential issue | 🟠 Major

Provide a screenshot of the built webapp reflecting this change.
Frontend verification is mandatory for Svelte component changes. Build, preview, and run the required checks:

  • nix develop -c npm run build -w @rainlanguage/webapp``
  • nix develop -c npm run preview -w @rainlanguage/webapp``
  • nix develop -c npm run svelte-lint-format-check -w @rainlanguage/webapp``
  • nix develop -c npm run test -w @rainlanguage/webapp``
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/webapp/src/routes/deploy/`[orderName]/[deploymentKey]/+page.svelte
around lines 69 - 88, The PR changes the conditional rendering in +page.svelte
for RaindexOrderBuilderProvider/DeploymentSteps; provide a frontend verification
screenshot of the built webapp showing the builder view (when builder is truthy)
and include the image in the PR, and run the full Svelte build/preview/lint/test
checks: execute `nix develop -c npm run build -w `@rainlanguage/webapp``, then
`nix develop -c npm run preview -w `@rainlanguage/webapp`` to capture the running
UI screenshot for the route /deploy/[orderName]/[deploymentKey], and finally run
`nix develop -c npm run svelte-lint-format-check -w `@rainlanguage/webapp`` and
`nix develop -c npm run test -w `@rainlanguage/webapp`` to show lint/format/tests
pass; attach the screenshot and CI output to the PR for review.
packages/ui-components/src/__tests__/DeploymentSteps.test.ts (1)

107-114: ⚠️ Potential issue | 🟡 Minor

Align getCurrentDeployment mock with the builder result shape.
Most mocked builder methods return { value }, but getCurrentDeployment returns mockDeployment directly. The actual builder API returns WasmEncodedResult<OrderBuilderDeploymentCfg> with shape { value, error }. While the first test doesn't exercise this mock, later tests override it correctly with the wrapped format. For consistency across the file and alignment with the API contract, wrap the initial mock:

🔧 Proposed fix
-			getCurrentDeployment: vi.fn().mockReturnValue(mockDeployment),
+			getCurrentDeployment: vi.fn().mockReturnValue({ value: mockDeployment }),
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/ui-components/src/__tests__/DeploymentSteps.test.ts` around lines
107 - 114, The mock for builderInstance.getCurrentDeployment returns
mockDeployment directly but should match the builder API shape
WasmEncodedResult<OrderBuilderDeploymentCfg> (an object with value and error);
update the initial mock on builderInstance (getCurrentDeployment) to return {
value: mockDeployment, error: null } (or appropriate error) so it aligns with
other mocks like getAllFieldDefinitions and with later tests that override it.
packages/orderbook/test/js_api/builder.test.ts (1)

1-23: 🧹 Nitpick | 🔵 Trivial

Please verify Orderbook TS build/test + format/lint/check runs.

Confirm npm run build:orderbook, npm run check -w @rainlanguage/orderbook, `npm run test -w `@rainlanguage/orderbook, and the package-level format/lint/check steps were executed.

As per coding guidelines, packages/orderbook/**/*.{ts,tsx,js,jsx}: ... run build:orderbook / check / test and **/*.{ts,tsx,svelte}: Format ... Lint ... Run check ....

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/orderbook/test/js_api/builder.test.ts` around lines 1 - 23, Run and
verify the Orderbook package build/test/lint/check steps: execute npm run
build:orderbook, npm run check -w `@rainlanguage/orderbook`, and npm run test -w
`@rainlanguage/orderbook` locally and confirm green results; also run the
package-level format/lint/check steps for packages/orderbook (format, lint, and
type-check) and correct any failures found (fix TypeScript errors, formatting,
or lint violations) so tests like packages/orderbook/test/js_api/builder.test.ts
import symbols (e.g., RaindexOrderBuilder, OrderbookYaml) from the compiled
output correctly and CI will pass.
crates/js_api/src/registry.rs (2)

415-522: 🧹 Nitpick | 🔵 Trivial

Leverage ? to simplify builder error propagation.
DotrainRegistryError already has #[from] for RaindexOrderBuilderWasmError, so explicit map_err isn’t needed.

♻️ Simplified error handling
-        let builder = result.map_err(DotrainRegistryError::BuilderError)?;
-        Ok(builder)
+        Ok(result?)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/js_api/src/registry.rs` around lines 415 - 522, The match produces a
Result<RaindexOrderBuilder, RaindexOrderBuilderWasmError> named result which is
then converted with map_err into DotrainRegistryError; since
DotrainRegistryError implements #[from] for RaindexOrderBuilderWasmError you can
replace the explicit map_err with the try operator. In get_order_builder, change
the final conversion from "let builder =
result.map_err(DotrainRegistryError::BuilderError)?; Ok(builder)" (or similar)
to simply use the try operator on result (e.g., let builder = result?; or return
Ok(result?);) so the RaindexOrderBuilderWasmError is automatically converted
into DotrainRegistryError.

12-115: ⚠️ Potential issue | 🟡 Minor

Fix getOrderBuilder example argument order.
The example passes stateCallback as the third argument, but the API expects serializedState third and stateUpdateCallback fourth. Passing a function in position 3 will fail conversion.

✍️ Suggested doc fix
-/// const builder = await registry.getOrderBuilder("fixed-limit", "mainnet", stateCallback);
+/// const builder = await registry.getOrderBuilder("fixed-limit", "mainnet", undefined, stateCallback);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/js_api/src/registry.rs` around lines 12 - 115, The example call to
DotrainRegistry.getOrderBuilder passes stateCallback as the third argument but
the API expects serializedState as the third and stateUpdateCallback as the
fourth; update the example so DotrainRegistry.new(...) is followed by
registry.getOrderBuilder("fixed-limit", "mainnet", serializedState,
stateCallback) (i.e., supply a serializedState value or null/undefined in the
third position and move stateCallback to the fourth) so it matches the
getOrderBuilder parameter order used in the implementation.
crates/settings/src/order_builder.rs (2)

1-16: 🧹 Nitpick | 🔵 Trivial

Run the required Rust format/lint/test commands for this crate.
Please run nix develop -c cargo fmt --all, nix develop -c rainix-rs-static, nix develop -c cargo build, nix develop -c cargo clippy --workspace --all-targets --all-features -D warnings, and nix develop -c cargo test --workspace for these changes.

As per coding guidelines “crates/**/*.rs: Run nix develop -c cargo build to check Rust dependency readiness before development; for Rust crates in crates/*, run linting with nix develop -c cargo clippy --workspace --all-targets --all-features -D warnings; for Rust crates in crates/*, run tests with nix develop -c cargo test --workspace or targeting specific packages with --package <crate>; and **/*.rs: Format Rust code with nix develop -c cargo fmt --all and lint with nix develop -c rainix-rs-static with preconfigured flags.”

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/settings/src/order_builder.rs` around lines 1 - 16, Run the Rust
formatting, static linting, build, clippy checks, and tests for this crate to
ensure changes compiling and follow style rules: execute `nix develop -c cargo
fmt --all`, `nix develop -c rainix-rs-static`, `nix develop -c cargo build`,
`nix develop -c cargo clippy --workspace --all-targets --all-features -D
warnings`, and `nix develop -c cargo test --workspace`; verify the module that
defines Context and OrderBuilderContextTrait (and related types like
DeploymentCfg, TokenCfg) in this crate compiles cleanly and fixes any formatting
or clippy warnings reported.

468-503: ⚠️ Potential issue | 🟠 Major

Short-description should remain optional in order details.
parse_order_details now requires short-description, but OrderBuilderCfg treats it as optional (and parse_from_yaml_optional allows it). This will error on valid configs that omit the field.

🛠️ Suggested fix
-                let short_description = require_string(
-                    get_hash_value(builder, "short-description", Some("builder".to_string()))?,
-                    None,
-                    Some("builder".to_string()),
-                )?;
+                let short_description = get_hash_value_as_option(builder, "short-description")
+                    .map(|v| {
+                        v.as_str().ok_or(YamlError::Field {
+                            kind: FieldErrorKind::InvalidType {
+                                field: "short-description".to_string(),
+                                expected: "a string".to_string(),
+                            },
+                            location: "builder".to_string(),
+                        })
+                    })
+                    .transpose()?
+                    .map(|s| s.to_string());
 
                 return Ok(NameAndDescriptionCfg {
                     name,
                     description,
-                    short_description: Some(short_description),
+                    short_description,
                 });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/settings/src/order_builder.rs` around lines 468 - 503,
parse_order_details currently treats "short-description" as required; change the
logic so "short-description" is fetched with the optional YAML helper (instead
of require_string) so missing short-description returns None rather than an
error, then set NameAndDescriptionCfg.short_description to that Option; update
the short_description retrieval that currently calls
require_string(get_hash_value(...), ...) to use the optional string helper (or
equivalent optional accessor) with get_hash_value(builder, "short-description",
Some("builder".to_string())) so valid configs without short-description no
longer error in parse_order_details.
crates/common/src/raindex_order_builder/order_operations.rs (1)

241-288: ⚠️ Potential issue | 🟠 Major

Avoid re-approving when allowance already exceeds the deposit.
Using !eq triggers approvals even when allowance > required, leading to unnecessary transactions. Compare against the required allowance instead.

🛠️ Suggested fix
-            let allowance_float = Float::from_fixed_decimal(token_allowance.allowance, decimals)?;
-
-            if !allowance_float.eq(*deposit_amount)? {
+            let required_allowance = deposit_amount.to_fixed_decimal(decimals)?;
+            if token_allowance.allowance < required_allowance {
                 let calldata = approveCall {
                     spender: tx_args.orderbook_address,
-                    amount: deposit_amount.to_fixed_decimal(decimals)?,
+                    amount: required_allowance,
                 }
                 .abi_encode();
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/common/src/raindex_order_builder/order_operations.rs` around lines 241
- 288, The current check uses !allowance_float.eq(*deposit_amount) which causes
approval when allowance is greater than the required amount; update
generate_approval_calldatas to only create an approval calldata when the
existing allowance is strictly less than the required deposit. Specifically,
compare allowance_float against the required deposit amount in the same units
(convert deposit_amount to the same fixed-decimal representation as
allowance_float) and replace the eq-based condition with a "allowance <
required" check (references: generate_approval_calldatas, allowance_float,
deposit_amount, check_allowance, to_fixed_decimal).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@crates/js_api/ARCHITECTURE.md`:
- Line 7: Update the phrasing to use hyphenated compound adjectives: change
"WASM output" to "WASM-output" and "JS facing" to "JS-facing" in the sentence
containing "Crate type: `cdylib` (WASM output). Most modules are
`#[cfg(target_family = \"wasm\")]` as they are JS facing." and apply the same
hyphenation fix to the repeated occurrences around lines 118–120.
- Around line 40-41: The docs currently omit the optional settings parameter in
JS examples for RaindexOrderBuilder; update the descriptions and examples for
RaindexOrderBuilder.newWithDeployment and RaindexOrderBuilder.newFromState to
mention the optional settings argument (inserted before the deployment or
serialized args) and show examples that pass either a settings object or
undefined; ensure getDeploymentKeys remains documented as-is and add a brief
note near the newWithDeployment/newFromState entries indicating the parameter
order and optionality so readers know to include undefined when skipping
settings.

In `@crates/js_api/src/raindex_order_builder/deposits.rs`:
- Around line 1-90: The WASM bindings in TokenDeposit and the
RaindexOrderBuilder methods (TokenDeposit, impl
From<inner_deposits::TokenDeposit>, get_deposits, set_deposit, unset_deposit,
get_deposit_presets, get_missing_deposits, has_any_deposit) need to be validated
by running Rust formatting, build, clippy and tests; run the suggested commands
(nix develop -c cargo fmt --all, nix develop -c rainix-rs-static, nix develop -c
cargo build, nix develop -c cargo clippy --workspace --all-targets
--all-features -D warnings, nix develop -c cargo test --workspace), fix any
formatting/lint/build/test errors reported (adjust types, imports, async
signatures, error conversions, or missing trait impls in the referenced
functions/impls), then re-run the commands until all pass.

In `@crates/js_api/src/raindex_order_builder/mod.rs`:
- Around line 138-142: The doc header for getBuilderConfig is inconsistent (says
"complete configuration including all deployments" but function filters to the
current deployment); update the function's top-level Rust doc comment in
raindex_order_builder::getBuilderConfig to clearly state it returns the parsed
builder section from the YAML filtered to the current deployment (not all
deployments), and adjust the summary line and first sentence to match the
detailed description so readers know this returns order-level metadata scoped to
the current deployment.
- Around line 273-276: The docs state that `builder.short-description` is
optional but tests expect it to be required; update the documentation comment
(the block that lists `builder.name`, `builder.description`, and
`builder.short-description`) to mark `builder.short-description` as required
(remove "optional but recommended" and state it is required), or alternatively
change the tests that enforce `short-description` to treat it as optional—choose
the approach consistent with the intended API and keep the wording for
`builder.name` and `builder.description` unchanged.

In `@crates/js_api/src/raindex_order_builder/select_tokens.rs`:
- Around line 1-2: The crate changes in select_tokens.rs need verification that
Rust build/lint/test steps were executed: run in the crate root (and workspace)
cargo build, cargo fmt, rainix-rs-static (nix develop -c ... if your repo uses
that wrapper), cargo clippy --workspace --all-targets --all-features -D
warnings, and cargo test --workspace; then update the PR or commit message with
a confirmation and any clippy/fmt fixes applied (or include the generated format
changes), and ensure the repository-level CI (nix/cargo steps) passes—refer to
this file select_tokens.rs and the crate js_api to locate where to run these
checks.

In `@packages/ui-components/src/__tests__/SelectToken.test.ts`:
- Around line 67-75: The beforeEach currently calls vi.clearAllMocks() after
setting up mocks which can hide prior call history if order changes; move
vi.clearAllMocks() to the top of the beforeEach so you clear previous mocks/call
history first, then initialize mockStateUpdateCallback, set
mockBuilder.setSelectToken's implementation, and call (useRaindexOrderBuilder as
Mock).mockReturnValue(mockBuilder) to set up the mocks in the correct, idiomatic
order.

In `@packages/ui-components/src/__tests__/TokenSelectionModal.test.ts`:
- Around line 38-40: The test mocks the wrong module specifier: replace the
relative path in the vi.mock call with the same module specifier used in the
import so the mock resolves correctly; update the vi.mock(...) entry to mock
"$lib/hooks/useRaindexOrderBuilder" and keep the exported shape
(useRaindexOrderBuilder: vi.fn()) so the imported hook in
TokenSelectionModal.test.ts is properly mocked.

In `@packages/ui-components/src/lib/components/deployment/DepositInput.svelte`:
- Around line 1-16: This change touches the DepositInput.svelte UI component in
packages/ui-components—please run the full frontend verification: build the
package (nix develop -c npm run build -w `@rainlanguage/ui-components`), run
svelte lint/format check (nix develop -c npm run svelte-lint-format-check -w
`@rainlanguage/ui-components`), run unit tests (nix develop -c npm run test -w
`@rainlanguage/ui-components`), and run project-wide formatting, linting and type
checks (nix develop -c npm run format, nix develop -c npm run lint, nix develop
-c npm run check); also build and preview the webapp, take and attach a
screenshot showing the updated DepositInput.svelte UI (and include test/build
logs or artifacts), then update the PR with these artifacts to confirm frontend
verification was completed.

In `@packages/ui-components/src/lib/components/detail/OrderDetail.svelte`:
- Around line 314-320: This change adds a "Builder State" TabItem rendering
formatBuilderState(data.orderBuilderState) in OrderDetail.svelte; attach a
screenshot of the webapp preview showing the Builder State tab open and the JSON
output (confirming data.orderBuilderState renders correctly) and run the
required verification commands: build and lint/test the ui-components package
(npm run format, svelte-lint-format-check, build, test for
`@rainlanguage/ui-components`) and build/preview the webapp (npm run build and npm
run preview for `@rainlanguage/webapp`) as listed in the review so CI/local checks
pass; include the screenshot and a short note that all listed commands completed
successfully.

In `@packages/ui-components/src/lib/hooks/useRaindexOrderBuilder.ts`:
- Line 2: The import of RaindexOrderBuilder is currently a runtime import but
it's only used as a type in getContext<RaindexOrderBuilder>; change it to a
type-only import so the module doesn't pull in the WASM/runtime side-effect at
import time. Replace the existing import with a type import for
RaindexOrderBuilder and keep the usage in getContext<RaindexOrderBuilder>
unchanged so tooling and runtime behave correctly.

In `@packages/ui-components/src/lib/services/registry.ts`:
- Around line 1-3: The PR lacks frontend verification artifacts for changes in
the order validation service
(packages/ui-components/src/lib/services/registry.ts which imports
InvalidOrderDetail, ValidOrderDetail and RaindexOrderBuilder); please run the
project checks and build for `@rainlanguage/ui-components` using nix develop -c
npm run format -w `@rainlanguage/ui-components`, ... -w
`@rainlanguage/ui-components` (format, lint, check, build,
svelte-lint-format-check, test), then build and preview the webapp with nix
develop -c npm run build -w `@rainlanguage/webapp` and nix develop -c npm run
preview -w `@rainlanguage/webapp`, exercise the UI flows that use the order
validation (create/submit various valid and invalid orders via the components
relying on RaindexOrderBuilder and ValidOrderDetail/InvalidOrderDetail), capture
a screenshot of the preview showing successful validation behavior and include
the screenshot and a brief bullet list of manual verification steps in the PR
description.

---

Outside diff comments:
In `@crates/common/src/raindex_order_builder/order_operations.rs`:
- Around line 241-288: The current check uses
!allowance_float.eq(*deposit_amount) which causes approval when allowance is
greater than the required amount; update generate_approval_calldatas to only
create an approval calldata when the existing allowance is strictly less than
the required deposit. Specifically, compare allowance_float against the required
deposit amount in the same units (convert deposit_amount to the same
fixed-decimal representation as allowance_float) and replace the eq-based
condition with a "allowance < required" check (references:
generate_approval_calldatas, allowance_float, deposit_amount, check_allowance,
to_fixed_decimal).

In `@crates/js_api/src/registry.rs`:
- Around line 415-522: The match produces a Result<RaindexOrderBuilder,
RaindexOrderBuilderWasmError> named result which is then converted with map_err
into DotrainRegistryError; since DotrainRegistryError implements #[from] for
RaindexOrderBuilderWasmError you can replace the explicit map_err with the try
operator. In get_order_builder, change the final conversion from "let builder =
result.map_err(DotrainRegistryError::BuilderError)?; Ok(builder)" (or similar)
to simply use the try operator on result (e.g., let builder = result?; or return
Ok(result?);) so the RaindexOrderBuilderWasmError is automatically converted
into DotrainRegistryError.
- Around line 12-115: The example call to DotrainRegistry.getOrderBuilder passes
stateCallback as the third argument but the API expects serializedState as the
third and stateUpdateCallback as the fourth; update the example so
DotrainRegistry.new(...) is followed by registry.getOrderBuilder("fixed-limit",
"mainnet", serializedState, stateCallback) (i.e., supply a serializedState value
or null/undefined in the third position and move stateCallback to the fourth) so
it matches the getOrderBuilder parameter order used in the implementation.

In `@crates/settings/src/order_builder.rs`:
- Around line 1-16: Run the Rust formatting, static linting, build, clippy
checks, and tests for this crate to ensure changes compiling and follow style
rules: execute `nix develop -c cargo fmt --all`, `nix develop -c
rainix-rs-static`, `nix develop -c cargo build`, `nix develop -c cargo clippy
--workspace --all-targets --all-features -D warnings`, and `nix develop -c cargo
test --workspace`; verify the module that defines Context and
OrderBuilderContextTrait (and related types like DeploymentCfg, TokenCfg) in
this crate compiles cleanly and fixes any formatting or clippy warnings
reported.
- Around line 468-503: parse_order_details currently treats "short-description"
as required; change the logic so "short-description" is fetched with the
optional YAML helper (instead of require_string) so missing short-description
returns None rather than an error, then set
NameAndDescriptionCfg.short_description to that Option; update the
short_description retrieval that currently calls
require_string(get_hash_value(...), ...) to use the optional string helper (or
equivalent optional accessor) with get_hash_value(builder, "short-description",
Some("builder".to_string())) so valid configs without short-description no
longer error in parse_order_details.

In `@crates/settings/src/yaml/emitter.rs`:
- Around line 14-33: The CANONICAL_ROOT_KEYS constant was changed to "builder"
which causes top-level "gui" keys to be filtered out in emit_documents and
silent for users because OrderBuilderCfg::parse_from_yaml_optional returns None;
update validate_and_emit_documents to detect a legacy "gui" top-level key (or
detect it in emit_documents) and either migrate it to "builder" before filtering
or emit a clear diagnostic error instead of silently dropping it, and ensure
OrderBuilderCfg::parse_from_yaml_optional surfaces an error or warning when a
legacy "gui" document is encountered so users are notified of the required
change.

In `@packages/orderbook/test/js_api/builder.test.ts`:
- Around line 1-23: Run and verify the Orderbook package build/test/lint/check
steps: execute npm run build:orderbook, npm run check -w
`@rainlanguage/orderbook`, and npm run test -w `@rainlanguage/orderbook` locally and
confirm green results; also run the package-level format/lint/check steps for
packages/orderbook (format, lint, and type-check) and correct any failures found
(fix TypeScript errors, formatting, or lint violations) so tests like
packages/orderbook/test/js_api/builder.test.ts import symbols (e.g.,
RaindexOrderBuilder, OrderbookYaml) from the compiled output correctly and CI
will pass.

In `@packages/orderbook/test/js_api/dotrainRegistry.test.ts`:
- Around line 1-6: This change touches the orderbook package tests — ensure the
package builds, type-checks, formats and tests by running the required nix/npm
commands: execute `nix develop -c npm run build:orderbook` to build, `nix
develop -c npm run check -w `@rainlanguage/orderbook`` to run TypeScript checks
for the package (covers symbols like OrderbookYaml and DotrainRegistry used in
dotrainRegistry.test.ts), and `nix develop -c npm run test -w
`@rainlanguage/orderbook`` to run the package tests; also run project-wide
formatting, linting and checks with `nix develop -c npm run format`, `nix
develop -c npm run lint`, and `nix develop -c npm run check` to ensure TS/Svelte
formatting and lint rules are satisfied before merging.

In `@packages/ui-components/src/__tests__/ComposedRainlangModal.test.ts`:
- Around line 1-37: Test fails because the package '@rainlanguage/orderbook'
needs a passthrough mock; add a vi.mock for '@rainlanguage/orderbook'
immediately after the svelte-codemirror-editor mock that calls importOriginal
and returns a spread of await importOriginal() so the original exports are
preserved (place this mock near the other vi.mock calls in
ComposedRainlangModal.test.ts alongside useRaindexOrderBuilder and mockBuilder
setup).

In `@packages/ui-components/src/__tests__/DeploymentSteps.test.ts`:
- Around line 107-114: The mock for builderInstance.getCurrentDeployment returns
mockDeployment directly but should match the builder API shape
WasmEncodedResult<OrderBuilderDeploymentCfg> (an object with value and error);
update the initial mock on builderInstance (getCurrentDeployment) to return {
value: mockDeployment, error: null } (or appropriate error) so it aligns with
other mocks like getAllFieldDefinitions and with later tests that override it.

In
`@packages/ui-components/src/lib/components/deployment/ComposedRainlangModal.svelte`:
- Around line 1-20: The PR modifies the UI in ComposedRainlangModal.svelte
(notably the generateRainlang function and UI around rainlangText/open) but
lacks the required built-app screenshot and preview instructions; please attach
a screenshot showing the modal/UI state after building the webapp and include
concise build/preview steps (commands used, environment, branch/commit, and URL
or local port used) so reviewers can reproduce the UI (e.g., build/install, run
dev/preview, navigate to the component and invoke generateRainlang to show the
modal).

In
`@packages/ui-components/src/lib/components/deployment/FieldDefinitionInput.svelte`:
- Around line 1-55: Run the full UI components verification for
packages/ui-components to ensure build, lint, format and type checks pass for
this change in FieldDefinitionInput.svelte: run the build and tests (e.g., npm
run build -w `@rainlanguage/ui-components` and npm run test -w
`@rainlanguage/ui-components`), run Svelte/TS formatting and linting (e.g., npm
run svelte-lint-format-check -w `@rainlanguage/ui-components`, npm run format, npm
run lint) and run type checks (npm run check) before merging; if any errors
reference FieldDefinitionInput.svelte (including onMount, handlePresetClick,
handleCustomInputChange or useRaindexOrderBuilder usage), fix
formatting/type/lint issues and re-run the commands until all checks succeed.

In `@packages/ui-components/src/lib/components/deployment/SelectToken.svelte`:
- Around line 26-40: The onMount block may throw a TypeError when
builder.getTokenInfo returns { value: null }; update the logic in the onMount
async handler (the function that calls builder.getTokenInfo) to guard access to
result.value before reading properties: check result.value exists (or use
optional chaining) before assigning tokenInfo, reading result.value.address,
setting inputValue, or calling onSelectTokenSelect(token.key), and preserve the
existing error handling behavior.

In
`@packages/ui-components/src/lib/components/deployment/TokenSelectionModal.svelte`:
- Around line 5-22: The reviewer requires a built-webapp screenshot showing the
TokenSelectionModal change: rebuild and preview the webapp and attach a
screenshot showing the updated token source UI (TokenSelectionModal.svelte /
loadTokens -> builder.getAllTokens). Run the prescribed commands to verify the
frontend: `nix develop -c npm run build -w `@rainlanguage/webapp`` then `nix
develop -c npm run preview -w `@rainlanguage/webapp``, open the page where
TokenSelectionModal is used, capture a clear screenshot of the modal/search
results, and add that image to the PR with a short confirmation comment stating
the build and preview commands succeeded.

In `@packages/ui-components/src/lib/services/registry.ts`:
- Around line 83-94: The code in RaindexOrderBuilder.getOrderDetails handling
incorrectly accesses result.error.msg; update the error property access to
result.error.readableMsg in the failure branch where you throw (inside the
function returning { valid: true, data: ... } path) so the thrown Error uses the
exported readableMsg; locate the usage in registry.ts around the variable
registryDotrain and replace `.msg` with `.readableMsg` (and mirror the same fix
in any other files listed like handleShareChoices.ts and TokenIOInput.svelte if
present).

In `@packages/webapp/src/lib/services/handleAddOrder.ts`:
- Around line 1-14: This PR touches frontend file handleAddOrder.ts (imports
like RaindexOrderBuilder, RaindexClient, QKEY_ORDERS), so run the required
webapp verification: execute nix develop -c npm run build -w
`@rainlanguage/webapp`, nix develop -c npm run svelte-lint-format-check -w
`@rainlanguage/webapp`, and nix develop -c npm run test -w `@rainlanguage/webapp`;
run formatting, linting and type checks via nix develop -c npm run format, nix
develop -c npm run lint, and nix develop -c npm run check; then start a preview
of the built webapp and attach a screenshot that clearly shows the changed
behavior/UI (include timestamp or browser URL in the shot) to the PR comments so
reviewers can confirm the frontend change.

In `@packages/webapp/src/routes/deploy/`[orderName]/[deploymentKey]/+page.svelte:
- Around line 69-88: The PR changes the conditional rendering in +page.svelte
for RaindexOrderBuilderProvider/DeploymentSteps; provide a frontend verification
screenshot of the built webapp showing the builder view (when builder is truthy)
and include the image in the PR, and run the full Svelte build/preview/lint/test
checks: execute `nix develop -c npm run build -w `@rainlanguage/webapp``, then
`nix develop -c npm run preview -w `@rainlanguage/webapp`` to capture the running
UI screenshot for the route /deploy/[orderName]/[deploymentKey], and finally run
`nix develop -c npm run svelte-lint-format-check -w `@rainlanguage/webapp`` and
`nix develop -c npm run test -w `@rainlanguage/webapp`` to show lint/format/tests
pass; attach the screenshot and CI output to the PR for review.

ℹ️ Review info

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d9fff37 and cd87ecc.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (81)
  • ai_commands/sdk-documentation-update.md
  • crates/bindings/ARCHITECTURE.md
  • crates/common/Cargo.toml
  • crates/common/src/add_order.rs
  • crates/common/src/dotrain_order.rs
  • crates/common/src/lib.rs
  • crates/common/src/parsed_meta.rs
  • crates/common/src/raindex_client/orders.rs
  • crates/common/src/raindex_order_builder/deposits.rs
  • crates/common/src/raindex_order_builder/field_values.rs
  • crates/common/src/raindex_order_builder/mod.rs
  • crates/common/src/raindex_order_builder/order_operations.rs
  • crates/common/src/raindex_order_builder/select_tokens.rs
  • crates/common/src/raindex_order_builder/state_management.rs
  • crates/common/src/raindex_order_builder/validation.rs
  • crates/common/src/test_helpers.rs
  • crates/js_api/ARCHITECTURE.md
  • crates/js_api/src/gui/deposits.rs
  • crates/js_api/src/gui/field_values.rs
  • crates/js_api/src/gui/select_tokens.rs
  • crates/js_api/src/lib.rs
  • crates/js_api/src/raindex_order_builder/deposits.rs
  • crates/js_api/src/raindex_order_builder/field_values.rs
  • crates/js_api/src/raindex_order_builder/mod.rs
  • crates/js_api/src/raindex_order_builder/order_operations.rs
  • crates/js_api/src/raindex_order_builder/select_tokens.rs
  • crates/js_api/src/raindex_order_builder/state_management.rs
  • crates/js_api/src/registry.rs
  • crates/settings/ARCHITECTURE.md
  • crates/settings/src/deployment.rs
  • crates/settings/src/lib.rs
  • crates/settings/src/order.rs
  • crates/settings/src/order_builder.rs
  • crates/settings/src/yaml/context.rs
  • crates/settings/src/yaml/dotrain.rs
  • crates/settings/src/yaml/emitter.rs
  • crates/settings/src/yaml/mod.rs
  • crates/settings/src/yaml/orderbook.rs
  • lib/rain.interpreter
  • packages/orderbook/ARCHITECTURE.md
  • packages/orderbook/README.md
  • packages/orderbook/test/js_api/builder.test.ts
  • packages/orderbook/test/js_api/dotrainRegistry.test.ts
  • packages/ui-components/ARCHITECTURE.md
  • packages/ui-components/src/__tests__/ComposedRainlangModal.test.ts
  • packages/ui-components/src/__tests__/DeploymentSteps.test.ts
  • packages/ui-components/src/__tests__/DepositInput.test.ts
  • packages/ui-components/src/__tests__/DotrainRegistryProvider.test.ts
  • packages/ui-components/src/__tests__/FieldDefinitionInput.test.ts
  • packages/ui-components/src/__tests__/OrderDetail.test.ts
  • packages/ui-components/src/__tests__/SelectToken.test.ts
  • packages/ui-components/src/__tests__/TokenIOInput.test.ts
  • packages/ui-components/src/__tests__/TokenSelectionModal.test.ts
  • packages/ui-components/src/__tests__/handleShareChoices.test.ts
  • packages/ui-components/src/__tests__/registry.test.ts
  • packages/ui-components/src/lib/components/deployment/ComposedRainlangModal.svelte
  • packages/ui-components/src/lib/components/deployment/DeploymentSteps.svelte
  • packages/ui-components/src/lib/components/deployment/DepositInput.svelte
  • packages/ui-components/src/lib/components/deployment/FieldDefinitionInput.svelte
  • packages/ui-components/src/lib/components/deployment/SelectToken.svelte
  • packages/ui-components/src/lib/components/deployment/TokenIOInput.svelte
  • packages/ui-components/src/lib/components/deployment/TokenSelectionModal.svelte
  • packages/ui-components/src/lib/components/detail/OrderDetail.svelte
  • packages/ui-components/src/lib/errors/DeploymentStepsError.ts
  • packages/ui-components/src/lib/hooks/useGui.test.ts
  • packages/ui-components/src/lib/hooks/useGui.ts
  • packages/ui-components/src/lib/hooks/useRaindexOrderBuilder.test.ts
  • packages/ui-components/src/lib/hooks/useRaindexOrderBuilder.ts
  • packages/ui-components/src/lib/index.ts
  • packages/ui-components/src/lib/providers/GuiProvider.svelte
  • packages/ui-components/src/lib/providers/RaindexOrderBuilderProvider.svelte
  • packages/ui-components/src/lib/services/handleShareChoices.ts
  • packages/ui-components/src/lib/services/registry.ts
  • packages/ui-components/test-setup.ts
  • packages/webapp/ARCHITECTURE.md
  • packages/webapp/src/__tests__/handleAddOrder.test.ts
  • packages/webapp/src/lib/services/handleAddOrder.ts
  • packages/webapp/src/lib/services/handleUpdateBuilderState.ts
  • packages/webapp/src/routes/deploy/[orderName]/[deploymentKey]/+page.svelte
  • packages/webapp/src/routes/deploy/[orderName]/[deploymentKey]/fullDeployment.test.ts
  • packages/webapp/src/routes/deploy/[orderName]/[deploymentKey]/page.test.ts
💤 Files with no reviewable changes (6)
  • packages/ui-components/src/lib/hooks/useGui.test.ts
  • packages/ui-components/src/lib/hooks/useGui.ts
  • crates/js_api/src/gui/select_tokens.rs
  • crates/js_api/src/gui/deposits.rs
  • crates/js_api/src/gui/field_values.rs
  • packages/ui-components/src/lib/providers/GuiProvider.svelte


**Build & Targets**
- Crate type: `cdylib` (WASM output). Most modules are `#[cfg(target_family = "wasm")]` as they are JS/GUI facing.
- Crate type: `cdylib` (WASM output). Most modules are `#[cfg(target_family = "wasm")]` as they are JS facing.
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.

⚠️ Potential issue | 🟡 Minor

Minor grammar: add hyphens for compound adjectives.

✍️ Suggested edits
-- Crate type: `cdylib` (WASM output). Most modules are `#[cfg(target_family = "wasm")]` as they are JS facing.
+- Crate type: `cdylib` (WASM output). Most modules are `#[cfg(target_family = "wasm")]` as they are JS-facing.

-- Provides `to_readable_msg()` with end-user friendly explanations.
+- Provides `to_readable_msg()` with end-user-friendly explanations.

Also applies to: 118-120

🧰 Tools
🪛 LanguageTool

[grammar] ~7-~7: Use a hyphen to join words.
Context: ...target_family = "wasm")]as they are JS facing. - Key dependencies:wasm-bindge...

(QB_NEW_EN_HYPHEN)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/js_api/ARCHITECTURE.md` at line 7, Update the phrasing to use
hyphenated compound adjectives: change "WASM output" to "WASM-output" and "JS
facing" to "JS-facing" in the sentence containing "Crate type: `cdylib` (WASM
output). Most modules are `#[cfg(target_family = \"wasm\")]` as they are JS
facing." and apply the same hyphenation fix to the repeated occurrences around
lines 118–120.

Comment on lines +40 to +41
- `RaindexOrderBuilder.getDeploymentKeys(dotrain: string) -> string[]` parses `builder.deployments`.
- `RaindexOrderBuilder.newWithDeployment(dotrain, selectedDeployment, stateUpdateCallback?) -> RaindexOrderBuilder` validates the deployment and bootstraps an order builder instance.
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.

⚠️ Potential issue | 🟡 Minor

Document the optional settings parameter in JS examples.
newWithDeployment/newFromState include an optional settings param before the deployment/serialized args; the docs should reflect that or show undefined.

📚 Suggested doc updates
-      - `RaindexOrderBuilder.newWithDeployment(dotrain, selectedDeployment, stateUpdateCallback?) -> RaindexOrderBuilder`
+      - `RaindexOrderBuilder.newWithDeployment(dotrain, settings?, selectedDeployment, stateUpdateCallback?) -> RaindexOrderBuilder`

-  - `const builder = await RaindexOrderBuilder.newWithDeployment(dotrain, deploymentKey, onStateChanged?)`
+  - `const builder = await RaindexOrderBuilder.newWithDeployment(dotrain, undefined, deploymentKey, onStateChanged?)`

-  - Persist UI state: read `serializeState()`; restore later with `RaindexOrderBuilder.newFromState(dotrain, serialized, callback?)`.
+  - Persist UI state: read `serializeState()`; restore later with `RaindexOrderBuilder.newFromState(dotrain, undefined, serialized, callback?)`.

Also applies to: 186-189

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/js_api/ARCHITECTURE.md` around lines 40 - 41, The docs currently omit
the optional settings parameter in JS examples for RaindexOrderBuilder; update
the descriptions and examples for RaindexOrderBuilder.newWithDeployment and
RaindexOrderBuilder.newFromState to mention the optional settings argument
(inserted before the deployment or serialized args) and show examples that pass
either a settings object or undefined; ensure getDeploymentKeys remains
documented as-is and add a brief note near the newWithDeployment/newFromState
entries indicating the parameter order and optionality so readers know to
include undefined when skipping settings.

Comment on lines +1 to +90
use super::*;
use alloy::primitives::Address;
use rain_orderbook_common::raindex_order_builder::deposits as inner_deposits;

#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Tsify)]
pub struct TokenDeposit {
pub token: String,
pub amount: String,
#[tsify(type = "string")]
pub address: Address,
}
impl_wasm_traits!(TokenDeposit);

impl From<inner_deposits::TokenDeposit> for TokenDeposit {
fn from(td: inner_deposits::TokenDeposit) -> Self {
Self {
token: td.token,
amount: td.amount,
address: td.address,
}
}
}

#[wasm_export]
impl RaindexOrderBuilder {
#[wasm_export(
js_name = "getDeposits",
unchecked_return_type = "TokenDeposit[]",
return_description = "Array of configured deposits with token info and amounts"
)]
pub fn get_deposits(&self) -> Result<Vec<TokenDeposit>, RaindexOrderBuilderWasmError> {
Ok(self
.inner
.get_deposits()?
.into_iter()
.map(Into::into)
.collect())
}

#[wasm_export(js_name = "setDeposit", unchecked_return_type = "void")]
pub async fn set_deposit(
&mut self,
#[wasm_export(param_description = "Token key from the YAML configuration")] token: String,
#[wasm_export(param_description = "Deposit amount as a decimal string")] amount: String,
) -> Result<(), RaindexOrderBuilderWasmError> {
self.inner.set_deposit(token, amount).await?;
self.execute_state_update_callback()?;
Ok(())
}

#[wasm_export(js_name = "unsetDeposit", unchecked_return_type = "void")]
pub fn unset_deposit(
&mut self,
#[wasm_export(param_description = "Token key to remove deposit for")] token: String,
) -> Result<(), RaindexOrderBuilderWasmError> {
self.inner.unset_deposit(token)?;
self.execute_state_update_callback()?;
Ok(())
}

#[wasm_export(
js_name = "getDepositPresets",
unchecked_return_type = "string[]",
return_description = "Array of preset deposit amounts"
)]
pub fn get_deposit_presets(
&self,
#[wasm_export(param_description = "Token key to get presets for")] key: String,
) -> Result<Vec<String>, RaindexOrderBuilderWasmError> {
Ok(self.inner.get_deposit_presets(key)?)
}

#[wasm_export(
js_name = "getMissingDeposits",
unchecked_return_type = "string[]",
return_description = "Array of token keys that need deposits"
)]
pub fn get_missing_deposits(&self) -> Result<Vec<String>, RaindexOrderBuilderWasmError> {
Ok(self.inner.get_missing_deposits()?)
}

#[wasm_export(
js_name = "hasAnyDeposit",
unchecked_return_type = "boolean",
return_description = "Whether any deposit has been set"
)]
pub fn has_any_deposit(&self) -> Result<bool, RaindexOrderBuilderWasmError> {
Ok(self.inner.has_any_deposit()?)
}
}
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.

🧹 Nitpick | 🔵 Trivial

Please confirm Rust formatting/lint/test runs for the new WASM bindings.
Suggested commands:

  • nix develop -c cargo fmt --all
  • nix develop -c rainix-rs-static
  • nix develop -c cargo build
  • nix develop -c cargo clippy --workspace --all-targets --all-features -D warnings
  • nix develop -c cargo test --workspace

As per coding guidelines, “crates//*.rs: Run nix develop -c cargo build … clippy … cargo test …” and “/*.rs: Format Rust code with nix develop -c cargo fmt --all; Lint Rust code with nix develop -c rainix-rs-static …”.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/js_api/src/raindex_order_builder/deposits.rs` around lines 1 - 90, The
WASM bindings in TokenDeposit and the RaindexOrderBuilder methods (TokenDeposit,
impl From<inner_deposits::TokenDeposit>, get_deposits, set_deposit,
unset_deposit, get_deposit_presets, get_missing_deposits, has_any_deposit) need
to be validated by running Rust formatting, build, clippy and tests; run the
suggested commands (nix develop -c cargo fmt --all, nix develop -c
rainix-rs-static, nix develop -c cargo build, nix develop -c cargo clippy
--workspace --all-targets --all-features -D warnings, nix develop -c cargo test
--workspace), fix any formatting/lint/build/test errors reported (adjust types,
imports, async signatures, error conversions, or missing trait impls in the
referenced functions/impls), then re-run the commands until all pass.

Comment on lines +138 to 142
/// Retrieves the complete builder configuration including all deployments.
///
/// This returns the parsed GUI section from the YAML, filtered to include only
/// This returns the parsed builder section from the YAML, filtered to include only
/// the current deployment. Use this to access order-level metadata.
///
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.

⚠️ Potential issue | 🟡 Minor

Clarify getBuilderConfig docs (current deployment vs all).
The header says “complete configuration including all deployments,” but the description says it’s filtered to the current deployment.

✍️ Suggested wording
-/// Retrieves the complete builder configuration including all deployments.
-///
-/// This returns the parsed builder section from the YAML, filtered to include only
-/// the current deployment. Use this to access order-level metadata.
+/// Retrieves the builder configuration for the currently selected deployment.
+///
+/// This returns the parsed builder section from the YAML filtered to the current
+/// deployment. Use this to access order-level metadata.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
/// Retrieves the complete builder configuration including all deployments.
///
/// This returns the parsed GUI section from the YAML, filtered to include only
/// This returns the parsed builder section from the YAML, filtered to include only
/// the current deployment. Use this to access order-level metadata.
///
/// Retrieves the builder configuration for the currently selected deployment.
///
/// This returns the parsed builder section from the YAML filtered to the current
/// deployment. Use this to access order-level metadata.
///
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/js_api/src/raindex_order_builder/mod.rs` around lines 138 - 142, The
doc header for getBuilderConfig is inconsistent (says "complete configuration
including all deployments" but function filters to the current deployment);
update the function's top-level Rust doc comment in
raindex_order_builder::getBuilderConfig to clearly state it returns the parsed
builder section from the YAML filtered to the current deployment (not all
deployments), and adjust the summary line and first sentence to match the
detailed description so readers know this returns order-level metadata scoped to
the current deployment.

Comment on lines +273 to 276
/// - `builder.name` - Order display name
/// - `builder.description` - Full order description
/// - `builder.short-description` - Brief summary (optional but recommended)
///
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.

⚠️ Potential issue | 🟡 Minor

Docs say short-description is optional, but tests treat it as required.
If it’s required (as the tests indicate), the docs should reflect that.

✍️ Suggested wording
-/// - `builder.short-description` - Brief summary (optional but recommended)
+/// - `builder.short-description` - Brief summary (required)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/js_api/src/raindex_order_builder/mod.rs` around lines 273 - 276, The
docs state that `builder.short-description` is optional but tests expect it to
be required; update the documentation comment (the block that lists
`builder.name`, `builder.description`, and `builder.short-description`) to mark
`builder.short-description` as required (remove "optional but recommended" and
state it is required), or alternatively change the tests that enforce
`short-description` to treat it as optional—choose the approach consistent with
the intended API and keep the wording for `builder.name` and
`builder.description` unchanged.

Comment on lines +38 to 40
vi.mock('../lib/hooks/useRaindexOrderBuilder', () => ({
useRaindexOrderBuilder: vi.fn()
}));
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.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# First, check the actual content of the test file, specifically looking at imports and the mock
sed -n '1,50p' packages/ui-components/src/__tests__/TokenSelectionModal.test.ts | cat -n

Repository: rainlanguage/rain.orderbook

Length of output: 1857


🏁 Script executed:

#!/bin/bash
# Check if there's a Vitest or Vite config that defines the $lib alias
fd -e config.ts -e vite.config.ts packages/ui-components | head -5

Repository: rainlanguage/rain.orderbook

Length of output: 464


🏁 Script executed:

#!/bin/bash
# Search for other vi.mock patterns in test files to see if relative or alias is standard
rg "vi\.mock\(" packages/ui-components/src/__tests__/ | head -20

Repository: rainlanguage/rain.orderbook

Length of output: 2330


🏁 Script executed:

#!/bin/bash
# Check the Vite config for $lib alias setup
cat packages/ui-components/vite.config.ts | head -50

Repository: rainlanguage/rain.orderbook

Length of output: 888


🏁 Script executed:

#!/bin/bash
# Search for other cases where vi.mock uses relative path while component/test imports using $lib
rg -B2 "from '\$lib" packages/ui-components/src/__tests__/*.test.ts | rg -A2 "vi\.mock\(" | head -30

Repository: rainlanguage/rain.orderbook

Length of output: 53


🏁 Script executed:

#!/bin/bash
# Check if there are other mismatch cases (relative path mocks with $lib imports)
rg "vi\.mock\('\.\./" packages/ui-components/src/__tests__/ -A1 -B5 | head -50

Repository: rainlanguage/rain.orderbook

Length of output: 4640


🏁 Script executed:

#!/bin/bash
# Verify if the test file actually runs and if the mock is being applied by checking test patterns
grep -A 20 "beforeEach\|it(" packages/ui-components/src/__tests__/TokenSelectionModal.test.ts | head -40

Repository: rainlanguage/rain.orderbook

Length of output: 1374


🏁 Script executed:

#!/bin/bash
# Check if there's any evidence of tests passing or failing with this mock setup
# Look for how the mock is actually used in tests
grep -n "useRaindexOrderBuilder\|mockBuilder\|getAllTokens" packages/ui-components/src/__tests__/TokenSelectionModal.test.ts | head -20

Repository: rainlanguage/rain.orderbook

Length of output: 1083


Use the same module specifier for import and mock.

useRaindexOrderBuilder is imported with the $lib alias (line 7) but mocked with a relative path (line 38). Module mocking in Vitest requires exact specifier matching. Change the mock to use $lib to align with the import.

🔧 Suggested fix
-vi.mock('../lib/hooks/useRaindexOrderBuilder', () => ({
+vi.mock('$lib/hooks/useRaindexOrderBuilder', () => ({
 	useRaindexOrderBuilder: vi.fn()
 }));
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
vi.mock('../lib/hooks/useRaindexOrderBuilder', () => ({
useRaindexOrderBuilder: vi.fn()
}));
vi.mock('$lib/hooks/useRaindexOrderBuilder', () => ({
useRaindexOrderBuilder: vi.fn()
}));
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/ui-components/src/__tests__/TokenSelectionModal.test.ts` around
lines 38 - 40, The test mocks the wrong module specifier: replace the relative
path in the vi.mock call with the same module specifier used in the import so
the mock resolves correctly; update the vi.mock(...) entry to mock
"$lib/hooks/useRaindexOrderBuilder" and keep the exported shape
(useRaindexOrderBuilder: vi.fn()) so the imported hook in
TokenSelectionModal.test.ts is properly mocked.

Comment on lines 1 to +16
<script lang="ts">
import { type GuiDepositCfg, type TokenDeposit, type TokenInfo } from '@rainlanguage/orderbook';
import {
type OrderBuilderDepositCfg,
type TokenDeposit,
type TokenInfo
} from '@rainlanguage/orderbook';
import { Input } from 'flowbite-svelte';
import ButtonSelectOption from './ButtonSelectOption.svelte';
import DeploymentSectionHeader from './DeploymentSectionHeader.svelte';
import { CloseCircleSolid } from 'flowbite-svelte-icons';
import { onMount } from 'svelte';
import { useGui } from '$lib/hooks/useGui';
import { useRaindexOrderBuilder } from '$lib/hooks/useRaindexOrderBuilder';

export let deposit: GuiDepositCfg;
export let deposit: OrderBuilderDepositCfg;

const gui = useGui();
const builder = useRaindexOrderBuilder();
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.

🧹 Nitpick | 🔵 Trivial

Please confirm required UI-component and frontend verification steps were run (and attach screenshot).

This change touches frontend UI components, so please provide:

  • nix develop -c npm run build -w @rainlanguage/ui-components``
  • nix develop -c npm run svelte-lint-format-check -w @rainlanguage/ui-components``
  • nix develop -c npm run test -w @rainlanguage/ui-components``
  • nix develop -c npm run format, nix develop -c npm run lint, nix develop -c npm run check (for TS/Svelte)
  • Webapp build + preview and a screenshot of the built webapp reflecting the change.

As per coding guidelines: “packages/ui-components//*.{ts,tsx,svelte,js,jsx}: … run nix develop -c npm run build -w @rainlanguage/ui-components, … `nix develop -c npm run svelte-lint-format-check -w `@rainlanguage/ui-components, … nix develop -c npm run test -w @rainlanguage/ui-components``”; “/.{ts,tsx,svelte}: Format TypeScript/Svelte code with nix develop -c npm run format … Lint … Run type checks …”; and “packages/{webapp,ui-components}/**/.{ts,tsx,svelte,js,jsx}: … MUST provide a screenshot … build … preview …”.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/ui-components/src/lib/components/deployment/DepositInput.svelte`
around lines 1 - 16, This change touches the DepositInput.svelte UI component in
packages/ui-components—please run the full frontend verification: build the
package (nix develop -c npm run build -w `@rainlanguage/ui-components`), run
svelte lint/format check (nix develop -c npm run svelte-lint-format-check -w
`@rainlanguage/ui-components`), run unit tests (nix develop -c npm run test -w
`@rainlanguage/ui-components`), and run project-wide formatting, linting and type
checks (nix develop -c npm run format, nix develop -c npm run lint, nix develop
-c npm run check); also build and preview the webapp, take and attach a
screenshot showing the updated DepositInput.svelte UI (and include test/build
logs or artifacts), then update the PR with these artifacts to confirm frontend
verification was completed.

Comment on lines +314 to 320
{#if data.orderBuilderState}
<TabItem title="Builder State">
<div class="mb-4">
<div class="overflow-auto rounded-lg border bg-gray-50 p-4 dark:bg-gray-800">
<pre class="text-sm" data-testid="gui-state-json">
{formatGuiState(data.dotrainGuiState)}
<pre class="text-sm" data-testid="builder-state-json">
{formatBuilderState(data.orderBuilderState)}
</pre>
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.

🧹 Nitpick | 🔵 Trivial

Builder State tab wiring looks good — please attach UI verification artifacts.

Please attach a screenshot from the webapp preview showing the Builder State tab, and confirm the UI-components/webapp checks for this change.

nix develop -c npm run format -w `@rainlanguage/ui-components`
nix develop -c npm run lint -w `@rainlanguage/ui-components`
nix develop -c npm run check -w `@rainlanguage/ui-components`
nix develop -c npm run build -w `@rainlanguage/ui-components`
nix develop -c npm run svelte-lint-format-check -w `@rainlanguage/ui-components`
nix develop -c npm run test -w `@rainlanguage/ui-components`
nix develop -c npm run build -w `@rainlanguage/webapp`
nix develop -c npm run preview -w `@rainlanguage/webapp`

As per coding guidelines: packages/{webapp,ui-components}/**/*.{ts,tsx,svelte,js,jsx}: If you modify frontend code or functionality affecting the frontend, you MUST provide a screenshot of the built webapp reflecting your change; frontend verification requires building and previewing the webapp with nix develop -c npm run build -w @rainlanguage/webapp followed by `nix develop -c npm run preview -w `@rainlanguage/webapp. packages/ui-components/**/*.{ts,tsx,svelte,js,jsx}: For UI components package (@rainlanguage/ui-components), run nix develop -c npm run build -w @rainlanguage/ui-components after making changes; run linting with `nix develop -c npm run svelte-lint-format-check -w `@rainlanguage/ui-components; run tests with nix develop -c npm run test -w @rainlanguage/ui-components``. **/*.{ts,tsx,svelte}: Format TypeScript/Svelte code with `nix develop -c npm run format` in each package; Lint TypeScript/Svelte code with `nix develop -c npm run lint` in each package; Run type checks on TypeScript/Svelte with `nix develop -c npm run check` in each package.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/ui-components/src/lib/components/detail/OrderDetail.svelte` around
lines 314 - 320, This change adds a "Builder State" TabItem rendering
formatBuilderState(data.orderBuilderState) in OrderDetail.svelte; attach a
screenshot of the webapp preview showing the Builder State tab open and the JSON
output (confirming data.orderBuilderState renders correctly) and run the
required verification commands: build and lint/test the ui-components package
(npm run format, svelte-lint-format-check, build, test for
`@rainlanguage/ui-components`) and build/preview the webapp (npm run build and npm
run preview for `@rainlanguage/webapp`) as listed in the review so CI/local checks
pass; include the screenshot and a short note that all listed commands completed
successfully.

@@ -0,0 +1,12 @@
import { getContext } from 'svelte';
import { RaindexOrderBuilder } from '@rainlanguage/orderbook';
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.

🧹 Nitpick | 🔵 Trivial

Prefer import type for type-only usage of RaindexOrderBuilder

RaindexOrderBuilder is used exclusively as a generic type parameter in getContext<RaindexOrderBuilder>. A type-only import makes the intent explicit and avoids a runtime side-effect import of the WASM class.

♻️ Suggested change
-import { RaindexOrderBuilder } from '@rainlanguage/orderbook';
+import type { RaindexOrderBuilder } from '@rainlanguage/orderbook';
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import { RaindexOrderBuilder } from '@rainlanguage/orderbook';
import type { RaindexOrderBuilder } from '@rainlanguage/orderbook';
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/ui-components/src/lib/hooks/useRaindexOrderBuilder.ts` at line 2,
The import of RaindexOrderBuilder is currently a runtime import but it's only
used as a type in getContext<RaindexOrderBuilder>; change it to a type-only
import so the module doesn't pull in the WASM/runtime side-effect at import
time. Replace the existing import with a type import for RaindexOrderBuilder and
keep the usage in getContext<RaindexOrderBuilder> unchanged so tooling and
runtime behave correctly.

Comment on lines 1 to 3
import type { InvalidOrderDetail, ValidOrderDetail } from '$lib/types/order';
import { DotrainOrderGui } from '@rainlanguage/orderbook';
import { RaindexOrderBuilder } from '@rainlanguage/orderbook';

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.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

cat -n packages/ui-components/src/lib/services/registry.ts | head -100

Repository: rainlanguage/rain.orderbook

Length of output: 3613


🏁 Script executed:

cat packages/ui-components/package.json | grep -A 3 '"name"'

Repository: rainlanguage/rain.orderbook

Length of output: 272


🏁 Script executed:

cat packages/webapp/package.json | grep -A 3 '"name"'

Repository: rainlanguage/rain.orderbook

Length of output: 177


🏁 Script executed:

cd packages && ls -la | grep package.json

Repository: rainlanguage/rain.orderbook

Length of output: 53


🏁 Script executed:

rg "RaindexOrderBuilder" -A 5 -B 2 packages/

Repository: rainlanguage/rain.orderbook

Length of output: 50386


🏁 Script executed:

find . -name "*.ts" -o -name "*.tsx" | head -20 | xargs grep -l "getOrderDetails" 2>/dev/null | head -5

Repository: rainlanguage/rain.orderbook

Length of output: 119


🏁 Script executed:

grep -A 10 "getOrderDetails" packages/orderbook/test/js_api/builder.test.ts | head -20

Repository: rainlanguage/rain.orderbook

Length of output: 727


🏁 Script executed:

rg "WasmEncodedResult|error.*msg|error.*readableMsg" packages/orderbook -A 2 -B 2 | head -40

Repository: rainlanguage/rain.orderbook

Length of output: 3518


Provide frontend verification steps and screenshot for this ui-components change.

This file is a service affecting frontend order validation. Per coding guidelines, run nix develop -c npm run format -w @rainlanguage/ui-components, `nix develop -c npm run lint -w `@rainlanguage/ui-components, nix develop -c npm run check -w @rainlanguage/ui-components, `nix develop -c npm run build -w `@rainlanguage/ui-components, nix develop -c npm run svelte-lint-format-check -w @rainlanguage/ui-components, and `nix develop -c npm run test -w `@rainlanguage/ui-components. Then build and preview the webapp with nix develop -c npm run build -w @rainlanguage/webapp followed by `nix develop -c npm run preview -w `@rainlanguage/webapp, and attach a screenshot of the preview.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/ui-components/src/lib/services/registry.ts` around lines 1 - 3, The
PR lacks frontend verification artifacts for changes in the order validation
service (packages/ui-components/src/lib/services/registry.ts which imports
InvalidOrderDetail, ValidOrderDetail and RaindexOrderBuilder); please run the
project checks and build for `@rainlanguage/ui-components` using nix develop -c
npm run format -w `@rainlanguage/ui-components`, ... -w
`@rainlanguage/ui-components` (format, lint, check, build,
svelte-lint-format-check, test), then build and preview the webapp with nix
develop -c npm run build -w `@rainlanguage/webapp` and nix develop -c npm run
preview -w `@rainlanguage/webapp`, exercise the UI flows that use the order
validation (create/submit various valid and invalid orders via the components
relying on RaindexOrderBuilder and ValidOrderDetail/InvalidOrderDetail), capture
a screenshot of the preview showing successful validation behavior and include
the screenshot and a brief bullet list of manual verification steps in the PR
description.

Copy link
Copy Markdown
Contributor

hardyjosh commented Apr 12, 2026

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
crates/common/src/add_order.rs (1)

330-348: ⚠️ Potential issue | 🟠 Major

Validate the builder-state hash before emitting meta.

At Line 334, subject comes from the decoded OrderBuilderStateV1, but the emitted payload is built from self.dotrain. If those ever diverge, this will publish the current dotrain under the wrong subject hash and poison metaboard lookups for that state. Please compare the embedded dotrain_hash() with the hash of self.dotrain and fail on mismatch.

🛡️ Suggested guard
 use rain_metadata::{
+    types::dotrain::source_v1::DotrainSourceV1,
     types::dotrain::order_builder_state_v1::OrderBuilderStateV1,
     types::raindex_signed_context_oracle::RaindexSignedContextOracleV1, ContentEncoding,
     ContentLanguage, ContentType, Error as RainMetaError, KnownMagic, RainMetaDocumentV1Item,
 };
@@
                 {
                     Some(doc) => {
                         let builder_state = OrderBuilderStateV1::try_from(doc.clone())?;
                         let subject_hash = builder_state.dotrain_hash();
+                        let expected_hash = DotrainSourceV1(self.dotrain.clone()).hash();
+                        if subject_hash != expected_hash {
+                            return Err(AddOrderArgsError::InvalidArgs(
+                                "order-builder state dotrain hash does not match emitted dotrain"
+                                    .to_string(),
+                            ));
+                        }
                         let meta_document = RainMetaDocumentV1Item {
                             payload: ByteBuf::from(self.dotrain.as_bytes()),
                             magic: KnownMagic::DotrainSourceV1,
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/common/src/add_order.rs` around lines 330 - 348, The code is emitting
meta using self.dotrain but sets subject from builder_state.dotrain_hash()
(OrderBuilderStateV1::dotrain_hash()), which can diverge; compute the hash of
self.dotrain (same hashing used by OrderBuilderStateV1::dotrain_hash()), compare
it to builder_state.dotrain_hash(), and if they differ return an error (or
propagate a failure) before constructing RainMetaDocumentV1Item and returning
emitMetaCall; update the block around OrderBuilderStateV1 handling (where
subject is set and meta is built) to perform this validation and fail on
mismatch.
crates/common/src/dotrain_order.rs (1)

757-814: ⚠️ Potential issue | 🟠 Major

Merge all builder sources before pruning.

create_with_profile() supports layered settings, but this helper stops at the first document that contains builder and returns None if that document does not also contain the selected deployment. That means generate_dotrain_for_deployment() can silently drop the builder block when root metadata lives in frontmatter and deployment config is added or overridden in a later settings file. Please merge builder across all documents, or at least keep scanning until the selected deployment is found, before filtering builder.deployments.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/common/src/dotrain_order.rs` around lines 757 - 814, The helper
clone_builder_config_for_deployment currently stops at the first document that
contains a "builder" and returns None if that document lacks the selected
deployment; change it to merge/accumulate the "builder" sections from all
documents (merging top-level builder keys and merging the "deployments" maps
across documents) and only then prune deployments to the single deployment_key
(or at least continue scanning all documents until that deployment is found).
Specifically, in clone_builder_config_for_deployment, iterate all documents to
collect/merge StrictYaml::Hash entries for "builder" (merge keys into
builder_hash, and for "deployments" merge each deployments_hash into a combined
deployments map), then after the merge locate deployment_key in the combined
deployments map, create filtered_deployments with that single entry, insert it
back into the merged builder_hash, and return
Ok(Some(StrictYaml::Hash(builder_hash))); ensure errors are preserved when types
are not maps and only return Ok(None) if no builder or no matching deployment is
present after the full merge.
crates/common/src/raindex_client/orders.rs (1)

1437-1453: ⚠️ Potential issue | 🟠 Major

Keep a legacy GUI-state fallback in fetch_dotrain_source().

This now returns early unless ParsedMeta::OrderBuilderStateV1 exists. Orders that were already published with the old GUI metadata will never satisfy that match, so dotrainSource stops hydrating for historical orders after the rename. crates/common/src/parsed_meta.rs:1-50 reinforces this because the legacy parsed variant is no longer available here either.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/common/src/raindex_client/orders.rs` around lines 1437 - 1453,
fetch_dotrain_source() currently returns early when
ParsedMeta::OrderBuilderStateV1 isn't found, causing legacy GUI-state orders to
never hydrate; update fetch_dotrain_source() to fallback to the legacy parsed
meta variant (the older GUI/state representation) when
ParsedMeta::OrderBuilderStateV1 is missing—search in the function for
self.parsed_meta.iter().find_map(...) and the use of
order_builder_state.dotrain_hash(), and change the match to first try
ParsedMeta::OrderBuilderStateV1 then fallback to the legacy variant (or
reconstruct equivalent state) so dotrainSource continues to be populated for
historical orders while keeping the existing get_metaboard_client() logic and
subject_hash usage.
♻️ Duplicate comments (2)
crates/js_api/src/raindex_order_builder/mod.rs (2)

270-291: ⚠️ Potential issue | 🟡 Minor

getOrderDetails docs still mark builder.short-description as optional.

The tests in this file treat missing builder.short-description as a validation error, so the required-fields list and return_description are still misleading.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/js_api/src/raindex_order_builder/mod.rs` around lines 270 - 291, The
docs for getOrderDetails are inconsistent: update the comment block and the
wasm_export attribute for the getOrderDetails function so that
`builder.short-description` is listed as required (remove "optional but
recommended") and adjust the return_description to reflect that the short
description is always returned; reference the `getOrderDetails` function and the
`builder.short-description` field in your edits so the documentation matches the
validation logic in the tests.

138-158: ⚠️ Potential issue | 🟡 Minor

getBuilderConfig docs still read like this returns all deployments.

The method is described as returning the complete builder config, but the text below it says it is filtered to the current deployment. Please make the summary and return_description match the scoped behavior.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/js_api/src/raindex_order_builder/mod.rs` around lines 138 - 158,
Update the getBuilderConfig doc comments and wasm_export metadata to reflect
that the returned config is scoped/filtered to the current deployment rather
than the complete set of deployments: change the summary sentence to state it
"Retrieves the builder configuration scoped to the current deployment" and
update the wasm_export return_description from "Complete builder configuration
with name, description, and deployments" to something like "Builder
configuration for the current deployment (name, description, and its
deployment-specific settings)"; ensure references to "all deployments" in the
doc block are removed or replaced with "current deployment" and keep the js_name
and unchecked_return_type unchanged.
🧹 Nitpick comments (1)
crates/common/src/raindex_order_builder/state_management.rs (1)

29-35: Add an explicit version envelope to the serialized builder state.

serialize_state() and new_from_state() round-trip a raw SerializedBuilderState payload, so the next field add/remove/rename turns persisted state into an opaque decode failure with no migration path. Since this blob is now a public cross-platform format, it should be versioned up front.

♻️ Possible shape
+#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
+struct VersionedSerializedBuilderState {
+    version: u8,
+    state: SerializedBuilderState,
+}
...
- let bytes = bincode::serialize(&state)?;
+ let bytes = bincode::serialize(&VersionedSerializedBuilderState {
+     version: 1,
+     state,
+ })?;
...
- let state: SerializedBuilderState = bincode::deserialize(&bytes)?;
+ let wrapper: VersionedSerializedBuilderState = bincode::deserialize(&bytes)?;
+ if wrapper.version != 1 {
+     return Err(RaindexOrderBuilderError::UnsupportedStateVersion(wrapper.version));
+ }
+ let state = wrapper.state;

Also applies to: 192-279

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/common/src/raindex_order_builder/state_management.rs` around lines 29
- 35, The serialized payload lacks a version envelope—add a top-level version
field to the persisted format and update serialization/deserialization to use
it: define a new wrapper type (e.g., VersionedSerializedBuilderState or add a
`version: u32` field to SerializedBuilderState) and change serialize_state() to
emit that versioned wrapper, and change new_from_state() to parse the version,
validate/handle known versions (return a clear error or perform migration for
unknown/older versions), ensuring any future field additions can be migrated;
update references to SerializedBuilderState, serialize_state, and new_from_state
accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@crates/js_api/src/raindex_order_builder/mod.rs`:
- Around line 86-106: The examples for RaindexOrderBuilder.newWithDeployment are
passing the deployment key as the second argument which is actually the settings
parameter; update both examples to call newWithDeployment(dotrainYaml, settings,
"mainnet-order", stateUpdateCallback) (i.e., provide a settings object or
null/{} as the second argument and pass the deployment key as the third
argument), and ensure the optional stateUpdateCallback is the fourth parameter
so selectedDeployment is set correctly.

---

Outside diff comments:
In `@crates/common/src/add_order.rs`:
- Around line 330-348: The code is emitting meta using self.dotrain but sets
subject from builder_state.dotrain_hash() (OrderBuilderStateV1::dotrain_hash()),
which can diverge; compute the hash of self.dotrain (same hashing used by
OrderBuilderStateV1::dotrain_hash()), compare it to
builder_state.dotrain_hash(), and if they differ return an error (or propagate a
failure) before constructing RainMetaDocumentV1Item and returning emitMetaCall;
update the block around OrderBuilderStateV1 handling (where subject is set and
meta is built) to perform this validation and fail on mismatch.

In `@crates/common/src/dotrain_order.rs`:
- Around line 757-814: The helper clone_builder_config_for_deployment currently
stops at the first document that contains a "builder" and returns None if that
document lacks the selected deployment; change it to merge/accumulate the
"builder" sections from all documents (merging top-level builder keys and
merging the "deployments" maps across documents) and only then prune deployments
to the single deployment_key (or at least continue scanning all documents until
that deployment is found). Specifically, in clone_builder_config_for_deployment,
iterate all documents to collect/merge StrictYaml::Hash entries for "builder"
(merge keys into builder_hash, and for "deployments" merge each deployments_hash
into a combined deployments map), then after the merge locate deployment_key in
the combined deployments map, create filtered_deployments with that single
entry, insert it back into the merged builder_hash, and return
Ok(Some(StrictYaml::Hash(builder_hash))); ensure errors are preserved when types
are not maps and only return Ok(None) if no builder or no matching deployment is
present after the full merge.

In `@crates/common/src/raindex_client/orders.rs`:
- Around line 1437-1453: fetch_dotrain_source() currently returns early when
ParsedMeta::OrderBuilderStateV1 isn't found, causing legacy GUI-state orders to
never hydrate; update fetch_dotrain_source() to fallback to the legacy parsed
meta variant (the older GUI/state representation) when
ParsedMeta::OrderBuilderStateV1 is missing—search in the function for
self.parsed_meta.iter().find_map(...) and the use of
order_builder_state.dotrain_hash(), and change the match to first try
ParsedMeta::OrderBuilderStateV1 then fallback to the legacy variant (or
reconstruct equivalent state) so dotrainSource continues to be populated for
historical orders while keeping the existing get_metaboard_client() logic and
subject_hash usage.

---

Duplicate comments:
In `@crates/js_api/src/raindex_order_builder/mod.rs`:
- Around line 270-291: The docs for getOrderDetails are inconsistent: update the
comment block and the wasm_export attribute for the getOrderDetails function so
that `builder.short-description` is listed as required (remove "optional but
recommended") and adjust the return_description to reflect that the short
description is always returned; reference the `getOrderDetails` function and the
`builder.short-description` field in your edits so the documentation matches the
validation logic in the tests.
- Around line 138-158: Update the getBuilderConfig doc comments and wasm_export
metadata to reflect that the returned config is scoped/filtered to the current
deployment rather than the complete set of deployments: change the summary
sentence to state it "Retrieves the builder configuration scoped to the current
deployment" and update the wasm_export return_description from "Complete builder
configuration with name, description, and deployments" to something like
"Builder configuration for the current deployment (name, description, and its
deployment-specific settings)"; ensure references to "all deployments" in the
doc block are removed or replaced with "current deployment" and keep the js_name
and unchecked_return_type unchanged.

---

Nitpick comments:
In `@crates/common/src/raindex_order_builder/state_management.rs`:
- Around line 29-35: The serialized payload lacks a version envelope—add a
top-level version field to the persisted format and update
serialization/deserialization to use it: define a new wrapper type (e.g.,
VersionedSerializedBuilderState or add a `version: u32` field to
SerializedBuilderState) and change serialize_state() to emit that versioned
wrapper, and change new_from_state() to parse the version, validate/handle known
versions (return a clear error or perform migration for unknown/older versions),
ensuring any future field additions can be migrated; update references to
SerializedBuilderState, serialize_state, and new_from_state accordingly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 8b07ca34-f708-4421-8be1-6a5cbe732e93

📥 Commits

Reviewing files that changed from the base of the PR and between e6f03ef and c804ebb.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (15)
  • Cargo.toml
  • crates/common/Cargo.toml
  • crates/common/src/add_order.rs
  • crates/common/src/dotrain_order.rs
  • crates/common/src/lib.rs
  • crates/common/src/parsed_meta.rs
  • crates/common/src/raindex_client/orders.rs
  • crates/common/src/raindex_order_builder/mod.rs
  • crates/common/src/raindex_order_builder/order_operations.rs
  • crates/common/src/raindex_order_builder/select_tokens.rs
  • crates/common/src/raindex_order_builder/state_management.rs
  • crates/common/src/test_helpers.rs
  • crates/js_api/src/raindex_order_builder/mod.rs
  • crates/js_api/src/registry.rs
  • crates/settings/src/deployment.rs
✅ Files skipped from review due to trivial changes (4)
  • crates/common/src/lib.rs
  • crates/settings/src/deployment.rs
  • crates/common/src/test_helpers.rs
  • crates/common/src/parsed_meta.rs
🚧 Files skipped from review as they are similar to previous changes (2)
  • crates/common/Cargo.toml
  • crates/js_api/src/registry.rs

Comment on lines 86 to 106
/// ```javascript
/// // Basic initialization
/// const result = await DotrainOrderGui.newWithDeployment(dotrainYaml, "mainnet-order");
/// const result = await RaindexOrderBuilder.newWithDeployment(dotrainYaml, "mainnet-order");
/// if (result.error) {
/// console.error("Init failed:", result.error.readableMsg);
/// return;
/// }
/// const gui = result.value;
/// const builder = result.value;
///
/// // With state persistence
/// const result = await DotrainOrderGui.newWithDeployment(
/// const result = await RaindexOrderBuilder.newWithDeployment(
/// dotrainYaml,
/// "mainnet-order",
/// (serializedState) => {
/// localStorage.setItem('orderState', serializedState);
/// }
/// );
/// if (!result.error) {
/// const gui = result.value;
/// // Use gui instance...
/// const builder = result.value;
/// // Use builder instance...
/// }
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.

⚠️ Potential issue | 🟡 Minor

Fix the newWithDeployment examples to match the real signature.

The exported method takes (dotrain, settings, selectedDeployment, stateUpdateCallback), but both examples pass the deployment key as the second argument. Copy/pasting this will send "mainnet-order" into settings and leave selected_deployment unset.

✍️ Suggested doc fix
-/// const result = await RaindexOrderBuilder.newWithDeployment(dotrainYaml, "mainnet-order");
+/// const result = await RaindexOrderBuilder.newWithDeployment(
+///   dotrainYaml,
+///   undefined,
+///   "mainnet-order"
+/// );
@@
-/// const result = await RaindexOrderBuilder.newWithDeployment(
-///   dotrainYaml,
-///   "mainnet-order",
-///   (serializedState) => {
+/// const result = await RaindexOrderBuilder.newWithDeployment(
+///   dotrainYaml,
+///   undefined,
+///   "mainnet-order",
+///   (serializedState) => {
 ///     localStorage.setItem('orderState', serializedState);
 ///   }
 /// );
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
/// ```javascript
/// // Basic initialization
/// const result = await DotrainOrderGui.newWithDeployment(dotrainYaml, "mainnet-order");
/// const result = await RaindexOrderBuilder.newWithDeployment(dotrainYaml, "mainnet-order");
/// if (result.error) {
/// console.error("Init failed:", result.error.readableMsg);
/// return;
/// }
/// const gui = result.value;
/// const builder = result.value;
///
/// // With state persistence
/// const result = await DotrainOrderGui.newWithDeployment(
/// const result = await RaindexOrderBuilder.newWithDeployment(
/// dotrainYaml,
/// "mainnet-order",
/// (serializedState) => {
/// localStorage.setItem('orderState', serializedState);
/// }
/// );
/// if (!result.error) {
/// const gui = result.value;
/// // Use gui instance...
/// const builder = result.value;
/// // Use builder instance...
/// }
///
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/js_api/src/raindex_order_builder/mod.rs` around lines 86 - 106, The
examples for RaindexOrderBuilder.newWithDeployment are passing the deployment
key as the second argument which is actually the settings parameter; update both
examples to call newWithDeployment(dotrainYaml, settings, "mainnet-order",
stateUpdateCallback) (i.e., provide a settings object or null/{} as the second
argument and pass the deployment key as the third argument), and ensure the
optional stateUpdateCallback is the fourth parameter so selectedDeployment is
set correctly.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
.github/copilot-instructions.md (1)

66-78: ⚠️ Potential issue | 🔴 Critical

The fallback command sequence is broken—referenced directories do not exist.

Lines 70–72 reference directories that don't exist in this repository:

  • lib/rain.interpreter/lib/rain.interpreter.interface/lib/rain.math.float (missing)
  • lib/rain.interpreter/lib/rain.metadata (missing)

lib/rain.interpreter exists but is empty. The cd commands in the fallback will fail immediately, defeating the purpose of the fallback. Either update the paths to match the actual repository structure or remove these commands if they are no longer needed.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/copilot-instructions.md around lines 66 - 78, The fallback steps in
.github/copilot-instructions.md reference non-existent directories (the cd
targets in the bash commands:
lib/rain.interpreter/lib/rain.interpreter.interface/lib/rain.math.float and
lib/rain.interpreter/lib/rain.metadata) so the fallback will fail; update the
sequence by correcting or removing those cd commands: either replace those paths
with the actual repository paths under lib/rain.interpreter (or other current
package locations) or remove the three failing lines entirely, and ensure the
remaining commands (including ./prep-all.sh, nix develop -c forge install, the
rainix-* prelude invocations, and the npm build commands) reflect the repo’s
real structure.
🧹 Nitpick comments (1)
.github/copilot-instructions.md (1)

80-83: Remove trailing whitespace on the EOF blank line (if any).

Line 82 indicates an end-of-file whitespace/formatting adjustment where a trailing-whitespace blank line was “preserved” while adding a trailing newline. If CI includes trailing-whitespace enforcement, that preserved whitespace can still fail formatting checks.

Consider removing any spaces/tabs on the final blank line so the file ends with a clean empty line.

Proposed whitespace-only cleanup
- 
+
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/copilot-instructions.md around lines 80 - 83, Remove any trailing
spaces or tabs on the final blank line after the line that starts with "Goal:
all CI checks in `.github/workflows` pass." so the file ends with a single clean
newline (no trailing whitespace); open the file, trim whitespace from the EOF
blank line and save so formatting/lint CI stops flagging preserved trailing
whitespace.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In @.github/copilot-instructions.md:
- Around line 66-78: The fallback steps in .github/copilot-instructions.md
reference non-existent directories (the cd targets in the bash commands:
lib/rain.interpreter/lib/rain.interpreter.interface/lib/rain.math.float and
lib/rain.interpreter/lib/rain.metadata) so the fallback will fail; update the
sequence by correcting or removing those cd commands: either replace those paths
with the actual repository paths under lib/rain.interpreter (or other current
package locations) or remove the three failing lines entirely, and ensure the
remaining commands (including ./prep-all.sh, nix develop -c forge install, the
rainix-* prelude invocations, and the npm build commands) reflect the repo’s
real structure.

---

Nitpick comments:
In @.github/copilot-instructions.md:
- Around line 80-83: Remove any trailing spaces or tabs on the final blank line
after the line that starts with "Goal: all CI checks in `.github/workflows`
pass." so the file ends with a single clean newline (no trailing whitespace);
open the file, trim whitespace from the EOF blank line and save so
formatting/lint CI stops flagging preserved trailing whitespace.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: a8201279-76b9-476b-bba5-8ce11707682b

📥 Commits

Reviewing files that changed from the base of the PR and between c804ebb and e7b44db.

📒 Files selected for processing (3)
  • .github/copilot-instructions.md
  • pointers.sh
  • prep-base.sh

@findolor findolor requested review from JuaniRios and hardyjosh April 30, 2026 06:19
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.

2 participants