Skip to content

Add gui state and dotrain for deployment to order meta#2163

Closed
findolor wants to merge 53 commits intomainfrom
dotrain-meta
Closed

Add gui state and dotrain for deployment to order meta#2163
findolor wants to merge 53 commits intomainfrom
dotrain-meta

Conversation

@findolor
Copy link
Copy Markdown
Collaborator

@findolor findolor commented Sep 24, 2025

Caution

rainlanguage/rain.metadata#84 needs to be merged before this PR
rainlanguage/rainlang#409 needs to be merged before this PR

Motivation

See issue: #888

Solution

Screenshot 2025-09-24 at 13 37 32 Screenshot 2025-09-24 at 13 37 44 Screenshot 2025-09-24 at 13 37 47

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

    • Publish order metadata during deployment when available; adds a “Publishing metadata” step and a dedicated metadata transaction.
    • Orders now surface Dotrain source and GUI State; Order Detail shows new conditional “Dotrain” and “Gui State” tabs.
    • Generate Dotrain documents scoped to a specific deployment.
  • Enhancements

    • Concurrent loading of orders and metadata for faster results.
    • Improved GUI hashing and state generation for Dotrain instances.
    • Dropdown networks auto-filter invalid chain IDs.
    • SelectToken dropdown now reflects the fetched selected token.
  • Documentation

    • Updated README and examples to include optional metadata publishing and new deployment args.

@findolor findolor self-assigned this Sep 24, 2025
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Sep 24, 2025

Walkthrough

Adds optional metadata support across CLI, common, JS API, UI, and webapp: AddOrderArgs now accepts optional meta and can produce an optional emitMeta call. Introduces parsing/handling of meta in Raindex client and orders, GUI state hashing with DotrainSourceV1, deployment-specific dotrain generation, YAML helpers, and UI flows to publish metadata before deployment.

Changes

Cohort / File(s) Summary
AddOrderArgs meta support
crates/common/src/add_order.rs, crates/cli/src/commands/order/add.rs, crates/cli/src/commands/order/calldata.rs, crates/common/src/replays.rs, crates/integration_tests/src/lib.rs, crates/quote/src/order_quotes.rs, crates/quote/src/quote_debug.rs, tauri-app/src-tauri/src/commands/order.rs, tauri-app/src-tauri/src/commands/order_quote.rs, tauri-app/src-tauri/src/commands/trade_debug.rs
AddOrderArgs gains new public field meta: Option<Vec<RainMetaDocumentV1Item>> and constructor signature new_from_deployment(..., meta). Call sites updated to pass None. Added meta generation/encoding and try_into_emit_meta_call for optional emitMeta external call.
Raindex client/order meta parsing & async flow
crates/common/src/raindex_client/mod.rs, crates/common/src/raindex_client/orders.rs, crates/common/src/raindex_client/add_orders.rs, crates/common/src/raindex_client/remove_orders.rs
Introduces resolve_networks, expands RaindexError variants, makes RaindexOrder::try_from_sg_order async, adds parsed_meta with helpers, and fetch_dotrain_source. Order construction/removal now concurrently fetches and augments meta.
Parsed meta module
crates/common/src/lib.rs, crates/common/src/parsed_meta.rs
Adds public parsed_meta module with ParsedMeta enum and parsers from meta items/bytes. Exposed via pub mod parsed_meta.
Dotrain generation per deployment
crates/common/src/dotrain_order.rs
Adds generate_dotrain_for_deployment(&self, deployment_key) with helpers to prune/assemble frontmatter and optional GUI subtree for specific deployment.
Settings YAML helpers
crates/settings/src/yaml/mod.rs, crates/settings/src/yaml/dotrain.rs
Adds clone_section_entry and clone_section_entries to fetch nested map entries across documents. Updates DotrainYaml::get_deployment to include GUI select-tokens in evaluation context.
JS API GUI and operations (meta emission)
crates/js_api/src/gui/mod.rs, crates/js_api/src/gui/order_operations.rs, crates/js_api/src/gui/state_management.rs, crates/js_api/Cargo.toml
Extends GUI error variants for metadata/subgraph. Adds ExternalCall and emit_meta_call plumbing in DeploymentTransactionArgs. Centralizes add-order arg preparation including meta. Adds metaboard client helpers and meta emission decision. Replaces GUI hashing with DotrainSourceV1. Updates deps.
UI components: order detail and dropdowns
packages/ui-components/src/lib/components/detail/OrderDetail.svelte, packages/ui-components/src/lib/components/dropdown/DropdownActiveNetworks.svelte, packages/ui-components/src/lib/components/deployment/SelectToken.svelte
OrderDetail adds conditional Dotrain and GUI State tabs and adjusts query key. DropdownActiveNetworks validates/syncs selected chain IDs to valid list. SelectToken syncs selectedToken with fetched info in dropdown mode.
Webapp add-order flow (metadata step)
packages/webapp/src/lib/services/handleAddOrder.ts, packages/webapp/src/__tests__/handleAddOrder.test.ts, packages/webapp/src/routes/deploy/[orderName]/[deploymentKey]/fullDeployment.test.ts, packages/webapp/src/routes/+layout.svelte
Inserts optional “Publishing metadata” modal/transaction before deployment based on emitMetaCall. Updates tests for metadata step and deployment args. Disables local DB sync in layout.
Tests for UI components
packages/ui-components/src/__tests__/OrderDetail.test.ts, packages/ui-components/src/__tests__/DropdownActiveNetworks.test.ts, packages/ui-components/src/__tests__/SelectToken.test.ts
Adds tests for Dotrain/GUI tabs, filtering invalid chain IDs, and prepopulated token selection display. Updates mock order fields.
Orderbook package tests and README
packages/orderbook/test/js_api/gui.test.ts, packages/orderbook/README.md
Tests decode/verify new emitMeta call and adjust calldata expectations. README examples updated to include emitMetaCall, orderbookAddress, chainId.
Build scripts
packages/orderbook/scripts/build.js, packages/orderbook/scripts/buildPackage.js
Introduces local run helper replacing direct execSync calls. No functional behavior changes.
Dependencies
crates/bindings/Cargo.toml, crates/common/Cargo.toml, crates/js_api/Cargo.toml
Adds getrandom and metadata-related workspace deps where needed.
Remote settings URL
tauri-app/src/lib/services/loadRemoteSettings.ts
Points to a different commit for remote settings URL.
Submodule update
lib/rain.interpreter
Updates submodule commit pointer.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User
  participant UI as Webapp/UI
  participant JS as JS API (order_operations)
  participant Common as AddOrderArgs (common)
  participant MB as Metaboard Subgraph
  participant OB as Orderbook

  User->>UI: Initiate Deploy
  UI->>JS: get_deployment_transaction_args()
  JS->>Common: AddOrderArgs::new_from_deployment(dotrain, deployment, meta)
  Common-->>JS: AddOrderArgs (maybe emitMetaCall)
  alt emitMetaCall present
    JS->>MB: Resolve metaboard address/check existing meta
    MB-->>JS: Address/exists?
    JS-->>UI: emitMetaCall + deploy multicall
    UI->>User: Modal: Publishing metadata
    User-->>UI: Confirm
    UI->>OB: send emitMeta tx
    OB-->>UI: tx hash/result
  end
  UI->>User: Modal: Deploying your order
  User-->>UI: Confirm
  UI->>OB: send deploy multicall
  OB-->>UI: tx hash/result
Loading
sequenceDiagram
  autonumber
  participant Client as RaindexClient
  participant SG as Subgraph
  participant RO as RaindexOrder
  participant MB as Metaboard Subgraph

  Client->>SG: get orders
  SG-->>Client: orders (with meta bytes?)
  loop each order (concurrent)
    Client->>RO: try_from_sg_order(... ) [async]
    RO->>RO: parse meta bytes -> ParsedMeta[]
    RO->>MB: fetch DotrainSource if missing
    MB-->>RO: DotrainSourceV1 (optional)
    RO-->>Client: RaindexOrder with parsed_meta
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60–90 minutes

Possibly related PRs

Suggested labels

rust, webapp, test, Tauri

Suggested reviewers

  • hardyjosh
  • 0xgleb

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 45.83% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title concisely and accurately captures the main change of the pull request by stating the addition of GUI state support and dotrain deployment metadata to order meta, directly reflecting the core objective and scope of the changeset.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch dotrain-meta

Comment @coderabbitai help to get the list of available commands and usage tips.

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: 25

Caution

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

⚠️ Outside diff range comments (4)
packages/orderbook/test/js_api/gui.test.ts (1)

1576-1576: Deployment calldata length increased — add hex-shape assertion

This makes the test slightly more resilient while keeping the strict length check.

-			assert.equal(result.deploymentCalldata.length, 6218);
+			assert.equal(result.deploymentCalldata.length, 6218);
+			expect(result.deploymentCalldata).toMatch(/^0x[0-9a-f]+$/i);
packages/orderbook/scripts/buildPackage.js (1)

6-19: Fix reserved identifier package in orderbook scripts

Rename the reserved identifier package to pkg everywhere. buildPackage.js fix is correct but build.js still uses package.

  • packages/orderbook/scripts/buildPackage.js — apply the provided diff: const [package]const [pkg] and update both run(...) template strings to use pkg.
  • packages/orderbook/scripts/build.js:25-27 — change for (const package of packages) {for (const pkg of packages) { and update run(\node ./scripts/buildPackage ${package}`)run(`node ./scripts/buildPackage ${pkg}`)`.
packages/webapp/src/routes/+layout.ts (1)

20-33: Add a fetch timeout to avoid a hanging UI on network stalls

A small AbortController keeps the layout load from waiting indefinitely.

-	try {
-		const response = await fetch(REMOTE_SETTINGS_URL);
+	try {
+		const controller = new AbortController();
+		const timeout = setTimeout(() => controller.abort(), 15000);
+		let response: Response;
+		try {
+			response = await fetch(REMOTE_SETTINGS_URL, { signal: controller.signal });
+		} finally {
+			clearTimeout(timeout);
+		}
 		if (!response.ok) {
 			throw new Error('Error status: ' + response.status.toString());
 		}
 		settingsYamlText = await response.text();
 	} catch (error: unknown) {
packages/ui-components/src/__tests__/OrderDetail.test.ts (1)

29-33: Prefer pass-through mock for @rainlanguage/orderbook (future-proofing)

Directly replacing the module can break when additional exports are used. Consider the pass-through pattern to preserve other exports.

-vi.mock('@rainlanguage/orderbook', () => ({
-  RaindexClient: vi.fn()
-}));
+vi.mock('@rainlanguage/orderbook', async (importOriginal) => {
+  const mod = await importOriginal<typeof import('@rainlanguage/orderbook')>();
+  return {
+    ...mod,
+    RaindexClient: vi.fn()
+  };
+});
📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b17a956 and b2796dc.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (29)
  • crates/cli/src/commands/order/add.rs (2 hunks)
  • crates/cli/src/commands/order/calldata.rs (1 hunks)
  • crates/common/src/add_order.rs (30 hunks)
  • crates/common/src/dotrain_order.rs (4 hunks)
  • crates/common/src/lib.rs (1 hunks)
  • crates/common/src/parsed_meta.rs (1 hunks)
  • crates/common/src/raindex_client/mod.rs (4 hunks)
  • crates/common/src/raindex_client/orders.rs (7 hunks)
  • crates/common/src/replays.rs (1 hunks)
  • crates/integration_tests/src/lib.rs (2 hunks)
  • crates/js_api/Cargo.toml (1 hunks)
  • crates/js_api/src/gui/mod.rs (11 hunks)
  • crates/js_api/src/gui/order_operations.rs (2 hunks)
  • crates/js_api/src/gui/state_management.rs (4 hunks)
  • crates/quote/src/order_quotes.rs (1 hunks)
  • crates/quote/src/quote_debug.rs (3 hunks)
  • crates/settings/src/yaml/mod.rs (2 hunks)
  • packages/orderbook/scripts/build.js (2 hunks)
  • packages/orderbook/scripts/buildPackage.js (1 hunks)
  • packages/orderbook/test/js_api/gui.test.ts (10 hunks)
  • packages/ui-components/src/__tests__/OrderDetail.test.ts (2 hunks)
  • packages/ui-components/src/lib/components/detail/OrderDetail.svelte (3 hunks)
  • packages/webapp/src/lib/constants.ts (1 hunks)
  • packages/webapp/src/routes/+layout.ts (1 hunks)
  • packages/webapp/src/routes/deploy/[orderName]/[deploymentKey]/fullDeployment.test.ts (2 hunks)
  • tauri-app/src-tauri/src/commands/order.rs (2 hunks)
  • tauri-app/src-tauri/src/commands/order_quote.rs (1 hunks)
  • tauri-app/src-tauri/src/commands/trade_debug.rs (1 hunks)
  • tauri-app/src/lib/services/loadRemoteSettings.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (5)
crates/**/{src,tests,benches,examples}/**/*.rs

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

crates/**/{src,tests,benches,examples}/**/*.rs: Rust crates: lint with cargo clippy --workspace --all-targets --all-features -D warnings
Rust crates: ensure cargo test --workspace passes
Rust crates: build with cargo build during development/readiness checks

Files:

  • crates/common/src/lib.rs
  • crates/js_api/src/gui/order_operations.rs
  • crates/integration_tests/src/lib.rs
  • crates/cli/src/commands/order/calldata.rs
  • crates/cli/src/commands/order/add.rs
  • crates/js_api/src/gui/mod.rs
  • crates/common/src/parsed_meta.rs
  • crates/common/src/replays.rs
  • crates/settings/src/yaml/mod.rs
  • crates/common/src/raindex_client/orders.rs
  • crates/common/src/raindex_client/mod.rs
  • crates/common/src/add_order.rs
  • crates/quote/src/quote_debug.rs
  • crates/js_api/src/gui/state_management.rs
  • crates/quote/src/order_quotes.rs
  • crates/common/src/dotrain_order.rs
packages/ui-components/**/*.{svelte,ts,js}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

packages/ui-components/**/*.{svelte,ts,js}: UI components: build with npm run build -w @rainlanguage/ui-components
UI components: lint/format check with npm run svelte-lint-format-check -w @rainlanguage/ui-components
UI components: run tests with npm run test -w @rainlanguage/ui-components

Files:

  • packages/ui-components/src/lib/components/detail/OrderDetail.svelte
  • packages/ui-components/src/__tests__/OrderDetail.test.ts
packages/{webapp,ui-components}/**/*.{svelte,ts,js,css,scss}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Frontend changes must include a screenshot of the built webapp after npm run build && npm run preview

Files:

  • packages/ui-components/src/lib/components/detail/OrderDetail.svelte
  • packages/webapp/src/lib/constants.ts
  • packages/webapp/src/routes/deploy/[orderName]/[deploymentKey]/fullDeployment.test.ts
  • packages/webapp/src/routes/+layout.ts
  • packages/ui-components/src/__tests__/OrderDetail.test.ts
packages/webapp/**/*.{svelte,ts,js}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

packages/webapp/**/*.{svelte,ts,js}: Webapp: build with npm run build -w @rainlanguage/webapp
Webapp: lint/format check with npm run svelte-lint-format-check -w @rainlanguage/webapp
Webapp: run tests with npm run test -w @rainlanguage/webapp

Files:

  • packages/webapp/src/lib/constants.ts
  • packages/webapp/src/routes/deploy/[orderName]/[deploymentKey]/fullDeployment.test.ts
  • packages/webapp/src/routes/+layout.ts
packages/orderbook/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

packages/orderbook/**/*.{ts,tsx}: Orderbook package: build with npm run build:orderbook
Orderbook package: type/lint check with npm run check -w @rainlanguage/orderbook
Orderbook package: run tests with npm run test -w @rainlanguage/orderbook

Files:

  • packages/orderbook/test/js_api/gui.test.ts
🧠 Learnings (54)
📚 Learning: 2025-06-04T10:21:01.388Z
Learnt from: findolor
PR: rainlanguage/rain.orderbook#1907
File: packages/orderbook/test/common/test.test.ts:75-77
Timestamp: 2025-06-04T10:21:01.388Z
Learning: The DotrainOrder.create API in packages/orderbook/test/common/test.test.ts is internal and not used directly in consumer applications, so API changes here don't require external breaking change documentation.

Applied to files:

  • crates/js_api/src/gui/order_operations.rs
  • packages/ui-components/src/__tests__/OrderDetail.test.ts
  • packages/orderbook/test/js_api/gui.test.ts
📚 Learning: 2025-07-26T06:56:28.207Z
Learnt from: hardyjosh
PR: rainlanguage/rain.orderbook#2035
File: packages/ui-components/src/lib/components/tables/OrdersListTable.svelte:167-174
Timestamp: 2025-07-26T06:56:28.207Z
Learning: In OrdersListTable.svelte, maintainer hardyjosh considers keyed each-blocks unnecessary for item.inputs and item.outputs arrays because the entire query result updates at once during refresh, making DOM diffing optimizations negligible when the whole dataset is replaced rather than individual items being modified.

Applied to files:

  • packages/ui-components/src/lib/components/detail/OrderDetail.svelte
📚 Learning: 2025-04-09T09:28:05.097Z
Learnt from: hardingjam
PR: rainlanguage/rain.orderbook#1512
File: packages/ui-components/src/__tests__/OrderDetail.test.ts:0-0
Timestamp: 2025-04-09T09:28:05.097Z
Learning: The OrderDetail component has been refactored to use an `onRemove` callback approach instead of the previous `handleOrderRemoveModal` pattern for order removal functionality, as part of PR #1512.

Applied to files:

  • packages/ui-components/src/lib/components/detail/OrderDetail.svelte
📚 Learning: 2025-04-11T06:05:46.473Z
Learnt from: findolor
PR: rainlanguage/rain.orderbook#1599
File: tauri-app/src/routes/orders/add/+page.svelte:287-287
Timestamp: 2025-04-11T06:05:46.473Z
Learning: The ScenarioDebugTable component in tauri-app/src/routes/orders/add/+page.svelte has been designed to manage its own data fetching internally without requiring a chartData prop.

Applied to files:

  • packages/ui-components/src/lib/components/detail/OrderDetail.svelte
📚 Learning: 2025-06-07T05:19:04.767Z
Learnt from: findolor
PR: rainlanguage/rain.orderbook#1872
File: packages/webapp/src/lib/services/handleVaultWithdraw.ts:50-54
Timestamp: 2025-06-07T05:19:04.767Z
Learning: In the rainlanguage/rain.orderbook codebase, the team prefers pragmatic code approaches over strict TypeScript patterns when the current implementation is sufficient for their use case, such as using `if (result.error)` instead of `if ('error' in result)` for discriminated union type checking.

Applied to files:

  • packages/ui-components/src/lib/components/detail/OrderDetail.svelte
📚 Learning: 2025-05-19T10:39:19.157Z
Learnt from: hardingjam
PR: rainlanguage/rain.orderbook#1831
File: packages/ui-components/src/lib/types/transaction.ts:71-77
Timestamp: 2025-05-19T10:39:19.157Z
Learning: In the Rain Orderbook project, `orderHash` is intentionally typed as `string` (not `Hex`) in the `InternalTransactionArgs` interface because it matches the return type of the `getRemoveOrderCalldata` WASM function which returns `Promise<string>`. String operations like `.slice()` are performed on `orderHash` in the code. Meanwhile, `txHash` is typed as `Hex` for blockchain transaction hashes.

Applied to files:

  • packages/ui-components/src/lib/components/detail/OrderDetail.svelte
📚 Learning: 2025-06-11T11:39:15.239Z
Learnt from: findolor
PR: rainlanguage/rain.orderbook#1917
File: tauri-app/src/routes/orders/add/+page.svelte:45-47
Timestamp: 2025-06-11T11:39:15.239Z
Learning: In the rain.orderbook codebase, every instance of `Config` (returned by helpers such as `parseDotrainAndYaml`) is guaranteed to include the `dotrainOrder` property; it is never `undefined`.

Applied to files:

  • packages/ui-components/src/lib/components/detail/OrderDetail.svelte
📚 Learning: 2025-09-06T07:12:25.751Z
Learnt from: CR
PR: rainlanguage/rain.orderbook#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-06T07:12:25.751Z
Learning: Applies to packages/orderbook/**/*.{ts,tsx} : Orderbook package: build with `npm run build:orderbook`

Applied to files:

  • packages/orderbook/scripts/build.js
  • packages/orderbook/scripts/buildPackage.js
📚 Learning: 2025-09-06T07:12:25.751Z
Learnt from: CR
PR: rainlanguage/rain.orderbook#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-06T07:12:25.751Z
Learning: Applies to packages/webapp/**/*.{svelte,ts,js} : Webapp: build with `npm run build -w rainlanguage/webapp`

Applied to files:

  • packages/orderbook/scripts/build.js
📚 Learning: 2025-09-06T07:12:25.751Z
Learnt from: CR
PR: rainlanguage/rain.orderbook#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-06T07:12:25.751Z
Learning: Applies to packages/ui-components/**/*.{svelte,ts,js} : UI components: build with `npm run build -w rainlanguage/ui-components`

Applied to files:

  • packages/orderbook/scripts/build.js
📚 Learning: 2025-05-14T04:49:14.621Z
Learnt from: findolor
PR: rainlanguage/rain.orderbook#1710
File: crates/quote/Cargo.toml:30-30
Timestamp: 2025-05-14T04:49:14.621Z
Learning: In the rain.orderbook repository, wasm-bindgen-utils is intentionally used as an unconditional dependency because non-wasm targets (like tests) sometimes need to use it.

Applied to files:

  • packages/orderbook/scripts/buildPackage.js
  • crates/js_api/Cargo.toml
  • crates/js_api/src/gui/state_management.rs
📚 Learning: 2025-09-06T07:12:25.751Z
Learnt from: CR
PR: rainlanguage/rain.orderbook#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-06T07:12:25.751Z
Learning: Applies to packages/orderbook/**/*.{ts,tsx} : Orderbook package: run tests with `npm run test -w rainlanguage/orderbook`

Applied to files:

  • packages/orderbook/scripts/buildPackage.js
  • packages/ui-components/src/__tests__/OrderDetail.test.ts
📚 Learning: 2025-04-30T09:28:36.960Z
Learnt from: findolor
PR: rainlanguage/rain.orderbook#1715
File: crates/js_api/src/common/mod.rs:111-118
Timestamp: 2025-04-30T09:28:36.960Z
Learning: In the rain.orderbook repository, the WASM tests are already properly configured with conditional compilation using `#[cfg(target_family = "wasm")]` and `#[cfg(not(target_family = "wasm"))]`, and don't require additional `wasm_bindgen_test_configure!(run_in_browser)` directives.

Applied to files:

  • packages/orderbook/scripts/buildPackage.js
📚 Learning: 2025-06-17T16:46:19.035Z
Learnt from: findolor
PR: rainlanguage/rain.orderbook#1903
File: crates/cli/src/commands/order/calldata.rs:47-57
Timestamp: 2025-06-17T16:46:19.035Z
Learning: In the CLI command `crates/cli/src/commands/order/calldata.rs`, the user prefers to let lower-level errors from `try_into_call()` bubble up when the RPCs list is empty, rather than adding early validation checks with custom error messages.

Applied to files:

  • crates/cli/src/commands/order/calldata.rs
📚 Learning: 2025-08-01T07:35:13.418Z
Learnt from: brusherru
PR: rainlanguage/rain.orderbook#2036
File: crates/js_api/src/filters/errors.rs:39-46
Timestamp: 2025-08-01T07:35:13.418Z
Learning: In the Rain Orderbook project's PersistentFilterStoreError (crates/js_api/src/filters/errors.rs), the Display implementation already provides user-friendly error messages, so using err.to_string() for both msg and readable_msg in the WasmEncodedError conversion is appropriate and doesn't require separate readable message handling.

Applied to files:

  • crates/js_api/src/gui/mod.rs
📚 Learning: 2025-05-15T22:27:49.771Z
Learnt from: 0xgleb
PR: rainlanguage/rain.orderbook#1777
File: tauri-app/src-tauri/Cargo.toml:64-64
Timestamp: 2025-05-15T22:27:49.771Z
Learning: User 0xgleb prefers to maintain the dot notation format for some Cargo.toml dependencies (e.g., `rain-interpreter-eval.path = "path"`) rather than converting all to inline table format, as both formats are valid in Rust.

Applied to files:

  • crates/js_api/Cargo.toml
📚 Learning: 2025-05-14T05:13:59.713Z
Learnt from: findolor
PR: rainlanguage/rain.orderbook#1744
File: crates/subgraph/src/orderbook_client.rs:44-46
Timestamp: 2025-05-14T05:13:59.713Z
Learning: In the rain.orderbook project, WASM dependencies are intentionally made available in non-WASM targets to facilitate testing of WASM-related functionality, so conditional compilation guards like `#[cfg(target_family = "wasm")]` should not be added to imports or implementations that may be needed for tests.

Applied to files:

  • crates/js_api/Cargo.toml
  • crates/js_api/src/gui/state_management.rs
📚 Learning: 2025-04-09T12:58:03.399Z
Learnt from: hardingjam
PR: rainlanguage/rain.orderbook#1565
File: packages/webapp/src/lib/services/loadRegistryUrl.ts:5-19
Timestamp: 2025-04-09T12:58:03.399Z
Learning: In the rain.orderbook application, URL validation for registry URLs is handled at the frontend/component level before the `loadRegistryUrl` function is called, so additional validation within this function is not necessary.

Applied to files:

  • packages/webapp/src/lib/constants.ts
📚 Learning: 2025-08-15T20:56:15.592Z
Learnt from: brusherru
PR: rainlanguage/rain.orderbook#1978
File: packages/webapp/src/routes/deploy/[orderName]/[deploymentKey]/fullDeployment.test.ts:22-29
Timestamp: 2025-08-15T20:56:15.592Z
Learning: In packages/webapp/src/routes/deploy/[orderName]/[deploymentKey]/fullDeployment.test.ts, brusherru prefers fail-fast testing approaches where type mismatches cause immediate test failures to alert developers about interface changes, rather than using defensive programming with type guards that might mask API evolution.

Applied to files:

  • packages/webapp/src/routes/deploy/[orderName]/[deploymentKey]/fullDeployment.test.ts
  • packages/orderbook/test/js_api/gui.test.ts
📚 Learning: 2025-07-17T10:35:53.182Z
Learnt from: findolor
PR: rainlanguage/rain.orderbook#1996
File: packages/webapp/src/routes/deploy/[strategyName]/[deploymentKey]/fullDeployment.test.ts:172-172
Timestamp: 2025-07-17T10:35:53.182Z
Learning: In packages/webapp/src/routes/deploy/[strategyName]/[deploymentKey]/fullDeployment.test.ts, findolor is comfortable with hardcoded 2-second delays using setTimeout after token selection elements appear, preferring this approach over deterministic waiting patterns with waitFor.

Applied to files:

  • packages/webapp/src/routes/deploy/[orderName]/[deploymentKey]/fullDeployment.test.ts
📚 Learning: 2025-07-17T10:35:09.329Z
Learnt from: findolor
PR: rainlanguage/rain.orderbook#1996
File: packages/webapp/src/routes/deploy/[strategyName]/[deploymentKey]/fullDeployment.test.ts:303-303
Timestamp: 2025-07-17T10:35:09.329Z
Learning: In packages/webapp/src/routes/deploy/[strategyName]/[deploymentKey]/fullDeployment.test.ts, findolor is fine with hardcoded 2-second delays using setTimeout in test cases for waiting after token selection, preferring this approach over deterministic waiting patterns.

Applied to files:

  • packages/webapp/src/routes/deploy/[orderName]/[deploymentKey]/fullDeployment.test.ts
📚 Learning: 2025-07-09T12:35:45.699Z
Learnt from: findolor
PR: rainlanguage/rain.orderbook#1974
File: packages/ui-components/src/__tests__/DeploymentSteps.test.ts:123-126
Timestamp: 2025-07-09T12:35:45.699Z
Learning: In packages/ui-components/src/__tests__/DeploymentSteps.test.ts, findolor prefers to keep mock initializations (like setSelectToken) in individual test cases rather than consolidating them into shared beforeEach blocks, even when it results in duplication.

Applied to files:

  • packages/webapp/src/routes/deploy/[orderName]/[deploymentKey]/fullDeployment.test.ts
  • packages/ui-components/src/__tests__/OrderDetail.test.ts
  • packages/orderbook/test/js_api/gui.test.ts
📚 Learning: 2025-07-10T12:52:47.468Z
Learnt from: findolor
PR: rainlanguage/rain.orderbook#1925
File: packages/ui-components/src/lib/errors/DeploymentStepsError.ts:16-16
Timestamp: 2025-07-10T12:52:47.468Z
Learning: In packages/ui-components/src/lib/errors/DeploymentStepsError.ts, the error codes NO_SELECT_TOKENS ('Error loading tokens') and NO_AVAILABLE_TOKENS ('Error loading available tokens') represent different failure scenarios in the token loading workflow and should remain as separate error codes.

Applied to files:

  • packages/webapp/src/routes/deploy/[orderName]/[deploymentKey]/fullDeployment.test.ts
📚 Learning: 2025-04-29T11:17:46.178Z
Learnt from: findolor
PR: rainlanguage/rain.orderbook#1687
File: crates/js_api/src/gui/order_operations.rs:470-489
Timestamp: 2025-04-29T11:17:46.178Z
Learning: In the `get_deployment_transaction_args` method of `DotrainOrderGui`, approvals are intentionally only checked against output tokens as per the design requirements.

Applied to files:

  • packages/webapp/src/routes/deploy/[orderName]/[deploymentKey]/fullDeployment.test.ts
📚 Learning: 2025-07-16T10:40:05.717Z
Learnt from: findolor
PR: rainlanguage/rain.orderbook#2000
File: crates/common/src/raindex_client/vaults.rs:183-183
Timestamp: 2025-07-16T10:40:05.717Z
Learning: In the rainlanguage/rain.orderbook codebase, user findolor considers breaking changes from Option<U256> to U256 for required fields like decimals in RaindexVaultToken to be acceptable and safe, even when they affect multiple usage sites across the codebase.

Applied to files:

  • crates/common/src/raindex_client/orders.rs
  • crates/js_api/src/gui/state_management.rs
📚 Learning: 2025-06-20T07:51:08.790Z
Learnt from: findolor
PR: rainlanguage/rain.orderbook#1941
File: crates/js_api/src/raindex/vaults.rs:175-181
Timestamp: 2025-06-20T07:51:08.790Z
Learning: In the RaindexClient vault methods, `&self` parameters are intentionally kept for API consistency to make all vault operations instance methods, even when the methods don't use client state. This is a design preference for maintaining a uniform interface.

Applied to files:

  • crates/common/src/raindex_client/orders.rs
📚 Learning: 2025-05-09T05:21:40.234Z
Learnt from: findolor
PR: rainlanguage/rain.orderbook#1744
File: crates/js_api/src/subgraph/vault.rs:19-37
Timestamp: 2025-05-09T05:21:40.234Z
Learning: In the rain.orderbook project, the developer prefers to use tuple structs for WASM wrappers (like VaultCalldataResult, GetVaultsResult) rather than structs with named fields.

Applied to files:

  • crates/common/src/raindex_client/orders.rs
  • crates/js_api/src/gui/state_management.rs
📚 Learning: 2025-06-24T08:46:03.368Z
Learnt from: findolor
PR: rainlanguage/rain.orderbook#1947
File: crates/common/src/raindex_client/orders.rs:98-125
Timestamp: 2025-06-24T08:46:03.368Z
Learning: In the vault merging logic in crates/common/src/raindex_client/orders.rs, optimization isn't necessary because the maximum list items are usually around 5 items. For such small datasets, the simple three-loop approach is preferred over HashMap-based optimization due to clarity and minimal performance impact.

Applied to files:

  • crates/common/src/raindex_client/orders.rs
📚 Learning: 2025-08-01T09:07:20.383Z
Learnt from: brusherru
PR: rainlanguage/rain.orderbook#2044
File: packages/orderbook/README.md:186-189
Timestamp: 2025-08-01T09:07:20.383Z
Learning: In the rainlanguage/rain.orderbook project, Rust methods on structs like RaindexVaultsList are exported as JavaScript getters in WASM bindings using #[wasm_bindgen(getter)]. This means while the Rust code uses method calls like items(), the JavaScript/WASM API exposes them as property access like .items. The README.md correctly documents the JavaScript API surface, not the Rust implementation details.

Applied to files:

  • crates/common/src/raindex_client/orders.rs
  • crates/js_api/src/gui/state_management.rs
📚 Learning: 2025-07-31T19:34:11.716Z
Learnt from: brusherru
PR: rainlanguage/rain.orderbook#2044
File: crates/common/src/raindex_client/vaults_list.rs:363-423
Timestamp: 2025-07-31T19:34:11.716Z
Learning: In the rainlanguage/rain.orderbook project, for WASM-exposed functionality like VaultsList, the team prefers to keep comprehensive tests in the non-WASM environment due to the complexity of recreating objects like RaindexVaults in WASM. WASM tests focus on basic functionality and error cases since the WASM code reuses the already-tested non-WASM implementation.

Applied to files:

  • crates/common/src/raindex_client/orders.rs
  • crates/js_api/src/gui/state_management.rs
📚 Learning: 2025-08-01T07:44:53.910Z
Learnt from: brusherru
PR: rainlanguage/rain.orderbook#2036
File: crates/js_api/src/filters/raindex_filter_store.rs:319-336
Timestamp: 2025-08-01T07:44:53.910Z
Learning: In the rainlanguage/rain.orderbook project's RaindexFilterStore (crates/js_api/src/filters/raindex_filter_store.rs), the team chose a simplified monolithic approach with hard-coded keys and default auto-save behavior over configurable stores. The update_vaults method intentionally auto-saves to both localStorage and URL after each update as the default behavior, following a design evolution from a previous configurable approach.

Applied to files:

  • crates/common/src/raindex_client/orders.rs
📚 Learning: 2025-06-24T13:36:28.797Z
Learnt from: findolor
PR: rainlanguage/rain.orderbook#1950
File: crates/common/src/raindex_client/orders.rs:301-301
Timestamp: 2025-06-24T13:36:28.797Z
Learning: In the RaindexClient codebase, when Arc::new(RwLock::new(self.clone())) is used (e.g., in get_orders and get_order_by_hash methods), this creates new Arc/RwLock wrappers around a cloned RaindexClient, but the underlying client data is functionally the same. This pattern is used to provide the correct Arc<RwLock<RaindexClient>> type expected by RaindexOrder::try_from_sg_order() method.

Applied to files:

  • crates/common/src/raindex_client/orders.rs
📚 Learning: 2025-07-04T10:26:24.289Z
Learnt from: findolor
PR: rainlanguage/rain.orderbook#1956
File: crates/common/src/raindex_client/mod.rs:116-135
Timestamp: 2025-07-04T10:26:24.289Z
Learning: In crates/common/src/raindex_client/mod.rs, the get_multi_subgraph_args method intentionally treats Some(empty vector) the same as None for chain_ids parameter. Both cases should return all networks to support UI behavior where no selection or empty selection means "show all networks". Only when specific chain IDs are provided should the results be filtered.

Applied to files:

  • crates/common/src/raindex_client/mod.rs
📚 Learning: 2025-05-09T05:28:22.089Z
Learnt from: findolor
PR: rainlanguage/rain.orderbook#1744
File: crates/js_api/src/subgraph/order.rs:109-114
Timestamp: 2025-05-09T05:28:22.089Z
Learning: In the rain.orderbook project, SubgraphError contains or converts from OrderbookSubgraphClientError, so using OrderbookSubgraphClientError in error creation followed by a conversion to SubgraphError (via ? operator) is acceptable.

Applied to files:

  • crates/common/src/raindex_client/mod.rs
📚 Learning: 2025-06-18T19:24:40.518Z
Learnt from: findolor
PR: rainlanguage/rain.orderbook#1938
File: crates/settings/src/yaml/orderbook.rs:185-199
Timestamp: 2025-06-18T19:24:40.518Z
Learning: In crates/settings/src/yaml/orderbook.rs, the user prefers not to refactor get_orderbook_by_network_key to handle multiple orderbooks per network key since their current architecture maintains a one-to-one mapping between orderbooks and networks. They would consider the refactoring if the system evolves to support multiple orderbooks per network in the future.

Applied to files:

  • crates/common/src/raindex_client/mod.rs
📚 Learning: 2025-06-18T18:24:32.049Z
Learnt from: findolor
PR: rainlanguage/rain.orderbook#1938
File: crates/settings/src/yaml/orderbook.rs:180-199
Timestamp: 2025-06-18T18:24:32.049Z
Learning: In crates/settings/src/yaml/orderbook.rs, the user prefers to avoid refactoring duplicate search logic between get_orderbook_by_address and get_orderbook_by_network_key when there are only 2 functions, indicating they would consider it if more similar functions are added in the future.

Applied to files:

  • crates/common/src/raindex_client/mod.rs
📚 Learning: 2025-06-18T18:18:44.330Z
Learnt from: findolor
PR: rainlanguage/rain.orderbook#1938
File: crates/js_api/src/raindex/mod.rs:92-99
Timestamp: 2025-06-18T18:18:44.330Z
Learning: In crates/js_api/src/raindex/mod.rs, the get_subgraph_url_for_chain method and get_multi_subgraph_args method intentionally duplicate lookup logic because they serve different purposes: get_subgraph_url_for_chain returns only the URL string, while get_multi_subgraph_args returns MultiSubgraphArgs structures containing both URL and network information (name/label). This duplication is acceptable and by design.

Applied to files:

  • crates/common/src/raindex_client/mod.rs
📚 Learning: 2025-05-20T10:20:08.206Z
Learnt from: 0xgleb
PR: rainlanguage/rain.orderbook#1859
File: crates/quote/src/quote_debug.rs:472-492
Timestamp: 2025-05-20T10:20:08.206Z
Learning: In the Rain Orderbook codebase, the `#[tokio::test(flavor = "multi_thread")]` annotation is specifically needed for tests that use `LocalEvm`, not just for consistency across all async tests.

Applied to files:

  • crates/common/src/add_order.rs
📚 Learning: 2025-06-17T16:32:04.554Z
Learnt from: findolor
PR: rainlanguage/rain.orderbook#1903
File: crates/js_api/src/gui/order_operations.rs:124-134
Timestamp: 2025-06-17T16:32:04.554Z
Learning: In the rain.orderbook codebase, RPC lists are typically small (2 items maximum), so performance optimizations around cloning and converting small Vec<Url> collections are generally unnecessary.

Applied to files:

  • crates/common/src/add_order.rs
📚 Learning: 2025-08-02T02:34:32.237Z
Learnt from: brusherru
PR: rainlanguage/rain.orderbook#2036
File: crates/js_api/src/filters/raindex_filter_store.rs:446-533
Timestamp: 2025-08-02T02:34:32.237Z
Learning: In the rainlanguage/rain.orderbook project's RaindexFilterStore WASM tests (crates/js_api/src/filters/raindex_filter_store.rs), brusherru decided to focus on testing only methods without side effects (that don't use web_sys) due to difficulties with mocking localStorage and window APIs in the WASM test environment. This pragmatic approach tests pure logic separately from browser integration.

Applied to files:

  • crates/common/src/add_order.rs
📚 Learning: 2025-04-08T12:56:03.272Z
Learnt from: hardingjam
PR: rainlanguage/rain.orderbook#1512
File: packages/ui-components/src/__tests__/OrderDetail.test.ts:125-143
Timestamp: 2025-04-08T12:56:03.272Z
Learning: The OrderDetail component in the Rain orderbook UI doesn't currently have error handling tests, but issue #1605 has been created to address this in the future.

Applied to files:

  • packages/ui-components/src/__tests__/OrderDetail.test.ts
📚 Learning: 2025-09-02T08:04:44.814Z
Learnt from: findolor
PR: rainlanguage/rain.orderbook#2117
File: packages/ui-components/src/__tests__/VaultIdInformation.test.ts:9-13
Timestamp: 2025-09-02T08:04:44.814Z
Learning: In packages/ui-components/src/__tests__/VaultIdInformation.test.ts and similar test files in the rain.orderbook project, the passthrough vi.mock('rainlanguage/orderbook', async (importOriginal) => { return { ...(await importOriginal()) }; }); block is required for tests to run properly, even when not overriding any exports. This is needed due to the specific Vitest configuration or test environment setup in the project.

Applied to files:

  • packages/ui-components/src/__tests__/OrderDetail.test.ts
📚 Learning: 2025-07-04T09:14:35.748Z
Learnt from: findolor
PR: rainlanguage/rain.orderbook#1956
File: packages/ui-components/src/__tests__/VaultDetail.test.ts:177-181
Timestamp: 2025-07-04T09:14:35.748Z
Learning: In the rain.orderbook project, maintainer findolor is fine with mutating mock data directly in test files using ts-expect-error comments, preferring this pragmatic approach over immutable patterns like spread operators for test data updates.

Applied to files:

  • packages/ui-components/src/__tests__/OrderDetail.test.ts
📚 Learning: 2025-08-14T18:29:32.933Z
Learnt from: brusherru
PR: rainlanguage/rain.orderbook#2083
File: packages/ui-components/src/__tests__/VaultsListTable.test.ts:16-19
Timestamp: 2025-08-14T18:29:32.933Z
Learning: In the rain.orderbook project's UI components tests, mocking hooks like useToasts is often required as infrastructure even when not directly asserting on their calls, because components internally depend on these hooks. Removing such mocks would break component rendering in tests and require more complex test setup with providers.

Applied to files:

  • packages/ui-components/src/__tests__/OrderDetail.test.ts
📚 Learning: 2025-04-02T08:11:19.742Z
Learnt from: hardingjam
PR: rainlanguage/rain.orderbook#1566
File: packages/webapp/src/routes/deploy/[strategyName]/[deploymentKey]/+page.svelte:26-31
Timestamp: 2025-04-02T08:11:19.742Z
Learning: In the Rain Orderbook deployment page component, the conditional check `if (dotrain && deployment)` inside `onMount` is necessary to prevent GUI initialization with null values, even though there's already a redirect logic outside the function and conditional rendering for the UI message. These serve different purposes in the component's error handling strategy.

Applied to files:

  • packages/orderbook/test/js_api/gui.test.ts
📚 Learning: 2025-03-26T16:22:50.224Z
Learnt from: hardingjam
PR: rainlanguage/rain.orderbook#1515
File: packages/webapp/src/routes/deploy/[strategyName]/[deploymentKey]/layout.test.ts:0-0
Timestamp: 2025-03-26T16:22:50.224Z
Learning: In the Rain Orderbook project, the DotrainOrderGui.getDeploymentDetail method resolves promises with objects that may contain either a value property or an error property, rather than rejecting promises on errors.

Applied to files:

  • packages/orderbook/test/js_api/gui.test.ts
📚 Learning: 2025-04-08T12:53:12.526Z
Learnt from: findolor
PR: rainlanguage/rain.orderbook#1588
File: packages/orderbook/test/js_api/gui.test.ts:2037-2057
Timestamp: 2025-04-08T12:53:12.526Z
Learning: In the remote network test for gui.test.ts, asserting that getCurrentDeployment() succeeds is sufficient validation that remote networks were properly fetched, as this operation would fail if the networks weren't correctly processed.

Applied to files:

  • packages/orderbook/test/js_api/gui.test.ts
📚 Learning: 2025-04-22T12:50:39.581Z
Learnt from: findolor
PR: rainlanguage/rain.orderbook#1687
File: crates/js_api/src/gui/mod.rs:258-259
Timestamp: 2025-04-22T12:50:39.581Z
Learning: In `DotrainOrderGui::generate_dotrain_text()`, the call to `.to_string()` on `self.dotrain_order.dotrain()` is necessary because there are two different implementations of the `dotrain()` method - one for WASM targets returning a String and one for non-WASM targets returning a &str. The `.to_string()` ensures type compatibility across different compilation targets.

Applied to files:

  • crates/js_api/src/gui/state_management.rs
  • crates/common/src/dotrain_order.rs
📚 Learning: 2025-07-18T10:31:05.498Z
Learnt from: findolor
PR: rainlanguage/rain.orderbook#2008
File: crates/common/src/raindex_client/add_orders.rs:85-86
Timestamp: 2025-07-18T10:31:05.498Z
Learning: In the rainlanguage/rain.orderbook codebase, cfg-guarded imports like `#[cfg(not(target_family = "wasm"))] use super::*;` in test modules are sometimes needed to fix compiler warnings, even when similar imports exist in nested sub-modules. These should not be removed as they serve a specific purpose in the compilation process.

Applied to files:

  • crates/js_api/src/gui/state_management.rs
📚 Learning: 2025-05-19T13:40:56.080Z
Learnt from: findolor
PR: rainlanguage/rain.orderbook#1858
File: crates/subgraph/src/orderbook_client/mod.rs:54-58
Timestamp: 2025-05-19T13:40:56.080Z
Learning: The `wasm_bindgen_utils` crate in the Rain Orderbook project handles conditional compilation for `JsValue` and `JsError` internally, allowing `impl From<Error> for JsValue` to work on non-WASM targets without explicit cfg guards.

Applied to files:

  • crates/js_api/src/gui/state_management.rs
📚 Learning: 2025-08-02T03:55:25.215Z
Learnt from: brusherru
PR: rainlanguage/rain.orderbook#2036
File: packages/orderbook/test/js_api/filters.test.ts:19-36
Timestamp: 2025-08-02T03:55:25.215Z
Learning: In the rainlanguage/rain.orderbook project's WASM tests, the pattern of chaining `.value!` calls on WASM result types (like from VaultsFilterBuilder methods) is the established and preferred approach for handling WASM results, and should not be refactored into intermediate variables as it would add unnecessary verbosity without improving the code.

Applied to files:

  • crates/js_api/src/gui/state_management.rs
📚 Learning: 2025-04-29T11:19:41.267Z
Learnt from: findolor
PR: rainlanguage/rain.orderbook#1687
File: crates/js_api/src/gui/state_management.rs:32-35
Timestamp: 2025-04-29T11:19:41.267Z
Learning: The team prefers the `get_dotrain_hash` function to accept owned String parameters instead of string references, even though it may result in additional allocations during serialization/deserialization.

Applied to files:

  • crates/js_api/src/gui/state_management.rs
📚 Learning: 2025-07-09T14:00:12.206Z
Learnt from: findolor
PR: rainlanguage/rain.orderbook#1975
File: crates/js_api/src/gui/state_management.rs:412-412
Timestamp: 2025-07-09T14:00:12.206Z
Learning: In crates/js_api/src/gui/state_management.rs tests, findolor prefers to keep hard-coded serialized state constants (like SERIALIZED_STATE) rather than dynamically generating them, even when it may make tests more brittle to maintain.

Applied to files:

  • crates/js_api/src/gui/state_management.rs
📚 Learning: 2025-07-04T10:24:29.750Z
Learnt from: findolor
PR: rainlanguage/rain.orderbook#1956
File: crates/common/src/raindex_client/add_orders.rs:132-132
Timestamp: 2025-07-04T10:24:29.750Z
Learning: In the rain.orderbook codebase, findolor prefers to use `unwrap_or("")` for optional frontmatter in dotrain parsing, allowing empty strings to be handled by downstream validation in `NewConfig::try_from_yaml()` rather than adding explicit early validation checks at the extraction point.

Applied to files:

  • crates/common/src/dotrain_order.rs
🧬 Code graph analysis (18)
crates/common/src/lib.rs (1)
crates/common/src/raindex_client/orders.rs (2)
  • parsed_meta (115-117)
  • parsed_meta (180-182)
tauri-app/src-tauri/src/commands/order_quote.rs (1)
crates/common/src/add_order.rs (1)
  • new_from_deployment (99-140)
crates/js_api/src/gui/order_operations.rs (1)
crates/common/src/add_order.rs (1)
  • new_from_deployment (99-140)
packages/orderbook/scripts/build.js (1)
packages/orderbook/scripts/buildPackage.js (2)
  • run (4-4)
  • package (7-7)
packages/orderbook/scripts/buildPackage.js (1)
packages/orderbook/scripts/build.js (1)
  • run (4-4)
tauri-app/src-tauri/src/commands/trade_debug.rs (1)
crates/common/src/add_order.rs (1)
  • new_from_deployment (99-140)
crates/integration_tests/src/lib.rs (1)
crates/common/src/add_order.rs (1)
  • new_from_deployment (99-140)
crates/cli/src/commands/order/calldata.rs (1)
crates/common/src/add_order.rs (1)
  • new_from_deployment (99-140)
crates/cli/src/commands/order/add.rs (1)
crates/common/src/add_order.rs (1)
  • new_from_deployment (99-140)
crates/common/src/replays.rs (1)
crates/common/src/add_order.rs (1)
  • new_from_deployment (99-140)
crates/settings/src/yaml/mod.rs (2)
crates/settings/src/yaml/orderbook.rs (1)
  • new (94-137)
crates/settings/src/yaml/dotrain.rs (1)
  • new (79-107)
crates/common/src/raindex_client/orders.rs (1)
crates/common/src/parsed_meta.rs (1)
  • parse_from_bytes (56-59)
packages/ui-components/src/__tests__/OrderDetail.test.ts (1)
packages/ui-components/src/lib/queries/queryClient.ts (1)
  • queryClient (4-10)
crates/quote/src/quote_debug.rs (1)
crates/common/src/add_order.rs (1)
  • new_from_deployment (99-140)
tauri-app/src-tauri/src/commands/order.rs (2)
crates/common/src/add_order.rs (1)
  • new_from_deployment (99-140)
crates/common/src/dotrain_order.rs (1)
  • dotrain (368-370)
crates/js_api/src/gui/state_management.rs (3)
crates/common/src/dotrain_order.rs (1)
  • dotrain (368-370)
crates/js_api/src/gui/deposits.rs (2)
  • deposits (76-107)
  • value (81-83)
crates/settings/src/gui.rs (4)
  • select_tokens (722-725)
  • parse_select_tokens (393-443)
  • s (947-947)
  • s (958-958)
crates/quote/src/order_quotes.rs (1)
crates/common/src/add_order.rs (1)
  • new_from_deployment (99-140)
crates/common/src/dotrain_order.rs (1)
crates/settings/src/yaml/mod.rs (4)
  • clone_section_entries (507-521)
  • clone_section_entry (486-505)
  • new (41-41)
  • get_yaml_string (47-60)
🪛 Biome (2.1.2)
packages/orderbook/scripts/build.js

[error] 26-26: Illegal use of reserved keyword package as an identifier in strict mode

(parse)


[error] 27-27: Illegal use of reserved keyword package as an identifier in strict mode

(parse)

packages/orderbook/scripts/buildPackage.js

[error] 7-7: Illegal use of reserved keyword package as an identifier in strict mode

(parse)


[error] 12-12: Illegal use of reserved keyword package as an identifier in strict mode

(parse)


[error] 13-13: Illegal use of reserved keyword package as an identifier in strict mode

(parse)


[error] 13-13: Illegal use of reserved keyword package as an identifier in strict mode

(parse)

🪛 Gitleaks (8.28.0)
packages/webapp/src/routes/deploy/[orderName]/[deploymentKey]/fullDeployment.test.ts

[high] 214-214: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)


[high] 215-215: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (16)
  • GitHub Check: test
  • GitHub Check: standard-tests (ubuntu-latest, rainix-sol-artifacts)
  • GitHub Check: standard-tests (ubuntu-latest, rainix-wasm-artifacts)
  • GitHub Check: standard-tests (ubuntu-latest, rainix-rs-static)
  • GitHub Check: standard-tests (ubuntu-latest, test-js-bindings)
  • GitHub Check: standard-tests (ubuntu-latest, rainix-wasm-test)
  • GitHub Check: standard-tests (ubuntu-latest, rainix-sol-test)
  • GitHub Check: standard-tests (ubuntu-latest, ob-rs-test, true)
  • GitHub Check: standard-tests (ubuntu-latest, rainix-sol-legal)
  • GitHub Check: standard-tests (ubuntu-latest, rainix-sol-static)
  • GitHub Check: standard-tests (ubuntu-latest, rainix-rs-artifacts, true)
  • GitHub Check: build-tauri (ubuntu-22.04, true)
  • GitHub Check: test
  • GitHub Check: git-clean
  • GitHub Check: Deploy-Docs-Preview
  • GitHub Check: Deploy-Preview-Push
🔇 Additional comments (57)
packages/orderbook/test/js_api/gui.test.ts (7)

971-971: Golden serialized state updated — verify determinism

The updated fixture looks fine given the new GUI/meta serialization. Please re-run locally on a clean environment to confirm the serialized output is deterministic across platforms/tooling.

Run:

  • npm run test -w @rainlanguage/orderbook
  • npm run check -w @rainlanguage/orderbook

1150-1150: Whitespace-only change

No action needed.


1618-1618: Whitespace-only change

No action needed.


1342-1342: Duplicate: strengthen add-order calldata assertions

Same recommendation as above to also assert hex-shape for the string.

-			assert.equal(addOrderCalldata.length, 5322);
+			assert.equal(addOrderCalldata.length, 5322);
+			expect(addOrderCalldata).toMatch(/^0x[0-9a-f]+$/i);

1427-1427: Deposit+Add multicall (defaulting field) — add hex-shape assertion

Same as above.

-			assert.equal(calldata.length, 6346);
+			assert.equal(calldata.length, 6346);
+			expect(calldata).toMatch(/^0x[0-9a-f]+$/i);

1487-1487: Deposit+Add multicall (no vault ids) — add hex-shape assertion

Same as above.

-			assert.equal(calldata.length, 6730);
+			assert.equal(calldata.length, 6730);
+			expect(calldata).toMatch(/^0x[0-9a-f]+$/i);

1786-1786: Deployment calldata length (no approvals) — add hex-shape assertion

Same recommendation.

-			assert.equal(result.deploymentCalldata.length, 5642);
+			assert.equal(result.deploymentCalldata.length, 5642);
+			expect(result.deploymentCalldata).toMatch(/^0x[0-9a-f]+$/i);
packages/webapp/src/lib/constants.ts (1)

1-2: REGISTRY_URL pin OK — single definition confirmed; run build/tests & attach preview

rg shows only packages/webapp/src/lib/constants.ts defines the pinned URL.

  • Run linter/build/tests: npm run svelte-lint-format-check -w @rainlanguage/webapp && npm run build -w @rainlanguage/webapp && npm run test -w @rainlanguage/webapp
  • Verify the new registry content matches the expected schema to avoid runtime parse errors
  • Attach a screenshot of the built webapp (after npm run build && npm run preview) to the PR
packages/orderbook/scripts/buildPackage.js (1)

4-5: Good: centralized exec wrapper.

Standardizing on a small run() helper improves readability and consistent stdio handling.

packages/orderbook/scripts/build.js (4)

4-5: Good: consistent command execution via run().


20-20: LGTM: wasm build step via wrapper.


31-31: LGTM: cleanup step via wrapper.


34-34: LGTM: bindings check via wrapper.

packages/webapp/src/routes/+layout.ts (1)

13-15: Remote settings URL reachable and CORS-enabled — continue FE checklist

Verified: HTTP/2 200; content-type: text/plain; charset=utf-8; access-control-allow-origin: *.

Actions required:

  • Run lint/format, build, and run tests.
  • Attach screenshot of the built webapp preview (ssr=false).
crates/settings/src/yaml/mod.rs (2)

486-506: Define/confirm precedence across multiple documents (first-wins vs last-wins)

Currently the first document containing the key wins. If you expect “overrides later sources” semantics, iterate in reverse:

  • for document in documents.iter().rev()

531-593: Good coverage; add tests for precedence and type mismatch

  • Add a test where the same key appears in multiple documents to assert intended precedence.
  • Add a test where the section exists but isn’t a map (e.g., section: "not-a-map") to assert InvalidType vs NotFound per the proposed change.
crates/common/src/lib.rs (1)

23-23: Exporting parsed_meta publicly is appropriate

Public module export is consistent with downstream usage (raindex_client, UI). No cfg-gating needed per project conventions.

tauri-app/src-tauri/src/commands/trade_debug.rs (1)

151-151: Arity update for AddOrderArgs::new_from_deployment: OK

Passing None for meta matches the new signature and preserves behavior in this test.

crates/quote/src/order_quotes.rs (1)

291-291: Arity update for AddOrderArgs::new_from_deployment in tests: OK

Call-site updated correctly to pass the new optional meta argument.

crates/integration_tests/src/lib.rs (1)

96-96: Integration tests updated for new AddOrderArgs arity: OK

Both call-sites now provide the explicit None for meta, consistent with the new API.

Also applies to: 208-208

tauri-app/src-tauri/src/commands/order_quote.rs (1)

149-149: Arity update for AddOrderArgs::new_from_deployment: OK — scan repo for stragglers

Automated scan returned no output (tools may be unavailable). Verify locally that there are no remaining two-arg calls to new_from_deployment; e.g. run: rg -nP --type=rust '\bnew_from_deployment\s*(' or ast-grep --pattern $'$::new_from_deployment($, $_)'.

crates/js_api/src/gui/order_operations.rs (2)

7-7: Import OK — confirm wasm compatibility

Import matches other usages in the repo (e.g. crates/js_api/src/gui/state_management.rs, crates/common/src/parsed_meta.rs). Verify rain_metadata and this crate’s Cargo.toml/features allow building for wasm (avoid enabling std-only features).


490-501: Remove unnecessary clone of dotrain_instance_v1

generate_dotrain_instance_v1 returns a DotrainGuiStateV1 (GUI state fields present) and dotrain_instance_v1 isn't used afterwards — safe to move instead of cloning.

-        let dotrain_instance_v1 = self.generate_dotrain_instance_v1()?;
-        let meta = RainMetaDocumentV1Item::try_from(dotrain_instance_v1.clone())?;
+        let dotrain_instance_v1 = self.generate_dotrain_instance_v1()?;
+        let meta = RainMetaDocumentV1Item::try_from(dotrain_instance_v1)?;
crates/js_api/Cargo.toml (1)

40-40: Add rain-metadata: workspace wiring OK — confirm wasm compatibility

  • Workspace wiring: confirmed — root Cargo.toml [workspace.dependencies] contains rain-metadata = { path = "lib/rain.interpreter/lib/rain.metadata/crates/cli" } (Cargo.toml:43); crates/cli (Cargo.toml:48), crates/common (Cargo.toml:32) and crates/js_api (Cargo.toml:40) use rain-metadata = { workspace = true }; tauri-app/src-tauri/Cargo.toml:22 also references the CLI path.
  • Wasm: not validated here — ensure js_api is built for wasm32-unknown-unknown in CI and inspect lib/rain.interpreter/lib/rain.metadata/crates/cli for non-wasm APIs or native deps (e.g., std::fs, std::process, libc/nix/openssl) or feature flags that enable them.
crates/cli/src/commands/order/add.rs (1)

122-122: Test update to expect meta: None looks correct

Matches the new AddOrderArgs field.

crates/common/src/replays.rs (1)

159-159: LGTM: new None meta arg is threaded correctly

Call site aligns with the updated API.

crates/js_api/src/gui/mod.rs (3)

391-391: Doc tweak is fine

Wording update is clear and accurate.


701-702: Good addition: map rain_metadata::Error into GuiError

Ensures consistent error propagation from metadata paths.


789-791: Readable message mapping for RainMetadataError looks good

Keeps user-facing error text consistent.

packages/ui-components/src/lib/components/detail/OrderDetail.svelte (3)

103-109: LGTM: conditional extraction of Dotrain meta

Simple and robust gating for optional parsedMeta entries.


265-276: Dotrain tab: OK

Conditional rendering and CodeMirror wiring are correct.


265-304: Frontend checklist — run build, lint, tests and attach UI screenshot

Sandbox couldn't run the workspace npm scripts (vite/prettier/vitest not found). Run locally and attach a screenshot showing the new "Dotrain" and "Gui State" tabs:

npm run build -w @rainlanguage/ui-components
npm run svelte-lint-format-check -w @rainlanguage/ui-components
npm run test -w @rainlanguage/ui-components

Confirm tabs appear in the built UI and upload the screenshot per project guidelines.

packages/ui-components/src/__tests__/OrderDetail.test.ts (3)

79-81: Test fixture update is appropriate

Providing a concrete rainlang and default parsedMeta matches component expectations.


340-362: Dotrain tab test: good coverage

Verifies conditional tab presence when Dotrain source exists.


363-397: GUI state tab test: good and realistic

Covers Map normalization and tab rendering.

crates/quote/src/quote_debug.rs (1)

174-175: LGTM: updated calls to pass None meta

All call sites reflect the new constructor arity without altering behavior.

Also applies to: 304-305, 441-442

crates/common/src/dotrain_order.rs (3)

623-647: Frontmatter/body assembly: LGTM

Combining StrictYAML-rendered frontmatter with FRONTMATTER_SEPARATOR and the original body is correct and spec-compliant.


649-706: GUI pruning logic: LGTM

Cloning gui and filtering to the selected deployment is straightforward and safe. Read-lock error mapping is appropriate.


1509-1754: Great test coverage for pruning behavior

The test thoroughly validates each pruned section and GUI deployment filtering. This will catch regressions in the frontmatter builder.

crates/common/src/parsed_meta.rs (3)

20-40: Selective metadata extraction is correct

Filtering to DotrainGuiStateV1 and DotrainSourceV1 and returning None for others matches the intended frontend scope.


42-52: Compact collect/filter: LGTM

The collect + flatten pattern is fine here and keeps control flow simple.


54-60: CBOR sequence parsing path is appropriate

Decoding via RainMetaDocumentV1Item::cbor_decode and reusing parse_multiple is the right split.

crates/common/src/raindex_client/mod.rs (3)

127-148: Network resolution behavior matches product expectations

Treating Some([]) the same as None is preserved. Returning concrete NetworkCfgs simplifies callers.

Please add a small WASM test to lock in the Some([]) behavior (treat as “all networks”), consistent with prior learnings.


150-174: get_multi_subgraph_args refactor: LGTM

The refactor is clean and preserves external behavior. Error on empty result is retained.


259-269: New error variants: good coverage

New variants cover meta and metaboard cases with clear messages. Readable messages look consistent.

crates/js_api/src/gui/state_management.rs (3)

119-157: Select-tokens resolution: LGTM

Resolving token addresses from current IO and emitting only configured select-tokens is correct and avoids leaking unrelated tokens.


159-173: Vault ID hex formatting: confirm expected casing

Hex is emitted lowercase (0x{:x}). Ensure consumers expect lowercase; if not, switch to {:X} or normalize downstream.


174-195: Preset ID handling in field_values

Using the preset ID when is_preset is true and the binding key otherwise is a convention; confirm this matches the expected GUI state schema for DotrainGuiStateV1.

crates/common/src/add_order.rs (2)

86-95: AddOrderArgs meta field: LGTM

The new optional meta field is well-placed and keeps the builder flexible.


1631-1701: Meta sequence test: LGTM

Verifies ordering and types (RainlangSource, DotrainSource, DotrainGuiState) and content-type. Good signal.

crates/common/src/raindex_client/orders.rs (7)

2-2: LGTM!

The import of ParsedMeta is correctly added to support the new parsing functionality.


11-11: LGTM!

The import of alloy::hex::decode is appropriate for hex string decoding in the metadata parsing functionality.


60-60: LGTM!

The addition of the parsed_meta field to the RaindexOrder struct correctly extends the data model to include parsed metadata information.


114-117: LGTM!

The WASM getter for parsed_meta is correctly implemented with proper attribute naming and return type.


180-182: LGTM!

The non-WASM getter for parsed_meta is correctly implemented for consistency across target environments.


621-622: Improve error handling for rainlang decoding.

The current pattern with map().transpose()? could cause silent failures if the metadata exists but rainlang decoding fails. The error should be explicitly propagated.

Apply this diff to improve error handling:

-        let rainlang = order
-            .meta
-            .as_ref()
-            .map(|meta| meta.0.try_decode_rainlangsource())
-            .transpose()?;
+        let rainlang = order
+            .meta
+            .as_ref()
+            .map(|meta| meta.0.try_decode_rainlangsource())
+            .transpose()
+            .map_err(|e| RaindexError::MetaDecodeError(format!("Failed to decode rainlang: {}", e)))?;

Likely an incorrect or invalid review comment.


664-676: Use the existing RaindexError::ParseMetaError or add a new RaindexError variant for contextual metadata parse errors.

crates/common/src/raindex_client/mod.rs defines ParseMetaError(#[from] rain_metadata::Error); the suggested diff references a non‑existent RaindexError::MetaParseError and tries to pass a String (won't compile). Either keep the current mapping (rain_metadata::Error -> RaindexError::ParseMetaError) or add a new RaindexError variant that includes context (e.g., order id) and map parse_from_bytes errors to that variant in crates/common/src/raindex_client/orders.rs.

Likely an incorrect or invalid review comment.

Comment thread crates/cli/src/commands/order/add.rs Outdated
Comment thread crates/cli/src/commands/order/calldata.rs
Comment thread crates/common/src/add_order.rs
Comment thread crates/common/src/add_order.rs
Comment thread crates/common/src/dotrain_order.rs
Comment on lines 216 to 218
gui.setVaultId('output', 'token2', '223');
gui.setVaultId('input', 'token1', '134');
gui.setFieldValue('fixed-io', '10');
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot Sep 24, 2025

Choose a reason for hiding this comment

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

🧹 Nitpick

Confirm decimal vault ID handling is intentional across UI and Dotrain

You switched to decimal strings ('223', '134') in Dotrain; ensure the UI inputs use the same values (see earlier comment) so the “only secret/nonce differ” assumption holds. If decimals are the new canonical format, consider adding a brief assertion or comment to make this explicit.

🤖 Prompt for AI Agents
In
packages/webapp/src/routes/deploy/[orderName]/[deploymentKey]/fullDeployment.test.ts
around lines 216 to 218, the test sets vault IDs as decimal strings in Dotrain
but the UI inputs may not match; update the test so the GUI calls use the same
decimal string values ('223', '134') for setVaultId (or explicitly assert the
UI-normalized value equals the Dotrain decimal) and add a short comment or
assertion stating that decimal string IDs are the canonical format to make the
“only secret/nonce differ” assumption explicit.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

nothing to do here

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.

@findolor, understood! I'll leave this as-is then.

( ._.)


🧠 Learnings used
Learnt from: brusherru
PR: rainlanguage/rain.orderbook#1978
File: packages/webapp/src/routes/deploy/[orderName]/[deploymentKey]/fullDeployment.test.ts:22-29
Timestamp: 2025-08-15T20:56:15.592Z
Learning: In packages/webapp/src/routes/deploy/[orderName]/[deploymentKey]/fullDeployment.test.ts, brusherru prefers fail-fast testing approaches where type mismatches cause immediate test failures to alert developers about interface changes, rather than using defensive programming with type guards that might mask API evolution.

Learnt from: findolor
PR: rainlanguage/rain.orderbook#1996
File: packages/webapp/src/routes/deploy/[strategyName]/[deploymentKey]/fullDeployment.test.ts:172-172
Timestamp: 2025-07-17T10:35:53.182Z
Learning: In packages/webapp/src/routes/deploy/[strategyName]/[deploymentKey]/fullDeployment.test.ts, findolor is comfortable with hardcoded 2-second delays using setTimeout after token selection elements appear, preferring this approach over deterministic waiting patterns with waitFor.

Learnt from: findolor
PR: rainlanguage/rain.orderbook#1996
File: packages/webapp/src/routes/deploy/[strategyName]/[deploymentKey]/fullDeployment.test.ts:303-303
Timestamp: 2025-07-17T10:35:09.329Z
Learning: In packages/webapp/src/routes/deploy/[strategyName]/[deploymentKey]/fullDeployment.test.ts, findolor is fine with hardcoded 2-second delays using setTimeout in test cases for waiting after token selection, preferring this approach over deterministic waiting patterns.

Learnt from: findolor
PR: rainlanguage/rain.orderbook#1974
File: packages/ui-components/src/__tests__/DeploymentSteps.test.ts:123-126
Timestamp: 2025-07-09T12:35:45.699Z
Learning: In packages/ui-components/src/__tests__/DeploymentSteps.test.ts, findolor prefers to keep mock initializations (like setSelectToken) in individual test cases rather than consolidating them into shared beforeEach blocks, even when it results in duplication.

Learnt from: findolor
PR: rainlanguage/rain.orderbook#1588
File: packages/orderbook/test/js_api/gui.test.ts:2037-2057
Timestamp: 2025-04-08T12:53:12.526Z
Learning: In the remote network test for gui.test.ts, asserting that getCurrentDeployment() succeeds is sufficient validation that remote networks were properly fetched, as this operation would fail if the networks weren't correctly processed.

Learnt from: findolor
PR: rainlanguage/rain.orderbook#1925
File: packages/ui-components/src/__tests__/DeploymentSteps.test.ts:519-554
Timestamp: 2025-07-11T08:46:07.606Z
Learning: In packages/ui-components/src/__tests__/DeploymentSteps.test.ts, findolor prefers to keep hardcoded timeout values (like 50ms and 100ms) inline in test cases rather than extracting them to named constants, viewing such refactoring as unnecessary for test maintainability.

Learnt from: findolor
PR: rainlanguage/rain.orderbook#1687
File: crates/js_api/src/gui/order_operations.rs:470-489
Timestamp: 2025-04-29T11:17:46.178Z
Learning: In the `get_deployment_transaction_args` method of `DotrainOrderGui`, approvals are intentionally only checked against output tokens as per the design requirements.

Learnt from: findolor
PR: rainlanguage/rain.orderbook#2048
File: packages/webapp/src/__tests__/WithdrawModal.test.ts:36-37
Timestamp: 2025-08-04T09:07:00.160Z
Learning: In packages/webapp/src/__tests__/WithdrawModal.test.ts and similar test files, findolor considers it acceptable to directly unwrap .value from Float.fromFixedDecimal() and Float.parse() calls without explicit error handling, preferring to keep test fixtures simple rather than adding comprehensive error checking.

Comment on lines +42 to 44
let add_order_args =
AddOrderArgs::new_from_deployment(dotrain, deployment, None).await?;
add_order_args
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot Sep 24, 2025

Choose a reason for hiding this comment

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

🧹 Nitpick

Plumb optional meta when available (future-proofing)

You currently drop meta by always passing None. If GUI/JS generates meta soon, consider adding a meta parameter to this command to pass through.

🤖 Prompt for AI Agents
In tauri-app/src-tauri/src/commands/order.rs around lines 42 to 44, the code
always calls AddOrderArgs::new_from_deployment(dotrain, deployment, None).await?
which drops any future meta; modify the command to accept an optional meta
parameter (e.g., meta: Option<YourMetaType>), thread that Option through to the
call instead of None, and update the function signature, any Tauri command
bindings and types used by the GUI/JS to accept and forward this optional meta
so AddOrderArgs::new_from_deployment receives the provided meta when present.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

this is not needed at the moment

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.

@findolor, understood! The current approach of passing None for meta works perfectly fine for the existing requirements. Thanks for the clarification.


🧠 Learnings used
Learnt from: findolor
PR: rainlanguage/rain.orderbook#2163
File: crates/cli/src/commands/order/calldata.rs:47-48
Timestamp: 2025-09-24T10:54:42.051Z
Learning: In crates/cli/src/commands/order/calldata.rs, the config_deployment variable is used both as a parameter to AddOrderArgs::new_from_deployment() and later to extract RPC information, requiring the clone() to maintain access after ownership transfer.

Learnt from: 0xgleb
PR: rainlanguage/rain.orderbook#1790
File: tauri-app/src-tauri/src/commands/vault.rs:67-67
Timestamp: 2025-05-17T15:32:28.733Z
Learning: For the PR focused on testing Tauri commands::order module, the generic type parameter R: Runtime was selectively added where needed for the PR scope, applying the changes primarily to order.rs and related files while leaving other modules like vault.rs for potential future refactoring.

Comment on lines +96 to 98
let add_order_args =
AddOrderArgs::new_from_deployment(dotrain, deployment, None).await?;
let calldata = add_order_args
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot Sep 24, 2025

Choose a reason for hiding this comment

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

🧹 Nitpick

Same as above: consider exposing meta for calldata generation

Helps preserve metadata end-to-end.

🤖 Prompt for AI Agents
In tauri-app/src-tauri/src/commands/order.rs around lines 96 to 98, the calldata
is built from AddOrderArgs::new_from_deployment but metadata is not propagated;
update the Create flow so AddOrderArgs/new_from_deployment (or the call site)
accepts and preserves an optional meta parameter and ensure that the calldata
construction includes that meta field. Concretely, add an Option<Meta> parameter
(or carry through deployment.meta) into the AddOrderArgs creation, propagate it
through the AddOrderArgs structure, and include the meta when generating
calldata so metadata is preserved end-to-end.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

this is not needed at the moment

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.

@findolor Understood! I'll skip this suggestion for now. You know the codebase requirements best.

🐰
( )
( )


---

<details>
<summary>🧠 Learnings used</summary>

```
Learnt from: findolor
PR: rainlanguage/rain.orderbook#2163
File: crates/cli/src/commands/order/calldata.rs:47-48
Timestamp: 2025-09-24T10:54:42.051Z
Learning: In crates/cli/src/commands/order/calldata.rs, the config_deployment variable is used both as a parameter to AddOrderArgs::new_from_deployment() and later to extract RPC information, requiring the clone() to maintain access after ownership transfer.
```

---

```
Learnt from: findolor
PR: rainlanguage/rain.orderbook#1903
File: crates/cli/src/commands/order/calldata.rs:47-57
Timestamp: 2025-06-17T16:46:19.035Z
Learning: In the CLI command `crates/cli/src/commands/order/calldata.rs`, the user prefers to let lower-level errors from `try_into_call()` bubble up when the RPCs list is empty, rather than adding early validation checks with custom error messages.
```

</details>



<!-- This is an auto-generated reply by CodeRabbit -->

Comment thread tauri-app/src/lib/services/loadRemoteSettings.ts
Comment thread crates/common/src/raindex_client/mod.rs Outdated
Comment on lines +141 to +143
let mut networks = Vec::with_capacity(all_nets.len());
for network in all_nets.values() {
networks.push(network.clone());
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
let mut networks = Vec::with_capacity(all_nets.len());
for network in all_nets.values() {
networks.push(network.clone());
let networks = all_nets.values().cloned().collect();

(meta) => 'DotrainGuiStateV1' in meta
)?.DotrainGuiStateV1;

const isPlainObject = (value: unknown): value is Record<string, unknown> => {
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.

hm this doesn't seem like the right place for this code at all, plus it looks like it's pointing to something not being very clean elsewhere

return proto === Object.prototype || proto === null;
};

const convertMaps = (value: unknown): unknown => {
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.

this too - why is this here?

};

$: dotrainSource = $orderDetailQuery.data?.parsedMeta?.find(
(meta) => 'DotrainSourceV1' in meta
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.

why do have to do this in the svelte component? this should be in the sdk - we can still include all meta found, sure, but DotrainSourceV1 and DotrainGuiStateV1 are important enough they should just have their own place on the order object and be ready for use immediately

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: 3

Caution

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

⚠️ Outside diff range comments (1)
crates/common/src/raindex_client/add_orders.rs (1)

37-41: Use Address type for orderbookAddress (consistency with removeOrders)

The wasm binding marks orderbookAddress as "Hex" but it’s an EVM address and is parsed as Address. Remove‑orders uses "Address". Align to avoid JS API inconsistency.

-        #[wasm_export(
-            js_name = "orderbookAddress",
-            param_description = "Orderbook contract address",
-            unchecked_param_type = "Hex"
-        )]
+        #[wasm_export(
+            js_name = "orderbookAddress",
+            param_description = "Orderbook contract address",
+            unchecked_param_type = "Address"
+        )]
♻️ Duplicate comments (3)
crates/common/src/raindex_client/orders.rs (2)

135-148: Avoid cloning parsed_meta in wasm dotrain getters

Iterate over references instead of calling parsed_meta() (which clones) and then into_iter(). This removes an extra Vec clone per call.

 #[wasm_bindgen(getter = dotrainSource)]
 pub fn dotrain_source(&self) -> Option<String> {
-    self.parsed_meta().into_iter().find_map(|meta| match meta {
-        ParsedMeta::DotrainSourceV1(source) => Some(source.0),
-        _ => None,
-    })
+    self.parsed_meta.iter().find_map(|meta| match meta {
+        ParsedMeta::DotrainSourceV1(source) => Some(source.0.clone()),
+        _ => None,
+    })
 }
 
 #[wasm_bindgen(getter = dotrainGuiState)]
 pub fn dotrain_gui_state(&self) -> Option<String> {
-    self.parsed_meta().into_iter().find_map(|meta| match meta {
-        ParsedMeta::DotrainGuiStateV1(state) => serde_json::to_string(&state).ok(),
-        _ => None,
-    })
+    self.parsed_meta.iter().find_map(|meta| match meta {
+        ParsedMeta::DotrainGuiStateV1(state) => serde_json::to_string(state).ok(),
+        _ => None,
+    })
 }

Based on learnings


213-224: Avoid cloning parsed_meta in non‑wasm dotrain getters

Same optimization as wasm: use iter() over the field to avoid cloning.

 pub fn dotrain_source(&self) -> Option<String> {
-    self.parsed_meta().into_iter().find_map(|meta| match meta {
-        ParsedMeta::DotrainSourceV1(source) => Some(source.0),
-        _ => None,
-    })
+    self.parsed_meta.iter().find_map(|meta| match meta {
+        ParsedMeta::DotrainSourceV1(source) => Some(source.0.clone()),
+        _ => None,
+    })
 }
 
 pub fn dotrain_gui_state(&self) -> Option<String> {
-    self.parsed_meta().into_iter().find_map(|meta| match meta {
-        ParsedMeta::DotrainGuiStateV1(state) => serde_json::to_string(&state).ok(),
-        _ => None,
-    })
+    self.parsed_meta.iter().find_map(|meta| match meta {
+        ParsedMeta::DotrainGuiStateV1(state) => serde_json::to_string(state).ok(),
+        _ => None,
+    })
 }

Based on learnings

crates/common/src/raindex_client/mod.rs (1)

148-166: Simplify collection when resolving ‘all networks’

Inline the map values collection to reduce locals.

-            Some(_) | None => {
-                let all_nets = self.orderbook_yaml.get_networks()?;
-                let networks = all_nets.values().cloned().collect();
-                Ok(networks)
-            }
+            Some(_) | None => Ok(self.orderbook_yaml.get_networks()?.values().cloned().collect()),

As per coding guidelines

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 87c4151 and d95d405.

📒 Files selected for processing (8)
  • crates/common/src/dotrain_order.rs (4 hunks)
  • crates/common/src/raindex_client/add_orders.rs (2 hunks)
  • crates/common/src/raindex_client/mod.rs (4 hunks)
  • crates/common/src/raindex_client/orders.rs (13 hunks)
  • crates/common/src/raindex_client/remove_orders.rs (2 hunks)
  • crates/js_api/src/gui/state_management.rs (8 hunks)
  • crates/settings/src/yaml/dotrain.rs (1 hunks)
  • packages/webapp/src/routes/+layout.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
crates/*/{src,tests,benches,examples}/**/*.rs

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Rust code must pass clippy with all warnings denied (cargo clippy --workspace --all-targets --all-features -D warnings)

Files:

  • crates/js_api/src/gui/state_management.rs
  • crates/common/src/raindex_client/orders.rs
  • crates/common/src/raindex_client/remove_orders.rs
  • crates/settings/src/yaml/dotrain.rs
  • crates/common/src/raindex_client/add_orders.rs
  • crates/common/src/raindex_client/mod.rs
  • crates/common/src/dotrain_order.rs
crates/**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

Rust code lives in the workspace under crates/* (e.g., cli, common, bindings, js_api, quote, subgraph, settings, math, integration_tests)

Files:

  • crates/js_api/src/gui/state_management.rs
  • crates/common/src/raindex_client/orders.rs
  • crates/common/src/raindex_client/remove_orders.rs
  • crates/settings/src/yaml/dotrain.rs
  • crates/common/src/raindex_client/add_orders.rs
  • crates/common/src/raindex_client/mod.rs
  • crates/common/src/dotrain_order.rs
**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

**/*.rs: Format Rust with nix develop -c cargo fmt --all
Lint Rust with nix develop -c rainix-rs-static (preconfigured flags)
Use snake_case for Rust crates/modules and PascalCase for types

Files:

  • crates/js_api/src/gui/state_management.rs
  • crates/common/src/raindex_client/orders.rs
  • crates/common/src/raindex_client/remove_orders.rs
  • crates/settings/src/yaml/dotrain.rs
  • crates/common/src/raindex_client/add_orders.rs
  • crates/common/src/raindex_client/mod.rs
  • crates/common/src/dotrain_order.rs
packages/webapp/**/*.{svelte,ts}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Webapp must pass Svelte lint/format checks (npm run svelte-lint-format-check -w @rainlanguage/webapp)

Files:

  • packages/webapp/src/routes/+layout.ts
packages/{webapp,ui-components}/**/*.{svelte,ts}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

If you modify frontend code, you must include a screenshot of the built webapp reflecting the change

Files:

  • packages/webapp/src/routes/+layout.ts
packages/**

📄 CodeRabbit inference engine (AGENTS.md)

JavaScript/Svelte projects live under packages/* (webapp, ui-components, orderbook)

Files:

  • packages/webapp/src/routes/+layout.ts
🧠 Learnings (17)
📚 Learning: 2025-09-24T10:59:25.666Z
Learnt from: findolor
PR: rainlanguage/rain.orderbook#2163
File: crates/js_api/src/gui/state_management.rs:196-203
Timestamp: 2025-09-24T10:59:25.666Z
Learning: In crates/js_api/src/gui/state_management.rs, the RainMetaDocumentV1Item::hash(false) method returns a slice, so wrapping the result with FixedBytes() is necessary to convert it to the expected FixedBytes type for DotrainGuiStateV1.dotrain_hash field.

Applied to files:

  • crates/js_api/src/gui/state_management.rs
📚 Learning: 2025-04-22T12:50:39.581Z
Learnt from: findolor
PR: rainlanguage/rain.orderbook#1687
File: crates/js_api/src/gui/mod.rs:258-259
Timestamp: 2025-04-22T12:50:39.581Z
Learning: In `DotrainOrderGui::generate_dotrain_text()`, the call to `.to_string()` on `self.dotrain_order.dotrain()` is necessary because there are two different implementations of the `dotrain()` method - one for WASM targets returning a String and one for non-WASM targets returning a &str. The `.to_string()` ensures type compatibility across different compilation targets.

Applied to files:

  • crates/js_api/src/gui/state_management.rs
📚 Learning: 2025-04-29T11:19:41.267Z
Learnt from: findolor
PR: rainlanguage/rain.orderbook#1687
File: crates/js_api/src/gui/state_management.rs:32-35
Timestamp: 2025-04-29T11:19:41.267Z
Learning: The team prefers the `get_dotrain_hash` function to accept owned String parameters instead of string references, even though it may result in additional allocations during serialization/deserialization.

Applied to files:

  • crates/js_api/src/gui/state_management.rs
📚 Learning: 2025-05-19T07:14:24.219Z
Learnt from: findolor
PR: rainlanguage/rain.orderbook#1838
File: crates/cli/src/output.rs:29-41
Timestamp: 2025-05-19T07:14:24.219Z
Learning: For the rainlanguage/rain.orderbook repository, findolor prefers minimal documentation for straightforward functions like `output` in crates/cli/src/output.rs where the implementation is self-explanatory.

Applied to files:

  • crates/js_api/src/gui/state_management.rs
📚 Learning: 2025-07-11T06:40:49.511Z
Learnt from: findolor
PR: rainlanguage/rain.orderbook#1983
File: crates/js_api/src/gui/mod.rs:964-1199
Timestamp: 2025-07-11T06:40:49.511Z
Learning: In crates/js_api/src/gui/mod.rs tests, findolor prefers to keep large hardcoded YAML strings (like the validation test YAML) inline in the test file rather than extracting them to separate external files for maintainability purposes.

Applied to files:

  • crates/js_api/src/gui/state_management.rs
📚 Learning: 2025-07-30T07:41:25.124Z
Learnt from: findolor
PR: rainlanguage/rain.orderbook#2012
File: crates/js_api/src/registry.rs:194-209
Timestamp: 2025-07-30T07:41:25.124Z
Learning: In the rainlanguage/rain.orderbook codebase, findolor considers performance implications of HashMap to js_sys::Map conversions in WASM getter methods to be negligible and prefers not to document such performance considerations in comments.

Applied to files:

  • crates/js_api/src/gui/state_management.rs
📚 Learning: 2025-09-02T08:04:34.729Z
Learnt from: findolor
PR: rainlanguage/rain.orderbook#2117
File: crates/js_api/src/gui/select_tokens.rs:421-424
Timestamp: 2025-09-02T08:04:34.729Z
Learning: User findolor in the rainlanguage/rain.orderbook codebase prefers not to change test code when tests are already passing, even if there appear to be type mismatches or potential issues. Working tests should be left alone unless there are actual errors.

Applied to files:

  • crates/js_api/src/gui/state_management.rs
📚 Learning: 2025-07-16T05:52:05.576Z
Learnt from: findolor
PR: rainlanguage/rain.orderbook#1994
File: crates/common/src/raindex_client/vaults.rs:59-59
Timestamp: 2025-07-16T05:52:05.576Z
Learning: User findolor prefers to handle documentation updates for getter methods in batch via dedicated PRs rather than addressing them individually during feature development, as mentioned for the formatted amount string fields in crates/common/src/raindex_client/vaults.rs.

Applied to files:

  • crates/js_api/src/gui/state_management.rs
📚 Learning: 2025-07-09T14:00:12.206Z
Learnt from: findolor
PR: rainlanguage/rain.orderbook#1975
File: crates/js_api/src/gui/state_management.rs:412-412
Timestamp: 2025-07-09T14:00:12.206Z
Learning: In crates/js_api/src/gui/state_management.rs tests, findolor prefers to keep hard-coded serialized state constants (like SERIALIZED_STATE) rather than dynamically generating them, even when it may make tests more brittle to maintain.

Applied to files:

  • crates/js_api/src/gui/state_management.rs
📚 Learning: 2025-10-02T19:17:20.332Z
Learnt from: findolor
PR: rainlanguage/rain.orderbook#2163
File: crates/common/src/raindex_client/orders.rs:738-741
Timestamp: 2025-10-02T19:17:20.332Z
Learning: In crates/common/src/raindex_client/orders.rs, fetch_dotrain_source() is intentionally called in try_from_sg_order for every order conversion because the dotrain source information is needed immediately. A future optimization with local DB logic is planned to eliminate the network round-trip concern.

Applied to files:

  • crates/common/src/raindex_client/orders.rs
  • crates/common/src/raindex_client/remove_orders.rs
  • crates/common/src/raindex_client/add_orders.rs
📚 Learning: 2025-08-01T09:07:20.383Z
Learnt from: brusherru
PR: rainlanguage/rain.orderbook#2044
File: packages/orderbook/README.md:186-189
Timestamp: 2025-08-01T09:07:20.383Z
Learning: In the rainlanguage/rain.orderbook project, Rust methods on structs like RaindexVaultsList are exported as JavaScript getters in WASM bindings using #[wasm_bindgen(getter)]. This means while the Rust code uses method calls like items(), the JavaScript/WASM API exposes them as property access like .items. The README.md correctly documents the JavaScript API surface, not the Rust implementation details.

Applied to files:

  • crates/common/src/raindex_client/orders.rs
📚 Learning: 2025-07-15T08:01:38.534Z
Learnt from: findolor
PR: rainlanguage/rain.orderbook#1994
File: crates/common/src/raindex_client/vaults.rs:282-292
Timestamp: 2025-07-15T08:01:38.534Z
Learning: In the rainlanguage/rain.orderbook codebase, findolor prefers to avoid concurrency optimizations like using `futures::future::try_join_all` for parallel processing of balance changes, considering such optimizations "not that critical at the moment" when the performance impact is minimal.

Applied to files:

  • crates/common/src/raindex_client/remove_orders.rs
  • crates/common/src/raindex_client/add_orders.rs
📚 Learning: 2025-06-24T13:36:28.797Z
Learnt from: findolor
PR: rainlanguage/rain.orderbook#1950
File: crates/common/src/raindex_client/orders.rs:301-301
Timestamp: 2025-06-24T13:36:28.797Z
Learning: In the RaindexClient codebase, when Arc::new(RwLock::new(self.clone())) is used (e.g., in get_orders and get_order_by_hash methods), this creates new Arc/RwLock wrappers around a cloned RaindexClient, but the underlying client data is functionally the same. This pattern is used to provide the correct Arc<RwLock<RaindexClient>> type expected by RaindexOrder::try_from_sg_order() method.

Applied to files:

  • crates/common/src/raindex_client/add_orders.rs
📚 Learning: 2025-07-30T07:41:39.271Z
Learnt from: findolor
PR: rainlanguage/rain.orderbook#2012
File: crates/js_api/src/registry.rs:485-512
Timestamp: 2025-07-30T07:41:39.271Z
Learning: In crates/js_api/src/registry.rs, findolor considers the current concurrent fetching of order files using futures::future::join_all without concurrency limits to be acceptable, preferring the simple approach over adding concurrency limiting mechanisms for the DotrainRegistry implementation.

Applied to files:

  • crates/common/src/raindex_client/add_orders.rs
📚 Learning: 2025-07-04T10:26:24.289Z
Learnt from: findolor
PR: rainlanguage/rain.orderbook#1956
File: crates/common/src/raindex_client/mod.rs:116-135
Timestamp: 2025-07-04T10:26:24.289Z
Learning: In crates/common/src/raindex_client/mod.rs, the get_multi_subgraph_args method intentionally treats Some(empty vector) the same as None for chain_ids parameter. Both cases should return all networks to support UI behavior where no selection or empty selection means "show all networks". Only when specific chain IDs are provided should the results be filtered.

Applied to files:

  • crates/common/src/raindex_client/mod.rs
📚 Learning: 2025-06-18T18:18:44.330Z
Learnt from: findolor
PR: rainlanguage/rain.orderbook#1938
File: crates/js_api/src/raindex/mod.rs:92-99
Timestamp: 2025-06-18T18:18:44.330Z
Learning: In crates/js_api/src/raindex/mod.rs, the get_subgraph_url_for_chain method and get_multi_subgraph_args method intentionally duplicate lookup logic because they serve different purposes: get_subgraph_url_for_chain returns only the URL string, while get_multi_subgraph_args returns MultiSubgraphArgs structures containing both URL and network information (name/label). This duplication is acceptable and by design.

Applied to files:

  • crates/common/src/raindex_client/mod.rs
📚 Learning: 2025-05-27T10:19:38.011Z
Learnt from: findolor
PR: rainlanguage/rain.orderbook#1897
File: crates/settings/src/yaml/orderbook.rs:311-311
Timestamp: 2025-05-27T10:19:38.011Z
Learning: The rainlanguage/rain.orderbook project uses strict YAML parsing (StrictYaml library), so concerns about inconsistent parsing between integer and string values in YAML (like `spec-version: 1` vs `spec-version: "1"`) are not relevant to this codebase.

Applied to files:

  • crates/common/src/dotrain_order.rs
🧬 Code graph analysis (7)
crates/js_api/src/gui/state_management.rs (4)
crates/common/src/dotrain_order.rs (2)
  • dotrain (364-366)
  • create (292-344)
crates/js_api/src/gui/deposits.rs (2)
  • deposits (76-107)
  • value (81-83)
crates/settings/src/gui.rs (4)
  • select_tokens (722-725)
  • parse_select_tokens (393-443)
  • s (947-947)
  • s (958-958)
crates/js_api/src/gui/order_operations.rs (2)
  • deployment (174-192)
  • field_values (389-392)
crates/common/src/raindex_client/orders.rs (2)
crates/js_api/src/gui/order_operations.rs (1)
  • get_metaboard_client (858-864)
crates/common/src/parsed_meta.rs (1)
  • parse_from_bytes (56-59)
crates/common/src/raindex_client/remove_orders.rs (1)
crates/common/src/raindex_client/orders.rs (7)
  • transaction (150-152)
  • transaction (225-227)
  • order (904-915)
  • order (918-929)
  • try_from_sg_order (884-953)
  • chain_id (91-93)
  • chain_id (180-182)
crates/settings/src/yaml/dotrain.rs (2)
crates/settings/src/gui.rs (2)
  • select_tokens (722-725)
  • parse_select_tokens (393-443)
crates/settings/src/yaml/context.rs (2)
  • select_tokens (69-69)
  • select_tokens (79-81)
crates/common/src/raindex_client/add_orders.rs (1)
crates/common/src/raindex_client/orders.rs (7)
  • transaction (150-152)
  • transaction (225-227)
  • order (904-915)
  • order (918-929)
  • try_from_sg_order (884-953)
  • chain_id (91-93)
  • chain_id (180-182)
crates/common/src/raindex_client/mod.rs (2)
crates/settings/src/yaml/orderbook.rs (1)
  • new (94-137)
crates/subgraph/src/multi_orderbook_client.rs (1)
  • new (25-27)
crates/common/src/dotrain_order.rs (3)
crates/settings/src/yaml/mod.rs (3)
  • clone_section_entry (486-506)
  • new (41-41)
  • get_yaml_string (47-60)
crates/settings/src/yaml/orderbook.rs (1)
  • new (94-137)
crates/settings/src/gui.rs (1)
  • deployments (135-211)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (17)
  • GitHub Check: Deploy-Preview-Push
  • GitHub Check: Deploy-Docs-Preview
  • GitHub Check: standard-tests (ubuntu-latest, rainix-sol-legal)
  • GitHub Check: standard-tests (ubuntu-latest, rainix-wasm-artifacts)
  • GitHub Check: standard-tests (ubuntu-latest, ob-rs-test, true)
  • GitHub Check: standard-tests (ubuntu-latest, test-js-bindings)
  • GitHub Check: standard-tests (ubuntu-latest, rainix-rs-static)
  • GitHub Check: standard-tests (ubuntu-latest, rainix-sol-test)
  • GitHub Check: standard-tests (ubuntu-latest, rainix-wasm-test)
  • GitHub Check: standard-tests (ubuntu-latest, rainix-sol-static)
  • GitHub Check: standard-tests (ubuntu-latest, rainix-sol-artifacts)
  • GitHub Check: standard-tests (ubuntu-latest, rainix-rs-artifacts, true)
  • GitHub Check: build-tauri (ubuntu-22.04, true)
  • GitHub Check: test
  • GitHub Check: test
  • GitHub Check: test
  • GitHub Check: git-clean
🔇 Additional comments (10)
packages/webapp/src/routes/+layout.ts (1)

14-15: Pinned settings URL looks good.

Thanks for bumping the settings source to the dotrain-enabled commit; this keeps the layout load logic aligned with the new metadata without further changes.

crates/settings/src/yaml/dotrain.rs (1)

201-203: LGTM! Consistent with existing pattern.

The addition of select-tokens parsing for deployments mirrors the implementation in get_order_for_gui_deployment (lines 168-172), ensuring consistency across the codebase. The select-tokens are correctly added to the context before DeploymentCfg::parse_from_yaml is called, allowing the deployment configuration to utilize the selected tokens during parsing.

crates/js_api/src/gui/state_management.rs (4)

41-46: LGTM: Clean DotrainSourceV1-based hashing.

The new get_dotrain_hash function correctly uses DotrainSourceV1 for hashing, replacing the previous bincode+Sha256 approach. The function signature and implementation are appropriate for its intended use.


95-203: LGTM: Well-structured state generation with proper data mapping.

The generate_dotrain_instance_v1 function correctly:

  • Computes hash from trimmed dotrain (for deployment metadata, distinct from full-template hash used in serialization)
  • Maps deposits with normalized amounts via get_deposits()
  • Resolves select tokens from current deployment state
  • Formats vault IDs deterministically as {io_type}_{index}
  • Converts field values to ValueCfg with proper preset linkage

The different hashing approach (trimmed vs. full dotrain) between this function and serialize_state/new_from_state is intentional: DotrainGuiStateV1 serves deployment metadata needs, while SerializedGuiState handles persistence/sharing with the full template.


314-316: LGTM: Consistent state restoration with full template.

The updated doc comment correctly describes that hash validation uses the "trimmed-for-deployment form" for DotrainGuiStateV1, while new_from_state continues using the full template for SerializedGuiState validation. This distinction is appropriate for their different use cases.

Also applies to: 354-355


535-636: LGTM: Test updates reflect new hashing behavior.

The refactored configured_gui helper and updated SERIALIZED_STATE constant correctly align with the new DotrainSourceV1-based hashing. Test coverage remains comprehensive.

crates/common/src/raindex_client/orders.rs (2)

631-637: Verify subgraph name uniqueness across networks

subgraph_to_chain maps by MultiSubgraphArgs.name (network label/key). If names collide across networks, chain resolution may be wrong.

Ensure all network labels/keys are unique in the YAML, or use a collision‑free identifier (e.g., pair of {url,name} or inject a unique suffix).


294-306: Graceful metaboard lookup

Returning None for missing metaboard entries is a good default; errors still propagate for other YAML issues. LGTM.

crates/common/src/raindex_client/remove_orders.rs (1)

70-86: Concurrent per‑item processing looks good

Building orders concurrently with try_join_all and fetching dotrain_source per item is correct and mirrors add‑orders path.

crates/common/src/raindex_client/add_orders.rs (1)

68-85: Concurrent per‑item processing looks good

Parallelizing order construction and dotrain fetch per item via try_join_all is appropriate here.

Comment on lines +719 to +727
let blocks_docs = StrictYamlLoader::load_from_str(&blocks_yaml).map_err(|err| {
DotrainOrderError::CleanUnusedFrontmatterError(format!(
"Failed to parse blocks YAML: {err}"
))
})?;
if let Some(blocks_doc) = blocks_docs.into_iter().next() {
scenario_hash.insert(StrictYaml::String("blocks".to_string()), blocks_doc);
}
}
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

Handle empty YAML parse result as an error.

If blocks exist in the scenario config but StrictYamlLoader::load_from_str returns an empty Vec (e.g., due to unexpected serialization output), the blocks are silently dropped rather than causing an error. This could hide issues where blocks fail to serialize/parse correctly.

Consider checking for an empty result and returning an error:

 let blocks_docs = StrictYamlLoader::load_from_str(&blocks_yaml).map_err(|err| {
     DotrainOrderError::CleanUnusedFrontmatterError(format!(
         "Failed to parse blocks YAML: {err}"
     ))
 })?;
-if let Some(blocks_doc) = blocks_docs.into_iter().next() {
-    scenario_hash.insert(StrictYaml::String("blocks".to_string()), blocks_doc);
-}
+let blocks_doc = blocks_docs.into_iter().next().ok_or_else(|| {
+    DotrainOrderError::CleanUnusedFrontmatterError(
+        "Blocks YAML parsing produced no documents".to_string()
+    )
+})?;
+scenario_hash.insert(StrictYaml::String("blocks".to_string()), blocks_doc);
📝 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
let blocks_docs = StrictYamlLoader::load_from_str(&blocks_yaml).map_err(|err| {
DotrainOrderError::CleanUnusedFrontmatterError(format!(
"Failed to parse blocks YAML: {err}"
))
})?;
if let Some(blocks_doc) = blocks_docs.into_iter().next() {
scenario_hash.insert(StrictYaml::String("blocks".to_string()), blocks_doc);
}
}
let blocks_docs = StrictYamlLoader::load_from_str(&blocks_yaml).map_err(|err| {
DotrainOrderError::CleanUnusedFrontmatterError(format!(
"Failed to parse blocks YAML: {err}"
))
})?;
let blocks_doc = blocks_docs.into_iter().next().ok_or_else(|| {
DotrainOrderError::CleanUnusedFrontmatterError(
"Blocks YAML parsing produced no documents".to_string()
)
})?;
scenario_hash.insert(StrictYaml::String("blocks".to_string()), blocks_doc);
}
🤖 Prompt for AI Agents
In crates/common/src/dotrain_order.rs around lines 719 to 727, the code
currently treats an Ok result from StrictYamlLoader::load_from_str that yields
an empty Vec as success and silently drops blocks; change this so that after
calling load_from_str you check whether the returned Vec is empty and, if so,
return a DotrainOrderError::CleanUnusedFrontmatterError describing that parsing
produced no documents for the blocks (include the offending blocks_yaml or a
brief context in the message). If the Vec is non-empty, proceed to take the
first document and insert it into scenario_hash as before.

Comment on lines +1486 to +1760
#[tokio::test]
async fn test_generate_dotrain_for_deployment_trims_sections() {
let dotrain = format!(
r#"version: {spec_version}
networks:
polygon:
rpcs:
- https://polygon.rpc
chain-id: 137
network-id: 137
currency: MATIC
goerli:
rpcs:
- https://goerli.rpc
chain-id: 5
network-id: 5
currency: ETH
tokens:
t1:
network: polygon
address: 0x1111111111111111111111111111111111111111
decimals: 18
label: Token1
symbol: TKN1
t2:
network: polygon
address: 0x2222222222222222222222222222222222222222
decimals: 18
label: Token2
symbol: TKN2
extra:
network: goerli
address: 0x3333333333333333333333333333333333333333
decimals: 18
label: Extra
symbol: EX
deployers:
polygon:
address: 0x4444444444444444444444444444444444444444
network: polygon
goerli:
address: 0x5555555555555555555555555555555555555555
network: goerli
orderbooks:
polygon-ob:
address: 0x6666666666666666666666666666666666666666
network: polygon
subgraph: polygon-subgraph
deployment-block: 123
goerli-ob:
address: 0x7777777777777777777777777777777777777777
network: goerli
subgraph: goerli-subgraph
deployment-block: 456
subgraphs:
polygon-subgraph: https://polygon.subgraph
goerli-subgraph: https://goerli.subgraph
metaboards:
polygon: https://polygon.metaboard
goerli: https://goerli.metaboard
orders:
polygon-order:
network: polygon
deployer: polygon
orderbook: polygon-ob
inputs:
- token: t1
vault-id: 0x111
outputs:
- token: t2
vault-id: 0x222
goerli-order:
network: goerli
deployer: goerli
orderbook: goerli-ob
inputs:
- token: extra
vault-id: 0x333
outputs:
- token: extra
vault-id: 0x444
scenarios:
polygon:
deployer: polygon
bindings:
key: value
goerli:
deployer: goerli
deployments:
polygon-deployment:
name: "Polygon"
description: "Polygon deployment"
order: polygon-order
scenario: polygon
goerli-deployment:
name: "Goerli"
description: "Goerli deployment"
order: goerli-order
scenario: goerli
gui:
name: "Order GUI"
description: "Order GUI description"
deployments:
polygon-deployment:
name: "Polygon GUI"
description: "Polygon GUI deployment"
deposits:
- token: t1
fields:
- binding: "key"
name: "Key Field"
goerli-deployment:
name: "Goerli GUI"
description: "Goerli GUI deployment"
deposits:
- token: extra
fields:
- binding: "other"
name: "Other Field"
---
#body
"#,
spec_version = SpecVersion::current()
);

let dotrain_order = DotrainOrder::create(dotrain.to_string(), None)
.await
.unwrap();

let trimmed = dotrain_order
.generate_dotrain_for_deployment("polygon-deployment")
.unwrap();

let frontmatter = RainDocument::get_front_matter(&trimmed).unwrap();
let yaml_value: Value = serde_yaml::from_str(frontmatter).unwrap();

let root = yaml_value.as_mapping().unwrap();
let gui = root
.get(Value::String("gui".to_string()))
.and_then(|v| v.as_mapping())
.unwrap();
assert_eq!(
gui.get(Value::String("name".to_string()))
.and_then(|v| v.as_str())
.unwrap(),
"Order GUI"
);
let gui_deployments = gui
.get(Value::String("deployments".to_string()))
.and_then(|v| v.as_mapping())
.unwrap();
assert_eq!(gui_deployments.len(), 1);
assert!(gui_deployments.contains_key(Value::String("polygon-deployment".to_string())));
assert!(!gui_deployments.contains_key(Value::String("goerli-deployment".to_string())));
let polygon_gui = gui_deployments
.get(Value::String("polygon-deployment".to_string()))
.and_then(|v| v.as_mapping())
.unwrap();
let polygon_deposits = polygon_gui
.get(Value::String("deposits".to_string()))
.and_then(|v| v.as_sequence())
.unwrap();
assert_eq!(polygon_deposits.len(), 1);
let deposit_token = polygon_deposits[0]
.as_mapping()
.unwrap()
.get(Value::String("token".to_string()))
.and_then(|v| v.as_str())
.unwrap();
assert_eq!(deposit_token, "t1");

let version = root
.get(Value::String("version".to_string()))
.and_then(|v| v.as_str())
.unwrap();
assert_eq!(version, SpecVersion::current());

let networks = root
.get(Value::String("networks".to_string()))
.and_then(|v| v.as_mapping())
.unwrap();
assert_eq!(networks.len(), 1);
assert!(networks.contains_key(Value::String("polygon".to_string())));
assert!(!networks.contains_key(Value::String("goerli".to_string())));

assert!(
root.get(Value::String("tokens".to_string())).is_none(),
"trimmed doc should omit tokens section"
);

let deployers = root
.get(Value::String("deployers".to_string()))
.and_then(|v| v.as_mapping())
.unwrap();
assert_eq!(deployers.len(), 1);
assert!(deployers.contains_key(Value::String("polygon".to_string())));

let orderbooks = root
.get(Value::String("orderbooks".to_string()))
.and_then(|v| v.as_mapping())
.unwrap();
assert_eq!(orderbooks.len(), 1);
assert!(orderbooks.contains_key(Value::String("polygon-ob".to_string())));

let subgraphs = root
.get(Value::String("subgraphs".to_string()))
.and_then(|v| v.as_mapping())
.unwrap();
assert_eq!(subgraphs.len(), 1);
assert!(subgraphs.contains_key(Value::String("polygon-subgraph".to_string())));

let metaboards = root
.get(Value::String("metaboards".to_string()))
.and_then(|v| v.as_mapping())
.unwrap();
assert_eq!(metaboards.len(), 1);
assert!(metaboards.contains_key(Value::String("polygon".to_string())));

let orders = root
.get(Value::String("orders".to_string()))
.and_then(|v| v.as_mapping())
.unwrap();
assert_eq!(orders.len(), 1);
assert!(orders.contains_key(Value::String("polygon-order".to_string())));
let polygon_order = orders
.get(Value::String("polygon-order".to_string()))
.and_then(|v| v.as_mapping())
.unwrap();
let polygon_inputs = polygon_order
.get(Value::String("inputs".to_string()))
.and_then(|v| v.as_sequence())
.unwrap();
let polygon_input_entry = polygon_inputs[0].as_mapping().unwrap();
assert!(
!polygon_input_entry.contains_key(Value::String("vault-id".to_string())),
"trimmed doc should omit input vault ids"
);
let polygon_outputs = polygon_order
.get(Value::String("outputs".to_string()))
.and_then(|v| v.as_sequence())
.unwrap();
let polygon_output_entry = polygon_outputs[0].as_mapping().unwrap();
assert!(
!polygon_output_entry.contains_key(Value::String("vault-id".to_string())),
"trimmed doc should omit output vault ids"
);

let deployments = root
.get(Value::String("deployments".to_string()))
.and_then(|v| v.as_mapping())
.unwrap();
assert_eq!(deployments.len(), 1);
assert!(deployments.contains_key(Value::String("polygon-deployment".to_string())));

let scenarios = root
.get(Value::String("scenarios".to_string()))
.and_then(|v| v.as_mapping())
.unwrap();
assert_eq!(scenarios.len(), 1);
let scenario_entry = scenarios
.get(Value::String("polygon".to_string()))
.and_then(|v| v.as_mapping())
.unwrap();
assert!(scenario_entry
.get(Value::String("scenarios".to_string()))
.is_none());
assert!(
scenario_entry
.get(Value::String("bindings".to_string()))
.is_none(),
"trimmed doc should omit scenario bindings"
);

assert!(!frontmatter.contains("goerli"));
}
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot Oct 9, 2025

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Consider adding test coverage for scenario blocks.

The test comprehensively validates the pruning behavior but doesn't cover scenarios that include a blocks field. Given the YAML round-trip serialization in scenario_to_yaml (lines 713-727), it would be valuable to verify this works correctly.

Consider adding a test case with a scenario that includes blocks, such as:

scenarios:
  polygon:
    deployer: polygon
    bindings:
      key: value
    blocks:
      - number: 100
        timestamp: 1234567890

Then verify the generated dotrain includes the blocks in the scenario section.

🤖 Prompt for AI Agents
crates/common/src/dotrain_order.rs lines 1486-1760: the existing test verifies
trimming but omits coverage for scenario blocks; add a new or extend this test
to include a scenario entry that contains a `blocks` list (e.g. one block with
number and timestamp), include that scenario in the deployment referenced by the
test, call generate_dotrain_for_deployment as before, parse the frontmatter, and
assert that the scenario mapping contains a `blocks` sequence with the expected
block fields (number and timestamp) present and correctly serialized.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

no need to do this

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.

@findolor, understood! I'll skip this suggestion.

Comment thread crates/common/src/raindex_client/orders.rs
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

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d95d405 and a435c26.

📒 Files selected for processing (4)
  • packages/ui-components/src/__tests__/DropdownActiveNetworks.test.ts (1 hunks)
  • packages/ui-components/src/__tests__/SelectToken.test.ts (1 hunks)
  • packages/ui-components/src/lib/components/deployment/SelectToken.svelte (2 hunks)
  • packages/ui-components/src/lib/components/dropdown/DropdownActiveNetworks.svelte (1 hunks)
🧰 Additional context used
📓 Path-based instructions (5)
packages/ui-components/**/*.{svelte,ts}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

UI components must pass Svelte lint/format checks (npm run svelte-lint-format-check -w @rainlanguage/ui-components)

Files:

  • packages/ui-components/src/__tests__/SelectToken.test.ts
  • packages/ui-components/src/lib/components/deployment/SelectToken.svelte
  • packages/ui-components/src/lib/components/dropdown/DropdownActiveNetworks.svelte
  • packages/ui-components/src/__tests__/DropdownActiveNetworks.test.ts
packages/ui-components/**/*.{test,spec}.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

UI components tests must pass (npm run test -w @rainlanguage/ui-components)

Files:

  • packages/ui-components/src/__tests__/SelectToken.test.ts
  • packages/ui-components/src/__tests__/DropdownActiveNetworks.test.ts
packages/{webapp,ui-components}/**/*.{svelte,ts}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

If you modify frontend code, you must include a screenshot of the built webapp reflecting the change

Files:

  • packages/ui-components/src/__tests__/SelectToken.test.ts
  • packages/ui-components/src/lib/components/deployment/SelectToken.svelte
  • packages/ui-components/src/lib/components/dropdown/DropdownActiveNetworks.svelte
  • packages/ui-components/src/__tests__/DropdownActiveNetworks.test.ts
packages/**

📄 CodeRabbit inference engine (AGENTS.md)

JavaScript/Svelte projects live under packages/* (webapp, ui-components, orderbook)

Files:

  • packages/ui-components/src/__tests__/SelectToken.test.ts
  • packages/ui-components/src/lib/components/deployment/SelectToken.svelte
  • packages/ui-components/src/lib/components/dropdown/DropdownActiveNetworks.svelte
  • packages/ui-components/src/__tests__/DropdownActiveNetworks.test.ts
packages/**/*.{test,spec}.ts

📄 CodeRabbit inference engine (AGENTS.md)

Name TypeScript test files as *.test.ts or *.spec.ts (Vitest)

Files:

  • packages/ui-components/src/__tests__/SelectToken.test.ts
  • packages/ui-components/src/__tests__/DropdownActiveNetworks.test.ts
🧠 Learnings (3)
📚 Learning: 2025-07-09T12:35:45.699Z
Learnt from: findolor
PR: rainlanguage/rain.orderbook#1974
File: packages/ui-components/src/__tests__/DeploymentSteps.test.ts:123-126
Timestamp: 2025-07-09T12:35:45.699Z
Learning: In packages/ui-components/src/__tests__/DeploymentSteps.test.ts, findolor prefers to keep mock initializations (like setSelectToken) in individual test cases rather than consolidating them into shared beforeEach blocks, even when it results in duplication.

Applied to files:

  • packages/ui-components/src/__tests__/SelectToken.test.ts
📚 Learning: 2025-07-29T12:30:44.350Z
Learnt from: findolor
PR: rainlanguage/rain.orderbook#2045
File: packages/ui-components/src/lib/components/deployment/TokenSelectionModal.svelte:52-59
Timestamp: 2025-07-29T12:30:44.350Z
Learning: In packages/ui-components/src/lib/components/deployment/TokenSelectionModal.svelte, the bind:this approach doesn't work for auto-focusing the Flowbite Input component when the modal opens, requiring the use of document.querySelector('.token-search-input') instead as a working solution.

Applied to files:

  • packages/ui-components/src/lib/components/deployment/SelectToken.svelte
📚 Learning: 2025-06-18T16:44:14.948Z
Learnt from: findolor
PR: rainlanguage/rain.orderbook#1925
File: packages/ui-components/src/lib/components/deployment/SelectToken.svelte:137-151
Timestamp: 2025-06-18T16:44:14.948Z
Learning: In the SelectToken.svelte component, the SDK validates addresses before making RPC calls, so calling saveTokenSelection on every keystroke in handleInput doesn't result in network calls until there's a full valid address.

Applied to files:

  • packages/ui-components/src/lib/components/deployment/SelectToken.svelte
🔇 Additional comments (6)
packages/ui-components/src/__tests__/DropdownActiveNetworks.test.ts (1)

81-92: LGTM! Well-structured test for filtering behavior.

The test correctly verifies that invalid chain IDs are automatically removed from the store when the component renders. The use of waitFor properly handles the async reactive updates.

packages/ui-components/src/lib/components/dropdown/DropdownActiveNetworks.svelte (2)

12-27: LGTM! Clean state management for valid chain IDs.

The introduction of validChainIds as a separate state variable improves clarity and provides a clear source of truth for validation. The reactive block properly handles both success and error cases.


37-40: LGTM! Proper filtering in event handler.

The filtering of incoming chain IDs ensures that only valid selections can be set through user interaction. This provides defense-in-depth alongside the reactive filtering block.

packages/ui-components/src/__tests__/SelectToken.test.ts (1)

87-93: LGTM! Test correctly verifies prepopulated token state rendering.

The test appropriately validates that when getTokenInfo returns prepopulated state (Ethereum token), the component displays the token name in dropdown mode. The use of waitFor with findByText properly handles the asynchronous rendering from onMount.

packages/ui-components/src/lib/components/deployment/SelectToken.svelte (2)

33-35: Correctly syncs selectedToken with tokenInfo in dropdown mode.

This ensures prepopulated token state is properly reflected in the dropdown UI when the component mounts.


96-98: Correctly syncs selectedToken after token selection.

This maintains consistency between tokenInfo and selectedToken in dropdown mode after setSelectToken completes, ensuring the UI displays the selected token.

Comment on lines +29 to +34
$: {
const filtered = $selectedChainIds.filter((chainId) => validChainIds.includes(chainId));
if (filtered.length !== $selectedChainIds.length) {
selectedChainIds.set(filtered);
}
}
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot Oct 12, 2025

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Consider adding a comment to explain the reactive self-correction.

This reactive block filters $selectedChainIds to remove invalid chain IDs and updates the store if needed. While the length check prevents infinite loops, this pattern of a reactive block updating a store it depends on can be subtle for maintainers.

Consider adding a brief comment:

+	// Reactive block to filter out invalid chain IDs from selectedChainIds
+	// Runs when validChainIds or selectedChainIds changes
 	$: {
 		const filtered = $selectedChainIds.filter((chainId) => validChainIds.includes(chainId));
 		if (filtered.length !== $selectedChainIds.length) {
 			selectedChainIds.set(filtered);
 		}
 	}

Additionally, verify that frequent updates to validChainIds won't cause performance issues or unwanted side effects in the reactive chain.

📝 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
$: {
const filtered = $selectedChainIds.filter((chainId) => validChainIds.includes(chainId));
if (filtered.length !== $selectedChainIds.length) {
selectedChainIds.set(filtered);
}
}
// Reactive block to filter out invalid chain IDs from selectedChainIds
// Runs when validChainIds or selectedChainIds changes
$: {
const filtered = $selectedChainIds.filter((chainId) => validChainIds.includes(chainId));
if (filtered.length !== $selectedChainIds.length) {
selectedChainIds.set(filtered);
}
}
🤖 Prompt for AI Agents
In
packages/ui-components/src/lib/components/dropdown/DropdownActiveNetworks.svelte
around lines 29 to 34, add a brief inline comment above the reactive block
explaining that the block self-corrects the $selectedChainIds by filtering out
invalid IDs and that the length comparison prevents an infinite reactive loop;
also add a short note about potential performance concerns if validChainIds
changes frequently and recommend introducing a guard (e.g., debounce or
change-detection) if that becomes an issue.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

not needed

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.

@findolor, understood. I'll skip this suggestion. Thank you for the feedback!

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

♻️ Duplicate comments (1)
crates/common/src/raindex_client/orders.rs (1)

994-1003: Make CBOR decode resilient to malformed metabytes.

The current implementation propagates CBOR decode and conversion errors, which aborts fetch_dotrain_source() if any metabytes blob is invalid. Since metabytes emission is permissionless (per @hardyjosh's previous comment), invalid data is expected and has caused production bugs.

Implement defensive error handling that skips invalid entries and continues scanning:

 for meta_bytes in metabytes {
-    let documents = RainMetaDocumentV1Item::cbor_decode(&meta_bytes)?;
+    let Ok(documents) = RainMetaDocumentV1Item::cbor_decode(&meta_bytes) else {
+        // Skip non-CBOR/unknown payloads from permissionless emitters
+        continue;
+    };
     for document in documents {
         if document.magic == KnownMagic::DotrainSourceV1 {
-            let source = DotrainSourceV1::try_from(document)?;
-            self.parsed_meta.push(ParsedMeta::DotrainSourceV1(source));
-            return Ok(());
+            match DotrainSourceV1::try_from(document) {
+                Ok(source) => {
+                    self.parsed_meta.push(ParsedMeta::DotrainSourceV1(source));
+                    return Ok(());
+                }
+                Err(_) => {
+                    // Skip invalid entries; continue scanning
+                    continue;
+                }
+            }
         }
     }
 }

As noted in the previous review, this issue is relevant and has caused bugs when malformed metadata from external sources breaks order retrieval.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a435c26 and 1acf00c.

📒 Files selected for processing (2)
  • crates/common/src/raindex_client/orders.rs (14 hunks)
  • crates/common/src/raindex_client/vaults.rs (1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
crates/*/{src,tests,benches,examples}/**/*.rs

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Rust code must pass clippy with all warnings denied (cargo clippy --workspace --all-targets --all-features -D warnings)

Files:

  • crates/common/src/raindex_client/orders.rs
  • crates/common/src/raindex_client/vaults.rs
crates/**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

Rust code lives in the workspace under crates/* (e.g., cli, common, bindings, js_api, quote, subgraph, settings, math, integration_tests)

Files:

  • crates/common/src/raindex_client/orders.rs
  • crates/common/src/raindex_client/vaults.rs
**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

**/*.rs: Format Rust with nix develop -c cargo fmt --all
Lint Rust with nix develop -c rainix-rs-static (preconfigured flags)
Use snake_case for Rust crates/modules and PascalCase for types

Files:

  • crates/common/src/raindex_client/orders.rs
  • crates/common/src/raindex_client/vaults.rs
🧠 Learnings (2)
📚 Learning: 2025-10-02T19:17:20.332Z
Learnt from: findolor
PR: rainlanguage/rain.orderbook#2163
File: crates/common/src/raindex_client/orders.rs:738-741
Timestamp: 2025-10-02T19:17:20.332Z
Learning: In crates/common/src/raindex_client/orders.rs, fetch_dotrain_source() is intentionally called in try_from_sg_order for every order conversion because the dotrain source information is needed immediately. A future optimization with local DB logic is planned to eliminate the network round-trip concern.

Applied to files:

  • crates/common/src/raindex_client/orders.rs
📚 Learning: 2025-08-01T09:07:20.383Z
Learnt from: brusherru
PR: rainlanguage/rain.orderbook#2044
File: packages/orderbook/README.md:186-189
Timestamp: 2025-08-01T09:07:20.383Z
Learning: In the rainlanguage/rain.orderbook project, Rust methods on structs like RaindexVaultsList are exported as JavaScript getters in WASM bindings using #[wasm_bindgen(getter)]. This means while the Rust code uses method calls like items(), the JavaScript/WASM API exposes them as property access like .items. The README.md correctly documents the JavaScript API surface, not the Rust implementation details.

Applied to files:

  • crates/common/src/raindex_client/orders.rs
🧬 Code graph analysis (1)
crates/common/src/raindex_client/orders.rs (3)
crates/js_api/src/gui/order_operations.rs (1)
  • get_metaboard_client (858-864)
crates/settings/src/yaml/orderbook.rs (1)
  • new (94-137)
crates/common/src/parsed_meta.rs (1)
  • parse_from_bytes (56-59)
🔇 Additional comments (3)
crates/common/src/raindex_client/orders.rs (3)

294-306: LGTM: Graceful degradation when metaboard is unavailable.

The error handling correctly distinguishes between expected absences (missing metaboard config) and genuine errors. Returning Ok(None) for KeyNotFound/NotFound allows the code to continue when metaboard integration is not configured.


635-663: LGTM: Order processing with metaboard integration.

The subgraph-to-chain-id mapping is built efficiently, and the fetch_dotrain_source call is intentionally placed here per previous discussion. The error handling appropriately propagates failures from order conversion and dotrain fetching.


943-952: LGTM: Defensive metadata parsing with graceful fallback.

The use of unwrap_or_default() ensures that parsing failures result in an empty parsed_meta vector rather than aborting the order conversion. This is appropriate since metadata is optional/auxiliary information.

Comment on lines +1044 to +1047
if !local_ids.is_empty() && !sg_ids.is_empty() {
let vaults = self.get_vaults_sg(None, filters, page).await?;
return Ok(RaindexVaultsList::new(vaults));
}
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot Oct 12, 2025

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Critical: Mixed-source short-circuit violates API contract and loses data.

When both local_ids and sg_ids are non-empty, the function calls get_vaults_sg(None, ...), which fetches vaults from all configured subgraphs instead of only the chains the caller requested. This has three critical problems:

  1. API contract violation: If a user requests vaults for chains [42161, 137], they receive vaults from all chains in the configuration, not just the two they asked for.
  2. Data loss: Local DB vaults are completely ignored, even for chains that support local DB and were explicitly requested.
  3. Performance: Fetching from all subgraphs when the user wants a subset is wasteful.

The correct behavior should be one of:

  • Option A (preserve original behavior): Fetch from local DB for local_ids, fetch from subgraph for sg_ids, then merge results (respecting the user's chain selection).
  • Option B (reject mixed sources): Return an error if mixed sources aren't supported, rather than silently changing behavior.
  • Option C (document and fix): If this behavior is intentional, document it clearly in the function signature and fix it to respect the requested chains.

Apply this diff to fix the issue by passing the requested sg_ids instead of None:

 if !local_ids.is_empty() && !sg_ids.is_empty() {
-    let vaults = self.get_vaults_sg(None, filters, page).await?;
+    let vaults = self.get_vaults_sg(Some(sg_ids), filters, page).await?;
     return Ok(RaindexVaultsList::new(vaults));
 }

However, this still ignores local DB data. If local DB support is being deprecated or is incompatible with subgraph data, consider returning an error instead:

 if !local_ids.is_empty() && !sg_ids.is_empty() {
-    let vaults = self.get_vaults_sg(None, filters, page).await?;
-    return Ok(RaindexVaultsList::new(vaults));
+    return Err(RaindexError::MixedSourcesNotSupported(
+        "Cannot query vaults from both local DB and subgraph sources simultaneously".to_string()
+    ));
 }

To confirm the impact, run this script to check how get_vaults is called and whether any callers rely on receiving vaults only from the requested chains:


🏁 Script executed:

#!/bin/bash
# Find all call sites of get_vaults and check the chain_ids usage pattern
rg -n -A 5 -B 2 '\.get_vaults\(' --type=rs | head -100

Length of output: 26


🏁 Script executed:

#!/bin/bash
# Search for all call sites of get_vaults in Rust sources
rg -n -C3 'get_vaults\(' -g '*.rs' | head -100

Length of output: 7524


Fix mixed-source short-circuit in get_vaults

When both local_ids and sg_ids are non-empty, the code calls

self.get_vaults_sg(None, filters, page)

which:

  • ignores the caller’s chain filter (fetches all chains),
  • drops local-DB results,
  • violates the API contract.

Replace with passing the requested sg_ids (and merge local results or reject mixed sources):

crates/common/src/raindex_client/vaults.rs:1044
 if !local_ids.is_empty() && !sg_ids.is_empty() {
-    let vaults = self.get_vaults_sg(None, filters, page).await?;
+    let vaults = self.get_vaults_sg(Some(sg_ids), filters, page).await?;
     return Ok(RaindexVaultsList::new(vaults));
 }
🤖 Prompt for AI Agents
In crates/common/src/raindex_client/vaults.rs around lines 1044-1047, the code
short-circuits to get_vaults_sg(None, filters, page) when both local_ids and
sg_ids are non-empty which ignores the caller’s chain filter and drops local
results; instead call get_vaults_sg with the actual sg_ids (pass Some(sg_ids)
not None) so the chain filter is preserved, then combine/merge the returned SG
vaults with the local-DB vaults (or explicitly return an error if mixed-source
responses are unacceptable) and return the merged RaindexVaultsList so local
results are not lost and the API contract is respected.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

yes this is the intended solution. during the local db usage we have a state that sits in between sg and local db. with this logic we make sure that if both are empty we rely on our sg logic which we used in the past.

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.

@findolor, thank you for clarifying that this is the intended behavior during the local DB transition phase. I understand now that when both local and subgraph chain IDs are present, falling back to the subgraph-only path with all chains is by design to maintain compatibility with the previous logic.

To help future reviewers understand this intentional behavior, it might be worth adding a brief comment in the code explaining this transition logic. For example:

if !local_ids.is_empty() && !sg_ids.is_empty() {
    // During transition to local DB, fall back to SG-only path for all chains
    // when mixed sources are requested to maintain compatibility.
    let vaults = self.get_vaults_sg(None, filters, page).await?;
    return Ok(RaindexVaultsList::new(vaults));
}

This would prevent similar concerns from being raised in future reviews.

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

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1acf00c and a9cc0fd.

📒 Files selected for processing (1)
  • crates/common/src/raindex_client/orders.rs (14 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
crates/*/{src,tests,benches,examples}/**/*.rs

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Rust code must pass clippy with all warnings denied (cargo clippy --workspace --all-targets --all-features -D warnings)

Files:

  • crates/common/src/raindex_client/orders.rs
crates/**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

Rust code lives in the workspace under crates/* (e.g., cli, common, bindings, js_api, quote, subgraph, settings, math, integration_tests)

Files:

  • crates/common/src/raindex_client/orders.rs
**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

**/*.rs: Format Rust with nix develop -c cargo fmt --all
Lint Rust with nix develop -c rainix-rs-static (preconfigured flags)
Use snake_case for Rust crates/modules and PascalCase for types

Files:

  • crates/common/src/raindex_client/orders.rs
🧠 Learnings (2)
📚 Learning: 2025-10-02T19:17:20.332Z
Learnt from: findolor
PR: rainlanguage/rain.orderbook#2163
File: crates/common/src/raindex_client/orders.rs:738-741
Timestamp: 2025-10-02T19:17:20.332Z
Learning: In crates/common/src/raindex_client/orders.rs, fetch_dotrain_source() is intentionally called in try_from_sg_order for every order conversion because the dotrain source information is needed immediately. A future optimization with local DB logic is planned to eliminate the network round-trip concern.

Applied to files:

  • crates/common/src/raindex_client/orders.rs
📚 Learning: 2025-08-01T09:07:20.383Z
Learnt from: brusherru
PR: rainlanguage/rain.orderbook#2044
File: packages/orderbook/README.md:186-189
Timestamp: 2025-08-01T09:07:20.383Z
Learning: In the rainlanguage/rain.orderbook project, Rust methods on structs like RaindexVaultsList are exported as JavaScript getters in WASM bindings using #[wasm_bindgen(getter)]. This means while the Rust code uses method calls like items(), the JavaScript/WASM API exposes them as property access like .items. The README.md correctly documents the JavaScript API surface, not the Rust implementation details.

Applied to files:

  • crates/common/src/raindex_client/orders.rs
🧬 Code graph analysis (1)
crates/common/src/raindex_client/orders.rs (2)
crates/js_api/src/gui/order_operations.rs (1)
  • get_metaboard_client (858-864)
crates/common/src/parsed_meta.rs (1)
  • parse_from_bytes (56-59)

Comment thread crates/common/src/raindex_client/orders.rs
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

♻️ Duplicate comments (1)
crates/common/src/raindex_client/orders.rs (1)

137-147: Avoid cloning parsed_meta in getters (duplicate).

Calling self.parsed_meta() clones the entire Vec<ParsedMeta> before iterating. Using self.parsed_meta.iter() would avoid the clone.

This was previously discussed and marked "not an issue" by the author.

Also applies to: 214-223

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a9cc0fd and 0e7ad4e.

📒 Files selected for processing (1)
  • crates/common/src/raindex_client/orders.rs (14 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
crates/*/{src,tests,benches,examples}/**/*.rs

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Rust code must pass clippy with all warnings denied (cargo clippy --workspace --all-targets --all-features -D warnings)

Files:

  • crates/common/src/raindex_client/orders.rs
crates/**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

Rust code lives in the workspace under crates/* (e.g., cli, common, bindings, js_api, quote, subgraph, settings, math, integration_tests)

Files:

  • crates/common/src/raindex_client/orders.rs
**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

**/*.rs: Format Rust with nix develop -c cargo fmt --all
Lint Rust with nix develop -c rainix-rs-static (preconfigured flags)
Use snake_case for Rust crates/modules and PascalCase for types

Files:

  • crates/common/src/raindex_client/orders.rs
🧠 Learnings (2)
📚 Learning: 2025-10-02T19:17:20.332Z
Learnt from: findolor
PR: rainlanguage/rain.orderbook#2163
File: crates/common/src/raindex_client/orders.rs:738-741
Timestamp: 2025-10-02T19:17:20.332Z
Learning: In crates/common/src/raindex_client/orders.rs, fetch_dotrain_source() is intentionally called in try_from_sg_order for every order conversion because the dotrain source information is needed immediately. A future optimization with local DB logic is planned to eliminate the network round-trip concern.

Applied to files:

  • crates/common/src/raindex_client/orders.rs
📚 Learning: 2025-08-01T09:07:20.383Z
Learnt from: brusherru
PR: rainlanguage/rain.orderbook#2044
File: packages/orderbook/README.md:186-189
Timestamp: 2025-08-01T09:07:20.383Z
Learning: In the rainlanguage/rain.orderbook project, Rust methods on structs like RaindexVaultsList are exported as JavaScript getters in WASM bindings using #[wasm_bindgen(getter)]. This means while the Rust code uses method calls like items(), the JavaScript/WASM API exposes them as property access like .items. The README.md correctly documents the JavaScript API surface, not the Rust implementation details.

Applied to files:

  • crates/common/src/raindex_client/orders.rs
🧬 Code graph analysis (1)
crates/common/src/raindex_client/orders.rs (2)
crates/js_api/src/gui/order_operations.rs (1)
  • get_metaboard_client (858-864)
crates/common/src/parsed_meta.rs (1)
  • parse_from_bytes (56-59)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Deploy-Docs-Preview

Comment thread crates/common/src/raindex_client/orders.rs Outdated
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 (1)
packages/webapp/src/routes/+layout.svelte (1)

21-55: Enable local DB sync only in non‐dev environments

-import { browser } from '$app/environment';
+import { browser, dev } from '$app/environment';-// import { startLocalDbSync } from '$lib/services/startLocalDbSync';
+import { startLocalDbSync } from '$lib/services/startLocalDbSync';-// let stopDbSync: (() => void) | undefined;
+let stopDbSync: (() => void) | undefined;-// onMount(() => {
-//   if (!browser || !raindexClient || !localDb) return;
-//   stopDbSync = startLocalDbSync({ raindexClient, localDb, chainId: 42161, intervalMs: 5_000 });
-// });
-//
-// onDestroy(() => {
-//   stopDbSync?.();
-// });
+onMount(() => {
+  if (!browser || !raindexClient || !localDb || dev) return;
+  stopDbSync = startLocalDbSync({ raindexClient, localDb, chainId: 42161, intervalMs: 5_000 });
+});
+
+onDestroy(() => stopDbSync?.());

This preserves sync in production while avoiding hot‐reload issues in development.

♻️ Duplicate comments (1)
crates/common/Cargo.toml (1)

48-48: Still missing getrandom’s wasm backend; wasm build will break.

getrandom fails to compile for wasm32 without the js feature. Please keep the workspace dependency, but add a wasm-target override with features = ["js"] so the wasm build keeps working.

 [target.'cfg(target_family = "wasm")'.dependencies]
 tokio = { workspace = true, features = [
     "sync",
     "macros",
     "io-util",
     "rt",
     "time",
 ] }
 serde-wasm-bindgen = "0.4"
-getrandom = { workspace = true }
+getrandom = { workspace = true, features = ["js"] }
 wasm-bindgen-test = "0.3"

Also applies to: 67-67

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between dc0605b and 20c9a0a.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (3)
  • crates/common/Cargo.toml (1 hunks)
  • crates/common/src/raindex_client/orders.rs (13 hunks)
  • packages/webapp/src/routes/+layout.svelte (2 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
crates/*/{src,tests,benches,examples}/**/*.rs

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Rust code must pass clippy with all warnings denied (cargo clippy --workspace --all-targets --all-features -D warnings)

Files:

  • crates/common/src/raindex_client/orders.rs
crates/**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

Rust code lives in the workspace under crates/* (e.g., cli, common, bindings, js_api, quote, subgraph, settings, math, integration_tests)

Files:

  • crates/common/src/raindex_client/orders.rs
**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

**/*.rs: Format Rust with nix develop -c cargo fmt --all
Lint Rust with nix develop -c rainix-rs-static (preconfigured flags)
Use snake_case for Rust crates/modules and PascalCase for types

Files:

  • crates/common/src/raindex_client/orders.rs
packages/webapp/**/*.{svelte,ts}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Webapp must pass Svelte lint/format checks (npm run svelte-lint-format-check -w @rainlanguage/webapp)

Files:

  • packages/webapp/src/routes/+layout.svelte
packages/{webapp,ui-components}/**/*.{svelte,ts}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

If you modify frontend code, you must include a screenshot of the built webapp reflecting the change

Files:

  • packages/webapp/src/routes/+layout.svelte
packages/**

📄 CodeRabbit inference engine (AGENTS.md)

JavaScript/Svelte projects live under packages/* (webapp, ui-components, orderbook)

Files:

  • packages/webapp/src/routes/+layout.svelte
🧠 Learnings (9)
📚 Learning: 2025-10-02T19:17:20.332Z
Learnt from: findolor
PR: rainlanguage/rain.orderbook#2163
File: crates/common/src/raindex_client/orders.rs:738-741
Timestamp: 2025-10-02T19:17:20.332Z
Learning: In crates/common/src/raindex_client/orders.rs, fetch_dotrain_source() is intentionally called in try_from_sg_order for every order conversion because the dotrain source information is needed immediately. A future optimization with local DB logic is planned to eliminate the network round-trip concern.

Applied to files:

  • crates/common/src/raindex_client/orders.rs
📚 Learning: 2025-07-15T08:01:38.534Z
Learnt from: findolor
PR: rainlanguage/rain.orderbook#1994
File: crates/common/src/raindex_client/vaults.rs:282-292
Timestamp: 2025-07-15T08:01:38.534Z
Learning: In the rainlanguage/rain.orderbook codebase, findolor prefers to avoid concurrency optimizations like using `futures::future::try_join_all` for parallel processing of balance changes, considering such optimizations "not that critical at the moment" when the performance impact is minimal.

Applied to files:

  • crates/common/src/raindex_client/orders.rs
📚 Learning: 2025-07-30T07:41:39.271Z
Learnt from: findolor
PR: rainlanguage/rain.orderbook#2012
File: crates/js_api/src/registry.rs:485-512
Timestamp: 2025-07-30T07:41:39.271Z
Learning: In crates/js_api/src/registry.rs, findolor considers the current concurrent fetching of order files using futures::future::join_all without concurrency limits to be acceptable, preferring the simple approach over adding concurrency limiting mechanisms for the DotrainRegistry implementation.

Applied to files:

  • crates/common/src/raindex_client/orders.rs
📚 Learning: 2025-08-01T09:07:20.383Z
Learnt from: brusherru
PR: rainlanguage/rain.orderbook#2044
File: packages/orderbook/README.md:186-189
Timestamp: 2025-08-01T09:07:20.383Z
Learning: In the rainlanguage/rain.orderbook project, Rust methods on structs like RaindexVaultsList are exported as JavaScript getters in WASM bindings using #[wasm_bindgen(getter)]. This means while the Rust code uses method calls like items(), the JavaScript/WASM API exposes them as property access like .items. The README.md correctly documents the JavaScript API surface, not the Rust implementation details.

Applied to files:

  • crates/common/src/raindex_client/orders.rs
📚 Learning: 2025-05-14T05:13:59.713Z
Learnt from: findolor
PR: rainlanguage/rain.orderbook#1744
File: crates/subgraph/src/orderbook_client.rs:44-46
Timestamp: 2025-05-14T05:13:59.713Z
Learning: In the rain.orderbook project, WASM dependencies are intentionally made available in non-WASM targets to facilitate testing of WASM-related functionality, so conditional compilation guards like `#[cfg(target_family = "wasm")]` should not be added to imports or implementations that may be needed for tests.

Applied to files:

  • crates/common/Cargo.toml
📚 Learning: 2025-04-30T09:28:36.960Z
Learnt from: findolor
PR: rainlanguage/rain.orderbook#1715
File: crates/js_api/src/common/mod.rs:111-118
Timestamp: 2025-04-30T09:28:36.960Z
Learning: In the rain.orderbook repository, the WASM tests are already properly configured with conditional compilation using `#[cfg(target_family = "wasm")]` and `#[cfg(not(target_family = "wasm"))]`, and don't require additional `wasm_bindgen_test_configure!(run_in_browser)` directives.

Applied to files:

  • crates/common/Cargo.toml
📚 Learning: 2025-05-14T04:49:14.621Z
Learnt from: findolor
PR: rainlanguage/rain.orderbook#1710
File: crates/quote/Cargo.toml:30-30
Timestamp: 2025-05-14T04:49:14.621Z
Learning: In the rain.orderbook repository, wasm-bindgen-utils is intentionally used as an unconditional dependency because non-wasm targets (like tests) sometimes need to use it.

Applied to files:

  • crates/common/Cargo.toml
📚 Learning: 2025-05-19T13:40:56.080Z
Learnt from: findolor
PR: rainlanguage/rain.orderbook#1858
File: crates/subgraph/src/orderbook_client/mod.rs:54-58
Timestamp: 2025-05-19T13:40:56.080Z
Learning: The `wasm_bindgen_utils` crate in the Rain Orderbook project handles conditional compilation for `JsValue` and `JsError` internally, allowing `impl From<Error> for JsValue` to work on non-WASM targets without explicit cfg guards.

Applied to files:

  • crates/common/Cargo.toml
📚 Learning: 2025-07-18T10:31:05.498Z
Learnt from: findolor
PR: rainlanguage/rain.orderbook#2008
File: crates/common/src/raindex_client/add_orders.rs:85-86
Timestamp: 2025-07-18T10:31:05.498Z
Learning: In the rainlanguage/rain.orderbook codebase, cfg-guarded imports like `#[cfg(not(target_family = "wasm"))] use super::*;` in test modules are sometimes needed to fix compiler warnings, even when similar imports exist in nested sub-modules. These should not be removed as they serve a specific purpose in the compilation process.

Applied to files:

  • crates/common/Cargo.toml
🧬 Code graph analysis (1)
crates/common/src/raindex_client/orders.rs (2)
crates/js_api/src/gui/order_operations.rs (1)
  • get_metaboard_client (858-864)
crates/common/src/parsed_meta.rs (1)
  • parse_from_bytes (56-59)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (17)
  • GitHub Check: standard-tests (ubuntu-latest, rainix-sol-legal)
  • GitHub Check: standard-tests (ubuntu-latest, rainix-wasm-artifacts)
  • GitHub Check: standard-tests (ubuntu-latest, rainix-wasm-test)
  • GitHub Check: standard-tests (ubuntu-latest, test-js-bindings)
  • GitHub Check: standard-tests (ubuntu-latest, rainix-rs-static)
  • GitHub Check: standard-tests (ubuntu-latest, rainix-sol-artifacts)
  • GitHub Check: standard-tests (ubuntu-latest, ob-rs-test, true)
  • GitHub Check: standard-tests (ubuntu-latest, rainix-sol-test)
  • GitHub Check: standard-tests (ubuntu-latest, rainix-rs-artifacts, true)
  • GitHub Check: standard-tests (ubuntu-latest, rainix-sol-static)
  • GitHub Check: build-tauri (ubuntu-22.04, true)
  • GitHub Check: test
  • GitHub Check: git-clean
  • GitHub Check: test
  • GitHub Check: test
  • GitHub Check: Deploy-Preview-Push
  • GitHub Check: Deploy-Docs-Preview
🔇 Additional comments (3)
crates/common/src/raindex_client/orders.rs (3)

294-306: LGTM! Proper error handling for optional metaboard.

The method correctly distinguishes between "metaboard not configured" (returns Ok(None)) and actual errors (propagated). This allows orders to function even when metaboard is unavailable.


635-667: Concurrent dotrain fetching improves performance.

The refactoring from sequential to concurrent processing addresses the past review suggestion. The implementation correctly:

  • Shares the subgraph_to_chain HashMap immutably across futures (line 646)
  • Uses try_join_all for concurrent execution
  • Maintains the same fail-fast error behavior as the previous sequential implementation

Note: If any order conversion or dotrain fetch fails, try_join_all returns the first error and cancels remaining futures. This matches the previous sequential behavior where the loop would exit on the first error.


947-952: LGTM! Resilient metadata parsing prevents order listing failures.

The implementation correctly handles malformed metadata blobs by swallowing decode/parse errors and returning an empty Vec instead of aborting. This ensures permissionless metadata emission cannot break order listings.

Comment on lines +959 to +1011
pub async fn fetch_dotrain_source(&mut self) -> Result<(), RaindexError> {
if self
.parsed_meta
.iter()
.any(|meta| matches!(meta, ParsedMeta::DotrainSourceV1(_)))
{
return Ok(());
}

let dotrain_gui_state = match self.parsed_meta.iter().find_map(|meta| {
if let ParsedMeta::DotrainGuiStateV1(state) = meta {
Some(state.clone())
} else {
None
}
}) {
Some(state) => state,
None => return Ok(()),
};

let client = match self.get_metaboard_client()? {
Some(client) => client,
None => return Ok(()),
};

let subject_hash = dotrain_gui_state.dotrain_hash();

let metabytes = match client
.get_metabytes_by_subject(&MetaBigInt(format!("0x{}", encode(subject_hash))))
.await
{
Ok(bytes) => bytes,
Err(_) => return Ok(()),
};

for meta_bytes in metabytes {
let documents = match RainMetaDocumentV1Item::cbor_decode(&meta_bytes) {
Ok(documents) => documents,
Err(_) => continue,
};

for document in documents {
if document.magic == KnownMagic::DotrainSourceV1 {
if let Ok(source) = DotrainSourceV1::try_from(document) {
self.parsed_meta.push(ParsedMeta::DotrainSourceV1(source));
return Ok(());
}
}
}
}

Ok(())
}
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

LGTM! Resilient error handling for optional dotrain metadata.

The method correctly implements fail-safe behavior:

  • Early returns when prerequisites are missing (no state, no client)
  • Skips invalid CBOR blobs (line 997) instead of aborting
  • Skips invalid document conversions (line 1002-1006) instead of aborting
  • Returns Ok(()) on all error paths, ensuring dotrain fetch failures don't break order operations

Optional enhancement: Consider logging skipped CBOR decode errors and conversion failures (lines 997, 1002-1006) for debugging purposes. Silent skipping is correct for resilience, but visibility into malformed metadata could aid troubleshooting.

🤖 Prompt for AI Agents
In crates/common/src/raindex_client/orders.rs around lines 959 to 1011, add
logging for the two silent skips: when CBOR decode of meta_bytes fails (around
line ~997) and when converting a document to DotrainSourceV1 fails (around lines
~1002-1006). Capture and log the decode error and the conversion error
(including a short identifier of the offending meta_bytes or document—e.g., its
length or a hex/snippet) at debug or warn level using the module's existing
logging facility, so the function still returns Ok(()) but records useful
diagnostic details for later troubleshooting.

pub async fn new_from_deployment(
dotrain: String,
deployment: DeploymentCfg,
meta: Option<Vec<RainMetaDocumentV1Item>>,
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.

why do we need this? the new meat we are adding is dotrain and it's already an arg for this 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.

why are these changes in this pr?

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.

why are these changes in this pr?

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.

why is this in this pr?

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.

why is this in this pr?

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.

why is this in this pr?

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.

why is this in this pr?

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.

not supposed to be in this pr?

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.

should this be in this pr?

@findolor
Copy link
Copy Markdown
Collaborator Author

Closing this as we have a new PR #2331

@findolor findolor closed this Nov 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants