Skip to content

Add batch order quotes WASM binding with RaindexOrders wrapper#2482

Merged
findolor merged 7 commits intomainfrom
2026-02-26-batch-quote-wasm-binding
Feb 27, 2026
Merged

Add batch order quotes WASM binding with RaindexOrders wrapper#2482
findolor merged 7 commits intomainfrom
2026-02-26-batch-quote-wasm-binding

Conversation

@findolor
Copy link
Collaborator

@findolor findolor commented Feb 26, 2026

Chained PRs

Motivation

The parent PR (#2480) flattened batch quotes into a single multicall at the crates/quote level. However, the WASM/JS layer still needed a way to call this batch function, and the existing candidates.rs was still quoting orders individually via a buffered stream with concurrency of 5.

This PR exposes the batch quoting to JS consumers and updates the internal candidate-building logic to use the same single-multicall path.

Solution

  • RaindexOrders module (orders_list.rs): New wrapper type following the RaindexVaultsList pattern. In WASM, uses an empty constructor + push(&RaindexOrder) to work around wasm-bindgen's inability to accept Vec<T> of opaque classes.
  • get_order_quotes_batch function (order_quotes.rs): Free function that converts &[RaindexOrder]Vec<SgOrder>, pre-computes pair counts per order, calls the single-multicall get_order_quotes, and slices the flat results back into per-order groups.
  • RaindexClient.getOrderQuotesBatch WASM method: Exposes the batch function to JS, accepting RaindexOrders, optional block number, and optional gas limit.
  • candidates.rs refactor: Replaced the futures::stream::buffered per-order quoting loop with a single get_order_quotes_batch call. Removed DEFAULT_QUOTE_CONCURRENCY constant and futures::StreamExt import.
  • Gas parameter cleanup: Changed gas from Option<String> to Option<u64> on both getQuotes and getOrderQuotesBatch, removing unnecessary string parsing.

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

    • Batch quote retrieval to request quotes for multiple orders in one call
    • New orders collection type (RaindexOrders) for batching orders
  • Improvements

    • Optimized quote fetching using batched requests and simplified concurrency
    • Added optional chunk-size tuning for batch requests
  • Tests

    • Added tests covering empty, single-order, and multi-order batch scenarios

New orders_list module with wasm_bindgen constructor, push, items
getter, and inner() accessor. Registered in mod.rs.
- Add get_order_quotes_batch free function that batches all order
  pairs into a single multicall and groups results per-order
- Add getOrderQuotesBatch wasm_export on RaindexClient accepting
  &RaindexOrders
- Update candidates.rs to use the batch function
- Change gas param from Option<String> to Option<u64> on getQuotes
  and getOrderQuotesBatch
@findolor findolor self-assigned this Feb 26, 2026
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 26, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 50004a9 and 62bd169.

📒 Files selected for processing (4)
  • crates/common/src/raindex_client/order_quotes.rs
  • crates/common/src/raindex_client/take_orders/mod.rs
  • crates/common/src/raindex_client/take_orders/selection.rs
  • crates/common/src/take_orders/candidates.rs

Walkthrough

Adds batch order-quoting: new RaindexOrders wrapper and a batched get_order_quotes_batch API (with wasm bindings), replaces per-order concurrent quote fetching with a single batched call, and propagates chunk_size through candidate-building paths. Tests updated to cover batch behavior.

Changes

Cohort / File(s) Summary
Batch quoting implementation
crates/common/src/raindex_client/order_quotes.rs
Added get_order_quotes_batch (method + free fn) to call a single multicall for many orders, compute per-order pair counts, and repartition flat results into per-order vectors. Exposed wasm binding getOrderQuotesBatch. Tests for empty/single/multi-order batches added.
Orders wrapper type
crates/common/src/raindex_client/orders_list.rs
New public RaindexOrders(Vec<RaindexOrder>) with serde derives, inner(), wasm-target constructors and push/items getters, and non-wasm constructors/getters. Includes tests.
Module registration
crates/common/src/raindex_client/mod.rs
Registered new public module: pub mod orders_list;.
Take-orders integration
crates/common/src/take_orders/candidates.rs, crates/common/src/raindex_client/take_orders/selection.rs, crates/common/src/raindex_client/take_orders/mod.rs
Replaced per-order concurrent quote streaming with a single get_order_quotes_batch call; added chunk_size: Option<u32> parameter propagation through build_take_order_candidates_for_pair -> build_candidates_for_chain -> get_take_orders_calldata call sites. Removed explicit concurrency stream logic.
JS API tests / exports
packages/orderbook/test/js_api/raindexClient.test.ts, dist/cjs/...
Added RaindexOrders export and test "should get order quotes batch" that constructs a RaindexOrders batch, calls getOrderQuotesBatch, and validates per-order quote alignment and fields.

Sequence Diagram

sequenceDiagram
    participant Client as Client
    participant RaindexClient as RaindexClient
    participant BatchProcessor as BatchProcessor
    participant RPC as RPC/Subgraph

    Client->>RaindexClient: get_order_quotes_batch(orders, block, chunk_size)
    RaindexClient->>BatchProcessor: to_subgraph_orders(orders)
    BatchProcessor->>BatchProcessor: compute per-order pair_counts
    BatchProcessor->>RPC: single multicall for all pairs (chunked by chunk_size)
    RPC-->>BatchProcessor: flat list of quotes
    BatchProcessor->>BatchProcessor: repartition flat results by pair_counts
    BatchProcessor-->>RaindexClient: Vec<Vec<RaindexOrderQuote>>
    RaindexClient-->>Client: per-order quote vectors
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • hardyjosh
🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main changes: adding a batch order quotes WASM binding and introducing the RaindexOrders wrapper type.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch 2026-02-26-batch-quote-wasm-binding

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@findolor findolor marked this pull request as ready for review February 26, 2026 12:53
@findolor
Copy link
Collaborator Author

@CodeRabbit review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 26, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
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

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@crates/common/src/raindex_client/order_quotes.rs`:
- Around line 198-203: Ensure get_order_quotes_batch enforces the single-chain
invariant before reusing RPCs from the first order: validate that every Order in
orders has the same chain identifier (e.g., compare chain_id or network property
exposed by Order) as orders[0] and return an error if any differ, then only
collect RPC URLs via get_rpc_urls() on orders[0] into rpcs after that check;
this prevents using first-order RPCs for mixed-chain inputs and fails fast when
orders span multiple chains.

ℹ️ Review info

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 520e924 and 50004a9.

📒 Files selected for processing (5)
  • crates/common/src/raindex_client/mod.rs
  • crates/common/src/raindex_client/order_quotes.rs
  • crates/common/src/raindex_client/orders_list.rs
  • crates/common/src/take_orders/candidates.rs
  • packages/orderbook/test/js_api/raindexClient.test.ts

@findolor findolor requested a review from hardyjosh February 26, 2026 13:07
Return an error early if orders span multiple chains, preventing
silent use of first-order RPCs for mixed-chain inputs.
…quote-wasm-binding

Resolve conflicts by replacing gas parameter with chunk_size across
batch quoting and candidate building. Plumb chunk_size through
build_take_order_candidates_for_pair and build_candidates_for_chain
to allow runtime configuration of quote chunk sizes.
Base automatically changed from 2026-02-25-batch-quote-research to main February 27, 2026 08:46
@findolor findolor merged commit a0ad195 into main Feb 27, 2026
19 of 22 checks passed
@github-actions
Copy link
Contributor

@coderabbitai assess this PR size classification for the totality of the PR with the following criterias and report it in your comment:

S/M/L PR Classification Guidelines:

This guide helps classify merged pull requests by effort and complexity rather than just line count. The goal is to assess the difficulty and scope of changes after they have been completed.

Small (S)

Characteristics:

  • Simple bug fixes, typos, or minor refactoring
  • Single-purpose changes affecting 1-2 files
  • Documentation updates
  • Configuration tweaks
  • Changes that require minimal context to review

Review Effort: Would have taken 5-10 minutes

Examples:

  • Fix typo in variable name
  • Update README with new instructions
  • Adjust configuration values
  • Simple one-line bug fixes
  • Import statement cleanup

Medium (M)

Characteristics:

  • Feature additions or enhancements
  • Refactoring that touches multiple files but maintains existing behavior
  • Breaking changes with backward compatibility
  • Changes requiring some domain knowledge to review

Review Effort: Would have taken 15-30 minutes

Examples:

  • Add new feature or component
  • Refactor common utility functions
  • Update dependencies with minor breaking changes
  • Add new component with tests
  • Performance optimizations
  • More complex bug fixes

Large (L)

Characteristics:

  • Major feature implementations
  • Breaking changes or API redesigns
  • Complex refactoring across multiple modules
  • New architectural patterns or significant design changes
  • Changes requiring deep context and multiple review rounds

Review Effort: Would have taken 45+ minutes

Examples:

  • Complete new feature with frontend/backend changes
  • Protocol upgrades or breaking changes
  • Major architectural refactoring
  • Framework or technology upgrades

Additional Factors to Consider

When deciding between sizes, also consider:

  • Test coverage impact: More comprehensive test changes lean toward larger classification
  • Risk level: Changes to critical systems bump up a size category
  • Team familiarity: Novel patterns or technologies increase complexity

Notes:

  • the assessment must be for the totality of the PR, that means comparing the base branch to the last commit of the PR
  • the assessment output must be exactly one of: S, M or L (single-line comment) in format of: SIZE={S/M/L}
  • do not include any additional text, only the size classification
  • your assessment comment must not include tips or additional sections
  • do NOT tag me or anyone else on your comment

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 27, 2026

Tip

For best results, initiate chat on the files or code changes.

SIZE=L


🧠 Learnings used
Learnt from: rouzwelt
Repo: rainlanguage/rain.orderbook PR: 0
File: :0-0
Timestamp: 2025-05-21T21:24:42.275Z
Learning: For PR `#1884`, after each commit review, I should provide a new comment with a PR size report in the format: `TOTAL=number ADDITIONS=number DELETIONS=number`, excluding irrelevant files such as lock files (package-lock.json, cargo.lock, etc.).

Learnt from: rouzwelt
Repo: rainlanguage/rain.orderbook PR: 0
File: :0-0
Timestamp: 2025-05-21T21:24:42.275Z
Learning: After each commit in PR `#1884`, I should provide a new comment with the PR size report in the format: `TOTAL=number ADDITIONS=number DELETIONS=number`. The report should exclude irrelevant files such as lock files (e.g., package-lock.json, cargo.lock).

Learnt from: rouzwelt
Repo: rainlanguage/rain.orderbook PR: 0
File: :0-0
Timestamp: 2025-05-21T21:25:47.873Z
Learning: After each new commit review for rainlanguage/rain.orderbook repository, generate a PR size report in a separate comment with the format: "TOTAL=number ADDITIONS=number DELETIONS=number". This report should exclude irrelevant files such as lock files (e.g., package-lock.json, cargo.lock).

Learnt from: rouzwelt
Repo: rainlanguage/rain.orderbook PR: 0
File: :0-0
Timestamp: 2025-05-21T21:25:47.873Z
Learning: After each new commit review for rainlanguage/rain.orderbook repository, generate a PR size report in a separate comment with the exact format: "TOTAL=number\nADDITIONS=number\nDELETIONS=number". This report should exclude irrelevant files such as lock files (package-lock.json, yarn.lock, pnpm-lock.yaml, cargo.lock).

Learnt from: rouzwelt
Repo: rainlanguage/rain.orderbook PR: 0
File: :0-0
Timestamp: 2025-05-21T22:14:22.646Z
Learning: For PR `#1884` in rainlanguage/rain.orderbook, I must consistently report the PR size after EVERY new commit in the exact format "TOTAL=number\nADDITIONS=number\nDELETIONS=number" without any formatting blocks. The report must exclude lock files (package-lock.json, yarn.lock, pnpm-lock.yaml, cargo.lock) and can be included either as part of the review or as a separate comment.

Learnt from: rouzwelt
Repo: rainlanguage/rain.orderbook PR: 0
File: :0-0
Timestamp: 2025-05-21T22:14:22.646Z
Learning: For PR `#1884` in rainlanguage/rain.orderbook, I must consistently report the PR size after EVERY new commit in the exact format "TOTAL=number\nADDITIONS=number\nDELETIONS=number" without any additional text or formatting blocks. The report must exclude lock files (package-lock.json, yarn.lock, pnpm-lock.yaml, cargo.lock) and can be included either as part of the review or as a separate comment.

Learnt from: rouzwelt
Repo: rainlanguage/rain.orderbook PR: 0
File: :0-0
Timestamp: 2025-05-21T22:46:08.530Z
Learning: For PR `#1884` in rainlanguage/rain.orderbook, the PR size report should be the only content in the comment - no text before it, no text after it, no formatting blocks, just the raw report in the exact format: "TOTAL=number\nADDITIONS=number\nDELETIONS=number". The report must exclude lock files (package-lock.json, yarn.lock, pnpm-lock.yaml, cargo.lock).

Learnt from: rouzwelt
Repo: rainlanguage/rain.orderbook PR: 0
File: :0-0
Timestamp: 2025-05-21T21:24:53.708Z
Learning: For PR `#1884` in rainlanguage/rain.orderbook, provide a separate comment after each review with PR size statistics in the format: `TOTAL=number ADDITIONS=number DELETIONS=number`, excluding lock files like package-lock.json and cargo.lock.

Learnt from: rouzwelt
Repo: rainlanguage/rain.orderbook PR: 0
File: :0-0
Timestamp: 2025-05-21T21:24:53.708Z
Learning: For PR `#1884` in rainlanguage/rain.orderbook, provide a separate comment after each review with PR size statistics in the format: `TOTAL=number ADDITIONS=number DELETIONS=number`, excluding lock files like package-lock.json and cargo.lock.

Learnt from: rouzwelt
Repo: rainlanguage/rain.orderbook PR: 0
File: :0-0
Timestamp: 2025-05-21T21:24:53.708Z
Learning: For PR `#1884` in rainlanguage/rain.orderbook, provide a separate comment after each review with PR size statistics in the format: `TOTAL=number ADDITIONS=number DELETIONS=number`, excluding lock files like package-lock.json and cargo.lock.

Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 1971
File: .github/workflows/vercel-docs-prod.yaml:32-34
Timestamp: 2025-07-11T12:30:09.245Z
Learning: findolor prefers not to pin Node versions explicitly in GitHub Actions workflows when using Nix with webapp-shell, considering the current setup sufficient for deterministic builds in the rainlanguage/rain.orderbook project.

Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 1971
File: .github/workflows/vercel-docs-prod.yaml:10-14
Timestamp: 2025-07-11T12:29:49.284Z
Learning: In GitHub Actions workflows for the rainlanguage/rain.orderbook project, findolor is comfortable with job names that may seem misleading (like "Deploy-Docs-Preview" in a production workflow) when there's only one job in the workflow, as the context makes it clear enough.

Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 2480
File: crates/quote/src/order_quotes.rs:113-115
Timestamp: 2026-02-26T05:32:00.991Z
Learning: In crates/quote/src/order_quotes.rs, get_order_quotes() intentionally uses a single BatchQuoteTarget multicall across all orders (rather than one multicall per order) to reduce RPC round-trips and improve performance. The number of quote targets is bounded by the number of non-same-token IO pairs across all submitted orders, and unbounded growth is not a concern in practice.

Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 1913
File: Cargo.toml:55-55
Timestamp: 2025-06-06T16:38:04.182Z
Learning: In rain.orderbook repository, during PR chains involving dependency updates, wasm-bindgen-utils may temporarily point to git commits that don't contain the full required functionality, with the understanding that subsequent PRs in the chain will update it to the correct commit.

Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 2480
File: crates/quote/src/order_quotes.rs:119-120
Timestamp: 2026-02-26T05:32:25.302Z
Learning: In rainlanguage/rain.orderbook, the `batch_quote` implementation guarantees that output length always equals input length across all code paths: the normal `aggregate3` success path returns exactly N results for N inputs (a multicall3 contract invariant), the `CallFailed` path manually constructs N error entries, and transport-level errors return `Err(...)` which hits the outer error branch without reaching any zip operations.

Learnt from: rouzwelt
Repo: rainlanguage/rain.orderbook PR: 0
File: :0-0
Timestamp: 2025-05-21T21:24:53.708Z
Learning: For PR `#1884` in rainlanguage/rain.orderbook, provide a separate comment after each review with PR size statistics in the format: `TOTAL=number ADDITIONS=number DELETIONS=number`, excluding lock files like package-lock.json and cargo.lock.

Learnt from: rouzwelt
Repo: rainlanguage/rain.orderbook PR: 0
File: :0-0
Timestamp: 2025-05-21T21:26:31.566Z
Learning: For PR `#1884` and future PRs in rainlanguage/rain.orderbook repository, provide PR size reports in a separate comment with ONLY the exact format "TOTAL=number\nADDITIONS=number\nDELETIONS=number", without any additional text or explanation. Reports should exclude irrelevant files such as lock files (package-lock.json, yarn.lock, pnpm-lock.yaml, cargo.lock).

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants